All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/44] hw/arm: New board model mps3-an547
@ 2021-02-19 14:45 Peter Maydell
  2021-02-19 14:45 ` [PATCH 01/44] clock: Add ClockEvent parameter to callbacks Peter Maydell
                   ` (45 more replies)
  0 siblings, 46 replies; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

This patchseries implements a model of the AN547 FPGA image for the
MPS3 board.  The main benefit of this new board is that it uses the
Cortex-M55 CPU and so it allows running guests which use a v8.1M CPU.

This FPGA image is based on the SSE-300, so most of the series is
really implementing the SSE-300 model.  The differences between the
SSE-200 and SSE-300 are mostly not very exciting, but there's a lot
of minor tweaking of things like ID register values.  We also need to
support the way the SSE-300 has rearranged the address map, so the
middle part of the series adds a framework for making the config of
the devices behind the PPUs data-driven.

The SSE-300 also has new counter and timer devices, so the series
includes models of those and tests for them.  The interesting feature
of these devices is that the SSE system counter device provides a
64-bit count to other timer devices in the system; those timer
devices do not run off a direct clock, but only off the count value. 
(In hardware, there is a 64-bit count value that's connected from the
counter to all the timers.) For QEMU I have implemented this by
giving the timers a QOM link property so they can be passed the
counter device they are connected to, plus some public functions
for the counter device for things like "get the count value"
and "tell me when the count will hit this value". The SSE-300
also has a system watchdog device which works off the counter in
the same way, but in this series I have not modelled the watchdog.

The first four patches in the series are the Clock API patches I put
out for review earlier.

Based-on: 20210215115138.20465-1-peter.maydell@linaro.org
("[PATCH v2 00/24] hw/arm: New board model mps3-an524")
which added most of the flexibility to the mps2-tz.c code
to support these new boards.

thanks
-- PMM

Peter Maydell (44):
  clock: Add ClockEvent parameter to callbacks
  clock: Add ClockPreUpdate callback event type
  clock: Add clock_ns_to_ticks() function
  hw/timer/npcm7xx_timer: Use new clock_ns_to_ticks()
  hw/arm/armsse: Introduce SSE subsystem version property
  hw/misc/iotkit-sysctl: Remove is_sse200 flag
  hw/misc/iotkit-secctl.c: Implement SSE-300 PID register values
  hw/misc/iotkit-sysinfo.c: Implement SSE-300 PID register values
  hw/arm/armsse.c: Use correct SYS_CONFIG0 register value for SSE-300
  hw/misc/iotkit-sysinfo.c: Implement SYS_CONFIG1 and IIDR
  hw/timer/sse-counter: Model the SSE Subsystem System Counter
  hw/timer/sse-timer: Model the SSE Subsystem System Timer
  hw/misc/iotkit-sysctl: Add SSE-300 cases which match SSE-200 behaviour
  hw/misc/iotkit-sysctl: Handle CPU_WAIT, NMI_ENABLE for SSE-300
  hw/misc/iotkit-sysctl: Handle INITSVTOR* for SSE-300
  hw/misc/iotkit-sysctl: Implement dummy version of SSE-300 PWRCTRL
    register
  hw/misc/iotkit-sysctl: Handle SSE-300 changes to PDCM_PD_*_SENSE
    registers
  hw/misc/iotkit-sysctl: Implement SSE-200 and SSE-300 PID register
    values
  hw/arm/Kconfig: Move ARMSSE_CPUID and ARMSSE_MHU stanzas to hw/misc
  hw/misc/sse-cpu-pwrctrl: Implement SSE-300 CPU<N>_PWRCTRL register
    block
  hw/arm/armsse: Use an array for apb_ppc fields in the state structure
  hw/arm/armsse: Add a define for number of IRQs used by the SSE itself
  hw/arm/armsse: Add framework for data-driven device placement
  hw/arm/armsse: Move dual-timer device into data-driven framework
  hw/arm/armsse: Move watchdogs into data-driven framework
  hw/arm/armsse: Move s32ktimer into data-driven framework
  hw/arm/armsse: Move sysinfo register block into data-driven framework
  hw/arm/armsse: Move sysctl register block into data-driven framework
  hw/arm/armsse: Move PPUs into data-driven framework
  hw/arm/armsse: Add missing SSE-200 SYS_PPU
  hw/arm/armsse: Indirect irq_is_common[] through ARMSSEInfo
  hw/arm/armsse: Add support for SSE variants with a system counter
  hw/arm/armsse: Add support for TYPE_SSE_TIMER in ARMSSEDeviceInfo
  hw/arm/armsse: Support variants with ARMSSE_CPU_PWRCTRL block
  hw/arm/armsse: Add SSE-300 support
  hw/arm/mps2-tz: Make UART overflow IRQ board-specific
  hw/misc/mps2-fpgaio: Fold counters subsection into main vmstate
  hw/misc/mps2-fpgaio: Support AN547 DBGCTRL register
  hw/misc/mps2-scc: Implement changes for AN547
  hw/arm/mps2-tz: Support running APB peripherals on different clock
  hw/arm/mps2-tz: Make initsvtor0 setting board-specific
  hw/arm/mps2-tz: Add new mps3-an547 board
  docs/system/arm/mps2.rst: Document the new mps3-an547 board
  tests/qtest/sse-timer-test: Add simple tests of the SSE timer and
    counter

 docs/devel/clocks.rst                |   71 +-
 docs/system/arm/mps2.rst             |    6 +-
 include/hw/arm/armsse-version.h      |   42 ++
 include/hw/arm/armsse.h              |   40 +-
 include/hw/clock.h                   |   63 +-
 include/hw/misc/armsse-cpu-pwrctrl.h |   40 +
 include/hw/misc/iotkit-secctl.h      |    2 +
 include/hw/misc/iotkit-sysctl.h      |   13 +-
 include/hw/misc/iotkit-sysinfo.h     |    2 +
 include/hw/misc/mps2-fpgaio.h        |    2 +
 include/hw/qdev-clock.h              |   17 +-
 include/hw/timer/sse-counter.h       |  105 +++
 include/hw/timer/sse-timer.h         |   53 ++
 hw/adc/npcm7xx_adc.c                 |    2 +-
 hw/arm/armsse.c                      | 1008 +++++++++++++++++++-------
 hw/arm/mps2-tz.c                     |  168 ++++-
 hw/char/cadence_uart.c               |    4 +-
 hw/char/ibex_uart.c                  |    4 +-
 hw/char/pl011.c                      |    5 +-
 hw/core/clock.c                      |   24 +-
 hw/core/qdev-clock.c                 |    8 +-
 hw/mips/cps.c                        |    2 +-
 hw/misc/armsse-cpu-pwrctrl.c         |  149 ++++
 hw/misc/bcm2835_cprman.c             |   23 +-
 hw/misc/iotkit-secctl.c              |   50 +-
 hw/misc/iotkit-sysctl.c              |  521 ++++++++++---
 hw/misc/iotkit-sysinfo.c             |   51 +-
 hw/misc/mps2-fpgaio.c                |   52 +-
 hw/misc/mps2-scc.c                   |   15 +-
 hw/misc/npcm7xx_clk.c                |   26 +-
 hw/misc/npcm7xx_pwm.c                |    2 +-
 hw/misc/zynq_slcr.c                  |    5 +-
 hw/timer/cmsdk-apb-dualtimer.c       |    5 +-
 hw/timer/cmsdk-apb-timer.c           |    4 +-
 hw/timer/npcm7xx_timer.c             |    6 +-
 hw/timer/sse-counter.c               |  474 ++++++++++++
 hw/timer/sse-timer.c                 |  470 ++++++++++++
 hw/watchdog/cmsdk-apb-watchdog.c     |    5 +-
 target/mips/cpu.c                    |    2 +-
 tests/qtest/sse-timer-test.c         |  240 ++++++
 MAINTAINERS                          |    7 +
 hw/arm/Kconfig                       |    9 +-
 hw/misc/Kconfig                      |    9 +
 hw/misc/meson.build                  |    1 +
 hw/misc/trace-events                 |    4 +
 hw/timer/Kconfig                     |    6 +
 hw/timer/meson.build                 |    2 +
 hw/timer/trace-events                |   12 +
 tests/qtest/meson.build              |    1 +
 49 files changed, 3356 insertions(+), 476 deletions(-)
 create mode 100644 include/hw/arm/armsse-version.h
 create mode 100644 include/hw/misc/armsse-cpu-pwrctrl.h
 create mode 100644 include/hw/timer/sse-counter.h
 create mode 100644 include/hw/timer/sse-timer.h
 create mode 100644 hw/misc/armsse-cpu-pwrctrl.c
 create mode 100644 hw/timer/sse-counter.c
 create mode 100644 hw/timer/sse-timer.c
 create mode 100644 tests/qtest/sse-timer-test.c

-- 
2.20.1



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

* [PATCH 01/44] clock: Add ClockEvent parameter to callbacks
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-03-04  2:50   ` Richard Henderson
  2021-02-19 14:45 ` [PATCH 02/44] clock: Add ClockPreUpdate callback event type Peter Maydell
                   ` (44 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The Clock framework allows users to specify a callback which is
called after the clock's period has been updated.  Some users need to
also have a callback which is called before the clock period is
updated.

As the first step in adding support for notifying Clock users on
pre-update events, add an argument to the ClockCallback to specify
what event is being notified, and add an argument to the various
functions for registering a callback to specify which events are
of interest to that callback.

Note that the documentation update renders correct the previously
incorrect claim in 'Adding a new clock' that callbacks "will be
explained in a following section".

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Luc Michel <luc@lmichel.fr>
---
v2->v3: used 'unsigned int' instead of 'int' for parameters
and struct fields containing an event mask, as suggested by Philippe;
fixed events argument to qdev_init_clock_in() with NULL callback
pointer in npcm7xx_adc.c (spotted by Hao)
---
 docs/devel/clocks.rst            | 52 +++++++++++++++++++++++++++-----
 include/hw/clock.h               | 21 +++++++++++--
 include/hw/qdev-clock.h          | 17 ++++++++---
 hw/adc/npcm7xx_adc.c             |  2 +-
 hw/arm/armsse.c                  |  9 +++---
 hw/char/cadence_uart.c           |  4 +--
 hw/char/ibex_uart.c              |  4 +--
 hw/char/pl011.c                  |  5 +--
 hw/core/clock.c                  | 21 ++++++++++---
 hw/core/qdev-clock.c             |  8 +++--
 hw/mips/cps.c                    |  2 +-
 hw/misc/bcm2835_cprman.c         | 23 ++++++++------
 hw/misc/npcm7xx_clk.c            | 26 +++++++++++++---
 hw/misc/npcm7xx_pwm.c            |  2 +-
 hw/misc/zynq_slcr.c              |  5 +--
 hw/timer/cmsdk-apb-dualtimer.c   |  5 +--
 hw/timer/cmsdk-apb-timer.c       |  4 +--
 hw/timer/npcm7xx_timer.c         |  2 +-
 hw/watchdog/cmsdk-apb-watchdog.c |  5 +--
 target/mips/cpu.c                |  2 +-
 20 files changed, 161 insertions(+), 58 deletions(-)

diff --git a/docs/devel/clocks.rst b/docs/devel/clocks.rst
index c54bbb82409..cd344e3fe5d 100644
--- a/docs/devel/clocks.rst
+++ b/docs/devel/clocks.rst
@@ -80,11 +80,12 @@ Adding clocks to a device must be done during the init method of the Device
 instance.
 
 To add an input clock to a device, the function ``qdev_init_clock_in()``
-must be used.  It takes the name, a callback and an opaque parameter
-for the callback (this will be explained in a following section).
+must be used.  It takes the name, a callback, an opaque parameter
+for the callback and a mask of events when the callback should be
+called (this will be explained in a following section).
 Output is simpler; only the name is required. Typically::
 
-    qdev_init_clock_in(DEVICE(dev), "clk_in", clk_in_callback, dev);
+    qdev_init_clock_in(DEVICE(dev), "clk_in", clk_in_callback, dev, ClockUpdate);
     qdev_init_clock_out(DEVICE(dev), "clk_out");
 
 Both functions return the created Clock pointer, which should be saved in the
@@ -113,7 +114,7 @@ output.
      * callback for the input clock (see "Callback on input clock
      * change" section below for more information).
      */
-    static void clk_in_callback(void *opaque);
+    static void clk_in_callback(void *opaque, ClockEvent event);
 
     /*
      * static array describing clocks:
@@ -124,7 +125,7 @@ output.
      *   the clk_out field of a MyDeviceState structure.
      */
     static const ClockPortInitArray mydev_clocks = {
-        QDEV_CLOCK_IN(MyDeviceState, clk_in, clk_in_callback),
+        QDEV_CLOCK_IN(MyDeviceState, clk_in, clk_in_callback, ClockUpdate),
         QDEV_CLOCK_OUT(MyDeviceState, clk_out),
         QDEV_CLOCK_END
     };
@@ -153,6 +154,40 @@ nothing else to do. This value will be propagated to other clocks when
 connecting the clocks together and devices will fetch the right value during
 the first reset.
 
+Clock callbacks
+---------------
+
+You can give a clock a callback function in several ways:
+
+ * by passing it as an argument to ``qdev_init_clock_in()``
+ * as an argument to the ``QDEV_CLOCK_IN()`` macro initializing an
+   array to be passed to ``qdev_init_clocks()``
+ * by directly calling the ``clock_set_callback()`` function
+
+The callback function must be of this type:
+
+.. code-block:: c
+
+   typedef void ClockCallback(void *opaque, ClockEvent event);
+
+The ``opaque`` argument is the pointer passed to ``qdev_init_clock_in()``
+or ``clock_set_callback()``; for ``qdev_init_clocks()`` it is the
+``dev`` device pointer.
+
+The ``event`` argument specifies why the callback has been called.
+When you register the callback you specify a mask of ClockEvent values
+that you are interested in. The callback will only be called for those
+events.
+
+The events currently supported are:
+
+ * ``ClockUpdate`` : called after the input clock's period has changed
+
+Note that a clock only has one callback: it is not possible to register
+different functions for different events. You must register a single
+callback which listens for all of the events you are interested in,
+and use the ``event`` argument to identify which event has happened.
+
 Retrieving clocks from a device
 -------------------------------
 
@@ -231,7 +266,7 @@ object during device instance init. For example:
 .. code-block:: c
 
     clk = qdev_init_clock_in(DEVICE(dev), "clk-in", clk_in_callback,
-                             dev);
+                             dev, ClockUpdate);
     /* set initial value to 10ns / 100MHz */
     clock_set_ns(clk, 10);
 
@@ -267,11 +302,12 @@ next lowest integer. This implies some inaccuracy due to the rounding,
 so be cautious about using it in calculations.
 
 It is also possible to register a callback on clock frequency changes.
-Here is an example:
+Here is an example, which assumes that ``clock_callback`` has been
+specified as the callback for the ``ClockUpdate`` event:
 
 .. code-block:: c
 
-    void clock_callback(void *opaque) {
+    void clock_callback(void *opaque, ClockEvent event) {
         MyDeviceState *s = (MyDeviceState *) opaque;
         /*
          * 'opaque' is the argument passed to qdev_init_clock_in();
diff --git a/include/hw/clock.h b/include/hw/clock.h
index e5f45e2626d..282a37f7c5a 100644
--- a/include/hw/clock.h
+++ b/include/hw/clock.h
@@ -22,7 +22,17 @@
 #define TYPE_CLOCK "clock"
 OBJECT_DECLARE_SIMPLE_TYPE(Clock, CLOCK)
 
-typedef void ClockCallback(void *opaque);
+/*
+ * Argument to ClockCallback functions indicating why the callback
+ * has been called. A mask of these values logically ORed together
+ * is used to specify which events are interesting when the callback
+ * is registered, so these values must all be different bit values.
+ */
+typedef enum ClockEvent {
+    ClockUpdate = 1, /* Clock period has just updated */
+} ClockEvent;
+
+typedef void ClockCallback(void *opaque, ClockEvent event);
 
 /*
  * clock store a value representing the clock's period in 2^-32ns unit.
@@ -50,6 +60,7 @@ typedef void ClockCallback(void *opaque);
  * @canonical_path: clock path string cache (used for trace purpose)
  * @callback: called when clock changes
  * @callback_opaque: argument for @callback
+ * @callback_events: mask of events when callback should be called
  * @source: source (or parent in clock tree) of the clock
  * @children: list of clocks connected to this one (it is their source)
  * @sibling: structure used to form a clock list
@@ -67,6 +78,7 @@ struct Clock {
     char *canonical_path;
     ClockCallback *callback;
     void *callback_opaque;
+    unsigned int callback_events;
 
     /* Clocks are organized in a clock tree */
     Clock *source;
@@ -114,10 +126,15 @@ Clock *clock_new(Object *parent, const char *name);
  * @clk: the clock to register the callback into
  * @cb: the callback function
  * @opaque: the argument to the callback
+ * @events: the events the callback should be called for
+ *          (logical OR of ClockEvent enum values)
  *
  * Register a callback called on every clock update.
+ * Note that a clock has only one callback: you cannot register
+ * different callback functions for different events.
  */
-void clock_set_callback(Clock *clk, ClockCallback *cb, void *opaque);
+void clock_set_callback(Clock *clk, ClockCallback *cb,
+                        void *opaque, unsigned int events);
 
 /**
  * clock_clear_callback:
diff --git a/include/hw/qdev-clock.h b/include/hw/qdev-clock.h
index 64ca4d266f2..ffa0f7ba09e 100644
--- a/include/hw/qdev-clock.h
+++ b/include/hw/qdev-clock.h
@@ -22,6 +22,8 @@
  * @name: the name of the clock (can't be NULL).
  * @callback: optional callback to be called on update or NULL.
  * @opaque: argument for the callback
+ * @events: the events the callback should be called for
+ *          (logical OR of ClockEvent enum values)
  * @returns: a pointer to the newly added clock
  *
  * Add an input clock to device @dev as a clock named @name.
@@ -29,7 +31,8 @@
  * The callback will be called with @opaque as opaque parameter.
  */
 Clock *qdev_init_clock_in(DeviceState *dev, const char *name,
-                          ClockCallback *callback, void *opaque);
+                          ClockCallback *callback, void *opaque,
+                          unsigned int events);
 
 /**
  * qdev_init_clock_out:
@@ -105,6 +108,7 @@ void qdev_finalize_clocklist(DeviceState *dev);
  * @output: indicates whether the clock is input or output
  * @callback: for inputs, optional callback to be called on clock's update
  * with device as opaque
+ * @callback_events: mask of ClockEvent values for when callback is called
  * @offset: optional offset to store the ClockIn or ClockOut pointer in device
  * state structure (0 means unused)
  */
@@ -112,6 +116,7 @@ struct ClockPortInitElem {
     const char *name;
     bool is_output;
     ClockCallback *callback;
+    unsigned int callback_events;
     size_t offset;
 };
 
@@ -119,10 +124,11 @@ struct ClockPortInitElem {
     (offsetof(devstate, field) + \
      type_check(Clock *, typeof_field(devstate, field)))
 
-#define QDEV_CLOCK(out_not_in, devstate, field, cb) { \
+#define QDEV_CLOCK(out_not_in, devstate, field, cb, cbevents) {  \
     .name = (stringify(field)), \
     .is_output = out_not_in, \
     .callback = cb, \
+    .callback_events = cbevents, \
     .offset = clock_offset_value(devstate, field), \
 }
 
@@ -133,14 +139,15 @@ struct ClockPortInitElem {
  * @field: a field in @_devstate (must be Clock*)
  * @callback: (for input only) callback (or NULL) to be called with the device
  * state as argument
+ * @cbevents: (for input only) ClockEvent mask for when callback is called
  *
  * The name of the clock will be derived from @field
  */
-#define QDEV_CLOCK_IN(devstate, field, callback) \
-    QDEV_CLOCK(false, devstate, field, callback)
+#define QDEV_CLOCK_IN(devstate, field, callback, cbevents)       \
+    QDEV_CLOCK(false, devstate, field, callback, cbevents)
 
 #define QDEV_CLOCK_OUT(devstate, field) \
-    QDEV_CLOCK(true, devstate, field, NULL)
+    QDEV_CLOCK(true, devstate, field, NULL, 0)
 
 #define QDEV_CLOCK_END { .name = NULL }
 
diff --git a/hw/adc/npcm7xx_adc.c b/hw/adc/npcm7xx_adc.c
index 870a6d50c27..0f0a9f63e20 100644
--- a/hw/adc/npcm7xx_adc.c
+++ b/hw/adc/npcm7xx_adc.c
@@ -238,7 +238,7 @@ static void npcm7xx_adc_init(Object *obj)
     memory_region_init_io(&s->iomem, obj, &npcm7xx_adc_ops, s,
                           TYPE_NPCM7XX_ADC, 4 * KiB);
     sysbus_init_mmio(sbd, &s->iomem);
-    s->clock = qdev_init_clock_in(DEVICE(s), "clock", NULL, NULL);
+    s->clock = qdev_init_clock_in(DEVICE(s), "clock", NULL, NULL, 0);
 
     for (i = 0; i < NPCM7XX_ADC_NUM_INPUTS; ++i) {
         object_property_add_uint32_ptr(obj, "adci[*]",
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index 26e1a8c95b6..fa155b72022 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -230,9 +230,10 @@ static void armsse_forward_sec_resp_cfg(ARMSSE *s)
     qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
 }
 
-static void armsse_mainclk_update(void *opaque)
+static void armsse_mainclk_update(void *opaque, ClockEvent event)
 {
     ARMSSE *s = ARM_SSE(opaque);
+
     /*
      * Set system_clock_scale from our Clock input; this is what
      * controls the tick rate of the CPU SysTick timer.
@@ -251,8 +252,8 @@ static void armsse_init(Object *obj)
     assert(info->num_cpus <= SSE_MAX_CPUS);
 
     s->mainclk = qdev_init_clock_in(DEVICE(s), "MAINCLK",
-                                    armsse_mainclk_update, s);
-    s->s32kclk = qdev_init_clock_in(DEVICE(s), "S32KCLK", NULL, NULL);
+                                    armsse_mainclk_update, s, ClockUpdate);
+    s->s32kclk = qdev_init_clock_in(DEVICE(s), "S32KCLK", NULL, NULL, 0);
 
     memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
 
@@ -1120,7 +1121,7 @@ static void armsse_realize(DeviceState *dev, Error **errp)
     sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
 
     /* Set initial system_clock_scale from MAINCLK */
-    armsse_mainclk_update(s);
+    armsse_mainclk_update(s, ClockUpdate);
 }
 
 static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
index c603e14012a..ceb677bc5a8 100644
--- a/hw/char/cadence_uart.c
+++ b/hw/char/cadence_uart.c
@@ -519,7 +519,7 @@ static void cadence_uart_realize(DeviceState *dev, Error **errp)
                              uart_event, NULL, s, NULL, true);
 }
 
-static void cadence_uart_refclk_update(void *opaque)
+static void cadence_uart_refclk_update(void *opaque, ClockEvent event)
 {
     CadenceUARTState *s = opaque;
 
@@ -537,7 +537,7 @@ static void cadence_uart_init(Object *obj)
     sysbus_init_irq(sbd, &s->irq);
 
     s->refclk = qdev_init_clock_in(DEVICE(obj), "refclk",
-            cadence_uart_refclk_update, s);
+                                   cadence_uart_refclk_update, s, ClockUpdate);
     /* initialize the frequency in case the clock remains unconnected */
     clock_set_hz(s->refclk, UART_DEFAULT_REF_CLK);
 
diff --git a/hw/char/ibex_uart.c b/hw/char/ibex_uart.c
index 89f1182c9bf..edcaa30aded 100644
--- a/hw/char/ibex_uart.c
+++ b/hw/char/ibex_uart.c
@@ -396,7 +396,7 @@ static void ibex_uart_write(void *opaque, hwaddr addr,
     }
 }
 
-static void ibex_uart_clk_update(void *opaque)
+static void ibex_uart_clk_update(void *opaque, ClockEvent event)
 {
     IbexUartState *s = opaque;
 
@@ -466,7 +466,7 @@ static void ibex_uart_init(Object *obj)
     IbexUartState *s = IBEX_UART(obj);
 
     s->f_clk = qdev_init_clock_in(DEVICE(obj), "f_clock",
-                                  ibex_uart_clk_update, s);
+                                  ibex_uart_clk_update, s, ClockUpdate);
     clock_set_hz(s->f_clk, IBEX_UART_CLOCK);
 
     sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->tx_watermark);
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
index ea4a4e52356..c5621a195ff 100644
--- a/hw/char/pl011.c
+++ b/hw/char/pl011.c
@@ -309,7 +309,7 @@ static void pl011_event(void *opaque, QEMUChrEvent event)
         pl011_put_fifo(opaque, 0x400);
 }
 
-static void pl011_clock_update(void *opaque)
+static void pl011_clock_update(void *opaque, ClockEvent event)
 {
     PL011State *s = PL011(opaque);
 
@@ -378,7 +378,8 @@ static void pl011_init(Object *obj)
         sysbus_init_irq(sbd, &s->irq[i]);
     }
 
-    s->clk = qdev_init_clock_in(DEVICE(obj), "clk", pl011_clock_update, s);
+    s->clk = qdev_init_clock_in(DEVICE(obj), "clk", pl011_clock_update, s,
+                                ClockUpdate);
 
     s->read_trigger = 1;
     s->ifl = 0x12;
diff --git a/hw/core/clock.c b/hw/core/clock.c
index 76b5f468b6e..4479eff145b 100644
--- a/hw/core/clock.c
+++ b/hw/core/clock.c
@@ -39,15 +39,17 @@ Clock *clock_new(Object *parent, const char *name)
     return clk;
 }
 
-void clock_set_callback(Clock *clk, ClockCallback *cb, void *opaque)
+void clock_set_callback(Clock *clk, ClockCallback *cb, void *opaque,
+                        unsigned int events)
 {
     clk->callback = cb;
     clk->callback_opaque = opaque;
+    clk->callback_events = events;
 }
 
 void clock_clear_callback(Clock *clk)
 {
-    clock_set_callback(clk, NULL, NULL);
+    clock_set_callback(clk, NULL, NULL, 0);
 }
 
 bool clock_set(Clock *clk, uint64_t period)
@@ -62,6 +64,17 @@ bool clock_set(Clock *clk, uint64_t period)
     return true;
 }
 
+static void clock_call_callback(Clock *clk, ClockEvent event)
+{
+    /*
+     * Call the Clock's callback for this event, if it has one and
+     * is interested in this event.
+     */
+    if (clk->callback && (clk->callback_events & event)) {
+        clk->callback(clk->callback_opaque, event);
+    }
+}
+
 static void clock_propagate_period(Clock *clk, bool call_callbacks)
 {
     Clock *child;
@@ -72,8 +85,8 @@ static void clock_propagate_period(Clock *clk, bool call_callbacks)
             trace_clock_update(CLOCK_PATH(child), CLOCK_PATH(clk),
                                CLOCK_PERIOD_TO_HZ(clk->period),
                                call_callbacks);
-            if (call_callbacks && child->callback) {
-                child->callback(child->callback_opaque);
+            if (call_callbacks) {
+                clock_call_callback(child, ClockUpdate);
             }
             clock_propagate_period(child, call_callbacks);
         }
diff --git a/hw/core/qdev-clock.c b/hw/core/qdev-clock.c
index eb05f2a13ca..117f4c6ea4a 100644
--- a/hw/core/qdev-clock.c
+++ b/hw/core/qdev-clock.c
@@ -111,7 +111,8 @@ Clock *qdev_init_clock_out(DeviceState *dev, const char *name)
 }
 
 Clock *qdev_init_clock_in(DeviceState *dev, const char *name,
-                            ClockCallback *callback, void *opaque)
+                          ClockCallback *callback, void *opaque,
+                          unsigned int events)
 {
     NamedClockList *ncl;
 
@@ -120,7 +121,7 @@ Clock *qdev_init_clock_in(DeviceState *dev, const char *name,
     ncl = qdev_init_clocklist(dev, name, false, NULL);
 
     if (callback) {
-        clock_set_callback(ncl->clock, callback, opaque);
+        clock_set_callback(ncl->clock, callback, opaque, events);
     }
     return ncl->clock;
 }
@@ -137,7 +138,8 @@ void qdev_init_clocks(DeviceState *dev, const ClockPortInitArray clocks)
         if (elem->is_output) {
             *clkp = qdev_init_clock_out(dev, elem->name);
         } else {
-            *clkp = qdev_init_clock_in(dev, elem->name, elem->callback, dev);
+            *clkp = qdev_init_clock_in(dev, elem->name, elem->callback, dev,
+                                       elem->callback_events);
         }
     }
 }
diff --git a/hw/mips/cps.c b/hw/mips/cps.c
index 7a0d289efaf..2b436700ce6 100644
--- a/hw/mips/cps.c
+++ b/hw/mips/cps.c
@@ -39,7 +39,7 @@ static void mips_cps_init(Object *obj)
     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
     MIPSCPSState *s = MIPS_CPS(obj);
 
-    s->clock = qdev_init_clock_in(DEVICE(obj), "clk-in", NULL, NULL);
+    s->clock = qdev_init_clock_in(DEVICE(obj), "clk-in", NULL, NULL, 0);
     /*
      * Cover entire address space as there do not seem to be any
      * constraints for the base address of CPC and GIC.
diff --git a/hw/misc/bcm2835_cprman.c b/hw/misc/bcm2835_cprman.c
index 7e415a017c9..75e6c574d46 100644
--- a/hw/misc/bcm2835_cprman.c
+++ b/hw/misc/bcm2835_cprman.c
@@ -107,7 +107,7 @@ static void pll_update(CprmanPllState *pll)
     clock_update_hz(pll->out, freq);
 }
 
-static void pll_xosc_update(void *opaque)
+static void pll_xosc_update(void *opaque, ClockEvent event)
 {
     pll_update(CPRMAN_PLL(opaque));
 }
@@ -116,7 +116,8 @@ static void pll_init(Object *obj)
 {
     CprmanPllState *s = CPRMAN_PLL(obj);
 
-    s->xosc_in = qdev_init_clock_in(DEVICE(s), "xosc-in", pll_xosc_update, s);
+    s->xosc_in = qdev_init_clock_in(DEVICE(s), "xosc-in", pll_xosc_update,
+                                    s, ClockUpdate);
     s->out = qdev_init_clock_out(DEVICE(s), "out");
 }
 
@@ -209,7 +210,7 @@ static void pll_update_all_channels(BCM2835CprmanState *s,
     }
 }
 
-static void pll_channel_pll_in_update(void *opaque)
+static void pll_channel_pll_in_update(void *opaque, ClockEvent event)
 {
     pll_channel_update(CPRMAN_PLL_CHANNEL(opaque));
 }
@@ -219,7 +220,8 @@ static void pll_channel_init(Object *obj)
     CprmanPllChannelState *s = CPRMAN_PLL_CHANNEL(obj);
 
     s->pll_in = qdev_init_clock_in(DEVICE(s), "pll-in",
-                                   pll_channel_pll_in_update, s);
+                                   pll_channel_pll_in_update, s,
+                                   ClockUpdate);
     s->out = qdev_init_clock_out(DEVICE(s), "out");
 }
 
@@ -303,7 +305,7 @@ static void clock_mux_update(CprmanClockMuxState *mux)
     clock_update_hz(mux->out, freq);
 }
 
-static void clock_mux_src_update(void *opaque)
+static void clock_mux_src_update(void *opaque, ClockEvent event)
 {
     CprmanClockMuxState **backref = opaque;
     CprmanClockMuxState *s = *backref;
@@ -335,7 +337,8 @@ static void clock_mux_init(Object *obj)
         s->backref[i] = s;
         s->srcs[i] = qdev_init_clock_in(DEVICE(s), name,
                                         clock_mux_src_update,
-                                        &s->backref[i]);
+                                        &s->backref[i],
+                                        ClockUpdate);
         g_free(name);
     }
 
@@ -380,7 +383,7 @@ static void dsi0hsck_mux_update(CprmanDsi0HsckMuxState *s)
     clock_update(s->out, clock_get(src));
 }
 
-static void dsi0hsck_mux_in_update(void *opaque)
+static void dsi0hsck_mux_in_update(void *opaque, ClockEvent event)
 {
     dsi0hsck_mux_update(CPRMAN_DSI0HSCK_MUX(opaque));
 }
@@ -390,8 +393,10 @@ static void dsi0hsck_mux_init(Object *obj)
     CprmanDsi0HsckMuxState *s = CPRMAN_DSI0HSCK_MUX(obj);
     DeviceState *dev = DEVICE(obj);
 
-    s->plla_in = qdev_init_clock_in(dev, "plla-in", dsi0hsck_mux_in_update, s);
-    s->plld_in = qdev_init_clock_in(dev, "plld-in", dsi0hsck_mux_in_update, s);
+    s->plla_in = qdev_init_clock_in(dev, "plla-in", dsi0hsck_mux_in_update,
+                                    s, ClockUpdate);
+    s->plld_in = qdev_init_clock_in(dev, "plld-in", dsi0hsck_mux_in_update,
+                                    s, ClockUpdate);
     s->out = qdev_init_clock_out(DEVICE(s), "out");
 }
 
diff --git a/hw/misc/npcm7xx_clk.c b/hw/misc/npcm7xx_clk.c
index 0bcae9ce957..a1ee67dc9a1 100644
--- a/hw/misc/npcm7xx_clk.c
+++ b/hw/misc/npcm7xx_clk.c
@@ -586,15 +586,26 @@ static const DividerInitInfo divider_init_info_list[] = {
     },
 };
 
+static void npcm7xx_clk_update_pll_cb(void *opaque, ClockEvent event)
+{
+    npcm7xx_clk_update_pll(opaque);
+}
+
 static void npcm7xx_clk_pll_init(Object *obj)
 {
     NPCM7xxClockPLLState *pll = NPCM7XX_CLOCK_PLL(obj);
 
     pll->clock_in = qdev_init_clock_in(DEVICE(pll), "clock-in",
-            npcm7xx_clk_update_pll, pll);
+                                       npcm7xx_clk_update_pll_cb, pll,
+                                       ClockUpdate);
     pll->clock_out = qdev_init_clock_out(DEVICE(pll), "clock-out");
 }
 
+static void npcm7xx_clk_update_sel_cb(void *opaque, ClockEvent event)
+{
+    npcm7xx_clk_update_sel(opaque);
+}
+
 static void npcm7xx_clk_sel_init(Object *obj)
 {
     int i;
@@ -603,16 +614,23 @@ static void npcm7xx_clk_sel_init(Object *obj)
     for (i = 0; i < NPCM7XX_CLK_SEL_MAX_INPUT; ++i) {
         sel->clock_in[i] = qdev_init_clock_in(DEVICE(sel),
                 g_strdup_printf("clock-in[%d]", i),
-                npcm7xx_clk_update_sel, sel);
+                npcm7xx_clk_update_sel_cb, sel, ClockUpdate);
     }
     sel->clock_out = qdev_init_clock_out(DEVICE(sel), "clock-out");
 }
+
+static void npcm7xx_clk_update_divider_cb(void *opaque, ClockEvent event)
+{
+    npcm7xx_clk_update_divider(opaque);
+}
+
 static void npcm7xx_clk_divider_init(Object *obj)
 {
     NPCM7xxClockDividerState *div = NPCM7XX_CLOCK_DIVIDER(obj);
 
     div->clock_in = qdev_init_clock_in(DEVICE(div), "clock-in",
-            npcm7xx_clk_update_divider, div);
+                                       npcm7xx_clk_update_divider_cb,
+                                       div, ClockUpdate);
     div->clock_out = qdev_init_clock_out(DEVICE(div), "clock-out");
 }
 
@@ -875,7 +893,7 @@ static void npcm7xx_clk_init_clock_hierarchy(NPCM7xxCLKState *s)
 {
     int i;
 
-    s->clkref = qdev_init_clock_in(DEVICE(s), "clkref", NULL, NULL);
+    s->clkref = qdev_init_clock_in(DEVICE(s), "clkref", NULL, NULL, 0);
 
     /* First pass: init all converter modules */
     QEMU_BUILD_BUG_ON(ARRAY_SIZE(pll_init_info_list) != NPCM7XX_CLOCK_NR_PLLS);
diff --git a/hw/misc/npcm7xx_pwm.c b/hw/misc/npcm7xx_pwm.c
index dabcb6c0f95..ce192bb2741 100644
--- a/hw/misc/npcm7xx_pwm.c
+++ b/hw/misc/npcm7xx_pwm.c
@@ -493,7 +493,7 @@ static void npcm7xx_pwm_init(Object *obj)
     memory_region_init_io(&s->iomem, obj, &npcm7xx_pwm_ops, s,
                           TYPE_NPCM7XX_PWM, 4 * KiB);
     sysbus_init_mmio(sbd, &s->iomem);
-    s->clock = qdev_init_clock_in(DEVICE(s), "clock", NULL, NULL);
+    s->clock = qdev_init_clock_in(DEVICE(s), "clock", NULL, NULL, 0);
 
     for (i = 0; i < NPCM7XX_PWM_PER_MODULE; ++i) {
         object_property_add_uint32_ptr(obj, "freq[*]",
diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c
index 66504a9d3ab..c66d7db177d 100644
--- a/hw/misc/zynq_slcr.c
+++ b/hw/misc/zynq_slcr.c
@@ -307,9 +307,10 @@ static void zynq_slcr_propagate_clocks(ZynqSLCRState *s)
     clock_propagate(s->uart1_ref_clk);
 }
 
-static void zynq_slcr_ps_clk_callback(void *opaque)
+static void zynq_slcr_ps_clk_callback(void *opaque, ClockEvent event)
 {
     ZynqSLCRState *s = (ZynqSLCRState *) opaque;
+
     zynq_slcr_compute_clocks(s);
     zynq_slcr_propagate_clocks(s);
 }
@@ -576,7 +577,7 @@ static const MemoryRegionOps slcr_ops = {
 };
 
 static const ClockPortInitArray zynq_slcr_clocks = {
-    QDEV_CLOCK_IN(ZynqSLCRState, ps_clk, zynq_slcr_ps_clk_callback),
+    QDEV_CLOCK_IN(ZynqSLCRState, ps_clk, zynq_slcr_ps_clk_callback, ClockUpdate),
     QDEV_CLOCK_OUT(ZynqSLCRState, uart0_ref_clk),
     QDEV_CLOCK_OUT(ZynqSLCRState, uart1_ref_clk),
     QDEV_CLOCK_END
diff --git a/hw/timer/cmsdk-apb-dualtimer.c b/hw/timer/cmsdk-apb-dualtimer.c
index ef49f5852d3..d4a509c798e 100644
--- a/hw/timer/cmsdk-apb-dualtimer.c
+++ b/hw/timer/cmsdk-apb-dualtimer.c
@@ -449,7 +449,7 @@ static void cmsdk_apb_dualtimer_reset(DeviceState *dev)
     s->timeritop = 0;
 }
 
-static void cmsdk_apb_dualtimer_clk_update(void *opaque)
+static void cmsdk_apb_dualtimer_clk_update(void *opaque, ClockEvent event)
 {
     CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(opaque);
     int i;
@@ -478,7 +478,8 @@ static void cmsdk_apb_dualtimer_init(Object *obj)
         sysbus_init_irq(sbd, &s->timermod[i].timerint);
     }
     s->timclk = qdev_init_clock_in(DEVICE(s), "TIMCLK",
-                                   cmsdk_apb_dualtimer_clk_update, s);
+                                   cmsdk_apb_dualtimer_clk_update, s,
+                                   ClockUpdate);
 }
 
 static void cmsdk_apb_dualtimer_realize(DeviceState *dev, Error **errp)
diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c
index ee51ce3369c..68aa1a76360 100644
--- a/hw/timer/cmsdk-apb-timer.c
+++ b/hw/timer/cmsdk-apb-timer.c
@@ -204,7 +204,7 @@ static void cmsdk_apb_timer_reset(DeviceState *dev)
     ptimer_transaction_commit(s->timer);
 }
 
-static void cmsdk_apb_timer_clk_update(void *opaque)
+static void cmsdk_apb_timer_clk_update(void *opaque, ClockEvent event)
 {
     CMSDKAPBTimer *s = CMSDK_APB_TIMER(opaque);
 
@@ -223,7 +223,7 @@ static void cmsdk_apb_timer_init(Object *obj)
     sysbus_init_mmio(sbd, &s->iomem);
     sysbus_init_irq(sbd, &s->timerint);
     s->pclk = qdev_init_clock_in(DEVICE(s), "pclk",
-                                 cmsdk_apb_timer_clk_update, s);
+                                 cmsdk_apb_timer_clk_update, s, ClockUpdate);
 }
 
 static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
diff --git a/hw/timer/npcm7xx_timer.c b/hw/timer/npcm7xx_timer.c
index 36e2c07db26..4efdf135b82 100644
--- a/hw/timer/npcm7xx_timer.c
+++ b/hw/timer/npcm7xx_timer.c
@@ -627,7 +627,7 @@ static void npcm7xx_timer_init(Object *obj)
     sysbus_init_mmio(sbd, &s->iomem);
     qdev_init_gpio_out_named(dev, &w->reset_signal,
             NPCM7XX_WATCHDOG_RESET_GPIO_OUT, 1);
-    s->clock = qdev_init_clock_in(dev, "clock", NULL, NULL);
+    s->clock = qdev_init_clock_in(dev, "clock", NULL, NULL, 0);
 }
 
 static const VMStateDescription vmstate_npcm7xx_base_timer = {
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
index 302f1711738..5a2cd46eb76 100644
--- a/hw/watchdog/cmsdk-apb-watchdog.c
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
@@ -310,7 +310,7 @@ static void cmsdk_apb_watchdog_reset(DeviceState *dev)
     ptimer_transaction_commit(s->timer);
 }
 
-static void cmsdk_apb_watchdog_clk_update(void *opaque)
+static void cmsdk_apb_watchdog_clk_update(void *opaque, ClockEvent event)
 {
     CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque);
 
@@ -329,7 +329,8 @@ static void cmsdk_apb_watchdog_init(Object *obj)
     sysbus_init_mmio(sbd, &s->iomem);
     sysbus_init_irq(sbd, &s->wdogint);
     s->wdogclk = qdev_init_clock_in(DEVICE(s), "WDOGCLK",
-                                    cmsdk_apb_watchdog_clk_update, s);
+                                    cmsdk_apb_watchdog_clk_update, s,
+                                    ClockUpdate);
 
     s->is_luminary = false;
     s->id = cmsdk_apb_watchdog_id;
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index ad163ead625..2f3d9d2ce2c 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -636,7 +636,7 @@ static void mips_cpu_initfn(Object *obj)
     MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(obj);
 
     cpu_set_cpustate_pointers(cpu);
-    cpu->clock = qdev_init_clock_in(DEVICE(obj), "clk-in", NULL, cpu);
+    cpu->clock = qdev_init_clock_in(DEVICE(obj), "clk-in", NULL, cpu, 0);
     env->cpu_model = mcc->cpu_def;
 }
 
-- 
2.20.1



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

* [PATCH 02/44] clock: Add ClockPreUpdate callback event type
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
  2021-02-19 14:45 ` [PATCH 01/44] clock: Add ClockEvent parameter to callbacks Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-02-19 14:45 ` [PATCH 03/44] clock: Add clock_ns_to_ticks() function Peter Maydell
                   ` (43 subsequent siblings)
  45 siblings, 0 replies; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Add a new callback event type ClockPreUpdate, which is called on
period changes before the period is updated.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Luc Michel <luc@lmichel.fr>
Reviewed-by: Hao Wu <wuhaotsh@google.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 docs/devel/clocks.rst | 9 ++++++++-
 include/hw/clock.h    | 1 +
 hw/core/clock.c       | 3 +++
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/docs/devel/clocks.rst b/docs/devel/clocks.rst
index cd344e3fe5d..f0391e76b4f 100644
--- a/docs/devel/clocks.rst
+++ b/docs/devel/clocks.rst
@@ -181,7 +181,14 @@ events.
 
 The events currently supported are:
 
- * ``ClockUpdate`` : called after the input clock's period has changed
+ * ``ClockPreUpdate`` : called when the input clock's period is about to
+   update. This is useful if the device needs to do some action for
+   which it needs to know the old value of the clock period. During
+   this callback, Clock API functions like ``clock_get()`` or
+   ``clock_ticks_to_ns()`` will use the old period.
+ * ``ClockUpdate`` : called after the input clock's period has changed.
+   During this callback, Clock API functions like ``clock_ticks_to_ns()``
+   will use the new period.
 
 Note that a clock only has one callback: it is not possible to register
 different functions for different events. You must register a single
diff --git a/include/hw/clock.h b/include/hw/clock.h
index 282a37f7c5a..2ba44e14424 100644
--- a/include/hw/clock.h
+++ b/include/hw/clock.h
@@ -30,6 +30,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(Clock, CLOCK)
  */
 typedef enum ClockEvent {
     ClockUpdate = 1, /* Clock period has just updated */
+    ClockPreUpdate = 2, /* Clock period is about to update */
 } ClockEvent;
 
 typedef void ClockCallback(void *opaque, ClockEvent event);
diff --git a/hw/core/clock.c b/hw/core/clock.c
index 4479eff145b..fc5a99683f8 100644
--- a/hw/core/clock.c
+++ b/hw/core/clock.c
@@ -81,6 +81,9 @@ static void clock_propagate_period(Clock *clk, bool call_callbacks)
 
     QLIST_FOREACH(child, &clk->children, sibling) {
         if (child->period != clk->period) {
+            if (call_callbacks) {
+                clock_call_callback(child, ClockPreUpdate);
+            }
             child->period = clk->period;
             trace_clock_update(CLOCK_PATH(child), CLOCK_PATH(clk),
                                CLOCK_PERIOD_TO_HZ(clk->period),
-- 
2.20.1



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

* [PATCH 03/44] clock: Add clock_ns_to_ticks() function
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
  2021-02-19 14:45 ` [PATCH 01/44] clock: Add ClockEvent parameter to callbacks Peter Maydell
  2021-02-19 14:45 ` [PATCH 02/44] clock: Add ClockPreUpdate callback event type Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-02-19 14:45 ` [PATCH 04/44] hw/timer/npcm7xx_timer: Use new clock_ns_to_ticks() Peter Maydell
                   ` (42 subsequent siblings)
  45 siblings, 0 replies; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Add a clock_ns_to_ticks() function which does the opposite of
clock_ticks_to_ns(): given a duration in nanoseconds, it returns the
number of clock ticks that would happen in that time.  This is useful
for devices that have a free running counter register whose value can
be calculated when it is read.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Luc Michel <luc@lmichel.fr>
Reviewed-by: Hao Wu <wuhaotsh@google.com>
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 docs/devel/clocks.rst | 12 ++++++++++++
 include/hw/clock.h    | 41 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)

diff --git a/docs/devel/clocks.rst b/docs/devel/clocks.rst
index f0391e76b4f..956bd147ea0 100644
--- a/docs/devel/clocks.rst
+++ b/docs/devel/clocks.rst
@@ -360,6 +360,18 @@ rather than simply passing it to a QEMUTimer function like
 ``timer_mod_ns()`` then you should be careful to avoid overflow
 in those calculations, of course.)
 
+Obtaining tick counts
+---------------------
+
+For calculations where you need to know the number of ticks in
+a given duration, use ``clock_ns_to_ticks()``. This function handles
+possible non-whole-number-of-nanoseconds periods and avoids
+potential rounding errors. It will return '0' if the clock is stopped
+(i.e. it has period zero). If the inputs imply a tick count that
+overflows a 64-bit value (a very long duration for a clock with a
+very short period) the output value is truncated, so effectively
+the 64-bit output wraps around.
+
 Changing a clock period
 -----------------------
 
diff --git a/include/hw/clock.h b/include/hw/clock.h
index 2ba44e14424..a7187eab95e 100644
--- a/include/hw/clock.h
+++ b/include/hw/clock.h
@@ -286,6 +286,47 @@ static inline uint64_t clock_ticks_to_ns(const Clock *clk, uint64_t ticks)
     return ns_low >> 32 | ns_high << 32;
 }
 
+/**
+ * clock_ns_to_ticks:
+ * @clk: the clock to query
+ * @ns: duration in nanoseconds
+ *
+ * Returns the number of ticks this clock would make in the given
+ * number of nanoseconds. Because a clock can have a period which
+ * is not a whole number of nanoseconds, it is important to use this
+ * function rather than attempting to obtain a "period in nanoseconds"
+ * value and then dividing the duration by that value.
+ *
+ * If the clock is stopped (ie it has period zero), returns 0.
+ *
+ * For some inputs the result could overflow a 64-bit value (because
+ * the clock's period is short and the duration is long). In these
+ * cases we truncate the result to a 64-bit value. This is on the
+ * assumption that generally the result is going to be used to report
+ * a 32-bit or 64-bit guest register value, so wrapping either cannot
+ * happen or is the desired behaviour.
+ */
+static inline uint64_t clock_ns_to_ticks(const Clock *clk, uint64_t ns)
+{
+    /*
+     * ticks = duration_in_ns / period_in_ns
+     *       = ns / (period / 2^32)
+     *       = (ns * 2^32) / period
+     * The hi, lo inputs to divu128() are (ns << 32) as a 128 bit value.
+     */
+    uint64_t lo = ns << 32;
+    uint64_t hi = ns >> 32;
+    if (clk->period == 0) {
+        return 0;
+    }
+    /*
+     * Ignore divu128() return value as we've caught div-by-zero and don't
+     * need different behaviour for overflow.
+     */
+    divu128(&lo, &hi, clk->period);
+    return lo;
+}
+
 /**
  * clock_is_enabled:
  * @clk: a clock
-- 
2.20.1



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

* [PATCH 04/44] hw/timer/npcm7xx_timer: Use new clock_ns_to_ticks()
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (2 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 03/44] clock: Add clock_ns_to_ticks() function Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-02-19 14:45 ` [PATCH 05/44] hw/arm/armsse: Introduce SSE subsystem version property Peter Maydell
                   ` (41 subsequent siblings)
  45 siblings, 0 replies; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Use the new clock_ns_to_ticks() function in npcm7xx_timer where
appropriate.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Luc Michel <luc@lmichel.fr>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Hao Wu <wuhaotsh@google.com>
---
 hw/timer/npcm7xx_timer.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/timer/npcm7xx_timer.c b/hw/timer/npcm7xx_timer.c
index 4efdf135b82..32f5e021f85 100644
--- a/hw/timer/npcm7xx_timer.c
+++ b/hw/timer/npcm7xx_timer.c
@@ -138,8 +138,8 @@ static int64_t npcm7xx_timer_count_to_ns(NPCM7xxTimer *t, uint32_t count)
 /* Convert a time interval in nanoseconds to a timer cycle count. */
 static uint32_t npcm7xx_timer_ns_to_count(NPCM7xxTimer *t, int64_t ns)
 {
-    return ns / clock_ticks_to_ns(t->ctrl->clock,
-                                  npcm7xx_tcsr_prescaler(t->tcsr));
+    return clock_ns_to_ticks(t->ctrl->clock, ns) /
+        npcm7xx_tcsr_prescaler(t->tcsr);
 }
 
 static uint32_t npcm7xx_watchdog_timer_prescaler(const NPCM7xxWatchdogTimer *t)
-- 
2.20.1



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

* [PATCH 05/44] hw/arm/armsse: Introduce SSE subsystem version property
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (3 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 04/44] hw/timer/npcm7xx_timer: Use new clock_ns_to_ticks() Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-03-04 17:10   ` Richard Henderson
  2021-02-19 14:45 ` [PATCH 06/44] hw/misc/iotkit-sysctl: Remove is_sse200 flag Peter Maydell
                   ` (40 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

We model Arm "Subsystems for Embedded" SoC subsystems using generic
code which is split into various sub-devices which are configurable
by QOM properties to handle the behaviour differences between the SSE
subsystems we implement.  Currently the only sub-device which needs
to change is the IOTKIT_SYSCTL device, and we do this with a mix of
properties that directly specify divergent behaviours (eg
CPUWAIT_RST) and passing it the SYS_VERSION register value as a way
for it to distinguish IoTKit from SSE-200.

The "pass SYS_VERSION" approach is already a bit hacky, since the
IOTKIT_SYSCTL device has to know that the different part of the
register value happens to be bits [31:28].  For SSE-300 this register
is renamed SOC_IDENTITY and has a different format entirely, all of
whose fields can be configured by the SoC integrator when they
integrate the SSE into their SoC, and so "pass SYS_VERSION" breaks
down completely.

Switch to using a simple integer property representing an
internal-to-QEMU enumeration of the SSE flavour.  For the moment we
only need this in IOTKIT_SYSCTL, but as we add SSE-300 support a few
of the other devices will also need to know.

We define and permit a value for the SSE-300 so we can start using
it in subsequent commits which add SSE-300 support.

The now-redundant is_sse200 flag in IoTKitSysCtl will be removed
in the following commit.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
I didn't use a full-on qdev/QOM 'enum' property here because that
requires messing with the QAPI schema, which seems like overkill for
this entirely-internal-to-the-implementation bit of information
passing.
---
 include/hw/arm/armsse-version.h | 42 +++++++++++++++++++++++++++++++++
 include/hw/misc/iotkit-sysctl.h |  7 +++---
 hw/arm/armsse.c                 |  8 +++++--
 hw/misc/iotkit-sysctl.c         | 11 +++++----
 4 files changed, 58 insertions(+), 10 deletions(-)
 create mode 100644 include/hw/arm/armsse-version.h

diff --git a/include/hw/arm/armsse-version.h b/include/hw/arm/armsse-version.h
new file mode 100644
index 00000000000..60780fa9843
--- /dev/null
+++ b/include/hw/arm/armsse-version.h
@@ -0,0 +1,42 @@
+/*
+ * ARM SSE (Subsystems for Embedded): IoTKit, SSE-200
+ *
+ * Copyright (c) 2020 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.
+ */
+
+#ifndef ARMSSE_VERSION_H
+#define ARMSSE_VERSION_H
+
+
+/*
+ * Define an enumeration of the possible values of the sse-version
+ * property implemented by various sub-devices of the SSE, and
+ * a validation function that checks that a valid value has been passed.
+ * These are arbitrary QEMU-internal values (nobody should be creating
+ * the sub-devices of the SSE except for the SSE object itself), but
+ * we pick obvious numbers for the benefit of people debugging with gdb.
+ */
+enum {
+    ARMSSE_IOTKIT = 0,
+    ARMSSE_SSE200 = 200,
+    ARMSSE_SSE300 = 300,
+};
+
+static inline bool armsse_version_valid(uint32_t sse_version)
+{
+    switch (sse_version) {
+    case ARMSSE_IOTKIT:
+    case ARMSSE_SSE200:
+    case ARMSSE_SSE300:
+        return true;
+    default:
+        return false;
+    }
+}
+
+#endif
diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
index 2bc391138db..7cdafea3e25 100644
--- a/include/hw/misc/iotkit-sysctl.h
+++ b/include/hw/misc/iotkit-sysctl.h
@@ -17,9 +17,8 @@
  * "system control register" blocks.
  *
  * QEMU interface:
- *  + QOM property "SYS_VERSION": value of the SYS_VERSION register of the
- *    system information block of the SSE
- *    (used to identify whether to provide SSE-200-only registers)
+ *  + QOM property "sse-version": indicates which SSE version this is part of
+ *    (used to identify whether to provide SSE-200-only registers, etc)
  *  + sysbus MMIO region 0: the system information register bank
  *  + sysbus MMIO region 1: the system control register bank
  */
@@ -61,7 +60,7 @@ struct IoTKitSysCtl {
     uint32_t pdcm_pd_sram3_sense;
 
     /* Properties */
-    uint32_t sys_version;
+    uint32_t sse_version;
     uint32_t cpuwait_rst;
     uint32_t initsvtor0_rst;
     uint32_t initsvtor1_rst;
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index fa155b72022..f509f59d4a8 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -19,6 +19,7 @@
 #include "migration/vmstate.h"
 #include "hw/registerfields.h"
 #include "hw/arm/armsse.h"
+#include "hw/arm/armsse-version.h"
 #include "hw/arm/boot.h"
 #include "hw/irq.h"
 #include "hw/qdev-clock.h"
@@ -31,6 +32,7 @@ typedef enum SysConfigFormat {
 
 struct ARMSSEInfo {
     const char *name;
+    uint32_t sse_version;
     int sram_banks;
     int num_cpus;
     uint32_t sys_version;
@@ -71,6 +73,7 @@ static Property armsse_properties[] = {
 static const ARMSSEInfo armsse_variants[] = {
     {
         .name = TYPE_IOTKIT,
+        .sse_version = ARMSSE_IOTKIT,
         .sram_banks = 1,
         .num_cpus = 1,
         .sys_version = 0x41743,
@@ -85,6 +88,7 @@ static const ARMSSEInfo armsse_variants[] = {
     },
     {
         .name = TYPE_SSE200,
+        .sse_version = ARMSSE_SSE200,
         .sram_banks = 4,
         .num_cpus = 2,
         .sys_version = 0x22041743,
@@ -951,8 +955,8 @@ static void armsse_realize(DeviceState *dev, Error **errp)
     /* System information registers */
     sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysinfo), 0, 0x40020000);
     /* System control registers */
-    object_property_set_int(OBJECT(&s->sysctl), "SYS_VERSION",
-                            info->sys_version, &error_abort);
+    object_property_set_int(OBJECT(&s->sysctl), "sse-version",
+                            info->sse_version, &error_abort);
     object_property_set_int(OBJECT(&s->sysctl), "CPUWAIT_RST",
                             info->cpuwait_rst, &error_abort);
     object_property_set_int(OBJECT(&s->sysctl), "INITSVTOR0_RST",
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
index 222511c4b04..34b37fe8824 100644
--- a/hw/misc/iotkit-sysctl.c
+++ b/hw/misc/iotkit-sysctl.c
@@ -28,6 +28,7 @@
 #include "hw/registerfields.h"
 #include "hw/misc/iotkit-sysctl.h"
 #include "hw/qdev-properties.h"
+#include "hw/arm/armsse-version.h"
 #include "target/arm/arm-powerctl.h"
 #include "target/arm/cpu.h"
 
@@ -438,10 +439,12 @@ static void iotkit_sysctl_realize(DeviceState *dev, Error **errp)
 {
     IoTKitSysCtl *s = IOTKIT_SYSCTL(dev);
 
-    /* The top 4 bits of the SYS_VERSION register tell us if we're an SSE-200 */
-    if (extract32(s->sys_version, 28, 4) == 2) {
-        s->is_sse200 = true;
+    if (!armsse_version_valid(s->sse_version)) {
+        error_setg(errp, "invalid sse-version value %d", s->sse_version);
+        return;
     }
+
+    s->is_sse200 = s->sse_version == ARMSSE_SSE200;
 }
 
 static bool sse200_needed(void *opaque)
@@ -493,7 +496,7 @@ static const VMStateDescription iotkit_sysctl_vmstate = {
 };
 
 static Property iotkit_sysctl_props[] = {
-    DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysCtl, sys_version, 0),
+    DEFINE_PROP_UINT32("sse-version", IoTKitSysCtl, sse_version, 0),
     DEFINE_PROP_UINT32("CPUWAIT_RST", IoTKitSysCtl, cpuwait_rst, 0),
     DEFINE_PROP_UINT32("INITSVTOR0_RST", IoTKitSysCtl, initsvtor0_rst,
                        0x10000000),
-- 
2.20.1



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

* [PATCH 06/44] hw/misc/iotkit-sysctl: Remove is_sse200 flag
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (4 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 05/44] hw/arm/armsse: Introduce SSE subsystem version property Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-03-04 17:13   ` Richard Henderson
  2021-02-19 14:45 ` [PATCH 07/44] hw/misc/iotkit-secctl.c: Implement SSE-300 PID register values Peter Maydell
                   ` (39 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Remove the is_sse200 flag in favour of just directly testing the new
sse_version field.

Since some of these registers exist in the SSE-300 but some do not or
have different behaviour, we expand out the if() statements in the
read and write functions into switch()es, so we have an easy place to
put SSE-300 specific behaviour.

(Until we do add the SSE-300 behaviour, the thing preventing us
reaching the "unreachable" default cases is that armsse.c doesn't
yet pass us an ARMSSE_SSE300 version.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/misc/iotkit-sysctl.h |   2 -
 hw/misc/iotkit-sysctl.c         | 256 +++++++++++++++++++++++---------
 2 files changed, 187 insertions(+), 71 deletions(-)

diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
index 7cdafea3e25..980c2ddfd3c 100644
--- a/include/hw/misc/iotkit-sysctl.h
+++ b/include/hw/misc/iotkit-sysctl.h
@@ -64,8 +64,6 @@ struct IoTKitSysCtl {
     uint32_t cpuwait_rst;
     uint32_t initsvtor0_rst;
     uint32_t initsvtor1_rst;
-
-    bool is_sse200;
 };
 
 #endif
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
index 34b37fe8824..c67f5b320ab 100644
--- a/hw/misc/iotkit-sysctl.c
+++ b/hw/misc/iotkit-sysctl.c
@@ -101,28 +101,48 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
         r = s->secure_debug;
         break;
     case A_SCSECCTRL:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            r = s->scsecctrl;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->scsecctrl;
         break;
     case A_FCLK_DIV:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            r = s->fclk_div;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->fclk_div;
         break;
     case A_SYSCLK_DIV:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            r = s->sysclk_div;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->sysclk_div;
         break;
     case A_CLOCK_FORCE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            r = s->clock_force;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->clock_force;
         break;
     case A_RESET_SYNDROME:
         r = s->reset_syndrome;
@@ -137,60 +157,100 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
         r = s->initsvtor0;
         break;
     case A_INITSVTOR1:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            r = s->initsvtor1;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->initsvtor1;
         break;
     case A_CPUWAIT:
         r = s->cpuwait;
         break;
     case A_NMI_ENABLE:
-        /* In IoTKit this is named BUSWAIT but is marked reserved, R/O, zero */
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
+            /* In IoTKit this is named BUSWAIT but marked reserved, R/O, zero */
             r = 0;
             break;
+        case ARMSSE_SSE200:
+            r = s->nmi_enable;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->nmi_enable;
         break;
     case A_WICCTRL:
         r = s->wicctrl;
         break;
     case A_EWCTRL:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            r = s->ewctrl;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->ewctrl;
         break;
     case A_PDCM_PD_SYS_SENSE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            r = s->pdcm_pd_sys_sense;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->pdcm_pd_sys_sense;
         break;
     case A_PDCM_PD_SRAM0_SENSE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            r = s->pdcm_pd_sram0_sense;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->pdcm_pd_sram0_sense;
         break;
     case A_PDCM_PD_SRAM1_SENSE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            r = s->pdcm_pd_sram1_sense;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->pdcm_pd_sram1_sense;
         break;
     case A_PDCM_PD_SRAM2_SENSE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            r = s->pdcm_pd_sram2_sense;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->pdcm_pd_sram2_sense;
         break;
     case A_PDCM_PD_SRAM3_SENSE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            r = s->pdcm_pd_sram3_sense;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->pdcm_pd_sram3_sense;
         break;
     case A_PID4 ... A_CID3:
         r = sysctl_id[(offset - A_PID4) / 4];
@@ -284,94 +344,154 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
         }
         break;
     case A_SCSECCTRL:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SCSECCTRL unimplemented\n");
+            s->scsecctrl = value;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SCSECCTRL unimplemented\n");
-        s->scsecctrl = value;
         break;
     case A_FCLK_DIV:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl FCLK_DIV unimplemented\n");
+            s->fclk_div = value;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl FCLK_DIV unimplemented\n");
-        s->fclk_div = value;
         break;
     case A_SYSCLK_DIV:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SYSCLK_DIV unimplemented\n");
+            s->sysclk_div = value;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SYSCLK_DIV unimplemented\n");
-        s->sysclk_div = value;
         break;
     case A_CLOCK_FORCE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CLOCK_FORCE unimplemented\n");
+            s->clock_force = value;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CLOCK_FORCE unimplemented\n");
-        s->clock_force = value;
         break;
     case A_INITSVTOR1:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            s->initsvtor1 = value;
+            set_init_vtor(1, s->initsvtor1);
+            break;
+        default:
+            g_assert_not_reached();
         }
-        s->initsvtor1 = value;
-        set_init_vtor(1, s->initsvtor1);
         break;
     case A_EWCTRL:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl EWCTRL unimplemented\n");
+            s->ewctrl = value;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl EWCTRL unimplemented\n");
-        s->ewctrl = value;
         break;
     case A_PDCM_PD_SYS_SENSE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            qemu_log_mask(LOG_UNIMP,
+                          "IoTKit SysCtl PDCM_PD_SYS_SENSE unimplemented\n");
+            s->pdcm_pd_sys_sense = value;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        qemu_log_mask(LOG_UNIMP,
-                      "IoTKit SysCtl PDCM_PD_SYS_SENSE unimplemented\n");
-        s->pdcm_pd_sys_sense = value;
         break;
     case A_PDCM_PD_SRAM0_SENSE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            qemu_log_mask(LOG_UNIMP,
+                          "IoTKit SysCtl PDCM_PD_SRAM0_SENSE unimplemented\n");
+            s->pdcm_pd_sram0_sense = value;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        qemu_log_mask(LOG_UNIMP,
-                      "IoTKit SysCtl PDCM_PD_SRAM0_SENSE unimplemented\n");
-        s->pdcm_pd_sram0_sense = value;
         break;
     case A_PDCM_PD_SRAM1_SENSE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            qemu_log_mask(LOG_UNIMP,
+                          "IoTKit SysCtl PDCM_PD_SRAM1_SENSE unimplemented\n");
+            s->pdcm_pd_sram1_sense = value;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        qemu_log_mask(LOG_UNIMP,
-                      "IoTKit SysCtl PDCM_PD_SRAM1_SENSE unimplemented\n");
-        s->pdcm_pd_sram1_sense = value;
         break;
     case A_PDCM_PD_SRAM2_SENSE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            qemu_log_mask(LOG_UNIMP,
+                          "IoTKit SysCtl PDCM_PD_SRAM2_SENSE unimplemented\n");
+            s->pdcm_pd_sram2_sense = value;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        qemu_log_mask(LOG_UNIMP,
-                      "IoTKit SysCtl PDCM_PD_SRAM2_SENSE unimplemented\n");
-        s->pdcm_pd_sram2_sense = value;
         break;
     case A_PDCM_PD_SRAM3_SENSE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            qemu_log_mask(LOG_UNIMP,
+                          "IoTKit SysCtl PDCM_PD_SRAM3_SENSE unimplemented\n");
+            s->pdcm_pd_sram3_sense = value;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        qemu_log_mask(LOG_UNIMP,
-                      "IoTKit SysCtl PDCM_PD_SRAM3_SENSE unimplemented\n");
-        s->pdcm_pd_sram3_sense = value;
         break;
     case A_NMI_ENABLE:
         /* In IoTKit this is BUSWAIT: reserved, R/O, zero */
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto ro_offset;
+        case ARMSSE_SSE200:
+            qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
+            s->nmi_enable = value;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
-        s->nmi_enable = value;
         break;
     case A_SECDBGSTAT:
     case A_PID4 ... A_CID3:
@@ -443,15 +563,13 @@ static void iotkit_sysctl_realize(DeviceState *dev, Error **errp)
         error_setg(errp, "invalid sse-version value %d", s->sse_version);
         return;
     }
-
-    s->is_sse200 = s->sse_version == ARMSSE_SSE200;
 }
 
 static bool sse200_needed(void *opaque)
 {
     IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
 
-    return s->is_sse200;
+    return s->sse_version == ARMSSE_SSE200;
 }
 
 static const VMStateDescription iotkit_sysctl_sse200_vmstate = {
-- 
2.20.1



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

* [PATCH 07/44] hw/misc/iotkit-secctl.c: Implement SSE-300 PID register values
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (5 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 06/44] hw/misc/iotkit-sysctl: Remove is_sse200 flag Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-03-04 17:29   ` Richard Henderson
  2021-02-19 14:45 ` [PATCH 08/44] hw/misc/iotkit-sysinfo.c: " Peter Maydell
                   ` (38 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The versions of the Secure Access Configuration Register Block
and Non-secure Access Configuration Register Block in the SSE-300
are the same as those in the SSE-200, but the CIDR/PIDR ID
register values are different.

Plumb through the sse-version property and use it to select
the correct ID register values.

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

diff --git a/include/hw/misc/iotkit-secctl.h b/include/hw/misc/iotkit-secctl.h
index 227d44abe49..79a36283201 100644
--- a/include/hw/misc/iotkit-secctl.h
+++ b/include/hw/misc/iotkit-secctl.h
@@ -120,6 +120,8 @@ struct IoTKitSecCtl {
     IoTKitSecCtlPPC apb[IOTS_NUM_APB_PPC];
     IoTKitSecCtlPPC apbexp[IOTS_NUM_APB_EXP_PPC];
     IoTKitSecCtlPPC ahbexp[IOTS_NUM_APB_EXP_PPC];
+
+    uint32_t sse_version;
 };
 
 #endif
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index f509f59d4a8..9632c287351 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -654,6 +654,8 @@ static void armsse_realize(DeviceState *dev, Error **errp)
     }
 
     /* Security controller */
+    object_property_set_int(OBJECT(&s->secctl), "sse-version",
+                            info->sse_version, &error_abort);
     if (!sysbus_realize(SYS_BUS_DEVICE(&s->secctl), errp)) {
         return;
     }
diff --git a/hw/misc/iotkit-secctl.c b/hw/misc/iotkit-secctl.c
index 9fdb82056a8..7b41cfa8fc5 100644
--- a/hw/misc/iotkit-secctl.c
+++ b/hw/misc/iotkit-secctl.c
@@ -19,6 +19,8 @@
 #include "hw/registerfields.h"
 #include "hw/irq.h"
 #include "hw/misc/iotkit-secctl.h"
+#include "hw/arm/armsse-version.h"
+#include "hw/qdev-properties.h"
 
 /* Registers in the secure privilege control block */
 REG32(SECRESPCFG, 0x10)
@@ -95,6 +97,19 @@ static const uint8_t iotkit_secctl_ns_idregs[] = {
     0x0d, 0xf0, 0x05, 0xb1,
 };
 
+static const uint8_t iotkit_secctl_s_sse300_idregs[] = {
+    0x04, 0x00, 0x00, 0x00,
+    0x52, 0xb8, 0x2b, 0x00,
+    0x0d, 0xf0, 0x05, 0xb1,
+};
+
+static const uint8_t iotkit_secctl_ns_sse300_idregs[] = {
+    0x04, 0x00, 0x00, 0x00,
+    0x53, 0xb8, 0x2b, 0x00,
+    0x0d, 0xf0, 0x05, 0xb1,
+};
+
+
 /* The register sets for the various PPCs (AHB internal, APB internal,
  * AHB expansion, APB expansion) are all set up so that they are
  * in 16-aligned blocks so offsets 0xN0, 0xN4, 0xN8, 0xNC are PPCs
@@ -213,7 +228,14 @@ static MemTxResult iotkit_secctl_s_read(void *opaque, hwaddr addr,
     case A_CID1:
     case A_CID2:
     case A_CID3:
-        r = iotkit_secctl_s_idregs[(offset - A_PID4) / 4];
+        switch (s->sse_version) {
+        case ARMSSE_SSE300:
+            r = iotkit_secctl_s_sse300_idregs[(offset - A_PID4) / 4];
+            break;
+        default:
+            r = iotkit_secctl_s_idregs[(offset - A_PID4) / 4];
+            break;
+        }
         break;
     case A_SECPPCINTCLR:
     case A_SECMSCINTCLR:
@@ -473,7 +495,14 @@ static MemTxResult iotkit_secctl_ns_read(void *opaque, hwaddr addr,
     case A_CID1:
     case A_CID2:
     case A_CID3:
-        r = iotkit_secctl_ns_idregs[(offset - A_PID4) / 4];
+        switch (s->sse_version) {
+        case ARMSSE_SSE300:
+            r = iotkit_secctl_ns_sse300_idregs[(offset - A_PID4) / 4];
+            break;
+        default:
+            r = iotkit_secctl_ns_idregs[(offset - A_PID4) / 4];
+            break;
+        }
         break;
     default:
         qemu_log_mask(LOG_GUEST_ERROR,
@@ -710,6 +739,16 @@ static void iotkit_secctl_init(Object *obj)
     sysbus_init_mmio(sbd, &s->ns_regs);
 }
 
+static void iotkit_secctl_realize(DeviceState *dev, Error **errp)
+{
+    IoTKitSecCtl *s = IOTKIT_SECCTL(dev);
+
+    if (!armsse_version_valid(s->sse_version)) {
+        error_setg(errp, "invalid sse-version value %d", s->sse_version);
+        return;
+    }
+}
+
 static const VMStateDescription iotkit_secctl_ppc_vmstate = {
     .name = "iotkit-secctl-ppc",
     .version_id = 1,
@@ -775,12 +814,19 @@ static const VMStateDescription iotkit_secctl_vmstate = {
     },
 };
 
+static Property iotkit_secctl_props[] = {
+    DEFINE_PROP_UINT32("sse-version", IoTKitSecCtl, sse_version, 0),
+    DEFINE_PROP_END_OF_LIST()
+};
+
 static void iotkit_secctl_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->vmsd = &iotkit_secctl_vmstate;
     dc->reset = iotkit_secctl_reset;
+    dc->realize = iotkit_secctl_realize;
+    device_class_set_props(dc, iotkit_secctl_props);
 }
 
 static const TypeInfo iotkit_secctl_info = {
-- 
2.20.1



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

* [PATCH 08/44] hw/misc/iotkit-sysinfo.c: Implement SSE-300 PID register values
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (6 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 07/44] hw/misc/iotkit-secctl.c: Implement SSE-300 PID register values Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-03-04 17:35   ` Richard Henderson
  2021-02-19 14:45 ` [PATCH 09/44] hw/arm/armsse.c: Use correct SYS_CONFIG0 register value for SSE-300 Peter Maydell
                   ` (37 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The version of the SYSINFO Register Block in the SSE-300 has
different CIDR/PIDR register values to the SSE-200; pass in
the sse-version property and use it to select the correct
ID register values.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/misc/iotkit-sysinfo.h |  1 +
 hw/arm/armsse.c                  |  2 ++
 hw/misc/iotkit-sysinfo.c         | 29 +++++++++++++++++++++++++++--
 3 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h
index 055771d2098..91bd14bdbff 100644
--- a/include/hw/misc/iotkit-sysinfo.h
+++ b/include/hw/misc/iotkit-sysinfo.h
@@ -38,6 +38,7 @@ struct IoTKitSysInfo {
     /* Properties */
     uint32_t sys_version;
     uint32_t sys_config;
+    uint32_t sse_version;
 };
 
 #endif
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index 9632c287351..67fa4ffe34a 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -951,6 +951,8 @@ static void armsse_realize(DeviceState *dev, Error **errp)
                                  armsse_sys_config_value(s, info), errp)) {
         return;
     }
+    object_property_set_int(OBJECT(&s->sysinfo), "sse-version",
+                            info->sse_version, &error_abort);
     if (!sysbus_realize(SYS_BUS_DEVICE(&s->sysinfo), errp)) {
         return;
     }
diff --git a/hw/misc/iotkit-sysinfo.c b/hw/misc/iotkit-sysinfo.c
index 52e70053df7..4bd3fd4c8f3 100644
--- a/hw/misc/iotkit-sysinfo.c
+++ b/hw/misc/iotkit-sysinfo.c
@@ -26,6 +26,7 @@
 #include "hw/registerfields.h"
 #include "hw/misc/iotkit-sysinfo.h"
 #include "hw/qdev-properties.h"
+#include "hw/arm/armsse-version.h"
 
 REG32(SYS_VERSION, 0x0)
 REG32(SYS_CONFIG, 0x4)
@@ -49,6 +50,12 @@ static const int sysinfo_id[] = {
     0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
 };
 
+static const int sysinfo_sse300_id[] = {
+    0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
+    0x58, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
+    0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
+};
+
 static uint64_t iotkit_sysinfo_read(void *opaque, hwaddr offset,
                                     unsigned size)
 {
@@ -64,7 +71,14 @@ static uint64_t iotkit_sysinfo_read(void *opaque, hwaddr offset,
         r = s->sys_config;
         break;
     case A_PID4 ... A_CID3:
-        r = sysinfo_id[(offset - A_PID4) / 4];
+        switch (s->sse_version) {
+        case ARMSSE_SSE300:
+            r = sysinfo_sse300_id[(offset - A_PID4) / 4];
+            break;
+        default:
+            r = sysinfo_id[(offset - A_PID4) / 4];
+            break;
+        }
         break;
     default:
         qemu_log_mask(LOG_GUEST_ERROR,
@@ -99,6 +113,7 @@ static const MemoryRegionOps iotkit_sysinfo_ops = {
 static Property iotkit_sysinfo_props[] = {
     DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysInfo, sys_version, 0),
     DEFINE_PROP_UINT32("SYS_CONFIG", IoTKitSysInfo, sys_config, 0),
+    DEFINE_PROP_UINT32("sse-version", IoTKitSysInfo, sse_version, 0),
     DEFINE_PROP_END_OF_LIST()
 };
 
@@ -112,6 +127,16 @@ static void iotkit_sysinfo_init(Object *obj)
     sysbus_init_mmio(sbd, &s->iomem);
 }
 
+static void iotkit_sysinfo_realize(DeviceState *dev, Error **errp)
+{
+    IoTKitSysInfo *s = IOTKIT_SYSINFO(dev);
+
+    if (!armsse_version_valid(s->sse_version)) {
+        error_setg(errp, "invalid sse-version value %d", s->sse_version);
+        return;
+    }
+}
+
 static void iotkit_sysinfo_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -120,7 +145,7 @@ 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.
      */
-
+    dc->realize = iotkit_sysinfo_realize;
     device_class_set_props(dc, iotkit_sysinfo_props);
 }
 
-- 
2.20.1



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

* [PATCH 09/44] hw/arm/armsse.c: Use correct SYS_CONFIG0 register value for SSE-300
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (7 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 08/44] hw/misc/iotkit-sysinfo.c: " Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-03-04 17:39   ` Richard Henderson
  2021-02-19 14:45 ` [PATCH 10/44] hw/misc/iotkit-sysinfo.c: Implement SYS_CONFIG1 and IIDR Peter Maydell
                   ` (36 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

In the SSE-300, the format of the SYS_CONFIG0 register has changed again;
pass through the correct value to the SYSINFO register block device.

We drop the old SysConfigFormat enum, which was implemented in the
hope that different flavours of SSE would share the same format;
since they all seem to be different and we now have an sse_version
enum to key off, just use that.

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

diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index 67fa4ffe34a..113a783a46a 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -24,12 +24,6 @@
 #include "hw/irq.h"
 #include "hw/qdev-clock.h"
 
-/* Format of the System Information block SYS_CONFIG register */
-typedef enum SysConfigFormat {
-    IoTKitFormat,
-    SSE200Format,
-} SysConfigFormat;
-
 struct ARMSSEInfo {
     const char *name;
     uint32_t sse_version;
@@ -37,7 +31,6 @@ struct ARMSSEInfo {
     int num_cpus;
     uint32_t sys_version;
     uint32_t cpuwait_rst;
-    SysConfigFormat sys_config_format;
     bool has_mhus;
     bool has_ppus;
     bool has_cachectrl;
@@ -78,7 +71,6 @@ static const ARMSSEInfo armsse_variants[] = {
         .num_cpus = 1,
         .sys_version = 0x41743,
         .cpuwait_rst = 0,
-        .sys_config_format = IoTKitFormat,
         .has_mhus = false,
         .has_ppus = false,
         .has_cachectrl = false,
@@ -93,7 +85,6 @@ static const ARMSSEInfo armsse_variants[] = {
         .num_cpus = 2,
         .sys_version = 0x22041743,
         .cpuwait_rst = 2,
-        .sys_config_format = SSE200Format,
         .has_mhus = true,
         .has_ppus = true,
         .has_cachectrl = true,
@@ -108,13 +99,13 @@ static uint32_t armsse_sys_config_value(ARMSSE *s, const ARMSSEInfo *info)
     /* Return the SYS_CONFIG value for this SSE */
     uint32_t sys_config;
 
-    switch (info->sys_config_format) {
-    case IoTKitFormat:
+    switch (info->sse_version) {
+    case ARMSSE_IOTKIT:
         sys_config = 0;
         sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
         sys_config = deposit32(sys_config, 4, 4, s->sram_addr_width - 12);
         break;
-    case SSE200Format:
+    case ARMSSE_SSE200:
         sys_config = 0;
         sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
         sys_config = deposit32(sys_config, 4, 5, s->sram_addr_width);
@@ -125,6 +116,12 @@ static uint32_t armsse_sys_config_value(ARMSSE *s, const ARMSSEInfo *info)
             sys_config = deposit32(sys_config, 28, 4, 2);
         }
         break;
+    case ARMSSE_SSE300:
+        sys_config = 0;
+        sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
+        sys_config = deposit32(sys_config, 4, 5, s->sram_addr_width);
+        sys_config = deposit32(sys_config, 16, 3, 3); /* CPU0 = Cortex-M55 */
+        break;
     default:
         g_assert_not_reached();
     }
-- 
2.20.1



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

* [PATCH 10/44] hw/misc/iotkit-sysinfo.c: Implement SYS_CONFIG1 and IIDR
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (8 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 09/44] hw/arm/armsse.c: Use correct SYS_CONFIG0 register value for SSE-300 Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-03-04 17:54   ` Richard Henderson
  2021-02-19 14:45 ` [PATCH 11/44] hw/timer/sse-counter: Model the SSE Subsystem System Counter Peter Maydell
                   ` (35 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

For SSE-300, the SYSINFO register block has two new registers:

 * SYS_CONFIG1 indicates the config for a potential CPU2 and CPU3;
   since the SSE-300 can only be configured with a single CPU it
   is always zero

 * IIDR is the subsystem implementation identity register;
   its value is set by the SoC integrator, so we plumb this in from
   the armsse.c code as we do with SYS_VERSION and SYS_CONFIG

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/misc/iotkit-sysinfo.h |  1 +
 hw/arm/armsse.c                  |  5 +++++
 hw/misc/iotkit-sysinfo.c         | 22 ++++++++++++++++++++++
 3 files changed, 28 insertions(+)

diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h
index 91bd14bdbff..91c23f90d23 100644
--- a/include/hw/misc/iotkit-sysinfo.h
+++ b/include/hw/misc/iotkit-sysinfo.h
@@ -39,6 +39,7 @@ struct IoTKitSysInfo {
     uint32_t sys_version;
     uint32_t sys_config;
     uint32_t sse_version;
+    uint32_t iidr;
 };
 
 #endif
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index 113a783a46a..326e161c8d4 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -30,6 +30,7 @@ struct ARMSSEInfo {
     int sram_banks;
     int num_cpus;
     uint32_t sys_version;
+    uint32_t iidr;
     uint32_t cpuwait_rst;
     bool has_mhus;
     bool has_ppus;
@@ -70,6 +71,7 @@ static const ARMSSEInfo armsse_variants[] = {
         .sram_banks = 1,
         .num_cpus = 1,
         .sys_version = 0x41743,
+        .iidr = 0,
         .cpuwait_rst = 0,
         .has_mhus = false,
         .has_ppus = false,
@@ -84,6 +86,7 @@ static const ARMSSEInfo armsse_variants[] = {
         .sram_banks = 4,
         .num_cpus = 2,
         .sys_version = 0x22041743,
+        .iidr = 0,
         .cpuwait_rst = 2,
         .has_mhus = true,
         .has_ppus = true,
@@ -950,6 +953,8 @@ static void armsse_realize(DeviceState *dev, Error **errp)
     }
     object_property_set_int(OBJECT(&s->sysinfo), "sse-version",
                             info->sse_version, &error_abort);
+    object_property_set_int(OBJECT(&s->sysinfo), "IIDR",
+                            info->iidr, &error_abort);
     if (!sysbus_realize(SYS_BUS_DEVICE(&s->sysinfo), errp)) {
         return;
     }
diff --git a/hw/misc/iotkit-sysinfo.c b/hw/misc/iotkit-sysinfo.c
index 4bd3fd4c8f3..aaa9305b2ea 100644
--- a/hw/misc/iotkit-sysinfo.c
+++ b/hw/misc/iotkit-sysinfo.c
@@ -30,6 +30,8 @@
 
 REG32(SYS_VERSION, 0x0)
 REG32(SYS_CONFIG, 0x4)
+REG32(SYS_CONFIG1, 0x8)
+REG32(IIDR, 0xfc8)
 REG32(PID4, 0xfd0)
 REG32(PID5, 0xfd4)
 REG32(PID6, 0xfd8)
@@ -70,6 +72,24 @@ static uint64_t iotkit_sysinfo_read(void *opaque, hwaddr offset,
     case A_SYS_CONFIG:
         r = s->sys_config;
         break;
+    case A_SYS_CONFIG1:
+        switch (s->sse_version) {
+        case ARMSSE_SSE300:
+            return 0;
+            break;
+        default:
+            goto bad_read;
+        }
+        break;
+    case A_IIDR:
+        switch (s->sse_version) {
+        case ARMSSE_SSE300:
+            return s->iidr;
+            break;
+        default:
+            goto bad_read;
+        }
+        break;
     case A_PID4 ... A_CID3:
         switch (s->sse_version) {
         case ARMSSE_SSE300:
@@ -81,6 +101,7 @@ static uint64_t iotkit_sysinfo_read(void *opaque, hwaddr offset,
         }
         break;
     default:
+    bad_read:
         qemu_log_mask(LOG_GUEST_ERROR,
                       "IoTKit SysInfo read: bad offset %x\n", (int)offset);
         r = 0;
@@ -114,6 +135,7 @@ static Property iotkit_sysinfo_props[] = {
     DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysInfo, sys_version, 0),
     DEFINE_PROP_UINT32("SYS_CONFIG", IoTKitSysInfo, sys_config, 0),
     DEFINE_PROP_UINT32("sse-version", IoTKitSysInfo, sse_version, 0),
+    DEFINE_PROP_UINT32("IIDR", IoTKitSysInfo, iidr, 0),
     DEFINE_PROP_END_OF_LIST()
 };
 
-- 
2.20.1



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

* [PATCH 11/44] hw/timer/sse-counter: Model the SSE Subsystem System Counter
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (9 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 10/44] hw/misc/iotkit-sysinfo.c: Implement SYS_CONFIG1 and IIDR Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-03-04 18:38   ` Richard Henderson
  2021-02-19 14:45 ` [PATCH 12/44] hw/timer/sse-timer: Model the SSE Subsystem System Timer Peter Maydell
                   ` (34 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The SSE-300 includes a counter module; implement a model of it.

This counter is documented in the SSE-123 Example Subsystem
Technical Reference Manual:
 https://developer.arm.com/documentation/101370/latest/

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/timer/sse-counter.h | 105 ++++++++
 hw/timer/sse-counter.c         | 474 +++++++++++++++++++++++++++++++++
 MAINTAINERS                    |   2 +
 hw/arm/Kconfig                 |   1 +
 hw/timer/Kconfig               |   3 +
 hw/timer/meson.build           |   1 +
 hw/timer/trace-events          |   7 +
 7 files changed, 593 insertions(+)
 create mode 100644 include/hw/timer/sse-counter.h
 create mode 100644 hw/timer/sse-counter.c

diff --git a/include/hw/timer/sse-counter.h b/include/hw/timer/sse-counter.h
new file mode 100644
index 00000000000..b433e58d370
--- /dev/null
+++ b/include/hw/timer/sse-counter.h
@@ -0,0 +1,105 @@
+/*
+ * Arm SSE Subsystem System Counter
+ *
+ * Copyright (c) 2020 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 counter" which is documented in
+ * the Arm SSE-123 Example Subsystem Technical Reference Manual:
+ * https://developer.arm.com/documentation/101370/latest/
+ *
+ * QEMU interface:
+ *  + Clock input "CLK": clock
+ *  + sysbus MMIO region 0: the control register frame
+ *  + sysbus MMIO region 1: the status register frame
+ *
+ * Consumers of the system counter's timestamp, such as the SSE
+ * System Timer device, can also use the APIs sse_counter_for_timestamp(),
+ * sse_counter_tick_to_time() and sse_counter_register_consumer() to
+ * interact with an instance of the System Counter. Generally the
+ * consumer device should have a QOM link property which the board
+ * code can set to the appropriate instance of the system counter.
+ */
+
+#ifndef SSE_COUNTER_H
+#define SSE_COUNTER_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+#include "qemu/notify.h"
+
+#define TYPE_SSE_COUNTER "sse-counter"
+OBJECT_DECLARE_SIMPLE_TYPE(SSECounter, SSE_COUNTER)
+
+struct SSECounter {
+    /*< private >*/
+    SysBusDevice parent_obj;
+
+    /*< public >*/
+    MemoryRegion control_mr;
+    MemoryRegion status_mr;
+    Clock *clk;
+    NotifierList notifier_list;
+
+    uint32_t cntcr;
+    uint32_t cntscr0;
+
+    /*
+     * These are used for handling clock frequency changes: they are a
+     * tuple of (QEMU_CLOCK_VIRTUAL timestamp, CNTCV at that time),
+     * taken when the clock frequency changes. sse_cntcv() needs them
+     * to calculate the current CNTCV.
+     */
+    uint64_t ns_then;
+    uint64_t ticks_then;
+};
+
+/*
+ * These functions are the interface by which a consumer of
+ * the system timestamp (such as the SSE system timer device)
+ * can communicate with the SSECounter.
+ */
+
+/**
+ * sse_counter_for_timestamp:
+ * @counter: SSECounter
+ * @ns: timestamp of QEMU_CLOCK_VIRTUAL in nanoseconds
+ *
+ * Returns the value of the timestamp counter at the specified
+ * point in time (assuming that no changes to scale factor, enable, etc
+ * happen in the meantime).
+ */
+uint64_t sse_counter_for_timestamp(SSECounter *counter, uint64_t ns);
+
+/**
+ * sse_counter_tick_to_time:
+ * @counter: SSECounter
+ * @tick: tick value
+ *
+ * Returns the time (a QEMU_CLOCK_VIRTUAL timestamp in nanoseconds)
+ * when the timestamp counter will reach the specified tick count.
+ * If the counter is not currently running, returns UINT64_MAX.
+ */
+uint64_t sse_counter_tick_to_time(SSECounter *counter, uint64_t tick);
+
+/**
+ * sse_counter_register_consumer:
+ * @counter: SSECounter
+ * @notifier: Notifier which is notified on counter changes
+ *
+ * Registers @notifier with the SSECounter. When the counter's
+ * configuration changes in a way that might invalidate information
+ * previously returned via sse_counter_for_timestamp() or
+ * sse_counter_tick_to_time(), the notifier will be called.
+ * Devices which consume the timestamp counter can use this as
+ * a cue to recalculate timer events.
+ */
+void sse_counter_register_consumer(SSECounter *counter, Notifier *notifier);
+
+#endif
diff --git a/hw/timer/sse-counter.c b/hw/timer/sse-counter.c
new file mode 100644
index 00000000000..0384051f151
--- /dev/null
+++ b/hw/timer/sse-counter.c
@@ -0,0 +1,474 @@
+/*
+ * Arm SSE Subsystem System Counter
+ *
+ * Copyright (c) 2020 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 counter" which is documented in
+ * the Arm SSE-123 Example Subsystem Technical Reference Manual:
+ * https://developer.arm.com/documentation/101370/latest/
+ *
+ * The system counter is a non-stop 64-bit up-counter. It provides
+ * this count value to other devices like the SSE system timer,
+ * which are driven by this system timestamp rather than directly
+ * from a clock. Internally to the counter the count is actually
+ * 88-bit precision (64.24 fixed point), with a programmable scale factor.
+ *
+ * The hardware has the optional feature that it supports dynamic
+ * clock switching, where two clock inputs are connected, and which
+ * one is used is selected via a CLKSEL input signal. Since the
+ * users of this device in QEMU don't use this feature, we only model
+ * the HWCLKSW=0 configuration.
+ */
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/timer.h"
+#include "qapi/error.h"
+#include "trace.h"
+#include "hw/timer/sse-counter.h"
+#include "hw/sysbus.h"
+#include "hw/irq.h"
+#include "hw/registerfields.h"
+#include "hw/clock.h"
+#include "hw/qdev-clock.h"
+#include "migration/vmstate.h"
+
+/* Registers in the control frame */
+REG32(CNTCR, 0x0)
+    FIELD(CNTCR, EN, 0, 1)
+    FIELD(CNTCR, HDBG, 1, 1)
+    FIELD(CNTCR, SCEN, 2, 1)
+    FIELD(CNTCR, INTRMASK, 3, 1)
+    FIELD(CNTCR, PSLVERRDIS, 4, 1)
+    FIELD(CNTCR, INTRCLR, 5, 1)
+/*
+ * Although CNTCR defines interrupt-related bits, the counter doesn't
+ * appear to actually have an interrupt output. So INTRCLR is
+ * effectively a RAZ/WI bit, as are the reserved bits [31:6].
+ */
+#define CNTCR_VALID_MASK (R_CNTCR_EN_MASK | R_CNTCR_HDBG_MASK | \
+                          R_CNTCR_SCEN_MASK | R_CNTCR_INTRMASK_MASK | \
+                          R_CNTCR_PSLVERRDIS_MASK)
+REG32(CNTSR, 0x4)
+REG32(CNTCV_LO, 0x8)
+REG32(CNTCV_HI, 0xc)
+REG32(CNTSCR, 0x10) /* Aliased with CNTSCR0 */
+REG32(CNTID, 0x1c)
+    FIELD(CNTID, CNTSC, 0, 4)
+    FIELD(CNTID, CNTCS, 16, 1)
+    FIELD(CNTID, CNTSELCLK, 17, 2)
+    FIELD(CNTID, CNTSCR_OVR, 19, 1)
+REG32(CNTSCR0, 0xd0)
+REG32(CNTSCR1, 0xd4)
+
+/* Registers in the status frame */
+REG32(STATUS_CNTCV_LO, 0x0)
+REG32(STATUS_CNTCV_HI, 0x4)
+
+/* Standard ID registers, present in both frames */
+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 control_id[] = {
+    0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
+    0xba, 0xb0, 0x0b, 0x00, /* PID0..PID3 */
+    0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
+};
+
+static const int status_id[] = {
+    0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
+    0xbb, 0xb0, 0x0b, 0x00, /* PID0..PID3 */
+    0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
+};
+
+static void sse_counter_notify_users(SSECounter *s)
+{
+    /*
+     * Notify users of the count timestamp that they may
+     * need to recalculate.
+     */
+    notifier_list_notify(&s->notifier_list, NULL);
+}
+
+static bool sse_counter_enabled(SSECounter *s)
+{
+    return (s->cntcr & R_CNTCR_EN_MASK) != 0;
+}
+
+uint64_t sse_counter_tick_to_time(SSECounter *s, uint64_t tick)
+{
+    if (!sse_counter_enabled(s)) {
+        return UINT64_MAX;
+    }
+
+    tick -= s->ticks_then;
+
+    if (s->cntcr & R_CNTCR_SCEN_MASK) {
+        /* Adjust the tick count to account for the scale factor */
+        tick = muldiv64(tick, 0x01000000, s->cntscr0);
+    }
+
+    return s->ns_then + clock_ticks_to_ns(s->clk, tick);
+}
+
+void sse_counter_register_consumer(SSECounter *s, Notifier *notifier)
+{
+    /*
+     * For the moment we assume that both we and the devices
+     * which consume us last for the life of the simulation,
+     * and so there is no mechanism for removing a notifier.
+     */
+    notifier_list_add(&s->notifier_list, notifier);
+}
+
+uint64_t sse_counter_for_timestamp(SSECounter *s, uint64_t now)
+{
+    /* Return the CNTCV value for a particular timestamp (clock ns value). */
+    uint64_t ticks;
+
+    if (!sse_counter_enabled(s)) {
+        /* Counter is disabled and does not increment */
+        return s->ticks_then;
+    }
+
+    ticks = clock_ns_to_ticks(s->clk, now - s->ns_then);
+    if (s->cntcr & R_CNTCR_SCEN_MASK) {
+        /*
+         * Scaling is enabled. The CNTSCR value is the amount added to
+         * the underlying 88-bit counter for every tick of the
+         * underlying clock; CNTCV is the top 64 bits of that full
+         * 88-bit value. Multiplying the tick count by CNTSCR tells us
+         * how much the full 88-bit counter has moved on; we then
+         * divide that by 0x01000000 to find out how much the 64-bit
+         * visible portion has advanced. muldiv64() gives us the
+         * necessary at-least-88-bit precision for the intermediate
+         * result.
+         */
+        ticks = muldiv64(ticks, s->cntscr0, 0x01000000);
+    }
+    return s->ticks_then + ticks;
+}
+
+static uint64_t sse_cntcv(SSECounter *s)
+{
+    /* Return the CNTCV value for the current time */
+    return sse_counter_for_timestamp(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
+}
+
+static void sse_write_cntcv(SSECounter *s, uint32_t value, unsigned startbit)
+{
+    /*
+     * Write one 32-bit half of the counter value; startbit is the
+     * bit position of this half in the 64-bit word, either 0 or 32.
+     */
+    uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+    uint64_t cntcv = sse_counter_for_timestamp(s, now);
+
+    cntcv = deposit64(cntcv, startbit, 32, value);
+    s->ticks_then = cntcv;
+    s->ns_then = now;
+    sse_counter_notify_users(s);
+}
+
+static uint64_t sse_counter_control_read(void *opaque, hwaddr offset,
+                                         unsigned size)
+{
+    SSECounter *s = SSE_COUNTER(opaque);
+    uint64_t r;
+
+    switch (offset) {
+    case A_CNTCR:
+        r = s->cntcr;
+        break;
+    case A_CNTSR:
+        /*
+         * The only bit here is DBGH, indicating that the counter has been
+         * halted via the Halt-on-Debug signal. We don't implement halting
+         * debug, so the whole register always reads as zero.
+         */
+        r = 0;
+        break;
+    case A_CNTCV_LO:
+        r = extract64(sse_cntcv(s), 0, 32);
+        break;
+    case A_CNTCV_HI:
+        r = extract64(sse_cntcv(s), 32, 32);
+        break;
+    case A_CNTID:
+        /*
+         * For our implementation:
+         *  - CNTSCR can only be written when CNTCR.EN == 0
+         *  - HWCLKSW=0, so selected clock is always CLK0
+         *  - counter scaling is implemented
+         */
+        r = (1 << R_CNTID_CNTSELCLK_SHIFT) | (1 << R_CNTID_CNTSC_SHIFT);
+        break;
+    case A_CNTSCR:
+    case A_CNTSCR0:
+        r = s->cntscr0;
+        break;
+    case A_CNTSCR1:
+        /* If HWCLKSW == 0, CNTSCR1 is RAZ/WI */
+        r = 0;
+        break;
+    case A_PID4 ... A_CID3:
+        r = control_id[(offset - A_PID4) / 4];
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "SSE System Counter control frame read: bad offset 0x%x",
+                      (unsigned)offset);
+        r = 0;
+        break;
+    }
+
+    trace_sse_counter_control_read(offset, r, size);
+    return r;
+}
+
+static void sse_counter_control_write(void *opaque, hwaddr offset,
+                                      uint64_t value, unsigned size)
+{
+    SSECounter *s = SSE_COUNTER(opaque);
+
+    trace_sse_counter_control_write(offset, value, size);
+
+    switch (offset) {
+    case A_CNTCR:
+        /*
+         * Although CNTCR defines interrupt-related bits, the counter doesn't
+         * appear to actually have an interrupt output. So INTRCLR is
+         * effectively a RAZ/WI bit, as are the reserved bits [31:6].
+         * The documentation does not explicitly say so, but we assume
+         * that changing the scale factor while the counter is enabled
+         * by toggling CNTCR.SCEN has the same behaviour (making the counter
+         * value UNKNOWN) as changing it by writing to CNTSCR, and so we
+         * don't need to try to recalculate for that case.
+         */
+        value &= CNTCR_VALID_MASK;
+        if ((value ^ s->cntcr) & R_CNTCR_EN_MASK) {
+            /*
+             * Whether the counter is being enabled or disabled, the
+             * required action is the same: sync the (ns_then, ticks_then)
+             * tuple.
+             */
+            uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+            s->ticks_then = sse_counter_for_timestamp(s, now);
+            s->ns_then = now;
+            sse_counter_notify_users(s);
+        }
+        s->cntcr = value;
+        break;
+    case A_CNTCV_LO:
+        sse_write_cntcv(s, value, 0);
+        break;
+    case A_CNTCV_HI:
+        sse_write_cntcv(s, value, 32);
+        break;
+    case A_CNTSCR:
+    case A_CNTSCR0:
+        /*
+         * If the scale registers are changed when the counter is enabled,
+         * the count value becomes UNKNOWN. So we don't try to recalculate
+         * anything here but only do it on a write to CNTCR.EN.
+         */
+        s->cntscr0 = value;
+        break;
+    case A_CNTSCR1:
+        /* If HWCLKSW == 0, CNTSCR1 is RAZ/WI */
+        break;
+    case A_CNTSR:
+    case A_CNTID:
+    case A_PID4 ... A_CID3:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "SSE System Counter control frame: write to RO offset 0x%x\n",
+                      (unsigned)offset);
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "SSE System Counter control frame: write to bad offset 0x%x\n",
+                      (unsigned)offset);
+        break;
+    }
+}
+
+static uint64_t sse_counter_status_read(void *opaque, hwaddr offset,
+                                        unsigned size)
+{
+    SSECounter *s = SSE_COUNTER(opaque);
+    uint64_t r;
+
+    switch (offset) {
+    case A_STATUS_CNTCV_LO:
+        r = extract64(sse_cntcv(s), 0, 32);
+        break;
+    case A_STATUS_CNTCV_HI:
+        r = extract64(sse_cntcv(s), 32, 32);
+        break;
+    case A_PID4 ... A_CID3:
+        r = status_id[(offset - A_PID4) / 4];
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "SSE System Counter status frame read: bad offset 0x%x",
+                      (unsigned)offset);
+        r = 0;
+        break;
+    }
+
+    trace_sse_counter_status_read(offset, r, size);
+    return r;
+}
+
+static void sse_counter_status_write(void *opaque, hwaddr offset,
+                                     uint64_t value, unsigned size)
+{
+    trace_sse_counter_status_write(offset, value, size);
+
+    switch (offset) {
+    case A_STATUS_CNTCV_LO:
+    case A_STATUS_CNTCV_HI:
+    case A_PID4 ... A_CID3:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "SSE System Counter status frame: write to RO offset 0x%x\n",
+                      (unsigned)offset);
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "SSE System Counter status frame: write to bad offset 0x%x\n",
+                      (unsigned)offset);
+        break;
+    }
+}
+
+static const MemoryRegionOps sse_counter_control_ops = {
+    .read = sse_counter_control_read,
+    .write = sse_counter_control_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid.min_access_size = 4,
+    .valid.max_access_size = 4,
+};
+
+static const MemoryRegionOps sse_counter_status_ops = {
+    .read = sse_counter_status_read,
+    .write = sse_counter_status_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid.min_access_size = 4,
+    .valid.max_access_size = 4,
+};
+
+static void sse_counter_reset(DeviceState *dev)
+{
+    SSECounter *s = SSE_COUNTER(dev);
+
+    trace_sse_counter_reset();
+
+    s->cntcr = 0;
+    s->cntscr0 = 0x01000000;
+    s->ns_then = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+    s->ticks_then = 0;
+}
+
+static void sse_clk_callback(void *opaque, ClockEvent event)
+{
+    SSECounter *s = SSE_COUNTER(opaque);
+    uint64_t now;
+
+    switch (event) {
+    case ClockPreUpdate:
+        /*
+         * Before the clock period updates, set (ticks_then, ns_then)
+         * to the current time and tick count (as calculated with
+         * the old clock period).
+         */
+        if (sse_counter_enabled(s)) {
+            now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+            s->ticks_then = sse_counter_for_timestamp(s, now);
+            s->ns_then = now;
+        }
+        break;
+    case ClockUpdate:
+        sse_counter_notify_users(s);
+        break;
+    default:
+        break;
+    }
+}
+
+static void sse_counter_init(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    SSECounter *s = SSE_COUNTER(obj);
+
+    notifier_list_init(&s->notifier_list);
+
+    s->clk = qdev_init_clock_in(DEVICE(obj), "CLK", sse_clk_callback, s,
+                                ClockPreUpdate | ClockUpdate);
+    memory_region_init_io(&s->control_mr, obj, &sse_counter_control_ops,
+                          s, "sse-counter-control", 0x1000);
+    memory_region_init_io(&s->status_mr, obj, &sse_counter_status_ops,
+                          s, "sse-counter-status", 0x1000);
+    sysbus_init_mmio(sbd, &s->control_mr);
+    sysbus_init_mmio(sbd, &s->status_mr);
+}
+
+static void sse_counter_realize(DeviceState *dev, Error **errp)
+{
+    SSECounter *s = SSE_COUNTER(dev);
+
+    if (!clock_has_source(s->clk)) {
+        error_setg(errp, "SSE system counter: CLK must be connected");
+        return;
+    }
+}
+
+static const VMStateDescription sse_counter_vmstate = {
+    .name = "sse-counter",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_CLOCK(clk, SSECounter),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void sse_counter_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = sse_counter_realize;
+    dc->vmsd = &sse_counter_vmstate;
+    dc->reset = sse_counter_reset;
+}
+
+static const TypeInfo sse_counter_info = {
+    .name = TYPE_SSE_COUNTER,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(SSECounter),
+    .instance_init = sse_counter_init,
+    .class_init = sse_counter_class_init,
+};
+
+static void sse_counter_register_types(void)
+{
+    type_register_static(&sse_counter_info);
+}
+
+type_init(sse_counter_register_types);
diff --git a/MAINTAINERS b/MAINTAINERS
index de5fe1c65f5..1c9b2f446ef 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -742,6 +742,8 @@ F: hw/misc/armsse-cpuid.c
 F: include/hw/misc/armsse-cpuid.h
 F: hw/misc/armsse-mhu.c
 F: include/hw/misc/armsse-mhu.h
+F: hw/timer/sse-counter.c
+F: include/hw/timer/sse-counter.h
 F: docs/system/arm/mps2.rst
 
 Musca
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index be017b997ab..3081efce20b 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -519,6 +519,7 @@ config ARMSSE
     select TZ_MSC
     select TZ_PPC
     select UNIMP
+    select SSE_COUNTER
 
 config ARMSSE_CPUID
     bool
diff --git a/hw/timer/Kconfig b/hw/timer/Kconfig
index 8749edfb6a5..e103c8872ab 100644
--- a/hw/timer/Kconfig
+++ b/hw/timer/Kconfig
@@ -42,5 +42,8 @@ config RENESAS_TMR
 config RENESAS_CMT
     bool
 
+config SSE_COUNTER
+    bool
+
 config AVR_TIMER16
     bool
diff --git a/hw/timer/meson.build b/hw/timer/meson.build
index be343f68fed..79a3012349d 100644
--- a/hw/timer/meson.build
+++ b/hw/timer/meson.build
@@ -32,6 +32,7 @@ softmmu_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_timer.c'))
 softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_systmr.c'))
 softmmu_ss.add(when: 'CONFIG_SH4', if_true: files('sh_timer.c'))
 softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_timer.c'))
+softmmu_ss.add(when: 'CONFIG_SSE_COUNTER', if_true: files('sse-counter.c'))
 softmmu_ss.add(when: 'CONFIG_STM32F2XX_TIMER', if_true: files('stm32f2xx_timer.c'))
 softmmu_ss.add(when: 'CONFIG_XILINX', if_true: files('xilinx_timer.c'))
 
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
index 7a4326d9566..bb9c1000878 100644
--- a/hw/timer/trace-events
+++ b/hw/timer/trace-events
@@ -93,3 +93,10 @@ avr_timer16_interrupt_count(uint8_t cnt) "count: %u"
 avr_timer16_interrupt_overflow(const char *reason) "overflow: %s"
 avr_timer16_next_alarm(uint64_t delay_ns) "next alarm: %" PRIu64 " ns from now"
 avr_timer16_clksrc_update(uint64_t freq_hz, uint64_t period_ns, uint64_t delay_s) "timer frequency: %" PRIu64 " Hz, period: %" PRIu64 " ns (%" PRId64 " us)"
+
+# sse_counter.c
+sse_counter_control_read(uint64_t offset, uint64_t data, unsigned size) "SSE system counter control frame read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+sse_counter_control_write(uint64_t offset, uint64_t data, unsigned size) "SSE system counter control framen write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+sse_counter_status_read(uint64_t offset, uint64_t data, unsigned size) "SSE system counter status frame read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+sse_counter_status_write(uint64_t offset, uint64_t data, unsigned size) "SSE system counter status frame write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+sse_counter_reset(void) "SSE system counter: reset"
-- 
2.20.1



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

* [PATCH 12/44] hw/timer/sse-timer: Model the SSE Subsystem System Timer
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (10 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 11/44] hw/timer/sse-counter: Model the SSE Subsystem System Counter Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-03-04 19:11   ` Richard Henderson
  2021-02-19 14:45 ` [PATCH 13/44] hw/misc/iotkit-sysctl: Add SSE-300 cases which match SSE-200 behaviour Peter Maydell
                   ` (33 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The SSE-300 includes some timers which are a different kind to
those in the SSE-200. Model them.

These timers are documented in the SSE-123 Example Subsystem
Technical Reference Manual:
 https://developer.arm.com/documentation/101370/latest/

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/timer/sse-timer.h |  53 ++++
 hw/timer/sse-timer.c         | 470 +++++++++++++++++++++++++++++++++++
 MAINTAINERS                  |   2 +
 hw/arm/Kconfig               |   1 +
 hw/timer/Kconfig             |   3 +
 hw/timer/meson.build         |   1 +
 hw/timer/trace-events        |   5 +
 7 files changed, 535 insertions(+)
 create mode 100644 include/hw/timer/sse-timer.h
 create mode 100644 hw/timer/sse-timer.c

diff --git a/include/hw/timer/sse-timer.h b/include/hw/timer/sse-timer.h
new file mode 100644
index 00000000000..b4ee8e7f6c4
--- /dev/null
+++ b/include/hw/timer/sse-timer.h
@@ -0,0 +1,53 @@
+/*
+ * Arm SSE Subsystem System Timer
+ *
+ * Copyright (c) 2020 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 timer" which is documented in
+ * the Arm SSE-123 Example Subsystem Technical Reference Manual:
+ * https://developer.arm.com/documentation/101370/latest/
+ *
+ * QEMU interface:
+ *  + QOM property "counter": link property to be set to the
+ *    TYPE_SSE_COUNTER timestamp counter device this timer runs off
+ *  + sysbus MMIO region 0: the register bank
+ *  + sysbus IRQ 0: timer interrupt
+ */
+
+#ifndef SSE_TIMER_H
+#define SSE_TIMER_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+#include "hw/timer/sse-counter.h"
+
+#define TYPE_SSE_TIMER "sse-timer"
+OBJECT_DECLARE_SIMPLE_TYPE(SSETimer, SSE_TIMER)
+
+struct SSETimer {
+    /*< private >*/
+    SysBusDevice parent_obj;
+
+    /*< public >*/
+    MemoryRegion iomem;
+    qemu_irq irq;
+    SSECounter *counter;
+    QEMUTimer timer;
+    Notifier counter_notifier;
+
+    uint32_t cntfrq;
+    uint32_t cntp_ctl;
+    uint64_t cntp_cval;
+    uint64_t cntp_aival;
+    uint32_t cntp_aival_ctl;
+    uint32_t cntp_aival_reload;
+};
+
+#endif
diff --git a/hw/timer/sse-timer.c b/hw/timer/sse-timer.c
new file mode 100644
index 00000000000..8dbe6ac651e
--- /dev/null
+++ b/hw/timer/sse-timer.c
@@ -0,0 +1,470 @@
+/*
+ * Arm SSE Subsystem System Timer
+ *
+ * Copyright (c) 2020 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 timer" which is documented in
+ * the Arm SSE-123 Example Subsystem Technical Reference Manual:
+ * https://developer.arm.com/documentation/101370/latest/
+ *
+ * The timer is based around a simple 64-bit incrementing counter
+ * (readable from CNTPCT_HI/LO). The timer fires when
+ *  Counter - CompareValue >= 0.
+ * The CompareValue is guest-writable, via CNTP_CVAL_HI/LO.
+ * CNTP_TVAL is an alternative view of the CompareValue defined by
+ *  TimerValue = CompareValue[31:0] - Counter[31:0]
+ * which can be both read and written.
+ * This part is similar to the generic timer in an Arm A-class CPU.
+ *
+ * The timer also has a separate auto-increment timer. When this
+ * timer is enabled, then the AutoIncrValue is set to:
+ *  AutoIncrValue = Reload + Counter
+ * and this timer fires when
+ *  Counter - AutoIncrValue >= 0
+ * at which point, an interrupt is generated and the new AutoIncrValue
+ * is calculated.
+ * When the auto-increment timer is enabled, interrupt generation
+ * via the compare/timervalue registers is disabled.
+ */
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/timer.h"
+#include "qapi/error.h"
+#include "trace.h"
+#include "hw/timer/sse-timer.h"
+#include "hw/timer/sse-counter.h"
+#include "hw/sysbus.h"
+#include "hw/irq.h"
+#include "hw/registerfields.h"
+#include "hw/clock.h"
+#include "hw/qdev-clock.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+
+REG32(CNTPCT_LO, 0x0)
+REG32(CNTPCT_HI, 0x4)
+REG32(CNTFRQ, 0x10)
+REG32(CNTP_CVAL_LO, 0x20)
+REG32(CNTP_CVAL_HI, 0x24)
+REG32(CNTP_TVAL, 0x28)
+REG32(CNTP_CTL, 0x2c)
+    FIELD(CNTP_CTL, ENABLE, 0, 1)
+    FIELD(CNTP_CTL, IMASK, 1, 1)
+    FIELD(CNTP_CTL, ISTATUS, 2, 1)
+REG32(CNTP_AIVAL_LO, 0x40)
+REG32(CNTP_AIVAL_HI, 0x44)
+REG32(CNTP_AIVAL_RELOAD, 0x48)
+REG32(CNTP_AIVAL_CTL, 0x4c)
+    FIELD(CNTP_AIVAL_CTL, EN, 0, 1)
+    FIELD(CNTP_AIVAL_CTL, CLR, 1, 1)
+REG32(CNTP_CFG, 0x50)
+    FIELD(CNTP_CFG, AIVAL, 0, 4)
+#define R_CNTP_CFG_AIVAL_IMPLEMENTED 1
+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 */
+    0xb7, 0xb0, 0x0b, 0x00, /* PID0..PID3 */
+    0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
+};
+
+static bool sse_is_autoinc(SSETimer *s)
+{
+    return (s->cntp_aival_ctl & R_CNTP_AIVAL_CTL_EN_MASK) != 0;
+}
+
+static bool sse_enabled(SSETimer *s)
+{
+    return (s->cntp_ctl & R_CNTP_CTL_ENABLE_MASK) != 0;
+}
+
+static uint64_t sse_cntpct(SSETimer *s)
+{
+    /* Return the CNTPCT value for the current time */
+    return sse_counter_for_timestamp(s->counter,
+                                     qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
+}
+
+static bool sse_timer_status(SSETimer *s)
+{
+    /*
+     * Return true if timer condition is met. This is used for both
+     * the CNTP_CTL.ISTATUS bit and for whether (unless masked) we
+     * assert our IRQ.
+     * The documentation is unclear about the behaviour of ISTATUS when
+     * in autoincrement mode; we assume that it follows CNTP_AIVAL_CTL.CLR
+     * (ie whether the autoincrement timer is asserting the interrupt).
+     */
+    if (!sse_enabled(s)) {
+        return false;
+    }
+
+    if (sse_is_autoinc(s)) {
+        return s->cntp_aival_ctl & R_CNTP_AIVAL_CTL_CLR_MASK;
+    } else {
+        return sse_cntpct(s) >= s->cntp_cval;
+    }
+}
+
+static void sse_update_irq(SSETimer *s)
+{
+    bool irqstate = (!(s->cntp_ctl & R_CNTP_CTL_IMASK_MASK) &&
+                     sse_timer_status(s));
+
+    qemu_set_irq(s->irq, irqstate);
+}
+
+static void sse_set_timer(SSETimer *s, uint64_t nexttick)
+{
+    /* Set the timer to expire at nexttick */
+    uint64_t expiry = sse_counter_tick_to_time(s->counter, nexttick);
+
+    if (expiry <= INT64_MAX) {
+        timer_mod_ns(&s->timer, expiry);
+    } else {
+        /*
+         * nexttick is so far in the future that it would overflow the
+         * signed 64-bit range of a QEMUTimer. Since timer_mod_ns()
+         * expiry times are absolute, not relative, we are never going
+         * to be able to set the timer to this value, so we must just
+         * assume that guest execution can never run so long that it
+         * reaches the theoretical point when the timer fires.
+         * This is also the code path for "counter is not running",
+         * which is signalled by expiry == UINT64_MAX.
+         */
+        timer_del(&s->timer);
+    }
+}
+
+static void sse_recalc_timer(SSETimer *s)
+{
+    /* Recalculate the normal timer */
+    uint64_t count, nexttick;
+
+    if (sse_is_autoinc(s)) {
+        return;
+    }
+
+    if (!sse_enabled(s)) {
+        timer_del(&s->timer);
+        return;
+    }
+
+    count = sse_cntpct(s);
+
+    if (count >= s->cntp_cval) {
+        /*
+         * Timer condition already met. In theory we have a transition when
+         * the count rolls back over to 0, but that is so far in the future
+         * that it is not representable as a timer_mod() expiry, so in
+         * fact sse_set_timer() will always just delete the timer.
+         */
+        nexttick = UINT64_MAX;
+    } else {
+        /* Next transition is when count hits cval */
+        nexttick = s->cntp_cval;
+    }
+    sse_set_timer(s, nexttick);
+    sse_update_irq(s);
+}
+
+static void sse_autoinc(SSETimer *s)
+{
+    /* Auto-increment the AIVAL, and set the timer accordingly */
+    s->cntp_aival = sse_cntpct(s) + s->cntp_aival_reload;
+    sse_set_timer(s, s->cntp_aival);
+}
+
+static void sse_timer_cb(void *opaque)
+{
+    SSETimer *s = SSE_TIMER(opaque);
+
+    if (sse_is_autoinc(s)) {
+        uint64_t count = sse_cntpct(s);
+
+        if (count >= s->cntp_aival) {
+            /* Timer condition met, set CLR and do another autoinc */
+            s->cntp_aival_ctl |= R_CNTP_AIVAL_CTL_CLR_MASK;
+            s->cntp_aival = count + s->cntp_aival_reload;
+        }
+        sse_set_timer(s, s->cntp_aival);
+        sse_update_irq(s);
+    } else {
+        sse_recalc_timer(s);
+    }
+}
+
+static uint64_t sse_timer_read(void *opaque, hwaddr offset, unsigned size)
+{
+    SSETimer *s = SSE_TIMER(opaque);
+    uint64_t r;
+
+    switch (offset) {
+    case A_CNTPCT_LO:
+        r = extract64(sse_cntpct(s), 0, 32);
+        break;
+    case A_CNTPCT_HI:
+        r = extract64(sse_cntpct(s), 32, 32);
+        break;
+    case A_CNTFRQ:
+        r = s->cntfrq;
+        break;
+    case A_CNTP_CVAL_LO:
+        r = extract64(s->cntp_cval, 0, 32);
+        break;
+    case A_CNTP_CVAL_HI:
+        r = extract64(s->cntp_cval, 32, 32);
+        break;
+    case A_CNTP_TVAL:
+        r = extract64(s->cntp_cval - sse_cntpct(s), 0, 32);
+        break;
+    case A_CNTP_CTL:
+        r = s->cntp_ctl;
+        if (sse_timer_status(s)) {
+            r |= R_CNTP_CTL_ISTATUS_MASK;
+        }
+        break;
+    case A_CNTP_AIVAL_LO:
+        r = extract64(s->cntp_aival, 0, 32);
+        break;
+    case A_CNTP_AIVAL_HI:
+        r = extract64(s->cntp_aival, 32, 32);
+        break;
+    case A_CNTP_AIVAL_RELOAD:
+        r = s->cntp_aival_reload;
+        break;
+    case A_CNTP_AIVAL_CTL:
+        /*
+         * All the bits of AIVAL_CTL are documented as WO, but this is probably
+         * a documentation error. We implement them as readable.
+         */
+        r = s->cntp_aival_ctl;
+        break;
+    case A_CNTP_CFG:
+        r = R_CNTP_CFG_AIVAL_IMPLEMENTED << R_CNTP_CFG_AIVAL_SHIFT;
+        break;
+    case A_PID4 ... A_CID3:
+        r = timer_id[(offset - A_PID4) / 4];
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "SSE System Timer read: bad offset 0x%x",
+                      (unsigned) offset);
+        r = 0;
+        break;
+    }
+
+    trace_sse_timer_read(offset, r, size);
+    return r;
+}
+
+static void sse_timer_write(void *opaque, hwaddr offset, uint64_t value,
+                            unsigned size)
+{
+    SSETimer *s = SSE_TIMER(opaque);
+
+    trace_sse_timer_write(offset, value, size);
+
+    switch (offset) {
+    case A_CNTFRQ:
+        s->cntfrq = value;
+        break;
+    case A_CNTP_CVAL_LO:
+        s->cntp_cval = deposit64(s->cntp_cval, 0, 32, value);
+        sse_recalc_timer(s);
+        break;
+    case A_CNTP_CVAL_HI:
+        s->cntp_cval = deposit64(s->cntp_cval, 32, 32, value);
+        sse_recalc_timer(s);
+        break;
+    case A_CNTP_TVAL:
+        s->cntp_cval = sse_cntpct(s) + sextract64(value, 0, 32);
+        sse_recalc_timer(s);
+        break;
+    case A_CNTP_CTL:
+    {
+        uint32_t old_ctl = s->cntp_ctl;
+        value &= R_CNTP_CTL_ENABLE_MASK | R_CNTP_CTL_IMASK_MASK;
+        s->cntp_ctl = value;
+        if ((old_ctl ^ s->cntp_ctl) & R_CNTP_CTL_ENABLE_MASK) {
+            if (sse_enabled(s)) {
+                if (sse_is_autoinc(s)) {
+                    sse_autoinc(s);
+                } else {
+                    sse_recalc_timer(s);
+                }
+            }
+        }
+        sse_update_irq(s);
+        break;
+    }
+    case A_CNTP_AIVAL_RELOAD:
+        s->cntp_aival_reload = value;
+        break;
+    case A_CNTP_AIVAL_CTL:
+    {
+        uint32_t old_ctl = s->cntp_aival_ctl;
+
+        /* EN bit is writeable; CLR bit is write-0-to-clear, write-1-ignored */
+        s->cntp_aival_ctl &= ~R_CNTP_AIVAL_CTL_EN_MASK;
+        s->cntp_aival_ctl |= value & R_CNTP_AIVAL_CTL_EN_MASK;
+        if (!(value & R_CNTP_AIVAL_CTL_CLR_MASK)) {
+            s->cntp_aival_ctl &= ~R_CNTP_AIVAL_CTL_CLR_MASK;
+        }
+        if ((old_ctl ^ s->cntp_aival_ctl) & R_CNTP_AIVAL_CTL_EN_MASK) {
+            /* Auto-increment toggled on/off */
+            if (sse_enabled(s)) {
+                if (sse_is_autoinc(s)) {
+                    sse_autoinc(s);
+                } else {
+                    sse_recalc_timer(s);
+                }
+            }
+        }
+        sse_update_irq(s);
+        break;
+    }
+    case A_CNTPCT_LO:
+    case A_CNTPCT_HI:
+    case A_CNTP_CFG:
+    case A_CNTP_AIVAL_LO:
+    case A_CNTP_AIVAL_HI:
+    case A_PID4 ... A_CID3:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "SSE System Timer write: write to RO offset 0x%x\n",
+                      (unsigned)offset);
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "SSE System Timer write: bad offset 0x%x\n",
+                      (unsigned)offset);
+        break;
+    }
+}
+
+static const MemoryRegionOps sse_timer_ops = {
+    .read = sse_timer_read,
+    .write = sse_timer_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid.min_access_size = 4,
+    .valid.max_access_size = 4,
+};
+
+static void sse_timer_reset(DeviceState *dev)
+{
+    SSETimer *s = SSE_TIMER(dev);
+
+    trace_sse_timer_reset();
+
+    timer_del(&s->timer);
+    s->cntfrq = 0;
+    s->cntp_ctl = 0;
+    s->cntp_cval = 0;
+    s->cntp_aival = 0;
+    s->cntp_aival_ctl = 0;
+    s->cntp_aival_reload = 0;
+}
+
+static void sse_timer_counter_callback(Notifier *notifier, void *data)
+{
+    SSETimer *s = container_of(notifier, SSETimer, counter_notifier);
+
+    /* System counter told us we need to recalculate */
+    if (sse_enabled(s)) {
+        if (sse_is_autoinc(s)) {
+            sse_set_timer(s, s->cntp_aival);
+        } else {
+            sse_recalc_timer(s);
+        }
+    }
+}
+
+static void sse_timer_init(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    SSETimer *s = SSE_TIMER(obj);
+
+    memory_region_init_io(&s->iomem, obj, &sse_timer_ops,
+                          s, "sse-timer", 0x1000);
+    sysbus_init_mmio(sbd, &s->iomem);
+    sysbus_init_irq(sbd, &s->irq);
+}
+
+static void sse_timer_realize(DeviceState *dev, Error **errp)
+{
+    SSETimer *s = SSE_TIMER(dev);
+
+    if (!s->counter) {
+        error_setg(errp, "counter property was not set");
+    }
+
+    s->counter_notifier.notify = sse_timer_counter_callback;
+    sse_counter_register_consumer(s->counter, &s->counter_notifier);
+
+    timer_init_ns(&s->timer, QEMU_CLOCK_VIRTUAL, sse_timer_cb, s);
+}
+
+static const VMStateDescription sse_timer_vmstate = {
+    .name = "sse-timer",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_TIMER(timer, SSETimer),
+        VMSTATE_UINT32(cntfrq, SSETimer),
+        VMSTATE_UINT32(cntp_ctl, SSETimer),
+        VMSTATE_UINT64(cntp_cval, SSETimer),
+        VMSTATE_UINT64(cntp_aival, SSETimer),
+        VMSTATE_UINT32(cntp_aival_ctl, SSETimer),
+        VMSTATE_UINT32(cntp_aival_reload, SSETimer),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static Property sse_timer_properties[] = {
+    DEFINE_PROP_LINK("counter", SSETimer, counter, TYPE_SSE_COUNTER, SSECounter *),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void sse_timer_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = sse_timer_realize;
+    dc->vmsd = &sse_timer_vmstate;
+    dc->reset = sse_timer_reset;
+    device_class_set_props(dc, sse_timer_properties);
+}
+
+static const TypeInfo sse_timer_info = {
+    .name = TYPE_SSE_TIMER,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(SSETimer),
+    .instance_init = sse_timer_init,
+    .class_init = sse_timer_class_init,
+};
+
+static void sse_timer_register_types(void)
+{
+    type_register_static(&sse_timer_info);
+}
+
+type_init(sse_timer_register_types);
diff --git a/MAINTAINERS b/MAINTAINERS
index 1c9b2f446ef..df0eddc7170 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -744,6 +744,8 @@ F: hw/misc/armsse-mhu.c
 F: include/hw/misc/armsse-mhu.h
 F: hw/timer/sse-counter.c
 F: include/hw/timer/sse-counter.h
+F: hw/timer/sse-timer.c
+F: include/hw/timer/sse-timer.h
 F: docs/system/arm/mps2.rst
 
 Musca
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 3081efce20b..ed007267a91 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -520,6 +520,7 @@ config ARMSSE
     select TZ_PPC
     select UNIMP
     select SSE_COUNTER
+    select SSE_TIMER
 
 config ARMSSE_CPUID
     bool
diff --git a/hw/timer/Kconfig b/hw/timer/Kconfig
index e103c8872ab..726be4f82ca 100644
--- a/hw/timer/Kconfig
+++ b/hw/timer/Kconfig
@@ -45,5 +45,8 @@ config RENESAS_CMT
 config SSE_COUNTER
     bool
 
+config SSE_TIMER
+    bool
+
 config AVR_TIMER16
     bool
diff --git a/hw/timer/meson.build b/hw/timer/meson.build
index 79a3012349d..91ab2aa803f 100644
--- a/hw/timer/meson.build
+++ b/hw/timer/meson.build
@@ -33,6 +33,7 @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_systmr.c'))
 softmmu_ss.add(when: 'CONFIG_SH4', if_true: files('sh_timer.c'))
 softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_timer.c'))
 softmmu_ss.add(when: 'CONFIG_SSE_COUNTER', if_true: files('sse-counter.c'))
+softmmu_ss.add(when: 'CONFIG_SSE_TIMER', if_true: files('sse-timer.c'))
 softmmu_ss.add(when: 'CONFIG_STM32F2XX_TIMER', if_true: files('stm32f2xx_timer.c'))
 softmmu_ss.add(when: 'CONFIG_XILINX', if_true: files('xilinx_timer.c'))
 
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
index bb9c1000878..f8b9db25c27 100644
--- a/hw/timer/trace-events
+++ b/hw/timer/trace-events
@@ -100,3 +100,8 @@ sse_counter_control_write(uint64_t offset, uint64_t data, unsigned size) "SSE sy
 sse_counter_status_read(uint64_t offset, uint64_t data, unsigned size) "SSE system counter status frame read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
 sse_counter_status_write(uint64_t offset, uint64_t data, unsigned size) "SSE system counter status frame write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
 sse_counter_reset(void) "SSE system counter: reset"
+
+# sse_timer.c
+sse_timer_read(uint64_t offset, uint64_t data, unsigned size) "SSE system timer read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+sse_timer_write(uint64_t offset, uint64_t data, unsigned size) "SSE system timer write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+sse_timer_reset(void) "SSE system timer: reset"
-- 
2.20.1



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

* [PATCH 13/44] hw/misc/iotkit-sysctl: Add SSE-300 cases which match SSE-200 behaviour
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (11 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 12/44] hw/timer/sse-timer: Model the SSE Subsystem System Timer Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-03-04 19:13   ` Richard Henderson
  2021-02-19 14:45 ` [PATCH 14/44] hw/misc/iotkit-sysctl: Handle CPU_WAIT, NMI_ENABLE for SSE-300 Peter Maydell
                   ` (32 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The SSE-300's iokit-sysctl device is similar to the SSE-200, but
some registers have moved address or have different behaviours.
In this commit we add case statements for the registers where
the SSE-300 and SSE-200 have the same behaviour. Some registers
are the same on all SSE versions and so need no code change at all.
Putting both of these categories together covers:

0x0 SECDBGSTAT
0x4 SECDBGSET
0x8 SECDBGCLR
0xc SCSECCTRL
0x10 CLK_CFG0 -- this is like SSE-200 FCLK_DIV but with a
   different set of clocks being controlled; our implementation
   is a dummy reads-as-written anyway
0x14 CLK_CFG1 -- similar to SSE-200 SYSCLK_DIV; our implementation
   is a dummy
0x18 CLK_FORCE -- similar to SSE-200 but different bit allocations;
   we have a dummy implementation
0x100 RESET_SYNDROME -- bit allocation differs from SSE-200 but our
   implementation is a dummy
0x104 RESET_MASK -- bit allocation differs from SSE-200 but our
   implementation is a dummy
0x108 SWRESET
0x10c GRETREG
0x200 PDCM_PD_SYS_SENSE -- some bit allocations differ, but our
   implementation is a dummy

We also need to migrate the state of these registers which are shared
between the SSE-200 and SSE-300, so update the vmstate 'needed'
function to do this.

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

diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
index c67f5b320ab..7f8608c814c 100644
--- a/hw/misc/iotkit-sysctl.c
+++ b/hw/misc/iotkit-sysctl.c
@@ -105,6 +105,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
         case ARMSSE_IOTKIT:
             goto bad_offset;
         case ARMSSE_SSE200:
+        case ARMSSE_SSE300:
             r = s->scsecctrl;
             break;
         default:
@@ -116,6 +117,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
         case ARMSSE_IOTKIT:
             goto bad_offset;
         case ARMSSE_SSE200:
+        case ARMSSE_SSE300:
             r = s->fclk_div;
             break;
         default:
@@ -127,6 +129,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
         case ARMSSE_IOTKIT:
             goto bad_offset;
         case ARMSSE_SSE200:
+        case ARMSSE_SSE300:
             r = s->sysclk_div;
             break;
         default:
@@ -138,6 +141,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
         case ARMSSE_IOTKIT:
             goto bad_offset;
         case ARMSSE_SSE200:
+        case ARMSSE_SSE300:
             r = s->clock_force;
             break;
         default:
@@ -202,6 +206,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
         case ARMSSE_IOTKIT:
             goto bad_offset;
         case ARMSSE_SSE200:
+        case ARMSSE_SSE300:
             r = s->pdcm_pd_sys_sense;
             break;
         default:
@@ -348,6 +353,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
         case ARMSSE_IOTKIT:
             goto bad_offset;
         case ARMSSE_SSE200:
+        case ARMSSE_SSE300:
             qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SCSECCTRL unimplemented\n");
             s->scsecctrl = value;
             break;
@@ -360,6 +366,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
         case ARMSSE_IOTKIT:
             goto bad_offset;
         case ARMSSE_SSE200:
+        case ARMSSE_SSE300:
             qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl FCLK_DIV unimplemented\n");
             s->fclk_div = value;
             break;
@@ -372,6 +379,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
         case ARMSSE_IOTKIT:
             goto bad_offset;
         case ARMSSE_SSE200:
+        case ARMSSE_SSE300:
             qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SYSCLK_DIV unimplemented\n");
             s->sysclk_div = value;
             break;
@@ -384,6 +392,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
         case ARMSSE_IOTKIT:
             goto bad_offset;
         case ARMSSE_SSE200:
+        case ARMSSE_SSE300:
             qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CLOCK_FORCE unimplemented\n");
             s->clock_force = value;
             break;
@@ -420,6 +429,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
         case ARMSSE_IOTKIT:
             goto bad_offset;
         case ARMSSE_SSE200:
+        case ARMSSE_SSE300:
             qemu_log_mask(LOG_UNIMP,
                           "IoTKit SysCtl PDCM_PD_SYS_SENSE unimplemented\n");
             s->pdcm_pd_sys_sense = value;
@@ -569,7 +579,7 @@ static bool sse200_needed(void *opaque)
 {
     IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
 
-    return s->sse_version == ARMSSE_SSE200;
+    return s->sse_version != ARMSSE_IOTKIT;
 }
 
 static const VMStateDescription iotkit_sysctl_sse200_vmstate = {
-- 
2.20.1



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

* [PATCH 14/44] hw/misc/iotkit-sysctl: Handle CPU_WAIT, NMI_ENABLE for SSE-300
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (12 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 13/44] hw/misc/iotkit-sysctl: Add SSE-300 cases which match SSE-200 behaviour Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-03-04 19:34   ` Richard Henderson
  2021-02-19 14:45 ` [PATCH 15/44] hw/misc/iotkit-sysctl: Handle INITSVTOR* " Peter Maydell
                   ` (31 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

In the SSE-300 the CPU_WAIT and NMI_ENABLE registers have
moved offsets, so they are now where the SSE-200's WICCTRL
and EWCTRL were. The SSE-300 does not have WICCTLR or EWCTRL
at all, and the old offsets are reserved:

 Offset    SSE-200      SSE-300
-----------------------------------
 0x118     CPUWAIT      reserved
 0x118     NMI_ENABLE   reserved
 0x120     WICCTRL      CPUWAIT
 0x124     EWCTRL       NMI_ENABLE

Handle this reshuffle, and the fact that SSE-300 has only
one CPU and so only one active bit in CPUWAIT.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/misc/iotkit-sysctl.c | 88 +++++++++++++++++++++++++++++++++++------
 1 file changed, 76 insertions(+), 12 deletions(-)

diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
index 7f8608c814c..54004bebcbf 100644
--- a/hw/misc/iotkit-sysctl.c
+++ b/hw/misc/iotkit-sysctl.c
@@ -172,7 +172,17 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
         }
         break;
     case A_CPUWAIT:
-        r = s->cpuwait;
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
+        case ARMSSE_SSE200:
+            r = s->cpuwait;
+            break;
+        case ARMSSE_SSE300:
+            /* In SSE300 this is reserved (for INITSVTOR2) */
+            goto bad_offset;
+        default:
+            g_assert_not_reached();
+        }
         break;
     case A_NMI_ENABLE:
         switch (s->sse_version) {
@@ -183,12 +193,26 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
         case ARMSSE_SSE200:
             r = s->nmi_enable;
             break;
+        case ARMSSE_SSE300:
+            /* In SSE300 this is reserved (for INITSVTOR3) */
+            goto bad_offset;
         default:
             g_assert_not_reached();
         }
         break;
     case A_WICCTRL:
-        r = s->wicctrl;
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
+        case ARMSSE_SSE200:
+            r = s->wicctrl;
+            break;
+        case ARMSSE_SSE300:
+            /* In SSE300 this offset is CPUWAIT */
+            r = s->cpuwait;
+            break;
+        default:
+            g_assert_not_reached();
+        }
         break;
     case A_EWCTRL:
         switch (s->sse_version) {
@@ -197,6 +221,10 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
         case ARMSSE_SSE200:
             r = s->ewctrl;
             break;
+        case ARMSSE_SSE300:
+            /* In SSE300 this offset is is NMI_ENABLE */
+            r = s->nmi_enable;
+            break;
         default:
             g_assert_not_reached();
         }
@@ -279,6 +307,21 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
     return r;
 }
 
+static void cpuwait_write(IoTKitSysCtl *s, uint32_t value)
+{
+    int num_cpus = (s->sse_version == ARMSSE_SSE300) ? 1 : 2;
+    int i;
+
+    for (i = 0; i < num_cpus; i++) {
+        uint32_t mask = 1 << i;
+        if ((s->cpuwait & mask) && !(value & mask)) {
+            /* Powering up CPU 0 */
+            arm_set_cpu_on_and_reset(i);
+        }
+    }
+    s->cpuwait = value;
+}
+
 static void iotkit_sysctl_write(void *opaque, hwaddr offset,
                                  uint64_t value, unsigned size)
 {
@@ -319,19 +362,32 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
         set_init_vtor(0, s->initsvtor0);
         break;
     case A_CPUWAIT:
-        if ((s->cpuwait & 1) && !(value & 1)) {
-            /* Powering up CPU 0 */
-            arm_set_cpu_on_and_reset(0);
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
+        case ARMSSE_SSE200:
+            cpuwait_write(s, value);
+            break;
+        case ARMSSE_SSE300:
+            /* In SSE300 this is reserved (for INITSVTOR2) */
+            goto bad_offset;
+        default:
+            g_assert_not_reached();
         }
-        if ((s->cpuwait & 2) && !(value & 2)) {
-            /* Powering up CPU 1 */
-            arm_set_cpu_on_and_reset(1);
-        }
-        s->cpuwait = value;
         break;
     case A_WICCTRL:
-        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl WICCTRL unimplemented\n");
-        s->wicctrl = value;
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
+        case ARMSSE_SSE200:
+            qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl WICCTRL unimplemented\n");
+            s->wicctrl = value;
+            break;
+        case ARMSSE_SSE300:
+            /* In SSE300 this offset is CPUWAIT */
+            cpuwait_write(s, value);
+            break;
+        default:
+            g_assert_not_reached();
+        }
         break;
     case A_SECDBGSET:
         /* write-1-to-set */
@@ -420,6 +476,11 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
             qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl EWCTRL unimplemented\n");
             s->ewctrl = value;
             break;
+        case ARMSSE_SSE300:
+            /* In SSE300 this offset is is NMI_ENABLE */
+            qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
+            s->nmi_enable = value;
+            break;
         default:
             g_assert_not_reached();
         }
@@ -499,6 +560,9 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
             qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
             s->nmi_enable = value;
             break;
+        case ARMSSE_SSE300:
+            /* In SSE300 this is reserved (for INITSVTOR3) */
+            goto bad_offset;
         default:
             g_assert_not_reached();
         }
-- 
2.20.1



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

* [PATCH 15/44] hw/misc/iotkit-sysctl: Handle INITSVTOR* for SSE-300
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (13 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 14/44] hw/misc/iotkit-sysctl: Handle CPU_WAIT, NMI_ENABLE for SSE-300 Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-03-04 19:38   ` Richard Henderson
  2021-02-19 14:45 ` [PATCH 16/44] hw/misc/iotkit-sysctl: Implement dummy version of SSE-300 PWRCTRL register Peter Maydell
                   ` (30 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The SSE-300 has only one CPU and so no INITSVTOR1. It does
have INITSVTOR0, but unlike the SSE-200 this register now
has a LOCK bit which can be set to 1 to prevent any further
writes to the register. Implement these differences.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/misc/iotkit-sysctl.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
index 54004bebcbf..ab97055f529 100644
--- a/hw/misc/iotkit-sysctl.c
+++ b/hw/misc/iotkit-sysctl.c
@@ -45,6 +45,7 @@ REG32(SWRESET, 0x108)
     FIELD(SWRESET, SWRESETREQ, 9, 1)
 REG32(GRETREG, 0x10c)
 REG32(INITSVTOR0, 0x110)
+    FIELD(INITSVTOR0, LOCK, 0, 1)
 REG32(INITSVTOR1, 0x114)
 REG32(CPUWAIT, 0x118)
 REG32(NMI_ENABLE, 0x11c) /* BUSWAIT in IoTKit */
@@ -167,6 +168,8 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
         case ARMSSE_SSE200:
             r = s->initsvtor1;
             break;
+        case ARMSSE_SSE300:
+            goto bad_offset;
         default:
             g_assert_not_reached();
         }
@@ -358,8 +361,25 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
         s->gretreg = value;
         break;
     case A_INITSVTOR0:
-        s->initsvtor0 = value;
-        set_init_vtor(0, s->initsvtor0);
+        switch (s->sse_version) {
+        case ARMSSE_SSE300:
+            /* SSE300 has a LOCK bit which prevents further writes when set */
+            if (s->initsvtor0 & R_INITSVTOR0_LOCK_MASK) {
+                qemu_log_mask(LOG_GUEST_ERROR,
+                              "IoTKit INITSVTOR0 write when register locked\n");
+                break;
+            }
+            s->initsvtor0 = value;
+            set_init_vtor(0, s->initsvtor0 & ~R_INITSVTOR0_LOCK_MASK);
+            break;
+        case ARMSSE_IOTKIT:
+        case ARMSSE_SSE200:
+            s->initsvtor0 = value;
+            set_init_vtor(0, s->initsvtor0);
+            break;
+        default:
+            g_assert_not_reached();
+        }
         break;
     case A_CPUWAIT:
         switch (s->sse_version) {
@@ -464,6 +484,8 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
             s->initsvtor1 = value;
             set_init_vtor(1, s->initsvtor1);
             break;
+        case ARMSSE_SSE300:
+            goto bad_offset;
         default:
             g_assert_not_reached();
         }
-- 
2.20.1



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

* [PATCH 16/44] hw/misc/iotkit-sysctl: Implement dummy version of SSE-300 PWRCTRL register
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (14 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 15/44] hw/misc/iotkit-sysctl: Handle INITSVTOR* " Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-03-04 19:49   ` Richard Henderson
  2021-02-19 14:45 ` [PATCH 17/44] hw/misc/iotkit-sysctl: Handle SSE-300 changes to PDCM_PD_*_SENSE registers Peter Maydell
                   ` (29 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The SSE-300 has a new PWRCTRL register at offset 0x1fc (previously
reserved). This register controls accessibility of some registers
in the Power Policy Units (PPUs). Since QEMU doesn't implement
the PPUs, we don't need to implement any real behaviour for this
register, so we just handle the UNLOCK bit which controls whether
writes to the register itself are permitted and otherwise make it
be reads-as-written.

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

diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
index 980c2ddfd3c..8859b15d73b 100644
--- a/include/hw/misc/iotkit-sysctl.h
+++ b/include/hw/misc/iotkit-sysctl.h
@@ -53,6 +53,7 @@ struct IoTKitSysCtl {
     uint32_t initsvtor1;
     uint32_t nmi_enable;
     uint32_t ewctrl;
+    uint32_t pwrctrl;
     uint32_t pdcm_pd_sys_sense;
     uint32_t pdcm_pd_sram0_sense;
     uint32_t pdcm_pd_sram1_sense;
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
index ab97055f529..e8255d26b5a 100644
--- a/hw/misc/iotkit-sysctl.c
+++ b/hw/misc/iotkit-sysctl.c
@@ -51,6 +51,9 @@ REG32(CPUWAIT, 0x118)
 REG32(NMI_ENABLE, 0x11c) /* BUSWAIT in IoTKit */
 REG32(WICCTRL, 0x120)
 REG32(EWCTRL, 0x124)
+REG32(PWRCTRL, 0x1fc)
+    FIELD(PWRCTRL, PPU_ACCESS_UNLOCK, 0, 1)
+    FIELD(PWRCTRL, PPU_ACCESS_FILTER, 1, 1)
 REG32(PDCM_PD_SYS_SENSE, 0x200)
 REG32(PDCM_PD_SRAM0_SENSE, 0x20c)
 REG32(PDCM_PD_SRAM1_SENSE, 0x210)
@@ -232,6 +235,18 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
             g_assert_not_reached();
         }
         break;
+    case A_PWRCTRL:
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
+        case ARMSSE_SSE200:
+            goto bad_offset;
+        case ARMSSE_SSE300:
+            r = s->pwrctrl;
+            break;
+        default:
+            g_assert_not_reached();
+        }
+        break;
     case A_PDCM_PD_SYS_SENSE:
         switch (s->sse_version) {
         case ARMSSE_IOTKIT:
@@ -507,6 +522,23 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
             g_assert_not_reached();
         }
         break;
+    case A_PWRCTRL:
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
+        case ARMSSE_SSE200:
+            goto bad_offset;
+        case ARMSSE_SSE300:
+            if (!(s->pwrctrl & R_PWRCTRL_PPU_ACCESS_UNLOCK_MASK)) {
+                qemu_log_mask(LOG_GUEST_ERROR,
+                              "IoTKit PWRCTRL write when register locked\n");
+                break;
+            }
+            s->pwrctrl = value;
+            break;
+        default:
+            g_assert_not_reached();
+        }
+        break;
     case A_PDCM_PD_SYS_SENSE:
         switch (s->sse_version) {
         case ARMSSE_IOTKIT:
@@ -634,6 +666,7 @@ static void iotkit_sysctl_reset(DeviceState *dev)
     s->clock_force = 0;
     s->nmi_enable = 0;
     s->ewctrl = 0;
+    s->pwrctrl = 0x3;
     s->pdcm_pd_sys_sense = 0x7f;
     s->pdcm_pd_sram0_sense = 0;
     s->pdcm_pd_sram1_sense = 0;
@@ -661,6 +694,24 @@ static void iotkit_sysctl_realize(DeviceState *dev, Error **errp)
     }
 }
 
+static bool sse300_needed(void *opaque)
+{
+    IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
+
+    return s->sse_version == ARMSSE_SSE300;
+}
+
+static const VMStateDescription iotkit_sysctl_sse300_vmstate = {
+    .name = "iotkit-sysctl/sse-300",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = sse300_needed,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(pwrctrl, IoTKitSysCtl),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static bool sse200_needed(void *opaque)
 {
     IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
@@ -705,6 +756,7 @@ static const VMStateDescription iotkit_sysctl_vmstate = {
     },
     .subsections = (const VMStateDescription*[]) {
         &iotkit_sysctl_sse200_vmstate,
+        &iotkit_sysctl_sse300_vmstate,
         NULL
     }
 };
-- 
2.20.1



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

* [PATCH 17/44] hw/misc/iotkit-sysctl: Handle SSE-300 changes to PDCM_PD_*_SENSE registers
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (15 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 16/44] hw/misc/iotkit-sysctl: Implement dummy version of SSE-300 PWRCTRL register Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-03-04 19:52   ` Richard Henderson
  2021-02-19 14:45 ` [PATCH 18/44] hw/misc/iotkit-sysctl: Implement SSE-200 and SSE-300 PID register values Peter Maydell
                   ` (28 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The sysctl PDCM_PD_*_SENSE registers control various power domains in
the system and allow the guest to configure which conditions keep a
power domain awake and what power state to use when the domain is in
a low power state.  QEMU doesn't model power domains, so for us these
registers are dummy reads-as-written implementations.

The SSE-300 has a different power domain setup, so the set of
registers is slightly different:

 Offset   SSE-200               SSE-300
---------------------------------------------------
 0x200    PDCM_PD_SYS_SENSE     PDCM_PD_SYS_SENSE
 0x204    reserved              PDCM_PD_CPU0_SENSE
 0x208    reserved              reserved
 0x20c    PDCM_PD_SRAM0_SENSE   reserved
 0x210    PDCM_PD_SRAM1_SENSE   reserved
 0x214    PDCM_PD_SRAM2_SENSE   PDCM_PD_VMR0_SENSE
 0x218    PDCM_PD_SRAM3_SENSE   PDCM_PD_VMR1_SENSE

Offsets 0x200 and 0x208 are the same for both, so handled in a
previous commit; here we deal with 0x204, 0x20c, 0x210, 0x214, 0x218.

(We can safely add new lines to the SSE300 vmstate because no board
uses this device in an SSE300 yet.)

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

diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
index 8859b15d73b..481e27f4db1 100644
--- a/include/hw/misc/iotkit-sysctl.h
+++ b/include/hw/misc/iotkit-sysctl.h
@@ -59,6 +59,9 @@ struct IoTKitSysCtl {
     uint32_t pdcm_pd_sram1_sense;
     uint32_t pdcm_pd_sram2_sense;
     uint32_t pdcm_pd_sram3_sense;
+    uint32_t pdcm_pd_cpu0_sense;
+    uint32_t pdcm_pd_vmr0_sense;
+    uint32_t pdcm_pd_vmr1_sense;
 
     /* Properties */
     uint32_t sse_version;
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
index e8255d26b5a..a80f68b7995 100644
--- a/hw/misc/iotkit-sysctl.c
+++ b/hw/misc/iotkit-sysctl.c
@@ -55,10 +55,11 @@ REG32(PWRCTRL, 0x1fc)
     FIELD(PWRCTRL, PPU_ACCESS_UNLOCK, 0, 1)
     FIELD(PWRCTRL, PPU_ACCESS_FILTER, 1, 1)
 REG32(PDCM_PD_SYS_SENSE, 0x200)
+REG32(PDCM_PD_CPU0_SENSE, 0x204)
 REG32(PDCM_PD_SRAM0_SENSE, 0x20c)
 REG32(PDCM_PD_SRAM1_SENSE, 0x210)
-REG32(PDCM_PD_SRAM2_SENSE, 0x214)
-REG32(PDCM_PD_SRAM3_SENSE, 0x218)
+REG32(PDCM_PD_SRAM2_SENSE, 0x214) /* PDCM_PD_VMR0_SENSE on SSE300 */
+REG32(PDCM_PD_SRAM3_SENSE, 0x218) /* PDCM_PD_VMR1_SENSE on SSE300 */
 REG32(PID4, 0xfd0)
 REG32(PID5, 0xfd4)
 REG32(PID6, 0xfd8)
@@ -259,6 +260,18 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
             g_assert_not_reached();
         }
         break;
+    case A_PDCM_PD_CPU0_SENSE:
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
+        case ARMSSE_SSE200:
+            goto bad_offset;
+        case ARMSSE_SSE300:
+            r = s->pdcm_pd_cpu0_sense;
+            break;
+        default:
+            g_assert_not_reached();
+        }
+        break;
     case A_PDCM_PD_SRAM0_SENSE:
         switch (s->sse_version) {
         case ARMSSE_IOTKIT:
@@ -266,6 +279,8 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
         case ARMSSE_SSE200:
             r = s->pdcm_pd_sram0_sense;
             break;
+        case ARMSSE_SSE300:
+            goto bad_offset;
         default:
             g_assert_not_reached();
         }
@@ -277,6 +292,8 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
         case ARMSSE_SSE200:
             r = s->pdcm_pd_sram1_sense;
             break;
+        case ARMSSE_SSE300:
+            goto bad_offset;
         default:
             g_assert_not_reached();
         }
@@ -288,6 +305,9 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
         case ARMSSE_SSE200:
             r = s->pdcm_pd_sram2_sense;
             break;
+        case ARMSSE_SSE300:
+            r = s->pdcm_pd_vmr0_sense;
+            break;
         default:
             g_assert_not_reached();
         }
@@ -299,6 +319,9 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
         case ARMSSE_SSE200:
             r = s->pdcm_pd_sram3_sense;
             break;
+        case ARMSSE_SSE300:
+            r = s->pdcm_pd_vmr1_sense;
+            break;
         default:
             g_assert_not_reached();
         }
@@ -553,6 +576,20 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
             g_assert_not_reached();
         }
         break;
+    case A_PDCM_PD_CPU0_SENSE:
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
+        case ARMSSE_SSE200:
+            goto bad_offset;
+        case ARMSSE_SSE300:
+            qemu_log_mask(LOG_UNIMP,
+                          "IoTKit SysCtl PDCM_PD_CPU0_SENSE unimplemented\n");
+            s->pdcm_pd_cpu0_sense = value;
+            break;
+        default:
+            g_assert_not_reached();
+        }
+        break;
     case A_PDCM_PD_SRAM0_SENSE:
         switch (s->sse_version) {
         case ARMSSE_IOTKIT:
@@ -562,6 +599,8 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
                           "IoTKit SysCtl PDCM_PD_SRAM0_SENSE unimplemented\n");
             s->pdcm_pd_sram0_sense = value;
             break;
+        case ARMSSE_SSE300:
+            goto bad_offset;
         default:
             g_assert_not_reached();
         }
@@ -575,6 +614,8 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
                           "IoTKit SysCtl PDCM_PD_SRAM1_SENSE unimplemented\n");
             s->pdcm_pd_sram1_sense = value;
             break;
+        case ARMSSE_SSE300:
+            goto bad_offset;
         default:
             g_assert_not_reached();
         }
@@ -588,6 +629,11 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
                           "IoTKit SysCtl PDCM_PD_SRAM2_SENSE unimplemented\n");
             s->pdcm_pd_sram2_sense = value;
             break;
+        case ARMSSE_SSE300:
+            qemu_log_mask(LOG_UNIMP,
+                          "IoTKit SysCtl PDCM_PD_VMR0_SENSE unimplemented\n");
+            s->pdcm_pd_vmr0_sense = value;
+            break;
         default:
             g_assert_not_reached();
         }
@@ -601,6 +647,11 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
                           "IoTKit SysCtl PDCM_PD_SRAM3_SENSE unimplemented\n");
             s->pdcm_pd_sram3_sense = value;
             break;
+        case ARMSSE_SSE300:
+            qemu_log_mask(LOG_UNIMP,
+                          "IoTKit SysCtl PDCM_PD_VMR1_SENSE unimplemented\n");
+            s->pdcm_pd_vmr1_sense = value;
+            break;
         default:
             g_assert_not_reached();
         }
@@ -672,6 +723,9 @@ static void iotkit_sysctl_reset(DeviceState *dev)
     s->pdcm_pd_sram1_sense = 0;
     s->pdcm_pd_sram2_sense = 0;
     s->pdcm_pd_sram3_sense = 0;
+    s->pdcm_pd_cpu0_sense = 0;
+    s->pdcm_pd_vmr0_sense = 0;
+    s->pdcm_pd_vmr1_sense = 0;
 }
 
 static void iotkit_sysctl_init(Object *obj)
@@ -708,6 +762,9 @@ static const VMStateDescription iotkit_sysctl_sse300_vmstate = {
     .needed = sse300_needed,
     .fields = (VMStateField[]) {
         VMSTATE_UINT32(pwrctrl, IoTKitSysCtl),
+        VMSTATE_UINT32(pdcm_pd_cpu0_sense, IoTKitSysCtl),
+        VMSTATE_UINT32(pdcm_pd_vmr0_sense, IoTKitSysCtl),
+        VMSTATE_UINT32(pdcm_pd_vmr1_sense, IoTKitSysCtl),
         VMSTATE_END_OF_LIST()
     }
 };
-- 
2.20.1



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

* [PATCH 18/44] hw/misc/iotkit-sysctl: Implement SSE-200 and SSE-300 PID register values
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (16 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 17/44] hw/misc/iotkit-sysctl: Handle SSE-300 changes to PDCM_PD_*_SENSE registers Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-03-04 19:57   ` Richard Henderson
  2021-02-19 14:45 ` [PATCH 19/44] hw/arm/Kconfig: Move ARMSSE_CPUID and ARMSSE_MHU stanzas to hw/misc Peter Maydell
                   ` (27 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The SSE-200 and SSE-300 have different PID register values from the
IoTKit for the sysctl register block.  We incorrectly implemented the
SSE-200 with the same PID values as IoTKit.  Fix the SSE-200 bug and
report these register values for SSE-300.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/misc/iotkit-sysctl.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
index a80f68b7995..54d6b6c165c 100644
--- a/hw/misc/iotkit-sysctl.c
+++ b/hw/misc/iotkit-sysctl.c
@@ -74,12 +74,19 @@ REG32(CID2, 0xff8)
 REG32(CID3, 0xffc)
 
 /* PID/CID values */
-static const int sysctl_id[] = {
+static const int iotkit_sysctl_id[] = {
     0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
     0x54, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
     0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
 };
 
+/* Also used by the SSE300 */
+static const int sse200_sysctl_id[] = {
+    0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
+    0x54, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
+    0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
+};
+
 /*
  * Set the initial secure vector table offset address for the core.
  * This will take effect when the CPU next resets.
@@ -327,7 +334,17 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
         }
         break;
     case A_PID4 ... A_CID3:
-        r = sysctl_id[(offset - A_PID4) / 4];
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
+            r = iotkit_sysctl_id[(offset - A_PID4) / 4];
+            break;
+        case ARMSSE_SSE200:
+        case ARMSSE_SSE300:
+            r = sse200_sysctl_id[(offset - A_PID4) / 4];
+            break;
+        default:
+            g_assert_not_reached();
+        }
         break;
     case A_SECDBGSET:
     case A_SECDBGCLR:
-- 
2.20.1



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

* [PATCH 19/44] hw/arm/Kconfig: Move ARMSSE_CPUID and ARMSSE_MHU stanzas to hw/misc
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (17 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 18/44] hw/misc/iotkit-sysctl: Implement SSE-200 and SSE-300 PID register values Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-02-21 13:31   ` Philippe Mathieu-Daudé
  2021-03-04 19:57   ` Richard Henderson
  2021-02-19 14:45 ` [PATCH 20/44] hw/misc/sse-cpu-pwrctrl: Implement SSE-300 CPU<N>_PWRCTRL register block Peter Maydell
                   ` (26 subsequent siblings)
  45 siblings, 2 replies; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The ARMSSE_CPUID and ARMSSE_MHU Kconfig stanzas are for the devices
implmemented by hw/misc/cpuid.c and hw/misc/armsse-mhu.c.  Move them
to hw/misc/Kconfig where they belong.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/Kconfig  | 6 ------
 hw/misc/Kconfig | 6 ++++++
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index ed007267a91..0492b212840 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -521,9 +521,3 @@ config ARMSSE
     select UNIMP
     select SSE_COUNTER
     select SSE_TIMER
-
-config ARMSSE_CPUID
-    bool
-
-config ARMSSE_MHU
-    bool
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 19c216f3efb..16b96e4dafb 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -2,6 +2,12 @@ config APPLESMC
     bool
     depends on ISA_BUS
 
+config ARMSSE_CPUID
+    bool
+
+config ARMSSE_MHU
+    bool
+
 config MAX111X
     bool
 
-- 
2.20.1



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

* [PATCH 20/44] hw/misc/sse-cpu-pwrctrl: Implement SSE-300 CPU<N>_PWRCTRL register block
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (18 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 19/44] hw/arm/Kconfig: Move ARMSSE_CPUID and ARMSSE_MHU stanzas to hw/misc Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-03-04 20:02   ` Richard Henderson
  2021-02-19 14:45 ` [PATCH 21/44] hw/arm/armsse: Use an array for apb_ppc fields in the state structure Peter Maydell
                   ` (25 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The SSE-300 has a new register block CPU<N>_PWRCTRL.  There is one
instance of this per CPU in the system (so just one for the SSE-300),
and as well as the usual CIDR/PIDR ID registers it has just one
register, CPUPWRCFG.  This register allows the guest to configure
behaviour of the system in power-down and deep-sleep states.  Since
QEMU does not model those, we make the register a dummy
reads-as-written implementation.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/misc/armsse-cpu-pwrctrl.h |  40 +++++++
 hw/misc/armsse-cpu-pwrctrl.c         | 149 +++++++++++++++++++++++++++
 MAINTAINERS                          |   2 +
 hw/arm/Kconfig                       |   1 +
 hw/misc/Kconfig                      |   3 +
 hw/misc/meson.build                  |   1 +
 hw/misc/trace-events                 |   4 +
 7 files changed, 200 insertions(+)
 create mode 100644 include/hw/misc/armsse-cpu-pwrctrl.h
 create mode 100644 hw/misc/armsse-cpu-pwrctrl.c

diff --git a/include/hw/misc/armsse-cpu-pwrctrl.h b/include/hw/misc/armsse-cpu-pwrctrl.h
new file mode 100644
index 00000000000..51d45ede7db
--- /dev/null
+++ b/include/hw/misc/armsse-cpu-pwrctrl.h
@@ -0,0 +1,40 @@
+/*
+ * ARM SSE CPU PWRCTRL register block
+ *
+ * Copyright (c) 2021 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 "CPU<N>_PWRCTRL block" which is part of the
+ * Arm Corstone SSE-300 Example Subsystem and documented in
+ * https://developer.arm.com/documentation/101773/0000
+ *
+ * QEMU interface:
+ *  + sysbus MMIO region 0: the register bank
+ */
+
+#ifndef HW_MISC_ARMSSE_CPU_PWRCTRL_H
+#define HW_MISC_ARMSSE_CPU_PWRCTRL_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+#define TYPE_ARMSSE_CPU_PWRCTRL "armsse-cpu-pwrctrl"
+OBJECT_DECLARE_SIMPLE_TYPE(ARMSSECPUPwrCtrl, ARMSSE_CPU_PWRCTRL)
+
+struct ARMSSECPUPwrCtrl {
+    /*< private >*/
+    SysBusDevice parent_obj;
+
+    /*< public >*/
+    MemoryRegion iomem;
+
+    uint32_t cpupwrcfg;
+};
+
+#endif
diff --git a/hw/misc/armsse-cpu-pwrctrl.c b/hw/misc/armsse-cpu-pwrctrl.c
new file mode 100644
index 00000000000..42fc38879f2
--- /dev/null
+++ b/hw/misc/armsse-cpu-pwrctrl.c
@@ -0,0 +1,149 @@
+/*
+ * Arm SSE CPU PWRCTRL register block
+ *
+ * Copyright (c) 2021 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 "CPU<N>_PWRCTRL block" which is part of the
+ * Arm Corstone SSE-300 Example Subsystem and documented in
+ * https://developer.arm.com/documentation/101773/0000
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "trace.h"
+#include "qapi/error.h"
+#include "migration/vmstate.h"
+#include "hw/sysbus.h"
+#include "hw/registerfields.h"
+#include "hw/misc/armsse-cpu-pwrctrl.h"
+
+REG32(CPUPWRCFG, 0x0)
+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 cpu_pwrctrl_id[] = {
+    0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
+    0x5a, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
+    0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
+};
+
+static uint64_t pwrctrl_read(void *opaque, hwaddr offset, unsigned size)
+{
+    ARMSSECPUPwrCtrl *s = ARMSSE_CPU_PWRCTRL(opaque);
+    uint64_t r;
+
+    switch (offset) {
+    case A_CPUPWRCFG:
+        r = s->cpupwrcfg;
+        break;
+    case A_PID4 ... A_CID3:
+        r = cpu_pwrctrl_id[(offset - A_PID4) / 4];
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "SSE CPU_PWRCTRL read: bad offset %x\n", (int)offset);
+        r = 0;
+        break;
+    }
+    trace_armsse_cpu_pwrctrl_read(offset, r, size);
+    return r;
+}
+
+static void pwrctrl_write(void *opaque, hwaddr offset,
+                          uint64_t value, unsigned size)
+{
+    ARMSSECPUPwrCtrl *s = ARMSSE_CPU_PWRCTRL(opaque);
+
+    trace_armsse_cpu_pwrctrl_write(offset, value, size);
+
+    switch (offset) {
+    case A_CPUPWRCFG:
+        qemu_log_mask(LOG_UNIMP,
+                      "SSE CPU_PWRCTRL: CPUPWRCFG unimplemented\n");
+        s->cpupwrcfg = value;
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "SSE CPU_PWRCTRL write: bad offset 0x%x\n", (int)offset);
+        break;
+    }
+}
+
+static const MemoryRegionOps pwrctrl_ops = {
+    .read = pwrctrl_read,
+    .write = pwrctrl_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl.min_access_size = 4,
+    .impl.max_access_size = 4,
+    .valid.min_access_size = 4,
+    .valid.max_access_size = 4,
+};
+
+static void pwrctrl_reset(DeviceState *dev)
+{
+    ARMSSECPUPwrCtrl *s = ARMSSE_CPU_PWRCTRL(dev);
+
+    s->cpupwrcfg = 0;
+}
+
+static const VMStateDescription pwrctrl_vmstate = {
+    .name = "armsse-cpu-pwrctrl",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(cpupwrcfg, ARMSSECPUPwrCtrl),
+        VMSTATE_END_OF_LIST()
+    },
+};
+
+static void pwrctrl_init(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    ARMSSECPUPwrCtrl *s = ARMSSE_CPU_PWRCTRL(obj);
+
+    memory_region_init_io(&s->iomem, obj, &pwrctrl_ops,
+                          s, "armsse-cpu-pwrctrl", 0x1000);
+    sysbus_init_mmio(sbd, &s->iomem);
+}
+
+static void pwrctrl_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->reset = pwrctrl_reset;
+    dc->vmsd = &pwrctrl_vmstate;
+}
+
+static const TypeInfo pwrctrl_info = {
+    .name = TYPE_ARMSSE_CPU_PWRCTRL,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(ARMSSECPUPwrCtrl),
+    .instance_init = pwrctrl_init,
+    .class_init = pwrctrl_class_init,
+};
+
+static void pwrctrl_register_types(void)
+{
+    type_register_static(&pwrctrl_info);
+}
+
+type_init(pwrctrl_register_types);
diff --git a/MAINTAINERS b/MAINTAINERS
index df0eddc7170..c2103b40b9b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -738,6 +738,8 @@ 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
+F: hw/misc/armsse-cpu-pwrctrl.c
+F: include/hw/misc/armsse-cpu-pwrctrl.h
 F: hw/misc/armsse-cpuid.c
 F: include/hw/misc/armsse-cpuid.h
 F: hw/misc/armsse-mhu.c
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 0492b212840..be9adf18594 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -504,6 +504,7 @@ config ARM11MPCORE
 config ARMSSE
     bool
     select ARM_V7M
+    select ARMSSE_CPU_PWRCTRL
     select ARMSSE_CPUID
     select ARMSSE_MHU
     select CMSDK_APB_TIMER
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 16b96e4dafb..5426b9b1a1a 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -8,6 +8,9 @@ config ARMSSE_CPUID
 config ARMSSE_MHU
     bool
 
+config ARMSSE_CPU_PWRCTRL
+    bool
+
 config MAX111X
     bool
 
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 629283957fc..e30a555db5c 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -96,6 +96,7 @@ softmmu_ss.add(when: 'CONFIG_TZ_MSC', if_true: files('tz-msc.c'))
 softmmu_ss.add(when: 'CONFIG_TZ_PPC', if_true: files('tz-ppc.c'))
 softmmu_ss.add(when: 'CONFIG_IOTKIT_SECCTL', if_true: files('iotkit-secctl.c'))
 softmmu_ss.add(when: 'CONFIG_IOTKIT_SYSINFO', if_true: files('iotkit-sysinfo.c'))
+softmmu_ss.add(when: 'CONFIG_ARMSSE_CPU_PWRCTRL', if_true: files('armsse-cpu-pwrctrl.c'))
 softmmu_ss.add(when: 'CONFIG_ARMSSE_CPUID', if_true: files('armsse-cpuid.c'))
 softmmu_ss.add(when: 'CONFIG_ARMSSE_MHU', if_true: files('armsse-mhu.c'))
 
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index d626b9d7a7c..4b15db8ca48 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -186,6 +186,10 @@ iotkit_sysctl_read(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysCtl
 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"
 
+# armsse-cpu-pwrctrl.c
+armsse_cpu_pwrctrl_read(uint64_t offset, uint64_t data, unsigned size) "SSE-300 CPU_PWRCTRL read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+armsse_cpu_pwrctrl_write(uint64_t offset, uint64_t data, unsigned size) "SSE-300 CPU_PWRCTRL write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+
 # armsse-cpuid.c
 armsse_cpuid_read(uint64_t offset, uint64_t data, unsigned size) "SSE-200 CPU_IDENTITY read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
 armsse_cpuid_write(uint64_t offset, uint64_t data, unsigned size) "SSE-200 CPU_IDENTITY write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
-- 
2.20.1



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

* [PATCH 21/44] hw/arm/armsse: Use an array for apb_ppc fields in the state structure
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (19 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 20/44] hw/misc/sse-cpu-pwrctrl: Implement SSE-300 CPU<N>_PWRCTRL register block Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-02-21 13:34   ` Philippe Mathieu-Daudé
  2021-03-04 20:04   ` Richard Henderson
  2021-02-19 14:45 ` [PATCH 22/44] hw/arm/armsse: Add a define for number of IRQs used by the SSE itself Peter Maydell
                   ` (24 subsequent siblings)
  45 siblings, 2 replies; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Convert the apb_ppc0 and apb_ppc1 fields in the ARMSSE state struct
to use an array instead of two separate fields.  We already had one
place in the code that wanted to be able to refer to the PPC by
index, and we're about to add more code like that.

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

diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
index 09284ca75cf..771150b0a94 100644
--- a/include/hw/arm/armsse.h
+++ b/include/hw/arm/armsse.h
@@ -124,8 +124,9 @@ OBJECT_DECLARE_TYPE(ARMSSE, ARMSSEClass,
 /* We have an IRQ splitter and an OR gate input for each external PPC
  * and the 2 internal PPCs
  */
+#define NUM_INTERNAL_PPCS 2
 #define NUM_EXTERNAL_PPCS (IOTS_NUM_AHB_EXP_PPC + IOTS_NUM_APB_EXP_PPC)
-#define NUM_PPCS (NUM_EXTERNAL_PPCS + 2)
+#define NUM_PPCS (NUM_EXTERNAL_PPCS + NUM_INTERNAL_PPCS)
 
 #define MAX_SRAM_BANKS 4
 #if MAX_SRAM_BANKS > IOTS_NUM_MPC
@@ -152,8 +153,7 @@ struct ARMSSE {
     ARMv7MState armv7m[SSE_MAX_CPUS];
     CPUClusterState cluster[SSE_MAX_CPUS];
     IoTKitSecCtl secctl;
-    TZPPC apb_ppc0;
-    TZPPC apb_ppc1;
+    TZPPC apb_ppc[NUM_INTERNAL_PPCS];
     TZMPC mpc[IOTS_NUM_MPC];
     CMSDKAPBTimer timer0;
     CMSDKAPBTimer timer1;
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index 326e161c8d4..2b25fca1ca2 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -291,8 +291,12 @@ static void armsse_init(Object *obj)
     }
 
     object_initialize_child(obj, "secctl", &s->secctl, TYPE_IOTKIT_SECCTL);
-    object_initialize_child(obj, "apb-ppc0", &s->apb_ppc0, TYPE_TZ_PPC);
-    object_initialize_child(obj, "apb-ppc1", &s->apb_ppc1, TYPE_TZ_PPC);
+
+    for (i = 0; i < ARRAY_SIZE(s->apb_ppc); i++) {
+        g_autofree char *name = g_strdup_printf("apb-ppc%d", i);
+        object_initialize_child(obj, name, &s->apb_ppc[i], TYPE_TZ_PPC);
+    }
+
     for (i = 0; i < info->sram_banks; i++) {
         char *name = g_strdup_printf("mpc%d", i);
         object_initialize_child(obj, name, &s->mpc[i], TYPE_TZ_MPC);
@@ -739,7 +743,7 @@ static void armsse_realize(DeviceState *dev, Error **errp)
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer0), 0,
                        armsse_get_common_irq_in(s, 3));
     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer0), 0);
-    object_property_set_link(OBJECT(&s->apb_ppc0), "port[0]", OBJECT(mr),
+    object_property_set_link(OBJECT(&s->apb_ppc[0]), "port[0]", OBJECT(mr),
                              &error_abort);
 
     qdev_connect_clock_in(DEVICE(&s->timer1), "pclk", s->mainclk);
@@ -749,7 +753,7 @@ static void armsse_realize(DeviceState *dev, Error **errp)
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer1), 0,
                        armsse_get_common_irq_in(s, 4));
     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer1), 0);
-    object_property_set_link(OBJECT(&s->apb_ppc0), "port[1]", OBJECT(mr),
+    object_property_set_link(OBJECT(&s->apb_ppc[0]), "port[1]", OBJECT(mr),
                              &error_abort);
 
     qdev_connect_clock_in(DEVICE(&s->dualtimer), "TIMCLK", s->mainclk);
@@ -759,7 +763,7 @@ static void armsse_realize(DeviceState *dev, Error **errp)
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->dualtimer), 0,
                        armsse_get_common_irq_in(s, 5));
     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dualtimer), 0);
-    object_property_set_link(OBJECT(&s->apb_ppc0), "port[2]", OBJECT(mr),
+    object_property_set_link(OBJECT(&s->apb_ppc[0]), "port[2]", OBJECT(mr),
                              &error_abort);
 
     if (info->has_mhus) {
@@ -782,7 +786,7 @@ static void armsse_realize(DeviceState *dev, Error **errp)
             }
             port = g_strdup_printf("port[%d]", i + 3);
             mr = sysbus_mmio_get_region(mhu_sbd, 0);
-            object_property_set_link(OBJECT(&s->apb_ppc0), port, OBJECT(mr),
+            object_property_set_link(OBJECT(&s->apb_ppc[0]), port, OBJECT(mr),
                                      &error_abort);
             g_free(port);
 
@@ -802,12 +806,12 @@ static void armsse_realize(DeviceState *dev, Error **errp)
         }
     }
 
-    if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc0), errp)) {
+    if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc[0]), errp)) {
         return;
     }
 
-    sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc0);
-    dev_apb_ppc0 = DEVICE(&s->apb_ppc0);
+    sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc[0]);
+    dev_apb_ppc0 = DEVICE(&s->apb_ppc[0]);
 
     mr = sysbus_mmio_get_region(sbd_apb_ppc0, 0);
     memory_region_add_subregion(&s->container, 0x40000000, mr);
@@ -917,16 +921,16 @@ static void armsse_realize(DeviceState *dev, Error **errp)
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32ktimer), 0,
                        armsse_get_common_irq_in(s, 2));
     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->s32ktimer), 0);
-    object_property_set_link(OBJECT(&s->apb_ppc1), "port[0]", OBJECT(mr),
+    object_property_set_link(OBJECT(&s->apb_ppc[1]), "port[0]", OBJECT(mr),
                              &error_abort);
 
-    if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc1), errp)) {
+    if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc[1]), errp)) {
         return;
     }
-    mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->apb_ppc1), 0);
+    mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->apb_ppc[1]), 0);
     memory_region_add_subregion(&s->container, 0x4002f000, mr);
 
-    dev_apb_ppc1 = DEVICE(&s->apb_ppc1);
+    dev_apb_ppc1 = DEVICE(&s->apb_ppc[1]);
     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_nonsec", 0,
                                 qdev_get_gpio_in_named(dev_apb_ppc1,
                                                        "cfg_nonsec", 0));
@@ -1063,7 +1067,7 @@ static void armsse_realize(DeviceState *dev, Error **errp)
         DeviceState *devs = DEVICE(&s->ppc_irq_splitter[i]);
         char *gpioname = g_strdup_printf("apb_ppc%d_irq_status",
                                          i - NUM_EXTERNAL_PPCS);
-        TZPPC *ppc = (i == NUM_EXTERNAL_PPCS) ? &s->apb_ppc0 : &s->apb_ppc1;
+        TZPPC *ppc = &s->apb_ppc[i - NUM_EXTERNAL_PPCS];
 
         qdev_connect_gpio_out(devs, 0,
                               qdev_get_gpio_in_named(dev_secctl, gpioname, 0));
-- 
2.20.1



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

* [PATCH 22/44] hw/arm/armsse: Add a define for number of IRQs used by the SSE itself
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (20 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 21/44] hw/arm/armsse: Use an array for apb_ppc fields in the state structure Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-02-21 13:34   ` Philippe Mathieu-Daudé
  2021-03-04 20:04   ` Richard Henderson
  2021-02-19 14:45 ` [PATCH 23/44] hw/arm/armsse: Add framework for data-driven device placement Peter Maydell
                   ` (23 subsequent siblings)
  45 siblings, 2 replies; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The SSE uses 32 interrupts for its own devices, and then passes through
its expansion IRQ inputs to the CPU's interrupts 33 and upward.
Add a define for the number of IRQs the SSE uses for itself, instead
of hardcoding 32.

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

diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
index 771150b0a94..e34263fed8b 100644
--- a/include/hw/arm/armsse.h
+++ b/include/hw/arm/armsse.h
@@ -145,6 +145,9 @@ OBJECT_DECLARE_TYPE(ARMSSE, ARMSSEClass,
 #define RAM3_PPU 6
 #define NUM_PPUS 7
 
+/* Number of CPU IRQs used by the SSE itself */
+#define NUM_SSE_IRQS 32
+
 struct ARMSSE {
     /*< private >*/
     SysBusDevice parent_obj;
@@ -165,7 +168,7 @@ struct ARMSSE {
     qemu_or_irq mpc_irq_orgate;
     qemu_or_irq nmi_orgate;
 
-    SplitIRQ cpu_irq_splitter[32];
+    SplitIRQ cpu_irq_splitter[NUM_SSE_IRQS];
 
     CMSDKAPBDualTimer dualtimer;
 
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index 2b25fca1ca2..5ae6ce344ee 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -531,7 +531,7 @@ static void armsse_realize(DeviceState *dev, Error **errp)
         int j;
         char *gpioname;
 
-        qdev_prop_set_uint32(cpudev, "num-irq", s->exp_numirq + 32);
+        qdev_prop_set_uint32(cpudev, "num-irq", s->exp_numirq + NUM_SSE_IRQS);
         /*
          * In real hardware the initial Secure VTOR is set from the INITSVTOR*
          * registers in the IoT Kit System Control Register block. In QEMU
@@ -602,7 +602,7 @@ static void armsse_realize(DeviceState *dev, Error **errp)
         /* Connect EXP_IRQ/EXP_CPUn_IRQ GPIOs to the NVIC's lines 32 and up */
         s->exp_irqs[i] = g_new(qemu_irq, s->exp_numirq);
         for (j = 0; j < s->exp_numirq; j++) {
-            s->exp_irqs[i][j] = qdev_get_gpio_in(cpudev, j + 32);
+            s->exp_irqs[i][j] = qdev_get_gpio_in(cpudev, j + NUM_SSE_IRQS);
         }
         if (i == 0) {
             gpioname = g_strdup("EXP_IRQ");
-- 
2.20.1



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

* [PATCH 23/44] hw/arm/armsse: Add framework for data-driven device placement
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (21 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 22/44] hw/arm/armsse: Add a define for number of IRQs used by the SSE itself Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-03-04 20:10   ` Richard Henderson
  2021-02-19 14:45 ` [PATCH 24/44] hw/arm/armsse: Move dual-timer device into data-driven framework Peter Maydell
                   ` (22 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The SSE-300 is mostly the same as the SSE-200, but it has moved some
of the devices in the memory map and uses different device types in
some cases.  To accommodate this, add a framework where the placement
and wiring of some devices can be specified in a data table.

This commit adds the framework for this data-driven device placement,
and makes the CMSDK APB timer devices use it.  Subsequent commits
will convert the other devices which differ between SSE-200 and
SSE-300.

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

diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
index e34263fed8b..c1f4df295a4 100644
--- a/include/hw/arm/armsse.h
+++ b/include/hw/arm/armsse.h
@@ -158,8 +158,7 @@ struct ARMSSE {
     IoTKitSecCtl secctl;
     TZPPC apb_ppc[NUM_INTERNAL_PPCS];
     TZMPC mpc[IOTS_NUM_MPC];
-    CMSDKAPBTimer timer0;
-    CMSDKAPBTimer timer1;
+    CMSDKAPBTimer timer[2];
     CMSDKAPBTimer s32ktimer;
     qemu_or_irq ppc_irq_orgate;
     SplitIRQ sec_resp_splitter;
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index 5ae6ce344ee..22dd437a4ba 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -24,6 +24,27 @@
 #include "hw/irq.h"
 #include "hw/qdev-clock.h"
 
+/*
+ * The SSE-300 puts some devices in different places to the
+ * SSE-200 (and original IoTKit). We use an array of these structs
+ * to define how each variant lays out these devices. (Parts of the
+ * SoC that are the same for all variants aren't handled via these
+ * data structures.)
+ */
+
+#define NO_IRQ -1
+#define NO_PPC -1
+
+typedef struct ARMSSEDeviceInfo {
+    const char *name; /* name to use for the QOM object; NULL terminates list */
+    const char *type; /* QOM type name */
+    unsigned int index; /* Which of the N devices of this type is this ? */
+    hwaddr addr;
+    int ppc; /* Index of APB PPC this device is wired up to, or NO_PPC */
+    int ppc_port; /* Port number of this device on the PPC */
+    int irq; /* NO_IRQ, or 0..NUM_SSE_IRQS-1 */
+} ARMSSEDeviceInfo;
+
 struct ARMSSEInfo {
     const char *name;
     uint32_t sse_version;
@@ -38,6 +59,7 @@ struct ARMSSEInfo {
     bool has_cpusecctrl;
     bool has_cpuid;
     Property *props;
+    const ARMSSEDeviceInfo *devinfo;
 };
 
 static Property iotkit_properties[] = {
@@ -64,6 +86,30 @@ static Property armsse_properties[] = {
     DEFINE_PROP_END_OF_LIST()
 };
 
+static const ARMSSEDeviceInfo sse200_devices[] = {
+    {
+        .name = "timer0",
+        .type = TYPE_CMSDK_APB_TIMER,
+        .index = 0,
+        .addr = 0x40000000,
+        .ppc = 0,
+        .ppc_port = 0,
+        .irq = 3,
+    },
+    {
+        .name = "timer1",
+        .type = TYPE_CMSDK_APB_TIMER,
+        .index = 1,
+        .addr = 0x40001000,
+        .ppc = 0,
+        .ppc_port = 1,
+        .irq = 4,
+    },
+    {
+        .name = NULL,
+    }
+};
+
 static const ARMSSEInfo armsse_variants[] = {
     {
         .name = TYPE_IOTKIT,
@@ -79,6 +125,7 @@ static const ARMSSEInfo armsse_variants[] = {
         .has_cpusecctrl = false,
         .has_cpuid = false,
         .props = iotkit_properties,
+        .devinfo = sse200_devices,
     },
     {
         .name = TYPE_SSE200,
@@ -94,6 +141,7 @@ static const ARMSSEInfo armsse_variants[] = {
         .has_cpusecctrl = true,
         .has_cpuid = true,
         .props = armsse_properties,
+        .devinfo = sse200_devices,
     },
 };
 
@@ -250,6 +298,7 @@ static void armsse_init(Object *obj)
     ARMSSE *s = ARM_SSE(obj);
     ARMSSEClass *asc = ARM_SSE_GET_CLASS(obj);
     const ARMSSEInfo *info = asc->info;
+    const ARMSSEDeviceInfo *devinfo;
     int i;
 
     assert(info->sram_banks <= MAX_SRAM_BANKS);
@@ -290,6 +339,18 @@ static void armsse_init(Object *obj)
         }
     }
 
+    for (devinfo = info->devinfo; devinfo->name; devinfo++) {
+        assert(devinfo->ppc == NO_PPC || devinfo->ppc < ARRAY_SIZE(s->apb_ppc));
+        if (!strcmp(devinfo->type, TYPE_CMSDK_APB_TIMER)) {
+            assert(devinfo->index < ARRAY_SIZE(s->timer));
+            object_initialize_child(obj, devinfo->name,
+                                    &s->timer[devinfo->index],
+                                    TYPE_CMSDK_APB_TIMER);
+        } else {
+            g_assert_not_reached();
+        }
+    }
+
     object_initialize_child(obj, "secctl", &s->secctl, TYPE_IOTKIT_SECCTL);
 
     for (i = 0; i < ARRAY_SIZE(s->apb_ppc); i++) {
@@ -312,8 +373,6 @@ static void armsse_init(Object *obj)
         object_initialize_child(obj, name, splitter, TYPE_SPLIT_IRQ);
         g_free(name);
     }
-    object_initialize_child(obj, "timer0", &s->timer0, TYPE_CMSDK_APB_TIMER);
-    object_initialize_child(obj, "timer1", &s->timer1, TYPE_CMSDK_APB_TIMER);
     object_initialize_child(obj, "s32ktimer", &s->s32ktimer,
                             TYPE_CMSDK_APB_TIMER);
     object_initialize_child(obj, "dualtimer", &s->dualtimer,
@@ -453,6 +512,7 @@ static void armsse_realize(DeviceState *dev, Error **errp)
     ARMSSE *s = ARM_SSE(dev);
     ARMSSEClass *asc = ARM_SSE_GET_CLASS(dev);
     const ARMSSEInfo *info = asc->info;
+    const ARMSSEDeviceInfo *devinfo;
     int i;
     MemoryRegion *mr;
     Error *err = NULL;
@@ -736,25 +796,53 @@ static void armsse_realize(DeviceState *dev, Error **errp)
      * it to the appropriate PPC port; then we can realize the PPC and
      * map its upstream ends to the right place in the container.
      */
-    qdev_connect_clock_in(DEVICE(&s->timer0), "pclk", s->mainclk);
-    if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer0), errp)) {
-        return;
-    }
-    sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer0), 0,
-                       armsse_get_common_irq_in(s, 3));
-    mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer0), 0);
-    object_property_set_link(OBJECT(&s->apb_ppc[0]), "port[0]", OBJECT(mr),
-                             &error_abort);
+    for (devinfo = info->devinfo; devinfo->name; devinfo++) {
+        SysBusDevice *sbd;
+        qemu_irq irq;
 
-    qdev_connect_clock_in(DEVICE(&s->timer1), "pclk", s->mainclk);
-    if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer1), errp)) {
-        return;
+        if (!strcmp(devinfo->type, TYPE_CMSDK_APB_TIMER)) {
+            sbd = SYS_BUS_DEVICE(&s->timer[devinfo->index]);
+
+            qdev_connect_clock_in(DEVICE(sbd), "pclk", s->mainclk);
+            if (!sysbus_realize(sbd, errp)) {
+                return;
+            }
+            mr = sysbus_mmio_get_region(sbd, 0);
+        } else {
+            g_assert_not_reached();
+        }
+
+        switch (devinfo->irq) {
+        case NO_IRQ:
+            irq = NULL;
+            break;
+        case 0 ... NUM_SSE_IRQS - 1:
+            irq = armsse_get_common_irq_in(s, devinfo->irq);
+            break;
+        default:
+            g_assert_not_reached();
+        }
+
+        if (irq) {
+            sysbus_connect_irq(sbd, 0, irq);
+        }
+
+        /*
+         * Devices connected to a PPC are connected to the port here;
+         * we will map the upstream end of that port to the right address
+         * in the container later after the PPC has been realized.
+         * Devices not connected to a PPC can be mapped immediately.
+         */
+        if (devinfo->ppc != NO_PPC) {
+            TZPPC *ppc = &s->apb_ppc[devinfo->ppc];
+            g_autofree char *portname = g_strdup_printf("port[%d]",
+                                                        devinfo->ppc_port);
+            object_property_set_link(OBJECT(ppc), portname, OBJECT(mr),
+                                     &error_abort);
+        } else {
+            memory_region_add_subregion(&s->container, devinfo->addr, mr);
+        }
     }
-    sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer1), 0,
-                       armsse_get_common_irq_in(s, 4));
-    mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer1), 0);
-    object_property_set_link(OBJECT(&s->apb_ppc[0]), "port[1]", OBJECT(mr),
-                             &error_abort);
 
     qdev_connect_clock_in(DEVICE(&s->dualtimer), "TIMCLK", s->mainclk);
     if (!sysbus_realize(SYS_BUS_DEVICE(&s->dualtimer), errp)) {
@@ -813,10 +901,6 @@ static void armsse_realize(DeviceState *dev, Error **errp)
     sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc[0]);
     dev_apb_ppc0 = DEVICE(&s->apb_ppc[0]);
 
-    mr = sysbus_mmio_get_region(sbd_apb_ppc0, 0);
-    memory_region_add_subregion(&s->container, 0x40000000, mr);
-    mr = sysbus_mmio_get_region(sbd_apb_ppc0, 1);
-    memory_region_add_subregion(&s->container, 0x40001000, mr);
     mr = sysbus_mmio_get_region(sbd_apb_ppc0, 2);
     memory_region_add_subregion(&s->container, 0x40002000, mr);
     if (info->has_mhus) {
@@ -947,6 +1031,23 @@ static void armsse_realize(DeviceState *dev, Error **errp)
                           qdev_get_gpio_in_named(dev_apb_ppc1,
                                                  "cfg_sec_resp", 0));
 
+    /*
+     * Now both PPCs are realized we can map the upstream ends of
+     * ports which correspond to entries in the devinfo array.
+     * The ports which are connected to non-devinfo devices have
+     * already been mapped.
+     */
+    for (devinfo = info->devinfo; devinfo->name; devinfo++) {
+        SysBusDevice *ppc_sbd;
+
+        if (devinfo->ppc == NO_PPC) {
+            continue;
+        }
+        ppc_sbd = SYS_BUS_DEVICE(&s->apb_ppc[devinfo->ppc]);
+        mr = sysbus_mmio_get_region(ppc_sbd, devinfo->ppc_port);
+        memory_region_add_subregion(&s->container, devinfo->addr, mr);
+    }
+
     if (!object_property_set_int(OBJECT(&s->sysinfo), "SYS_VERSION",
                                  info->sys_version, errp)) {
         return;
-- 
2.20.1



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

* [PATCH 24/44] hw/arm/armsse: Move dual-timer device into data-driven framework
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (22 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 23/44] hw/arm/armsse: Add framework for data-driven device placement Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-03-04 20:12   ` Richard Henderson
  2021-02-19 14:45 ` [PATCH 25/44] hw/arm/armsse: Move watchdogs " Peter Maydell
                   ` (21 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Move the CMSDK dualtimer device handling into the data-driven
device placement framework.

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

diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index 22dd437a4ba..f8da7fb00f9 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -105,6 +105,15 @@ static const ARMSSEDeviceInfo sse200_devices[] = {
         .ppc_port = 1,
         .irq = 4,
     },
+    {
+        .name = "dualtimer",
+        .type = TYPE_CMSDK_APB_DUALTIMER,
+        .index = 0,
+        .addr = 0x40002000,
+        .ppc = 0,
+        .ppc_port = 2,
+        .irq = 5,
+    },
     {
         .name = NULL,
     }
@@ -346,6 +355,10 @@ static void armsse_init(Object *obj)
             object_initialize_child(obj, devinfo->name,
                                     &s->timer[devinfo->index],
                                     TYPE_CMSDK_APB_TIMER);
+        } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_DUALTIMER)) {
+            assert(devinfo->index == 0);
+            object_initialize_child(obj, devinfo->name, &s->dualtimer,
+                                    TYPE_CMSDK_APB_DUALTIMER);
         } else {
             g_assert_not_reached();
         }
@@ -375,8 +388,6 @@ static void armsse_init(Object *obj)
     }
     object_initialize_child(obj, "s32ktimer", &s->s32ktimer,
                             TYPE_CMSDK_APB_TIMER);
-    object_initialize_child(obj, "dualtimer", &s->dualtimer,
-                            TYPE_CMSDK_APB_DUALTIMER);
     object_initialize_child(obj, "s32kwatchdog", &s->s32kwatchdog,
                             TYPE_CMSDK_APB_WATCHDOG);
     object_initialize_child(obj, "nswatchdog", &s->nswatchdog,
@@ -808,6 +819,14 @@ static void armsse_realize(DeviceState *dev, Error **errp)
                 return;
             }
             mr = sysbus_mmio_get_region(sbd, 0);
+        } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_DUALTIMER)) {
+            sbd = SYS_BUS_DEVICE(&s->dualtimer);
+
+            qdev_connect_clock_in(DEVICE(sbd), "TIMCLK", s->mainclk);
+            if (!sysbus_realize(sbd, errp)) {
+                return;
+            }
+            mr = sysbus_mmio_get_region(sbd, 0);
         } else {
             g_assert_not_reached();
         }
@@ -844,16 +863,6 @@ static void armsse_realize(DeviceState *dev, Error **errp)
         }
     }
 
-    qdev_connect_clock_in(DEVICE(&s->dualtimer), "TIMCLK", s->mainclk);
-    if (!sysbus_realize(SYS_BUS_DEVICE(&s->dualtimer), errp)) {
-        return;
-    }
-    sysbus_connect_irq(SYS_BUS_DEVICE(&s->dualtimer), 0,
-                       armsse_get_common_irq_in(s, 5));
-    mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dualtimer), 0);
-    object_property_set_link(OBJECT(&s->apb_ppc[0]), "port[2]", OBJECT(mr),
-                             &error_abort);
-
     if (info->has_mhus) {
         /*
          * An SSE-200 with only one CPU should have only one MHU created,
@@ -901,8 +910,6 @@ static void armsse_realize(DeviceState *dev, Error **errp)
     sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc[0]);
     dev_apb_ppc0 = DEVICE(&s->apb_ppc[0]);
 
-    mr = sysbus_mmio_get_region(sbd_apb_ppc0, 2);
-    memory_region_add_subregion(&s->container, 0x40002000, mr);
     if (info->has_mhus) {
         mr = sysbus_mmio_get_region(sbd_apb_ppc0, 3);
         memory_region_add_subregion(&s->container, 0x40003000, mr);
-- 
2.20.1



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

* [PATCH 25/44] hw/arm/armsse: Move watchdogs into data-driven framework
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (23 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 24/44] hw/arm/armsse: Move dual-timer device into data-driven framework Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-03-04 20:15   ` Richard Henderson
  2021-02-19 14:45 ` [PATCH 26/44] hw/arm/armsse: Move s32ktimer " Peter Maydell
                   ` (20 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Move the CMSDK watchdog device handling into the data-driven device
placement framework.  This is slightly more complicated because these
devices might wire their IRQs up to the NMI line, and because one of
them uses the slow 32KHz clock rather than the main clock.

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

diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
index c1f4df295a4..3f8f3750577 100644
--- a/include/hw/arm/armsse.h
+++ b/include/hw/arm/armsse.h
@@ -171,9 +171,7 @@ struct ARMSSE {
 
     CMSDKAPBDualTimer dualtimer;
 
-    CMSDKAPBWatchdog s32kwatchdog;
-    CMSDKAPBWatchdog nswatchdog;
-    CMSDKAPBWatchdog swatchdog;
+    CMSDKAPBWatchdog cmsdk_watchdog[3];
 
     IoTKitSysCtl sysctl;
     IoTKitSysCtl sysinfo;
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index f8da7fb00f9..6540ffb919b 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -34,6 +34,13 @@
 
 #define NO_IRQ -1
 #define NO_PPC -1
+/*
+ * Special values for ARMSSEDeviceInfo::irq to indicate that this
+ * device uses one of the inputs to the OR gate that feeds into the
+ * CPU NMI input.
+ */
+#define NMI_0 10000
+#define NMI_1 10001
 
 typedef struct ARMSSEDeviceInfo {
     const char *name; /* name to use for the QOM object; NULL terminates list */
@@ -42,7 +49,8 @@ typedef struct ARMSSEDeviceInfo {
     hwaddr addr;
     int ppc; /* Index of APB PPC this device is wired up to, or NO_PPC */
     int ppc_port; /* Port number of this device on the PPC */
-    int irq; /* NO_IRQ, or 0..NUM_SSE_IRQS-1 */
+    int irq; /* NO_IRQ, or 0..NUM_SSE_IRQS-1, or NMI_0 or NMI_1 */
+    bool slowclk; /* true if device uses the slow 32KHz clock */
 } ARMSSEDeviceInfo;
 
 struct ARMSSEInfo {
@@ -114,6 +122,31 @@ static const ARMSSEDeviceInfo sse200_devices[] = {
         .ppc_port = 2,
         .irq = 5,
     },
+    {
+        .name = "s32kwatchdog",
+        .type = TYPE_CMSDK_APB_WATCHDOG,
+        .index = 0,
+        .addr = 0x5002e000,
+        .ppc = NO_PPC,
+        .irq = NMI_0,
+        .slowclk = true,
+    },
+    {
+        .name = "nswatchdog",
+        .type = TYPE_CMSDK_APB_WATCHDOG,
+        .index = 1,
+        .addr = 0x40081000,
+        .ppc = NO_PPC,
+        .irq = 1,
+    },
+    {
+        .name = "swatchdog",
+        .type = TYPE_CMSDK_APB_WATCHDOG,
+        .index = 2,
+        .addr = 0x50081000,
+        .ppc = NO_PPC,
+        .irq = NMI_1,
+    },
     {
         .name = NULL,
     }
@@ -359,6 +392,11 @@ static void armsse_init(Object *obj)
             assert(devinfo->index == 0);
             object_initialize_child(obj, devinfo->name, &s->dualtimer,
                                     TYPE_CMSDK_APB_DUALTIMER);
+        } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_WATCHDOG)) {
+            assert(devinfo->index < ARRAY_SIZE(s->cmsdk_watchdog));
+            object_initialize_child(obj, devinfo->name,
+                                    &s->cmsdk_watchdog[devinfo->index],
+                                    TYPE_CMSDK_APB_WATCHDOG);
         } else {
             g_assert_not_reached();
         }
@@ -386,14 +424,9 @@ static void armsse_init(Object *obj)
         object_initialize_child(obj, name, splitter, TYPE_SPLIT_IRQ);
         g_free(name);
     }
+
     object_initialize_child(obj, "s32ktimer", &s->s32ktimer,
                             TYPE_CMSDK_APB_TIMER);
-    object_initialize_child(obj, "s32kwatchdog", &s->s32kwatchdog,
-                            TYPE_CMSDK_APB_WATCHDOG);
-    object_initialize_child(obj, "nswatchdog", &s->nswatchdog,
-                            TYPE_CMSDK_APB_WATCHDOG);
-    object_initialize_child(obj, "swatchdog", &s->swatchdog,
-                            TYPE_CMSDK_APB_WATCHDOG);
     object_initialize_child(obj, "armsse-sysctl", &s->sysctl,
                             TYPE_IOTKIT_SYSCTL);
     object_initialize_child(obj, "armsse-sysinfo", &s->sysinfo,
@@ -797,6 +830,17 @@ static void armsse_realize(DeviceState *dev, Error **errp)
     qdev_connect_gpio_out(DEVICE(&s->mpc_irq_orgate), 0,
                           armsse_get_common_irq_in(s, 9));
 
+    /* This OR gate wires together outputs from the secure watchdogs to NMI */
+    if (!object_property_set_int(OBJECT(&s->nmi_orgate), "num-lines", 2,
+                                 errp)) {
+        return;
+    }
+    if (!qdev_realize(DEVICE(&s->nmi_orgate), NULL, errp)) {
+        return;
+    }
+    qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
+                          qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
+
     /* Devices behind APB PPC0:
      *   0x40000000: timer0
      *   0x40001000: timer1
@@ -827,6 +871,15 @@ static void armsse_realize(DeviceState *dev, Error **errp)
                 return;
             }
             mr = sysbus_mmio_get_region(sbd, 0);
+        } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_WATCHDOG)) {
+            sbd = SYS_BUS_DEVICE(&s->cmsdk_watchdog[devinfo->index]);
+
+            qdev_connect_clock_in(DEVICE(sbd), "WDOGCLK",
+                                  devinfo->slowclk ? s->s32kclk : s->mainclk);
+            if (!sysbus_realize(sbd, errp)) {
+                return;
+            }
+            mr = sysbus_mmio_get_region(sbd, 0);
         } else {
             g_assert_not_reached();
         }
@@ -838,6 +891,11 @@ static void armsse_realize(DeviceState *dev, Error **errp)
         case 0 ... NUM_SSE_IRQS - 1:
             irq = armsse_get_common_irq_in(s, devinfo->irq);
             break;
+        case NMI_0:
+        case NMI_1:
+            irq = qdev_get_gpio_in(DEVICE(&s->nmi_orgate),
+                                   devinfo->irq - NMI_0);
+            break;
         default:
             g_assert_not_reached();
         }
@@ -1108,43 +1166,6 @@ static void armsse_realize(DeviceState *dev, Error **errp)
         }
     }
 
-    /* This OR gate wires together outputs from the secure watchdogs to NMI */
-    if (!object_property_set_int(OBJECT(&s->nmi_orgate), "num-lines", 2,
-                                 errp)) {
-        return;
-    }
-    if (!qdev_realize(DEVICE(&s->nmi_orgate), NULL, errp)) {
-        return;
-    }
-    qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
-                          qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
-
-    qdev_connect_clock_in(DEVICE(&s->s32kwatchdog), "WDOGCLK", s->s32kclk);
-    if (!sysbus_realize(SYS_BUS_DEVICE(&s->s32kwatchdog), errp)) {
-        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 : ARMSSE second Base peripheral region */
-
-    qdev_connect_clock_in(DEVICE(&s->nswatchdog), "WDOGCLK", s->mainclk);
-    if (!sysbus_realize(SYS_BUS_DEVICE(&s->nswatchdog), errp)) {
-        return;
-    }
-    sysbus_connect_irq(SYS_BUS_DEVICE(&s->nswatchdog), 0,
-                       armsse_get_common_irq_in(s, 1));
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->nswatchdog), 0, 0x40081000);
-
-    qdev_connect_clock_in(DEVICE(&s->swatchdog), "WDOGCLK", s->mainclk);
-    if (!sysbus_realize(SYS_BUS_DEVICE(&s->swatchdog), errp)) {
-        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.20.1



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

* [PATCH 26/44] hw/arm/armsse: Move s32ktimer into data-driven framework
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (24 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 25/44] hw/arm/armsse: Move watchdogs " Peter Maydell
@ 2021-02-19 14:45 ` Peter Maydell
  2021-03-04 20:16   ` Richard Henderson
  2021-02-19 14:46 ` [PATCH 27/44] hw/arm/armsse: Move sysinfo register block " Peter Maydell
                   ` (19 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:45 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Move the CMSDK timer that uses the S32K slow clock into the data-driven
device placement framework.

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

diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
index 3f8f3750577..7416c08a802 100644
--- a/include/hw/arm/armsse.h
+++ b/include/hw/arm/armsse.h
@@ -158,8 +158,7 @@ struct ARMSSE {
     IoTKitSecCtl secctl;
     TZPPC apb_ppc[NUM_INTERNAL_PPCS];
     TZMPC mpc[IOTS_NUM_MPC];
-    CMSDKAPBTimer timer[2];
-    CMSDKAPBTimer s32ktimer;
+    CMSDKAPBTimer timer[3];
     qemu_or_irq ppc_irq_orgate;
     SplitIRQ sec_resp_splitter;
     SplitIRQ ppc_irq_splitter[NUM_PPCS];
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index 6540ffb919b..3270362d599 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -113,6 +113,16 @@ static const ARMSSEDeviceInfo sse200_devices[] = {
         .ppc_port = 1,
         .irq = 4,
     },
+    {
+        .name = "s32ktimer",
+        .type = TYPE_CMSDK_APB_TIMER,
+        .index = 2,
+        .addr = 0x4002f000,
+        .ppc = 1,
+        .ppc_port = 0,
+        .irq = 2,
+        .slowclk = true,
+    },
     {
         .name = "dualtimer",
         .type = TYPE_CMSDK_APB_DUALTIMER,
@@ -425,8 +435,6 @@ static void armsse_init(Object *obj)
         g_free(name);
     }
 
-    object_initialize_child(obj, "s32ktimer", &s->s32ktimer,
-                            TYPE_CMSDK_APB_TIMER);
     object_initialize_child(obj, "armsse-sysctl", &s->sysctl,
                             TYPE_IOTKIT_SYSCTL);
     object_initialize_child(obj, "armsse-sysinfo", &s->sysinfo,
@@ -858,7 +866,8 @@ static void armsse_realize(DeviceState *dev, Error **errp)
         if (!strcmp(devinfo->type, TYPE_CMSDK_APB_TIMER)) {
             sbd = SYS_BUS_DEVICE(&s->timer[devinfo->index]);
 
-            qdev_connect_clock_in(DEVICE(sbd), "pclk", s->mainclk);
+            qdev_connect_clock_in(DEVICE(sbd), "pclk",
+                                  devinfo->slowclk ? s->s32kclk : s->mainclk);
             if (!sysbus_realize(sbd, errp)) {
                 return;
             }
@@ -1059,25 +1068,9 @@ static void armsse_realize(DeviceState *dev, Error **errp)
         }
     }
 
-    /* 0x40020000 .. 0x4002ffff : ARMSSE system control peripheral region */
-    /* Devices behind APB PPC1:
-     *   0x4002f000: S32K timer
-     */
-    qdev_connect_clock_in(DEVICE(&s->s32ktimer), "pclk", s->s32kclk);
-    if (!sysbus_realize(SYS_BUS_DEVICE(&s->s32ktimer), errp)) {
-        return;
-    }
-    sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32ktimer), 0,
-                       armsse_get_common_irq_in(s, 2));
-    mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->s32ktimer), 0);
-    object_property_set_link(OBJECT(&s->apb_ppc[1]), "port[0]", OBJECT(mr),
-                             &error_abort);
-
     if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc[1]), errp)) {
         return;
     }
-    mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->apb_ppc[1]), 0);
-    memory_region_add_subregion(&s->container, 0x4002f000, mr);
 
     dev_apb_ppc1 = DEVICE(&s->apb_ppc[1]);
     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_nonsec", 0,
-- 
2.20.1



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

* [PATCH 27/44] hw/arm/armsse: Move sysinfo register block into data-driven framework
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (25 preceding siblings ...)
  2021-02-19 14:45 ` [PATCH 26/44] hw/arm/armsse: Move s32ktimer " Peter Maydell
@ 2021-02-19 14:46 ` Peter Maydell
  2021-03-04 20:19   ` Richard Henderson
  2021-02-19 14:46 ` [PATCH 28/44] hw/arm/armsse: Move sysctl " Peter Maydell
                   ` (18 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:46 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Move the sysinfo register block into the data-driven framework.

While we are moving the code for configuring this device around,
regularize on using &error_abortw when setting the integer
properties: they are all simple DEFINE_PROP_UINT32 properties so the
setting can never fail.

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

diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index 3270362d599..91f30b1fdc4 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -157,6 +157,14 @@ static const ARMSSEDeviceInfo sse200_devices[] = {
         .ppc = NO_PPC,
         .irq = NMI_1,
     },
+    {
+        .name = "armsse-sysinfo",
+        .type = TYPE_IOTKIT_SYSINFO,
+        .index = 0,
+        .addr = 0x40020000,
+        .ppc = NO_PPC,
+        .irq = NO_IRQ,
+    },
     {
         .name = NULL,
     }
@@ -407,6 +415,10 @@ static void armsse_init(Object *obj)
             object_initialize_child(obj, devinfo->name,
                                     &s->cmsdk_watchdog[devinfo->index],
                                     TYPE_CMSDK_APB_WATCHDOG);
+        } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSINFO)) {
+            assert(devinfo->index == 0);
+            object_initialize_child(obj, devinfo->name, &s->sysinfo,
+                                    TYPE_IOTKIT_SYSINFO);
         } else {
             g_assert_not_reached();
         }
@@ -437,8 +449,6 @@ static void armsse_init(Object *obj)
 
     object_initialize_child(obj, "armsse-sysctl", &s->sysctl,
                             TYPE_IOTKIT_SYSCTL);
-    object_initialize_child(obj, "armsse-sysinfo", &s->sysinfo,
-                            TYPE_IOTKIT_SYSINFO);
     if (info->has_mhus) {
         object_initialize_child(obj, "mhu0", &s->mhu[0], TYPE_ARMSSE_MHU);
         object_initialize_child(obj, "mhu1", &s->mhu[1], TYPE_ARMSSE_MHU);
@@ -889,6 +899,22 @@ static void armsse_realize(DeviceState *dev, Error **errp)
                 return;
             }
             mr = sysbus_mmio_get_region(sbd, 0);
+        } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSINFO)) {
+            sbd = SYS_BUS_DEVICE(&s->sysinfo);
+
+            object_property_set_int(OBJECT(&s->sysinfo), "SYS_VERSION",
+                                    info->sys_version, &error_abort);
+            object_property_set_int(OBJECT(&s->sysinfo), "SYS_CONFIG",
+                                    armsse_sys_config_value(s, info),
+                                    &error_abort);
+            object_property_set_int(OBJECT(&s->sysinfo), "sse-version",
+                                    info->sse_version, &error_abort);
+            object_property_set_int(OBJECT(&s->sysinfo), "IIDR",
+                                    info->iidr, &error_abort);
+            if (!sysbus_realize(sbd, errp)) {
+                return;
+            }
+            mr = sysbus_mmio_get_region(sbd, 0);
         } else {
             g_assert_not_reached();
         }
@@ -1106,23 +1132,6 @@ static void armsse_realize(DeviceState *dev, Error **errp)
         memory_region_add_subregion(&s->container, devinfo->addr, mr);
     }
 
-    if (!object_property_set_int(OBJECT(&s->sysinfo), "SYS_VERSION",
-                                 info->sys_version, errp)) {
-        return;
-    }
-    if (!object_property_set_int(OBJECT(&s->sysinfo), "SYS_CONFIG",
-                                 armsse_sys_config_value(s, info), errp)) {
-        return;
-    }
-    object_property_set_int(OBJECT(&s->sysinfo), "sse-version",
-                            info->sse_version, &error_abort);
-    object_property_set_int(OBJECT(&s->sysinfo), "IIDR",
-                            info->iidr, &error_abort);
-    if (!sysbus_realize(SYS_BUS_DEVICE(&s->sysinfo), errp)) {
-        return;
-    }
-    /* System information registers */
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysinfo), 0, 0x40020000);
     /* System control registers */
     object_property_set_int(OBJECT(&s->sysctl), "sse-version",
                             info->sse_version, &error_abort);
-- 
2.20.1



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

* [PATCH 28/44] hw/arm/armsse: Move sysctl register block into data-driven framework
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (26 preceding siblings ...)
  2021-02-19 14:46 ` [PATCH 27/44] hw/arm/armsse: Move sysinfo register block " Peter Maydell
@ 2021-02-19 14:46 ` Peter Maydell
  2021-03-04 20:21   ` Richard Henderson
  2021-02-19 14:46 ` [PATCH 29/44] hw/arm/armsse: Move PPUs " Peter Maydell
                   ` (17 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:46 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Move the sysctl register block into the data-driven device placement
framework.

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

diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index 91f30b1fdc4..961b2d44137 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -165,6 +165,14 @@ static const ARMSSEDeviceInfo sse200_devices[] = {
         .ppc = NO_PPC,
         .irq = NO_IRQ,
     },
+    {
+        .name = "armsse-sysctl",
+        .type = TYPE_IOTKIT_SYSCTL,
+        .index = 0,
+        .addr = 0x50021000,
+        .ppc = NO_PPC,
+        .irq = NO_IRQ,
+    },
     {
         .name = NULL,
     }
@@ -419,6 +427,10 @@ static void armsse_init(Object *obj)
             assert(devinfo->index == 0);
             object_initialize_child(obj, devinfo->name, &s->sysinfo,
                                     TYPE_IOTKIT_SYSINFO);
+        } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSCTL)) {
+            assert(devinfo->index == 0);
+            object_initialize_child(obj, devinfo->name, &s->sysctl,
+                                    TYPE_IOTKIT_SYSCTL);
         } else {
             g_assert_not_reached();
         }
@@ -447,8 +459,6 @@ static void armsse_init(Object *obj)
         g_free(name);
     }
 
-    object_initialize_child(obj, "armsse-sysctl", &s->sysctl,
-                            TYPE_IOTKIT_SYSCTL);
     if (info->has_mhus) {
         object_initialize_child(obj, "mhu0", &s->mhu[0], TYPE_ARMSSE_MHU);
         object_initialize_child(obj, "mhu1", &s->mhu[1], TYPE_ARMSSE_MHU);
@@ -915,6 +925,22 @@ static void armsse_realize(DeviceState *dev, Error **errp)
                 return;
             }
             mr = sysbus_mmio_get_region(sbd, 0);
+        } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSCTL)) {
+            /* System control registers */
+            sbd = SYS_BUS_DEVICE(&s->sysctl);
+
+            object_property_set_int(OBJECT(&s->sysctl), "sse-version",
+                                    info->sse_version, &error_abort);
+            object_property_set_int(OBJECT(&s->sysctl), "CPUWAIT_RST",
+                                    info->cpuwait_rst, &error_abort);
+            object_property_set_int(OBJECT(&s->sysctl), "INITSVTOR0_RST",
+                                    s->init_svtor, &error_abort);
+            object_property_set_int(OBJECT(&s->sysctl), "INITSVTOR1_RST",
+                                    s->init_svtor, &error_abort);
+            if (!sysbus_realize(sbd, errp)) {
+                return;
+            }
+            mr = sysbus_mmio_get_region(sbd, 0);
         } else {
             g_assert_not_reached();
         }
@@ -1132,20 +1158,6 @@ static void armsse_realize(DeviceState *dev, Error **errp)
         memory_region_add_subregion(&s->container, devinfo->addr, mr);
     }
 
-    /* System control registers */
-    object_property_set_int(OBJECT(&s->sysctl), "sse-version",
-                            info->sse_version, &error_abort);
-    object_property_set_int(OBJECT(&s->sysctl), "CPUWAIT_RST",
-                            info->cpuwait_rst, &error_abort);
-    object_property_set_int(OBJECT(&s->sysctl), "INITSVTOR0_RST",
-                            s->init_svtor, &error_abort);
-    object_property_set_int(OBJECT(&s->sysctl), "INITSVTOR1_RST",
-                            s->init_svtor, &error_abort);
-    if (!sysbus_realize(SYS_BUS_DEVICE(&s->sysctl), errp)) {
-        return;
-    }
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysctl), 0, 0x50021000);
-
     if (info->has_ppus) {
         /* CPUnCORE_PPU for each CPU */
         for (i = 0; i < info->num_cpus; i++) {
-- 
2.20.1



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

* [PATCH 29/44] hw/arm/armsse: Move PPUs into data-driven framework
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (27 preceding siblings ...)
  2021-02-19 14:46 ` [PATCH 28/44] hw/arm/armsse: Move sysctl " Peter Maydell
@ 2021-02-19 14:46 ` Peter Maydell
  2021-03-04 20:24   ` Richard Henderson
  2021-02-19 14:46 ` [PATCH 30/44] hw/arm/armsse: Add missing SSE-200 SYS_PPU Peter Maydell
                   ` (16 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:46 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Move the PPUs into the data-driven device placement framework.
We don't implement them, so they are just TYPE_UNIMPLEMENTED stubs.

Because the SSE-200 and the IotKit diverge here (the IoTKit does
not have the PPUs) we need to separate out the ARMSSEDeviceInfo
for the two variants, and only add the PPUs to the SSE-200.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/arm/armsse.h |  10 +-
 hw/arm/armsse.c         | 222 +++++++++++++++++++++++++++++-----------
 2 files changed, 165 insertions(+), 67 deletions(-)

diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
index 7416c08a802..eb4e937173f 100644
--- a/include/hw/arm/armsse.h
+++ b/include/hw/arm/armsse.h
@@ -135,14 +135,6 @@ OBJECT_DECLARE_TYPE(ARMSSE, ARMSSEClass,
 
 #define SSE_MAX_CPUS 2
 
-/* These define what each PPU in the ppu[] index is for */
-#define CPU0CORE_PPU 0
-#define CPU1CORE_PPU 1
-#define DBG_PPU 2
-#define RAM0_PPU 3
-#define RAM1_PPU 4
-#define RAM2_PPU 5
-#define RAM3_PPU 6
 #define NUM_PPUS 7
 
 /* Number of CPU IRQs used by the SSE itself */
@@ -176,7 +168,7 @@ struct ARMSSE {
     IoTKitSysCtl sysinfo;
 
     ARMSSEMHU mhu[2];
-    UnimplementedDeviceState ppu[NUM_PPUS];
+    UnimplementedDeviceState unimp[NUM_PPUS];
     UnimplementedDeviceState cachectrl[SSE_MAX_CPUS];
     UnimplementedDeviceState cpusecctrl[SSE_MAX_CPUS];
 
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index 961b2d44137..f72d1adafea 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -47,6 +47,7 @@ typedef struct ARMSSEDeviceInfo {
     const char *type; /* QOM type name */
     unsigned int index; /* Which of the N devices of this type is this ? */
     hwaddr addr;
+    hwaddr size; /* only needed for TYPE_UNIMPLEMENTED_DEVICE */
     int ppc; /* Index of APB PPC this device is wired up to, or NO_PPC */
     int ppc_port; /* Port number of this device on the PPC */
     int irq; /* NO_IRQ, or 0..NUM_SSE_IRQS-1, or NMI_0 or NMI_1 */
@@ -62,7 +63,6 @@ struct ARMSSEInfo {
     uint32_t iidr;
     uint32_t cpuwait_rst;
     bool has_mhus;
-    bool has_ppus;
     bool has_cachectrl;
     bool has_cpusecctrl;
     bool has_cpuid;
@@ -94,7 +94,7 @@ static Property armsse_properties[] = {
     DEFINE_PROP_END_OF_LIST()
 };
 
-static const ARMSSEDeviceInfo sse200_devices[] = {
+static const ARMSSEDeviceInfo iotkit_devices[] = {
     {
         .name = "timer0",
         .type = TYPE_CMSDK_APB_TIMER,
@@ -178,6 +178,153 @@ static const ARMSSEDeviceInfo sse200_devices[] = {
     }
 };
 
+static const ARMSSEDeviceInfo sse200_devices[] = {
+    {
+        .name = "timer0",
+        .type = TYPE_CMSDK_APB_TIMER,
+        .index = 0,
+        .addr = 0x40000000,
+        .ppc = 0,
+        .ppc_port = 0,
+        .irq = 3,
+    },
+    {
+        .name = "timer1",
+        .type = TYPE_CMSDK_APB_TIMER,
+        .index = 1,
+        .addr = 0x40001000,
+        .ppc = 0,
+        .ppc_port = 1,
+        .irq = 4,
+    },
+    {
+        .name = "s32ktimer",
+        .type = TYPE_CMSDK_APB_TIMER,
+        .index = 2,
+        .addr = 0x4002f000,
+        .ppc = 1,
+        .ppc_port = 0,
+        .irq = 2,
+        .slowclk = true,
+    },
+    {
+        .name = "dualtimer",
+        .type = TYPE_CMSDK_APB_DUALTIMER,
+        .index = 0,
+        .addr = 0x40002000,
+        .ppc = 0,
+        .ppc_port = 2,
+        .irq = 5,
+    },
+    {
+        .name = "s32kwatchdog",
+        .type = TYPE_CMSDK_APB_WATCHDOG,
+        .index = 0,
+        .addr = 0x5002e000,
+        .ppc = NO_PPC,
+        .irq = NMI_0,
+        .slowclk = true,
+    },
+    {
+        .name = "nswatchdog",
+        .type = TYPE_CMSDK_APB_WATCHDOG,
+        .index = 1,
+        .addr = 0x40081000,
+        .ppc = NO_PPC,
+        .irq = 1,
+    },
+    {
+        .name = "swatchdog",
+        .type = TYPE_CMSDK_APB_WATCHDOG,
+        .index = 2,
+        .addr = 0x50081000,
+        .ppc = NO_PPC,
+        .irq = NMI_1,
+    },
+    {
+        .name = "armsse-sysinfo",
+        .type = TYPE_IOTKIT_SYSINFO,
+        .index = 0,
+        .addr = 0x40020000,
+        .ppc = NO_PPC,
+        .irq = NO_IRQ,
+    },
+    {
+        .name = "armsse-sysctl",
+        .type = TYPE_IOTKIT_SYSCTL,
+        .index = 0,
+        .addr = 0x50021000,
+        .ppc = NO_PPC,
+        .irq = NO_IRQ,
+    },
+    {
+        .name = "CPU0CORE_PPU",
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .index = 0,
+        .addr = 0x50023000,
+        .size = 0x1000,
+        .ppc = NO_PPC,
+        .irq = NO_IRQ,
+    },
+    {
+        .name = "CPU1CORE_PPU",
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .index = 1,
+        .addr = 0x50025000,
+        .size = 0x1000,
+        .ppc = NO_PPC,
+        .irq = NO_IRQ,
+    },
+    {
+        .name = "DBG_PPU",
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .index = 2,
+        .addr = 0x50029000,
+        .size = 0x1000,
+        .ppc = NO_PPC,
+        .irq = NO_IRQ,
+    },
+    {
+        .name = "RAM0_PPU",
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .index = 3,
+        .addr = 0x5002a000,
+        .size = 0x1000,
+        .ppc = NO_PPC,
+        .irq = NO_IRQ,
+    },
+    {
+        .name = "RAM1_PPU",
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .index = 4,
+        .addr = 0x5002b000,
+        .size = 0x1000,
+        .ppc = NO_PPC,
+        .irq = NO_IRQ,
+    },
+    {
+        .name = "RAM2_PPU",
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .index = 5,
+        .addr = 0x5002c000,
+        .size = 0x1000,
+        .ppc = NO_PPC,
+        .irq = NO_IRQ,
+    },
+    {
+        .name = "RAM3_PPU",
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .index = 6,
+        .addr = 0x5002d000,
+        .size = 0x1000,
+        .ppc = NO_PPC,
+        .irq = NO_IRQ,
+    },
+    {
+        .name = NULL,
+    }
+};
+
 static const ARMSSEInfo armsse_variants[] = {
     {
         .name = TYPE_IOTKIT,
@@ -188,12 +335,11 @@ static const ARMSSEInfo armsse_variants[] = {
         .iidr = 0,
         .cpuwait_rst = 0,
         .has_mhus = false,
-        .has_ppus = false,
         .has_cachectrl = false,
         .has_cpusecctrl = false,
         .has_cpuid = false,
         .props = iotkit_properties,
-        .devinfo = sse200_devices,
+        .devinfo = iotkit_devices,
     },
     {
         .name = TYPE_SSE200,
@@ -204,7 +350,6 @@ static const ARMSSEInfo armsse_variants[] = {
         .iidr = 0,
         .cpuwait_rst = 2,
         .has_mhus = true,
-        .has_ppus = true,
         .has_cachectrl = true,
         .has_cpusecctrl = true,
         .has_cpuid = true,
@@ -431,6 +576,11 @@ static void armsse_init(Object *obj)
             assert(devinfo->index == 0);
             object_initialize_child(obj, devinfo->name, &s->sysctl,
                                     TYPE_IOTKIT_SYSCTL);
+        } else if (!strcmp(devinfo->type, TYPE_UNIMPLEMENTED_DEVICE)) {
+            assert(devinfo->index < ARRAY_SIZE(s->unimp));
+            object_initialize_child(obj, devinfo->name,
+                                    &s->unimp[devinfo->index],
+                                    TYPE_UNIMPLEMENTED_DEVICE);
         } else {
             g_assert_not_reached();
         }
@@ -463,26 +613,6 @@ static void armsse_init(Object *obj)
         object_initialize_child(obj, "mhu0", &s->mhu[0], TYPE_ARMSSE_MHU);
         object_initialize_child(obj, "mhu1", &s->mhu[1], TYPE_ARMSSE_MHU);
     }
-    if (info->has_ppus) {
-        for (i = 0; i < info->num_cpus; i++) {
-            char *name = g_strdup_printf("CPU%dCORE_PPU", i);
-            int ppuidx = CPU0CORE_PPU + i;
-
-            object_initialize_child(obj, name, &s->ppu[ppuidx],
-                                    TYPE_UNIMPLEMENTED_DEVICE);
-            g_free(name);
-        }
-        object_initialize_child(obj, "DBG_PPU", &s->ppu[DBG_PPU],
-                                TYPE_UNIMPLEMENTED_DEVICE);
-        for (i = 0; i < info->sram_banks; i++) {
-            char *name = g_strdup_printf("RAM%d_PPU", i);
-            int ppuidx = RAM0_PPU + i;
-
-            object_initialize_child(obj, name, &s->ppu[ppuidx],
-                                    TYPE_UNIMPLEMENTED_DEVICE);
-            g_free(name);
-        }
-    }
     if (info->has_cachectrl) {
         for (i = 0; i < info->num_cpus; i++) {
             char *name = g_strdup_printf("cachectrl%d", i);
@@ -568,17 +698,6 @@ static qemu_irq armsse_get_common_irq_in(ARMSSE *s, int irqno)
     }
 }
 
-static void map_ppu(ARMSSE *s, int ppuidx, const char *name, hwaddr addr)
-{
-    /* Map a PPU unimplemented device stub */
-    DeviceState *dev = DEVICE(&s->ppu[ppuidx]);
-
-    qdev_prop_set_string(dev, "name", name);
-    qdev_prop_set_uint64(dev, "size", 0x1000);
-    sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->ppu[ppuidx]), 0, addr);
-}
-
 static void armsse_realize(DeviceState *dev, Error **errp)
 {
     ARMSSE *s = ARM_SSE(dev);
@@ -941,6 +1060,15 @@ static void armsse_realize(DeviceState *dev, Error **errp)
                 return;
             }
             mr = sysbus_mmio_get_region(sbd, 0);
+        } else if (!strcmp(devinfo->type, TYPE_UNIMPLEMENTED_DEVICE)) {
+            sbd = SYS_BUS_DEVICE(&s->unimp[devinfo->index]);
+
+            qdev_prop_set_string(DEVICE(sbd), "name", devinfo->name);
+            qdev_prop_set_uint64(DEVICE(sbd), "size", devinfo->size);
+            if (!sysbus_realize(sbd, errp)) {
+                return;
+            }
+            mr = sysbus_mmio_get_region(sbd, 0);
         } else {
             g_assert_not_reached();
         }
@@ -1158,28 +1286,6 @@ static void armsse_realize(DeviceState *dev, Error **errp)
         memory_region_add_subregion(&s->container, devinfo->addr, mr);
     }
 
-    if (info->has_ppus) {
-        /* CPUnCORE_PPU for each CPU */
-        for (i = 0; i < info->num_cpus; i++) {
-            char *name = g_strdup_printf("CPU%dCORE_PPU", i);
-
-            map_ppu(s, CPU0CORE_PPU + i, name, 0x50023000 + i * 0x2000);
-            /*
-             * We don't support CPU debug so don't create the
-             * CPU0DEBUG_PPU at 0x50024000 and 0x50026000.
-             */
-            g_free(name);
-        }
-        map_ppu(s, DBG_PPU, "DBG_PPU", 0x50029000);
-
-        for (i = 0; i < info->sram_banks; i++) {
-            char *name = g_strdup_printf("RAM%d_PPU", i);
-
-            map_ppu(s, RAM0_PPU + i, name, 0x5002a000 + i * 0x1000);
-            g_free(name);
-        }
-    }
-
     for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
         Object *splitter = OBJECT(&s->ppc_irq_splitter[i]);
 
-- 
2.20.1



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

* [PATCH 30/44] hw/arm/armsse: Add missing SSE-200 SYS_PPU
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (28 preceding siblings ...)
  2021-02-19 14:46 ` [PATCH 29/44] hw/arm/armsse: Move PPUs " Peter Maydell
@ 2021-02-19 14:46 ` Peter Maydell
  2021-03-04 20:25   ` Richard Henderson
  2021-02-19 14:46 ` [PATCH 31/44] hw/arm/armsse: Indirect irq_is_common[] through ARMSSEInfo Peter Maydell
                   ` (15 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:46 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

We forgot to implement a TYPE_UNIMPLEMENTED_DEVICE stub
for the SYS_PPU in the SSE-200, which is at 0x50022000.

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

diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
index eb4e937173f..104ba8d26ec 100644
--- a/include/hw/arm/armsse.h
+++ b/include/hw/arm/armsse.h
@@ -135,7 +135,7 @@ OBJECT_DECLARE_TYPE(ARMSSE, ARMSSEClass,
 
 #define SSE_MAX_CPUS 2
 
-#define NUM_PPUS 7
+#define NUM_PPUS 8
 
 /* Number of CPU IRQs used by the SSE itself */
 #define NUM_SSE_IRQS 32
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index f72d1adafea..f43f0524e28 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -320,6 +320,15 @@ static const ARMSSEDeviceInfo sse200_devices[] = {
         .ppc = NO_PPC,
         .irq = NO_IRQ,
     },
+    {
+        .name = "SYS_PPU",
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .index = 7,
+        .addr = 0x50022000,
+        .size = 0x1000,
+        .ppc = NO_PPC,
+        .irq = NO_IRQ,
+    },
     {
         .name = NULL,
     }
-- 
2.20.1



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

* [PATCH 31/44] hw/arm/armsse: Indirect irq_is_common[] through ARMSSEInfo
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (29 preceding siblings ...)
  2021-02-19 14:46 ` [PATCH 30/44] hw/arm/armsse: Add missing SSE-200 SYS_PPU Peter Maydell
@ 2021-02-19 14:46 ` Peter Maydell
  2021-03-04 20:19   ` Philippe Mathieu-Daudé
  2021-03-04 20:26   ` Richard Henderson
  2021-02-19 14:46 ` [PATCH 32/44] hw/arm/armsse: Add support for SSE variants with a system counter Peter Maydell
                   ` (14 subsequent siblings)
  45 siblings, 2 replies; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:46 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The SSE-300 has a slightly different set of shared-per-CPU interrupts,
allow the irq_is_common[] array to be different per SSE variant.

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

diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index f43f0524e28..b316fe69571 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -68,6 +68,7 @@ struct ARMSSEInfo {
     bool has_cpuid;
     Property *props;
     const ARMSSEDeviceInfo *devinfo;
+    const bool *irq_is_common;
 };
 
 static Property iotkit_properties[] = {
@@ -334,6 +335,21 @@ static const ARMSSEDeviceInfo sse200_devices[] = {
     }
 };
 
+/* Is internal IRQ n shared between CPUs in a multi-core SSE ? */
+static const bool sse200_irq_is_common[32] = {
+    [0 ... 5] = true,
+    /* 6, 7: per-CPU MHU interrupts */
+    [8 ... 12] = true,
+    /* 13: per-CPU icache interrupt */
+    /* 14: reserved */
+    [15 ... 20] = true,
+    /* 21: reserved */
+    [22 ... 26] = true,
+    /* 27: reserved */
+    /* 28, 29: per-CPU CTI interrupts */
+    /* 30, 31: reserved */
+};
+
 static const ARMSSEInfo armsse_variants[] = {
     {
         .name = TYPE_IOTKIT,
@@ -349,6 +365,7 @@ static const ARMSSEInfo armsse_variants[] = {
         .has_cpuid = false,
         .props = iotkit_properties,
         .devinfo = iotkit_devices,
+        .irq_is_common = sse200_irq_is_common,
     },
     {
         .name = TYPE_SSE200,
@@ -364,6 +381,7 @@ static const ARMSSEInfo armsse_variants[] = {
         .has_cpuid = true,
         .props = armsse_properties,
         .devinfo = sse200_devices,
+        .irq_is_common = sse200_irq_is_common,
     },
 };
 
@@ -404,21 +422,6 @@ static uint32_t armsse_sys_config_value(ARMSSE *s, const ARMSSEInfo *info)
 /* Clock frequency in HZ of the 32KHz "slow clock" */
 #define S32KCLK (32 * 1000)
 
-/* Is internal IRQ n shared between CPUs in a multi-core SSE ? */
-static bool irq_is_common[32] = {
-    [0 ... 5] = true,
-    /* 6, 7: per-CPU MHU interrupts */
-    [8 ... 12] = true,
-    /* 13: per-CPU icache interrupt */
-    /* 14: reserved */
-    [15 ... 20] = true,
-    /* 21: reserved */
-    [22 ... 26] = true,
-    /* 27: reserved */
-    /* 28, 29: per-CPU CTI interrupts */
-    /* 30, 31: reserved */
-};
-
 /*
  * Create an alias region in @container of @size bytes starting at @base
  * which mirrors the memory starting at @orig.
@@ -663,7 +666,7 @@ static void armsse_init(Object *obj)
     }
     if (info->num_cpus > 1) {
         for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
-            if (irq_is_common[i]) {
+            if (info->irq_is_common[i]) {
                 char *name = g_strdup_printf("cpu-irq-splitter%d", i);
                 SplitIRQ *splitter = &s->cpu_irq_splitter[i];
 
@@ -696,7 +699,7 @@ static qemu_irq armsse_get_common_irq_in(ARMSSE *s, int irqno)
     ARMSSEClass *asc = ARM_SSE_GET_CLASS(s);
     const ARMSSEInfo *info = asc->info;
 
-    assert(irq_is_common[irqno]);
+    assert(info->irq_is_common[irqno]);
 
     if (info->num_cpus == 1) {
         /* Only one CPU -- just connect directly to it */
@@ -878,7 +881,7 @@ static void armsse_realize(DeviceState *dev, Error **errp)
     /* Wire up the splitters that connect common IRQs to all CPUs */
     if (info->num_cpus > 1) {
         for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
-            if (irq_is_common[i]) {
+            if (info->irq_is_common[i]) {
                 Object *splitter = OBJECT(&s->cpu_irq_splitter[i]);
                 DeviceState *devs = DEVICE(splitter);
                 int cpunum;
-- 
2.20.1



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

* [PATCH 32/44] hw/arm/armsse: Add support for SSE variants with a system counter
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (30 preceding siblings ...)
  2021-02-19 14:46 ` [PATCH 31/44] hw/arm/armsse: Indirect irq_is_common[] through ARMSSEInfo Peter Maydell
@ 2021-02-19 14:46 ` Peter Maydell
  2021-03-04 20:30   ` Richard Henderson
  2021-02-19 14:46 ` [PATCH 33/44] hw/arm/armsse: Add support for TYPE_SSE_TIMER in ARMSSEDeviceInfo Peter Maydell
                   ` (13 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:46 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The SSE-300 has a system counter device; add support for SSE
variants having this device.

As with the existing devices like the cache control block, CPUID
block, etc, we don't try to make the MMIO addresses configurable.  We
can do that if and when we need to model a future SSE variant which
has the counter in a different location.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/arm/armsse.h |  3 +++
 hw/arm/armsse.c         | 27 +++++++++++++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
index 104ba8d26ec..149f17dfc88 100644
--- a/include/hw/arm/armsse.h
+++ b/include/hw/arm/armsse.h
@@ -97,6 +97,7 @@
 #include "hw/misc/tz-mpc.h"
 #include "hw/timer/cmsdk-apb-timer.h"
 #include "hw/timer/cmsdk-apb-dualtimer.h"
+#include "hw/timer/sse-counter.h"
 #include "hw/watchdog/cmsdk-apb-watchdog.h"
 #include "hw/misc/iotkit-sysctl.h"
 #include "hw/misc/iotkit-sysinfo.h"
@@ -164,6 +165,8 @@ struct ARMSSE {
 
     CMSDKAPBWatchdog cmsdk_watchdog[3];
 
+    SSECounter sse_counter;
+
     IoTKitSysCtl sysctl;
     IoTKitSysCtl sysinfo;
 
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index b316fe69571..4387e98376c 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -66,6 +66,7 @@ struct ARMSSEInfo {
     bool has_cachectrl;
     bool has_cpusecctrl;
     bool has_cpuid;
+    bool has_sse_counter;
     Property *props;
     const ARMSSEDeviceInfo *devinfo;
     const bool *irq_is_common;
@@ -363,6 +364,7 @@ static const ARMSSEInfo armsse_variants[] = {
         .has_cachectrl = false,
         .has_cpusecctrl = false,
         .has_cpuid = false,
+        .has_sse_counter = false,
         .props = iotkit_properties,
         .devinfo = iotkit_devices,
         .irq_is_common = sse200_irq_is_common,
@@ -379,6 +381,7 @@ static const ARMSSEInfo armsse_variants[] = {
         .has_cachectrl = true,
         .has_cpusecctrl = true,
         .has_cpuid = true,
+        .has_sse_counter = false,
         .props = armsse_properties,
         .devinfo = sse200_devices,
         .irq_is_common = sse200_irq_is_common,
@@ -652,6 +655,11 @@ static void armsse_init(Object *obj)
             g_free(name);
         }
     }
+    if (info->has_sse_counter) {
+        object_initialize_child(obj, "sse-counter", &s->sse_counter,
+                                TYPE_SSE_COUNTER);
+    }
+
     object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate, TYPE_OR_IRQ);
     object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate,
                             TYPE_OR_IRQ);
@@ -1000,6 +1008,25 @@ static void armsse_realize(DeviceState *dev, Error **errp)
     qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
                           qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
 
+    /* The SSE-300 has a System Counter / System Timestamp Generator */
+    if (info->has_sse_counter) {
+        SysBusDevice *sbd = SYS_BUS_DEVICE(&s->sse_counter);
+
+        qdev_connect_clock_in(DEVICE(sbd), "CLK", s->mainclk);
+        if (!sysbus_realize(sbd, errp)) {
+            return;
+        }
+        /*
+         * The control frame is only in the Secure region;
+         * the status frame is in the NS region (and visible in the
+         * S region via the alias mapping).
+         */
+        memory_region_add_subregion(&s->container, 0x58100000,
+                                    sysbus_mmio_get_region(sbd, 0));
+        memory_region_add_subregion(&s->container, 0x48101000,
+                                    sysbus_mmio_get_region(sbd, 1));
+    }
+
     /* Devices behind APB PPC0:
      *   0x40000000: timer0
      *   0x40001000: timer1
-- 
2.20.1



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

* [PATCH 33/44] hw/arm/armsse: Add support for TYPE_SSE_TIMER in ARMSSEDeviceInfo
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (31 preceding siblings ...)
  2021-02-19 14:46 ` [PATCH 32/44] hw/arm/armsse: Add support for SSE variants with a system counter Peter Maydell
@ 2021-02-19 14:46 ` Peter Maydell
  2021-03-04 20:22   ` Philippe Mathieu-Daudé
  2021-03-04 20:34   ` Richard Henderson
  2021-02-19 14:46 ` [PATCH 34/44] hw/arm/armsse: Support variants with ARMSSE_CPU_PWRCTRL block Peter Maydell
                   ` (12 subsequent siblings)
  45 siblings, 2 replies; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:46 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The SSE-300 has four timers of type TYPE_SSE_TIMER; add support in
the code for having these in an ARMSSEDeviceInfo array.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/arm/armsse.h |  2 ++
 hw/arm/armsse.c         | 15 +++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
index 149f17dfc88..f4e2b680479 100644
--- a/include/hw/arm/armsse.h
+++ b/include/hw/arm/armsse.h
@@ -98,6 +98,7 @@
 #include "hw/timer/cmsdk-apb-timer.h"
 #include "hw/timer/cmsdk-apb-dualtimer.h"
 #include "hw/timer/sse-counter.h"
+#include "hw/timer/sse-timer.h"
 #include "hw/watchdog/cmsdk-apb-watchdog.h"
 #include "hw/misc/iotkit-sysctl.h"
 #include "hw/misc/iotkit-sysinfo.h"
@@ -166,6 +167,7 @@ struct ARMSSE {
     CMSDKAPBWatchdog cmsdk_watchdog[3];
 
     SSECounter sse_counter;
+    SSETimer sse_timer[4];
 
     IoTKitSysCtl sysctl;
     IoTKitSysCtl sysinfo;
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index 4387e98376c..ec9c30e0996 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -578,6 +578,11 @@ static void armsse_init(Object *obj)
             assert(devinfo->index == 0);
             object_initialize_child(obj, devinfo->name, &s->dualtimer,
                                     TYPE_CMSDK_APB_DUALTIMER);
+        } else if (!strcmp(devinfo->type, TYPE_SSE_TIMER)) {
+            assert(devinfo->index < ARRAY_SIZE(s->sse_timer));
+            object_initialize_child(obj, devinfo->name,
+                                    &s->sse_timer[devinfo->index],
+                                    TYPE_SSE_TIMER);
         } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_WATCHDOG)) {
             assert(devinfo->index < ARRAY_SIZE(s->cmsdk_watchdog));
             object_initialize_child(obj, devinfo->name,
@@ -1058,6 +1063,16 @@ static void armsse_realize(DeviceState *dev, Error **errp)
                 return;
             }
             mr = sysbus_mmio_get_region(sbd, 0);
+        } else if (!strcmp(devinfo->type, TYPE_SSE_TIMER)) {
+            sbd = SYS_BUS_DEVICE(&s->sse_timer[devinfo->index]);
+
+            assert(info->has_sse_counter);
+            object_property_set_link(OBJECT(sbd), "counter",
+                                     OBJECT(&s->sse_counter), &error_abort);
+            if (!sysbus_realize(sbd, errp)) {
+                return;
+            }
+            mr = sysbus_mmio_get_region(sbd, 0);
         } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_WATCHDOG)) {
             sbd = SYS_BUS_DEVICE(&s->cmsdk_watchdog[devinfo->index]);
 
-- 
2.20.1



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

* [PATCH 34/44] hw/arm/armsse: Support variants with ARMSSE_CPU_PWRCTRL block
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (32 preceding siblings ...)
  2021-02-19 14:46 ` [PATCH 33/44] hw/arm/armsse: Add support for TYPE_SSE_TIMER in ARMSSEDeviceInfo Peter Maydell
@ 2021-02-19 14:46 ` Peter Maydell
  2021-03-04 20:37   ` Richard Henderson
  2021-02-19 14:46 ` [PATCH 35/44] hw/arm/armsse: Add SSE-300 support Peter Maydell
                   ` (11 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:46 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Support SSE variants like the SSE-300 with an ARMSSE_CPU_PWRCTRL register
block. Because this block is per-CPU and does not clash with any of the
SSE-200 devices, we handle it with a has_cpu_pwrctrl flag like the
existing has_cachectrl, has_cpusectrl and has_cpuid, rather than
trying to add per-CPU-device support to the devinfo array handling code.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/arm/armsse.h |  3 +++
 hw/arm/armsse.c         | 26 ++++++++++++++++++++++++++
 2 files changed, 29 insertions(+)

diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
index f4e2b680479..21d239c381c 100644
--- a/include/hw/arm/armsse.h
+++ b/include/hw/arm/armsse.h
@@ -104,6 +104,7 @@
 #include "hw/misc/iotkit-sysinfo.h"
 #include "hw/misc/armsse-cpuid.h"
 #include "hw/misc/armsse-mhu.h"
+#include "hw/misc/armsse-cpu-pwrctrl.h"
 #include "hw/misc/unimp.h"
 #include "hw/or-irq.h"
 #include "hw/clock.h"
@@ -179,6 +180,8 @@ struct ARMSSE {
 
     ARMSSECPUID cpuid[SSE_MAX_CPUS];
 
+    ARMSSECPUPwrCtrl cpu_pwrctrl[SSE_MAX_CPUS];
+
     /*
      * 'container' holds all devices seen by all CPUs.
      * 'cpu_container[i]' is the view that CPU i has: this has the
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index ec9c30e0996..2366c49376d 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -66,6 +66,7 @@ struct ARMSSEInfo {
     bool has_cachectrl;
     bool has_cpusecctrl;
     bool has_cpuid;
+    bool has_cpu_pwrctrl;
     bool has_sse_counter;
     Property *props;
     const ARMSSEDeviceInfo *devinfo;
@@ -364,6 +365,7 @@ static const ARMSSEInfo armsse_variants[] = {
         .has_cachectrl = false,
         .has_cpusecctrl = false,
         .has_cpuid = false,
+        .has_cpu_pwrctrl = false,
         .has_sse_counter = false,
         .props = iotkit_properties,
         .devinfo = iotkit_devices,
@@ -381,6 +383,7 @@ static const ARMSSEInfo armsse_variants[] = {
         .has_cachectrl = true,
         .has_cpusecctrl = true,
         .has_cpuid = true,
+        .has_cpu_pwrctrl = false,
         .has_sse_counter = false,
         .props = armsse_properties,
         .devinfo = sse200_devices,
@@ -660,6 +663,15 @@ static void armsse_init(Object *obj)
             g_free(name);
         }
     }
+    if (info->has_cpu_pwrctrl) {
+        for (i = 0; i < info->num_cpus; i++) {
+            char *name = g_strdup_printf("cpu_pwrctrl%d", i);
+
+            object_initialize_child(obj, name, &s->cpu_pwrctrl[i],
+                                    TYPE_ARMSSE_CPU_PWRCTRL);
+            g_free(name);
+        }
+    }
     if (info->has_sse_counter) {
         object_initialize_child(obj, "sse-counter", &s->sse_counter,
                                 TYPE_SSE_COUNTER);
@@ -1255,6 +1267,8 @@ static void armsse_realize(DeviceState *dev, Error **errp)
      *  0x50010000: L1 icache control registers
      *  0x50011000: CPUSECCTRL (CPU local security control registers)
      *  0x4001f000 and 0x5001f000: CPU_IDENTITY register block
+     * The SSE-300 has an extra:
+     *  0x40012000 and 0x50012000: CPU_PWRCTRL register block
      */
     if (info->has_cachectrl) {
         for (i = 0; i < info->num_cpus; i++) {
@@ -1301,6 +1315,18 @@ static void armsse_realize(DeviceState *dev, Error **errp)
             memory_region_add_subregion(&s->cpu_container[i], 0x4001F000, mr);
         }
     }
+    if (info->has_cpu_pwrctrl) {
+        for (i = 0; i < info->num_cpus; i++) {
+            MemoryRegion *mr;
+
+            if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpu_pwrctrl[i]), errp)) {
+                return;
+            }
+
+            mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpu_pwrctrl[i]), 0);
+            memory_region_add_subregion(&s->cpu_container[i], 0x40012000, mr);
+        }
+    }
 
     if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc[1]), errp)) {
         return;
-- 
2.20.1



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

* [PATCH 35/44] hw/arm/armsse: Add SSE-300 support
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (33 preceding siblings ...)
  2021-02-19 14:46 ` [PATCH 34/44] hw/arm/armsse: Support variants with ARMSSE_CPU_PWRCTRL block Peter Maydell
@ 2021-02-19 14:46 ` Peter Maydell
  2021-03-04 20:39   ` Richard Henderson
  2021-02-19 14:46 ` [PATCH 36/44] hw/arm/mps2-tz: Make UART overflow IRQ board-specific Peter Maydell
                   ` (10 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:46 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Now we have sufficiently parameterised the code, we can add SSE-300
support by adding a new entry to the armsse_variants[] array.

Note that the main watchdog (unlike the s32k watchdog) in the SSE-300
is a different device from the CMSDK watchdog; we don't have a model
of it so we leave it as a TYPE_UNIMPLEMENTED_DEVICE stub.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/arm/armsse.h |   1 +
 hw/arm/armsse.c         | 152 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 153 insertions(+)

diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
index 21d239c381c..36592be62c5 100644
--- a/include/hw/arm/armsse.h
+++ b/include/hw/arm/armsse.h
@@ -123,6 +123,7 @@ OBJECT_DECLARE_TYPE(ARMSSE, ARMSSEClass,
  */
 #define TYPE_IOTKIT "iotkit"
 #define TYPE_SSE200 "sse-200"
+#define TYPE_SSE300 "sse-300"
 
 /* We have an IRQ splitter and an OR gate input for each external PPC
  * and the 2 internal PPCs
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index 2366c49376d..e5aeb9e485f 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -337,6 +337,128 @@ static const ARMSSEDeviceInfo sse200_devices[] = {
     }
 };
 
+static const ARMSSEDeviceInfo sse300_devices[] = {
+    {
+        .name = "timer0",
+        .type = TYPE_SSE_TIMER,
+        .index = 0,
+        .addr = 0x48000000,
+        .ppc = 0,
+        .ppc_port = 0,
+        .irq = 3,
+    },
+    {
+        .name = "timer1",
+        .type = TYPE_SSE_TIMER,
+        .index = 1,
+        .addr = 0x48001000,
+        .ppc = 0,
+        .ppc_port = 1,
+        .irq = 4,
+    },
+    {
+        .name = "timer2",
+        .type = TYPE_SSE_TIMER,
+        .index = 2,
+        .addr = 0x48002000,
+        .ppc = 0,
+        .ppc_port = 2,
+        .irq = 5,
+    },
+    {
+        .name = "timer3",
+        .type = TYPE_SSE_TIMER,
+        .index = 3,
+        .addr = 0x48003000,
+        .ppc = 0,
+        .ppc_port = 5,
+        .irq = 27,
+    },
+    {
+        .name = "s32ktimer",
+        .type = TYPE_CMSDK_APB_TIMER,
+        .index = 0,
+        .addr = 0x4802f000,
+        .ppc = 1,
+        .ppc_port = 0,
+        .irq = 2,
+        .slowclk = true,
+    },
+    {
+        .name = "s32kwatchdog",
+        .type = TYPE_CMSDK_APB_WATCHDOG,
+        .index = 0,
+        .addr = 0x4802e000,
+        .ppc = NO_PPC,
+        .irq = NMI_0,
+        .slowclk = true,
+    },
+    {
+        .name = "watchdog",
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .index = 0,
+        .addr = 0x48040000,
+        .size = 0x2000,
+        .ppc = NO_PPC,
+        .irq = NO_IRQ,
+    },
+    {
+        .name = "armsse-sysinfo",
+        .type = TYPE_IOTKIT_SYSINFO,
+        .index = 0,
+        .addr = 0x48020000,
+        .ppc = NO_PPC,
+        .irq = NO_IRQ,
+    },
+    {
+        .name = "armsse-sysctl",
+        .type = TYPE_IOTKIT_SYSCTL,
+        .index = 0,
+        .addr = 0x58021000,
+        .ppc = NO_PPC,
+        .irq = NO_IRQ,
+    },
+    {
+        .name = "SYS_PPU",
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .index = 1,
+        .addr = 0x58022000,
+        .size = 0x1000,
+        .ppc = NO_PPC,
+        .irq = NO_IRQ,
+    },
+    {
+        .name = "CPU0CORE_PPU",
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .index = 2,
+        .addr = 0x50023000,
+        .size = 0x1000,
+        .ppc = NO_PPC,
+        .irq = NO_IRQ,
+    },
+    {
+        .name = "MGMT_PPU",
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .index = 3,
+        .addr = 0x50028000,
+        .size = 0x1000,
+        .ppc = NO_PPC,
+        .irq = NO_IRQ,
+    },
+    {
+        .name = "DEBUG_PPU",
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .index = 4,
+        .addr = 0x50029000,
+        .size = 0x1000,
+        .ppc = NO_PPC,
+        .irq = NO_IRQ,
+    },
+    {
+        .name = NULL,
+    }
+};
+
 /* Is internal IRQ n shared between CPUs in a multi-core SSE ? */
 static const bool sse200_irq_is_common[32] = {
     [0 ... 5] = true,
@@ -352,6 +474,18 @@ static const bool sse200_irq_is_common[32] = {
     /* 30, 31: reserved */
 };
 
+static const bool sse300_irq_is_common[32] = {
+    [0 ... 5] = true,
+    /* 6, 7: per-CPU MHU interrupts */
+    [8 ... 12] = true,
+    /* 13: reserved */
+    [14 ... 16] = true,
+    /* 17-25: reserved */
+    [26 ... 27] = true,
+    /* 28, 29: per-CPU CTI interrupts */
+    /* 30, 31: reserved */
+};
+
 static const ARMSSEInfo armsse_variants[] = {
     {
         .name = TYPE_IOTKIT,
@@ -389,6 +523,24 @@ static const ARMSSEInfo armsse_variants[] = {
         .devinfo = sse200_devices,
         .irq_is_common = sse200_irq_is_common,
     },
+    {
+        .name = TYPE_SSE300,
+        .sse_version = ARMSSE_SSE300,
+        .sram_banks = 2,
+        .num_cpus = 1,
+        .sys_version = 0x7e00043b,
+        .iidr = 0x74a0043b,
+        .cpuwait_rst = 0,
+        .has_mhus = false,
+        .has_cachectrl = false,
+        .has_cpusecctrl = true,
+        .has_cpuid = true,
+        .has_cpu_pwrctrl = true,
+        .has_sse_counter = true,
+        .props = armsse_properties,
+        .devinfo = sse300_devices,
+        .irq_is_common = sse300_irq_is_common,
+    },
 };
 
 static uint32_t armsse_sys_config_value(ARMSSE *s, const ARMSSEInfo *info)
-- 
2.20.1



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

* [PATCH 36/44] hw/arm/mps2-tz: Make UART overflow IRQ board-specific
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (34 preceding siblings ...)
  2021-02-19 14:46 ` [PATCH 35/44] hw/arm/armsse: Add SSE-300 support Peter Maydell
@ 2021-02-19 14:46 ` Peter Maydell
  2021-03-04 20:16   ` Philippe Mathieu-Daudé
  2021-03-04 20:43   ` Richard Henderson
  2021-02-19 14:46 ` [PATCH 37/44] hw/misc/mps2-fpgaio: Fold counters subsection into main vmstate Peter Maydell
                   ` (9 subsequent siblings)
  45 siblings, 2 replies; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:46 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The AN547 puts the combined UART overflow IRQ at 48, not 47 like the
other images. Make this setting board-specific.

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

diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
index aca8efba6cf..779fdb9a544 100644
--- a/hw/arm/mps2-tz.c
+++ b/hw/arm/mps2-tz.c
@@ -111,6 +111,7 @@ struct MPS2TZMachineClass {
     uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
     bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
     int numirq; /* Number of external interrupts */
+    int uart_overflow_irq; /* number of the combined UART overflow IRQ */
     const RAMInfo *raminfo;
     const char *armsse_type;
 };
@@ -760,7 +761,7 @@ static void mps2tz_common_init(MachineState *machine)
                             &error_fatal);
     qdev_realize(DEVICE(&mms->uart_irq_orgate), NULL, &error_fatal);
     qdev_connect_gpio_out(DEVICE(&mms->uart_irq_orgate), 0,
-                          get_sse_irq_in(mms, 47));
+                          get_sse_irq_in(mms, mmc->uart_overflow_irq));
 
     /* Most of the devices in the FPGA are behind Peripheral Protection
      * Controllers. The required order for initializing things is:
@@ -1036,6 +1037,7 @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
     mmc->fpgaio_num_leds = 2;
     mmc->fpgaio_has_switches = false;
     mmc->numirq = 92;
+    mmc->uart_overflow_irq = 47;
     mmc->raminfo = an505_raminfo;
     mmc->armsse_type = TYPE_IOTKIT;
     mps2tz_set_default_ram_info(mmc);
@@ -1059,6 +1061,7 @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
     mmc->fpgaio_num_leds = 2;
     mmc->fpgaio_has_switches = false;
     mmc->numirq = 92;
+    mmc->uart_overflow_irq = 47;
     mmc->raminfo = an505_raminfo; /* AN521 is the same as AN505 here */
     mmc->armsse_type = TYPE_SSE200;
     mps2tz_set_default_ram_info(mmc);
@@ -1082,6 +1085,7 @@ static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
     mmc->fpgaio_num_leds = 10;
     mmc->fpgaio_has_switches = true;
     mmc->numirq = 95;
+    mmc->uart_overflow_irq = 47;
     mmc->raminfo = an524_raminfo;
     mmc->armsse_type = TYPE_SSE200;
     mps2tz_set_default_ram_info(mmc);
-- 
2.20.1



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

* [PATCH 37/44] hw/misc/mps2-fpgaio: Fold counters subsection into main vmstate
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (35 preceding siblings ...)
  2021-02-19 14:46 ` [PATCH 36/44] hw/arm/mps2-tz: Make UART overflow IRQ board-specific Peter Maydell
@ 2021-02-19 14:46 ` Peter Maydell
  2021-03-04 20:45   ` Richard Henderson
  2021-02-19 14:46 ` [PATCH 38/44] hw/misc/mps2-fpgaio: Support AN547 DBGCTRL register Peter Maydell
                   ` (8 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:46 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

We've already broken migration compatibility for all the MPS
boards, so we might as well take advantage of this to simplify
the vmstate for the FPGAIO device by folding the counters
subsection into the main vmstate description.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/misc/mps2-fpgaio.c | 30 +++++-------------------------
 1 file changed, 5 insertions(+), 25 deletions(-)

diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
index 76308543fcb..e3fabd58b7b 100644
--- a/hw/misc/mps2-fpgaio.c
+++ b/hw/misc/mps2-fpgaio.c
@@ -285,41 +285,21 @@ static void mps2_fpgaio_realize(DeviceState *dev, Error **errp)
     }
 }
 
-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",
+static const VMStateDescription mps2_fpgaio_vmstate = {
+    .name = "mps2-fpgaio",
     .version_id = 2,
     .minimum_version_id = 2,
-    .needed = mps2_fpgaio_counters_needed,
     .fields = (VMStateField[]) {
+        VMSTATE_UINT32(led0, MPS2FPGAIO),
+        VMSTATE_UINT32(prescale, MPS2FPGAIO),
+        VMSTATE_UINT32(misc, MPS2FPGAIO),
         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()
-    }
-};
-
-static const VMStateDescription mps2_fpgaio_vmstate = {
-    .name = "mps2-fpgaio",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT32(led0, MPS2FPGAIO),
-        VMSTATE_UINT32(prescale, MPS2FPGAIO),
-        VMSTATE_UINT32(misc, MPS2FPGAIO),
-        VMSTATE_END_OF_LIST()
     },
-    .subsections = (const VMStateDescription*[]) {
-        &mps2_fpgaio_counters_vmstate,
-        NULL
-    }
 };
 
 static Property mps2_fpgaio_properties[] = {
-- 
2.20.1



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

* [PATCH 38/44] hw/misc/mps2-fpgaio: Support AN547 DBGCTRL register
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (36 preceding siblings ...)
  2021-02-19 14:46 ` [PATCH 37/44] hw/misc/mps2-fpgaio: Fold counters subsection into main vmstate Peter Maydell
@ 2021-02-19 14:46 ` Peter Maydell
  2021-03-04 20:24   ` Philippe Mathieu-Daudé
  2021-03-04 20:50   ` Richard Henderson
  2021-02-19 14:46 ` [PATCH 39/44] hw/misc/mps2-scc: Implement changes for AN547 Peter Maydell
                   ` (7 subsequent siblings)
  45 siblings, 2 replies; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:46 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

For the AN547 image, the FPGAIO block has an extra DBGCTRL register,
which is used to control the SPNIDEN, SPIDEN, NPIDEN and DBGEN inputs
to the CPU.  These signals control when the CPU permits use of the
external debug interface.  Our CPU models don't implement the
external debug interface, so we model the register as
reads-as-written.

Implement the register, with a property defining whether it is
present, and allow mps2-tz boards to specify that it is present.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/misc/mps2-fpgaio.h |  2 ++
 hw/arm/mps2-tz.c              |  5 +++++
 hw/misc/mps2-fpgaio.c         | 22 ++++++++++++++++++++--
 3 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
index e04fd590b63..7b8bd604de0 100644
--- a/include/hw/misc/mps2-fpgaio.h
+++ b/include/hw/misc/mps2-fpgaio.h
@@ -39,10 +39,12 @@ struct MPS2FPGAIO {
     LEDState *led[MPS2FPGAIO_MAX_LEDS];
     uint32_t num_leds;
     bool has_switches;
+    bool has_dbgctrl;
 
     uint32_t led0;
     uint32_t prescale;
     uint32_t misc;
+    uint32_t dbgctrl;
 
     /* QEMU_CLOCK_VIRTUAL time at which counter and pscntr were last synced */
     int64_t pscntr_sync_ticks;
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
index 779fdb9a544..fe324e86b3d 100644
--- a/hw/arm/mps2-tz.c
+++ b/hw/arm/mps2-tz.c
@@ -110,6 +110,7 @@ struct MPS2TZMachineClass {
     const uint32_t *oscclk;
     uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
     bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
+    bool fpgaio_has_dbgctrl; /* Does FPGAIO have DBGCTRL register? */
     int numirq; /* Number of external interrupts */
     int uart_overflow_irq; /* number of the combined UART overflow IRQ */
     const RAMInfo *raminfo;
@@ -412,6 +413,7 @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
     object_initialize_child(OBJECT(mms), "fpgaio", fpgaio, TYPE_MPS2_FPGAIO);
     qdev_prop_set_uint32(DEVICE(fpgaio), "num-leds", mmc->fpgaio_num_leds);
     qdev_prop_set_bit(DEVICE(fpgaio), "has-switches", mmc->fpgaio_has_switches);
+    qdev_prop_set_bit(DEVICE(fpgaio), "has-dbgctrl", mmc->fpgaio_has_dbgctrl);
     sysbus_realize(SYS_BUS_DEVICE(fpgaio), &error_fatal);
     return sysbus_mmio_get_region(SYS_BUS_DEVICE(fpgaio), 0);
 }
@@ -1036,6 +1038,7 @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
     mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
     mmc->fpgaio_num_leds = 2;
     mmc->fpgaio_has_switches = false;
+    mmc->fpgaio_has_dbgctrl = false;
     mmc->numirq = 92;
     mmc->uart_overflow_irq = 47;
     mmc->raminfo = an505_raminfo;
@@ -1060,6 +1063,7 @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
     mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
     mmc->fpgaio_num_leds = 2;
     mmc->fpgaio_has_switches = false;
+    mmc->fpgaio_has_dbgctrl = false;
     mmc->numirq = 92;
     mmc->uart_overflow_irq = 47;
     mmc->raminfo = an505_raminfo; /* AN521 is the same as AN505 here */
@@ -1084,6 +1088,7 @@ static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
     mmc->len_oscclk = ARRAY_SIZE(an524_oscclk);
     mmc->fpgaio_num_leds = 10;
     mmc->fpgaio_has_switches = true;
+    mmc->fpgaio_has_dbgctrl = false;
     mmc->numirq = 95;
     mmc->uart_overflow_irq = 47;
     mmc->raminfo = an524_raminfo;
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
index e3fabd58b7b..1c699410720 100644
--- a/hw/misc/mps2-fpgaio.c
+++ b/hw/misc/mps2-fpgaio.c
@@ -29,6 +29,7 @@
 #include "qemu/timer.h"
 
 REG32(LED0, 0)
+REG32(DBGCTRL, 4)
 REG32(BUTTON, 8)
 REG32(CLK1HZ, 0x10)
 REG32(CLK100HZ, 0x14)
@@ -129,6 +130,12 @@ static uint64_t mps2_fpgaio_read(void *opaque, hwaddr offset, unsigned size)
     case A_LED0:
         r = s->led0;
         break;
+    case A_DBGCTRL:
+        if (!s->has_dbgctrl) {
+            goto bad_offset;
+        }
+        r = s->dbgctrl;
+        break;
     case A_BUTTON:
         /* User-pressable board buttons. We don't model that, so just return
          * zeroes.
@@ -195,6 +202,14 @@ static void mps2_fpgaio_write(void *opaque, hwaddr offset, uint64_t value,
             }
         }
         break;
+    case A_DBGCTRL:
+        if (!s->has_dbgctrl) {
+            goto bad_offset;
+        }
+        qemu_log_mask(LOG_UNIMP,
+                      "MPS2 FPGAIO: DBGCTRL unimplemented\n");
+        s->dbgctrl = value;
+        break;
     case A_PRESCALE:
         resync_counter(s);
         s->prescale = value;
@@ -225,6 +240,7 @@ static void mps2_fpgaio_write(void *opaque, hwaddr offset, uint64_t value,
         s->pscntr = value;
         break;
     default:
+    bad_offset:
         qemu_log_mask(LOG_GUEST_ERROR,
                       "MPS2 FPGAIO write: bad offset 0x%x\n", (int) offset);
         break;
@@ -287,12 +303,13 @@ static void mps2_fpgaio_realize(DeviceState *dev, Error **errp)
 
 static const VMStateDescription mps2_fpgaio_vmstate = {
     .name = "mps2-fpgaio",
-    .version_id = 2,
-    .minimum_version_id = 2,
+    .version_id = 3,
+    .minimum_version_id = 3,
     .fields = (VMStateField[]) {
         VMSTATE_UINT32(led0, MPS2FPGAIO),
         VMSTATE_UINT32(prescale, MPS2FPGAIO),
         VMSTATE_UINT32(misc, MPS2FPGAIO),
+        VMSTATE_UINT32(dbgctrl, MPS2FPGAIO),
         VMSTATE_INT64(clk1hz_tick_offset, MPS2FPGAIO),
         VMSTATE_INT64(clk100hz_tick_offset, MPS2FPGAIO),
         VMSTATE_UINT32(counter, MPS2FPGAIO),
@@ -308,6 +325,7 @@ static Property mps2_fpgaio_properties[] = {
     /* Number of LEDs controlled by LED0 register */
     DEFINE_PROP_UINT32("num-leds", MPS2FPGAIO, num_leds, 2),
     DEFINE_PROP_BOOL("has-switches", MPS2FPGAIO, has_switches, false),
+    DEFINE_PROP_BOOL("has-dbgctrl", MPS2FPGAIO, has_dbgctrl, false),
     DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.20.1



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

* [PATCH 39/44] hw/misc/mps2-scc: Implement changes for AN547
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (37 preceding siblings ...)
  2021-02-19 14:46 ` [PATCH 38/44] hw/misc/mps2-fpgaio: Support AN547 DBGCTRL register Peter Maydell
@ 2021-02-19 14:46 ` Peter Maydell
  2021-03-05  0:30   ` Richard Henderson
  2021-02-19 14:46 ` [PATCH 40/44] hw/arm/mps2-tz: Support running APB peripherals on different clock Peter Maydell
                   ` (6 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:46 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Implement the minor changes required to the SCC block for AN547 images:
 * CFG2 and CFG5 exist (like AN524)
 * CFG3 is reserved (like AN524)
 * CFG0 bit 1 is CPU_WAIT; we don't implement it, but note this
   in the TODO comment

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/misc/mps2-scc.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
index 140a4b9ceba..c56aca86ad5 100644
--- a/hw/misc/mps2-scc.c
+++ b/hw/misc/mps2-scc.c
@@ -110,14 +110,14 @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
         r = s->cfg1;
         break;
     case A_CFG2:
-        if (scc_partno(s) != 0x524) {
+        if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
             /* CFG2 reserved on other boards */
             goto bad_offset;
         }
         r = s->cfg2;
         break;
     case A_CFG3:
-        if (scc_partno(s) == 0x524) {
+        if (scc_partno(s) == 0x524 && scc_partno(s) == 0x547) {
             /* CFG3 reserved on AN524 */
             goto bad_offset;
         }
@@ -130,7 +130,7 @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
         r = s->cfg4;
         break;
     case A_CFG5:
-        if (scc_partno(s) != 0x524) {
+        if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
             /* CFG5 reserved on other boards */
             goto bad_offset;
         }
@@ -185,7 +185,10 @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
 
     switch (offset) {
     case A_CFG0:
-        /* TODO on some boards bit 0 controls RAM remapping */
+        /*
+         * TODO on some boards bit 0 controls RAM remapping;
+         * on others bit 1 is CPU_WAIT.
+         */
         s->cfg0 = value;
         break;
     case A_CFG1:
@@ -195,7 +198,7 @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
         }
         break;
     case A_CFG2:
-        if (scc_partno(s) != 0x524) {
+        if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
             /* CFG2 reserved on other boards */
             goto bad_offset;
         }
@@ -203,7 +206,7 @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
         s->cfg2 = value;
         break;
     case A_CFG5:
-        if (scc_partno(s) != 0x524) {
+        if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
             /* CFG5 reserved on other boards */
             goto bad_offset;
         }
-- 
2.20.1



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

* [PATCH 40/44] hw/arm/mps2-tz: Support running APB peripherals on different clock
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (38 preceding siblings ...)
  2021-02-19 14:46 ` [PATCH 39/44] hw/misc/mps2-scc: Implement changes for AN547 Peter Maydell
@ 2021-02-19 14:46 ` Peter Maydell
  2021-03-04 20:27   ` Philippe Mathieu-Daudé
  2021-03-05  1:01   ` Richard Henderson
  2021-02-19 14:46 ` [PATCH 41/44] hw/arm/mps2-tz: Make initsvtor0 setting board-specific Peter Maydell
                   ` (5 subsequent siblings)
  45 siblings, 2 replies; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:46 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The AN547 runs the APB peripherals outside the SSE-300 on a different
and slightly slower clock than it runs the SSE-300 with.  Support
making the APB peripheral clock frequency board-specific.  (For our
implementation only the UARTs actually take a clock.)

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

diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
index fe324e86b3d..47215f1b97c 100644
--- a/hw/arm/mps2-tz.c
+++ b/hw/arm/mps2-tz.c
@@ -106,6 +106,7 @@ struct MPS2TZMachineClass {
     MPS2TZFPGAType fpga_type;
     uint32_t scc_id;
     uint32_t sysclk_frq; /* Main SYSCLK frequency in Hz */
+    uint32_t apb_periph_frq; /* APB peripheral frequency in Hz */
     uint32_t len_oscclk;
     const uint32_t *oscclk;
     uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
@@ -369,7 +370,7 @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
 
     object_initialize_child(OBJECT(mms), name, uart, TYPE_CMSDK_APB_UART);
     qdev_prop_set_chr(DEVICE(uart), "chardev", serial_hd(i));
-    qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", mmc->sysclk_frq);
+    qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", mmc->apb_periph_frq);
     sysbus_realize(SYS_BUS_DEVICE(uart), &error_fatal);
     s = SYS_BUS_DEVICE(uart);
     sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
@@ -1034,6 +1035,7 @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
     mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
     mmc->scc_id = 0x41045050;
     mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
+    mmc->apb_periph_frq = mmc->sysclk_frq;
     mmc->oscclk = an505_oscclk;
     mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
     mmc->fpgaio_num_leds = 2;
@@ -1059,6 +1061,7 @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
     mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
     mmc->scc_id = 0x41045210;
     mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
+    mmc->apb_periph_frq = mmc->sysclk_frq;
     mmc->oscclk = an505_oscclk; /* AN521 is the same as AN505 here */
     mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
     mmc->fpgaio_num_leds = 2;
@@ -1084,6 +1087,7 @@ static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
     mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
     mmc->scc_id = 0x41045240;
     mmc->sysclk_frq = 32 * 1000 * 1000; /* 32MHz */
+    mmc->apb_periph_frq = mmc->sysclk_frq;
     mmc->oscclk = an524_oscclk;
     mmc->len_oscclk = ARRAY_SIZE(an524_oscclk);
     mmc->fpgaio_num_leds = 10;
-- 
2.20.1



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

* [PATCH 41/44] hw/arm/mps2-tz: Make initsvtor0 setting board-specific
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (39 preceding siblings ...)
  2021-02-19 14:46 ` [PATCH 40/44] hw/arm/mps2-tz: Support running APB peripherals on different clock Peter Maydell
@ 2021-02-19 14:46 ` Peter Maydell
  2021-03-04 20:17   ` Philippe Mathieu-Daudé
  2021-03-05  1:05   ` Richard Henderson
  2021-02-19 14:46 ` [PATCH 42/44] hw/arm/mps2-tz: Add new mps3-an547 board Peter Maydell
                   ` (4 subsequent siblings)
  45 siblings, 2 replies; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:46 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The AN547 configures the SSE-300 with a different initsvtor0
setting from its default; make this a board-specific setting.

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

diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
index 47215f1b97c..bb72f78fb55 100644
--- a/hw/arm/mps2-tz.c
+++ b/hw/arm/mps2-tz.c
@@ -114,6 +114,7 @@ struct MPS2TZMachineClass {
     bool fpgaio_has_dbgctrl; /* Does FPGAIO have DBGCTRL register? */
     int numirq; /* Number of external interrupts */
     int uart_overflow_irq; /* number of the combined UART overflow IRQ */
+    uint32_t init_svtor; /* init-svtor setting for SSE */
     const RAMInfo *raminfo;
     const char *armsse_type;
 };
@@ -690,6 +691,7 @@ static void mps2tz_common_init(MachineState *machine)
     object_property_set_link(OBJECT(&mms->iotkit), "memory",
                              OBJECT(system_memory), &error_abort);
     qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", mmc->numirq);
+    qdev_prop_set_uint32(iotkitdev, "init-svtor", mmc->init_svtor);
     qdev_connect_clock_in(iotkitdev, "MAINCLK", mms->sysclk);
     qdev_connect_clock_in(iotkitdev, "S32KCLK", mms->s32kclk);
     sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
@@ -1043,6 +1045,7 @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
     mmc->fpgaio_has_dbgctrl = false;
     mmc->numirq = 92;
     mmc->uart_overflow_irq = 47;
+    mmc->init_svtor = 0x10000000;
     mmc->raminfo = an505_raminfo;
     mmc->armsse_type = TYPE_IOTKIT;
     mps2tz_set_default_ram_info(mmc);
@@ -1069,6 +1072,7 @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
     mmc->fpgaio_has_dbgctrl = false;
     mmc->numirq = 92;
     mmc->uart_overflow_irq = 47;
+    mmc->init_svtor = 0x10000000;
     mmc->raminfo = an505_raminfo; /* AN521 is the same as AN505 here */
     mmc->armsse_type = TYPE_SSE200;
     mps2tz_set_default_ram_info(mmc);
@@ -1095,6 +1099,7 @@ static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
     mmc->fpgaio_has_dbgctrl = false;
     mmc->numirq = 95;
     mmc->uart_overflow_irq = 47;
+    mmc->init_svtor = 0x10000000;
     mmc->raminfo = an524_raminfo;
     mmc->armsse_type = TYPE_SSE200;
     mps2tz_set_default_ram_info(mmc);
-- 
2.20.1



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

* [PATCH 42/44] hw/arm/mps2-tz: Add new mps3-an547 board
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (40 preceding siblings ...)
  2021-02-19 14:46 ` [PATCH 41/44] hw/arm/mps2-tz: Make initsvtor0 setting board-specific Peter Maydell
@ 2021-02-19 14:46 ` Peter Maydell
  2021-03-05  1:19   ` Richard Henderson
  2021-02-19 14:46 ` [PATCH 43/44] docs/system/arm/mps2.rst: Document the " Peter Maydell
                   ` (3 subsequent siblings)
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:46 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Add support for the mps3-an547 board; this is an SSE-300 based
FPGA image that runs on the MPS3.

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

diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
index bb72f78fb55..a1f43555013 100644
--- a/hw/arm/mps2-tz.c
+++ b/hw/arm/mps2-tz.c
@@ -17,6 +17,7 @@
  *  "mps2-an505" -- Cortex-M33 as documented in ARM Application Note AN505
  *  "mps2-an521" -- Dual Cortex-M33 as documented in Application Note AN521
  *  "mps2-an524" -- Dual Cortex-M33 as documented in Application Note AN524
+ *  "mps2-an547" -- Single Cortex-M55 as documented in Application Note AN547
  *
  * Links to the TRM for the board itself and to the various Application
  * Notes which document the FPGA images can be found here:
@@ -30,6 +31,8 @@
  * https://developer.arm.com/documentation/dai0521/latest/
  * Application Note AN524:
  * https://developer.arm.com/documentation/dai0524/latest/
+ * Application Note AN547:
+ * https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/DAI0547B_SSE300_PLUS_U55_FPGA_for_mps3.pdf
  *
  * The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
  * (ARM ECM0601256) for the details of some of the device layout:
@@ -37,6 +40,8 @@
  * Similarly, the AN521 and AN524 use the SSE-200, and the SSE-200 TRM defines
  * most of the device layout:
  *  https://developer.arm.com/documentation/101104/latest/
+ * and the AN547 uses the SSE-300, whose layout is in the SSE-300 TRM:
+ *  https://developer.arm.com/documentation/101773/latest/
  */
 
 #include "qemu/osdep.h"
@@ -68,13 +73,14 @@
 #include "hw/qdev-clock.h"
 #include "qom/object.h"
 
-#define MPS2TZ_NUMIRQ_MAX 95
-#define MPS2TZ_RAM_MAX 4
+#define MPS2TZ_NUMIRQ_MAX 96
+#define MPS2TZ_RAM_MAX 5
 
 typedef enum MPS2TZFPGAType {
     FPGA_AN505,
     FPGA_AN521,
     FPGA_AN524,
+    FPGA_AN547,
 } MPS2TZFPGAType;
 
 /*
@@ -153,6 +159,7 @@ struct MPS2TZMachineState {
 #define TYPE_MPS2TZ_AN505_MACHINE MACHINE_TYPE_NAME("mps2-an505")
 #define TYPE_MPS2TZ_AN521_MACHINE MACHINE_TYPE_NAME("mps2-an521")
 #define TYPE_MPS3TZ_AN524_MACHINE MACHINE_TYPE_NAME("mps3-an524")
+#define TYPE_MPS3TZ_AN547_MACHINE MACHINE_TYPE_NAME("mps3-an547")
 
 OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
 
@@ -242,6 +249,49 @@ static const RAMInfo an524_raminfo[] = { {
     },
 };
 
+static const RAMInfo an547_raminfo[] = { {
+        .name = "itcm",
+        .base = 0x00000000,
+        .size = 512 * KiB,
+        .mpc = -1,
+        .mrindex = 0,
+    }, {
+        .name = "sram",
+        .base = 0x01000000,
+        .size = 2 * MiB,
+        .mpc = 0,
+        .mrindex = 1,
+    }, {
+        .name = "dtcm",
+        .base = 0x20000000,
+        .size = 4 * 128 * KiB,
+        .mpc = -1,
+        .mrindex = 2,
+    }, {
+        .name = "sram 2",
+        .base = 0x21000000,
+        .size = 4 * MiB,
+        .mpc = -1,
+        .mrindex = 3,
+    }, {
+        /* We don't model QSPI flash yet; for now expose it as simple ROM */
+        .name = "QSPI",
+        .base = 0x28000000,
+        .size = 8 * MiB,
+        .mpc = 1,
+        .mrindex = 4,
+        .flags = IS_ROM,
+    }, {
+        .name = "DDR",
+        .base = 0x60000000,
+        .size = 2 * GiB,
+        .mpc = 2,
+        .mrindex = -1,
+    }, {
+        .name = NULL,
+    },
+};
+
 static const RAMInfo *find_raminfo_for_mpc(MPS2TZMachineState *mms, int mpc)
 {
     MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
@@ -883,6 +933,55 @@ static void mps2tz_common_init(MachineState *machine)
         },
     };
 
+    const PPCInfo an547_ppcs[] = { {
+            .name = "apb_ppcexp0",
+            .ports = {
+                { "ssram-mpc", make_mpc, &mms->mpc[0], 0x57000000, 0x1000 },
+                { "qspi-mpc", make_mpc, &mms->mpc[1], 0x57001000, 0x1000 },
+                { "ddr-mpc", make_mpc, &mms->mpc[2], 0x57002000, 0x1000 },
+            },
+        }, {
+            .name = "apb_ppcexp1",
+            .ports = {
+                { "i2c0", make_i2c, &mms->i2c[0], 0x49200000, 0x1000 },
+                { "i2c1", make_i2c, &mms->i2c[1], 0x49201000, 0x1000 },
+                { "spi0", make_spi, &mms->spi[0], 0x49202000, 0x1000, { 53 } },
+                { "spi1", make_spi, &mms->spi[1], 0x49203000, 0x1000, { 54 } },
+                { "spi2", make_spi, &mms->spi[2], 0x49204000, 0x1000, { 55 } },
+                { "i2c2", make_i2c, &mms->i2c[2], 0x49205000, 0x1000 },
+                { "i2c3", make_i2c, &mms->i2c[3], 0x49206000, 0x1000 },
+                { /* port 7 reserved */ },
+                { "i2c4", make_i2c, &mms->i2c[4], 0x49208000, 0x1000 },
+            },
+        }, {
+            .name = "apb_ppcexp2",
+            .ports = {
+                { "scc", make_scc, &mms->scc, 0x49300000, 0x1000 },
+                { "i2s-audio", make_unimp_dev, &mms->i2s_audio, 0x49301000, 0x1000 },
+                { "fpgaio", make_fpgaio, &mms->fpgaio, 0x49302000, 0x1000 },
+                { "uart0", make_uart, &mms->uart[0], 0x49303000, 0x1000, { 33, 34, 43 } },
+                { "uart1", make_uart, &mms->uart[1], 0x49304000, 0x1000, { 35, 36, 44 } },
+                { "uart2", make_uart, &mms->uart[2], 0x49305000, 0x1000, { 37, 38, 45 } },
+                { "uart3", make_uart, &mms->uart[3], 0x49306000, 0x1000, { 39, 40, 46 } },
+                { "uart4", make_uart, &mms->uart[4], 0x49307000, 0x1000, { 41, 42, 47 } },
+                { "uart5", make_uart, &mms->uart[5], 0x49308000, 0x1000, { 125, 126, 127 } },
+
+                { /* port 9 reserved */ },
+                { "clcd", make_unimp_dev, &mms->cldc, 0x4930a000, 0x1000 },
+                { "rtc", make_rtc, &mms->rtc, 0x4930b000, 0x1000 },
+            },
+        }, {
+            .name = "ahb_ppcexp0",
+            .ports = {
+                { "gpio0", make_unimp_dev, &mms->gpio[0], 0x41100000, 0x1000 },
+                { "gpio1", make_unimp_dev, &mms->gpio[1], 0x41101000, 0x1000 },
+                { "gpio2", make_unimp_dev, &mms->gpio[2], 0x41102000, 0x1000 },
+                { "gpio3", make_unimp_dev, &mms->gpio[3], 0x41103000, 0x1000 },
+                { "eth-usb", make_eth_usb, NULL, 0x41400000, 0x200000, { 49 } },
+            },
+        },
+    };
+
     switch (mmc->fpga_type) {
     case FPGA_AN505:
     case FPGA_AN521:
@@ -893,6 +992,10 @@ static void mps2tz_common_init(MachineState *machine)
         ppcs = an524_ppcs;
         num_ppcs = ARRAY_SIZE(an524_ppcs);
         break;
+    case FPGA_AN547:
+        ppcs = an547_ppcs;
+        num_ppcs = ARRAY_SIZE(an547_ppcs);
+        break;
     default:
         g_assert_not_reached();
     }
@@ -971,6 +1074,11 @@ static void mps2tz_common_init(MachineState *machine)
 
     create_unimplemented_device("FPGA NS PC", 0x48007000, 0x1000);
 
+    if (mmc->fpga_type == FPGA_AN547) {
+        create_unimplemented_device("U55 timing adapter 0", 0x48102000, 0x1000);
+        create_unimplemented_device("U55 timing adapter 1", 0x48103000, 0x1000);
+    }
+
     create_non_mpc_ram(mms);
 
     armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
@@ -1105,6 +1213,33 @@ static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
     mps2tz_set_default_ram_info(mmc);
 }
 
+static void mps3tz_an547_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc);
+
+    mc->desc = "ARM MPS3 with AN547 FPGA image for Cortex-M55";
+    mc->default_cpus = 1;
+    mc->min_cpus = mc->default_cpus;
+    mc->max_cpus = mc->default_cpus;
+    mmc->fpga_type = FPGA_AN547;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m55");
+    mmc->scc_id = 0x41055470;
+    mmc->sysclk_frq = 32 * 1000 * 1000; /* 32MHz */
+    mmc->apb_periph_frq = 25 * 1000 * 1000; /* 25MHz */
+    mmc->oscclk = an524_oscclk; /* same as AN524 */
+    mmc->len_oscclk = ARRAY_SIZE(an524_oscclk);
+    mmc->fpgaio_num_leds = 10;
+    mmc->fpgaio_has_switches = true;
+    mmc->fpgaio_has_dbgctrl = true;
+    mmc->numirq = 96;
+    mmc->uart_overflow_irq = 48;
+    mmc->init_svtor = 0x00000000;
+    mmc->raminfo = an547_raminfo;
+    mmc->armsse_type = TYPE_SSE300;
+    mps2tz_set_default_ram_info(mmc);
+}
+
 static const TypeInfo mps2tz_info = {
     .name = TYPE_MPS2TZ_MACHINE,
     .parent = TYPE_MACHINE,
@@ -1136,12 +1271,19 @@ static const TypeInfo mps3tz_an524_info = {
     .class_init = mps3tz_an524_class_init,
 };
 
+static const TypeInfo mps3tz_an547_info = {
+    .name = TYPE_MPS3TZ_AN547_MACHINE,
+    .parent = TYPE_MPS2TZ_MACHINE,
+    .class_init = mps3tz_an547_class_init,
+};
+
 static void mps2tz_machine_init(void)
 {
     type_register_static(&mps2tz_info);
     type_register_static(&mps2tz_an505_info);
     type_register_static(&mps2tz_an521_info);
     type_register_static(&mps3tz_an524_info);
+    type_register_static(&mps3tz_an547_info);
 }
 
 type_init(mps2tz_machine_init);
-- 
2.20.1



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

* [PATCH 43/44] docs/system/arm/mps2.rst: Document the new mps3-an547 board
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (41 preceding siblings ...)
  2021-02-19 14:46 ` [PATCH 42/44] hw/arm/mps2-tz: Add new mps3-an547 board Peter Maydell
@ 2021-02-19 14:46 ` Peter Maydell
  2021-03-04 20:28   ` Philippe Mathieu-Daudé
  2021-03-05  1:28   ` Richard Henderson
  2021-02-19 14:46 ` [PATCH 44/44] tests/qtest/sse-timer-test: Add simple tests of the SSE timer and counter Peter Maydell
                   ` (2 subsequent siblings)
  45 siblings, 2 replies; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:46 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Add brief documentation of the new mps3-an547 board.

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

diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
index 601ccea15cb..f83b1517871 100644
--- a/docs/system/arm/mps2.rst
+++ b/docs/system/arm/mps2.rst
@@ -1,5 +1,5 @@
-Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``)
-=========================================================================================================================================
+Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an547``)
+=========================================================================================================================================================
 
 These board models all use Arm M-profile CPUs.
 
@@ -27,6 +27,8 @@ QEMU models the following FPGA images:
   Dual Cortex-M33 as documented in Arm Application Note AN521
 ``mps3-an524``
   Dual Cortex-M33 on an MPS3, as documented in Arm Application Note AN524
+``mps3-an547``
+  Cortex-M55 on an MPS3, as documented in Arm Application Note AN547
 
 Differences between QEMU and real hardware:
 
-- 
2.20.1



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

* [PATCH 44/44] tests/qtest/sse-timer-test: Add simple tests of the SSE timer and counter
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (42 preceding siblings ...)
  2021-02-19 14:46 ` [PATCH 43/44] docs/system/arm/mps2.rst: Document the " Peter Maydell
@ 2021-02-19 14:46 ` Peter Maydell
  2021-03-05 11:08   ` Philippe Mathieu-Daudé
  2021-02-19 15:43 ` [PATCH 00/44] hw/arm: New board model mps3-an547 no-reply
  2021-03-05 11:56 ` Philippe Mathieu-Daudé
  45 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-02-19 14:46 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

Add a simple qtest to exercise the new system counter and
system timer device in the SSE-300.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 tests/qtest/sse-timer-test.c | 240 +++++++++++++++++++++++++++++++++++
 MAINTAINERS                  |   1 +
 tests/qtest/meson.build      |   1 +
 3 files changed, 242 insertions(+)
 create mode 100644 tests/qtest/sse-timer-test.c

diff --git a/tests/qtest/sse-timer-test.c b/tests/qtest/sse-timer-test.c
new file mode 100644
index 00000000000..cb29c995077
--- /dev/null
+++ b/tests/qtest/sse-timer-test.c
@@ -0,0 +1,240 @@
+/*
+ * QTest testcase for the SSE timer device
+ *
+ * Copyright (c) 2021 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+#include "libqtest-single.h"
+
+/*
+ * SSE-123/SSE-300 timer in the mps3-an547 board, where it is driven
+ * at 32MHz, so 31.25ns per tick.
+ */
+#define TIMER_BASE 0x48000000
+
+/* PERIPHNSPPC0 register in the SSE-300 Secure Access Configuration block */
+#define PERIPHNSPPC0 (0x50080000 + 0x70)
+
+/* Base of the System Counter control frame */
+#define COUNTER_BASE 0x58100000
+
+/* SSE counter register offsets in the control frame */
+#define CNTCR 0
+#define CNTSR 0x4
+#define CNTCV_LO 0x8
+#define CNTCV_HI 0xc
+#define CNTSCR 0x10
+
+/* SSE timer register offsets */
+#define CNTPCT_LO 0
+#define CNTPCT_HI 4
+#define CNTFRQ 0x10
+#define CNTP_CVAL_LO 0x20
+#define CNTP_CVAL_HI 0x24
+#define CNTP_TVAL 0x28
+#define CNTP_CTL 0x2c
+#define CNTP_AIVAL_LO 0x40
+#define CNTP_AIVAL_HI 0x44
+#define CNTP_AIVAL_RELOAD 0x48
+#define CNTP_AIVAL_CTL 0x4c
+
+/* 4 ticks in nanoseconds (so we can work in integers) */
+#define FOUR_TICKS 125
+
+static void clock_step_ticks(uint64_t ticks)
+{
+    /*
+     * Advance the qtest clock by however many nanoseconds we
+     * need to move the timer forward the specified number of ticks.
+     * ticks must be a multiple of 4, so we get a whole number of ns.
+     */
+    assert(!(ticks & 3));
+    clock_step(FOUR_TICKS * (ticks >> 2));
+}
+
+static void reset_counter_and_timer(void)
+{
+    /*
+     * Reset the system counter and the timer between tests. This
+     * isn't a full reset, but it's sufficient for what the tests check.
+     */
+    writel(COUNTER_BASE + CNTCR, 0);
+    writel(TIMER_BASE + CNTP_CTL, 0);
+    writel(TIMER_BASE + CNTP_AIVAL_CTL, 0);
+    writel(COUNTER_BASE + CNTCV_LO, 0);
+    writel(COUNTER_BASE + CNTCV_HI, 0);
+}
+
+static void test_timer(void)
+{
+    /* Basic timer functionality test */
+
+    reset_counter_and_timer();
+    /*
+     * The timer is behind a Peripheral Protection Controller, and
+     * qtest accesses are always non-secure (no memory attributes),
+     * so we must program the PPC to accept NS transactions.  TIMER0
+     * is on port 0 of PPC0, controlled by bit 0 of this register.
+     */
+    writel(PERIPHNSPPC0, 1);
+    /* We must enable the System Counter or the timer won't run. */
+    writel(COUNTER_BASE + CNTCR, 1);
+
+    /* Timer starts disabled and with a counter of 0 */
+    g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 0);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTPCT_LO), ==, 0);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTPCT_HI), ==, 0);
+
+    /* Turn it on */
+    writel(TIMER_BASE + CNTP_CTL, 1);
+
+    /* Is the timer ticking? */
+    clock_step_ticks(100);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTPCT_LO), ==, 100);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTPCT_HI), ==, 0);
+
+    /* Set the CompareValue to 4000 ticks */
+    writel(TIMER_BASE + CNTP_CVAL_LO, 4000);
+    writel(TIMER_BASE + CNTP_CVAL_HI, 0);
+
+    /* Check TVAL view of the counter */
+    g_assert_cmpuint(readl(TIMER_BASE + CNTP_TVAL), ==, 3900);
+
+    /* Advance to the CompareValue mark and check ISTATUS is set */
+    clock_step_ticks(3900);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTP_TVAL), ==, 0);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 5);
+
+    /* Now exercise the auto-reload part of the timer */
+    writel(TIMER_BASE + CNTP_AIVAL_RELOAD, 200);
+    writel(TIMER_BASE + CNTP_AIVAL_CTL, 1);
+
+    /* Check AIVAL was reloaded and that ISTATUS is now clear */
+    g_assert_cmpuint(readl(TIMER_BASE + CNTP_AIVAL_LO), ==, 4200);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTP_AIVAL_HI), ==, 0);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 1);
+
+    /*
+     * Check that when we advance forward to the reload time the interrupt
+     * fires and the value reloads
+     */
+    clock_step_ticks(100);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 1);
+    clock_step_ticks(100);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 5);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTP_AIVAL_LO), ==, 4400);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTP_AIVAL_HI), ==, 0);
+
+    clock_step_ticks(100);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 5);
+    /* Check that writing 0 to CLR clears the interrupt */
+    writel(TIMER_BASE + CNTP_AIVAL_CTL, 1);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 1);
+    /* Check that when we move forward to the reload time it fires again */
+    clock_step_ticks(100);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 5);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTP_AIVAL_LO), ==, 4600);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTP_AIVAL_HI), ==, 0);
+
+    /*
+     * Step the clock far enough that we overflow the low half of the
+     * CNTPCT and AIVAL registers, and check that their high halves
+     * give the right values. We do the forward movement in
+     * non-autoinc mode because otherwise it takes forever as the
+     * timer has to emulate all the 'reload at t + N, t + 2N, etc'
+     * steps.
+     */
+    writel(TIMER_BASE + CNTP_AIVAL_CTL, 0);
+    clock_step_ticks(0x42ULL << 32);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTPCT_LO), ==, 4400);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTPCT_HI), ==, 0x42);
+
+    /* Turn on the autoinc again to check AIVAL_HI */
+    writel(TIMER_BASE + CNTP_AIVAL_CTL, 1);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTP_AIVAL_LO), ==, 4600);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTP_AIVAL_HI), ==, 0x42);
+}
+
+static void test_counter(void)
+{
+    /* Basic counter functionality test */
+
+    reset_counter_and_timer();
+    /* The counter should start disabled: check that it doesn't move */
+    clock_step_ticks(100);
+    g_assert_cmpuint(readl(COUNTER_BASE + CNTCV_LO), ==, 0);
+    g_assert_cmpuint(readl(COUNTER_BASE + CNTCV_HI), ==, 0);
+    /* Now enable it and check that it does count */
+    writel(COUNTER_BASE + CNTCR, 1);
+    clock_step_ticks(100);
+    g_assert_cmpuint(readl(COUNTER_BASE + CNTCV_LO), ==, 100);
+    g_assert_cmpuint(readl(COUNTER_BASE + CNTCV_HI), ==, 0);
+    /* Check the counter scaling functionality */
+    writel(COUNTER_BASE + CNTCR, 0);
+    writel(COUNTER_BASE + CNTSCR, 0x00100000); /* 1/16th normal speed */
+    writel(COUNTER_BASE + CNTCR, 5); /* EN, SCEN */
+    clock_step_ticks(160);
+    g_assert_cmpuint(readl(COUNTER_BASE + CNTCV_LO), ==, 110);
+    g_assert_cmpuint(readl(COUNTER_BASE + CNTCV_HI), ==, 0);
+}
+
+static void test_timer_scale_change(void)
+{
+    /*
+     * Test that the timer responds correctly to counter
+     * scaling changes while it has an active timer.
+     */
+    reset_counter_and_timer();
+    /* Give ourselves access to the timer, and enable the counter and timer */
+    writel(PERIPHNSPPC0, 1);
+    writel(COUNTER_BASE + CNTCR, 1);
+    writel(TIMER_BASE + CNTP_CTL, 1);
+    /* Set the CompareValue to 4000 ticks */
+    writel(TIMER_BASE + CNTP_CVAL_LO, 4000);
+    writel(TIMER_BASE + CNTP_CVAL_HI, 0);
+    /* Advance halfway and check ISTATUS is not set */
+    clock_step_ticks(2000);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 1);
+    /* Reprogram the counter to run at 1/16th speed */
+    writel(COUNTER_BASE + CNTCR, 0);
+    writel(COUNTER_BASE + CNTSCR, 0x00100000); /* 1/16th normal speed */
+    writel(COUNTER_BASE + CNTCR, 5); /* EN, SCEN */
+    /* Advance to where the timer would have fired and check it has not */
+    clock_step_ticks(2000);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 1);
+    /* Advance to where the timer must fire at the new clock rate */
+    clock_step_ticks(29996);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 1);
+    clock_step_ticks(4);
+    g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 5);
+}
+
+int main(int argc, char **argv)
+{
+    int r;
+
+    g_test_init(&argc, &argv, NULL);
+
+    qtest_start("-machine mps3-an547");
+
+    qtest_add_func("/sse-timer/timer", test_timer);
+    qtest_add_func("/sse-timer/counter", test_counter);
+    qtest_add_func("/sse-timer/timer-scale-change", test_timer_scale_change);
+
+    r = g_test_run();
+
+    qtest_end();
+
+    return r;
+}
diff --git a/MAINTAINERS b/MAINTAINERS
index c2103b40b9b..cbe790add60 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -748,6 +748,7 @@ F: hw/timer/sse-counter.c
 F: include/hw/timer/sse-counter.h
 F: hw/timer/sse-timer.c
 F: include/hw/timer/sse-timer.h
+F: tests/qtest/sse-timer-test.c
 F: docs/system/arm/mps2.rst
 
 Musca
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index c83bc211b6a..f38ebbf67c3 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -142,6 +142,7 @@ qtests_npcm7xx = \
    'npcm7xx_timer-test',
    'npcm7xx_watchdog_timer-test']
 qtests_arm = \
+  (config_all_devices.has_key('CONFIG_MPS2') ? ['sse-timer-test'] : []) + \
   (config_all_devices.has_key('CONFIG_CMSDK_APB_DUALTIMER') ? ['cmsdk-apb-dualtimer-test'] : []) + \
   (config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
   (config_all_devices.has_key('CONFIG_CMSDK_APB_WATCHDOG') ? ['cmsdk-apb-watchdog-test'] : []) + \
-- 
2.20.1



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

* Re: [PATCH 00/44] hw/arm: New board model mps3-an547
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (43 preceding siblings ...)
  2021-02-19 14:46 ` [PATCH 44/44] tests/qtest/sse-timer-test: Add simple tests of the SSE timer and counter Peter Maydell
@ 2021-02-19 15:43 ` no-reply
  2021-03-05 11:56 ` Philippe Mathieu-Daudé
  45 siblings, 0 replies; 103+ messages in thread
From: no-reply @ 2021-02-19 15:43 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-arm, qemu-devel

Patchew URL: https://patchew.org/QEMU/20210219144617.4782-1-peter.maydell@linaro.org/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20210219144617.4782-1-peter.maydell@linaro.org
Subject: [PATCH 00/44] hw/arm: New board model mps3-an547

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
   c79f01c..6de76c5  master     -> master
 - [tag update]      patchew/20210219120422.600850-1-armbru@redhat.com -> patchew/20210219120422.600850-1-armbru@redhat.com
 * [new tag]         patchew/20210219144617.4782-1-peter.maydell@linaro.org -> patchew/20210219144617.4782-1-peter.maydell@linaro.org
Switched to a new branch 'test'
9f50b75 tests/qtest/sse-timer-test: Add simple tests of the SSE timer and counter
5721ef1 docs/system/arm/mps2.rst: Document the new mps3-an547 board
8f4f44d hw/arm/mps2-tz: Add new mps3-an547 board
56ae353 hw/arm/mps2-tz: Make initsvtor0 setting board-specific
cedcec0 hw/arm/mps2-tz: Support running APB peripherals on different clock
8a3cb29 hw/misc/mps2-scc: Implement changes for AN547
d7aba2f hw/misc/mps2-fpgaio: Support AN547 DBGCTRL register
0196623 hw/misc/mps2-fpgaio: Fold counters subsection into main vmstate
cb9bc35 hw/arm/mps2-tz: Make UART overflow IRQ board-specific
e88392d hw/arm/armsse: Add SSE-300 support
7dfad6e hw/arm/armsse: Support variants with ARMSSE_CPU_PWRCTRL block
8743323 hw/arm/armsse: Add support for TYPE_SSE_TIMER in ARMSSEDeviceInfo
2e453a2 hw/arm/armsse: Add support for SSE variants with a system counter
b306dd5 hw/arm/armsse: Indirect irq_is_common[] through ARMSSEInfo
d256d57 hw/arm/armsse: Add missing SSE-200 SYS_PPU
f9d119e hw/arm/armsse: Move PPUs into data-driven framework
505892c hw/arm/armsse: Move sysctl register block into data-driven framework
71cb081 hw/arm/armsse: Move sysinfo register block into data-driven framework
4d82c84 hw/arm/armsse: Move s32ktimer into data-driven framework
95a46fc hw/arm/armsse: Move watchdogs into data-driven framework
caebd17 hw/arm/armsse: Move dual-timer device into data-driven framework
40f2c7d hw/arm/armsse: Add framework for data-driven device placement
2fbd6a8 hw/arm/armsse: Add a define for number of IRQs used by the SSE itself
3ae2516 hw/arm/armsse: Use an array for apb_ppc fields in the state structure
dc77980 hw/misc/sse-cpu-pwrctrl: Implement SSE-300 CPU<N>_PWRCTRL register block
ffa29a9 hw/arm/Kconfig: Move ARMSSE_CPUID and ARMSSE_MHU stanzas to hw/misc
c716381 hw/misc/iotkit-sysctl: Implement SSE-200 and SSE-300 PID register values
8ce7637 hw/misc/iotkit-sysctl: Handle SSE-300 changes to PDCM_PD_*_SENSE registers
9d4b193 hw/misc/iotkit-sysctl: Implement dummy version of SSE-300 PWRCTRL register
6cec0a9 hw/misc/iotkit-sysctl: Handle INITSVTOR* for SSE-300
2f8e871 hw/misc/iotkit-sysctl: Handle CPU_WAIT, NMI_ENABLE for SSE-300
29de343 hw/misc/iotkit-sysctl: Add SSE-300 cases which match SSE-200 behaviour
8023c4f hw/timer/sse-timer: Model the SSE Subsystem System Timer
a94b08a hw/timer/sse-counter: Model the SSE Subsystem System Counter
ef374a1 hw/misc/iotkit-sysinfo.c: Implement SYS_CONFIG1 and IIDR
4577400 hw/arm/armsse.c: Use correct SYS_CONFIG0 register value for SSE-300
5edfae6 hw/misc/iotkit-sysinfo.c: Implement SSE-300 PID register values
2e20f8d hw/misc/iotkit-secctl.c: Implement SSE-300 PID register values
311ed7f hw/misc/iotkit-sysctl: Remove is_sse200 flag
d9ebf7b hw/arm/armsse: Introduce SSE subsystem version property
480ef06 hw/timer/npcm7xx_timer: Use new clock_ns_to_ticks()
66bec50 clock: Add clock_ns_to_ticks() function
463dd4b clock: Add ClockPreUpdate callback event type
8af60a1 clock: Add ClockEvent parameter to callbacks

=== OUTPUT BEGIN ===
1/44 Checking commit 8af60a13fd16 (clock: Add ClockEvent parameter to callbacks)
WARNING: line over 80 characters
#552: FILE: hw/misc/zynq_slcr.c:580:
+    QDEV_CLOCK_IN(ZynqSLCRState, ps_clk, zynq_slcr_ps_clk_callback, ClockUpdate),

total: 0 errors, 1 warnings, 592 lines checked

Patch 1/44 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
2/44 Checking commit 463dd4bcfb89 (clock: Add ClockPreUpdate callback event type)
3/44 Checking commit 66bec50bf71e (clock: Add clock_ns_to_ticks() function)
4/44 Checking commit 480ef0656650 (hw/timer/npcm7xx_timer: Use new clock_ns_to_ticks())
5/44 Checking commit d9ebf7be3922 (hw/arm/armsse: Introduce SSE subsystem version property)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#130: 
new file mode 100644

total: 0 errors, 1 warnings, 129 lines checked

Patch 5/44 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
6/44 Checking commit 311ed7f81f89 (hw/misc/iotkit-sysctl: Remove is_sse200 flag)
WARNING: line over 80 characters
#245: FILE: hw/misc/iotkit-sysctl.c:375:
+            qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SYSCLK_DIV unimplemented\n");

WARNING: line over 80 characters
#260: FILE: hw/misc/iotkit-sysctl.c:387:
+            qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CLOCK_FORCE unimplemented\n");

WARNING: line over 80 characters
#391: FILE: hw/misc/iotkit-sysctl.c:489:
+            qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");

total: 0 errors, 3 warnings, 392 lines checked

Patch 6/44 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
7/44 Checking commit 2e20f8da2f2c (hw/misc/iotkit-secctl.c: Implement SSE-300 PID register values)
8/44 Checking commit 5edfae6d740b (hw/misc/iotkit-sysinfo.c: Implement SSE-300 PID register values)
9/44 Checking commit 45774005e911 (hw/arm/armsse.c: Use correct SYS_CONFIG0 register value for SSE-300)
10/44 Checking commit ef374a100126 (hw/misc/iotkit-sysinfo.c: Implement SYS_CONFIG1 and IIDR)
11/44 Checking commit a94b08ad84ba (hw/timer/sse-counter: Model the SSE Subsystem System Counter)
12/44 Checking commit 8023c4f73f96 (hw/timer/sse-timer: Model the SSE Subsystem System Timer)
WARNING: line over 80 characters
#525: FILE: hw/timer/sse-timer.c:443:
+    DEFINE_PROP_LINK("counter", SSETimer, counter, TYPE_SSE_COUNTER, SSECounter *),

total: 0 errors, 1 warnings, 561 lines checked

Patch 12/44 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
13/44 Checking commit 29de34333dbd (hw/misc/iotkit-sysctl: Add SSE-300 cases which match SSE-200 behaviour)
14/44 Checking commit 2f8e871626f0 (hw/misc/iotkit-sysctl: Handle CPU_WAIT, NMI_ENABLE for SSE-300)
WARNING: line over 80 characters
#162: FILE: hw/misc/iotkit-sysctl.c:481:
+            qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");

total: 0 errors, 1 warnings, 138 lines checked

Patch 14/44 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
15/44 Checking commit 6cec0a9166a9 (hw/misc/iotkit-sysctl: Handle INITSVTOR* for SSE-300)
16/44 Checking commit 9d4b193da770 (hw/misc/iotkit-sysctl: Implement dummy version of SSE-300 PWRCTRL register)
17/44 Checking commit 8ce7637ee794 (hw/misc/iotkit-sysctl: Handle SSE-300 changes to PDCM_PD_*_SENSE registers)
18/44 Checking commit c716381e120c (hw/misc/iotkit-sysctl: Implement SSE-200 and SSE-300 PID register values)
19/44 Checking commit ffa29a93bd0a (hw/arm/Kconfig: Move ARMSSE_CPUID and ARMSSE_MHU stanzas to hw/misc)
20/44 Checking commit dc77980485cf (hw/misc/sse-cpu-pwrctrl: Implement SSE-300 CPU<N>_PWRCTRL register block)
21/44 Checking commit 3ae2516f1ad2 (hw/arm/armsse: Use an array for apb_ppc fields in the state structure)
22/44 Checking commit 2fbd6a885f8e (hw/arm/armsse: Add a define for number of IRQs used by the SSE itself)
23/44 Checking commit 40f2c7de310c (hw/arm/armsse: Add framework for data-driven device placement)
24/44 Checking commit caebd17875a5 (hw/arm/armsse: Move dual-timer device into data-driven framework)
25/44 Checking commit 95a46fc57c93 (hw/arm/armsse: Move watchdogs into data-driven framework)
26/44 Checking commit 4d82c84b1328 (hw/arm/armsse: Move s32ktimer into data-driven framework)
27/44 Checking commit 71cb0813e119 (hw/arm/armsse: Move sysinfo register block into data-driven framework)
28/44 Checking commit 505892cce1df (hw/arm/armsse: Move sysctl register block into data-driven framework)
29/44 Checking commit f9d119e5c005 (hw/arm/armsse: Move PPUs into data-driven framework)
30/44 Checking commit d256d5716097 (hw/arm/armsse: Add missing SSE-200 SYS_PPU)
31/44 Checking commit b306dd56e51b (hw/arm/armsse: Indirect irq_is_common[] through ARMSSEInfo)
32/44 Checking commit 2e453a2b7b25 (hw/arm/armsse: Add support for SSE variants with a system counter)
33/44 Checking commit 87433233c730 (hw/arm/armsse: Add support for TYPE_SSE_TIMER in ARMSSEDeviceInfo)
34/44 Checking commit 7dfad6e8b373 (hw/arm/armsse: Support variants with ARMSSE_CPU_PWRCTRL block)
35/44 Checking commit e88392d4ecf9 (hw/arm/armsse: Add SSE-300 support)
36/44 Checking commit cb9bc357dbe5 (hw/arm/mps2-tz: Make UART overflow IRQ board-specific)
37/44 Checking commit 0196623c8264 (hw/misc/mps2-fpgaio: Fold counters subsection into main vmstate)
38/44 Checking commit d7aba2ff0c17 (hw/misc/mps2-fpgaio: Support AN547 DBGCTRL register)
39/44 Checking commit 8a3cb29dde24 (hw/misc/mps2-scc: Implement changes for AN547)
40/44 Checking commit cedcec0ea104 (hw/arm/mps2-tz: Support running APB peripherals on different clock)
41/44 Checking commit 56ae353735b9 (hw/arm/mps2-tz: Make initsvtor0 setting board-specific)
42/44 Checking commit 8f4f44decdaa (hw/arm/mps2-tz: Add new mps3-an547 board)
WARNING: Block comments use a leading /* on a separate line
#143: FILE: hw/arm/mps2-tz.c:953:
+                { /* port 7 reserved */ },

WARNING: line over 80 characters
#150: FILE: hw/arm/mps2-tz.c:960:
+                { "i2s-audio", make_unimp_dev, &mms->i2s_audio, 0x49301000, 0x1000 },

WARNING: line over 80 characters
#152: FILE: hw/arm/mps2-tz.c:962:
+                { "uart0", make_uart, &mms->uart[0], 0x49303000, 0x1000, { 33, 34, 43 } },

WARNING: line over 80 characters
#153: FILE: hw/arm/mps2-tz.c:963:
+                { "uart1", make_uart, &mms->uart[1], 0x49304000, 0x1000, { 35, 36, 44 } },

WARNING: line over 80 characters
#154: FILE: hw/arm/mps2-tz.c:964:
+                { "uart2", make_uart, &mms->uart[2], 0x49305000, 0x1000, { 37, 38, 45 } },

WARNING: line over 80 characters
#155: FILE: hw/arm/mps2-tz.c:965:
+                { "uart3", make_uart, &mms->uart[3], 0x49306000, 0x1000, { 39, 40, 46 } },

WARNING: line over 80 characters
#156: FILE: hw/arm/mps2-tz.c:966:
+                { "uart4", make_uart, &mms->uart[4], 0x49307000, 0x1000, { 41, 42, 47 } },

ERROR: line over 90 characters
#157: FILE: hw/arm/mps2-tz.c:967:
+                { "uart5", make_uart, &mms->uart[5], 0x49308000, 0x1000, { 125, 126, 127 } },

WARNING: Block comments use a leading /* on a separate line
#159: FILE: hw/arm/mps2-tz.c:969:
+                { /* port 9 reserved */ },

total: 1 errors, 8 warnings, 223 lines checked

Patch 42/44 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

43/44 Checking commit 5721ef19d42c (docs/system/arm/mps2.rst: Document the new mps3-an547 board)
44/44 Checking commit 9f50b7570a19 (tests/qtest/sse-timer-test: Add simple tests of the SSE timer and counter)
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20210219144617.4782-1-peter.maydell@linaro.org/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

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

* Re: [PATCH 19/44] hw/arm/Kconfig: Move ARMSSE_CPUID and ARMSSE_MHU stanzas to hw/misc
  2021-02-19 14:45 ` [PATCH 19/44] hw/arm/Kconfig: Move ARMSSE_CPUID and ARMSSE_MHU stanzas to hw/misc Peter Maydell
@ 2021-02-21 13:31   ` Philippe Mathieu-Daudé
  2021-03-04 19:57   ` Richard Henderson
  1 sibling, 0 replies; 103+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-02-21 13:31 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 3:45 PM, Peter Maydell wrote:
> The ARMSSE_CPUID and ARMSSE_MHU Kconfig stanzas are for the devices
> implmemented by hw/misc/cpuid.c and hw/misc/armsse-mhu.c.  Move them
> to hw/misc/Kconfig where they belong.

Typo "implemented", otherwise:
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/arm/Kconfig  | 6 ------
>  hw/misc/Kconfig | 6 ++++++
>  2 files changed, 6 insertions(+), 6 deletions(-)


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

* Re: [PATCH 21/44] hw/arm/armsse: Use an array for apb_ppc fields in the state structure
  2021-02-19 14:45 ` [PATCH 21/44] hw/arm/armsse: Use an array for apb_ppc fields in the state structure Peter Maydell
@ 2021-02-21 13:34   ` Philippe Mathieu-Daudé
  2021-03-04 20:04   ` Richard Henderson
  1 sibling, 0 replies; 103+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-02-21 13:34 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 3:45 PM, Peter Maydell wrote:
> Convert the apb_ppc0 and apb_ppc1 fields in the ARMSSE state struct
> to use an array instead of two separate fields.  We already had one
> place in the code that wanted to be able to refer to the PPC by
> index, and we're about to add more code like that.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  include/hw/arm/armsse.h |  6 +++---
>  hw/arm/armsse.c         | 32 ++++++++++++++++++--------------
>  2 files changed, 21 insertions(+), 17 deletions(-)

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


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

* Re: [PATCH 22/44] hw/arm/armsse: Add a define for number of IRQs used by the SSE itself
  2021-02-19 14:45 ` [PATCH 22/44] hw/arm/armsse: Add a define for number of IRQs used by the SSE itself Peter Maydell
@ 2021-02-21 13:34   ` Philippe Mathieu-Daudé
  2021-03-04 20:04   ` Richard Henderson
  1 sibling, 0 replies; 103+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-02-21 13:34 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 3:45 PM, Peter Maydell wrote:
> The SSE uses 32 interrupts for its own devices, and then passes through
> its expansion IRQ inputs to the CPU's interrupts 33 and upward.
> Add a define for the number of IRQs the SSE uses for itself, instead
> of hardcoding 32.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  include/hw/arm/armsse.h | 5 ++++-
>  hw/arm/armsse.c         | 4 ++--
>  2 files changed, 6 insertions(+), 3 deletions(-)

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


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

* Re: [PATCH 01/44] clock: Add ClockEvent parameter to callbacks
  2021-02-19 14:45 ` [PATCH 01/44] clock: Add ClockEvent parameter to callbacks Peter Maydell
@ 2021-03-04  2:50   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04  2:50 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:45 AM, Peter Maydell wrote:
> The Clock framework allows users to specify a callback which is
> called after the clock's period has been updated.  Some users need to
> also have a callback which is called before the clock period is
> updated.
> 
> As the first step in adding support for notifying Clock users on
> pre-update events, add an argument to the ClockCallback to specify
> what event is being notified, and add an argument to the various
> functions for registering a callback to specify which events are
> of interest to that callback.
> 
> Note that the documentation update renders correct the previously
> incorrect claim in 'Adding a new clock' that callbacks "will be
> explained in a following section".
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> Reviewed-by: Philippe Mathieu-Daudé<f4bug@amsat.org>
> Reviewed-by: Luc Michel<luc@lmichel.fr>
> ---

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

r~



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

* Re: [PATCH 05/44] hw/arm/armsse: Introduce SSE subsystem version property
  2021-02-19 14:45 ` [PATCH 05/44] hw/arm/armsse: Introduce SSE subsystem version property Peter Maydell
@ 2021-03-04 17:10   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 17:10 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:45 AM, Peter Maydell wrote:
> We model Arm "Subsystems for Embedded" SoC subsystems using generic
> code which is split into various sub-devices which are configurable
> by QOM properties to handle the behaviour differences between the SSE
> subsystems we implement.  Currently the only sub-device which needs
> to change is the IOTKIT_SYSCTL device, and we do this with a mix of
> properties that directly specify divergent behaviours (eg
> CPUWAIT_RST) and passing it the SYS_VERSION register value as a way
> for it to distinguish IoTKit from SSE-200.
> 
> The "pass SYS_VERSION" approach is already a bit hacky, since the
> IOTKIT_SYSCTL device has to know that the different part of the
> register value happens to be bits [31:28].  For SSE-300 this register
> is renamed SOC_IDENTITY and has a different format entirely, all of
> whose fields can be configured by the SoC integrator when they
> integrate the SSE into their SoC, and so "pass SYS_VERSION" breaks
> down completely.
> 
> Switch to using a simple integer property representing an
> internal-to-QEMU enumeration of the SSE flavour.  For the moment we
> only need this in IOTKIT_SYSCTL, but as we add SSE-300 support a few
> of the other devices will also need to know.
> 
> We define and permit a value for the SSE-300 so we can start using
> it in subsequent commits which add SSE-300 support.
> 
> The now-redundant is_sse200 flag in IoTKitSysCtl will be removed
> in the following commit.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>

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

r~



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

* Re: [PATCH 06/44] hw/misc/iotkit-sysctl: Remove is_sse200 flag
  2021-02-19 14:45 ` [PATCH 06/44] hw/misc/iotkit-sysctl: Remove is_sse200 flag Peter Maydell
@ 2021-03-04 17:13   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 17:13 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:45 AM, Peter Maydell wrote:
> Remove the is_sse200 flag in favour of just directly testing the new
> sse_version field.
> 
> Since some of these registers exist in the SSE-300 but some do not or
> have different behaviour, we expand out the if() statements in the
> read and write functions into switch()es, so we have an easy place to
> put SSE-300 specific behaviour.
> 
> (Until we do add the SSE-300 behaviour, the thing preventing us
> reaching the "unreachable" default cases is that armsse.c doesn't
> yet pass us an ARMSSE_SSE300 version.)
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---
>   include/hw/misc/iotkit-sysctl.h |   2 -
>   hw/misc/iotkit-sysctl.c         | 256 +++++++++++++++++++++++---------
>   2 files changed, 187 insertions(+), 71 deletions(-)

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

r~




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

* Re: [PATCH 07/44] hw/misc/iotkit-secctl.c: Implement SSE-300 PID register values
  2021-02-19 14:45 ` [PATCH 07/44] hw/misc/iotkit-secctl.c: Implement SSE-300 PID register values Peter Maydell
@ 2021-03-04 17:29   ` Richard Henderson
  2021-03-04 17:51     ` Richard Henderson
  0 siblings, 1 reply; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 17:29 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:45 AM, Peter Maydell wrote:
> The versions of the Secure Access Configuration Register Block
> and Non-secure Access Configuration Register Block in the SSE-300
> are the same as those in the SSE-200, but the CIDR/PIDR ID
> register values are different.
> 
> Plumb through the sse-version property and use it to select
> the correct ID register values.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---
>   include/hw/misc/iotkit-secctl.h |  2 ++
>   hw/arm/armsse.c                 |  2 ++
>   hw/misc/iotkit-secctl.c         | 50 +++++++++++++++++++++++++++++++--
>   3 files changed, 52 insertions(+), 2 deletions(-)

Which document am I looking for here?  I found DAI 0547B "Application Note 
AN547", but I don't see these register definitions.

Apart from validating the constant values, the actual code looks good.

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

r~


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

* Re: [PATCH 08/44] hw/misc/iotkit-sysinfo.c: Implement SSE-300 PID register values
  2021-02-19 14:45 ` [PATCH 08/44] hw/misc/iotkit-sysinfo.c: " Peter Maydell
@ 2021-03-04 17:35   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 17:35 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:45 AM, Peter Maydell wrote:
> The version of the SYSINFO Register Block in the SSE-300 has
> different CIDR/PIDR register values to the SSE-200; pass in
> the sse-version property and use it to select the correct
> ID register values.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---
>   include/hw/misc/iotkit-sysinfo.h |  1 +
>   hw/arm/armsse.c                  |  2 ++
>   hw/misc/iotkit-sysinfo.c         | 29 +++++++++++++++++++++++++++--
>   3 files changed, 30 insertions(+), 2 deletions(-)

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

r~


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

* Re: [PATCH 09/44] hw/arm/armsse.c: Use correct SYS_CONFIG0 register value for SSE-300
  2021-02-19 14:45 ` [PATCH 09/44] hw/arm/armsse.c: Use correct SYS_CONFIG0 register value for SSE-300 Peter Maydell
@ 2021-03-04 17:39   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 17:39 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:45 AM, Peter Maydell wrote:
> In the SSE-300, the format of the SYS_CONFIG0 register has changed again;
> pass through the correct value to the SYSINFO register block device.
> 
> We drop the old SysConfigFormat enum, which was implemented in the
> hope that different flavours of SSE would share the same format;
> since they all seem to be different and we now have an sse_version
> enum to key off, just use that.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---
>   hw/arm/armsse.c | 21 +++++++++------------
>   1 file changed, 9 insertions(+), 12 deletions(-)

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

r~


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

* Re: [PATCH 07/44] hw/misc/iotkit-secctl.c: Implement SSE-300 PID register values
  2021-03-04 17:29   ` Richard Henderson
@ 2021-03-04 17:51     ` Richard Henderson
  2021-03-04 19:28       ` Peter Maydell
  0 siblings, 1 reply; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 17:51 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 3/4/21 9:29 AM, Richard Henderson wrote:
> On 2/19/21 6:45 AM, Peter Maydell wrote:
>> The versions of the Secure Access Configuration Register Block
>> and Non-secure Access Configuration Register Block in the SSE-300
>> are the same as those in the SSE-200, but the CIDR/PIDR ID
>> register values are different.
>>
>> Plumb through the sse-version property and use it to select
>> the correct ID register values.
>>
>> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
>> ---
>>   include/hw/misc/iotkit-secctl.h |  2 ++
>>   hw/arm/armsse.c                 |  2 ++
>>   hw/misc/iotkit-secctl.c         | 50 +++++++++++++++++++++++++++++++--
>>   3 files changed, 52 insertions(+), 2 deletions(-)
> 
> Which document am I looking for here?  I found DAI 0547B "Application Note 
> AN547", but I don't see these register definitions.

I finally found the sse-300 subsystem trm: 101773_0000_02_en.

r~


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

* Re: [PATCH 10/44] hw/misc/iotkit-sysinfo.c: Implement SYS_CONFIG1 and IIDR
  2021-02-19 14:45 ` [PATCH 10/44] hw/misc/iotkit-sysinfo.c: Implement SYS_CONFIG1 and IIDR Peter Maydell
@ 2021-03-04 17:54   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 17:54 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:45 AM, Peter Maydell wrote:
> For SSE-300, the SYSINFO register block has two new registers:
> 
>   * SYS_CONFIG1 indicates the config for a potential CPU2 and CPU3;
>     since the SSE-300 can only be configured with a single CPU it
>     is always zero
> 
>   * IIDR is the subsystem implementation identity register;
>     its value is set by the SoC integrator, so we plumb this in from
>     the armsse.c code as we do with SYS_VERSION and SYS_CONFIG
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---
>   include/hw/misc/iotkit-sysinfo.h |  1 +
>   hw/arm/armsse.c                  |  5 +++++
>   hw/misc/iotkit-sysinfo.c         | 22 ++++++++++++++++++++++
>   3 files changed, 28 insertions(+)

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

r~


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

* Re: [PATCH 11/44] hw/timer/sse-counter: Model the SSE Subsystem System Counter
  2021-02-19 14:45 ` [PATCH 11/44] hw/timer/sse-counter: Model the SSE Subsystem System Counter Peter Maydell
@ 2021-03-04 18:38   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 18:38 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:45 AM, Peter Maydell wrote:
> The SSE-300 includes a counter module; implement a model of it.
> 
> This counter is documented in the SSE-123 Example Subsystem
> Technical Reference Manual:
>   https://developer.arm.com/documentation/101370/latest/
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 12/44] hw/timer/sse-timer: Model the SSE Subsystem System Timer
  2021-02-19 14:45 ` [PATCH 12/44] hw/timer/sse-timer: Model the SSE Subsystem System Timer Peter Maydell
@ 2021-03-04 19:11   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 19:11 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:45 AM, Peter Maydell wrote:
> The SSE-300 includes some timers which are a different kind to
> those in the SSE-200. Model them.
> 
> These timers are documented in the SSE-123 Example Subsystem
> Technical Reference Manual:
>   https://developer.arm.com/documentation/101370/latest/
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 13/44] hw/misc/iotkit-sysctl: Add SSE-300 cases which match SSE-200 behaviour
  2021-02-19 14:45 ` [PATCH 13/44] hw/misc/iotkit-sysctl: Add SSE-300 cases which match SSE-200 behaviour Peter Maydell
@ 2021-03-04 19:13   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 19:13 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:45 AM, Peter Maydell wrote:
> The SSE-300's iokit-sysctl device is similar to the SSE-200, but
> some registers have moved address or have different behaviours.
> In this commit we add case statements for the registers where
> the SSE-300 and SSE-200 have the same behaviour. Some registers
> are the same on all SSE versions and so need no code change at all.
> Putting both of these categories together covers:
> 
> 0x0 SECDBGSTAT
> 0x4 SECDBGSET
> 0x8 SECDBGCLR
> 0xc SCSECCTRL
> 0x10 CLK_CFG0 -- this is like SSE-200 FCLK_DIV but with a
>     different set of clocks being controlled; our implementation
>     is a dummy reads-as-written anyway
> 0x14 CLK_CFG1 -- similar to SSE-200 SYSCLK_DIV; our implementation
>     is a dummy
> 0x18 CLK_FORCE -- similar to SSE-200 but different bit allocations;
>     we have a dummy implementation
> 0x100 RESET_SYNDROME -- bit allocation differs from SSE-200 but our
>     implementation is a dummy
> 0x104 RESET_MASK -- bit allocation differs from SSE-200 but our
>     implementation is a dummy
> 0x108 SWRESET
> 0x10c GRETREG
> 0x200 PDCM_PD_SYS_SENSE -- some bit allocations differ, but our
>     implementation is a dummy
> 
> We also need to migrate the state of these registers which are shared
> between the SSE-200 and SSE-300, so update the vmstate 'needed'
> function to do this.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 07/44] hw/misc/iotkit-secctl.c: Implement SSE-300 PID register values
  2021-03-04 17:51     ` Richard Henderson
@ 2021-03-04 19:28       ` Peter Maydell
  0 siblings, 0 replies; 103+ messages in thread
From: Peter Maydell @ 2021-03-04 19:28 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, QEMU Developers

On Thu, 4 Mar 2021 at 17:51, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> On 3/4/21 9:29 AM, Richard Henderson wrote:
> > On 2/19/21 6:45 AM, Peter Maydell wrote:
> >> The versions of the Secure Access Configuration Register Block
> >> and Non-secure Access Configuration Register Block in the SSE-300
> >> are the same as those in the SSE-200, but the CIDR/PIDR ID
> >> register values are different.
> >>
> >> Plumb through the sse-version property and use it to select
> >> the correct ID register values.
> >>
> >> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> >> ---
> >>   include/hw/misc/iotkit-secctl.h |  2 ++
> >>   hw/arm/armsse.c                 |  2 ++
> >>   hw/misc/iotkit-secctl.c         | 50 +++++++++++++++++++++++++++++++--
> >>   3 files changed, 52 insertions(+), 2 deletions(-)
> >
> > Which document am I looking for here?  I found DAI 0547B "Application Note
> > AN547", but I don't see these register definitions.
>
> I finally found the sse-300 subsystem trm: 101773_0000_02_en.

https://developer.arm.com/documentation/101773/latest/

The URL does turn up in this patchset, but not til patch 42 :-/

thanks
-- PMM


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

* Re: [PATCH 14/44] hw/misc/iotkit-sysctl: Handle CPU_WAIT, NMI_ENABLE for SSE-300
  2021-02-19 14:45 ` [PATCH 14/44] hw/misc/iotkit-sysctl: Handle CPU_WAIT, NMI_ENABLE for SSE-300 Peter Maydell
@ 2021-03-04 19:34   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 19:34 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:45 AM, Peter Maydell wrote:
> In the SSE-300 the CPU_WAIT and NMI_ENABLE registers have
> moved offsets, so they are now where the SSE-200's WICCTRL
> and EWCTRL were. The SSE-300 does not have WICCTLR or EWCTRL
> at all, and the old offsets are reserved:
> 
>   Offset    SSE-200      SSE-300
> -----------------------------------
>   0x118     CPUWAIT      reserved
>   0x118     NMI_ENABLE   reserved

     0x11c

>   0x120     WICCTRL      CPUWAIT
>   0x124     EWCTRL       NMI_ENABLE
> 
> Handle this reshuffle, and the fact that SSE-300 has only
> one CPU and so only one active bit in CPUWAIT.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

What an irritating and pointless change.

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

r~


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

* Re: [PATCH 15/44] hw/misc/iotkit-sysctl: Handle INITSVTOR* for SSE-300
  2021-02-19 14:45 ` [PATCH 15/44] hw/misc/iotkit-sysctl: Handle INITSVTOR* " Peter Maydell
@ 2021-03-04 19:38   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 19:38 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:45 AM, Peter Maydell wrote:
> +            s->initsvtor0 = value;
> +            set_init_vtor(0, s->initsvtor0 & ~R_INITSVTOR0_LOCK_MASK);

As long as you're clearing bits, initsvtor0 begins at bit 7.

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

r~


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

* Re: [PATCH 16/44] hw/misc/iotkit-sysctl: Implement dummy version of SSE-300 PWRCTRL register
  2021-02-19 14:45 ` [PATCH 16/44] hw/misc/iotkit-sysctl: Implement dummy version of SSE-300 PWRCTRL register Peter Maydell
@ 2021-03-04 19:49   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 19:49 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:45 AM, Peter Maydell wrote:
> The SSE-300 has a new PWRCTRL register at offset 0x1fc (previously
> reserved). This register controls accessibility of some registers
> in the Power Policy Units (PPUs). Since QEMU doesn't implement
> the PPUs, we don't need to implement any real behaviour for this
> register, so we just handle the UNLOCK bit which controls whether
> writes to the register itself are permitted and otherwise make it
> be reads-as-written.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 17/44] hw/misc/iotkit-sysctl: Handle SSE-300 changes to PDCM_PD_*_SENSE registers
  2021-02-19 14:45 ` [PATCH 17/44] hw/misc/iotkit-sysctl: Handle SSE-300 changes to PDCM_PD_*_SENSE registers Peter Maydell
@ 2021-03-04 19:52   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 19:52 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:45 AM, Peter Maydell wrote:
> The sysctl PDCM_PD_*_SENSE registers control various power domains in
> the system and allow the guest to configure which conditions keep a
> power domain awake and what power state to use when the domain is in
> a low power state.  QEMU doesn't model power domains, so for us these
> registers are dummy reads-as-written implementations.
> 
> The SSE-300 has a different power domain setup, so the set of
> registers is slightly different:
> 
>   Offset   SSE-200               SSE-300
> ---------------------------------------------------
>   0x200    PDCM_PD_SYS_SENSE     PDCM_PD_SYS_SENSE
>   0x204    reserved              PDCM_PD_CPU0_SENSE
>   0x208    reserved              reserved
>   0x20c    PDCM_PD_SRAM0_SENSE   reserved
>   0x210    PDCM_PD_SRAM1_SENSE   reserved
>   0x214    PDCM_PD_SRAM2_SENSE   PDCM_PD_VMR0_SENSE
>   0x218    PDCM_PD_SRAM3_SENSE   PDCM_PD_VMR1_SENSE
> 
> Offsets 0x200 and 0x208 are the same for both, so handled in a
> previous commit; here we deal with 0x204, 0x20c, 0x210, 0x214, 0x218.
> 
> (We can safely add new lines to the SSE300 vmstate because no board
> uses this device in an SSE300 yet.)
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 18/44] hw/misc/iotkit-sysctl: Implement SSE-200 and SSE-300 PID register values
  2021-02-19 14:45 ` [PATCH 18/44] hw/misc/iotkit-sysctl: Implement SSE-200 and SSE-300 PID register values Peter Maydell
@ 2021-03-04 19:57   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 19:57 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:45 AM, Peter Maydell wrote:
> The SSE-200 and SSE-300 have different PID register values from the
> IoTKit for the sysctl register block.  We incorrectly implemented the
> SSE-200 with the same PID values as IoTKit.  Fix the SSE-200 bug and
> report these register values for SSE-300.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 19/44] hw/arm/Kconfig: Move ARMSSE_CPUID and ARMSSE_MHU stanzas to hw/misc
  2021-02-19 14:45 ` [PATCH 19/44] hw/arm/Kconfig: Move ARMSSE_CPUID and ARMSSE_MHU stanzas to hw/misc Peter Maydell
  2021-02-21 13:31   ` Philippe Mathieu-Daudé
@ 2021-03-04 19:57   ` Richard Henderson
  1 sibling, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 19:57 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:45 AM, Peter Maydell wrote:
> The ARMSSE_CPUID and ARMSSE_MHU Kconfig stanzas are for the devices
> implmemented by hw/misc/cpuid.c and hw/misc/armsse-mhu.c.  Move them
> to hw/misc/Kconfig where they belong.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 20/44] hw/misc/sse-cpu-pwrctrl: Implement SSE-300 CPU<N>_PWRCTRL register block
  2021-02-19 14:45 ` [PATCH 20/44] hw/misc/sse-cpu-pwrctrl: Implement SSE-300 CPU<N>_PWRCTRL register block Peter Maydell
@ 2021-03-04 20:02   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 20:02 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:45 AM, Peter Maydell wrote:
> The SSE-300 has a new register block CPU<N>_PWRCTRL.  There is one
> instance of this per CPU in the system (so just one for the SSE-300),
> and as well as the usual CIDR/PIDR ID registers it has just one
> register, CPUPWRCFG.  This register allows the guest to configure
> behaviour of the system in power-down and deep-sleep states.  Since
> QEMU does not model those, we make the register a dummy
> reads-as-written implementation.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 21/44] hw/arm/armsse: Use an array for apb_ppc fields in the state structure
  2021-02-19 14:45 ` [PATCH 21/44] hw/arm/armsse: Use an array for apb_ppc fields in the state structure Peter Maydell
  2021-02-21 13:34   ` Philippe Mathieu-Daudé
@ 2021-03-04 20:04   ` Richard Henderson
  1 sibling, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 20:04 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:45 AM, Peter Maydell wrote:
> Convert the apb_ppc0 and apb_ppc1 fields in the ARMSSE state struct
> to use an array instead of two separate fields.  We already had one
> place in the code that wanted to be able to refer to the PPC by
> index, and we're about to add more code like that.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 22/44] hw/arm/armsse: Add a define for number of IRQs used by the SSE itself
  2021-02-19 14:45 ` [PATCH 22/44] hw/arm/armsse: Add a define for number of IRQs used by the SSE itself Peter Maydell
  2021-02-21 13:34   ` Philippe Mathieu-Daudé
@ 2021-03-04 20:04   ` Richard Henderson
  1 sibling, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 20:04 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:45 AM, Peter Maydell wrote:
> The SSE uses 32 interrupts for its own devices, and then passes through
> its expansion IRQ inputs to the CPU's interrupts 33 and upward.
> Add a define for the number of IRQs the SSE uses for itself, instead
> of hardcoding 32.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 23/44] hw/arm/armsse: Add framework for data-driven device placement
  2021-02-19 14:45 ` [PATCH 23/44] hw/arm/armsse: Add framework for data-driven device placement Peter Maydell
@ 2021-03-04 20:10   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 20:10 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:45 AM, Peter Maydell wrote:
> The SSE-300 is mostly the same as the SSE-200, but it has moved some
> of the devices in the memory map and uses different device types in
> some cases.  To accommodate this, add a framework where the placement
> and wiring of some devices can be specified in a data table.
> 
> This commit adds the framework for this data-driven device placement,
> and makes the CMSDK APB timer devices use it.  Subsequent commits
> will convert the other devices which differ between SSE-200 and
> SSE-300.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 24/44] hw/arm/armsse: Move dual-timer device into data-driven framework
  2021-02-19 14:45 ` [PATCH 24/44] hw/arm/armsse: Move dual-timer device into data-driven framework Peter Maydell
@ 2021-03-04 20:12   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 20:12 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:45 AM, Peter Maydell wrote:
> Move the CMSDK dualtimer device handling into the data-driven
> device placement framework.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 25/44] hw/arm/armsse: Move watchdogs into data-driven framework
  2021-02-19 14:45 ` [PATCH 25/44] hw/arm/armsse: Move watchdogs " Peter Maydell
@ 2021-03-04 20:15   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 20:15 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:45 AM, Peter Maydell wrote:
> Move the CMSDK watchdog device handling into the data-driven device
> placement framework.  This is slightly more complicated because these
> devices might wire their IRQs up to the NMI line, and because one of
> them uses the slow 32KHz clock rather than the main clock.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 36/44] hw/arm/mps2-tz: Make UART overflow IRQ board-specific
  2021-02-19 14:46 ` [PATCH 36/44] hw/arm/mps2-tz: Make UART overflow IRQ board-specific Peter Maydell
@ 2021-03-04 20:16   ` Philippe Mathieu-Daudé
  2021-03-04 20:43   ` Richard Henderson
  1 sibling, 0 replies; 103+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-03-04 20:16 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 3:46 PM, Peter Maydell wrote:
> The AN547 puts the combined UART overflow IRQ at 48, not 47 like the
> other images. Make this setting board-specific.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/arm/mps2-tz.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)

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


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

* Re: [PATCH 26/44] hw/arm/armsse: Move s32ktimer into data-driven framework
  2021-02-19 14:45 ` [PATCH 26/44] hw/arm/armsse: Move s32ktimer " Peter Maydell
@ 2021-03-04 20:16   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 20:16 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:45 AM, Peter Maydell wrote:
> Move the CMSDK timer that uses the S32K slow clock into the data-driven
> device placement framework.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 41/44] hw/arm/mps2-tz: Make initsvtor0 setting board-specific
  2021-02-19 14:46 ` [PATCH 41/44] hw/arm/mps2-tz: Make initsvtor0 setting board-specific Peter Maydell
@ 2021-03-04 20:17   ` Philippe Mathieu-Daudé
  2021-03-05  1:05   ` Richard Henderson
  1 sibling, 0 replies; 103+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-03-04 20:17 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 3:46 PM, Peter Maydell wrote:
> The AN547 configures the SSE-300 with a different initsvtor0
> setting from its default; make this a board-specific setting.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/arm/mps2-tz.c | 5 +++++
>  1 file changed, 5 insertions(+)

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


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

* Re: [PATCH 31/44] hw/arm/armsse: Indirect irq_is_common[] through ARMSSEInfo
  2021-02-19 14:46 ` [PATCH 31/44] hw/arm/armsse: Indirect irq_is_common[] through ARMSSEInfo Peter Maydell
@ 2021-03-04 20:19   ` Philippe Mathieu-Daudé
  2021-03-05 10:50     ` Philippe Mathieu-Daudé
  2021-03-04 20:26   ` Richard Henderson
  1 sibling, 1 reply; 103+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-03-04 20:19 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 3:46 PM, Peter Maydell wrote:
> The SSE-300 has a slightly different set of shared-per-CPU interrupts,
> allow the irq_is_common[] array to be different per SSE variant.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/arm/armsse.c | 39 +++++++++++++++++++++------------------
>  1 file changed, 21 insertions(+), 18 deletions(-)
> 
> diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
> index f43f0524e28..b316fe69571 100644
> --- a/hw/arm/armsse.c
> +++ b/hw/arm/armsse.c
> @@ -68,6 +68,7 @@ struct ARMSSEInfo {
>      bool has_cpuid;
>      Property *props;
>      const ARMSSEDeviceInfo *devinfo;
> +    const bool *irq_is_common;

Maybe *const?

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


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

* Re: [PATCH 27/44] hw/arm/armsse: Move sysinfo register block into data-driven framework
  2021-02-19 14:46 ` [PATCH 27/44] hw/arm/armsse: Move sysinfo register block " Peter Maydell
@ 2021-03-04 20:19   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 20:19 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:46 AM, Peter Maydell wrote:
> Move the sysinfo register block into the data-driven framework.
> 
> While we are moving the code for configuring this device around,
> regularize on using &error_abortw when setting the integer
> properties: they are all simple DEFINE_PROP_UINT32 properties so the
> setting can never fail.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 28/44] hw/arm/armsse: Move sysctl register block into data-driven framework
  2021-02-19 14:46 ` [PATCH 28/44] hw/arm/armsse: Move sysctl " Peter Maydell
@ 2021-03-04 20:21   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 20:21 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:46 AM, Peter Maydell wrote:
> Move the sysctl register block into the data-driven device placement
> framework.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 33/44] hw/arm/armsse: Add support for TYPE_SSE_TIMER in ARMSSEDeviceInfo
  2021-02-19 14:46 ` [PATCH 33/44] hw/arm/armsse: Add support for TYPE_SSE_TIMER in ARMSSEDeviceInfo Peter Maydell
@ 2021-03-04 20:22   ` Philippe Mathieu-Daudé
  2021-03-04 20:34   ` Richard Henderson
  1 sibling, 0 replies; 103+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-03-04 20:22 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 3:46 PM, Peter Maydell wrote:
> The SSE-300 has four timers of type TYPE_SSE_TIMER; add support in
> the code for having these in an ARMSSEDeviceInfo array.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  include/hw/arm/armsse.h |  2 ++
>  hw/arm/armsse.c         | 15 +++++++++++++++
>  2 files changed, 17 insertions(+)

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


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

* Re: [PATCH 29/44] hw/arm/armsse: Move PPUs into data-driven framework
  2021-02-19 14:46 ` [PATCH 29/44] hw/arm/armsse: Move PPUs " Peter Maydell
@ 2021-03-04 20:24   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 20:24 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:46 AM, Peter Maydell wrote:
> Move the PPUs into the data-driven device placement framework.
> We don't implement them, so they are just TYPE_UNIMPLEMENTED stubs.
> 
> Because the SSE-200 and the IotKit diverge here (the IoTKit does
> not have the PPUs) we need to separate out the ARMSSEDeviceInfo
> for the two variants, and only add the PPUs to the SSE-200.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 38/44] hw/misc/mps2-fpgaio: Support AN547 DBGCTRL register
  2021-02-19 14:46 ` [PATCH 38/44] hw/misc/mps2-fpgaio: Support AN547 DBGCTRL register Peter Maydell
@ 2021-03-04 20:24   ` Philippe Mathieu-Daudé
  2021-03-04 20:50   ` Richard Henderson
  1 sibling, 0 replies; 103+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-03-04 20:24 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 3:46 PM, Peter Maydell wrote:
> For the AN547 image, the FPGAIO block has an extra DBGCTRL register,
> which is used to control the SPNIDEN, SPIDEN, NPIDEN and DBGEN inputs
> to the CPU.  These signals control when the CPU permits use of the
> external debug interface.  Our CPU models don't implement the
> external debug interface, so we model the register as
> reads-as-written.
> 
> Implement the register, with a property defining whether it is
> present, and allow mps2-tz boards to specify that it is present.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  include/hw/misc/mps2-fpgaio.h |  2 ++
>  hw/arm/mps2-tz.c              |  5 +++++
>  hw/misc/mps2-fpgaio.c         | 22 ++++++++++++++++++++--
>  3 files changed, 27 insertions(+), 2 deletions(-)

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


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

* Re: [PATCH 30/44] hw/arm/armsse: Add missing SSE-200 SYS_PPU
  2021-02-19 14:46 ` [PATCH 30/44] hw/arm/armsse: Add missing SSE-200 SYS_PPU Peter Maydell
@ 2021-03-04 20:25   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 20:25 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:46 AM, Peter Maydell wrote:
> We forgot to implement a TYPE_UNIMPLEMENTED_DEVICE stub
> for the SYS_PPU in the SSE-200, which is at 0x50022000.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 31/44] hw/arm/armsse: Indirect irq_is_common[] through ARMSSEInfo
  2021-02-19 14:46 ` [PATCH 31/44] hw/arm/armsse: Indirect irq_is_common[] through ARMSSEInfo Peter Maydell
  2021-03-04 20:19   ` Philippe Mathieu-Daudé
@ 2021-03-04 20:26   ` Richard Henderson
  1 sibling, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 20:26 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:46 AM, Peter Maydell wrote:
> The SSE-300 has a slightly different set of shared-per-CPU interrupts,
> allow the irq_is_common[] array to be different per SSE variant.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 40/44] hw/arm/mps2-tz: Support running APB peripherals on different clock
  2021-02-19 14:46 ` [PATCH 40/44] hw/arm/mps2-tz: Support running APB peripherals on different clock Peter Maydell
@ 2021-03-04 20:27   ` Philippe Mathieu-Daudé
  2021-03-05  1:01   ` Richard Henderson
  1 sibling, 0 replies; 103+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-03-04 20:27 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 3:46 PM, Peter Maydell wrote:
> The AN547 runs the APB peripherals outside the SSE-300 on a different
> and slightly slower clock than it runs the SSE-300 with.  Support
> making the APB peripheral clock frequency board-specific.  (For our
> implementation only the UARTs actually take a clock.)
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/arm/mps2-tz.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


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

* Re: [PATCH 43/44] docs/system/arm/mps2.rst: Document the new mps3-an547 board
  2021-02-19 14:46 ` [PATCH 43/44] docs/system/arm/mps2.rst: Document the " Peter Maydell
@ 2021-03-04 20:28   ` Philippe Mathieu-Daudé
  2021-03-05  1:28   ` Richard Henderson
  1 sibling, 0 replies; 103+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-03-04 20:28 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 3:46 PM, Peter Maydell wrote:
> Add brief documentation of the new mps3-an547 board.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  docs/system/arm/mps2.rst | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)

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


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

* Re: [PATCH 32/44] hw/arm/armsse: Add support for SSE variants with a system counter
  2021-02-19 14:46 ` [PATCH 32/44] hw/arm/armsse: Add support for SSE variants with a system counter Peter Maydell
@ 2021-03-04 20:30   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 20:30 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:46 AM, Peter Maydell wrote:
> The SSE-300 has a system counter device; add support for SSE
> variants having this device.
> 
> As with the existing devices like the cache control block, CPUID
> block, etc, we don't try to make the MMIO addresses configurable.  We
> can do that if and when we need to model a future SSE variant which
> has the counter in a different location.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 33/44] hw/arm/armsse: Add support for TYPE_SSE_TIMER in ARMSSEDeviceInfo
  2021-02-19 14:46 ` [PATCH 33/44] hw/arm/armsse: Add support for TYPE_SSE_TIMER in ARMSSEDeviceInfo Peter Maydell
  2021-03-04 20:22   ` Philippe Mathieu-Daudé
@ 2021-03-04 20:34   ` Richard Henderson
  1 sibling, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 20:34 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:46 AM, Peter Maydell wrote:
> The SSE-300 has four timers of type TYPE_SSE_TIMER; add support in
> the code for having these in an ARMSSEDeviceInfo array.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 34/44] hw/arm/armsse: Support variants with ARMSSE_CPU_PWRCTRL block
  2021-02-19 14:46 ` [PATCH 34/44] hw/arm/armsse: Support variants with ARMSSE_CPU_PWRCTRL block Peter Maydell
@ 2021-03-04 20:37   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 20:37 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:46 AM, Peter Maydell wrote:
> Support SSE variants like the SSE-300 with an ARMSSE_CPU_PWRCTRL register
> block. Because this block is per-CPU and does not clash with any of the
> SSE-200 devices, we handle it with a has_cpu_pwrctrl flag like the
> existing has_cachectrl, has_cpusectrl and has_cpuid, rather than
> trying to add per-CPU-device support to the devinfo array handling code.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 35/44] hw/arm/armsse: Add SSE-300 support
  2021-02-19 14:46 ` [PATCH 35/44] hw/arm/armsse: Add SSE-300 support Peter Maydell
@ 2021-03-04 20:39   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 20:39 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:46 AM, Peter Maydell wrote:
> Now we have sufficiently parameterised the code, we can add SSE-300
> support by adding a new entry to the armsse_variants[] array.
> 
> Note that the main watchdog (unlike the s32k watchdog) in the SSE-300
> is a different device from the CMSDK watchdog; we don't have a model
> of it so we leave it as a TYPE_UNIMPLEMENTED_DEVICE stub.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 36/44] hw/arm/mps2-tz: Make UART overflow IRQ board-specific
  2021-02-19 14:46 ` [PATCH 36/44] hw/arm/mps2-tz: Make UART overflow IRQ board-specific Peter Maydell
  2021-03-04 20:16   ` Philippe Mathieu-Daudé
@ 2021-03-04 20:43   ` Richard Henderson
  1 sibling, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 20:43 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:46 AM, Peter Maydell wrote:
> The AN547 puts the combined UART overflow IRQ at 48, not 47 like the
> other images. Make this setting board-specific.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 37/44] hw/misc/mps2-fpgaio: Fold counters subsection into main vmstate
  2021-02-19 14:46 ` [PATCH 37/44] hw/misc/mps2-fpgaio: Fold counters subsection into main vmstate Peter Maydell
@ 2021-03-04 20:45   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 20:45 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:46 AM, Peter Maydell wrote:
> We've already broken migration compatibility for all the MPS
> boards, so we might as well take advantage of this to simplify
> the vmstate for the FPGAIO device by folding the counters
> subsection into the main vmstate description.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 38/44] hw/misc/mps2-fpgaio: Support AN547 DBGCTRL register
  2021-02-19 14:46 ` [PATCH 38/44] hw/misc/mps2-fpgaio: Support AN547 DBGCTRL register Peter Maydell
  2021-03-04 20:24   ` Philippe Mathieu-Daudé
@ 2021-03-04 20:50   ` Richard Henderson
  1 sibling, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-04 20:50 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:46 AM, Peter Maydell wrote:
> For the AN547 image, the FPGAIO block has an extra DBGCTRL register,
> which is used to control the SPNIDEN, SPIDEN, NPIDEN and DBGEN inputs
> to the CPU.  These signals control when the CPU permits use of the
> external debug interface.  Our CPU models don't implement the
> external debug interface, so we model the register as
> reads-as-written.
> 
> Implement the register, with a property defining whether it is
> present, and allow mps2-tz boards to specify that it is present.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 39/44] hw/misc/mps2-scc: Implement changes for AN547
  2021-02-19 14:46 ` [PATCH 39/44] hw/misc/mps2-scc: Implement changes for AN547 Peter Maydell
@ 2021-03-05  0:30   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-05  0:30 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:46 AM, Peter Maydell wrote:
> Implement the minor changes required to the SCC block for AN547 images:
>   * CFG2 and CFG5 exist (like AN524)
>   * CFG3 is reserved (like AN524)
>   * CFG0 bit 1 is CPU_WAIT; we don't implement it, but note this
>     in the TODO comment
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 40/44] hw/arm/mps2-tz: Support running APB peripherals on different clock
  2021-02-19 14:46 ` [PATCH 40/44] hw/arm/mps2-tz: Support running APB peripherals on different clock Peter Maydell
  2021-03-04 20:27   ` Philippe Mathieu-Daudé
@ 2021-03-05  1:01   ` Richard Henderson
  1 sibling, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-05  1:01 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:46 AM, Peter Maydell wrote:
> The AN547 runs the APB peripherals outside the SSE-300 on a different
> and slightly slower clock than it runs the SSE-300 with.  Support
> making the APB peripheral clock frequency board-specific.  (For our
> implementation only the UARTs actually take a clock.)
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 41/44] hw/arm/mps2-tz: Make initsvtor0 setting board-specific
  2021-02-19 14:46 ` [PATCH 41/44] hw/arm/mps2-tz: Make initsvtor0 setting board-specific Peter Maydell
  2021-03-04 20:17   ` Philippe Mathieu-Daudé
@ 2021-03-05  1:05   ` Richard Henderson
  1 sibling, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-05  1:05 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:46 AM, Peter Maydell wrote:
> The AN547 configures the SSE-300 with a different initsvtor0
> setting from its default; make this a board-specific setting.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 42/44] hw/arm/mps2-tz: Add new mps3-an547 board
  2021-02-19 14:46 ` [PATCH 42/44] hw/arm/mps2-tz: Add new mps3-an547 board Peter Maydell
@ 2021-03-05  1:19   ` Richard Henderson
  0 siblings, 0 replies; 103+ messages in thread
From: Richard Henderson @ 2021-03-05  1:19 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:46 AM, Peter Maydell wrote:
> Add support for the mps3-an547 board; this is an SSE-300 based
> FPGA image that runs on the MPS3.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

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

r~


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

* Re: [PATCH 43/44] docs/system/arm/mps2.rst: Document the new mps3-an547 board
  2021-02-19 14:46 ` [PATCH 43/44] docs/system/arm/mps2.rst: Document the " Peter Maydell
  2021-03-04 20:28   ` Philippe Mathieu-Daudé
@ 2021-03-05  1:28   ` Richard Henderson
  2021-03-05 10:22     ` Peter Maydell
  1 sibling, 1 reply; 103+ messages in thread
From: Richard Henderson @ 2021-03-05  1:28 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 6:46 AM, Peter Maydell wrote:
> @@ -1,5 +1,5 @@
> -Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``)
> -=========================================================================================================================================
> +Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an547``)'
I think you should drop the list here, as it has gotten *way* too long.

> @@ -27,6 +27,8 @@ QEMU models the following FPGA images:
>     Dual Cortex-M33 as documented in Arm Application Note AN521
>   ``mps3-an524``
>     Dual Cortex-M33 on an MPS3, as documented in Arm Application Note AN524
> +``mps3-an547``
> +  Cortex-M55 on an MPS3, as documented in Arm Application Note AN547

The list is down here, anyway.


r~


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

* Re: [PATCH 43/44] docs/system/arm/mps2.rst: Document the new mps3-an547 board
  2021-03-05  1:28   ` Richard Henderson
@ 2021-03-05 10:22     ` Peter Maydell
  2021-03-08 17:35       ` Peter Maydell
  0 siblings, 1 reply; 103+ messages in thread
From: Peter Maydell @ 2021-03-05 10:22 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, QEMU Developers

On Fri, 5 Mar 2021 at 01:28, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> On 2/19/21 6:46 AM, Peter Maydell wrote:
> > @@ -1,5 +1,5 @@
> > -Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``)
> > -=========================================================================================================================================
> > +Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an547``)'
> I think you should drop the list here, as it has gotten *way* too long.
>
> > @@ -27,6 +27,8 @@ QEMU models the following FPGA images:
> >     Dual Cortex-M33 as documented in Arm Application Note AN521
> >   ``mps3-an524``
> >     Dual Cortex-M33 on an MPS3, as documented in Arm Application Note AN524
> > +``mps3-an547``
> > +  Cortex-M55 on an MPS3, as documented in Arm Application Note AN547
>
> The list is down here, anyway.

The title is what generates the text for the table of contents in the
next page up:

https://qemu-project.gitlab.io/qemu/system/target-arm.html#board-specific-documentation

I like having every board model listed explicitly in that ToC. (Though we
have broken this rule for the Aspeed boards with "*-bmc"...)

-- PMM


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

* Re: [PATCH 31/44] hw/arm/armsse: Indirect irq_is_common[] through ARMSSEInfo
  2021-03-04 20:19   ` Philippe Mathieu-Daudé
@ 2021-03-05 10:50     ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 103+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-03-05 10:50 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 3/4/21 9:19 PM, Philippe Mathieu-Daudé wrote:
> On 2/19/21 3:46 PM, Peter Maydell wrote:
>> The SSE-300 has a slightly different set of shared-per-CPU interrupts,
>> allow the irq_is_common[] array to be different per SSE variant.
>>
>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>> ---
>>  hw/arm/armsse.c | 39 +++++++++++++++++++++------------------
>>  1 file changed, 21 insertions(+), 18 deletions(-)
>>
>> diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
>> index f43f0524e28..b316fe69571 100644
>> --- a/hw/arm/armsse.c
>> +++ b/hw/arm/armsse.c
>> @@ -68,6 +68,7 @@ struct ARMSSEInfo {
>>      bool has_cpuid;
>>      Property *props;
>>      const ARMSSEDeviceInfo *devinfo;
>> +    const bool *irq_is_common;
> 
> Maybe *const?

Forget what I said, I thought it was an array of pointers
to bool arrays, but it is only an pointer to an array of
booleans.

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


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

* Re: [PATCH 44/44] tests/qtest/sse-timer-test: Add simple tests of the SSE timer and counter
  2021-02-19 14:46 ` [PATCH 44/44] tests/qtest/sse-timer-test: Add simple tests of the SSE timer and counter Peter Maydell
@ 2021-03-05 11:08   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 103+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-03-05 11:08 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

Hi Peter,

On 2/19/21 3:46 PM, Peter Maydell wrote:
> Add a simple qtest to exercise the new system counter and
> system timer device in the SSE-300.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  tests/qtest/sse-timer-test.c | 240 +++++++++++++++++++++++++++++++++++
>  MAINTAINERS                  |   1 +
>  tests/qtest/meson.build      |   1 +
>  3 files changed, 242 insertions(+)
>  create mode 100644 tests/qtest/sse-timer-test.c

> +static void reset_counter_and_timer(void)
> +{
> +    /*
> +     * Reset the system counter and the timer between tests. This
> +     * isn't a full reset, but it's sufficient for what the tests check.
> +     */
> +    writel(COUNTER_BASE + CNTCR, 0);
> +    writel(TIMER_BASE + CNTP_CTL, 0);
> +    writel(TIMER_BASE + CNTP_AIVAL_CTL, 0);
> +    writel(COUNTER_BASE + CNTCV_LO, 0);
> +    writel(COUNTER_BASE + CNTCV_HI, 0);
> +}
> +
> +static void test_timer(void)
> +{
> +    /* Basic timer functionality test */

Minor comment, I'd move the timer mode test *after* the counter mode
ones, which are easier to review. Eventually consider adding this
single timer test as a separate patch to ease review, as it is quite
complex.

Having this patch preferably split (no need to repost):
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

Regards,

Phil.


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

* Re: [PATCH 00/44] hw/arm: New board model mps3-an547
  2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
                   ` (44 preceding siblings ...)
  2021-02-19 15:43 ` [PATCH 00/44] hw/arm: New board model mps3-an547 no-reply
@ 2021-03-05 11:56 ` Philippe Mathieu-Daudé
  45 siblings, 0 replies; 103+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-03-05 11:56 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 2/19/21 3:45 PM, Peter Maydell wrote:
> This patchseries implements a model of the AN547 FPGA image for the
> MPS3 board.  The main benefit of this new board is that it uses the
> Cortex-M55 CPU and so it allows running guests which use a v8.1M CPU.

> Peter Maydell (44):
>   clock: Add ClockEvent parameter to callbacks
>   clock: Add ClockPreUpdate callback event type
>   clock: Add clock_ns_to_ticks() function
>   hw/timer/npcm7xx_timer: Use new clock_ns_to_ticks()
>   hw/arm/armsse: Introduce SSE subsystem version property
>   hw/misc/iotkit-sysctl: Remove is_sse200 flag
>   hw/misc/iotkit-secctl.c: Implement SSE-300 PID register values
>   hw/misc/iotkit-sysinfo.c: Implement SSE-300 PID register values
>   hw/arm/armsse.c: Use correct SYS_CONFIG0 register value for SSE-300
>   hw/misc/iotkit-sysinfo.c: Implement SYS_CONFIG1 and IIDR
>   hw/timer/sse-counter: Model the SSE Subsystem System Counter
>   hw/timer/sse-timer: Model the SSE Subsystem System Timer
>   hw/misc/iotkit-sysctl: Add SSE-300 cases which match SSE-200 behaviour
>   hw/misc/iotkit-sysctl: Handle CPU_WAIT, NMI_ENABLE for SSE-300
>   hw/misc/iotkit-sysctl: Handle INITSVTOR* for SSE-300
>   hw/misc/iotkit-sysctl: Implement dummy version of SSE-300 PWRCTRL
>     register
>   hw/misc/iotkit-sysctl: Handle SSE-300 changes to PDCM_PD_*_SENSE
>     registers
>   hw/misc/iotkit-sysctl: Implement SSE-200 and SSE-300 PID register
>     values
>   hw/arm/Kconfig: Move ARMSSE_CPUID and ARMSSE_MHU stanzas to hw/misc
>   hw/misc/sse-cpu-pwrctrl: Implement SSE-300 CPU<N>_PWRCTRL register
>     block
>   hw/arm/armsse: Use an array for apb_ppc fields in the state structure
>   hw/arm/armsse: Add a define for number of IRQs used by the SSE itself
>   hw/arm/armsse: Add framework for data-driven device placement
>   hw/arm/armsse: Move dual-timer device into data-driven framework
>   hw/arm/armsse: Move watchdogs into data-driven framework
>   hw/arm/armsse: Move s32ktimer into data-driven framework
>   hw/arm/armsse: Move sysinfo register block into data-driven framework
>   hw/arm/armsse: Move sysctl register block into data-driven framework
>   hw/arm/armsse: Move PPUs into data-driven framework
>   hw/arm/armsse: Add missing SSE-200 SYS_PPU
>   hw/arm/armsse: Indirect irq_is_common[] through ARMSSEInfo
>   hw/arm/armsse: Add support for SSE variants with a system counter
>   hw/arm/armsse: Add support for TYPE_SSE_TIMER in ARMSSEDeviceInfo
>   hw/arm/armsse: Support variants with ARMSSE_CPU_PWRCTRL block
>   hw/arm/armsse: Add SSE-300 support
>   hw/arm/mps2-tz: Make UART overflow IRQ board-specific
>   hw/misc/mps2-fpgaio: Fold counters subsection into main vmstate
>   hw/misc/mps2-fpgaio: Support AN547 DBGCTRL register
>   hw/misc/mps2-scc: Implement changes for AN547
>   hw/arm/mps2-tz: Support running APB peripherals on different clock
>   hw/arm/mps2-tz: Make initsvtor0 setting board-specific
>   hw/arm/mps2-tz: Add new mps3-an547 board
>   docs/system/arm/mps2.rst: Document the new mps3-an547 board
>   tests/qtest/sse-timer-test: Add simple tests of the SSE timer and
>     counter
> 
>  docs/devel/clocks.rst                |   71 +-
>  docs/system/arm/mps2.rst             |    6 +-
>  include/hw/arm/armsse-version.h      |   42 ++
>  include/hw/arm/armsse.h              |   40 +-
>  include/hw/clock.h                   |   63 +-
>  include/hw/misc/armsse-cpu-pwrctrl.h |   40 +
>  include/hw/misc/iotkit-secctl.h      |    2 +
>  include/hw/misc/iotkit-sysctl.h      |   13 +-
>  include/hw/misc/iotkit-sysinfo.h     |    2 +
>  include/hw/misc/mps2-fpgaio.h        |    2 +
>  include/hw/qdev-clock.h              |   17 +-
>  include/hw/timer/sse-counter.h       |  105 +++
>  include/hw/timer/sse-timer.h         |   53 ++
>  hw/adc/npcm7xx_adc.c                 |    2 +-
>  hw/arm/armsse.c                      | 1008 +++++++++++++++++++-------
>  hw/arm/mps2-tz.c                     |  168 ++++-
>  hw/char/cadence_uart.c               |    4 +-
>  hw/char/ibex_uart.c                  |    4 +-
>  hw/char/pl011.c                      |    5 +-
>  hw/core/clock.c                      |   24 +-
>  hw/core/qdev-clock.c                 |    8 +-
>  hw/mips/cps.c                        |    2 +-
>  hw/misc/armsse-cpu-pwrctrl.c         |  149 ++++
>  hw/misc/bcm2835_cprman.c             |   23 +-
>  hw/misc/iotkit-secctl.c              |   50 +-
>  hw/misc/iotkit-sysctl.c              |  521 ++++++++++---
>  hw/misc/iotkit-sysinfo.c             |   51 +-
>  hw/misc/mps2-fpgaio.c                |   52 +-
>  hw/misc/mps2-scc.c                   |   15 +-
>  hw/misc/npcm7xx_clk.c                |   26 +-
>  hw/misc/npcm7xx_pwm.c                |    2 +-
>  hw/misc/zynq_slcr.c                  |    5 +-
>  hw/timer/cmsdk-apb-dualtimer.c       |    5 +-
>  hw/timer/cmsdk-apb-timer.c           |    4 +-
>  hw/timer/npcm7xx_timer.c             |    6 +-
>  hw/timer/sse-counter.c               |  474 ++++++++++++
>  hw/timer/sse-timer.c                 |  470 ++++++++++++
>  hw/watchdog/cmsdk-apb-watchdog.c     |    5 +-
>  target/mips/cpu.c                    |    2 +-
>  tests/qtest/sse-timer-test.c         |  240 ++++++
>  MAINTAINERS                          |    7 +
>  hw/arm/Kconfig                       |    9 +-
>  hw/misc/Kconfig                      |    9 +
>  hw/misc/meson.build                  |    1 +
>  hw/misc/trace-events                 |    4 +
>  hw/timer/Kconfig                     |    6 +
>  hw/timer/meson.build                 |    2 +
>  hw/timer/trace-events                |   12 +
>  tests/qtest/meson.build              |    1 +
>  49 files changed, 3356 insertions(+), 476 deletions(-)
>  create mode 100644 include/hw/arm/armsse-version.h
>  create mode 100644 include/hw/misc/armsse-cpu-pwrctrl.h
>  create mode 100644 include/hw/timer/sse-counter.h
>  create mode 100644 include/hw/timer/sse-timer.h
>  create mode 100644 hw/misc/armsse-cpu-pwrctrl.c
>  create mode 100644 hw/timer/sse-counter.c
>  create mode 100644 hw/timer/sse-timer.c
>  create mode 100644 tests/qtest/sse-timer-test.c

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


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

* Re: [PATCH 43/44] docs/system/arm/mps2.rst: Document the new mps3-an547 board
  2021-03-05 10:22     ` Peter Maydell
@ 2021-03-08 17:35       ` Peter Maydell
  0 siblings, 0 replies; 103+ messages in thread
From: Peter Maydell @ 2021-03-08 17:35 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, QEMU Developers

On Fri, 5 Mar 2021 at 10:22, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On Fri, 5 Mar 2021 at 01:28, Richard Henderson
> <richard.henderson@linaro.org> wrote:
> >
> > On 2/19/21 6:46 AM, Peter Maydell wrote:
> > > @@ -1,5 +1,5 @@
> > > -Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``)
> > > -=========================================================================================================================================
> > > +Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an547``)'
> > I think you should drop the list here, as it has gotten *way* too long.
> >
> > > @@ -27,6 +27,8 @@ QEMU models the following FPGA images:
> > >     Dual Cortex-M33 as documented in Arm Application Note AN521
> > >   ``mps3-an524``
> > >     Dual Cortex-M33 on an MPS3, as documented in Arm Application Note AN524
> > > +``mps3-an547``
> > > +  Cortex-M55 on an MPS3, as documented in Arm Application Note AN547
> >
> > The list is down here, anyway.
>
> The title is what generates the text for the table of contents in the
> next page up:
>
> https://qemu-project.gitlab.io/qemu/system/target-arm.html#board-specific-documentation
>
> I like having every board model listed explicitly in that ToC. (Though we
> have broken this rule for the Aspeed boards with "*-bmc"...)

I put this patch into the pullreq as-is, because the series is otherwise
ready to go and this was a minor thing; happy to send a followup patch
tweaking the title text if we conclude that we want to do that.

thanks
-- PMM


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

end of thread, other threads:[~2021-03-08 18:42 UTC | newest]

Thread overview: 103+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-19 14:45 [PATCH 00/44] hw/arm: New board model mps3-an547 Peter Maydell
2021-02-19 14:45 ` [PATCH 01/44] clock: Add ClockEvent parameter to callbacks Peter Maydell
2021-03-04  2:50   ` Richard Henderson
2021-02-19 14:45 ` [PATCH 02/44] clock: Add ClockPreUpdate callback event type Peter Maydell
2021-02-19 14:45 ` [PATCH 03/44] clock: Add clock_ns_to_ticks() function Peter Maydell
2021-02-19 14:45 ` [PATCH 04/44] hw/timer/npcm7xx_timer: Use new clock_ns_to_ticks() Peter Maydell
2021-02-19 14:45 ` [PATCH 05/44] hw/arm/armsse: Introduce SSE subsystem version property Peter Maydell
2021-03-04 17:10   ` Richard Henderson
2021-02-19 14:45 ` [PATCH 06/44] hw/misc/iotkit-sysctl: Remove is_sse200 flag Peter Maydell
2021-03-04 17:13   ` Richard Henderson
2021-02-19 14:45 ` [PATCH 07/44] hw/misc/iotkit-secctl.c: Implement SSE-300 PID register values Peter Maydell
2021-03-04 17:29   ` Richard Henderson
2021-03-04 17:51     ` Richard Henderson
2021-03-04 19:28       ` Peter Maydell
2021-02-19 14:45 ` [PATCH 08/44] hw/misc/iotkit-sysinfo.c: " Peter Maydell
2021-03-04 17:35   ` Richard Henderson
2021-02-19 14:45 ` [PATCH 09/44] hw/arm/armsse.c: Use correct SYS_CONFIG0 register value for SSE-300 Peter Maydell
2021-03-04 17:39   ` Richard Henderson
2021-02-19 14:45 ` [PATCH 10/44] hw/misc/iotkit-sysinfo.c: Implement SYS_CONFIG1 and IIDR Peter Maydell
2021-03-04 17:54   ` Richard Henderson
2021-02-19 14:45 ` [PATCH 11/44] hw/timer/sse-counter: Model the SSE Subsystem System Counter Peter Maydell
2021-03-04 18:38   ` Richard Henderson
2021-02-19 14:45 ` [PATCH 12/44] hw/timer/sse-timer: Model the SSE Subsystem System Timer Peter Maydell
2021-03-04 19:11   ` Richard Henderson
2021-02-19 14:45 ` [PATCH 13/44] hw/misc/iotkit-sysctl: Add SSE-300 cases which match SSE-200 behaviour Peter Maydell
2021-03-04 19:13   ` Richard Henderson
2021-02-19 14:45 ` [PATCH 14/44] hw/misc/iotkit-sysctl: Handle CPU_WAIT, NMI_ENABLE for SSE-300 Peter Maydell
2021-03-04 19:34   ` Richard Henderson
2021-02-19 14:45 ` [PATCH 15/44] hw/misc/iotkit-sysctl: Handle INITSVTOR* " Peter Maydell
2021-03-04 19:38   ` Richard Henderson
2021-02-19 14:45 ` [PATCH 16/44] hw/misc/iotkit-sysctl: Implement dummy version of SSE-300 PWRCTRL register Peter Maydell
2021-03-04 19:49   ` Richard Henderson
2021-02-19 14:45 ` [PATCH 17/44] hw/misc/iotkit-sysctl: Handle SSE-300 changes to PDCM_PD_*_SENSE registers Peter Maydell
2021-03-04 19:52   ` Richard Henderson
2021-02-19 14:45 ` [PATCH 18/44] hw/misc/iotkit-sysctl: Implement SSE-200 and SSE-300 PID register values Peter Maydell
2021-03-04 19:57   ` Richard Henderson
2021-02-19 14:45 ` [PATCH 19/44] hw/arm/Kconfig: Move ARMSSE_CPUID and ARMSSE_MHU stanzas to hw/misc Peter Maydell
2021-02-21 13:31   ` Philippe Mathieu-Daudé
2021-03-04 19:57   ` Richard Henderson
2021-02-19 14:45 ` [PATCH 20/44] hw/misc/sse-cpu-pwrctrl: Implement SSE-300 CPU<N>_PWRCTRL register block Peter Maydell
2021-03-04 20:02   ` Richard Henderson
2021-02-19 14:45 ` [PATCH 21/44] hw/arm/armsse: Use an array for apb_ppc fields in the state structure Peter Maydell
2021-02-21 13:34   ` Philippe Mathieu-Daudé
2021-03-04 20:04   ` Richard Henderson
2021-02-19 14:45 ` [PATCH 22/44] hw/arm/armsse: Add a define for number of IRQs used by the SSE itself Peter Maydell
2021-02-21 13:34   ` Philippe Mathieu-Daudé
2021-03-04 20:04   ` Richard Henderson
2021-02-19 14:45 ` [PATCH 23/44] hw/arm/armsse: Add framework for data-driven device placement Peter Maydell
2021-03-04 20:10   ` Richard Henderson
2021-02-19 14:45 ` [PATCH 24/44] hw/arm/armsse: Move dual-timer device into data-driven framework Peter Maydell
2021-03-04 20:12   ` Richard Henderson
2021-02-19 14:45 ` [PATCH 25/44] hw/arm/armsse: Move watchdogs " Peter Maydell
2021-03-04 20:15   ` Richard Henderson
2021-02-19 14:45 ` [PATCH 26/44] hw/arm/armsse: Move s32ktimer " Peter Maydell
2021-03-04 20:16   ` Richard Henderson
2021-02-19 14:46 ` [PATCH 27/44] hw/arm/armsse: Move sysinfo register block " Peter Maydell
2021-03-04 20:19   ` Richard Henderson
2021-02-19 14:46 ` [PATCH 28/44] hw/arm/armsse: Move sysctl " Peter Maydell
2021-03-04 20:21   ` Richard Henderson
2021-02-19 14:46 ` [PATCH 29/44] hw/arm/armsse: Move PPUs " Peter Maydell
2021-03-04 20:24   ` Richard Henderson
2021-02-19 14:46 ` [PATCH 30/44] hw/arm/armsse: Add missing SSE-200 SYS_PPU Peter Maydell
2021-03-04 20:25   ` Richard Henderson
2021-02-19 14:46 ` [PATCH 31/44] hw/arm/armsse: Indirect irq_is_common[] through ARMSSEInfo Peter Maydell
2021-03-04 20:19   ` Philippe Mathieu-Daudé
2021-03-05 10:50     ` Philippe Mathieu-Daudé
2021-03-04 20:26   ` Richard Henderson
2021-02-19 14:46 ` [PATCH 32/44] hw/arm/armsse: Add support for SSE variants with a system counter Peter Maydell
2021-03-04 20:30   ` Richard Henderson
2021-02-19 14:46 ` [PATCH 33/44] hw/arm/armsse: Add support for TYPE_SSE_TIMER in ARMSSEDeviceInfo Peter Maydell
2021-03-04 20:22   ` Philippe Mathieu-Daudé
2021-03-04 20:34   ` Richard Henderson
2021-02-19 14:46 ` [PATCH 34/44] hw/arm/armsse: Support variants with ARMSSE_CPU_PWRCTRL block Peter Maydell
2021-03-04 20:37   ` Richard Henderson
2021-02-19 14:46 ` [PATCH 35/44] hw/arm/armsse: Add SSE-300 support Peter Maydell
2021-03-04 20:39   ` Richard Henderson
2021-02-19 14:46 ` [PATCH 36/44] hw/arm/mps2-tz: Make UART overflow IRQ board-specific Peter Maydell
2021-03-04 20:16   ` Philippe Mathieu-Daudé
2021-03-04 20:43   ` Richard Henderson
2021-02-19 14:46 ` [PATCH 37/44] hw/misc/mps2-fpgaio: Fold counters subsection into main vmstate Peter Maydell
2021-03-04 20:45   ` Richard Henderson
2021-02-19 14:46 ` [PATCH 38/44] hw/misc/mps2-fpgaio: Support AN547 DBGCTRL register Peter Maydell
2021-03-04 20:24   ` Philippe Mathieu-Daudé
2021-03-04 20:50   ` Richard Henderson
2021-02-19 14:46 ` [PATCH 39/44] hw/misc/mps2-scc: Implement changes for AN547 Peter Maydell
2021-03-05  0:30   ` Richard Henderson
2021-02-19 14:46 ` [PATCH 40/44] hw/arm/mps2-tz: Support running APB peripherals on different clock Peter Maydell
2021-03-04 20:27   ` Philippe Mathieu-Daudé
2021-03-05  1:01   ` Richard Henderson
2021-02-19 14:46 ` [PATCH 41/44] hw/arm/mps2-tz: Make initsvtor0 setting board-specific Peter Maydell
2021-03-04 20:17   ` Philippe Mathieu-Daudé
2021-03-05  1:05   ` Richard Henderson
2021-02-19 14:46 ` [PATCH 42/44] hw/arm/mps2-tz: Add new mps3-an547 board Peter Maydell
2021-03-05  1:19   ` Richard Henderson
2021-02-19 14:46 ` [PATCH 43/44] docs/system/arm/mps2.rst: Document the " Peter Maydell
2021-03-04 20:28   ` Philippe Mathieu-Daudé
2021-03-05  1:28   ` Richard Henderson
2021-03-05 10:22     ` Peter Maydell
2021-03-08 17:35       ` Peter Maydell
2021-02-19 14:46 ` [PATCH 44/44] tests/qtest/sse-timer-test: Add simple tests of the SSE timer and counter Peter Maydell
2021-03-05 11:08   ` Philippe Mathieu-Daudé
2021-02-19 15:43 ` [PATCH 00/44] hw/arm: New board model mps3-an547 no-reply
2021-03-05 11:56 ` Philippe Mathieu-Daudé

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.