All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55
@ 2020-11-19 21:55 Peter Maydell
  2020-11-19 21:55 ` [PATCH v2 01/28] hw/intc/armv7m_nvic: Make all of system PPB range be RAZWI/BusFault Peter Maydell
                   ` (28 more replies)
  0 siblings, 29 replies; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:55 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

This is a v2 because it's a respin of "target/arm: More v8.1M
features".  The bad news is it's nearly doubled in length.  The good
news is that this is because the new patches on the end are enough to
implement all the remaining missing v8.1M specifics to the point
where we can provide a Cortex-M55 CPU.  (There is as yet no board
model that uses the Cortex-M55, though; that's next on my todo list.)

As before, the series is a mix of bugfixes and new features:

In the bugfix category:
 * RAZWI (or BusFault for unprivileged accesses) the whole of the
   system PPB address range, not just the SCS
 * Don't clobber ID_PFR1.Security on M-profile
 * Don't allow VMRS/VMSR to fp sysregs that don't exist on M-profile
 * CCR.BFHFNMIGN should RAZ/WI for Nonsecure if AIRCR.BFHFNMINS == 0
 * The change in commit 077d7449100d824a4 to handle "bad returns from
   NMI/HardFault forcibly deactivate those exceptions" wasn't quite
   right; we would deactivate those exceptions but generally not
   trigger the illegal exception return that we ought to
 * fix a typo in the name we give the NVIC object when we create it

In the features category:
 * v8.1M PXN extension
 * VSCCLRM and CLRM insns
 * VLDR/VSTR (sysreg) insns
 * new M-profile fp sysregs: FPSCR_nzcvqc, FPCXT_S, FPCXT_NS
 * update FPDSCR masking to allow new-in-v8.1M bits in that register
 * v8.1M has a new REVIDR register
 * v8.1M does not set HFSR.FORCED on vector table fetch failure
 * v8.1M always clears R0-R3, R12, APSR, EPSR on exception entry
   (the behaviour is tightened up compared to v8.0M)
 * v8.1M has a new check on exception return which might trigger
   a NOCP UsageFault
 * v8.1M has new VLLDM and VLSTM encodings
 * v8.1M's new CCR.TRD bit that enables an extra integrity check
   when executing an SG instruction
 * v8.1M "minimal RAS" (the architecturally minimum permitted
   do-nothing implementation, essentially)
  
Already reviewed: patches 1-6, 8, 11, 12.

thanks
-- PMM

Peter Maydell (28):
  hw/intc/armv7m_nvic: Make all of system PPB range be RAZWI/BusFault
  target/arm: Implement v8.1M PXN extension
  target/arm: Don't clobber ID_PFR1.Security on M-profile cores
  target/arm: Implement VSCCLRM insn
  target/arm: Implement CLRM instruction
  target/arm: Enforce M-profile VMRS/VMSR register restrictions
  target/arm: Refactor M-profile VMSR/VMRS handling
  target/arm: Move general-use constant expanders up in translate.c
  target/arm: Implement VLDR/VSTR system register
  target/arm: Implement M-profile FPSCR_nzcvqc
  target/arm: Use new FPCR_NZCV_MASK constant
  target/arm: Factor out preserve-fp-state from full_vfp_access_check()
  target/arm: Implement FPCXT_S fp system register
  target/arm: Implement FPCXT_NS fp system register
  hw/intc/armv7m_nvic: Update FPDSCR masking for v8.1M
  target/arm: For v8.1M, always clear R0-R3, R12, APSR, EPSR on
    exception entry
  target/arm: In v8.1M, don't set HFSR.FORCED on vector table fetch
    failures
  target/arm: Implement v8.1M REVIDR register
  target/arm: Implement new v8.1M NOCP check for exception return
  target/arm: Implement new v8.1M VLLDM and VLSTM encodings
  hw/intc/armv7m_nvic: Correct handling of CCR.BFHFNMIGN
  hw/intc/armv7m_nvic: Support v8.1M CCR.TRD bit
  target/arm: Implement CCR_S.TRD behaviour for SG insns
  hw/intc/armv7m_nvic: Fix "return from inactive handler" check
  target/arm: Implement M-profile "minimal RAS implementation"
  hw/intc/armv7m_nvic: Implement read/write for RAS register block
  hw/arm/armv7m: Correct typo in QOM object name
  target/arm: Implement Cortex-M55 model

 include/hw/intc/armv7m_nvic.h  |   2 +
 target/arm/cpu.h               |  46 +++
 target/arm/m-nocp.decode       |  10 +-
 target/arm/t32.decode          |  10 +-
 target/arm/vfp.decode          |  14 +
 hw/arm/armv7m.c                |   4 +-
 hw/intc/armv7m_nvic.c          | 257 +++++++++++---
 target/arm/cpu.c               |   5 +-
 target/arm/cpu_tcg.c           |  42 +++
 target/arm/helper.c            |   7 +-
 target/arm/m_helper.c          | 130 ++++++-
 target/arm/translate.c         | 105 ++++--
 target/arm/translate-vfp.c.inc | 604 +++++++++++++++++++++++++++++++--
 13 files changed, 1115 insertions(+), 121 deletions(-)

-- 
2.20.1



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

* [PATCH v2 01/28] hw/intc/armv7m_nvic: Make all of system PPB range be RAZWI/BusFault
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
@ 2020-11-19 21:55 ` Peter Maydell
  2020-11-19 21:55 ` [PATCH v2 02/28] target/arm: Implement v8.1M PXN extension Peter Maydell
                   ` (27 subsequent siblings)
  28 siblings, 0 replies; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:55 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

For M-profile CPUs, the range from 0xe0000000 to 0xe00fffff is the
Private Peripheral Bus range, which includes all of the memory mapped
devices and registers that are part of the CPU itself, including the
NVIC, systick timer, and debug and trace components like the Data
Watchpoint and Trace unit (DWT).  Within this large region, the range
0xe000e000 to 0xe000efff is the System Control Space (NVIC, system
registers, systick) and 0xe002e000 to 0exe002efff is its Non-secure
alias.

The architecture is clear that within the SCS unimplemented registers
should be RES0 for privileged accesses and generate BusFault for
unprivileged accesses, and we currently implement this.

It is less clear about how to handle accesses to unimplemented
regions of the wider PPB.  Unprivileged accesses should definitely
cause BusFaults (R_DQQS), but the behaviour of privileged accesses is
not given as a general rule.  However, the register definitions of
individual registers for components like the DWT all state that they
are RES0 if the relevant component is not implemented, so the
simplest way to provide that is to provide RAZ/WI for the whole range
for privileged accesses.  (The v7M Arm ARM does say that reserved
registers should be UNK/SBZP.)

Expand the container MemoryRegion that the NVIC exposes so that
it covers the whole PPB space. This means:
 * moving the address that the ARMV7M device maps it to down by
   0xe000 bytes
 * moving the off and the offsets within the container of all the
   subregions forward by 0xe000 bytes
 * adding a new default MemoryRegion that covers the whole container
   at a lower priority than anything else and which provides the
   RAZWI/BusFault behaviour

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/hw/intc/armv7m_nvic.h |  1 +
 hw/arm/armv7m.c               |  2 +-
 hw/intc/armv7m_nvic.c         | 78 ++++++++++++++++++++++++++++++-----
 3 files changed, 69 insertions(+), 12 deletions(-)

diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
index bb087b23c35..33b6d8810c7 100644
--- a/include/hw/intc/armv7m_nvic.h
+++ b/include/hw/intc/armv7m_nvic.h
@@ -84,6 +84,7 @@ struct NVICState {
     MemoryRegion systickmem;
     MemoryRegion systick_ns_mem;
     MemoryRegion container;
+    MemoryRegion defaultmem;
 
     uint32_t num_irq;
     qemu_irq excpout;
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 8113b29f1fd..944f261dd05 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -225,7 +225,7 @@ static void armv7m_realize(DeviceState *dev, Error **errp)
     sysbus_connect_irq(sbd, 0,
                        qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
 
-    memory_region_add_subregion(&s->container, 0xe000e000,
+    memory_region_add_subregion(&s->container, 0xe0000000,
                                 sysbus_mmio_get_region(sbd, 0));
 
     for (i = 0; i < ARRAY_SIZE(s->bitband); i++) {
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 42b1ad59e65..9628ce876e0 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -2479,6 +2479,43 @@ static const MemoryRegionOps nvic_systick_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
+/*
+ * Unassigned portions of the PPB space are RAZ/WI for privileged
+ * accesses, and fault for non-privileged accesses.
+ */
+static MemTxResult ppb_default_read(void *opaque, hwaddr addr,
+                                    uint64_t *data, unsigned size,
+                                    MemTxAttrs attrs)
+{
+    qemu_log_mask(LOG_UNIMP, "Read of unassigned area of PPB: offset 0x%x\n",
+                  (uint32_t)addr);
+    if (attrs.user) {
+        return MEMTX_ERROR;
+    }
+    *data = 0;
+    return MEMTX_OK;
+}
+
+static MemTxResult ppb_default_write(void *opaque, hwaddr addr,
+                                     uint64_t value, unsigned size,
+                                     MemTxAttrs attrs)
+{
+    qemu_log_mask(LOG_UNIMP, "Write of unassigned area of PPB: offset 0x%x\n",
+                  (uint32_t)addr);
+    if (attrs.user) {
+        return MEMTX_ERROR;
+    }
+    return MEMTX_OK;
+}
+
+static const MemoryRegionOps ppb_default_ops = {
+    .read_with_attrs = ppb_default_read,
+    .write_with_attrs = ppb_default_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid.min_access_size = 1,
+    .valid.max_access_size = 8,
+};
+
 static int nvic_post_load(void *opaque, int version_id)
 {
     NVICState *s = opaque;
@@ -2675,7 +2712,6 @@ static void nvic_systick_trigger(void *opaque, int n, int level)
 static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
 {
     NVICState *s = NVIC(dev);
-    int regionlen;
 
     /* The armv7m container object will have set our CPU pointer */
     if (!s->cpu || !arm_feature(&s->cpu->env, ARM_FEATURE_M)) {
@@ -2718,7 +2754,20 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
                                                   M_REG_S));
     }
 
-    /* The NVIC and System Control Space (SCS) starts at 0xe000e000
+    /*
+     * This device provides a single sysbus memory region which
+     * represents the whole of the "System PPB" space. This is the
+     * range from 0xe0000000 to 0xe00fffff and includes the NVIC,
+     * the System Control Space (system registers), the systick timer,
+     * and for CPUs with the Security extension an NS banked version
+     * of all of these.
+     *
+     * The default behaviour for unimplemented registers/ranges
+     * (for instance the Data Watchpoint and Trace unit at 0xe0001000)
+     * is to RAZ/WI for privileged access and BusFault for non-privileged
+     * access.
+     *
+     * The NVIC and System Control Space (SCS) starts at 0xe000e000
      * and looks like this:
      *  0x004 - ICTR
      *  0x010 - 0xff - systick
@@ -2741,32 +2790,39 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
      * generally code determining which banked register to use should
      * use attrs.secure; code determining actual behaviour of the system
      * should use env->v7m.secure.
+     *
+     * The container covers the whole PPB space. Within it the priority
+     * of overlapping regions is:
+     *  - default region (for RAZ/WI and BusFault) : -1
+     *  - system register regions : 0
+     *  - systick : 1
+     * This is because the systick device is a small block of registers
+     * in the middle of the other system control registers.
      */
-    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.
-     */
+    memory_region_init(&s->container, OBJECT(s), "nvic", 0x100000);
+    memory_region_init_io(&s->defaultmem, OBJECT(s), &ppb_default_ops, s,
+                          "nvic-default", 0x100000);
+    memory_region_add_subregion_overlap(&s->container, 0, &s->defaultmem, -1);
     memory_region_init_io(&s->sysregmem, OBJECT(s), &nvic_sysreg_ops, s,
                           "nvic_sysregs", 0x1000);
-    memory_region_add_subregion(&s->container, 0, &s->sysregmem);
+    memory_region_add_subregion(&s->container, 0xe000, &s->sysregmem);
 
     memory_region_init_io(&s->systickmem, OBJECT(s),
                           &nvic_systick_ops, s,
                           "nvic_systick", 0xe0);
 
-    memory_region_add_subregion_overlap(&s->container, 0x10,
+    memory_region_add_subregion_overlap(&s->container, 0xe010,
                                         &s->systickmem, 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->sysregmem,
                               "nvic_sysregs_ns", 0x1000);
-        memory_region_add_subregion(&s->container, 0x20000, &s->sysreg_ns_mem);
+        memory_region_add_subregion(&s->container, 0x2e000, &s->sysreg_ns_mem);
         memory_region_init_io(&s->systick_ns_mem, OBJECT(s),
                               &nvic_sysreg_ns_ops, &s->systickmem,
                               "nvic_systick_ns", 0xe0);
-        memory_region_add_subregion_overlap(&s->container, 0x20010,
+        memory_region_add_subregion_overlap(&s->container, 0x2e010,
                                             &s->systick_ns_mem, 1);
     }
 
-- 
2.20.1



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

* [PATCH v2 02/28] target/arm: Implement v8.1M PXN extension
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
  2020-11-19 21:55 ` [PATCH v2 01/28] hw/intc/armv7m_nvic: Make all of system PPB range be RAZWI/BusFault Peter Maydell
@ 2020-11-19 21:55 ` Peter Maydell
  2020-11-19 21:55 ` [PATCH v2 03/28] target/arm: Don't clobber ID_PFR1.Security on M-profile cores Peter Maydell
                   ` (26 subsequent siblings)
  28 siblings, 0 replies; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:55 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

In v8.1M the PXN architecture extension adds a new PXN bit to the
MPU_RLAR registers, which forbids execution of code in the region
from a privileged mode.

This is another feature which is just in the generic "in v8.1M" set
and has no ID register field indicating its presence.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/helper.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 11b0803df72..abc470d9f17 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11754,6 +11754,11 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
     } else {
         uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2);
         uint32_t xn = extract32(env->pmsav8.rbar[secure][matchregion], 0, 1);
+        bool pxn = false;
+
+        if (arm_feature(env, ARM_FEATURE_V8_1M)) {
+            pxn = extract32(env->pmsav8.rlar[secure][matchregion], 4, 1);
+        }
 
         if (m_is_system_region(env, address)) {
             /* System space is always execute never */
@@ -11761,7 +11766,7 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
         }
 
         *prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
-        if (*prot && !xn) {
+        if (*prot && !xn && !(pxn && !is_user)) {
             *prot |= PAGE_EXEC;
         }
         /* We don't need to look the attribute up in the MAIR0/MAIR1
-- 
2.20.1



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

* [PATCH v2 03/28] target/arm: Don't clobber ID_PFR1.Security on M-profile cores
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
  2020-11-19 21:55 ` [PATCH v2 01/28] hw/intc/armv7m_nvic: Make all of system PPB range be RAZWI/BusFault Peter Maydell
  2020-11-19 21:55 ` [PATCH v2 02/28] target/arm: Implement v8.1M PXN extension Peter Maydell
@ 2020-11-19 21:55 ` Peter Maydell
  2020-11-19 21:55 ` [PATCH v2 04/28] target/arm: Implement VSCCLRM insn Peter Maydell
                   ` (25 subsequent siblings)
  28 siblings, 0 replies; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:55 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

In arm_cpu_realizefn() we check whether the board code disabled EL3
via the has_el3 CPU object property, which we create if the CPU
starts with the ARM_FEATURE_EL3 feature bit.  If it is disabled, then
we turn off ARM_FEATURE_EL3 and also zero out the relevant fields in
the ID_PFR1 and ID_AA64PFR0 registers.

This codepath was incorrectly being taken for M-profile CPUs, which
do not have an EL3 and don't set ARM_FEATURE_EL3, but which may have
the M-profile Security extension and so should have non-zero values
in the ID_PFR1.Security field.

Restrict the handling of the feature flag to A/R-profile cores.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/cpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 07492e9f9a4..40f3f798b2b 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1674,7 +1674,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
         }
     }
 
