All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI
@ 2018-08-20 14:10 Peter Maydell
  2018-08-20 14:10 ` [Qemu-devel] [PATCH 01/22] hw/misc/mps2-fpgaio: Implement 1Hz and 100Hz counters Peter Maydell
                   ` (21 more replies)
  0 siblings, 22 replies; 56+ messages in thread
From: Peter Maydell @ 2018-08-20 14:10 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Philippe Mathieu-Daudé

This patchset is a combination of the remaining patches
from the v1 patchsets
 * mps2: Implement FPGAIO counters and dual-timer
 * arm: Implement MPS2 watchdogs and DMA

plus some new patches which clean up the PL022 and
instantiate it in the MPS2, and one final patch to fix
some SCC config register values.

Patches which need review:
1, 3, 4, 5, 8, 9, 10, 11, 15-22
(2, 6, 7, 12, 13, 14 have been reviewed already in v1)

Changes since v1:
 * some patches that were reviewed have been upstreamed
 * I have split the sysinfo registers out of "iotkit-sysctl"
   and into their own "iotkit-sysinfo" devices
 * patches 15-22 are new

These are all the enhancements I plan to make to the MPS2
boards. I won't be doing anything more except in response to
bug reports.

thanks
-- PMM

Peter Maydell (22):
  hw/misc/mps2-fpgaio: Implement 1Hz and 100Hz counters
  hw/misc/mps2-fpgaio: Implement PSCNTR and COUNTER
  hw/timer/cmsdk-apb-dualtimer: Implement CMSDK dual timer module
  hw/arm/iotkit: Wire up the dualtimer
  hw/arm/mps2: Wire up dual-timer in mps2-an385 and mps2-an511
  hw/arm/iotkit: Wire up the watchdogs
  hw/arm/iotkit: Wire up the S32KTIMER
  hw/misc/iotkit-sysctl: Implement IoTKit system control element
  hw/misc/iotkit-sysinfo: Implement IoTKit system information block
  hw/misc/iotkit: Wire up the sysctl and sysinfo register blocks
  hw/misc/tz-msc: Model TrustZone Master Security Controller
  hw/misc/iotkit-secctl: Wire up registers for controlling MSCs
  hw/arm/iotkit: Wire up the lines for MSCs
  hw/arm/mps2-tz: Create PL081s and MSCs
  hw/ssi/pl022: Allow use as embedded-struct device
  hw/ssi/pl022: Set up reset function in class init
  hw/ssi/pl022: Don't directly call vmstate_register()
  hw/ssi/pl022: Use DeviceState::realize rather than SysBusDevice::init
  hw/ssi/pl022: Correct wrong value for PL022_INT_RT
  hw/ssi/pl022: Correct wrong DMACR and ICR handling
  hw/arm/mps2-tz: Instantiate SPI controllers
  hw/arm/mps2-tz: Fix MPS2 SCC config register values

 hw/misc/Makefile.objs                  |   3 +
 hw/timer/Makefile.objs                 |   1 +
 include/hw/arm/iotkit.h                |  25 +-
 include/hw/misc/iotkit-secctl.h        |  14 +
 include/hw/misc/iotkit-sysctl.h        |  49 +++
 include/hw/misc/iotkit-sysinfo.h       |  37 ++
 include/hw/misc/mps2-fpgaio.h          |  10 +
 include/hw/misc/tz-msc.h               |  79 ++++
 include/hw/ssi/pl022.h                 |  51 +++
 include/hw/timer/cmsdk-apb-dualtimer.h |  72 ++++
 hw/arm/iotkit.c                        | 114 +++++-
 hw/arm/mps2-tz.c                       | 142 ++++++-
 hw/arm/mps2.c                          |  11 +
 hw/misc/iotkit-secctl.c                |  73 +++-
 hw/misc/iotkit-sysctl.c                | 261 +++++++++++++
 hw/misc/iotkit-sysinfo.c               | 128 ++++++
 hw/misc/mps2-fpgaio.c                  | 146 ++++++-
 hw/misc/tz-msc.c                       | 308 +++++++++++++++
 hw/ssi/pl022.c                         |  57 +--
 hw/timer/cmsdk-apb-dualtimer.c         | 515 +++++++++++++++++++++++++
 MAINTAINERS                            |  10 +
 default-configs/arm-softmmu.mak        |   4 +
 hw/misc/trace-events                   |  16 +
 hw/timer/trace-events                  |   5 +
 24 files changed, 2049 insertions(+), 82 deletions(-)
 create mode 100644 include/hw/misc/iotkit-sysctl.h
 create mode 100644 include/hw/misc/iotkit-sysinfo.h
 create mode 100644 include/hw/misc/tz-msc.h
 create mode 100644 include/hw/ssi/pl022.h
 create mode 100644 include/hw/timer/cmsdk-apb-dualtimer.h
 create mode 100644 hw/misc/iotkit-sysctl.c
 create mode 100644 hw/misc/iotkit-sysinfo.c
 create mode 100644 hw/misc/tz-msc.c
 create mode 100644 hw/timer/cmsdk-apb-dualtimer.c

-- 
2.18.0

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

