From a2508d0e29b69525f39733c5726e1412e5663eb0 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Wed, 11 Dec 2024 14:44:36 +0000 Subject: [PATCH] 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 Reviewed-by: Richard Henderson Message-id: 20241211144440.2700268-3-peter.maydell@linaro.org --- target/arm/cpregs.h | 8 ++++++++ target/arm/helper.c | 25 +++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h index 87704762ef..1759d9defb 100644 --- a/target/arm/cpregs.h +++ b/target/arm/cpregs.h @@ -126,6 +126,14 @@ enum { * equivalent EL1 register when FEAT_NV2 is enabled. */ 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, }; /* diff --git a/target/arm/helper.c b/target/arm/helper.c index 8e62769ec0..c2a70f8c05 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -9146,6 +9146,31 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu, if (r->state != state && r->state != ARM_CP_STATE_BOTH) { 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) { /* * Under AArch32 CP registers can be common -- 2.30.2