-    if (!cpu->has_el3) {
+    if (!arm_feature(env, ARM_FEATURE_M) && !cpu->has_el3) {
         /* If the has_el3 CPU property is disabled then we need to disable the
          * feature.
          */
-- 
2.20.1



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

* [PATCH v2 04/28] target/arm: Implement VSCCLRM insn
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (2 preceding siblings ...)
  2020-11-19 21:55 ` [PATCH v2 03/28] target/arm: Don't clobber ID_PFR1.Security on M-profile cores Peter Maydell
@ 2020-11-19 21:55 ` Peter Maydell
  2020-11-19 21:55 ` [PATCH v2 05/28] target/arm: Implement CLRM instruction Peter Maydell
                   ` (24 subsequent siblings)
  28 siblings, 0 replies; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:55 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Implement the v8.1M VSCCLRM insn, which zeros floating point
registers if there is an active floating point context.
This requires support in write_neon_element32() for the MO_32
element size, so add it.

Because we want to use arm_gen_condlabel(), we need to move
the definition of that function up in translate.c so it is
before the #include of translate-vfp.c.inc.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/cpu.h               |  9 ++++
 target/arm/m-nocp.decode       |  8 +++-
 target/arm/translate.c         | 21 +++++----
 target/arm/translate-vfp.c.inc | 84 ++++++++++++++++++++++++++++++++++
 4 files changed, 111 insertions(+), 11 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index e5514c82862..11400a9d248 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3555,6 +3555,15 @@ static inline bool isar_feature_aa32_mprofile(const ARMISARegisters *id)
     return FIELD_EX32(id->id_pfr1, ID_PFR1, MPROGMOD) != 0;
 }
 
+static inline bool isar_feature_aa32_m_sec_state(const ARMISARegisters *id)
+{
+    /*
+     * Return true if M-profile state handling insns
+     * (VSCCLRM, CLRM, FPCTX access insns) are implemented
+     */
+    return FIELD_EX32(id->id_pfr1, ID_PFR1, SECURITY) >= 3;
+}
+
 static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
 {
     /* Sadly this is encoded differently for A-profile and M-profile */
diff --git a/target/arm/m-nocp.decode b/target/arm/m-nocp.decode
index 28c8ac6b94c..ccd62e8739a 100644
--- a/target/arm/m-nocp.decode
+++ b/target/arm/m-nocp.decode
@@ -29,13 +29,17 @@
 # If the coprocessor is not present or disabled then we will generate
 # the NOCP exception; otherwise we let the insn through to the main decode.
 
+%vd_dp  22:1 12:4
+%vd_sp  12:4 22:1
+
 &nocp cp
 
 {
   # Special cases which do not take an early NOCP: VLLDM and VLSTM
   VLLDM_VLSTM  1110 1100 001 l:1 rn:4 0000 1010 0000 0000
-  # TODO: VSCCLRM (new in v8.1M) is similar:
-  #VSCCLRM      1110 1100 1-01 1111 ---- 1011 ---- ---0
+  # VSCCLRM (new in v8.1M) is similar:
+  VSCCLRM      1110 1100 1.01 1111 .... 1011 imm:7 0   vd=%vd_dp size=3
+  VSCCLRM      1110 1100 1.01 1111 .... 1010 imm:8     vd=%vd_sp size=2
 
   NOCP         111- 1110 ---- ---- ---- cp:4 ---- ---- &nocp
   NOCP         111- 110- ---- ---- ---- cp:4 ---- ---- &nocp
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 6d04ca3a8a0..9f2b6018a21 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -100,6 +100,15 @@ void arm_translate_init(void)
     a64_translate_init();
 }
 
+/* Generate a label used for skipping this instruction */
+static void arm_gen_condlabel(DisasContext *s)
+{
+    if (!s->condjmp) {
+        s->condlabel = gen_new_label();
+        s->condjmp = 1;
+    }
+}
+
 /* Flags for the disas_set_da_iss info argument:
  * lower bits hold the Rt register number, higher bits are flags.
  */
@@ -1221,6 +1230,9 @@ static void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
     long off = neon_element_offset(reg, ele, memop);
 
     switch (memop) {
+    case MO_32:
+        tcg_gen_st32_i64(src, cpu_env, off);
+        break;
     case MO_64:
         tcg_gen_st_i64(src, cpu_env, off);
         break;
@@ -5156,15 +5168,6 @@ static void gen_srs(DisasContext *s,
     s->base.is_jmp = DISAS_UPDATE_EXIT;
 }
 
-/* Generate a label used for skipping this instruction */
-static void arm_gen_condlabel(DisasContext *s)
-{
-    if (!s->condjmp) {
-        s->condlabel = gen_new_label();
-        s->condjmp = 1;
-    }
-}
-
 /* Skip this instruction if the ARM condition is false */
 static void arm_skip_unless(DisasContext *s, uint32_t cond)
 {
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
index 96948f5a2d3..2a67ed0f6e2 100644
--- a/target/arm/translate-vfp.c.inc
+++ b/target/arm/translate-vfp.c.inc
@@ -3406,6 +3406,90 @@ static bool trans_VLLDM_VLSTM(DisasContext *s, arg_VLLDM_VLSTM *a)
     return true;
 }
 
+static bool trans_VSCCLRM(DisasContext *s, arg_VSCCLRM *a)
+{
+    int btmreg, topreg;
+    TCGv_i64 zero;
+    TCGv_i32 aspen, sfpa;
+
+    if (!dc_isar_feature(aa32_m_sec_state, s)) {
+        /* Before v8.1M, fall through in decode to NOCP check */
+        return false;
+    }
+
+    /* Explicitly UNDEF because this takes precedence over NOCP */
+    if (!arm_dc_feature(s, ARM_FEATURE_M_MAIN) || !s->v8m_secure) {
+        unallocated_encoding(s);
+        return true;
+    }
+
+    if (!dc_isar_feature(aa32_vfp_simd, s)) {
+        /* NOP if we have neither FP nor MVE */
+        return true;
+    }
+
+    /*
+     * If FPCCR.ASPEN != 0 && CONTROL_S.SFPA == 0 then there is no
+     * active floating point context so we must NOP (without doing
+     * any lazy state preservation or the NOCP check).
+     */
+    aspen = load_cpu_field(v7m.fpccr[M_REG_S]);
+    sfpa = load_cpu_field(v7m.control[M_REG_S]);
+    tcg_gen_andi_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
+    tcg_gen_xori_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
+    tcg_gen_andi_i32(sfpa, sfpa, R_V7M_CONTROL_SFPA_MASK);
+    tcg_gen_or_i32(sfpa, sfpa, aspen);
+    arm_gen_condlabel(s);
+    tcg_gen_brcondi_i32(TCG_COND_EQ, sfpa, 0, s->condlabel);
+
+    if (s->fp_excp_el != 0) {
+        gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
+                           syn_uncategorized(), s->fp_excp_el);
+        return true;
+    }
+
+    topreg = a->vd + a->imm - 1;
+    btmreg = a->vd;
+
+    /* Convert to Sreg numbers if the insn specified in Dregs */
+    if (a->size == 3) {
+        topreg = topreg * 2 + 1;
+        btmreg *= 2;
+    }
+
+    if (topreg > 63 || (topreg > 31 && !(topreg & 1))) {
+        /* UNPREDICTABLE: we choose to undef */
+        unallocated_encoding(s);
+        return true;
+    }
+
+    /* Silently ignore requests to clear D16-D31 if they don't exist */
+    if (topreg > 31 && !dc_isar_feature(aa32_simd_r32, s)) {
+        topreg = 31;
+    }
+
+    if (!vfp_access_check(s)) {
+        return true;
+    }
+
+    /* Zero the Sregs from btmreg to topreg inclusive. */
+    zero = tcg_const_i64(0);
+    if (btmreg & 1) {
+        write_neon_element64(zero, btmreg >> 1, 1, MO_32);
+        btmreg++;
+    }
+    for (; btmreg + 1 <= topreg; btmreg += 2) {
+        write_neon_element64(zero, btmreg >> 1, 0, MO_64);
+    }
+    if (btmreg == topreg) {
+        write_neon_element64(zero, btmreg >> 1, 0, MO_32);
+        btmreg++;
+    }
+    assert(btmreg == topreg + 1);
+    /* TODO: when MVE is implemented, zero VPR here */
+    return true;
+}
+
 static bool trans_NOCP(DisasContext *s, arg_nocp *a)
 {
     /*
-- 
2.20.1



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

* [PATCH v2 05/28] target/arm: Implement CLRM instruction
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (3 preceding siblings ...)
  2020-11-19 21:55 ` [PATCH v2 04/28] target/arm: Implement VSCCLRM insn Peter Maydell
@ 2020-11-19 21:55 ` Peter Maydell
  2020-11-19 21:55 ` [PATCH v2 06/28] target/arm: Enforce M-profile VMRS/VMSR register restrictions Peter Maydell
                   ` (23 subsequent siblings)
  28 siblings, 0 replies; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:55 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

In v8.1M the new CLRM instruction allows zeroing an arbitrary set of
the general-purpose registers and APSR.  Implement this.

The encoding is a subset of the LDMIA T2 encoding, using what would
be Rn=0b1111 (which UNDEFs for LDMIA).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/t32.decode  |  6 +++++-
 target/arm/translate.c | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/target/arm/t32.decode b/target/arm/t32.decode
index cfcc71bfb0a..f045eb62c84 100644
--- a/target/arm/t32.decode
+++ b/target/arm/t32.decode
@@ -609,7 +609,11 @@ UXTAB            1111 1010 0101 .... 1111 .... 10.. ....      @rrr_rot
 
 STM_t32          1110 1000 10.0 .... ................         @ldstm i=1 b=0
 STM_t32          1110 1001 00.0 .... ................         @ldstm i=0 b=1
-LDM_t32          1110 1000 10.1 .... ................         @ldstm i=1 b=0
+{
+  # Rn=15 UNDEFs for LDM; M-profile CLRM uses that encoding
+  CLRM           1110 1000 1001 1111 list:16
+  LDM_t32        1110 1000 10.1 .... ................         @ldstm i=1 b=0
+}
 LDM_t32          1110 1001 00.1 .... ................         @ldstm i=0 b=1
 
 &rfe             !extern rn w pu
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 9f2b6018a21..47a1a5739c8 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -7968,6 +7968,44 @@ static bool trans_LDM_t16(DisasContext *s, arg_ldst_block *a)
     return do_ldm(s, a, 1);
 }
 
+static bool trans_CLRM(DisasContext *s, arg_CLRM *a)
+{
+    int i;
+    TCGv_i32 zero;
+
+    if (!dc_isar_feature(aa32_m_sec_state, s)) {
+        return false;
+    }
+
+    if (extract32(a->list, 13, 1)) {
+        return false;
+    }
+
+    if (!a->list) {
+        /* UNPREDICTABLE; we choose to UNDEF */
+        return false;
+    }
+
+    zero = tcg_const_i32(0);
+    for (i = 0; i < 15; i++) {
+        if (extract32(a->list, i, 1)) {
+            /* Clear R[i] */
+            tcg_gen_mov_i32(cpu_R[i], zero);
+        }
+    }
+    if (extract32(a->list, 15, 1)) {
+        /*
+         * Clear APSR (by calling the MSR helper with the same argument
+         * as for "MSR APSR_nzcvqg, Rn": mask = 0b1100, SYSM=0)
+         */
+        TCGv_i32 maskreg = tcg_const_i32(0xc << 8);
+        gen_helper_v7m_msr(cpu_env, maskreg, zero);
+        tcg_temp_free_i32(maskreg);
+    }
+    tcg_temp_free_i32(zero);
+    return true;
+}
+
 /*
  * Branch, branch with link
  */
-- 
2.20.1



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

* [PATCH v2 06/28] target/arm: Enforce M-profile VMRS/VMSR register restrictions
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (4 preceding siblings ...)
  2020-11-19 21:55 ` [PATCH v2 05/28] target/arm: Implement CLRM instruction Peter Maydell
@ 2020-11-19 21:55 ` Peter Maydell
  2020-11-19 21:55 ` [PATCH v2 07/28] target/arm: Refactor M-profile VMSR/VMRS handling Peter Maydell
                   ` (22 subsequent siblings)
  28 siblings, 0 replies; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:55 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

For M-profile before v8.1M, the only valid register for VMSR/VMRS is
the FPSCR.  We have a comment that states this, but the actual logic
to forbid accesses for any other register value is missing, so we
would end up with A-profile style behaviour.  Add the missing check.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/translate-vfp.c.inc | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
index 2a67ed0f6e2..e100182a32c 100644
--- a/target/arm/translate-vfp.c.inc
+++ b/target/arm/translate-vfp.c.inc
@@ -622,7 +622,10 @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
          * Accesses to R15 are UNPREDICTABLE; we choose to undef.
          * (FPSCR -> r15 is a special case which writes to the PSR flags.)
          */
-        if (a->rt == 15 && (!a->l || a->reg != ARM_VFP_FPSCR)) {
+        if (a->reg != ARM_VFP_FPSCR) {
+            return false;
+        }
+        if (a->rt == 15 && !a->l) {
             return false;
         }
     }
-- 
2.20.1



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

* [PATCH v2 07/28] target/arm: Refactor M-profile VMSR/VMRS handling
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (5 preceding siblings ...)
  2020-11-19 21:55 ` [PATCH v2 06/28] target/arm: Enforce M-profile VMRS/VMSR register restrictions Peter Maydell
@ 2020-11-19 21:55 ` Peter Maydell
  2020-12-01 12:54   ` Richard Henderson
  2020-11-19 21:55 ` [PATCH v2 08/28] target/arm: Move general-use constant expanders up in translate.c Peter Maydell
                   ` (21 subsequent siblings)
  28 siblings, 1 reply; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:55 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Currently M-profile borrows the A-profile code for VMSR and VMRS
(access to the FP system registers), because all it needs to support
is the FPSCR.  In v8.1M things become significantly more complicated
in two ways:

 * there are several new FP system registers; some have side effects
   on read, and one (FPCXT_NS) needs to avoid the usual
   vfp_access_check() and the "only if FPU implemented" check

 * all sysregs are now accessible both by VMRS/VMSR (which
   reads/writes a general purpose register) and also by VLDR/VSTR
   (which reads/writes them directly to memory)

Refactor the structure of how we handle VMSR/VMRS to cope with this:

 * keep the M-profile code entirely separate from the A-profile code

 * abstract out the "read or write the general purpose register" part
   of the code into a loadfn or storefn function pointer, so we can
   reuse it for VLDR/VSTR.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu.h               |   3 +
 target/arm/translate-vfp.c.inc | 181 ++++++++++++++++++++++++++++++---
 2 files changed, 170 insertions(+), 14 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 11400a9d248..ad8b80c667d 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1569,6 +1569,9 @@ enum arm_cpu_mode {
 #define ARM_VFP_FPINST  9
 #define ARM_VFP_FPINST2 10
 
+/* QEMU-internal value meaning "FPSCR, but we care only about NZCV" */
+#define QEMU_VFP_FPSCR_NZCV 0xffff
+
 /* iwMMXt coprocessor control registers.  */
 #define ARM_IWMMXT_wCID  0
 #define ARM_IWMMXT_wCon  1
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
index e100182a32c..2d201ad0888 100644
--- a/target/arm/translate-vfp.c.inc
+++ b/target/arm/translate-vfp.c.inc
@@ -607,27 +607,180 @@ static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
     return true;
 }
 
+/*
+ * M-profile provides two different sets of instructions that can
+ * access floating point system registers: VMSR/VMRS (which move
+ * to/from a general purpose register) and VLDR/VSTR sysreg (which
+ * move directly to/from memory). In some cases there are also side
+ * effects which must happen after any write to memory (which could
+ * cause an exception). So we implement the common logic for the
+ * sysreg access in gen_M_fp_sysreg_write() and gen_M_fp_sysreg_read(),
+ * which take pointers to callback functions which will perform the
+ * actual "read/write general purpose register" and "read/write
+ * memory" operations.
+ */
+
+/*
+ * Emit code to store the sysreg to its final destination; frees the
+ * TCG temp 'value' it is passed.
+ */
+typedef void fp_sysreg_storefn(DisasContext *s, void *opaque, TCGv_i32 value);
+/*
+ * Emit code to load the value to be copied to the sysreg; returns
+ * a new TCG temporary
+ */
+typedef TCGv_i32 fp_sysreg_loadfn(DisasContext *s, void *opaque);
+
+/* Common decode/access checks for fp sysreg read/write */
+typedef enum fp_sysreg_check_result {
+    fp_sysreg_check_failed, /* caller should return false */
+    fp_sysreg_check_done, /* caller should return true */
+    fp_sysreg_check_continue, /* caller should continue generating code */
+} fp_sysreg_check_result;
+
+static fp_sysreg_check_result fp_sysreg_checks(DisasContext *s, int regno)
+{
+    if (!dc_isar_feature(aa32_fpsp_v2, s)) {
+        return fp_sysreg_check_failed;
+    }
+
+    switch (regno) {
+    case ARM_VFP_FPSCR:
+    case QEMU_VFP_FPSCR_NZCV:
+        break;
+    default:
+        return fp_sysreg_check_failed;
+    }
+
+    if (!vfp_access_check(s)) {
+        return fp_sysreg_check_done;
+    }
+
+    return fp_sysreg_check_continue;
+}
+
+static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
+                                 fp_sysreg_loadfn *loadfn,
+                                 void *opaque)
+{
+    /* Do a write to an M-profile floating point system register */
+    TCGv_i32 tmp;
+
+    switch (fp_sysreg_checks(s, regno)) {
+    case fp_sysreg_check_failed:
+        return false;
+    case fp_sysreg_check_done:
+        return true;
+    case fp_sysreg_check_continue:
+        break;
+    }
+
+    switch (regno) {
+    case ARM_VFP_FPSCR:
+        tmp = loadfn(s, opaque);
+        gen_helper_vfp_set_fpscr(cpu_env, tmp);
+        tcg_temp_free_i32(tmp);
+        gen_lookup_tb(s);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    return true;
+}
+
+static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
+                                fp_sysreg_storefn *storefn,
+                                void *opaque)
+{
+    /* Do a read from an M-profile floating point system register */
+    TCGv_i32 tmp;
+
+    switch (fp_sysreg_checks(s, regno)) {
+    case fp_sysreg_check_failed:
+        return false;
+    case fp_sysreg_check_done:
+        return true;
+    case fp_sysreg_check_continue:
+        break;
+    }
+
+    switch (regno) {
+    case ARM_VFP_FPSCR:
+        tmp = tcg_temp_new_i32();
+        gen_helper_vfp_get_fpscr(tmp, cpu_env);
+        storefn(s, opaque, tmp);
+        break;
+    case QEMU_VFP_FPSCR_NZCV:
+        /*
+         * Read just NZCV; this is a special case to avoid the
+         * helper call for the "VMRS to CPSR.NZCV" insn.
+         */
+        tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
+        tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
+        storefn(s, opaque, tmp);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    return true;
+}
+
+static void fp_sysreg_to_gpr(DisasContext *s, void *opaque, TCGv_i32 value)
+{
+    arg_VMSR_VMRS *a = opaque;
+
+    if (a->rt == 15) {
+        /* Set the 4 flag bits in the CPSR */
+        gen_set_nzcv(value);
+        tcg_temp_free_i32(value);
+    } else {
+        store_reg(s, a->rt, value);
+    }
+}
+
+static TCGv_i32 gpr_to_fp_sysreg(DisasContext *s, void *opaque)
+{
+    arg_VMSR_VMRS *a = opaque;
+
+    return load_reg(s, a->rt);
+}
+
+static bool gen_M_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
+{
+    /*
+     * Accesses to R15 are UNPREDICTABLE; we choose to undef.
+     * FPSCR -> r15 is a special case which writes to the PSR flags;
+     * set a->reg to a special value to tell gen_M_fp_sysreg_read()
+     * we only care about the top 4 bits of FPSCR there.
+     */
+    if (a->rt == 15) {
+        if (a->l && a->reg == ARM_VFP_FPSCR) {
+            a->reg = QEMU_VFP_FPSCR_NZCV;
+        } else {
+            return false;
+        }
+    }
+
+    if (a->l) {
+        /* VMRS, move FP system register to gp register */
+        return gen_M_fp_sysreg_read(s, a->reg, fp_sysreg_to_gpr, a);
+    } else {
+        /* VMSR, move gp register to FP system register */
+        return gen_M_fp_sysreg_write(s, a->reg, gpr_to_fp_sysreg, a);
+    }
+}
+
 static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
 {
     TCGv_i32 tmp;
     bool ignore_vfp_enabled = false;
 
-    if (!dc_isar_feature(aa32_fpsp_v2, s)) {
-        return false;
+    if (arm_dc_feature(s, ARM_FEATURE_M)) {
+        return gen_M_VMSR_VMRS(s, a);
     }
 
-    if (arm_dc_feature(s, ARM_FEATURE_M)) {
-        /*
-         * The only M-profile VFP vmrs/vmsr sysreg is FPSCR.
-         * Accesses to R15 are UNPREDICTABLE; we choose to undef.
-         * (FPSCR -> r15 is a special case which writes to the PSR flags.)
-         */
-        if (a->reg != ARM_VFP_FPSCR) {
-            return false;
-        }
-        if (a->rt == 15 && !a->l) {
-            return false;
-        }
+    if (!dc_isar_feature(aa32_fpsp_v2, s)) {
+        return false;
     }
 
     switch (a->reg) {
-- 
2.20.1



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

* [PATCH v2 08/28] target/arm: Move general-use constant expanders up in translate.c
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (6 preceding siblings ...)
  2020-11-19 21:55 ` [PATCH v2 07/28] target/arm: Refactor M-profile VMSR/VMRS handling Peter Maydell
@ 2020-11-19 21:55 ` Peter Maydell
  2020-11-19 21:55 ` [PATCH v2 09/28] target/arm: Implement VLDR/VSTR system register Peter Maydell
                   ` (20 subsequent siblings)
  28 siblings, 0 replies; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:55 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The constant-expander functions like negate, plus_2, etc, are
generally useful; move them up in translate.c so we can use them in
the VFP/Neon decoders as well as in the A32/T32/T16 decoders.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/translate.c | 46 +++++++++++++++++++++++-------------------
 1 file changed, 25 insertions(+), 21 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index 47a1a5739c8..f5acd32e76a 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -109,6 +109,30 @@ static void arm_gen_condlabel(DisasContext *s)
     }
 }
 
+/*
+ * Constant expanders for the decoders.
+ */
+
+static int negate(DisasContext *s, int x)
+{
+    return -x;
+}
+
+static int plus_2(DisasContext *s, int x)
+{
+    return x + 2;
+}
+
+static int times_2(DisasContext *s, int x)
+{
+    return x * 2;
+}
+
+static int times_4(DisasContext *s, int x)
+{
+    return x * 4;
+}
+
 /* Flags for the disas_set_da_iss info argument:
  * lower bits hold the Rt register number, higher bits are flags.
  */
@@ -5177,29 +5201,9 @@ static void arm_skip_unless(DisasContext *s, uint32_t cond)
 
 
 /*
- * Constant expanders for the decoders.
+ * Constant expanders used by T16/T32 decode
  */
 
-static int negate(DisasContext *s, int x)
-{
-    return -x;
-}
-
-static int plus_2(DisasContext *s, int x)
-{
-    return x + 2;
-}
-
-static int times_2(DisasContext *s, int x)
-{
-    return x * 2;
-}
-
-static int times_4(DisasContext *s, int x)
-{
-    return x * 4;
-}
-
 /* Return only the rotation part of T32ExpandImm.  */
 static int t32_expandimm_rot(DisasContext *s, int x)
 {
-- 
2.20.1



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

* [PATCH v2 09/28] target/arm: Implement VLDR/VSTR system register
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (7 preceding siblings ...)
  2020-11-19 21:55 ` [PATCH v2 08/28] target/arm: Move general-use constant expanders up in translate.c Peter Maydell
@ 2020-11-19 21:55 ` Peter Maydell
  2020-12-01 13:11   ` Richard Henderson
  2020-11-19 21:55 ` [PATCH v2 10/28] target/arm: Implement M-profile FPSCR_nzcvqc Peter Maydell
                   ` (19 subsequent siblings)
  28 siblings, 1 reply; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:55 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Implement the new-in-v8.1M VLDR/VSTR variants which directly
read or write FP system registers to memory.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/vfp.decode          | 14 ++++++
 target/arm/translate-vfp.c.inc | 89 ++++++++++++++++++++++++++++++++++
 2 files changed, 103 insertions(+)

diff --git a/target/arm/vfp.decode b/target/arm/vfp.decode
index 1300ba045dd..6f7f28f9a46 100644
--- a/target/arm/vfp.decode
+++ b/target/arm/vfp.decode
@@ -84,6 +84,20 @@ VLDR_VSTR_hp ---- 1101 u:1 .0 l:1 rn:4 .... 1001 imm:8      vd=%vd_sp
 VLDR_VSTR_sp ---- 1101 u:1 .0 l:1 rn:4 .... 1010 imm:8      vd=%vd_sp
 VLDR_VSTR_dp ---- 1101 u:1 .0 l:1 rn:4 .... 1011 imm:8      vd=%vd_dp
 
+# M-profile VLDR/VSTR to sysreg
+%vldr_sysreg 22:1 13:3
+%imm7_0x4 0:7 !function=times_4
+
+&vldr_sysreg rn reg imm a w p
+@vldr_sysreg .... ... . a:1 . . . rn:4 ... . ... .. ....... \
+             reg=%vldr_sysreg imm=%imm7_0x4 &vldr_sysreg
+
+# P=0 W=0 is SEE "Related encodings", so split into two patterns
+VLDR_sysreg  ---- 110 1 . . w:1 1 .... ... 0 111 11 ....... @vldr_sysreg p=1
+VLDR_sysreg  ---- 110 0 . . 1   1 .... ... 0 111 11 ....... @vldr_sysreg p=0 w=1
+VSTR_sysreg  ---- 110 1 . . w:1 0 .... ... 0 111 11 ....... @vldr_sysreg p=1
+VSTR_sysreg  ---- 110 0 . . 1   0 .... ... 0 111 11 ....... @vldr_sysreg p=0 w=1
+
 # We split the load/store multiple up into two patterns to avoid
 # overlap with other insns in the "Advanced SIMD load/store and 64-bit move"
 # grouping:
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
index 2d201ad0888..dc26759ab95 100644
--- a/target/arm/translate-vfp.c.inc
+++ b/target/arm/translate-vfp.c.inc
@@ -912,6 +912,95 @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
     return true;
 }
 
