From: Shlomo Pongratz <shlomo.pongr...@huawei.com> In order to support up to 128 cores with GIC-500 (GICv3 implementation) affinity1 must be used. GIC-500 support up to 32 clusters with up to 8 cores in a cluster. So for example, if one wishes to have 16 cores, the options are: 2 clusters of 8 cores each, 4 clusters with 4 cores each Currently only the first option is supported. In order to have more flexible scheme the virt machine must pass the desired scheme.
Signed-off-by: Shlomo Pongratz <shlomo.pongr...@huawei.com> --- target-arm/helper.c | 12 ++++++++++-- target-arm/psci.c | 18 ++++++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index f8f8d76..f555c0b 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -2035,11 +2035,19 @@ static const ARMCPRegInfo strongarm_cp_reginfo[] = { static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri) { CPUState *cs = CPU(arm_env_get_cpu(env)); - uint32_t mpidr = cs->cpu_index; - /* We don't support setting cluster ID ([8..11]) (known as Aff1 + uint32_t mpidr, aff0, aff1; + uint32_t cpuid = cs->cpu_index; + /* We don't support setting cluster ID ([16..23]) (known as Aff2 * in later ARM ARM versions), or any of the higher affinity level fields, * so these bits always RAZ. */ + /* Currently GIC-500 code supports 64 cores in 16 clusters with 8 cores each + * Future code will remove this limitation. + * This code is valid for GIC-400 too. + */ + aff0 = cpuid % 8; + aff1 = cpuid / 8; + mpidr = (aff1 << 8) | aff0; if (arm_feature(env, ARM_FEATURE_V7MP)) { mpidr |= (1U << 31); /* Cores which are uniprocessor (non-coherent) diff --git a/target-arm/psci.c b/target-arm/psci.c index d8fafab..64fbe61 100644 --- a/target-arm/psci.c +++ b/target-arm/psci.c @@ -86,6 +86,7 @@ void arm_handle_psci_call(ARMCPU *cpu) CPUARMState *env = &cpu->env; uint64_t param[4]; uint64_t context_id, mpidr; + uint32_t core, Aff1, Aff0; target_ulong entry; int32_t ret = 0; int i; @@ -121,7 +122,16 @@ void arm_handle_psci_call(ARMCPU *cpu) switch (param[2]) { case 0: - target_cpu_state = qemu_get_cpu(mpidr & 0xff); + /* MPIDR_EL1 [RES0:affinity-3:RES1:U:RES0:MT:affinity-1:affinity-0] + * GIC 500 code currently supports 32 clusters with 8 cores each + * but no more than 128 cores. Future version will have flexible + * affinity selection + * GIC 400 supports 8 cores so 0x7 for Aff0 is O.K. too + */ + Aff1 = (mpidr & 0xff00) >> (8 - 3); /* Shift by 8 multiply by 8 */ + Aff0 = mpidr & 0x7; + core = Aff1 + Aff0; + target_cpu_state = qemu_get_cpu(core); if (!target_cpu_state) { ret = QEMU_PSCI_RET_INVALID_PARAMS; break; @@ -153,7 +163,11 @@ void arm_handle_psci_call(ARMCPU *cpu) context_id = param[3]; /* change to the cpu we are powering up */ - target_cpu_state = qemu_get_cpu(mpidr & 0xff); + /* Currently supports 64 cores in 16 clusters with 8 cores each */ + Aff1 = (mpidr & 0xff00) >> (8 - 3); /* Shift by 8 multiply by 8 */ + Aff0 = mpidr & 0x7; + core = Aff1 + Aff0; + target_cpu_state = qemu_get_cpu(core); if (!target_cpu_state) { ret = QEMU_PSCI_RET_INVALID_PARAMS; break; -- 1.9.1