* [Qemu-devel] [PATCH 01/22] hw/misc/mps2-fpgaio: Implement 1Hz and 100Hz counters
  2018-08-20 14:10 [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI Peter Maydell
@ 2018-08-20 14:10 ` Peter Maydell
  2018-08-21 18:34   ` Richard Henderson
  2018-08-20 14:10 ` [Qemu-devel] [PATCH 02/22] hw/misc/mps2-fpgaio: Implement PSCNTR and COUNTER Peter Maydell
                   ` (20 subsequent siblings)
  21 siblings, 1 reply; 56+ messages in thread
From: Peter Maydell @ 2018-08-20 14:10 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Philippe Mathieu-Daudé

The MPS2 FPGAIO block includes some simple free-running counters.
Implement these.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/misc/mps2-fpgaio.h |  4 +++
 hw/misc/mps2-fpgaio.c         | 53 ++++++++++++++++++++++++++++++++++-
 2 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
index eedf17ebc6d..ec057d38c76 100644
--- a/include/hw/misc/mps2-fpgaio.h
+++ b/include/hw/misc/mps2-fpgaio.h
@@ -38,6 +38,10 @@ typedef struct {
     uint32_t misc;
 
     uint32_t prescale_clk;
+
+    /* These hold the CLOCK_VIRTUAL ns tick when the CLK1HZ/CLK100HZ was zero */
+    int64_t clk1hz_tick_offset;
+    int64_t clk100hz_tick_offset;
 } MPS2FPGAIO;
 
 #endif
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
index 7394a057d82..bbc28f641f0 100644
--- a/hw/misc/mps2-fpgaio.c
+++ b/hw/misc/mps2-fpgaio.c
@@ -22,6 +22,7 @@
 #include "hw/sysbus.h"
 #include "hw/registerfields.h"
 #include "hw/misc/mps2-fpgaio.h"
+#include "qemu/timer.h"
 
 REG32(LED0, 0)
 REG32(BUTTON, 8)
@@ -32,10 +33,21 @@ REG32(PRESCALE, 0x1c)
 REG32(PSCNTR, 0x20)
 REG32(MISC, 0x4c)
 
+static uint32_t counter_from_tickoff(int64_t now, int64_t tick_offset, int frq)
+{
+    return muldiv64(now - tick_offset, frq, NANOSECONDS_PER_SECOND);
+}
+
+static int64_t tickoff_from_counter(int64_t now, uint32_t count, int frq)
+{
+    return now - muldiv64(count, NANOSECONDS_PER_SECOND, frq);
+}
+
 static uint64_t mps2_fpgaio_read(void *opaque, hwaddr offset, unsigned size)
 {
     MPS2FPGAIO *s = MPS2_FPGAIO(opaque);
     uint64_t r;
+    int64_t now;
 
     switch (offset) {
     case A_LED0:
@@ -54,10 +66,15 @@ static uint64_t mps2_fpgaio_read(void *opaque, hwaddr offset, unsigned size)
         r = s->misc;
         break;
     case A_CLK1HZ:
+        now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+        r = counter_from_tickoff(now, s->clk1hz_tick_offset, 1);
+        break;
     case A_CLK100HZ:
+        now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+        r = counter_from_tickoff(now, s->clk100hz_tick_offset, 100);
+        break;
     case A_COUNTER:
     case A_PSCNTR:
-        /* These are all upcounters of various frequencies. */
         qemu_log_mask(LOG_UNIMP, "MPS2 FPGAIO: counters unimplemented\n");
         r = 0;
         break;
@@ -76,6 +93,7 @@ static void mps2_fpgaio_write(void *opaque, hwaddr offset, uint64_t value,
                               unsigned size)
 {
     MPS2FPGAIO *s = MPS2_FPGAIO(opaque);
+    int64_t now;
 
     trace_mps2_fpgaio_write(offset, value, size);
 
@@ -100,6 +118,14 @@ static void mps2_fpgaio_write(void *opaque, hwaddr offset, uint64_t value,
                       "MPS2 FPGAIO: MISC control bits unimplemented\n");
         s->misc = value;
         break;
+    case A_CLK1HZ:
+        now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+        s->clk1hz_tick_offset = tickoff_from_counter(now, value, 1);
+        break;
+    case A_CLK100HZ:
+        now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+        s->clk100hz_tick_offset = tickoff_from_counter(now, value, 100);
+        break;
     default:
         qemu_log_mask(LOG_GUEST_ERROR,
                       "MPS2 FPGAIO write: bad offset 0x%x\n", (int) offset);
@@ -116,11 +142,14 @@ static const MemoryRegionOps mps2_fpgaio_ops = {
 static void mps2_fpgaio_reset(DeviceState *dev)
 {
     MPS2FPGAIO *s = MPS2_FPGAIO(dev);
+    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
     trace_mps2_fpgaio_reset();
     s->led0 = 0;
     s->prescale = 0;
     s->misc = 0;
+    s->clk1hz_tick_offset = tickoff_from_counter(now, 0, 1);
+    s->clk100hz_tick_offset = tickoff_from_counter(now, 0, 100);
 }
 
 static void mps2_fpgaio_init(Object *obj)
@@ -133,6 +162,24 @@ static void mps2_fpgaio_init(Object *obj)
     sysbus_init_mmio(sbd, &s->iomem);
 }
 
+static bool mps2_fpgaio_counters_needed(void *opaque)
+{
+    /* Currently vmstate.c insists all subsections have a 'needed' function */
+    return true;
+}
+
+static const VMStateDescription mps2_fpgaio_counters_vmstate = {
+    .name = "mps2-fpgaio/counters",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = mps2_fpgaio_counters_needed,
+    .fields = (VMStateField[]) {
+        VMSTATE_INT64(clk1hz_tick_offset, MPS2FPGAIO),
+        VMSTATE_INT64(clk100hz_tick_offset, MPS2FPGAIO),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static const VMStateDescription mps2_fpgaio_vmstate = {
     .name = "mps2-fpgaio",
     .version_id = 1,
@@ -142,6 +189,10 @@ static const VMStateDescription mps2_fpgaio_vmstate = {
         VMSTATE_UINT32(prescale, MPS2FPGAIO),
         VMSTATE_UINT32(misc, MPS2FPGAIO),
         VMSTATE_END_OF_LIST()
+    },
+    .subsections = (const VMStateDescription*[]) {
+        &mps2_fpgaio_counters_vmstate,
+        NULL
     }
 };
 
-- 
2.18.0

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

* [Qemu-devel] [PATCH 02/22] hw/misc/mps2-fpgaio: Implement PSCNTR and COUNTER
  2018-08-20 14:10 [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI Peter Maydell
  2018-08-20 14:10 ` [Qemu-devel] [PATCH 01/22] hw/misc/mps2-fpgaio: Implement 1Hz and 100Hz counters Peter Maydell
@ 2018-08-20 14:10 ` Peter Maydell
  2018-08-23 13:31   ` Richard Henderson
  2018-08-20 14:10 ` [Qemu-devel] [PATCH 03/22] hw/timer/cmsdk-apb-dualtimer: Implement CMSDK dual timer module Peter Maydell
                   ` (19 subsequent siblings)
  21 siblings, 1 reply; 56+ messages in thread
From: Peter Maydell @ 2018-08-20 14:10 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Philippe Mathieu-Daudé

In the MPS2 FPGAIO, PSCNTR is a free-running downcounter with
a reload value configured via the PRESCALE register, and
COUNTER counts up by 1 every time PSCNTR reaches zero.
Implement these counters.

We can just increment the counters migration subsection's
version ID because we only added it in the previous commit,
so no released QEMU versions will be using it.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 include/hw/misc/mps2-fpgaio.h |  6 +++
 hw/misc/mps2-fpgaio.c         | 97 +++++++++++++++++++++++++++++++++--
 2 files changed, 99 insertions(+), 4 deletions(-)

diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
index ec057d38c76..69e265cd4b2 100644
--- a/include/hw/misc/mps2-fpgaio.h
+++ b/include/hw/misc/mps2-fpgaio.h
@@ -37,6 +37,12 @@ typedef struct {
     uint32_t prescale;
     uint32_t misc;
 
+    /* QEMU_CLOCK_VIRTUAL time at which counter and pscntr were last synced */
+    int64_t pscntr_sync_ticks;
+    /* Values of COUNTER and PSCNTR at time pscntr_sync_ticks */
+    uint32_t counter;
+    uint32_t pscntr;
+
     uint32_t prescale_clk;
 
     /* These hold the CLOCK_VIRTUAL ns tick when the CLK1HZ/CLK100HZ was zero */
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
index bbc28f641f0..5cf10ebd66a 100644
--- a/hw/misc/mps2-fpgaio.c
+++ b/hw/misc/mps2-fpgaio.c
@@ -43,6 +43,77 @@ static int64_t tickoff_from_counter(int64_t now, uint32_t count, int frq)
     return now - muldiv64(count, NANOSECONDS_PER_SECOND, frq);
 }
 
+static void resync_counter(MPS2FPGAIO *s)
+{
+    /*
+     * Update s->counter and s->pscntr to their true current values
+     * by calculating how many times PSCNTR has ticked since the
+     * last time we did a resync.
+     */
+    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+    int64_t elapsed = now - s->pscntr_sync_ticks;
+
+    /*
+     * Round elapsed down to a whole number of PSCNTR ticks, so we don't
+     * lose time if we do multiple resyncs in a single tick.
+     */
+    uint64_t ticks = muldiv64(elapsed, s->prescale_clk, NANOSECONDS_PER_SECOND);
+
+    /*
+     * Work out what PSCNTR and COUNTER have moved to. We assume that
+     * PSCNTR reloads from PRESCALE one tick-period after it hits zero,
+     * and that COUNTER increments at the same moment.
+     */
+    if (ticks == 0) {
+        /* We haven't ticked since the last time we were asked */
+        return;
+    } else if (ticks < s->pscntr) {
+        /* We haven't yet reached zero, just reduce the PSCNTR */
+        s->pscntr -= ticks;
+    } else {
+        if (s->prescale == 0) {
+            /*
+             * If the reload value is zero then the PSCNTR will stick
+             * at zero once it reaches it, and so we will increment
+             * COUNTER every tick after that.
+             */
+            s->counter += ticks - s->pscntr;
+            s->pscntr = 0;
+        } else {
+            /*
+             * This is the complicated bit. This ASCII art diagram gives an
+             * example with PRESCALE==5 PSCNTR==7:
+             *
+             * ticks  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14
+             * PSCNTR 7  6  5  4  3  2  1  0  5  4  3  2  1  0  5
+             * cinc                           1                 2
+             * y            0  1  2  3  4  5  6  7  8  9 10 11 12
+             * x            0  1  2  3  4  5  0  1  2  3  4  5  0
+             *
+             * where x = y % (s->prescale + 1)
+             * and so PSCNTR = s->prescale - x
+             * and COUNTER is incremented by y / (s->prescale + 1)
+             *
+             * The case where PSCNTR < PRESCALE works out the same,
+             * though we must be careful to calculate y as 64-bit unsigned
+             * for all parts of the expression.
+             * y < 0 is not possible because that implies ticks < s->pscntr.
+             */
+            uint64_t y = ticks - s->pscntr + s->prescale;
+            s->pscntr = s->prescale - (y % (s->prescale + 1));
+            s->counter += y / (s->prescale + 1);
+        }
+    }
+
+    /*
+     * Only advance the sync time to the timestamp of the last PSCNTR tick,
+     * not all the way to 'now', so we don't lose time if we do multiple
+     * resyncs in a single tick.
+     */
+    s->pscntr_sync_ticks += muldiv64(ticks, NANOSECONDS_PER_SECOND,
+                                     s->prescale_clk);
+}
+
 static uint64_t mps2_fpgaio_read(void *opaque, hwaddr offset, unsigned size)
 {
     MPS2FPGAIO *s = MPS2_FPGAIO(opaque);
@@ -74,9 +145,12 @@ static uint64_t mps2_fpgaio_read(void *opaque, hwaddr offset, unsigned size)
         r = counter_from_tickoff(now, s->clk100hz_tick_offset, 100);
         break;
     case A_COUNTER:
+        resync_counter(s);
+        r = s->counter;
+        break;
     case A_PSCNTR:
-        qemu_log_mask(LOG_UNIMP, "MPS2 FPGAIO: counters unimplemented\n");
-        r = 0;
+        resync_counter(s);
+        r = s->pscntr;
         break;
     default:
         qemu_log_mask(LOG_GUEST_ERROR,
@@ -107,6 +181,7 @@ static void mps2_fpgaio_write(void *opaque, hwaddr offset, uint64_t value,
         s->led0 = value & 0x3;
         break;
     case A_PRESCALE:
+        resync_counter(s);
         s->prescale = value;
         break;
     case A_MISC:
@@ -126,6 +201,14 @@ static void mps2_fpgaio_write(void *opaque, hwaddr offset, uint64_t value,
         now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         s->clk100hz_tick_offset = tickoff_from_counter(now, value, 100);
         break;
+    case A_COUNTER:
+        resync_counter(s);
+        s->counter = value;
+        break;
+    case A_PSCNTR:
+        resync_counter(s);
+        s->pscntr = value;
+        break;
     default:
         qemu_log_mask(LOG_GUEST_ERROR,
                       "MPS2 FPGAIO write: bad offset 0x%x\n", (int) offset);
@@ -150,6 +233,9 @@ static void mps2_fpgaio_reset(DeviceState *dev)
     s->misc = 0;
     s->clk1hz_tick_offset = tickoff_from_counter(now, 0, 1);
     s->clk100hz_tick_offset = tickoff_from_counter(now, 0, 100);
+    s->counter = 0;
+    s->pscntr = 0;
+    s->pscntr_sync_ticks = now;
 }
 
 static void mps2_fpgaio_init(Object *obj)
@@ -170,12 +256,15 @@ static bool mps2_fpgaio_counters_needed(void *opaque)
 
 static const VMStateDescription mps2_fpgaio_counters_vmstate = {
     .name = "mps2-fpgaio/counters",
-    .version_id = 1,
-    .minimum_version_id = 1,
+    .version_id = 2,
+    .minimum_version_id = 2,
     .needed = mps2_fpgaio_counters_needed,
     .fields = (VMStateField[]) {
         VMSTATE_INT64(clk1hz_tick_offset, MPS2FPGAIO),
         VMSTATE_INT64(clk100hz_tick_offset, MPS2FPGAIO),
+        VMSTATE_UINT32(counter, MPS2FPGAIO),
+        VMSTATE_UINT32(pscntr, MPS2FPGAIO),
+        VMSTATE_INT64(pscntr_sync_ticks, MPS2FPGAIO),
         VMSTATE_END_OF_LIST()
     }
 };
-- 
2.18.0

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

* [Qemu-devel] [PATCH 03/22] hw/timer/cmsdk-apb-dualtimer: Implement CMSDK dual timer module
  2018-08-20 14:10 [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI Peter Maydell
  2018-08-20 14:10 ` [Qemu-devel] [PATCH 01/22] hw/misc/mps2-fpgaio: Implement 1Hz and 100Hz counters Peter Maydell
  2018-08-20 14:10 ` [Qemu-devel] [PATCH 02/22] hw/misc/mps2-fpgaio: Implement PSCNTR and COUNTER Peter Maydell
@ 2018-08-20 14:10 ` Peter Maydell
  2018-08-23 14:08   ` Richard Henderson
  2018-08-20 14:10 ` [Qemu-devel] [PATCH 04/22] hw/arm/iotkit: Wire up the dualtimer Peter Maydell
                   ` (18 subsequent siblings)
  21 siblings, 1 reply; 56+ messages in thread
From: Peter Maydell @ 2018-08-20 14:10 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Philippe Mathieu-Daudé

The Arm Cortex-M System Design Kit includes a "dual-input timer module"
which combines two programmable down-counters. Implement a model
of this device.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/timer/Makefile.objs                 |   1 +
 include/hw/timer/cmsdk-apb-dualtimer.h |  72 ++++
 hw/timer/cmsdk-apb-dualtimer.c         | 515 +++++++++++++++++++++++++
 MAINTAINERS                            |   2 +
 default-configs/arm-softmmu.mak        |   1 +
 hw/timer/trace-events                  |   5 +
 6 files changed, 596 insertions(+)
 create mode 100644 include/hw/timer/cmsdk-apb-dualtimer.h
 create mode 100644 hw/timer/cmsdk-apb-dualtimer.c

diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index e16b2b913ce..b32194d153d 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -44,4 +44,5 @@ common-obj-$(CONFIG_ASPEED_SOC) += aspeed_timer.o
 
 common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
 common-obj-$(CONFIG_CMSDK_APB_TIMER) += cmsdk-apb-timer.o
+common-obj-$(CONFIG_CMSDK_APB_DUALTIMER) += cmsdk-apb-dualtimer.o
 common-obj-$(CONFIG_MSF2) += mss-timer.o
diff --git a/include/hw/timer/cmsdk-apb-dualtimer.h b/include/hw/timer/cmsdk-apb-dualtimer.h
new file mode 100644
index 00000000000..9843a9dbb1d
--- /dev/null
+++ b/include/hw/timer/cmsdk-apb-dualtimer.h
@@ -0,0 +1,72 @@
+/*
+ * ARM CMSDK APB dual-timer emulation
+ *
+ * Copyright (c) 2018 Linaro Limited
+ * Written by Peter Maydell
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 or
+ *  (at your option) any later version.
+ */
+
+/*
+ * This is a model of the "APB dual-input timer" which is part of the Cortex-M
+ * System Design Kit (CMSDK) and documented in the Cortex-M System
+ * Design Kit Technical Reference Manual (ARM DDI0479C):
+ * https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
+ *
+ * QEMU interface:
+ *  + QOM property "pclk-frq": frequency at which the timer is clocked
+ *  + sysbus MMIO region 0: the register bank
+ *  + sysbus IRQ 0: combined timer interrupt TIMINTC
+ *  + sysbus IRO 1: timer block 1 interrupt TIMINT1
+ *  + sysbus IRQ 2: timer block 2 interrupt TIMINT2
+ */
+
+#ifndef CMSDK_APB_DUALTIMER_H
+#define CMSDK_APB_DUALTIMER_H
+
+#include "hw/sysbus.h"
+#include "hw/ptimer.h"
+
+#define TYPE_CMSDK_APB_DUALTIMER "cmsdk-apb-dualtimer"
+#define CMSDK_APB_DUALTIMER(obj) OBJECT_CHECK(CMSDKAPBDualTimer, (obj), \
+                                              TYPE_CMSDK_APB_DUALTIMER)
+
+typedef struct CMSDKAPBDualTimer CMSDKAPBDualTimer;
+
+/* One of the two identical timer modules in the dual-timer module */
+typedef struct CMSDKAPBDualTimerModule {
+    CMSDKAPBDualTimer *parent;
+    struct ptimer_state *timer;
+    qemu_irq timerint;
+    /*
+     * We must track the guest LOAD and VALUE register state by hand
+     * rather than leaving this state only in the ptimer limit/count,
+     * because if CONTROL.SIZE is 0 then only the low 16 bits of the
+     * counter actually counts, but the high half is still guest
+     * accessible.
+     */
+    uint32_t load;
+    uint32_t value;
+    uint32_t control;
+    uint32_t intstatus;
+} CMSDKAPBDualTimerModule;
+
+#define CMSDK_APB_DUALTIMER_NUM_MODULES 2
+
+struct CMSDKAPBDualTimer {
+    /*< private >*/
+    SysBusDevice parent_obj;
+
+    /*< public >*/
+    MemoryRegion iomem;
+    qemu_irq timerintc;
+    uint32_t pclk_frq;
+
+    CMSDKAPBDualTimerModule timermod[CMSDK_APB_DUALTIMER_NUM_MODULES];
+    uint32_t timeritcr;
+    uint32_t timeritop;
+};
+
+#endif
diff --git a/hw/timer/cmsdk-apb-dualtimer.c b/hw/timer/cmsdk-apb-dualtimer.c
new file mode 100644
index 00000000000..4b005e28136
--- /dev/null
+++ b/hw/timer/cmsdk-apb-dualtimer.c
@@ -0,0 +1,515 @@
+/*
+ * ARM CMSDK APB dual-timer emulation
+ *
+ * Copyright (c) 2018 Linaro Limited
+ * Written by Peter Maydell
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 or
+ *  (at your option) any later version.
+ */
+
+/*
+ * This is a model of the "APB dual-input timer" which is part of the Cortex-M
+ * System Design Kit (CMSDK) and documented in the Cortex-M System
+ * Design Kit Technical Reference Manual (ARM DDI0479C):
+ * https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "trace.h"
+#include "qapi/error.h"
+#include "qemu/main-loop.h"
+#include "hw/sysbus.h"
+#include "hw/registerfields.h"
+#include "hw/timer/cmsdk-apb-dualtimer.h"
+
+REG32(TIMER1LOAD, 0x0)
+REG32(TIMER1VALUE, 0x4)
+REG32(TIMER1CONTROL, 0x8)
+    FIELD(CONTROL, ONESHOT, 0, 1)
+    FIELD(CONTROL, SIZE, 1, 1)
+    FIELD(CONTROL, PRESCALE, 2, 2)
+    FIELD(CONTROL, INTEN, 5, 1)
+    FIELD(CONTROL, MODE, 6, 1)
+    FIELD(CONTROL, ENABLE, 7, 1)
+#define R_CONTROL_VALID_MASK (R_CONTROL_ONESHOT_MASK | R_CONTROL_SIZE_MASK | \
+                              R_CONTROL_PRESCALE_MASK | R_CONTROL_INTEN_MASK | \
+                              R_CONTROL_MODE_MASK | R_CONTROL_ENABLE_MASK)
+REG32(TIMER1INTCLR, 0xc)
+REG32(TIMER1RIS, 0x10)
+REG32(TIMER1MIS, 0x14)
+REG32(TIMER1BGLOAD, 0x18)
+REG32(TIMER2LOAD, 0x20)
+REG32(TIMER2VALUE, 0x24)
+REG32(TIMER2CONTROL, 0x28)
+REG32(TIMER2INTCLR, 0x2c)
+REG32(TIMER2RIS, 0x30)
+REG32(TIMER2MIS, 0x34)
+REG32(TIMER2BGLOAD, 0x38)
+REG32(TIMERITCR, 0xf00)
+    FIELD(TIMERITCR, ENABLE, 0, 1)
+#define R_TIMERITCR_VALID_MASK R_TIMERITCR_ENABLE_MASK
+REG32(TIMERITOP, 0xf04)
+    FIELD(TIMERITOP, TIMINT1, 0, 1)
+    FIELD(TIMERITOP, TIMINT2, 1, 1)
+#define R_TIMERITOP_VALID_MASK (R_TIMERITOP_TIMINT1_MASK | \
+                                R_TIMERITOP_TIMINT2_MASK)
+REG32(PID4, 0xfd0)
+REG32(PID5, 0xfd4)
+REG32(PID6, 0xfd8)
+REG32(PID7, 0xfdc)
+REG32(PID0, 0xfe0)
+REG32(PID1, 0xfe4)
+REG32(PID2, 0xfe8)
+REG32(PID3, 0xfec)
+REG32(CID0, 0xff0)
+REG32(CID1, 0xff4)
+REG32(CID2, 0xff8)
+REG32(CID3, 0xffc)
+
+/* PID/CID values */
+static const int timer_id[] = {
+    0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
+    0x23, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
+    0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
+};
+
+static bool cmsdk_dualtimermod_intstatus(CMSDKAPBDualTimerModule *m)
+{
+    /* Return masked interrupt status for the timer module */
+    return m->intstatus && (m->control & R_CONTROL_INTEN_MASK);
+}
+
+static void cmsdk_apb_dualtimer_update(CMSDKAPBDualTimer *s)
+{
+    bool timint1, timint2, timintc;
+
+    if (s->timeritcr) {
+        /* Integration test mode: outputs driven directly from TIMERITOP bits */
+        timint1 = s->timeritop & R_TIMERITOP_TIMINT1_MASK;
+        timint2 = s->timeritop & R_TIMERITOP_TIMINT2_MASK;
+    } else {
+        timint1 = cmsdk_dualtimermod_intstatus(&s->timermod[0]);
+        timint2 = cmsdk_dualtimermod_intstatus(&s->timermod[1]);
+    }
+
+    timintc = timint1 || timint2;
+
+    qemu_set_irq(s->timermod[0].timerint, timint1);
+    qemu_set_irq(s->timermod[1].timerint, timint2);
+    qemu_set_irq(s->timerintc, timintc);
+}
+
+static void cmsdk_dualtimermod_write_control(CMSDKAPBDualTimerModule *m,
+                                             uint32_t newctrl)
+{
+    /* Handle a write to the CONTROL register */
+    uint32_t changed;
+
+    newctrl &= R_CONTROL_VALID_MASK;
+
+    changed = m->control ^ newctrl;
+
+    if (changed & ~newctrl & R_CONTROL_ENABLE_MASK) {
+        /* ENABLE cleared, stop timer before any further changes */
+        ptimer_stop(m->timer);
+    }
+
+    if (changed & R_CONTROL_PRESCALE_MASK) {
+        int divisor;
+
+        switch (FIELD_EX32(newctrl, CONTROL, PRESCALE)) {
+        case 0:
+            divisor = 1;
+            break;
+        case 1:
+            divisor = 16;
+            break;
+        case 2:
+            divisor = 256;
+            break;
+        case 3:
+            /* UNDEFINED; complain, and arbitrarily treat like 2 */
+            qemu_log_mask(LOG_GUEST_ERROR,
+                          "CMSDK APB dual-timer: CONTROL.PRESCALE==0b11"
+                          " is undefined behaviour\n");
+            divisor = 256;
+            break;
+        default:
+            g_assert_not_reached();
+        }
+        ptimer_set_freq(m->timer, m->parent->pclk_frq / divisor);
+    }
+
+    if (changed & R_CONTROL_MODE_MASK) {
+        uint32_t load;
+        if (newctrl & R_CONTROL_MODE_MASK) {
+            /* Periodic: the limit is the LOAD register value */
+            load = m->load;
+        } else {
+            /* Free-running: counter wraps around */
+            load = ptimer_get_limit(m->timer);
+            if (!(m->control & R_CONTROL_SIZE_MASK)) {
+                load = deposit32(load, 16, 16, extract32(m->load, 16, 16));
+            }
+            m->load = load;
+            load = 0xffffffff;
+        }
+        if (!(m->control & R_CONTROL_SIZE_MASK)) {
+            load &= 0xffff;
+        }
+        ptimer_set_limit(m->timer, load, 0);
+    }
+
+    if (changed & R_CONTROL_SIZE_MASK) {
+        /* Timer switched between 16 and 32 bit count */
+        uint32_t value, load;
+
+        value = ptimer_get_count(m->timer);
+        load = ptimer_get_limit(m->timer);
+        if (newctrl & R_CONTROL_SIZE_MASK) {
+            /* 16 -> 32, top half of VALUE is in struct field */
+            value = deposit32(value, 16, 16, extract32(m->value, 16, 16));
+        } else {
+            /* 32 -> 16: save top half to struct field and truncate */
+            m->value = value;
+            value &= 0xffff;
+        }
+
+        if (newctrl & R_CONTROL_MODE_MASK) {
+            /* Periodic, timer limit has LOAD value */
+            if (newctrl & R_CONTROL_SIZE_MASK) {
+                load = deposit32(load, 16, 16, extract32(m->load, 16, 16));
+            } else {
+                m->load = load;
+                load &= 0xffff;
+            }
+        } else {
+            /* Free-running, timer limit is set to give wraparound */
+            if (newctrl & R_CONTROL_SIZE_MASK) {
+                load = 0xffffffff;
+            } else {
+                load = 0xffff;
+            }
+        }
+        ptimer_set_count(m->timer, value);
+        ptimer_set_limit(m->timer, load, 0);
+    }
+
+    if (newctrl & R_CONTROL_ENABLE_MASK) {
+        /*
+         * ENABLE is set; start the timer after all other changes.
+         * We start it even if the ENABLE bit didn't actually change,
+         * in case the timer was an expired one-shot timer that has
+         * now been changed into a free-running or periodic timer.
+         */
+        ptimer_run(m->timer, !!(newctrl & R_CONTROL_ONESHOT_MASK));
+    }
+
+    m->control = newctrl;
+}
+
+static uint64_t cmsdk_apb_dualtimer_read(void *opaque, hwaddr offset,
+                                          unsigned size)
+{
+    CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(opaque);
+    uint64_t r;
+
+    if (offset >= A_TIMERITCR) {
+        switch (offset) {
+        case A_TIMERITCR:
+            r = s->timeritcr;
+            break;
+        case A_PID4 ... A_CID3:
+            r = timer_id[(offset - A_PID4) / 4];
+            break;
+        default:
+        bad_offset:
+            qemu_log_mask(LOG_GUEST_ERROR,
+                          "CMSDK APB dual-timer read: bad offset %x\n",
+                          (int) offset);
+            r = 0;
+            break;
+        }
+    } else {
+        int timer = offset >> 5;
+        CMSDKAPBDualTimerModule *m;
+
+        if (timer >= ARRAY_SIZE(s->timermod)) {
+            goto bad_offset;
+        }
+
+        m = &s->timermod[timer];
+
+        switch (offset & 0x1F) {
+        case A_TIMER1LOAD:
+        case A_TIMER1BGLOAD:
+            if (m->control & R_CONTROL_MODE_MASK) {
+                /*
+                 * Periodic: the ptimer limit is the LOAD register value, (or
+                 * just the low 16 bits of it if the timer is in 16-bit mode)
+                 */
+                r = ptimer_get_limit(m->timer);
+                if (!(m->control & R_CONTROL_SIZE_MASK)) {
+                    r = deposit32(r, 16, 16, extract32(m->load, 16, 16));
+                }
+            } else {
+                /* Free-running: LOAD register value is just in m->load */
+                r = m->load;
+            }
+            break;
+        case A_TIMER1VALUE:
+            r = ptimer_get_count(m->timer);
+            if (!(m->control & R_CONTROL_SIZE_MASK)) {
+                r = deposit32(r, 16, 16, extract32(m->value, 16, 16));
+            }
+            break;
+        case A_TIMER1CONTROL:
+            r = m->control;
+            break;
+        case A_TIMER1RIS:
+            r = m->intstatus;
+            break;
+        case A_TIMER1MIS:
+            r = cmsdk_dualtimermod_intstatus(m);
+            break;
+        default:
+            goto bad_offset;
+        }
+    }
+
+    trace_cmsdk_apb_dualtimer_read(offset, r, size);
+    return r;
+}
+
+static void cmsdk_apb_dualtimer_write(void *opaque, hwaddr offset,
+                                       uint64_t value, unsigned size)
+{
+    CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(opaque);
+
+    trace_cmsdk_apb_dualtimer_write(offset, value, size);
+
+    if (offset >= A_TIMERITCR) {
+        switch (offset) {
+        case A_TIMERITCR:
+            s->timeritcr = value & R_TIMERITCR_VALID_MASK;
+            cmsdk_apb_dualtimer_update(s);
+        case A_TIMERITOP:
+            s->timeritop = value & R_TIMERITOP_VALID_MASK;
+            cmsdk_apb_dualtimer_update(s);
+        default:
+        bad_offset:
+            qemu_log_mask(LOG_GUEST_ERROR,
+                          "CMSDK APB dual-timer write: bad offset %x\n",
+                          (int) offset);
+            break;
+        }
+    } else {
+        int timer = offset >> 5;
+        CMSDKAPBDualTimerModule *m;
+
+        if (timer >= ARRAY_SIZE(s->timermod)) {
+            goto bad_offset;
+        }
+
+        m = &s->timermod[timer];
+
+        switch (offset & 0x1F) {
+        case A_TIMER1LOAD:
+            /* Set the limit, and immediately reload the count from it */
+            m->load = value;
+            m->value = value;
+            if (!(m->control & R_CONTROL_SIZE_MASK)) {
+                value &= 0xffff;
+            }
+            if (!(m->control & R_CONTROL_MODE_MASK)) {
+                /*
+                 * In free-running mode this won't set the limit but will
+                 * still change the current count value.
+                 */
+                ptimer_set_count(m->timer, value);
+            } else {
+                if (!value) {
+                    ptimer_stop(m->timer);
+                }
+                ptimer_set_limit(m->timer, value, 1);
+                if (value && (m->control & R_CONTROL_ENABLE_MASK)) {
+                    /* Force possibly-expired oneshot timer to restart */
+                    ptimer_run(m->timer, 1);
+                }
+            }
+            break;
+        case A_TIMER1BGLOAD:
+            /* Set the limit, but not the current count */
+            m->load = value;
+            if (!(m->control & R_CONTROL_MODE_MASK)) {
+                /* In free-running mode there is no limit */
+                break;
+            }
+            if (!(m->control & R_CONTROL_SIZE_MASK)) {
+                value &= 0xffff;
+            }
+            ptimer_set_limit(m->timer, value, 0);
+            break;
+        case A_TIMER1CONTROL:
+            cmsdk_dualtimermod_write_control(m, value);
+            cmsdk_apb_dualtimer_update(s);
+            break;
+        case A_TIMER1INTCLR:
+            m->intstatus = 0;
+            cmsdk_apb_dualtimer_update(s);
+            break;
+        default:
+            goto bad_offset;
+        }
+    }
+}
+
+static const MemoryRegionOps cmsdk_apb_dualtimer_ops = {
+    .read = cmsdk_apb_dualtimer_read,
+    .write = cmsdk_apb_dualtimer_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    /* byte/halfword accesses are just zero-padded on reads and writes */
+    .impl.min_access_size = 4,
+    .impl.max_access_size = 4,
+    .valid.min_access_size = 1,
+    .valid.max_access_size = 4,
+};
+
+static void cmsdk_dualtimermod_tick(void *opaque)
+{
+    CMSDKAPBDualTimerModule *m = opaque;
+
+    m->intstatus = 1;
+    cmsdk_apb_dualtimer_update(m->parent);
+}
+
+static void cmsdk_dualtimermod_reset(CMSDKAPBDualTimerModule *m)
+{
+    m->control = R_CONTROL_INTEN_MASK;
+    m->intstatus = 0;
+    m->load = 0;
+    m->value = 0xffffffff;
+    ptimer_stop(m->timer);
+    /*
+     * We start in free-running mode, with VALUE at 0xffffffff, and
+     * in 16-bit counter mode. This means that the ptimer count and
+     * limit must both be set to 0xffff, so we wrap at 16 bits.
+     */
+    ptimer_set_limit(m->timer, 0xffff, 1);
+    ptimer_set_freq(m->timer, m->parent->pclk_frq);
+}
+
+static void cmsdk_apb_dualtimer_reset(DeviceState *dev)
+{
+    CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(dev);
+    int i;
+
+    trace_cmsdk_apb_dualtimer_reset();
+
+    for (i = 0; i < ARRAY_SIZE(s->timermod); i++) {
+        cmsdk_dualtimermod_reset(&s->timermod[i]);
+    }
+    s->timeritcr = 0;
+    s->timeritop = 0;
+}
+
+static void cmsdk_apb_dualtimer_init(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(obj);
+    int i;
+
+    memory_region_init_io(&s->iomem, obj, &cmsdk_apb_dualtimer_ops,
+                          s, "cmsdk-apb-dualtimer", 0x1000);
+    sysbus_init_mmio(sbd, &s->iomem);
+    sysbus_init_irq(sbd, &s->timerintc);
+
+    for (i = 0; i < ARRAY_SIZE(s->timermod); i++) {
+        sysbus_init_irq(sbd, &s->timermod[i].timerint);
+    }
+}
+
+static void cmsdk_apb_dualtimer_realize(DeviceState *dev, Error **errp)
+{
+    CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(dev);
+    int i;
+
+    if (s->pclk_frq == 0) {
+        error_setg(errp, "CMSDK APB timer: pclk-frq property must be set");
+        return;
+    }
+
+    for (i = 0; i < ARRAY_SIZE(s->timermod); i++) {
+        CMSDKAPBDualTimerModule *m = &s->timermod[i];
+        QEMUBH *bh = qemu_bh_new(cmsdk_dualtimermod_tick, m);
+
+        m->parent = s;
+        m->timer = ptimer_init(bh,
+                               PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD |
+                               PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT |
+                               PTIMER_POLICY_NO_IMMEDIATE_RELOAD |
+                               PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
+    }
+}
+
+static const VMStateDescription cmsdk_dualtimermod_vmstate = {
+    .name = "cmsdk-apb-dualtimer-module",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_PTIMER(timer, CMSDKAPBDualTimerModule),
+        VMSTATE_UINT32(load, CMSDKAPBDualTimerModule),
+        VMSTATE_UINT32(value, CMSDKAPBDualTimerModule),
+        VMSTATE_UINT32(control, CMSDKAPBDualTimerModule),
+        VMSTATE_UINT32(intstatus, CMSDKAPBDualTimerModule),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription cmsdk_apb_dualtimer_vmstate = {
+    .name = "cmsdk-apb-dualtimer",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_STRUCT_ARRAY(timermod, CMSDKAPBDualTimer,
+                             CMSDK_APB_DUALTIMER_NUM_MODULES,
+                             1, cmsdk_dualtimermod_vmstate,
+                             CMSDKAPBDualTimerModule),
+        VMSTATE_UINT32(timeritcr, CMSDKAPBDualTimer),
+        VMSTATE_UINT32(timeritop, CMSDKAPBDualTimer),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static Property cmsdk_apb_dualtimer_properties[] = {
+    DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBDualTimer, pclk_frq, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void cmsdk_apb_dualtimer_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = cmsdk_apb_dualtimer_realize;
+    dc->vmsd = &cmsdk_apb_dualtimer_vmstate;
+    dc->reset = cmsdk_apb_dualtimer_reset;
+    dc->props = cmsdk_apb_dualtimer_properties;
+}
+
+static const TypeInfo cmsdk_apb_dualtimer_info = {
+    .name = TYPE_CMSDK_APB_DUALTIMER,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(CMSDKAPBDualTimer),
+    .instance_init = cmsdk_apb_dualtimer_init,
+    .class_init = cmsdk_apb_dualtimer_class_init,
+};
+
+static void cmsdk_apb_dualtimer_register_types(void)
+{
+    type_register_static(&cmsdk_apb_dualtimer_info);
+}
+
+type_init(cmsdk_apb_dualtimer_register_types);
diff --git a/MAINTAINERS b/MAINTAINERS
index 6902a568f44..2a4c9d63f2d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -455,6 +455,8 @@ F: hw/timer/pl031.c
 F: include/hw/arm/primecell.h
 F: hw/timer/cmsdk-apb-timer.c
 F: include/hw/timer/cmsdk-apb-timer.h
+F: hw/timer/cmsdk-apb-dualtimer.c
+F: include/hw/timer/cmsdk-apb-dualtimer.h
 F: hw/char/cmsdk-apb-uart.c
 F: include/hw/char/cmsdk-apb-uart.h
 F: hw/watchdog/cmsdk-apb-watchdog.c
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index a92bc34fb24..c8137a5d3c7 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -103,6 +103,7 @@ CONFIG_STM32F2XX_SPI=y
 CONFIG_STM32F205_SOC=y
 
 CONFIG_CMSDK_APB_TIMER=y
+CONFIG_CMSDK_APB_DUALTIMER=y
 CONFIG_CMSDK_APB_UART=y
 CONFIG_CMSDK_APB_WATCHDOG=y
 
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
index e6e042fddb7..fa4213df5be 100644
--- a/hw/timer/trace-events
+++ b/hw/timer/trace-events
@@ -61,5 +61,10 @@ cmsdk_apb_timer_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB t
 cmsdk_apb_timer_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB timer write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
 cmsdk_apb_timer_reset(void) "CMSDK APB timer: reset"
 
+# hw/timer/cmsdk_apb_dualtimer.c
+cmsdk_apb_dualtimer_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB dualtimer read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+cmsdk_apb_dualtimer_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB dualtimer write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+cmsdk_apb_dualtimer_reset(void) "CMSDK APB dualtimer: reset"
+
 # hw/timer/xlnx-zynqmp-rtc.c
 xlnx_zynqmp_rtc_gettime(int year, int month, int day, int hour, int min, int sec) "Get time from host: %d-%d-%d %2d:%02d:%02d"
-- 
2.18.0

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

* [Qemu-devel] [PATCH 04/22] hw/arm/iotkit: Wire up the dualtimer
  2018-08-20 14:10 [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI Peter Maydell
                   ` (2 preceding siblings ...)
  2018-08-20 14:10 ` [Qemu-devel] [PATCH 03/22] hw/timer/cmsdk-apb-dualtimer: Implement CMSDK dual timer module Peter Maydell
@ 2018-08-20 14:10 ` Peter Maydell
  2018-08-21  6:41   ` Philippe Mathieu-Daudé
  2018-08-23 14:09   ` Richard Henderson
  2018-08-20 14:10 ` [Qemu-devel] [PATCH 05/22] hw/arm/mps2: Wire up dual-timer in mps2-an385 and mps2-an511 Peter Maydell
                   ` (17 subsequent siblings)
  21 siblings, 2 replies; 56+ messages in thread
From: Peter Maydell @ 2018-08-20 14:10 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Philippe Mathieu-Daudé

Now we have a model of the CMSDK dual timer, we can wire it
up in the IoTKit.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/arm/iotkit.h | 3 ++-
 hw/arm/iotkit.c         | 8 +++++---
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h
index 2cddde55dd1..3e6d806e352 100644
--- a/include/hw/arm/iotkit.h
+++ b/include/hw/arm/iotkit.h
@@ -56,6 +56,7 @@
 #include "hw/misc/tz-ppc.h"
 #include "hw/misc/tz-mpc.h"
 #include "hw/timer/cmsdk-apb-timer.h"
+#include "hw/timer/cmsdk-apb-dualtimer.h"
 #include "hw/misc/unimp.h"
 #include "hw/or-irq.h"
 #include "hw/core/split-irq.h"
@@ -87,7 +88,7 @@ typedef struct IoTKit {
     SplitIRQ mpc_irq_splitter[IOTS_NUM_EXP_MPC + IOTS_NUM_MPC];
     qemu_or_irq mpc_irq_orgate;
 
-    UnimplementedDeviceState dualtimer;
+    CMSDKAPBDualTimer dualtimer;
     UnimplementedDeviceState s32ktimer;
 
     MemoryRegion container;
diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
index 8cadc8b1608..130d013909e 100644
--- a/hw/arm/iotkit.c
+++ b/hw/arm/iotkit.c
@@ -139,7 +139,7 @@ static void iotkit_init(Object *obj)
     sysbus_init_child_obj(obj, "timer1", &s->timer1, sizeof(s->timer1),
                           TYPE_CMSDK_APB_TIMER);
     sysbus_init_child_obj(obj, "dualtimer", &s->dualtimer, sizeof(s->dualtimer),
-                          TYPE_UNIMPLEMENTED_DEVICE);
+                          TYPE_CMSDK_APB_DUALTIMER);
     object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate,
                             sizeof(s->ppc_irq_orgate), TYPE_OR_IRQ,
                             &error_abort, NULL);
@@ -390,13 +390,15 @@ static void iotkit_realize(DeviceState *dev, Error **errp)
         return;
     }
 
-    qdev_prop_set_string(DEVICE(&s->dualtimer), "name", "Dual timer");
-    qdev_prop_set_uint64(DEVICE(&s->dualtimer), "size", 0x1000);
+
+    qdev_prop_set_uint32(DEVICE(&s->dualtimer), "pclk-frq", s->mainclk_frq);
     object_property_set_bool(OBJECT(&s->dualtimer), true, "realized", &err);
     if (err) {
         error_propagate(errp, err);
         return;
     }
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->dualtimer), 0,
+                       qdev_get_gpio_in(DEVICE(&s->armv7m), 5));
     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dualtimer), 0);
     object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[2]", &err);
     if (err) {
-- 
2.18.0

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

* [Qemu-devel] [PATCH 05/22] hw/arm/mps2: Wire up dual-timer in mps2-an385 and mps2-an511
  2018-08-20 14:10 [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI Peter Maydell
                   ` (3 preceding siblings ...)
  2018-08-20 14:10 ` [Qemu-devel] [PATCH 04/22] hw/arm/iotkit: Wire up the dualtimer Peter Maydell
@ 2018-08-20 14:10 ` Peter Maydell
  2018-08-21  6:43   ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
  2018-08-23 14:11   ` [Qemu-devel] " Richard Henderson
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 06/22] hw/arm/iotkit: Wire up the watchdogs Peter Maydell
                   ` (16 subsequent siblings)
  21 siblings, 2 replies; 56+ messages in thread
From: Peter Maydell @ 2018-08-20 14:10 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Philippe Mathieu-Daudé

The MPS2 FPGA images for the Cortex-M3 (mps2-an385 and mps2-511)
both include a CMSDK dual-timer module. Wire this up.

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

diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
index 0a0ae867d9b..564624629d0 100644
--- a/hw/arm/mps2.c
+++ b/hw/arm/mps2.c
@@ -34,6 +34,7 @@
 #include "hw/misc/unimp.h"
 #include "hw/char/cmsdk-apb-uart.h"
 #include "hw/timer/cmsdk-apb-timer.h"
+#include "hw/timer/cmsdk-apb-dualtimer.h"
 #include "hw/misc/mps2-scc.h"
 #include "hw/devices.h"
 #include "net/net.h"
@@ -64,6 +65,7 @@ typedef struct {
     MemoryRegion blockram_m3;
     MemoryRegion sram;
     MPS2SCC scc;
+    CMSDKAPBDualTimer dualtimer;
 } MPS2MachineState;
 
 #define TYPE_MPS2_MACHINE "mps2"
@@ -297,6 +299,15 @@ static void mps2_common_init(MachineState *machine)
     cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
     cmsdk_apb_timer_create(0x40001000, qdev_get_gpio_in(armv7m, 9), SYSCLK_FRQ);
 
+    sysbus_init_child_obj(OBJECT(mms), "dualtimer", &mms->dualtimer,
+                          sizeof(mms->dualtimer), TYPE_CMSDK_APB_DUALTIMER);
+    qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ);
+    object_property_set_bool(OBJECT(&mms->dualtimer), true, "realized",
+                             &error_fatal);
+    sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
+                       qdev_get_gpio_in(armv7m, 10));
+    sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0x40002000);
+
     object_initialize(&mms->scc, sizeof(mms->scc), TYPE_MPS2_SCC);
     sccdev = DEVICE(&mms->scc);
     qdev_set_parent_bus(sccdev, sysbus_get_default());
-- 
2.18.0

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

* [Qemu-devel] [PATCH 06/22] hw/arm/iotkit: Wire up the watchdogs
  2018-08-20 14:10 [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI Peter Maydell
                   ` (4 preceding siblings ...)
  2018-08-20 14:10 ` [Qemu-devel] [PATCH 05/22] hw/arm/mps2: Wire up dual-timer in mps2-an385 and mps2-an511 Peter Maydell
@ 2018-08-20 14:11 ` Peter Maydell
  2018-08-23 14:17   ` Richard Henderson
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 07/22] hw/arm/iotkit: Wire up the S32KTIMER Peter Maydell
                   ` (15 subsequent siblings)
  21 siblings, 1 reply; 56+ messages in thread
From: Peter Maydell @ 2018-08-20 14:11 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Philippe Mathieu-Daudé

The IoTKit includes three different instances of the
CMSDK APB watchdog; create and wire them up.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 include/hw/arm/iotkit.h |  6 +++++
 hw/arm/iotkit.c         | 58 ++++++++++++++++++++++++++++++++++++++---
 2 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h
index 3e6d806e352..776d0497087 100644
--- a/include/hw/arm/iotkit.h
+++ b/include/hw/arm/iotkit.h
@@ -57,6 +57,7 @@
 #include "hw/misc/tz-mpc.h"
 #include "hw/timer/cmsdk-apb-timer.h"
 #include "hw/timer/cmsdk-apb-dualtimer.h"
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
 #include "hw/misc/unimp.h"
 #include "hw/or-irq.h"
 #include "hw/core/split-irq.h"
@@ -87,10 +88,15 @@ typedef struct IoTKit {
     SplitIRQ ppc_irq_splitter[NUM_PPCS];
     SplitIRQ mpc_irq_splitter[IOTS_NUM_EXP_MPC + IOTS_NUM_MPC];
     qemu_or_irq mpc_irq_orgate;
+    qemu_or_irq nmi_orgate;
 
     CMSDKAPBDualTimer dualtimer;
     UnimplementedDeviceState s32ktimer;
 
+    CMSDKAPBWatchdog s32kwatchdog;
+    CMSDKAPBWatchdog nswatchdog;
+    CMSDKAPBWatchdog swatchdog;
+
     MemoryRegion container;
     MemoryRegion alias1;
     MemoryRegion alias2;
diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
index 130d013909e..5cedfa03570 100644
--- a/hw/arm/iotkit.c
+++ b/hw/arm/iotkit.c
@@ -19,6 +19,9 @@
 #include "hw/misc/unimp.h"
 #include "hw/arm/arm.h"
 
+/* Clock frequency in HZ of the 32KHz "slow clock" */
+#define S32KCLK (32 * 1000)
+
 /* Create an alias region of @size bytes starting at @base
  * which mirrors the memory starting at @orig.
  */
@@ -140,6 +143,15 @@ static void iotkit_init(Object *obj)
                           TYPE_CMSDK_APB_TIMER);
     sysbus_init_child_obj(obj, "dualtimer", &s->dualtimer, sizeof(s->dualtimer),
                           TYPE_CMSDK_APB_DUALTIMER);
+    sysbus_init_child_obj(obj, "s32kwatchdog", &s->s32kwatchdog,
+                          sizeof(s->s32kwatchdog), TYPE_CMSDK_APB_WATCHDOG);
+    sysbus_init_child_obj(obj, "nswatchdog", &s->nswatchdog,
+                          sizeof(s->nswatchdog), TYPE_CMSDK_APB_WATCHDOG);
+    sysbus_init_child_obj(obj, "swatchdog", &s->swatchdog,
+                          sizeof(s->swatchdog), TYPE_CMSDK_APB_WATCHDOG);
+    object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
+                            sizeof(s->nmi_orgate), TYPE_OR_IRQ,
+                            &error_abort, NULL);
     object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate,
                             sizeof(s->ppc_irq_orgate), TYPE_OR_IRQ,
                             &error_abort, NULL);