+static void fp_sysreg_to_memory(DisasContext *s, void *opaque, TCGv_i32 value)
+{
+    arg_vldr_sysreg *a = opaque;
+    uint32_t offset = a->imm;
+    TCGv_i32 addr;
+
+    if (!a->a) {
+        offset = - offset;
+    }
+
+    addr = load_reg(s, a->rn);
+    if (a->p) {
+        tcg_gen_addi_i32(addr, addr, offset);
+    }
+
+    if (s->v8m_stackcheck && a->rn == 13 && a->w) {
+        gen_helper_v8m_stackcheck(cpu_env, addr);
+    }
+
+    gen_aa32_st32(s, value, addr, get_mem_index(s));
+    tcg_temp_free_i32(value);
+
+    if (a->w) {
+        /* writeback */
+        if (!a->p) {
+            tcg_gen_addi_i32(addr, addr, offset);
+        }
+        store_reg(s, a->rn, addr);
+    } else {
+        tcg_temp_free_i32(addr);
+    }
+}
+
+static TCGv_i32 memory_to_fp_sysreg(DisasContext *s, void *opaque)
+{
+    arg_vldr_sysreg *a = opaque;
+    uint32_t offset = a->imm;
+    TCGv_i32 addr;
+    TCGv_i32 value = tcg_temp_new_i32();
+
+    if (!a->a) {
+        offset = - offset;
+    }
+
+    addr = load_reg(s, a->rn);
+    if (a->p) {
+        tcg_gen_addi_i32(addr, addr, offset);
+    }
+
+    if (s->v8m_stackcheck && a->rn == 13 && a->w) {
+        gen_helper_v8m_stackcheck(cpu_env, addr);
+    }
+
+    gen_aa32_ld32u(s, value, addr, get_mem_index(s));
+
+    if (a->w) {
+        /* writeback */
+        if (!a->p) {
+            tcg_gen_addi_i32(addr, addr, offset);
+        }
+        store_reg(s, a->rn, addr);
+    } else {
+        tcg_temp_free_i32(addr);
+    }
+    return value;
+}
+
+static bool trans_VLDR_sysreg(DisasContext *s, arg_vldr_sysreg *a)
+{
+    if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
+        return false;
+    }
+    if (a->rn == 15) {
+        return false;
+    }
+    return gen_M_fp_sysreg_write(s, a->reg, memory_to_fp_sysreg, a);
+}
+
+static bool trans_VSTR_sysreg(DisasContext *s, arg_vldr_sysreg *a)
+{
+    if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
+        return false;
+    }
+    if (a->rn == 15) {
+        return false;
+    }
+    return gen_M_fp_sysreg_read(s, a->reg, fp_sysreg_to_memory, a);
+}
+
 static bool trans_VMOV_half(DisasContext *s, arg_VMOV_single *a)
 {
     TCGv_i32 tmp;
-- 
2.20.1



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

* [PATCH v2 10/28] target/arm: Implement M-profile FPSCR_nzcvqc
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (8 preceding siblings ...)
  2020-11-19 21:55 ` [PATCH v2 09/28] target/arm: Implement VLDR/VSTR system register Peter Maydell
@ 2020-11-19 21:55 ` Peter Maydell
  2020-12-01 13:16   ` Richard Henderson
  2020-11-19 21:56 ` [PATCH v2 11/28] target/arm: Use new FPCR_NZCV_MASK constant Peter Maydell
                   ` (18 subsequent siblings)
  28 siblings, 1 reply; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:55 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

v8.1M defines a new FP system register FPSCR_nzcvqc; this behaves
like the existing FPSCR, except that it reads and writes only bits
[31:27] of the FPSCR (the N, Z, C, V and QC flag bits).  (Unlike the
FPSCR, the special case for Rt=15 of writing the CPSR.NZCV is not
permitted.)

Implement the register.  Since we don't yet implement MVE, we handle
the QC bit as RES0, with todo comments for where we will need to add
support later.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu.h               | 13 +++++++++++++
 target/arm/translate-vfp.c.inc | 27 +++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index ad8b80c667d..04f6220b2f7 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1524,6 +1524,13 @@ void vfp_set_fpscr(CPUARMState *env, uint32_t val);
 #define FPCR_FZ     (1 << 24)   /* Flush-to-zero enable bit */
 #define FPCR_DN     (1 << 25)   /* Default NaN enable bit */
 #define FPCR_QC     (1 << 27)   /* Cumulative saturation bit */
+#define FPCR_V      (1 << 28)   /* FP overflow flag */
+#define FPCR_C      (1 << 29)   /* FP carry flag */
+#define FPCR_Z      (1 << 30)   /* FP zero flag */
+#define FPCR_N      (1 << 31)   /* FP negative flag */
+
+#define FPCR_NZCV_MASK (FPCR_N | FPCR_Z | FPCR_C | FPCR_V)
+#define FPCR_NZCVQC_MASK (FPCR_NZCV_MASK | FPCR_QC)
 
 static inline uint32_t vfp_get_fpsr(CPUARMState *env)
 {
@@ -1568,6 +1575,12 @@ enum arm_cpu_mode {
 #define ARM_VFP_FPEXC   8
 #define ARM_VFP_FPINST  9
 #define ARM_VFP_FPINST2 10
+/* These ones are M-profile only */
+#define ARM_VFP_FPSCR_NZCVQC 2
+#define ARM_VFP_VPR 12
+#define ARM_VFP_P0 13
+#define ARM_VFP_FPCXT_NS 14
+#define ARM_VFP_FPCXT_S 15
 
 /* QEMU-internal value meaning "FPSCR, but we care only about NZCV" */
 #define QEMU_VFP_FPSCR_NZCV 0xffff
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
index dc26759ab95..6c4b7db8213 100644
--- a/target/arm/translate-vfp.c.inc
+++ b/target/arm/translate-vfp.c.inc
@@ -648,6 +648,11 @@ static fp_sysreg_check_result fp_sysreg_checks(DisasContext *s, int regno)
     case ARM_VFP_FPSCR:
     case QEMU_VFP_FPSCR_NZCV:
         break;
+    case ARM_VFP_FPSCR_NZCVQC:
+        if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
+            return false;
+        }
+        break;
     default:
         return fp_sysreg_check_failed;
     }
@@ -682,6 +687,22 @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
         tcg_temp_free_i32(tmp);
         gen_lookup_tb(s);
         break;
+    case ARM_VFP_FPSCR_NZCVQC:
+    {
+        TCGv_i32 fpscr;
+        tmp = loadfn(s, opaque);
+        /*
+         * TODO: when we implement MVE, write the QC bit.
+         * For non-MVE, QC is RES0.
+         */
+        tcg_gen_andi_i32(tmp, tmp, FPCR_NZCV_MASK);
+        fpscr = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
+        tcg_gen_andi_i32(fpscr, fpscr, ~FPCR_NZCV_MASK);
+        tcg_gen_or_i32(fpscr, fpscr, tmp);
+        store_cpu_field(fpscr, vfp.xregs[ARM_VFP_FPSCR]);
+        tcg_temp_free_i32(tmp);
+        break;
+    }
     default:
         g_assert_not_reached();
     }
@@ -710,6 +731,12 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
         gen_helper_vfp_get_fpscr(tmp, cpu_env);
         storefn(s, opaque, tmp);
         break;
+    case ARM_VFP_FPSCR_NZCVQC:
+        /*
+         * TODO: MVE has a QC bit, which we probably won't store
+         * in the xregs[] field. For non-MVE, where QC is RES0,
+         * we can just fall through to the FPSCR_NZCV case.
+         */
     case QEMU_VFP_FPSCR_NZCV:
         /*
          * Read just NZCV; this is a special case to avoid the
-- 
2.20.1



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

* [PATCH v2 11/28] target/arm: Use new FPCR_NZCV_MASK constant
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (9 preceding siblings ...)
  2020-11-19 21:55 ` [PATCH v2 10/28] target/arm: Implement M-profile FPSCR_nzcvqc Peter Maydell
@ 2020-11-19 21:56 ` Peter Maydell
  2020-11-19 21:56 ` [PATCH v2 12/28] target/arm: Factor out preserve-fp-state from full_vfp_access_check() Peter Maydell
                   ` (17 subsequent siblings)
  28 siblings, 0 replies; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:56 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

We defined a constant name for the mask of NZCV bits in the FPCR/FPSCR
in the previous commit; use it in a couple of places in existing code,
where we're masking out everything except NZCV for the "load to Rt=15
sets CPSR.NZCV" special case.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/translate-vfp.c.inc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
index 6c4b7db8213..6bc327e9819 100644
--- a/target/arm/translate-vfp.c.inc
+++ b/target/arm/translate-vfp.c.inc
@@ -743,7 +743,7 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
          * helper call for the "VMRS to CPSR.NZCV" insn.
          */
         tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
-        tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
+        tcg_gen_andi_i32(tmp, tmp, FPCR_NZCV_MASK);
         storefn(s, opaque, tmp);
         break;
     default:
@@ -884,7 +884,7 @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
         case ARM_VFP_FPSCR:
             if (a->rt == 15) {
                 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
-                tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
+                tcg_gen_andi_i32(tmp, tmp, FPCR_NZCV_MASK);
             } else {
                 tmp = tcg_temp_new_i32();
                 gen_helper_vfp_get_fpscr(tmp, cpu_env);
-- 
2.20.1



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

* [PATCH v2 12/28] target/arm: Factor out preserve-fp-state from full_vfp_access_check()
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (10 preceding siblings ...)
  2020-11-19 21:56 ` [PATCH v2 11/28] target/arm: Use new FPCR_NZCV_MASK constant Peter Maydell
@ 2020-11-19 21:56 ` Peter Maydell
  2020-11-19 22:18   ` Philippe Mathieu-Daudé
  2020-11-19 21:56 ` [PATCH v2 13/28] target/arm: Implement FPCXT_S fp system register Peter Maydell
                   ` (16 subsequent siblings)
  28 siblings, 1 reply; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:56 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Factor out the code which handles M-profile lazy FP state preservation
from full_vfp_access_check(); accesses to the FPCXT_NS register are
a special case which need to do just this part (corresponding in the
pseudocode to the PreserveFPState() function), and not the full
set of actions matching the pseudocode ExecuteFPCheck() which
normal FP instructions need to do.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/translate-vfp.c.inc | 45 ++++++++++++++++++++--------------
 1 file changed, 27 insertions(+), 18 deletions(-)

diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
index 6bc327e9819..9c90c0647bd 100644
--- a/target/arm/translate-vfp.c.inc
+++ b/target/arm/translate-vfp.c.inc
@@ -83,6 +83,32 @@ static inline long vfp_f16_offset(unsigned reg, bool top)
     return offs;
 }
 
+/*
+ * Generate code for M-profile lazy FP state preservation if needed;
+ * this corresponds to the pseudocode PreserveFPState() function.
+ */
+static void gen_preserve_fp_state(DisasContext *s)
+{
+    if (s->v7m_lspact) {
+        /*
+         * Lazy state saving affects external memory and also the NVIC,
+         * so we must mark it as an IO operation for icount (and cause
+         * this to be the last insn in the TB).
+         */
+        if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
+            s->base.is_jmp = DISAS_UPDATE_EXIT;
+            gen_io_start();
+        }
+        gen_helper_v7m_preserve_fp_state(cpu_env);
+        /*
+         * If the preserve_fp_state helper doesn't throw an exception
+         * then it will clear LSPACT; we don't need to repeat this for
+         * any further FP insns in this TB.
+         */
+        s->v7m_lspact = false;
+    }
+}
+
 /*
  * Check that VFP access is enabled. If it is, do the necessary
  * M-profile lazy-FP handling and then return true.
@@ -113,24 +139,7 @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
         /* Handle M-profile lazy FP state mechanics */
 
         /* Trigger lazy-state preservation if necessary */
