static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
CPState state, CPSecureState secstate,
int cp, int crm, int opc1, int opc2,
- const char *name)
+ const char *name, uint32_t key)
{
CPUARMState *env = &cpu->env;
- uint32_t key;
ARMCPRegInfo *r2;
- bool is64 = r->type & ARM_CP_64BIT;
bool ns = secstate & ARM_CP_SECSTATE_NS;
size_t name_len;
- switch (state) {
- case ARM_CP_STATE_AA32:
- key = ENCODE_CP_REG(cp, is64, ns, r->crn, crm, opc1, opc2);
- break;
- case ARM_CP_STATE_AA64:
- key = ENCODE_AA64_CP_REG(r->opc0, opc1, r->crn, crm, opc2);
- break;
- default:
- g_assert_not_reached();
- }
-
/* Overriding of an existing definition must be explicitly requested. */
if (!(r->type & ARM_CP_OVERRIDE)) {
const ARMCPRegInfo *oldreg = get_arm_cp_reginfo(cpu->cp_regs, key);
* (same for secure and non-secure world) or banked.
*/
char *name;
+ bool is64 = r->type & ARM_CP_64BIT;
+ uint32_t key = ENCODE_CP_REG(cp, is64, 0, r->crn, crm, opc1, opc2);
assert(!(r->type & ARM_CP_ADD_TLBI_NXS)); /* aa64 only */
switch (r->secure) {
- case ARM_CP_SECSTATE_S:
case ARM_CP_SECSTATE_NS:
+ key |= CP_REG_AA32_NS_MASK;
+ /* fall through */
+ case ARM_CP_SECSTATE_S:
add_cpreg_to_hashtable(cpu, r, ARM_CP_STATE_AA32, r->secure,
- cp, crm, opc1, opc2, r->name);
+ cp, crm, opc1, opc2, r->name, key);
break;
case ARM_CP_SECSTATE_BOTH:
name = g_strdup_printf("%s_S", r->name);
add_cpreg_to_hashtable(cpu, r, ARM_CP_STATE_AA32, ARM_CP_SECSTATE_S,
- cp, crm, opc1, opc2, name);
+ cp, crm, opc1, opc2, name, key);
g_free(name);
+
+ key |= CP_REG_AA32_NS_MASK;
add_cpreg_to_hashtable(cpu, r, ARM_CP_STATE_AA32, ARM_CP_SECSTATE_NS,
- cp, crm, opc1, opc2, r->name);
+ cp, crm, opc1, opc2, r->name, key);
break;
default:
g_assert_not_reached();
static void add_cpreg_to_hashtable_aa64(ARMCPU *cpu, const ARMCPRegInfo *r,
int crm, int opc1, int opc2)
{
+ uint32_t key = ENCODE_AA64_CP_REG(r->opc0, opc1, r->crn, crm, opc2);
+
if ((r->type & ARM_CP_ADD_TLBI_NXS) &&
cpu_isar_feature(aa64_xs, cpu)) {
/*
*/
ARMCPRegInfo nxs_ri = *r;
g_autofree char *name = g_strdup_printf("%sNXS", r->name);
+ uint32_t nxs_key;
assert(nxs_ri.crn < 0xf);
nxs_ri.crn++;
+ /* Also increment the CRN field inside the key value */
+ nxs_key = key + (1 << CP_REG_ARM64_SYSREG_CRN_SHIFT);
if (nxs_ri.fgt) {
nxs_ri.fgt |= R_FGT_NXS_MASK;
}
+
add_cpreg_to_hashtable(cpu, &nxs_ri, ARM_CP_STATE_AA64,
- ARM_CP_SECSTATE_NS, 0, crm, opc1, opc2, name);
+ ARM_CP_SECSTATE_NS, 0, crm, opc1, opc2,
+ name, nxs_key);
}
add_cpreg_to_hashtable(cpu, r, ARM_CP_STATE_AA64, ARM_CP_SECSTATE_NS,
- 0, crm, opc1, opc2, r->name);
+ 0, crm, opc1, opc2, r->name, key);
}
void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *r)