All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/20] first steps towards v8M support
@ 2017-08-22 15:08 Peter Maydell
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 01/20] target/arm: Implement ARMv8M's PMSAv8 registers Peter Maydell
                   ` (19 more replies)
  0 siblings, 20 replies; 60+ messages in thread
From: Peter Maydell @ 2017-08-22 15:08 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

Hi; this patchset is the first slice of work aiming at support
of the ARM v8M architecture. It doesn't do anything by itself
(there's no CPU yet that enables the new feature) and there's
a lot more work still to do to get something actually functional,
but it seems better to push the work out for review a slice
at a time rather than hanging onto it and sending a 100-patch
set at the end.

This patchset sits on top of my target-arm.next tree, which
has the 'preliminary patchset' I sent out a while back in it.

It includes:
 * implementation of PMSAv8
 * banking of most of the main CPU registers which need it
   (the NVIC proper also gets banked exceptions, and the
   systick device is banked, but neither of those are done here)
 * the "let secure access the NS view of the NVIC" alias region
 * an implementation of the BXNS instruction, mostly as the
   simplest thing that needs the banking of stack pointers

We don't yet actually properly swap the stack pointer around
on other kinds of S<->NS transition including exception
entry and exit. I have some patches working in that direction,
so if the BXNS patch doesn't have enough context yet to make
sense I can keep it around and resend it with those later.

Next thing probably will be the NVIC changes, once I've
got my head around the priority related changes v8M brings...

Series available also at 
https://git.linaro.org/people/peter.maydell/qemu-arm.git v8m
(on top of the target-arm.next stuff.)

thanks
-- PMM

Peter Maydell (20):
  target/arm: Implement ARMv8M's PMSAv8 registers
  target/arm: Implement new PMSAv8 behaviour
  target/arm: Add state field, feature bit and migration for v8M secure
    state
  target/arm: Register second AddressSpace for secure v8M CPUs
  target/arm: Add MMU indexes for secure v8M
  target/arm: Make BASEPRI register banked for v8M
  target/arm: Make PRIMASK register banked for v8M
  target/arm: Make FAULTMASK register banked for v8M
  target/arm: Make CONTROL register banked for v8M
  nvic: Add NS alias SCS region
  target/arm: Make VTOR register banked for v8M
  target/arm: Make MPU_MAIR0, MPU_MAIR1 registers banked for v8M
  target/arm: Make MPU_RBAR, MPU_RLAR banked for v8M
  target/arm: Make MPU_RNR register banked for v8M
  target/arm: Make MPU_CTRL register banked for v8M
  target/arm: Make CCR register banked for v8M
  target/arm: Make MMFAR banked for v8M
  target/arm: Make CFSR register banked for v8M
  target/arm: Move regime_is_secure() to target/arm/internals.h
  target/arm: Implement BXNS, and banked stack pointers

 include/hw/intc/armv7m_nvic.h |   1 +
 target/arm/cpu.h              | 100 ++++++++++++--
 target/arm/helper.h           |   2 +
 target/arm/internals.h        |  26 ++++
 target/arm/translate.h        |   1 +
 hw/intc/armv7m_nvic.c         | 294 +++++++++++++++++++++++++++++++++------
 target/arm/cpu.c              |  82 ++++++++---
 target/arm/helper.c           | 315 +++++++++++++++++++++++++++++++++---------
 target/arm/machine.c          | 104 ++++++++++++--
 target/arm/translate.c        |  52 ++++++-
 10 files changed, 820 insertions(+), 157 deletions(-)

-- 
2.7.4

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

* [Qemu-devel] [PATCH 01/20] target/arm: Implement ARMv8M's PMSAv8 registers
  2017-08-22 15:08 [Qemu-devel] [PATCH 00/20] first steps towards v8M support Peter Maydell
@ 2017-08-22 15:08 ` Peter Maydell
  2017-08-29 15:21   ` Richard Henderson
  2017-09-05 19:16   ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 02/20] target/arm: Implement new PMSAv8 behaviour Peter Maydell
                   ` (18 subsequent siblings)
  19 siblings, 2 replies; 60+ messages in thread
From: Peter Maydell @ 2017-08-22 15:08 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

As part of ARMv8M, we need to add support for the PMSAv8 MPU
architecture.

PMSAv8 differs from PMSAv7 both in register/data layout (for instance
using base and limit registers rather than base and size) and also in
behaviour (for example it does not have subregions); rather than
trying to wedge it into the existing PMSAv7 code and data structures,
we define separate ones.

This commit adds the data structures which hold the state for a
PMSAv8 MPU and the register interface to it.  The implementation of
the MPU behaviour will be added in a subsequent commit.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu.h      |  13 ++++++
 hw/intc/armv7m_nvic.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++----
 target/arm/cpu.c      |  36 ++++++++++-----
 target/arm/machine.c  |  28 +++++++++++-
 4 files changed, 179 insertions(+), 20 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index fe6edb7..b6bb78a 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -522,6 +522,19 @@ typedef struct CPUARMState {
         uint32_t rnr;
     } pmsav7;
 
+    /* PMSAv8 MPU */
+    struct {
+        /* The PMSAv8 implementation also shares some PMSAv7 config
+         * and state:
+         *  pmsav7.rnr (region number register)
+         *  pmsav7_dregion (number of configured regions)
+         */
+        uint32_t *rbar;
+        uint32_t *rlar;
+        uint32_t mair0;
+        uint32_t mair1;
+    } pmsav8;
+
     void *nvic;
     const struct arm_boot_info *boot_info;
     /* Store GICv3CPUState to access from this struct */
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index bbfe2d5..c0dbbad 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -544,25 +544,67 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset)
     {
         int region = cpu->env.pmsav7.rnr;
 
+        if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+            /* PMSAv8M handling of the aliases is different from v7M:
+             * aliases A1, A2, A3 override the low two bits of the region
+             * number in MPU_RNR, and there is no 'region' field in the
+             * RBAR register.
+             */
+            int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
+            if (aliasno) {
+                region = deposit32(region, 0, 2, aliasno);
+            }
+            if (region >= cpu->pmsav7_dregion) {
+                return 0;
+            }
+            return cpu->env.pmsav8.rbar[region];
+        }
+
         if (region >= cpu->pmsav7_dregion) {
             return 0;
         }
         return (cpu->env.pmsav7.drbar[region] & 0x1f) | (region & 0xf);
     }
-    case 0xda0: /* MPU_RASR */
-    case 0xda8: /* MPU_RASR_A1 */
-    case 0xdb0: /* MPU_RASR_A2 */
-    case 0xdb8: /* MPU_RASR_A3 */
+    case 0xda0: /* MPU_RASR (v7M), MPU_RLAR (v8M) */
+    case 0xda8: /* MPU_RASR_A1 (v7M), MPU_RLAR_A1 (v8M) */
+    case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */
+    case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */
     {
         int region = cpu->env.pmsav7.rnr;
 
+        if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+            /* PMSAv8M handling of the aliases is different from v7M:
+             * aliases A1, A2, A3 override the low two bits of the region
+             * number in MPU_RNR.
+             */
+            int aliasno = (offset - 0xda0) / 8; /* 0..3 */
+            if (aliasno) {
+                region = deposit32(region, 0, 2, aliasno);
+            }
+            if (region >= cpu->pmsav7_dregion) {
+                return 0;
+            }
+            return cpu->env.pmsav8.rlar[region];
+        }
+
         if (region >= cpu->pmsav7_dregion) {
             return 0;
         }
         return ((cpu->env.pmsav7.dracr[region] & 0xffff) << 16) |
             (cpu->env.pmsav7.drsr[region] & 0xffff);
     }
+    case 0xdc0: /* MPU_MAIR0 */
+        if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+            goto bad_offset;
+        }
+        return cpu->env.pmsav8.mair0;
+    case 0xdc4: /* MPU_MAIR1 */
+        if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+            goto bad_offset;
+        }
+        return cpu->env.pmsav8.mair1;
     default:
+    bad_offset:
         qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);
         return 0;
     }
@@ -691,6 +733,26 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
     {
         int region;
 
+        if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+            /* PMSAv8M handling of the aliases is different from v7M:
+             * aliases A1, A2, A3 override the low two bits of the region
+             * number in MPU_RNR, and there is no 'region' field in the
+             * RBAR register.
+             */
+            int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
+
+            region = cpu->env.pmsav7.rnr;
+            if (aliasno) {
+                region = deposit32(region, 0, 2, aliasno);
+            }
+            if (region >= cpu->pmsav7_dregion) {
+                return;
+            }
+            cpu->env.pmsav8.rbar[region] = value;
+            tlb_flush(CPU(cpu));
+            return;
+        }
+
         if (value & (1 << 4)) {
             /* VALID bit means use the region number specified in this
              * value and also update MPU_RNR.REGION with that value.
@@ -715,13 +777,32 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
         tlb_flush(CPU(cpu));
         break;
     }
-    case 0xda0: /* MPU_RASR */
-    case 0xda8: /* MPU_RASR_A1 */
-    case 0xdb0: /* MPU_RASR_A2 */
-    case 0xdb8: /* MPU_RASR_A3 */
+    case 0xda0: /* MPU_RASR (v7M), MPU_RLAR (v8M) */
+    case 0xda8: /* MPU_RASR_A1 (v7M), MPU_RLAR_A1 (v8M) */
+    case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */
+    case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */
     {
         int region = cpu->env.pmsav7.rnr;
 
+        if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+            /* PMSAv8M handling of the aliases is different from v7M:
+             * aliases A1, A2, A3 override the low two bits of the region
+             * number in MPU_RNR.
+             */
+            int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
+
+            region = cpu->env.pmsav7.rnr;
+            if (aliasno) {
+                region = deposit32(region, 0, 2, aliasno);
+            }
+            if (region >= cpu->pmsav7_dregion) {
+                return;
+            }
+            cpu->env.pmsav8.rlar[region] = value;
+            tlb_flush(CPU(cpu));
+            return;
+        }
+
         if (region >= cpu->pmsav7_dregion) {
             return;
         }
@@ -731,6 +812,30 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
         tlb_flush(CPU(cpu));
         break;
     }
+    case 0xdc0: /* MPU_MAIR0 */
+        if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+            goto bad_offset;
+        }
+        if (cpu->pmsav7_dregion) {
+            /* Register is RES0 if no MPU regions are implemented */
+            cpu->env.pmsav8.mair0 = value;
+        }
+        /* We don't need to do anything else because memory attributes
+         * only affect cacheability, and we don't implement caching.
+         */
+        break;
+    case 0xdc4: /* MPU_MAIR1 */
+        if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+            goto bad_offset;
+        }
+        if (cpu->pmsav7_dregion) {
+            /* Register is RES0 if no MPU regions are implemented */
+            cpu->env.pmsav8.mair1 = value;
+        }
+        /* We don't need to do anything else because memory attributes
+         * only affect cacheability, and we don't implement caching.
+         */
+        break;
     case 0xf00: /* Software Triggered Interrupt Register */
     {
         int excnum = (value & 0x1ff) + NVIC_FIRST_IRQ;
@@ -740,6 +845,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
         break;
     }
     default:
+    bad_offset:
         qemu_log_mask(LOG_GUEST_ERROR,
                       "NVIC: Bad write offset 0x%x\n", offset);
     }
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 41ae6ba..8b610de 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -228,17 +228,25 @@ static void arm_cpu_reset(CPUState *s)
     env->vfp.xregs[ARM_VFP_FPEXC] = 0;
 #endif
 
-    if (arm_feature(env, ARM_FEATURE_PMSA) &&
-        arm_feature(env, ARM_FEATURE_V7)) {
+    if (arm_feature(env, ARM_FEATURE_PMSA)) {
         if (cpu->pmsav7_dregion > 0) {
-            memset(env->pmsav7.drbar, 0,
-                   sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion);
-            memset(env->pmsav7.drsr, 0,
-                   sizeof(*env->pmsav7.drsr) * cpu->pmsav7_dregion);
-            memset(env->pmsav7.dracr, 0,
-                   sizeof(*env->pmsav7.dracr) * cpu->pmsav7_dregion);
+            if (arm_feature(env, ARM_FEATURE_V8)) {
+                memset(env->pmsav8.rbar, 0,
+                       sizeof(*env->pmsav8.rbar) * cpu->pmsav7_dregion);
+                memset(env->pmsav8.rlar, 0,
+                       sizeof(*env->pmsav8.rlar) * cpu->pmsav7_dregion);
+            } else if (arm_feature(env, ARM_FEATURE_V7)) {
+                memset(env->pmsav7.drbar, 0,
+                       sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion);
+                memset(env->pmsav7.drsr, 0,
+                       sizeof(*env->pmsav7.drsr) * cpu->pmsav7_dregion);
+                memset(env->pmsav7.dracr, 0,
+                       sizeof(*env->pmsav7.dracr) * cpu->pmsav7_dregion);
+            }
         }
         env->pmsav7.rnr = 0;
+        env->pmsav8.mair0 = 0;
+        env->pmsav8.mair1 = 0;
     }
 
     set_flush_to_zero(1, &env->vfp.standard_fp_status);
@@ -809,9 +817,15 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
         }
 
         if (nr) {
-            env->pmsav7.drbar = g_new0(uint32_t, nr);
-            env->pmsav7.drsr = g_new0(uint32_t, nr);
-            env->pmsav7.dracr = g_new0(uint32_t, nr);
+            if (arm_feature(env, ARM_FEATURE_V8)) {
+                /* PMSAv8 */
+                env->pmsav8.rbar = g_new0(uint32_t, nr);
+                env->pmsav8.rlar = g_new0(uint32_t, nr);
+            } else {
+                env->pmsav7.drbar = g_new0(uint32_t, nr);
+                env->pmsav7.drsr = g_new0(uint32_t, nr);
+                env->pmsav7.dracr = g_new0(uint32_t, nr);
+            }
         }
     }
 
diff --git a/target/arm/machine.c b/target/arm/machine.c
index 3193b00..05e2909 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -159,7 +159,8 @@ static bool pmsav7_needed(void *opaque)
     CPUARMState *env = &cpu->env;
 
     return arm_feature(env, ARM_FEATURE_PMSA) &&
-           arm_feature(env, ARM_FEATURE_V7);
+           arm_feature(env, ARM_FEATURE_V7) &&
+           !arm_feature(env, ARM_FEATURE_V8);
 }
 
 static bool pmsav7_rgnr_vmstate_validate(void *opaque, int version_id)
@@ -209,6 +210,31 @@ static const VMStateDescription vmstate_pmsav7_rnr = {
     }
 };
 
+static bool pmsav8_needed(void *opaque)
+{
+    ARMCPU *cpu = opaque;
+    CPUARMState *env = &cpu->env;
+
+    return arm_feature(env, ARM_FEATURE_PMSA) &&
+        arm_feature(env, ARM_FEATURE_V8);
+}
+
+static const VMStateDescription vmstate_pmsav8 = {
+    .name = "cpu/pmsav8",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = pmsav8_needed,
+    .fields = (VMStateField[]) {
+        VMSTATE_VARRAY_UINT32(env.pmsav8.rbar, ARMCPU, pmsav7_dregion, 0,
+                              vmstate_info_uint32, uint32_t),
+        VMSTATE_VARRAY_UINT32(env.pmsav8.rlar, ARMCPU, pmsav7_dregion, 0,
+                              vmstate_info_uint32, uint32_t),
+        VMSTATE_UINT32(env.pmsav8.mair0, ARMCPU),
+        VMSTATE_UINT32(env.pmsav8.mair1, ARMCPU),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
                     VMStateField *field)
 {
-- 
2.7.4

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

* [Qemu-devel] [PATCH 02/20] target/arm: Implement new PMSAv8 behaviour
  2017-08-22 15:08 [Qemu-devel] [PATCH 00/20] first steps towards v8M support Peter Maydell
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 01/20] target/arm: Implement ARMv8M's PMSAv8 registers Peter Maydell
@ 2017-08-22 15:08 ` Peter Maydell
  2017-08-29 15:25   ` Richard Henderson
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 03/20] target/arm: Add state field, feature bit and migration for v8M secure state Peter Maydell
                   ` (17 subsequent siblings)
  19 siblings, 1 reply; 60+ messages in thread
From: Peter Maydell @ 2017-08-22 15:08 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

Implement the behavioural side of the new PMSAv8 specification.

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

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 7920153..887490a 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8416,6 +8416,111 @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
     return !(*prot & (1 << access_type));
 }
 
+static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
+                                 MMUAccessType access_type, ARMMMUIdx mmu_idx,
+                                 hwaddr *phys_ptr, int *prot, uint32_t *fsr)
+{
+    ARMCPU *cpu = arm_env_get_cpu(env);
+    bool is_user = regime_is_user(env, mmu_idx);
+    int n;
+    int matchregion = -1;
+    bool hit = false;
+
+    *phys_ptr = address;
+    *prot = 0;
+
+    /* Unlike the ARM ARM pseudocode, we don't need to check whether this
+     * was an exception vector read from the vector table (which is always
+     * done using the default system address map), because those accesses
+     * are done in arm_v7m_load_vector(), which always does a direct
+     * read using address_space_ldl(), rather than going via this function.
+     */
+    if (regime_translation_disabled(env, mmu_idx)) { /* MPU disabled */
+        hit = true;
+    } else if (m_is_ppb_region(env, address)) {
+        hit = true;
+    } else if (pmsav7_use_background_region(cpu, mmu_idx, is_user)) {
+        hit = true;
+    } else {
+        for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {
+            /* region search */
+            /* Note that the base address is bits [31:5] from the register
+             * with bits [4:0] all zeroes, but the limit address is bits
+             * [31:5] from the register with bits [4:0] all ones.
+             */
+            uint32_t base = env->pmsav8.rbar[n] & ~0x1f;
+            uint32_t limit = env->pmsav8.rlar[n] | 0x1f;
+
+            if (!(env->pmsav8.rlar[n] & 0x1)) {
+                /* Region disabled */
+                continue;
+            }
+
+            if (address < base || address > limit) {
+                continue;
+            }
+
+            if (hit) {
+                /* Multiple regions match -- always a failure (unlike
+                 * PMSAv7 where highest-numbered-region wins)
+                 */
+                *fsr = 0x00d; /* permission fault */
+                return true;
+            }
+
+            matchregion = n;
+            hit = true;
+
+            if (base & ~TARGET_PAGE_MASK) {
+                qemu_log_mask(LOG_UNIMP,
+                              "MPU_RBAR[%d]: No support for MPU region base"
+                              "address of 0x%" PRIx32 ". Minimum alignment is "
+                              "%d\n",
+                              n, base, TARGET_PAGE_BITS);
+                continue;
+            }
+            if ((limit + 1) & ~TARGET_PAGE_MASK) {
+                qemu_log_mask(LOG_UNIMP,
+                              "MPU_RBAR[%d]: No support for MPU region limit"
+                              "address of 0x%" PRIx32 ". Minimum alignment is "
+                              "%d\n",
+                              n, limit, TARGET_PAGE_BITS);
+                continue;
+            }
+        }
+    }
+
+    if (!hit) {
+        /* background fault */
+        *fsr = 0;
+        return true;
+    }
+
+    if (matchregion == -1) {
+        /* hit using the background region */
+        get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
+    } else {
+        uint32_t ap = extract32(env->pmsav8.rbar[matchregion], 1, 2);
+        uint32_t xn = extract32(env->pmsav8.rbar[matchregion], 0, 1);
+
+        if (m_is_system_region(env, address)) {
+            /* System space is always execute never */
+            xn = 1;
+        }
+
+        *prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
+        if (*prot && !xn) {
+            *prot |= PAGE_EXEC;
+        }
+        /* We don't need to look the attribute up in the MAIR0/MAIR1
+         * registers because that only tells us about cacheability.
+         */
+    }
+
+    *fsr = 0x00d; /* Permission fault */
+    return !(*prot & (1 << access_type));
+}
+
 static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
                                  MMUAccessType access_type, ARMMMUIdx mmu_idx,
                                  hwaddr *phys_ptr, int *prot, uint32_t *fsr)
@@ -8585,7 +8690,11 @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
         bool ret;
         *page_size = TARGET_PAGE_SIZE;
 
-        if (arm_feature(env, ARM_FEATURE_V7)) {
+        if (arm_feature(env, ARM_FEATURE_V8)) {
+            /* PMSAv8 */
+            ret = get_phys_addr_pmsav8(env, address, access_type, mmu_idx,
+                                       phys_ptr, prot, fsr);
+        } else if (arm_feature(env, ARM_FEATURE_V7)) {
             /* PMSAv7 */
             ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
                                        phys_ptr, prot, fsr);
-- 
2.7.4

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

* [Qemu-devel] [PATCH 03/20] target/arm: Add state field, feature bit and migration for v8M secure state
  2017-08-22 15:08 [Qemu-devel] [PATCH 00/20] first steps towards v8M support Peter Maydell
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 01/20] target/arm: Implement ARMv8M's PMSAv8 registers Peter Maydell
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 02/20] target/arm: Implement new PMSAv8 behaviour Peter Maydell
@ 2017-08-22 15:08 ` Peter Maydell
  2017-08-29 15:28   ` Richard Henderson
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 04/20] target/arm: Register second AddressSpace for secure v8M CPUs Peter Maydell
                   ` (16 subsequent siblings)
  19 siblings, 1 reply; 60+ messages in thread
From: Peter Maydell @ 2017-08-22 15:08 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

As the first step in implementing ARM v8M's security extension:
 * add a new feature bit ARM_FEATURE_M_SECURITY
 * add the CPU state field that indicates whether the CPU is
   currently in the secure state
 * add a migration subsection for this new state
   (we will add the Secure copies of banked register state
   to this subsection in later patches)
 * add a #define for the one new-in-v8M exception type
 * make the CPU debug log print S/NS status

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu.h       |  3 +++
 target/arm/cpu.c       |  4 ++++
 target/arm/machine.c   | 20 ++++++++++++++++++++
 target/arm/translate.c |  8 +++++++-
 4 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index b6bb78a..24666baa 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -66,6 +66,7 @@
 #define ARMV7M_EXCP_MEM     4
 #define ARMV7M_EXCP_BUS     5
 #define ARMV7M_EXCP_USAGE   6
+#define ARMV7M_EXCP_SECURE  7
 #define ARMV7M_EXCP_SVC     11
 #define ARMV7M_EXCP_DEBUG   12
 #define ARMV7M_EXCP_PENDSV  14
@@ -420,6 +421,7 @@ typedef struct CPUARMState {
         int exception;
         uint32_t primask;
         uint32_t faultmask;
+        uint32_t secure; /* Is CPU in Secure state? (not guest visible) */
     } v7m;
 
     /* Information associated with an exception about to be taken:
@@ -1264,6 +1266,7 @@ enum arm_features {
     ARM_FEATURE_THUMB_DSP, /* DSP insns supported in the Thumb encodings */
     ARM_FEATURE_PMU, /* has PMU support */
     ARM_FEATURE_VBAR, /* has cp15 VBAR */
+    ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
 };
 
 static inline int arm_feature(CPUARMState *env, int feature)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 8b610de..f32317e 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -185,6 +185,10 @@ static void arm_cpu_reset(CPUState *s)
         uint32_t initial_pc; /* Loaded from 0x4 */
         uint8_t *rom;
 
+        if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
+            env->v7m.secure = true;
+        }
+
         /* The reset value of this bit is IMPDEF, but ARM recommends
          * that it resets to 1, so QEMU always does that rather than making
          * it dependent on CPU model.
diff --git a/target/arm/machine.c b/target/arm/machine.c
index 05e2909..745adae 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -235,6 +235,25 @@ static const VMStateDescription vmstate_pmsav8 = {
     }
 };
 
+static bool m_security_needed(void *opaque)
+{
+    ARMCPU *cpu = opaque;
+    CPUARMState *env = &cpu->env;
+
+    return arm_feature(env, ARM_FEATURE_M_SECURITY);
+}
+
+static const VMStateDescription vmstate_m_security = {
+    .name = "cpu/m-security",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = m_security_needed,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(env.v7m.secure, ARMCPU),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
                     VMStateField *field)
 {
@@ -484,6 +503,7 @@ const VMStateDescription vmstate_arm_cpu = {
          */
         &vmstate_pmsav7_rnr,
         &vmstate_pmsav7,
+        &vmstate_m_security,
         NULL
     }
 };
diff --git a/target/arm/translate.c b/target/arm/translate.c
index e52a6d7..dea0a6f 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -12232,6 +12232,11 @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
     if (arm_feature(env, ARM_FEATURE_M)) {
         uint32_t xpsr = xpsr_read(env);
         const char *mode;
+        const char *ns_status = "";
+
+        if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
+            ns_status = env->v7m.secure ? "S " : "NS ";
+        }
 
         if (xpsr & XPSR_EXCP) {
             mode = "handler";
@@ -12243,13 +12248,14 @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
             }
         }
 
-        cpu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s\n",
+        cpu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
                     xpsr,
                     xpsr & XPSR_N ? 'N' : '-',
                     xpsr & XPSR_Z ? 'Z' : '-',
                     xpsr & XPSR_C ? 'C' : '-',
                     xpsr & XPSR_V ? 'V' : '-',
                     xpsr & XPSR_T ? 'T' : 'A',