-        if (s->v7m_lspact) {
-            /*
-             * Lazy state saving affects external memory and also the NVIC,
-             * so we must mark it as an IO operation for icount (and cause
-             * this to be the last insn in the TB).
-             */
-            if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-                s->base.is_jmp = DISAS_UPDATE_EXIT;
-                gen_io_start();
-            }
-            gen_helper_v7m_preserve_fp_state(cpu_env);
-            /*
-             * If the preserve_fp_state helper doesn't throw an exception
-             * then it will clear LSPACT; we don't need to repeat this for
-             * any further FP insns in this TB.
-             */
-            s->v7m_lspact = false;
-        }
+        gen_preserve_fp_state(s);
 
         /* Update ownership of FP context: set FPCCR.S to match current state */
         if (s->v8m_fpccr_s_wrong) {
-- 
2.20.1



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

* [PATCH v2 13/28] target/arm: Implement FPCXT_S fp system register
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (11 preceding siblings ...)
  2020-11-19 21:56 ` [PATCH v2 12/28] target/arm: Factor out preserve-fp-state from full_vfp_access_check() Peter Maydell
@ 2020-11-19 21:56 ` Peter Maydell
  2020-12-01 13:40   ` Richard Henderson
  2020-11-19 21:56 ` [PATCH v2 14/28] target/arm: Implement FPCXT_NS " Peter Maydell
                   ` (15 subsequent siblings)
  28 siblings, 1 reply; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:56 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Implement the new-in-v8.1M FPCXT_S floating point system register.
This is for saving and restoring the secure floating point context,
and it reads and writes bits [27:0] from the FPSCR and the
CONTROL.SFPA bit in bit [31].

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

diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
index 9c90c0647bd..ebc59daf613 100644
--- a/target/arm/translate-vfp.c.inc
+++ b/target/arm/translate-vfp.c.inc
@@ -662,6 +662,14 @@ static fp_sysreg_check_result fp_sysreg_checks(DisasContext *s, int regno)
             return false;
         }
         break;
+    case ARM_VFP_FPCXT_S:
+        if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
+            return false;
+        }
+        if (!s->v8m_secure) {
+            return false;
+        }
+        break;
     default:
         return fp_sysreg_check_failed;
     }
@@ -712,6 +720,26 @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
         tcg_temp_free_i32(tmp);
         break;
     }
+    case ARM_VFP_FPCXT_S:
+    {
+        TCGv_i32 sfpa, control, fpscr;
+        /* Set FPSCR[27:0] and CONTROL.SFPA from value */
+        tmp = loadfn(s, opaque);
+        sfpa = tcg_temp_new_i32();
+        tcg_gen_shri_i32(sfpa, tmp, 31);
+        control = load_cpu_field(v7m.control[M_REG_S]);
+        tcg_gen_deposit_i32(control, control, sfpa,
+                            R_V7M_CONTROL_SFPA_SHIFT, 1);
+        store_cpu_field(control, v7m.control[M_REG_S]);
+        fpscr = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
+        tcg_gen_andi_i32(fpscr, fpscr, FPCR_NZCV_MASK);
+        tcg_gen_andi_i32(tmp, tmp, ~FPCR_NZCV_MASK);
+        tcg_gen_or_i32(fpscr, fpscr, tmp);
+        store_cpu_field(fpscr, vfp.xregs[ARM_VFP_FPSCR]);
+        tcg_temp_free_i32(tmp);
+        tcg_temp_free_i32(sfpa);
+        break;
+    }
     default:
         g_assert_not_reached();
     }
@@ -755,6 +783,36 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
         tcg_gen_andi_i32(tmp, tmp, FPCR_NZCV_MASK);
         storefn(s, opaque, tmp);
         break;
+    case ARM_VFP_FPCXT_S:
+    {
+        TCGv_i32 control, sfpa, fpscr;
+        /* Bits [27:0] from FPSCR, bit [31] from CONTROL.SFPA */
+        tmp = tcg_temp_new_i32();
+        sfpa = tcg_temp_new_i32();
+        gen_helper_vfp_get_fpscr(tmp, cpu_env);
+        tcg_gen_andi_i32(tmp, tmp, ~FPCR_NZCV_MASK);
+        control = load_cpu_field(v7m.control[M_REG_S]);
+        tcg_gen_andi_i32(sfpa, control, R_V7M_CONTROL_SFPA_MASK);
+        tcg_gen_shli_i32(sfpa, sfpa, 31 - R_V7M_CONTROL_SFPA_SHIFT);
+        tcg_gen_or_i32(tmp, tmp, sfpa);
+        tcg_temp_free_i32(sfpa);
+        /*
+         * Store result before updating FPSCR etc, in case
+         * it is a memory write which causes an exception.
+         */
+        storefn(s, opaque, tmp);
+        /*
+         * Now we must reset FPSCR from FPDSCR_NS, and clear
+         * CONTROL.SFPA; so we'll end the TB here.
+         */
+        tcg_gen_andi_i32(control, control, ~R_V7M_CONTROL_SFPA_MASK);
+        store_cpu_field(control, v7m.control[M_REG_S]);
+        fpscr = load_cpu_field(v7m.fpdscr[M_REG_NS]);
+        gen_helper_vfp_set_fpscr(cpu_env, fpscr);
+        tcg_temp_free_i32(fpscr);
+        gen_lookup_tb(s);
+        break;
+    }
     default:
         g_assert_not_reached();
     }
-- 
2.20.1



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

* [PATCH v2 14/28] target/arm: Implement FPCXT_NS fp system register
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (12 preceding siblings ...)
  2020-11-19 21:56 ` [PATCH v2 13/28] target/arm: Implement FPCXT_S fp system register Peter Maydell
@ 2020-11-19 21:56 ` Peter Maydell
  2020-12-01 14:05   ` Richard Henderson
  2020-11-19 21:56 ` [PATCH v2 15/28] hw/intc/armv7m_nvic: Update FPDSCR masking for v8.1M Peter Maydell
                   ` (14 subsequent siblings)
  28 siblings, 1 reply; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:56 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Implement the v8.1M FPCXT_NS floating-point system register.  This is
a little more complicated than FPCXT_S, because it has specific
handling for "current FP state is inactive", and it only wants to do
PreserveFPState(), not the full set of actions done by
ExecuteFPCheck() which vfp_access_check() implements.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/translate-vfp.c.inc | 110 ++++++++++++++++++++++++++++++---
 1 file changed, 103 insertions(+), 7 deletions(-)

diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
index ebc59daf613..1c2d31f6f30 100644
--- a/target/arm/translate-vfp.c.inc
+++ b/target/arm/translate-vfp.c.inc
@@ -647,8 +647,20 @@ typedef enum fp_sysreg_check_result {
     fp_sysreg_check_continue, /* caller should continue generating code */
 } fp_sysreg_check_result;
 
-static fp_sysreg_check_result fp_sysreg_checks(DisasContext *s, int regno)
+/*
+ * Emit code to check common UNDEF cases and handle lazy state preservation
+ * including the special casing for FPCXT_NS. For reads of sysregs, caller
+ * should provide storefn and opaque; for writes to sysregs these can be NULL.
+ * On return, if *insn_end_label is not NULL the caller needs to gen_set_label()
+ * it at the end of the other code generated for the insn.
+ */
+static fp_sysreg_check_result fp_sysreg_checks(DisasContext *s, int regno,
+                                               fp_sysreg_storefn *storefn,
+                                               void *opaque,
+                                               TCGLabel **insn_end_label)
 {
+    *insn_end_label = NULL;
+
     if (!dc_isar_feature(aa32_fpsp_v2, s)) {
         return fp_sysreg_check_failed;
     }
@@ -663,6 +675,7 @@ static fp_sysreg_check_result fp_sysreg_checks(DisasContext *s, int regno)
         }
         break;
     case ARM_VFP_FPCXT_S:
+    case ARM_VFP_FPCXT_NS:
         if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
             return false;
         }
@@ -674,8 +687,46 @@ static fp_sysreg_check_result fp_sysreg_checks(DisasContext *s, int regno)
         return fp_sysreg_check_failed;
     }
 
