All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 00/11] v8m: minor missing regs and bugfixes
@ 2018-02-09 16:57 Peter Maydell
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 01/11] hw/intc/armv7m_nvic: Don't hardcode M profile ID registers in NVIC Peter Maydell
                   ` (10 more replies)
  0 siblings, 11 replies; 22+ messages in thread
From: Peter Maydell @ 2018-02-09 16:57 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

This patchset is the result of comparing the registers
listed in the v8M Arm ARM against what QEMU was implementing.
It adds a collection of generally unexciting missing registers
(most of which we can simply NOP or make reads-as-written).
There are also a couple of bug fixes in there, of which the
worst is the byte-to-interrupt-number conversions being
completely wrong in several places.

Version 2 adds 3 new patches at the end:
 * we had a couple of things we were forgetting to migrate
 * implementation of MSPLIM and PSPLIM, which were the missing
   special registers

I've updated the cache ID registers patch to use some constants
for register bit fields; otherwise the first 8 patches are the
same as v1. The derived-exceptions patches are in master now,
so this should apply to master.

thanks
-- PMM

Peter Maydell (11):
  hw/intc/armv7m_nvic: Don't hardcode M profile ID registers in NVIC
  hw/intc/armv7m_nvic: Fix ICSR PENDNMISET/CLR handling
  hw/intc/armv7m_nvic: Implement M profile cache maintenance ops
  hw/intc/armv7m_nvic: Implement v8M CPPWR register
  hw/intc/armv7m_nvic: Implement cache ID registers
  hw/intc/armv7m_nvic: Implement SCR
  target/arm: Implement writing to CONTROL_NS for v8M
  hw/intc/armv7m_nvic: Fix byte-to-interrupt number conversions
  target/arm: Add AIRCR to vmstate struct
  target/arm: Migrate v7m.other_sp
  target/arm: Implement v8M MSPLIM and PSPLIM registers

 target/arm/cpu.h      | 35 ++++++++++++++++++
 hw/intc/armv7m_nvic.c | 98 ++++++++++++++++++++++++++++++++++++++-------------
 target/arm/cpu.c      | 28 +++++++++++++++
 target/arm/helper.c   | 56 +++++++++++++++++++++++++++++
 target/arm/machine.c  | 84 +++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 276 insertions(+), 25 deletions(-)

-- 
2.16.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH v2 01/11] hw/intc/armv7m_nvic: Don't hardcode M profile ID registers in NVIC
  2018-02-09 16:57 [Qemu-devel] [PATCH v2 00/11] v8m: minor missing regs and bugfixes Peter Maydell
@ 2018-02-09 16:58 ` Peter Maydell
  2018-02-09 20:28   ` Richard Henderson
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 02/11] hw/intc/armv7m_nvic: Fix ICSR PENDNMISET/CLR handling Peter Maydell
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: Peter Maydell @ 2018-02-09 16:58 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

Instead of hardcoding the values of M profile ID registers in the
NVIC, use the fields in the CPU struct. This will allow us to
give different M profile CPU types different ID register values.

This commit includes the addition of the missing ID_ISAR5,
which exists as RES0 in both v7M and v8M.

(The values of the ID registers might be wrong for the M4 --
this commit leaves the behaviour there unchanged.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 hw/intc/armv7m_nvic.c | 30 ++++++++++++++++--------------
 target/arm/cpu.c      | 28 ++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 360889d30b..63da0fee34 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -990,31 +990,33 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
                       "Aux Fault status registers unimplemented\n");
         return 0;
     case 0xd40: /* PFR0.  */
-        return 0x00000030;
-    case 0xd44: /* PRF1.  */
-        return 0x00000200;
+        return cpu->id_pfr0;
+    case 0xd44: /* PFR1.  */
+        return cpu->id_pfr1;
     case 0xd48: /* DFR0.  */
-        return 0x00100000;
+        return cpu->id_dfr0;
     case 0xd4c: /* AFR0.  */
-        return 0x00000000;
+        return cpu->id_afr0;
     case 0xd50: /* MMFR0.  */
-        return 0x00000030;
+        return cpu->id_mmfr0;
     case 0xd54: /* MMFR1.  */
-        return 0x00000000;
+        return cpu->id_mmfr1;
     case 0xd58: /* MMFR2.  */
-        return 0x00000000;
+        return cpu->id_mmfr2;
     case 0xd5c: /* MMFR3.  */
-        return 0x00000000;
+        return cpu->id_mmfr3;
     case 0xd60: /* ISAR0.  */
-        return 0x01141110;
+        return cpu->id_isar0;
     case 0xd64: /* ISAR1.  */
-        return 0x02111000;
+        return cpu->id_isar1;
     case 0xd68: /* ISAR2.  */
-        return 0x21112231;
+        return cpu->id_isar2;
     case 0xd6c: /* ISAR3.  */
-        return 0x01111110;
+        return cpu->id_isar3;
     case 0xd70: /* ISAR4.  */
-        return 0x01310102;
+        return cpu->id_isar4;
+    case 0xd74: /* ISAR5.  */
+        return cpu->id_isar5;
     /* TODO: Implement debug registers.  */
     case 0xd90: /* MPU_TYPE */
         /* Unified MPU; if the MPU is not present this value is zero */
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 89ccdeae12..d796085be9 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1146,6 +1146,20 @@ static void cortex_m3_initfn(Object *obj)
     set_feature(&cpu->env, ARM_FEATURE_M);
     cpu->midr = 0x410fc231;
     cpu->pmsav7_dregion = 8;
+    cpu->id_pfr0 = 0x00000030;
+    cpu->id_pfr1 = 0x00000200;
+    cpu->id_dfr0 = 0x00100000;
+    cpu->id_afr0 = 0x00000000;
+    cpu->id_mmfr0 = 0x00000030;
+    cpu->id_mmfr1 = 0x00000000;
+    cpu->id_mmfr2 = 0x00000000;
+    cpu->id_mmfr3 = 0x00000000;
+    cpu->id_isar0 = 0x01141110;
+    cpu->id_isar1 = 0x02111000;
+    cpu->id_isar2 = 0x21112231;
+    cpu->id_isar3 = 0x01111110;
+    cpu->id_isar4 = 0x01310102;
+    cpu->id_isar5 = 0x00000000;
 }
 
 static void cortex_m4_initfn(Object *obj)
@@ -1157,6 +1171,20 @@ static void cortex_m4_initfn(Object *obj)
     set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
     cpu->midr = 0x410fc240; /* r0p0 */
     cpu->pmsav7_dregion = 8;
+    cpu->id_pfr0 = 0x00000030;
+    cpu->id_pfr1 = 0x00000200;
+    cpu->id_dfr0 = 0x00100000;
+    cpu->id_afr0 = 0x00000000;
+    cpu->id_mmfr0 = 0x00000030;
+    cpu->id_mmfr1 = 0x00000000;
+    cpu->id_mmfr2 = 0x00000000;
+    cpu->id_mmfr3 = 0x00000000;
+    cpu->id_isar0 = 0x01141110;
+    cpu->id_isar1 = 0x02111000;
+    cpu->id_isar2 = 0x21112231;
+    cpu->id_isar3 = 0x01111110;
+    cpu->id_isar4 = 0x01310102;
+    cpu->id_isar5 = 0x00000000;
 }
 
 static void arm_v7m_class_init(ObjectClass *oc, void *data)
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH v2 02/11] hw/intc/armv7m_nvic: Fix ICSR PENDNMISET/CLR handling
  2018-02-09 16:57 [Qemu-devel] [PATCH v2 00/11] v8m: minor missing regs and bugfixes Peter Maydell
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 01/11] hw/intc/armv7m_nvic: Don't hardcode M profile ID registers in NVIC Peter Maydell
@ 2018-02-09 16:58 ` Peter Maydell
  2018-02-09 20:30   ` Richard Henderson
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 03/11] hw/intc/armv7m_nvic: Implement M profile cache maintenance ops Peter Maydell
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: Peter Maydell @ 2018-02-09 16:58 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

The PENDNMISET/CLR bits in the ICSR should be RAZ/WI from
NonSecure state if the AIRCR.BFHFNMINS bit is zero. We had
misimplemented this as making the bits RAZ/WI from both
Secure and NonSecure states. Fix this bug by checking
attrs.secure so that Secure code can pend and unpend NMIs.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/intc/armv7m_nvic.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 63da0fee34..06b9598fbe 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -830,8 +830,8 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
             }
         }
         /* NMIPENDSET */
-        if ((cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) &&
-            s->vectors[ARMV7M_EXCP_NMI].pending) {
+        if ((attrs.secure || (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK))
+            && s->vectors[ARMV7M_EXCP_NMI].pending) {
             val |= (1 << 31);
         }
         /* ISRPREEMPT: RES0 when halting debug not implemented */
@@ -1193,7 +1193,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
         break;
     }
     case 0xd04: /* Interrupt Control State (ICSR) */
-        if (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
+        if (attrs.secure || cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
             if (value & (1 << 31)) {
                 armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI, false);
             } else if (value & (1 << 30) &&
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH v2 03/11] hw/intc/armv7m_nvic: Implement M profile cache maintenance ops
  2018-02-09 16:57 [Qemu-devel] [PATCH v2 00/11] v8m: minor missing regs and bugfixes Peter Maydell
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 01/11] hw/intc/armv7m_nvic: Don't hardcode M profile ID registers in NVIC Peter Maydell
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 02/11] hw/intc/armv7m_nvic: Fix ICSR PENDNMISET/CLR handling Peter Maydell
@ 2018-02-09 16:58 ` Peter Maydell
  2018-02-09 20:34   ` Richard Henderson
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 04/11] hw/intc/armv7m_nvic: Implement v8M CPPWR register Peter Maydell
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: Peter Maydell @ 2018-02-09 16:58 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

For M profile cores, cache maintenance operations are done by
writing to special registers in the system register space.
For QEMU, cache operations are always NOPs, since we don't
implement the cache. Implementing these explicitly avoids
a spurious LOG_GUEST_ERROR when the guest uses them.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/intc/armv7m_nvic.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 06b9598fbe..74b25ce92c 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -1594,6 +1594,18 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
         }
         break;
     }
+    case 0xf50: /* ICIALLU */
+    case 0xf58: /* ICIMVAU */
+    case 0xf5c: /* DCIMVAC */
+    case 0xf60: /* DCISW */
+    case 0xf64: /* DCCMVAU */
+    case 0xf68: /* DCCMVAC */
+    case 0xf6c: /* DCCSW */
+    case 0xf70: /* DCCIMVAC */
+    case 0xf74: /* DCCISW */
+    case 0xf78: /* BPIALL */
+        /* Cache and branch predictor maintenance: for QEMU these always NOP */
+        break;
     default:
     bad_offset:
         qemu_log_mask(LOG_GUEST_ERROR,
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH v2 04/11] hw/intc/armv7m_nvic: Implement v8M CPPWR register
  2018-02-09 16:57 [Qemu-devel] [PATCH v2 00/11] v8m: minor missing regs and bugfixes Peter Maydell
                   ` (2 preceding siblings ...)
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 03/11] hw/intc/armv7m_nvic: Implement M profile cache maintenance ops Peter Maydell
@ 2018-02-09 16:58 ` Peter Maydell
  2018-02-09 20:37   ` Richard Henderson
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 05/11] hw/intc/armv7m_nvic: Implement cache ID registers Peter Maydell
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: Peter Maydell @ 2018-02-09 16:58 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

