aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-04-29 17:35:58 +0100
committerPeter Maydell <peter.maydell@linaro.org>2019-04-29 17:35:58 +0100
commitd33abe82c7c9847284a23e575e1078cccab540b5 (patch)
tree9878dcce1f87a2ac46c0e89044829392c240e64b /target
parent84d2e3e2ae76fdb0c8f3063fa8c46c8ce14ab201 (diff)
downloadqemu-d33abe82c7c9847284a23e575e1078cccab540b5.zip
qemu-d33abe82c7c9847284a23e575e1078cccab540b5.tar.gz
qemu-d33abe82c7c9847284a23e575e1078cccab540b5.tar.bz2
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.c5
-rw-r--r--target/arm/cpu.h34
-rw-r--r--target/arm/machine.c16
3 files changed, 55 insertions, 0 deletions
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index bb9fdc6..be81e19 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 f7f2f5a..67e4e95 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 b292549..09567d4 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
}
};