diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2019-04-29 17:35:58 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-04-29 17:35:58 +0100 |
commit | d33abe82c7c9847284a23e575e1078cccab540b5 (patch) | |
tree | 9878dcce1f87a2ac46c0e89044829392c240e64b /target | |
parent | 84d2e3e2ae76fdb0c8f3063fa8c46c8ce14ab201 (diff) |
target/arm: Implement dummy versions of M-profile FP-related registers
The M-profile floating point support has three associated config
registers: FPCAR, FPCCR and FPDSCR. It also makes the registers
CPACR and NSACR have behaviour other than reads-as-zero.
Add support for all of these as simple reads-as-written registers.
We will hook up actual functionality later.
The main complexity here is handling the FPCCR register, which
has a mix of banked and unbanked bits.
Note that we don't share storage with the A-profile
cpu->cp15.nsacr and cpu->cp15.cpacr_el1, though the behaviour
is quite similar, for two reasons:
* the M profile CPACR is banked between security states
* it preserves the invariant that M profile uses no state
inside the cp15 substruct
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20190416125744.27770-4-peter.maydell@linaro.org
Diffstat (limited to 'target')
-rw-r--r-- | target/arm/cpu.c | 5 | ||||
-rw-r--r-- | target/arm/cpu.h | 34 | ||||
-rw-r--r-- | target/arm/machine.c | 16 |
3 files changed, 55 insertions, 0 deletions
diff --git a/target/arm/cpu.c b/target/arm/cpu.c index bb9fdc6304..be81e197ee 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -281,6 +281,11 @@ static void arm_cpu_reset(CPUState *s) env->v7m.ccr[M_REG_S] |= R_V7M_CCR_UNALIGN_TRP_MASK; } + if (arm_feature(env, ARM_FEATURE_VFP)) { + env->v7m.fpccr[M_REG_NS] = R_V7M_FPCCR_ASPEN_MASK; + env->v7m.fpccr[M_REG_S] = R_V7M_FPCCR_ASPEN_MASK | + R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK; + } /* Unlike A/R profile, M profile defines the reset LR value */ env->regs[14] = 0xffffffff; diff --git a/target/arm/cpu.h b/target/arm/cpu.h index f7f2f5a99c..67e4e95d44 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -533,6 +533,11 @@ typedef struct CPUARMState { uint32_t scr[M_REG_NUM_BANKS]; uint32_t msplim[M_REG_NUM_BANKS]; uint32_t psplim[M_REG_NUM_BANKS]; + uint32_t fpcar[M_REG_NUM_BANKS]; + uint32_t fpccr[M_REG_NUM_BANKS]; + uint32_t fpdscr[M_REG_NUM_BANKS]; + uint32_t cpacr[M_REG_NUM_BANKS]; + uint32_t nsacr; } v7m; /* Information associated with an exception about to be taken: @@ -1576,6 +1581,35 @@ FIELD(V7M_CSSELR, LEVEL, 1, 3) */ FIELD(V7M_CSSELR, INDEX, 0, 4) +/* v7M FPCCR bits */ +FIELD(V7M_FPCCR, LSPACT, 0, 1) +FIELD(V7M_FPCCR, USER, 1, 1) +FIELD(V7M_FPCCR, S, 2, 1) +FIELD(V7M_FPCCR, THREAD, 3, 1) +FIELD(V7M_FPCCR, HFRDY, 4, 1) +FIELD(V7M_FPCCR, MMRDY, 5, 1) +FIELD(V7M_FPCCR, BFRDY, 6, 1) +FIELD(V7M_FPCCR, SFRDY, 7, 1) +FIELD(V7M_FPCCR, MONRDY, 8, 1) +FIELD(V7M_FPCCR, SPLIMVIOL, 9, 1) +FIELD(V7M_FPCCR, UFRDY, 10, 1) +FIELD(V7M_FPCCR, RES0, 11, 15) +FIELD(V7M_FPCCR, TS, 26, 1) +FIELD(V7M_FPCCR, CLRONRETS, 27, 1) +FIELD(V7M_FPCCR, CLRONRET, 28, 1) +FIELD(V7M_FPCCR, LSPENS, 29, 1) +FIELD(V7M_FPCCR, LSPEN, 30, 1) +FIELD(V7M_FPCCR, ASPEN, 31, 1) +/* These bits are banked. Others are non-banked and live in the M_REG_S bank */ +#define R_V7M_FPCCR_BANKED_MASK \ + (R_V7M_FPCCR_LSPACT_MASK | \ + R_V7M_FPCCR_USER_MASK | \ + R_V7M_FPCCR_THREAD_MASK | \ + R_V7M_FPCCR_MMRDY_MASK | \ + R_V7M_FPCCR_SPLIMVIOL_MASK | \ + R_V7M_FPCCR_UFRDY_MASK | \ + R_V7M_FPCCR_ASPEN_MASK) + /* * System register ID fields. */ diff --git a/target/arm/machine.c b/target/arm/machine.c index b292549614..09567d4fc6 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -305,6 +305,21 @@ static const VMStateDescription vmstate_m_v8m = { } }; +static const VMStateDescription vmstate_m_fp = { + .name = "cpu/m/fp", + .version_id = 1, + .minimum_version_id = 1, + .needed = vfp_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(env.v7m.fpcar, ARMCPU, M_REG_NUM_BANKS), + VMSTATE_UINT32_ARRAY(env.v7m.fpccr, ARMCPU, M_REG_NUM_BANKS), + VMSTATE_UINT32_ARRAY(env.v7m.fpdscr, ARMCPU, M_REG_NUM_BANKS), + VMSTATE_UINT32_ARRAY(env.v7m.cpacr, ARMCPU, M_REG_NUM_BANKS), + VMSTATE_UINT32(env.v7m.nsacr, ARMCPU), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_m = { .name = "cpu/m", .version_id = 4, @@ -330,6 +345,7 @@ static const VMStateDescription vmstate_m = { &vmstate_m_scr, &vmstate_m_other_sp, &vmstate_m_v8m, + &vmstate_m_fp, NULL } }; |