@@ -510,12 +522,52 @@ static void iotkit_realize(DeviceState *dev, Error **errp)
     create_unimplemented_device("SYSINFO", 0x40020000, 0x1000);
 
     create_unimplemented_device("SYSCONTROL", 0x50021000, 0x1000);
-    create_unimplemented_device("S32KWATCHDOG", 0x5002e000, 0x1000);
+
+    /* This OR gate wires together outputs from the secure watchdogs to NMI */
+    object_property_set_int(OBJECT(&s->nmi_orgate), 2, "num-lines", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    object_property_set_bool(OBJECT(&s->nmi_orgate), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
+                          qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
+
+    qdev_prop_set_uint32(DEVICE(&s->s32kwatchdog), "wdogclk-frq", S32KCLK);
+    object_property_set_bool(OBJECT(&s->s32kwatchdog), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32kwatchdog), 0,
+                       qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 0));
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->s32kwatchdog), 0, 0x5002e000);
 
     /* 0x40080000 .. 0x4008ffff : IoTKit second Base peripheral region */
 
-    create_unimplemented_device("NS watchdog", 0x40081000, 0x1000);
-    create_unimplemented_device("S watchdog", 0x50081000, 0x1000);
+    qdev_prop_set_uint32(DEVICE(&s->nswatchdog), "wdogclk-frq", s->mainclk_frq);
+    object_property_set_bool(OBJECT(&s->nswatchdog), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->nswatchdog), 0,
+                       qdev_get_gpio_in(DEVICE(&s->armv7m), 1));
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->nswatchdog), 0, 0x40081000);
+
+    qdev_prop_set_uint32(DEVICE(&s->swatchdog), "wdogclk-frq", s->mainclk_frq);
+    object_property_set_bool(OBJECT(&s->swatchdog), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->swatchdog), 0,
+                       qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 1));
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->swatchdog), 0, 0x50081000);
 
     for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
         Object *splitter = OBJECT(&s->ppc_irq_splitter[i]);
-- 
2.18.0

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

* [Qemu-devel] [PATCH 07/22] hw/arm/iotkit: Wire up the S32KTIMER
  2018-08-20 14:10 [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI Peter Maydell
                   ` (5 preceding siblings ...)
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 06/22] hw/arm/iotkit: Wire up the watchdogs Peter Maydell
@ 2018-08-20 14:11 ` Peter Maydell
  2018-08-23 14:18   ` Richard Henderson
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 08/22] hw/misc/iotkit-sysctl: Implement IoTKit system control element Peter Maydell
                   ` (14 subsequent siblings)
  21 siblings, 1 reply; 56+ messages in thread
From: Peter Maydell @ 2018-08-20 14:11 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Philippe Mathieu-Daudé

The IoTKit has a CMSDK timer device that runs on the S32KCLK.
Create this and wire it up.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 include/hw/arm/iotkit.h | 2 +-
 hw/arm/iotkit.c         | 9 +++++----
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h
index 776d0497087..0f5c5101708 100644
--- a/include/hw/arm/iotkit.h
+++ b/include/hw/arm/iotkit.h
@@ -83,6 +83,7 @@ typedef struct IoTKit {
     TZMPC mpc;
     CMSDKAPBTIMER timer0;
     CMSDKAPBTIMER timer1;
+    CMSDKAPBTIMER s32ktimer;
     qemu_or_irq ppc_irq_orgate;
     SplitIRQ sec_resp_splitter;
     SplitIRQ ppc_irq_splitter[NUM_PPCS];
@@ -91,7 +92,6 @@ typedef struct IoTKit {
     qemu_or_irq nmi_orgate;
 
     CMSDKAPBDualTimer dualtimer;
-    UnimplementedDeviceState s32ktimer;
 
     CMSDKAPBWatchdog s32kwatchdog;
     CMSDKAPBWatchdog nswatchdog;
diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
index 5cedfa03570..cb0ec456f39 100644
--- a/hw/arm/iotkit.c
+++ b/hw/arm/iotkit.c
@@ -141,6 +141,8 @@ static void iotkit_init(Object *obj)
                           TYPE_CMSDK_APB_TIMER);
     sysbus_init_child_obj(obj, "timer1", &s->timer1, sizeof(s->timer1),
                           TYPE_CMSDK_APB_TIMER);
+    sysbus_init_child_obj(obj, "s32ktimer", &s->s32ktimer, sizeof(s->s32ktimer),
+                          TYPE_CMSDK_APB_TIMER);
     sysbus_init_child_obj(obj, "dualtimer", &s->dualtimer, sizeof(s->dualtimer),
                           TYPE_CMSDK_APB_DUALTIMER);
     sysbus_init_child_obj(obj, "s32kwatchdog", &s->s32kwatchdog,
@@ -166,8 +168,6 @@ static void iotkit_init(Object *obj)
                                 TYPE_SPLIT_IRQ, &error_abort, NULL);
         g_free(name);
     }
-    sysbus_init_child_obj(obj, "s32ktimer", &s->s32ktimer, sizeof(s->s32ktimer),
-                          TYPE_UNIMPLEMENTED_DEVICE);
 }
 
 static void iotkit_exp_irq(void *opaque, int n, int level)
@@ -476,13 +476,14 @@ static void iotkit_realize(DeviceState *dev, Error **errp)
     /* Devices behind APB PPC1:
      *   0x4002f000: S32K timer
      */
-    qdev_prop_set_string(DEVICE(&s->s32ktimer), "name", "S32KTIMER");
-    qdev_prop_set_uint64(DEVICE(&s->s32ktimer), "size", 0x1000);
+    qdev_prop_set_uint32(DEVICE(&s->s32ktimer), "pclk-frq", S32KCLK);
     object_property_set_bool(OBJECT(&s->s32ktimer), true, "realized", &err);
     if (err) {
         error_propagate(errp, err);
         return;
     }
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32ktimer), 0,
+                       qdev_get_gpio_in(DEVICE(&s->armv7m), 2));
     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->s32ktimer), 0);
     object_property_set_link(OBJECT(&s->apb_ppc1), OBJECT(mr), "port[0]", &err);
     if (err) {
-- 
2.18.0

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

* [Qemu-devel] [PATCH 08/22] hw/misc/iotkit-sysctl: Implement IoTKit system control element
  2018-08-20 14:10 [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI Peter Maydell
                   ` (6 preceding siblings ...)
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 07/22] hw/arm/iotkit: Wire up the S32KTIMER Peter Maydell
@ 2018-08-20 14:11 ` Peter Maydell
  2018-08-23 14:24   ` Richard Henderson
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 09/22] hw/misc/iotkit-sysinfo: Implement IoTKit system information block Peter Maydell
                   ` (13 subsequent siblings)
  21 siblings, 1 reply; 56+ messages in thread
From: Peter Maydell @ 2018-08-20 14:11 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Philippe Mathieu-Daudé

The Arm IoTKit includes a system control element which
provides a block of read-only ID registers and a block
of read-write control registers. Implement a minimal
version of this.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/misc/Makefile.objs           |   1 +
 include/hw/misc/iotkit-sysctl.h |  49 ++++++
 hw/misc/iotkit-sysctl.c         | 261 ++++++++++++++++++++++++++++++++
 MAINTAINERS                     |   2 +
 default-configs/arm-softmmu.mak |   1 +
 hw/misc/trace-events            |   7 +
 6 files changed, 321 insertions(+)
 create mode 100644 include/hw/misc/iotkit-sysctl.h
 create mode 100644 hw/misc/iotkit-sysctl.c

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 22714b08510..ac1f3bc030c 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -66,6 +66,7 @@ obj-$(CONFIG_MPS2_SCC) += mps2-scc.o
 obj-$(CONFIG_TZ_MPC) += tz-mpc.o
 obj-$(CONFIG_TZ_PPC) += tz-ppc.o
 obj-$(CONFIG_IOTKIT_SECCTL) += iotkit-secctl.o
+obj-$(CONFIG_IOTKIT_SYSCTL) += iotkit-sysctl.o
 
 obj-$(CONFIG_PVPANIC) += pvpanic.o
 obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
new file mode 100644
index 00000000000..e36613cb5ee
--- /dev/null
+++ b/include/hw/misc/iotkit-sysctl.h
@@ -0,0 +1,49 @@
+/*
+ * ARM IoTKit system control element
+ *
+ * Copyright (c) 2018 Linaro Limited
+ * Written by Peter Maydell
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 or
+ *  (at your option) any later version.
+ */
+
+/*
+ * This is a model of the "system control element" which is part of the
+ * Arm IoTKit and documented in
+ * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
+ * Specifically, it implements the "system information block" and
+ * "system control register" blocks.
+ *
+ * QEMU interface:
+ *  + sysbus MMIO region 0: the system information register bank
+ *  + sysbus MMIO region 1: the system control register bank
+ */
+
+#ifndef HW_MISC_IOTKIT_SYSCTL_H
+#define HW_MISC_IOTKIT_SYSCTL_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_IOTKIT_SYSCTL "iotkit-sysctl"
+#define IOTKIT_SYSCTL(obj) OBJECT_CHECK(IoTKitSysCtl, (obj), \
+                                        TYPE_IOTKIT_SYSCTL)
+
+typedef struct IoTKitSysCtl {
+    /*< private >*/
+    SysBusDevice parent_obj;
+
+    /*< public >*/
+    MemoryRegion iomem;
+
+    uint32_t secure_debug;
+    uint32_t reset_syndrome;
+    uint32_t reset_mask;
+    uint32_t gretreg;
+    uint32_t initsvrtor0;
+    uint32_t cpuwait;
+    uint32_t wicctrl;
+} IoTKitSysCtl;
+
+#endif
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
new file mode 100644
index 00000000000..a21d8bd6789
--- /dev/null
+++ b/hw/misc/iotkit-sysctl.c
@@ -0,0 +1,261 @@
+/*
+ * ARM IoTKit system control element
+ *
+ * Copyright (c) 2018 Linaro Limited
+ * Written by Peter Maydell
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 or
+ *  (at your option) any later version.
+ */
+
+/*
+ * This is a model of the "system control element" which is part of the
+ * Arm IoTKit and documented in
+ * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
+ * Specifically, it implements the "system control register" blocks.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "trace.h"
+#include "qapi/error.h"
+#include "sysemu/sysemu.h"
+#include "hw/sysbus.h"
+#include "hw/registerfields.h"
+#include "hw/misc/iotkit-sysctl.h"
+
+REG32(SECDBGSTAT, 0x0)
+REG32(SECDBGSET, 0x4)
+REG32(SECDBGCLR, 0x8)
+REG32(RESET_SYNDROME, 0x100)
+REG32(RESET_MASK, 0x104)
+REG32(SWRESET, 0x108)
+    FIELD(SWRESET, SWRESETREQ, 9, 1)
+REG32(GRETREG, 0x10c)
+REG32(INITSVRTOR0, 0x110)
+REG32(CPUWAIT, 0x118)
+REG32(BUSWAIT, 0x11c)
+REG32(WICCTRL, 0x120)
+REG32(PID4, 0xfd0)
+REG32(PID5, 0xfd4)
+REG32(PID6, 0xfd8)
+REG32(PID7, 0xfdc)
+REG32(PID0, 0xfe0)
+REG32(PID1, 0xfe4)
+REG32(PID2, 0xfe8)
+REG32(PID3, 0xfec)
+REG32(CID0, 0xff0)
+REG32(CID1, 0xff4)
+REG32(CID2, 0xff8)
+REG32(CID3, 0xffc)
+
+/* PID/CID values */
+static const int sysctl_id[] = {
+    0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
+    0x54, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
+    0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
+};
+
+static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
+                                    unsigned size)
+{
+    IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
+    uint64_t r;
+
+    switch (offset) {
+    case A_SECDBGSTAT:
+        r = s->secure_debug;
+        break;
+    case A_RESET_SYNDROME:
+        r = s->reset_syndrome;
+        break;
+    case A_RESET_MASK:
+        r = s->reset_mask;
+        break;
+    case A_GRETREG:
+        r = s->gretreg;
+        break;
+    case A_INITSVRTOR0:
+        r = s->initsvrtor0;
+        break;
+    case A_CPUWAIT:
+        r = s->cpuwait;
+        break;
+    case A_BUSWAIT:
+        /* In IoTKit BUSWAIT is reserved, R/O, zero */
+        r = 0;
+        break;
+    case A_WICCTRL:
+        r = s->wicctrl;
+        break;
+    case A_PID4 ... A_CID3:
+        r = sysctl_id[(offset - A_PID4) / 4];
+        break;
+    case A_SECDBGSET:
+    case A_SECDBGCLR:
+    case A_SWRESET:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "IoTKit SysCtl read: read of WO offset %x\n",
+                      (int)offset);
+        r = 0;
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "IoTKit SysCtl read: bad offset %x\n", (int)offset);
+        r = 0;
+        break;
+    }
+    trace_iotkit_sysctl_read(offset, r, size);
+    return r;
+}
+
+static void iotkit_sysctl_write(void *opaque, hwaddr offset,
+                                 uint64_t value, unsigned size)
+{
+    IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
+
+    trace_iotkit_sysctl_write(offset, value, size);
+
+    /*
+     * Most of the state here has to do with control of reset and
+     * similar kinds of power up -- for instance the guest can ask
+     * what the reason for the last reset was, or forbid reset for
+     * some causes (like the non-secure watchdog). Most of this is
+     * not relevant to QEMU, which doesn't really model anything other
+     * than a full power-on reset.
+     * We just model the registers as reads-as-written.
+     */
+
+    switch (offset) {
+    case A_RESET_SYNDROME:
+        qemu_log_mask(LOG_UNIMP,
+                      "IoTKit SysCtl RESET_SYNDROME unimplemented\n");
+        s->reset_syndrome = value;
+        break;
+    case A_RESET_MASK:
+        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl RESET_MASK unimplemented\n");
+        s->reset_mask = value;
+        break;
+    case A_GRETREG:
+        /*
+         * General retention register, which is only reset by a power-on
+         * reset. Technically this implementation is complete, since
+         * QEMU only supports power-on resets...
+         */
+        s->gretreg = value;
+        break;
+    case A_INITSVRTOR0:
+        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl INITSVRTOR0 unimplemented\n");
+        s->initsvrtor0 = value;
+        break;
+    case A_CPUWAIT:
+        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CPUWAIT unimplemented\n");
+        s->cpuwait = value;
+        break;
+    case A_WICCTRL:
+        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl WICCTRL unimplemented\n");
+        s->wicctrl = value;
+        break;
+    case A_SECDBGSET:
+        /* write-1-to-set */
+        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SECDBGSET unimplemented\n");
+        s->secure_debug |= value;
+        break;
+    case A_SECDBGCLR:
+        /* write-1-to-clear */
+        s->secure_debug &= ~value;
+        break;
+    case A_SWRESET:
+        /* One w/o bit to request a reset; all other bits reserved */
+        if (value & R_SWRESET_SWRESETREQ_MASK) {
+            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
+        }
+        break;
+    case A_BUSWAIT:        /* In IoTKit BUSWAIT is reserved, R/O, zero */
+    case A_SECDBGSTAT:
+    case A_PID4 ... A_CID3:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "IoTKit SysCtl write: write of RO offset %x\n",
+                      (int)offset);
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "IoTKit SysCtl write: bad offset %x\n", (int)offset);
+        break;
+    }
+}
+
+static const MemoryRegionOps iotkit_sysctl_ops = {
+    .read = iotkit_sysctl_read,
+    .write = iotkit_sysctl_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    /* byte/halfword accesses are just zero-padded on reads and writes */
+    .impl.min_access_size = 4,
+    .impl.max_access_size = 4,
+    .valid.min_access_size = 1,
+    .valid.max_access_size = 4,
+};
+
+static void iotkit_sysctl_reset(DeviceState *dev)
+{
+    IoTKitSysCtl *s = IOTKIT_SYSCTL(dev);
+
+    trace_iotkit_sysctl_reset();
+    s->secure_debug = 0;
+    s->reset_syndrome = 1;
+    s->reset_mask = 0;
+    s->gretreg = 0;
+    s->initsvrtor0 = 0x10000000;
+    s->cpuwait = 0;
+    s->wicctrl = 0;
+}
+
+static void iotkit_sysctl_init(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    IoTKitSysCtl *s = IOTKIT_SYSCTL(obj);
+
+    memory_region_init_io(&s->iomem, obj, &iotkit_sysctl_ops,
+                          s, "iotkit-sysctl", 0x1000);
+    sysbus_init_mmio(sbd, &s->iomem);
+}
+
+static const VMStateDescription iotkit_sysctl_vmstate = {
+    .name = "iotkit-sysctl",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(secure_debug, IoTKitSysCtl),
+        VMSTATE_UINT32(reset_syndrome, IoTKitSysCtl),
+        VMSTATE_UINT32(reset_mask, IoTKitSysCtl),
+        VMSTATE_UINT32(gretreg, IoTKitSysCtl),
+        VMSTATE_UINT32(initsvrtor0, IoTKitSysCtl),
+        VMSTATE_UINT32(cpuwait, IoTKitSysCtl),
+        VMSTATE_UINT32(wicctrl, IoTKitSysCtl),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void iotkit_sysctl_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->vmsd = &iotkit_sysctl_vmstate;
+    dc->reset = iotkit_sysctl_reset;
+}
+
+static const TypeInfo iotkit_sysctl_info = {
+    .name = TYPE_IOTKIT_SYSCTL,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(IoTKitSysCtl),
+    .instance_init = iotkit_sysctl_init,
+    .class_init = iotkit_sysctl_class_init,
+};
+
+static void iotkit_sysctl_register_types(void)
+{
+    type_register_static(&iotkit_sysctl_info);
+}
+
+type_init(iotkit_sysctl_register_types);
diff --git a/MAINTAINERS b/MAINTAINERS
index 2a4c9d63f2d..ea35aa2cca5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -539,6 +539,8 @@ F: hw/misc/mps2-*.c
 F: include/hw/misc/mps2-*.h
 F: hw/arm/iotkit.c
 F: include/hw/arm/iotkit.h
+F: hw/misc/iotkit-sysctl.c
+F: include/hw/misc/iotkit-sysctl.h
 
 Musicpal
 M: Jan Kiszka <jan.kiszka@web.de>
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index c8137a5d3c7..79aac7702a9 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -114,6 +114,7 @@ CONFIG_TZ_MPC=y
 CONFIG_TZ_PPC=y
 CONFIG_IOTKIT=y
 CONFIG_IOTKIT_SECCTL=y
+CONFIG_IOTKIT_SYSCTL=y
 
 CONFIG_VERSATILE=y
 CONFIG_VERSATILE_PCI=y
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index 1341508b336..7faf7592832 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -116,3 +116,10 @@ ccm_freq(uint32_t freq) "freq = %d\n"
 ccm_clock_freq(uint32_t clock, uint32_t freq) "(Clock = %d) = %d\n"
 ccm_read_reg(const char *reg_name, uint32_t value) "reg[%s] <= 0x%" PRIx32 "\n"
 ccm_write_reg(const char *reg_name, uint32_t value) "reg[%s] => 0x%" PRIx32 "\n"