The Coprocessor Power Control Register (CPPWR) is new in v8M.
It allows software to control whether coprocessors are allowed
to power down and lose their state. QEMU doesn't have any
notion of power control, so we choose the IMPDEF option of
making the whole register RAZ/WI (indicating that no coprocessors
can ever power down and lose state).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/intc/armv7m_nvic.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 74b25ce92c..eb49fd77c7 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -776,6 +776,14 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
     switch (offset) {
     case 4: /* Interrupt Control Type.  */
         return ((s->num_irq - NVIC_FIRST_IRQ) / 32) - 1;
+    case 0xc: /* CPPWR */
+        if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+            goto bad_offset;
+        }
+        /* We make the IMPDEF choice that nothing can ever go into a
+         * non-retentive power state, which allows us to RAZ/WI this.
+         */
+        return 0;
     case 0x380 ... 0x3bf: /* NVIC_ITNS<n> */
     {
         int startvec = 8 * (offset - 0x380) + NVIC_FIRST_IRQ;
@@ -1175,6 +1183,12 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
     ARMCPU *cpu = s->cpu;
 
     switch (offset) {
+    case 0xc: /* CPPWR */
+        if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+            goto bad_offset;
+        }
+        /* Make the IMPDEF choice to RAZ/WI this. */
+        break;
     case 0x380 ... 0x3bf: /* NVIC_ITNS<n> */
     {
         int startvec = 8 * (offset - 0x380) + NVIC_FIRST_IRQ;
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH v2 05/11] hw/intc/armv7m_nvic: Implement cache ID registers
  2018-02-09 16:57 [Qemu-devel] [PATCH v2 00/11] v8m: minor missing regs and bugfixes Peter Maydell
                   ` (3 preceding siblings ...)
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 04/11] hw/intc/armv7m_nvic: Implement v8M CPPWR register Peter Maydell
@ 2018-02-09 16:58 ` Peter Maydell
  2018-02-09 20:59   ` Richard Henderson
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 06/11] hw/intc/armv7m_nvic: Implement SCR Peter Maydell
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: Peter Maydell @ 2018-02-09 16:58 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

M profile cores have a similar setup for cache ID registers
to A profile:
 * Cache Level ID Register (CLIDR) is a fixed value
 * Cache Type Register (CTR) is a fixed value
 * Cache Size ID Registers (CCSIDR) are a bank of registers;
   which one you see is selected by the Cache Size Selection
   Register (CSSELR)

The only difference is that they're in the NVIC memory mapped
register space rather than being coprocessor registers.
Implement the M profile view of them.

Since neither Cortex-M3 nor Cortex-M4 implement caches,
we don't need to update their init functions and can leave
the ctr/clidr/ccsidr[] fields in their ARMCPU structs at zero.
Newer cores (like the Cortex-M33) will want to be able to
set these ID registers to non-zero values, though.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
v1->v2 changes: use FIELD() to define some constants;
add compile-time assert that we won't index outside cssidr[]
---
 target/arm/cpu.h      | 26 ++++++++++++++++++++++++++
 hw/intc/armv7m_nvic.c | 16 ++++++++++++++++
 target/arm/machine.c  | 36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 78 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 521444a5a1..4c1b9e9814 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -496,6 +496,7 @@ typedef struct CPUARMState {
         uint32_t faultmask[M_REG_NUM_BANKS];
         uint32_t aircr; /* only holds r/w state if security extn implemented */
         uint32_t secure; /* Is CPU in Secure state? (not guest visible) */
+        uint32_t csselr[M_REG_NUM_BANKS];
     } v7m;
 
     /* Information associated with an exception about to be taken:
@@ -1325,6 +1326,23 @@ FIELD(V7M_MPU_CTRL, ENABLE, 0, 1)
 FIELD(V7M_MPU_CTRL, HFNMIENA, 1, 1)
 FIELD(V7M_MPU_CTRL, PRIVDEFENA, 2, 1)
 
+/* v7M CLIDR bits */
+FIELD(V7M_CLIDR, CTYPE_ALL, 0, 21)
+FIELD(V7M_CLIDR, LOUIS, 21, 3)
+FIELD(V7M_CLIDR, LOC, 24, 3)
+FIELD(V7M_CLIDR, LOUU, 27, 3)
+FIELD(V7M_CLIDR, ICB, 30, 2)
+
+FIELD(V7M_CSSELR, IND, 0, 1)
+FIELD(V7M_CSSELR, LEVEL, 1, 3)
+/* We use the combination of InD and Level to index into cpu->ccsidr[];
+ * define a mask for this and check that it doesn't permit running off
+ * the end of the array.
+ */
+FIELD(V7M_CSSELR, INDEX, 0, 4)
+
+QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
+
 /* If adding a feature bit which corresponds to a Linux ELF
  * HWCAP bit, remember to update the feature-bit-to-hwcap
  * mapping in linux-user/elfload.c:get_elf_hwcap().
@@ -2485,6 +2503,14 @@ static inline int arm_debug_target_el(CPUARMState *env)
     }
 }
 
+static inline bool arm_v7m_csselr_razwi(ARMCPU *cpu)
+{
+    /* If all the CLIDR.Ctypem bits are 0 there are no caches, and
+     * CSSELR is RAZ/WI.
+     */
+    return (cpu->clidr & R_V7M_CLIDR_CTYPE_ALL_MASK) != 0;
+}
+
 static inline bool aa64_generate_debug_exceptions(CPUARMState *env)
 {
     if (arm_is_secure(env)) {
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index eb49fd77c7..040f3380ec 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -1025,6 +1025,17 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
         return cpu->id_isar4;
     case 0xd74: /* ISAR5.  */
         return cpu->id_isar5;
+    case 0xd78: /* CLIDR */
+        return cpu->clidr;
+    case 0xd7c: /* CTR */
+        return cpu->ctr;
+    case 0xd80: /* CSSIDR */
+    {
+        int idx = cpu->env.v7m.csselr[attrs.secure] & R_V7M_CSSELR_INDEX_MASK;
+        return cpu->ccsidr[idx];
+    }
+    case 0xd84: /* CSSELR */
+        return cpu->env.v7m.csselr[attrs.secure];
     /* TODO: Implement debug registers.  */
     case 0xd90: /* MPU_TYPE */
         /* Unified MPU; if the MPU is not present this value is zero */
@@ -1385,6 +1396,11 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
         qemu_log_mask(LOG_UNIMP,
                       "NVIC: Aux fault status registers unimplemented\n");
         break;
+    case 0xd84: /* CSSELR */
+        if (!arm_v7m_csselr_razwi(cpu)) {
+            cpu->env.v7m.csselr[attrs.secure] = value & R_V7M_CSSELR_INDEX_MASK;
+        }
+        break;
     case 0xd90: /* MPU_TYPE */
         return; /* RO */
     case 0xd94: /* MPU_CTRL */
diff --git a/target/arm/machine.c b/target/arm/machine.c
index 2c8b43062f..cae63c2f98 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -191,6 +191,41 @@ static const VMStateDescription vmstate_m_faultmask_primask = {
     }
 };
 
+/* CSSELR is in a subsection because we didn't implement it previously.
+ * Migration from an old implementation will leave it at zero, which
+ * is OK since the only CPUs in the old implementation make the
+ * register RAZ/WI.
+ * Since there was no version of QEMU which implemented the CSSELR for
+ * just non-secure, we transfer both banks here rather than putting
+ * the secure banked version in the m-security subsection.
+ */
+static bool csselr_vmstate_validate(void *opaque, int version_id)
+{
+    ARMCPU *cpu = opaque;
+
+    return cpu->env.v7m.csselr[M_REG_NS] <= R_V7M_CSSELR_INDEX_MASK
+        && cpu->env.v7m.csselr[M_REG_S] <= R_V7M_CSSELR_INDEX_MASK;
+}
+
+static bool m_csselr_needed(void *opaque)
+{
+    ARMCPU *cpu = opaque;
+
+    return !arm_v7m_csselr_razwi(cpu);
+}
+
+static const VMStateDescription vmstate_m_csselr = {
+    .name = "cpu/m/csselr",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = m_csselr_needed,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(env.v7m.csselr, ARMCPU, M_REG_NUM_BANKS),
+        VMSTATE_VALIDATE("CSSELR is valid", csselr_vmstate_validate),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static const VMStateDescription vmstate_m = {
     .name = "cpu/m",
     .version_id = 4,
@@ -212,6 +247,7 @@ static const VMStateDescription vmstate_m = {
     },
     .subsections = (const VMStateDescription*[]) {
         &vmstate_m_faultmask_primask,
+        &vmstate_m_csselr,
         NULL
     }
 };
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH v2 06/11] hw/intc/armv7m_nvic: Implement SCR
  2018-02-09 16:57 [Qemu-devel] [PATCH v2 00/11] v8m: minor missing regs and bugfixes Peter Maydell
                   ` (4 preceding siblings ...)
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 05/11] hw/intc/armv7m_nvic: Implement cache ID registers Peter Maydell
@ 2018-02-09 16:58 ` Peter Maydell
  2018-02-09 21:03   ` Richard Henderson
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 07/11] target/arm: Implement writing to CONTROL_NS for v8M Peter Maydell
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: Peter Maydell @ 2018-02-09 16:58 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