+                    ns_status,
                     mode);
     } else {
         uint32_t psr = cpsr_read(env);
-- 
2.7.4

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

* [Qemu-devel] [PATCH 04/20] target/arm: Register second AddressSpace for secure v8M CPUs
  2017-08-22 15:08 [Qemu-devel] [PATCH 00/20] first steps towards v8M support Peter Maydell
                   ` (2 preceding siblings ...)
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 03/20] target/arm: Add state field, feature bit and migration for v8M secure state Peter Maydell
@ 2017-08-22 15:08 ` Peter Maydell
  2017-08-29 15:29   ` Richard Henderson
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 05/20] target/arm: Add MMU indexes for secure v8M Peter Maydell
                   ` (15 subsequent siblings)
  19 siblings, 1 reply; 60+ messages in thread
From: Peter Maydell @ 2017-08-22 15:08 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

If a v8M CPU supports the security extension then we need to
give it two AddressSpaces, the same way we do already for
an A profile core with EL3.

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

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index f32317e..ae866be 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -843,22 +843,21 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
     init_cpreg_list(cpu);
 
 #ifndef CONFIG_USER_ONLY
-    if (cpu->has_el3) {
-        cs->num_ases = 2;
-    } else {
-        cs->num_ases = 1;
-    }
-
-    if (cpu->has_el3) {
+    if (cpu->has_el3 || arm_feature(env, ARM_FEATURE_M_SECURITY)) {
         AddressSpace *as;
 
+        cs->num_ases = 2;
+
         if (!cpu->secure_memory) {
             cpu->secure_memory = cs->memory;
         }
         as = address_space_init_shareable(cpu->secure_memory,
                                           "cpu-secure-memory");
         cpu_address_space_init(cs, as, ARMASIdx_S);
+    } else {
+        cs->num_ases = 1;
     }
+
     cpu_address_space_init(cs,
                            address_space_init_shareable(cs->memory,
                                                         "cpu-memory"),
-- 
2.7.4

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

* [Qemu-devel] [PATCH 05/20] target/arm: Add MMU indexes for secure v8M
  2017-08-22 15:08 [Qemu-devel] [PATCH 00/20] first steps towards v8M support Peter Maydell
                   ` (3 preceding siblings ...)
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 04/20] target/arm: Register second AddressSpace for secure v8M CPUs Peter Maydell
@ 2017-08-22 15:08 ` Peter Maydell
  2017-08-25  9:34   ` [Qemu-devel] [Qemu-arm] " Peter Maydell
  2017-08-29 15:36   ` [Qemu-devel] " Richard Henderson
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 06/20] target/arm: Make BASEPRI register banked for v8M Peter Maydell
                   ` (14 subsequent siblings)
  19 siblings, 2 replies; 60+ messages in thread
From: Peter Maydell @ 2017-08-22 15:08 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

Now that MPU lookups can return different results for v8M
when the CPU is in secure vs non-secure state, we need to
have separate MMU indexes; add the secure counterparts
to the existing three M profile MMU indexes.

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

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 24666baa..436ca0d 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -2104,6 +2104,10 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
  *  Execution priority negative (this is like privileged, but the
  *  MPU HFNMIENA bit means that it may have different access permission
  *  check results to normal privileged code, so can't share a TLB).
+ * If the CPU supports the v8M Security Extension then there are also:
+ *  Secure User
+ *  Secure Privileged
+ *  Secure, execution priority negative
  *
  * The ARMMMUIdx and the mmu index value used by the core QEMU TLB code
  * are not quite the same -- different CPU types (most notably M profile
@@ -2141,6 +2145,9 @@ typedef enum ARMMMUIdx {
     ARMMMUIdx_MUser = 0 | ARM_MMU_IDX_M,
     ARMMMUIdx_MPriv = 1 | ARM_MMU_IDX_M,
     ARMMMUIdx_MNegPri = 2 | ARM_MMU_IDX_M,
+    ARMMMUIdx_MSUser = 3 | ARM_MMU_IDX_M,
+    ARMMMUIdx_MSPriv = 4 | ARM_MMU_IDX_M,
+    ARMMMUIdx_MSNegPri = 5 | ARM_MMU_IDX_M,
     /* Indexes below here don't have TLBs and are used only for AT system
      * instructions or for the first stage of an S12 page table walk.
      */
@@ -2162,6 +2169,9 @@ typedef enum ARMMMUIdxBit {
     ARMMMUIdxBit_MUser = 1 << 0,
     ARMMMUIdxBit_MPriv = 1 << 1,
     ARMMMUIdxBit_MNegPri = 1 << 2,
+    ARMMMUIdxBit_MSUser = 1 << 3,
+    ARMMMUIdxBit_MSPriv = 1 << 4,
+    ARMMMUIdxBit_MSNegPri = 1 << 5,
 } ARMMMUIdxBit;
 
 #define MMU_USER_IDX 0
@@ -2187,7 +2197,8 @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
     case ARM_MMU_IDX_A:
         return mmu_idx & 3;
     case ARM_MMU_IDX_M:
-        return mmu_idx == ARMMMUIdx_MUser ? 0 : 1;
+        return (mmu_idx == ARMMMUIdx_MUser || mmu_idx == ARMMMUIdx_MSUser)
+            ? 0 : 1;
     default:
         g_assert_not_reached();
     }
@@ -2206,7 +2217,11 @@ static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
          */
         if ((env->v7m.exception > 0 && env->v7m.exception <= 3)
             || env->v7m.faultmask) {
-            return arm_to_core_mmu_idx(ARMMMUIdx_MNegPri);
+            mmu_idx = ARMMMUIdx_MNegPri;
+        }
+
+        if (env->v7m.secure) {
+            mmu_idx += ARMMMUIdx_MSUser;
         }
 
         return arm_to_core_mmu_idx(mmu_idx);
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 887490a..1debebc 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -7037,6 +7037,9 @@ static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
     case ARMMMUIdx_MPriv:
     case ARMMMUIdx_MNegPri:
     case ARMMMUIdx_MUser:
+    case ARMMMUIdx_MSPriv:
+    case ARMMMUIdx_MSNegPri:
+    case ARMMMUIdx_MSUser:
         return 1;
     default:
         g_assert_not_reached();
@@ -7060,6 +7063,9 @@ static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
     case ARMMMUIdx_S1E3:
     case ARMMMUIdx_S1SE0:
     case ARMMMUIdx_S1SE1:
+    case ARMMMUIdx_MSPriv:
+    case ARMMMUIdx_MSNegPri:
+    case ARMMMUIdx_MSUser:
         return true;
     default:
         g_assert_not_reached();
@@ -7081,7 +7087,8 @@ static inline bool regime_translation_disabled(CPUARMState *env,
                 (R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK)) {
         case R_V7M_MPU_CTRL_ENABLE_MASK:
             /* Enabled, but not for HardFault and NMI */
-            return mmu_idx == ARMMMUIdx_MNegPri;
+            return mmu_idx == ARMMMUIdx_MNegPri ||
+                mmu_idx == ARMMMUIdx_MSNegPri;
         case R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK:
             /* Enabled for all cases */
             return false;
-- 
2.7.4

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

* [Qemu-devel] [PATCH 06/20] target/arm: Make BASEPRI register banked for v8M
  2017-08-22 15:08 [Qemu-devel] [PATCH 00/20] first steps towards v8M support Peter Maydell
                   ` (4 preceding siblings ...)
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 05/20] target/arm: Add MMU indexes for secure v8M Peter Maydell
@ 2017-08-22 15:08 ` Peter Maydell
  2017-08-29 15:37   ` Richard Henderson
  2017-09-05 22:45   ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 07/20] target/arm: Make PRIMASK " Peter Maydell
                   ` (13 subsequent siblings)
  19 siblings, 2 replies; 60+ messages in thread
From: Peter Maydell @ 2017-08-22 15:08 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

Make the BASEPRI register banked if v8M security extensions are enabled.

Note that we do not yet implement the functionality of the new
AIRCR.PRIS bit (which allows the effect of the NS copy of BASEPRI to
be restricted).

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

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 436ca0d..0c28dfd 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -72,6 +72,18 @@
 #define ARMV7M_EXCP_PENDSV  14
 #define ARMV7M_EXCP_SYSTICK 15
 
+/* For M profile, some registers are banked secure vs non-secure;
+ * these are represented as a 2-element array where the first element
+ * is the non-secure copy and the second is the secure copy.
+ * When the CPU does not have implement the security extension then
+ * only the first element is used.
+ * This means that the copy for the current security state can be
+ * accessed via env->registerfield[env->v7m.secure] (whether the security
+ * extension is implemented or not).
+ */
+#define M_REG_NS 0
+#define M_REG_S 1
+
 /* ARM-specific interrupt pending bits.  */
 #define CPU_INTERRUPT_FIQ   CPU_INTERRUPT_TGT_EXT_1
 #define CPU_INTERRUPT_VIRQ  CPU_INTERRUPT_TGT_EXT_2
@@ -409,7 +421,7 @@ typedef struct CPUARMState {
     struct {
         uint32_t other_sp;
         uint32_t vecbase;
-        uint32_t basepri;
+        uint32_t basepri[2];
         uint32_t control;
         uint32_t ccr; /* Configuration and Control */
         uint32_t cfsr; /* Configurable Fault Status */
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index c0dbbad..2a41e5d 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -171,8 +171,8 @@ static inline int nvic_exec_prio(NVICState *s)
         running = -1;
     } else if (env->v7m.primask) {
         running = 0;
-    } else if (env->v7m.basepri > 0) {
-        running = env->v7m.basepri & nvic_gprio_mask(s);
+    } else if (env->v7m.basepri[env->v7m.secure] > 0) {
+        running = env->v7m.basepri[env->v7m.secure] & nvic_gprio_mask(s);
     } else {
         running = NVIC_NOEXC_PRIO; /* lower than any possible priority */
     }
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 1debebc..1087f19 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8838,7 +8838,7 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
         return env->v7m.primask;
     case 17: /* BASEPRI */
     case 18: /* BASEPRI_MAX */
-        return env->v7m.basepri;
+        return env->v7m.basepri[env->v7m.secure];
     case 19: /* FAULTMASK */
         return env->v7m.faultmask;
     default:
@@ -8898,12 +8898,14 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
         env->v7m.primask = val & 1;
         break;
     case 17: /* BASEPRI */
-        env->v7m.basepri = val & 0xff;
+        env->v7m.basepri[env->v7m.secure] = val & 0xff;
         break;
     case 18: /* BASEPRI_MAX */
         val &= 0xff;
-        if (val != 0 && (val < env->v7m.basepri || env->v7m.basepri == 0))
-            env->v7m.basepri = val;
+        if (val != 0 && (val < env->v7m.basepri[env->v7m.secure]
+                         || env->v7m.basepri[env->v7m.secure] == 0)) {
+            env->v7m.basepri[env->v7m.secure] = val;
+        }
         break;
     case 19: /* FAULTMASK */
         env->v7m.faultmask = val & 1;
diff --git a/target/arm/machine.c b/target/arm/machine.c
index 745adae..8476efd 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -115,7 +115,7 @@ static const VMStateDescription vmstate_m = {
     .needed = m_needed,
     .fields = (VMStateField[]) {
         VMSTATE_UINT32(env.v7m.vecbase, ARMCPU),
-        VMSTATE_UINT32(env.v7m.basepri, ARMCPU),
+        VMSTATE_UINT32(env.v7m.basepri[M_REG_NS], ARMCPU),
         VMSTATE_UINT32(env.v7m.control, ARMCPU),
         VMSTATE_UINT32(env.v7m.ccr, ARMCPU),
         VMSTATE_UINT32(env.v7m.cfsr, ARMCPU),
@@ -250,6 +250,7 @@ static const VMStateDescription vmstate_m_security = {
     .needed = m_security_needed,
     .fields = (VMStateField[]) {
         VMSTATE_UINT32(env.v7m.secure, ARMCPU),
+        VMSTATE_UINT32(env.v7m.basepri[M_REG_S], ARMCPU),
         VMSTATE_END_OF_LIST()
     }
 };
-- 
2.7.4

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

* [Qemu-devel] [PATCH 07/20] target/arm: Make PRIMASK register banked for v8M
  2017-08-22 15:08 [Qemu-devel] [PATCH 00/20] first steps towards v8M support Peter Maydell
                   ` (5 preceding siblings ...)
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 06/20] target/arm: Make BASEPRI register banked for v8M Peter Maydell
@ 2017-08-22 15:08 ` Peter Maydell
  2017-08-29 15:38   ` Richard Henderson
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 08/20] target/arm: Make FAULTMASK " Peter Maydell
                   ` (12 subsequent siblings)
  19 siblings, 1 reply; 60+ messages in thread
From: Peter Maydell @ 2017-08-22 15:08 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

Make the PRIMASK register banked if v8M security extensions are enabled.

Note that we do not yet implement the functionality of the new
AIRCR.PRIS bit (which allows the effect of the NS copy of PRIMASK to
be restricted).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu.h      | 2 +-
 hw/intc/armv7m_nvic.c | 2 +-
 target/arm/helper.c   | 4 ++--
 target/arm/machine.c  | 9 +++++++--
 4 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 0c28dfd..fee337b 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -431,7 +431,7 @@ typedef struct CPUARMState {
         uint32_t bfar; /* BusFault Address */
         unsigned mpu_ctrl; /* MPU_CTRL */
         int exception;
-        uint32_t primask;
+        uint32_t primask[2];
         uint32_t faultmask;
         uint32_t secure; /* Is CPU in Secure state? (not guest visible) */
     } v7m;
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 2a41e5d..a654792 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -169,7 +169,7 @@ static inline int nvic_exec_prio(NVICState *s)
 
     if (env->v7m.faultmask) {
         running = -1;
-    } else if (env->v7m.primask) {
+    } else if (env->v7m.primask[env->v7m.secure]) {
         running = 0;
     } else if (env->v7m.basepri[env->v7m.secure] > 0) {
         running = env->v7m.basepri[env->v7m.secure] & nvic_gprio_mask(s);
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 1087f19..c0a6dbd 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8835,7 +8835,7 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
         return (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) ?
             env->regs[13] : env->v7m.other_sp;
     case 16: /* PRIMASK */
-        return env->v7m.primask;
+        return env->v7m.primask[env->v7m.secure];
     case 17: /* BASEPRI */
     case 18: /* BASEPRI_MAX */
         return env->v7m.basepri[env->v7m.secure];
@@ -8895,7 +8895,7 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
         }
         break;
     case 16: /* PRIMASK */
-        env->v7m.primask = val & 1;
+        env->v7m.primask[env->v7m.secure] = val & 1;
         break;
     case 17: /* BASEPRI */
         env->v7m.basepri[env->v7m.secure] = val & 0xff;
diff --git a/target/arm/machine.c b/target/arm/machine.c
index 8476efd..6f0f6c9 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -103,7 +103,7 @@ static const VMStateDescription vmstate_m_faultmask_primask = {
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
         VMSTATE_UINT32(env.v7m.faultmask, ARMCPU),
-        VMSTATE_UINT32(env.v7m.primask, ARMCPU),
+        VMSTATE_UINT32(env.v7m.primask[M_REG_NS], ARMCPU),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -251,6 +251,7 @@ static const VMStateDescription vmstate_m_security = {
     .fields = (VMStateField[]) {
         VMSTATE_UINT32(env.v7m.secure, ARMCPU),
         VMSTATE_UINT32(env.v7m.basepri[M_REG_S], ARMCPU),
+        VMSTATE_UINT32(env.v7m.primask[M_REG_S], ARMCPU),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -271,9 +272,13 @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
              * differences are that the T bit is not in the same place, the
              * primask/faultmask info may be in the CPSR I and F bits, and
              * we do not want the mode bits.
+             * We know that this cleanup happened before v8M, so there
+             * is no complication with banked primask/faultmask.
              */
             uint32_t newval = val;
 
+            assert(!arm_feature(env, ARM_FEATURE_M_SECURITY));
+
             newval &= (CPSR_NZCV | CPSR_Q | CPSR_IT | CPSR_GE);
             if (val & CPSR_T) {
                 newval |= XPSR_T;
@@ -287,7 +292,7 @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
                 env->v7m.faultmask = 1;
             }
             if (val & CPSR_I) {
-                env->v7m.primask = 1;
+                env->v7m.primask[M_REG_NS] = 1;
             }
             val = newval;
         }
-- 
2.7.4

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

* [Qemu-devel] [PATCH 08/20] target/arm: Make FAULTMASK register banked for v8M
  2017-08-22 15:08 [Qemu-devel] [PATCH 00/20] first steps towards v8M support Peter Maydell
                   ` (6 preceding siblings ...)
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 07/20] target/arm: Make PRIMASK " Peter Maydell
@ 2017-08-22 15:08 ` Peter Maydell
  2017-08-29 15:41   ` Richard Henderson
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 09/20] target/arm: Make CONTROL " Peter Maydell
                   ` (11 subsequent siblings)
  19 siblings, 1 reply; 60+ messages in thread
From: Peter Maydell @ 2017-08-22 15:08 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

Make the FAULTMASK register banked if v8M security extensions are enabled.

Note that we do not yet implement the functionality of the new
AIRCR.PRIS bit (which allows the effect of the NS copy of FAULTMASK to
be restricted).

This patch includes the code to determine for v8M which copy
of FAULTMASK should be updated on exception exit; further
changes will be required to the exception exit code in general
to support v8M, so this is just a small piece of that.

The v8M ARM ARM introduces a notation where individual paragraphs
are labelled with R (for rule) or I (for information) followed
by a random group of subscript letters. In comments where we want
to refer to a particular part of the manual we use this convention,
which should be more stable across document revisions than using
section or page numbers.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu.h      | 14 ++++++++++++--
 hw/intc/armv7m_nvic.c |  9 ++++++++-
 target/arm/helper.c   | 20 ++++++++++++++++----
 target/arm/machine.c  |  5 +++--
 4 files changed, 39 insertions(+), 9 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index fee337b..edd4c9e 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -432,7 +432,7 @@ typedef struct CPUARMState {
         unsigned mpu_ctrl; /* MPU_CTRL */
         int exception;
         uint32_t primask[2];
-        uint32_t faultmask;
+        uint32_t faultmask[2];
         uint32_t secure; /* Is CPU in Secure state? (not guest visible) */
     } v7m;
 
@@ -1443,6 +1443,16 @@ void armv7m_nvic_acknowledge_irq(void *opaque);
  * (Ignoring -1, this is the same as the RETTOBASE value before completion.)
  */
 int armv7m_nvic_complete_irq(void *opaque, int irq);
+/**
+ * armv7m_nvic_raw_execution_priority: return the raw execution priority
+ * @opaque: the NVIC
+ *
+ * Returns: the raw execution priority as defined by the v8M architecture.
+ * This is the execution priority minus the effects of AIRCR.PRIS,
+ * and minus any PRIMASK/FAULTMASK/BASEPRI priority boosting.
+ * (v8M ARM ARM I_PKLD.)
+ */
+int armv7m_nvic_raw_execution_priority(void *opaque);
 
 /* Interface for defining coprocessor registers.
  * Registers are defined in tables of arm_cp_reginfo structs
@@ -2228,7 +2238,7 @@ static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
          * we're in a HardFault or NMI handler.
          */
         if ((env->v7m.exception > 0 && env->v7m.exception <= 3)
-            || env->v7m.faultmask) {
+            || env->v7m.faultmask[env->v7m.secure]) {
             mmu_idx = ARMMMUIdx_MNegPri;
         }
 
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index a654792..babdc3b 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -167,7 +167,7 @@ static inline int nvic_exec_prio(NVICState *s)
     CPUARMState *env = &s->cpu->env;
     int running;
 
-    if (env->v7m.faultmask) {
+    if (env->v7m.faultmask[env->v7m.secure]) {
         running = -1;
     } else if (env->v7m.primask[env->v7m.secure]) {
         running = 0;
@@ -187,6 +187,13 @@ bool armv7m_nvic_can_take_pending_exception(void *opaque)
     return nvic_exec_prio(s) > nvic_pending_prio(s);
 }
 
+int armv7m_nvic_raw_execution_priority(void *opaque)
+{
+    NVICState *s = opaque;
+
+    return s->exception_prio;
+}
+
 /* caller must call nvic_irq_update() after this */
 static void set_prio(NVICState *s, unsigned irq, uint8_t prio)
 {
diff --git a/target/arm/helper.c b/target/arm/helper.c
index c0a6dbd..b8f3b23 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6171,8 +6171,20 @@ static void do_v7m_exception_exit(ARMCPU *cpu)
     }
 
     if (env->v7m.exception != ARMV7M_EXCP_NMI) {
-        /* Auto-clear FAULTMASK on return from other than NMI */
-        env->v7m.faultmask = 0;
+        /* Auto-clear FAULTMASK on return from other than NMI.
+         * If the security extension is implemented then this only
+         * happens if the raw execution priority is >= 0; the
+         * value of the ES bit in the exception return value indicates
+         * which security state's faultmask to clear. (v8M ARM ARM R_KBNF.)
+         */
+        if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
+            int es = type & 1;
+            if (armv7m_nvic_raw_execution_priority(env->nvic) >= 0) {
+                env->v7m.faultmask[es] = 0;
+            }
+        } else {
+            env->v7m.faultmask[M_REG_NS] = 0;
+        }
     }
 
     switch (armv7m_nvic_complete_irq(env->nvic, env->v7m.exception)) {
@@ -8840,7 +8852,7 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
     case 18: /* BASEPRI_MAX */
         return env->v7m.basepri[env->v7m.secure];
     case 19: /* FAULTMASK */
-        return env->v7m.faultmask;
+        return env->v7m.faultmask[env->v7m.secure];
     default:
         qemu_log_mask(LOG_GUEST_ERROR, "Attempt to read unknown special"
                                        " register %d\n", reg);
@@ -8908,7 +8920,7 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
         }
         break;
     case 19: /* FAULTMASK */
-        env->v7m.faultmask = val & 1;
+        env->v7m.faultmask[env->v7m.secure] = val & 1;
         break;
     case 20: /* CONTROL */
         /* Writing to the SPSEL bit only has an effect if we are in
diff --git a/target/arm/machine.c b/target/arm/machine.c
index 6f0f6c9..bd7aba1 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -102,7 +102,7 @@ static const VMStateDescription vmstate_m_faultmask_primask = {
     .version_id = 1,
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
-        VMSTATE_UINT32(env.v7m.faultmask, ARMCPU),
+        VMSTATE_UINT32(env.v7m.faultmask[M_REG_NS], ARMCPU),
         VMSTATE_UINT32(env.v7m.primask[M_REG_NS], ARMCPU),
         VMSTATE_END_OF_LIST()
     }
@@ -252,6 +252,7 @@ static const VMStateDescription vmstate_m_security = {
         VMSTATE_UINT32(env.v7m.secure, ARMCPU),
         VMSTATE_UINT32(env.v7m.basepri[M_REG_S], ARMCPU),
         VMSTATE_UINT32(env.v7m.primask[M_REG_S], ARMCPU),
+        VMSTATE_UINT32(env.v7m.faultmask[M_REG_S], ARMCPU),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -289,7 +290,7 @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
              * transferred using the vmstate_m_faultmask_primask subsection.
              */
             if (val & CPSR_F) {
-                env->v7m.faultmask = 1;
+                env->v7m.faultmask[M_REG_NS] = 1;
             }
             if (val & CPSR_I) {
                 env->v7m.primask[M_REG_NS] = 1;
-- 
2.7.4

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

* [Qemu-devel] [PATCH 09/20] target/arm: Make CONTROL register banked for v8M
  2017-08-22 15:08 [Qemu-devel] [PATCH 00/20] first steps towards v8M support Peter Maydell
                   ` (7 preceding siblings ...)
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 08/20] target/arm: Make FAULTMASK " Peter Maydell
@ 2017-08-22 15:08 ` Peter Maydell
  2017-08-29 15:43   ` Richard Henderson
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 10/20] nvic: Add NS alias SCS region Peter Maydell
                   ` (10 subsequent siblings)
  19 siblings, 1 reply; 60+ messages in thread
From: Peter Maydell @ 2017-08-22 15:08 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

Make the CONTROL register banked if v8M security extensions are enabled.

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

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index edd4c9e..e922d1f 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -422,7 +422,7 @@ typedef struct CPUARMState {
         uint32_t other_sp;
         uint32_t vecbase;
         uint32_t basepri[2];
-        uint32_t control;
+        uint32_t control[2];
         uint32_t ccr; /* Configuration and Control */
         uint32_t cfsr; /* Configurable Fault Status */
         uint32_t hfsr; /* HardFault Status */
@@ -1682,7 +1682,8 @@ static inline bool arm_v7m_is_handler_mode(CPUARMState *env)
 static inline int arm_current_el(CPUARMState *env)
 {
     if (arm_feature(env, ARM_FEATURE_M)) {
-        return arm_v7m_is_handler_mode(env) || !(env->v7m.control & 1);
+        return arm_v7m_is_handler_mode(env) ||
+            !(env->v7m.control[env->v7m.secure] & 1);
     }
 
     if (is_a64(env)) {
diff --git a/target/arm/helper.c b/target/arm/helper.c
index b8f3b23..8e74b10 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6053,14 +6053,15 @@ static uint32_t v7m_pop(CPUARMState *env)
 static void switch_v7m_sp(CPUARMState *env, bool new_spsel)
 {
     uint32_t tmp;
-    bool old_spsel = env->v7m.control & R_V7M_CONTROL_SPSEL_MASK;
+    uint32_t old_control = env->v7m.control[env->v7m.secure];
+    bool old_spsel = old_control & R_V7M_CONTROL_SPSEL_MASK;
 
     if (old_spsel != new_spsel) {
         tmp = env->v7m.other_sp;
         env->v7m.other_sp = env->regs[13];
         env->regs[13] = tmp;
 
-        env->v7m.control = deposit32(env->v7m.control,
+        env->v7m.control[env->v7m.secure] = deposit32(old_control,
                                      R_V7M_CONTROL_SPSEL_SHIFT,
                                      R_V7M_CONTROL_SPSEL_LENGTH, new_spsel);
     }
@@ -6414,7 +6415,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
     }
 
     lr = 0xfffffff1;
-    if (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) {
+    if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) {
         lr |= 4;
     }
     if (!arm_v7m_is_handler_mode(env)) {
@@ -8832,7 +8833,7 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
         return xpsr_read(env) & mask;
         break;
     case 20: /* CONTROL */
-        return env->v7m.control;
+        return env->v7m.control[env->v7m.secure];
     }
 
     if (el == 0) {
@@ -8841,10 +8842,10 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
 
     switch (reg) {
     case 8: /* MSP */
-        return (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) ?
+        return (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) ?
             env->v7m.other_sp : env->regs[13];
     case 9: /* PSP */
-        return (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) ?
+        return (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) ?
             env->regs[13] : env->v7m.other_sp;
     case 16: /* PRIMASK */
         return env->v7m.primask[env->v7m.secure];
@@ -8893,14 +8894,14 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
         }
         break;
     case 8: /* MSP */
-        if (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) {
+        if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) {
             env->v7m.other_sp = val;
         } else {
             env->regs[13] = val;
         }
         break;
     case 9: /* PSP */
-        if (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) {
+        if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) {
             env->regs[13] = val;
         } else {
             env->v7m.other_sp = val;
@@ -8931,8 +8932,8 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
         if (!arm_v7m_is_handler_mode(env)) {
             switch_v7m_sp(env, (val & R_V7M_CONTROL_SPSEL_MASK) != 0);
         }
-        env->v7m.control &= ~R_V7M_CONTROL_NPRIV_MASK;
-        env->v7m.control |= val & R_V7M_CONTROL_NPRIV_MASK;
+        env->v7m.control[env->v7m.secure] &= ~R_V7M_CONTROL_NPRIV_MASK;
+        env->v7m.control[env->v7m.secure] |= val & R_V7M_CONTROL_NPRIV_MASK;
         break;
     default:
         qemu_log_mask(LOG_GUEST_ERROR, "Attempt to write unknown special"
diff --git a/target/arm/machine.c b/target/arm/machine.c
index bd7aba1..2cd64c5 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -116,7 +116,7 @@ static const VMStateDescription vmstate_m = {
     .fields = (VMStateField[]) {
         VMSTATE_UINT32(env.v7m.vecbase, ARMCPU),
         VMSTATE_UINT32(env.v7m.basepri[M_REG_NS], ARMCPU),
-        VMSTATE_UINT32(env.v7m.control, ARMCPU),
+        VMSTATE_UINT32(env.v7m.control[M_REG_NS], ARMCPU),
         VMSTATE_UINT32(env.v7m.ccr, ARMCPU),
         VMSTATE_UINT32(env.v7m.cfsr, ARMCPU),
         VMSTATE_UINT32(env.v7m.hfsr, ARMCPU),
@@ -253,6 +253,7 @@ static const VMStateDescription vmstate_m_security = {
         VMSTATE_UINT32(env.v7m.basepri[M_REG_S], ARMCPU),
         VMSTATE_UINT32(env.v7m.primask[M_REG_S], ARMCPU),
         VMSTATE_UINT32(env.v7m.faultmask[M_REG_S], ARMCPU),
+        VMSTATE_UINT32(env.v7m.control[M_REG_S], ARMCPU),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/target/arm/translate.c b/target/arm/translate.c
index dea0a6f..6aa2d7c 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -12241,7 +12241,7 @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
         if (xpsr & XPSR_EXCP) {
             mode = "handler";
         } else {
-            if (env->v7m.control & R_V7M_CONTROL_NPRIV_MASK) {
+            if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
                 mode = "unpriv-thread";
             } else {
                 mode = "priv-thread";
-- 
2.7.4

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

* [Qemu-devel] [PATCH 10/20] nvic: Add NS alias SCS region
  2017-08-22 15:08 [Qemu-devel] [PATCH 00/20] first steps towards v8M support Peter Maydell
                   ` (8 preceding siblings ...)
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 09/20] target/arm: Make CONTROL " Peter Maydell
@ 2017-08-22 15:08 ` Peter Maydell
  2017-08-29 16:00   ` Richard Henderson
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 11/20] target/arm: Make VTOR register banked for v8M Peter Maydell
                   ` (9 subsequent siblings)
  19 siblings, 1 reply; 60+ messages in thread
From: Peter Maydell @ 2017-08-22 15:08 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

For v8M the range 0xe002e000..0xe002efff is an alias region which
for secure accesses behaves like a NonSecure access to the main
SCS region. (For nonsecure accesses including when the security
extension is not implemented, it is RAZ/WI.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/intc/armv7m_nvic.h |  1 +
 hw/intc/armv7m_nvic.c         | 66 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
index 1d145fb..1a4cce7 100644
--- a/include/hw/intc/armv7m_nvic.h
+++ b/include/hw/intc/armv7m_nvic.h
@@ -50,6 +50,7 @@ typedef struct NVICState {
     int exception_prio; /* group prio of the highest prio active exception */
 
     MemoryRegion sysregmem;
+    MemoryRegion sysreg_ns_mem;
     MemoryRegion container;
 
     uint32_t num_irq;
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index babdc3b..2b0b328 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -1040,6 +1040,47 @@ static const MemoryRegionOps nvic_sysreg_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
+static MemTxResult nvic_sysreg_ns_write(void *opaque, hwaddr addr,
+                                        uint64_t value, unsigned size,
+                                        MemTxAttrs attrs)
+{
+    if (attrs.secure) {
+        /* S accesses to the alias act like NS accesses to the real region */
+        attrs.secure = 0;
+        return nvic_sysreg_write(opaque, addr, value, size, attrs);
+    } else {
+        /* NS attrs are RAZ/WI for privileged, and BusFault for user */
+        if (attrs.user) {
+            return MEMTX_ERROR;
+        }
+        return MEMTX_OK;
+    }
+}
+
+static MemTxResult nvic_sysreg_ns_read(void *opaque, hwaddr addr,
+                                       uint64_t *data, unsigned size,
+                                       MemTxAttrs attrs)
+{
+    if (attrs.secure) {
+        /* S accesses to the alias act like NS accesses to the real region */
+        attrs.secure = 0;
+        return nvic_sysreg_read(opaque, addr, data, size, attrs);
+    } else {
+        /* NS attrs are RAZ/WI for privileged, and BusFault for user */
+        if (attrs.user) {
+            return MEMTX_ERROR;
+        }
+        *data = 0;
+        return MEMTX_OK;
+    }
+}
+
+static const MemoryRegionOps nvic_sysreg_ns_ops = {
+    .read_with_attrs = nvic_sysreg_ns_read,
+    .write_with_attrs = nvic_sysreg_ns_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
 static int nvic_post_load(void *opaque, int version_id)
 {
     NVICState *s = opaque;
@@ -1141,6 +1182,7 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
     NVICState *s = NVIC(dev);
     SysBusDevice *systick_sbd;
     Error *err = NULL;
+    int regionlen;
 
     s->cpu = ARM_CPU(qemu_get_cpu(0));
     assert(s->cpu);
@@ -1173,8 +1215,23 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
      *  0xd00..0xd3c - SCS registers
      *  0xd40..0xeff - Reserved or Not implemented
      *  0xf00 - STIR
+     *
+     * Some registers within this space are banked between security states.
+     * In v8M there is a second range 0xe002e000..0xe002efff which is the
+     * NonSecure alias SCS; secure accesses to this behave like NS accesses
+     * to the main SCS range, and non-secure accesses (including when
+     * the security extension is not implemented) are RAZ/WI.
+     * Note that both the main SCS range and the alias range are defined
+     * to be exempt from memory attribution (R_BLJT) and so the memory
+     * transaction attribute always matches the current CPU security
+     * state (attrs.secure == env->v7m.secure). In the nvic_sysreg_ns_ops
+     * wrappers we change attrs.secure to indicate the NS access; so
+     * generally code determining which banked register to use should
+     * use attrs.secure; code determining actual behaviour of the system
+     * should use env->v7m.secure.
      */
-    memory_region_init(&s->container, OBJECT(s), "nvic", 0x1000);
+    regionlen = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? 0x21000 : 0x1000;
+    memory_region_init(&s->container, OBJECT(s), "nvic", regionlen);
     /* The system register region goes at the bottom of the priority
      * stack as it covers the whole page.
      */
@@ -1185,6 +1242,13 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
                                         sysbus_mmio_get_region(systick_sbd, 0),
                                         1);
 
+    if (arm_feature(&s->cpu->env, ARM_FEATURE_V8)) {
+        memory_region_init_io(&s->sysreg_ns_mem, OBJECT(s),
+                              &nvic_sysreg_ns_ops, s,
+                              "nvic_sysregs_ns", 0x1000);
+        memory_region_add_subregion(&s->container, 0x20000, &s->sysreg_ns_mem);
+    }
+
     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->container);
 }
 
-- 
2.7.4

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

* [Qemu-devel] [PATCH 11/20] target/arm: Make VTOR register banked for v8M
  2017-08-22 15:08 [Qemu-devel] [PATCH 00/20] first steps towards v8M support Peter Maydell
                   ` (9 preceding siblings ...)
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 10/20] nvic: Add NS alias SCS region Peter Maydell
@ 2017-08-22 15:08 ` Peter Maydell
  2017-08-29 16:02   ` Richard Henderson
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 12/20] target/arm: Make MPU_MAIR0, MPU_MAIR1 registers " Peter Maydell
                   ` (8 subsequent siblings)
  19 siblings, 1 reply; 60+ messages in thread
From: Peter Maydell @ 2017-08-22 15:08 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

Make the VTOR register banked if v8M security extensions are enabled.

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

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index e922d1f..d0b0936 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -420,7 +420,7 @@ typedef struct CPUARMState {
 
     struct {
         uint32_t other_sp;
-        uint32_t vecbase;
+        uint32_t vecbase[2];
         uint32_t basepri[2];
         uint32_t control[2];
         uint32_t ccr; /* Configuration and Control */
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 2b0b328..3a1f02d 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -403,7 +403,7 @@ static void set_irq_level(void *opaque, int n, int level)
     }
 }
 
-static uint32_t nvic_readl(NVICState *s, uint32_t offset)
+static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
 {
     ARMCPU *cpu = s->cpu;
     uint32_t val;
@@ -441,7 +441,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset)
         /* ISRPREEMPT not implemented */
         return val;
     case 0xd08: /* Vector Table Offset.  */
-        return cpu->env.v7m.vecbase;
+        return cpu->env.v7m.vecbase[attrs.secure];
     case 0xd0c: /* Application Interrupt/Reset Control.  */
         return 0xfa050000 | (s->prigroup << 8);
     case 0xd10: /* System Control.  */
@@ -617,7 +617,8 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset)
     }
 }
 
-static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
+static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
+                        MemTxAttrs attrs)
 {
     ARMCPU *cpu = s->cpu;
 
@@ -638,7 +639,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
         }
         break;
     case 0xd08: /* Vector Table Offset.  */
-        cpu->env.v7m.vecbase = value & 0xffffff80;
+        cpu->env.v7m.vecbase[attrs.secure] = value & 0xffffff80;
         break;
     case 0xd0c: /* Application Interrupt/Reset Control.  */
         if ((value >> 16) == 0x05fa) {
@@ -944,7 +945,7 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
         break;
     default:
         if (size == 4) {
-            val = nvic_readl(s, offset);
+            val = nvic_readl(s, offset, attrs);
         } else {
             qemu_log_mask(LOG_GUEST_ERROR,
                           "NVIC: Bad read of size %d at offset 0x%x\n",
@@ -1025,7 +1026,7 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
         return MEMTX_OK;
     }
     if (size == 4) {
-        nvic_writel(s, offset, value);
+        nvic_writel(s, offset, value, attrs);
         return MEMTX_OK;
     }
     qemu_log_mask(LOG_GUEST_ERROR,
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 8e74b10..b1bb507 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6072,7 +6072,7 @@ static uint32_t arm_v7m_load_vector(ARMCPU *cpu)
     CPUState *cs = CPU(cpu);
     CPUARMState *env = &cpu->env;
     MemTxResult result;
-    hwaddr vec = env->v7m.vecbase + env->v7m.exception * 4;
+    hwaddr vec = env->v7m.vecbase[env->v7m.secure] + env->v7m.exception * 4;
     uint32_t addr;
 
     addr = address_space_ldl(cs->as, vec,
diff --git a/target/arm/machine.c b/target/arm/machine.c
index 2cd64c5..cd6b6af 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -114,7 +114,7 @@ static const VMStateDescription vmstate_m = {
     .minimum_version_id = 4,
     .needed = m_needed,
     .fields = (VMStateField[]) {
-        VMSTATE_UINT32(env.v7m.vecbase, ARMCPU),
+        VMSTATE_UINT32(env.v7m.vecbase[M_REG_NS], ARMCPU),
         VMSTATE_UINT32(env.v7m.basepri[M_REG_NS], ARMCPU),
         VMSTATE_UINT32(env.v7m.control[M_REG_NS], ARMCPU),
         VMSTATE_UINT32(env.v7m.ccr, ARMCPU),
@@ -254,6 +254,7 @@ static const VMStateDescription vmstate_m_security = {
         VMSTATE_UINT32(env.v7m.primask[M_REG_S], ARMCPU),
         VMSTATE_UINT32(env.v7m.faultmask[M_REG_S], ARMCPU),
         VMSTATE_UINT32(env.v7m.control[M_REG_S], ARMCPU),
+        VMSTATE_UINT32(env.v7m.vecbase[M_REG_S], ARMCPU),
         VMSTATE_END_OF_LIST()
     }
 };
-- 
2.7.4

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

* [Qemu-devel] [PATCH 12/20] target/arm: Make MPU_MAIR0, MPU_MAIR1 registers banked for v8M
  2017-08-22 15:08 [Qemu-devel] [PATCH 00/20] first steps towards v8M support Peter Maydell
                   ` (10 preceding siblings ...)
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 11/20] target/arm: Make VTOR register banked for v8M Peter Maydell
@ 2017-08-22 15:08 ` Peter Maydell
  2017-08-29 16:02   ` Richard Henderson
  2017-09-05 22:59   ` Philippe Mathieu-Daudé
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 13/20] target/arm: Make MPU_RBAR, MPU_RLAR " Peter Maydell
                   ` (7 subsequent siblings)
  19 siblings, 2 replies; 60+ messages in thread