+
+# hw/misc/iotkit-sysctl.c
+iotkit_sysinfo_read(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysInfo read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+iotkit_sysinfo_write(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysInfo write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+iotkit_sysctl_read(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysCtl read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+iotkit_sysctl_write(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysCtl write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+iotkit_sysctl_reset(void) "IoTKit SysCtl: reset"
-- 
2.18.0

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

* [Qemu-devel] [PATCH 09/22] hw/misc/iotkit-sysinfo: Implement IoTKit system information block
  2018-08-20 14:10 [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI Peter Maydell
                   ` (7 preceding siblings ...)
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 08/22] hw/misc/iotkit-sysctl: Implement IoTKit system control element Peter Maydell
@ 2018-08-20 14:11 ` Peter Maydell
  2018-08-21  6:45   ` Philippe Mathieu-Daudé
  2018-08-23 14:28   ` Richard Henderson
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 10/22] hw/misc/iotkit: Wire up the sysctl and sysinfo register blocks Peter Maydell
                   ` (12 subsequent siblings)
  21 siblings, 2 replies; 56+ messages in thread
From: Peter Maydell @ 2018-08-20 14:11 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Philippe Mathieu-Daudé

Implement the IoTKit system control element's system information
block; this is just a pair of read-only version/config registers,
plus the usual PID/CID ID registers.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/misc/Makefile.objs            |   1 +
 include/hw/misc/iotkit-sysinfo.h |  37 +++++++++
 hw/misc/iotkit-sysinfo.c         | 128 +++++++++++++++++++++++++++++++
 MAINTAINERS                      |   2 +
 default-configs/arm-softmmu.mak  |   1 +
 5 files changed, 169 insertions(+)
 create mode 100644 include/hw/misc/iotkit-sysinfo.h
 create mode 100644 hw/misc/iotkit-sysinfo.c

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index ac1f3bc030c..af2b503824e 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -67,6 +67,7 @@ obj-$(CONFIG_TZ_MPC) += tz-mpc.o
 obj-$(CONFIG_TZ_PPC) += tz-ppc.o
 obj-$(CONFIG_IOTKIT_SECCTL) += iotkit-secctl.o
 obj-$(CONFIG_IOTKIT_SYSCTL) += iotkit-sysctl.o
+obj-$(CONFIG_IOTKIT_SYSINFO) += iotkit-sysinfo.o
 
 obj-$(CONFIG_PVPANIC) += pvpanic.o
 obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h
new file mode 100644
index 00000000000..7b2e1a5e48b
--- /dev/null
+++ b/include/hw/misc/iotkit-sysinfo.h
@@ -0,0 +1,37 @@
+/*
+ * ARM IoTKit system information block
+ *
+ * Copyright (c) 2018 Linaro Limited
+ * Written by Peter Maydell
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 or
+ *  (at your option) any later version.
+ */
+
+/*
+ * This is a model of the "system information block" which is part of the
+ * Arm IoTKit and documented in
+ * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
+ * QEMU interface:
+ *  + sysbus MMIO region 0: the system information register bank
+ */
+
+#ifndef HW_MISC_IOTKIT_SYSINFO_H
+#define HW_MISC_IOTKIT_SYSINFO_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_IOTKIT_SYSINFO "iotkit-sysinfo"
+#define IOTKIT_SYSINFO(obj) OBJECT_CHECK(IoTKitSysInfo, (obj), \
+                                        TYPE_IOTKIT_SYSINFO)
+
+typedef struct IoTKitSysInfo {
+    /*< private >*/
+    SysBusDevice parent_obj;
+
+    /*< public >*/
+    MemoryRegion iomem;
+} IoTKitSysInfo;
+
+#endif
diff --git a/hw/misc/iotkit-sysinfo.c b/hw/misc/iotkit-sysinfo.c
new file mode 100644
index 00000000000..78955bc45f5
--- /dev/null
+++ b/hw/misc/iotkit-sysinfo.c
@@ -0,0 +1,128 @@
+/*
+ * ARM IoTKit system information block
+ *
+ * Copyright (c) 2018 Linaro Limited
+ * Written by Peter Maydell
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 or
+ *  (at your option) any later version.
+ */
+
+/*
+ * This is a model of the "system information block" which is part of the
+ * Arm IoTKit and documented in
+ * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
+ * It consists of 2 read-only version/config registers, plus the
+ * usual ID registers.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "trace.h"
+#include "qapi/error.h"
+#include "sysemu/sysemu.h"
+#include "hw/sysbus.h"
+#include "hw/registerfields.h"
+#include "hw/misc/iotkit-sysinfo.h"
+
+REG32(SYS_VERSION, 0x0)
+REG32(SYS_CONFIG, 0x4)
+REG32(PID4, 0xfd0)
+REG32(PID5, 0xfd4)
+REG32(PID6, 0xfd8)
+REG32(PID7, 0xfdc)
+REG32(PID0, 0xfe0)
+REG32(PID1, 0xfe4)
+REG32(PID2, 0xfe8)
+REG32(PID3, 0xfec)
+REG32(CID0, 0xff0)
+REG32(CID1, 0xff4)
+REG32(CID2, 0xff8)
+REG32(CID3, 0xffc)
+
+/* PID/CID values */
+static const int sysinfo_id[] = {
+    0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
+    0x58, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
+    0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
+};
+
+static uint64_t iotkit_sysinfo_read(void *opaque, hwaddr offset,
+                                    unsigned size)
+{
+    uint64_t r;
+
+    switch (offset) {
+    case A_SYS_VERSION:
+        r = 0x41743;
+        break;
+
+    case A_SYS_CONFIG:
+        r = 0x31;
+        break;
+    case A_PID4 ... A_CID3:
+        r = sysinfo_id[(offset - A_PID4) / 4];
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "IoTKit SysInfo read: bad offset %x\n", (int)offset);
+        r = 0;
+        break;
+    }
+    trace_iotkit_sysinfo_read(offset, r, size);
+    return r;
+}
+
+static void iotkit_sysinfo_write(void *opaque, hwaddr offset,
+                                 uint64_t value, unsigned size)
+{
+    trace_iotkit_sysinfo_write(offset, value, size);
+
+    qemu_log_mask(LOG_GUEST_ERROR,
+                  "IoTKit SysInfo: write to RO offset 0x%x\n", (int)offset);
+}
+
+static const MemoryRegionOps iotkit_sysinfo_ops = {
+    .read = iotkit_sysinfo_read,
+    .write = iotkit_sysinfo_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    /* byte/halfword accesses are just zero-padded on reads and writes */
+    .impl.min_access_size = 4,
+    .impl.max_access_size = 4,
+    .valid.min_access_size = 1,
+    .valid.max_access_size = 4,
+};
+
+static void iotkit_sysinfo_init(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    IoTKitSysInfo *s = IOTKIT_SYSINFO(obj);
+
+    memory_region_init_io(&s->iomem, obj, &iotkit_sysinfo_ops,
+                          s, "iotkit-sysinfo", 0x1000);
+    sysbus_init_mmio(sbd, &s->iomem);
+}
+
+static void iotkit_sysinfo_class_init(ObjectClass *klass, void *data)
+{
+    /*
+     * This device has no guest-modifiable state and so it
+     * does not need a reset function or VMState.
+     */
+}
+
+static const TypeInfo iotkit_sysinfo_info = {
+    .name = TYPE_IOTKIT_SYSINFO,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(IoTKitSysInfo),
+    .instance_init = iotkit_sysinfo_init,
+    .class_init = iotkit_sysinfo_class_init,
+};
+
+static void iotkit_sysinfo_register_types(void)
+{
+    type_register_static(&iotkit_sysinfo_info);
+}
+
+type_init(iotkit_sysinfo_register_types);
diff --git a/MAINTAINERS b/MAINTAINERS
index ea35aa2cca5..cb780f463cb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -541,6 +541,8 @@ F: hw/arm/iotkit.c
 F: include/hw/arm/iotkit.h
 F: hw/misc/iotkit-sysctl.c
 F: include/hw/misc/iotkit-sysctl.h
+F: hw/misc/iotkit-sysinfo.c
+F: include/hw/misc/iotkit-sysinfo.h
 
 Musicpal
 M: Jan Kiszka <jan.kiszka@web.de>
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 79aac7702a9..ebbdcb29f38 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -115,6 +115,7 @@ CONFIG_TZ_PPC=y
 CONFIG_IOTKIT=y
 CONFIG_IOTKIT_SECCTL=y
 CONFIG_IOTKIT_SYSCTL=y
+CONFIG_IOTKIT_SYSINFO=y
 
 CONFIG_VERSATILE=y
 CONFIG_VERSATILE_PCI=y
-- 
2.18.0

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

* [Qemu-devel] [PATCH 10/22] hw/misc/iotkit: Wire up the sysctl and sysinfo register blocks
  2018-08-20 14:10 [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI Peter Maydell
                   ` (8 preceding siblings ...)
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 09/22] hw/misc/iotkit-sysinfo: Implement IoTKit system information block Peter Maydell
@ 2018-08-20 14:11 ` Peter Maydell
  2018-08-21  6:47   ` Philippe Mathieu-Daudé
  2018-08-23 14:29   ` Richard Henderson
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 11/22] hw/misc/tz-msc: Model TrustZone Master Security Controller Peter Maydell
                   ` (11 subsequent siblings)
  21 siblings, 2 replies; 56+ messages in thread
From: Peter Maydell @ 2018-08-20 14:11 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Philippe Mathieu-Daudé

Wire up the system control element's register banks
(sysctl and sysinfo).

This is the last of the previously completely unimplemented
components in the IoTKit.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/arm/iotkit.h |  6 +++++-
 hw/arm/iotkit.c         | 26 ++++++++++++++++++--------
 2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h
index 0f5c5101708..426dc326a0d 100644
--- a/include/hw/arm/iotkit.h
+++ b/include/hw/arm/iotkit.h
@@ -58,7 +58,8 @@
 #include "hw/timer/cmsdk-apb-timer.h"
 #include "hw/timer/cmsdk-apb-dualtimer.h"
 #include "hw/watchdog/cmsdk-apb-watchdog.h"
-#include "hw/misc/unimp.h"
+#include "hw/misc/iotkit-sysctl.h"
+#include "hw/misc/iotkit-sysinfo.h"
 #include "hw/or-irq.h"
 #include "hw/core/split-irq.h"
 
@@ -97,6 +98,9 @@ typedef struct IoTKit {
     CMSDKAPBWatchdog nswatchdog;
     CMSDKAPBWatchdog swatchdog;
 
+    IoTKitSysCtl sysctl;
+    IoTKitSysCtl sysinfo;
+
     MemoryRegion container;
     MemoryRegion alias1;
     MemoryRegion alias2;
diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
index cb0ec456f39..f8276b5425c 100644
--- a/hw/arm/iotkit.c
+++ b/hw/arm/iotkit.c
@@ -16,7 +16,6 @@
 #include "hw/sysbus.h"
 #include "hw/registerfields.h"
 #include "hw/arm/iotkit.h"
-#include "hw/misc/unimp.h"
 #include "hw/arm/arm.h"
 
 /* Clock frequency in HZ of the 32KHz "slow clock" */
@@ -151,6 +150,10 @@ static void iotkit_init(Object *obj)
                           sizeof(s->nswatchdog), TYPE_CMSDK_APB_WATCHDOG);
     sysbus_init_child_obj(obj, "swatchdog", &s->swatchdog,
                           sizeof(s->swatchdog), TYPE_CMSDK_APB_WATCHDOG);
+    sysbus_init_child_obj(obj, "iotkit-sysctl", &s->sysctl,
+                          sizeof(s->sysctl), TYPE_IOTKIT_SYSCTL);
+    sysbus_init_child_obj(obj, "iotkit-sysinfo", &s->sysinfo,
+                          sizeof(s->sysinfo), TYPE_IOTKIT_SYSINFO);
     object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
                             sizeof(s->nmi_orgate), TYPE_OR_IRQ,
                             &error_abort, NULL);
@@ -516,13 +519,20 @@ static void iotkit_realize(DeviceState *dev, Error **errp)
                           qdev_get_gpio_in_named(dev_apb_ppc1,
                                                  "cfg_sec_resp", 0));
 
-    /* Using create_unimplemented_device() maps the stub into the
-     * system address space rather than into our container, but the
-     * overall effect to the guest is the same.
-     */
-    create_unimplemented_device("SYSINFO", 0x40020000, 0x1000);
-
-    create_unimplemented_device("SYSCONTROL", 0x50021000, 0x1000);
+    object_property_set_bool(OBJECT(&s->sysinfo), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    /* System information registers */
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysinfo), 0, 0x40020000);
+    /* System control registers */
+    object_property_set_bool(OBJECT(&s->sysctl), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysctl), 0, 0x50021000);
 
     /* This OR gate wires together outputs from the secure watchdogs to NMI */
     object_property_set_int(OBJECT(&s->nmi_orgate), 2, "num-lines", &err);
-- 
2.18.0

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