-    if (!vfp_access_check(s)) {
-        return fp_sysreg_check_done;
+    /*
+     * FPCXT_NS is a special case: it has specific handling for
+     * "current FP state is inactive", and must do the PreserveFPState()
+     * but not the usual full set of actions done by ExecuteFPCheck().
+     * We don't have a TB flag that matches the fpInactive check, so we
+     * do it at runtime as we don't expect FPCXT_NS accesses to be frequent.
+     * The code emitted here handles the fpInactive special case;
+     * the caller just has to do the codegen for the normal (!fpInactive)
+     * special case, and then set the label at the end.
+     */
+    if (regno == ARM_VFP_FPCXT_NS) {
+        /* fpInactive = FPCCR_NS.ASPEN == 1 && CONTROL.FPCA == 0 */
+        TCGLabel *fp_active_label = gen_new_label();
+        TCGv_i32 aspen, fpca;
+        aspen = load_cpu_field(v7m.fpccr[M_REG_NS]);
+        fpca = load_cpu_field(v7m.control[M_REG_S]);
+        tcg_gen_andi_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
+        tcg_gen_xori_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
+        tcg_gen_andi_i32(fpca, fpca, R_V7M_CONTROL_FPCA_MASK);
+        tcg_gen_or_i32(fpca, fpca, aspen);
+        tcg_gen_brcondi_i32(TCG_COND_NE, fpca, 0, fp_active_label);
+        tcg_temp_free_i32(aspen);
+        tcg_temp_free_i32(fpca);
+
+        /* fpInactive case: FPCXT_NS reads as FPDSCR_NS, write is NOP */
+        if (storefn) {
+            TCGv_i32 tmp = load_cpu_field(v7m.fpdscr[M_REG_NS]);
+            storefn(s, opaque, tmp);
+        }
+        /* jump to end of insn */
+        *insn_end_label = gen_new_label();
+        tcg_gen_br(*insn_end_label);
+
+        gen_set_label(fp_active_label);
+        /* !fpInactive: PreserveFPState() and handle register as normal */
+        gen_preserve_fp_state(s);
+    } else {
+        if (!vfp_access_check(s)) {
+            return fp_sysreg_check_done;
+        }
     }
 
     return fp_sysreg_check_continue;
@@ -687,8 +738,10 @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
 {
     /* Do a write to an M-profile floating point system register */
     TCGv_i32 tmp;
+    TCGLabel *insn_end_label;
+    bool lookup_tb = false;
 
-    switch (fp_sysreg_checks(s, regno)) {
+    switch (fp_sysreg_checks(s, regno, NULL, NULL, &insn_end_label)) {
     case fp_sysreg_check_failed:
         return false;
     case fp_sysreg_check_done:
@@ -702,7 +755,7 @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
         tmp = loadfn(s, opaque);
         gen_helper_vfp_set_fpscr(cpu_env, tmp);
         tcg_temp_free_i32(tmp);
-        gen_lookup_tb(s);
+        lookup_tb = true;
         break;
     case ARM_VFP_FPSCR_NZCVQC:
     {
@@ -721,6 +774,7 @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
         break;
     }
     case ARM_VFP_FPCXT_S:
+    case ARM_VFP_FPCXT_NS:
     {
         TCGv_i32 sfpa, control, fpscr;
         /* Set FPSCR[27:0] and CONTROL.SFPA from value */
@@ -743,6 +797,12 @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
     default:
         g_assert_not_reached();
     }
+    if (insn_end_label) {
+        gen_set_label(insn_end_label);
+    }
+    if (lookup_tb) {
+        gen_lookup_tb(s);
+    }
     return true;
 }
 
@@ -752,8 +812,10 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
 {
     /* Do a read from an M-profile floating point system register */
     TCGv_i32 tmp;
+    TCGLabel *insn_end_label;
+    bool lookup_tb = false;
 
-    switch (fp_sysreg_checks(s, regno)) {
+    switch (fp_sysreg_checks(s, regno, storefn, opaque, &insn_end_label)) {
     case fp_sysreg_check_failed:
         return false;
     case fp_sysreg_check_done:
@@ -810,12 +872,46 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
         fpscr = load_cpu_field(v7m.fpdscr[M_REG_NS]);
         gen_helper_vfp_set_fpscr(cpu_env, fpscr);
         tcg_temp_free_i32(fpscr);
-        gen_lookup_tb(s);
+        lookup_tb = true;
+        break;
+    }
+    case ARM_VFP_FPCXT_NS:
+    {
+        TCGv_i32 control, sfpa, fpscr, fpdscr, zero;
+        /* Reads the same as FPCXT_S, but side effects differ */
+        tmp = tcg_temp_new_i32();
+        sfpa = tcg_temp_new_i32();
+        fpscr = tcg_temp_new_i32();
+        gen_helper_vfp_get_fpscr(fpscr, cpu_env);
+        tcg_gen_andi_i32(tmp, fpscr, ~FPCR_NZCV_MASK);
+        control = load_cpu_field(v7m.control[M_REG_S]);
+        tcg_gen_andi_i32(sfpa, control, R_V7M_CONTROL_SFPA_MASK);
+        tcg_gen_shli_i32(sfpa, sfpa, 31 - R_V7M_CONTROL_SFPA_SHIFT);
+        tcg_gen_or_i32(tmp, tmp, sfpa);
+        tcg_temp_free_i32(control);
+        /* Store result before updating FPSCR, in case it faults */
+        storefn(s, opaque, tmp);
+        /* If SFPA is zero then set FPSCR from FPDSCR_NS */
+        fpdscr = load_cpu_field(v7m.fpdscr[M_REG_NS]);
+        zero = tcg_const_i32(0);
+        tcg_gen_movcond_i32(TCG_COND_EQ, fpscr, sfpa, zero, fpdscr, fpscr);
+        gen_helper_vfp_set_fpscr(cpu_env, fpscr);
+        tcg_temp_free_i32(zero);
+        tcg_temp_free_i32(sfpa);
+        tcg_temp_free_i32(fpdscr);
+        tcg_temp_free_i32(fpscr);
+        lookup_tb = true;
         break;
     }
     default:
         g_assert_not_reached();
     }
+    if (insn_end_label) {
+        gen_set_label(insn_end_label);
+    }
+    if (lookup_tb) {
+        gen_lookup_tb(s);
+    }
     return true;
 }
 
-- 
2.20.1



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

* [PATCH v2 15/28] hw/intc/armv7m_nvic: Update FPDSCR masking for v8.1M
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (13 preceding siblings ...)
  2020-11-19 21:56 ` [PATCH v2 14/28] target/arm: Implement FPCXT_NS " Peter Maydell
@ 2020-11-19 21:56 ` Peter Maydell
  2020-12-01 14:28   ` Richard Henderson
  2020-11-19 21:56 ` [PATCH v2 16/28] target/arm: For v8.1M, always clear R0-R3, R12, APSR, EPSR on exception entry Peter Maydell
                   ` (13 subsequent siblings)
  28 siblings, 1 reply; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:56 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The FPDSCR register has a similar layout to the FPSCR.  In v8.1M it
gains new fields FZ16 (if half-precision floating point is supported)
and LTPSIZE (always reads as 4).  Update the reset value and the code
that handles writes to this register accordingly.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu.h      | 5 +++++
 hw/intc/armv7m_nvic.c | 9 ++++++++-
 target/arm/cpu.c      | 3 +++
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 04f6220b2f7..47cb5032ce9 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1521,14 +1521,19 @@ void vfp_set_fpscr(CPUARMState *env, uint32_t val);
 #define FPCR_IXE    (1 << 12)   /* Inexact exception trap enable */
 #define FPCR_IDE    (1 << 15)   /* Input Denormal exception trap enable */
 #define FPCR_FZ16   (1 << 19)   /* ARMv8.2+, FP16 flush-to-zero */
+#define FPCR_RMODE_MASK (3 << 22) /* Rounding mode */
 #define FPCR_FZ     (1 << 24)   /* Flush-to-zero enable bit */
 #define FPCR_DN     (1 << 25)   /* Default NaN enable bit */
+#define FPCR_AHP    (1 << 26)   /* Alternative half-precision */
 #define FPCR_QC     (1 << 27)   /* Cumulative saturation bit */
 #define FPCR_V      (1 << 28)   /* FP overflow flag */
 #define FPCR_C      (1 << 29)   /* FP carry flag */
 #define FPCR_Z      (1 << 30)   /* FP zero flag */
 #define FPCR_N      (1 << 31)   /* FP negative flag */
 
+#define FPCR_LTPSIZE_SHIFT 16   /* LTPSIZE, M-profile only */
+#define FPCR_LTPSIZE_MASK (7 << FPCR_LTPSIZE_SHIFT)
+
 #define FPCR_NZCV_MASK (FPCR_N | FPCR_Z | FPCR_C | FPCR_V)
 #define FPCR_NZCVQC_MASK (FPCR_NZCV_MASK | FPCR_QC)
 
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 9628ce876e0..be3bc1f1f45 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -2068,7 +2068,14 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
         break;
     case 0xf3c: /* FPDSCR */
         if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
-            value &= 0x07c00000;
+            uint32_t mask = FPCR_AHP | FPCR_DN | FPCR_FZ | FPCR_RMODE_MASK;
+            if (cpu_isar_feature(any_fp16, cpu)) {
+                mask |= FPCR_FZ16;
+            }
+            value &= mask;
+            if (cpu_isar_feature(aa32_lob, cpu)) {
+                value |= 4 << FPCR_LTPSIZE_SHIFT;
+            }
             cpu->env.v7m.fpdscr[attrs.secure] = value;
         }
         break;
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 40f3f798b2b..d6188f6566a 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -262,6 +262,9 @@ static void arm_cpu_reset(DeviceState *dev)
              * always reset to 4.
              */
             env->v7m.ltpsize = 4;
+            /* The LTPSIZE field in FPDSCR is constant and reads as 4. */
+            env->v7m.fpdscr[M_REG_NS] = 4 << FPCR_LTPSIZE_SHIFT;
+            env->v7m.fpdscr[M_REG_S] = 4 << FPCR_LTPSIZE_SHIFT;
         }
 
         if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
-- 
2.20.1



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

* [PATCH v2 16/28] target/arm: For v8.1M, always clear R0-R3, R12, APSR, EPSR on exception entry
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (14 preceding siblings ...)
  2020-11-19 21:56 ` [PATCH v2 15/28] hw/intc/armv7m_nvic: Update FPDSCR masking for v8.1M Peter Maydell
@ 2020-11-19 21:56 ` Peter Maydell
  2020-12-01 14:33   ` Richard Henderson
  2020-11-19 21:56 ` [PATCH v2 17/28] target/arm: In v8.1M, don't set HFSR.FORCED on vector table fetch failures Peter Maydell
                   ` (12 subsequent siblings)
  28 siblings, 1 reply; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:56 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

In v8.0M, on exception entry the registers R0-R3, R12, APSR and EPSR
are zeroed for an exception taken to Non-secure state; for an
exception taken to Secure state they become UNKNOWN, and we chose to
leave them at their previous values.

In v8.1M the behaviour is specified more tightly and these registers
are always zeroed regardless of the security state that the exception
targets (see rule R_KPZV).  Implement this.

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

diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
index aad01ea0127..721b4b4896e 100644
--- a/target/arm/m_helper.c
+++ b/target/arm/m_helper.c
@@ -897,10 +897,12 @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
          * Clear registers if necessary to prevent non-secure exception
          * code being able to see register values from secure code.
          * Where register values become architecturally UNKNOWN we leave
-         * them with their previous values.
+         * them with their previous values. v8.1M is tighter than v8.0M
+         * here and always zeroes the caller-saved registers regardless
+         * of the security state the exception is targeting.
          */
         if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
-            if (!targets_secure) {
+            if (!targets_secure || arm_feature(env, ARM_FEATURE_V8_1M)) {
                 /*
                  * Always clear the caller-saved registers (they have been
                  * pushed to the stack earlier in v7m_push_stack()).
@@ -909,10 +911,16 @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
                  * v7m_push_callee_stack()).
                  */
                 int i;
+                /*
+                 * r4..r11 are callee-saves, zero only if background
+                 * state was Secure (EXCRET.S == 1) and exception
+                 * targets Non-secure state
+                 */
+                bool zero_callee_saves = !targets_secure &&
+                    (lr & R_V7M_EXCRET_S_MASK);
 
                 for (i = 0; i < 13; i++) {
-                    /* r4..r11 are callee-saves, zero only if EXCRET.S == 1 */
-                    if (i < 4 || i > 11 || (lr & R_V7M_EXCRET_S_MASK)) {
+                    if (i < 4 || i > 11 || zero_callee_saves) {
                         env->regs[i] = 0;
                     }
                 }
-- 
2.20.1



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

* [PATCH v2 17/28] target/arm: In v8.1M, don't set HFSR.FORCED on vector table fetch failures
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (15 preceding siblings ...)
  2020-11-19 21:56 ` [PATCH v2 16/28] target/arm: For v8.1M, always clear R0-R3, R12, APSR, EPSR on exception entry Peter Maydell
@ 2020-11-19 21:56 ` Peter Maydell
  2020-12-01 14:41   ` Richard Henderson
  2020-11-19 21:56 ` [PATCH v2 18/28] target/arm: Implement v8.1M REVIDR register Peter Maydell
                   ` (11 subsequent siblings)
  28 siblings, 1 reply; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:56 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

In v8.1M, vector table fetch failures don't set HFSR.FORCED (see rule
R_LLRP).  (In previous versions of the architecture this was either
required or IMPDEF.)

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

diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
index 721b4b4896e..9cdc8a64c29 100644
--- a/target/arm/m_helper.c
+++ b/target/arm/m_helper.c
@@ -722,11 +722,15 @@ load_fail:
      * The HardFault is Secure if BFHFNMINS is 0 (meaning that all HFs are
      * secure); otherwise it targets the same security state as the
      * underlying exception.
+     * In v8.1M HardFaults from vector table fetch fails don't set FORCED.
      */
     if (!(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
         exc_secure = true;
     }
-    env->v7m.hfsr |= R_V7M_HFSR_VECTTBL_MASK | R_V7M_HFSR_FORCED_MASK;
+    env->v7m.hfsr |= R_V7M_HFSR_VECTTBL_MASK;
+    if (!arm_feature(env, ARM_FEATURE_V8_1M)) {
+        env->v7m.hfsr |= R_V7M_HFSR_FORCED_MASK;
+    }
     armv7m_nvic_set_pending_derived(env->nvic, ARMV7M_EXCP_HARD, exc_secure);
     return false;
 }
-- 
2.20.1



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

* [PATCH v2 18/28] target/arm: Implement v8.1M REVIDR register
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (16 preceding siblings ...)
  2020-11-19 21:56 ` [PATCH v2 17/28] target/arm: In v8.1M, don't set HFSR.FORCED on vector table fetch failures Peter Maydell
@ 2020-11-19 21:56 ` Peter Maydell
  2020-12-01 14:43   ` Richard Henderson
  2020-11-19 21:56 ` [PATCH v2 19/28] target/arm: Implement new v8.1M NOCP check for exception return Peter Maydell
                   ` (10 subsequent siblings)
  28 siblings, 1 reply; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:56 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

In v8.1M a REVIDR register is defined, which is at address 0xe00ecfc
and is a read-only IMPDEF register providing implementation specific
minor revision information, like the v8A REVIDR_EL1. Implement this.

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

diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index be3bc1f1f45..effc4a784ca 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -1025,6 +1025,11 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
         }
         return val;
     }
+    case 0xcfc:
+        if (!arm_feature(&cpu->env, ARM_FEATURE_V8_1M)) {
+            goto bad_offset;
+        }
+        return cpu->revidr;
     case 0xd00: /* CPUID Base.  */
         return cpu->midr;
     case 0xd04: /* Interrupt Control State (ICSR) */
-- 
2.20.1



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

* [PATCH v2 19/28] target/arm: Implement new v8.1M NOCP check for exception return
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (17 preceding siblings ...)
  2020-11-19 21:56 ` [PATCH v2 18/28] target/arm: Implement v8.1M REVIDR register Peter Maydell
@ 2020-11-19 21:56 ` Peter Maydell
  2020-12-01 14:49   ` Richard Henderson
  2020-11-19 21:56 ` [PATCH v2 20/28] target/arm: Implement new v8.1M VLLDM and VLSTM encodings Peter Maydell
                   ` (9 subsequent siblings)
  28 siblings, 1 reply; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:56 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

In v8.1M a new exception return check is added which may cause a NOCP
UsageFault (see rule R_XLTP): before we clear s0..s15 and the FPSCR
we must check whether access to CP10 from the Security state of the
returning exception is disabled; if it is then we must take a fault.

(Note that for our implementation CPPWR is always RAZ/WI and so can
never cause CP10 accesses to fail.)

The other v8.1M change to this register-clearing code is that if MVE
is implemented VPR must also be cleared, so add a TODO comment to
that effect.

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

diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
index 9cdc8a64c29..0bdd3cc10e9 100644
--- a/target/arm/m_helper.c
+++ b/target/arm/m_helper.c
@@ -1515,7 +1515,27 @@ static void do_v7m_exception_exit(ARMCPU *cpu)
             v7m_exception_taken(cpu, excret, true, false);
             return;
         } else {
-            /* Clear s0..s15 and FPSCR */
+            if (arm_feature(env, ARM_FEATURE_V8_1M)) {
+                /* v8.1M adds this NOCP check */
+                bool nsacr_pass = exc_secure ||
+                    extract32(env->v7m.nsacr, 10, 1);
+                bool cpacr_pass = v7m_cpacr_pass(env, exc_secure, true);
+                if (!nsacr_pass) {
+                    armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, true);
+                    env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
+                    qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing "
+                        "stackframe: NSACR prevents clearing FPU registers\n");
+                    v7m_exception_taken(cpu, excret, true, false);
+                } else if (!cpacr_pass) {
+                    armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
+                                            exc_secure);
+                    env->v7m.cfsr[exc_secure] |= R_V7M_CFSR_NOCP_MASK;
+                    qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing "
+                        "stackframe: CPACR prevents clearing FPU registers\n");
+                    v7m_exception_taken(cpu, excret, true, false);
+                }
+            }
+            /* Clear s0..s15 and FPSCR; TODO also VPR when MVE is implemented */
             int i;
 
             for (i = 0; i < 16; i += 2) {
-- 
2.20.1



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

* [PATCH v2 20/28] target/arm: Implement new v8.1M VLLDM and VLSTM encodings
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (18 preceding siblings ...)
  2020-11-19 21:56 ` [PATCH v2 19/28] target/arm: Implement new v8.1M NOCP check for exception return Peter Maydell
@ 2020-11-19 21:56 ` Peter Maydell
  2020-12-01 15:09   ` Richard Henderson
  2020-11-19 21:56 ` [PATCH v2 21/28] hw/intc/armv7m_nvic: Correct handling of CCR.BFHFNMIGN Peter Maydell
                   ` (8 subsequent siblings)
  28 siblings, 1 reply; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:56 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

v8.1M adds new encodings of VLLDM and VLSTM (where bit 7 is set).
The only difference is that:
 * the old T1 encodings UNDEF if the implementation implements 32
   Dregs (this is currently architecturally impossible for M-profile)
 * the new T2 encodings have the implementation-defined option to
   read from memory (discarding the data) or write UNKNOWN values to
   memory for the stack slots that would be D16-D31

We choose not to make those accesses, so for us the two
instructions behave identically assuming they don't UNDEF.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/m-nocp.decode       |  2 +-
 target/arm/translate-vfp.c.inc | 25 +++++++++++++++++++++++++
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/target/arm/m-nocp.decode b/target/arm/m-nocp.decode
index ccd62e8739a..6699626d7cb 100644
--- a/target/arm/m-nocp.decode
+++ b/target/arm/m-nocp.decode
@@ -36,7 +36,7 @@
 
 {
   # Special cases which do not take an early NOCP: VLLDM and VLSTM
-  VLLDM_VLSTM  1110 1100 001 l:1 rn:4 0000 1010 0000 0000
+  VLLDM_VLSTM  1110 1100 001 l:1 rn:4 0000 1010 op:1 000 0000
   # VSCCLRM (new in v8.1M) is similar:
   VSCCLRM      1110 1100 1.01 1111 .... 1011 imm:7 0   vd=%vd_dp size=3
   VSCCLRM      1110 1100 1.01 1111 .... 1010 imm:8     vd=%vd_sp size=2
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
index 1c2d31f6f30..c974d5b0e16 100644
--- a/target/arm/translate-vfp.c.inc
+++ b/target/arm/translate-vfp.c.inc
@@ -3814,6 +3814,31 @@ static bool trans_VLLDM_VLSTM(DisasContext *s, arg_VLLDM_VLSTM *a)
         !arm_dc_feature(s, ARM_FEATURE_V8)) {
         return false;
     }
+
+    if (a->op) {
+        /*
+         * T2 encoding ({D0-D31} reglist): v8.1M and up. We choose not
+         * to take the IMPDEF option to make memory accesses to the stack
+         * slots that correspond to the D16-D31 registers (discarding
+         * read data and writing UNKNOWN values), so for us the T2
+         * encoding behaves identically to the T1 encoding.
+         */
+        if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
+            return false;
+        }
+    } else {
+        /*
+         * T1 encoding ({D0-D15} reglist); undef if we have 32 Dregs.
+         * This is currently architecturally impossible, but we add the
+         * check to stay in line with the pseudocode. Note that we must
+         * emit code for the UNDEF so it takes precedence over the NOCP.
+         */
+        if (dc_isar_feature(aa32_simd_r32, s)) {
+            unallocated_encoding(s);
+            return true;
+        }
+    }
+
     /*
      * If not secure, UNDEF. We must emit code for this
      * rather than returning false so that this takes
-- 
2.20.1



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

* [PATCH v2 21/28] hw/intc/armv7m_nvic: Correct handling of CCR.BFHFNMIGN
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (19 preceding siblings ...)
  2020-11-19 21:56 ` [PATCH v2 20/28] target/arm: Implement new v8.1M VLLDM and VLSTM encodings Peter Maydell
@ 2020-11-19 21:56 ` Peter Maydell
  2020-12-01 15:16   ` Richard Henderson
  2020-11-19 21:56 ` [PATCH v2 22/28] hw/intc/armv7m_nvic: Support v8.1M CCR.TRD bit Peter Maydell
                   ` (7 subsequent siblings)
  28 siblings, 1 reply; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:56 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The CCR is a register most of whose bits are banked between security
states but where BFHFNMIGN is not, and we keep it in the non-secure
entry of the v7m.ccr[] array.  The logic which tries to handle this
bit fails to implement the "RAZ/WI from Nonsecure if AIRCR.BFHFNMINS
is zero" requirement; correct the omission.

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

diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index effc4a784ca..deb4bd56c95 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -1100,6 +1100,12 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
          */
         val = cpu->env.v7m.ccr[attrs.secure];
         val |= cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK;
+        /* BFHFNMIGN is RAZ/WI from NS if AIRCR.BFHFNMINS is 0 */
+        if (!attrs.secure) {
+            if (!(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
+                val &= ~R_V7M_CCR_BFHFNMIGN_MASK;
+            }
+        }
         return val;
     case 0xd24: /* System Handler Control and State (SHCSR) */
         if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) {
@@ -1662,6 +1668,11 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
                 (cpu->env.v7m.ccr[M_REG_NS] & ~R_V7M_CCR_BFHFNMIGN_MASK)
                 | (value & R_V7M_CCR_BFHFNMIGN_MASK);
             value &= ~R_V7M_CCR_BFHFNMIGN_MASK;
+        } else {
+            /* BFHFNMIGN is RAZ/WI from NS if AIRCR.BFHFNMINS is 0 */
+            if (!(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
+                value &= ~R_V7M_CCR_BFHFNMIGN_MASK;
+            }
         }
 
         cpu->env.v7m.ccr[attrs.secure] = value;
-- 
2.20.1



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

* [PATCH v2 22/28] hw/intc/armv7m_nvic: Support v8.1M CCR.TRD bit
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (20 preceding siblings ...)
  2020-11-19 21:56 ` [PATCH v2 21/28] hw/intc/armv7m_nvic: Correct handling of CCR.BFHFNMIGN Peter Maydell
@ 2020-11-19 21:56 ` Peter Maydell
  2020-12-01 15:19   ` Richard Henderson
  2020-11-19 21:56 ` [PATCH v2 23/28] target/arm: Implement CCR_S.TRD behaviour for SG insns Peter Maydell
                   ` (6 subsequent siblings)
  28 siblings, 1 reply; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:56 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

v8.1M introduces a new TRD flag in the CCR register, which enables
checking for stack frame integrity signatures on SG instructions.
This bit is not banked, and is always RAZ/WI to Non-secure code.
Adjust the code for handling CCR reads and writes to handle this.

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

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 47cb5032ce9..22c55c81933 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1611,6 +1611,8 @@ FIELD(V7M_CCR, STKOFHFNMIGN, 10, 1)
 FIELD(V7M_CCR, DC, 16, 1)
 FIELD(V7M_CCR, IC, 17, 1)
 FIELD(V7M_CCR, BP, 18, 1)
+FIELD(V7M_CCR, LOB, 19, 1)
+FIELD(V7M_CCR, TRD, 20, 1)
 
 /* V7M SCR bits */
 FIELD(V7M_SCR, SLEEPONEXIT, 1, 1)
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index deb4bd56c95..c901d20ae00 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -1095,8 +1095,9 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
         }
         return cpu->env.v7m.scr[attrs.secure];
     case 0xd14: /* Configuration Control.  */
-        /* The BFHFNMIGN bit is the only non-banked bit; we
-         * keep it in the non-secure copy of the register.
+        /*
+         * Non-banked bits: BFHFNMIGN (stored in the NS copy of the register)
+         * and TRD (stored in the S copy of the register)
          */
         val = cpu->env.v7m.ccr[attrs.secure];
         val |= cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK;
@@ -1645,17 +1646,25 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
         cpu->env.v7m.scr[attrs.secure] = value;
         break;
     case 0xd14: /* Configuration Control.  */
+    {
+        uint32_t mask;
+
         if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
             goto bad_offset;
         }
 
         /* Enforce RAZ/WI on reserved and must-RAZ/WI bits */
-        value &= (R_V7M_CCR_STKALIGN_MASK |
-                  R_V7M_CCR_BFHFNMIGN_MASK |
-                  R_V7M_CCR_DIV_0_TRP_MASK |
-                  R_V7M_CCR_UNALIGN_TRP_MASK |
-                  R_V7M_CCR_USERSETMPEND_MASK |
-                  R_V7M_CCR_NONBASETHRDENA_MASK);
+        mask = R_V7M_CCR_STKALIGN_MASK |
+            R_V7M_CCR_BFHFNMIGN_MASK |
+            R_V7M_CCR_DIV_0_TRP_MASK |
+            R_V7M_CCR_UNALIGN_TRP_MASK |
+            R_V7M_CCR_USERSETMPEND_MASK |
+            R_V7M_CCR_NONBASETHRDENA_MASK;
+        if (arm_feature(&cpu->env, ARM_FEATURE_V8_1M) && attrs.secure) {
+            /* TRD is always RAZ/WI from NS */
+            mask |= R_V7M_CCR_TRD_MASK;
+        }
+        value &= mask;
 
         if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
             /* v8M makes NONBASETHRDENA and STKALIGN be RES1 */
@@ -1677,6 +1686,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
 
         cpu->env.v7m.ccr[attrs.secure] = value;
         break;
+    }
     case 0xd24: /* System Handler Control and State (SHCSR) */
         if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) {
             goto bad_offset;
-- 
2.20.1



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

* [PATCH v2 23/28] target/arm: Implement CCR_S.TRD behaviour for SG insns
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (21 preceding siblings ...)
  2020-11-19 21:56 ` [PATCH v2 22/28] hw/intc/armv7m_nvic: Support v8.1M CCR.TRD bit Peter Maydell
@ 2020-11-19 21:56 ` Peter Maydell
  2020-12-01 15:53   ` Richard Henderson
  2020-11-19 21:56 ` [PATCH v2 24/28] hw/intc/armv7m_nvic: Fix "return from inactive handler" check Peter Maydell
                   ` (5 subsequent siblings)
  28 siblings, 1 reply; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:56 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

v8.1M introduces a new TRD flag in the CCR register, which enables
checking for stack frame integrity signatures on SG instructions.
Add the code in the SG insn implementation for the new behaviour.

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

diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
index 0bdd3cc10e9..643dcafb83d 100644
--- a/target/arm/m_helper.c
+++ b/target/arm/m_helper.c
@@ -1999,6 +1999,64 @@ static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx,
     return true;
 }
 
+static bool v7m_read_sg_stack_word(ARMCPU *cpu, ARMMMUIdx mmu_idx,
+                                   uint32_t addr, uint32_t *spdata)
+{
+    /*
+     * Read a word of data from the stack for the SG instruction,
+     * writing the value into *spdata. If the load succeeds, return
+     * true; otherwise pend an appropriate exception and return false.
+     * (We can't use data load helpers here that throw an exception
+     * because of the context we're called in, which is halfway through
+     * arm_v7m_cpu_do_interrupt().)
+     */
+    CPUState *cs = CPU(cpu);
+    CPUARMState *env = &cpu->env;
+    MemTxAttrs attrs = {};
+    MemTxResult txres;
+    target_ulong page_size;
+    hwaddr physaddr;
+    int prot;
+    ARMMMUFaultInfo fi = {};
+    ARMCacheAttrs cacheattrs = {};
+    uint32_t value;
+
+    if (get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &physaddr,
+                      &attrs, &prot, &page_size, &fi, &cacheattrs)) {
+        /* MPU/SAU lookup failed */
+        if (fi.type == ARMFault_QEMU_SFault) {
+            qemu_log_mask(CPU_LOG_INT,
+                          "...SecureFault during stack word read\n");
+            env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK | R_V7M_SFSR_SFARVALID_MASK;
+            env->v7m.sfar = addr;
+            armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
+        } else {
+            qemu_log_mask(CPU_LOG_INT,
+                          "...MemManageFault during stack word read\n");
+            env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_DACCVIOL_MASK |
+                R_V7M_CFSR_MMARVALID_MASK;
+            env->v7m.mmfar[M_REG_S] = addr;
+            armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM, false);
+        }
+        return false;
+    }
+    value = address_space_ldl(arm_addressspace(cs, attrs), physaddr,
+                              attrs, &txres);
+    if (txres != MEMTX_OK) {
+        /* BusFault trying to read the data */
+        qemu_log_mask(CPU_LOG_INT,
+                      "...BusFault during stack word read\n");
+        env->v7m.cfsr[M_REG_NS] |=
+            (R_V7M_CFSR_PRECISERR_MASK | R_V7M_CFSR_BFARVALID_MASK);
+        env->v7m.bfar = addr;
+        armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_BUS, false);
+        return false;
+    }
+
+    *spdata = value;
+    return true;
+}
+
 static bool v7m_handle_execute_nsc(ARMCPU *cpu)
 {
     /*
@@ -2055,6 +2113,34 @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
      */
     qemu_log_mask(CPU_LOG_INT, "...really an SG instruction at 0x%08" PRIx32
                   ", executing it\n", env->regs[15]);
+
+    if (cpu_isar_feature(aa32_m_sec_state, cpu) &&
+        !arm_v7m_is_handler_mode(env)) {
+        /*
+         * v8.1M exception stack frame integrity check. Note that we
+         * must perform the memory access even if CCR_S.TRD is zero
+         * and we aren't going to check what the data loaded is.
+         */
+        uint32_t spdata, sp;
+
+        /*
+         * We know we are currently NS, so the S stack pointers must be
+         * in other_ss_{psp,msp}, not in regs[13]/other_sp.
+         */
+        sp = v7m_using_psp(env) ? env->v7m.other_ss_psp : env->v7m.other_ss_msp;
+        if (!v7m_read_sg_stack_word(cpu, mmu_idx, sp, &spdata)) {
+            /* Stack access failed and an exception has been pended */
+            return false;
+        }
+
+        if (env->v7m.ccr[M_REG_S] & R_V7M_CCR_TRD_MASK) {
+            if (((spdata & ~1) == 0xfefa125a) ||
+                !(env->v7m.control[M_REG_S] & 1)) {
+                goto gen_invep;
+            }
+        }
+    }
+
     env->regs[14] &= ~1;
     env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
     switch_v7m_security_state(env, true);
-- 
2.20.1



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

* [PATCH v2 24/28] hw/intc/armv7m_nvic: Fix "return from inactive handler" check
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (22 preceding siblings ...)
  2020-11-19 21:56 ` [PATCH v2 23/28] target/arm: Implement CCR_S.TRD behaviour for SG insns Peter Maydell
@ 2020-11-19 21:56 ` Peter Maydell
  2020-12-01 15:58   ` Richard Henderson
  2020-11-19 21:56 ` [PATCH v2 25/28] target/arm: Implement M-profile "minimal RAS implementation" Peter Maydell
                   ` (4 subsequent siblings)
  28 siblings, 1 reply; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:56 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

In commit 077d7449100d824a4 we added code to handle the v8M
requirement that returns from NMI or HardFault forcibly deactivate
those exceptions regardless of what interrupt the guest is trying to
deactivate.  Unfortunately this broke the handling of the "illegal
exception return because the returning exception number is not
active" check for those cases.  In the pseudocode this test is done
on the exception the guest asks to return from, but because our
implementation was doing this in armv7m_nvic_complete_irq() after the
new "deactivate NMI/HardFault regardless" code we ended up doing the
test on the VecInfo for that exception instead, which usually meant
failing to raise the illegal exception return fault.

In the case for "configurable exception targeting the opposite
security state" we detected the illegal-return case but went ahead
and deactivated the VecInfo anyway, which is wrong because that is
the VecInfo for the other security state.

Rearrange the code so that we first identify the illegal return
cases, then see if we really need to deactivate NMI or HardFault
instead, and finally do the deactivation.

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

diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index c901d20ae00..fa8aeca82ec 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -832,10 +832,40 @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
 {
     NVICState *s = (NVICState *)opaque;
     VecInfo *vec = NULL;
-    int ret;
+    int ret = 0;
 
     assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
 
+    trace_nvic_complete_irq(irq, secure);
+
+    if (secure && exc_is_banked(irq)) {
+        vec = &s->sec_vectors[irq];
+    } else {
+        vec = &s->vectors[irq];
+    }
+
+    /*
+     * Identify illegal exception return cases. We can't immediately
+     * return at this point because we still need to deactivate
+     * (either this exception or NMI/HardFault) first.
+     */
+    if (!exc_is_banked(irq) && exc_targets_secure(s, irq) != secure) {
+        /*
+         * Return from a configurable exception targeting the opposite
+         * security state from the one we're trying to complete it for.
+         * Clear vec because it's not really the VecInfo for this
+         * (irq, secstate) so we mustn't deactivate it.
+         */
+        ret = -1;
+        vec = NULL;
+    } else if (!vec->active) {
+        /* Return from an inactive interrupt */
+        ret = -1;
+    } else {
+        /* Legal return, we will return the RETTOBASE bit value to the caller */
+        ret = nvic_rettobase(s);
+    }
+
     /*
      * For negative priorities, v8M will forcibly deactivate the appropriate
      * NMI or HardFault regardless of what interrupt we're being asked to
@@ -865,32 +895,7 @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
     }
 
     if (!vec) {
-        if (secure && exc_is_banked(irq)) {
-            vec = &s->sec_vectors[irq];
-        } else {
-            vec = &s->vectors[irq];
-        }
-    }
-
-    trace_nvic_complete_irq(irq, secure);
-
-    if (!vec->active) {
-        /* Tell the caller this was an illegal exception return */
-        return -1;
-    }
-
-    /*
-     * If this is a configurable exception and it is currently
-     * targeting the opposite security state from the one we're trying
-     * to complete it for, this counts as an illegal exception return.
-     * We still need to deactivate whatever vector the logic above has
-     * selected, though, as it might not be the same as the one for the
-     * requested exception number.
-     */
-    if (!exc_is_banked(irq) && exc_targets_secure(s, irq) != secure) {
-        ret = -1;
-    } else {
-        ret = nvic_rettobase(s);
+        return ret;
     }
 
     vec->active = 0;
-- 
2.20.1



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

* [PATCH v2 25/28] target/arm: Implement M-profile "minimal RAS implementation"
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (23 preceding siblings ...)
  2020-11-19 21:56 ` [PATCH v2 24/28] hw/intc/armv7m_nvic: Fix "return from inactive handler" check Peter Maydell
@ 2020-11-19 21:56 ` Peter Maydell
  2020-12-01 16:04   ` Richard Henderson
  2020-11-19 21:56 ` [PATCH v2 26/28] hw/intc/armv7m_nvic: Implement read/write for RAS register block Peter Maydell
                   ` (3 subsequent siblings)
  28 siblings, 1 reply; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:56 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

For v8.1M the architecture mandates that CPUs must provide at
least the "minimal RAS implementation" from the Reliability,
Availability and Serviceability extension. This consists of:
 * an ESB instruction which is a NOP
   -- since it is in the HINT space we need only add a comment
 * an RFSR register which will RAZ/WI
 * a RAZ/WI AIRCR.IESB bit
   -- the code which handles writes to AIRCR does not allow setting
      of RES0 bits, so we already treat this as RAZ/WI; add a comment
      noting that this is deliberate
 * minimal implementation of the RAS register block at 0xe0005000
   -- this will be in a subsequent commit
 * setting the ID_PFR0.RAS field to 0b0010
   -- we will do this when we add the Cortex-M55 CPU model

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu.h      | 14 ++++++++++++++
 target/arm/t32.decode |  4 ++++
 hw/intc/armv7m_nvic.c | 13 +++++++++++++
 3 files changed, 31 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 22c55c81933..7e6c881a7e2 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1827,6 +1827,15 @@ FIELD(ID_MMFR4, LSM, 20, 4)
 FIELD(ID_MMFR4, CCIDX, 24, 4)
 FIELD(ID_MMFR4, EVT, 28, 4)
 
+FIELD(ID_PFR0, STATE0, 0, 4)
+FIELD(ID_PFR0, STATE1, 4, 4)
+FIELD(ID_PFR0, STATE2, 8, 4)
+FIELD(ID_PFR0, STATE3, 12, 4)
+FIELD(ID_PFR0, CSV2, 16, 4)
+FIELD(ID_PFR0, AMU, 20, 4)
+FIELD(ID_PFR0, DIT, 24, 4)
+FIELD(ID_PFR0, RAS, 28, 4)
+
 FIELD(ID_PFR1, PROGMOD, 0, 4)
 FIELD(ID_PFR1, SECURITY, 4, 4)
 FIELD(ID_PFR1, MPROGMOD, 8, 4)
@@ -3573,6 +3582,11 @@ static inline bool isar_feature_aa32_predinv(const ARMISARegisters *id)
     return FIELD_EX32(id->id_isar6, ID_ISAR6, SPECRES) != 0;
 }
 