From: Peter Maydell @ 2017-08-22 15:08 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

Make the MPU registers MPU_MAIR0 and MPU_MAIR1 banked if v8M security
extensions are enabled.

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

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index d0b0936..2f59828 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -545,8 +545,8 @@ typedef struct CPUARMState {
          */
         uint32_t *rbar;
         uint32_t *rlar;
-        uint32_t mair0;
-        uint32_t mair1;
+        uint32_t mair0[2];
+        uint32_t mair1[2];
     } pmsav8;
 
     void *nvic;
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 3a1f02d..e98eb95 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -604,12 +604,12 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
             goto bad_offset;
         }
-        return cpu->env.pmsav8.mair0;
+        return cpu->env.pmsav8.mair0[attrs.secure];
     case 0xdc4: /* MPU_MAIR1 */
         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
             goto bad_offset;
         }
-        return cpu->env.pmsav8.mair1;
+        return cpu->env.pmsav8.mair1[attrs.secure];
     default:
     bad_offset:
         qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);
@@ -826,7 +826,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
         }
         if (cpu->pmsav7_dregion) {
             /* Register is RES0 if no MPU regions are implemented */
-            cpu->env.pmsav8.mair0 = value;
+            cpu->env.pmsav8.mair0[attrs.secure] = value;
         }
         /* We don't need to do anything else because memory attributes
          * only affect cacheability, and we don't implement caching.
@@ -838,7 +838,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
         }
         if (cpu->pmsav7_dregion) {
             /* Register is RES0 if no MPU regions are implemented */
-            cpu->env.pmsav8.mair1 = value;
+            cpu->env.pmsav8.mair1[attrs.secure] = value;
         }
         /* We don't need to do anything else because memory attributes
          * only affect cacheability, and we don't implement caching.
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index ae866be..ae8af19 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -249,8 +249,8 @@ static void arm_cpu_reset(CPUState *s)
             }
         }
         env->pmsav7.rnr = 0;
-        env->pmsav8.mair0 = 0;
-        env->pmsav8.mair1 = 0;
+        memset(env->pmsav8.mair0, 0, sizeof(env->pmsav8.mair0));
+        memset(env->pmsav8.mair1, 0, sizeof(env->pmsav8.mair1));
     }
 
     set_flush_to_zero(1, &env->vfp.standard_fp_status);
diff --git a/target/arm/machine.c b/target/arm/machine.c
index cd6b6af..414a879 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -229,8 +229,8 @@ static const VMStateDescription vmstate_pmsav8 = {
                               vmstate_info_uint32, uint32_t),
         VMSTATE_VARRAY_UINT32(env.pmsav8.rlar, ARMCPU, pmsav7_dregion, 0,
                               vmstate_info_uint32, uint32_t),
-        VMSTATE_UINT32(env.pmsav8.mair0, ARMCPU),
-        VMSTATE_UINT32(env.pmsav8.mair1, ARMCPU),
+        VMSTATE_UINT32(env.pmsav8.mair0[M_REG_NS], ARMCPU),
+        VMSTATE_UINT32(env.pmsav8.mair1[M_REG_NS], ARMCPU),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -255,6 +255,8 @@ static const VMStateDescription vmstate_m_security = {
         VMSTATE_UINT32(env.v7m.faultmask[M_REG_S], ARMCPU),
         VMSTATE_UINT32(env.v7m.control[M_REG_S], ARMCPU),
         VMSTATE_UINT32(env.v7m.vecbase[M_REG_S], ARMCPU),
+        VMSTATE_UINT32(env.pmsav8.mair0[M_REG_S], ARMCPU),
+        VMSTATE_UINT32(env.pmsav8.mair1[M_REG_S], ARMCPU),
         VMSTATE_END_OF_LIST()
     }
 };
-- 
2.7.4

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

* [Qemu-devel] [PATCH 13/20] target/arm: Make MPU_RBAR, MPU_RLAR banked for v8M
  2017-08-22 15:08 [Qemu-devel] [PATCH 00/20] first steps towards v8M support Peter Maydell
                   ` (11 preceding siblings ...)
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 12/20] target/arm: Make MPU_MAIR0, MPU_MAIR1 registers " Peter Maydell
@ 2017-08-22 15:08 ` Peter Maydell
  2017-08-29 16:04   ` Richard Henderson
  2017-09-05 23:02   ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 14/20] target/arm: Make MPU_RNR register " Peter Maydell
                   ` (6 subsequent siblings)
  19 siblings, 2 replies; 60+ messages in thread
From: Peter Maydell @ 2017-08-22 15:08 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

Make the MPU registers MPU_MAIR0 and MPU_MAIR1 banked if v8M security
extensions are enabled.

We can freely add more items to vmstate_m_security without
breaking migration compatibility, because no CPU currently
has the ARM_FEATURE_M_SECURITY bit enabled and so this
subsection is not yet used by anything.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu.h      |  4 ++--
 hw/intc/armv7m_nvic.c |  8 ++++----
 target/arm/cpu.c      | 26 ++++++++++++++++++++------
 target/arm/helper.c   | 11 ++++++-----
 target/arm/machine.c  | 12 ++++++++----
 5 files changed, 40 insertions(+), 21 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 2f59828..12fa95e 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -543,8 +543,8 @@ typedef struct CPUARMState {
          *  pmsav7.rnr (region number register)
          *  pmsav7_dregion (number of configured regions)
          */
-        uint32_t *rbar;
-        uint32_t *rlar;
+        uint32_t *rbar[2];
+        uint32_t *rlar[2];
         uint32_t mair0[2];
         uint32_t mair1[2];
     } pmsav8;
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index e98eb95..9ced7af 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -564,7 +564,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
             if (region >= cpu->pmsav7_dregion) {
                 return 0;
             }
-            return cpu->env.pmsav8.rbar[region];
+            return cpu->env.pmsav8.rbar[attrs.secure][region];
         }
 
         if (region >= cpu->pmsav7_dregion) {
@@ -591,7 +591,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
             if (region >= cpu->pmsav7_dregion) {
                 return 0;
             }
-            return cpu->env.pmsav8.rlar[region];
+            return cpu->env.pmsav8.rlar[attrs.secure][region];
         }
 
         if (region >= cpu->pmsav7_dregion) {
@@ -756,7 +756,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
             if (region >= cpu->pmsav7_dregion) {
                 return;
             }
-            cpu->env.pmsav8.rbar[region] = value;
+            cpu->env.pmsav8.rbar[attrs.secure][region] = value;
             tlb_flush(CPU(cpu));
             return;
         }
@@ -806,7 +806,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
             if (region >= cpu->pmsav7_dregion) {
                 return;
             }