* [Qemu-devel] [PATCH 11/22] hw/misc/tz-msc: Model TrustZone Master Security Controller
  2018-08-20 14:10 [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI Peter Maydell
                   ` (9 preceding siblings ...)
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 10/22] hw/misc/iotkit: Wire up the sysctl and sysinfo register blocks Peter Maydell
@ 2018-08-20 14:11 ` Peter Maydell
  2018-08-23 17:18   ` Richard Henderson
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 12/22] hw/misc/iotkit-secctl: Wire up registers for controlling MSCs Peter Maydell
                   ` (10 subsequent siblings)
  21 siblings, 1 reply; 56+ messages in thread
From: Peter Maydell @ 2018-08-20 14:11 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Philippe Mathieu-Daudé

Implement a model of the TrustZone Master Securtiy Controller,
as documented in the Arm CoreLink SIE-200 System IP for
Embedded TRM  (DDI0571G):
  https://developer.arm.com/products/architecture/m-profile/docs/ddi0571/g

The MSC is intended to sit in front of a device which can
be a bus master (eg a DMA controller) and programmably gate
its transactions. This allows a bus-mastering device to be
controlled by non-secure code but still restricted from
making accesses to addresses which are secure-only.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/misc/Makefile.objs           |   1 +
 include/hw/misc/tz-msc.h        |  79 ++++++++
 hw/misc/tz-msc.c                | 308 ++++++++++++++++++++++++++++++++
 MAINTAINERS                     |   2 +
 default-configs/arm-softmmu.mak |   1 +
 hw/misc/trace-events            |   9 +
 6 files changed, 400 insertions(+)
 create mode 100644 include/hw/misc/tz-msc.h
 create mode 100644 hw/misc/tz-msc.c

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index af2b503824e..6d50b03cfdb 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -64,6 +64,7 @@ obj-$(CONFIG_MPS2_FPGAIO) += mps2-fpgaio.o
 obj-$(CONFIG_MPS2_SCC) += mps2-scc.o
 
 obj-$(CONFIG_TZ_MPC) += tz-mpc.o
+obj-$(CONFIG_TZ_MSC) += tz-msc.o
 obj-$(CONFIG_TZ_PPC) += tz-ppc.o
 obj-$(CONFIG_IOTKIT_SECCTL) += iotkit-secctl.o
 obj-$(CONFIG_IOTKIT_SYSCTL) += iotkit-sysctl.o
diff --git a/include/hw/misc/tz-msc.h b/include/hw/misc/tz-msc.h
new file mode 100644
index 00000000000..116b96ae9b8
--- /dev/null
+++ b/include/hw/misc/tz-msc.h
@@ -0,0 +1,79 @@
+/*
+ * ARM TrustZone master security controller emulation
+ *
+ * Copyright (c) 2018 Linaro Limited
+ * Written by Peter Maydell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 or
+ * (at your option) any later version.
+ */
+
+/*
+ * This is a model of the TrustZone master security controller (MSC).
+ * It is documented in the ARM CoreLink SIE-200 System IP for Embedded TRM
+ * (DDI 0571G):
+ * https://developer.arm.com/products/architecture/m-profile/docs/ddi0571/g
+ *
+ * The MSC sits in front of a device which can be a bus master (such as
+ * a DMA controller) and allows secure software to configure it to either
+ * pass through or reject transactions made by that bus master.
+ * Rejected transactions may be configured to either be aborted, or to
+ * behave as RAZ/WI. An interrupt can be signalled for a rejected transaction.
+ *
+ * The MSC has no register interface -- it is configured purely by a
+ * collection of input signals from other hardware in the system. Typically
+ * they are either hardwired or exposed in an ad-hoc register interface by
+ * the SoC that uses the MSC.
+ *
+ * We don't currently implement the irq_enable GPIO input, because on
+ * the MPS2 FPGA images it is always tied high, which is awkward to
+ * implement in QEMU.
+ *
+ * QEMU interface:
+ * + Named GPIO input "cfg_nonsec": set to 1 if the bus master should be
+ *   treated as nonsecure, or 0 for secure
+ * + Named GPIO input "cfg_sec_resp": set to 1 if a rejected transaction should
+ *   result in a transaction error, or 0 for the transaction to RAZ/WI
+ * + Named GPIO input "irq_clear": set to 1 to clear a pending interrupt
+ * + Named GPIO output "irq": set for a transaction-failed interrupt
+ * + Property "downstream": MemoryRegion defining where bus master transactions
+ *   are made if they are not blocked
+ * + Property "idau": an object implementing IDAUInterface, which defines which
+ *   addresses should be treated as secure and which as non-secure.
+ *   This need not be the same IDAU as the one used by the CPU.
+ * + sysbus MMIO region 0: MemoryRegion defining the upstream end of the MSC;
+ *   this should be passed to the bus master device as the region it should
+ *   make memory transactions to
+ */
+
+#ifndef TZ_MSC_H
+#define TZ_MSC_H
+
+#include "hw/sysbus.h"
+#include "target/arm/idau.h"
+
+#define TYPE_TZ_MSC "tz-msc"
+#define TZ_MSC(obj) OBJECT_CHECK(TZMSC, (obj), TYPE_TZ_MSC)
+
+typedef struct TZMSC {
+    /*< private >*/
+    SysBusDevice parent_obj;
+
+    /*< public >*/
+
+    /* State: these just track the values of our input signals */
+    bool cfg_nonsec;
+    bool cfg_sec_resp;
+    bool irq_clear;
+    /* State: are we asserting irq ? */
+    bool irq_status;
+
+    qemu_irq irq;
+    MemoryRegion *downstream;
+    AddressSpace downstream_as;
+    MemoryRegion upstream;
+    IDAUInterface *idau;
+} TZMSC;
+
+#endif
diff --git a/hw/misc/tz-msc.c b/hw/misc/tz-msc.c
new file mode 100644
index 00000000000..9e352044ea5
--- /dev/null
+++ b/hw/misc/tz-msc.c
@@ -0,0 +1,308 @@
+/*
+ * ARM TrustZone master security controller emulation
+ *
+ * Copyright (c) 2018 Linaro Limited
+ * Written by Peter Maydell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 or
+ * (at your option) any later version.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "trace.h"
+#include "hw/sysbus.h"
+#include "hw/registerfields.h"
+#include "hw/misc/tz-msc.h"
+
+static void tz_msc_update_irq(TZMSC *s)
+{
+    bool level = s->irq_status;
+
+    trace_tz_msc_update_irq(level);
+    qemu_set_irq(s->irq, level);
+}
+
+static void tz_msc_cfg_nonsec(void *opaque, int n, int level)
+{
+    TZMSC *s = TZ_MSC(opaque);
+
+    trace_tz_msc_cfg_nonsec(level);
+    s->cfg_nonsec = level;
+}
+
+static void tz_msc_cfg_sec_resp(void *opaque, int n, int level)
+{
+    TZMSC *s = TZ_MSC(opaque);
+
+    trace_tz_msc_cfg_sec_resp(level);
+    s->cfg_sec_resp = level;
+}
+
+static void tz_msc_irq_clear(void *opaque, int n, int level)
+{
+    TZMSC *s = TZ_MSC(opaque);
+
+    trace_tz_msc_irq_clear(level);
+
+    s->irq_clear = level;
+    if (level) {
+        s->irq_status = false;
+        tz_msc_update_irq(s);
+    }
+}
+
+/* The MSC may either block a transaction by aborting it, block a
+ * transaction by making it RAZ/WI, allow it through with
+ * MemTxAttrs indicating a secure transaction, or allow it with
+ * MemTxAttrs indicating a non-secure transaction.
+ */
+typedef enum MSCAction {
+    MSCBlockAbort,
+    MSCBlockRAZWI,
+    MSCAllowSecure,
+    MSCAllowNonSecure,
+} MSCAction;
+
+static MSCAction tz_msc_check(TZMSC *s, hwaddr addr)
+{
+    /*
+     * Check whether to allow an access from the bus master, returning
+     * an MSCAction indicating the required behaviour. If the transaction
+     * is blocked, the caller must check cfg_sec_resp to determine
+     * whether to abort or RAZ/WI the transaction.
+     */
+    IDAUInterfaceClass *iic = IDAU_INTERFACE_GET_CLASS(s->idau);
+    IDAUInterface *ii = IDAU_INTERFACE(s->idau);
+    bool idau_exempt = false, idau_ns = true, idau_nsc = true;
+    int idau_region = IREGION_NOTVALID;
+
+    iic->check(ii, addr, &idau_region, &idau_exempt, &idau_ns, &idau_nsc);
+
+    if (idau_exempt) {
+        /*
+         * Uncheck region -- OK, transaction type depends on
+         * whether bus master is configured as Secure or NonSecure
+         */
+        return s->cfg_nonsec ? MSCAllowNonSecure : MSCAllowSecure;
+    }
+
+    if (idau_ns) {
+        /* NonSecure region -- always forward as NS transaction */
+        return MSCAllowNonSecure;
+    }
+
+    if (!s->cfg_nonsec) {
+        /* Access to Secure region by Secure bus master: OK */
+        return MSCAllowSecure;
+    }
+
+    /* Attempted access to Secure region by NS bus master: block */
+    trace_tz_msc_access_blocked(addr);
+    if (!s->cfg_sec_resp) {
+        return MSCBlockRAZWI;
+    }
+
+    /*
+     * The TRM isn't clear on behaviour if irq_clear is high when a
+     * transaction is blocked. We assume that the MSC behaves like the
+     * PPC, where holding irq_clear high suppresses the interrupt.
+     */
+    if (!s->irq_clear) {
+        s->irq_status = true;
+        tz_msc_update_irq(s);
+    }
+    return MSCBlockAbort;
+}
+
+static MemTxResult tz_msc_read(void *opaque, hwaddr addr, uint64_t *pdata,
+                               unsigned size, MemTxAttrs attrs)
+{
+    TZMSC *s = opaque;
+    AddressSpace *as = &s->downstream_as;
+    uint64_t data;
+    MemTxResult res;
+
+    switch (tz_msc_check(s, addr)) {
+    case MSCBlockAbort:
+        return MEMTX_ERROR;
+    case MSCBlockRAZWI:
+        *pdata = 0;
+        return MEMTX_OK;
+    case MSCAllowSecure:
+        attrs.secure = 1;
+        attrs.unspecified = 0;
+        break;
+    case MSCAllowNonSecure:
+        attrs.secure = 0;
+        attrs.unspecified = 0;
+        break;
+    }
+
+    switch (size) {
+    case 1:
+        data = address_space_ldub(as, addr, attrs, &res);
+        break;
+    case 2:
+        data = address_space_lduw_le(as, addr, attrs, &res);
+        break;
+    case 4:
+        data = address_space_ldl_le(as, addr, attrs, &res);
+        break;
+    case 8:
+        data = address_space_ldq_le(as, addr, attrs, &res);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    *pdata = data;
+    return res;
+}
+
+static MemTxResult tz_msc_write(void *opaque, hwaddr addr, uint64_t val,
+                                unsigned size, MemTxAttrs attrs)
+{
+    TZMSC *s = opaque;
+    AddressSpace *as = &s->downstream_as;
+    MemTxResult res;
+
+    switch (tz_msc_check(s, addr)) {
+    case MSCBlockAbort:
+        return MEMTX_ERROR;
+    case MSCBlockRAZWI:
+        return MEMTX_OK;
+    case MSCAllowSecure:
+        attrs.secure = 1;
+        attrs.unspecified = 0;
+        break;
+    case MSCAllowNonSecure:
+        attrs.secure = 0;
+        attrs.unspecified = 0;
+        break;
+    }
+
+    switch (size) {
+    case 1:
+        address_space_stb(as, addr, val, attrs, &res);
+        break;
+    case 2:
+        address_space_stw_le(as, addr, val, attrs, &res);
+        break;
+    case 4:
+        address_space_stl_le(as, addr, val, attrs, &res);
+        break;
+    case 8:
+        address_space_stq_le(as, addr, val, attrs, &res);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    return res;
+}
+
+static const MemoryRegionOps tz_msc_ops = {
+    .read_with_attrs = tz_msc_read,
+    .write_with_attrs = tz_msc_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void tz_msc_reset(DeviceState *dev)
+{
+    TZMSC *s = TZ_MSC(dev);
+
+    trace_tz_msc_reset();
+    s->cfg_sec_resp = false;
+    s->cfg_nonsec = false;
+    s->irq_clear = 0;
+    s->irq_status = 0;
+}
+
+static void tz_msc_init(Object *obj)
+{
+    DeviceState *dev = DEVICE(obj);
+    TZMSC *s = TZ_MSC(obj);
+
+    qdev_init_gpio_in_named(dev, tz_msc_cfg_nonsec, "cfg_nonsec", 1);
+    qdev_init_gpio_in_named(dev, tz_msc_cfg_sec_resp, "cfg_sec_resp", 1);
+    qdev_init_gpio_in_named(dev, tz_msc_irq_clear, "irq_clear", 1);
+    qdev_init_gpio_out_named(dev, &s->irq, "irq", 1);
+}
+
+static void tz_msc_realize(DeviceState *dev, Error **errp)
+{
+    Object *obj = OBJECT(dev);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+    TZMSC *s = TZ_MSC(dev);
+    const char *name = "tz-msc-downstream";
+    uint64_t size;
+
+    /*
+     * We can't create the upstream end of the port until realize,
+     * as we don't know the size of the MR used as the downstream until then.
+     * We insist on having a downstream, to avoid complicating the
+     * code with handling the "don't know how big this is" case. It's easy
+     * enough for the user to create an unimplemented_device as downstream
+     * if they have nothing else to plug into this.
+     */
+    if (!s->downstream) {
+        error_setg(errp, "MSC 'downstream' link not set");
+        return;
+    }
+    if (!s->idau) {
+        error_setg(errp, "MSC 'idau' link not set");
+        return;
+    }
+
+    size = memory_region_size(s->downstream);
+    address_space_init(&s->downstream_as, s->downstream, name);
+    memory_region_init_io(&s->upstream, obj, &tz_msc_ops, s, name, size);
+    sysbus_init_mmio(sbd, &s->upstream);
+}
+
+static const VMStateDescription tz_msc_vmstate = {
+    .name = "tz-msc",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_BOOL(cfg_nonsec, TZMSC),
+        VMSTATE_BOOL(cfg_sec_resp, TZMSC),
+        VMSTATE_BOOL(irq_clear, TZMSC),
+        VMSTATE_BOOL(irq_status, TZMSC),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static Property tz_msc_properties[] = {
+    DEFINE_PROP_LINK("downstream", TZMSC, downstream,
+                     TYPE_MEMORY_REGION, MemoryRegion *),
+    DEFINE_PROP_LINK("idau", TZMSC, idau,
+                     TYPE_IDAU_INTERFACE, IDAUInterface *),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void tz_msc_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = tz_msc_realize;
+    dc->vmsd = &tz_msc_vmstate;
+    dc->reset = tz_msc_reset;
+    dc->props = tz_msc_properties;
+}
+
+static const TypeInfo tz_msc_info = {
+    .name = TYPE_TZ_MSC,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(TZMSC),
+    .instance_init = tz_msc_init,
+    .class_init = tz_msc_class_init,
+};
+
+static void tz_msc_register_types(void)
+{
+    type_register_static(&tz_msc_info);
+}
+
+type_init(tz_msc_register_types);
diff --git a/MAINTAINERS b/MAINTAINERS
index cb780f463cb..b2f8b562dc5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -465,6 +465,8 @@ F: hw/misc/tz-ppc.c
 F: include/hw/misc/tz-ppc.h
 F: hw/misc/tz-mpc.c
 F: include/hw/misc/tz-mpc.h
+F: hw/misc/tz-msc.c
+F: include/hw/misc/tz-msc.h
 
 ARM cores
 M: Peter Maydell <peter.maydell@linaro.org>
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index ebbdcb29f38..0483d548d96 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -111,6 +111,7 @@ CONFIG_MPS2_FPGAIO=y
 CONFIG_MPS2_SCC=y
 
 CONFIG_TZ_MPC=y
+CONFIG_TZ_MSC=y
 CONFIG_TZ_PPC=y
 CONFIG_IOTKIT=y
 CONFIG_IOTKIT_SECCTL=y
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index 7faf7592832..52466c77c4e 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -92,6 +92,15 @@ tz_mpc_mem_blocked_write(uint64_t addr, uint64_t data, unsigned size, bool secur
 tz_mpc_translate(uint64_t addr, int flags, const char *idx, const char *res) "TZ MPC translate: addr 0x%" PRIx64 " flags 0x%x iommu_idx %s: %s"
 tz_mpc_iommu_notify(uint64_t addr) "TZ MPC iommu: notifying UNMAP/MAP for 0x%" PRIx64
 
+# hw/misc/tz-msc.c
+tz_msc_reset(void) "TZ MSC: reset"
+tz_msc_cfg_nonsec(int level) "TZ MSC: cfg_nonsec = %d"
+tz_msc_cfg_sec_resp(int level) "TZ MSC: cfg_sec_resp = %d"
+tz_msc_irq_enable(int level) "TZ MSC: int_enable = %d"
+tz_msc_irq_clear(int level) "TZ MSC: int_clear = %d"
+tz_msc_update_irq(int level) "TZ MSC: setting irq line to %d"
+tz_msc_access_blocked(uint64_t offset) "TZ MSC: offset 0x%" PRIx64 " access blocked"
+
 # hw/misc/tz-ppc.c
 tz_ppc_reset(void) "TZ PPC: reset"
 tz_ppc_cfg_nonsec(int n, int level) "TZ PPC: cfg_nonsec[%d] = %d"
-- 
2.18.0

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

* [Qemu-devel] [PATCH 12/22] hw/misc/iotkit-secctl: Wire up registers for controlling MSCs
  2018-08-20 14:10 [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI Peter Maydell
                   ` (10 preceding siblings ...)
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 11/22] hw/misc/tz-msc: Model TrustZone Master Security Controller Peter Maydell
@ 2018-08-20 14:11 ` Peter Maydell
  2018-08-23 17:21   ` Richard Henderson
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 13/22] hw/arm/iotkit: Wire up the lines for MSCs Peter Maydell
                   ` (9 subsequent siblings)
  21 siblings, 1 reply; 56+ messages in thread
From: Peter Maydell @ 2018-08-20 14:11 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Philippe Mathieu-Daudé

The IoTKit does not have any Master Security Contollers itself,
but it does provide registers in the secure privilege control
block which allow control of MSCs in the external system.
Add support for these registers.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 include/hw/misc/iotkit-secctl.h | 14 +++++++
 hw/misc/iotkit-secctl.c         | 73 +++++++++++++++++++++++++++++----
 2 files changed, 79 insertions(+), 8 deletions(-)

diff --git a/include/hw/misc/iotkit-secctl.h b/include/hw/misc/iotkit-secctl.h
index 082c14c925e..1a193b306f1 100644
--- a/include/hw/misc/iotkit-secctl.h
+++ b/include/hw/misc/iotkit-secctl.h
@@ -19,6 +19,7 @@
  *  + named GPIO output "sec_resp_cfg" indicating whether blocked accesses
  *    should RAZ/WI or bus error
  *  + named GPIO output "nsc_cfg" whose value tracks the NSCCFG register value
+ *  + named GPIO output "msc_irq" for the combined IRQ line from the MSCs
  * Controlling the 2 APB PPCs in the IoTKit:
  *  + named GPIO outputs apb_ppc0_nonsec[0..2] and apb_ppc1_nonsec
  *  + named GPIO outputs apb_ppc0_ap[0..2] and apb_ppc1_ap
@@ -44,6 +45,11 @@
  * Controlling each of the 16 expansion MPCs which a system using the IoTKit
  * might provide:
  *  + named GPIO inputs mpcexp_status[0..15]
+ * Controlling each of the 16 expansion MSCs which a system using the IoTKit
+ * might provide:
+ *  + named GPIO inputs mscexp_status[0..15]
+ *  + named GPIO outputs mscexp_clear[0..15]
+ *  + named GPIO outputs mscexp_ns[0..15]
  */
 
 #ifndef IOTKIT_SECCTL_H
@@ -62,6 +68,7 @@
 #define IOTS_NUM_AHB_EXP_PPC 4
 #define IOTS_NUM_EXP_MPC 16
 #define IOTS_NUM_MPC 1
+#define IOTS_NUM_EXP_MSC 16
 
 typedef struct IoTKitSecCtl IoTKitSecCtl;
 
@@ -103,6 +110,13 @@ struct IoTKitSecCtl {
     uint32_t brginten;
     uint32_t mpcintstatus;
 
+    uint32_t secmscintstat;
+    uint32_t secmscinten;
+    uint32_t nsmscexp;
+    qemu_irq mscexp_clear[IOTS_NUM_EXP_MSC];
+    qemu_irq mscexp_ns[IOTS_NUM_EXP_MSC];
+    qemu_irq msc_irq;
+
     IoTKitSecCtlPPC apb[IOTS_NUM_APB_PPC];
     IoTKitSecCtlPPC apbexp[IOTS_NUM_APB_EXP_PPC];
     IoTKitSecCtlPPC ahbexp[IOTS_NUM_APB_EXP_PPC];
diff --git a/hw/misc/iotkit-secctl.c b/hw/misc/iotkit-secctl.c
index de4fd8e36d2..2222b3e147d 100644
--- a/hw/misc/iotkit-secctl.c
+++ b/hw/misc/iotkit-secctl.c
@@ -190,12 +190,13 @@ static MemTxResult iotkit_secctl_s_read(void *opaque, hwaddr addr,
         r = s->apbexp[offset_to_ppc_idx(offset)].sp;
         break;
     case A_SECMSCINTSTAT:
+        r = s->secmscintstat;
+        break;
     case A_SECMSCINTEN:
+        r = s->secmscinten;
+        break;
     case A_NSMSCEXP:
-        qemu_log_mask(LOG_UNIMP,
-                      "IoTKit SecCtl S block read: "
-                      "unimplemented offset 0x%x\n", offset);
-        r = 0;
+        r = s->nsmscexp;
         break;
     case A_PID4:
     case A_PID5:
@@ -291,6 +292,23 @@ static void iotkit_secctl_ppc_update_irq_enable(IoTKitSecCtlPPC *ppc)
     qemu_set_irq(ppc->irq_enable, extract32(value, ppc->irq_bit_offset, 1));
 }
 
+static void iotkit_secctl_update_mscexp_irqs(qemu_irq *msc_irqs, uint32_t value)
+{
+    int i;
+
+    for (i = 0; i < IOTS_NUM_EXP_MSC; i++) {
+        qemu_set_irq(msc_irqs[i], extract32(value, i + 16, 1));
+    }
+}
+
+static void iotkit_secctl_update_msc_irq(IoTKitSecCtl *s)
+{
+    /* Update the combined MSC IRQ, based on S_MSCEXP_STATUS and S_MSCEXP_EN */
+    bool level = s->secmscintstat & s->secmscinten;
+
+    qemu_set_irq(s->msc_irq, level);
+}
+
 static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr,
                                          uint64_t value,
                                          unsigned size, MemTxAttrs attrs)
@@ -370,10 +388,15 @@ static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr,
         iotkit_secctl_ppc_sp_write(ppc, value);
         break;
     case A_SECMSCINTCLR:
+        iotkit_secctl_update_mscexp_irqs(s->mscexp_clear, value);
+        break;
     case A_SECMSCINTEN:
-        qemu_log_mask(LOG_UNIMP,
-                      "IoTKit SecCtl S block write: "
-                      "unimplemented offset 0x%x\n", offset);
+        s->secmscinten = value;
+        iotkit_secctl_update_msc_irq(s);
+        break;
+    case A_NSMSCEXP:
+        s->nsmscexp = value;
+        iotkit_secctl_update_mscexp_irqs(s->mscexp_ns, value);
         break;
     case A_SECMPCINTSTATUS:
     case A_SECPPCINTSTAT:
@@ -381,7 +404,6 @@ static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr,
     case A_BRGINTSTAT:
     case A_AHBNSPPC0:
     case A_AHBSPPPC0:
-    case A_NSMSCEXP:
     case A_PID4:
     case A_PID5:
     case A_PID6:
@@ -588,6 +610,14 @@ static void iotkit_secctl_mpcexp_status(void *opaque, int n, int level)
     s->mpcintstatus = deposit32(s->mpcintstatus, n + 16, 1, !!level);
 }
 
+static void iotkit_secctl_mscexp_status(void *opaque, int n, int level)
+{
+    IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
+
+    s->secmscintstat = deposit32(s->secmscintstat, n + 16, 1, !!level);
+    iotkit_secctl_update_msc_irq(s);
+}
+
 static void iotkit_secctl_ppc_irqstatus(void *opaque, int n, int level)
 {
     IoTKitSecCtlPPC *ppc = opaque;
@@ -660,6 +690,14 @@ static void iotkit_secctl_init(Object *obj)
     qdev_init_gpio_in_named(dev, iotkit_secctl_mpcexp_status,
                             "mpcexp_status", IOTS_NUM_EXP_MPC);
 
+    qdev_init_gpio_in_named(dev, iotkit_secctl_mscexp_status,
+                            "mscexp_status", IOTS_NUM_EXP_MSC);
+    qdev_init_gpio_out_named(dev, s->mscexp_clear, "mscexp_clear",
+                             IOTS_NUM_EXP_MSC);
+    qdev_init_gpio_out_named(dev, s->mscexp_ns, "mscexp_ns",
+                             IOTS_NUM_EXP_MSC);
+    qdev_init_gpio_out_named(dev, &s->msc_irq, "msc_irq", 1);
+
     memory_region_init_io(&s->s_regs, obj, &iotkit_secctl_s_ops,
                           s, "iotkit-secctl-s-regs", 0x1000);
     memory_region_init_io(&s->ns_regs, obj, &iotkit_secctl_ns_ops,
@@ -690,6 +728,24 @@ static const VMStateDescription iotkit_secctl_mpcintstatus_vmstate = {
     }
 };
 
+static bool needed_always(void *opaque)
+{
+    return true;
+}
+
+static const VMStateDescription iotkit_secctl_msc_vmstate = {
+    .name = "iotkit-secctl/msc",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = needed_always,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(secmscintstat, IoTKitSecCtl),
+        VMSTATE_UINT32(secmscinten, IoTKitSecCtl),
+        VMSTATE_UINT32(nsmscexp, IoTKitSecCtl),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static const VMStateDescription iotkit_secctl_vmstate = {
     .name = "iotkit-secctl",
     .version_id = 1,
@@ -710,6 +766,7 @@ static const VMStateDescription iotkit_secctl_vmstate = {
     },
     .subsections = (const VMStateDescription*[]) {
         &iotkit_secctl_mpcintstatus_vmstate,
+        &iotkit_secctl_msc_vmstate,
         NULL
     },
 };
-- 
2.18.0

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

* [Qemu-devel] [PATCH 13/22] hw/arm/iotkit: Wire up the lines for MSCs
  2018-08-20 14:10 [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI Peter Maydell
                   ` (11 preceding siblings ...)
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 12/22] hw/misc/iotkit-secctl: Wire up registers for controlling MSCs Peter Maydell
@ 2018-08-20 14:11 ` Peter Maydell
  2018-08-23 17:23   ` Richard Henderson
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 14/22] hw/arm/mps2-tz: Create PL081s and MSCs Peter Maydell
                   ` (8 subsequent siblings)
  21 siblings, 1 reply; 56+ messages in thread
From: Peter Maydell @ 2018-08-20 14:11 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Philippe Mathieu-Daudé

The IoTKit doesn't have any MSCs itself but it does need
some wiring to connect the external signals from MSCs
in the outer board model up to the registers and the
NVIC IRQ line.

We also need to expose a MemoryRegion corresponding to
the AHB bus, so that MSCs in the outer board model can
use that as their downstream port. (In the FPGA this is
the "AHB Slave Expansion" ports shown in the block
diagram in the AN505 documentation.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 include/hw/arm/iotkit.h |  8 ++++++++
 hw/arm/iotkit.c         | 15 +++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h
index 426dc326a0d..3a8ee639085 100644
--- a/include/hw/arm/iotkit.h
+++ b/include/hw/arm/iotkit.h
@@ -28,6 +28,9 @@
  *  + QOM property "EXP_NUMIRQ" sets the number of expansion interrupts
  *  + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts, which
  *    are wired to the NVIC lines 32 .. n+32
+ *  + sysbus MMIO region 0 is the "AHB Slave Expansion" which allows
+ *    bus master devices in the board model to make transactions into
+ *    all the devices and memory areas in the IoTKit
  * Controlling up to 4 AHB expansion PPBs which a system using the IoTKit
  * might provide:
  *  + named GPIO outputs apb_ppcexp{0,1,2,3}_nonsec[0..15]
@@ -45,6 +48,11 @@
  * Controlling each of the 16 expansion MPCs which a system using the IoTKit
  * might provide:
  *  + named GPIO inputs mpcexp_status[0..15]
+ * Controlling each of the 16 expansion MSCs which a system using the IoTKit
+ * might provide:
+ *  + named GPIO inputs mscexp_status[0..15]
+ *  + named GPIO outputs mscexp_clear[0..15]
+ *  + named GPIO outputs mscexp_ns[0..15]
  */
 
 #ifndef IOTKIT_H
diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
index f8276b5425c..8742200fb42 100644
--- a/hw/arm/iotkit.c
+++ b/hw/arm/iotkit.c
@@ -667,6 +667,21 @@ static void iotkit_realize(DeviceState *dev, Error **errp)
 
     iotkit_forward_sec_resp_cfg(s);
 
+    /* Forward the MSC related signals */
+    qdev_pass_gpios(dev_secctl, dev, "mscexp_status");
+    qdev_pass_gpios(dev_secctl, dev, "mscexp_clear");
+    qdev_pass_gpios(dev_secctl, dev, "mscexp_ns");
+    qdev_connect_gpio_out_named(dev_secctl, "msc_irq", 0,
+                                qdev_get_gpio_in(DEVICE(&s->armv7m), 11));
+
+    /*
+     * Expose our container region to the board model; this corresponds
+     * to the AHB Slave Expansion ports which allow bus master devices
+     * (eg DMA controllers) in the board model to make transactions into
+     * devices in the IoTKit.
+     */
+    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
+
     system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq;
 }
 
-- 
2.18.0

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

* [Qemu-devel] [PATCH 14/22] hw/arm/mps2-tz: Create PL081s and MSCs
  2018-08-20 14:10 [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI Peter Maydell
                   ` (12 preceding siblings ...)
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 13/22] hw/arm/iotkit: Wire up the lines for MSCs Peter Maydell
@ 2018-08-20 14:11 ` Peter Maydell
  2018-08-23 17:27   ` Richard Henderson
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 15/22] hw/ssi/pl022: Allow use as embedded-struct device Peter Maydell
                   ` (7 subsequent siblings)
  21 siblings, 1 reply; 56+ messages in thread
From: Peter Maydell @ 2018-08-20 14:11 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Philippe Mathieu-Daudé

The AN505 FPGA image includes four PL081 DMA controllers, each
of which is gated by a Master Security Controller that allows
the guest to prevent a non-secure DMA controller from accessing
memory that is used by secure guest code. Create and wire
up these devices.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
v2 changes:
 - use 'sizeof(*msc)', 'sizeof(*dma)' as suggested
   by Phillipe in code review
 - s/init_sysbus_child/sysbus_init_child_obj/, required by
   rebase on current master
---
 hw/arm/mps2-tz.c | 100 +++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 93 insertions(+), 7 deletions(-)

diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
index dc0f34abe53..d810e51a1b4 100644
--- a/hw/arm/mps2-tz.c
+++ b/hw/arm/mps2-tz.c
@@ -45,7 +45,9 @@
 #include "hw/misc/mps2-scc.h"
 #include "hw/misc/mps2-fpgaio.h"
 #include "hw/misc/tz-mpc.h"
+#include "hw/misc/tz-msc.h"
 #include "hw/arm/iotkit.h"
+#include "hw/dma/pl080.h"
 #include "hw/devices.h"
 #include "net/net.h"
 #include "hw/core/split-irq.h"
@@ -75,8 +77,9 @@ typedef struct {
     UnimplementedDeviceState i2c[4];
     UnimplementedDeviceState i2s_audio;
     UnimplementedDeviceState gpio[4];
-    UnimplementedDeviceState dma[4];
     UnimplementedDeviceState gfx;
+    PL080State dma[4];
+    TZMSC msc[4];
     CMSDKAPBUART uart[5];
     SplitIRQ sec_resp_splitter;
     qemu_or_irq uart_irq_orgate;
@@ -263,6 +266,64 @@ static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
     return sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 0);
 }
 
+static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
+                              const char *name, hwaddr size)
+{
+    PL080State *dma = opaque;
+    int i = dma - &mms->dma[0];
+    SysBusDevice *s;
+    char *mscname = g_strdup_printf("%s-msc", name);
+    TZMSC *msc = &mms->msc[i];
+    DeviceState *iotkitdev = DEVICE(&mms->iotkit);
+    MemoryRegion *msc_upstream;
+    MemoryRegion *msc_downstream;
+
+    /*
+     * Each DMA device is a PL081 whose transaction master interface
+     * is guarded by a Master Security Controller. The downstream end of
+     * the MSC connects to the IoTKit AHB Slave Expansion port, so the
+     * DMA devices can see all devices and memory that the CPU does.
+     */
+    sysbus_init_child_obj(OBJECT(mms), mscname, msc, sizeof(*msc), TYPE_TZ_MSC);
+    msc_downstream = sysbus_mmio_get_region(SYS_BUS_DEVICE(&mms->iotkit), 0);
+    object_property_set_link(OBJECT(msc), OBJECT(msc_downstream),
+                             "downstream", &error_fatal);
+    object_property_set_link(OBJECT(msc), OBJECT(mms),
+                             "idau", &error_fatal);
+    object_property_set_bool(OBJECT(msc), true, "realized", &error_fatal);
+
+    qdev_connect_gpio_out_named(DEVICE(msc), "irq", 0,
+                                qdev_get_gpio_in_named(iotkitdev,
+                                                       "mscexp_status", i));
+    qdev_connect_gpio_out_named(iotkitdev, "mscexp_clear", i,
+                                qdev_get_gpio_in_named(DEVICE(msc),
+                                                       "irq_clear", 0));
+    qdev_connect_gpio_out_named(iotkitdev, "mscexp_ns", i,
+                                qdev_get_gpio_in_named(DEVICE(msc),
+                                                       "cfg_nonsec", 0));
+    qdev_connect_gpio_out(DEVICE(&mms->sec_resp_splitter),
+                          ARRAY_SIZE(mms->ppc) + i,
+                          qdev_get_gpio_in_named(DEVICE(msc),
+                                                 "cfg_sec_resp", 0));
+    msc_upstream = sysbus_mmio_get_region(SYS_BUS_DEVICE(msc), 0);
+
+    sysbus_init_child_obj(OBJECT(mms), name, dma, sizeof(*dma), TYPE_PL081);
+    object_property_set_link(OBJECT(dma), OBJECT(msc_upstream),
+                             "downstream", &error_fatal);
+    object_property_set_bool(OBJECT(dma), true, "realized", &error_fatal);
+
+    s = SYS_BUS_DEVICE(dma);
+    /* Wire up DMACINTR, DMACINTERR, DMACINTTC */
+    sysbus_connect_irq(s, 0, qdev_get_gpio_in_named(iotkitdev,
+                                                    "EXP_IRQ", 58 + i * 3));
+    sysbus_connect_irq(s, 1, qdev_get_gpio_in_named(iotkitdev,
+                                                    "EXP_IRQ", 56 + i * 3));
+    sysbus_connect_irq(s, 2, qdev_get_gpio_in_named(iotkitdev,
+                                                    "EXP_IRQ", 57 + i * 3));
+
+    return sysbus_mmio_get_region(s, 0);
+}
+
 static void mps2tz_common_init(MachineState *machine)
 {
     MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
@@ -289,13 +350,14 @@ static void mps2tz_common_init(MachineState *machine)
                              &error_fatal);
 
     /* The sec_resp_cfg output from the IoTKit must be split into multiple
-     * lines, one for each of the PPCs we create here.
+     * lines, one for each of the PPCs we create here, plus one per MSC.
      */
     object_initialize(&mms->sec_resp_splitter, sizeof(mms->sec_resp_splitter),
                       TYPE_SPLIT_IRQ);
     object_property_add_child(OBJECT(machine), "sec-resp-splitter",
                               OBJECT(&mms->sec_resp_splitter), &error_abort);
-    object_property_set_int(OBJECT(&mms->sec_resp_splitter), 5,
+    object_property_set_int(OBJECT(&mms->sec_resp_splitter),
+                            ARRAY_SIZE(mms->ppc) + ARRAY_SIZE(mms->msc),
                             "num-lines", &error_fatal);
     object_property_set_bool(OBJECT(&mms->sec_resp_splitter), true,
                              "realized", &error_fatal);
@@ -396,10 +458,10 @@ static void mps2tz_common_init(MachineState *machine)
         }, {
             .name = "ahb_ppcexp1",
             .ports = {
-                { "dma0", make_unimp_dev, &mms->dma[0], 0x40110000, 0x1000 },
-                { "dma1", make_unimp_dev, &mms->dma[1], 0x40111000, 0x1000 },
-                { "dma2", make_unimp_dev, &mms->dma[2], 0x40112000, 0x1000 },
-                { "dma3", make_unimp_dev, &mms->dma[3], 0x40113000, 0x1000 },
+                { "dma0", make_dma, &mms->dma[0], 0x40110000, 0x1000 },
+                { "dma1", make_dma, &mms->dma[1], 0x40111000, 0x1000 },
+                { "dma2", make_dma, &mms->dma[2], 0x40112000, 0x1000 },
+                { "dma3", make_dma, &mms->dma[3], 0x40113000, 0x1000 },
             },
         },
     };
@@ -480,12 +542,32 @@ static void mps2tz_common_init(MachineState *machine)
     armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x400000);
 }
 
+static void mps2_tz_idau_check(IDAUInterface *ii, uint32_t address,
+                               int *iregion, bool *exempt, bool *ns, bool *nsc)
+{
+    /*
+     * The MPS2 TZ FPGA images have IDAUs in them which are connected to
+     * the Master Security Controllers. Thes have the same logic as
+     * is used by the IoTKit for the IDAU connected to the CPU, except
+     * that MSCs don't care about the NSC attribute.
+     */
+    int region = extract32(address, 28, 4);
+
+    *ns = !(region & 1);
+    *nsc = false;
+    /* 0xe0000000..0xe00fffff and 0xf0000000..0xf00fffff are exempt */
+    *exempt = (address & 0xeff00000) == 0xe0000000;
+    *iregion = region;
+}
+
 static void mps2tz_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
+    IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(oc);
 
     mc->init = mps2tz_common_init;
     mc->max_cpus = 1;
+    iic->check = mps2_tz_idau_check;
 }
 
 static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
@@ -506,6 +588,10 @@ static const TypeInfo mps2tz_info = {
     .instance_size = sizeof(MPS2TZMachineState),
     .class_size = sizeof(MPS2TZMachineClass),
     .class_init = mps2tz_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_IDAU_INTERFACE },
+        { }
+    },
 };
 
 static const TypeInfo mps2tz_an505_info = {
-- 
2.18.0

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

* [Qemu-devel] [PATCH 15/22] hw/ssi/pl022: Allow use as embedded-struct device
  2018-08-20 14:10 [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI Peter Maydell
                   ` (13 preceding siblings ...)
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 14/22] hw/arm/mps2-tz: Create PL081s and MSCs Peter Maydell
@ 2018-08-20 14:11 ` Peter Maydell
  2018-08-21  6:48   ` Philippe Mathieu-Daudé
  2018-08-23 17:29   ` Richard Henderson
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 16/22] hw/ssi/pl022: Set up reset function in class init Peter Maydell
                   ` (6 subsequent siblings)
  21 siblings, 2 replies; 56+ messages in thread
From: Peter Maydell @ 2018-08-20 14:11 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Philippe Mathieu-Daudé

Create a new include file for the pl022's device struct,
type macros, etc, so that it can be instantiated using
the "embedded struct" coding style.

While we're adding the new file to MAINTAINERS, add
also the .c file, which was missing an entry.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/ssi/pl022.h | 51 ++++++++++++++++++++++++++++++++++++++++++
 hw/ssi/pl022.c         | 26 +--------------------
 MAINTAINERS            |  2 ++
 3 files changed, 54 insertions(+), 25 deletions(-)
 create mode 100644 include/hw/ssi/pl022.h

diff --git a/include/hw/ssi/pl022.h b/include/hw/ssi/pl022.h
new file mode 100644
index 00000000000..a080519366d
--- /dev/null
+++ b/include/hw/ssi/pl022.h
@@ -0,0 +1,51 @@
+/*
+ * ARM PrimeCell PL022 Synchronous Serial Port
+ *
+ * Copyright (c) 2007 CodeSourcery.
+ * Written by Paul Brook
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 or
+ * (at your option) any later version.
+ */
+
+/* This is a model of the Arm PrimeCell PL022 synchronous serial port.
+ * The PL022 TRM is:
+ * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0194h/DDI0194H_ssp_pl022_trm.pdf
+ *
+ * QEMU interface:
+ * + sysbus IRQ: SSPINTR combined interrupt line
+ * + sysbus MMIO region 0: MemoryRegion for the device's registers
+ */
+
+#ifndef HW_SSI_PL022_H
+#define HW_SSI_PL022_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_PL022 "pl022"
+#define PL022(obj) OBJECT_CHECK(PL022State, (obj), TYPE_PL022)
+
+typedef struct PL022State {
+    SysBusDevice parent_obj;
+
+    MemoryRegion iomem;
+    uint32_t cr0;
+    uint32_t cr1;
+    uint32_t bitmask;
+    uint32_t sr;
+    uint32_t cpsr;
+    uint32_t is;
+    uint32_t im;
+    /* The FIFO head points to the next empty entry.  */
+    int tx_fifo_head;
+    int rx_fifo_head;
+    int tx_fifo_len;
+    int rx_fifo_len;
+    uint16_t tx_fifo[8];
+    uint16_t rx_fifo[8];
+    qemu_irq irq;
+    SSIBus *ssi;
+} PL022State;
+
+#endif
diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c
index c1368018ee3..379d3093987 100644
--- a/hw/ssi/pl022.c
+++ b/hw/ssi/pl022.c
@@ -9,6 +9,7 @@
 
 #include "qemu/osdep.h"
 #include "hw/sysbus.h"
+#include "hw/ssi/pl022.h"
 #include "hw/ssi/ssi.h"
 #include "qemu/log.h"
 
@@ -41,31 +42,6 @@ do { fprintf(stderr, "pl022: error: " fmt , ## __VA_ARGS__);} while (0)
 #define PL022_INT_RX  0x04
 #define PL022_INT_TX  0x08
 
-#define TYPE_PL022 "pl022"
-#define PL022(obj) OBJECT_CHECK(PL022State, (obj), TYPE_PL022)
-
-typedef struct PL022State {
-    SysBusDevice parent_obj;
-
-    MemoryRegion iomem;
-    uint32_t cr0;
-    uint32_t cr1;
-    uint32_t bitmask;
-    uint32_t sr;
-    uint32_t cpsr;
-    uint32_t is;
-    uint32_t im;
-    /* The FIFO head points to the next empty entry.  */
-    int tx_fifo_head;
-    int rx_fifo_head;
-    int tx_fifo_len;
-    int rx_fifo_len;
-    uint16_t tx_fifo[8];
-    uint16_t rx_fifo[8];
-    qemu_irq irq;
-    SSIBus *ssi;
-} PL022State;
-
 static const unsigned char pl022_id[8] =
   { 0x22, 0x10, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
 
diff --git a/MAINTAINERS b/MAINTAINERS
index b2f8b562dc5..1e81ad8d4b1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -451,6 +451,8 @@ F: hw/gpio/pl061.c
 F: hw/input/pl050.c
 F: hw/intc/pl190.c
 F: hw/sd/pl181.c
+F: hw/ssi/pl022.c
+F: include/hw/ssi/pl022.h
 F: hw/timer/pl031.c
 F: include/hw/arm/primecell.h
 F: hw/timer/cmsdk-apb-timer.c
-- 
2.18.0

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

* [Qemu-devel] [PATCH 16/22] hw/ssi/pl022: Set up reset function in class init
  2018-08-20 14:10 [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI Peter Maydell
                   ` (14 preceding siblings ...)
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 15/22] hw/ssi/pl022: Allow use as embedded-struct device Peter Maydell
@ 2018-08-20 14:11 ` Peter Maydell
  2018-08-21  6:49   ` Philippe Mathieu-Daudé
  2018-08-23 17:29   ` Richard Henderson
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 17/22] hw/ssi/pl022: Don't directly call vmstate_register() Peter Maydell
                   ` (5 subsequent siblings)
  21 siblings, 2 replies; 56+ messages in thread
From: Peter Maydell @ 2018-08-20 14:11 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Philippe Mathieu-Daudé

Currently the PL022 calls pl022_reset() from its class init
function. Make it register a DeviceState reset method instead,
so that we reset the device on system reset.

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

diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c
index 379d3093987..0b5f90b857f 100644
--- a/hw/ssi/pl022.c
+++ b/hw/ssi/pl022.c
@@ -203,8 +203,10 @@ static void pl022_write(void *opaque, hwaddr offset,
     }
 }
 
-static void pl022_reset(PL022State *s)
+static void pl022_reset(DeviceState *dev)
 {
+    PL022State *s = PL022(dev);
+
     s->rx_fifo_len = 0;
     s->tx_fifo_len = 0;
     s->im = 0;
@@ -277,7 +279,6 @@ static int pl022_init(SysBusDevice *sbd)
     sysbus_init_mmio(sbd, &s->iomem);
     sysbus_init_irq(sbd, &s->irq);
     s->ssi = ssi_create_bus(dev, "ssi");
-    pl022_reset(s);
     vmstate_register(dev, -1, &vmstate_pl022, s);
     return 0;
 }
@@ -285,8 +286,10 @@ static int pl022_init(SysBusDevice *sbd)
 static void pl022_class_init(ObjectClass *klass, void *data)
 {
     SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
     sdc->init = pl022_init;
+    dc->reset = pl022_reset;
 }
 
 static const TypeInfo pl022_info = {
-- 
2.18.0

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

* [Qemu-devel] [PATCH 17/22] hw/ssi/pl022: Don't directly call vmstate_register()
  2018-08-20 14:10 [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI Peter Maydell
                   ` (15 preceding siblings ...)
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 16/22] hw/ssi/pl022: Set up reset function in class init Peter Maydell
@ 2018-08-20 14:11 ` Peter Maydell
  2018-08-23 17:30   ` Richard Henderson
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 18/22] hw/ssi/pl022: Use DeviceState::realize rather than SysBusDevice::init Peter Maydell
                   ` (4 subsequent siblings)
  21 siblings, 1 reply; 56+ messages in thread
From: Peter Maydell @ 2018-08-20 14:11 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Philippe Mathieu-Daudé

Use the DeviceState vmsd pointer rather than calling vmstate_register()
directly.

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

diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c
index 0b5f90b857f..c9989537062 100644
--- a/hw/ssi/pl022.c
+++ b/hw/ssi/pl022.c
@@ -279,7 +279,6 @@ static int pl022_init(SysBusDevice *sbd)
     sysbus_init_mmio(sbd, &s->iomem);
     sysbus_init_irq(sbd, &s->irq);
     s->ssi = ssi_create_bus(dev, "ssi");
-    vmstate_register(dev, -1, &vmstate_pl022, s);
     return 0;
 }
 
@@ -290,6 +289,7 @@ static void pl022_class_init(ObjectClass *klass, void *data)
 
     sdc->init = pl022_init;
     dc->reset = pl022_reset;
+    dc->vmsd = &vmstate_pl022;
 }
 
 static const TypeInfo pl022_info = {
-- 
2.18.0

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

* [Qemu-devel] [PATCH 18/22] hw/ssi/pl022: Use DeviceState::realize rather than SysBusDevice::init
  2018-08-20 14:10 [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI Peter Maydell
                   ` (16 preceding siblings ...)
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 17/22] hw/ssi/pl022: Don't directly call vmstate_register() Peter Maydell
@ 2018-08-20 14:11 ` Peter Maydell
  2018-08-21  6:53   ` Philippe Mathieu-Daudé
  2018-08-23 17:31   ` Richard Henderson
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 19/22] hw/ssi/pl022: Correct wrong value for PL022_INT_RT Peter Maydell
                   ` (3 subsequent siblings)
  21 siblings, 2 replies; 56+ messages in thread
From: Peter Maydell @ 2018-08-20 14:11 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Philippe Mathieu-Daudé

Move from the legacy SysBusDevice::init method to using
DeviceState::realize.

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

diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c
index c9989537062..3ac57f4c96a 100644
--- a/hw/ssi/pl022.c
+++ b/hw/ssi/pl022.c
@@ -270,26 +270,24 @@ static const VMStateDescription vmstate_pl022 = {
     }
 };
 
-static int pl022_init(SysBusDevice *sbd)
+static void pl022_realize(DeviceState *dev, Error **errp)
 {
-    DeviceState *dev = DEVICE(sbd);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
     PL022State *s = PL022(dev);
 
     memory_region_init_io(&s->iomem, OBJECT(s), &pl022_ops, s, "pl022", 0x1000);
     sysbus_init_mmio(sbd, &s->iomem);
     sysbus_init_irq(sbd, &s->irq);
     s->ssi = ssi_create_bus(dev, "ssi");
-    return 0;
 }
 
 static void pl022_class_init(ObjectClass *klass, void *data)
 {
-    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
     DeviceClass *dc = DEVICE_CLASS(klass);
 
-    sdc->init = pl022_init;
     dc->reset = pl022_reset;
     dc->vmsd = &vmstate_pl022;
+    dc->realize = pl022_realize;
 }
 
 static const TypeInfo pl022_info = {
-- 
2.18.0

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

* [Qemu-devel] [PATCH 19/22] hw/ssi/pl022: Correct wrong value for PL022_INT_RT
  2018-08-20 14:10 [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI Peter Maydell
                   ` (17 preceding siblings ...)
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 18/22] hw/ssi/pl022: Use DeviceState::realize rather than SysBusDevice::init Peter Maydell
@ 2018-08-20 14:11 ` Peter Maydell
  2018-08-23 17:33   ` Richard Henderson
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 20/22] hw/ssi/pl022: Correct wrong DMACR and ICR handling Peter Maydell
                   ` (2 subsequent siblings)
  21 siblings, 1 reply; 56+ messages in thread
From: Peter Maydell @ 2018-08-20 14:11 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Philippe Mathieu-Daudé

The PL022 interrupt registers have bits allocated as:
 0: ROR (receive overrun)
 1: RT (receive timeout)
 2: RX (receive FIFO half full or less)
 3: TX (transmit FIFO half full or less)

A cut and paste error meant we had the wrong value for
the PL022_INT_RT constant. This bug doesn't affect device
behaviour, because we don't implmenet the receive timeout
feature and so never set that interrupt bit.

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

diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c
index 3ac57f4c96a..d310671d18e 100644
--- a/hw/ssi/pl022.c
+++ b/hw/ssi/pl022.c
@@ -38,7 +38,7 @@ do { fprintf(stderr, "pl022: error: " fmt , ## __VA_ARGS__);} while (0)
 #define PL022_SR_BSY  0x10
 
 #define PL022_INT_ROR 0x01
-#define PL022_INT_RT  0x04
+#define PL022_INT_RT  0x02
 #define PL022_INT_RX  0x04
 #define PL022_INT_TX  0x08
 
-- 
2.18.0

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

* [Qemu-devel] [PATCH 20/22] hw/ssi/pl022: Correct wrong DMACR and ICR handling
  2018-08-20 14:10 [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI Peter Maydell
                   ` (18 preceding siblings ...)
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 19/22] hw/ssi/pl022: Correct wrong value for PL022_INT_RT Peter Maydell
@ 2018-08-20 14:11 ` Peter Maydell
  2018-08-23 17:38   ` Richard Henderson
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 21/22] hw/arm/mps2-tz: Instantiate SPI controllers Peter Maydell
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 22/22] hw/arm/mps2-tz: Fix MPS2 SCC config register values Peter Maydell
  21 siblings, 1 reply; 56+ messages in thread
