diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index d4848c701c6e..7a342e01fcf5 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -310,6 +310,42 @@ static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu, ret = sysparm_st(buffer, length, ¶m_val, sizeof(param_val)); break; } + case RTAS_SYSPARM_PROCESSOR_MODULE_INFO: { + int i, offset = 0; + uint16_t cores[SPAPR_MAX_MODULE_TYPES], + chips[SPAPR_MAX_MODULE_TYPES], + sockets[SPAPR_MAX_MODULE_TYPES], + mtypes = 0, len; + + if (kvmppc_rtas_get_proc_module_info(&mtypes,sockets,chips,cores)) { + ret = RTAS_OUT_NOT_SUPPORTED; + break; + } + len = (mtypes*6) + 2; + + stw_be_phys(&address_space_memory, + ppc64_phys_to_real(buffer+offset), len); + offset += 2; + + stw_be_phys(&address_space_memory, + ppc64_phys_to_real(buffer+offset), mtypes); + offset += 2; + + for (i = 0; i < mtypes; i++) { + stw_be_phys(&address_space_memory, + ppc64_phys_to_real(buffer+offset), sockets[i]); + offset += 2; + stw_be_phys(&address_space_memory, + ppc64_phys_to_real(buffer+offset), chips[i]); + offset += 2; + stw_be_phys(&address_space_memory, + ppc64_phys_to_real(buffer+offset), cores[i]); + offset += 2; + } + + ret = RTAS_OUT_SUCCESS; + break; + } case RTAS_SYSPARM_UUID: ret = sysparm_st(buffer, length, qemu_uuid, (qemu_uuid_set ? 16 : 0)); break; @@ -332,6 +368,7 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu, switch (parameter) { case RTAS_SYSPARM_SPLPAR_CHARACTERISTICS: case RTAS_SYSPARM_DIAGNOSTICS_RUN_MODE: + case RTAS_SYSPARM_PROCESSOR_MODULE_INFO: case RTAS_SYSPARM_UUID: ret = RTAS_OUT_NOT_AUTHORIZED; break; diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index ff5dc8753c49..23112da66ef3 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -489,6 +489,7 @@ int spapr_allocate_irq_block(int num, bool lsi, bool msi); /* RTAS ibm,get-system-parameter token values */ #define RTAS_SYSPARM_SPLPAR_CHARACTERISTICS 20 #define RTAS_SYSPARM_DIAGNOSTICS_RUN_MODE 42 +#define RTAS_SYSPARM_PROCESSOR_MODULE_INFO 43 #define RTAS_SYSPARM_UUID 48 /* RTAS indicator/sensor types @@ -658,4 +659,6 @@ int spapr_rng_populate_dt(void *fdt); */ #define SPAPR_LMB_FLAGS_ASSIGNED 0x00000008 +#define SPAPR_MAX_MODULE_TYPES 1 + #endif /* !defined (__HW_SPAPR_H__) */ diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 6c9c27496950..2350e48c15e9 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -2801,3 +2801,24 @@ int kvmppc_count_ppc_cores_dt(void) return num_cores; } + +int kvmppc_rtas_get_proc_module_info(uint16_t *mtypes, uint16_t *sockets, uint16_t *chips, uint16_t *cores) +{ + int _sockets = 0, _chips = 0, _cores = 0; + + /* POWER systems only support 1 module type per system + * currently + */ + mtypes[0] = 1; + if (kvmppc_count_sockets_chips_dt(&_sockets, &_chips)) + return -1; + _cores = kvmppc_count_ppc_cores_dt(); + if ( _cores <= 0 ) + return -1; + + sockets[0] = _sockets; + chips[0] = _chips / _sockets; + cores[0] = _cores / _chips; + + return 0; +} diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h index 011a4766eab0..5c02c28f5879 100644 --- a/target-ppc/kvm_ppc.h +++ b/target-ppc/kvm_ppc.h @@ -61,6 +61,7 @@ int kvmppc_put_books_sregs(PowerPCCPU *cpu); PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void); void kvmppc_set_reg_ppc_online(PowerPCCPU *cpu, unsigned int online); int kvmppc_count_ppc_cores_dt(void); +int kvmppc_rtas_get_proc_module_info(uint16_t *mtypes, uint16_t *sockets, uint16_t *chips, uint16_t *cores); #else @@ -165,6 +166,14 @@ static inline int kvmppc_count_ppc_cores_dt(void) return -1; } +static int kvmppc_rtas_get_proc_module_info(uint16_t *mtypes, + uint16_t *sockets, + uint16_t *chips, + uint16_t *cores) +{ + return -1; +} + #ifndef CONFIG_USER_ONLY static inline off_t kvmppc_alloc_rma(void **rma) {