At the moment MPIDR_EL1 has no real storage. Instead cpu mp_affinity field stores the Aff0-Aff2 bits only and the ID register is reconstructed when needed. There is also an mp-affinity property used for TCG only.
Keep the mp-affinity property and its associated storage while making sure the MPIDR_EL1 full register is stored in cpu->isar.idregs[] as other ID registers. Signed-off-by: Eric Auger <[email protected]> --- target/arm/cpu.h | 8 +++++++- target/arm/cpu-sysregs.h.inc | 1 + target/arm/cpu.c | 17 +++++++++++++++++ target/arm/helper.c | 14 +------------- target/arm/hvf/hvf.c | 2 +- target/arm/kvm.c | 1 + target/arm/whpx/whpx-all.c | 2 +- 7 files changed, 29 insertions(+), 16 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index dcdd4eb18e..639be0713e 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1128,7 +1128,13 @@ struct ArchCPU { uint32_t reset_sctlr; uint64_t pmceid0; uint64_t pmceid1; - uint64_t mp_affinity; /* MP ID without feature bits */ + /* + * MP ID without feature bits, ie. Aff0..Aff3 only + * used to store the corresponding property value for TCG vcpus. + * The MPIDR_EL1 value (affinity + feature bits) is stored in a + * consistent manner in isar.idregs[MPIDR_EL1_IDX]. + */ + uint64_t mp_affinity; uint64_t reset_cbar; uint32_t reset_auxcr; bool reset_hivecs; diff --git a/target/arm/cpu-sysregs.h.inc b/target/arm/cpu-sysregs.h.inc index 709dc8fc97..f148f6f565 100644 --- a/target/arm/cpu-sysregs.h.inc +++ b/target/arm/cpu-sysregs.h.inc @@ -42,6 +42,7 @@ DEF(ID_PFR0_EL1, 3, 0, 0, 1, 0) DEF(ID_PFR1_EL1, 3, 0, 0, 1, 1) DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4) DEF(MIDR_EL1, 3, 0, 0, 0, 0) +DEF(MPIDR_EL1, 3, 0, 0, 0, 5) DEF(MVFR0_EL1, 3, 0, 0, 3, 0) DEF(MVFR1_EL1, 3, 0, 0, 3, 1) DEF(MVFR2_EL1, 3, 0, 0, 3, 2) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 2f545482bc..bee74c0f94 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -2174,6 +2174,23 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) ARM_DEFAULT_CPUS_PER_CLUSTER); } + /* Consistently update MPIDR_EL1 in isar.idregs[] by adding feature bits */ + { + uint64_t mpidr = cpu->mp_affinity; + + if (arm_feature(env, ARM_FEATURE_V7MP)) { + mpidr |= (1U << 31); + /* + * Uniprocessor (non-coherent) cores that still implement the MP + * extensions set U (bit 30), e.g. Cortex-R5. + */ + if (cpu->mp_is_up) { + mpidr |= (1u << 30); + } + } + SET_IDREG(&cpu->isar, MPIDR, mpidr); + } + if (cpu->reset_hivecs) { cpu->reset_sctlr |= (1 << 13); } diff --git a/target/arm/helper.c b/target/arm/helper.c index dfd71f1b51..36e8119f79 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -3176,20 +3176,8 @@ static uint64_t midr_read(CPUARMState *env, const ARMCPRegInfo *ri) static uint64_t mpidr_read_val(CPUARMState *env) { ARMCPU *cpu = env_archcpu(env); - uint64_t mpidr = cpu->mp_affinity; - if (arm_feature(env, ARM_FEATURE_V7MP)) { - mpidr |= (1U << 31); - /* - * Cores which are uniprocessor (non-coherent) - * but still implement the MP extensions set - * bit 30. (For instance, Cortex-R5). - */ - if (cpu->mp_is_up) { - mpidr |= (1u << 30); - } - } - return mpidr; + return GET_IDREG(&cpu->isar, MPIDR); } static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri) diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c index f9f3d22014..4b947e9ba5 100644 --- a/target/arm/hvf/hvf.c +++ b/target/arm/hvf/hvf.c @@ -1476,7 +1476,7 @@ int hvf_arch_init_vcpu(CPUState *cpu) assert_hvf_ok(ret); ret = hv_vcpu_set_sys_reg(cpu->accel->fd, HV_SYS_REG_MPIDR_EL1, - arm_cpu->mp_affinity); + GET_IDREG(&arm_cpu->isar, MPIDR)); assert_hvf_ok(ret); pfr = GET_IDREG(&arm_cpu->isar, ID_AA64PFR0); diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 3d905f8565..9d68801c26 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -2096,6 +2096,7 @@ int kvm_arch_init_vcpu(CPUState *cs) if (ret) { return ret; } + SET_IDREG(&cpu->isar, MPIDR, mpidr); cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK; return kvm_arm_init_cpreg_list(cpu); diff --git a/target/arm/whpx/whpx-all.c b/target/arm/whpx/whpx-all.c index 18009d6c8d..024d18df04 100644 --- a/target/arm/whpx/whpx-all.c +++ b/target/arm/whpx/whpx-all.c @@ -842,7 +842,7 @@ int whpx_init_vcpu(CPUState *cpu) clean_whv_register_value(&val); - val.Reg64 = deposit64(arm_cpu->mp_affinity, 31, 1, 1 /* RES1 */); + val.Reg64 = GET_IDREG(&arm_cpu->isar, MPIDR); whpx_set_reg(cpu, WHvArm64RegisterMpidrEl1, val); clamp_id_aa64mmfr0_parange_to_ipa_size(&arm_cpu->isar); -- 2.53.0
