target/arm: Add ARM_CP_ADD_TLBI_NXS type flag for NXS insns
All of the TLBI insns with an NXS variant put that variant at the same encoding but with a CRn field that is one greater than for the original TLBI insn. To avoid having to define every TLBI insn effectively twice, once in the normal way and once in a set of cpreg arrays that are only registered when FEAT_XS is present, we define a new ARM_CP_ADD_TLB_NXS type flag for cpregs. When this flag is set in a cpreg struct and FEAT_XS is present, define_one_arm_cp_reg_with_opaque() will automatically add a second cpreg to the hash table for the TLBI NXS insn with: * the crn+1 encoding * an FGT field that indicates that it should honour HCR_EL2.FGTnXS * a name with the "NXS" suffix (If there are future TLBI NXS insns that don't use this same encoding convention, it is also possible to define them manually.) Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20241211144440.2700268-3-peter.maydell@linaro.org
This commit is contained in:
parent
2b745c8f91
commit
a2508d0e29
@ -126,6 +126,14 @@ enum {
|
|||||||
* equivalent EL1 register when FEAT_NV2 is enabled.
|
* equivalent EL1 register when FEAT_NV2 is enabled.
|
||||||
*/
|
*/
|
||||||
ARM_CP_NV2_REDIRECT = 1 << 20,
|
ARM_CP_NV2_REDIRECT = 1 << 20,
|
||||||
|
/*
|
||||||
|
* Flag: this is a TLBI insn which (when FEAT_XS is present) also has
|
||||||
|
* an NXS variant at the same encoding except that crn is 1 greater,
|
||||||
|
* so when registering this cpreg automatically also register one
|
||||||
|
* for the TLBI NXS variant. (For QEMU the NXS variant behaves
|
||||||
|
* identically to the normal one, other than FGT trapping handling.)
|
||||||
|
*/
|
||||||
|
ARM_CP_ADD_TLBI_NXS = 1 << 21,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -9146,6 +9146,31 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
|
|||||||
if (r->state != state && r->state != ARM_CP_STATE_BOTH) {
|
if (r->state != state && r->state != ARM_CP_STATE_BOTH) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if ((r->type & ARM_CP_ADD_TLBI_NXS) &&
|
||||||
|
cpu_isar_feature(aa64_xs, cpu)) {
|
||||||
|
/*
|
||||||
|
* This is a TLBI insn which has an NXS variant. The
|
||||||
|
* NXS variant is at the same encoding except that
|
||||||
|
* crn is +1, and has the same behaviour except for
|
||||||
|
* fine-grained trapping. Add the NXS insn here and
|
||||||
|
* then fall through to add the normal register.
|
||||||
|
* add_cpreg_to_hashtable() copies the cpreg struct
|
||||||
|
* and name that it is passed, so it's OK to use
|
||||||
|
* a local struct here.
|
||||||
|
*/
|
||||||
|
ARMCPRegInfo nxs_ri = *r;
|
||||||
|
g_autofree char *name = g_strdup_printf("%sNXS", r->name);
|
||||||
|
|
||||||
|
assert(state == ARM_CP_STATE_AA64);
|
||||||
|
assert(nxs_ri.crn < 0xf);
|
||||||
|
nxs_ri.crn++;
|
||||||
|
if (nxs_ri.fgt) {
|
||||||
|
nxs_ri.fgt |= R_FGT_NXS_MASK;
|
||||||
|
}
|
||||||
|
add_cpreg_to_hashtable(cpu, &nxs_ri, opaque, state,
|
||||||
|
ARM_CP_SECSTATE_NS,
|
||||||
|
crm, opc1, opc2, name);
|
||||||
|
}
|
||||||
if (state == ARM_CP_STATE_AA32) {
|
if (state == ARM_CP_STATE_AA32) {
|
||||||
/*
|
/*
|
||||||
* Under AArch32 CP registers can be common
|
* Under AArch32 CP registers can be common
|
||||||
|
Loading…
x
Reference in New Issue
Block a user