-            cpu->env.pmsav8.rlar[region] = value;
+            cpu->env.pmsav8.rlar[attrs.secure][region] = value;
             tlb_flush(CPU(cpu));
             return;
         }
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index ae8af19..333029c 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -235,10 +235,20 @@ static void arm_cpu_reset(CPUState *s)
     if (arm_feature(env, ARM_FEATURE_PMSA)) {
         if (cpu->pmsav7_dregion > 0) {
             if (arm_feature(env, ARM_FEATURE_V8)) {
-                memset(env->pmsav8.rbar, 0,
-                       sizeof(*env->pmsav8.rbar) * cpu->pmsav7_dregion);
-                memset(env->pmsav8.rlar, 0,
-                       sizeof(*env->pmsav8.rlar) * cpu->pmsav7_dregion);
+                memset(env->pmsav8.rbar[M_REG_NS], 0,
+                       sizeof(*env->pmsav8.rbar[M_REG_NS])
+                       * cpu->pmsav7_dregion);
+                memset(env->pmsav8.rlar[M_REG_NS], 0,
+                       sizeof(*env->pmsav8.rlar[M_REG_NS])
+                       * cpu->pmsav7_dregion);
+                if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
+                    memset(env->pmsav8.rbar[M_REG_S], 0,
+                           sizeof(*env->pmsav8.rbar[M_REG_S])
+                           * cpu->pmsav7_dregion);
+                    memset(env->pmsav8.rlar[M_REG_S], 0,
+                           sizeof(*env->pmsav8.rlar[M_REG_S])
+                           * cpu->pmsav7_dregion);
+                }
             } else if (arm_feature(env, ARM_FEATURE_V7)) {
                 memset(env->pmsav7.drbar, 0,
                        sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion);
@@ -823,8 +833,12 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
         if (nr) {
             if (arm_feature(env, ARM_FEATURE_V8)) {
                 /* PMSAv8 */
-                env->pmsav8.rbar = g_new0(uint32_t, nr);
-                env->pmsav8.rlar = g_new0(uint32_t, nr);
+                env->pmsav8.rbar[M_REG_NS] = g_new0(uint32_t, nr);
+                env->pmsav8.rlar[M_REG_NS] = g_new0(uint32_t, nr);
+                if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
+                    env->pmsav8.rbar[M_REG_S] = g_new0(uint32_t, nr);
+                    env->pmsav8.rlar[M_REG_S] = g_new0(uint32_t, nr);
+                }
             } else {
                 env->pmsav7.drbar = g_new0(uint32_t, nr);
                 env->pmsav7.drsr = g_new0(uint32_t, nr);
diff --git a/target/arm/helper.c b/target/arm/helper.c
index b1bb507..5394cef 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8442,6 +8442,7 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
 {
     ARMCPU *cpu = arm_env_get_cpu(env);
     bool is_user = regime_is_user(env, mmu_idx);
+    uint32_t secure = regime_is_secure(env, mmu_idx);
     int n;
     int matchregion = -1;
     bool hit = false;
@@ -8468,10 +8469,10 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
              * with bits [4:0] all zeroes, but the limit address is bits
              * [31:5] from the register with bits [4:0] all ones.
              */
-            uint32_t base = env->pmsav8.rbar[n] & ~0x1f;
-            uint32_t limit = env->pmsav8.rlar[n] | 0x1f;
+            uint32_t base = env->pmsav8.rbar[secure][n] & ~0x1f;
+            uint32_t limit = env->pmsav8.rlar[secure][n] | 0x1f;
 
-            if (!(env->pmsav8.rlar[n] & 0x1)) {
+            if (!(env->pmsav8.rlar[secure][n] & 0x1)) {
                 /* Region disabled */
                 continue;
             }
@@ -8520,8 +8521,8 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
         /* hit using the background region */
         get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
     } else {
-        uint32_t ap = extract32(env->pmsav8.rbar[matchregion], 1, 2);
-        uint32_t xn = extract32(env->pmsav8.rbar[matchregion], 0, 1);
+        uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2);
+        uint32_t xn = extract32(env->pmsav8.rbar[secure][matchregion], 0, 1);
 
         if (m_is_system_region(env, address)) {
             /* System space is always execute never */
diff --git a/target/arm/machine.c b/target/arm/machine.c
index 414a879..05c6c7a 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -225,10 +225,10 @@ static const VMStateDescription vmstate_pmsav8 = {
     .minimum_version_id = 1,
     .needed = pmsav8_needed,
     .fields = (VMStateField[]) {
-        VMSTATE_VARRAY_UINT32(env.pmsav8.rbar, ARMCPU, pmsav7_dregion, 0,
-                              vmstate_info_uint32, uint32_t),
-        VMSTATE_VARRAY_UINT32(env.pmsav8.rlar, ARMCPU, pmsav7_dregion, 0,
-                              vmstate_info_uint32, uint32_t),
+        VMSTATE_VARRAY_UINT32(env.pmsav8.rbar[M_REG_NS], ARMCPU, pmsav7_dregion,
+                              0, vmstate_info_uint32, uint32_t),
+        VMSTATE_VARRAY_UINT32(env.pmsav8.rlar[M_REG_NS], ARMCPU, pmsav7_dregion,
+                              0, vmstate_info_uint32, uint32_t),
         VMSTATE_UINT32(env.pmsav8.mair0[M_REG_NS], ARMCPU),
         VMSTATE_UINT32(env.pmsav8.mair1[M_REG_NS], ARMCPU),
         VMSTATE_END_OF_LIST()
@@ -257,6 +257,10 @@ static const VMStateDescription vmstate_m_security = {
         VMSTATE_UINT32(env.v7m.vecbase[M_REG_S], ARMCPU),
         VMSTATE_UINT32(env.pmsav8.mair0[M_REG_S], ARMCPU),
         VMSTATE_UINT32(env.pmsav8.mair1[M_REG_S], ARMCPU),
+        VMSTATE_VARRAY_UINT32(env.pmsav8.rbar[M_REG_S], ARMCPU, pmsav7_dregion,
+                              0, vmstate_info_uint32, uint32_t),
+        VMSTATE_VARRAY_UINT32(env.pmsav8.rlar[M_REG_S], ARMCPU, pmsav7_dregion,
+                              0, vmstate_info_uint32, uint32_t),
         VMSTATE_END_OF_LIST()
     }
 };
-- 
2.7.4

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

* [Qemu-devel] [PATCH 14/20] target/arm: Make MPU_RNR register banked for v8M
  2017-08-22 15:08 [Qemu-devel] [PATCH 00/20] first steps towards v8M support Peter Maydell
                   ` (12 preceding siblings ...)
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 13/20] target/arm: Make MPU_RBAR, MPU_RLAR " Peter Maydell
@ 2017-08-22 15:08 ` Peter Maydell
  2017-08-29 16:05   ` Richard Henderson
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 15/20] target/arm: Make MPU_CTRL " Peter Maydell
                   ` (5 subsequent siblings)
  19 siblings, 1 reply; 60+ messages in thread
From: Peter Maydell @ 2017-08-22 15:08 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

Make the MPU_RNR register banked if v8M security extensions are
enabled.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu.h      |  2 +-
 hw/intc/armv7m_nvic.c | 18 +++++++++---------
 target/arm/cpu.c      |  3 ++-
 target/arm/helper.c   |  6 +++---
 target/arm/machine.c  | 13 +++++++++++--
 5 files changed, 26 insertions(+), 16 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 12fa95e..43d36d6 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -533,7 +533,7 @@ typedef struct CPUARMState {
         uint32_t *drbar;
         uint32_t *drsr;
         uint32_t *dracr;
-        uint32_t rnr;
+        uint32_t rnr[2];
     } pmsav7;
 
     /* PMSAv8 MPU */
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 9ced7af..c3c214c 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -543,13 +543,13 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
     case 0xd94: /* MPU_CTRL */
         return cpu->env.v7m.mpu_ctrl;
     case 0xd98: /* MPU_RNR */
-        return cpu->env.pmsav7.rnr;
+        return cpu->env.pmsav7.rnr[attrs.secure];
     case 0xd9c: /* MPU_RBAR */
     case 0xda4: /* MPU_RBAR_A1 */
     case 0xdac: /* MPU_RBAR_A2 */
     case 0xdb4: /* MPU_RBAR_A3 */
     {
-        int region = cpu->env.pmsav7.rnr;
+        int region = cpu->env.pmsav7.rnr[attrs.secure];
 
         if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
             /* PMSAv8M handling of the aliases is different from v7M:
@@ -577,7 +577,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
     case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */
     case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */
     {
-        int region = cpu->env.pmsav7.rnr;
+        int region = cpu->env.pmsav7.rnr[attrs.secure];
 
         if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
             /* PMSAv8M handling of the aliases is different from v7M:
@@ -731,7 +731,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
                           PRIu32 "/%" PRIu32 "\n",
                           value, cpu->pmsav7_dregion);
         } else {
-            cpu->env.pmsav7.rnr = value;
+            cpu->env.pmsav7.rnr[attrs.secure] = value;
         }
         break;
     case 0xd9c: /* MPU_RBAR */
@@ -749,7 +749,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
              */
             int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
 
-            region = cpu->env.pmsav7.rnr;
+            region = cpu->env.pmsav7.rnr[attrs.secure];
             if (aliasno) {
                 region = deposit32(region, 0, 2, aliasno);
             }
@@ -772,9 +772,9 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
                               region, cpu->pmsav7_dregion);
                 return;
             }
-            cpu->env.pmsav7.rnr = region;
+            cpu->env.pmsav7.rnr[attrs.secure] = region;
         } else {
-            region = cpu->env.pmsav7.rnr;
+            region = cpu->env.pmsav7.rnr[attrs.secure];
         }
 
         if (region >= cpu->pmsav7_dregion) {
@@ -790,7 +790,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
     case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */
     case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */
     {
-        int region = cpu->env.pmsav7.rnr;
+        int region = cpu->env.pmsav7.rnr[attrs.secure];
 
         if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
             /* PMSAv8M handling of the aliases is different from v7M:
@@ -799,7 +799,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
              */
             int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
 
-            region = cpu->env.pmsav7.rnr;
+            region = cpu->env.pmsav7.rnr[attrs.secure];
             if (aliasno) {
                 region = deposit32(region, 0, 2, aliasno);
             }
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 333029c..11038b8 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -258,7 +258,8 @@ static void arm_cpu_reset(CPUState *s)
                        sizeof(*env->pmsav7.dracr) * cpu->pmsav7_dregion);
             }
         }
-        env->pmsav7.rnr = 0;
+        env->pmsav7.rnr[M_REG_NS] = 0;
+        env->pmsav7.rnr[M_REG_S] = 0;
         memset(env->pmsav8.mair0, 0, sizeof(env->pmsav8.mair0));
         memset(env->pmsav8.mair1, 0, sizeof(env->pmsav8.mair1));
     }
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 5394cef..48e0fc6 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -2385,7 +2385,7 @@ static uint64_t pmsav7_read(CPUARMState *env, const ARMCPRegInfo *ri)
         return 0;
     }
 
-    u32p += env->pmsav7.rnr;
+    u32p += env->pmsav7.rnr[M_REG_NS];
     return *u32p;
 }
 
@@ -2399,7 +2399,7 @@ static void pmsav7_write(CPUARMState *env, const ARMCPRegInfo *ri,
         return;
     }
 
-    u32p += env->pmsav7.rnr;
+    u32p += env->pmsav7.rnr[M_REG_NS];
     tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
     *u32p = value;
 }
@@ -2442,7 +2442,7 @@ static const ARMCPRegInfo pmsav7_cp_reginfo[] = {
       .resetfn = arm_cp_reset_ignore },
     { .name = "RGNR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 2, .opc2 = 0,
       .access = PL1_RW,
-      .fieldoffset = offsetof(CPUARMState, pmsav7.rnr),
+      .fieldoffset = offsetof(CPUARMState, pmsav7.rnr[M_REG_NS]),
       .writefn = pmsav7_rgnr_write,
       .resetfn = arm_cp_reset_ignore },
     REGINFO_SENTINEL
diff --git a/target/arm/machine.c b/target/arm/machine.c
index 05c6c7a..6941e35 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -167,7 +167,7 @@ static bool pmsav7_rgnr_vmstate_validate(void *opaque, int version_id)
 {
     ARMCPU *cpu = opaque;
 
-    return cpu->env.pmsav7.rnr < cpu->pmsav7_dregion;
+    return cpu->env.pmsav7.rnr[M_REG_NS] < cpu->pmsav7_dregion;
 }
 
 static const VMStateDescription vmstate_pmsav7 = {
@@ -205,7 +205,7 @@ static const VMStateDescription vmstate_pmsav7_rnr = {
     .minimum_version_id = 1,
     .needed = pmsav7_rnr_needed,
     .fields = (VMStateField[]) {
-        VMSTATE_UINT32(env.pmsav7.rnr, ARMCPU),
+        VMSTATE_UINT32(env.pmsav7.rnr[M_REG_NS], ARMCPU),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -235,6 +235,13 @@ static const VMStateDescription vmstate_pmsav8 = {
     }
 };
 
+static bool s_rnr_vmstate_validate(void *opaque, int version_id)
+{
+    ARMCPU *cpu = opaque;
+
+    return cpu->env.pmsav7.rnr[M_REG_S] < cpu->pmsav7_dregion;
+}
+
 static bool m_security_needed(void *opaque)
 {
     ARMCPU *cpu = opaque;
@@ -261,6 +268,8 @@ static const VMStateDescription vmstate_m_security = {
                               0, vmstate_info_uint32, uint32_t),
         VMSTATE_VARRAY_UINT32(env.pmsav8.rlar[M_REG_S], ARMCPU, pmsav7_dregion,
                               0, vmstate_info_uint32, uint32_t),
+        VMSTATE_UINT32(env.pmsav7.rnr[M_REG_S], ARMCPU),
+        VMSTATE_VALIDATE("secure MPU_RNR is valid", s_rnr_vmstate_validate),
         VMSTATE_END_OF_LIST()
     }
 };
-- 
2.7.4

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

* [Qemu-devel] [PATCH 15/20] target/arm: Make MPU_CTRL register banked for v8M
  2017-08-22 15:08 [Qemu-devel] [PATCH 00/20] first steps towards v8M support Peter Maydell
                   ` (13 preceding siblings ...)
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 14/20] target/arm: Make MPU_RNR register " Peter Maydell
@ 2017-08-22 15:08 ` Peter Maydell
  2017-08-29 16:06   ` Richard Henderson
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 16/20] target/arm: Make CCR " Peter Maydell
                   ` (4 subsequent siblings)
  19 siblings, 1 reply; 60+ messages in thread
From: Peter Maydell @ 2017-08-22 15:08 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

Make the MPU_CTRL register banked if v8M security extensions are
enabled.

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

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 43d36d6..78cd3f0 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -429,7 +429,7 @@ typedef struct CPUARMState {
         uint32_t dfsr; /* Debug Fault Status Register */
         uint32_t mmfar; /* MemManage Fault Address */
         uint32_t bfar; /* BusFault Address */
-        unsigned mpu_ctrl; /* MPU_CTRL */
+        unsigned mpu_ctrl[2]; /* MPU_CTRL */
         int exception;
         uint32_t primask[2];
         uint32_t faultmask[2];
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index c3c214c..a4c298f 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -541,7 +541,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
         return cpu->pmsav7_dregion << 8;
         break;
     case 0xd94: /* MPU_CTRL */
-        return cpu->env.v7m.mpu_ctrl;
+        return cpu->env.v7m.mpu_ctrl[attrs.secure];
     case 0xd98: /* MPU_RNR */
         return cpu->env.pmsav7.rnr[attrs.secure];
     case 0xd9c: /* MPU_RBAR */
@@ -720,9 +720,10 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
             qemu_log_mask(LOG_GUEST_ERROR, "MPU_CTRL: HFNMIENA and !ENABLE is "
                           "UNPREDICTABLE\n");
         }
-        cpu->env.v7m.mpu_ctrl = value & (R_V7M_MPU_CTRL_ENABLE_MASK |
-                                         R_V7M_MPU_CTRL_HFNMIENA_MASK |
-                                         R_V7M_MPU_CTRL_PRIVDEFENA_MASK);
+        cpu->env.v7m.mpu_ctrl[attrs.secure]
+            = value & (R_V7M_MPU_CTRL_ENABLE_MASK |
+                       R_V7M_MPU_CTRL_HFNMIENA_MASK |
+                       R_V7M_MPU_CTRL_PRIVDEFENA_MASK);
         tlb_flush(CPU(cpu));
         break;
     case 0xd98: /* MPU_RNR */
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 48e0fc6..4a2148c 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -7096,7 +7096,7 @@ static inline bool regime_translation_disabled(CPUARMState *env,
                                                ARMMMUIdx mmu_idx)
 {
     if (arm_feature(env, ARM_FEATURE_M)) {
-        switch (env->v7m.mpu_ctrl &
+        switch (env->v7m.mpu_ctrl[regime_is_secure(env, mmu_idx)] &
                 (R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK)) {
         case R_V7M_MPU_CTRL_ENABLE_MASK:
             /* Enabled, but not for HardFault and NMI */
@@ -8256,7 +8256,8 @@ static bool pmsav7_use_background_region(ARMCPU *cpu,
     }
 
     if (arm_feature(env, ARM_FEATURE_M)) {
-        return env->v7m.mpu_ctrl & R_V7M_MPU_CTRL_PRIVDEFENA_MASK;
+        return env->v7m.mpu_ctrl[regime_is_secure(env, mmu_idx)]
+            & R_V7M_MPU_CTRL_PRIVDEFENA_MASK;
     } else {
         return regime_sctlr(env, mmu_idx) & SCTLR_BR;
     }
diff --git a/target/arm/machine.c b/target/arm/machine.c
index 6941e35..5cc95e8 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -123,7 +123,7 @@ static const VMStateDescription vmstate_m = {
         VMSTATE_UINT32(env.v7m.dfsr, ARMCPU),
         VMSTATE_UINT32(env.v7m.mmfar, ARMCPU),
         VMSTATE_UINT32(env.v7m.bfar, ARMCPU),
-        VMSTATE_UINT32(env.v7m.mpu_ctrl, ARMCPU),
+        VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_NS], ARMCPU),
         VMSTATE_INT32(env.v7m.exception, ARMCPU),
         VMSTATE_END_OF_LIST()
     },
@@ -270,6 +270,7 @@ static const VMStateDescription vmstate_m_security = {
                               0, vmstate_info_uint32, uint32_t),
         VMSTATE_UINT32(env.pmsav7.rnr[M_REG_S], ARMCPU),
         VMSTATE_VALIDATE("secure MPU_RNR is valid", s_rnr_vmstate_validate),
+        VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_S], ARMCPU),
         VMSTATE_END_OF_LIST()
     }
 };
-- 
2.7.4

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

* [Qemu-devel] [PATCH 16/20] target/arm: Make CCR register banked for v8M
  2017-08-22 15:08 [Qemu-devel] [PATCH 00/20] first steps towards v8M support Peter Maydell
                   ` (14 preceding siblings ...)
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 15/20] target/arm: Make MPU_CTRL " Peter Maydell
@ 2017-08-22 15:08 ` Peter Maydell
  2017-08-29 16:08   ` Richard Henderson
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 17/20] target/arm: Make MMFAR " Peter Maydell
                   ` (3 subsequent siblings)
  19 siblings, 1 reply; 60+ messages in thread
From: Peter Maydell @ 2017-08-22 15:08 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

Make the CCR register banked if v8M security extensions are enabled.

This is slightly more complicated than the other "add banking"
patches because there is one bit in the register which is not
banked. We keep the live data in the NS copy of the register,
and adjust it on register reads and writes. (Since we don't
currently implement the behaviour that the bit controls, there
is nowhere else that needs to care.)

This patch includes the enforcement of the bits which are newly
RES1 in ARMv8M.

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

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 78cd3f0..25ebf9e 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -423,7 +423,7 @@ typedef struct CPUARMState {
         uint32_t vecbase[2];
         uint32_t basepri[2];
         uint32_t control[2];
-        uint32_t ccr; /* Configuration and Control */
+        uint32_t ccr[2]; /* Configuration and Control */
         uint32_t cfsr; /* Configurable Fault Status */
         uint32_t hfsr; /* HardFault Status */
         uint32_t dfsr; /* Debug Fault Status Register */
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index a4c298f..f071649 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -448,7 +448,12 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
         /* TODO: Implement SLEEPONEXIT.  */
         return 0;
     case 0xd14: /* Configuration Control.  */
-        return cpu->env.v7m.ccr;
+        /* The BFHFNMIGN bit is the only non-banked bit; we
+         * keep it in the non-secure copy of the register.
+         */
+        val = cpu->env.v7m.ccr[attrs.secure];
+        val |= cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK;
+        return val;
     case 0xd24: /* System Handler Status.  */
         val = 0;
         if (s->vectors[ARMV7M_EXCP_MEM].active) {
@@ -673,7 +678,23 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
                   R_V7M_CCR_USERSETMPEND_MASK |
                   R_V7M_CCR_NONBASETHRDENA_MASK);
 
-        cpu->env.v7m.ccr = value;
+        if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+            /* v8M makes NONBASETHRDENA and STKALIGN be RES1 */
+            value |= R_V7M_CCR_NONBASETHRDENA_MASK
+                | R_V7M_CCR_STKALIGN_MASK;
+        }
+        if (attrs.secure) {
+            /* the BFHFNMIGN bit is not banked; keep that in the NS copy */
+            int new_bfhnmign = !!(value & R_V7M_CCR_BFHFNMIGN_MASK);
+
+            cpu->env.v7m.ccr[M_REG_NS] = deposit32(cpu->env.v7m.ccr[M_REG_NS],
+                                                    R_V7M_CCR_BFHFNMIGN_SHIFT,
+                                                    R_V7M_CCR_BFHFNMIGN_LENGTH,
+                                                    new_bfhnmign);
+            value &= ~R_V7M_CCR_BFHFNMIGN_MASK;
+        }
+
+        cpu->env.v7m.ccr[attrs.secure] = value;
         break;
     case 0xd24: /* System Handler Control.  */
         s->vectors[ARMV7M_EXCP_MEM].active = (value & (1 << 0)) != 0;
@@ -860,12 +881,15 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
     }
 }
 
-static bool nvic_user_access_ok(NVICState *s, hwaddr offset)
+static bool nvic_user_access_ok(NVICState *s, hwaddr offset, MemTxAttrs attrs)
 {
     /* Return true if unprivileged access to this register is permitted. */
     switch (offset) {
     case 0xf00: /* STIR: accessible only if CCR.USERSETMPEND permits */
-        return s->cpu->env.v7m.ccr & R_V7M_CCR_USERSETMPEND_MASK;
+        /* For access via STIR_NS it is the NS CCR.USERSETMPEND that
+         * controls access even though the CPU is in Secure state (I_QDKX).
+         */
+        return s->cpu->env.v7m.ccr[attrs.secure] & R_V7M_CCR_USERSETMPEND_MASK;
     default:
         /* All other user accesses cause a BusFault unconditionally */
         return false;
@@ -881,7 +905,7 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
     unsigned i, startvec, end;
     uint32_t val;
 
-    if (attrs.user && !nvic_user_access_ok(s, addr)) {
+    if (attrs.user && !nvic_user_access_ok(s, addr, attrs)) {
         /* Generate BusFault for unprivileged accesses */
         return MEMTX_ERROR;
     }
@@ -971,7 +995,7 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
 
     trace_nvic_sysreg_write(addr, value, size);
 
-    if (attrs.user && !nvic_user_access_ok(s, addr)) {
+    if (attrs.user && !nvic_user_access_ok(s, addr, attrs)) {
         /* Generate BusFault for unprivileged accesses */
         return MEMTX_ERROR;
     }
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 11038b8..3c2ff11 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -189,11 +189,17 @@ static void arm_cpu_reset(CPUState *s)
             env->v7m.secure = true;
         }
 
-        /* The reset value of this bit is IMPDEF, but ARM recommends
+        /* In v7M the reset value of this bit is IMPDEF, but ARM recommends
          * that it resets to 1, so QEMU always does that rather than making
-         * it dependent on CPU model.
+         * it dependent on CPU model. In v8M it is RES1.
          */
-        env->v7m.ccr = R_V7M_CCR_STKALIGN_MASK;
+        env->v7m.ccr[M_REG_NS] = R_V7M_CCR_STKALIGN_MASK;
+        env->v7m.ccr[M_REG_S] = R_V7M_CCR_STKALIGN_MASK;
+        if (arm_feature(env, ARM_FEATURE_V8)) {
+            /* in v8M the NONBASETHRDENA bit [0] is RES1 */
+            env->v7m.ccr[M_REG_NS] |= R_V7M_CCR_NONBASETHRDENA_MASK;
+            env->v7m.ccr[M_REG_S] |= R_V7M_CCR_NONBASETHRDENA_MASK;
+        }
 
         /* Unlike A/R profile, M profile defines the reset LR value */
         env->regs[14] = 0xffffffff;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 4a2148c..28b3d6c 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6118,7 +6118,8 @@ static void v7m_push_stack(ARMCPU *cpu)
     uint32_t xpsr = xpsr_read(env);
 
     /* Align stack pointer if the guest wants that */
-    if ((env->regs[13] & 4) && (env->v7m.ccr & R_V7M_CCR_STKALIGN_MASK)) {
+    if ((env->regs[13] & 4) &&
+        (env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_STKALIGN_MASK)) {
         env->regs[13] -= 4;
         xpsr |= XPSR_SPREALIGN;
     }
@@ -6216,7 +6217,7 @@ static void do_v7m_exception_exit(ARMCPU *cpu)
         /* fall through */
     case 9: /* Return to Thread using Main stack */
         if (!rettobase &&
-            !(env->v7m.ccr & R_V7M_CCR_NONBASETHRDENA_MASK)) {
+            !(env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_NONBASETHRDENA_MASK)) {
             ufault = true;
         }
         break;
diff --git a/target/arm/machine.c b/target/arm/machine.c
index 5cc95e8..4457ec6 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -117,7 +117,7 @@ static const VMStateDescription vmstate_m = {
         VMSTATE_UINT32(env.v7m.vecbase[M_REG_NS], ARMCPU),
         VMSTATE_UINT32(env.v7m.basepri[M_REG_NS], ARMCPU),
         VMSTATE_UINT32(env.v7m.control[M_REG_NS], ARMCPU),
-        VMSTATE_UINT32(env.v7m.ccr, ARMCPU),
+        VMSTATE_UINT32(env.v7m.ccr[M_REG_NS], ARMCPU),
         VMSTATE_UINT32(env.v7m.cfsr, ARMCPU),
         VMSTATE_UINT32(env.v7m.hfsr, ARMCPU),
         VMSTATE_UINT32(env.v7m.dfsr, ARMCPU),
@@ -271,6 +271,7 @@ static const VMStateDescription vmstate_m_security = {
         VMSTATE_UINT32(env.pmsav7.rnr[M_REG_S], ARMCPU),
         VMSTATE_VALIDATE("secure MPU_RNR is valid", s_rnr_vmstate_validate),
         VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_S], ARMCPU),
+        VMSTATE_UINT32(env.v7m.ccr[M_REG_S], ARMCPU),
         VMSTATE_END_OF_LIST()
     }
 };
-- 
2.7.4

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

* [Qemu-devel] [PATCH 17/20] target/arm: Make MMFAR banked for v8M
  2017-08-22 15:08 [Qemu-devel] [PATCH 00/20] first steps towards v8M support Peter Maydell
                   ` (15 preceding siblings ...)
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 16/20] target/arm: Make CCR " Peter Maydell
@ 2017-08-22 15:08 ` Peter Maydell
  2017-08-29 16:10   ` Richard Henderson
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 18/20] target/arm: Make CFSR register " Peter Maydell
                   ` (2 subsequent siblings)
  19 siblings, 1 reply; 60+ messages in thread
From: Peter Maydell @ 2017-08-22 15:08 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

Make the MMFAR register banked if v8M security extensions are
enabled.

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

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 25ebf9e..21c68d7 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -427,7 +427,7 @@ typedef struct CPUARMState {
         uint32_t cfsr; /* Configurable Fault Status */
         uint32_t hfsr; /* HardFault Status */
         uint32_t dfsr; /* Debug Fault Status Register */
-        uint32_t mmfar; /* MemManage Fault Address */
+        uint32_t mmfar[2]; /* MemManage Fault Address */
         uint32_t bfar; /* BusFault Address */
         unsigned mpu_ctrl[2]; /* MPU_CTRL */
         int exception;
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index f071649..99b62ac 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -506,7 +506,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
     case 0xd30: /* Debug Fault Status.  */
         return cpu->env.v7m.dfsr;
     case 0xd34: /* MMFAR MemManage Fault Address */
-        return cpu->env.v7m.mmfar;
+        return cpu->env.v7m.mmfar[attrs.secure];
     case 0xd38: /* Bus Fault Address.  */
         return cpu->env.v7m.bfar;
     case 0xd3c: /* Aux Fault Status.  */
@@ -723,7 +723,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
         cpu->env.v7m.dfsr &= ~value; /* W1C */
         break;
     case 0xd34: /* Mem Manage Address.  */
-        cpu->env.v7m.mmfar = value;
+        cpu->env.v7m.mmfar[attrs.secure] = value;
         return;
     case 0xd38: /* Bus Fault Address.  */
         cpu->env.v7m.bfar = value;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 28b3d6c..e587e85 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6380,10 +6380,10 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
             case EXCP_DATA_ABORT:
                 env->v7m.cfsr |=
                     (R_V7M_CFSR_DACCVIOL_MASK | R_V7M_CFSR_MMARVALID_MASK);
-                env->v7m.mmfar = env->exception.vaddress;
+                env->v7m.mmfar[env->v7m.secure] = env->exception.vaddress;
                 qemu_log_mask(CPU_LOG_INT,
                               "...with CFSR.DACCVIOL and MMFAR 0x%x\n",
-                              env->v7m.mmfar);
+                              env->v7m.mmfar[env->v7m.secure]);
                 break;
             }
             armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM);