From: Peter Maydell @ 2018-08-20 14:11 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Philippe Mathieu-Daudé

In the PL022, register offset 0x20 is the ICR, a write-only
interrupt-clear register.  Register offset 0x24 is DMACR, the DMA
control register.  We were incorrectly implementing (a stub version
of) DMACR at 0x20, and not implementing anything at 0x24.  Fix this
bug.

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

diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c
index d310671d18e..e58247554cc 100644
--- a/hw/ssi/pl022.c
+++ b/hw/ssi/pl022.c
@@ -146,7 +146,7 @@ static uint64_t pl022_read(void *opaque, hwaddr offset,
         return s->is;
     case 0x1c: /* MIS */
         return s->im & s->is;
-    case 0x20: /* DMACR */
+    case 0x24: /* DMACR */
         /* Not implemented.  */
         return 0;
     default:
@@ -192,7 +192,15 @@ static void pl022_write(void *opaque, hwaddr offset,
         s->im = value;
         pl022_update(s);
         break;
-    case 0x20: /* DMACR */
+    case 0x20: /* ICR */
+        /*
+         * write-1-to-clear: bit 0 clears ROR, bit 1 clears RT;
+         * RX and TX interrupts cannot be cleared this way.
+         */
+        value &= PL022_INT_ROR | PL022_INT_RT;
+        s->is &= ~value;
+        break;
+    case 0x24: /* DMACR */
         if (value) {
             qemu_log_mask(LOG_UNIMP, "pl022: DMA not implemented\n");
         }
-- 
2.18.0

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

* [Qemu-devel] [PATCH 21/22] hw/arm/mps2-tz: Instantiate SPI controllers
  2018-08-20 14:10 [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI Peter Maydell
                   ` (19 preceding siblings ...)
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 20/22] hw/ssi/pl022: Correct wrong DMACR and ICR handling Peter Maydell
@ 2018-08-20 14:11 ` Peter Maydell
  2018-08-23 17:39   ` Richard Henderson
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 22/22] hw/arm/mps2-tz: Fix MPS2 SCC config register values Peter Maydell
  21 siblings, 1 reply; 56+ messages in thread
From: Peter Maydell @ 2018-08-20 14:11 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Philippe Mathieu-Daudé

The SPI controllers in the MPS2 AN505 board are PL022s.
We have a model of the PL022, so create these devices.

We don't currently model the LCD controller that sits behind
one of the PL022s; the others are intended to control devices
that sit on the FPGA's general purpose SPI connector or
"shield" expansion connectors.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/mps2-tz.c | 38 ++++++++++++++++++++++++++++++++------
 1 file changed, 32 insertions(+), 6 deletions(-)

diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
index d810e51a1b4..cedf605e20e 100644
--- a/hw/arm/mps2-tz.c
+++ b/hw/arm/mps2-tz.c
@@ -48,6 +48,7 @@
 #include "hw/misc/tz-msc.h"
 #include "hw/arm/iotkit.h"
 #include "hw/dma/pl080.h"
+#include "hw/ssi/pl022.h"
 #include "hw/devices.h"
 #include "net/net.h"
 #include "hw/core/split-irq.h"
@@ -73,7 +74,7 @@ typedef struct {
     MPS2FPGAIO fpgaio;
     TZPPC ppc[5];
     TZMPC ssram_mpc[3];
-    UnimplementedDeviceState spi[5];
+    PL022State spi[5];
     UnimplementedDeviceState i2c[4];
     UnimplementedDeviceState i2s_audio;
     UnimplementedDeviceState gpio[4];
@@ -324,6 +325,31 @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
     return sysbus_mmio_get_region(s, 0);
 }
 
+static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
+                              const char *name, hwaddr size)
+{
+    /*
+     * The AN505 has five PL022 SPI controllers.
+     * One of these should have the LCD controller behind it; the others
+     * are connected only to the FPGA's "general purpose SPI connector"
+     * or "shield" expansion connectors.
+     * Note that if we do implement devices behind SPI, the chip select
+     * lines are set via the "MISC" register in the MPS2 FPGAIO device.
+     */
+    PL022State *spi = opaque;
+    int i = spi - &mms->spi[0];
+    DeviceState *iotkitdev = DEVICE(&mms->iotkit);
+    SysBusDevice *s;
+
+    sysbus_init_child_obj(OBJECT(mms), name, spi, sizeof(mms->spi[0]),
+                          TYPE_PL022);
+    object_property_set_bool(OBJECT(spi), true, "realized", &error_fatal);
+    s = SYS_BUS_DEVICE(spi);
+    sysbus_connect_irq(s, 0,
+                       qdev_get_gpio_in_named(iotkitdev, "EXP_IRQ", 51 + i));
+    return sysbus_mmio_get_region(s, 0);
+}
+
 static void mps2tz_common_init(MachineState *machine)
 {
     MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
@@ -422,11 +448,11 @@ static void mps2tz_common_init(MachineState *machine)
         }, {
             .name = "apb_ppcexp1",
             .ports = {
-                { "spi0", make_unimp_dev, &mms->spi[0], 0x40205000, 0x1000 },
-                { "spi1", make_unimp_dev, &mms->spi[1], 0x40206000, 0x1000 },
-                { "spi2", make_unimp_dev, &mms->spi[2], 0x40209000, 0x1000 },
-                { "spi3", make_unimp_dev, &mms->spi[3], 0x4020a000, 0x1000 },
-                { "spi4", make_unimp_dev, &mms->spi[4], 0x4020b000, 0x1000 },
+                { "spi0", make_spi, &mms->spi[0], 0x40205000, 0x1000 },
+                { "spi1", make_spi, &mms->spi[1], 0x40206000, 0x1000 },
+                { "spi2", make_spi, &mms->spi[2], 0x40209000, 0x1000 },
+                { "spi3", make_spi, &mms->spi[3], 0x4020a000, 0x1000 },
+                { "spi4", make_spi, &mms->spi[4], 0x4020b000, 0x1000 },
                 { "uart0", make_uart, &mms->uart[0], 0x40200000, 0x1000 },
                 { "uart1", make_uart, &mms->uart[1], 0x40201000, 0x1000 },
                 { "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000 },
-- 
2.18.0

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

* [Qemu-devel] [PATCH 22/22] hw/arm/mps2-tz: Fix MPS2 SCC config register values
  2018-08-20 14:10 [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI Peter Maydell
                   ` (20 preceding siblings ...)
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 21/22] hw/arm/mps2-tz: Instantiate SPI controllers Peter Maydell
@ 2018-08-20 14:11 ` Peter Maydell
  2018-08-23 17:42   ` Richard Henderson
  21 siblings, 1 reply; 56+ messages in thread
From: Peter Maydell @ 2018-08-20 14:11 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Philippe Mathieu-Daudé

Some of the config register values we were setting for the MPS2 SCC
weren't correct:
 * the SCC_AID bits [23:20] specify the FPGA build target board revision,
   and the SCC_CFG4 register specifies the actual board revision, so
   these should have matching values. Claim to be board revision C,
   consistently -- we had the revision in the wrong part of SCC_AID.
 * SCC_ID bits [15:4] should be 0x505, not decimal 505

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

diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
index cedf605e20e..cb252d8ebcc 100644
--- a/hw/arm/mps2-tz.c
+++ b/hw/arm/mps2-tz.c
@@ -192,7 +192,7 @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
     sccdev = DEVICE(scc);
     qdev_set_parent_bus(sccdev, sysbus_get_default());
     qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
-    qdev_prop_set_uint32(sccdev, "scc-aid", 0x02000008);
+    qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
     qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
     object_property_set_bool(OBJECT(scc), true, "realized", &error_fatal);
     return sysbus_mmio_get_region(SYS_BUS_DEVICE(sccdev), 0);
@@ -604,7 +604,7 @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
     mc->desc = "ARM MPS2 with AN505 FPGA image for Cortex-M33";
     mmc->fpga_type = FPGA_AN505;
     mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
-    mmc->scc_id = 0x41040000 | (505 << 4);
+    mmc->scc_id = 0x41040000 | (0x505 << 4);
 }
 
 static const TypeInfo mps2tz_info = {
-- 
2.18.0

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

* Re: [Qemu-devel] [PATCH 04/22] hw/arm/iotkit: Wire up the dualtimer
  2018-08-20 14:10 ` [Qemu-devel] [PATCH 04/22] hw/arm/iotkit: Wire up the dualtimer Peter Maydell
@ 2018-08-21  6:41   ` Philippe Mathieu-Daudé
  2018-08-23 14:09   ` Richard Henderson
  1 sibling, 0 replies; 56+ messages in thread
From: Philippe Mathieu-Daudé @ 2018-08-21  6:41 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/20/2018 11:10 AM, Peter Maydell wrote:
> Now we have a model of the CMSDK dual timer, we can wire it
> up in the IoTKit.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

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

> ---
>  include/hw/arm/iotkit.h | 3 ++-
>  hw/arm/iotkit.c         | 8 +++++---
>  2 files changed, 7 insertions(+), 4 deletions(-)
> 
> diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h
> index 2cddde55dd1..3e6d806e352 100644
> --- a/include/hw/arm/iotkit.h
> +++ b/include/hw/arm/iotkit.h
> @@ -56,6 +56,7 @@
>  #include "hw/misc/tz-ppc.h"
>  #include "hw/misc/tz-mpc.h"
>  #include "hw/timer/cmsdk-apb-timer.h"
> +#include "hw/timer/cmsdk-apb-dualtimer.h"
>  #include "hw/misc/unimp.h"
>  #include "hw/or-irq.h"
>  #include "hw/core/split-irq.h"
> @@ -87,7 +88,7 @@ typedef struct IoTKit {
>      SplitIRQ mpc_irq_splitter[IOTS_NUM_EXP_MPC + IOTS_NUM_MPC];
>      qemu_or_irq mpc_irq_orgate;
>  
> -    UnimplementedDeviceState dualtimer;
> +    CMSDKAPBDualTimer dualtimer;
>      UnimplementedDeviceState s32ktimer;
>  
>      MemoryRegion container;
> diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
> index 8cadc8b1608..130d013909e 100644
> --- a/hw/arm/iotkit.c
> +++ b/hw/arm/iotkit.c
> @@ -139,7 +139,7 @@ static void iotkit_init(Object *obj)
>      sysbus_init_child_obj(obj, "timer1", &s->timer1, sizeof(s->timer1),
>                            TYPE_CMSDK_APB_TIMER);
>      sysbus_init_child_obj(obj, "dualtimer", &s->dualtimer, sizeof(s->dualtimer),
> -                          TYPE_UNIMPLEMENTED_DEVICE);
> +                          TYPE_CMSDK_APB_DUALTIMER);
>      object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate,
>                              sizeof(s->ppc_irq_orgate), TYPE_OR_IRQ,
>                              &error_abort, NULL);
> @@ -390,13 +390,15 @@ static void iotkit_realize(DeviceState *dev, Error **errp)
>          return;
>      }
>  
> -    qdev_prop_set_string(DEVICE(&s->dualtimer), "name", "Dual timer");
> -    qdev_prop_set_uint64(DEVICE(&s->dualtimer), "size", 0x1000);
> +
> +    qdev_prop_set_uint32(DEVICE(&s->dualtimer), "pclk-frq", s->mainclk_frq);
>      object_property_set_bool(OBJECT(&s->dualtimer), true, "realized", &err);
>      if (err) {
>          error_propagate(errp, err);
>          return;
>      }
> +    sysbus_connect_irq(SYS_BUS_DEVICE(&s->dualtimer), 0,
> +                       qdev_get_gpio_in(DEVICE(&s->armv7m), 5));
>      mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dualtimer), 0);
>      object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[2]", &err);
>      if (err) {
> 

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

* Re: [Qemu-devel] [Qemu-arm] [PATCH 05/22] hw/arm/mps2: Wire up dual-timer in mps2-an385 and mps2-an511
  2018-08-20 14:10 ` [Qemu-devel] [PATCH 05/22] hw/arm/mps2: Wire up dual-timer in mps2-an385 and mps2-an511 Peter Maydell
@ 2018-08-21  6:43   ` Philippe Mathieu-Daudé
  2018-08-23 14:11   ` [Qemu-devel] " Richard Henderson
  1 sibling, 0 replies; 56+ messages in thread
From: Philippe Mathieu-Daudé @ 2018-08-21  6:43 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/20/2018 11:10 AM, Peter Maydell wrote:
> The MPS2 FPGA images for the Cortex-M3 (mps2-an385 and mps2-511)
> both include a CMSDK dual-timer module. Wire this up.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

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

> ---
>  hw/arm/mps2.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
> index 0a0ae867d9b..564624629d0 100644
> --- a/hw/arm/mps2.c
> +++ b/hw/arm/mps2.c
> @@ -34,6 +34,7 @@
>  #include "hw/misc/unimp.h"
>  #include "hw/char/cmsdk-apb-uart.h"
>  #include "hw/timer/cmsdk-apb-timer.h"
> +#include "hw/timer/cmsdk-apb-dualtimer.h"
>  #include "hw/misc/mps2-scc.h"
>  #include "hw/devices.h"
>  #include "net/net.h"
> @@ -64,6 +65,7 @@ typedef struct {
>      MemoryRegion blockram_m3;
>      MemoryRegion sram;
>      MPS2SCC scc;
> +    CMSDKAPBDualTimer dualtimer;
>  } MPS2MachineState;
>  
>  #define TYPE_MPS2_MACHINE "mps2"
> @@ -297,6 +299,15 @@ static void mps2_common_init(MachineState *machine)
>      cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
>      cmsdk_apb_timer_create(0x40001000, qdev_get_gpio_in(armv7m, 9), SYSCLK_FRQ);
>  
> +    sysbus_init_child_obj(OBJECT(mms), "dualtimer", &mms->dualtimer,
> +                          sizeof(mms->dualtimer), TYPE_CMSDK_APB_DUALTIMER);
> +    qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ);
> +    object_property_set_bool(OBJECT(&mms->dualtimer), true, "realized",
> +                             &error_fatal);
> +    sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
> +                       qdev_get_gpio_in(armv7m, 10));
> +    sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0x40002000);
> +
>      object_initialize(&mms->scc, sizeof(mms->scc), TYPE_MPS2_SCC);
>      sccdev = DEVICE(&mms->scc);
>      qdev_set_parent_bus(sccdev, sysbus_get_default());
> 

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

* Re: [Qemu-devel] [PATCH 09/22] hw/misc/iotkit-sysinfo: Implement IoTKit system information block
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 09/22] hw/misc/iotkit-sysinfo: Implement IoTKit system information block Peter Maydell
@ 2018-08-21  6:45   ` Philippe Mathieu-Daudé
  2018-08-23 14:28   ` Richard Henderson
  1 sibling, 0 replies; 56+ messages in thread
From: Philippe Mathieu-Daudé @ 2018-08-21  6:45 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/20/2018 11:11 AM, Peter Maydell wrote:
> Implement the IoTKit system control element's system information
> block; this is just a pair of read-only version/config registers,
> plus the usual PID/CID ID registers.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

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