+static inline bool isar_feature_aa32_ras(const ARMISARegisters *id)
+{
+    return FIELD_EX32(id->id_pfr0, ID_PFR0, RAS) != 0;
+}
+
 static inline bool isar_feature_aa32_mprofile(const ARMISARegisters *id)
 {
     return FIELD_EX32(id->id_pfr1, ID_PFR1, MPROGMOD) != 0;
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
index f045eb62c84..8b2c487fa7a 100644
--- a/target/arm/t32.decode
+++ b/target/arm/t32.decode
@@ -307,6 +307,10 @@ CLZ              1111 1010 1011 ---- 1111 .... 1000 ....      @rdm
       # SEV      1111 0011 1010 1111 1000 0000 0000 0100
       # SEVL     1111 0011 1010 1111 1000 0000 0000 0101
 
+      # For M-profile minimal-RAS ESB can be a NOP, which is the
+      # default behaviour since it is in the hint space.
+      # ESB      1111 0011 1010 1111 1000 0000 0001 0000
+
       # The canonical nop ends in 0000 0000, but the whole rest
       # of the space is "reserved hint, behaves as nop".
       NOP        1111 0011 1010 1111 1000 0000 ---- ----
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index fa8aeca82ec..c42b291f881 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -1489,6 +1489,12 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
             return 0;
         }
         return cpu->env.v7m.sfar;
+    case 0xf04: /* RFSR */
+        if (!cpu_isar_feature(aa32_ras, cpu)) {
+            goto bad_offset;
+        }
+        /* We provide minimal-RAS only: RFSR is RAZ/WI */
+        return 0;
     case 0xf34: /* FPCCR */
         if (!cpu_isar_feature(aa32_vfp_simd, cpu)) {
             return 0;
@@ -1617,6 +1623,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
                               R_V7M_AIRCR_PRIGROUP_SHIFT,
                               R_V7M_AIRCR_PRIGROUP_LENGTH);
             }
+            /* AIRCR.IESB is RAZ/WI because we implement only minimal RAS */
             if (attrs.secure) {
                 /* These bits are only writable by secure */
                 cpu->env.v7m.aircr = value &
@@ -2037,6 +2044,12 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
         }
         break;
     }
+    case 0xf04: /* RFSR */
+        if (!cpu_isar_feature(aa32_ras, cpu)) {
+            goto bad_offset;
+        }
+        /* We provide minimal-RAS only: RFSR is RAZ/WI */
+        break;
     case 0xf34: /* FPCCR */
         if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
             /* Not all bits here are banked. */
-- 
2.20.1



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

* [PATCH v2 26/28] hw/intc/armv7m_nvic: Implement read/write for RAS register block
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (24 preceding siblings ...)
  2020-11-19 21:56 ` [PATCH v2 25/28] target/arm: Implement M-profile "minimal RAS implementation" Peter Maydell
@ 2020-11-19 21:56 ` Peter Maydell
  2020-12-01 16:11   ` Richard Henderson
  2020-11-19 21:56 ` [PATCH v2 27/28] hw/arm/armv7m: Correct typo in QOM object name Peter Maydell
                   ` (2 subsequent siblings)
  28 siblings, 1 reply; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:56 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The RAS feature has a block of memory-mapped registers at offset
0x5000 within the PPB.  For a "minimal RAS" implementation we provide
no error records and so the only registers that exist in the block
are ERRIIDR and ERRDEVID.

The "RAZ/WI for privileged, BusFault for nonprivileged" behaviour
of the "nvic-default" region is actually valid for minimal-RAS,
so the main benefit of providing an explicit implementation of
the register block is more accurate LOG_UNIMP messages, and a
framework for where we could add a real RAS implementation later
if necessary.

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

diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
index 33b6d8810c7..39c71e15936 100644
--- a/include/hw/intc/armv7m_nvic.h
+++ b/include/hw/intc/armv7m_nvic.h
@@ -83,6 +83,7 @@ struct NVICState {
     MemoryRegion sysreg_ns_mem;
     MemoryRegion systickmem;
     MemoryRegion systick_ns_mem;
+    MemoryRegion ras_mem;
     MemoryRegion container;
     MemoryRegion defaultmem;
 
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index c42b291f881..5ab77a3530c 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -2530,6 +2530,56 @@ static const MemoryRegionOps nvic_systick_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
+
+static MemTxResult ras_read(void *opaque, hwaddr addr,
+                            uint64_t *data, unsigned size,
+                            MemTxAttrs attrs)
+{
+    if (attrs.user) {
+        return MEMTX_ERROR;
+    }
+
+    switch (addr) {
+    case 0xe10: /* ERRIIDR */
+        /* architect field = Arm; product/variant/revision 0 */
+        *data = 0x43b;
+        break;
+    case 0xfc8: /* ERRDEVID */
+        /* Minimal RAS: we implement 0 error record indexes */
+        *data = 0;
+        break;
+    default:
+        qemu_log_mask(LOG_UNIMP, "Read RAS register offset 0x%x\n",
+                      (uint32_t)addr);
+        *data = 0;
+        break;
+    }
+    return MEMTX_OK;
+}
+
+static MemTxResult ras_write(void *opaque, hwaddr addr,
+                             uint64_t value, unsigned size,
+                             MemTxAttrs attrs)
+{
+    if (attrs.user) {
+        return MEMTX_ERROR;
+    }
+
+    switch (addr) {
+    default:
+        qemu_log_mask(LOG_UNIMP, "Write to RAS register offset 0x%x\n",
+                      (uint32_t)addr);
+        break;
+    }
+    return MEMTX_OK;
+}
+
+static const MemoryRegionOps ras_ops = {
+    .read_with_attrs = ras_read,
+    .write_with_attrs = ras_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
 /*
  * Unassigned portions of the PPB space are RAZ/WI for privileged
  * accesses, and fault for non-privileged accesses.
@@ -2877,6 +2927,12 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
                                             &s->systick_ns_mem, 1);
     }
 
+    if (cpu_isar_feature(aa32_ras, s->cpu)) {
+        memory_region_init_io(&s->ras_mem, OBJECT(s),
+                              &ras_ops, s, "nvic_ras", 0x1000);
+        memory_region_add_subregion(&s->container, 0x5000, &s->ras_mem);
+    }
+
     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->container);
 }
 
-- 
2.20.1



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

* [PATCH v2 27/28] hw/arm/armv7m: Correct typo in QOM object name
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (25 preceding siblings ...)
  2020-11-19 21:56 ` [PATCH v2 26/28] hw/intc/armv7m_nvic: Implement read/write for RAS register block Peter Maydell
@ 2020-11-19 21:56 ` Peter Maydell
  2020-11-19 22:19   ` Philippe Mathieu-Daudé
  2020-12-01 16:12   ` Richard Henderson
  2020-11-19 21:56 ` [PATCH v2 28/28] target/arm: Implement Cortex-M55 model Peter Maydell
  2020-12-03 12:02 ` [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
  28 siblings, 2 replies; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:56 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Correct a typo in the name we give the NVIC object.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/armv7m.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 944f261dd05..8224d4ade9f 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -136,7 +136,7 @@ static void armv7m_instance_init(Object *obj)
 
     memory_region_init(&s->container, obj, "armv7m-container", UINT64_MAX);
 
-    object_initialize_child(obj, "nvnic", &s->nvic, TYPE_NVIC);
+    object_initialize_child(obj, "nvic", &s->nvic, TYPE_NVIC);
     object_property_add_alias(obj, "num-irq",
                               OBJECT(&s->nvic), "num-irq");
 
-- 
2.20.1



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

* [PATCH v2 28/28] target/arm: Implement Cortex-M55 model
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (26 preceding siblings ...)
  2020-11-19 21:56 ` [PATCH v2 27/28] hw/arm/armv7m: Correct typo in QOM object name Peter Maydell