diff --git a/target/arm/machine.c b/target/arm/machine.c
index 4457ec6..5122e58 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -121,7 +121,7 @@ static const VMStateDescription vmstate_m = {
         VMSTATE_UINT32(env.v7m.cfsr, ARMCPU),
         VMSTATE_UINT32(env.v7m.hfsr, ARMCPU),
         VMSTATE_UINT32(env.v7m.dfsr, ARMCPU),
-        VMSTATE_UINT32(env.v7m.mmfar, ARMCPU),
+        VMSTATE_UINT32(env.v7m.mmfar[M_REG_NS], ARMCPU),
         VMSTATE_UINT32(env.v7m.bfar, ARMCPU),
         VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_NS], ARMCPU),
         VMSTATE_INT32(env.v7m.exception, ARMCPU),
@@ -272,6 +272,7 @@ static const VMStateDescription vmstate_m_security = {
         VMSTATE_VALIDATE("secure MPU_RNR is valid", s_rnr_vmstate_validate),
         VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_S], ARMCPU),
         VMSTATE_UINT32(env.v7m.ccr[M_REG_S], ARMCPU),
+        VMSTATE_UINT32(env.v7m.mmfar[M_REG_S], ARMCPU),
         VMSTATE_END_OF_LIST()
     }
 };
-- 
2.7.4

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

* [Qemu-devel] [PATCH 18/20] target/arm: Make CFSR register banked for v8M
  2017-08-22 15:08 [Qemu-devel] [PATCH 00/20] first steps towards v8M support Peter Maydell
                   ` (16 preceding siblings ...)
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 17/20] target/arm: Make MMFAR " Peter Maydell
@ 2017-08-22 15:08 ` Peter Maydell
  2017-08-29 16:12   ` Richard Henderson
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 19/20] target/arm: Move regime_is_secure() to target/arm/internals.h Peter Maydell
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 20/20] target/arm: Implement BXNS, and banked stack pointers Peter Maydell
  19 siblings, 1 reply; 60+ messages in thread
From: Peter Maydell @ 2017-08-22 15:08 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

Make the CFSR register banked if v8M security extensions are enabled.

Not all the bits in this register are banked: the BFSR
bits [15:8] are shared between S and NS, and we store them
in the NS copy of the register.

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

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 21c68d7..3683537 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -424,7 +424,7 @@ typedef struct CPUARMState {
         uint32_t basepri[2];
         uint32_t control[2];
         uint32_t ccr[2]; /* Configuration and Control */
-        uint32_t cfsr; /* Configurable Fault Status */
+        uint32_t cfsr[2]; /* Configurable Fault Status */
         uint32_t hfsr; /* HardFault Status */
         uint32_t dfsr; /* Debug Fault Status Register */
         uint32_t mmfar[2]; /* MemManage Fault Address */
@@ -1210,6 +1210,11 @@ FIELD(V7M_CFSR, NOCP, 16 + 3, 1)
 FIELD(V7M_CFSR, UNALIGNED, 16 + 8, 1)
 FIELD(V7M_CFSR, DIVBYZERO, 16 + 9, 1)
 
+/* V7M CFSR bit masks covering all of the subregister bits */
+FIELD(V7M_CFSR, MMFSR, 0, 8)
+FIELD(V7M_CFSR, BFSR, 8, 8)
+FIELD(V7M_CFSR, UFSR, 16, 16)
+
 /* V7M HFSR bits */
 FIELD(V7M_HFSR, VECTTBL, 1, 1)
 FIELD(V7M_HFSR, FORCED, 30, 1)
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 99b62ac..3c14cc8 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -500,7 +500,12 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
         }
         return val;
     case 0xd28: /* Configurable Fault Status.  */
-        return cpu->env.v7m.cfsr;
+        /* The BFSR bits [15:8] are shared between security states
+         * and we store them in the NS copy
+         */
+        val = cpu->env.v7m.cfsr[attrs.secure];
+        val |= cpu->env.v7m.cfsr[M_REG_NS] & R_V7M_CFSR_BFSR_MASK;
+        return val;
     case 0xd2c: /* Hard Fault Status.  */
         return cpu->env.v7m.hfsr;
     case 0xd30: /* Debug Fault Status.  */
@@ -714,7 +719,13 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
         nvic_irq_update(s);
         break;
     case 0xd28: /* Configurable Fault Status.  */
-        cpu->env.v7m.cfsr &= ~value; /* W1C */
+        cpu->env.v7m.cfsr[attrs.secure] &= ~value; /* W1C */
+        if (attrs.secure) {
+            /* The BFSR bits [15:8] are shared between security states
+             * and we store them in the NS copy.
+             */
+            cpu->env.v7m.cfsr[M_REG_NS] &= ~(value & R_V7M_CFSR_BFSR_MASK);
+        }
         break;
     case 0xd2c: /* Hard Fault Status.  */
         cpu->env.v7m.hfsr &= ~value; /* W1C */
diff --git a/target/arm/helper.c b/target/arm/helper.c
index e587e85..67b3874 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6229,7 +6229,7 @@ static void do_v7m_exception_exit(ARMCPU *cpu)
         /* Bad exception return: instead of popping the exception
          * stack, directly take a usage fault on the current stack.
          */
-        env->v7m.cfsr |= R_V7M_CFSR_INVPC_MASK;
+        env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK;
         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
         v7m_exception_taken(cpu, type | 0xf0000000);
         qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing "
@@ -6271,7 +6271,7 @@ static void do_v7m_exception_exit(ARMCPU *cpu)
     if (return_to_handler != arm_v7m_is_handler_mode(env)) {
         /* Take an INVPC UsageFault by pushing the stack again. */
         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
-        env->v7m.cfsr |= R_V7M_CFSR_INVPC_MASK;
+        env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK;
         v7m_push_stack(cpu);
         v7m_exception_taken(cpu, type | 0xf0000000);
         qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on new stackframe: "
@@ -6330,15 +6330,15 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
     switch (cs->exception_index) {
     case EXCP_UDEF:
         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
-        env->v7m.cfsr |= R_V7M_CFSR_UNDEFINSTR_MASK;
+        env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNDEFINSTR_MASK;
         break;
     case EXCP_NOCP:
         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
-        env->v7m.cfsr |= R_V7M_CFSR_NOCP_MASK;
+        env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_NOCP_MASK;
         break;
     case EXCP_INVSTATE:
         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
-        env->v7m.cfsr |= R_V7M_CFSR_INVSTATE_MASK;
+        env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVSTATE_MASK;
         break;
     case EXCP_SWI:
         /* The PC already points to the next instruction.  */
@@ -6354,11 +6354,11 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
         case 0x8: /* External Abort */
             switch (cs->exception_index) {
             case EXCP_PREFETCH_ABORT:
-                env->v7m.cfsr |= R_V7M_CFSR_PRECISERR_MASK;
+                env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_PRECISERR_MASK;
                 qemu_log_mask(CPU_LOG_INT, "...with CFSR.PRECISERR\n");
                 break;
             case EXCP_DATA_ABORT:
-                env->v7m.cfsr |=
+                env->v7m.cfsr[M_REG_NS] |=
                     (R_V7M_CFSR_IBUSERR_MASK | R_V7M_CFSR_BFARVALID_MASK);
                 env->v7m.bfar = env->exception.vaddress;
                 qemu_log_mask(CPU_LOG_INT,
@@ -6374,11 +6374,11 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
              */
             switch (cs->exception_index) {
             case EXCP_PREFETCH_ABORT:
-                env->v7m.cfsr |= R_V7M_CFSR_IACCVIOL_MASK;
+                env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_IACCVIOL_MASK;
                 qemu_log_mask(CPU_LOG_INT, "...with CFSR.IACCVIOL\n");
                 break;
             case EXCP_DATA_ABORT:
-                env->v7m.cfsr |=
+                env->v7m.cfsr[env->v7m.secure] |=
                     (R_V7M_CFSR_DACCVIOL_MASK | R_V7M_CFSR_MMARVALID_MASK);
                 env->v7m.mmfar[env->v7m.secure] = env->exception.vaddress;
                 qemu_log_mask(CPU_LOG_INT,
diff --git a/target/arm/machine.c b/target/arm/machine.c
index 5122e58..3cc94b4 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -118,7 +118,7 @@ static const VMStateDescription vmstate_m = {
         VMSTATE_UINT32(env.v7m.basepri[M_REG_NS], ARMCPU),
         VMSTATE_UINT32(env.v7m.control[M_REG_NS], ARMCPU),
         VMSTATE_UINT32(env.v7m.ccr[M_REG_NS], ARMCPU),
-        VMSTATE_UINT32(env.v7m.cfsr, ARMCPU),
+        VMSTATE_UINT32(env.v7m.cfsr[M_REG_NS], ARMCPU),
         VMSTATE_UINT32(env.v7m.hfsr, ARMCPU),
         VMSTATE_UINT32(env.v7m.dfsr, ARMCPU),
         VMSTATE_UINT32(env.v7m.mmfar[M_REG_NS], ARMCPU),
@@ -273,6 +273,7 @@ static const VMStateDescription vmstate_m_security = {
         VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_S], ARMCPU),
         VMSTATE_UINT32(env.v7m.ccr[M_REG_S], ARMCPU),
         VMSTATE_UINT32(env.v7m.mmfar[M_REG_S], ARMCPU),
+        VMSTATE_UINT32(env.v7m.cfsr[M_REG_S], ARMCPU),
         VMSTATE_END_OF_LIST()
     }
 };
-- 
2.7.4

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

* [Qemu-devel] [PATCH 19/20] target/arm: Move regime_is_secure() to target/arm/internals.h
  2017-08-22 15:08 [Qemu-devel] [PATCH 00/20] first steps towards v8M support Peter Maydell
                   ` (17 preceding siblings ...)
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 18/20] target/arm: Make CFSR register " Peter Maydell
@ 2017-08-22 15:08 ` Peter Maydell
  2017-08-29 16:12   ` Richard Henderson
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 20/20] target/arm: Implement BXNS, and banked stack pointers Peter Maydell
  19 siblings, 1 reply; 60+ messages in thread
From: Peter Maydell @ 2017-08-22 15:08 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

Move the regime_is_secure() utility function to internals.h;
we are going to want to call it from translate.c.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/internals.h | 26 ++++++++++++++++++++++++++
 target/arm/helper.c    | 26 --------------------------
 2 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index bb06946..eb171b1 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -478,4 +478,30 @@ static inline void arm_call_el_change_hook(ARMCPU *cpu)
     }
 }
 
+/* Return true if this address translation regime is secure */
+static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
+{
+    switch (mmu_idx) {
+    case ARMMMUIdx_S12NSE0:
+    case ARMMMUIdx_S12NSE1:
+    case ARMMMUIdx_S1NSE0:
+    case ARMMMUIdx_S1NSE1:
+    case ARMMMUIdx_S1E2:
+    case ARMMMUIdx_S2NS:
+    case ARMMMUIdx_MPriv:
+    case ARMMMUIdx_MNegPri:
+    case ARMMMUIdx_MUser:
+        return false;
+    case ARMMMUIdx_S1E3:
+    case ARMMMUIdx_S1SE0:
+    case ARMMMUIdx_S1SE1:
+    case ARMMMUIdx_MSPriv:
+    case ARMMMUIdx_MSNegPri:
+    case ARMMMUIdx_MSUser:
+        return true;
+    default:
+        g_assert_not_reached();
+    }
+}
+
 #endif
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 67b3874..b1ae73c 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -7060,32 +7060,6 @@ static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
     }
 }
 
-/* Return true if this address translation regime is secure */
-static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
-{
-    switch (mmu_idx) {
-    case ARMMMUIdx_S12NSE0:
-    case ARMMMUIdx_S12NSE1:
-    case ARMMMUIdx_S1NSE0:
-    case ARMMMUIdx_S1NSE1:
-    case ARMMMUIdx_S1E2:
-    case ARMMMUIdx_S2NS:
-    case ARMMMUIdx_MPriv:
-    case ARMMMUIdx_MNegPri:
-    case ARMMMUIdx_MUser:
-        return false;
-    case ARMMMUIdx_S1E3:
-    case ARMMMUIdx_S1SE0:
-    case ARMMMUIdx_S1SE1:
-    case ARMMMUIdx_MSPriv:
-    case ARMMMUIdx_MSNegPri:
-    case ARMMMUIdx_MSUser:
-        return true;
-    default:
-        g_assert_not_reached();
-    }
-}
-
 /* Return the SCTLR value which controls this address translation regime */
 static inline uint32_t regime_sctlr(CPUARMState *env, ARMMMUIdx mmu_idx)
 {
-- 
2.7.4

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

* [Qemu-devel] [PATCH 20/20] target/arm: Implement BXNS, and banked stack pointers
  2017-08-22 15:08 [Qemu-devel] [PATCH 00/20] first steps towards v8M support Peter Maydell
                   ` (18 preceding siblings ...)
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 19/20] target/arm: Move regime_is_secure() to target/arm/internals.h Peter Maydell
@ 2017-08-22 15:08 ` Peter Maydell
  2017-08-29 16:31   ` Richard Henderson
  19 siblings, 1 reply; 60+ messages in thread
From: Peter Maydell @ 2017-08-22 15:08 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches

Implement the BXNS v8M instruction, which is like BX but will do a
jump-and-switch-to-NonSecure if the branch target address has bit 0
clear.

This is the first piece of code which implements "switch to the
other security state", so the commit also includes the code to
switch the stack pointers around, which is the only complicated
part of switching security state.

BLXNS is more complicated than just "BXNS but set the link register",
so we leave it for a separate commit.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu.h       | 13 +++++++++
 target/arm/helper.h    |  2 ++
 target/arm/translate.h |  1 +
 target/arm/helper.c    | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++
 target/arm/machine.c   |  2 ++
 target/arm/translate.c | 42 ++++++++++++++++++++++++++-
 6 files changed, 138 insertions(+), 1 deletion(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 3683537..5e7b68b 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -419,7 +419,20 @@ typedef struct CPUARMState {
     } cp15;
 
     struct {
+        /* M profile has up to 4 stack pointers:
+         * a Main Stack Pointer and a Process Stack Pointer for each
+         * of the Secure and Non-Secure states. (If the CPU doesn't support
+         * the security extension then it has only two SPs.)
+         * In QEMU we always store the currently active SP in regs[13],
+         * and the non-active SP for the current security state in
+         * v7m.other_sp. The stack pointers for the inactive security state
+         * are stored in other_ss_msp and other_ss_psp.
+         * switch_v7m_security_state() is responsible for rearranging them
+         * when we change security state.
+         */
         uint32_t other_sp;
+        uint32_t other_ss_msp;
+        uint32_t other_ss_psp;
         uint32_t vecbase[2];
         uint32_t basepri[2];
         uint32_t control[2];
diff --git a/target/arm/helper.h b/target/arm/helper.h
index df86bf7..64afbac 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -63,6 +63,8 @@ DEF_HELPER_1(cpsr_read, i32, env)
 DEF_HELPER_3(v7m_msr, void, env, i32, i32)
 DEF_HELPER_2(v7m_mrs, i32, env, i32)
 
+DEF_HELPER_2(v7m_bxns, void, env, i32)
+
 DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
 DEF_HELPER_3(set_cp_reg, void, env, ptr, i32)
 DEF_HELPER_2(get_cp_reg, i32, env, ptr)
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 2fe144b..ef625ad 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -32,6 +32,7 @@ typedef struct DisasContext {
     int vec_len;
     int vec_stride;
     bool v7m_handler_mode;
+    bool v8m_secure; /* true if v8M and we're in Secure mode */
     /* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
      * so that top level loop can generate correct syndrome information.
      */
diff --git a/target/arm/helper.c b/target/arm/helper.c
index b1ae73c..4489bbd 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -5875,6 +5875,12 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
     return 0;
 }
 
+void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest)
+{
+    /* translate.c should never generate calls here in user-only mode */
+    g_assert_not_reached();
+}
+
 void switch_mode(CPUARMState *env, int mode)
 {
     ARMCPU *cpu = arm_env_get_cpu(env);
@@ -6049,6 +6055,18 @@ static uint32_t v7m_pop(CPUARMState *env)
     return val;
 }
 
+/* Return true if we're using the process stack pointer (not the MSP) */
+static bool v7m_using_psp(CPUARMState *env)
+{
+    /* Handler mode always uses the main stack; for thread mode
+     * the CONTROL.SPSEL bit determines the answer.
+     * Note that in v7M it is not possible to be in Handler mode with
+     * CONTROL.SPSEL non-zero, but in v8M it is, so we must check both.
+     */
+    return !arm_v7m_is_handler_mode(env) &&
+        env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK;
+}
+
 /* Switch to V7M main or process stack pointer.  */
 static void switch_v7m_sp(CPUARMState *env, bool new_spsel)
 {
@@ -6067,6 +6085,67 @@ static void switch_v7m_sp(CPUARMState *env, bool new_spsel)
     }
 }
 
+/* Switch M profile security state between NS and S */
+static void switch_v7m_security_state(CPUARMState *env, bool new_secstate)
+{
+    uint32_t new_ss_msp, new_ss_psp;
+
+    if (env->v7m.secure == new_secstate) {
+        return;
+    }
+
+    /* All the banked state is accessed by looking at env->v7m.secure
+     * except for the stack pointer; rearrange the SP appropriately.
+     */
+    new_ss_msp = env->v7m.other_ss_msp;
+    new_ss_psp = env->v7m.other_ss_psp;
+
+    if (v7m_using_psp(env)) {
+        env->v7m.other_ss_psp = env->regs[13];
+        env->v7m.other_ss_msp = env->v7m.other_sp;
+    } else {
+        env->v7m.other_ss_msp = env->regs[13];
+        env->v7m.other_ss_psp = env->v7m.other_sp;
+    }
+
+    env->v7m.secure = new_secstate;
+
+    if (v7m_using_psp(env)) {
+        env->regs[13] = new_ss_psp;
+        env->v7m.other_sp = new_ss_msp;
+    } else {
+        env->regs[13] = new_ss_msp;
+        env->v7m.other_sp = new_ss_psp;
+    }
+}
+
+void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest)
+{
+    /* Handle v7M BXNS:
+     *  - if the return value is a magic value, do exception return (like BX)
+     *  - otherwise bit 0 of the return value is the target security state
+     */
+    if (dest >= 0xff000000) {
+        /* This is an exception return magic value; put it where
+         * do_v7m_exception_exit() expects and raise EXCEPTION_EXIT.
+         * Note that if we ever add gen_ss_advance() singlestep support to
+         * M profile this should count as an "instruction execution complete"
+         * event (compare gen_bx_excret_final_code()).
+         */
+        env->regs[15] = dest & ~1;
+        env->thumb = dest & 1;
+        HELPER(exception_internal)(env, EXCP_EXCEPTION_EXIT);
+        /* notreached */
+    }
+
+    /* translate.c should have made BXNS UNDEF unless we're secure */
+    assert(env->v7m.secure);
+
+    switch_v7m_security_state(env, dest & 1);
+    env->thumb = 1;
+    env->regs[15] = dest & ~1;
+}
+
 static uint32_t arm_v7m_load_vector(ARMCPU *cpu)
 {
     CPUState *cs = CPU(cpu);
diff --git a/target/arm/machine.c b/target/arm/machine.c
index 3cc94b4..1aca40d 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -257,6 +257,8 @@ static const VMStateDescription vmstate_m_security = {
     .needed = m_security_needed,
     .fields = (VMStateField[]) {
         VMSTATE_UINT32(env.v7m.secure, ARMCPU),
+        VMSTATE_UINT32(env.v7m.other_ss_msp, ARMCPU),
+        VMSTATE_UINT32(env.v7m.other_ss_psp, ARMCPU),
         VMSTATE_UINT32(env.v7m.basepri[M_REG_S], ARMCPU),
         VMSTATE_UINT32(env.v7m.primask[M_REG_S], ARMCPU),
         VMSTATE_UINT32(env.v7m.faultmask[M_REG_S], ARMCPU),
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 6aa2d7c..e7966e2 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -994,6 +994,25 @@ static inline void gen_bx_excret_final_code(DisasContext *s)
     gen_exception_internal(EXCP_EXCEPTION_EXIT);
 }
 
+static inline void gen_bxns(DisasContext *s, int rm)
+{
+    TCGv_i32 var = load_reg(s, rm);
+
+    /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
+     * we need to sync state before calling it, but:
+     *  - we don't need to do gen_set_pc_im() because the bxns helper will
+     *    always set the PC itself
+     *  - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
+     *    unless it's outside an IT block or the last insn in an IT block,
+     *    so we know that condexec == 0 (already set at the top of the TB)
+     *    is correct in the non-UNPREDICTABLE cases, and we can choose
+     *    "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
+     */
+    gen_helper_v7m_bxns(cpu_env, var);
+    tcg_temp_free_i32(var);
+    s->is_jmp = DISAS_EXIT;
+}
+
 /* Variant of store_reg which uses branch&exchange logic when storing
    to r15 in ARM architecture v7 and above. The source must be a temporary
    and will be marked as dead. */
@@ -11185,12 +11204,31 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
                  */
                 bool link = insn & (1 << 7);
 
-                if (insn & 7) {
+                if (insn & 3) {
                     goto undef;
                 }
                 if (link) {
                     ARCH(5);
                 }
+                if ((insn & 4)) {
+                    /* BXNS/BLXNS: only exists for v8M with the
+                     * security extensions, and always UNDEF if NonSecure.
+                     * We don't implement these in the user-only mode
+                     * either (in theory you can use them from Secure User
+                     * mode but they are too tied in to system emulation.)
+                     */
+                    if (!s->v8m_secure || IS_USER_ONLY) {
+                        goto undef;
+                    }
+                    if (link) {
+                        /* BLXNS: not yet implemented */
+                        goto undef;
+                    } else {
+                        gen_bxns(s, rm);
+                    }
+                    break;
+                }
+                /* BLX/BX */
                 tmp = load_reg(s, rm);
                 if (link) {
                     val = (uint32_t)s->pc | 1;
@@ -11878,6 +11916,8 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
     dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
     dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags);
     dc->v7m_handler_mode = ARM_TBFLAG_HANDLER(tb->flags);
+    dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
+        regime_is_secure(env, dc->mmu_idx);
     dc->cp_regs = cpu->cp_regs;
     dc->features = env->features;
 
-- 
2.7.4

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

* Re: [Qemu-devel] [Qemu-arm] [PATCH 05/20] target/arm: Add MMU indexes for secure v8M
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 05/20] target/arm: Add MMU indexes for secure v8M Peter Maydell
@ 2017-08-25  9:34   ` Peter Maydell
  2017-08-29 15:36   ` [Qemu-devel] " Richard Henderson
  1 sibling, 0 replies; 60+ messages in thread
From: Peter Maydell @ 2017-08-25  9:34 UTC (permalink / raw)
  To: qemu-arm, QEMU Developers; +Cc: patches

On 22 August 2017 at 16:08, Peter Maydell <peter.maydell@linaro.org> wrote:
> Now that MPU lookups can return different results for v8M
> when the CPU is in secure vs non-secure state, we need to
> have separate MMU indexes; add the secure counterparts
> to the existing three M profile MMU indexes.

> @@ -2206,7 +2217,11 @@ static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
>           */
>          if ((env->v7m.exception > 0 && env->v7m.exception <= 3)
>              || env->v7m.faultmask) {
> -            return arm_to_core_mmu_idx(ARMMMUIdx_MNegPri);
> +            mmu_idx = ARMMMUIdx_MNegPri;
> +        }

Incidentally this is not exactly the right check to make when
the security extension is present, but at this point in the
series it's the best we can do (the right check requires us
to have exception banking support in the NVIC so we can
check secure HF and nonsecure HF separately); the patch to
do it right will come after the NVIC patches.

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH 01/20] target/arm: Implement ARMv8M's PMSAv8 registers
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 01/20] target/arm: Implement ARMv8M's PMSAv8 registers Peter Maydell
@ 2017-08-29 15:21   ` Richard Henderson
  2017-09-05 19:16   ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
  1 sibling, 0 replies; 60+ messages in thread
From: Richard Henderson @ 2017-08-29 15:21 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/22/2017 08:08 AM, Peter Maydell wrote:
> As part of ARMv8M, we need to add support for the PMSAv8 MPU
> architecture.
> 
> PMSAv8 differs from PMSAv7 both in register/data layout (for instance
> using base and limit registers rather than base and size) and also in
> behaviour (for example it does not have subregions); rather than
> trying to wedge it into the existing PMSAv7 code and data structures,
> we define separate ones.
> 
> This commit adds the data structures which hold the state for a
> PMSAv8 MPU and the register interface to it.  The implementation of
> the MPU behaviour will be added in a subsequent commit.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h      |  13 ++++++
>  hw/intc/armv7m_nvic.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++----
>  target/arm/cpu.c      |  36 ++++++++++-----
>  target/arm/machine.c  |  28 +++++++++++-
>  4 files changed, 179 insertions(+), 20 deletions(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 02/20] target/arm: Implement new PMSAv8 behaviour
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 02/20] target/arm: Implement new PMSAv8 behaviour Peter Maydell
@ 2017-08-29 15:25   ` Richard Henderson
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Henderson @ 2017-08-29 15:25 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/22/2017 08:08 AM, Peter Maydell wrote:
> Implement the behavioural side of the new PMSAv8 specification.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/helper.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 110 insertions(+), 1 deletion(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 03/20] target/arm: Add state field, feature bit and migration for v8M secure state
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 03/20] target/arm: Add state field, feature bit and migration for v8M secure state Peter Maydell
@ 2017-08-29 15:28   ` Richard Henderson
  2017-09-05 23:09     ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 60+ messages in thread
