@@ -7345,11 +7345,16 @@ void register_cp_regs_for_features(ARMCPU *cpu)
define_arm_cp_regs(cpu, not_v7_cp_reginfo);
}
if (arm_feature(env, ARM_FEATURE_V8)) {
- /* AArch64 ID registers, which all have impdef reset values.
+ /*
+ * v8 ID registers, which all have impdef reset values.
* Note that within the ID register ranges the unused slots
* must all RAZ, not UNDEF; future architecture versions may
* define new registers here.
+ * ID registers which are AArch64 views of the AArch32 ID registers
+ * which already existed in v6 and v7 are handled elsewhere,
+ * in v6_idregs[].
*/
+ int i;
ARMCPRegInfo v8_idregs[] = {
/*
* ID_AA64PFR0_EL1 is not a plain ARM_CP_CONST in system
@@ -7539,7 +7544,34 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
.resetvalue = cpu->isar.mvfr2 },
- { .name = "MVFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
+ /*
+ * "0, c0, c3, {0,1,2}" are the encodings corresponding to
+ * AArch64 MVFR[012]_EL1. Define the STATE_AA32 encoding
+ * as RAZ, since it is in the "reserved for future ID
+ * registers, RAZ" part of the AArch32 encoding space.
+ */
+ { .name = "RES_0_C0_C3_0", .state = ARM_CP_STATE_AA32,
+ .cp = 15, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 0,
+ .access = PL1_R, .type = ARM_CP_CONST,
+ .accessfn = access_aa64_tid3,
+ .resetvalue = 0 },
+ { .name = "RES_0_C0_C3_1", .state = ARM_CP_STATE_AA32,
+ .cp = 15, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 1,
+ .access = PL1_R, .type = ARM_CP_CONST,
+ .accessfn = access_aa64_tid3,
+ .resetvalue = 0 },
+ { .name = "RES_0_C0_C3_2", .state = ARM_CP_STATE_AA32,
+ .cp = 15, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2,
+ .access = PL1_R, .type = ARM_CP_CONST,
+ .accessfn = access_aa64_tid3,
+ .resetvalue = 0 },
+ /*
+ * Other encodings in "0, c0, c3, ..." are STATE_BOTH because
+ * they're also RAZ for AArch64, and in v8 are gradually
+ * being filled with AArch64-view-of-AArch32-ID-register
+ * for new ID registers.
+ */
+ { .name = "RES_0_C0_C3_3", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 3,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
@@ -7549,17 +7581,17 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
.resetvalue = cpu->isar.id_pfr2 },
- { .name = "MVFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
+ { .name = "RES_0_C0_C3_5", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 5,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
.resetvalue = 0 },
- { .name = "MVFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
+ { .name = "RES_0_C0_C3_6", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 6,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
.resetvalue = 0 },
- { .name = "MVFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
+ { .name = "RES_0_C0_C3_7", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 7,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
@@ -7625,6 +7657,29 @@ void register_cp_regs_for_features(ARMCPU *cpu)
}
define_arm_cp_regs(cpu, v8_idregs);
define_arm_cp_regs(cpu, v8_cp_reginfo);
+
+ for (i = 4; i < 16; i++) {
+ /*
+ * Encodings in "0, c0, {c4-c7}, {0-7}" are RAZ for AArch32.
+ * For pre-v8 cores there are RAZ patterns for these in
+ * id_pre_v8_midr_cp_reginfo[]; for v8 we do that here.
+ * v8 extends the "must RAZ" part of the ID register space
+ * to also cover c0, 0, c{8-15}, {0-7}.
+ * These are STATE_AA32 because in the AArch64 sysreg space
+ * c4-c7 is where the AArch64 ID registers live (and we've
+ * already defined those in v8_idregs[]), and c8-c15 are not
+ * "must RAZ" for AArch64.
+ */
+ g_autofree char *name = g_strdup_printf("RES_0_C0_C%d_X", i);
+ ARMCPRegInfo v8_aa32_raz_idregs = {
+ .name = name,
+ .state = ARM_CP_STATE_AA32,
+ .cp = 15, .opc1 = 0, .crn = 0, .crm = i, .opc2 = CP_ANY,
+ .access = PL1_R, .type = ARM_CP_CONST,
+ .accessfn = access_aa64_tid3,
+ .resetvalue = 0 };
+ define_one_arm_cp_reg(cpu, &v8_aa32_raz_idregs);
+ }
}
/*