@ 2020-11-19 21:56 ` Peter Maydell
  2020-12-01 16:24   ` Richard Henderson
  2020-12-03 12:02 ` [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
  28 siblings, 1 reply; 54+ messages in thread
From: Peter Maydell @ 2020-11-19 21:56 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Now that we have implemented all the features needed by the v8.1M
architecture, we can add the model of the Cortex-M55.  This is the
configuration without MVE support; we'll add MVE later.

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

diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
index 0013e25412f..98544db2df3 100644
--- a/target/arm/cpu_tcg.c
+++ b/target/arm/cpu_tcg.c
@@ -401,6 +401,46 @@ static void cortex_m33_initfn(Object *obj)
     cpu->ctr = 0x8000c000;
 }
 
+static void cortex_m55_initfn(Object *obj)
+{
+    ARMCPU *cpu = ARM_CPU(obj);
+
+    set_feature(&cpu->env, ARM_FEATURE_V8);
+    set_feature(&cpu->env, ARM_FEATURE_V8_1M);
+    set_feature(&cpu->env, ARM_FEATURE_M);
+    set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
+    set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
+    set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
+    cpu->midr = 0x410fd221; /* r0p1 */
+    cpu->revidr = 0;
+    cpu->pmsav7_dregion = 16;
+    cpu->sau_sregion = 8;
+    /*
+     * These are the MVFR* values for the FPU, no MVE configuration;
+     * we will update them later when we implement MVE
+     */
+    cpu->isar.mvfr0 = 0x10110221;
+    cpu->isar.mvfr1 = 0x12100011;
+    cpu->isar.mvfr2 = 0x00000040;
+    cpu->isar.id_pfr0 = 0x20000030;
+    cpu->isar.id_pfr1 = 0x00000230;
+    cpu->isar.id_dfr0 = 0x10200000;
+    cpu->id_afr0 = 0x00000000;
+    cpu->isar.id_mmfr0 = 0x00111040;
+    cpu->isar.id_mmfr1 = 0x00000000;
+    cpu->isar.id_mmfr2 = 0x01000000;
+    cpu->isar.id_mmfr3 = 0x00000011;
+    cpu->isar.id_isar0 = 0x01103110;
+    cpu->isar.id_isar1 = 0x02212000;
+    cpu->isar.id_isar2 = 0x20232232;
+    cpu->isar.id_isar3 = 0x01111131;
+    cpu->isar.id_isar4 = 0x01310132;
+    cpu->isar.id_isar5 = 0x00000000;
+    cpu->isar.id_isar6 = 0x00000000;
+    cpu->clidr = 0x00000000; /* caches not implemented */
+    cpu->ctr = 0x8303c003;
+}
+
 static const ARMCPRegInfo cortexr5_cp_reginfo[] = {
     /* Dummy the TCM region regs for the moment */
     { .name = "ATCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
@@ -655,6 +695,8 @@ static const ARMCPUInfo arm_tcg_cpus[] = {
                              .class_init = arm_v7m_class_init },
     { .name = "cortex-m33",  .initfn = cortex_m33_initfn,
                              .class_init = arm_v7m_class_init },
+    { .name = "cortex-m55",  .initfn = cortex_m55_initfn,
+                             .class_init = arm_v7m_class_init },
     { .name = "cortex-r5",   .initfn = cortex_r5_initfn },
     { .name = "cortex-r5f",  .initfn = cortex_r5f_initfn },
     { .name = "ti925t",      .initfn = ti925t_initfn },
-- 
2.20.1



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

* Re: [PATCH v2 12/28] target/arm: Factor out preserve-fp-state from full_vfp_access_check()
  2020-11-19 21:56 ` [PATCH v2 12/28] target/arm: Factor out preserve-fp-state from full_vfp_access_check() Peter Maydell
@ 2020-11-19 22:18   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 54+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-11-19 22:18 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 11/19/20 10:56 PM, Peter Maydell wrote:
> Factor out the code which handles M-profile lazy FP state preservation
> from full_vfp_access_check(); accesses to the FPCXT_NS register are
> a special case which need to do just this part (corresponding in the
> pseudocode to the PreserveFPState() function), and not the full
> set of actions matching the pseudocode ExecuteFPCheck() which
> normal FP instructions need to do.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/translate-vfp.c.inc | 45 ++++++++++++++++++++--------------
>  1 file changed, 27 insertions(+), 18 deletions(-)

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


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

* Re: [PATCH v2 27/28] hw/arm/armv7m: Correct typo in QOM object name
  2020-11-19 21:56 ` [PATCH v2 27/28] hw/arm/armv7m: Correct typo in QOM object name Peter Maydell
@ 2020-11-19 22:19   ` Philippe Mathieu-Daudé
  2020-12-01 16:12   ` Richard Henderson
  1 sibling, 0 replies; 54+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-11-19 22:19 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 11/19/20 10:56 PM, Peter Maydell wrote:
> Correct a typo in the name we give the NVIC object.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/arm/armv7m.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

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


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

* Re: [PATCH v2 07/28] target/arm: Refactor M-profile VMSR/VMRS handling
  2020-11-19 21:55 ` [PATCH v2 07/28] target/arm: Refactor M-profile VMSR/VMRS handling Peter Maydell
@ 2020-12-01 12:54   ` Richard Henderson
  0 siblings, 0 replies; 54+ messages in thread
From: Richard Henderson @ 2020-12-01 12:54 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 11/19/20 3:55 PM, Peter Maydell wrote:
> +/*
> + * Emit code to store the sysreg to its final destination; frees the
> + * TCG temp 'value' it is passed.
> + */
> +typedef void fp_sysreg_storefn(DisasContext *s, void *opaque, TCGv_i32 value);
> +/*
> + * Emit code to load the value to be copied to the sysreg; returns
> + * a new TCG temporary
> + */
> +typedef TCGv_i32 fp_sysreg_loadfn(DisasContext *s, void *opaque);
> +
> +/* Common decode/access checks for fp sysreg read/write */
> +typedef enum fp_sysreg_check_result {
> +    fp_sysreg_check_failed, /* caller should return false */
> +    fp_sysreg_check_done, /* caller should return true */
> +    fp_sysreg_check_continue, /* caller should continue generating code */
> +} fp_sysreg_check_result;

CamelCase?  Otherwise,

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

r~


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

* Re: [PATCH v2 09/28] target/arm: Implement VLDR/VSTR system register
  2020-11-19 21:55 ` [PATCH v2 09/28] target/arm: Implement VLDR/VSTR system register Peter Maydell
@ 2020-12-01 13:11   ` Richard Henderson
  2020-12-03 11:39     ` Peter Maydell
  0 siblings, 1 reply; 54+ messages in thread
From: Richard Henderson @ 2020-12-01 13:11 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 11/19/20 3:55 PM, Peter Maydell wrote:
> +    gen_aa32_st32(s, value, addr, get_mem_index(s));

This is MemA, so should use

  gen_aa32_st_i32(s, value, addr, get_mem_index(s),
                  MO_UL | MO_ALIGN);

a-la my patch set from last week fixing other instances.

> +    gen_aa32_ld32u(s, value, addr, get_mem_index(s));

Similarly.

Otherwise,

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

r~


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

* Re: [PATCH v2 10/28] target/arm: Implement M-profile FPSCR_nzcvqc
  2020-11-19 21:55 ` [PATCH v2 10/28] target/arm: Implement M-profile FPSCR_nzcvqc Peter Maydell
@ 2020-12-01 13:16   ` Richard Henderson
  0 siblings, 0 replies; 54+ messages in thread
From: Richard Henderson @ 2020-12-01 13:16 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 11/19/20 3:55 PM, Peter Maydell wrote:
> v8.1M defines a new FP system register FPSCR_nzcvqc; this behaves
> like the existing FPSCR, except that it reads and writes only bits
> [31:27] of the FPSCR (the N, Z, C, V and QC flag bits).  (Unlike the
> FPSCR, the special case for Rt=15 of writing the CPSR.NZCV is not
> permitted.)
> 
> Implement the register.  Since we don't yet implement MVE, we handle
> the QC bit as RES0, with todo comments for where we will need to add
> support later.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h               | 13 +++++++++++++
>  target/arm/translate-vfp.c.inc | 27 +++++++++++++++++++++++++++
>  2 files changed, 40 insertions(+)

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

r~


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

* Re: [PATCH v2 13/28] target/arm: Implement FPCXT_S fp system register
  2020-11-19 21:56 ` [PATCH v2 13/28] target/arm: Implement FPCXT_S fp system register Peter Maydell
@ 2020-12-01 13:40   ` Richard Henderson
  0 siblings, 0 replies; 54+ messages in thread
From: Richard Henderson @ 2020-12-01 13:40 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 11/19/20 3:56 PM, Peter Maydell wrote:
> Implement the new-in-v8.1M FPCXT_S floating point system register.
> This is for saving and restoring the secure floating point context,
> and it reads and writes bits [27:0] from the FPSCR and the
> CONTROL.SFPA bit in bit [31].
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/translate-vfp.c.inc | 58 ++++++++++++++++++++++++++++++++++
>  1 file changed, 58 insertions(+)

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

r~


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

* Re: [PATCH v2 14/28] target/arm: Implement FPCXT_NS fp system register
  2020-11-19 21:56 ` [PATCH v2 14/28] target/arm: Implement FPCXT_NS " Peter Maydell
@ 2020-12-01 14:05   ` Richard Henderson
  0 siblings, 0 replies; 54+ messages in thread
From: Richard Henderson @ 2020-12-01 14:05 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 11/19/20 3:56 PM, Peter Maydell wrote:
> Implement the v8.1M FPCXT_NS floating-point system register.  This is
> a little more complicated than FPCXT_S, because it has specific
> handling for "current FP state is inactive", and it only wants to do
> PreserveFPState(), not the full set of actions done by
> ExecuteFPCheck() which vfp_access_check() implements.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/translate-vfp.c.inc | 110 ++++++++++++++++++++++++++++++---
>  1 file changed, 103 insertions(+), 7 deletions(-)
> 
> diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
> index ebc59daf613..1c2d31f6f30 100644
> --- a/target/arm/translate-vfp.c.inc
> +++ b/target/arm/translate-vfp.c.inc
> @@ -647,8 +647,20 @@ typedef enum fp_sysreg_check_result {
>      fp_sysreg_check_continue, /* caller should continue generating code */
>  } fp_sysreg_check_result;
>  
> -static fp_sysreg_check_result fp_sysreg_checks(DisasContext *s, int regno)
> +/*
> + * Emit code to check common UNDEF cases and handle lazy state preservation
> + * including the special casing for FPCXT_NS. For reads of sysregs, caller
> + * should provide storefn and opaque; for writes to sysregs these can be NULL.
> + * On return, if *insn_end_label is not NULL the caller needs to gen_set_label()
> + * it at the end of the other code generated for the insn.
> + */
> +static fp_sysreg_check_result fp_sysreg_checks(DisasContext *s, int regno,
> +                                               fp_sysreg_storefn *storefn,
> +                                               void *opaque,
> +                                               TCGLabel **insn_end_label)

I think it is really ugly to bury the fpAccess check in here.

> -    if (!vfp_access_check(s)) {
> -        return fp_sysreg_check_done;

I think it would be better to do

  if (regno != ARM_VFP_FPCXT_NS && !vfp_access_check(s))

and split out

> +        /* fpInactive = FPCCR_NS.ASPEN == 1 && CONTROL.FPCA == 0 */
> +        TCGLabel *fp_active_label = gen_new_label();
> +        TCGv_i32 aspen, fpca;
> +        aspen = load_cpu_field(v7m.fpccr[M_REG_NS]);
> +        fpca = load_cpu_field(v7m.control[M_REG_S]);
> +        tcg_gen_andi_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
> +        tcg_gen_xori_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
> +        tcg_gen_andi_i32(fpca, fpca, R_V7M_CONTROL_FPCA_MASK);
> +        tcg_gen_or_i32(fpca, fpca, aspen);
> +        tcg_gen_brcondi_i32(TCG_COND_NE, fpca, 0, fp_active_label);
> +        tcg_temp_free_i32(aspen);
> +        tcg_temp_free_i32(fpca);
> +
> +        /* fpInactive case: FPCXT_NS reads as FPDSCR_NS, write is NOP */
> +        if (storefn) {
> +            TCGv_i32 tmp = load_cpu_field(v7m.fpdscr[M_REG_NS]);
> +            storefn(s, opaque, tmp);
> +        }
> +        /* jump to end of insn */
> +        *insn_end_label = gen_new_label();
> +        tcg_gen_br(*insn_end_label);
> +
> +        gen_set_label(fp_active_label);
> +        /* !fpInactive: PreserveFPState() and handle register as normal */
> +        gen_preserve_fp_state(s);

... all of this to a separate function.

Then VLDR becomes

   case ARM_VFP_FPCXT_NS:
        lab_inactive = gen_new_label();
        gen_branch_fpInactive(s, TCG_COND_NE, lab_inactive);
        ...
        gen_set_label(lab_inactive);
        gen_lookup_tb();
        break;

and VSTR becomes

   case ARM_VFP_FPCXT_NS:
       lab_end = gen_new_label();
       lab_active = gen_new_label();
       gen_branch_fpInactive(s, TCG_COND_EQ, lab_active);
       ...
       tcg_gen_br(lab_end);
       gen_set_label(lab_active);
       /* fall through */
   case ARM_VFP_FPCXT_S:
       ...
   }
   if (lab_end) {
       gen_set_label(lab_end);
   }


r~


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

* Re: [PATCH v2 15/28] hw/intc/armv7m_nvic: Update FPDSCR masking for v8.1M
  2020-11-19 21:56 ` [PATCH v2 15/28] hw/intc/armv7m_nvic: Update FPDSCR masking for v8.1M Peter Maydell
@ 2020-12-01 14:28   ` Richard Henderson
  0 siblings, 0 replies; 54+ messages in thread
From: Richard Henderson @ 2020-12-01 14:28 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 11/19/20 3:56 PM, Peter Maydell wrote:
> The FPDSCR register has a similar layout to the FPSCR.  In v8.1M it
> gains new fields FZ16 (if half-precision floating point is supported)
> and LTPSIZE (always reads as 4).  Update the reset value and the code
> that handles writes to this register accordingly.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h      | 5 +++++
>  hw/intc/armv7m_nvic.c | 9 ++++++++-
>  target/arm/cpu.c      | 3 +++
>  3 files changed, 16 insertions(+), 1 deletion(-)

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

r~



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

* Re: [PATCH v2 16/28] target/arm: For v8.1M, always clear R0-R3, R12,  APSR, EPSR on exception entry
  2020-11-19 21:56 ` [PATCH v2 16/28] target/arm: For v8.1M, always clear R0-R3, R12, APSR, EPSR on exception entry Peter Maydell
@ 2020-12-01 14:33   ` Richard Henderson
  0 siblings, 0 replies; 54+ messages in thread
From: Richard Henderson @ 2020-12-01 14:33 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 11/19/20 3:56 PM, Peter Maydell wrote:
> In v8.0M, on exception entry the registers R0-R3, R12, APSR and EPSR
> are zeroed for an exception taken to Non-secure state; for an
> exception taken to Secure state they become UNKNOWN, and we chose to
> leave them at their previous values.
> 
> In v8.1M the behaviour is specified more tightly and these registers
> are always zeroed regardless of the security state that the exception
> targets (see rule R_KPZV).  Implement this.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/m_helper.c | 16 ++++++++++++----
>  1 file changed, 12 insertions(+), 4 deletions(-)

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

r~



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

* Re: [PATCH v2 17/28] target/arm: In v8.1M, don't set HFSR.FORCED on vector table fetch failures
  2020-11-19 21:56 ` [PATCH v2 17/28] target/arm: In v8.1M, don't set HFSR.FORCED on vector table fetch failures Peter Maydell
@ 2020-12-01 14:41   ` Richard Henderson
  0 siblings, 0 replies; 54+ messages in thread
From: Richard Henderson @ 2020-12-01 14:41 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 11/19/20 3:56 PM, Peter Maydell wrote:
> In v8.1M, vector table fetch failures don't set HFSR.FORCED (see rule
> R_LLRP).  (In previous versions of the architecture this was either
> required or IMPDEF.)
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/m_helper.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)

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

r~



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

* Re: [PATCH v2 18/28] target/arm: Implement v8.1M REVIDR register
  2020-11-19 21:56 ` [PATCH v2 18/28] target/arm: Implement v8.1M REVIDR register Peter Maydell
@ 2020-12-01 14:43   ` Richard Henderson
  0 siblings, 0 replies; 54+ messages in thread
From: Richard Henderson @ 2020-12-01 14:43 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 11/19/20 3:56 PM, Peter Maydell wrote:
> In v8.1M a REVIDR register is defined, which is at address 0xe00ecfc
> and is a read-only IMPDEF register providing implementation specific
> minor revision information, like the v8A REVIDR_EL1. Implement this.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/intc/armv7m_nvic.c | 5 +++++
>  1 file changed, 5 insertions(+)

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

r~



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

* Re: [PATCH v2 19/28] target/arm: Implement new v8.1M NOCP check for exception return
  2020-11-19 21:56 ` [PATCH v2 19/28] target/arm: Implement new v8.1M NOCP check for exception return Peter Maydell
@ 2020-12-01 14:49   ` Richard Henderson
  0 siblings, 0 replies; 54+ messages in thread
From: Richard Henderson @ 2020-12-01 14:49 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 11/19/20 3:56 PM, Peter Maydell wrote:
> In v8.1M a new exception return check is added which may cause a NOCP
> UsageFault (see rule R_XLTP): before we clear s0..s15 and the FPSCR
> we must check whether access to CP10 from the Security state of the
> returning exception is disabled; if it is then we must take a fault.
> 
> (Note that for our implementation CPPWR is always RAZ/WI and so can
> never cause CP10 accesses to fail.)
> 
> The other v8.1M change to this register-clearing code is that if MVE
> is implemented VPR must also be cleared, so add a TODO comment to
> that effect.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/m_helper.c | 22 +++++++++++++++++++++-
>  1 file changed, 21 insertions(+), 1 deletion(-)

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

r~



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

* Re: [PATCH v2 20/28] target/arm: Implement new v8.1M VLLDM and VLSTM encodings
  2020-11-19 21:56 ` [PATCH v2 20/28] target/arm: Implement new v8.1M VLLDM and VLSTM encodings Peter Maydell
@ 2020-12-01 15:09   ` Richard Henderson
  0 siblings, 0 replies; 54+ messages in thread