We were previously making the system control register (SCR)
just RAZ/WI. Although we don't implement the functionality
this register controls, we should at least provide the state,
including the banked state for v8M.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu.h      |  7 +++++++
 hw/intc/armv7m_nvic.c | 12 ++++++++----
 target/arm/machine.c  | 12 ++++++++++++
 3 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 4c1b9e9814..cfa92c477b 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -497,6 +497,7 @@ typedef struct CPUARMState {
         uint32_t aircr; /* only holds r/w state if security extn implemented */
         uint32_t secure; /* Is CPU in Secure state? (not guest visible) */
         uint32_t csselr[M_REG_NUM_BANKS];
+        uint32_t scr[M_REG_NUM_BANKS];
     } v7m;
 
     /* Information associated with an exception about to be taken:
@@ -1258,6 +1259,12 @@ FIELD(V7M_CCR, STKALIGN, 9, 1)
 FIELD(V7M_CCR, DC, 16, 1)
 FIELD(V7M_CCR, IC, 17, 1)
 
+/* V7M SCR bits */
+FIELD(V7M_SCR, SLEEPONEXIT, 1, 1)
+FIELD(V7M_SCR, SLEEPDEEP, 2, 1)
+FIELD(V7M_SCR, SLEEPDEEPS, 3, 1)
+FIELD(V7M_SCR, SEVONPEND, 4, 1)
+
 /* V7M AIRCR bits */
 FIELD(V7M_AIRCR, VECTRESET, 0, 1)
 FIELD(V7M_AIRCR, VECTCLRACTIVE, 1, 1)
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 040f3380ec..ea3b7cce14 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -863,8 +863,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
         }
         return val;
     case 0xd10: /* System Control.  */