From: Richard Henderson @ 2017-08-29 15:28 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/22/2017 08:08 AM, Peter Maydell wrote:
> As the first step in implementing ARM v8M's security extension:
>  * add a new feature bit ARM_FEATURE_M_SECURITY
>  * add the CPU state field that indicates whether the CPU is
>    currently in the secure state
>  * add a migration subsection for this new state
>    (we will add the Secure copies of banked register state
>    to this subsection in later patches)
>  * add a #define for the one new-in-v8M exception type
>  * make the CPU debug log print S/NS status
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h       |  3 +++
>  target/arm/cpu.c       |  4 ++++
>  target/arm/machine.c   | 20 ++++++++++++++++++++
>  target/arm/translate.c |  8 +++++++-
>  4 files changed, 34 insertions(+), 1 deletion(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 04/20] target/arm: Register second AddressSpace for secure v8M CPUs
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 04/20] target/arm: Register second AddressSpace for secure v8M CPUs Peter Maydell
@ 2017-08-29 15:29   ` Richard Henderson
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Henderson @ 2017-08-29 15:29 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/22/2017 08:08 AM, Peter Maydell wrote:
> If a v8M CPU supports the security extension then we need to
> give it two AddressSpaces, the same way we do already for
> an A profile core with EL3.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.c | 13 ++++++-------
>  1 file changed, 6 insertions(+), 7 deletions(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 05/20] target/arm: Add MMU indexes for secure v8M
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 05/20] target/arm: Add MMU indexes for secure v8M Peter Maydell
  2017-08-25  9:34   ` [Qemu-devel] [Qemu-arm] " Peter Maydell
@ 2017-08-29 15:36   ` Richard Henderson
  1 sibling, 0 replies; 60+ messages in thread
From: Richard Henderson @ 2017-08-29 15:36 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/22/2017 08:08 AM, Peter Maydell wrote:
> Now that MPU lookups can return different results for v8M
> when the CPU is in secure vs non-secure state, we need to
> have separate MMU indexes; add the secure counterparts
> to the existing three M profile MMU indexes.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h    | 19 +++++++++++++++++--
>  target/arm/helper.c |  9 ++++++++-
>  2 files changed, 25 insertions(+), 3 deletions(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 06/20] target/arm: Make BASEPRI register banked for v8M
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 06/20] target/arm: Make BASEPRI register banked for v8M Peter Maydell
@ 2017-08-29 15:37   ` Richard Henderson
  2017-09-05 22:45   ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
  1 sibling, 0 replies; 60+ messages in thread
From: Richard Henderson @ 2017-08-29 15:37 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/22/2017 08:08 AM, Peter Maydell wrote:
> Make the BASEPRI register banked if v8M security extensions are enabled.
> 
> Note that we do not yet implement the functionality of the new
> AIRCR.PRIS bit (which allows the effect of the NS copy of BASEPRI to
> be restricted).
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h      | 14 +++++++++++++-
>  hw/intc/armv7m_nvic.c |  4 ++--
>  target/arm/helper.c   | 10 ++++++----
>  target/arm/machine.c  |  3 ++-
>  4 files changed, 23 insertions(+), 8 deletions(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 07/20] target/arm: Make PRIMASK register banked for v8M
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 07/20] target/arm: Make PRIMASK " Peter Maydell
@ 2017-08-29 15:38   ` Richard Henderson
  2017-09-05 22:53     ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
  0 siblings, 1 reply; 60+ messages in thread
From: Richard Henderson @ 2017-08-29 15:38 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/22/2017 08:08 AM, Peter Maydell wrote:
> Make the PRIMASK register banked if v8M security extensions are enabled.
> 
> Note that we do not yet implement the functionality of the new
> AIRCR.PRIS bit (which allows the effect of the NS copy of PRIMASK to
> be restricted).
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h      | 2 +-
>  hw/intc/armv7m_nvic.c | 2 +-
>  target/arm/helper.c   | 4 ++--
>  target/arm/machine.c  | 9 +++++++--
>  4 files changed, 11 insertions(+), 6 deletions(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 08/20] target/arm: Make FAULTMASK register banked for v8M
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 08/20] target/arm: Make FAULTMASK " Peter Maydell
@ 2017-08-29 15:41   ` Richard Henderson
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Henderson @ 2017-08-29 15:41 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/22/2017 08:08 AM, Peter Maydell wrote:
> Make the FAULTMASK register banked if v8M security extensions are enabled.
> 
> Note that we do not yet implement the functionality of the new
> AIRCR.PRIS bit (which allows the effect of the NS copy of FAULTMASK to
> be restricted).
> 
> This patch includes the code to determine for v8M which copy
> of FAULTMASK should be updated on exception exit; further
> changes will be required to the exception exit code in general
> to support v8M, so this is just a small piece of that.
> 
> The v8M ARM ARM introduces a notation where individual paragraphs
> are labelled with R (for rule) or I (for information) followed
> by a random group of subscript letters. In comments where we want
> to refer to a particular part of the manual we use this convention,
> which should be more stable across document revisions than using
> section or page numbers.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h      | 14 ++++++++++++--
>  hw/intc/armv7m_nvic.c |  9 ++++++++-
>  target/arm/helper.c   | 20 ++++++++++++++++----
>  target/arm/machine.c  |  5 +++--
>  4 files changed, 39 insertions(+), 9 deletions(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 09/20] target/arm: Make CONTROL register banked for v8M
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 09/20] target/arm: Make CONTROL " Peter Maydell
@ 2017-08-29 15:43   ` Richard Henderson
  2017-09-05 22:54     ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
  0 siblings, 1 reply; 60+ messages in thread
From: Richard Henderson @ 2017-08-29 15:43 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/22/2017 08:08 AM, Peter Maydell wrote:
> Make the CONTROL register banked if v8M security extensions are enabled.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h       |  5 +++--
>  target/arm/helper.c    | 21 +++++++++++----------
>  target/arm/machine.c   |  3 ++-
>  target/arm/translate.c |  2 +-
>  4 files changed, 17 insertions(+), 14 deletions(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 10/20] nvic: Add NS alias SCS region
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 10/20] nvic: Add NS alias SCS region Peter Maydell
@ 2017-08-29 16:00   ` Richard Henderson
  2017-09-05 16:26     ` Peter Maydell
  0 siblings, 1 reply; 60+ messages in thread
From: Richard Henderson @ 2017-08-29 16:00 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/22/2017 08:08 AM, Peter Maydell wrote:
> +    regionlen = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? 0x21000 : 0x1000;
> +    memory_region_init(&s->container, OBJECT(s), "nvic", regionlen);
>      /* The system register region goes at the bottom of the priority
>       * stack as it covers the whole page.
>       */
> @@ -1185,6 +1242,13 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
>                                          sysbus_mmio_get_region(systick_sbd, 0),
>                                          1);
>  
> +    if (arm_feature(&s->cpu->env, ARM_FEATURE_V8)) {
> +        memory_region_init_io(&s->sysreg_ns_mem, OBJECT(s),
> +                              &nvic_sysreg_ns_ops, s,
> +                              "nvic_sysregs_ns", 0x1000);
> +        memory_region_add_subregion(&s->container, 0x20000, &s->sysreg_ns_mem);

There's a whole in between the two regions, which you are leaving mapped.  Why
create a sub-region instead of two separate top-level regions for which you can
leave the whole unmapped?


r~

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

* Re: [Qemu-devel] [PATCH 11/20] target/arm: Make VTOR register banked for v8M
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 11/20] target/arm: Make VTOR register banked for v8M Peter Maydell
@ 2017-08-29 16:02   ` Richard Henderson
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Henderson @ 2017-08-29 16:02 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/22/2017 08:08 AM, Peter Maydell wrote:
> Make the VTOR register banked if v8M security extensions are enabled.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h      |  2 +-
>  hw/intc/armv7m_nvic.c | 13 +++++++------
>  target/arm/helper.c   |  2 +-
>  target/arm/machine.c  |  3 ++-
>  4 files changed, 11 insertions(+), 9 deletions(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 12/20] target/arm: Make MPU_MAIR0, MPU_MAIR1 registers banked for v8M
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 12/20] target/arm: Make MPU_MAIR0, MPU_MAIR1 registers " Peter Maydell
@ 2017-08-29 16:02   ` Richard Henderson
  2017-09-05 22:59   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 60+ messages in thread
From: Richard Henderson @ 2017-08-29 16:02 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/22/2017 08:08 AM, Peter Maydell wrote:
> Make the MPU registers MPU_MAIR0 and MPU_MAIR1 banked if v8M security
> extensions are enabled.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h      | 4 ++--
>  hw/intc/armv7m_nvic.c | 8 ++++----
>  target/arm/cpu.c      | 4 ++--
>  target/arm/machine.c  | 6 ++++--
>  4 files changed, 12 insertions(+), 10 deletions(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 13/20] target/arm: Make MPU_RBAR, MPU_RLAR banked for v8M
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 13/20] target/arm: Make MPU_RBAR, MPU_RLAR " Peter Maydell
@ 2017-08-29 16:04   ` Richard Henderson
  2017-09-05 23:02   ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
  1 sibling, 0 replies; 60+ messages in thread
From: Richard Henderson @ 2017-08-29 16:04 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/22/2017 08:08 AM, Peter Maydell wrote:
> Make the MPU registers MPU_MAIR0 and MPU_MAIR1 banked if v8M security
> extensions are enabled.
> 
> We can freely add more items to vmstate_m_security without
> breaking migration compatibility, because no CPU currently
> has the ARM_FEATURE_M_SECURITY bit enabled and so this
> subsection is not yet used by anything.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h      |  4 ++--
>  hw/intc/armv7m_nvic.c |  8 ++++----
>  target/arm/cpu.c      | 26 ++++++++++++++++++++------
>  target/arm/helper.c   | 11 ++++++-----
>  target/arm/machine.c  | 12 ++++++++----
>  5 files changed, 40 insertions(+), 21 deletions(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 14/20] target/arm: Make MPU_RNR register banked for v8M
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 14/20] target/arm: Make MPU_RNR register " Peter Maydell
@ 2017-08-29 16:05   ` Richard Henderson
  2017-08-29 16:06     ` Peter Maydell
  0 siblings, 1 reply; 60+ messages in thread
From: Richard Henderson @ 2017-08-29 16:05 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/22/2017 08:08 AM, Peter Maydell wrote:
> +        env->pmsav7.rnr[M_REG_NS] = 0;
> +        env->pmsav7.rnr[M_REG_S] = 0;
>          memset(env->pmsav8.mair0, 0, sizeof(env->pmsav8.mair0));
>          memset(env->pmsav8.mair1, 0, sizeof(env->pmsav8.mair1));

Why some memset and some by-element?

Otherwise,

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


r~

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

* Re: [Qemu-devel] [PATCH 15/20] target/arm: Make MPU_CTRL register banked for v8M
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 15/20] target/arm: Make MPU_CTRL " Peter Maydell
@ 2017-08-29 16:06   ` Richard Henderson
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Henderson @ 2017-08-29 16:06 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/22/2017 08:08 AM, Peter Maydell wrote:
> Make the MPU_CTRL register banked if v8M security extensions are
> enabled.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h      | 2 +-
>  hw/intc/armv7m_nvic.c | 9 +++++----
>  target/arm/helper.c   | 5 +++--
>  target/arm/machine.c  | 3 ++-
>  4 files changed, 11 insertions(+), 8 deletions(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 14/20] target/arm: Make MPU_RNR register banked for v8M
  2017-08-29 16:05   ` Richard Henderson
@ 2017-08-29 16:06     ` Peter Maydell
  2017-08-29 16:09       ` Richard Henderson
  0 siblings, 1 reply; 60+ messages in thread
From: Peter Maydell @ 2017-08-29 16:06 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, QEMU Developers, patches

On 29 August 2017 at 17:05, Richard Henderson
<richard.henderson@linaro.org> wrote:
> On 08/22/2017 08:08 AM, Peter Maydell wrote:
>> +        env->pmsav7.rnr[M_REG_NS] = 0;
>> +        env->pmsav7.rnr[M_REG_S] = 0;
>>          memset(env->pmsav8.mair0, 0, sizeof(env->pmsav8.mair0));
>>          memset(env->pmsav8.mair1, 0, sizeof(env->pmsav8.mair1));
>
> Why some memset and some by-element?

Roughly, memset where I would otherwise have to write a
for loop (ie where there's more than 2 elements).

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH 16/20] target/arm: Make CCR register banked for v8M
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 16/20] target/arm: Make CCR " Peter Maydell
@ 2017-08-29 16:08   ` Richard Henderson
  2017-09-05 16:39     ` Peter Maydell
  0 siblings, 1 reply; 60+ messages in thread
From: Richard Henderson @ 2017-08-29 16:08 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/22/2017 08:08 AM, Peter Maydell wrote:
> +        if (attrs.secure) {
> +            /* the BFHFNMIGN bit is not banked; keep that in the NS copy */
> +            int new_bfhnmign = !!(value & R_V7M_CCR_BFHFNMIGN_MASK);
> +
> +            cpu->env.v7m.ccr[M_REG_NS] = deposit32(cpu->env.v7m.ccr[M_REG_NS],
> +                                                    R_V7M_CCR_BFHFNMIGN_SHIFT,
> +                                                    R_V7M_CCR_BFHFNMIGN_LENGTH,
> +                                                    new_bfhnmign);
> +            value &= ~R_V7M_CCR_BFHFNMIGN_MASK;
> +        }

No need to extract and then redeposit, just use the mask.

    cpu->env.v7m.ccr[M_REG_NS] =
      (cpu->env.v7m.ccr[M_REG_NS] & ~R_V7M_CCR_BFHFNMIGN_MASK)
      | (value & R_V7M_CCR_BFHFNMIGN_MASK);


r~

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

* Re: [Qemu-devel] [PATCH 14/20] target/arm: Make MPU_RNR register banked for v8M
  2017-08-29 16:06     ` Peter Maydell
@ 2017-08-29 16:09       ` Richard Henderson
  2017-09-05 16:41         ` Peter Maydell
  0 siblings, 1 reply; 60+ messages in thread
From: Richard Henderson @ 2017-08-29 16:09 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-arm, QEMU Developers, patches

On 08/29/2017 09:06 AM, Peter Maydell wrote:
> On 29 August 2017 at 17:05, Richard Henderson
> <richard.henderson@linaro.org> wrote:
>> On 08/22/2017 08:08 AM, Peter Maydell wrote:
>>> +        env->pmsav7.rnr[M_REG_NS] = 0;
>>> +        env->pmsav7.rnr[M_REG_S] = 0;
>>>          memset(env->pmsav8.mair0, 0, sizeof(env->pmsav8.mair0));
>>>          memset(env->pmsav8.mair1, 0, sizeof(env->pmsav8.mair1));
>>
>> Why some memset and some by-element?
> 
> Roughly, memset where I would otherwise have to write a
> for loop (ie where there's more than 2 elements).

There's only 2 elements of mair0 and mair1...


r~

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

* Re: [Qemu-devel] [PATCH 17/20] target/arm: Make MMFAR banked for v8M
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 17/20] target/arm: Make MMFAR " Peter Maydell
@ 2017-08-29 16:10   ` Richard Henderson
  2017-09-05 23:05     ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
  0 siblings, 1 reply; 60+ messages in thread
From: Richard Henderson @ 2017-08-29 16:10 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/22/2017 08:08 AM, Peter Maydell wrote:
> Make the MMFAR register banked if v8M security extensions are
> enabled.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h      | 2 +-
>  hw/intc/armv7m_nvic.c | 4 ++--
>  target/arm/helper.c   | 4 ++--
>  target/arm/machine.c  | 3 ++-
>  4 files changed, 7 insertions(+), 6 deletions(-)


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


r~

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

* Re: [Qemu-devel] [PATCH 18/20] target/arm: Make CFSR register banked for v8M
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 18/20] target/arm: Make CFSR register " Peter Maydell
@ 2017-08-29 16:12   ` Richard Henderson
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Henderson @ 2017-08-29 16:12 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/22/2017 08:08 AM, Peter Maydell wrote:
> Make the CFSR register banked if v8M security extensions are enabled.
> 
> Not all the bits in this register are banked: the BFSR
> bits [15:8] are shared between S and NS, and we store them
> in the NS copy of the register.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h      |  7 ++++++-
>  hw/intc/armv7m_nvic.c | 15 +++++++++++++--
>  target/arm/helper.c   | 18 +++++++++---------
>  target/arm/machine.c  |  3 ++-
>  4 files changed, 30 insertions(+), 13 deletions(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 19/20] target/arm: Move regime_is_secure() to target/arm/internals.h
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 19/20] target/arm: Move regime_is_secure() to target/arm/internals.h Peter Maydell
@ 2017-08-29 16:12   ` Richard Henderson
  2017-09-05 22:51     ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
  0 siblings, 1 reply; 60+ messages in thread
From: Richard Henderson @ 2017-08-29 16:12 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/22/2017 08:08 AM, Peter Maydell wrote:
> Move the regime_is_secure() utility function to internals.h;
> we are going to want to call it from translate.c.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/internals.h | 26 ++++++++++++++++++++++++++
>  target/arm/helper.c    | 26 --------------------------
>  2 files changed, 26 insertions(+), 26 deletions(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 20/20] target/arm: Implement BXNS, and banked stack pointers
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 20/20] target/arm: Implement BXNS, and banked stack pointers Peter Maydell
@ 2017-08-29 16:31   ` Richard Henderson
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Henderson @ 2017-08-29 16:31 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/22/2017 08:08 AM, Peter Maydell wrote:
> Implement the BXNS v8M instruction, which is like BX but will do a
> jump-and-switch-to-NonSecure if the branch target address has bit 0
> clear.
> 
> This is the first piece of code which implements "switch to the
> other security state", so the commit also includes the code to
> switch the stack pointers around, which is the only complicated
> part of switching security state.
> 
> BLXNS is more complicated than just "BXNS but set the link register",
> so we leave it for a separate commit.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h       | 13 +++++++++
>  target/arm/helper.h    |  2 ++
>  target/arm/translate.h |  1 +
>  target/arm/helper.c    | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  target/arm/machine.c   |  2 ++
>  target/arm/translate.c | 42 ++++++++++++++++++++++++++-
>  6 files changed, 138 insertions(+), 1 deletion(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 10/20] nvic: Add NS alias SCS region
  2017-08-29 16:00   ` Richard Henderson
@ 2017-09-05 16:26     ` Peter Maydell
  2017-09-05 16:48       ` Richard Henderson
  0 siblings, 1 reply; 60+ messages in thread
From: Peter Maydell @ 2017-09-05 16:26 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, QEMU Developers, patches

On 29 August 2017 at 17:00, Richard Henderson
<richard.henderson@linaro.org> wrote:
> On 08/22/2017 08:08 AM, Peter Maydell wrote:
>> +    regionlen = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? 0x21000 : 0x1000;
>> +    memory_region_init(&s->container, OBJECT(s), "nvic", regionlen);
>>      /* The system register region goes at the bottom of the priority
>>       * stack as it covers the whole page.
>>       */
>> @@ -1185,6 +1242,13 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
>>                                          sysbus_mmio_get_region(systick_sbd, 0),
>>                                          1);
>>
>> +    if (arm_feature(&s->cpu->env, ARM_FEATURE_V8)) {
>> +        memory_region_init_io(&s->sysreg_ns_mem, OBJECT(s),
>> +                              &nvic_sysreg_ns_ops, s,
>> +                              "nvic_sysregs_ns", 0x1000);
>> +        memory_region_add_subregion(&s->container, 0x20000, &s->sysreg_ns_mem);
>
> There's a whole in between the two regions, which you are leaving mapped.  Why
> create a sub-region instead of two separate top-level regions for which you can
> leave the whole unmapped?

We don't map the hole. The container is 0x21000 in size, the normal
nvic_sysregs region is 0x1000 at offset 0x0 (which will be 0xe000e000
in the system address space), and the NS alias region
is 0x1000 at offset 0x20000 (0xe002e000 in the system address space).
There's nothing mapped in the hole in the container, so accesses
there will busfault, as they will for other PPB accesses before or
after the SCSes.

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH 16/20] target/arm: Make CCR register banked for v8M
  2017-08-29 16:08   ` Richard Henderson
@ 2017-09-05 16:39     ` Peter Maydell
  0 siblings, 0 replies; 60+ messages in thread
From: Peter Maydell @ 2017-09-05 16:39 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, QEMU Developers, patches

On 29 August 2017 at 17:08, Richard Henderson
<richard.henderson@linaro.org> wrote:
> On 08/22/2017 08:08 AM, Peter Maydell wrote:
>> +        if (attrs.secure) {
>> +            /* the BFHFNMIGN bit is not banked; keep that in the NS copy */
>> +            int new_bfhnmign = !!(value & R_V7M_CCR_BFHFNMIGN_MASK);
>> +
>> +            cpu->env.v7m.ccr[M_REG_NS] = deposit32(cpu->env.v7m.ccr[M_REG_NS],
>> +                                                    R_V7M_CCR_BFHFNMIGN_SHIFT,
>> +                                                    R_V7M_CCR_BFHFNMIGN_LENGTH,
>> +                                                    new_bfhnmign);
>> +            value &= ~R_V7M_CCR_BFHFNMIGN_MASK;
>> +        }
>
> No need to extract and then redeposit, just use the mask.
>
>     cpu->env.v7m.ccr[M_REG_NS] =
>       (cpu->env.v7m.ccr[M_REG_NS] & ~R_V7M_CCR_BFHFNMIGN_MASK)
>       | (value & R_V7M_CCR_BFHFNMIGN_MASK);

Mmm. This is one of the operations that deposit/extract aren't
too wonderful for. I don't generally like direct messing with
bit operations, I think they're harder to read, but there's not
much in it here so I'll go with your version.

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH 14/20] target/arm: Make MPU_RNR register banked for v8M
  2017-08-29 16:09       ` Richard Henderson
@ 2017-09-05 16:41         ` Peter Maydell
  0 siblings, 0 replies; 60+ messages in thread
From: Peter Maydell @ 2017-09-05 16:41 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, QEMU Developers, patches