> ---
>  hw/misc/Makefile.objs            |   1 +
>  include/hw/misc/iotkit-sysinfo.h |  37 +++++++++
>  hw/misc/iotkit-sysinfo.c         | 128 +++++++++++++++++++++++++++++++
>  MAINTAINERS                      |   2 +
>  default-configs/arm-softmmu.mak  |   1 +
>  5 files changed, 169 insertions(+)
>  create mode 100644 include/hw/misc/iotkit-sysinfo.h
>  create mode 100644 hw/misc/iotkit-sysinfo.c
> 
> diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
> index ac1f3bc030c..af2b503824e 100644
> --- a/hw/misc/Makefile.objs
> +++ b/hw/misc/Makefile.objs
> @@ -67,6 +67,7 @@ obj-$(CONFIG_TZ_MPC) += tz-mpc.o
>  obj-$(CONFIG_TZ_PPC) += tz-ppc.o
>  obj-$(CONFIG_IOTKIT_SECCTL) += iotkit-secctl.o
>  obj-$(CONFIG_IOTKIT_SYSCTL) += iotkit-sysctl.o
> +obj-$(CONFIG_IOTKIT_SYSINFO) += iotkit-sysinfo.o
>  
>  obj-$(CONFIG_PVPANIC) += pvpanic.o
>  obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
> diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h
> new file mode 100644
> index 00000000000..7b2e1a5e48b
> --- /dev/null
> +++ b/include/hw/misc/iotkit-sysinfo.h
> @@ -0,0 +1,37 @@
> +/*
> + * ARM IoTKit system information block
> + *
> + * Copyright (c) 2018 Linaro Limited
> + * Written by Peter Maydell
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License version 2 or
> + *  (at your option) any later version.
> + */
> +
> +/*
> + * This is a model of the "system information block" which is part of the
> + * Arm IoTKit and documented in
> + * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
> + * QEMU interface:
> + *  + sysbus MMIO region 0: the system information register bank
> + */
> +
> +#ifndef HW_MISC_IOTKIT_SYSINFO_H
> +#define HW_MISC_IOTKIT_SYSINFO_H
> +
> +#include "hw/sysbus.h"
> +
> +#define TYPE_IOTKIT_SYSINFO "iotkit-sysinfo"
> +#define IOTKIT_SYSINFO(obj) OBJECT_CHECK(IoTKitSysInfo, (obj), \
> +                                        TYPE_IOTKIT_SYSINFO)
> +
> +typedef struct IoTKitSysInfo {
> +    /*< private >*/
> +    SysBusDevice parent_obj;
> +
> +    /*< public >*/
> +    MemoryRegion iomem;
> +} IoTKitSysInfo;
> +
> +#endif
> diff --git a/hw/misc/iotkit-sysinfo.c b/hw/misc/iotkit-sysinfo.c
> new file mode 100644
> index 00000000000..78955bc45f5
> --- /dev/null
> +++ b/hw/misc/iotkit-sysinfo.c
> @@ -0,0 +1,128 @@
> +/*
> + * ARM IoTKit system information block
> + *
> + * Copyright (c) 2018 Linaro Limited
> + * Written by Peter Maydell
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License version 2 or
> + *  (at your option) any later version.
> + */
> +
> +/*
> + * This is a model of the "system information block" which is part of the
> + * Arm IoTKit and documented in
> + * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
> + * It consists of 2 read-only version/config registers, plus the
> + * usual ID registers.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/log.h"
> +#include "trace.h"
> +#include "qapi/error.h"
> +#include "sysemu/sysemu.h"
> +#include "hw/sysbus.h"
> +#include "hw/registerfields.h"
> +#include "hw/misc/iotkit-sysinfo.h"
> +
> +REG32(SYS_VERSION, 0x0)
> +REG32(SYS_CONFIG, 0x4)
> +REG32(PID4, 0xfd0)
> +REG32(PID5, 0xfd4)
> +REG32(PID6, 0xfd8)
> +REG32(PID7, 0xfdc)
> +REG32(PID0, 0xfe0)
> +REG32(PID1, 0xfe4)
> +REG32(PID2, 0xfe8)
> +REG32(PID3, 0xfec)
> +REG32(CID0, 0xff0)
> +REG32(CID1, 0xff4)
> +REG32(CID2, 0xff8)
> +REG32(CID3, 0xffc)
> +
> +/* PID/CID values */
> +static const int sysinfo_id[] = {
> +    0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
> +    0x58, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
> +    0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
> +};
> +
> +static uint64_t iotkit_sysinfo_read(void *opaque, hwaddr offset,
> +                                    unsigned size)
> +{
> +    uint64_t r;
> +
> +    switch (offset) {
> +    case A_SYS_VERSION:
> +        r = 0x41743;
> +        break;
> +
> +    case A_SYS_CONFIG:
> +        r = 0x31;
> +        break;
> +    case A_PID4 ... A_CID3:
> +        r = sysinfo_id[(offset - A_PID4) / 4];
> +        break;
> +    default:
> +        qemu_log_mask(LOG_GUEST_ERROR,
> +                      "IoTKit SysInfo read: bad offset %x\n", (int)offset);
> +        r = 0;
> +        break;
> +    }
> +    trace_iotkit_sysinfo_read(offset, r, size);
> +    return r;
> +}
> +
> +static void iotkit_sysinfo_write(void *opaque, hwaddr offset,
> +                                 uint64_t value, unsigned size)
> +{
> +    trace_iotkit_sysinfo_write(offset, value, size);
> +
> +    qemu_log_mask(LOG_GUEST_ERROR,
> +                  "IoTKit SysInfo: write to RO offset 0x%x\n", (int)offset);
> +}
> +
> +static const MemoryRegionOps iotkit_sysinfo_ops = {
> +    .read = iotkit_sysinfo_read,
> +    .write = iotkit_sysinfo_write,
> +    .endianness = DEVICE_LITTLE_ENDIAN,
> +    /* byte/halfword accesses are just zero-padded on reads and writes */
> +    .impl.min_access_size = 4,
> +    .impl.max_access_size = 4,
> +    .valid.min_access_size = 1,
> +    .valid.max_access_size = 4,
> +};
> +
> +static void iotkit_sysinfo_init(Object *obj)
> +{
> +    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
> +    IoTKitSysInfo *s = IOTKIT_SYSINFO(obj);
> +
> +    memory_region_init_io(&s->iomem, obj, &iotkit_sysinfo_ops,
> +                          s, "iotkit-sysinfo", 0x1000);
> +    sysbus_init_mmio(sbd, &s->iomem);
> +}
> +
> +static void iotkit_sysinfo_class_init(ObjectClass *klass, void *data)
> +{
> +    /*
> +     * This device has no guest-modifiable state and so it
> +     * does not need a reset function or VMState.
> +     */
> +}
> +
> +static const TypeInfo iotkit_sysinfo_info = {
> +    .name = TYPE_IOTKIT_SYSINFO,
> +    .parent = TYPE_SYS_BUS_DEVICE,
> +    .instance_size = sizeof(IoTKitSysInfo),
> +    .instance_init = iotkit_sysinfo_init,
> +    .class_init = iotkit_sysinfo_class_init,
> +};
> +
> +static void iotkit_sysinfo_register_types(void)
> +{
> +    type_register_static(&iotkit_sysinfo_info);
> +}
> +
> +type_init(iotkit_sysinfo_register_types);
> diff --git a/MAINTAINERS b/MAINTAINERS
> index ea35aa2cca5..cb780f463cb 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -541,6 +541,8 @@ F: hw/arm/iotkit.c
>  F: include/hw/arm/iotkit.h
>  F: hw/misc/iotkit-sysctl.c
>  F: include/hw/misc/iotkit-sysctl.h
> +F: hw/misc/iotkit-sysinfo.c
> +F: include/hw/misc/iotkit-sysinfo.h
>  
>  Musicpal
>  M: Jan Kiszka <jan.kiszka@web.de>
> diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
> index 79aac7702a9..ebbdcb29f38 100644
> --- a/default-configs/arm-softmmu.mak
> +++ b/default-configs/arm-softmmu.mak
> @@ -115,6 +115,7 @@ CONFIG_TZ_PPC=y
>  CONFIG_IOTKIT=y
>  CONFIG_IOTKIT_SECCTL=y
>  CONFIG_IOTKIT_SYSCTL=y
> +CONFIG_IOTKIT_SYSINFO=y
>  
>  CONFIG_VERSATILE=y
>  CONFIG_VERSATILE_PCI=y
> 

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

* Re: [Qemu-devel] [PATCH 10/22] hw/misc/iotkit: Wire up the sysctl and sysinfo register blocks
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 10/22] hw/misc/iotkit: Wire up the sysctl and sysinfo register blocks Peter Maydell
@ 2018-08-21  6:47   ` Philippe Mathieu-Daudé
  2018-08-23 14:29   ` Richard Henderson
  1 sibling, 0 replies; 56+ messages in thread
From: Philippe Mathieu-Daudé @ 2018-08-21  6:47 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/20/2018 11:11 AM, Peter Maydell wrote:
> Wire up the system control element's register banks
> (sysctl and sysinfo).
> 
> This is the last of the previously completely unimplemented
> components in the IoTKit.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

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

> ---
>  include/hw/arm/iotkit.h |  6 +++++-
>  hw/arm/iotkit.c         | 26 ++++++++++++++++++--------
>  2 files changed, 23 insertions(+), 9 deletions(-)
> 
> diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h
> index 0f5c5101708..426dc326a0d 100644
> --- a/include/hw/arm/iotkit.h
> +++ b/include/hw/arm/iotkit.h
> @@ -58,7 +58,8 @@
>  #include "hw/timer/cmsdk-apb-timer.h"
>  #include "hw/timer/cmsdk-apb-dualtimer.h"
>  #include "hw/watchdog/cmsdk-apb-watchdog.h"
> -#include "hw/misc/unimp.h"
> +#include "hw/misc/iotkit-sysctl.h"
> +#include "hw/misc/iotkit-sysinfo.h"
>  #include "hw/or-irq.h"
>  #include "hw/core/split-irq.h"
>  
> @@ -97,6 +98,9 @@ typedef struct IoTKit {
>      CMSDKAPBWatchdog nswatchdog;
>      CMSDKAPBWatchdog swatchdog;
>  
> +    IoTKitSysCtl sysctl;
> +    IoTKitSysCtl sysinfo;
> +
>      MemoryRegion container;
>      MemoryRegion alias1;
>      MemoryRegion alias2;
> diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
> index cb0ec456f39..f8276b5425c 100644
> --- a/hw/arm/iotkit.c
> +++ b/hw/arm/iotkit.c
> @@ -16,7 +16,6 @@
>  #include "hw/sysbus.h"
>  #include "hw/registerfields.h"
>  #include "hw/arm/iotkit.h"
> -#include "hw/misc/unimp.h"
>  #include "hw/arm/arm.h"
>  
>  /* Clock frequency in HZ of the 32KHz "slow clock" */
> @@ -151,6 +150,10 @@ static void iotkit_init(Object *obj)
>                            sizeof(s->nswatchdog), TYPE_CMSDK_APB_WATCHDOG);
>      sysbus_init_child_obj(obj, "swatchdog", &s->swatchdog,
>                            sizeof(s->swatchdog), TYPE_CMSDK_APB_WATCHDOG);
> +    sysbus_init_child_obj(obj, "iotkit-sysctl", &s->sysctl,
> +                          sizeof(s->sysctl), TYPE_IOTKIT_SYSCTL);
> +    sysbus_init_child_obj(obj, "iotkit-sysinfo", &s->sysinfo,
> +                          sizeof(s->sysinfo), TYPE_IOTKIT_SYSINFO);
>      object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
>                              sizeof(s->nmi_orgate), TYPE_OR_IRQ,
>                              &error_abort, NULL);
> @@ -516,13 +519,20 @@ static void iotkit_realize(DeviceState *dev, Error **errp)
>                            qdev_get_gpio_in_named(dev_apb_ppc1,
>                                                   "cfg_sec_resp", 0));
>  
> -    /* Using create_unimplemented_device() maps the stub into the
> -     * system address space rather than into our container, but the
> -     * overall effect to the guest is the same.
> -     */
> -    create_unimplemented_device("SYSINFO", 0x40020000, 0x1000);
> -
> -    create_unimplemented_device("SYSCONTROL", 0x50021000, 0x1000);
> +    object_property_set_bool(OBJECT(&s->sysinfo), true, "realized", &err);
> +    if (err) {
> +        error_propagate(errp, err);
> +        return;
> +    }
> +    /* System information registers */
> +    sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysinfo), 0, 0x40020000);
> +    /* System control registers */
> +    object_property_set_bool(OBJECT(&s->sysctl), true, "realized", &err);
> +    if (err) {
> +        error_propagate(errp, err);
> +        return;
> +    }
> +    sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysctl), 0, 0x50021000);
>  
>      /* This OR gate wires together outputs from the secure watchdogs to NMI */
>      object_property_set_int(OBJECT(&s->nmi_orgate), 2, "num-lines", &err);
> 

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

* Re: [Qemu-devel] [PATCH 15/22] hw/ssi/pl022: Allow use as embedded-struct device
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 15/22] hw/ssi/pl022: Allow use as embedded-struct device Peter Maydell
@ 2018-08-21  6:48   ` Philippe Mathieu-Daudé
  2018-08-23 17:29   ` Richard Henderson
  1 sibling, 0 replies; 56+ messages in thread
From: Philippe Mathieu-Daudé @ 2018-08-21  6:48 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/20/2018 11:11 AM, Peter Maydell wrote:
> Create a new include file for the pl022's device struct,
> type macros, etc, so that it can be instantiated using
> the "embedded struct" coding style.
> 
> While we're adding the new file to MAINTAINERS, add
> also the .c file, which was missing an entry.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

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

> ---
>  include/hw/ssi/pl022.h | 51 ++++++++++++++++++++++++++++++++++++++++++
>  hw/ssi/pl022.c         | 26 +--------------------
>  MAINTAINERS            |  2 ++
>  3 files changed, 54 insertions(+), 25 deletions(-)
>  create mode 100644 include/hw/ssi/pl022.h
> 
> diff --git a/include/hw/ssi/pl022.h b/include/hw/ssi/pl022.h
> new file mode 100644
> index 00000000000..a080519366d
> --- /dev/null
> +++ b/include/hw/ssi/pl022.h
> @@ -0,0 +1,51 @@
> +/*
> + * ARM PrimeCell PL022 Synchronous Serial Port
> + *
> + * Copyright (c) 2007 CodeSourcery.
> + * Written by Paul Brook
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 or
> + * (at your option) any later version.
> + */
> +
> +/* This is a model of the Arm PrimeCell PL022 synchronous serial port.
> + * The PL022 TRM is:
> + * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0194h/DDI0194H_ssp_pl022_trm.pdf
> + *
> + * QEMU interface:
> + * + sysbus IRQ: SSPINTR combined interrupt line
> + * + sysbus MMIO region 0: MemoryRegion for the device's registers
> + */
> +
> +#ifndef HW_SSI_PL022_H
> +#define HW_SSI_PL022_H
> +
> +#include "hw/sysbus.h"
> +
> +#define TYPE_PL022 "pl022"
> +#define PL022(obj) OBJECT_CHECK(PL022State, (obj), TYPE_PL022)
> +
> +typedef struct PL022State {
> +    SysBusDevice parent_obj;
> +
> +    MemoryRegion iomem;
> +    uint32_t cr0;
> +    uint32_t cr1;
> +    uint32_t bitmask;
> +    uint32_t sr;
> +    uint32_t cpsr;
> +    uint32_t is;
> +    uint32_t im;
> +    /* The FIFO head points to the next empty entry.  */
> +    int tx_fifo_head;
> +    int rx_fifo_head;
> +    int tx_fifo_len;
> +    int rx_fifo_len;
> +    uint16_t tx_fifo[8];
> +    uint16_t rx_fifo[8];
> +    qemu_irq irq;
> +    SSIBus *ssi;
> +} PL022State;
> +
> +#endif
> diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c
> index c1368018ee3..379d3093987 100644
> --- a/hw/ssi/pl022.c
> +++ b/hw/ssi/pl022.c
> @@ -9,6 +9,7 @@
>  
>  #include "qemu/osdep.h"
>  #include "hw/sysbus.h"
> +#include "hw/ssi/pl022.h"
>  #include "hw/ssi/ssi.h"
>  #include "qemu/log.h"
>  
> @@ -41,31 +42,6 @@ do { fprintf(stderr, "pl022: error: " fmt , ## __VA_ARGS__);} while (0)
>  #define PL022_INT_RX  0x04
>  #define PL022_INT_TX  0x08
>  
> -#define TYPE_PL022 "pl022"
> -#define PL022(obj) OBJECT_CHECK(PL022State, (obj), TYPE_PL022)
> -
> -typedef struct PL022State {
> -    SysBusDevice parent_obj;
> -
> -    MemoryRegion iomem;
> -    uint32_t cr0;
> -    uint32_t cr1;
> -    uint32_t bitmask;
> -    uint32_t sr;
> -    uint32_t cpsr;
> -    uint32_t is;
> -    uint32_t im;
> -    /* The FIFO head points to the next empty entry.  */
> -    int tx_fifo_head;
> -    int rx_fifo_head;
> -    int tx_fifo_len;
> -    int rx_fifo_len;
> -    uint16_t tx_fifo[8];
> -    uint16_t rx_fifo[8];
> -    qemu_irq irq;
> -    SSIBus *ssi;
> -} PL022State;
> -
>  static const unsigned char pl022_id[8] =
>    { 0x22, 0x10, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
>  
> diff --git a/MAINTAINERS b/MAINTAINERS
> index b2f8b562dc5..1e81ad8d4b1 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -451,6 +451,8 @@ F: hw/gpio/pl061.c
>  F: hw/input/pl050.c
>  F: hw/intc/pl190.c
>  F: hw/sd/pl181.c
> +F: hw/ssi/pl022.c
> +F: include/hw/ssi/pl022.h
>  F: hw/timer/pl031.c
>  F: include/hw/arm/primecell.h
>  F: hw/timer/cmsdk-apb-timer.c
> 

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

* Re: [Qemu-devel] [PATCH 16/22] hw/ssi/pl022: Set up reset function in class init
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 16/22] hw/ssi/pl022: Set up reset function in class init Peter Maydell
@ 2018-08-21  6:49   ` Philippe Mathieu-Daudé
  2018-08-23 17:29   ` Richard Henderson
  1 sibling, 0 replies; 56+ messages in thread
From: Philippe Mathieu-Daudé @ 2018-08-21  6:49 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/20/2018 11:11 AM, Peter Maydell wrote:
> Currently the PL022 calls pl022_reset() from its class init
> function. Make it register a DeviceState reset method instead,
> so that we reset the device on system reset.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

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

> ---
>  hw/ssi/pl022.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c
> index 379d3093987..0b5f90b857f 100644
> --- a/hw/ssi/pl022.c
> +++ b/hw/ssi/pl022.c
> @@ -203,8 +203,10 @@ static void pl022_write(void *opaque, hwaddr offset,
>      }
>  }
>  
> -static void pl022_reset(PL022State *s)
> +static void pl022_reset(DeviceState *dev)
>  {
> +    PL022State *s = PL022(dev);
> +
>      s->rx_fifo_len = 0;
>      s->tx_fifo_len = 0;
>      s->im = 0;
> @@ -277,7 +279,6 @@ static int pl022_init(SysBusDevice *sbd)
>      sysbus_init_mmio(sbd, &s->iomem);
>      sysbus_init_irq(sbd, &s->irq);
>      s->ssi = ssi_create_bus(dev, "ssi");
> -    pl022_reset(s);
>      vmstate_register(dev, -1, &vmstate_pl022, s);
>      return 0;
>  }
> @@ -285,8 +286,10 @@ static int pl022_init(SysBusDevice *sbd)
>  static void pl022_class_init(ObjectClass *klass, void *data)
>  {
>      SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
> +    DeviceClass *dc = DEVICE_CLASS(klass);
>  
>      sdc->init = pl022_init;
> +    dc->reset = pl022_reset;
>  }
>  
>  static const TypeInfo pl022_info = {
> 

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

* Re: [Qemu-devel] [PATCH 18/22] hw/ssi/pl022: Use DeviceState::realize rather than SysBusDevice::init
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 18/22] hw/ssi/pl022: Use DeviceState::realize rather than SysBusDevice::init Peter Maydell
@ 2018-08-21  6:53   ` Philippe Mathieu-Daudé
  2018-08-23 10:11     ` Peter Maydell
  2018-08-23 17:31   ` Richard Henderson
  1 sibling, 1 reply; 56+ messages in thread
From: Philippe Mathieu-Daudé @ 2018-08-21  6:53 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches

On 08/20/2018 11:11 AM, Peter Maydell wrote:
> Move from the legacy SysBusDevice::init method to using
> DeviceState::realize.

It would be nice to have a wiki page where each maintainer list his
deprecated/legacy API and which current API to use instead (and why,
some examples how to use or port, pointing to git commits).

> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

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

> ---
>  hw/ssi/pl022.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c
> index c9989537062..3ac57f4c96a 100644
> --- a/hw/ssi/pl022.c
> +++ b/hw/ssi/pl022.c
> @@ -270,26 +270,24 @@ static const VMStateDescription vmstate_pl022 = {
>      }
>  };
>  
> -static int pl022_init(SysBusDevice *sbd)
> +static void pl022_realize(DeviceState *dev, Error **errp)
>  {
> -    DeviceState *dev = DEVICE(sbd);
> +    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
>      PL022State *s = PL022(dev);
>  
>      memory_region_init_io(&s->iomem, OBJECT(s), &pl022_ops, s, "pl022", 0x1000);
>      sysbus_init_mmio(sbd, &s->iomem);
>      sysbus_init_irq(sbd, &s->irq);
>      s->ssi = ssi_create_bus(dev, "ssi");
> -    return 0;
>  }
>  
>  static void pl022_class_init(ObjectClass *klass, void *data)
>  {
> -    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
>      DeviceClass *dc = DEVICE_CLASS(klass);
>  
> -    sdc->init = pl022_init;
>      dc->reset = pl022_reset;
>      dc->vmsd = &vmstate_pl022;
> +    dc->realize = pl022_realize;
>  }
>  
>  static const TypeInfo pl022_info = {
> 

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

* Re: [Qemu-devel] [PATCH 01/22] hw/misc/mps2-fpgaio: Implement 1Hz and 100Hz counters
  2018-08-20 14:10 ` [Qemu-devel] [PATCH 01/22] hw/misc/mps2-fpgaio: Implement 1Hz and 100Hz counters Peter Maydell
@ 2018-08-21 18:34   ` Richard Henderson
  0 siblings, 0 replies; 56+ messages in thread
From: Richard Henderson @ 2018-08-21 18:34 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Philippe Mathieu-Daudé, patches

On 08/20/2018 07:10 AM, Peter Maydell wrote:
> The MPS2 FPGAIO block includes some simple free-running counters.
> Implement these.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  include/hw/misc/mps2-fpgaio.h |  4 +++
>  hw/misc/mps2-fpgaio.c         | 53 ++++++++++++++++++++++++++++++++++-
>  2 files changed, 56 insertions(+), 1 deletion(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 18/22] hw/ssi/pl022: Use DeviceState::realize rather than SysBusDevice::init
  2018-08-21  6:53   ` Philippe Mathieu-Daudé
@ 2018-08-23 10:11     ` Peter Maydell
  0 siblings, 0 replies; 56+ messages in thread
From: Peter Maydell @ 2018-08-23 10:11 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé; +Cc: qemu-arm, QEMU Developers, patches

On 21 August 2018 at 07:53, Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
> On 08/20/2018 11:11 AM, Peter Maydell wrote:
>> Move from the legacy SysBusDevice::init method to using
>> DeviceState::realize.
>
> It would be nice to have a wiki page where each maintainer list his
> deprecated/legacy API and which current API to use instead (and why,
> some examples how to use or port, pointing to git commits).

This one is mentioned in:
https://wiki.qemu.org/ToDo/CodeTransitions

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH 02/22] hw/misc/mps2-fpgaio: Implement PSCNTR and COUNTER
  2018-08-20 14:10 ` [Qemu-devel] [PATCH 02/22] hw/misc/mps2-fpgaio: Implement PSCNTR and COUNTER Peter Maydell
@ 2018-08-23 13:31   ` Richard Henderson
  0 siblings, 0 replies; 56+ messages in thread
From: Richard Henderson @ 2018-08-23 13:31 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Philippe Mathieu-Daudé, patches

On 08/20/2018 07:10 AM, Peter Maydell wrote:
> In the MPS2 FPGAIO, PSCNTR is a free-running downcounter with
> a reload value configured via the PRESCALE register, and
> COUNTER counts up by 1 every time PSCNTR reaches zero.
> Implement these counters.
> 
> We can just increment the counters migration subsection's
> version ID because we only added it in the previous commit,
> so no released QEMU versions will be using it.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
> ---
>  include/hw/misc/mps2-fpgaio.h |  6 +++
>  hw/misc/mps2-fpgaio.c         | 97 +++++++++++++++++++++++++++++++++--
>  2 files changed, 99 insertions(+), 4 deletions(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 03/22] hw/timer/cmsdk-apb-dualtimer: Implement CMSDK dual timer module
  2018-08-20 14:10 ` [Qemu-devel] [PATCH 03/22] hw/timer/cmsdk-apb-dualtimer: Implement CMSDK dual timer module Peter Maydell
@ 2018-08-23 14:08   ` Richard Henderson
  0 siblings, 0 replies; 56+ messages in thread
From: Richard Henderson @ 2018-08-23 14:08 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Philippe Mathieu-Daudé, patches

On 08/20/2018 07:10 AM, Peter Maydell wrote:
> +            if (!(m->control & R_CONTROL_SIZE_MASK)) {
> +                load = deposit32(load, 16, 16, extract32(m->load, 16, 16));
> +            }

The same result, but clearer as

  load = deposit32(m->load, 0, 16, load);

Several instances of this same pattern.

Otherwise,

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


r~

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

* Re: [Qemu-devel] [PATCH 04/22] hw/arm/iotkit: Wire up the dualtimer
  2018-08-20 14:10 ` [Qemu-devel] [PATCH 04/22] hw/arm/iotkit: Wire up the dualtimer Peter Maydell
  2018-08-21  6:41   ` Philippe Mathieu-Daudé
@ 2018-08-23 14:09   ` Richard Henderson
  1 sibling, 0 replies; 56+ messages in thread
From: Richard Henderson @ 2018-08-23 14:09 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Philippe Mathieu-Daudé, patches

On 08/20/2018 07:10 AM, Peter Maydell wrote:
> Now we have a model of the CMSDK dual timer, we can wire it
> up in the IoTKit.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  include/hw/arm/iotkit.h | 3 ++-
>  hw/arm/iotkit.c         | 8 +++++---
>  2 files changed, 7 insertions(+), 4 deletions(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 05/22] hw/arm/mps2: Wire up dual-timer in mps2-an385 and mps2-an511
  2018-08-20 14:10 ` [Qemu-devel] [PATCH 05/22] hw/arm/mps2: Wire up dual-timer in mps2-an385 and mps2-an511 Peter Maydell
  2018-08-21  6:43   ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
@ 2018-08-23 14:11   ` Richard Henderson
  1 sibling, 0 replies; 56+ messages in thread
From: Richard Henderson @ 2018-08-23 14:11 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Philippe Mathieu-Daudé, patches

On 08/20/2018 07:10 AM, Peter Maydell wrote:
> The MPS2 FPGA images for the Cortex-M3 (mps2-an385 and mps2-511)
> both include a CMSDK dual-timer module. Wire this up.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/arm/mps2.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)

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