-        /* TODO: Implement SLEEPONEXIT.  */
-        return 0;
+        return cpu->env.v7m.scr[attrs.secure];
     case 0xd14: /* Configuration Control.  */
         /* The BFHFNMIGN bit is the only non-banked bit; we
          * keep it in the non-secure copy of the register.
@@ -1285,8 +1284,13 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
         }
         break;
     case 0xd10: /* System Control.  */
-        /* TODO: Implement control registers.  */
-        qemu_log_mask(LOG_UNIMP, "NVIC: SCR unimplemented\n");
+        /* We don't implement deep-sleep so these bits are RAZ/WI.
+         * The other bits in the register are banked.
+         * QEMU's implementation ignores SEVONPEND and SLEEPONEXIT, which
+         * is architecturally permitted.
+         */
+        value &= ~(R_V7M_SCR_SLEEPDEEP_MASK | R_V7M_SCR_SLEEPDEEPS_MASK);
+        cpu->env.v7m.scr[attrs.secure] = value;
         break;
     case 0xd14: /* Configuration Control.  */
         /* Enforce RAZ/WI on reserved and must-RAZ/WI bits */
diff --git a/target/arm/machine.c b/target/arm/machine.c
index cae63c2f98..30fb1454a6 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -226,6 +226,16 @@ static const VMStateDescription vmstate_m_csselr = {
     }
 };
 