On 29 August 2017 at 17:09, Richard Henderson
<richard.henderson@linaro.org> wrote:
> On 08/29/2017 09:06 AM, Peter Maydell wrote:
>> On 29 August 2017 at 17:05, Richard Henderson
>> <richard.henderson@linaro.org> wrote:
>>> On 08/22/2017 08:08 AM, Peter Maydell wrote:
>>>> +        env->pmsav7.rnr[M_REG_NS] = 0;
>>>> +        env->pmsav7.rnr[M_REG_S] = 0;
>>>>          memset(env->pmsav8.mair0, 0, sizeof(env->pmsav8.mair0));
>>>>          memset(env->pmsav8.mair1, 0, sizeof(env->pmsav8.mair1));
>>>
>>> Why some memset and some by-element?
>>
>> Roughly, memset where I would otherwise have to write a
>> for loop (ie where there's more than 2 elements).
>
> There's only 2 elements of mair0 and mair1...

So there are. Let's go with assignments for mair0/mair1 then.

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH 10/20] nvic: Add NS alias SCS region
  2017-09-05 16:26     ` Peter Maydell
@ 2017-09-05 16:48       ` Richard Henderson
  2017-09-05 17:09         ` Peter Maydell
  0 siblings, 1 reply; 60+ messages in thread
From: Richard Henderson @ 2017-09-05 16:48 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-arm, QEMU Developers, patches

On 09/05/2017 09:26 AM, Peter Maydell wrote:
> We don't map the hole. The container is 0x21000 in size, the normal
> nvic_sysregs region is 0x1000 at offset 0x0 (which will be 0xe000e000
> in the system address space), and the NS alias region
> is 0x1000 at offset 0x20000 (0xe002e000 in the system address space).
> There's nothing mapped in the hole in the container, so accesses
> there will busfault, as they will for other PPB accesses before or
> after the SCSes.

Ok, it's not wrong, but I still don't understand the need for the container.


r~

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

* Re: [Qemu-devel] [PATCH 10/20] nvic: Add NS alias SCS region
  2017-09-05 16:48       ` Richard Henderson
@ 2017-09-05 17:09         ` Peter Maydell
  0 siblings, 0 replies; 60+ messages in thread
From: Peter Maydell @ 2017-09-05 17:09 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, QEMU Developers, patches

On 5 September 2017 at 17:48, Richard Henderson
<richard.henderson@linaro.org> wrote:
> On 09/05/2017 09:26 AM, Peter Maydell wrote:
>> We don't map the hole. The container is 0x21000 in size, the normal
>> nvic_sysregs region is 0x1000 at offset 0x0 (which will be 0xe000e000
>> in the system address space), and the NS alias region
>> is 0x1000 at offset 0x20000 (0xe002e000 in the system address space).
>> There's nothing mapped in the hole in the container, so accesses
>> there will busfault, as they will for other PPB accesses before or
>> after the SCSes.
>
> Ok, it's not wrong, but I still don't understand the need for the container.

It lets us assemble all the parts of this bit of the address space --
SCS, systick (which sits on top of some of the SCS), NS SCS --
in the right place, rather than requiring any caller that wants
to instantiate an NVIC to do it (and to check whether the cpu
has the security extension to figure out whether the NS alias
exists, and so on).

Now that we've QOMified hw/arm/armv7m.c it's less important that
the NVIC in particular does that, and it's partly historical legacy
that most of this is done in the NVIC realize function rather than
in armv7m_instance_init() (we used to implement systick directly
in the NVIC source file rather than as its own device). It doesn't
seem worth shuffling the code around now, though (the container
already existed prior to this patch, we're just making it a bit
bigger and adding another thing to it.)

thanks
-- PMM

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

* Re: [Qemu-devel] [Qemu-arm] [PATCH 01/20] target/arm: Implement ARMv8M's PMSAv8 registers
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 01/20] target/arm: Implement ARMv8M's PMSAv8 registers Peter Maydell
  2017-08-29 15:21   ` Richard Henderson
@ 2017-09-05 19:16   ` Philippe Mathieu-Daudé
  2017-09-05 21:28     ` Peter Maydell
  1 sibling, 1 reply; 60+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-09-05 19:16 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

Hi Peter,

