Mark up the sysreg definitions for the registers trapped
by HFGRTR/HFGWTR bits 36..63.
Of these, some correspond to RAS registers which we implement as
always-UNDEF: these don't need any extra handling for FGT because the
UNDEF-to-EL1 always takes priority over any theoretical
FGT-trap-to-EL2.
Bit 50 (NACCDATA_EL1) is for the ACCDATA_EL1 register which is part
of the FEAT_LS64_ACCDATA feature which we don't yet implement.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Fuad Tabba <tabba@google.com>
Message-id:
20230130182459.
3309057-14-peter.maydell@linaro.org
Message-id:
20230127175507.
2895013-14-peter.maydell@linaro.org
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 6,
.type = ARM_CP_IO | ARM_CP_NO_RAW,
.access = PL1_RW, .accessfn = gicv3_fiq_access,
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 6,
.type = ARM_CP_IO | ARM_CP_NO_RAW,
.access = PL1_RW, .accessfn = gicv3_fiq_access,
+ .fgt = FGT_ICC_IGRPENN_EL1,
.readfn = icc_igrpen_read,
.writefn = icc_igrpen_write,
},
.readfn = icc_igrpen_read,
.writefn = icc_igrpen_write,
},
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 7,
.type = ARM_CP_IO | ARM_CP_NO_RAW,
.access = PL1_RW, .accessfn = gicv3_irq_access,
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 7,
.type = ARM_CP_IO | ARM_CP_NO_RAW,
.access = PL1_RW, .accessfn = gicv3_irq_access,
+ .fgt = FGT_ICC_IGRPENN_EL1,
.readfn = icc_igrpen_read,
.writefn = icc_igrpen_write,
},
.readfn = icc_igrpen_read,
.writefn = icc_igrpen_write,
},
DO_BIT(HFGRTR, TPIDR_EL1),
DO_BIT(HFGRTR, TPIDRRO_EL0),
DO_BIT(HFGRTR, TPIDR_EL0),
DO_BIT(HFGRTR, TPIDR_EL1),
DO_BIT(HFGRTR, TPIDRRO_EL0),
DO_BIT(HFGRTR, TPIDR_EL0),
+ DO_BIT(HFGRTR, TTBR0_EL1),
+ DO_BIT(HFGRTR, TTBR1_EL1),
+ DO_BIT(HFGRTR, VBAR_EL1),
+ DO_BIT(HFGRTR, ICC_IGRPENN_EL1),
+ DO_BIT(HFGRTR, ERRIDR_EL1),
+ DO_REV_BIT(HFGRTR, NSMPRI_EL1),
+ DO_REV_BIT(HFGRTR, NTPIDR2_EL0),
{ .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 0,
.access = PL1_RW, .accessfn = access_tvm_trvm,
{ .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 0,
.access = PL1_RW, .accessfn = access_tvm_trvm,
.writefn = vmsa_ttbr_write, .resetvalue = 0,
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
offsetof(CPUARMState, cp15.ttbr0_ns) } },
{ .name = "TTBR1_EL1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 1,
.access = PL1_RW, .accessfn = access_tvm_trvm,
.writefn = vmsa_ttbr_write, .resetvalue = 0,
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
offsetof(CPUARMState, cp15.ttbr0_ns) } },
{ .name = "TTBR1_EL1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 1,
.access = PL1_RW, .accessfn = access_tvm_trvm,
.writefn = vmsa_ttbr_write, .resetvalue = 0,
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
offsetof(CPUARMState, cp15.ttbr1_ns) } },
.writefn = vmsa_ttbr_write, .resetvalue = 0,
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
offsetof(CPUARMState, cp15.ttbr1_ns) } },
* ERRSELR_EL1
* may generate UNDEFINED, which is the effect we get by not
* listing them at all.
* ERRSELR_EL1
* may generate UNDEFINED, which is the effect we get by not
* listing them at all.
+ *
+ * These registers have fine-grained trap bits, but UNDEF-to-EL1
+ * is higher priority than FGT-to-EL2 so we do not need to list them
+ * in order to check for an FGT.
*/
static const ARMCPRegInfo minimal_ras_reginfo[] = {
{ .name = "DISR_EL1", .state = ARM_CP_STATE_BOTH,
*/
static const ARMCPRegInfo minimal_ras_reginfo[] = {
{ .name = "DISR_EL1", .state = ARM_CP_STATE_BOTH,
{ .name = "ERRIDR_EL1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 5, .crm = 3, .opc2 = 0,
.access = PL1_R, .accessfn = access_terr,
{ .name = "ERRIDR_EL1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 5, .crm = 3, .opc2 = 0,
.access = PL1_R, .accessfn = access_terr,
.type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "VDISR_EL2", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 1, .opc2 = 1,
.type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "VDISR_EL2", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 1, .opc2 = 1,
{ .name = "TPIDR2_EL0", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 3, .crn = 13, .crm = 0, .opc2 = 5,
.access = PL0_RW, .accessfn = access_tpidr2,
{ .name = "TPIDR2_EL0", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 3, .crn = 13, .crm = 0, .opc2 = 5,
.access = PL0_RW, .accessfn = access_tpidr2,
+ .fgt = FGT_NTPIDR2_EL0,
.fieldoffset = offsetof(CPUARMState, cp15.tpidr2_el0) },
{ .name = "SVCR", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 2,
.fieldoffset = offsetof(CPUARMState, cp15.tpidr2_el0) },
{ .name = "SVCR", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 2,
{ .name = "SMPRI_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 4,
.access = PL1_RW, .accessfn = access_esm,
{ .name = "SMPRI_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 4,
.access = PL1_RW, .accessfn = access_esm,
.type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "SMPRIMAP_EL2", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 5,
.type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "SMPRIMAP_EL2", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 5,
{ .name = "VBAR", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,
.access = PL1_RW, .writefn = vbar_write,
{ .name = "VBAR", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,
.access = PL1_RW, .writefn = vbar_write,
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s),
offsetof(CPUARMState, cp15.vbar_ns) },
.resetvalue = 0 },
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s),
offsetof(CPUARMState, cp15.vbar_ns) },
.resetvalue = 0 },