target/arm: Add CONTEXTIDR_EL2

Not all of the breakpoint types are supported, but those that
only examine contextidr are extended to support the new register.

Backports commit e2a1a4616c86159eb4c07659a02fff8bb25d3729 from qemu
This commit is contained in:
Richard Henderson 2020-03-21 13:39:19 -04:00 committed by Lioncash
parent fe6825ca4d
commit 35508d46c7
2 changed files with 50 additions and 12 deletions

View file

@ -20,6 +20,7 @@ static bool linked_bp_matches(ARMCPU *cpu, int lbn)
int ctx_cmps = extract32(cpu->dbgdidr, 20, 4);
int bt;
uint32_t contextidr;
uint64_t hcr_el2;
/*
* Links to unimplemented or non-context aware breakpoints are
@ -40,24 +41,44 @@ static bool linked_bp_matches(ARMCPU *cpu, int lbn)
}
bt = extract64(bcr, 20, 4);
/*
* We match the whole register even if this is AArch32 using the
* short descriptor format (in which case it holds both PROCID and ASID),
* since we don't implement the optional v7 context ID masking.
*/
contextidr = extract64(env->cp15.contextidr_el[1], 0, 32);
hcr_el2 = arm_hcr_el2_eff(env);
switch (bt) {
case 3: /* linked context ID match */
if (arm_current_el(env) > 1) {
/* Context matches never fire in EL2 or (AArch64) EL3 */
switch (arm_current_el(env)) {
default:
/* Context matches never fire in AArch64 EL3 */
return false;
case 2:
if (!(hcr_el2 & HCR_E2H)) {
/* Context matches never fire in EL2 without E2H enabled. */
return false;
}
contextidr = env->cp15.contextidr_el[2];
break;
case 1:
contextidr = env->cp15.contextidr_el[1];
break;
case 0:
if ((hcr_el2 & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
contextidr = env->cp15.contextidr_el[2];
} else {
contextidr = env->cp15.contextidr_el[1];
}
break;
}
return (contextidr == extract64(env->cp15.dbgbvr[lbn], 0, 32));
case 5: /* linked address mismatch (reserved in AArch64) */
break;
case 7: /* linked contextidr_el1 match */
contextidr = env->cp15.contextidr_el[1];
break;
case 13: /* linked contextidr_el2 match */
contextidr = env->cp15.contextidr_el[2];
break;
case 9: /* linked VMID match (reserved if no EL2) */
case 11: /* linked context ID and VMID match (reserved if no EL2) */
case 15: /* linked full context ID match */
default:
/*
* Links to Unlinked context breakpoints must generate no
@ -66,7 +87,12 @@ static bool linked_bp_matches(ARMCPU *cpu, int lbn)
return false;
}
return false;
/*
* We match the whole register even if this is AArch32 using the
* short descriptor format (in which case it holds both PROCID and ASID),
* since we don't implement the optional v7 context ID masking.
*/
return contextidr == (uint32_t)env->cp15.dbgbvr[lbn];
}
static bool bp_wp_matches(ARMCPU *cpu, int n, bool is_wp)

View file

@ -5906,6 +5906,14 @@ static const ARMCPRegInfo jazelle_regs[] = {
REGINFO_SENTINEL
};
static const ARMCPRegInfo vhe_reginfo[] = {
{ .name = "CONTEXTIDR_EL2", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 1,
.access = PL2_RW,
.fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[2]) },
REGINFO_SENTINEL
};
void register_cp_regs_for_features(ARMCPU *cpu)
{
/* Register all the coprocessor registers based on feature bits */
@ -6855,6 +6863,10 @@ void register_cp_regs_for_features(ARMCPU *cpu)
define_arm_cp_regs(cpu, lor_reginfo);
}
if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) {
define_arm_cp_regs(cpu, vhe_reginfo);
}
if (cpu_isar_feature(aa64_sve, cpu)) {
define_one_arm_cp_reg(cpu, &zcr_el1_reginfo);
if (arm_feature(env, ARM_FEATURE_EL2)) {