From: Richard Henderson @ 2020-12-01 15:09 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 11/19/20 3:56 PM, Peter Maydell wrote:
> v8.1M adds new encodings of VLLDM and VLSTM (where bit 7 is set).
> The only difference is that:
>  * the old T1 encodings UNDEF if the implementation implements 32
>    Dregs (this is currently architecturally impossible for M-profile)
>  * the new T2 encodings have the implementation-defined option to
>    read from memory (discarding the data) or write UNKNOWN values to
>    memory for the stack slots that would be D16-D31
> 
> We choose not to make those accesses, so for us the two
> instructions behave identically assuming they don't UNDEF.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/m-nocp.decode       |  2 +-
>  target/arm/translate-vfp.c.inc | 25 +++++++++++++++++++++++++
>  2 files changed, 26 insertions(+), 1 deletion(-)

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

r~



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

* Re: [PATCH v2 21/28] hw/intc/armv7m_nvic: Correct handling of CCR.BFHFNMIGN
  2020-11-19 21:56 ` [PATCH v2 21/28] hw/intc/armv7m_nvic: Correct handling of CCR.BFHFNMIGN Peter Maydell
@ 2020-12-01 15:16   ` Richard Henderson
  2020-12-01 15:22     ` Peter Maydell
  0 siblings, 1 reply; 54+ messages in thread
From: Richard Henderson @ 2020-12-01 15:16 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 11/19/20 3:56 PM, Peter Maydell wrote:
> +        } else {
> +            /* BFHFNMIGN is RAZ/WI from NS if AIRCR.BFHFNMINS is 0 */
> +            if (!(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
> +                value &= ~R_V7M_CCR_BFHFNMIGN_MASK;
> +            }

This isn't WI, as you're zeroing the bit not preserving it.
I think you need to merge the current state of the bit to preserve the value
for secure state.


r~


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

* Re: [PATCH v2 22/28] hw/intc/armv7m_nvic: Support v8.1M CCR.TRD bit
  2020-11-19 21:56 ` [PATCH v2 22/28] hw/intc/armv7m_nvic: Support v8.1M CCR.TRD bit Peter Maydell
@ 2020-12-01 15:19   ` Richard Henderson
  0 siblings, 0 replies; 54+ messages in thread
From: Richard Henderson @ 2020-12-01 15:19 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 11/19/20 3:56 PM, Peter Maydell wrote:
> v8.1M introduces a new TRD flag in the CCR register, which enables
> checking for stack frame integrity signatures on SG instructions.
> This bit is not banked, and is always RAZ/WI to Non-secure code.
> Adjust the code for handling CCR reads and writes to handle this.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h      |  2 ++
>  hw/intc/armv7m_nvic.c | 26 ++++++++++++++++++--------
>  2 files changed, 20 insertions(+), 8 deletions(-)


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

r~


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

* Re: [PATCH v2 21/28] hw/intc/armv7m_nvic: Correct handling of CCR.BFHFNMIGN
  2020-12-01 15:16   ` Richard Henderson
@ 2020-12-01 15:22     ` Peter Maydell
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Maydell @ 2020-12-01 15:22 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, QEMU Developers

On Tue, 1 Dec 2020 at 15:16, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> On 11/19/20 3:56 PM, Peter Maydell wrote:
> > +        } else {
> > +            /* BFHFNMIGN is RAZ/WI from NS if AIRCR.BFHFNMINS is 0 */
> > +            if (!(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
> > +                value &= ~R_V7M_CCR_BFHFNMIGN_MASK;
> > +            }
>
> This isn't WI, as you're zeroing the bit not preserving it.
> I think you need to merge the current state of the bit to preserve the value
> for secure state.

Oops, yes.

thanks
-- PMM


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

* Re: [PATCH v2 23/28] target/arm: Implement CCR_S.TRD behaviour for SG insns
  2020-11-19 21:56 ` [PATCH v2 23/28] target/arm: Implement CCR_S.TRD behaviour for SG insns Peter Maydell
@ 2020-12-01 15:53   ` Richard Henderson
  0 siblings, 0 replies; 54+ messages in thread
From: Richard Henderson @ 2020-12-01 15:53 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 11/19/20 3:56 PM, Peter Maydell wrote:
> v8.1M introduces a new TRD flag in the CCR register, which enables
> checking for stack frame integrity signatures on SG instructions.
> Add the code in the SG insn implementation for the new behaviour.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/m_helper.c | 86 +++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 86 insertions(+)

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

r~




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

* Re: [PATCH v2 24/28] hw/intc/armv7m_nvic: Fix "return from inactive handler" check
  2020-11-19 21:56 ` [PATCH v2 24/28] hw/intc/armv7m_nvic: Fix "return from inactive handler" check Peter Maydell
@ 2020-12-01 15:58   ` Richard Henderson
  0 siblings, 0 replies; 54+ messages in thread
From: Richard Henderson @ 2020-12-01 15:58 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 11/19/20 3:56 PM, Peter Maydell wrote:
> In commit 077d7449100d824a4 we added code to handle the v8M
> requirement that returns from NMI or HardFault forcibly deactivate
> those exceptions regardless of what interrupt the guest is trying to
> deactivate.  Unfortunately this broke the handling of the "illegal
> exception return because the returning exception number is not
> active" check for those cases.  In the pseudocode this test is done
> on the exception the guest asks to return from, but because our
> implementation was doing this in armv7m_nvic_complete_irq() after the
> new "deactivate NMI/HardFault regardless" code we ended up doing the
> test on the VecInfo for that exception instead, which usually meant
> failing to raise the illegal exception return fault.
> 
> In the case for "configurable exception targeting the opposite
> security state" we detected the illegal-return case but went ahead
> and deactivated the VecInfo anyway, which is wrong because that is
> the VecInfo for the other security state.
> 
> Rearrange the code so that we first identify the illegal return
> cases, then see if we really need to deactivate NMI or HardFault
> instead, and finally do the deactivation.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/intc/armv7m_nvic.c | 59 +++++++++++++++++++++++--------------------
>  1 file changed, 32 insertions(+), 27 deletions(-)

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

r~




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

* Re: [PATCH v2 25/28] target/arm: Implement M-profile "minimal RAS implementation"
  2020-11-19 21:56 ` [PATCH v2 25/28] target/arm: Implement M-profile "minimal RAS implementation" Peter Maydell
@ 2020-12-01 16:04   ` Richard Henderson
  0 siblings, 0 replies; 54+ messages in thread
From: Richard Henderson @ 2020-12-01 16:04 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 11/19/20 3:56 PM, Peter Maydell wrote:
> For v8.1M the architecture mandates that CPUs must provide at
> least the "minimal RAS implementation" from the Reliability,
> Availability and Serviceability extension. This consists of:
>  * an ESB instruction which is a NOP
>    -- since it is in the HINT space we need only add a comment
>  * an RFSR register which will RAZ/WI
>  * a RAZ/WI AIRCR.IESB bit
>    -- the code which handles writes to AIRCR does not allow setting
>       of RES0 bits, so we already treat this as RAZ/WI; add a comment
>       noting that this is deliberate
>  * minimal implementation of the RAS register block at 0xe0005000
>    -- this will be in a subsequent commit
>  * setting the ID_PFR0.RAS field to 0b0010
>    -- we will do this when we add the Cortex-M55 CPU model
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h      | 14 ++++++++++++++
>  target/arm/t32.decode |  4 ++++
>  hw/intc/armv7m_nvic.c | 13 +++++++++++++
>  3 files changed, 31 insertions(+)

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

r~




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

* Re: [PATCH v2 26/28] hw/intc/armv7m_nvic: Implement read/write for RAS register block
  2020-11-19 21:56 ` [PATCH v2 26/28] hw/intc/armv7m_nvic: Implement read/write for RAS register block Peter Maydell
@ 2020-12-01 16:11   ` Richard Henderson
  0 siblings, 0 replies; 54+ messages in thread
From: Richard Henderson @ 2020-12-01 16:11 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 11/19/20 3:56 PM, Peter Maydell wrote:
> The RAS feature has a block of memory-mapped registers at offset
> 0x5000 within the PPB.  For a "minimal RAS" implementation we provide
> no error records and so the only registers that exist in the block
> are ERRIIDR and ERRDEVID.
> 
> The "RAZ/WI for privileged, BusFault for nonprivileged" behaviour
> of the "nvic-default" region is actually valid for minimal-RAS,
> so the main benefit of providing an explicit implementation of
> the register block is more accurate LOG_UNIMP messages, and a
> framework for where we could add a real RAS implementation later
> if necessary.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  include/hw/intc/armv7m_nvic.h |  1 +
>  hw/intc/armv7m_nvic.c         | 56 +++++++++++++++++++++++++++++++++++
>  2 files changed, 57 insertions(+)

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

r~


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

* Re: [PATCH v2 27/28] hw/arm/armv7m: Correct typo in QOM object name
  2020-11-19 21:56 ` [PATCH v2 27/28] hw/arm/armv7m: Correct typo in QOM object name Peter Maydell
  2020-11-19 22:19   ` Philippe Mathieu-Daudé
@ 2020-12-01 16:12   ` Richard Henderson
  1 sibling, 0 replies; 54+ messages in thread
From: Richard Henderson @ 2020-12-01 16:12 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 11/19/20 3:56 PM, Peter Maydell wrote:
> Correct a typo in the name we give the NVIC object.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/arm/armv7m.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

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

r~


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

* Re: [PATCH v2 28/28] target/arm: Implement Cortex-M55 model
  2020-11-19 21:56 ` [PATCH v2 28/28] target/arm: Implement Cortex-M55 model Peter Maydell
@ 2020-12-01 16:24   ` Richard Henderson
  0 siblings, 0 replies; 54+ messages in thread
From: Richard Henderson @ 2020-12-01 16:24 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 11/19/20 3:56 PM, Peter Maydell wrote:
> Now that we have implemented all the features needed by the v8.1M
> architecture, we can add the model of the Cortex-M55.  This is the
> configuration without MVE support; we'll add MVE later.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu_tcg.c | 42 ++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 42 insertions(+)

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

r~


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

* Re: [PATCH v2 09/28] target/arm: Implement VLDR/VSTR system register
  2020-12-01 13:11   ` Richard Henderson
@ 2020-12-03 11:39     ` Peter Maydell
  2020-12-03 16:14       ` Richard Henderson
  0 siblings, 1 reply; 54+ messages in thread
From: Peter Maydell @ 2020-12-03 11:39 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, QEMU Developers

On Tue, 1 Dec 2020 at 13:11, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> On 11/19/20 3:55 PM, Peter Maydell wrote:
> > +    gen_aa32_st32(s, value, addr, get_mem_index(s));
>
> This is MemA, so should use
>
>   gen_aa32_st_i32(s, value, addr, get_mem_index(s),
>                   MO_UL | MO_ALIGN);
>
> a-la my patch set from last week fixing other instances.

Also " | s->be_data", right ?

thanks
-- PMM


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

* Re: [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55
  2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
                   ` (27 preceding siblings ...)
  2020-11-19 21:56 ` [PATCH v2 28/28] target/arm: Implement Cortex-M55 model Peter Maydell
@ 2020-12-03 12:02 ` Peter Maydell
  28 siblings, 0 replies; 54+ messages in thread
From: Peter Maydell @ 2020-12-03 12:02 UTC (permalink / raw)
  To: qemu-arm, QEMU Developers

On Thu, 19 Nov 2020 at 21:56, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> This is a v2 because it's a respin of "target/arm: More v8.1M
> features".  The bad news is it's nearly doubled in length.  The good
> news is that this is because the new patches on the end are enough to
> implement all the remaining missing v8.1M specifics to the point
> where we can provide a Cortex-M55 CPU.  (There is as yet no board
> model that uses the Cortex-M55, though; that's next on my todo list.)

I'm going to take all of this series into target-arm.next except:

>   target/arm: Implement FPCXT_NS fp system register
>   hw/intc/armv7m_nvic: Correct handling of CCR.BFHFNMIGN
>   target/arm: Implement Cortex-M55 model

(since the first two need a v2 and we don't want to enable the
CPU until all the pieces are there).

thanks
-- PMM


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

* Re: [PATCH v2 09/28] target/arm: Implement VLDR/VSTR system register
  2020-12-03 11:39     ` Peter Maydell
@ 2020-12-03 16:14       ` Richard Henderson
  0 siblings, 0 replies; 54+ messages in thread
From: Richard Henderson @ 2020-12-03 16:14 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-arm, QEMU Developers

On 12/3/20 5:39 AM, Peter Maydell wrote:
> On Tue, 1 Dec 2020 at 13:11, Richard Henderson
> <richard.henderson@linaro.org> wrote:
>>
>> On 11/19/20 3:55 PM, Peter Maydell wrote:
>>> +    gen_aa32_st32(s, value, addr, get_mem_index(s));
>>
>> This is MemA, so should use
>>
>>   gen_aa32_st_i32(s, value, addr, get_mem_index(s),
>>                   MO_UL | MO_ALIGN);
>>
>> a-la my patch set from last week fixing other instances.
> 
> Also " | s->be_data", right ?

Ho hum, yes.  I saw your comment on this in the alignment patch set and I'll
think about A Better Way.


r~



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

end of thread, other threads:[~2020-12-03 16:17 UTC | newest]

Thread overview: 54+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-19 21:55 [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell
2020-11-19 21:55 ` [PATCH v2 01/28] hw/intc/armv7m_nvic: Make all of system PPB range be RAZWI/BusFault Peter Maydell
2020-11-19 21:55 ` [PATCH v2 02/28] target/arm: Implement v8.1M PXN extension Peter Maydell
2020-11-19 21:55 ` [PATCH v2 03/28] target/arm: Don't clobber ID_PFR1.Security on M-profile cores Peter Maydell
2020-11-19 21:55 ` [PATCH v2 04/28] target/arm: Implement VSCCLRM insn Peter Maydell
2020-11-19 21:55 ` [PATCH v2 05/28] target/arm: Implement CLRM instruction Peter Maydell
2020-11-19 21:55 ` [PATCH v2 06/28] target/arm: Enforce M-profile VMRS/VMSR register restrictions Peter Maydell
2020-11-19 21:55 ` [PATCH v2 07/28] target/arm: Refactor M-profile VMSR/VMRS handling Peter Maydell
2020-12-01 12:54   ` Richard Henderson
2020-11-19 21:55 ` [PATCH v2 08/28] target/arm: Move general-use constant expanders up in translate.c Peter Maydell
2020-11-19 21:55 ` [PATCH v2 09/28] target/arm: Implement VLDR/VSTR system register Peter Maydell
2020-12-01 13:11   ` Richard Henderson
2020-12-03 11:39     ` Peter Maydell
2020-12-03 16:14       ` Richard Henderson
2020-11-19 21:55 ` [PATCH v2 10/28] target/arm: Implement M-profile FPSCR_nzcvqc Peter Maydell
2020-12-01 13:16   ` Richard Henderson
2020-11-19 21:56 ` [PATCH v2 11/28] target/arm: Use new FPCR_NZCV_MASK constant Peter Maydell
2020-11-19 21:56 ` [PATCH v2 12/28] target/arm: Factor out preserve-fp-state from full_vfp_access_check() Peter Maydell
2020-11-19 22:18   ` Philippe Mathieu-Daudé
2020-11-19 21:56 ` [PATCH v2 13/28] target/arm: Implement FPCXT_S fp system register Peter Maydell
2020-12-01 13:40   ` Richard Henderson
2020-11-19 21:56 ` [PATCH v2 14/28] target/arm: Implement FPCXT_NS " Peter Maydell
2020-12-01 14:05   ` Richard Henderson
2020-11-19 21:56 ` [PATCH v2 15/28] hw/intc/armv7m_nvic: Update FPDSCR masking for v8.1M Peter Maydell
2020-12-01 14:28   ` Richard Henderson
2020-11-19 21:56 ` [PATCH v2 16/28] target/arm: For v8.1M, always clear R0-R3, R12, APSR, EPSR on exception entry Peter Maydell
2020-12-01 14:33   ` Richard Henderson
2020-11-19 21:56 ` [PATCH v2 17/28] target/arm: In v8.1M, don't set HFSR.FORCED on vector table fetch failures Peter Maydell
2020-12-01 14:41   ` Richard Henderson
2020-11-19 21:56 ` [PATCH v2 18/28] target/arm: Implement v8.1M REVIDR register Peter Maydell
2020-12-01 14:43   ` Richard Henderson
2020-11-19 21:56 ` [PATCH v2 19/28] target/arm: Implement new v8.1M NOCP check for exception return Peter Maydell
2020-12-01 14:49   ` Richard Henderson
2020-11-19 21:56 ` [PATCH v2 20/28] target/arm: Implement new v8.1M VLLDM and VLSTM encodings Peter Maydell
2020-12-01 15:09   ` Richard Henderson
2020-11-19 21:56 ` [PATCH v2 21/28] hw/intc/armv7m_nvic: Correct handling of CCR.BFHFNMIGN Peter Maydell
2020-12-01 15:16   ` Richard Henderson
2020-12-01 15:22     ` Peter Maydell
2020-11-19 21:56 ` [PATCH v2 22/28] hw/intc/armv7m_nvic: Support v8.1M CCR.TRD bit Peter Maydell
2020-12-01 15:19   ` Richard Henderson
2020-11-19 21:56 ` [PATCH v2 23/28] target/arm: Implement CCR_S.TRD behaviour for SG insns Peter Maydell
2020-12-01 15:53   ` Richard Henderson
2020-11-19 21:56 ` [PATCH v2 24/28] hw/intc/armv7m_nvic: Fix "return from inactive handler" check Peter Maydell
2020-12-01 15:58   ` Richard Henderson
2020-11-19 21:56 ` [PATCH v2 25/28] target/arm: Implement M-profile "minimal RAS implementation" Peter Maydell
2020-12-01 16:04   ` Richard Henderson
2020-11-19 21:56 ` [PATCH v2 26/28] hw/intc/armv7m_nvic: Implement read/write for RAS register block Peter Maydell
2020-12-01 16:11   ` Richard Henderson
2020-11-19 21:56 ` [PATCH v2 27/28] hw/arm/armv7m: Correct typo in QOM object name Peter Maydell
2020-11-19 22:19   ` Philippe Mathieu-Daudé
2020-12-01 16:12   ` Richard Henderson
2020-11-19 21:56 ` [PATCH v2 28/28] target/arm: Implement Cortex-M55 model Peter Maydell
2020-12-01 16:24   ` Richard Henderson
2020-12-03 12:02 ` [PATCH v2 00/28] target/arm: Implement v8.1M and Cortex-M55 Peter Maydell

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.