From 5075a0158a8d9941d48b74447d04d9fda91e4702 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 8 Mar 2019 01:26:06 -0500 Subject: [PATCH] target/arm: Restore Qemu's organization of coprocessor registers These changes were mostly made in upstream unicorn for what I can guess, was to support old versions of MSVC's compiler. This is also a pain to maintain, since everything needs to be done manually and can be a source of errors. It also makes it take more work than it needs to, to backport changes from qemu. Because of that, this change restores Qemu's organization of the coprocessor registers. --- qemu/target/arm/cpu64.c | 69 +- qemu/target/arm/helper.c | 3294 +++++++++++++++++++++++--------------- 2 files changed, 2051 insertions(+), 1312 deletions(-) diff --git a/qemu/target/arm/cpu64.c b/qemu/target/arm/cpu64.c index 2ebd3ee8..96f42df5 100644 --- a/qemu/target/arm/cpu64.c +++ b/qemu/target/arm/cpu64.c @@ -47,35 +47,48 @@ static uint64_t a57_a53_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri) static const ARMCPRegInfo cortex_a72_a57_a53_cp_reginfo[] = { #ifndef CONFIG_USER_ONLY - { "L2CTLR_EL1", 0,11,0, 3,1,2, ARM_CP_STATE_AA64, - 0, PL1_RW, 0, NULL, 0, 0, {0, 0}, - NULL, a57_a53_l2ctlr_read, arm_cp_write_ignore, }, - { "L2CTLR", 15,9,0, 0,1,2, 0, - 0, PL1_RW, 0, NULL, 0, 0, {0, 0}, - NULL, a57_a53_l2ctlr_read, arm_cp_write_ignore, }, + { .name = "L2CTLR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 2, + .access = PL1_RW, .readfn = a57_a53_l2ctlr_read, + .writefn = arm_cp_write_ignore }, + { .name = "L2CTLR", + .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 2, + .access = PL1_RW, .readfn = a57_a53_l2ctlr_read, + .writefn = arm_cp_write_ignore }, #endif - { "L2ECTLR_EL1", 0,11,0, 3,1,3, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL1_RW, 0, NULL, 0, }, - { "L2ECTLR", 15,9,0, 0,1,3, 0, - ARM_CP_CONST, PL1_RW, 0, NULL, 0, }, - { "L2ACTLR", 0,15,0, 3,1,0, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL1_RW, 0, NULL, 0 }, - { "CPUACTLR_EL1", 0,15,2, 3,1,0, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL1_RW, 0, NULL, 0 }, - { "CPUACTLR", 15,0,15, 0,0,0, 0, - ARM_CP_CONST | ARM_CP_64BIT, PL1_RW, 0, NULL, 0, }, - { "CPUECTLR_EL1", 0,15,2, 3,1,1, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL1_RW, 0, NULL, 0, }, - { "CPUECTLR", 15,0,15, 0,1,0, 0, - ARM_CP_CONST | ARM_CP_64BIT, PL1_RW, 0, NULL, 0, }, - { "CPUMERRSR_EL1", 0,15,2, 3,1,2, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL1_RW, 0, NULL, 0 }, - { "CPUMERRSR", 15,0,15, 0,2,0, 0, - ARM_CP_CONST | ARM_CP_64BIT, PL1_RW, 0, NULL, 0 }, - { "L2MERRSR_EL1", 0,15,2, 3,1,3, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL1_RW, 0, NULL, 0 }, - { "L2MERRSR", 15,0,15, 0,3,0, 0, - ARM_CP_CONST | ARM_CP_64BIT, PL1_RW, 0, NULL, 0 }, + { .name = "L2ECTLR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 3, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "L2ECTLR", + .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 3, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "L2ACTLR", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 0, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "CPUACTLR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "CPUACTLR", + .cp = 15, .opc1 = 0, .crm = 15, + .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, + { .name = "CPUECTLR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 1, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "CPUECTLR", + .cp = 15, .opc1 = 1, .crm = 15, + .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, + { .name = "CPUMERRSR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 2, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "CPUMERRSR", + .cp = 15, .opc1 = 2, .crm = 15, + .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, + { .name = "L2MERRSR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 3, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "L2MERRSR", + .cp = 15, .opc1 = 3, .crm = 15, + .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, REGINFO_SENTINEL }; diff --git a/qemu/target/arm/helper.c b/qemu/target/arm/helper.c index a4997466..cdd1661a 100644 --- a/qemu/target/arm/helper.c +++ b/qemu/target/arm/helper.c @@ -643,27 +643,32 @@ static const ARMCPRegInfo cp_reginfo[] = { * the secure register to be properly reset and migrated. There is also no * v8 EL1 version of the register so the non-secure instance stands alone. */ - { "FCSEIDR", 15,13,0, 0,0,0, 0,0, - PL1_RW, ARM_CP_SECSTATE_NS, NULL, 0, - offsetof(CPUARMState, cp15.fcseidr_ns), {0, 0}, - NULL, NULL, fcse_write, NULL, raw_write, }, - { "FCSEIDR_S", 15,13,0, 0,0,0, 0,0, - PL1_RW, ARM_CP_SECSTATE_S, NULL, 0, - offsetof(CPUARMState, cp15.fcseidr_s), {0, 0}, - NULL, NULL, fcse_write, NULL, raw_write, }, + { .name = "FCSEIDR", + .cp = 15, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 0, + .access = PL1_RW, .secure = ARM_CP_SECSTATE_NS, + .fieldoffset = offsetof(CPUARMState, cp15.fcseidr_ns), + .resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, }, + { .name = "FCSEIDR_S", + .cp = 15, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 0, + .access = PL1_RW, .secure = ARM_CP_SECSTATE_S, + .fieldoffset = offsetof(CPUARMState, cp15.fcseidr_s), + .resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, }, /* Define the secure and non-secure context identifier CP registers * separately because there is no secure bank in V8 (no _EL3). This allows * the secure register to be properly reset and migrated. In the * non-secure case, the 32-bit register will have reset and migration * disabled during registration as it is handled by the 64-bit instance. */ - { "CONTEXTIDR_EL1", 0,13,0, 3,0,1, ARM_CP_STATE_BOTH, - 0, PL1_RW, ARM_CP_SECSTATE_NS, NULL, 0, offsetof(CPUARMState, cp15.contextidr_el[1]), {0, 0}, - NULL, NULL, contextidr_write, NULL, raw_write, NULL, }, - { "CONTEXTIDR_S", 15,13,0, 0,0,1, ARM_CP_STATE_AA32,0, - PL1_RW, ARM_CP_SECSTATE_S, NULL, 0, - offsetof(CPUARMState, cp15.contextidr_s), {0, 0}, - NULL, NULL, contextidr_write, NULL, raw_write, NULL, }, + { .name = "CONTEXTIDR_EL1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1, + .access = PL1_RW, .secure = ARM_CP_SECSTATE_NS, + .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[1]), + .resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, }, + { .name = "CONTEXTIDR_S", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1, + .access = PL1_RW, .secure = ARM_CP_SECSTATE_S, + .fieldoffset = offsetof(CPUARMState, cp15.contextidr_s), + .resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, }, REGINFO_SENTINEL }; @@ -672,24 +677,27 @@ static const ARMCPRegInfo not_v8_cp_reginfo[] = { * definitions that don't use CP_ANY wildcards (mostly in v8_cp_reginfo[]). */ /* MMU Domain access control / MPU write buffer control */ - { "DACR", 15,3,CP_ANY, 0,CP_ANY,CP_ANY, 0, - 0, PL1_RW, 0, NULL, 0, 0, - { offsetoflow32(CPUARMState, cp15.dacr_s), offsetoflow32(CPUARMState, cp15.dacr_ns) }, - NULL, NULL, dacr_write, NULL, raw_write, NULL, }, + { .name = "DACR", + .cp = 15, .opc1 = CP_ANY, .crn = 3, .crm = CP_ANY, .opc2 = CP_ANY, + .access = PL1_RW, .resetvalue = 0, + .writefn = dacr_write, .raw_writefn = raw_write, + .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s), + offsetoflow32(CPUARMState, cp15.dacr_ns) } }, /* ARMv7 allocates a range of implementation defined TLB LOCKDOWN regs. * For v6 and v5, these mappings are overly broad. */ - { "TLB_LOCKDOWN", 15,10,0, 0,CP_ANY,CP_ANY, 0, - ARM_CP_NOP, PL1_RW, }, - { "TLB_LOCKDOWN", 15,10,1, 0,CP_ANY,CP_ANY, 0, - ARM_CP_NOP, PL1_RW, }, - { "TLB_LOCKDOWN", 15,10,4, 0,CP_ANY,CP_ANY, 0, - ARM_CP_NOP, PL1_RW, }, - { "TLB_LOCKDOWN", 15,10,8, 0,CP_ANY,CP_ANY, 0, - ARM_CP_NOP, PL1_RW, }, + { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 0, + .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP }, + { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 1, + .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP }, + { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 4, + .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP }, + { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 8, + .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP }, /* Cache maintenance ops; some of this space may be overridden later. */ - { "CACHEMAINT", 15,7,CP_ANY, 0,0,CP_ANY, 0, - ARM_CP_NOP | ARM_CP_OVERRIDE, PL1_W, }, + { .name = "CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY, + .opc1 = 0, .opc2 = CP_ANY, .access = PL1_W, + .type = ARM_CP_NOP | ARM_CP_OVERRIDE }, REGINFO_SENTINEL }; @@ -697,8 +705,8 @@ static const ARMCPRegInfo not_v6_cp_reginfo[] = { /* Not all pre-v6 cores implemented this WFI, so this is slightly * over-broad. */ - { "WFI_v5", 15,7,8, 0,0,2, 0, - ARM_CP_WFI, PL1_W, }, + { .name = "WFI_v5", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = 2, + .access = PL1_W, .type = ARM_CP_WFI }, REGINFO_SENTINEL }; @@ -706,45 +714,48 @@ static const ARMCPRegInfo not_v7_cp_reginfo[] = { /* Standard v6 WFI (also used in some pre-v6 cores); not in v7 (which * is UNPREDICTABLE; we choose to NOP as most implementations do). */ - { "WFI_v6", 15,7,0, 0,0,4, 0, - ARM_CP_WFI, PL1_W, }, + { .name = "WFI_v6", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4, + .access = PL1_W, .type = ARM_CP_WFI }, /* L1 cache lockdown. Not architectural in v6 and earlier but in practice * implemented in 926, 946, 1026, 1136, 1176 and 11MPCore. StrongARM and * OMAPCP will override this space. */ - { "DLOCKDOWN", 15,9,0, 0,0,0, 0, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c9_data), }, - { "ILOCKDOWN", 15,9,0, 0,0,1, 0, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c9_insn), }, + { .name = "DLOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_data), + .resetvalue = 0 }, + { .name = "ILOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 0, .opc2 = 1, + .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_insn), + .resetvalue = 0 }, /* v6 doesn't have the cache ID registers but Linux reads them anyway */ - { "DUMMY", 15,0,0, 0,1,CP_ANY, 0, - ARM_CP_CONST | ARM_CP_NO_RAW, PL1_R, 0, NULL, 0 }, + { .name = "DUMMY", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = CP_ANY, + .access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW, + .resetvalue = 0 }, /* We don't implement pre-v7 debug but most CPUs had at least a DBGDIDR; * implementing it as RAZ means the "debug architecture version" bits * will read as a reserved value, which should cause Linux to not try * to use the debug hardware. */ - { "DBGDIDR", 14,0,0, 0,0,0, 0, - ARM_CP_CONST, PL0_R, 0, NULL, 0 }, + { .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL0_R, .type = ARM_CP_CONST, .resetvalue = 0 }, /* MMU TLB control. Note that the wildcarding means we cover not just * the unified TLB ops but also the dside/iside/inner-shareable variants. */ - { "TLBIALL", 15,8,CP_ANY, 0,CP_ANY,0, 0, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbiall_write, }, - { "TLBIMVA", 15,8,CP_ANY, 0,CP_ANY,1, 0, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbimva_write, }, - { "TLBIASID", 15,8,CP_ANY, 0,CP_ANY,2, 0, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbiasid_write, }, - { "TLBIMVAA", 15,8,CP_ANY, 0,CP_ANY,3, 0, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbimvaa_write, }, - { "PRRR", 15,10,2, 0,0,0, 0, ARM_CP_NOP, - PL1_RW }, - { "NMRR", 15,10,2, 0,0,1, 0, ARM_CP_NOP, - PL1_RW }, + { .name = "TLBIALL", .cp = 15, .crn = 8, .crm = CP_ANY, + .opc1 = CP_ANY, .opc2 = 0, .access = PL1_W, .writefn = tlbiall_write, + .type = ARM_CP_NO_RAW }, + { .name = "TLBIMVA", .cp = 15, .crn = 8, .crm = CP_ANY, + .opc1 = CP_ANY, .opc2 = 1, .access = PL1_W, .writefn = tlbimva_write, + .type = ARM_CP_NO_RAW }, + { .name = "TLBIASID", .cp = 15, .crn = 8, .crm = CP_ANY, + .opc1 = CP_ANY, .opc2 = 2, .access = PL1_W, .writefn = tlbiasid_write, + .type = ARM_CP_NO_RAW }, + { .name = "TLBIMVAA", .cp = 15, .crn = 8, .crm = CP_ANY, + .opc1 = CP_ANY, .opc2 = 3, .access = PL1_W, .writefn = tlbimvaa_write, + .type = ARM_CP_NO_RAW }, + { .name = "PRRR", .cp = 15, .crn = 10, .crm = 2, + .opc1 = 0, .opc2 = 0, .access = PL1_RW, .type = ARM_CP_NOP }, + { .name = "NMRR", .cp = 15, .crn = 10, .crm = 2, + .opc1 = 0, .opc2 = 1, .access = PL1_RW, .type = ARM_CP_NOP }, REGINFO_SENTINEL }; @@ -782,6 +793,14 @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri, env->cp15.cpacr_el1 = value; } +static void cpacr_reset(CPUARMState *env, const ARMCPRegInfo *ri) +{ + /* Call cpacr_write() so that we reset with the correct RAO bits set + * for our CPU features. + */ + cpacr_write(env, ri, 0); +} + static CPAccessResult cpacr_access(CPUARMState *env, const ARMCPRegInfo *ri, bool isread) { @@ -813,30 +832,33 @@ static CPAccessResult cptr_access(CPUARMState *env, const ARMCPRegInfo *ri, static const ARMCPRegInfo v6_cp_reginfo[] = { /* prefetch by MVA in v6, NOP in v7 */ - { "MVA_prefetch", 15,7,13, 0,0,1, 0, - ARM_CP_NOP, PL1_W, }, + { .name = "MVA_prefetch", + .cp = 15, .crn = 7, .crm = 13, .opc1 = 0, .opc2 = 1, + .access = PL1_W, .type = ARM_CP_NOP }, /* We need to break the TB after ISB to execute self-modifying code * correctly and also to take any pending interrupts immediately. * So use arm_cp_write_ignore() function instead of ARM_CP_NOP flag. */ - { "ISB", 15,7,5, 0,0,4, 0, ARM_CP_NO_RAW, - PL0_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, arm_cp_write_ignore }, - { "DSB", 15,7,10, 0,0,4, 0, - ARM_CP_NOP, PL0_W, }, - { "DMB", 15,7,10, 0,0,5, 0, - ARM_CP_NOP, PL0_W, }, - { "IFAR", 15,6,0, 0,0,2, 0, - 0, PL1_RW, 0, NULL, 0, 0, - { offsetof(CPUARMState, cp15.ifar_s), offsetof(CPUARMState, cp15.ifar_ns) } }, + { .name = "ISB", .cp = 15, .crn = 7, .crm = 5, .opc1 = 0, .opc2 = 4, + .access = PL0_W, .type = ARM_CP_NO_RAW, .writefn = arm_cp_write_ignore }, + { .name = "DSB", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 4, + .access = PL0_W, .type = ARM_CP_NOP }, + { .name = "DMB", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 5, + .access = PL0_W, .type = ARM_CP_NOP }, + { .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 2, + .access = PL1_RW, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ifar_s), + offsetof(CPUARMState, cp15.ifar_ns) }, + .resetvalue = 0, }, /* Watchpoint Fault Address Register : should actually only be present * for 1136, 1176, 11MPCore. */ - { "WFAR", 15,6,0, 0,0,1, 0, - ARM_CP_CONST, PL1_RW, 0, NULL, 0, }, - { "CPACR", 0,1,0, 3,0,2, ARM_CP_STATE_BOTH, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.cpacr_el1), {0, 0}, - cpacr_access, NULL, cpacr_write }, + { .name = "WFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0, }, + { .name = "CPACR", .state = ARM_CP_STATE_BOTH, .opc0 = 3, + .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 2, .accessfn = cpacr_access, + .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.cpacr_el1), + .resetfn = cpacr_reset, .writefn = cpacr_write }, REGINFO_SENTINEL }; @@ -1715,8 +1737,8 @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri) static const ARMCPRegInfo v7_cp_reginfo[] = { /* the old v6 WFI, UNPREDICTABLE in v7 but we choose to NOP */ - { "NOP", 15,7,0, 0,0,4, 0, - ARM_CP_NOP, PL1_W, }, + { .name = "NOP", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4, + .access = PL1_W, .type = ARM_CP_NOP }, /* Performance monitors are implementation defined in v7, * but with an ARM recommended set of registers, which we * follow. @@ -1728,103 +1750,171 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { * For the cases controlled by PMUSERENR we must set .access to PL0_RW * or PL0_RO as appropriate and then check PMUSERENR in the helper fn. */ - { "PMCNTENSET", 15,9,12, 0,0,1, 0, - ARM_CP_ALIAS, PL0_RW, 0, NULL, 0, offsetoflow32(CPUARMState, cp15.c9_pmcnten), {0, 0}, - pmreg_access, NULL, pmcntenset_write, NULL, raw_write }, - { "PMCNTENSET_EL0", 0,9,12, 3,3,1, ARM_CP_STATE_AA64, - 0, PL0_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c9_pmcnten), {0, 0}, - pmreg_access, NULL, pmcntenset_write, NULL, raw_write }, - { "PMCNTENCLR", 15,9,12, 0,0,2, 0, - ARM_CP_ALIAS, PL0_RW, 0, NULL, 0, offsetoflow32(CPUARMState, cp15.c9_pmcnten), {0, 0}, - pmreg_access, NULL, pmcntenclr_write, }, - { "PMCNTENCLR_EL0", 0,9,12, 3,3,2, ARM_CP_STATE_AA64, - ARM_CP_ALIAS, PL0_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c9_pmcnten), {0, 0}, - pmreg_access, NULL, pmcntenclr_write }, - { "PMOVSR", 15,9,12, 0,0,3, 0, - ARM_CP_IO, PL0_RW, 0, NULL, 0, offsetoflow32(CPUARMState, cp15.c9_pmovsr), {0, 0}, - pmreg_access, NULL, pmovsr_write, NULL, raw_write }, - { "PMOVSCLR_EL0", 0,9,12, 3,3,3, ARM_CP_STATE_AA64, ARM_CP_ALIAS | ARM_CP_IO, - PL0_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c9_pmovsr), {0, 0}, - pmreg_access, NULL, pmovsr_write, NULL, raw_write }, - { "PMSWINC", 15,9,12, 0,0,4, 0, - ARM_CP_NO_RAW | ARM_CP_IO, PL0_W, 0, NULL, 0, 0, {0, 0}, - pmreg_access_swinc, NULL, pmswinc_write }, - { "PMSWINC_EL0", 0,9,12, 3,3,4, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW | ARM_CP_IO, PL0_W, 0, NULL, 0, 0, {0, 0}, - pmreg_access_swinc, NULL, pmswinc_write }, - { "PMSELR", 15,9,12, 0,0,5, 0, ARM_CP_ALIAS, - PL0_RW, 0, NULL, 0, offsetoflow32(CPUARMState, cp15.c9_pmselr), {0, 0}, - pmreg_access_selr, NULL, pmselr_write, NULL, raw_write}, - { "PMSELR_EL0", 0,9,12, 3,3,5, ARM_CP_STATE_AA64, 0, - PL0_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c9_pmselr), {0, 0}, - pmreg_access_selr, NULL, pmselr_write, NULL, raw_write, }, - { "PMCCNTR", 15,9,13, 0,0,0, 0, - ARM_CP_ALIAS | ARM_CP_IO, PL0_RW, 0, NULL, 0, 0, {0, 0}, - pmreg_access_ccntr, pmccntr_read, pmccntr_write32, }, - { "PMCCNTR_EL0", 0,9,13, 3,3,0, ARM_CP_STATE_AA64, - ARM_CP_IO, PL0_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c15_ccnt), {0, 0}, - pmreg_access_ccntr, pmccntr_read, pmccntr_write, raw_read, raw_write }, - { "PMCCFILTR", 15,14,15, 0,0,7, 0, ARM_CP_ALIAS | ARM_CP_IO, PL0_RW, 0, - NULL, 0, 0, {0, 0}, pmreg_access, pmccfiltr_read_a32, pmccfiltr_write_a32 }, - { "PMCCFILTR_EL0", 0,14,15, 3,3,7, ARM_CP_STATE_AA64, - ARM_CP_IO, PL0_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.pmccfiltr_el0), {0, 0}, - pmreg_access, NULL, pmccfiltr_write, NULL, raw_write }, - { "PMXEVTYPER", 15,9,13, 0,0,1, 0, ARM_CP_NO_RAW | ARM_CP_IO, - PL0_RW, 0, NULL, 0, 0, {0, 0}, - pmreg_access, pmxevtyper_read, pmxevtyper_write }, - { "PMXEVTYPER_EL0", 0,9,13, 3,3,1, ARM_CP_STATE_AA64, ARM_CP_NO_RAW | ARM_CP_IO, - PL0_RW, 0, NULL, 0, 0, {0, 0}, - pmreg_access, pmxevtyper_read, pmxevtyper_write }, - { "PMXEVCNTR", 15,9,13, 0,0,2, 0, - ARM_CP_NO_RAW | ARM_CP_IO, PL0_RW, 0, NULL, 0, 0, {0, 0}, - pmreg_access_xevcntr, pmxevcntr_read, pmxevcntr_write }, - { "PMXEVCNTR_EL0", 0,9,13, 3,3,2, ARM_CP_STATE_AA64, ARM_CP_NO_RAW | ARM_CP_IO, - PL0_RW, 0, NULL, 0, 0, {0, 0}, - pmreg_access_xevcntr, pmxevcntr_read, pmxevcntr_write }, - { "PMUSERENR", 15,9,14, 0,0,0, 0, - 0, PL0_R | PL1_RW, 0, NULL, 0, offsetoflow32(CPUARMState, cp15.c9_pmuserenr), {0, 0}, - access_tpm, NULL, pmuserenr_write, NULL, raw_write }, - { "PMUSERENR_EL0", 0,9,14,3,3,0, ARM_CP_STATE_AA64, ARM_CP_ALIAS, - PL0_R | PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c9_pmuserenr), {0, 0}, - access_tpm, NULL, pmuserenr_write, NULL, raw_write }, - { "PMINTENSET", 15,9,14, 0,0,1, 0, ARM_CP_ALIAS | ARM_CP_IO, - PL1_RW, 0, NULL, 0, offsetoflow32(CPUARMState, cp15.c9_pminten), {0, 0}, - access_tpm, NULL, pmintenset_write, NULL, raw_write }, - { "PMINTENSET_EL1", 0,9,14, 3,0,1, ARM_CP_STATE_AA64, ARM_CP_IO, - PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c9_pminten), {0, 0}, - access_tpm, NULL, pmintenset_write, NULL, raw_write }, - { "PMINTENCLR", 15,9,14, 0,0,2, 0, - ARM_CP_ALIAS | ARM_CP_IO, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c9_pminten), {0, 0}, - access_tpm, NULL, pmintenclr_write, }, - { "PMINTENCLR_EL1", 0,9,14, 3,0,2, ARM_CP_STATE_AA64, ARM_CP_ALIAS | ARM_CP_IO, - PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c9_pminten), {0, 0}, - access_tpm, NULL, pmintenclr_write }, - { "CCSIDR", 0,0,0, 3,1,0, ARM_CP_STATE_BOTH, - ARM_CP_NO_RAW, PL1_R, 0, NULL, 0, 0, {0, 0}, - NULL, ccsidr_read, }, - { "CSSELR", 0,0,0, 3,2,0, ARM_CP_STATE_BOTH, - 0, PL1_RW, 0, NULL, 0, 0, - { offsetof(CPUARMState, cp15.csselr_s), offsetof(CPUARMState, cp15.csselr_ns) }, - NULL, NULL, csselr_write, }, + { .name = "PMCNTENSET", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 1, + .access = PL0_RW, .type = ARM_CP_ALIAS, + .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcnten), + .writefn = pmcntenset_write, + .accessfn = pmreg_access, + .raw_writefn = raw_write }, + { .name = "PMCNTENSET_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 1, + .access = PL0_RW, .accessfn = pmreg_access, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten), .resetvalue = 0, + .writefn = pmcntenset_write, .raw_writefn = raw_write }, + { .name = "PMCNTENCLR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 2, + .access = PL0_RW, + .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcnten), + .accessfn = pmreg_access, + .writefn = pmcntenclr_write, + .type = ARM_CP_ALIAS }, + { .name = "PMCNTENCLR_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 2, + .access = PL0_RW, .accessfn = pmreg_access, + .type = ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten), + .writefn = pmcntenclr_write }, + { .name = "PMOVSR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 3, + .access = PL0_RW, .type = ARM_CP_IO, + .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmovsr), + .accessfn = pmreg_access, + .writefn = pmovsr_write, + .raw_writefn = raw_write }, + { .name = "PMOVSCLR_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 3, + .access = PL0_RW, .accessfn = pmreg_access, + .type = ARM_CP_ALIAS | ARM_CP_IO, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr), + .writefn = pmovsr_write, + .raw_writefn = raw_write }, + { .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4, + .access = PL0_W, .accessfn = pmreg_access_swinc, + .type = ARM_CP_NO_RAW | ARM_CP_IO, + .writefn = pmswinc_write }, + { .name = "PMSWINC_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 4, + .access = PL0_W, .accessfn = pmreg_access_swinc, + .type = ARM_CP_NO_RAW | ARM_CP_IO, + .writefn = pmswinc_write }, + { .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5, + .access = PL0_RW, .type = ARM_CP_ALIAS, + .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmselr), + .accessfn = pmreg_access_selr, .writefn = pmselr_write, + .raw_writefn = raw_write}, + { .name = "PMSELR_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 5, + .access = PL0_RW, .accessfn = pmreg_access_selr, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pmselr), + .writefn = pmselr_write, .raw_writefn = raw_write, }, + { .name = "PMCCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 0, + .access = PL0_RW, .resetvalue = 0, .type = ARM_CP_ALIAS | ARM_CP_IO, + .readfn = pmccntr_read, .writefn = pmccntr_write32, + .accessfn = pmreg_access_ccntr }, + { .name = "PMCCNTR_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 0, + .access = PL0_RW, .accessfn = pmreg_access_ccntr, + .type = ARM_CP_IO, + .fieldoffset = offsetof(CPUARMState, cp15.c15_ccnt), + .readfn = pmccntr_read, .writefn = pmccntr_write, + .raw_readfn = raw_read, .raw_writefn = raw_write, }, + { .name = "PMCCFILTR", .cp = 15, .opc1 = 0, .crn = 14, .crm = 15, .opc2 = 7, + .writefn = pmccfiltr_write_a32, .readfn = pmccfiltr_read_a32, + .access = PL0_RW, .accessfn = pmreg_access, + .type = ARM_CP_ALIAS | ARM_CP_IO, + .resetvalue = 0, }, + { .name = "PMCCFILTR_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 15, .opc2 = 7, + .writefn = pmccfiltr_write, .raw_writefn = raw_write, + .access = PL0_RW, .accessfn = pmreg_access, + .type = ARM_CP_IO, + .fieldoffset = offsetof(CPUARMState, cp15.pmccfiltr_el0), + .resetvalue = 0, }, + { .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1, + .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO, + .accessfn = pmreg_access, + .writefn = pmxevtyper_write, .readfn = pmxevtyper_read }, + { .name = "PMXEVTYPER_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 1, + .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO, + .accessfn = pmreg_access, + .writefn = pmxevtyper_write, .readfn = pmxevtyper_read }, + { .name = "PMXEVCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 2, + .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO, + .accessfn = pmreg_access_xevcntr, + .writefn = pmxevcntr_write, .readfn = pmxevcntr_read }, + { .name = "PMXEVCNTR_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 2, + .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO, + .accessfn = pmreg_access_xevcntr, + .writefn = pmxevcntr_write, .readfn = pmxevcntr_read }, + { .name = "PMUSERENR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 0, + .access = PL0_R | PL1_RW, .accessfn = access_tpm, + .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmuserenr), + .resetvalue = 0, + .writefn = pmuserenr_write, .raw_writefn = raw_write }, + { .name = "PMUSERENR_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 14, .opc2 = 0, + .access = PL0_R | PL1_RW, .accessfn = access_tpm, .type = ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pmuserenr), + .resetvalue = 0, + .writefn = pmuserenr_write, .raw_writefn = raw_write }, + { .name = "PMINTENSET", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 1, + .access = PL1_RW, .accessfn = access_tpm, + .type = ARM_CP_ALIAS | ARM_CP_IO, + .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pminten), + .resetvalue = 0, + .writefn = pmintenset_write, .raw_writefn = raw_write }, + { .name = "PMINTENSET_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 1, + .access = PL1_RW, .accessfn = access_tpm, + .type = ARM_CP_IO, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten), + .writefn = pmintenset_write, .raw_writefn = raw_write, + .resetvalue = 0x0 }, + { .name = "PMINTENCLR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 2, + .access = PL1_RW, .accessfn = access_tpm, + .type = ARM_CP_ALIAS | ARM_CP_IO, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten), + .writefn = pmintenclr_write, }, + { .name = "PMINTENCLR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 2, + .access = PL1_RW, .accessfn = access_tpm, + .type = ARM_CP_ALIAS | ARM_CP_IO, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten), + .writefn = pmintenclr_write }, + { .name = "CCSIDR", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0, + .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_RAW }, + { .name = "CSSELR", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0, + .access = PL1_RW, .writefn = csselr_write, .resetvalue = 0, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.csselr_s), + offsetof(CPUARMState, cp15.csselr_ns) } }, /* Auxiliary ID register: this actually has an IMPDEF value but for now * just RAZ for all cores: */ - { "AIDR", 0,0,0, 3,1,7, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL1_R, 0, NULL, 0 }, + { .name = "AIDR", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 7, + .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, /* Auxiliary fault status registers: these also are IMPDEF, and we * choose to RAZ/WI for all cores. */ - { "AFSR0_EL1", 0,5,1, 3,0,0, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL1_RW, 0, NULL, 0 }, - { "AFSR1_EL1", 0,5,1, 3,0,1, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL1_RW, 0, NULL, 0 }, + { .name = "AFSR0_EL1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "AFSR1_EL1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 1, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, /* MAIR can just read-as-written because we don't implement caches * and so don't need to care about memory attributes. */ - { "MAIR_EL1", 0,10,2, 3,0,0, ARM_CP_STATE_AA64, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.mair_el[1]), }, - { "MAIR_EL3", 0,10,2, 3,6,0, ARM_CP_STATE_AA64, 0, - PL3_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.mair_el[3]) }, + { .name = "MAIR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0, + .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[1]), + .resetvalue = 0 }, + { .name = "MAIR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 10, .crm = 2, .opc2 = 0, + .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[3]), + .resetvalue = 0 }, /* For non-long-descriptor page tables these are PRRR and NMRR; * regardless they still act as reads-as-written for QEMU. */ @@ -1832,78 +1922,75 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { * allows them to assign the correct fieldoffset based on the endianness * handled in the field definitions. */ - { "MAIR0", 15,10,2, 0,0,0, ARM_CP_STATE_AA32, 0, - PL1_RW, 0, NULL, 0, 0, - { offsetof(CPUARMState, cp15.mair0_s), offsetof(CPUARMState, cp15.mair0_ns) }, - NULL, NULL, NULL, NULL, NULL, arm_cp_reset_ignore }, - { "MAIR1", 15,10,2, 0,0,1, ARM_CP_STATE_AA32, 0, - PL1_RW, 0, NULL, 0, 0, - { offsetof(CPUARMState, cp15.mair1_s), offsetof(CPUARMState, cp15.mair1_ns) }, - NULL, NULL, NULL, NULL, NULL, arm_cp_reset_ignore }, - { "ISR_EL1", 0,12,1, 3,0,0, ARM_CP_STATE_BOTH, - ARM_CP_NO_RAW, PL1_R, 0, NULL, 0, 0, {0, 0}, - NULL, isr_read }, + { .name = "MAIR0", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0, .access = PL1_RW, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.mair0_s), + offsetof(CPUARMState, cp15.mair0_ns) }, + .resetfn = arm_cp_reset_ignore }, + { .name = "MAIR1", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 1, .access = PL1_RW, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.mair1_s), + offsetof(CPUARMState, cp15.mair1_ns) }, + .resetfn = arm_cp_reset_ignore }, + { .name = "ISR_EL1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 1, .opc2 = 0, + .type = ARM_CP_NO_RAW, .access = PL1_R, .readfn = isr_read }, /* 32 bit ITLB invalidates */ - { "ITLBIALL", 15,8,5, 0,0,0, 0, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbiall_write }, - { "ITLBIMVA", 15,8,5, 0,0,1, 0, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbimva_write }, - { "ITLBIASID", 15,8,5, 0,0,2, 0, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbiasid_write }, + { .name = "ITLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 0, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write }, + { .name = "ITLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 1, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write }, + { .name = "ITLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 2, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write }, /* 32 bit DTLB invalidates */ - { "DTLBIALL", 15,8,6, 0,0,0, 0, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbiall_write }, - { "DTLBIMVA", 15,8,6, 0,0,1, 0, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbimva_write }, - { "DTLBIASID", 15,8,6, 0,0,2, 0, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbiasid_write }, + { .name = "DTLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 0, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write }, + { .name = "DTLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 1, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write }, + { .name = "DTLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 2, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write }, /* 32 bit TLB invalidates */ - { "TLBIALL", 15,8,7, 0,0,0, 0, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbiall_write }, - { "TLBIMVA", 15,8,7, 0,0,1, 0, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbimva_write }, - { "TLBIASID", 15,8,7, 0,0,2, 0, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbiasid_write }, - { "TLBIMVAA", 15,8,7, 0,0,3, 0, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbimvaa_write }, + { .name = "TLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write }, + { .name = "TLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write }, + { .name = "TLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write }, + { .name = "TLBIMVAA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write }, REGINFO_SENTINEL }; static const ARMCPRegInfo v7mp_cp_reginfo[] = { /* 32 bit TLB invalidates, Inner Shareable */ - { "TLBIALLIS", 15,8,3, 0,0,0, 0, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbiall_is_write }, - { "TLBIMVAIS", 15,8,3, 0,0,1, 0, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbimva_is_write }, - { "TLBIASIDIS", 15,8,3, 0,0,2, 0, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbiasid_is_write }, - { "TLBIMVAAIS", 15,8,3, 0,0,3, 0, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbimvaa_is_write }, + { .name = "TLBIALLIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_is_write }, + { .name = "TLBIMVAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_is_write }, + { .name = "TLBIASIDIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2, + .type = ARM_CP_NO_RAW, .access = PL1_W, + .writefn = tlbiasid_is_write }, + { .name = "TLBIMVAAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3, + .type = ARM_CP_NO_RAW, .access = PL1_W, + .writefn = tlbimvaa_is_write }, REGINFO_SENTINEL }; static const ARMCPRegInfo pmovsset_cp_reginfo[] = { /* PMOVSSET is not implemented in v7 before v7ve */ - { "PMOVSSET", 15,9,14, 0,0,3, 0, ARM_CP_ALIAS | ARM_CP_IO, PL0_RW, 0, - NULL, 0, offsetoflow32(CPUARMState, cp15.c9_pmovsr), {0, 0}, - pmreg_access, NULL, pmovsset_write, NULL, raw_write }, - { "PMOVSSET_EL0", 0,9,14, 3,3,3, ARM_CP_STATE_AA64, ARM_CP_ALIAS | ARM_CP_IO, PL0_RW, 0, - NULL, 0, offsetof(CPUARMState, cp15.c9_pmovsr), {0, 0}, - pmreg_access, NULL, pmovsset_write, NULL, raw_write }, + { .name = "PMOVSSET", .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 3, + .access = PL0_RW, .accessfn = pmreg_access, + .type = ARM_CP_ALIAS | ARM_CP_IO, + .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmovsr), + .writefn = pmovsset_write, + .raw_writefn = raw_write }, + { .name = "PMOVSSET_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 14, .opc2 = 3, + .access = PL0_RW, .accessfn = pmreg_access, + .type = ARM_CP_ALIAS | ARM_CP_IO, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr), + .writefn = pmovsset_write, + .raw_writefn = raw_write }, REGINFO_SENTINEL }; @@ -1924,33 +2011,45 @@ static CPAccessResult teehbr_access(CPUARMState *env, const ARMCPRegInfo *ri, } static const ARMCPRegInfo t2ee_cp_reginfo[] = { - { "TEECR", 14,0,0, 0,6,0, 0, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, teecr), {0, 0}, - NULL, NULL, teecr_write }, - { "TEEHBR", 14,1,0, 0,6,0, 0, - 0, PL0_RW, 0, NULL, 0, offsetof(CPUARMState, teehbr), {0, 0}, - teehbr_access, }, + { .name = "TEECR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 6, .opc2 = 0, + .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, teecr), + .resetvalue = 0, + .writefn = teecr_write }, + { .name = "TEEHBR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 6, .opc2 = 0, + .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, teehbr), + .accessfn = teehbr_access, .resetvalue = 0 }, REGINFO_SENTINEL }; static const ARMCPRegInfo v6k_cp_reginfo[] = { - { "TPIDR_EL0", 0,13,0, 3,3,2, ARM_CP_STATE_AA64, - 0, PL0_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.tpidr_el[0]), }, - { "TPIDRURW", 15,13,0, 0,0,2, 0, - 0, PL0_RW, 0, NULL, 0, 0, - { offsetoflow32(CPUARMState, cp15.tpidrurw_s), offsetoflow32(CPUARMState, cp15.tpidrurw_ns) }, - NULL, NULL, NULL, NULL, NULL, arm_cp_reset_ignore }, - { "TPIDRRO_EL0", 0,13,0, 3,3,3, ARM_CP_STATE_AA64, - 0, PL0_R|PL1_W, 0, NULL, 0, offsetof(CPUARMState, cp15.tpidrro_el[0]) }, - { "TPIDRURO", 15,13,0, 0,0,3, 0, - 0, PL0_R|PL1_W, 0, NULL, 0, 0, - {offsetoflow32(CPUARMState, cp15.tpidruro_s), offsetoflow32(CPUARMState, cp15.tpidruro_ns) }, - NULL, NULL, NULL, NULL, NULL, arm_cp_reset_ignore }, - { "TPIDR_EL1", 0,13,0, 3,0,4, ARM_CP_STATE_AA64, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.tpidr_el[1]) }, - { "TPIDRPRW", 15,13,0, 0,0,4, 0,0, - PL1_RW, 0, NULL, 0,0, - { offsetoflow32(CPUARMState, cp15.tpidrprw_s), offsetoflow32(CPUARMState, cp15.tpidrprw_ns)} }, + { .name = "TPIDR_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .opc2 = 2, .crn = 13, .crm = 0, + .access = PL0_RW, + .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[0]), .resetvalue = 0 }, + { .name = "TPIDRURW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 2, + .access = PL0_RW, + .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrurw_s), + offsetoflow32(CPUARMState, cp15.tpidrurw_ns) }, + .resetfn = arm_cp_reset_ignore }, + { .name = "TPIDRRO_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .opc2 = 3, .crn = 13, .crm = 0, + .access = PL0_R|PL1_W, + .fieldoffset = offsetof(CPUARMState, cp15.tpidrro_el[0]), + .resetvalue = 0}, + { .name = "TPIDRURO", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 3, + .access = PL0_R|PL1_W, + .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidruro_s), + offsetoflow32(CPUARMState, cp15.tpidruro_ns) }, + .resetfn = arm_cp_reset_ignore }, + { .name = "TPIDR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .opc2 = 4, .crn = 13, .crm = 0, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[1]), .resetvalue = 0 }, + { .name = "TPIDRPRW", .opc1 = 0, .cp = 15, .crn = 13, .crm = 0, .opc2 = 4, + .access = PL1_RW, + .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrprw_s), + offsetoflow32(CPUARMState, cp15.tpidrprw_ns) }, + .resetvalue = 0 }, REGINFO_SENTINEL }; @@ -2368,89 +2467,183 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = { * of software; writing it doesn't actually change the timer frequency. * Our reset value matches the fixed frequency we implement the timer at. */ - { "CNTFRQ", 15,14,0, 0,0,0, 0, - ARM_CP_ALIAS, PL1_RW | PL0_R, 0, NULL, 0, offsetoflow32(CPUARMState, cp15.c14_cntfrq), {0, 0}, - gt_cntfrq_access, NULL, NULL, NULL, NULL, NULL }, - { "CNTFRQ_EL0", 0,14,0, 3,3,0, ARM_CP_STATE_AA64, - 0, PL1_RW | PL0_R, 0, NULL, (1000 * 1000 * 1000) / GTIMER_SCALE, offsetof(CPUARMState, cp15.c14_cntfrq), {0, 0}, - gt_cntfrq_access, }, + { .name = "CNTFRQ", .cp = 15, .crn = 14, .crm = 0, .opc1 = 0, .opc2 = 0, + .type = ARM_CP_ALIAS, + .access = PL1_RW | PL0_R, .accessfn = gt_cntfrq_access, + .fieldoffset = offsetoflow32(CPUARMState, cp15.c14_cntfrq), + }, + { .name = "CNTFRQ_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 0, + .access = PL1_RW | PL0_R, .accessfn = gt_cntfrq_access, + .fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq), + .resetvalue = (1000 * 1000 * 1000) / GTIMER_SCALE, + }, /* overall control: mostly access permissions */ - { "CNTKCTL", 0,14,1, 3,0,0, ARM_CP_STATE_BOTH, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c14_cntkctl), }, + { .name = "CNTKCTL", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 14, .crm = 1, .opc2 = 0, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.c14_cntkctl), + .resetvalue = 0, + }, /* per-timer control */ - { "CNTP_CTL", 15,14,2, 0,0,1, 0, - ARM_CP_IO | ARM_CP_ALIAS, PL1_RW | PL0_R, ARM_CP_SECSTATE_NS, NULL, 0, offsetoflow32(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl), {0, 0}, - gt_ptimer_access, NULL, gt_phys_ctl_write, NULL, raw_write, NULL }, - { "CNTP_CTL_S", 15,14,2, 0,0,1, 0, ARM_CP_IO | ARM_CP_ALIAS, - PL1_RW | PL0_R, ARM_CP_SECSTATE_S, NULL, 0, offsetoflow32(CPUARMState, cp15.c14_timer[GTIMER_SEC].ctl), {0, 0}, - gt_ptimer_access, NULL, gt_sec_ctl_write, NULL, raw_write }, - { "CNTP_CTL_EL0", 0,14,2, 3,3,1, ARM_CP_STATE_AA64, - ARM_CP_IO, PL1_RW | PL0_R, 0, NULL, 0, offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl), {0, 0}, - gt_ptimer_access, NULL,gt_phys_ctl_write, NULL,raw_write, }, - { "CNTV_CTL", 15,14,3, 0,0,1, 0, - ARM_CP_IO | ARM_CP_ALIAS, PL1_RW | PL0_R, 0, NULL, 0, offsetoflow32(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl), {0, 0}, - gt_vtimer_access, NULL, gt_virt_ctl_write, NULL, raw_write, NULL }, - { "CNTV_CTL_EL0", 0,14,3, 3,3,1, ARM_CP_STATE_AA64, - ARM_CP_IO, PL1_RW | PL0_R, 0, NULL, 0, offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl), {0, 0}, - gt_vtimer_access, NULL,gt_virt_ctl_write, NULL,raw_write, }, + { .name = "CNTP_CTL", .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 1, + .secure = ARM_CP_SECSTATE_NS, + .type = ARM_CP_IO | ARM_CP_ALIAS, .access = PL1_RW | PL0_R, + .accessfn = gt_ptimer_access, + .fieldoffset = offsetoflow32(CPUARMState, + cp15.c14_timer[GTIMER_PHYS].ctl), + .writefn = gt_phys_ctl_write, .raw_writefn = raw_write, + }, + { .name = "CNTP_CTL_S", + .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 1, + .secure = ARM_CP_SECSTATE_S, + .type = ARM_CP_IO | ARM_CP_ALIAS, .access = PL1_RW | PL0_R, + .accessfn = gt_ptimer_access, + .fieldoffset = offsetoflow32(CPUARMState, + cp15.c14_timer[GTIMER_SEC].ctl), + .writefn = gt_sec_ctl_write, .raw_writefn = raw_write, + }, + { .name = "CNTP_CTL_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 1, + .type = ARM_CP_IO, .access = PL1_RW | PL0_R, + .accessfn = gt_ptimer_access, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl), + .resetvalue = 0, + .writefn = gt_phys_ctl_write, .raw_writefn = raw_write, + }, + { .name = "CNTV_CTL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 1, + .type = ARM_CP_IO | ARM_CP_ALIAS, .access = PL1_RW | PL0_R, + .accessfn = gt_vtimer_access, + .fieldoffset = offsetoflow32(CPUARMState, + cp15.c14_timer[GTIMER_VIRT].ctl), + .writefn = gt_virt_ctl_write, .raw_writefn = raw_write, + }, + { .name = "CNTV_CTL_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 1, + .type = ARM_CP_IO, .access = PL1_RW | PL0_R, + .accessfn = gt_vtimer_access, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl), + .resetvalue = 0, + .writefn = gt_virt_ctl_write, .raw_writefn = raw_write, + }, /* TimerValue views: a 32 bit downcounting view of the underlying state */ - { "CNTP_TVAL", 15,14,2, 0,0,0, 0, - ARM_CP_NO_RAW | ARM_CP_IO, PL1_RW | PL0_R, ARM_CP_SECSTATE_NS, NULL, 0, 0, {0, 0}, - gt_ptimer_access, gt_phys_tval_read, gt_phys_tval_write, }, - { "CNTP_TVAL_S", 15,14,2, 0,0,0, 0, ARM_CP_NO_RAW | ARM_CP_IO, - PL1_RW | PL0_R, ARM_CP_SECSTATE_S, NULL, 0, 0, {0, 0}, - gt_ptimer_access, gt_sec_tval_read, gt_sec_tval_write }, - { "CNTP_TVAL_EL0", 0,14,2, 3,3,0, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW | ARM_CP_IO, PL1_RW | PL0_R, 0, NULL, 0, 0, {0, 0}, - gt_ptimer_access, gt_phys_tval_read, gt_phys_tval_write, NULL, NULL, gt_phys_timer_reset }, - { "CNTV_TVAL", 15,14,3, 0,0,0, 0, - ARM_CP_NO_RAW | ARM_CP_IO, PL1_RW | PL0_R, 0, NULL, 0, 0, {0, 0}, - gt_vtimer_access, gt_virt_tval_read, gt_virt_tval_write, }, - { "CNTV_TVAL_EL0", 0,14,3, 3,3,0, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW | ARM_CP_IO, PL1_RW | PL0_R, 0, NULL, 0, 0, {0, 0}, - gt_vtimer_access, gt_virt_tval_read, gt_virt_tval_write, NULL, NULL, gt_virt_timer_reset }, + { .name = "CNTP_TVAL", .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 0, + .secure = ARM_CP_SECSTATE_NS, + .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW | PL0_R, + .accessfn = gt_ptimer_access, + .readfn = gt_phys_tval_read, .writefn = gt_phys_tval_write, + }, + { .name = "CNTP_TVAL_S", + .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 0, + .secure = ARM_CP_SECSTATE_S, + .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW | PL0_R, + .accessfn = gt_ptimer_access, + .readfn = gt_sec_tval_read, .writefn = gt_sec_tval_write, + }, + { .name = "CNTP_TVAL_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 0, + .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW | PL0_R, + .accessfn = gt_ptimer_access, .resetfn = gt_phys_timer_reset, + .readfn = gt_phys_tval_read, .writefn = gt_phys_tval_write, + }, + { .name = "CNTV_TVAL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 0, + .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW | PL0_R, + .accessfn = gt_vtimer_access, + .readfn = gt_virt_tval_read, .writefn = gt_virt_tval_write, + }, + { .name = "CNTV_TVAL_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 0, + .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW | PL0_R, + .accessfn = gt_vtimer_access, .resetfn = gt_virt_timer_reset, + .readfn = gt_virt_tval_read, .writefn = gt_virt_tval_write, + }, /* The counter itself */ - { "CNTPCT", 15,0,14, 0,0, 0, 0, - ARM_CP_64BIT | ARM_CP_NO_RAW | ARM_CP_IO, PL0_R, 0, NULL, 0, 0, {0, 0}, - gt_pct_access, gt_cnt_read,NULL, NULL,NULL, arm_cp_reset_ignore, }, - { "CNTPCT_EL0", 0,14,0, 3,3,1, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW | ARM_CP_IO, PL0_R, 0, NULL, 0, 0, {0, 0}, - gt_pct_access, gt_cnt_read, NULL, NULL, NULL, NULL }, - { "CNTVCT", 15,0,14, 0,1,0, 0, - ARM_CP_64BIT | ARM_CP_NO_RAW | ARM_CP_IO, PL0_R, 0, NULL, 0, 0, {0, 0}, - gt_vct_access, gt_virt_cnt_read, NULL, NULL, NULL, arm_cp_reset_ignore, }, - { "CNTVCT_EL0", 0,14,0, 3,3,2, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW | ARM_CP_IO, PL0_R, 0, NULL, 0, 0, {0, 0}, - gt_vct_access, gt_virt_cnt_read, NULL, NULL, NULL, NULL }, + { .name = "CNTPCT", .cp = 15, .crm = 14, .opc1 = 0, + .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_RAW | ARM_CP_IO, + .accessfn = gt_pct_access, + .readfn = gt_cnt_read, .resetfn = arm_cp_reset_ignore, + }, + { .name = "CNTPCT_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 1, + .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO, + .accessfn = gt_pct_access, .readfn = gt_cnt_read, + }, + { .name = "CNTVCT", .cp = 15, .crm = 14, .opc1 = 1, + .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_RAW | ARM_CP_IO, + .accessfn = gt_vct_access, + .readfn = gt_virt_cnt_read, .resetfn = arm_cp_reset_ignore, + }, + { .name = "CNTVCT_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 2, + .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO, + .accessfn = gt_vct_access, .readfn = gt_virt_cnt_read, + }, /* Comparison value, indicating when the timer goes off */ - { "CNTP_CVAL", 15, 0,14, 0,2, 0, 0, - ARM_CP_64BIT | ARM_CP_IO | ARM_CP_ALIAS, PL1_RW | PL0_R, ARM_CP_SECSTATE_NS, NULL, 0, offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval), {0, 0}, - gt_ptimer_access, NULL, gt_phys_cval_write, NULL, raw_write, NULL }, - { "CNTP_CVAL_S", 15,0,14, 0,2,0, 0, ARM_CP_64BIT | ARM_CP_IO | ARM_CP_ALIAS, - PL1_RW | PL0_R, ARM_CP_SECSTATE_S, NULL, 0, offsetof(CPUARMState, cp15.c14_timer[GTIMER_SEC].cval), {0, 0}, - gt_ptimer_access, NULL, gt_sec_cval_write, NULL, raw_write }, - { "CNTP_CVAL_EL0", 0,14,2, 3,3,2, ARM_CP_STATE_AA64, - ARM_CP_IO, PL1_RW | PL0_R, 0, NULL, 0, offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval), {0, 0}, - gt_ptimer_access, NULL, gt_phys_cval_write, NULL, raw_write, }, - { "CNTV_CVAL", 15, 0,14, 0,3,0, 0, - ARM_CP_64BIT | ARM_CP_IO | ARM_CP_ALIAS, PL1_RW | PL0_R, 0, NULL, 0, offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval), {0, 0}, - gt_vtimer_access, NULL, gt_virt_cval_write, NULL, raw_write, NULL }, - { "CNTV_CVAL_EL0", 0,14,3, 3,3,2, ARM_CP_STATE_AA64, - ARM_CP_IO, PL1_RW | PL0_R, 0, NULL, 0, offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval), {0, 0}, - gt_vtimer_access, NULL, gt_virt_cval_write, NULL, raw_write, }, + { .name = "CNTP_CVAL", .cp = 15, .crm = 14, .opc1 = 2, + .secure = ARM_CP_SECSTATE_NS, + .access = PL1_RW | PL0_R, + .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval), + .accessfn = gt_ptimer_access, + .writefn = gt_phys_cval_write, .raw_writefn = raw_write, + }, + { .name = "CNTP_CVAL_S", .cp = 15, .crm = 14, .opc1 = 2, + .secure = ARM_CP_SECSTATE_S, + .access = PL1_RW | PL0_R, + .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_SEC].cval), + .accessfn = gt_ptimer_access, + .writefn = gt_sec_cval_write, .raw_writefn = raw_write, + }, + { .name = "CNTP_CVAL_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 2, + .access = PL1_RW | PL0_R, + .type = ARM_CP_IO, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval), + .resetvalue = 0, .accessfn = gt_ptimer_access, + .writefn = gt_phys_cval_write, .raw_writefn = raw_write, + }, + { .name = "CNTV_CVAL", .cp = 15, .crm = 14, .opc1 = 3, + .access = PL1_RW | PL0_R, + .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval), + .accessfn = gt_vtimer_access, + .writefn = gt_virt_cval_write, .raw_writefn = raw_write, + }, + { .name = "CNTV_CVAL_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 2, + .access = PL1_RW | PL0_R, + .type = ARM_CP_IO, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval), + .resetvalue = 0, .accessfn = gt_vtimer_access, + .writefn = gt_virt_cval_write, .raw_writefn = raw_write, + }, /* Secure timer -- this is actually restricted to only EL3 * and configurably Secure-EL1 via the accessfn. */ - { "CNTPS_TVAL_EL1", 0,14,2, 3,7,0, ARM_CP_STATE_AA64, ARM_CP_NO_RAW | ARM_CP_IO, - PL1_RW, 0, NULL, 0, 0, {0, 0}, - gt_stimer_access, gt_sec_tval_read, gt_sec_tval_write, - NULL, NULL, gt_sec_timer_reset }, - { "CNTPS_CTL_EL1", 0,14,2, 3,7,1, ARM_CP_STATE_AA64, ARM_CP_IO, - PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c14_timer[GTIMER_SEC].ctl), {0, 0}, - gt_stimer_access, NULL, gt_sec_ctl_write, NULL, raw_write }, - { "CNTPS_CVAL_EL1", 0,14,2, 3,7,2, ARM_CP_STATE_AA64, ARM_CP_IO, - PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c14_timer[GTIMER_SEC].cval), {0, 0}, - gt_stimer_access, NULL, gt_sec_cval_write, NULL, raw_write }, + { .name = "CNTPS_TVAL_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 7, .crn = 14, .crm = 2, .opc2 = 0, + .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW, + .accessfn = gt_stimer_access, + .readfn = gt_sec_tval_read, + .writefn = gt_sec_tval_write, + .resetfn = gt_sec_timer_reset, + }, + { .name = "CNTPS_CTL_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 7, .crn = 14, .crm = 2, .opc2 = 1, + .type = ARM_CP_IO, .access = PL1_RW, + .accessfn = gt_stimer_access, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_SEC].ctl), + .resetvalue = 0, + .writefn = gt_sec_ctl_write, .raw_writefn = raw_write, + }, + { .name = "CNTPS_CVAL_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 7, .crn = 14, .crm = 2, .opc2 = 2, + .type = ARM_CP_IO, .access = PL1_RW, + .accessfn = gt_stimer_access, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_SEC].cval), + .writefn = gt_sec_cval_write, .raw_writefn = raw_write, + }, REGINFO_SENTINEL }; @@ -2469,12 +2662,16 @@ static uint64_t gt_virt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri) } static const ARMCPRegInfo generic_timer_cp_reginfo[] = { - { "CNTFRQ_EL0", 0,14,0, 3,3,0, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL0_R /* no PL1_RW in linux-user */, 0, NULL, NANOSECONDS_PER_SECOND / GTIMER_SCALE, - offsetof(CPUARMState, cp15.c14_cntfrq), + { .name = "CNTFRQ_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 0, + .type = ARM_CP_CONST, .access = PL0_R /* no PL1_RW in linux-user */, + .fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq), + .resetvalue = NANOSECONDS_PER_SECOND / GTIMER_SCALE, }, - { "CNTVCT_EL0", 0,14,0, 3,3,2, ARM_CP_STATE_AA64, ARM_CP_NO_RAW | ARM_CP_IO, - PL0_R, 0, NULL, 0, 0, 0, NULL, gt_virt_cnt_read, + { .name = "CNTVCT_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 2, + .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO, + .readfn = gt_virt_cnt_read, }, REGINFO_SENTINEL }; @@ -2838,53 +3035,77 @@ static const ARMCPRegInfo pmsav7_cp_reginfo[] = { * because the PMSAv7 is also used by M-profile CPUs, which do * not register cpregs but still need the state to be reset. */ - { "DRBAR", 15,6,1, 0,0,0, 0,ARM_CP_NO_RAW, - PL1_RW, 0, NULL, 0, offsetof(CPUARMState, pmsav7.drbar), {0, 0}, - NULL, pmsav7_read, pmsav7_write, NULL, NULL, arm_cp_reset_ignore }, - { "DRSR", 15,6,1, 0,0,2, 0,ARM_CP_NO_RAW, - PL1_RW, 0, NULL, 0, offsetof(CPUARMState, pmsav7.drsr), {0, 0}, - NULL, pmsav7_read, pmsav7_write, NULL, NULL, arm_cp_reset_ignore }, - { "DRACR", 15,6,1, 0,0,4, 0,ARM_CP_NO_RAW, - PL1_RW, 0, NULL, 0, offsetof(CPUARMState, pmsav7.dracr), {0, 0}, - NULL, pmsav7_read, pmsav7_write, NULL, NULL, arm_cp_reset_ignore }, - { "RGNR", 15,6,2, 0,0,0, 0,0, - PL1_RW, 0, NULL, 0, offsetof(CPUARMState, pmsav7.rnr[M_REG_NS]), {0, 0}, - NULL, NULL, pmsav7_rgnr_write, NULL, NULL, arm_cp_reset_ignore }, + { .name = "DRBAR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_NO_RAW, + .fieldoffset = offsetof(CPUARMState, pmsav7.drbar), + .readfn = pmsav7_read, .writefn = pmsav7_write, + .resetfn = arm_cp_reset_ignore }, + { .name = "DRSR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 2, + .access = PL1_RW, .type = ARM_CP_NO_RAW, + .fieldoffset = offsetof(CPUARMState, pmsav7.drsr), + .readfn = pmsav7_read, .writefn = pmsav7_write, + .resetfn = arm_cp_reset_ignore }, + { .name = "DRACR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 4, + .access = PL1_RW, .type = ARM_CP_NO_RAW, + .fieldoffset = offsetof(CPUARMState, pmsav7.dracr), + .readfn = pmsav7_read, .writefn = pmsav7_write, + .resetfn = arm_cp_reset_ignore }, + { .name = "RGNR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 2, .opc2 = 0, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, pmsav7.rnr[M_REG_NS]), + .writefn = pmsav7_rgnr_write, + .resetfn = arm_cp_reset_ignore }, REGINFO_SENTINEL }; static const ARMCPRegInfo pmsav5_cp_reginfo[] = { - { "DATA_AP", 15,5,0, 0,0,0, 0, - ARM_CP_ALIAS, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.pmsav5_data_ap), {0, 0}, - NULL, pmsav5_data_ap_read, pmsav5_data_ap_write, }, - { "INSN_AP", 15,5,0, 0,0,1, 0, - ARM_CP_ALIAS,PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.pmsav5_insn_ap), {0, 0}, - NULL, pmsav5_insn_ap_read, pmsav5_insn_ap_write, }, - { "DATA_EXT_AP", 15,5,0, 0,0,2, 0, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.pmsav5_data_ap), }, - { "INSN_EXT_AP", 15,5,0, 0,0,3, 0, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.pmsav5_insn_ap), }, - { "DCACHE_CFG", 15,2,0, 0,0,0, 0, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c2_data), }, - { "ICACHE_CFG", 15,2,0, 0,0,1, 0, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c2_insn), }, + { .name = "DATA_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_data_ap), + .readfn = pmsav5_data_ap_read, .writefn = pmsav5_data_ap_write, }, + { .name = "INSN_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1, + .access = PL1_RW, .type = ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_insn_ap), + .readfn = pmsav5_insn_ap_read, .writefn = pmsav5_insn_ap_write, }, + { .name = "DATA_EXT_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 2, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_data_ap), + .resetvalue = 0, }, + { .name = "INSN_EXT_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 3, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_insn_ap), + .resetvalue = 0, }, + { .name = "DCACHE_CFG", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.c2_data), .resetvalue = 0, }, + { .name = "ICACHE_CFG", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 1, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.c2_insn), .resetvalue = 0, }, /* Protection region base and size registers */ - { "946_PRBS0", 15,6,0, 0,0,CP_ANY, 0, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c6_region[0]) }, - { "946_PRBS1", 15,6,1, 0,0,CP_ANY, 0, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c6_region[1]) }, - { "946_PRBS2", 15,6,2, 0,0,CP_ANY, 0, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c6_region[2]) }, - { "946_PRBS3", 15,6,3, 0,0,CP_ANY, 0, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c6_region[3]) }, - { "946_PRBS4", 15,6,4, 0,0,CP_ANY, 0, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c6_region[4]) }, - { "946_PRBS5", 15,6,5, 0,0,CP_ANY, 0, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c6_region[5]) }, - { "946_PRBS6", 15,6,6, 0,0,CP_ANY, 0, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c6_region[6]) }, - { "946_PRBS7", 15,6,7, 0,0,CP_ANY, 0, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c6_region[7]) }, + { .name = "946_PRBS0", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, + .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.c6_region[0]) }, + { .name = "946_PRBS1", .cp = 15, .crn = 6, .crm = 1, .opc1 = 0, + .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.c6_region[1]) }, + { .name = "946_PRBS2", .cp = 15, .crn = 6, .crm = 2, .opc1 = 0, + .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.c6_region[2]) }, + { .name = "946_PRBS3", .cp = 15, .crn = 6, .crm = 3, .opc1 = 0, + .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.c6_region[3]) }, + { .name = "946_PRBS4", .cp = 15, .crn = 6, .crm = 4, .opc1 = 0, + .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.c6_region[4]) }, + { .name = "946_PRBS5", .cp = 15, .crn = 6, .crm = 5, .opc1 = 0, + .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.c6_region[5]) }, + { .name = "946_PRBS6", .cp = 15, .crn = 6, .crm = 6, .opc1 = 0, + .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.c6_region[6]) }, + { .name = "946_PRBS7", .cp = 15, .crn = 6, .crm = 7, .opc1 = 0, + .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.c6_region[7]) }, REGINFO_SENTINEL }; @@ -2990,39 +3211,50 @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri, } static const ARMCPRegInfo vmsa_pmsa_cp_reginfo[] = { - { "DFSR", 15,5,0, 0,0,0, 0, - ARM_CP_ALIAS, PL1_RW, 0, NULL, 0, 0, - { offsetoflow32(CPUARMState, cp15.dfsr_s), offsetoflow32(CPUARMState, cp15.dfsr_ns) }, - NULL, NULL, NULL, NULL, NULL, NULL }, - { "IFSR", 15,5,0, 0,0,1, 0, - 0, PL1_RW, 0, NULL, 0, 0, - { offsetoflow32(CPUARMState, cp15.ifsr_s), offsetoflow32(CPUARMState, cp15.ifsr_ns) }}, - { "FAR_EL1", 0,6,0, 3,0,0, ARM_CP_STATE_AA64, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.far_el[1]), }, - { "DFAR", 15,6,0, 0,0,0, 0,0, - PL1_RW, 0, NULL, 0, 0, - { offsetof(CPUARMState, cp15.dfar_s), offsetof(CPUARMState, cp15.dfar_ns) } }, + { .name = "DFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_ALIAS, + .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dfsr_s), + offsetoflow32(CPUARMState, cp15.dfsr_ns) }, }, + { .name = "IFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1, + .access = PL1_RW, .resetvalue = 0, + .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.ifsr_s), + offsetoflow32(CPUARMState, cp15.ifsr_ns) } }, + { .name = "DFAR", .cp = 15, .opc1 = 0, .crn = 6, .crm = 0, .opc2 = 0, + .access = PL1_RW, .resetvalue = 0, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.dfar_s), + offsetof(CPUARMState, cp15.dfar_ns) } }, + { .name = "FAR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[1]), + .resetvalue = 0, }, REGINFO_SENTINEL }; static const ARMCPRegInfo vmsa_cp_reginfo[] = { - { "ESR_EL1", 0,5,2, 3,0,0, ARM_CP_STATE_AA64, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.esr_el[1]), }, - { "TTBR0_EL1", 0,2,0, 3,0,0, ARM_CP_STATE_BOTH, - 0, PL1_RW, 0, NULL, 0, 0, - { offsetof(CPUARMState, cp15.ttbr0_s), offsetof(CPUARMState, cp15.ttbr0_ns) }, - NULL, NULL, vmsa_ttbr_write, }, - { "TTBR1_EL1", 0,2,0, 3,0,1, ARM_CP_STATE_BOTH, - 0, PL1_RW, 0, NULL, 0, 0, - { offsetof(CPUARMState, cp15.ttbr1_s), offsetof(CPUARMState, cp15.ttbr1_ns) }, - NULL, NULL, vmsa_ttbr_write, }, - { "TCR_EL1", 0,2,0, 3,0,2, ARM_CP_STATE_AA64, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.tcr_el[1]), {0, 0}, - NULL, NULL,vmsa_tcr_el1_write, NULL,raw_write, vmsa_ttbcr_reset, }, - { "TTBCR", 15,2,0, 0,0,2, 0, - ARM_CP_ALIAS, PL1_RW, 0, NULL, 0, 0, - { offsetoflow32(CPUARMState, cp15.tcr_el[3]), offsetoflow32(CPUARMState, cp15.tcr_el[1]) }, - NULL, NULL, vmsa_ttbcr_write, NULL, vmsa_ttbcr_raw_write, NULL }, + { .name = "ESR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .crn = 5, .crm = 2, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.esr_el[1]), .resetvalue = 0, }, + { .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 0, + .access = PL1_RW, .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, .writefn = vmsa_ttbr_write, .resetvalue = 0, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s), + offsetof(CPUARMState, cp15.ttbr1_ns) } }, + { .name = "TCR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2, + .access = PL1_RW, .writefn = vmsa_tcr_el1_write, + .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write, + .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[1]) }, + { .name = "TTBCR", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2, + .access = PL1_RW, .type = ARM_CP_ALIAS, .writefn = vmsa_ttbcr_write, + .raw_writefn = vmsa_ttbcr_raw_write, + .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tcr_el[3]), + offsetoflow32(CPUARMState, cp15.tcr_el[1])} }, REGINFO_SENTINEL }; @@ -3069,33 +3301,42 @@ static void omap_cachemaint_write(CPUARMState *env, const ARMCPRegInfo *ri, } static const ARMCPRegInfo omap_cp_reginfo[] = { - { "DFSR", 15,5,CP_ANY, 0,CP_ANY,CP_ANY, 0, - ARM_CP_OVERRIDE, PL1_RW, 0, NULL, 0, offsetoflow32(CPUARMState, cp15.esr_el[1]), }, - { "", 15,15,0, 0,0,0, 0, - ARM_CP_NOP, PL1_RW, 0, NULL, 0, 0, }, - { "TICONFIG", 15,15,1, 0,0,0, 0, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c15_ticonfig), {0, 0}, - NULL, NULL, omap_ticonfig_write }, - { "IMAX", 15,15,2, 0,0,0, 0, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c15_i_max), }, - { "IMIN", 15,15,3, 0,0,0, 0, - 0, PL1_RW, 0, NULL, 0xff0, offsetof(CPUARMState, cp15.c15_i_min) }, - { "THREADID", 15,15,4, 0,0,0, 0, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c15_threadid), {0, 0}, - NULL, NULL, omap_threadid_write }, - { "TI925T_STATUS", 15,15,8, 0,0,0, 0, - ARM_CP_NO_RAW, PL1_RW, 0, NULL, 0, 0, {0, 0}, - NULL, arm_cp_read_zero, omap_wfi_write, }, + { .name = "DFSR", .cp = 15, .crn = 5, .crm = CP_ANY, + .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_OVERRIDE, + .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el[1]), + .resetvalue = 0, }, + { .name = "", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_NOP }, + { .name = "TICONFIG", .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.c15_ticonfig), .resetvalue = 0, + .writefn = omap_ticonfig_write }, + { .name = "IMAX", .cp = 15, .crn = 15, .crm = 2, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.c15_i_max), .resetvalue = 0, }, + { .name = "IMIN", .cp = 15, .crn = 15, .crm = 3, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, .resetvalue = 0xff0, + .fieldoffset = offsetof(CPUARMState, cp15.c15_i_min) }, + { .name = "THREADID", .cp = 15, .crn = 15, .crm = 4, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.c15_threadid), .resetvalue = 0, + .writefn = omap_threadid_write }, + { .name = "TI925T_STATUS", .cp = 15, .crn = 15, + .crm = 8, .opc1 = 0, .opc2 = 0, .access = PL1_RW, + .type = ARM_CP_NO_RAW, + .readfn = arm_cp_read_zero, .writefn = omap_wfi_write, }, /* TODO: Peripheral port remap register: * On OMAP2 mcr p15, 0, rn, c15, c2, 4 sets up the interrupt controller * base address at $rn & ~0xfff and map size of 0x200 << ($rn & 0xfff), * when MMU is off. */ - { "OMAP_CACHEMAINT", 15,7,CP_ANY, 0,0,CP_ANY, 0, - ARM_CP_OVERRIDE | ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, omap_cachemaint_write }, - { "C9", 15,9,CP_ANY, 0,CP_ANY,CP_ANY, 0, - ARM_CP_CONST | ARM_CP_OVERRIDE, PL1_RW, 0, NULL, 0, 0, }, + { .name = "OMAP_CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY, + .opc1 = 0, .opc2 = CP_ANY, .access = PL1_W, + .type = ARM_CP_OVERRIDE | ARM_CP_NO_RAW, + .writefn = omap_cachemaint_write }, + { .name = "C9", .cp = 15, .crn = 9, + .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, + .type = ARM_CP_CONST | ARM_CP_OVERRIDE, .resetvalue = 0 }, REGINFO_SENTINEL }; @@ -3106,22 +3347,29 @@ static void xscale_cpar_write(CPUARMState *env, const ARMCPRegInfo *ri, } static const ARMCPRegInfo xscale_cp_reginfo[] = { - { "XSCALE_CPAR", 15,15,1, 0,0,0, 0, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c15_cpar), {0, 0}, - NULL, NULL, xscale_cpar_write, }, - { "XSCALE_AUXCR", 15,1,0, 0,0,1, 0, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c1_xscaleauxcr), }, + { .name = "XSCALE_CPAR", + .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0, .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.c15_cpar), .resetvalue = 0, + .writefn = xscale_cpar_write, }, + { .name = "XSCALE_AUXCR", + .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 1, .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.c1_xscaleauxcr), + .resetvalue = 0, }, /* XScale specific cache-lockdown: since we have no cache we NOP these * and hope the guest does not really rely on cache behaviour. */ - { "XSCALE_LOCK_ICACHE_LINE", 15,9,1, 0,0,0, 0, - ARM_CP_NOP, PL1_W }, - { "XSCALE_UNLOCK_ICACHE", 15,9,1, 0,0,1, 0, - ARM_CP_NOP, PL1_W, }, - { "XSCALE_DCACHE_LOCK", 15,9,2, 0,0,0, 0, - ARM_CP_NOP, PL1_RW }, - { "XSCALE_UNLOCK_DCACHE", 15,9,2, 0,0,1, 0, - ARM_CP_NOP, PL1_W, }, + { .name = "XSCALE_LOCK_ICACHE_LINE", + .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0, + .access = PL1_W, .type = ARM_CP_NOP }, + { .name = "XSCALE_UNLOCK_ICACHE", + .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1, + .access = PL1_W, .type = ARM_CP_NOP }, + { .name = "XSCALE_DCACHE_LOCK", + .cp = 15, .opc1 = 0, .crn = 9, .crm = 2, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_NOP }, + { .name = "XSCALE_UNLOCK_DCACHE", + .cp = 15, .opc1 = 0, .crn = 9, .crm = 2, .opc2 = 1, + .access = PL1_W, .type = ARM_CP_NOP }, REGINFO_SENTINEL }; @@ -3131,35 +3379,40 @@ static const ARMCPRegInfo dummy_c15_cp_reginfo[] = { * Ideally this should eventually disappear in favour of actually * implementing the correct behaviour for all cores. */ - { "C15_IMPDEF", 15,15,CP_ANY, 0,CP_ANY,CP_ANY, 0, - ARM_CP_CONST | ARM_CP_NO_RAW | ARM_CP_OVERRIDE, PL1_RW, 0, NULL, 0 }, + { .name = "C15_IMPDEF", .cp = 15, .crn = 15, + .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, + .access = PL1_RW, + .type = ARM_CP_CONST | ARM_CP_NO_RAW | ARM_CP_OVERRIDE, + .resetvalue = 0 }, REGINFO_SENTINEL }; static const ARMCPRegInfo cache_dirty_status_cp_reginfo[] = { /* Cache status: RAZ because we have no cache so it's always clean */ - { "CDSR", 15,7,10, 0,0,6, 0, - ARM_CP_CONST | ARM_CP_NO_RAW, PL1_R, 0, NULL, 0 }, + { .name = "CDSR", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 6, + .access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW, + .resetvalue = 0 }, REGINFO_SENTINEL }; static const ARMCPRegInfo cache_block_ops_cp_reginfo[] = { /* We never have a a block transfer operation in progress */ - { "BXSR", 15,7,12, 0,0,4, 0, - ARM_CP_CONST | ARM_CP_NO_RAW, PL0_R, 0, NULL, 0 }, + { .name = "BXSR", .cp = 15, .crn = 7, .crm = 12, .opc1 = 0, .opc2 = 4, + .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW, + .resetvalue = 0 }, /* The cache ops themselves: these all NOP for QEMU */ - { "IICR", 15, 0,5, 0,0, 0, 0, - ARM_CP_NOP|ARM_CP_64BIT, PL1_W }, - { "IDCR", 15, 0,6, 0,0, 0, 0, - ARM_CP_NOP|ARM_CP_64BIT, PL1_W, }, - { "CDCR", 15, 0,12, 0,0, 0, 0, - ARM_CP_NOP|ARM_CP_64BIT, PL0_W, }, - { "PIR", 15, 0,12, 0,1, 0, 0, - ARM_CP_NOP|ARM_CP_64BIT, PL0_W, }, - { "PDR", 15, 0,12, 0,2, 0, 0, - ARM_CP_NOP|ARM_CP_64BIT, PL0_W, }, - { "CIDCR", 15, 0,14, 0,0, 0, 0, - ARM_CP_NOP|ARM_CP_64BIT, PL1_W, }, + { .name = "IICR", .cp = 15, .crm = 5, .opc1 = 0, + .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT }, + { .name = "IDCR", .cp = 15, .crm = 6, .opc1 = 0, + .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT }, + { .name = "CDCR", .cp = 15, .crm = 12, .opc1 = 0, + .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT }, + { .name = "PIR", .cp = 15, .crm = 12, .opc1 = 1, + .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT }, + { .name = "PDR", .cp = 15, .crm = 12, .opc1 = 2, + .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT }, + { .name = "CIDCR", .cp = 15, .crm = 14, .opc1 = 0, + .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT }, REGINFO_SENTINEL }; @@ -3167,17 +3420,21 @@ static const ARMCPRegInfo cache_test_clean_cp_reginfo[] = { /* The cache test-and-clean instructions always return (1 << 30) * to indicate that there are no dirty cache lines. */ - { "TC_DCACHE", 15,7,10, 0,0,3, 0, - ARM_CP_CONST | ARM_CP_NO_RAW, PL0_R, 0, NULL, (1 << 30) }, - { "TCI_DCACHE", 15,7,14, 0,0,3, 0, - ARM_CP_CONST | ARM_CP_NO_RAW, PL0_R, 0, NULL, (1 << 30) }, + { .name = "TC_DCACHE", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 3, + .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW, + .resetvalue = (1 << 30) }, + { .name = "TCI_DCACHE", .cp = 15, .crn = 7, .crm = 14, .opc1 = 0, .opc2 = 3, + .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW, + .resetvalue = (1 << 30) }, REGINFO_SENTINEL }; static const ARMCPRegInfo strongarm_cp_reginfo[] = { /* Ignore ReadBuffer accesses */ - { "C9_READBUFFER", 15,9,CP_ANY, 0,CP_ANY,CP_ANY, 0, - ARM_CP_CONST | ARM_CP_OVERRIDE | ARM_CP_NO_RAW, PL1_RW, 0, NULL, 0, }, + { .name = "C9_READBUFFER", .cp = 15, .crn = 9, + .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, + .access = PL1_RW, .resetvalue = 0, + .type = ARM_CP_CONST | ARM_CP_OVERRIDE | ARM_CP_NO_RAW }, REGINFO_SENTINEL }; @@ -3224,22 +3481,28 @@ static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri) static const ARMCPRegInfo lpae_cp_reginfo[] = { /* NOP AMAIR0/1 */ - { "AMAIR0", 0,10,3, 3,0,0, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL1_RW, 0, NULL, 0 }, + { .name = "AMAIR0", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, /* AMAIR1 is mapped to AMAIR_EL1[63:32] */ - { "AMAIR1", 15,10,3, 0,0,1, 0, - ARM_CP_CONST, PL1_RW, 0, NULL, 0 }, - { "PAR", 15, 0,7, 0,0, 0, 0, - ARM_CP_64BIT, PL1_RW, 0, NULL, 0, 0, - { offsetof(CPUARMState, cp15.par_s), offsetof(CPUARMState, cp15.par_ns) } }, - { "TTBR0", 15, 0,2, 0,0, 0, 0, - ARM_CP_64BIT | ARM_CP_ALIAS, PL1_RW, 0, NULL, 0, 0, - { offsetof(CPUARMState, cp15.ttbr0_s), offsetof(CPUARMState, cp15.ttbr0_ns) }, - NULL, NULL, vmsa_ttbr_write, NULL, NULL, NULL }, - { "TTBR1", 15, 0,2, 0,1, 0, 0, - ARM_CP_64BIT | ARM_CP_ALIAS, PL1_RW, 0, NULL, 0, 0, - { offsetof(CPUARMState, cp15.ttbr1_s), offsetof(CPUARMState, cp15.ttbr1_ns) }, - NULL, NULL, vmsa_ttbr_write, NULL, NULL, NULL }, + { .name = "AMAIR1", .cp = 15, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 1, + .access = PL1_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "PAR", .cp = 15, .crm = 7, .opc1 = 0, + .access = PL1_RW, .type = ARM_CP_64BIT, .resetvalue = 0, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.par_s), + offsetof(CPUARMState, cp15.par_ns)} }, + { .name = "TTBR0", .cp = 15, .crm = 2, .opc1 = 0, + .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s), + offsetof(CPUARMState, cp15.ttbr0_ns) }, + .writefn = vmsa_ttbr_write, }, + { .name = "TTBR1", .cp = 15, .crm = 2, .opc1 = 1, + .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s), + offsetof(CPUARMState, cp15.ttbr1_ns) }, + .writefn = vmsa_ttbr_write, }, REGINFO_SENTINEL }; @@ -3671,337 +3934,454 @@ static const ARMCPRegInfo v8_cp_reginfo[] = { /* Minimal set of EL0-visible registers. This will need to be expanded * significantly for system emulation of AArch64 CPUs. */ - { "NZCV", 0,4,2, 3,3,0, ARM_CP_STATE_AA64, - ARM_CP_NZCV, PL0_RW, }, - { "DAIF", 0,4,2, 3,3,1, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW, PL0_RW, 0, NULL, 0, offsetof(CPUARMState, daif), {0, 0}, - aa64_daif_access, NULL, aa64_daif_write, NULL,NULL, arm_cp_reset_ignore }, - { "FPCR", 0,4,4, 3,3,0, ARM_CP_STATE_AA64, ARM_CP_FPU | ARM_CP_SUPPRESS_TB_END, - PL0_RW, 0, NULL, 0, 0, {0, 0}, - NULL, aa64_fpcr_read, aa64_fpcr_write }, - { "FPSR", 0,4,4, 3,3,1, ARM_CP_STATE_AA64, ARM_CP_FPU | ARM_CP_SUPPRESS_TB_END, - PL0_RW, 0, NULL, 0, 0, {0, 0}, - NULL, aa64_fpsr_read, aa64_fpsr_write }, - { "DCZID_EL0", 0,0,0, 3,3,7, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW, PL0_R, 0, NULL, 0, 0, {0, 0}, - NULL, aa64_dczid_read }, - { "DC_ZVA", 0,7,4, 1,3,1, ARM_CP_STATE_AA64, - ARM_CP_DC_ZVA, PL0_W, 0, NULL, 0, 0, {0, 0}, + { .name = "NZCV", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 2, + .access = PL0_RW, .type = ARM_CP_NZCV }, + { .name = "DAIF", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 2, + .type = ARM_CP_NO_RAW, + .access = PL0_RW, .accessfn = aa64_daif_access, + .fieldoffset = offsetof(CPUARMState, daif), + .writefn = aa64_daif_write, .resetfn = arm_cp_reset_ignore }, + { .name = "FPCR", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 4, + .access = PL0_RW, .type = ARM_CP_FPU | ARM_CP_SUPPRESS_TB_END, + .readfn = aa64_fpcr_read, .writefn = aa64_fpcr_write }, + { .name = "FPSR", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 4, + .access = PL0_RW, .type = ARM_CP_FPU | ARM_CP_SUPPRESS_TB_END, + .readfn = aa64_fpsr_read, .writefn = aa64_fpsr_write }, + { .name = "DCZID_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .opc2 = 7, .crn = 0, .crm = 0, + .access = PL0_R, .type = ARM_CP_NO_RAW, + .readfn = aa64_dczid_read }, + { .name = "DC_ZVA", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 4, .opc2 = 1, + .access = PL0_W, .type = ARM_CP_DC_ZVA, #ifndef CONFIG_USER_ONLY /* Avoid overhead of an access check that always passes in user-mode */ - aa64_zva_access, + .accessfn = aa64_zva_access, #endif }, - { "CURRENTEL", 0,4,2, 3,0,2, ARM_CP_STATE_AA64, - ARM_CP_CURRENTEL, PL1_R, }, + { .name = "CURRENTEL", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .opc2 = 2, .crn = 4, .crm = 2, + .access = PL1_R, .type = ARM_CP_CURRENTEL }, /* Cache ops: all NOPs since we don't emulate caches */ - { "IC_IALLUIS", 0,7,1, 1,0,0, ARM_CP_STATE_AA64, - ARM_CP_NOP, PL1_W, }, - { "IC_IALLU", 0,7,5, 1,0,0, ARM_CP_STATE_AA64, - ARM_CP_NOP, PL1_W, }, - { "IC_IVAU", 0,7,5, 1,3,1, ARM_CP_STATE_AA64, - ARM_CP_NOP, PL0_W, 0, NULL, 0, 0, {0, 0}, - aa64_cacheop_access }, - { "DC_IVAC", 0,7,6, 1,0,1, ARM_CP_STATE_AA64, - ARM_CP_NOP, PL1_W, }, - { "DC_ISW", 0,7,6, 1,0,2, ARM_CP_STATE_AA64, - ARM_CP_NOP, PL1_W, }, - { "DC_CVAC", 0,7,10, 1,3,1, ARM_CP_STATE_AA64, - ARM_CP_NOP, PL0_W, 0, NULL, 0, 0, {0, 0}, - aa64_cacheop_access }, - { "DC_CSW", 0,7,10, 1,0,2, ARM_CP_STATE_AA64, - ARM_CP_NOP, PL1_W, }, - { "DC_CVAU", 0,7,11, 1,3,1, ARM_CP_STATE_AA64, - ARM_CP_NOP, PL0_W, 0, NULL, 0, 0, {0, 0}, - aa64_cacheop_access }, - { "DC_CIVAC", 0,7,14, 1,3,1, ARM_CP_STATE_AA64, - ARM_CP_NOP, PL0_W, 0, NULL, 0, 0, {0, 0}, - aa64_cacheop_access }, - { "DC_CISW", 0,7,14, 1,0,2, ARM_CP_STATE_AA64, - ARM_CP_NOP, PL1_W, }, + { .name = "IC_IALLUIS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0, + .access = PL1_W, .type = ARM_CP_NOP }, + { .name = "IC_IALLU", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 0, + .access = PL1_W, .type = ARM_CP_NOP }, + { .name = "IC_IVAU", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 5, .opc2 = 1, + .access = PL0_W, .type = ARM_CP_NOP, + .accessfn = aa64_cacheop_access }, + { .name = "DC_IVAC", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1, + .access = PL1_W, .type = ARM_CP_NOP }, + { .name = "DC_ISW", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2, + .access = PL1_W, .type = ARM_CP_NOP }, + { .name = "DC_CVAC", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 1, + .access = PL0_W, .type = ARM_CP_NOP, + .accessfn = aa64_cacheop_access }, + { .name = "DC_CSW", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2, + .access = PL1_W, .type = ARM_CP_NOP }, + { .name = "DC_CVAU", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 11, .opc2 = 1, + .access = PL0_W, .type = ARM_CP_NOP, + .accessfn = aa64_cacheop_access }, + { .name = "DC_CIVAC", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 1, + .access = PL0_W, .type = ARM_CP_NOP, + .accessfn = aa64_cacheop_access }, + { .name = "DC_CISW", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2, + .access = PL1_W, .type = ARM_CP_NOP }, /* TLBI operations */ - { "TLBI_VMALLE1IS", 0,8,3, 1,0,0, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_vmalle1is_write }, - { "TLBI_VAE1IS", 0,8,3, 1,0,1, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_vae1is_write }, - { "TLBI_ASIDE1IS", 0,8,3, 1,0,2, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_vmalle1is_write }, - { "TLBI_VAAE1IS", 0,8,3, 1,0,3, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_vae1is_write }, - { "TLBI_VALE1IS", 0,8,3, 1,0,5, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_vae1is_write }, - { "TLBI_VAALE1IS", 0,8,3, 1,0,7, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_vae1is_write }, - { "TLBI_VMALLE1", 0,8,7, 1,0,0, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_vmalle1_write }, - { "TLBI_VAE1", 0,8,7, 1,0,1, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_vae1_write }, - { "TLBI_ASIDE1", 0,8,7, 1,0,2, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_vmalle1_write }, - { "TLBI_VAAE1", 0,8,7, 1,0,3, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_vae1_write }, - { "TLBI_VALE1", 0,8,7, 1,0,5, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_vae1_write }, - { "TLBI_VAALE1", 0,8,7, 1,0,7, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_vae1_write }, - { "TLBI_VMALLS12E1IS", 0,8,3, 1,4,6, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_alle1is_write }, - { "TLBI_IPAS2E1IS", 0,8,0, 1,4,1, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_ipas2e1is_write }, - { "TLBI_IPAS2LE1IS", 0,8,0, 1,4,5, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_ipas2e1is_write }, - { "TLBI_ALLE1IS", 0,8,3, 1,4,4, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_alle1is_write }, - { "TLBI_IPAS2E1", 0,8,4, 1,4,1, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_ipas2e1_write }, - { "TLBI_IPAS2LE1", 0,8,4, 1,4,5, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_ipas2e1_write }, - { "TLBI_ALLE1", 0,8,7, 1,4,4, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_alle1_write }, - { "TLBI_VMALLS12E1", 0,8,7, 1,4,6, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_alle1is_write }, + { .name = "TLBI_VMALLE1IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vmalle1is_write }, + { .name = "TLBI_VAE1IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae1is_write }, + { .name = "TLBI_ASIDE1IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vmalle1is_write }, + { .name = "TLBI_VAAE1IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae1is_write }, + { .name = "TLBI_VALE1IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae1is_write }, + { .name = "TLBI_VAALE1IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae1is_write }, + { .name = "TLBI_VMALLE1", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vmalle1_write }, + { .name = "TLBI_VAE1", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae1_write }, + { .name = "TLBI_ASIDE1", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vmalle1_write }, + { .name = "TLBI_VAAE1", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae1_write }, + { .name = "TLBI_VALE1", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae1_write }, + { .name = "TLBI_VAALE1", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae1_write }, + { .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_ipas2e1is_write }, + { .name = "TLBI_IPAS2LE1IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_ipas2e1is_write }, + { .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_alle1is_write }, + { .name = "TLBI_VMALLS12E1IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 6, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_alle1is_write }, + { .name = "TLBI_IPAS2E1", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_ipas2e1_write }, + { .name = "TLBI_IPAS2LE1", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_ipas2e1_write }, + { .name = "TLBI_ALLE1", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_alle1_write }, + { .name = "TLBI_VMALLS12E1", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 6, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_alle1is_write }, #ifndef CONFIG_USER_ONLY /* 64 bit address translation operations */ - { "AT_S1E1R", 0,7,8, 1,0,0, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, ats_write64 }, - { "AT_S1E1W", 0,7,8, 1,0,1, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, ats_write64 }, - { "AT_S1E0R", 0,7,8, 1,0,2, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, ats_write64 }, - { "AT_S1E0W", 0,7,8, 1,0,3, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, ats_write64 }, - { "AT_S12E1R", 0,7,8, 1,4,4, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, ats_write64 }, - { "AT_S12E1W", 0,7,8, 1,4,5, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, ats_write64 }, - { "AT_S12E0R", 0,7,8, 1,4,6, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, ats_write64 }, - { "AT_S12E0W", 0,7,8, 1,4,7, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, ats_write64 }, + { .name = "AT_S1E1R", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 0, + .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + { .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 1, + .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + { .name = "AT_S1E0R", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 2, + .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + { .name = "AT_S1E0W", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 3, + .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + { .name = "AT_S12E1R", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 4, + .access = PL2_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + { .name = "AT_S12E1W", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 5, + .access = PL2_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + { .name = "AT_S12E0R", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 6, + .access = PL2_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + { .name = "AT_S12E0W", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 7, + .access = PL2_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, /* AT S1E2* are elsewhere as they UNDEF from EL3 if EL2 is not present */ - { "AT_S1E3R", 0,7,8, 1,6,0, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL3_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, ats_write64 }, - { "AT_S1E3W", 0,7,8, 1,6,1, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL3_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, ats_write64 }, - { "PAR_EL1", 0,7,4, 3,0,0, ARM_CP_STATE_AA64, ARM_CP_ALIAS, - PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.par_el[1]), {0, 0}, - NULL, NULL, par_write }, + { .name = "AT_S1E3R", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 8, .opc2 = 0, + .access = PL3_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + { .name = "AT_S1E3W", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 8, .opc2 = 1, + .access = PL3_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + { .name = "PAR_EL1", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 0, .crn = 7, .crm = 4, .opc2 = 0, + .access = PL1_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.par_el[1]), + .writefn = par_write }, #endif /* TLB invalidate last level of translation table walk */ - { "TLBIMVALIS", 15,8,3, 0,0,5, 0, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbimva_is_write }, - { "TLBIMVAALIS", 15,8,3, 0,0,7, 0, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbimvaa_is_write }, - { "TLBIMVAL", 15,8,7, 0,0,5, 0, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbimva_write }, - { "TLBIMVAAL", 15,8,7, 0,0,7, 0, - ARM_CP_NO_RAW, PL1_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbimvaa_write }, - { "TLBIMVALH", 15,8,7, 0,4,5, 0, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbimva_hyp_write }, - { "TLBIMVALHIS", 15,8,3, 0,4,5, 0, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbimva_hyp_is_write }, - { "TLBIIPAS2", 15,8,4, 0,4,1, 0, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbiipas2_write }, - { "TLBIIPAS2IS", 15,8,0, 0,4,1, 0, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbiipas2_is_write }, - { "TLBIIPAS2L", 15,8,4, 0,4,5, 0, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbiipas2_write }, - { "TLBIIPAS2LIS", 15,8,0, 0,4,5, 0, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbiipas2_is_write }, + { .name = "TLBIMVALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_is_write }, + { .name = "TLBIMVAALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7, + .type = ARM_CP_NO_RAW, .access = PL1_W, + .writefn = tlbimvaa_is_write }, + { .name = "TLBIMVAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write }, + { .name = "TLBIMVAAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write }, + { .name = "TLBIMVALH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbimva_hyp_write }, + { .name = "TLBIMVALHIS", + .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 5, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbimva_hyp_is_write }, + { .name = "TLBIIPAS2", + .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbiipas2_write }, + { .name = "TLBIIPAS2IS", + .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbiipas2_is_write }, + { .name = "TLBIIPAS2L", + .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbiipas2_write }, + { .name = "TLBIIPAS2LIS", + .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbiipas2_is_write }, /* 32 bit cache operations */ - { "ICIALLUIS", 15,7,1, 0,0,0, 0, - ARM_CP_NOP, PL1_W }, - { "BPIALLUIS", 15,7,1, 0,0,6, 0, - ARM_CP_NOP, PL1_W }, - { "ICIALLU", 15,7,5, 0,0,0, 0, - ARM_CP_NOP, PL1_W }, - { "ICIMVAU", 15,7,5, 0,0,1, 0, - ARM_CP_NOP, PL1_W }, - { "BPIALL", 15,7,5, 0,0,6, 0, - ARM_CP_NOP, PL1_W }, - { "BPIMVA", 15,7,5, 0,0,7, 0, - ARM_CP_NOP, PL1_W }, - { "DCIMVAC", 15,7,6, 0,0,1, 0, - ARM_CP_NOP, PL1_W }, - { "DCISW", 15,7,6, 0,0,2, 0, - ARM_CP_NOP, PL1_W }, - { "DCCMVAC", 15,7,10, 0,0,1, 0, - ARM_CP_NOP, PL1_W }, - { "DCCSW", 15,7,10, 0,0,2, 0, - ARM_CP_NOP, PL1_W }, - { "DCCMVAU", 15,7,11, 0,0,1, 0, - ARM_CP_NOP, PL1_W }, - { "DCCIMVAC", 15,7,14, 0,0,1, 0, - ARM_CP_NOP, PL1_W }, - { "DCCISW", 15,7,14, 0,0,2, 0, - ARM_CP_NOP, PL1_W }, + { .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "BPIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 6, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "ICIALLU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 0, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "ICIMVAU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 1, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "BPIALL", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 6, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "BPIMVA", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 7, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "DCIMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "DCISW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "DCCMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 1, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "DCCSW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "DCCMVAU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 11, .opc2 = 1, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "DCCIMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 1, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "DCCISW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2, + .type = ARM_CP_NOP, .access = PL1_W }, /* MMU Domain access control / MPU write buffer control */ - { "DACR", 15,3,0, 0,0,0, 0, - 0, PL1_RW, 0, NULL, 0, 0, - { offsetoflow32(CPUARMState, cp15.dacr_s), offsetoflow32(CPUARMState, cp15.dacr_ns) }, - NULL, NULL,dacr_write, NULL,raw_write, }, - { "ELR_EL1", 0,4,0, 3,0,1, ARM_CP_STATE_AA64, - ARM_CP_ALIAS, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, elr_el[1]) }, - { "SPSR_EL1", 0,4,0, 3,0,0, ARM_CP_STATE_AA64, - ARM_CP_ALIAS, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, banked_spsr[BANK_SVC]) }, + { .name = "DACR", .cp = 15, .opc1 = 0, .crn = 3, .crm = 0, .opc2 = 0, + .access = PL1_RW, .resetvalue = 0, + .writefn = dacr_write, .raw_writefn = raw_write, + .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s), + offsetoflow32(CPUARMState, cp15.dacr_ns) } }, + { .name = "ELR_EL1", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 1, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, elr_el[1]) }, + { .name = "SPSR_EL1", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 0, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_SVC]) }, /* We rely on the access checks not allowing the guest to write to the * state field when SPSel indicates that it's being used as the stack * pointer. */ - { "SP_EL0", 0,4,1, 3,0,0, ARM_CP_STATE_AA64, - ARM_CP_ALIAS, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, sp_el[0]), {0, 0}, - sp_el0_access, }, - { "SP_EL1", 0,4,1, 3,4,0, ARM_CP_STATE_AA64, ARM_CP_ALIAS, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, sp_el[1]) }, - { "SPSel", 0,4,2, 3,0,0, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW, PL1_RW, 0, NULL, 0, 0, {0, 0}, - NULL, spsel_read, spsel_write }, - { "FPEXC32_EL2", 0,5,3, 3,4,0, ARM_CP_STATE_AA64, ARM_CP_ALIAS, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, vfp.xregs[ARM_VFP_FPEXC]), {0, 0}, - fpexc32_access }, - { "DACR32_EL2", 0,3,0, 3,4,0, ARM_CP_STATE_AA64,0, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.dacr32_el2), {0, 0}, - NULL, NULL, dacr_write, NULL, raw_write }, - { "IFSR32_EL2", 0,5,0, 3,4,1, ARM_CP_STATE_AA64,0, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.ifsr32_el2) }, - { "SPSR_IRQ", 0,4,3, 3,4,0, ARM_CP_STATE_AA64, ARM_CP_ALIAS, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, banked_spsr[BANK_IRQ]) }, - { "SPSR_ABT", 0,4,3, 3,4,1, ARM_CP_STATE_AA64, ARM_CP_ALIAS, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, banked_spsr[BANK_ABT]) }, - { "SPSR_UND", 0,4,3, 3,4,2, ARM_CP_STATE_AA64, ARM_CP_ALIAS, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, banked_spsr[BANK_UND]) }, - { "SPSR_FIQ", 0,4,3, 3,4,3, ARM_CP_STATE_AA64, ARM_CP_ALIAS, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, banked_spsr[BANK_FIQ]) }, - { "MDCR_EL3", 0,1,3, 3,6,1, ARM_CP_STATE_AA64, 0, - PL3_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.mdcr_el3) }, - { "SDCR", 15,1,3, 0,0,1, 0, ARM_CP_ALIAS, - PL1_RW, 0, NULL, 0, offsetoflow32(CPUARMState, cp15.mdcr_el3), {0, 0}, - access_trap_aa32s_el1, NULL, sdcr_write }, + { .name = "SP_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 1, .opc2 = 0, + .access = PL1_RW, .accessfn = sp_el0_access, + .type = ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, sp_el[0]) }, + { .name = "SP_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 1, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, sp_el[1]) }, + { .name = "SPSel", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 0, + .type = ARM_CP_NO_RAW, + .access = PL1_RW, .readfn = spsel_read, .writefn = spsel_write }, + { .name = "FPEXC32_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 3, .opc2 = 0, + .type = ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, vfp.xregs[ARM_VFP_FPEXC]), + .access = PL2_RW, .accessfn = fpexc32_access }, + { .name = "DACR32_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 3, .crm = 0, .opc2 = 0, + .access = PL2_RW, .resetvalue = 0, + .writefn = dacr_write, .raw_writefn = raw_write, + .fieldoffset = offsetof(CPUARMState, cp15.dacr32_el2) }, + { .name = "IFSR32_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 0, .opc2 = 1, + .access = PL2_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.ifsr32_el2) }, + { .name = "SPSR_IRQ", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 0, + .access = PL2_RW, + .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_IRQ]) }, + { .name = "SPSR_ABT", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 1, + .access = PL2_RW, + .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_ABT]) }, + { .name = "SPSR_UND", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 2, + .access = PL2_RW, + .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_UND]) }, + { .name = "SPSR_FIQ", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 3, + .access = PL2_RW, + .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_FIQ]) }, + { .name = "MDCR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 3, .opc2 = 1, + .resetvalue = 0, + .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.mdcr_el3) }, + { .name = "SDCR", .type = ARM_CP_ALIAS, + .cp = 15, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 1, + .access = PL1_RW, .accessfn = access_trap_aa32s_el1, + .writefn = sdcr_write, + .fieldoffset = offsetoflow32(CPUARMState, cp15.mdcr_el3) }, REGINFO_SENTINEL }; /* Used to describe the behaviour of EL2 regs when EL2 does not exist. */ static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = { - { "VBAR_EL2", 0,12,0, 3,4,0, ARM_CP_STATE_BOTH, - 0, PL2_RW, 0, NULL, 0, 0, {0, 0}, - NULL, arm_cp_read_zero, arm_cp_write_ignore }, - { "HCR_EL2", 0,1,1, 3,4,0, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL2_RW, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, NULL }, - { "HACR_EL2", 0,1,1, 3,4,7, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL2_RW, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, NULL }, - { "ESR_EL2", 0,5,2, 3,1,0, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "CPTR_EL2", 0,1,1, 3,4,2, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "MAIR_EL2", 0,10,2, 3,4,0, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "HMAIR1", 15,10,2, 0,4,1, ARM_CP_STATE_AA32, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "AMAIR_EL2", 0,10,3, 3,4,0, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "HAMAIR1", 15,10,3, 0,4,1, ARM_CP_STATE_AA32, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "AFSR0_EL2", 0,5,1, 3,4,0, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "AFSR1_EL2", 0,5,1, 3,4,1, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "TCR_EL2", 0,2,0, 3,4,2, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "VTCR_EL2", 0,2,1, 3,4,2, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL2_RW, 0, NULL, 0, 0, {0, 0}, - access_el3_aa32ns_aa64any }, - { "VTTBR", 15,0,2, 0,6,0, ARM_CP_STATE_AA32, ARM_CP_CONST | ARM_CP_64BIT, - PL2_RW, 0, NULL, 0, 0, {0, 0}, - access_el3_aa32ns }, - { "VTTBR_EL2", 0,2,1, 3,4,0, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "SCTLR_EL2", 0,1,0, 3,4,0, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "TPIDR_EL2", 0,13,0, 3,4,2, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "TTBR0_EL2", 0,2,0, 3,4,0, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "HTTBR", 15,0,2, 0,4,0, 0, ARM_CP_64BIT | ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "CNTHCTL_EL2", 0,14,1, 3,4,0, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "CNTVOFF_EL2", 0,14,0, 3,4,3, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "CNTVOFF", 15,0,14, 0,4,0, ARM_CP_64BIT | ARM_CP_CONST, 0, - PL2_RW, 0, NULL, 0 }, - { "CNTHP_CVAL_EL2", 0,14,2, 3,4,2, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "CNTHP_CVAL", 15,0,14, 0,6,0, 0, ARM_CP_64BIT | ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "CNTHP_TVAL_EL2", 0,14,2, 3,4,0, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "CNTHP_CTL_EL2", 0,14,2, 3,4,1, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "MDCR_EL2", 0,1,1, 3,4,1, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL2_RW, 0, NULL, 0, 0, {0, 0}, - access_tda }, - { "HPFAR_EL2", 0,6,0, 3,4,4, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL2_RW, 0, NULL, 0, 0, {0, 0}, - access_el3_aa32ns_aa64any }, - { "HSTR_EL2", 0,1,1, 3,4,3, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "FAR_EL2", 0,6,0, 3,4,0, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "HIFAR", 15,6,0, 0,4,2, ARM_CP_STATE_AA32, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, + { .name = "VBAR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0, + .access = PL2_RW, + .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore }, + { .name = "HCR_EL2", .state = ARM_CP_STATE_BOTH, + .type = ARM_CP_NO_RAW, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0, + .access = PL2_RW, + .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "HACR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 7, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "ESR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0, + .access = PL2_RW, + .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "CPTR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 2, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "MAIR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "HMAIR1", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "AMAIR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "HAMAIR1", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1, + .access = PL2_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "AFSR0_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "AFSR1_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 1, + .access = PL2_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "TCR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 2, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "VTCR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2, + .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any, + .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "VTTBR", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 6, .crm = 2, + .access = PL2_RW, .accessfn = access_el3_aa32ns, + .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, + { .name = "VTTBR_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "TPIDR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 2, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "TTBR0_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2, + .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "CNTHCTL_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 1, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "CNTVOFF_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 0, .opc2 = 3, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "CNTVOFF", .cp = 15, .opc1 = 4, .crm = 14, + .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "CNTHP_CVAL_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 2, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "CNTHP_CVAL", .cp = 15, .opc1 = 6, .crm = 14, + .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "CNTHP_TVAL_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "CNTHP_CTL_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 1, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1, + .access = PL2_RW, .accessfn = access_tda, + .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "HPFAR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4, + .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any, + .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "HSTR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 3, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "FAR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "HIFAR", .state = ARM_CP_STATE_AA32, + .type = ARM_CP_CONST, + .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 2, + .access = PL2_RW, .resetvalue = 0 }, REGINFO_SENTINEL }; /* Ditto, but for registers which exist in ARMv8 but not v7 */ static const ARMCPRegInfo el3_no_el2_v8_cp_reginfo[] = { - { "HCR2", 15,1,1, 0,4,4, ARM_CP_STATE_AA32, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, + { .name = "HCR2", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 4, + .access = PL2_RW, + .type = ARM_CP_CONST, .resetvalue = 0 }, REGINFO_SENTINEL }; - static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { ARMCPU *cpu = arm_env_get_cpu(env); @@ -4118,180 +4498,260 @@ uint64_t arm_hcr_el2_eff(CPUARMState *env) } static const ARMCPRegInfo el2_cp_reginfo[] = { - { "HCR_EL2", 0,1,1, 3,4,0, ARM_CP_STATE_AA64, - ARM_CP_IO, PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.hcr_el2), {0, 0}, - NULL, NULL, hcr_write }, - { "HCR", 15,1,1, 0,4,0, ARM_CP_STATE_AA32, - ARM_CP_ALIAS | ARM_CP_IO, PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.hcr_el2), - {0, 0}, NULL, NULL, hcr_writelow }, - { "ELR_EL2", 0,4,0, 3,4,1, ARM_CP_STATE_AA64, - ARM_CP_ALIAS, PL2_RW, 0, NULL, 0, offsetof(CPUARMState, elr_el[2]) }, - { "HACR_EL2", 0,1,1, 3,4,7, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL2_RW, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, NULL }, - { "ESR_EL2", 0,5,2, 3,4,0, ARM_CP_STATE_BOTH, 0, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.esr_el[2]) }, - { "FAR_EL2", 0,6,0, 3,4,0, ARM_CP_STATE_BOTH, - 0, PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.far_el[2]) }, - { "HIFAR", 15,6,0, 0,4,2, ARM_CP_STATE_AA32, - ARM_CP_ALIAS, PL2_RW, 0, NULL, 0, offsetofhigh32(CPUARMState, cp15.far_el[2]) }, - { "SPSR_EL2", 0,4,0, 3,4,0, ARM_CP_STATE_AA64, - ARM_CP_ALIAS, PL2_RW, 0, NULL, 0, offsetof(CPUARMState, banked_spsr[BANK_HYP]) }, - { "VBAR_EL2", 0,12,0, 3,4,0, ARM_CP_STATE_BOTH, - 0, PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.vbar_el[2]), {0, 0}, - NULL, NULL, vbar_write, }, - { "SP_EL2", 0,4,1, 3,6,0, ARM_CP_STATE_AA64, ARM_CP_ALIAS, - PL3_RW, 0, NULL, 0, offsetof(CPUARMState, sp_el[2]) }, - { "CPTR_EL2", 0,1,1, 3,4,2, ARM_CP_STATE_BOTH, 0, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.cptr_el[2]), {0, 0}, - cptr_access }, - { "MAIR_EL2", 0,10,2, 3,4,0, ARM_CP_STATE_BOTH, 0, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.mair_el[2]) }, - { "HMAIR1", 15,10,2, 0,4,1, ARM_CP_STATE_AA32, ARM_CP_ALIAS, - PL2_RW, 0, NULL, 0, offsetofhigh32(CPUARMState, cp15.mair_el[2]) }, - { "AMAIR_EL2", 0,10,3, 3,4,0, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, + { .name = "HCR_EL2", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_IO, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0, + .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2), + .writefn = hcr_write }, + { .name = "HCR", .state = ARM_CP_STATE_AA32, + .type = ARM_CP_ALIAS | ARM_CP_IO, + .cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0, + .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2), + .writefn = hcr_writelow }, + { .name = "HACR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 7, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "ELR_EL2", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1, + .access = PL2_RW, + .fieldoffset = offsetof(CPUARMState, elr_el[2]) }, + { .name = "ESR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0, + .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[2]) }, + { .name = "FAR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0, + .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[2]) }, + { .name = "HIFAR", .state = ARM_CP_STATE_AA32, + .type = ARM_CP_ALIAS, + .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 2, + .access = PL2_RW, + .fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el[2]) }, + { .name = "SPSR_EL2", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0, + .access = PL2_RW, + .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_HYP]) }, + { .name = "VBAR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0, + .access = PL2_RW, .writefn = vbar_write, + .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[2]), + .resetvalue = 0 }, + { .name = "SP_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 1, .opc2 = 0, + .access = PL3_RW, .type = ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, sp_el[2]) }, + { .name = "CPTR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 2, + .access = PL2_RW, .accessfn = cptr_access, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.cptr_el[2]) }, + { .name = "MAIR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 0, + .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[2]), + .resetvalue = 0 }, + { .name = "HMAIR1", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1, + .access = PL2_RW, .type = ARM_CP_ALIAS, + .fieldoffset = offsetofhigh32(CPUARMState, cp15.mair_el[2]) }, + { .name = "AMAIR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, /* HAMAIR1 is mapped to AMAIR_EL2[63:32] */ - { "HAMAIR1", 15,10,3, 0,4,1, ARM_CP_STATE_AA32, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "AFSR0_EL2", 0,5,1, 3,4,0, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "AFSR1_EL2", 0,5,1, 3,4,1, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "TCR_EL2", 0,2,0, 3,4,2, ARM_CP_STATE_BOTH, 0, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.tcr_el[2]), {0, 0}, + { .name = "HAMAIR1", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1, + .access = PL2_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "AFSR0_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "AFSR1_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 1, + .access = PL2_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "TCR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 2, + .access = PL2_RW, /* no .writefn needed as this can't cause an ASID change; * no .raw_writefn or .resetfn needed as we never use mask/base_mask */ - NULL, NULL, NULL, NULL, NULL, NULL }, - { "VTCR", 15,2,1, 0,4,2, ARM_CP_STATE_AA32, ARM_CP_ALIAS, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.vtcr_el2), {0, 0}, - access_el3_aa32ns }, - { "VTCR_EL2", 0,2,1, 3,4,2, ARM_CP_STATE_AA64, 0, - PL2_RW, 0, NULL, 0, + .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[2]) }, + { .name = "VTCR", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2, + .type = ARM_CP_ALIAS, + .access = PL2_RW, .accessfn = access_el3_aa32ns, + .fieldoffset = offsetof(CPUARMState, cp15.vtcr_el2) }, + { .name = "VTCR_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2, + .access = PL2_RW, /* no .writefn needed as this can't cause an ASID change; * no .raw_writefn or .resetfn needed as we never use mask/base_mask */ - offsetof(CPUARMState, cp15.vtcr_el2) }, - { "VTTBR", 15,0,2, 0,6,0, ARM_CP_STATE_AA32, ARM_CP_64BIT | ARM_CP_ALIAS, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.vttbr_el2), {0, 0}, - access_el3_aa32ns, NULL, vttbr_write }, - { "VTTBR_EL2", 0,2,1, 3,4,0, ARM_CP_STATE_AA64, 0, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.vttbr_el2), {0, 0}, - NULL, NULL, vttbr_write }, - { "SCTLR_EL2", 0,1,0, 3,4,0, ARM_CP_STATE_BOTH, 0, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.sctlr_el[2]), {0, 0}, - NULL, NULL, sctlr_write, NULL, raw_write }, - { "TPIDR_EL2", 0,13,0, 3,4,2, ARM_CP_STATE_BOTH, 0, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.tpidr_el[2]) }, - { "TTBR0_EL2", 0,2,0, 3,4,0, ARM_CP_STATE_AA64, 0, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.ttbr0_el[2]) }, - { "HTTBR", 15,0,2, 0,4,0, 0, ARM_CP_64BIT | ARM_CP_ALIAS, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.ttbr0_el[2]) }, - { "TLBIALLNSNH", 15,8,7, 0,4,4, 0, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbiall_nsnh_write }, - { "TLBIALLNSNHIS", 15,8,3, 0,4,4, 0, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbiall_nsnh_is_write }, - { "TLBIALLH", 15,8,7, 0,4,0, 0, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbiall_hyp_write }, - { "TLBIALLHIS", 15,8,3, 0,4,0, 0, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbiall_hyp_is_write }, - { "TLBIMVAH", 15,8,7, 0,4,1, 0, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbimva_hyp_write }, - { "TLBIMVAHIS", 15,8,3, 0,4,1, 0, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbimva_hyp_is_write }, - { "TLBI_ALLE2", 0,8,7, 1,4,0, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_alle2_write }, - { "TLBI_VAE2", 0,8,7, 1,4,1, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_vae2_write }, - { "TLBI_VALE2", 0,8,7, 1,4,5, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_vae2_write }, - { "TLBI_ALLE2IS", 0,8,3, 1,4,0, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_alle2is_write }, - { "TLBI_VAE2IS", 0,8,3, 1,4,1, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_vae2is_write }, - { "TLBI_VALE2IS", 0,8,3, 1,4,5, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_vae2is_write }, + .fieldoffset = offsetof(CPUARMState, cp15.vtcr_el2) }, + { .name = "VTTBR", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 6, .crm = 2, + .type = ARM_CP_64BIT | ARM_CP_ALIAS, + .access = PL2_RW, .accessfn = access_el3_aa32ns, + .fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2), + .writefn = vttbr_write }, + { .name = "VTTBR_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 0, + .access = PL2_RW, .writefn = vttbr_write, + .fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2) }, + { .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0, + .access = PL2_RW, .raw_writefn = raw_write, .writefn = sctlr_write, + .fieldoffset = offsetof(CPUARMState, cp15.sctlr_el[2]) }, + { .name = "TPIDR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 2, + .access = PL2_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[2]) }, + { .name = "TTBR0_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0, + .access = PL2_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) }, + { .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2, + .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) }, + { .name = "TLBIALLNSNH", + .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbiall_nsnh_write }, + { .name = "TLBIALLNSNHIS", + .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbiall_nsnh_is_write }, + { .name = "TLBIALLH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbiall_hyp_write }, + { .name = "TLBIALLHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 0, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbiall_hyp_is_write }, + { .name = "TLBIMVAH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbimva_hyp_write }, + { .name = "TLBIMVAHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 1, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbimva_hyp_is_write }, + { .name = "TLBI_ALLE2", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbi_aa64_alle2_write }, + { .name = "TLBI_VAE2", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbi_aa64_vae2_write }, + { .name = "TLBI_VALE2", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae2_write }, + { .name = "TLBI_ALLE2IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 0, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_alle2is_write }, + { .name = "TLBI_VAE2IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 1, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbi_aa64_vae2is_write }, + { .name = "TLBI_VALE2IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 5, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae2is_write }, #ifndef CONFIG_USER_ONLY /* Unlike the other EL2-related AT operations, these must * UNDEF from EL3 if EL2 is not implemented, which is why we * define them here rather than with the rest of the AT ops. */ - { "AT_S1E2R", 0,7,8, 1,4,0, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - at_s1e2_access, NULL, ats_write64 }, - { "AT_S1E2W", 0,7,8, 1,4,1, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - at_s1e2_access, NULL, ats_write64 }, + { .name = "AT_S1E2R", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 0, + .access = PL2_W, .accessfn = at_s1e2_access, + .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + { .name = "AT_S1E2W", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 1, + .access = PL2_W, .accessfn = at_s1e2_access, + .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, /* The AArch32 ATS1H* operations are CONSTRAINED UNPREDICTABLE * if EL2 is not implemented; we choose to UNDEF. Behaviour at EL3 * with SCR.NS == 0 outside Monitor mode is UNPREDICTABLE; we choose * to behave as if SCR.NS was 1. */ - { "ATS1HR", 15,7,8, 0,4,0, 0, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, ats1h_write }, - { "ATS1HW", 15,7,8, 0,4,1, 0, ARM_CP_NO_RAW, - PL2_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, ats1h_write }, + { .name = "ATS1HR", .cp = 15, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 0, + .access = PL2_W, + .writefn = ats1h_write, .type = ARM_CP_NO_RAW }, + { .name = "ATS1HW", .cp = 15, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 1, + .access = PL2_W, + .writefn = ats1h_write, .type = ARM_CP_NO_RAW }, + { .name = "CNTHCTL_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 1, .opc2 = 0, /* ARMv7 requires bit 0 and 1 to reset to 1. ARMv8 defines the * reset values as IMPDEF. We choose to reset to 3 to comply with * both ARMv7 and ARMv8. */ - { "CNTHCTL_EL2", 0,14,1, 3,4,0, ARM_CP_STATE_BOTH, 0, - PL2_RW, 0, NULL, 3, offsetof(CPUARMState, cp15.cnthctl_el2) }, - { "CNTVOFF_EL2", 0,140,0, 3,4,3, ARM_CP_STATE_AA64, ARM_CP_IO, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.cntvoff_el2), {0, 0}, - NULL, NULL, gt_cntvoff_write }, - { "CNTVOFF", 15,0,14, 0,4,0, 0, ARM_CP_64BIT | ARM_CP_ALIAS | ARM_CP_IO, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.cntvoff_el2), {0, 0}, - NULL, NULL, gt_cntvoff_write }, - { "CNTHP_CVAL_EL2", 0,14,2, 3,4,2, ARM_CP_STATE_AA64, ARM_CP_IO, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYP].cval), {0, 0}, - NULL, NULL, gt_hyp_cval_write, NULL, raw_write }, - { "CNTHP_CVAL", 15,0,14, 0,6,0, 0, ARM_CP_64BIT | ARM_CP_IO, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYP].cval), {0, 0}, - NULL, NULL, gt_hyp_cval_write, NULL, raw_write }, - { "CNTHP_TVAL_EL2", 0,14,2, 3,4,0, ARM_CP_STATE_BOTH, ARM_CP_NO_RAW | ARM_CP_IO, - PL2_RW, 0, NULL, 0, 0, {0, 0}, - NULL, gt_hyp_tval_read, gt_hyp_tval_write, NULL, NULL, gt_hyp_timer_reset }, - { "CNTHP_CTL_EL2", 0,14,2, 3,4,1, ARM_CP_STATE_BOTH, ARM_CP_IO, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYP].ctl), {0, 0}, - NULL, NULL, gt_hyp_ctl_write, NULL, raw_write }, + .access = PL2_RW, .resetvalue = 3, + .fieldoffset = offsetof(CPUARMState, cp15.cnthctl_el2) }, + { .name = "CNTVOFF_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 0, .opc2 = 3, + .access = PL2_RW, .type = ARM_CP_IO, .resetvalue = 0, + .writefn = gt_cntvoff_write, + .fieldoffset = offsetof(CPUARMState, cp15.cntvoff_el2) }, + { .name = "CNTVOFF", .cp = 15, .opc1 = 4, .crm = 14, + .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS | ARM_CP_IO, + .writefn = gt_cntvoff_write, + .fieldoffset = offsetof(CPUARMState, cp15.cntvoff_el2) }, + { .name = "CNTHP_CVAL_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 2, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYP].cval), + .type = ARM_CP_IO, .access = PL2_RW, + .writefn = gt_hyp_cval_write, .raw_writefn = raw_write }, + { .name = "CNTHP_CVAL", .cp = 15, .opc1 = 6, .crm = 14, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYP].cval), + .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_IO, + .writefn = gt_hyp_cval_write, .raw_writefn = raw_write }, + { .name = "CNTHP_TVAL_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 0, + .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL2_RW, + .resetfn = gt_hyp_timer_reset, + .readfn = gt_hyp_tval_read, .writefn = gt_hyp_tval_write }, + { .name = "CNTHP_CTL_EL2", .state = ARM_CP_STATE_BOTH, + .type = ARM_CP_IO, + .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 1, + .access = PL2_RW, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYP].ctl), + .resetvalue = 0, + .writefn = gt_hyp_ctl_write, .raw_writefn = raw_write }, #endif /* The only field of MDCR_EL2 that has a defined architectural reset value * is MDCR_EL2.HPMN which should reset to the value of PMCR_EL0.N; but we * don't implement any PMU event counters, so using zero as a reset * value for MDCR_EL2 is okay */ - { "MDCR_EL2", 0,1,1, 3,4,1, ARM_CP_STATE_BOTH, 0, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.mdcr_el2), }, - { "HPFAR", 15,6,0, 0,4,4, ARM_CP_STATE_AA32, 0, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.hpfar_el2), {0, 0}, - access_el3_aa32ns }, - { "HPFAR_EL2", 0,6,0, 3,4,4, ARM_CP_STATE_AA64, 0, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.hpfar_el2) }, - { "HSTR_EL2", 15,1,1, 3,4,3, ARM_CP_STATE_BOTH, 0, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.hstr_el2) }, + { .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1, + .access = PL2_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.mdcr_el2), }, + { .name = "HPFAR", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4, + .access = PL2_RW, .accessfn = access_el3_aa32ns, + .fieldoffset = offsetof(CPUARMState, cp15.hpfar_el2) }, + { .name = "HPFAR_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4, + .access = PL2_RW, + .fieldoffset = offsetof(CPUARMState, cp15.hpfar_el2) }, + { .name = "HSTR_EL2", .state = ARM_CP_STATE_BOTH, + .cp = 15, .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 3, + .access = PL2_RW, + .fieldoffset = offsetof(CPUARMState, cp15.hstr_el2) }, REGINFO_SENTINEL }; static const ARMCPRegInfo el2_v8_cp_reginfo[] = { - { "HCR2", 15,1,1, 0,4,4, ARM_CP_STATE_AA32, - ARM_CP_ALIAS | ARM_CP_IO, PL2_RW, 0, NULL, 0, offsetofhigh32(CPUARMState, cp15.hcr_el2), - {0, 0}, NULL, NULL, hcr_writehigh }, + { .name = "HCR2", .state = ARM_CP_STATE_AA32, + .type = ARM_CP_ALIAS | ARM_CP_IO, + .cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 4, + .access = PL2_RW, + .fieldoffset = offsetofhigh32(CPUARMState, cp15.hcr_el2), + .writefn = hcr_writehigh }, REGINFO_SENTINEL }; @@ -4315,70 +4775,106 @@ static CPAccessResult nsacr_access(CPUARMState *env, const ARMCPRegInfo *ri, } static const ARMCPRegInfo el3_cp_reginfo[] = { - { "SCR_EL3", 0,1,1, 3,6,0, ARM_CP_STATE_AA64,0, - PL3_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.scr_el3), {0, 0}, - NULL, NULL, scr_write }, - { "SCR", 15,1,1, 0,0,0, 0,ARM_CP_ALIAS, - PL1_RW, 0, NULL, 0, offsetoflow32(CPUARMState, cp15.scr_el3), {0, 0}, - access_trap_aa32s_el1, NULL, scr_write, NULL, NULL, NULL }, - { "SDER32_EL3", 0,1,1, 3,6,1, ARM_CP_STATE_AA64,0, - PL3_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.sder) }, - { "SDER", 15,1,1, 0,0,1, 0,0, - PL3_RW, 0, NULL, 0, offsetoflow32(CPUARMState, cp15.sder) }, - { "MVBAR", 15,12,0, 0,0,1, 0,0, - PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.mvbar), {0, 0}, - access_trap_aa32s_el1, NULL, vbar_write }, - { "TTBR0_EL3", 0,2,0, 3,6,0, ARM_CP_STATE_AA64,0, - PL3_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.ttbr0_el[3]), {0, 0}, - NULL, NULL, NULL }, - { "TCR_EL3", 0,2,0, 3,6,2, ARM_CP_STATE_AA64,0, - PL3_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.tcr_el[3]), {0, 0}, + { .name = "SCR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0, + .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3), + .resetvalue = 0, .writefn = scr_write }, + { .name = "SCR", .type = ARM_CP_ALIAS, + .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 0, + .access = PL1_RW, .accessfn = access_trap_aa32s_el1, + .fieldoffset = offsetoflow32(CPUARMState, cp15.scr_el3), + .writefn = scr_write }, + { .name = "SDER32_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 1, + .access = PL3_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.sder) }, + { .name = "SDER", + .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 1, + .access = PL3_RW, .resetvalue = 0, + .fieldoffset = offsetoflow32(CPUARMState, cp15.sder) }, + { .name = "MVBAR", .cp = 15, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1, + .access = PL1_RW, .accessfn = access_trap_aa32s_el1, + .writefn = vbar_write, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.mvbar) }, + { .name = "TTBR0_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 0, .opc2 = 0, + .access = PL3_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[3]) }, + { .name = "TCR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 0, .opc2 = 2, + .access = PL3_RW, /* no .writefn needed as this can't cause an ASID change; * we must provide a .raw_writefn and .resetfn because we handle * reset and migration for the AArch32 TTBCR(S), which might be * using mask and base_mask. */ - NULL, NULL, NULL, NULL, vmsa_ttbcr_raw_write, vmsa_ttbcr_reset }, - { "ELR_EL3", 0,4,0, 3,6,1, ARM_CP_STATE_AA64, - ARM_CP_ALIAS, PL3_RW, 0, NULL, 0, offsetof(CPUARMState, elr_el[3]) }, - { "ESR_EL3", 0,5,2, 3,6,0, ARM_CP_STATE_AA64, 0, - PL3_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.esr_el[3]) }, - { "FAR_EL3", 0,6,0, 3,6,0, ARM_CP_STATE_AA64, - 0, PL3_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.far_el[3]) }, - { "SPSR_EL3", 0,4,0, 3,6,0, ARM_CP_STATE_AA64, - ARM_CP_ALIAS, PL3_RW, 0, NULL, 0, offsetof(CPUARMState, banked_spsr[BANK_MON]) }, - { "VBAR_EL3", 0,12,0, 3,6,0, ARM_CP_STATE_AA64, - 0, PL3_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.vbar_el[3]), {0, 0}, - NULL, NULL, vbar_write, }, - { "CPTR_EL3", 0,1,1, 3,6,2, ARM_CP_STATE_AA64, 0, - PL3_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.cptr_el[3]), {0, 0}, - cptr_access }, - { "TPIDR_EL3", 0,13,0, 3,6,2, ARM_CP_STATE_AA64, 0, - PL3_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.tpidr_el[3]) }, - { "AMAIR_EL3", 0,10,3, 3,6,0, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL3_RW, 0, NULL, 0 }, - { "AFSR0_EL3", 0,5,1, 3,6,0, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL3_RW, 0, NULL, 0 }, - { "AFSR1_EL3", 0,5,1, 3,6,1, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL3_RW, 0, NULL, 0 }, - { "TLBI_ALLE3IS", 0,8,3, 1,6,0, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL3_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_alle3is_write }, - { "TLBI_VAE3IS", 0,8,3, 1,6,1, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL3_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_vae3is_write }, - { "TLBI_VALE3IS", 0,8,3, 1,6,5, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL3_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_vae3is_write }, - { "TLBI_ALLE3", 0,8,7, 1,6,0, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL3_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_alle3_write }, - { "TLBI_VAE3", 0,8,7, 1,6,1, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL3_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_vae3_write }, - { "TLBI_VALE3", 0,8,7, 1,6,5, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, - PL3_W, 0, NULL, 0, 0, {0, 0}, - NULL, NULL, tlbi_aa64_vae3_write }, + .resetfn = vmsa_ttbcr_reset, .raw_writefn = vmsa_ttbcr_raw_write, + .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[3]) }, + { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 1, + .access = PL3_RW, + .fieldoffset = offsetof(CPUARMState, elr_el[3]) }, + { .name = "ESR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 2, .opc2 = 0, + .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[3]) }, + { .name = "FAR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 6, .crm = 0, .opc2 = 0, + .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[3]) }, + { .name = "SPSR_EL3", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 0, + .access = PL3_RW, + .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_MON]) }, + { .name = "VBAR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 0, + .access = PL3_RW, .writefn = vbar_write, + .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[3]), + .resetvalue = 0 }, + { .name = "CPTR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 2, + .access = PL3_RW, .accessfn = cptr_access, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.cptr_el[3]) }, + { .name = "TPIDR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 13, .crm = 0, .opc2 = 2, + .access = PL3_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[3]) }, + { .name = "AMAIR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 10, .crm = 3, .opc2 = 0, + .access = PL3_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "AFSR0_EL3", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 1, .opc2 = 0, + .access = PL3_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "AFSR1_EL3", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 1, .opc2 = 1, + .access = PL3_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "TLBI_ALLE3IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 0, + .access = PL3_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_alle3is_write }, + { .name = "TLBI_VAE3IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 1, + .access = PL3_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae3is_write }, + { .name = "TLBI_VALE3IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 5, + .access = PL3_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae3is_write }, + { .name = "TLBI_ALLE3", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 0, + .access = PL3_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_alle3_write }, + { .name = "TLBI_VAE3", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 1, + .access = PL3_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae3_write }, + { .name = "TLBI_VALE3", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 5, + .access = PL3_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae3_write }, REGINFO_SENTINEL }; @@ -4418,59 +4914,76 @@ static const ARMCPRegInfo debug_cp_reginfo[] = { * DBGDSAR is deprecated and must RAZ from v8 anyway, so it has no AArch64 * accessor. */ - { "DBGDRAR", 14,1,0, 0,0,0, 0, - ARM_CP_CONST, PL0_R, 0, NULL, 0, 0, {0, 0}, - access_tdra }, - { "MDRAR_EL1", 0,1,0, 2,0,0, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL1_R, 0, NULL, 0, 0, {0, 0}, - access_tdra }, - { "DBGDSAR", 14,2,0, 0,0,0, 0, - ARM_CP_CONST, PL0_R, 0, NULL, 0, 0, {0, 0}, - access_tdra }, + { .name = "DBGDRAR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL0_R, .accessfn = access_tdra, + .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "MDRAR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0, + .access = PL1_R, .accessfn = access_tdra, + .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "DBGDSAR", .cp = 14, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL0_R, .accessfn = access_tdra, + .type = ARM_CP_CONST, .resetvalue = 0 }, /* Monitor debug system control register; the 32-bit alias is DBGDSCRext. */ - { "MDSCR_EL1", 14,0,2, 2,0,2, ARM_CP_STATE_BOTH, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.mdscr_el1), }, + { .name = "MDSCR_EL1", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2, + .access = PL1_RW, .accessfn = access_tda, + .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1), + .resetvalue = 0 }, /* MDCCSR_EL0, aka DBGDSCRint. This is a read-only mirror of MDSCR_EL1. * We don't implement the configurable EL0 access. */ - { "MDCCSR_EL0", 14,0,1, 2,0,0, ARM_CP_STATE_BOTH, - ARM_CP_ALIAS, PL1_R, 0, NULL, 0, offsetof(CPUARMState, cp15.mdscr_el1), {0, 0}, - access_tda, NULL, NULL, NULL, NULL, NULL }, - { "OSLAR_EL1", 14,1,0, 2,0,4, ARM_CP_STATE_BOTH, ARM_CP_NO_RAW, - PL1_W, 0, NULL, 0, 0, {0, 0}, - access_tdosa, NULL, oslar_write }, - { "OSLSR_EL1", 14,1,1, 2,0,4, ARM_CP_STATE_BOTH, 0, - PL1_R, 0, NULL, 10, offsetof(CPUARMState, cp15.oslsr_el1), {0, 0}, - access_tdosa }, + { .name = "MDCCSR_EL0", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0, + .type = ARM_CP_ALIAS, + .access = PL1_R, .accessfn = access_tda, + .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1), }, + { .name = "OSLAR_EL1", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 4, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .accessfn = access_tdosa, + .writefn = oslar_write }, + { .name = "OSLSR_EL1", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 4, + .access = PL1_R, .resetvalue = 10, + .accessfn = access_tdosa, + .fieldoffset = offsetof(CPUARMState, cp15.oslsr_el1) }, /* Dummy OSDLR_EL1: 32-bit Linux will read this */ - { "OSDLR_EL1", 14,1,3, 2,0,4, ARM_CP_STATE_BOTH, - ARM_CP_NOP, PL1_RW, 0, NULL, 0, 0, {0, 0}, - access_tdosa }, + { .name = "OSDLR_EL1", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 4, + .access = PL1_RW, .accessfn = access_tdosa, + .type = ARM_CP_NOP }, /* Dummy DBGVCR: Linux wants to clear this on startup, but we don't * implement vector catch debug events yet. */ - { "DBGVCR", 14,0,7, 0,0,0, 0, - ARM_CP_NOP, PL1_RW, 0, NULL, 0, 0, {0, 0}, - access_tda }, - { "DBGVCR32_EL2", 0,0,7, 2,4,0, ARM_CP_STATE_AA64, ARM_CP_NOP, - PL2_RW, 0, NULL, 0, 0, {0, 0}, - access_tda }, + { .name = "DBGVCR", + .cp = 14, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0, + .access = PL1_RW, .accessfn = access_tda, + .type = ARM_CP_NOP }, + /* Dummy DBGVCR32_EL2 (which is only for a 64-bit hypervisor + * to save and restore a 32-bit guest's DBGVCR) + */ + { .name = "DBGVCR32_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 2, .opc1 = 4, .crn = 0, .crm = 7, .opc2 = 0, + .access = PL2_RW, .accessfn = access_tda, + .type = ARM_CP_NOP }, /* Dummy MDCCINT_EL1, since we don't implement the Debug Communications * Channel but Linux may try to access this register. The 32-bit * alias is DBGDCCINT. */ - { "MDCCINT_EL1", 14,0,2, 2,0,0, ARM_CP_STATE_BOTH, ARM_CP_NOP, - PL1_RW, 0, NULL, 0, 0, {0, 0}, - access_tda }, + { .name = "MDCCINT_EL1", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0, + .access = PL1_RW, .accessfn = access_tda, + .type = ARM_CP_NOP }, REGINFO_SENTINEL }; static const ARMCPRegInfo debug_lpae_cp_reginfo[] = { /* 64 bit access versions of the (dummy) debug registers */ - { "DBGDRAR", 14, 0,1, 0,0, 0, 0, - ARM_CP_CONST|ARM_CP_64BIT, PL0_R, 0, NULL, 0 }, - { "DBGDSAR", 14, 0,2, 0,0, 0, 0, - ARM_CP_CONST|ARM_CP_64BIT, PL0_R, 0, NULL, 0 }, + { .name = "DBGDRAR", .cp = 14, .crm = 1, .opc1 = 0, + .access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 }, + { .name = "DBGDSAR", .cp = 14, .crm = 2, .opc1 = 0, + .access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 }, REGINFO_SENTINEL }; @@ -4575,27 +5088,34 @@ static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri, } static const ARMCPRegInfo zcr_el1_reginfo = { - "ZCR_EL1", 0,1,2, 3,0,0, ARM_CP_STATE_AA64, ARM_CP_SVE, - PL1_RW, 0, NULL, 0, offsetof(CPUARMState, vfp.zcr_el[1]), {0, 0}, - NULL, NULL, zcr_write, NULL, raw_write + .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_SVE, + .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]), + .writefn = zcr_write, .raw_writefn = raw_write }; static const ARMCPRegInfo zcr_el2_reginfo = { - "ZCR_EL2", 0,1,2, 3,4,0, ARM_CP_STATE_AA64, ARM_CP_SVE, - PL2_RW, 0, NULL, 0, offsetof(CPUARMState, vfp.zcr_el[2]), {0, 0}, - NULL, NULL, zcr_write, NULL, raw_write + .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_SVE, + .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]), + .writefn = zcr_write, .raw_writefn = raw_write }; static const ARMCPRegInfo zcr_no_el2_reginfo = { - "ZCR_EL2", 0,1,2, 3,4,0, ARM_CP_STATE_AA64, ARM_CP_SVE, - PL2_RW, 0, NULL, 0, 0, {0, 0}, - NULL, arm_cp_read_zero, arm_cp_write_ignore + .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_SVE, + .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore }; static const ARMCPRegInfo zcr_el3_reginfo = { - "ZCR_EL3", 0,1,2, 3,6,0, ARM_CP_STATE_AA64, ARM_CP_SVE, - PL3_RW, 0, NULL, 0, offsetof(CPUARMState, vfp.zcr_el[3]), {0, 0}, - NULL, NULL, zcr_write, NULL, raw_write + .name = "ZCR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0, + .access = PL3_RW, .type = ARM_CP_SVE, + .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]), + .writefn = zcr_write, .raw_writefn = raw_write }; void hw_watchpoint_update(ARMCPU *cpu, int n) @@ -4849,9 +5369,9 @@ static void define_debug_regs(ARMCPU *cpu) int i; int wrps, brps, ctx_cmps; ARMCPRegInfo dbgdidr = { - "DBGDIDR", 14,0,0, 0,0,0, 0, - ARM_CP_CONST, PL0_R, 0, NULL, cpu->dbgdidr, 0, {0, 0}, - access_tda + .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL0_R, .accessfn = access_tda, + .type = ARM_CP_CONST, .resetvalue = cpu->dbgdidr, }; /* Note that all these register fields hold "number of Xs minus 1". */ @@ -4880,13 +5400,17 @@ static void define_debug_regs(ARMCPU *cpu) for (i = 0; i < brps + 1; i++) { ARMCPRegInfo dbgregs[] = { - { "DBGBVR", 14,0,i, 2,0,4,ARM_CP_STATE_BOTH, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.dbgbvr[i]), {0, 0}, - access_tda, NULL,dbgbvr_write, NULL,raw_write + { .name = "DBGBVR", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4, + .access = PL1_RW, .accessfn = access_tda, + .fieldoffset = offsetof(CPUARMState, cp15.dbgbvr[i]), + .writefn = dbgbvr_write, .raw_writefn = raw_write }, - { "DBGBCR", 14,0,i, 2,0,5, ARM_CP_STATE_BOTH, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.dbgbcr[i]), {0, 0}, - access_tda, NULL,dbgbcr_write, NULL,raw_write + { .name = "DBGBCR", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5, + .access = PL1_RW, .accessfn = access_tda, + .fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]), + .writefn = dbgbcr_write, .raw_writefn = raw_write }, REGINFO_SENTINEL }; @@ -4895,13 +5419,17 @@ static void define_debug_regs(ARMCPU *cpu) for (i = 0; i < wrps + 1; i++) { ARMCPRegInfo dbgregs[] = { - { "DBGWVR", 14,0,i, 2,0,6, ARM_CP_STATE_BOTH, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.dbgwvr[i]), {0, 0}, - access_tda, NULL,dbgwvr_write, NULL,raw_write + { .name = "DBGWVR", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6, + .access = PL1_RW, .accessfn = access_tda, + .fieldoffset = offsetof(CPUARMState, cp15.dbgwvr[i]), + .writefn = dbgwvr_write, .raw_writefn = raw_write }, - { "DBGWCR", 14,0,i, 2,0,7, ARM_CP_STATE_BOTH, - 0, PL1_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.dbgwcr[i]), {0, 0}, - access_tda, NULL,dbgwcr_write, NULL,raw_write + { .name = "DBGWCR", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 7, + .access = PL1_RW, .accessfn = access_tda, + .fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]), + .writefn = dbgwcr_write, .raw_writefn = raw_write }, REGINFO_SENTINEL }; @@ -5100,42 +5628,74 @@ void register_cp_regs_for_features(ARMCPU *cpu) if (arm_feature(env, ARM_FEATURE_V6)) { /* The ID registers all have impdef reset values */ ARMCPRegInfo v6_idregs[] = { - { "ID_PFR0", 0,0,1, 3,0,0, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->id_pfr0 }, + { .name = "ID_PFR0", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_pfr0 }, /* ID_PFR1 is not a plain ARM_CP_CONST because we don't know * the value of the GIC field until after we define these regs. */ - { "ID_PFR1", 0,0,1, 3,0,1, ARM_CP_STATE_BOTH, - ARM_CP_NO_RAW, PL1_R, 0, NULL, cpu->id_pfr1, 0, {0, 0}, - NULL, id_pfr1_read, arm_cp_write_ignore }, - { "ID_DFR0", 0,0,1, 3,0,2, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->id_dfr0 }, - { "ID_AFR0", 0,0,1, 3,0,3, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->id_afr0 }, - { "ID_MMFR0", 0,0,1, 3,0,4, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->id_mmfr0 }, - { "ID_MMFR1", 0,0,1, 3,0,5, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->id_mmfr1 }, - { "ID_MMFR2", 0,0,1, 3,0,6, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->id_mmfr2 }, - { "ID_MMFR3", 0,0,1, 3,0,7, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->id_mmfr3 }, - { "ID_ISAR0", 0,0,2, 3,0,0, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->isar.id_isar0 }, - { "ID_ISAR1", 0,0,2, 3,0,1, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->isar.id_isar1 }, - { "ID_ISAR2", 0,0,2, 3,0,2, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->isar.id_isar2 }, - { "ID_ISAR3", 0,0,2, 3,0,3, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->isar.id_isar3 }, - { "ID_ISAR4", 0,0,2, 3,0,4, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->isar.id_isar4 }, - { "ID_ISAR5", 0,0,2, 3,0,5, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->isar.id_isar5 }, - { "ID_MMFR4", 0,0,2, 3,0,6, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL1_R, 0, NULL, cpu->id_mmfr4 }, - { "ID_ISAR6", 0,0,2, 3,0,7, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->isar.id_isar6 }, + { .name = "ID_PFR1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 1, + .access = PL1_R, .type = ARM_CP_NO_RAW, + .readfn = id_pfr1_read, + .writefn = arm_cp_write_ignore }, + { .name = "ID_DFR0", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 2, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_dfr0 }, + { .name = "ID_AFR0", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 3, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_afr0 }, + { .name = "ID_MMFR0", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 4, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_mmfr0 }, + { .name = "ID_MMFR1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 5, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_mmfr1 }, + { .name = "ID_MMFR2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 6, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_mmfr2 }, + { .name = "ID_MMFR3", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 7, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_mmfr3 }, + { .name = "ID_ISAR0", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->isar.id_isar0 }, + { .name = "ID_ISAR1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 1, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->isar.id_isar1 }, + { .name = "ID_ISAR2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->isar.id_isar2 }, + { .name = "ID_ISAR3", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 3, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->isar.id_isar3 }, + { .name = "ID_ISAR4", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 4, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->isar.id_isar4 }, + { .name = "ID_ISAR5", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 5, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->isar.id_isar5 }, + { .name = "ID_MMFR4", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_mmfr4 }, + { .name = "ID_ISAR6", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->isar.id_isar6 }, REGINFO_SENTINEL }; define_arm_cp_regs(cpu, v6_idregs); @@ -5160,14 +5720,21 @@ void register_cp_regs_for_features(ARMCPU *cpu) */ unsigned int i, pmcrn = 4; ARMCPRegInfo pmcr = { - "PMCR", 15,9,12, 0,0,0, 0, - ARM_CP_IO | ARM_CP_ALIAS, PL0_RW, 0, NULL, 0, offsetoflow32(CPUARMState, cp15.c9_pmcr), {0, 0}, - pmreg_access, NULL,pmcr_write, NULL,raw_write, + .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0, + .access = PL0_RW, + .type = ARM_CP_IO | ARM_CP_ALIAS, + .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr), + .accessfn = pmreg_access, .writefn = pmcr_write, + .raw_writefn = raw_write, }; ARMCPRegInfo pmcr64 = { - "PMCR_EL0", 0,9,12, 3,3,0, ARM_CP_STATE_AA64, - ARM_CP_IO, PL0_RW, 0, NULL, (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT), offsetof(CPUARMState, cp15.c9_pmcr), {0, 0}, - pmreg_access, NULL,pmcr_write, NULL,raw_write, + .name = "PMCR_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 0, + .access = PL0_RW, .accessfn = pmreg_access, + .type = ARM_CP_IO, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr), + .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT), + .writefn = pmcr_write, .raw_writefn = raw_write, }; define_one_arm_cp_reg(cpu, &pmcr); define_one_arm_cp_reg(cpu, &pmcr64); @@ -5177,20 +5744,29 @@ void register_cp_regs_for_features(ARMCPU *cpu) char *pmevtyper_name = g_strdup_printf("PMEVTYPER%d", i); char *pmevtyper_el0_name = g_strdup_printf("PMEVTYPER%d_EL0", i); ARMCPRegInfo pmev_regs[] = { - { pmevcntr_name, 15, 14, 8 | (3 & (i >> 3)), 0,0,i & 7, - 0, ARM_CP_IO | ARM_CP_ALIAS, PL0_RW, 0, NULL, 0, 0, {0, 0}, - pmreg_access, pmevcntr_readfn, pmevcntr_writefn }, - { pmevcntr_el0_name, 0,14, 8 | (3 & (i >> 3)), 3,3,i & 7, - ARM_CP_STATE_AA64, ARM_CP_IO, PL0_RW, 0, NULL, 0, 0, {0, 0}, - pmreg_access, pmevcntr_readfn, pmevcntr_writefn, - pmevcntr_rawread, pmevcntr_rawwrite }, - { pmevtyper_name, 15,14,12 | (3 & (i >> 3)), 0,0,i & 7, - 0, ARM_CP_IO | ARM_CP_ALIAS, PL0_RW, 0, NULL, 0, 0, {0, 0}, - pmreg_access, pmevtyper_readfn, pmevtyper_writefn }, - { pmevtyper_el0_name, 0,14,12 | (3 & (i >> 3)), 3,3,i & 7, - ARM_CP_STATE_AA64, ARM_CP_IO, PL0_RW, 0, NULL, 0, 0, {0, 0}, - pmreg_access, pmevtyper_readfn, pmevtyper_writefn, NULL, - pmevtyper_rawwrite }, + { .name = pmevcntr_name, .cp = 15, .crn = 14, + .crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7, + .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS, + .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn, + .accessfn = pmreg_access }, + { .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 8 | (3 & (i >> 3)), + .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access, + .type = ARM_CP_IO, + .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn, + .raw_readfn = pmevcntr_rawread, + .raw_writefn = pmevcntr_rawwrite }, + { .name = pmevtyper_name, .cp = 15, .crn = 14, + .crm = 12 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7, + .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS, + .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn, + .accessfn = pmreg_access }, + { .name = pmevtyper_el0_name, .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 12 | (3 & (i >> 3)), + .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access, + .type = ARM_CP_IO, + .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn, + .raw_writefn = pmevtyper_rawwrite }, REGINFO_SENTINEL }; define_arm_cp_regs(cpu, pmev_regs); @@ -5200,8 +5776,9 @@ void register_cp_regs_for_features(ARMCPU *cpu) g_free(pmevtyper_el0_name); } ARMCPRegInfo clidr = { - "CLIDR", 0,0,0, 3,1,1, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->clidr + .name = "CLIDR", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1, + .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->clidr }; define_one_arm_cp_reg(cpu, &clidr); define_arm_cp_regs(cpu, v7_cp_reginfo); @@ -5212,10 +5789,14 @@ void register_cp_regs_for_features(ARMCPU *cpu) if (FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) >= 4 && FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) != 0xf) { ARMCPRegInfo v81_pmu_regs[] = { - { "PMCEID2", 15,9,14, 0,0,4, ARM_CP_STATE_AA32, ARM_CP_CONST, - PL0_R, 0, NULL, extract64(cpu->pmceid0, 32, 32), 0, {0, 0}, pmreg_access }, - { "PMCEID3", 15,9,14, 0,0,5, ARM_CP_STATE_AA32, ARM_CP_CONST, - PL0_R, 0, NULL, extract64(cpu->pmceid1, 32, 32), 0, {0, 0}, pmreg_access }, + { .name = "PMCEID2", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4, + .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST, + .resetvalue = extract64(cpu->pmceid0, 32, 32) }, + { .name = "PMCEID3", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 5, + .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST, + .resetvalue = extract64(cpu->pmceid1, 32, 32) }, REGINFO_SENTINEL }; define_arm_cp_regs(cpu, v81_pmu_regs); @@ -5231,100 +5812,184 @@ void register_cp_regs_for_features(ARMCPU *cpu) * know the right value for the GIC field until after we * define these regs. */ - { "ID_AA64PFR0_EL1", 0,0,4, 3,0,0, ARM_CP_STATE_AA64, - ARM_CP_NO_RAW, PL1_R, 0, NULL, cpu->isar.id_aa64pfr0, 0, {0, 0}, - NULL, id_aa64pfr0_read, arm_cp_write_ignore }, - { "ID_AA64PFR1_EL1", 0,0,4, 3,0,1, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->isar.id_aa64pfr1}, - { "ID_AA64PFR2_EL1_RESERVED", 0,0,4, 3,0,2, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "ID_AA64PFR3_EL1_RESERVED", 0,0,4, 3,0,3, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0,}, - { "ID_AA64ZFR0_EL1", 0,0,4, 3,0,4, ARM_CP_STATE_AA64, ARM_CP_CONST, + { .name = "ID_AA64PFR0_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 0, + .access = PL1_R, .type = ARM_CP_NO_RAW, + .readfn = id_aa64pfr0_read, + .writefn = arm_cp_write_ignore }, + { .name = "ID_AA64PFR1_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->isar.id_aa64pfr1}, + { .name = "ID_AA64PFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 2, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "ID_AA64PFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 3, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "ID_AA64ZFR0_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 4, + .access = PL1_R, .type = ARM_CP_CONST, /* At present, only SVEver == 0 is defined anyway. */ - PL1_R, 0, NULL, 0 }, - { "ID_AA64PFR5_EL1_RESERVED", 0,0,4, 3,0,5, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "ID_AA64PFR6_EL1_RESERVED", 0,0,4, 3,0,6, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "ID_AA64PFR7_EL1_RESERVED", 0,0,4, 3,0,7, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "ID_AA64DFR0_EL1", 0,0,5, 3,0,0, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->id_aa64dfr0 }, - { "ID_AA64DFR1_EL1", 0,0,5, 3,0,1, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->id_aa64dfr1 }, - { "ID_AA64DFR2_EL1_RESERVED", 0,0,5, 3,0,2, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "ID_AA64DFR3_EL1_RESERVED", 0,0,5, 3,0,3, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "ID_AA64AFR0_EL1", 0,0,5, 3,0,4, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->id_aa64afr0 }, - { "ID_AA64AFR1_EL1", 0,0,5, 3,0,5, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->id_aa64afr1 }, - { "ID_AA64AFR2_EL1_RESERVED", 0,0,5, 3,0,6, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "ID_AA64AFR3_EL1_RESERVED", 0,0,5, 3,0,7, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "ID_AA64ISAR0_EL1", 0,0,6, 3,0,0, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->isar.id_aa64isar0 }, - { "ID_AA64ISAR1_EL1", 0,0,6, 3,0,1, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->isar.id_aa64isar1 }, - { "ID_AA64ISAR2_EL1_RESERVED", 0,0,6, 3,0,2, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "ID_AA64ISAR3_EL1_RESERVED", 0,0,6, 3,0,3, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "ID_AA64ISAR4_EL1_RESERVED", 0,0,6, 3,0,4, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "ID_AA64ISAR5_EL1_RESERVED", 0,0,6, 3,0,5, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "ID_AA64ISAR6_EL1_RESERVED", 0,0,6, 3,0,6, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "ID_AA64ISAR7_EL1_RESERVED", 0,0,6, 3,0,7, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "ID_AA64MMFR0_EL1", 0,0,7, 3,0,0, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->isar.id_aa64mmfr0 }, - { "ID_AA64MMFR1_EL1", 0,0,7, 3,0,1, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->isar.id_aa64mmfr1 }, - { "ID_AA64MMFR2_EL1_RESERVED", 0,0,7, 3,0,2, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "ID_AA64MMFR3_EL1_RESERVED", 0,0,7, 3,0,3, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "ID_AA64MMFR4_EL1_RESERVED", 0,0,7, 3,0,4, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "ID_AA64MMFR5_EL1_RESERVED", 0,0,7, 3,0,5, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "ID_AA64MMFR6_EL1_RESERVED", 0,0,7, 3,0,6, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "ID_AA64MMFR7_EL1_RESERVED", 0,0,7, 3,0,7, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "MVFR0_EL1", 0,0,3, 3,0,0, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->isar.mvfr0 }, - { "MVFR1_EL1", 0,0,3, 3,0,1, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->isar.mvfr1 }, - { "MVFR2_EL1", 0,0,3, 3,0,2, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->isar.mvfr2 }, - { "MVFR3_EL1_RESERVED", 0,0,3, 3,0,3, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "MVFR4_EL1_RESERVED", 0,0,3, 3,0,4, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "MVFR5_EL1_RESERVED", 0,0,3, 3,0,5, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "MVFR6_EL1_RESERVED", 0,0,3, 3,0,6, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "MVFR7_EL1_RESERVED", 0,0,3, 3,0,7, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL1_R, 0, NULL, 0 }, - { "PMCEID0", 15,9,12, 0,0,6, ARM_CP_STATE_AA32, ARM_CP_CONST, - PL0_R, 0, NULL, extract64(cpu->pmceid0, 0, 32), 0, {0, 0}, - pmreg_access }, - { "PMCEID0_EL0", 0,9,12, 3,3,6, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL0_R, 0, NULL, cpu->pmceid0, 0, {0, 0}, - pmreg_access }, - { "PMCEID1", 15,9,12, 0,0,7, ARM_CP_STATE_AA32, ARM_CP_CONST, - PL0_R, 0, NULL, extract64(cpu->pmceid1, 0, 32), 0, {0, 0}, - pmreg_access }, - { "PMCEID1_EL0", 0,9,12, 3,3,7, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL0_R, 0, NULL, cpu->pmceid1, 0, {0, 0}, - pmreg_access }, + .resetvalue = 0 }, + { .name = "ID_AA64PFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 5, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "ID_AA64PFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 6, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "ID_AA64PFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 7, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "ID_AA64DFR0_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_aa64dfr0 }, + { .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_aa64dfr1 }, + { .name = "ID_AA64DFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 2, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "ID_AA64DFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 3, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "ID_AA64AFR0_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 4, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_aa64afr0 }, + { .name = "ID_AA64AFR1_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 5, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_aa64afr1 }, + { .name = "ID_AA64AFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 6, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "ID_AA64AFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 7, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "ID_AA64ISAR0_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 0, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->isar.id_aa64isar0 }, + { .name = "ID_AA64ISAR1_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->isar.id_aa64isar1 }, + { .name = "ID_AA64ISAR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "ID_AA64ISAR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 3, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "ID_AA64ISAR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 4, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "ID_AA64ISAR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 5, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "ID_AA64ISAR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 6, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "ID_AA64ISAR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 7, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "ID_AA64MMFR0_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->isar.id_aa64mmfr0 }, + { .name = "ID_AA64MMFR1_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->isar.id_aa64mmfr1 }, + { .name = "ID_AA64MMFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "ID_AA64MMFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 3, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "ID_AA64MMFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 4, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "ID_AA64MMFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 5, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "ID_AA64MMFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 6, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "ID_AA64MMFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 7, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "MVFR0_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 0, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->isar.mvfr0 }, + { .name = "MVFR1_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 1, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->isar.mvfr1 }, + { .name = "MVFR2_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->isar.mvfr2 }, + { .name = "MVFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 3, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "MVFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 4, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "MVFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 5, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "MVFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 6, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "MVFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 7, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "PMCEID0", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 6, + .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST, + .resetvalue = extract64(cpu->pmceid0, 0, 32) }, + { .name = "PMCEID0_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 6, + .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST, + .resetvalue = cpu->pmceid0 }, + { .name = "PMCEID1", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 7, + .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST, + .resetvalue = extract64(cpu->pmceid1, 0, 32) }, + { .name = "PMCEID1_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 7, + .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST, + .resetvalue = cpu->pmceid1 }, REGINFO_SENTINEL }; #ifdef CONFIG_USER_ONLY @@ -5363,8 +6028,9 @@ void register_cp_regs_for_features(ARMCPU *cpu) if (!arm_feature(env, ARM_FEATURE_EL3) && !arm_feature(env, ARM_FEATURE_EL2)) { ARMCPRegInfo rvbar = { - "RVBAR_EL1", 0,12,0, 3,0,1, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->rvbar + .name = "RVBAR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1, + .type = ARM_CP_CONST, .access = PL1_R, .resetvalue = cpu->rvbar }; define_one_arm_cp_reg(cpu, &rvbar); } @@ -5374,16 +6040,25 @@ void register_cp_regs_for_features(ARMCPU *cpu) if (arm_feature(env, ARM_FEATURE_EL2)) { uint64_t vmpidr_def = mpidr_read_val(env); ARMCPRegInfo vpidr_regs[] = { - { "VPIDR", 15,0,0, 0,4,0, ARM_CP_STATE_AA32, ARM_CP_ALIAS, - PL2_RW, 0, NULL, cpu->midr, offsetoflow32(CPUARMState, cp15.vpidr_el2), {0, 0}, - access_el3_aa32ns }, - { "VPIDR_EL2", 0,0,0, 3,4,0, ARM_CP_STATE_AA64, 0, - PL2_RW, 0, NULL, cpu->midr, offsetof(CPUARMState, cp15.vpidr_el2) }, - { "VMPIDR", 15,0,0, 0,4,5, ARM_CP_STATE_AA32, ARM_CP_ALIAS, - PL2_RW, 0, NULL, vmpidr_def, offsetoflow32(CPUARMState, cp15.vmpidr_el2), {0, 0}, - access_el3_aa32ns }, - { "VMPIDR_EL2", 0,0,0, 3,4,5, ARM_CP_STATE_AA64, 0, - PL2_RW, 0, NULL, vmpidr_def, offsetof(CPUARMState, cp15.vmpidr_el2) }, + { .name = "VPIDR", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0, + .access = PL2_RW, .accessfn = access_el3_aa32ns, + .resetvalue = cpu->midr, .type = ARM_CP_ALIAS, + .fieldoffset = offsetoflow32(CPUARMState, cp15.vpidr_el2) }, + { .name = "VPIDR_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0, + .access = PL2_RW, .resetvalue = cpu->midr, + .fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) }, + { .name = "VMPIDR", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5, + .access = PL2_RW, .accessfn = access_el3_aa32ns, + .resetvalue = vmpidr_def, .type = ARM_CP_ALIAS, + .fieldoffset = offsetoflow32(CPUARMState, cp15.vmpidr_el2) }, + { .name = "VMPIDR_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5, + .access = PL2_RW, + .resetvalue = vmpidr_def, + .fieldoffset = offsetof(CPUARMState, cp15.vmpidr_el2) }, REGINFO_SENTINEL }; define_arm_cp_regs(cpu, vpidr_regs); @@ -5394,8 +6069,9 @@ void register_cp_regs_for_features(ARMCPU *cpu) /* RVBAR_EL2 is only implemented if EL2 is the highest EL */ if (!arm_feature(env, ARM_FEATURE_EL3)) { ARMCPRegInfo rvbar = { - "RVBAR_EL2", 0,12,0, 3,4,1, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL2_R, 0, NULL, cpu->rvbar + .name = "RVBAR_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 1, + .type = ARM_CP_CONST, .access = PL2_R, .resetvalue = cpu->rvbar }; define_one_arm_cp_reg(cpu, &rvbar); } @@ -5408,12 +6084,16 @@ void register_cp_regs_for_features(ARMCPU *cpu) * of MIDR_EL1 and MPIDR_EL1. */ ARMCPRegInfo vpidr_regs[] = { - { "VPIDR_EL2", 0,0,0, 3,4,0, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL2_RW, 0, NULL, cpu->midr, offsetof(CPUARMState, cp15.vpidr_el2), {0, 0}, - access_el3_aa32ns_aa64any }, - { "VMPIDR_EL2", 0,0,0, 3,4,5, ARM_CP_STATE_BOTH, ARM_CP_NO_RAW, - PL2_RW, 0, NULL, 0, 0, {0, 0}, - access_el3_aa32ns_aa64any, mpidr_read, arm_cp_write_ignore }, + { .name = "VPIDR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0, + .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any, + .type = ARM_CP_CONST, .resetvalue = cpu->midr, + .fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) }, + { .name = "VMPIDR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5, + .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any, + .type = ARM_CP_NO_RAW, + .writefn = arm_cp_write_ignore, .readfn = mpidr_read }, REGINFO_SENTINEL }; define_arm_cp_regs(cpu, vpidr_regs); @@ -5426,11 +6106,16 @@ void register_cp_regs_for_features(ARMCPU *cpu) if (arm_feature(env, ARM_FEATURE_EL3)) { define_arm_cp_regs(cpu, el3_cp_reginfo); ARMCPRegInfo el3_regs[] = { - { "RVBAR_EL3", 0,12,0, 3,6,1, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL3_R, 0, NULL, cpu->rvbar }, - { "SCTLR_EL3", 0,1,0, 3,6,0, ARM_CP_STATE_AA64, 0, - PL3_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.sctlr_el[3]), {0, 0}, - NULL, NULL, sctlr_write, NULL, raw_write, }, + { .name = "RVBAR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 1, + .type = ARM_CP_CONST, .access = PL3_R, .resetvalue = cpu->rvbar }, + { .name = "SCTLR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 0, .opc2 = 0, + .access = PL3_RW, + .raw_writefn = raw_write, .writefn = sctlr_write, + .fieldoffset = offsetof(CPUARMState, cp15.sctlr_el[3]), + .resetvalue = cpu->reset_sctlr }, + REGINFO_SENTINEL }; define_arm_cp_regs(cpu, el3_regs); @@ -5446,23 +6131,29 @@ void register_cp_regs_for_features(ARMCPU *cpu) if (arm_feature(env, ARM_FEATURE_EL3)) { if (arm_feature(env, ARM_FEATURE_AARCH64)) { ARMCPRegInfo nsacr = { - "NSACR", 15,1,1, 0,0,2, 0, ARM_CP_CONST, - PL1_RW, 0, NULL, 0xc00, 0, {0, 0}, - nsacr_access + .name = "NSACR", .type = ARM_CP_CONST, + .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2, + .access = PL1_RW, .accessfn = nsacr_access, + .resetvalue = 0xc00 }; define_one_arm_cp_reg(cpu, &nsacr); } else { ARMCPRegInfo nsacr = { - "NSACR", 15,1,1, 0,0,2, 0,0, - PL3_RW | PL1_R, 0, NULL, 0, offsetof(CPUARMState, cp15.nsacr) + .name = "NSACR", + .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2, + .access = PL3_RW | PL1_R, + .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.nsacr) }; define_one_arm_cp_reg(cpu, &nsacr); } } else { if (arm_feature(env, ARM_FEATURE_V8)) { ARMCPRegInfo nsacr = { - "NSACR", 15,1,1, 0,0,2, 0, ARM_CP_CONST, - PL1_R, 0, NULL, 0xc00 + .name = "NSACR", .type = ARM_CP_CONST, + .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2, + .access = PL1_R, + .resetvalue = 0xc00 }; define_one_arm_cp_reg(cpu, &nsacr); } @@ -5533,65 +6224,81 @@ void register_cp_regs_for_features(ARMCPU *cpu) * MIDR. Define MIDR first as this entire space, then CTR, TCMTR * and friends override accordingly. */ - { "MIDR", 15,0,0, 0,0,CP_ANY, 0, - ARM_CP_OVERRIDE, PL1_R, 0, NULL, cpu->midr, offsetof(CPUARMState, cp15.c0_cpuid), {0, 0}, - NULL, midr_read, arm_cp_write_ignore, NULL, raw_write, }, + { .name = "MIDR", + .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = CP_ANY, + .access = PL1_R, .resetvalue = cpu->midr, + .writefn = arm_cp_write_ignore, .raw_writefn = raw_write, + .readfn = midr_read, + .fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid), + .type = ARM_CP_OVERRIDE }, /* crn = 0 op1 = 0 crm = 3..7 : currently unassigned; we RAZ. */ - { "DUMMY", - 15,0,3, 0,0,CP_ANY, 0, - ARM_CP_CONST, PL1_R, 0, NULL, 0 }, - { "DUMMY", - 15,0,4, 0,0,CP_ANY, 0, - ARM_CP_CONST, PL1_R, 0, NULL, 0 }, - { "DUMMY", - 15,0,5, 0,0,CP_ANY, 0, - ARM_CP_CONST, PL1_R, 0, NULL, 0 }, - { "DUMMY", - 15,0,6, 0,0,CP_ANY, 0, - ARM_CP_CONST, PL1_R, 0, NULL, 0 }, - { "DUMMY", - 15,0,7, 0,0,CP_ANY, 0, - ARM_CP_CONST, PL1_R, 0, NULL, 0 }, + { .name = "DUMMY", + .cp = 15, .crn = 0, .crm = 3, .opc1 = 0, .opc2 = CP_ANY, + .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "DUMMY", + .cp = 15, .crn = 0, .crm = 4, .opc1 = 0, .opc2 = CP_ANY, + .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "DUMMY", + .cp = 15, .crn = 0, .crm = 5, .opc1 = 0, .opc2 = CP_ANY, + .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "DUMMY", + .cp = 15, .crn = 0, .crm = 6, .opc1 = 0, .opc2 = CP_ANY, + .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "DUMMY", + .cp = 15, .crn = 0, .crm = 7, .opc1 = 0, .opc2 = CP_ANY, + .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, REGINFO_SENTINEL }; ARMCPRegInfo id_v8_midr_cp_reginfo[] = { - { "MIDR_EL1", 0,0,0, 3,0,0, ARM_CP_STATE_BOTH, - ARM_CP_NO_RAW, PL1_R, 0, NULL, cpu->midr, offsetof(CPUARMState, cp15.c0_cpuid), {0, 0}, - NULL, midr_read }, + { .name = "MIDR_EL1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 0, + .access = PL1_R, .type = ARM_CP_NO_RAW, .resetvalue = cpu->midr, + .fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid), + .readfn = midr_read }, /* crn = 0 op1 = 0 crm = 0 op2 = 4,7 : AArch32 aliases of MIDR */ - { "MIDR", 15,0,0, 0,0,4, 0, ARM_CP_ALIAS | ARM_CP_CONST, - PL1_R, 0, NULL, cpu->midr }, - { "MIDR", 15,0,0, 0,0,7, 0, ARM_CP_ALIAS | ARM_CP_CONST, - PL1_R, 0, NULL, cpu->midr }, - { "REVIDR_EL1", 0,0,0, 3,0,6, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->revidr }, + { .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST, + .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4, + .access = PL1_R, .resetvalue = cpu->midr }, + { .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST, + .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 7, + .access = PL1_R, .resetvalue = cpu->midr }, + { .name = "REVIDR_EL1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 6, + .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->revidr }, REGINFO_SENTINEL }; ARMCPRegInfo id_cp_reginfo[] = { /* These are common to v8 and pre-v8 */ - { "CTR", 15,0,0, 0,0,1, 0, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->ctr }, - { "CTR_EL0", 0,0,0, 3,3,1, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL0_R, 0, NULL, cpu->ctr, 0, {0, 0}, - ctr_el0_access, }, + { .name = "CTR", + .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 1, + .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->ctr }, + { .name = "CTR_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 0, .crm = 0, + .access = PL0_R, .accessfn = ctr_el0_access, + .type = ARM_CP_CONST, .resetvalue = cpu->ctr }, /* TCMTR and TLBTR exist in v8 but have no 64-bit versions */ - { "TCMTR", 15,0,0, 0,0,2, 0, - ARM_CP_CONST, PL1_R, 0, NULL, 0 }, + { .name = "TCMTR", + .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 2, + .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, REGINFO_SENTINEL }; /* TLBTR is specific to VMSA */ ARMCPRegInfo id_tlbtr_reginfo = { - "TLBTR", 15,0,0, 0,0,3, 0, - ARM_CP_CONST, PL1_R, 0, NULL, 0, + .name = "TLBTR", + .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 3, + .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0, }; /* MPUIR is specific to PMSA V6+ */ ARMCPRegInfo id_mpuir_reginfo = { - "MPUIR", 15,0,0, 0,0,4, 0,ARM_CP_CONST, - PL1_R, 0, NULL, cpu->pmsav7_dregion << 8 + .name = "MPUIR", + .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->pmsav7_dregion << 8 }; ARMCPRegInfo crn0_wi_reginfo = { - "CRN0_WI", 15,0,CP_ANY, 0,CP_ANY,CP_ANY, 0, - ARM_CP_NOP | ARM_CP_OVERRIDE, PL1_W, + .name = "CRN0_WI", .cp = 15, .crn = 0, .crm = CP_ANY, + .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W, + .type = ARM_CP_NOP | ARM_CP_OVERRIDE }; #ifdef CONFIG_USER_ONLY ARMCPRegUserSpaceInfo id_v8_user_midr_cp_reginfo[] = { @@ -5654,20 +6361,28 @@ void register_cp_regs_for_features(ARMCPU *cpu) if (arm_feature(env, ARM_FEATURE_AUXCR)) { ARMCPRegInfo auxcr_reginfo[] = { - { "ACTLR_EL1", 0,1,0, 3,0,1, ARM_CP_STATE_BOTH, - ARM_CP_CONST, PL1_RW, 0, NULL, cpu->reset_auxcr }, - { "ACTLR_EL2",0,1,0, 3,4,1, ARM_CP_STATE_BOTH, ARM_CP_CONST, - PL2_RW, 0, NULL, 0 }, - { "ACTLR_EL3", 0,1,0, 3,6,1, ARM_CP_STATE_AA64, ARM_CP_CONST, - PL3_RW, 0, NULL, 0 }, + { .name = "ACTLR_EL1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 1, + .access = PL1_RW, .type = ARM_CP_CONST, + .resetvalue = cpu->reset_auxcr }, + { .name = "ACTLR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 1, + .access = PL2_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "ACTLR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 0, .opc2 = 1, + .access = PL3_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, REGINFO_SENTINEL }; define_arm_cp_regs(cpu, auxcr_reginfo); if (arm_feature(env, ARM_FEATURE_V8)) { /* HACTLR2 maps to ACTLR_EL2[63:32] and is not in ARMv7 */ ARMCPRegInfo hactlr2_reginfo = { - "HACTLR2", 15,1,0, 0,4,3, ARM_CP_STATE_AA32, - ARM_CP_CONST, PL2_RW, 0, NULL, 0 + .name = "HACTLR2", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 3, + .access = PL2_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }; define_one_arm_cp_reg(cpu, &hactlr2_reginfo); } @@ -5679,10 +6394,14 @@ void register_cp_regs_for_features(ARMCPU *cpu) uint32_t cbar32 = (extract64(cpu->reset_cbar, 18, 14) << 18) | extract64(cpu->reset_cbar, 32, 12); ARMCPRegInfo cbar_reginfo[] = { - { "CBAR", 15,15,0, 0,4,0, 0, - ARM_CP_CONST, PL1_R, 0, NULL, cpu->reset_cbar }, - { "CBAR_EL1", 0,15,3, 3,1,0, ARM_CP_STATE_AA64, - ARM_CP_CONST, PL1_R, 0, NULL, cbar32 }, + { .name = "CBAR", + .type = ARM_CP_CONST, + .cp = 15, .crn = 15, .crm = 0, .opc1 = 4, .opc2 = 0, + .access = PL1_R, .resetvalue = cpu->reset_cbar }, + { .name = "CBAR_EL1", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_CONST, + .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 0, + .access = PL1_R, .resetvalue = cbar32 }, REGINFO_SENTINEL }; /* We don't implement a r/w 64 bit CBAR currently */ @@ -5690,8 +6409,11 @@ void register_cp_regs_for_features(ARMCPU *cpu) define_arm_cp_regs(cpu, cbar_reginfo); } else { ARMCPRegInfo cbar = { - "CBAR", 15,15,0, 0,4,0, 0, - 0, PL1_R|PL3_W, 0, NULL, cpu->reset_cbar, offsetof(CPUARMState, cp15.c15_config_base_address) + .name = "CBAR", + .cp = 15, .crn = 15, .crm = 0, .opc1 = 4, .opc2 = 0, + .access = PL1_R|PL3_W, .resetvalue = cpu->reset_cbar, + .fieldoffset = offsetof(CPUARMState, + cp15.c15_config_base_address) }; if (arm_feature(env, ARM_FEATURE_CBAR_RO)) { cbar.access = PL1_R; @@ -5704,11 +6426,12 @@ void register_cp_regs_for_features(ARMCPU *cpu) if (arm_feature(env, ARM_FEATURE_VBAR)) { ARMCPRegInfo vbar_cp_reginfo[] = { - { "VBAR", 0,12,0, 3,0,0, ARM_CP_STATE_BOTH, 0, - PL1_RW, 0, NULL, 0, 0, - { offsetof(CPUARMState, cp15.vbar_s), - offsetof(CPUARMState, cp15.vbar_ns) }, - NULL, NULL, 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 }, REGINFO_SENTINEL }; define_arm_cp_regs(cpu, vbar_cp_reginfo); @@ -5717,10 +6440,13 @@ void register_cp_regs_for_features(ARMCPU *cpu) /* Generic registers whose values depend on the implementation */ { ARMCPRegInfo sctlr = { - "SCTLR", 0,1,0, 3,0,0, ARM_CP_STATE_BOTH, - 0, PL1_RW, 0, NULL, cpu->reset_sctlr, 0, - {offsetof(CPUARMState, cp15.sctlr_s), offsetof(CPUARMState, cp15.sctlr_ns)}, - NULL, NULL,sctlr_write, NULL,raw_write, + .name = "SCTLR", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0, + .access = PL1_RW, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.sctlr_s), + offsetof(CPUARMState, cp15.sctlr_ns) }, + .writefn = sctlr_write, .resetvalue = cpu->reset_sctlr, + .raw_writefn = raw_write, }; if (arm_feature(env, ARM_FEATURE_XSCALE)) { /* Normally we would always end the TB on an SCTLR write, but Linux