From 5ee0abed51231949ef91d7f8e1115be69ed91e93 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:45:34 +0000 Subject: clock: Add ClockEvent parameter to callbacks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Luc Michel Tested-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20210219144617.4782-2-peter.maydell@linaro.org --- include/hw/clock.h | 21 +++++++++++++++++++-- include/hw/qdev-clock.h | 17 ++++++++++++----- 2 files changed, 31 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/hw/clock.h b/include/hw/clock.h index e5f45e2626..282a37f7c5 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 64ca4d266f..ffa0f7ba09 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 } -- cgit v1.2.3 From e4341623a3b87e7eca87d42b7b88da967cd21c49 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:45:35 +0000 Subject: clock: Add ClockPreUpdate callback event type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new callback event type ClockPreUpdate, which is called on period changes before the period is updated. Signed-off-by: Peter Maydell Reviewed-by: Luc Michel Reviewed-by: Hao Wu Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Message-id: 20210219144617.4782-3-peter.maydell@linaro.org --- include/hw/clock.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/hw/clock.h b/include/hw/clock.h index 282a37f7c5..2ba44e1442 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); -- cgit v1.2.3 From cd3a53b727d2f86e9db795cee69cc142332ca079 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:45:36 +0000 Subject: clock: Add clock_ns_to_ticks() function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Luc Michel Reviewed-by: Hao Wu Tested-by: Philippe Mathieu-Daudé Message-id: 20210219144617.4782-4-peter.maydell@linaro.org --- include/hw/clock.h | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'include') diff --git a/include/hw/clock.h b/include/hw/clock.h index 2ba44e1442..a7187eab95 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 -- cgit v1.2.3 From 419a7f8075e24734ee22c3ceef6a446ba5306b27 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:45:38 +0000 Subject: hw/arm/armsse: Introduce SSE subsystem version property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Tested-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20210219144617.4782-6-peter.maydell@linaro.org --- include/hw/arm/armsse-version.h | 42 +++++++++++++++++++++++++++++++++++++++++ include/hw/misc/iotkit-sysctl.h | 7 +++---- 2 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 include/hw/arm/armsse-version.h (limited to 'include') diff --git a/include/hw/arm/armsse-version.h b/include/hw/arm/armsse-version.h new file mode 100644 index 0000000000..60780fa984 --- /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 2bc391138d..7cdafea3e2 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; -- cgit v1.2.3 From 1cbd6fe4b8d5ae77de583b298d7834c8abe6ff46 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:45:39 +0000 Subject: hw/misc/iotkit-sysctl: Remove is_sse200 flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Tested-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20210219144617.4782-7-peter.maydell@linaro.org --- include/hw/misc/iotkit-sysctl.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include') diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h index 7cdafea3e2..980c2ddfd3 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 -- cgit v1.2.3 From 0eb6b0ad16dfb3c4834c6943c3132b8d96294730 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:45:40 +0000 Subject: hw/misc/iotkit-secctl.c: Implement SSE-300 PID register values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Tested-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20210219144617.4782-8-peter.maydell@linaro.org --- include/hw/misc/iotkit-secctl.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/hw/misc/iotkit-secctl.h b/include/hw/misc/iotkit-secctl.h index 227d44abe4..79a3628320 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 -- cgit v1.2.3 From 407664539d76523222a4a4a3ef273645593f75b2 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:45:41 +0000 Subject: hw/misc/iotkit-sysinfo.c: Implement SSE-300 PID register values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Tested-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20210219144617.4782-9-peter.maydell@linaro.org --- include/hw/misc/iotkit-sysinfo.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h index 055771d209..91bd14bdbf 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 -- cgit v1.2.3 From 446587a914cfa57c2ce529056a9ca2215bde7111 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:45:43 +0000 Subject: hw/misc/iotkit-sysinfo.c: Implement SYS_CONFIG1 and IIDR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Tested-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20210219144617.4782-11-peter.maydell@linaro.org --- include/hw/misc/iotkit-sysinfo.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h index 91bd14bdbf..91c23f90d2 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 -- cgit v1.2.3 From 0d10df30384c22c5f683cbfebc42cee6cf83fed4 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:45:44 +0000 Subject: hw/timer/sse-counter: Model the SSE Subsystem System Counter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Tested-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20210219144617.4782-12-peter.maydell@linaro.org --- include/hw/timer/sse-counter.h | 105 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 include/hw/timer/sse-counter.h (limited to 'include') diff --git a/include/hw/timer/sse-counter.h b/include/hw/timer/sse-counter.h new file mode 100644 index 0000000000..b433e58d37 --- /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 -- cgit v1.2.3 From 0b8ceee822ae6d3bc4033c9b406c5f8d8c71ee6d Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:45:45 +0000 Subject: hw/timer/sse-timer: Model the SSE Subsystem System Timer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Tested-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20210219144617.4782-13-peter.maydell@linaro.org --- include/hw/timer/sse-timer.h | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 include/hw/timer/sse-timer.h (limited to 'include') diff --git a/include/hw/timer/sse-timer.h b/include/hw/timer/sse-timer.h new file mode 100644 index 0000000000..b4ee8e7f6c --- /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 -- cgit v1.2.3 From 2672a6ca72311bdf97f9e324ab2e71ff60bd2db9 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:45:49 +0000 Subject: hw/misc/iotkit-sysctl: Implement dummy version of SSE-300 PWRCTRL register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Tested-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20210219144617.4782-17-peter.maydell@linaro.org --- include/hw/misc/iotkit-sysctl.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h index 980c2ddfd3..8859b15d73 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; -- cgit v1.2.3 From c5ffe6c8dd5623f1893f54971e23e7c1ddf094ee Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:45:50 +0000 Subject: hw/misc/iotkit-sysctl: Handle SSE-300 changes to PDCM_PD_*_SENSE registers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Tested-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20210219144617.4782-18-peter.maydell@linaro.org --- include/hw/misc/iotkit-sysctl.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h index 8859b15d73..481e27f4db 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; -- cgit v1.2.3 From 4239b311467bea86578d9da3cd22909de69d7af7 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:45:53 +0000 Subject: hw/misc/sse-cpu-pwrctrl: Implement SSE-300 CPU_PWRCTRL register block MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SSE-300 has a new register block CPU_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 Tested-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20210219144617.4782-21-peter.maydell@linaro.org --- include/hw/misc/armsse-cpu-pwrctrl.h | 40 ++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 include/hw/misc/armsse-cpu-pwrctrl.h (limited to 'include') diff --git a/include/hw/misc/armsse-cpu-pwrctrl.h b/include/hw/misc/armsse-cpu-pwrctrl.h new file mode 100644 index 0000000000..51d45ede7d --- /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_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 -- cgit v1.2.3 From 91eb4f64eb49ea8dc7e5ebf5fdb377008ee0b688 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:45:54 +0000 Subject: hw/arm/armsse: Use an array for apb_ppc fields in the state structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Tested-by: Philippe Mathieu-Daudé Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20210219144617.4782-22-peter.maydell@linaro.org --- include/hw/arm/armsse.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h index 09284ca75c..771150b0a9 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; -- cgit v1.2.3 From 3378873802afe8af0355c4fac3e11e6510fc1f27 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:45:55 +0000 Subject: hw/arm/armsse: Add a define for number of IRQs used by the SSE itself MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Tested-by: Philippe Mathieu-Daudé Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20210219144617.4782-23-peter.maydell@linaro.org --- include/hw/arm/armsse.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h index 771150b0a9..e34263fed8 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; -- cgit v1.2.3 From e94d7723b5c0e7e51775ee8fc94a10e975392d0b Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:45:56 +0000 Subject: hw/arm/armsse: Add framework for data-driven device placement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Tested-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20210219144617.4782-24-peter.maydell@linaro.org --- include/hw/arm/armsse.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h index e34263fed8..c1f4df295a 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; -- cgit v1.2.3 From 1292b93289f8545f416f1d25ee701caa91d24415 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:45:58 +0000 Subject: hw/arm/armsse: Move watchdogs into data-driven framework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Tested-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20210219144617.4782-26-peter.maydell@linaro.org --- include/hw/arm/armsse.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'include') diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h index c1f4df295a..3f8f375057 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; -- cgit v1.2.3 From 99865afc66bafca6f734712a897c0b68460f7757 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:45:59 +0000 Subject: hw/arm/armsse: Move s32ktimer into data-driven framework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the CMSDK timer that uses the S32K slow clock into the data-driven device placement framework. Signed-off-by: Peter Maydell Tested-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20210219144617.4782-27-peter.maydell@linaro.org --- include/hw/arm/armsse.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h index 3f8f375057..7416c08a80 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]; -- cgit v1.2.3 From a459e849aa2b683fac20fc72db9b4b1d90a4b4b9 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:46:02 +0000 Subject: hw/arm/armsse: Move PPUs into data-driven framework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Tested-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20210219144617.4782-30-peter.maydell@linaro.org --- include/hw/arm/armsse.h | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'include') diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h index 7416c08a80..eb4e937173 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]; -- cgit v1.2.3 From 6fe8acb41ed5a4b033ae7b5f876968e568476129 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:46:03 +0000 Subject: hw/arm/armsse: Add missing SSE-200 SYS_PPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Tested-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20210219144617.4782-31-peter.maydell@linaro.org --- include/hw/arm/armsse.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h index eb4e937173..104ba8d26e 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 -- cgit v1.2.3 From 9febd175415dbc84e6ff7bda9bf6d90fe060181e Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:46:05 +0000 Subject: hw/arm/armsse: Add support for SSE variants with a system counter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Tested-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20210219144617.4782-33-peter.maydell@linaro.org --- include/hw/arm/armsse.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h index 104ba8d26e..149f17dfc8 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; -- cgit v1.2.3 From f11de23158528c90b51c603c0cc3b2286e71d3fc Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:46:06 +0000 Subject: hw/arm/armsse: Add support for TYPE_SSE_TIMER in ARMSSEDeviceInfo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Tested-by: Philippe Mathieu-Daudé Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20210219144617.4782-34-peter.maydell@linaro.org --- include/hw/arm/armsse.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h index 149f17dfc8..f4e2b68047 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; -- cgit v1.2.3 From 4668b441cb667619916d4bc6a204f3df06730dfb Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:46:07 +0000 Subject: hw/arm/armsse: Support variants with ARMSSE_CPU_PWRCTRL block MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Tested-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20210219144617.4782-35-peter.maydell@linaro.org --- include/hw/arm/armsse.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h index f4e2b68047..21d239c381 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 -- cgit v1.2.3 From 8901bb414a2416a3ad3bc870770daaebb08c3aa8 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:46:08 +0000 Subject: hw/arm/armsse: Add SSE-300 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Tested-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20210219144617.4782-36-peter.maydell@linaro.org --- include/hw/arm/armsse.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h index 21d239c381..36592be62c 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 -- cgit v1.2.3 From 39901aea063fb4be77a89d7badfed3998ad8fb4a Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 19 Feb 2021 14:46:11 +0000 Subject: hw/misc/mps2-fpgaio: Support AN547 DBGCTRL register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Tested-by: Philippe Mathieu-Daudé Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20210219144617.4782-39-peter.maydell@linaro.org --- include/hw/misc/mps2-fpgaio.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h index e04fd590b6..7b8bd604de 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; -- cgit v1.2.3 From 35593573b25f8774ce16be8a7d703b7740964e81 Mon Sep 17 00:00:00 2001 From: Xuzhou Cheng Date: Wed, 3 Mar 2021 21:52:50 +0800 Subject: hw/dma: Implement a Xilinx CSU DMA model ZynqMP QSPI supports SPI transfer using DMA mode, but currently this is unimplemented. When QSPI is programmed to use DMA mode, QEMU will crash. This is observed when testing VxWorks 7. This adds a Xilinx CSU DMA model and the implementation is based on https://github.com/Xilinx/qemu/blob/master/hw/dma/csu_stream_dma.c. The DST part of the model is verified along with ZynqMP GQSPI model. Signed-off-by: Xuzhou Cheng Signed-off-by: Bin Meng Tested-by: Edgar E. Iglesias Reviewed-by: Edgar E. Iglesias Message-id: 20210303135254.3970-2-bmeng.cn@gmail.com Signed-off-by: Peter Maydell --- include/hw/dma/xlnx_csu_dma.h | 52 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 include/hw/dma/xlnx_csu_dma.h (limited to 'include') diff --git a/include/hw/dma/xlnx_csu_dma.h b/include/hw/dma/xlnx_csu_dma.h new file mode 100644 index 0000000000..204d94c673 --- /dev/null +++ b/include/hw/dma/xlnx_csu_dma.h @@ -0,0 +1,52 @@ +/* + * Xilinx Platform CSU Stream DMA emulation + * + * This implementation is based on + * https://github.com/Xilinx/qemu/blob/master/hw/dma/csu_stream_dma.c + * + * 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 or + * (at your option) version 3 of the License. + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + */ + +#ifndef XLNX_CSU_DMA_H +#define XLNX_CSU_DMA_H + +#define TYPE_XLNX_CSU_DMA "xlnx.csu_dma" + +#define XLNX_CSU_DMA_R_MAX (0x2c / 4) + +typedef struct XlnxCSUDMA { + SysBusDevice busdev; + MemoryRegion iomem; + MemTxAttrs attr; + MemoryRegion *dma_mr; + AddressSpace *dma_as; + qemu_irq irq; + StreamSink *tx_dev; /* Used as generic StreamSink */ + ptimer_state *src_timer; + + uint16_t width; + bool is_dst; + bool r_size_last_word; + + StreamCanPushNotifyFn notify; + void *notify_opaque; + + uint32_t regs[XLNX_CSU_DMA_R_MAX]; + RegisterInfo regs_info[XLNX_CSU_DMA_R_MAX]; +} XlnxCSUDMA; + +#define XLNX_CSU_DMA(obj) \ + OBJECT_CHECK(XlnxCSUDMA, (obj), TYPE_XLNX_CSU_DMA) + +#endif -- cgit v1.2.3 From 21bce3717e2cb70e3bea06e8684bae111c9f4dda Mon Sep 17 00:00:00 2001 From: Xuzhou Cheng Date: Wed, 3 Mar 2021 21:52:51 +0800 Subject: hw/arm: xlnx-zynqmp: Clean up coding convention issues There are some coding convention warnings in xlnx-zynqmp.c and xlnx-zynqmp.h, as reported by: $ ./scripts/checkpatch.pl include/hw/arm/xlnx-zynqmp.h $ ./scripts/checkpatch.pl hw/arm/xlnx-zynqmp.c Let's clean them up. Signed-off-by: Xuzhou Cheng Signed-off-by: Bin Meng Reviewed-by: Edgar E. Iglesias Message-id: 20210303135254.3970-3-bmeng.cn@gmail.com Signed-off-by: Peter Maydell --- include/hw/arm/xlnx-zynqmp.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h index 0678b419a2..c83ef23e92 100644 --- a/include/hw/arm/xlnx-zynqmp.h +++ b/include/hw/arm/xlnx-zynqmp.h @@ -60,7 +60,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP) #define XLNX_ZYNQMP_GIC_REGIONS 6 -/* ZynqMP maps the ARM GIC regions (GICC, GICD ...) at consecutive 64k offsets +/* + * ZynqMP maps the ARM GIC regions (GICC, GICD ...) at consecutive 64k offsets * and under-decodes the 64k region. This mirrors the 4k regions to every 4k * aligned address in the 64k region. To implement each GIC region needs a * number of memory region aliases. -- cgit v1.2.3 From 668351a54883b6283e7ae94daf4d4eca1a071158 Mon Sep 17 00:00:00 2001 From: Xuzhou Cheng Date: Wed, 3 Mar 2021 21:52:52 +0800 Subject: hw/arm: xlnx-zynqmp: Connect a Xilinx CSU DMA module for QSPI Add a Xilinx CSU DMA module to ZynqMP SoC, and connent the stream link of GQSPI to CSU DMA. Signed-off-by: Xuzhou Cheng Signed-off-by: Bin Meng Reviewed-by: Edgar E. Iglesias Message-id: 20210303135254.3970-4-bmeng.cn@gmail.com Signed-off-by: Peter Maydell --- include/hw/arm/xlnx-zynqmp.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h index c83ef23e92..1676a84ec8 100644 --- a/include/hw/arm/xlnx-zynqmp.h +++ b/include/hw/arm/xlnx-zynqmp.h @@ -35,6 +35,7 @@ #include "target/arm/cpu.h" #include "qom/object.h" #include "net/can_emu.h" +#include "hw/dma/xlnx_csu_dma.h" #define TYPE_XLNX_ZYNQMP "xlnx,zynqmp" OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP) @@ -108,6 +109,7 @@ struct XlnxZynqMPState { XlnxZynqMPRTC rtc; XlnxZDMA gdma[XLNX_ZYNQMP_NUM_GDMA_CH]; XlnxZDMA adma[XLNX_ZYNQMP_NUM_ADMA_CH]; + XlnxCSUDMA qspi_dma; char *boot_cpu; ARMCPU *boot_cpu_ptr; -- cgit v1.2.3 From d6bafaf45c5ff31ad7d7d87c3c3d37ae675684cc Mon Sep 17 00:00:00 2001 From: Xuzhou Cheng Date: Wed, 3 Mar 2021 21:52:54 +0800 Subject: hw/ssi: xilinx_spips: Remove DMA related dead codes from zynqmp_spips Now that the Xilinx CSU DMA model is implemented, the existing DMA related dead codes in the ZynqMP QSPI are useless and should be removed. The maximum register number is also updated to only include the QSPI registers. Signed-off-by: Xuzhou Cheng Signed-off-by: Bin Meng Reviewed-by: Edgar E. Iglesias Message-id: 20210303135254.3970-6-bmeng.cn@gmail.com Signed-off-by: Peter Maydell --- include/hw/ssi/xilinx_spips.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/hw/ssi/xilinx_spips.h b/include/hw/ssi/xilinx_spips.h index 3eae73480e..06bfd18312 100644 --- a/include/hw/ssi/xilinx_spips.h +++ b/include/hw/ssi/xilinx_spips.h @@ -34,7 +34,7 @@ typedef struct XilinxSPIPS XilinxSPIPS; #define XLNX_SPIPS_R_MAX (0x100 / 4) -#define XLNX_ZYNQMP_SPIPS_R_MAX (0x830 / 4) +#define XLNX_ZYNQMP_SPIPS_R_MAX (0x200 / 4) /* Bite off 4k chunks at a time */ #define LQSPI_CACHE_SIZE 1024 -- cgit v1.2.3