Message ID | 20181102134112.26370-5-richard.henderson@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | target/arm: LOR, HPD, AA32HPD extensions | expand |
On 2 November 2018 at 13:41, Richard Henderson <richard.henderson@linaro.org> wrote: > The bulk of the work here, beyond base HPD, is defining the TTBCR2 register. > In addition we must check TTBCR.T2E, which is not present (RES0) for AArch64. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > target/arm/cpu.h | 8 ++++++++ > target/arm/cpu.c | 4 ++++ > target/arm/helper.c | 37 +++++++++++++++++++++++++++++-------- > 3 files changed, 41 insertions(+), 8 deletions(-) > > diff --git a/target/arm/cpu.h b/target/arm/cpu.h > index f12a6afddc..a253cdebde 100644 > --- a/target/arm/cpu.h > +++ b/target/arm/cpu.h > @@ -1517,6 +1517,14 @@ FIELD(ID_ISAR6, FHM, 8, 4) > FIELD(ID_ISAR6, SB, 12, 4) > FIELD(ID_ISAR6, SPECRES, 16, 4) > > +FIELD(ID_MMFR4, SPECSEI, 0, 4) > +FIELD(ID_MMFR4, AC2, 4, 4) > +FIELD(ID_MMFR4, XNX, 8, 4) > +FIELD(ID_MMFR4, CNP, 12, 4) > +FIELD(ID_MMFR4, HPDS, 16, 4) > +FIELD(ID_MMFR4, LSM, 20, 4) > +FIELD(ID_MMFR4, CCIDX, 24, 4) Maybe add the v8.5 field too? FIELD(ID_MMFR4, EVT, 28, 4) > +/* Note that unlike TTBCR, writing to TTBCR2 does not require flushing > + * qemu tlbs nor adjusting cached masks. > + */ > +static const ARMCPRegInfo ttbcr2_reginfo = { > + .name = "TTBCR2", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 3, Our usual order for these fields is cp, opc1, crn, crm, opc2. > + .access = PL1_RW, .type = ARM_CP_ALIAS, > + .bank_fieldoffsets = { offsetofhigh32(CPUARMState, cp15.tcr_el[3]), > + offsetofhigh32(CPUARMState, cp15.tcr_el[1]) }, > +}; Otherwise Reviewed-by: Peter Maydell <peter.maydell@linaro.org> thanks -- PMM
On 2 November 2018 at 13:41, Richard Henderson <richard.henderson@linaro.org> wrote: > The bulk of the work here, beyond base HPD, is defining the TTBCR2 register. > In addition we must check TTBCR.T2E, which is not present (RES0) for AArch64. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > target/arm/cpu.h | 8 ++++++++ > target/arm/cpu.c | 4 ++++ > target/arm/helper.c | 37 +++++++++++++++++++++++++++++-------- > 3 files changed, 41 insertions(+), 8 deletions(-) > > diff --git a/target/arm/cpu.h b/target/arm/cpu.h > index f12a6afddc..a253cdebde 100644 > --- a/target/arm/cpu.h > +++ b/target/arm/cpu.h > @@ -1517,6 +1517,14 @@ FIELD(ID_ISAR6, FHM, 8, 4) > FIELD(ID_ISAR6, SB, 12, 4) > FIELD(ID_ISAR6, SPECRES, 16, 4) > > +FIELD(ID_MMFR4, SPECSEI, 0, 4) > +FIELD(ID_MMFR4, AC2, 4, 4) > +FIELD(ID_MMFR4, XNX, 8, 4) > +FIELD(ID_MMFR4, CNP, 12, 4) > +FIELD(ID_MMFR4, HPDS, 16, 4) > +FIELD(ID_MMFR4, LSM, 20, 4) > +FIELD(ID_MMFR4, CCIDX, 24, 4) Why all caps for SpecSEI in this register, but honouring the capitalization from the spec in the equivalent ID register added in patch 1? ("FIELD(ID_AA64MMFR1, SpecSEI, 24, 4)") I don't mind which, but we should pick a convention and stick to it. thanks -- PMM
diff --git a/target/arm/cpu.h b/target/arm/cpu.h index f12a6afddc..a253cdebde 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1517,6 +1517,14 @@ FIELD(ID_ISAR6, FHM, 8, 4) FIELD(ID_ISAR6, SB, 12, 4) FIELD(ID_ISAR6, SPECRES, 16, 4) +FIELD(ID_MMFR4, SPECSEI, 0, 4) +FIELD(ID_MMFR4, AC2, 4, 4) +FIELD(ID_MMFR4, XNX, 8, 4) +FIELD(ID_MMFR4, CNP, 12, 4) +FIELD(ID_MMFR4, HPDS, 16, 4) +FIELD(ID_MMFR4, LSM, 20, 4) +FIELD(ID_MMFR4, CCIDX, 24, 4) + FIELD(ID_AA64ISAR0, AES, 4, 4) FIELD(ID_AA64ISAR0, SHA1, 8, 4) FIELD(ID_AA64ISAR0, SHA2, 12, 4) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 8f16e96b6c..3fd85f21c5 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1856,6 +1856,10 @@ static void arm_max_initfn(Object *obj) t = cpu->isar.id_isar6; t = FIELD_DP32(t, ID_ISAR6, DP, 1); cpu->isar.id_isar6 = t; + + t = cpu->id_mmfr4; + t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */ + cpu->id_mmfr4 = t; } #endif } diff --git a/target/arm/helper.c b/target/arm/helper.c index 312d3e6f02..85d3f4ad89 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -2722,6 +2722,7 @@ static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { ARMCPU *cpu = arm_env_get_cpu(env); + TCR *tcr = raw_ptr(env, ri); if (arm_feature(env, ARM_FEATURE_LPAE)) { /* With LPAE the TTBCR could result in a change of ASID @@ -2729,6 +2730,8 @@ static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri, */ tlb_flush(CPU(cpu)); } + /* Preserve the high half of TCR_EL1, set via TTBCR2. */ + value = deposit64(tcr->raw_tcr, 0, 32, value); vmsa_ttbcr_raw_write(env, ri, value); } @@ -2831,6 +2834,16 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = { REGINFO_SENTINEL }; +/* Note that unlike TTBCR, writing to TTBCR2 does not require flushing + * qemu tlbs nor adjusting cached masks. + */ +static const ARMCPRegInfo ttbcr2_reginfo = { + .name = "TTBCR2", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 3, + .access = PL1_RW, .type = ARM_CP_ALIAS, + .bank_fieldoffsets = { offsetofhigh32(CPUARMState, cp15.tcr_el[3]), + offsetofhigh32(CPUARMState, cp15.tcr_el[1]) }, +}; + static void omap_ticonfig_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { @@ -5454,6 +5467,10 @@ void register_cp_regs_for_features(ARMCPU *cpu) } else { define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo); define_arm_cp_regs(cpu, vmsa_cp_reginfo); + /* TTCBR2 is introduced with ARMv8.2-A32HPD. */ + if (FIELD_EX32(cpu->id_mmfr4, ID_MMFR4, HPDS) != 0) { + define_one_arm_cp_reg(cpu, &ttbcr2_reginfo); + } } if (arm_feature(env, ARM_FEATURE_THUMB2EE)) { define_arm_cp_regs(cpu, t2ee_cp_reginfo); @@ -9797,12 +9814,14 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address, if (tg == 2) { /* 16KB pages */ stride = 11; } - if (aarch64) { - if (el > 1) { - hpd = extract64(tcr->raw_tcr, 24, 1); - } else { - hpd = extract64(tcr->raw_tcr, 41, 1); - } + if (aarch64 && el > 1) { + hpd = extract64(tcr->raw_tcr, 24, 1); + } else { + hpd = extract64(tcr->raw_tcr, 41, 1); + } + if (!aarch64) { + /* For aarch32, hpd0 is not enabled without t2e as well. */ + hpd &= extract64(tcr->raw_tcr, 6, 1); } } else { /* We should only be here if TTBR1 is valid */ @@ -9819,8 +9838,10 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address, if (tg == 1) { /* 16KB pages */ stride = 11; } - if (aarch64) { - hpd = extract64(tcr->raw_tcr, 42, 1); + hpd = extract64(tcr->raw_tcr, 42, 1); + if (!aarch64) { + /* For aarch32, hpd1 is not enabled without t2e as well. */ + hpd &= extract64(tcr->raw_tcr, 6, 1); } }
The bulk of the work here, beyond base HPD, is defining the TTBCR2 register. In addition we must check TTBCR.T2E, which is not present (RES0) for AArch64. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/arm/cpu.h | 8 ++++++++ target/arm/cpu.c | 4 ++++ target/arm/helper.c | 37 +++++++++++++++++++++++++++++-------- 3 files changed, 41 insertions(+), 8 deletions(-) -- 2.17.2