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
This commit is contained in:
Richard Henderson 2018-12-18 04:23:35 -05:00 committed by Lioncash
parent 3cfd660814
commit 4515df5ee7
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
3 changed files with 42 additions and 8 deletions

View file

@ -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

View file

@ -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)

View file

@ -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);
}
}