+static const VMStateDescription vmstate_m_scr = {
+    .name = "cpu/m/scr",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(env.v7m.scr[M_REG_NS], ARMCPU),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static const VMStateDescription vmstate_m = {
     .name = "cpu/m",
     .version_id = 4,
@@ -248,6 +258,7 @@ static const VMStateDescription vmstate_m = {
     .subsections = (const VMStateDescription*[]) {
         &vmstate_m_faultmask_primask,
         &vmstate_m_csselr,
+        &vmstate_m_scr,
         NULL
     }
 };
@@ -411,6 +422,7 @@ static const VMStateDescription vmstate_m_security = {
         VMSTATE_UINT32(env.sau.rnr, ARMCPU),
         VMSTATE_VALIDATE("SAU_RNR is valid", sau_rnr_vmstate_validate),
         VMSTATE_UINT32(env.sau.ctrl, ARMCPU),
+        VMSTATE_UINT32(env.v7m.scr[M_REG_S], ARMCPU),
         VMSTATE_END_OF_LIST()
     }
 };
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH v2 07/11] target/arm: Implement writing to CONTROL_NS for v8M
  2018-02-09 16:57 [Qemu-devel] [PATCH v2 00/11] v8m: minor missing regs and bugfixes Peter Maydell
                   ` (5 preceding siblings ...)
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 06/11] hw/intc/armv7m_nvic: Implement SCR Peter Maydell
@ 2018-02-09 16:58 ` Peter Maydell
  2018-02-09 21:08   ` Richard Henderson
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 08/11] hw/intc/armv7m_nvic: Fix byte-to-interrupt number conversions Peter Maydell
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: Peter Maydell @ 2018-02-09 16:58 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

In commit 50f11062d4c896 we added support for MSR/MRS access
to the NS banked special registers, but we forgot to implement
the support for writing to CONTROL_NS. Correct the omission.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/helper.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 180ab75458..7c1dcb0330 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -10519,6 +10519,16 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
             }
             env->v7m.faultmask[M_REG_NS] = val & 1;
             return;
+        case 0x94: /* CONTROL_NS */
+            if (!env->v7m.secure) {
+                return;
+            }
+            write_v7m_control_spsel_for_secstate(env,
+                                                 val & R_V7M_CONTROL_SPSEL_MASK,
+                                                 M_REG_NS);
+            env->v7m.control[M_REG_NS] &= ~R_V7M_CONTROL_NPRIV_MASK;
+            env->v7m.control[M_REG_NS] |= val & R_V7M_CONTROL_NPRIV_MASK;
+            return;
         case 0x98: /* SP_NS */
         {
             /* This gives the non-secure SP selected based on whether we're
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH v2 08/11] hw/intc/armv7m_nvic: Fix byte-to-interrupt number conversions
  2018-02-09 16:57 [Qemu-devel] [PATCH v2 00/11] v8m: minor missing regs and bugfixes Peter Maydell
                   ` (6 preceding siblings ...)
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 07/11] target/arm: Implement writing to CONTROL_NS for v8M Peter Maydell
@ 2018-02-09 16:58 ` Peter Maydell
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 09/11] target/arm: Add AIRCR to vmstate struct Peter Maydell
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 22+ messages in thread
From: Peter Maydell @ 2018-02-09 16:58 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

In many of the NVIC registers relating to interrupts, we
have to convert from a byte offset within a register set
into the number of the first interrupt which is affected.
We were getting this wrong for:
 * reads of NVIC_ISPR<n>, NVIC_ISER<n>, NVIC_ICPR<n>, NVIC_ICER<n>,
   NVIC_IABR<n> -- in all these cases we were missing the "* 8"
   needed to convert from the byte offset to the interrupt number
   (since all these registers use one bit per interrupt)
 * writes of NVIC_IPR<n> had the opposite problem of a spurious
   "* 8" (since these registers use one byte per interrupt)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 hw/intc/armv7m_nvic.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index ea3b7cce14..c51151fa8a 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -1724,7 +1724,7 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
         /* fall through */
     case 0x180 ... 0x1bf: /* NVIC Clear enable */
         val = 0;
-        startvec = offset - 0x180 + NVIC_FIRST_IRQ; /* vector # */
+        startvec = 8 * (offset - 0x180) + NVIC_FIRST_IRQ; /* vector # */
 
         for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
             if (s->vectors[startvec + i].enabled &&
@@ -1738,7 +1738,7 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
         /* fall through */
     case 0x280 ... 0x2bf: /* NVIC Clear pend */
         val = 0;
-        startvec = offset - 0x280 + NVIC_FIRST_IRQ; /* vector # */
+        startvec = 8 * (offset - 0x280) + NVIC_FIRST_IRQ; /* vector # */
         for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
             if (s->vectors[startvec + i].pending &&
                 (attrs.secure || s->itns[startvec + i])) {
@@ -1748,7 +1748,7 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
         break;
     case 0x300 ... 0x33f: /* NVIC Active */
         val = 0;
-        startvec = offset - 0x300 + NVIC_FIRST_IRQ; /* vector # */
+        startvec = 8 * (offset - 0x300) + NVIC_FIRST_IRQ; /* vector # */
 
         for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
             if (s->vectors[startvec + i].active &&
@@ -1863,7 +1863,7 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
     case 0x300 ... 0x33f: /* NVIC Active */
         return MEMTX_OK; /* R/O */
     case 0x400 ... 0x5ef: /* NVIC Priority */
-        startvec = 8 * (offset - 0x400) + NVIC_FIRST_IRQ; /* vector # */
+        startvec = (offset - 0x400) + NVIC_FIRST_IRQ; /* vector # */
 
         for (i = 0; i < size && startvec + i < s->num_irq; i++) {
             if (attrs.secure || s->itns[startvec + i]) {
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH v2 09/11] target/arm: Add AIRCR to vmstate struct
  2018-02-09 16:57 [Qemu-devel] [PATCH v2 00/11] v8m: minor missing regs and bugfixes Peter Maydell
                   ` (7 preceding siblings ...)
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 08/11] hw/intc/armv7m_nvic: Fix byte-to-interrupt number conversions Peter Maydell
@ 2018-02-09 16:58 ` Peter Maydell
  2018-02-09 21:12   ` Richard Henderson
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 10/11] target/arm: Migrate v7m.other_sp Peter Maydell
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 11/11] target/arm: Implement v8M MSPLIM and PSPLIM registers Peter Maydell
  10 siblings, 1 reply; 22+ messages in thread
From: Peter Maydell @ 2018-02-09 16:58 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

