All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-arm@nongnu.org, qemu-devel@nongnu.org
Subject: [PATCH 11/44] hw/timer/sse-counter: Model the SSE Subsystem System Counter
Date: Fri, 19 Feb 2021 14:45:44 +0000	[thread overview]
Message-ID: <20210219144617.4782-12-peter.maydell@linaro.org> (raw)
In-Reply-To: <20210219144617.4782-1-peter.maydell@linaro.org>

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



  parent reply	other threads:[~2021-02-19 14:54 UTC|newest]

Thread overview: 103+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 ` Peter Maydell [this message]
2021-03-04 18:38   ` [PATCH 11/44] hw/timer/sse-counter: Model the SSE Subsystem System Counter 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é

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210219144617.4782-12-peter.maydell@linaro.org \
    --to=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.