diff options
author | Fabian Aggeler <aggelerf@ethz.ch> | 2014-12-11 12:07:52 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2014-12-11 12:07:52 +0000 |
commit | 54bf36ed351c526cde0c853079f9ff1ab7e2ff89 (patch) | |
tree | 475c6b03dddd779267e58c250e0aeaf32322d4db /target-arm/helper.c | |
parent | fb6c91ba2bb0b1c1b8662ceeeeb9474a025f9a6b (diff) |
target-arm: make c13 cp regs banked (FCSEIDR, ...)
When EL3 is running in AArch32 (or ARMv7 with Security Extensions)
FCSEIDR, CONTEXTIDR, TPIDRURW, TPIDRURO and TPIDRPRW have a secure
and a non-secure instance.
Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1416242878-876-25-git-send-email-greg.bellows@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-arm/helper.c')
-rw-r--r-- | target-arm/helper.c | 58 |
1 files changed, 45 insertions, 13 deletions
diff --git a/target-arm/helper.c b/target-arm/helper.c index bc73c4fbbf..0357f41e9a 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -424,13 +424,36 @@ static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri, } static const ARMCPRegInfo cp_reginfo[] = { - { .name = "FCSEIDR", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c13_fcse), + /* Define the secure and non-secure FCSE 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. There is also no + * v8 EL1 version of the register so the non-secure instance stands alone. + */ + { .name = "FCSEIDR(NS)", + .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, }, - { .name = "CONTEXTIDR", .state = ARM_CP_STATE_BOTH, + /* 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. + */ + { .name = "CONTEXTIDR_EL1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1, - .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el1), + .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 }; @@ -1031,23 +1054,31 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = { { .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_el0), .resetvalue = 0 }, + .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[0]), .resetvalue = 0 }, { .name = "TPIDRURW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 2, .access = PL0_RW, - .fieldoffset = offsetoflow32(CPUARMState, cp15.tpidr_el0), + .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_el0), .resetvalue = 0 }, + .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, - .fieldoffset = offsetoflow32(CPUARMState, cp15.tpidrro_el0), + .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidruro_s), + offsetoflow32(CPUARMState, cp15.tpidruro_ns) }, .resetfn = arm_cp_reset_ignore }, - { .name = "TPIDR_EL1", .state = ARM_CP_STATE_BOTH, + { .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_el1), .resetvalue = 0 }, + .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 }; @@ -5051,8 +5082,9 @@ static inline int get_phys_addr(CPUARMState *env, target_ulong address, uint32_t sctlr = A32_BANKED_CURRENT_REG_GET(env, sctlr); /* Fast Context Switch Extension. */ - if (address < 0x02000000) - address += env->cp15.c13_fcse; + if (address < 0x02000000) { + address += A32_BANKED_CURRENT_REG_GET(env, fcseidr); + } if ((sctlr & SCTLR_M) == 0) { /* MMU/MPU disabled. */ |