In commit commit 3b2e934463121 we added support for the AIRCR
register holding state, but forgot to add it to the vmstate
structs. Since it only holds r/w state if the security extension
is implemented, we can just add it to vmstate_m_security.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/machine.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/target/arm/machine.c b/target/arm/machine.c
index 30fb1454a6..25cdf4d581 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -423,6 +423,10 @@ static const VMStateDescription vmstate_m_security = {
         VMSTATE_VALIDATE("SAU_RNR is valid", sau_rnr_vmstate_validate),
         VMSTATE_UINT32(env.sau.ctrl, ARMCPU),
         VMSTATE_UINT32(env.v7m.scr[M_REG_S], ARMCPU),
+        /* AIRCR is not secure-only, but our implementation is R/O if the
+         * security extension is unimplemented, so we migrate it here.
+         */
+        VMSTATE_UINT32(env.v7m.aircr, ARMCPU),
         VMSTATE_END_OF_LIST()
     }
 };
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH v2 10/11] target/arm: Migrate v7m.other_sp
  2018-02-09 16:57 [Qemu-devel] [PATCH v2 00/11] v8m: minor missing regs and bugfixes Peter Maydell
                   ` (8 preceding siblings ...)
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 09/11] target/arm: Add AIRCR to vmstate struct Peter Maydell
@ 2018-02-09 16:58 ` Peter Maydell
  2018-02-09 21:13   ` Richard Henderson
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 11/11] target/arm: Implement v8M MSPLIM and PSPLIM registers Peter Maydell
  10 siblings, 1 reply; 22+ messages in thread
From: Peter Maydell @ 2018-02-09 16:58 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

In commit abc24d86cc0364f we accidentally broke migration of
the stack pointer value for the mode (process, handler) the CPU
is not currently running as. (The commit correctly removed the
no-longer-used v7m.current_sp flag from the VMState but also
deleted the still very much in use v7m.other_sp SP value field.)

Add a subsection to migrate it again. (We don't need to care
about trying to retain compatibility with pre-abc24d86cc0364f
versions of QEMU, because that commit bumped the version_id
and we've since bumped it again a couple of times.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/machine.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/target/arm/machine.c b/target/arm/machine.c
index 25cdf4d581..1a20d6c36c 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -236,6 +236,16 @@ static const VMStateDescription vmstate_m_scr = {
     }
 };
 
+static const VMStateDescription vmstate_m_other_sp = {
+    .name = "cpu/m/other-sp",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(env.v7m.other_sp, ARMCPU),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static const VMStateDescription vmstate_m = {
     .name = "cpu/m",
     .version_id = 4,
@@ -259,6 +269,7 @@ static const VMStateDescription vmstate_m = {
         &vmstate_m_faultmask_primask,
         &vmstate_m_csselr,
         &vmstate_m_scr,
+        &vmstate_m_other_sp,
         NULL
     }
 };
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH v2 11/11] target/arm: Implement v8M MSPLIM and PSPLIM registers
  2018-02-09 16:57 [Qemu-devel] [PATCH v2 00/11] v8m: minor missing regs and bugfixes Peter Maydell
                   ` (9 preceding siblings ...)
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 10/11] target/arm: Migrate v7m.other_sp Peter Maydell
@ 2018-02-09 16:58 ` Peter Maydell
  2018-02-09 21:15   ` Richard Henderson
  10 siblings, 1 reply; 22+ messages in thread
From: Peter Maydell @ 2018-02-09 16:58 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

The v8M architecture includes hardware support for enforcing
stack pointer limits. We don't implement this behaviour yet,
but provide the MSPLIM and PSPLIM stack pointer limit registers
as reads-as-written, so that when we do implement the checks
in future this won't break guest migration.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu.h     |  2 ++
 target/arm/helper.c  | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 target/arm/machine.c | 21 +++++++++++++++++++++
 3 files changed, 69 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index cfa92c477b..3ef523ddbd 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -498,6 +498,8 @@ typedef struct CPUARMState {
         uint32_t secure; /* Is CPU in Secure state? (not guest visible) */
         uint32_t csselr[M_REG_NUM_BANKS];
         uint32_t scr[M_REG_NUM_BANKS];
+        uint32_t msplim[M_REG_NUM_BANKS];
+        uint32_t psplim[M_REG_NUM_BANKS];
     } v7m;
 
     /* Information associated with an exception about to be taken:
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 7c1dcb0330..03b1a3fd92 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -10415,6 +10415,16 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
                 return 0;
             }
             return env->v7m.other_ss_psp;
+        case 0x8a: /* MSPLIM_NS */
+            if (!env->v7m.secure) {
+                return 0;
+            }
+            return env->v7m.msplim[M_REG_NS];
+        case 0x8b: /* PSPLIM_NS */
+            if (!env->v7m.secure) {
+                return 0;
+            }
+            return env->v7m.psplim[M_REG_NS];
         case 0x90: /* PRIMASK_NS */
             if (!env->v7m.secure) {
                 return 0;
@@ -10456,6 +10466,16 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
         return v7m_using_psp(env) ? env->v7m.other_sp : env->regs[13];
     case 9: /* PSP */
         return v7m_using_psp(env) ? env->regs[13] : env->v7m.other_sp;
+    case 10: /* MSPLIM */
+        if (!arm_feature(env, ARM_FEATURE_V8)) {
+            goto bad_reg;
+        }
+        return env->v7m.msplim[env->v7m.secure];
+    case 11: /* PSPLIM */
+        if (!arm_feature(env, ARM_FEATURE_V8)) {
+            goto bad_reg;
+        }
+        return env->v7m.psplim[env->v7m.secure];
     case 16: /* PRIMASK */
         return env->v7m.primask[env->v7m.secure];
     case 17: /* BASEPRI */
@@ -10464,6 +10484,7 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
     case 19: /* FAULTMASK */
         return env->v7m.faultmask[env->v7m.secure];
     default:
+    bad_reg:
         qemu_log_mask(LOG_GUEST_ERROR, "Attempt to read unknown special"
                                        " register %d\n", reg);
         return 0;
@@ -10501,6 +10522,18 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
             }
             env->v7m.other_ss_psp = val;
             return;
+        case 0x8a: /* MSPLIM_NS */
+            if (!env->v7m.secure) {
+                return;
+            }
+            env->v7m.msplim[M_REG_NS] = val & ~7;
+            return;
+        case 0x8b: /* PSPLIM_NS */
+            if (!env->v7m.secure) {
+                return;
+            }
+            env->v7m.psplim[M_REG_NS] = val & ~7;
+            return;
         case 0x90: /* PRIMASK_NS */
             if (!env->v7m.secure) {
                 return;
@@ -10580,6 +10613,18 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
             env->v7m.other_sp = val;
         }
         break;