On 08/22/2017 12:08 PM, Peter Maydell wrote:
> As part of ARMv8M, we need to add support for the PMSAv8 MPU
> architecture.
> 
> PMSAv8 differs from PMSAv7 both in register/data layout (for instance
> using base and limit registers rather than base and size) and also in
> behaviour (for example it does not have subregions); rather than
> trying to wedge it into the existing PMSAv7 code and data structures,
> we define separate ones.
> 
> This commit adds the data structures which hold the state for a
> PMSAv8 MPU and the register interface to it.  The implementation of
> the MPU behaviour will be added in a subsequent commit.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>   target/arm/cpu.h      |  13 ++++++
>   hw/intc/armv7m_nvic.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++----
>   target/arm/cpu.c      |  36 ++++++++++-----
>   target/arm/machine.c  |  28 +++++++++++-
>   4 files changed, 179 insertions(+), 20 deletions(-)
> 
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index fe6edb7..b6bb78a 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -522,6 +522,19 @@ typedef struct CPUARMState {
>           uint32_t rnr;
>       } pmsav7;
>   
> +    /* PMSAv8 MPU */
> +    struct {
> +        /* The PMSAv8 implementation also shares some PMSAv7 config
> +         * and state:
> +         *  pmsav7.rnr (region number register)
> +         *  pmsav7_dregion (number of configured regions)
> +         */
> +        uint32_t *rbar;
> +        uint32_t *rlar;
> +        uint32_t mair0;
> +        uint32_t mair1;
> +    } pmsav8;
> +
>       void *nvic;
>       const struct arm_boot_info *boot_info;
>       /* Store GICv3CPUState to access from this struct */
> diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
> index bbfe2d5..c0dbbad 100644
> --- a/hw/intc/armv7m_nvic.c
> +++ b/hw/intc/armv7m_nvic.c
> @@ -544,25 +544,67 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset)
>       {
>           int region = cpu->env.pmsav7.rnr;
>   
> +        if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
> +            /* PMSAv8M handling of the aliases is different from v7M:
> +             * aliases A1, A2, A3 override the low two bits of the region
> +             * number in MPU_RNR, and there is no 'region' field in the
> +             * RBAR register.
> +             */
> +            int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
> +            if (aliasno) {
> +                region = deposit32(region, 0, 2, aliasno);
> +            }
> +            if (region >= cpu->pmsav7_dregion) {
> +                return 0;
> +            }
> +            return cpu->env.pmsav8.rbar[region];
> +        }
> +
>           if (region >= cpu->pmsav7_dregion) {
>               return 0;
>           }
>           return (cpu->env.pmsav7.drbar[region] & 0x1f) | (region & 0xf);
>       }
> -    case 0xda0: /* MPU_RASR */
> -    case 0xda8: /* MPU_RASR_A1 */
> -    case 0xdb0: /* MPU_RASR_A2 */
> -    case 0xdb8: /* MPU_RASR_A3 */
> +    case 0xda0: /* MPU_RASR (v7M), MPU_RLAR (v8M) */
> +    case 0xda8: /* MPU_RASR_A1 (v7M), MPU_RLAR_A1 (v8M) */
> +    case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */
> +    case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */
>       {
>           int region = cpu->env.pmsav7.rnr;
>   
> +        if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
> +            /* PMSAv8M handling of the aliases is different from v7M:
> +             * aliases A1, A2, A3 override the low two bits of the region
> +             * number in MPU_RNR.
> +             */
> +            int aliasno = (offset - 0xda0) / 8; /* 0..3 */
> +            if (aliasno) {
> +                region = deposit32(region, 0, 2, aliasno);
> +            }
> +            if (region >= cpu->pmsav7_dregion) {
> +                return 0;
> +            }
> +            return cpu->env.pmsav8.rlar[region];
> +        }
> +
>           if (region >= cpu->pmsav7_dregion) {
>               return 0;
>           }
>           return ((cpu->env.pmsav7.dracr[region] & 0xffff) << 16) |
>               (cpu->env.pmsav7.drsr[region] & 0xffff);
>       }
> +    case 0xdc0: /* MPU_MAIR0 */
> +        if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
> +            goto bad_offset;
> +        }
> +        return cpu->env.pmsav8.mair0;
> +    case 0xdc4: /* MPU_MAIR1 */
> +        if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
> +            goto bad_offset;
> +        }
> +        return cpu->env.pmsav8.mair1;
>       default:
> +    bad_offset:
>           qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);
>           return 0;
>       }
> @@ -691,6 +733,26 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
>       {
>           int region;
>   
> +        if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
> +            /* PMSAv8M handling of the aliases is different from v7M:
> +             * aliases A1, A2, A3 override the low two bits of the region
> +             * number in MPU_RNR, and there is no 'region' field in the
> +             * RBAR register.
> +             */
> +            int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
> +
> +            region = cpu->env.pmsav7.rnr;
> +            if (aliasno) {
> +                region = deposit32(region, 0, 2, aliasno);
> +            }
> +            if (region >= cpu->pmsav7_dregion) {
> +                return;
> +            }
> +            cpu->env.pmsav8.rbar[region] = value;
> +            tlb_flush(CPU(cpu));
> +            return;
> +        }
> +
>           if (value & (1 << 4)) {
>               /* VALID bit means use the region number specified in this
>                * value and also update MPU_RNR.REGION with that value.
> @@ -715,13 +777,32 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
>           tlb_flush(CPU(cpu));
>           break;
>       }
> -    case 0xda0: /* MPU_RASR */
> -    case 0xda8: /* MPU_RASR_A1 */
> -    case 0xdb0: /* MPU_RASR_A2 */
> -    case 0xdb8: /* MPU_RASR_A3 */
> +    case 0xda0: /* MPU_RASR (v7M), MPU_RLAR (v8M) */
> +    case 0xda8: /* MPU_RASR_A1 (v7M), MPU_RLAR_A1 (v8M) */
> +    case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */
> +    case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */
>       {
>           int region = cpu->env.pmsav7.rnr;
>   
> +        if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
> +            /* PMSAv8M handling of the aliases is different from v7M:
> +             * aliases A1, A2, A3 override the low two bits of the region
> +             * number in MPU_RNR.
> +             */
> +            int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
> +
> +            region = cpu->env.pmsav7.rnr;
> +            if (aliasno) {
> +                region = deposit32(region, 0, 2, aliasno);
> +            }
> +            if (region >= cpu->pmsav7_dregion) {
> +                return;
> +            }
> +            cpu->env.pmsav8.rlar[region] = value;
> +            tlb_flush(CPU(cpu));
> +            return;
> +        }
> +
>           if (region >= cpu->pmsav7_dregion) {
>               return;
>           }
> @@ -731,6 +812,30 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
>           tlb_flush(CPU(cpu));
>           break;
>       }
> +    case 0xdc0: /* MPU_MAIR0 */
> +        if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
> +            goto bad_offset;
> +        }
> +        if (cpu->pmsav7_dregion) {
> +            /* Register is RES0 if no MPU regions are implemented */
> +            cpu->env.pmsav8.mair0 = value;
> +        }
> +        /* We don't need to do anything else because memory attributes
> +         * only affect cacheability, and we don't implement caching.
> +         */
> +        break;
> +    case 0xdc4: /* MPU_MAIR1 */
> +        if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
> +            goto bad_offset;
> +        }
> +        if (cpu->pmsav7_dregion) {
> +            /* Register is RES0 if no MPU regions are implemented */
> +            cpu->env.pmsav8.mair1 = value;
> +        }
> +        /* We don't need to do anything else because memory attributes
> +         * only affect cacheability, and we don't implement caching.
> +         */
> +        break;
>       case 0xf00: /* Software Triggered Interrupt Register */
>       {
>           int excnum = (value & 0x1ff) + NVIC_FIRST_IRQ;
> @@ -740,6 +845,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
>           break;
>       }
>       default:
> +    bad_offset:
>           qemu_log_mask(LOG_GUEST_ERROR,
>                         "NVIC: Bad write offset 0x%x\n", offset);
>       }
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index 41ae6ba..8b610de 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -228,17 +228,25 @@ static void arm_cpu_reset(CPUState *s)
>       env->vfp.xregs[ARM_VFP_FPEXC] = 0;
>   #endif
>   
> -    if (arm_feature(env, ARM_FEATURE_PMSA) &&
> -        arm_feature(env, ARM_FEATURE_V7)) {
> +    if (arm_feature(env, ARM_FEATURE_PMSA)) {
>           if (cpu->pmsav7_dregion > 0) {
> -            memset(env->pmsav7.drbar, 0,
> -                   sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion);
> -            memset(env->pmsav7.drsr, 0,
> -                   sizeof(*env->pmsav7.drsr) * cpu->pmsav7_dregion);
> -            memset(env->pmsav7.dracr, 0,
> -                   sizeof(*env->pmsav7.dracr) * cpu->pmsav7_dregion);
> +            if (arm_feature(env, ARM_FEATURE_V8)) {
> +                memset(env->pmsav8.rbar, 0,
> +                       sizeof(*env->pmsav8.rbar) * cpu->pmsav7_dregion);
> +                memset(env->pmsav8.rlar, 0,
> +                       sizeof(*env->pmsav8.rlar) * cpu->pmsav7_dregion);
> +            } else if (arm_feature(env, ARM_FEATURE_V7)) {
> +                memset(env->pmsav7.drbar, 0,
> +                       sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion);
> +                memset(env->pmsav7.drsr, 0,
> +                       sizeof(*env->pmsav7.drsr) * cpu->pmsav7_dregion);
> +                memset(env->pmsav7.dracr, 0,
> +                       sizeof(*env->pmsav7.dracr) * cpu->pmsav7_dregion);
> +            }
>           }
>           env->pmsav7.rnr = 0;
> +        env->pmsav8.mair0 = 0;
> +        env->pmsav8.mair1 = 0;
>       }
>   
>       set_flush_to_zero(1, &env->vfp.standard_fp_status);
> @@ -809,9 +817,15 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
>           }
>   
>           if (nr) {
> -            env->pmsav7.drbar = g_new0(uint32_t, nr);
> -            env->pmsav7.drsr = g_new0(uint32_t, nr);
> -            env->pmsav7.dracr = g_new0(uint32_t, nr);
> +            if (arm_feature(env, ARM_FEATURE_V8)) {
> +                /* PMSAv8 */
> +                env->pmsav8.rbar = g_new0(uint32_t, nr);
> +                env->pmsav8.rlar = g_new0(uint32_t, nr);
> +            } else {
> +                env->pmsav7.drbar = g_new0(uint32_t, nr);
> +                env->pmsav7.drsr = g_new0(uint32_t, nr);
> +                env->pmsav7.dracr = g_new0(uint32_t, nr);
> +            }
>           }
>       }
>   
> diff --git a/target/arm/machine.c b/target/arm/machine.c
> index 3193b00..05e2909 100644
> --- a/target/arm/machine.c
> +++ b/target/arm/machine.c
> @@ -159,7 +159,8 @@ static bool pmsav7_needed(void *opaque)
>       CPUARMState *env = &cpu->env;
>   
>       return arm_feature(env, ARM_FEATURE_PMSA) &&
> -           arm_feature(env, ARM_FEATURE_V7);
> +           arm_feature(env, ARM_FEATURE_V7) &&
> +           !arm_feature(env, ARM_FEATURE_V8);
>   }
>   
>   static bool pmsav7_rgnr_vmstate_validate(void *opaque, int version_id)
> @@ -209,6 +210,31 @@ static const VMStateDescription vmstate_pmsav7_rnr = {
>       }
>   };
>   
> +static bool pmsav8_needed(void *opaque)
> +{
> +    ARMCPU *cpu = opaque;
> +    CPUARMState *env = &cpu->env;
> +
> +    return arm_feature(env, ARM_FEATURE_PMSA) &&
> +        arm_feature(env, ARM_FEATURE_V8);
> +}
> +
> +static const VMStateDescription vmstate_pmsav8 = {
> +    .name = "cpu/pmsav8",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .needed = pmsav8_needed,
> +    .fields = (VMStateField[]) {
> +        VMSTATE_VARRAY_UINT32(env.pmsav8.rbar, ARMCPU, pmsav7_dregion, 0,
> +                              vmstate_info_uint32, uint32_t),
> +        VMSTATE_VARRAY_UINT32(env.pmsav8.rlar, ARMCPU, pmsav7_dregion, 0,
> +                              vmstate_info_uint32, uint32_t),
> +        VMSTATE_UINT32(env.pmsav8.mair0, ARMCPU),
> +        VMSTATE_UINT32(env.pmsav8.mair1, ARMCPU),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> +
>   static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
>                       VMStateField *field)
>   {
> 

maybe you plan to add migration between version 22 and 23 in a later 
patch, else

...
const VMStateDescription vmstate_arm_cpu = {
     ...
     .subsections = (const VMStateDescription*[]) {
         ...
         &vmstate_pmsav8,

do not forget this ^

Regards,

Phil.

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

* Re: [Qemu-devel] [Qemu-arm] [PATCH 01/20] target/arm: Implement ARMv8M's PMSAv8 registers
  2017-09-05 19:16   ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
@ 2017-09-05 21:28     ` Peter Maydell
  0 siblings, 0 replies; 60+ messages in thread
From: Peter Maydell @ 2017-09-05 21:28 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé; +Cc: qemu-arm, QEMU Developers, patches

On 5 September 2017 at 20:16, Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
> Hi Peter,
>
>
> On 08/22/2017 12:08 PM, Peter Maydell wrote:
>>   diff --git a/target/arm/machine.c b/target/arm/machine.c
>> index 3193b00..05e2909 100644
>> --- a/target/arm/machine.c
>> +++ b/target/arm/machine.c
>> @@ -159,7 +159,8 @@ static bool pmsav7_needed(void *opaque)
>>       CPUARMState *env = &cpu->env;
>>         return arm_feature(env, ARM_FEATURE_PMSA) &&
>> -           arm_feature(env, ARM_FEATURE_V7);
>> +           arm_feature(env, ARM_FEATURE_V7) &&
>> +           !arm_feature(env, ARM_FEATURE_V8);
>>   }
>>     static bool pmsav7_rgnr_vmstate_validate(void *opaque, int version_id)
>> @@ -209,6 +210,31 @@ static const VMStateDescription vmstate_pmsav7_rnr =
>> {
>>       }
>>   };
>>   +static bool pmsav8_needed(void *opaque)
>> +{
>> +    ARMCPU *cpu = opaque;
>> +    CPUARMState *env = &cpu->env;
>> +
>> +    return arm_feature(env, ARM_FEATURE_PMSA) &&
>> +        arm_feature(env, ARM_FEATURE_V8);
>> +}
>> +
>> +static const VMStateDescription vmstate_pmsav8 = {
>> +    .name = "cpu/pmsav8",
>> +    .version_id = 1,
>> +    .minimum_version_id = 1,
>> +    .needed = pmsav8_needed,
>> +    .fields = (VMStateField[]) {
>> +        VMSTATE_VARRAY_UINT32(env.pmsav8.rbar, ARMCPU, pmsav7_dregion, 0,
>> +                              vmstate_info_uint32, uint32_t),
>> +        VMSTATE_VARRAY_UINT32(env.pmsav8.rlar, ARMCPU, pmsav7_dregion, 0,
>> +                              vmstate_info_uint32, uint32_t),
>> +        VMSTATE_UINT32(env.pmsav8.mair0, ARMCPU),
>> +        VMSTATE_UINT32(env.pmsav8.mair1, ARMCPU),
>> +        VMSTATE_END_OF_LIST()
>> +    }
>> +};
>> +
>>   static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
>>                       VMStateField *field)
>>   {
>>
>
> maybe you plan to add migration between version 22 and 23 in a later patch,
> else
>
> ...
> const VMStateDescription vmstate_arm_cpu = {
>     ...
>     .subsections = (const VMStateDescription*[]) {
>         ...
>         &vmstate_pmsav8,
>
> do not forget this ^

Whoops, yes, I forgot that bit. I'm surprised the compiler
didn't complain about the unused variables...

There's no need to worry about migration compat in any
of these v8M-specific vmstate structs, because right now
there are no QEMU CPUs with v8M enabled and so the
vmstate struct can't be used. That means we can freely
add fields to them in later patches without having to
bump version numbers or otherwise keep compatibility.
Once the patch which adds a cortex-m33 CPU lands in
master the rules will change and we'll need to be more
careful.


thanks
-- PMM

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

* Re: [Qemu-devel] [Qemu-arm] [PATCH 06/20] target/arm: Make BASEPRI register banked for v8M
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 06/20] target/arm: Make BASEPRI register banked for v8M Peter Maydell
  2017-08-29 15:37   ` Richard Henderson
@ 2017-09-05 22:45   ` Philippe Mathieu-Daudé
  2017-09-05 22:53     ` Philippe Mathieu-Daudé
  1 sibling, 1 reply; 60+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-09-05 22:45 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

Hi Peter,

On 08/22/2017 12:08 PM, Peter Maydell wrote:
> Make the BASEPRI register banked if v8M security extensions are enabled.
> 
> Note that we do not yet implement the functionality of the new
> AIRCR.PRIS bit (which allows the effect of the NS copy of BASEPRI to
> be restricted).
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>   target/arm/cpu.h      | 14 +++++++++++++-
>   hw/intc/armv7m_nvic.c |  4 ++--
>   target/arm/helper.c   | 10 ++++++----
>   target/arm/machine.c  |  3 ++-
>   4 files changed, 23 insertions(+), 8 deletions(-)
> 
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index 436ca0d..0c28dfd 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -72,6 +72,18 @@
>   #define ARMV7M_EXCP_PENDSV  14
>   #define ARMV7M_EXCP_SYSTICK 15
>   
> +/* For M profile, some registers are banked secure vs non-secure;
> + * these are represented as a 2-element array where the first element
> + * is the non-secure copy and the second is the secure copy.
> + * When the CPU does not have implement the security extension then
> + * only the first element is used.
> + * This means that the copy for the current security state can be
> + * accessed via env->registerfield[env->v7m.secure] (whether the security
> + * extension is implemented or not).
> + */
> +#define M_REG_NS 0
> +#define M_REG_S 1

enum {
     M_REG_NS = 0,
     M_REG_S = 1,
     M_BANKED_SECURE_REG_COUNT = 2;
};

or directly this?

#define M_BANKED_SECURE_REG_COUNT 2

shorter nicer...

#define M_BANKED_SECURE_REGS 2

> +
>   /* ARM-specific interrupt pending bits.  */
>   #define CPU_INTERRUPT_FIQ   CPU_INTERRUPT_TGT_EXT_1
>   #define CPU_INTERRUPT_VIRQ  CPU_INTERRUPT_TGT_EXT_2
> @@ -409,7 +421,7 @@ typedef struct CPUARMState {
>       struct {
>           uint32_t other_sp;
>           uint32_t vecbase;
> -        uint32_t basepri;
> +        uint32_t basepri[2];

             uint32_t basepri[M_BANKED_SECURE_REGS];

(and following patches of this series...)

>           uint32_t control;
>           uint32_t ccr; /* Configuration and Control */
>           uint32_t cfsr; /* Configurable Fault Status */
> diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
> index c0dbbad..2a41e5d 100644
> --- a/hw/intc/armv7m_nvic.c
> +++ b/hw/intc/armv7m_nvic.c
> @@ -171,8 +171,8 @@ static inline int nvic_exec_prio(NVICState *s)
>           running = -1;
>       } else if (env->v7m.primask) {
>           running = 0;
> -    } else if (env->v7m.basepri > 0) {
> -        running = env->v7m.basepri & nvic_gprio_mask(s);
> +    } else if (env->v7m.basepri[env->v7m.secure] > 0) {
> +        running = env->v7m.basepri[env->v7m.secure] & nvic_gprio_mask(s);
>       } else {
>           running = NVIC_NOEXC_PRIO; /* lower than any possible priority */
>       }
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index 1debebc..1087f19 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -8838,7 +8838,7 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
>           return env->v7m.primask;
>       case 17: /* BASEPRI */
>       case 18: /* BASEPRI_MAX */
> -        return env->v7m.basepri;
> +        return env->v7m.basepri[env->v7m.secure];
>       case 19: /* FAULTMASK */
>           return env->v7m.faultmask;
>       default:
> @@ -8898,12 +8898,14 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
>           env->v7m.primask = val & 1;
>           break;
>       case 17: /* BASEPRI */
> -        env->v7m.basepri = val & 0xff;
> +        env->v7m.basepri[env->v7m.secure] = val & 0xff;
>           break;
>       case 18: /* BASEPRI_MAX */
>           val &= 0xff;
> -        if (val != 0 && (val < env->v7m.basepri || env->v7m.basepri == 0))
> -            env->v7m.basepri = val;
> +        if (val != 0 && (val < env->v7m.basepri[env->v7m.secure]
> +                         || env->v7m.basepri[env->v7m.secure] == 0)) {
> +            env->v7m.basepri[env->v7m.secure] = val;
> +        }
>           break;
>       case 19: /* FAULTMASK */
>           env->v7m.faultmask = val & 1;
> diff --git a/target/arm/machine.c b/target/arm/machine.c
> index 745adae..8476efd 100644
> --- a/target/arm/machine.c
> +++ b/target/arm/machine.c
> @@ -115,7 +115,7 @@ static const VMStateDescription vmstate_m = {
>       .needed = m_needed,
>       .fields = (VMStateField[]) {
>           VMSTATE_UINT32(env.v7m.vecbase, ARMCPU),
> -        VMSTATE_UINT32(env.v7m.basepri, ARMCPU),
> +        VMSTATE_UINT32(env.v7m.basepri[M_REG_NS], ARMCPU),
>           VMSTATE_UINT32(env.v7m.control, ARMCPU),
>           VMSTATE_UINT32(env.v7m.ccr, ARMCPU),
>           VMSTATE_UINT32(env.v7m.cfsr, ARMCPU),
> @@ -250,6 +250,7 @@ static const VMStateDescription vmstate_m_security = {
>       .needed = m_security_needed,
>       .fields = (VMStateField[]) {
>           VMSTATE_UINT32(env.v7m.secure, ARMCPU),
> +        VMSTATE_UINT32(env.v7m.basepri[M_REG_S], ARMCPU),
>           VMSTATE_END_OF_LIST()
>       }
>   };
> 

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

* Re: [Qemu-devel] [Qemu-arm] [PATCH 19/20] target/arm: Move regime_is_secure() to target/arm/internals.h
  2017-08-29 16:12   ` Richard Henderson
@ 2017-09-05 22:51     ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 60+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-09-05 22:51 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Richard Henderson, patches

On 08/29/2017 01:12 PM, Richard Henderson wrote:
> On 08/22/2017 08:08 AM, Peter Maydell wrote:
>> Move the regime_is_secure() utility function to internals.h;
>> we are going to want to call it from translate.c.
>>
>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>> ---
>>   target/arm/internals.h | 26 ++++++++++++++++++++++++++
>>   target/arm/helper.c    | 26 --------------------------
>>   2 files changed, 26 insertions(+), 26 deletions(-)
> 
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

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

* Re: [Qemu-devel] [Qemu-arm] [PATCH 06/20] target/arm: Make BASEPRI register banked for v8M
  2017-09-05 22:45   ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
@ 2017-09-05 22:53     ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 60+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-09-05 22:53 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

> On 08/22/2017 12:08 PM, Peter Maydell wrote:
>> Make the BASEPRI register banked if v8M security extensions are enabled.
>>
>> Note that we do not yet implement the functionality of the new
>> AIRCR.PRIS bit (which allows the effect of the NS copy of BASEPRI to
>> be restricted).
>>
>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

(forgot to add)

Anyway:
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

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

* Re: [Qemu-devel] [Qemu-arm] [PATCH 07/20] target/arm: Make PRIMASK register banked for v8M
  2017-08-29 15:38   ` Richard Henderson
@ 2017-09-05 22:53     ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 60+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-09-05 22:53 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Richard Henderson, patches

> On 08/22/2017 08:08 AM, Peter Maydell wrote:
>> Make the PRIMASK register banked if v8M security extensions are enabled.
>>
>> Note that we do not yet implement the functionality of the new
>> AIRCR.PRIS bit (which allows the effect of the NS copy of PRIMASK to
>> be restricted).
>>
>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>> ---
>>   target/arm/cpu.h      | 2 +-
>>   hw/intc/armv7m_nvic.c | 2 +-
>>   target/arm/helper.c   | 4 ++--
>>   target/arm/machine.c  | 9 +++++++--
>>   4 files changed, 11 insertions(+), 6 deletions(-)
> 
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

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

* Re: [Qemu-devel] [Qemu-arm] [PATCH 09/20] target/arm: Make CONTROL register banked for v8M
  2017-08-29 15:43   ` Richard Henderson
@ 2017-09-05 22:54     ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 60+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-09-05 22:54 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Richard Henderson, patches

On 08/29/2017 12:43 PM, Richard Henderson wrote:
> On 08/22/2017 08:08 AM, Peter Maydell wrote:
>> Make the CONTROL register banked if v8M security extensions are enabled.
>>
>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>> ---
>>   target/arm/cpu.h       |  5 +++--
>>   target/arm/helper.c    | 21 +++++++++++----------
>>   target/arm/machine.c   |  3 ++-
>>   target/arm/translate.c |  2 +-
>>   4 files changed, 17 insertions(+), 14 deletions(-)
> 
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

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

* Re: [Qemu-devel] [PATCH 12/20] target/arm: Make MPU_MAIR0, MPU_MAIR1 registers banked for v8M
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 12/20] target/arm: Make MPU_MAIR0, MPU_MAIR1 registers " Peter Maydell
  2017-08-29 16:02   ` Richard Henderson
@ 2017-09-05 22:59   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 60+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-09-05 22:59 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/22/2017 12:08 PM, Peter Maydell wrote:
> Make the MPU registers MPU_MAIR0 and MPU_MAIR1 banked if v8M security
> extensions are enabled.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>   target/arm/cpu.h      | 4 ++--
>   hw/intc/armv7m_nvic.c | 8 ++++----
>   target/arm/cpu.c      | 4 ++--
>   target/arm/machine.c  | 6 ++++--
>   4 files changed, 12 insertions(+), 10 deletions(-)
> 
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index d0b0936..2f59828 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -545,8 +545,8 @@ typedef struct CPUARMState {
>            */
>           uint32_t *rbar;
>           uint32_t *rlar;
> -        uint32_t mair0;
> -        uint32_t mair1;
> +        uint32_t mair0[2];
> +        uint32_t mair1[2];

I'm tempted to ask:

             uint32_t mair[2][2];

>       } pmsav8;
>   
>       void *nvic;
> diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
> index 3a1f02d..e98eb95 100644
> --- a/hw/intc/armv7m_nvic.c
> +++ b/hw/intc/armv7m_nvic.c
> @@ -604,12 +604,12 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
>           if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
>               goto bad_offset;
>           }
> -        return cpu->env.pmsav8.mair0;
> +        return cpu->env.pmsav8.mair0[attrs.secure];

            return cpu->env.pmsav8.mair[0][attrs.secure];

>       case 0xdc4: /* MPU_MAIR1 */
>           if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
>               goto bad_offset;
>           }
> -        return cpu->env.pmsav8.mair1;
> +        return cpu->env.pmsav8.mair1[attrs.secure];

            return cpu->env.pmsav8.mair[1][attrs.secure];

>       default:
>       bad_offset:
>           qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);
> @@ -826,7 +826,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
>           }
>           if (cpu->pmsav7_dregion) {
>               /* Register is RES0 if no MPU regions are implemented */
> -            cpu->env.pmsav8.mair0 = value;
> +            cpu->env.pmsav8.mair0[attrs.secure] = value;

                cpu->env.pmsav8.mair[0][attrs.secure] = value;

>           }
>           /* We don't need to do anything else because memory attributes
>            * only affect cacheability, and we don't implement caching.
> @@ -838,7 +838,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
>           }
>           if (cpu->pmsav7_dregion) {
>               /* Register is RES0 if no MPU regions are implemented */
> -            cpu->env.pmsav8.mair1 = value;
> +            cpu->env.pmsav8.mair1[attrs.secure] = value;

                cpu->env.pmsav8.mair[1][attrs.secure] = value;

>           }
>           /* We don't need to do anything else because memory attributes
>            * only affect cacheability, and we don't implement caching.
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index ae866be..ae8af19 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -249,8 +249,8 @@ static void arm_cpu_reset(CPUState *s)
>               }
>           }
>           env->pmsav7.rnr = 0;
> -        env->pmsav8.mair0 = 0;
> -        env->pmsav8.mair1 = 0;
> +        memset(env->pmsav8.mair0, 0, sizeof(env->pmsav8.mair0));
> +        memset(env->pmsav8.mair1, 0, sizeof(env->pmsav8.mair1));
            memset(env->pmsav8.mair, 0, sizeof(env->pmsav8.mair));

>       }
>   
>       set_flush_to_zero(1, &env->vfp.standard_fp_status);
> diff --git a/target/arm/machine.c b/target/arm/machine.c
> index cd6b6af..414a879 100644
> --- a/target/arm/machine.c
> +++ b/target/arm/machine.c
> @@ -229,8 +229,8 @@ static const VMStateDescription vmstate_pmsav8 = {
>                                 vmstate_info_uint32, uint32_t),
>           VMSTATE_VARRAY_UINT32(env.pmsav8.rlar, ARMCPU, pmsav7_dregion, 0,
>                                 vmstate_info_uint32, uint32_t),
> -        VMSTATE_UINT32(env.pmsav8.mair0, ARMCPU),
> -        VMSTATE_UINT32(env.pmsav8.mair1, ARMCPU),
> +        VMSTATE_UINT32(env.pmsav8.mair0[M_REG_NS], ARMCPU),
> +        VMSTATE_UINT32(env.pmsav8.mair1[M_REG_NS], ARMCPU),

etc...

matter of taste, so:
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

>           VMSTATE_END_OF_LIST()
>       }
>   };
> @@ -255,6 +255,8 @@ static const VMStateDescription vmstate_m_security = {
>           VMSTATE_UINT32(env.v7m.faultmask[M_REG_S], ARMCPU),
>           VMSTATE_UINT32(env.v7m.control[M_REG_S], ARMCPU),
>           VMSTATE_UINT32(env.v7m.vecbase[M_REG_S], ARMCPU),
> +        VMSTATE_UINT32(env.pmsav8.mair0[M_REG_S], ARMCPU),
> +        VMSTATE_UINT32(env.pmsav8.mair1[M_REG_S], ARMCPU),
>           VMSTATE_END_OF_LIST()
>       }
>   };
> 

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

* Re: [Qemu-devel] [Qemu-arm] [PATCH 13/20] target/arm: Make MPU_RBAR, MPU_RLAR banked for v8M
  2017-08-22 15:08 ` [Qemu-devel] [PATCH 13/20] target/arm: Make MPU_RBAR, MPU_RLAR " Peter Maydell
  2017-08-29 16:04   ` Richard Henderson
@ 2017-09-05 23:02   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 60+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-09-05 23:02 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/22/2017 12:08 PM, Peter Maydell wrote:
> Make the MPU registers MPU_MAIR0 and MPU_MAIR1 banked if v8M security
> extensions are enabled.
> 
> We can freely add more items to vmstate_m_security without
> breaking migration compatibility, because no CPU currently
> has the ARM_FEATURE_M_SECURITY bit enabled and so this
> subsection is not yet used by anything.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>   target/arm/cpu.h      |  4 ++--
>   hw/intc/armv7m_nvic.c |  8 ++++----
>   target/arm/cpu.c      | 26 ++++++++++++++++++++------
>   target/arm/helper.c   | 11 ++++++-----
>   target/arm/machine.c  | 12 ++++++++----
>   5 files changed, 40 insertions(+), 21 deletions(-)
> 
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index 2f59828..12fa95e 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -543,8 +543,8 @@ typedef struct CPUARMState {
>            *  pmsav7.rnr (region number register)
>            *  pmsav7_dregion (number of configured regions)
>            */
> -        uint32_t *rbar;
> -        uint32_t *rlar;
> +        uint32_t *rbar[2];
> +        uint32_t *rlar[2];
>           uint32_t mair0[2];
>           uint32_t mair1[2];
>       } pmsav8;
> diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
> index e98eb95..9ced7af 100644
> --- a/hw/intc/armv7m_nvic.c
> +++ b/hw/intc/armv7m_nvic.c
> @@ -564,7 +564,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
>               if (region >= cpu->pmsav7_dregion) {
>                   return 0;
>               }
> -            return cpu->env.pmsav8.rbar[region];
> +            return cpu->env.pmsav8.rbar[attrs.secure][region];
>           }
>   
>           if (region >= cpu->pmsav7_dregion) {
> @@ -591,7 +591,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
>               if (region >= cpu->pmsav7_dregion) {
>                   return 0;
>               }
> -            return cpu->env.pmsav8.rlar[region];
> +            return cpu->env.pmsav8.rlar[attrs.secure][region];
>           }
>   
>           if (region >= cpu->pmsav7_dregion) {
> @@ -756,7 +756,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
>               if (region >= cpu->pmsav7_dregion) {
>                   return;
>               }
> -            cpu->env.pmsav8.rbar[region] = value;
> +            cpu->env.pmsav8.rbar[attrs.secure][region] = value;
>               tlb_flush(CPU(cpu));
>               return;
>           }
> @@ -806,7 +806,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
>               if (region >= cpu->pmsav7_dregion) {
>                   return;
>               }
> -            cpu->env.pmsav8.rlar[region] = value;
> +            cpu->env.pmsav8.rlar[attrs.secure][region] = value;
>               tlb_flush(CPU(cpu));
>               return;
>           }
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index ae8af19..333029c 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -235,10 +235,20 @@ static void arm_cpu_reset(CPUState *s)
>       if (arm_feature(env, ARM_FEATURE_PMSA)) {
>           if (cpu->pmsav7_dregion > 0) {
>               if (arm_feature(env, ARM_FEATURE_V8)) {
> -                memset(env->pmsav8.rbar, 0,
> -                       sizeof(*env->pmsav8.rbar) * cpu->pmsav7_dregion);
> -                memset(env->pmsav8.rlar, 0,
> -                       sizeof(*env->pmsav8.rlar) * cpu->pmsav7_dregion);
> +                memset(env->pmsav8.rbar[M_REG_NS], 0,
> +                       sizeof(*env->pmsav8.rbar[M_REG_NS])
> +                       * cpu->pmsav7_dregion);
> +                memset(env->pmsav8.rlar[M_REG_NS], 0,
> +                       sizeof(*env->pmsav8.rlar[M_REG_NS])
> +                       * cpu->pmsav7_dregion);
> +                if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
> +                    memset(env->pmsav8.rbar[M_REG_S], 0,
> +                           sizeof(*env->pmsav8.rbar[M_REG_S])
> +                           * cpu->pmsav7_dregion);
> +                    memset(env->pmsav8.rlar[M_REG_S], 0,
> +                           sizeof(*env->pmsav8.rlar[M_REG_S])
> +                           * cpu->pmsav7_dregion);
> +                }
>               } else if (arm_feature(env, ARM_FEATURE_V7)) {
>                   memset(env->pmsav7.drbar, 0,
>                          sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion);
> @@ -823,8 +833,12 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
>           if (nr) {
>               if (arm_feature(env, ARM_FEATURE_V8)) {
>                   /* PMSAv8 */
> -                env->pmsav8.rbar = g_new0(uint32_t, nr);
> -                env->pmsav8.rlar = g_new0(uint32_t, nr);
> +                env->pmsav8.rbar[M_REG_NS] = g_new0(uint32_t, nr);
> +                env->pmsav8.rlar[M_REG_NS] = g_new0(uint32_t, nr);
> +                if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
> +                    env->pmsav8.rbar[M_REG_S] = g_new0(uint32_t, nr);
> +                    env->pmsav8.rlar[M_REG_S] = g_new0(uint32_t, nr);
> +                }
>               } else {
>                   env->pmsav7.drbar = g_new0(uint32_t, nr);
>                   env->pmsav7.drsr = g_new0(uint32_t, nr);
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index b1bb507..5394cef 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -8442,6 +8442,7 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
>   {
>       ARMCPU *cpu = arm_env_get_cpu(env);
>       bool is_user = regime_is_user(env, mmu_idx);
> +    uint32_t secure = regime_is_secure(env, mmu_idx);

        bool secure = regime_is_secure(env, mmu_idx);

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

>       int n;
>       int matchregion = -1;
>       bool hit = false;
> @@ -8468,10 +8469,10 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
>                * with bits [4:0] all zeroes, but the limit address is bits
>                * [31:5] from the register with bits [4:0] all ones.
>                */
> -            uint32_t base = env->pmsav8.rbar[n] & ~0x1f;
> -            uint32_t limit = env->pmsav8.rlar[n] | 0x1f;
> +            uint32_t base = env->pmsav8.rbar[secure][n] & ~0x1f;
> +            uint32_t limit = env->pmsav8.rlar[secure][n] | 0x1f;
>   
> -            if (!(env->pmsav8.rlar[n] & 0x1)) {
> +            if (!(env->pmsav8.rlar[secure][n] & 0x1)) {
>                   /* Region disabled */
>                   continue;
>               }
> @@ -8520,8 +8521,8 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
>           /* hit using the background region */
>           get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
>       } else {
> -        uint32_t ap = extract32(env->pmsav8.rbar[matchregion], 1, 2);
> -        uint32_t xn = extract32(env->pmsav8.rbar[matchregion], 0, 1);
> +        uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2);
> +        uint32_t xn = extract32(env->pmsav8.rbar[secure][matchregion], 0, 1);
>   
>           if (m_is_system_region(env, address)) {
>               /* System space is always execute never */
> diff --git a/target/arm/machine.c b/target/arm/machine.c
> index 414a879..05c6c7a 100644
> --- a/target/arm/machine.c
> +++ b/target/arm/machine.c
> @@ -225,10 +225,10 @@ static const VMStateDescription vmstate_pmsav8 = {
>       .minimum_version_id = 1,
>       .needed = pmsav8_needed,
>       .fields = (VMStateField[]) {
> -        VMSTATE_VARRAY_UINT32(env.pmsav8.rbar, ARMCPU, pmsav7_dregion, 0,
> -                              vmstate_info_uint32, uint32_t),
> -        VMSTATE_VARRAY_UINT32(env.pmsav8.rlar, ARMCPU, pmsav7_dregion, 0,
> -                              vmstate_info_uint32, uint32_t),
> +        VMSTATE_VARRAY_UINT32(env.pmsav8.rbar[M_REG_NS], ARMCPU, pmsav7_dregion,
> +                              0, vmstate_info_uint32, uint32_t),
> +        VMSTATE_VARRAY_UINT32(env.pmsav8.rlar[M_REG_NS], ARMCPU, pmsav7_dregion,
> +                              0, vmstate_info_uint32, uint32_t),
>           VMSTATE_UINT32(env.pmsav8.mair0[M_REG_NS], ARMCPU),
>           VMSTATE_UINT32(env.pmsav8.mair1[M_REG_NS], ARMCPU),
>           VMSTATE_END_OF_LIST()
> @@ -257,6 +257,10 @@ static const VMStateDescription vmstate_m_security = {
>           VMSTATE_UINT32(env.v7m.vecbase[M_REG_S], ARMCPU),
>           VMSTATE_UINT32(env.pmsav8.mair0[M_REG_S], ARMCPU),
>           VMSTATE_UINT32(env.pmsav8.mair1[M_REG_S], ARMCPU),
> +        VMSTATE_VARRAY_UINT32(env.pmsav8.rbar[M_REG_S], ARMCPU, pmsav7_dregion,
> +                              0, vmstate_info_uint32, uint32_t),
> +        VMSTATE_VARRAY_UINT32(env.pmsav8.rlar[M_REG_S], ARMCPU, pmsav7_dregion,
> +                              0, vmstate_info_uint32, uint32_t),
>           VMSTATE_END_OF_LIST()
>       }
>   };
> 

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

* Re: [Qemu-devel] [Qemu-arm] [PATCH 17/20] target/arm: Make MMFAR banked for v8M
  2017-08-29 16:10   ` Richard Henderson
@ 2017-09-05 23:05     ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 60+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-09-05 23:05 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Richard Henderson, patches

On 08/29/2017 01:10 PM, Richard Henderson wrote:
> On 08/22/2017 08:08 AM, Peter Maydell wrote:
>> Make the MMFAR register banked if v8M security extensions are
>> enabled.
>>
>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>> ---
>>   target/arm/cpu.h      | 2 +-
>>   hw/intc/armv7m_nvic.c | 4 ++--
>>   target/arm/helper.c   | 4 ++--
>>   target/arm/machine.c  | 3 ++-
>>   4 files changed, 7 insertions(+), 6 deletions(-)
> 
> 
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

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

* Re: [Qemu-devel] [PATCH 03/20] target/arm: Add state field, feature bit and migration for v8M secure state
  2017-08-29 15:28   ` Richard Henderson
@ 2017-09-05 23:09     ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 60+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-09-05 23:09 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Richard Henderson, patches

On 08/29/2017 12:28 PM, Richard Henderson wrote:
> On 08/22/2017 08:08 AM, Peter Maydell wrote:
>> As the first step in implementing ARM v8M's security extension:
>>   * add a new feature bit ARM_FEATURE_M_SECURITY
>>   * add the CPU state field that indicates whether the CPU is
>>     currently in the secure state
>>   * add a migration subsection for this new state
>>     (we will add the Secure copies of banked register state
>>     to this subsection in later patches)
>>   * add a #define for the one new-in-v8M exception type
>>   * make the CPU debug log print S/NS status
>>
>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>> ---
>>   target/arm/cpu.h       |  3 +++
>>   target/arm/cpu.c       |  4 ++++
>>   target/arm/machine.c   | 20 ++++++++++++++++++++
>>   target/arm/translate.c |  8 +++++++-
>>   4 files changed, 34 insertions(+), 1 deletion(-)
> 
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

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

end of thread, other threads:[~2017-09-05 23:09 UTC | newest]

Thread overview: 60+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-22 15:08 [Qemu-devel] [PATCH 00/20] first steps towards v8M support Peter Maydell
2017-08-22 15:08 ` [Qemu-devel] [PATCH 01/20] target/arm: Implement ARMv8M's PMSAv8 registers Peter Maydell
2017-08-29 15:21   ` Richard Henderson
2017-09-05 19:16   ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
2017-09-05 21:28     ` Peter Maydell
2017-08-22 15:08 ` [Qemu-devel] [PATCH 02/20] target/arm: Implement new PMSAv8 behaviour Peter Maydell
2017-08-29 15:25   ` Richard Henderson
2017-08-22 15:08 ` [Qemu-devel] [PATCH 03/20] target/arm: Add state field, feature bit and migration for v8M secure state Peter Maydell
2017-08-29 15:28   ` Richard Henderson
2017-09-05 23:09     ` Philippe Mathieu-Daudé
2017-08-22 15:08 ` [Qemu-devel] [PATCH 04/20] target/arm: Register second AddressSpace for secure v8M CPUs Peter Maydell
2017-08-29 15:29   ` Richard Henderson
2017-08-22 15:08 ` [Qemu-devel] [PATCH 05/20] target/arm: Add MMU indexes for secure v8M Peter Maydell
2017-08-25  9:34   ` [Qemu-devel] [Qemu-arm] " Peter Maydell
2017-08-29 15:36   ` [Qemu-devel] " Richard Henderson
2017-08-22 15:08 ` [Qemu-devel] [PATCH 06/20] target/arm: Make BASEPRI register banked for v8M Peter Maydell
2017-08-29 15:37   ` Richard Henderson
2017-09-05 22:45   ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
2017-09-05 22:53     ` Philippe Mathieu-Daudé
2017-08-22 15:08 ` [Qemu-devel] [PATCH 07/20] target/arm: Make PRIMASK " Peter Maydell
2017-08-29 15:38   ` Richard Henderson
2017-09-05 22:53     ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
2017-08-22 15:08 ` [Qemu-devel] [PATCH 08/20] target/arm: Make FAULTMASK " Peter Maydell
2017-08-29 15:41   ` Richard Henderson
2017-08-22 15:08 ` [Qemu-devel] [PATCH 09/20] target/arm: Make CONTROL " Peter Maydell
2017-08-29 15:43   ` Richard Henderson
2017-09-05 22:54     ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
2017-08-22 15:08 ` [Qemu-devel] [PATCH 10/20] nvic: Add NS alias SCS region Peter Maydell
2017-08-29 16:00   ` Richard Henderson
2017-09-05 16:26     ` Peter Maydell
2017-09-05 16:48       ` Richard Henderson
2017-09-05 17:09         ` Peter Maydell
2017-08-22 15:08 ` [Qemu-devel] [PATCH 11/20] target/arm: Make VTOR register banked for v8M Peter Maydell
2017-08-29 16:02   ` Richard Henderson
2017-08-22 15:08 ` [Qemu-devel] [PATCH 12/20] target/arm: Make MPU_MAIR0, MPU_MAIR1 registers " Peter Maydell
2017-08-29 16:02   ` Richard Henderson
2017-09-05 22:59   ` Philippe Mathieu-Daudé
2017-08-22 15:08 ` [Qemu-devel] [PATCH 13/20] target/arm: Make MPU_RBAR, MPU_RLAR " Peter Maydell
2017-08-29 16:04   ` Richard Henderson
2017-09-05 23:02   ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
2017-08-22 15:08 ` [Qemu-devel] [PATCH 14/20] target/arm: Make MPU_RNR register " Peter Maydell
2017-08-29 16:05   ` Richard Henderson
2017-08-29 16:06     ` Peter Maydell
2017-08-29 16:09       ` Richard Henderson
2017-09-05 16:41         ` Peter Maydell
2017-08-22 15:08 ` [Qemu-devel] [PATCH 15/20] target/arm: Make MPU_CTRL " Peter Maydell
2017-08-29 16:06   ` Richard Henderson
2017-08-22 15:08 ` [Qemu-devel] [PATCH 16/20] target/arm: Make CCR " Peter Maydell
2017-08-29 16:08   ` Richard Henderson
2017-09-05 16:39     ` Peter Maydell
2017-08-22 15:08 ` [Qemu-devel] [PATCH 17/20] target/arm: Make MMFAR " Peter Maydell
2017-08-29 16:10   ` Richard Henderson
2017-09-05 23:05     ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
2017-08-22 15:08 ` [Qemu-devel] [PATCH 18/20] target/arm: Make CFSR register " Peter Maydell
2017-08-29 16:12   ` Richard Henderson
2017-08-22 15:08 ` [Qemu-devel] [PATCH 19/20] target/arm: Move regime_is_secure() to target/arm/internals.h Peter Maydell
2017-08-29 16:12   ` Richard Henderson
2017-09-05 22:51     ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
2017-08-22 15:08 ` [Qemu-devel] [PATCH 20/20] target/arm: Implement BXNS, and banked stack pointers Peter Maydell
2017-08-29 16:31   ` 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.