From 4515df5ee75e8df4d9d08282a3ed94160ffa4513 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 18 Dec 2018 04:23:35 -0500 Subject: [PATCH] target/arm: Implement the ARMv8.2-AA32HPD extension 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. Backports commit ab638a328fd099ba0b23c8c818eb39f2c35414f3 from qemu --- qemu/target/arm/cpu.c | 4 ++++ qemu/target/arm/cpu.h | 9 +++++++++ qemu/target/arm/helper.c | 37 +++++++++++++++++++++++++++++-------- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/qemu/target/arm/cpu.c b/qemu/target/arm/cpu.c index 480dfd6b..8e9f97db 100644 --- a/qemu/target/arm/cpu.c +++ b/qemu/target/arm/cpu.c @@ -1657,6 +1657,10 @@ static void arm_max_initfn(struct uc_struct *uc, Object *obj, void *opaque) 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/qemu/target/arm/cpu.h b/qemu/target/arm/cpu.h index 5f6a504c..2b6f40ab 100644 --- a/qemu/target/arm/cpu.h +++ b/qemu/target/arm/cpu.h @@ -1492,6 +1492,15 @@ 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_MMFR4, EVT, 28, 4) + FIELD(ID_AA64ISAR0, AES, 4, 4) FIELD(ID_AA64ISAR0, SHA1, 8, 4) FIELD(ID_AA64ISAR0, SHA2, 12, 4) diff --git a/qemu/target/arm/helper.c b/qemu/target/arm/helper.c index 976272c5..73216c2f 100644 --- a/qemu/target/arm/helper.c +++ b/qemu/target/arm/helper.c @@ -2418,6 +2418,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 @@ -2425,6 +2426,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); } @@ -2516,6 +2519,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, .opc1 = 0, .crn = 2, .crm = 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) { @@ -4694,6 +4707,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); @@ -8955,12 +8972,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 */ @@ -8977,8 +8996,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); } }