+    case 10: /* MSPLIM */
+        if (!arm_feature(env, ARM_FEATURE_V8)) {
+            goto bad_reg;
+        }
+        env->v7m.msplim[env->v7m.secure] = val & ~7;
+        break;
+    case 11: /* PSPLIM */
+        if (!arm_feature(env, ARM_FEATURE_V8)) {
+            goto bad_reg;
+        }
+        env->v7m.psplim[env->v7m.secure] = val & ~7;
+        break;
     case 16: /* PRIMASK */
         env->v7m.primask[env->v7m.secure] = val & 1;
         break;
@@ -10612,6 +10657,7 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
         env->v7m.control[env->v7m.secure] |= val & R_V7M_CONTROL_NPRIV_MASK;
         break;
     default:
+    bad_reg:
         qemu_log_mask(LOG_GUEST_ERROR, "Attempt to write unknown special"
                                        " register %d\n", reg);
         return;
diff --git a/target/arm/machine.c b/target/arm/machine.c
index 1a20d6c36c..2e28d086bd 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -246,6 +246,26 @@ static const VMStateDescription vmstate_m_other_sp = {
     }
 };
 
+static bool m_v8m_needed(void *opaque)
+{
+    ARMCPU *cpu = opaque;
+    CPUARMState *env = &cpu->env;
+
+    return arm_feature(env, ARM_FEATURE_M) && arm_feature(env, ARM_FEATURE_V8);
+}
+
+static const VMStateDescription vmstate_m_v8m = {
+    .name = "cpu/m/v8m",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = m_v8m_needed,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(env.v7m.msplim, ARMCPU, M_REG_NUM_BANKS),
+        VMSTATE_UINT32_ARRAY(env.v7m.psplim, ARMCPU, M_REG_NUM_BANKS),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static const VMStateDescription vmstate_m = {
     .name = "cpu/m",
     .version_id = 4,
@@ -270,6 +290,7 @@ static const VMStateDescription vmstate_m = {
         &vmstate_m_csselr,
         &vmstate_m_scr,
         &vmstate_m_other_sp,
+        &vmstate_m_v8m,
         NULL
     }
 };
-- 
2.16.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH v2 01/11] hw/intc/armv7m_nvic: Don't hardcode M profile ID registers in NVIC
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 01/11] hw/intc/armv7m_nvic: Don't hardcode M profile ID registers in NVIC Peter Maydell
@ 2018-02-09 20:28   ` Richard Henderson
  0 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2018-02-09 20:28 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 02/09/2018 08:58 AM, Peter Maydell wrote:
> Instead of hardcoding the values of M profile ID registers in the
> NVIC, use the fields in the CPU struct. This will allow us to
> give different M profile CPU types different ID register values.
> 
> This commit includes the addition of the missing ID_ISAR5,
> which exists as RES0 in both v7M and v8M.
> 
> (The values of the ID registers might be wrong for the M4 --
> this commit leaves the behaviour there unchanged.)
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
>  hw/intc/armv7m_nvic.c | 30 ++++++++++++++++--------------
>  target/arm/cpu.c      | 28 ++++++++++++++++++++++++++++
>  2 files changed, 44 insertions(+), 14 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH v2 02/11] hw/intc/armv7m_nvic: Fix ICSR PENDNMISET/CLR handling
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 02/11] hw/intc/armv7m_nvic: Fix ICSR PENDNMISET/CLR handling Peter Maydell
@ 2018-02-09 20:30   ` Richard Henderson
  0 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2018-02-09 20:30 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 02/09/2018 08:58 AM, Peter Maydell wrote:
> The PENDNMISET/CLR bits in the ICSR should be RAZ/WI from
> NonSecure state if the AIRCR.BFHFNMINS bit is zero. We had
> misimplemented this as making the bits RAZ/WI from both
> Secure and NonSecure states. Fix this bug by checking
> attrs.secure so that Secure code can pend and unpend NMIs.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/intc/armv7m_nvic.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH v2 03/11] hw/intc/armv7m_nvic: Implement M profile cache maintenance ops
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 03/11] hw/intc/armv7m_nvic: Implement M profile cache maintenance ops Peter Maydell
@ 2018-02-09 20:34   ` Richard Henderson
  0 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2018-02-09 20:34 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 02/09/2018 08:58 AM, Peter Maydell wrote:
> For M profile cores, cache maintenance operations are done by
> writing to special registers in the system register space.
> For QEMU, cache operations are always NOPs, since we don't
> implement the cache. Implementing these explicitly avoids
> a spurious LOG_GUEST_ERROR when the guest uses them.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/intc/armv7m_nvic.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH v2 04/11] hw/intc/armv7m_nvic: Implement v8M CPPWR register
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 04/11] hw/intc/armv7m_nvic: Implement v8M CPPWR register Peter Maydell
@ 2018-02-09 20:37   ` Richard Henderson
  0 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2018-02-09 20:37 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 02/09/2018 08:58 AM, Peter Maydell wrote:
> The Coprocessor Power Control Register (CPPWR) is new in v8M.
> It allows software to control whether coprocessors are allowed
> to power down and lose their state. QEMU doesn't have any
> notion of power control, so we choose the IMPDEF option of
> making the whole register RAZ/WI (indicating that no coprocessors
> can ever power down and lose state).
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/intc/armv7m_nvic.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH v2 05/11] hw/intc/armv7m_nvic: Implement cache ID registers
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 05/11] hw/intc/armv7m_nvic: Implement cache ID registers Peter Maydell
@ 2018-02-09 20:59   ` Richard Henderson
  0 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2018-02-09 20:59 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 02/09/2018 08:58 AM, Peter Maydell wrote:
> M profile cores have a similar setup for cache ID registers
> to A profile:
>  * Cache Level ID Register (CLIDR) is a fixed value
>  * Cache Type Register (CTR) is a fixed value
>  * Cache Size ID Registers (CCSIDR) are a bank of registers;
>    which one you see is selected by the Cache Size Selection
>    Register (CSSELR)
> 
> The only difference is that they're in the NVIC memory mapped
> register space rather than being coprocessor registers.
> Implement the M profile view of them.
> 
> Since neither Cortex-M3 nor Cortex-M4 implement caches,
> we don't need to update their init functions and can leave
> the ctr/clidr/ccsidr[] fields in their ARMCPU structs at zero.
> Newer cores (like the Cortex-M33) will want to be able to
> set these ID registers to non-zero values, though.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> v1->v2 changes: use FIELD() to define some constants;
> add compile-time assert that we won't index outside cssidr[]
> ---
>  target/arm/cpu.h      | 26 ++++++++++++++++++++++++++
>  hw/intc/armv7m_nvic.c | 16 ++++++++++++++++
>  target/arm/machine.c  | 36 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 78 insertions(+)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH v2 06/11] hw/intc/armv7m_nvic: Implement SCR
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 06/11] hw/intc/armv7m_nvic: Implement SCR Peter Maydell
@ 2018-02-09 21:03   ` Richard Henderson
  0 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2018-02-09 21:03 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 02/09/2018 08:58 AM, Peter Maydell wrote:
> We were previously making the system control register (SCR)
> just RAZ/WI. Although we don't implement the functionality
> this register controls, we should at least provide the state,
> including the banked state for v8M.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h      |  7 +++++++
>  hw/intc/armv7m_nvic.c | 12 ++++++++----
>  target/arm/machine.c  | 12 ++++++++++++
>  3 files changed, 27 insertions(+), 4 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH v2 07/11] target/arm: Implement writing to CONTROL_NS for v8M
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 07/11] target/arm: Implement writing to CONTROL_NS for v8M Peter Maydell
@ 2018-02-09 21:08   ` Richard Henderson
  0 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2018-02-09 21:08 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 02/09/2018 08:58 AM, Peter Maydell wrote:
> In commit 50f11062d4c896 we added support for MSR/MRS access
> to the NS banked special registers, but we forgot to implement
> the support for writing to CONTROL_NS. Correct the omission.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/helper.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH v2 09/11] target/arm: Add AIRCR to vmstate struct
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 09/11] target/arm: Add AIRCR to vmstate struct Peter Maydell
@ 2018-02-09 21:12   ` Richard Henderson
  0 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2018-02-09 21:12 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 02/09/2018 08:58 AM, Peter Maydell wrote:
> In commit commit 3b2e934463121 we added support for the AIRCR
> register holding state, but forgot to add it to the vmstate
> structs. Since it only holds r/w state if the security extension
> is implemented, we can just add it to vmstate_m_security.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/machine.c | 4 ++++
>  1 file changed, 4 insertions(+)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH v2 10/11] target/arm: Migrate v7m.other_sp
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 10/11] target/arm: Migrate v7m.other_sp Peter Maydell
@ 2018-02-09 21:13   ` Richard Henderson
  0 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2018-02-09 21:13 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 02/09/2018 08:58 AM, Peter Maydell wrote:
> In commit abc24d86cc0364f we accidentally broke migration of
> the stack pointer value for the mode (process, handler) the CPU
> is not currently running as. (The commit correctly removed the
> no-longer-used v7m.current_sp flag from the VMState but also
> deleted the still very much in use v7m.other_sp SP value field.)
> 
> Add a subsection to migrate it again. (We don't need to care
> about trying to retain compatibility with pre-abc24d86cc0364f
> versions of QEMU, because that commit bumped the version_id
> and we've since bumped it again a couple of times.)
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/machine.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH v2 11/11] target/arm: Implement v8M MSPLIM and PSPLIM registers
  2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 11/11] target/arm: Implement v8M MSPLIM and PSPLIM registers Peter Maydell
@ 2018-02-09 21:15   ` Richard Henderson
  0 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2018-02-09 21:15 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 02/09/2018 08:58 AM, Peter Maydell wrote:
> The v8M architecture includes hardware support for enforcing
> stack pointer limits. We don't implement this behaviour yet,
> but provide the MSPLIM and PSPLIM stack pointer limit registers
> as reads-as-written, so that when we do implement the checks
> in future this won't break guest migration.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h     |  2 ++
>  target/arm/helper.c  | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>  target/arm/machine.c | 21 +++++++++++++++++++++
>  3 files changed, 69 insertions(+)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2018-02-09 21:15 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-09 16:57 [Qemu-devel] [PATCH v2 00/11] v8m: minor missing regs and bugfixes Peter Maydell
2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 01/11] hw/intc/armv7m_nvic: Don't hardcode M profile ID registers in NVIC Peter Maydell
2018-02-09 20:28   ` Richard Henderson
2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 02/11] hw/intc/armv7m_nvic: Fix ICSR PENDNMISET/CLR handling Peter Maydell
2018-02-09 20:30   ` Richard Henderson
2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 03/11] hw/intc/armv7m_nvic: Implement M profile cache maintenance ops Peter Maydell
2018-02-09 20:34   ` Richard Henderson
2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 04/11] hw/intc/armv7m_nvic: Implement v8M CPPWR register Peter Maydell
2018-02-09 20:37   ` Richard Henderson
2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 05/11] hw/intc/armv7m_nvic: Implement cache ID registers Peter Maydell
2018-02-09 20:59   ` Richard Henderson
2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 06/11] hw/intc/armv7m_nvic: Implement SCR Peter Maydell
2018-02-09 21:03   ` Richard Henderson
2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 07/11] target/arm: Implement writing to CONTROL_NS for v8M Peter Maydell
2018-02-09 21:08   ` Richard Henderson
2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 08/11] hw/intc/armv7m_nvic: Fix byte-to-interrupt number conversions Peter Maydell
2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 09/11] target/arm: Add AIRCR to vmstate struct Peter Maydell
2018-02-09 21:12   ` Richard Henderson
2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 10/11] target/arm: Migrate v7m.other_sp Peter Maydell
2018-02-09 21:13   ` Richard Henderson
2018-02-09 16:58 ` [Qemu-devel] [PATCH v2 11/11] target/arm: Implement v8M MSPLIM and PSPLIM registers Peter Maydell
2018-02-09 21:15   ` Richard Henderson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.