From a4f332f3e9204c14f73077dacac1940343e135b8 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Tue, 30 Apr 2019 10:13:39 -0400 Subject: [PATCH] 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 Backports commit d33abe82c7c9847284a23e575e1078cccab540b5 from qemu --- qemu/target/arm/cpu.c | 5 +++++ qemu/target/arm/cpu.h | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/qemu/target/arm/cpu.c b/qemu/target/arm/cpu.c index 5ad45670..325bcf47 100644 --- a/qemu/target/arm/cpu.c +++ b/qemu/target/arm/cpu.c @@ -275,6 +275,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/qemu/target/arm/cpu.h b/qemu/target/arm/cpu.h index 4bf0ca5d..d41a4660 100644 --- a/qemu/target/arm/cpu.h +++ b/qemu/target/arm/cpu.h @@ -522,6 +522,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: @@ -1518,6 +1523,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. */