r~

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

* Re: [Qemu-devel] [PATCH 06/22] hw/arm/iotkit: Wire up the watchdogs
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 06/22] hw/arm/iotkit: Wire up the watchdogs Peter Maydell
@ 2018-08-23 14:17   ` Richard Henderson
  0 siblings, 0 replies; 56+ messages in thread
From: Richard Henderson @ 2018-08-23 14:17 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Philippe Mathieu-Daudé, patches

On 08/20/2018 07:11 AM, Peter Maydell wrote:
> The IoTKit includes three different instances of the
> CMSDK APB watchdog; create and wire them up.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
>  include/hw/arm/iotkit.h |  6 +++++
>  hw/arm/iotkit.c         | 58 ++++++++++++++++++++++++++++++++++++++---
>  2 files changed, 61 insertions(+), 3 deletions(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 07/22] hw/arm/iotkit: Wire up the S32KTIMER
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 07/22] hw/arm/iotkit: Wire up the S32KTIMER Peter Maydell
@ 2018-08-23 14:18   ` Richard Henderson
  0 siblings, 0 replies; 56+ messages in thread
From: Richard Henderson @ 2018-08-23 14:18 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Philippe Mathieu-Daudé, patches

On 08/20/2018 07:11 AM, Peter Maydell wrote:
> The IoTKit has a CMSDK timer device that runs on the S32KCLK.
> Create this and wire it up.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
>  include/hw/arm/iotkit.h | 2 +-
>  hw/arm/iotkit.c         | 9 +++++----
>  2 files changed, 6 insertions(+), 5 deletions(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 08/22] hw/misc/iotkit-sysctl: Implement IoTKit system control element
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 08/22] hw/misc/iotkit-sysctl: Implement IoTKit system control element Peter Maydell
@ 2018-08-23 14:24   ` Richard Henderson
  0 siblings, 0 replies; 56+ messages in thread
From: Richard Henderson @ 2018-08-23 14:24 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Philippe Mathieu-Daudé, patches

On 08/20/2018 07:11 AM, Peter Maydell wrote:
> The Arm IoTKit includes a system control element which
> provides a block of read-only ID registers and a block
> of read-write control registers. Implement a minimal
> version of this.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/misc/Makefile.objs           |   1 +
>  include/hw/misc/iotkit-sysctl.h |  49 ++++++
>  hw/misc/iotkit-sysctl.c         | 261 ++++++++++++++++++++++++++++++++
>  MAINTAINERS                     |   2 +
>  default-configs/arm-softmmu.mak |   1 +
>  hw/misc/trace-events            |   7 +
>  6 files changed, 321 insertions(+)
>  create mode 100644 include/hw/misc/iotkit-sysctl.h
>  create mode 100644 hw/misc/iotkit-sysctl.c

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


r~

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

* Re: [Qemu-devel] [PATCH 09/22] hw/misc/iotkit-sysinfo: Implement IoTKit system information block
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 09/22] hw/misc/iotkit-sysinfo: Implement IoTKit system information block Peter Maydell
  2018-08-21  6:45   ` Philippe Mathieu-Daudé
@ 2018-08-23 14:28   ` Richard Henderson
  1 sibling, 0 replies; 56+ messages in thread
From: Richard Henderson @ 2018-08-23 14:28 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Philippe Mathieu-Daudé, patches

On 08/20/2018 07:11 AM, Peter Maydell wrote:
> Implement the IoTKit system control element's system information
> block; this is just a pair of read-only version/config registers,
> plus the usual PID/CID ID registers.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/misc/Makefile.objs            |   1 +
>  include/hw/misc/iotkit-sysinfo.h |  37 +++++++++
>  hw/misc/iotkit-sysinfo.c         | 128 +++++++++++++++++++++++++++++++
>  MAINTAINERS                      |   2 +
>  default-configs/arm-softmmu.mak  |   1 +
>  5 files changed, 169 insertions(+)
>  create mode 100644 include/hw/misc/iotkit-sysinfo.h
>  create mode 100644 hw/misc/iotkit-sysinfo.c

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


r~

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

* Re: [Qemu-devel] [PATCH 10/22] hw/misc/iotkit: Wire up the sysctl and sysinfo register blocks
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 10/22] hw/misc/iotkit: Wire up the sysctl and sysinfo register blocks Peter Maydell
  2018-08-21  6:47   ` Philippe Mathieu-Daudé
@ 2018-08-23 14:29   ` Richard Henderson
  1 sibling, 0 replies; 56+ messages in thread
From: Richard Henderson @ 2018-08-23 14:29 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Philippe Mathieu-Daudé, patches

On 08/20/2018 07:11 AM, Peter Maydell wrote:
> Wire up the system control element's register banks
> (sysctl and sysinfo).
> 
> This is the last of the previously completely unimplemented
> components in the IoTKit.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  include/hw/arm/iotkit.h |  6 +++++-
>  hw/arm/iotkit.c         | 26 ++++++++++++++++++--------
>  2 files changed, 23 insertions(+), 9 deletions(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 11/22] hw/misc/tz-msc: Model TrustZone Master Security Controller
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 11/22] hw/misc/tz-msc: Model TrustZone Master Security Controller Peter Maydell
@ 2018-08-23 17:18   ` Richard Henderson
  0 siblings, 0 replies; 56+ messages in thread
From: Richard Henderson @ 2018-08-23 17:18 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Philippe Mathieu-Daudé, patches

On 08/20/2018 07:11 AM, Peter Maydell wrote:
> Implement a model of the TrustZone Master Securtiy Controller,
> as documented in the Arm CoreLink SIE-200 System IP for
> Embedded TRM  (DDI0571G):
>   https://developer.arm.com/products/architecture/m-profile/docs/ddi0571/g
> 
> The MSC is intended to sit in front of a device which can
> be a bus master (eg a DMA controller) and programmably gate
> its transactions. This allows a bus-mastering device to be
> controlled by non-secure code but still restricted from
> making accesses to addresses which are secure-only.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/misc/Makefile.objs           |   1 +
>  include/hw/misc/tz-msc.h        |  79 ++++++++
>  hw/misc/tz-msc.c                | 308 ++++++++++++++++++++++++++++++++
>  MAINTAINERS                     |   2 +
>  default-configs/arm-softmmu.mak |   1 +
>  hw/misc/trace-events            |   9 +
>  6 files changed, 400 insertions(+)
>  create mode 100644 include/hw/misc/tz-msc.h
>  create mode 100644 hw/misc/tz-msc.c

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


r~

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

* Re: [Qemu-devel] [PATCH 12/22] hw/misc/iotkit-secctl: Wire up registers for controlling MSCs
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 12/22] hw/misc/iotkit-secctl: Wire up registers for controlling MSCs Peter Maydell
@ 2018-08-23 17:21   ` Richard Henderson
  2018-08-23 17:25     ` Peter Maydell
  0 siblings, 1 reply; 56+ messages in thread
From: Richard Henderson @ 2018-08-23 17:21 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Philippe Mathieu-Daudé, patches

On 08/20/2018 07:11 AM, Peter Maydell wrote:
> The IoTKit does not have any Master Security Contollers itself,
> but it does provide registers in the secure privilege control
> block which allow control of MSCs in the external system.
> Add support for these registers.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
>  include/hw/misc/iotkit-secctl.h | 14 +++++++
>  hw/misc/iotkit-secctl.c         | 73 +++++++++++++++++++++++++++++----
>  2 files changed, 79 insertions(+), 8 deletions(-)


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

>  
> +static bool needed_always(void *opaque)
> +{
> +    return true;
> +}

We really should either make NULL imply just this,
or export one copy from generic code.  Soon...


r~

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

* Re: [Qemu-devel] [PATCH 13/22] hw/arm/iotkit: Wire up the lines for MSCs
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 13/22] hw/arm/iotkit: Wire up the lines for MSCs Peter Maydell
@ 2018-08-23 17:23   ` Richard Henderson
  0 siblings, 0 replies; 56+ messages in thread
From: Richard Henderson @ 2018-08-23 17:23 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Philippe Mathieu-Daudé, patches

On 08/20/2018 07:11 AM, Peter Maydell wrote:
> The IoTKit doesn't have any MSCs itself but it does need
> some wiring to connect the external signals from MSCs
> in the outer board model up to the registers and the
> NVIC IRQ line.
> 
> We also need to expose a MemoryRegion corresponding to
> the AHB bus, so that MSCs in the outer board model can
> use that as their downstream port. (In the FPGA this is
> the "AHB Slave Expansion" ports shown in the block
> diagram in the AN505 documentation.)
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
>  include/hw/arm/iotkit.h |  8 ++++++++
>  hw/arm/iotkit.c         | 15 +++++++++++++++
>  2 files changed, 23 insertions(+)

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


r~

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

* Re: [Qemu-devel] [PATCH 12/22] hw/misc/iotkit-secctl: Wire up registers for controlling MSCs
  2018-08-23 17:21   ` Richard Henderson
@ 2018-08-23 17:25     ` Peter Maydell
  0 siblings, 0 replies; 56+ messages in thread
From: Peter Maydell @ 2018-08-23 17:25 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-arm, QEMU Developers, Philippe Mathieu-Daudé, patches

On 23 August 2018 at 18:21, Richard Henderson
<richard.henderson@linaro.org> wrote:
> On 08/20/2018 07:11 AM, Peter Maydell wrote:
>> The IoTKit does not have any Master Security Contollers itself,
>> but it does provide registers in the secure privilege control
>> block which allow control of MSCs in the external system.
>> Add support for these registers.
>>
>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
>> ---
>>  include/hw/misc/iotkit-secctl.h | 14 +++++++
>>  hw/misc/iotkit-secctl.c         | 73 +++++++++++++++++++++++++++++----
>>  2 files changed, 79 insertions(+), 8 deletions(-)
>
>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>
>>
>> +static bool needed_always(void *opaque)
>> +{
>> +    return true;
>> +}
>
> We really should either make NULL imply just this,
> or export one copy from generic code.  Soon...

I sent a patch for doing the former, but it got some pushback
from Juan:
https://patchwork.ozlabs.org/patch/954507/

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH 14/22] hw/arm/mps2-tz: Create PL081s and MSCs
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 14/22] hw/arm/mps2-tz: Create PL081s and MSCs Peter Maydell
@ 2018-08-23 17:27   ` Richard Henderson
  0 siblings, 0 replies; 56+ messages in thread
From: Richard Henderson @ 2018-08-23 17:27 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Philippe Mathieu-Daudé, patches

On 08/20/2018 07:11 AM, Peter Maydell wrote:
> The AN505 FPGA image includes four PL081 DMA controllers, each
> of which is gated by a Master Security Controller that allows
> the guest to prevent a non-secure DMA controller from accessing
> memory that is used by secure guest code. Create and wire
> up these devices.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
> v2 changes:
>  - use 'sizeof(*msc)', 'sizeof(*dma)' as suggested
>    by Phillipe in code review
>  - s/init_sysbus_child/sysbus_init_child_obj/, required by
>    rebase on current master
> ---
>  hw/arm/mps2-tz.c | 100 +++++++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 93 insertions(+), 7 deletions(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 15/22] hw/ssi/pl022: Allow use as embedded-struct device
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 15/22] hw/ssi/pl022: Allow use as embedded-struct device Peter Maydell
  2018-08-21  6:48   ` Philippe Mathieu-Daudé
@ 2018-08-23 17:29   ` Richard Henderson
  1 sibling, 0 replies; 56+ messages in thread
From: Richard Henderson @ 2018-08-23 17:29 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Philippe Mathieu-Daudé, patches

On 08/20/2018 07:11 AM, Peter Maydell wrote:
> Create a new include file for the pl022's device struct,
> type macros, etc, so that it can be instantiated using
> the "embedded struct" coding style.
> 
> While we're adding the new file to MAINTAINERS, add
> also the .c file, which was missing an entry.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  include/hw/ssi/pl022.h | 51 ++++++++++++++++++++++++++++++++++++++++++
>  hw/ssi/pl022.c         | 26 +--------------------
>  MAINTAINERS            |  2 ++
>  3 files changed, 54 insertions(+), 25 deletions(-)
>  create mode 100644 include/hw/ssi/pl022.h

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


r~

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

* Re: [Qemu-devel] [PATCH 16/22] hw/ssi/pl022: Set up reset function in class init
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 16/22] hw/ssi/pl022: Set up reset function in class init Peter Maydell
  2018-08-21  6:49   ` Philippe Mathieu-Daudé
@ 2018-08-23 17:29   ` Richard Henderson
  1 sibling, 0 replies; 56+ messages in thread
From: Richard Henderson @ 2018-08-23 17:29 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Philippe Mathieu-Daudé, patches

On 08/20/2018 07:11 AM, Peter Maydell wrote:
> Currently the PL022 calls pl022_reset() from its class init
> function. Make it register a DeviceState reset method instead,
> so that we reset the device on system reset.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/ssi/pl022.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 17/22] hw/ssi/pl022: Don't directly call vmstate_register()
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 17/22] hw/ssi/pl022: Don't directly call vmstate_register() Peter Maydell
@ 2018-08-23 17:30   ` Richard Henderson
  0 siblings, 0 replies; 56+ messages in thread
From: Richard Henderson @ 2018-08-23 17:30 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Philippe Mathieu-Daudé, patches

On 08/20/2018 07:11 AM, Peter Maydell wrote:
> Use the DeviceState vmsd pointer rather than calling vmstate_register()
> directly.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/ssi/pl022.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 18/22] hw/ssi/pl022: Use DeviceState::realize rather than SysBusDevice::init
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 18/22] hw/ssi/pl022: Use DeviceState::realize rather than SysBusDevice::init Peter Maydell
  2018-08-21  6:53   ` Philippe Mathieu-Daudé
@ 2018-08-23 17:31   ` Richard Henderson
  1 sibling, 0 replies; 56+ messages in thread
From: Richard Henderson @ 2018-08-23 17:31 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Philippe Mathieu-Daudé, patches

On 08/20/2018 07:11 AM, Peter Maydell wrote:
> Move from the legacy SysBusDevice::init method to using
> DeviceState::realize.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/ssi/pl022.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 19/22] hw/ssi/pl022: Correct wrong value for PL022_INT_RT
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 19/22] hw/ssi/pl022: Correct wrong value for PL022_INT_RT Peter Maydell
@ 2018-08-23 17:33   ` Richard Henderson
  0 siblings, 0 replies; 56+ messages in thread
From: Richard Henderson @ 2018-08-23 17:33 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Philippe Mathieu-Daudé, patches

On 08/20/2018 07:11 AM, Peter Maydell wrote:
> The PL022 interrupt registers have bits allocated as:
>  0: ROR (receive overrun)
>  1: RT (receive timeout)
>  2: RX (receive FIFO half full or less)
>  3: TX (transmit FIFO half full or less)
> 
> A cut and paste error meant we had the wrong value for
> the PL022_INT_RT constant. This bug doesn't affect device
> behaviour, because we don't implmenet the receive timeout

implement.

> feature and so never set that interrupt bit.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/ssi/pl022.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 20/22] hw/ssi/pl022: Correct wrong DMACR and ICR handling
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 20/22] hw/ssi/pl022: Correct wrong DMACR and ICR handling Peter Maydell
@ 2018-08-23 17:38   ` Richard Henderson
  0 siblings, 0 replies; 56+ messages in thread
From: Richard Henderson @ 2018-08-23 17:38 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Philippe Mathieu-Daudé, patches

On 08/20/2018 07:11 AM, Peter Maydell wrote:
> In the PL022, register offset 0x20 is the ICR, a write-only
> interrupt-clear register.  Register offset 0x24 is DMACR, the DMA
> control register.  We were incorrectly implementing (a stub version
> of) DMACR at 0x20, and not implementing anything at 0x24.  Fix this
> bug.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/ssi/pl022.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 21/22] hw/arm/mps2-tz: Instantiate SPI controllers
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 21/22] hw/arm/mps2-tz: Instantiate SPI controllers Peter Maydell
@ 2018-08-23 17:39   ` Richard Henderson
  0 siblings, 0 replies; 56+ messages in thread
From: Richard Henderson @ 2018-08-23 17:39 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Philippe Mathieu-Daudé, patches

On 08/20/2018 07:11 AM, Peter Maydell wrote:
> The SPI controllers in the MPS2 AN505 board are PL022s.
> We have a model of the PL022, so create these devices.
> 
> We don't currently model the LCD controller that sits behind
> one of the PL022s; the others are intended to control devices
> that sit on the FPGA's general purpose SPI connector or
> "shield" expansion connectors.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/arm/mps2-tz.c | 38 ++++++++++++++++++++++++++++++++------
>  1 file changed, 32 insertions(+), 6 deletions(-)

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


r~

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

* Re: [Qemu-devel] [PATCH 22/22] hw/arm/mps2-tz: Fix MPS2 SCC config register values
  2018-08-20 14:11 ` [Qemu-devel] [PATCH 22/22] hw/arm/mps2-tz: Fix MPS2 SCC config register values Peter Maydell
@ 2018-08-23 17:42   ` Richard Henderson
  2018-08-23 17:45     ` Peter Maydell
  0 siblings, 1 reply; 56+ messages in thread
From: Richard Henderson @ 2018-08-23 17:42 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Philippe Mathieu-Daudé, patches

On 08/20/2018 07:11 AM, Peter Maydell wrote:
> +    mmc->scc_id = 0x41040000 | (0x505 << 4);

Is it any less clear to say 0x41045050?

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


r~

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

* Re: [Qemu-devel] [PATCH 22/22] hw/arm/mps2-tz: Fix MPS2 SCC config register values
  2018-08-23 17:42   ` Richard Henderson
@ 2018-08-23 17:45     ` Peter Maydell
  2018-08-23 17:46       ` Peter Maydell
  0 siblings, 1 reply; 56+ messages in thread
From: Peter Maydell @ 2018-08-23 17:45 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-arm, QEMU Developers, Philippe Mathieu-Daudé, patches

On 23 August 2018 at 18:42, Richard Henderson
<richard.henderson@linaro.org> wrote:
> On 08/20/2018 07:11 AM, Peter Maydell wrote:
>> +    mmc->scc_id = 0x41040000 | (0x505 << 4);
>
> Is it any less clear to say 0x41045050?

It makes it a bit clearer that that field is the number
from the image name, I think. (Compare the an385
and an511 init functions, which I notice I also need
to update to fix the equivalent bug there.)

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH 22/22] hw/arm/mps2-tz: Fix MPS2 SCC config register values
  2018-08-23 17:45     ` Peter Maydell
@ 2018-08-23 17:46       ` Peter Maydell
  0 siblings, 0 replies; 56+ messages in thread
From: Peter Maydell @ 2018-08-23 17:46 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-arm, QEMU Developers, Philippe Mathieu-Daudé, patches

On 23 August 2018 at 18:45, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 23 August 2018 at 18:42, Richard Henderson
> <richard.henderson@linaro.org> wrote:
>> On 08/20/2018 07:11 AM, Peter Maydell wrote:
>>> +    mmc->scc_id = 0x41040000 | (0x505 << 4);
>>
>> Is it any less clear to say 0x41045050?
>
> It makes it a bit clearer that that field is the number
> from the image name, I think. (Compare the an385
> and an511 init functions, which I notice I also need
> to update to fix the equivalent bug there.)

...though I guess that's less true now we're using a
hex constant rather than decimal. So yeah, we could just
say 0x41045050.

thanks
-- PMM

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

end of thread, other threads:[~2018-08-23 17:47 UTC | newest]

Thread overview: 56+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-20 14:10 [Qemu-devel] [PATCH 00/22] MPS devices: FPGAIO, timer, watchdogs, MSC, DMA, SPI Peter Maydell
2018-08-20 14:10 ` [Qemu-devel] [PATCH 01/22] hw/misc/mps2-fpgaio: Implement 1Hz and 100Hz counters Peter Maydell
2018-08-21 18:34   ` Richard Henderson
2018-08-20 14:10 ` [Qemu-devel] [PATCH 02/22] hw/misc/mps2-fpgaio: Implement PSCNTR and COUNTER Peter Maydell
2018-08-23 13:31   ` Richard Henderson
2018-08-20 14:10 ` [Qemu-devel] [PATCH 03/22] hw/timer/cmsdk-apb-dualtimer: Implement CMSDK dual timer module Peter Maydell
2018-08-23 14:08   ` Richard Henderson
2018-08-20 14:10 ` [Qemu-devel] [PATCH 04/22] hw/arm/iotkit: Wire up the dualtimer Peter Maydell
2018-08-21  6:41   ` Philippe Mathieu-Daudé
2018-08-23 14:09   ` Richard Henderson
2018-08-20 14:10 ` [Qemu-devel] [PATCH 05/22] hw/arm/mps2: Wire up dual-timer in mps2-an385 and mps2-an511 Peter Maydell
2018-08-21  6:43   ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
2018-08-23 14:11   ` [Qemu-devel] " Richard Henderson
2018-08-20 14:11 ` [Qemu-devel] [PATCH 06/22] hw/arm/iotkit: Wire up the watchdogs Peter Maydell
2018-08-23 14:17   ` Richard Henderson
2018-08-20 14:11 ` [Qemu-devel] [PATCH 07/22] hw/arm/iotkit: Wire up the S32KTIMER Peter Maydell
2018-08-23 14:18   ` Richard Henderson
2018-08-20 14:11 ` [Qemu-devel] [PATCH 08/22] hw/misc/iotkit-sysctl: Implement IoTKit system control element Peter Maydell
2018-08-23 14:24   ` Richard Henderson
2018-08-20 14:11 ` [Qemu-devel] [PATCH 09/22] hw/misc/iotkit-sysinfo: Implement IoTKit system information block Peter Maydell
2018-08-21  6:45   ` Philippe Mathieu-Daudé
2018-08-23 14:28   ` Richard Henderson
2018-08-20 14:11 ` [Qemu-devel] [PATCH 10/22] hw/misc/iotkit: Wire up the sysctl and sysinfo register blocks Peter Maydell
2018-08-21  6:47   ` Philippe Mathieu-Daudé
2018-08-23 14:29   ` Richard Henderson
2018-08-20 14:11 ` [Qemu-devel] [PATCH 11/22] hw/misc/tz-msc: Model TrustZone Master Security Controller Peter Maydell
2018-08-23 17:18   ` Richard Henderson
2018-08-20 14:11 ` [Qemu-devel] [PATCH 12/22] hw/misc/iotkit-secctl: Wire up registers for controlling MSCs Peter Maydell
2018-08-23 17:21   ` Richard Henderson
2018-08-23 17:25     ` Peter Maydell
2018-08-20 14:11 ` [Qemu-devel] [PATCH 13/22] hw/arm/iotkit: Wire up the lines for MSCs Peter Maydell
2018-08-23 17:23   ` Richard Henderson
2018-08-20 14:11 ` [Qemu-devel] [PATCH 14/22] hw/arm/mps2-tz: Create PL081s and MSCs Peter Maydell
2018-08-23 17:27   ` Richard Henderson
2018-08-20 14:11 ` [Qemu-devel] [PATCH 15/22] hw/ssi/pl022: Allow use as embedded-struct device Peter Maydell
2018-08-21  6:48   ` Philippe Mathieu-Daudé
2018-08-23 17:29   ` Richard Henderson
2018-08-20 14:11 ` [Qemu-devel] [PATCH 16/22] hw/ssi/pl022: Set up reset function in class init Peter Maydell
2018-08-21  6:49   ` Philippe Mathieu-Daudé
2018-08-23 17:29   ` Richard Henderson
2018-08-20 14:11 ` [Qemu-devel] [PATCH 17/22] hw/ssi/pl022: Don't directly call vmstate_register() Peter Maydell
2018-08-23 17:30   ` Richard Henderson
2018-08-20 14:11 ` [Qemu-devel] [PATCH 18/22] hw/ssi/pl022: Use DeviceState::realize rather than SysBusDevice::init Peter Maydell
2018-08-21  6:53   ` Philippe Mathieu-Daudé
2018-08-23 10:11     ` Peter Maydell
2018-08-23 17:31   ` Richard Henderson
2018-08-20 14:11 ` [Qemu-devel] [PATCH 19/22] hw/ssi/pl022: Correct wrong value for PL022_INT_RT Peter Maydell
2018-08-23 17:33   ` Richard Henderson
2018-08-20 14:11 ` [Qemu-devel] [PATCH 20/22] hw/ssi/pl022: Correct wrong DMACR and ICR handling Peter Maydell
2018-08-23 17:38   ` Richard Henderson
2018-08-20 14:11 ` [Qemu-devel] [PATCH 21/22] hw/arm/mps2-tz: Instantiate SPI controllers Peter Maydell
2018-08-23 17:39   ` Richard Henderson
2018-08-20 14:11 ` [Qemu-devel] [PATCH 22/22] hw/arm/mps2-tz: Fix MPS2 SCC config register values Peter Maydell
2018-08-23 17:42   ` Richard Henderson
2018-08-23 17:45     ` Peter Maydell
2018-08-23 17:46       ` 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.