1
Almost nothing in here is arm-related, but the target-arm
1
This is almost all the mps3-an547 series, but there are a few
2
queue was convenient for these last minute bits and pieces
2
other bits in there too.
3
for 5.0...
4
3
5
thanks
4
thanks
6
-- PMM
5
-- PMM
7
6
8
The following changes since commit 14e5526b51910efd62cd31cd95b49baca975c83f:
9
7
10
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging (2020-04-13 15:42:51 +0100)
8
The following changes since commit 0436c55edf6b357ff56e2a5bf688df8636f83456:
9
10
Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging (2021-03-08 13:51:41 +0000)
11
11
12
are available in the Git repository at:
12
are available in the Git repository at:
13
13
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200414
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210308-1
15
15
16
for you to fetch changes up to 84f82ddcbb4ac4ed04c8675e85155329f23184f0:
16
for you to fetch changes up to da2140183ac3a04b1ccb861aeac1f2c048c71b66:
17
17
18
Deprecate KVM support for AArch32 (2020-04-14 17:20:22 +0100)
18
hw/timer/renesas_tmr: Fix use of uninitialized data in read_tcnt() (2021-03-08 17:20:04 +0000)
19
19
20
----------------------------------------------------------------
20
----------------------------------------------------------------
21
patch queue:
21
* Add new mps3-an547 board
22
* Fix some problems that trip up Coverity's scanner
22
* target/arm: Restrict v7A TCG cpus to TCG accel
23
* run-coverity-scan: New script automating the scan-and-upload process
23
* Implement a Xilinx CSU DMA model
24
* docs: Improve our gdbstub documentation
24
* hw/timer/renesas_tmr: Fix use of uninitialized data in read_tcnt()
25
* configure: Honour --disable-werror for Sphinx
26
* docs: Fix errors produced when building with Sphinx 3.0
27
* docs: Require Sphinx 1.6 or better
28
* Add deprecation notice for KVM support on AArch32 hosts
29
25
30
----------------------------------------------------------------
26
----------------------------------------------------------------
31
Peter Maydell (12):
27
Peter Maydell (48):
32
osdep.h: Drop no-longer-needed Coverity workarounds
28
clock: Add ClockEvent parameter to callbacks
33
thread.h: Fix Coverity version of qemu_cond_timedwait()
29
clock: Add ClockPreUpdate callback event type
34
thread.h: Remove trailing semicolons from Coverity qemu_mutex_lock() etc
30
clock: Add clock_ns_to_ticks() function
35
linux-user/flatload.c: Use "" for include of QEMU header target_flat.h
31
hw/timer/npcm7xx_timer: Use new clock_ns_to_ticks()
36
scripts/run-coverity-scan: Script to run Coverity Scan build
32
hw/arm/armsse: Introduce SSE subsystem version property
37
scripts/coverity-scan: Add Docker support
33
hw/misc/iotkit-sysctl: Remove is_sse200 flag
38
docs: Improve our gdbstub documentation
34
hw/misc/iotkit-secctl.c: Implement SSE-300 PID register values
39
configure: Honour --disable-werror for Sphinx
35
hw/misc/iotkit-sysinfo.c: Implement SSE-300 PID register values
40
scripts/kernel-doc: Add missing close-paren in c:function directives
36
hw/arm/armsse.c: Use correct SYS_CONFIG0 register value for SSE-300
41
kernel-doc: Use c:struct for Sphinx 3.0 and later
37
hw/misc/iotkit-sysinfo.c: Implement SYS_CONFIG1 and IIDR
42
docs: Require Sphinx 1.6 or better
38
hw/timer/sse-counter: Model the SSE Subsystem System Counter
43
Deprecate KVM support for AArch32
39
hw/timer/sse-timer: Model the SSE Subsystem System Timer
40
hw/misc/iotkit-sysctl: Add SSE-300 cases which match SSE-200 behaviour
41
hw/misc/iotkit-sysctl: Handle CPU_WAIT, NMI_ENABLE for SSE-300
42
hw/misc/iotkit-sysctl: Handle INITSVTOR* for SSE-300
43
hw/misc/iotkit-sysctl: Implement dummy version of SSE-300 PWRCTRL register
44
hw/misc/iotkit-sysctl: Handle SSE-300 changes to PDCM_PD_*_SENSE registers
45
hw/misc/iotkit-sysctl: Implement SSE-200 and SSE-300 PID register values
46
hw/arm/Kconfig: Move ARMSSE_CPUID and ARMSSE_MHU stanzas to hw/misc
47
hw/misc/sse-cpu-pwrctrl: Implement SSE-300 CPU<N>_PWRCTRL register block
48
hw/arm/armsse: Use an array for apb_ppc fields in the state structure
49
hw/arm/armsse: Add a define for number of IRQs used by the SSE itself
50
hw/arm/armsse: Add framework for data-driven device placement
51
hw/arm/armsse: Move dual-timer device into data-driven framework
52
hw/arm/armsse: Move watchdogs into data-driven framework
53
hw/arm/armsse: Move s32ktimer into data-driven framework
54
hw/arm/armsse: Move sysinfo register block into data-driven framework
55
hw/arm/armsse: Move sysctl register block into data-driven framework
56
hw/arm/armsse: Move PPUs into data-driven framework
57
hw/arm/armsse: Add missing SSE-200 SYS_PPU
58
hw/arm/armsse: Indirect irq_is_common[] through ARMSSEInfo
59
hw/arm/armsse: Add support for SSE variants with a system counter
60
hw/arm/armsse: Add support for TYPE_SSE_TIMER in ARMSSEDeviceInfo
61
hw/arm/armsse: Support variants with ARMSSE_CPU_PWRCTRL block
62
hw/arm/armsse: Add SSE-300 support
63
hw/arm/mps2-tz: Make UART overflow IRQ board-specific
64
hw/misc/mps2-fpgaio: Fold counters subsection into main vmstate
65
hw/misc/mps2-fpgaio: Support AN547 DBGCTRL register
66
hw/misc/mps2-scc: Implement changes for AN547
67
hw/arm/mps2-tz: Support running APB peripherals on different clock
68
hw/arm/mps2-tz: Make initsvtor0 setting board-specific
69
hw/arm/mps2-tz: Add new mps3-an547 board
70
docs/system/arm/mps2.rst: Document the new mps3-an547 board
71
tests/qtest/sse-timer-test: Add simple test of the SSE counter
72
tests/qtest/sse-timer-test: Test the system timer
73
tests/qtest/sse-timer-test: Test counter scaling changes
74
hw/timer/renesas_tmr: Prefix constants for CSS values with CSS_
75
hw/timer/renesas_tmr: Fix use of uninitialized data in read_tcnt()
44
76
45
configure | 9 +-
77
Philippe Mathieu-Daudé (1):
46
Makefile | 2 +-
78
target/arm: Restrict v7A TCG cpus to TCG accel
47
include/qemu/osdep.h | 14 -
48
include/qemu/thread.h | 12 +-
49
linux-user/flatload.c | 2 +-
50
MAINTAINERS | 5 +
51
docs/conf.py | 6 +-
52
docs/sphinx/kerneldoc.py | 1 +
53
docs/system/deprecated.rst | 8 +
54
docs/system/gdb.rst | 22 +-
55
qemu-options.hx | 24 +-
56
scripts/coverity-scan/coverity-scan.docker | 131 ++++++++++
57
scripts/coverity-scan/run-coverity-scan | 401 +++++++++++++++++++++++++++++
58
scripts/kernel-doc | 18 +-
59
14 files changed, 615 insertions(+), 40 deletions(-)
60
create mode 100644 scripts/coverity-scan/coverity-scan.docker
61
create mode 100755 scripts/coverity-scan/run-coverity-scan
62
79
80
Xuzhou Cheng (5):
81
hw/dma: Implement a Xilinx CSU DMA model
82
hw/arm: xlnx-zynqmp: Clean up coding convention issues
83
hw/arm: xlnx-zynqmp: Connect a Xilinx CSU DMA module for QSPI
84
hw/ssi: xilinx_spips: Clean up coding convention issues
85
hw/ssi: xilinx_spips: Remove DMA related dead codes from zynqmp_spips
86
87
docs/devel/clocks.rst | 71 ++-
88
docs/system/arm/mps2.rst | 6 +-
89
include/hw/arm/armsse-version.h | 42 ++
90
include/hw/arm/armsse.h | 40 +-
91
include/hw/arm/xlnx-zynqmp.h | 5 +-
92
include/hw/clock.h | 63 ++-
93
include/hw/dma/xlnx_csu_dma.h | 52 ++
94
include/hw/misc/armsse-cpu-pwrctrl.h | 40 ++
95
include/hw/misc/iotkit-secctl.h | 2 +
96
include/hw/misc/iotkit-sysctl.h | 13 +-
97
include/hw/misc/iotkit-sysinfo.h | 2 +
98
include/hw/misc/mps2-fpgaio.h | 2 +
99
include/hw/qdev-clock.h | 17 +-
100
include/hw/ssi/xilinx_spips.h | 2 +-
101
include/hw/timer/sse-counter.h | 105 ++++
102
include/hw/timer/sse-timer.h | 53 ++
103
hw/adc/npcm7xx_adc.c | 2 +-
104
hw/arm/armsse.c | 1008 +++++++++++++++++++++++++---------
105
hw/arm/mps2-tz.c | 168 +++++-
106
hw/arm/xlnx-zynqmp.c | 21 +-
107
hw/char/cadence_uart.c | 4 +-
108
hw/char/ibex_uart.c | 4 +-
109
hw/char/pl011.c | 5 +-
110
hw/core/clock.c | 24 +-
111
hw/core/qdev-clock.c | 8 +-
112
hw/dma/xlnx_csu_dma.c | 745 +++++++++++++++++++++++++
113
hw/mips/cps.c | 2 +-
114
hw/misc/armsse-cpu-pwrctrl.c | 149 +++++
115
hw/misc/bcm2835_cprman.c | 23 +-
116
hw/misc/iotkit-secctl.c | 50 +-
117
hw/misc/iotkit-sysctl.c | 522 +++++++++++++++---
118
hw/misc/iotkit-sysinfo.c | 51 +-
119
hw/misc/mps2-fpgaio.c | 52 +-
120
hw/misc/mps2-scc.c | 15 +-
121
hw/misc/npcm7xx_clk.c | 26 +-
122
hw/misc/npcm7xx_pwm.c | 2 +-
123
hw/misc/zynq_slcr.c | 5 +-
124
hw/ssi/xilinx_spips.c | 33 +-
125
hw/timer/cmsdk-apb-dualtimer.c | 5 +-
126
hw/timer/cmsdk-apb-timer.c | 4 +-
127
hw/timer/npcm7xx_timer.c | 6 +-
128
hw/timer/renesas_tmr.c | 33 +-
129
hw/timer/sse-counter.c | 474 ++++++++++++++++
130
hw/timer/sse-timer.c | 470 ++++++++++++++++
131
hw/watchdog/cmsdk-apb-watchdog.c | 5 +-
132
target/arm/cpu.c | 335 -----------
133
target/arm/cpu_tcg.c | 318 +++++++++++
134
target/mips/cpu.c | 2 +-
135
tests/qtest/sse-timer-test.c | 240 ++++++++
136
MAINTAINERS | 7 +
137
hw/arm/Kconfig | 10 +-
138
hw/dma/Kconfig | 4 +
139
hw/dma/meson.build | 1 +
140
hw/misc/Kconfig | 9 +
141
hw/misc/meson.build | 1 +
142
hw/misc/trace-events | 4 +
143
hw/timer/Kconfig | 6 +
144
hw/timer/meson.build | 2 +
145
hw/timer/trace-events | 12 +
146
tests/qtest/meson.build | 1 +
147
60 files changed, 4537 insertions(+), 846 deletions(-)
148
create mode 100644 include/hw/arm/armsse-version.h
149
create mode 100644 include/hw/dma/xlnx_csu_dma.h
150
create mode 100644 include/hw/misc/armsse-cpu-pwrctrl.h
151
create mode 100644 include/hw/timer/sse-counter.h
152
create mode 100644 include/hw/timer/sse-timer.h
153
create mode 100644 hw/dma/xlnx_csu_dma.c
154
create mode 100644 hw/misc/armsse-cpu-pwrctrl.c
155
create mode 100644 hw/timer/sse-counter.c
156
create mode 100644 hw/timer/sse-timer.c
157
create mode 100644 tests/qtest/sse-timer-test.c
158
diff view generated by jsdifflib
New patch
1
The Clock framework allows users to specify a callback which is
2
called after the clock's period has been updated. Some users need to
3
also have a callback which is called before the clock period is
4
updated.
1
5
6
As the first step in adding support for notifying Clock users on
7
pre-update events, add an argument to the ClockCallback to specify
8
what event is being notified, and add an argument to the various
9
functions for registering a callback to specify which events are
10
of interest to that callback.
11
12
Note that the documentation update renders correct the previously
13
incorrect claim in 'Adding a new clock' that callbacks "will be
14
explained in a following section".
15
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Reviewed-by: Luc Michel <luc@lmichel.fr>
19
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Message-id: 20210219144617.4782-2-peter.maydell@linaro.org
22
---
23
docs/devel/clocks.rst | 52 +++++++++++++++++++++++++++-----
24
include/hw/clock.h | 21 +++++++++++--
25
include/hw/qdev-clock.h | 17 ++++++++---
26
hw/adc/npcm7xx_adc.c | 2 +-
27
hw/arm/armsse.c | 9 +++---
28
hw/char/cadence_uart.c | 4 +--
29
hw/char/ibex_uart.c | 4 +--
30
hw/char/pl011.c | 5 +--
31
hw/core/clock.c | 21 ++++++++++---
32
hw/core/qdev-clock.c | 8 +++--
33
hw/mips/cps.c | 2 +-
34
hw/misc/bcm2835_cprman.c | 23 ++++++++------
35
hw/misc/npcm7xx_clk.c | 26 +++++++++++++---
36
hw/misc/npcm7xx_pwm.c | 2 +-
37
hw/misc/zynq_slcr.c | 5 +--
38
hw/timer/cmsdk-apb-dualtimer.c | 5 +--
39
hw/timer/cmsdk-apb-timer.c | 4 +--
40
hw/timer/npcm7xx_timer.c | 2 +-
41
hw/watchdog/cmsdk-apb-watchdog.c | 5 +--
42
target/mips/cpu.c | 2 +-
43
20 files changed, 161 insertions(+), 58 deletions(-)
44
45
diff --git a/docs/devel/clocks.rst b/docs/devel/clocks.rst
46
index XXXXXXX..XXXXXXX 100644
47
--- a/docs/devel/clocks.rst
48
+++ b/docs/devel/clocks.rst
49
@@ -XXX,XX +XXX,XX @@ Adding clocks to a device must be done during the init method of the Device
50
instance.
51
52
To add an input clock to a device, the function ``qdev_init_clock_in()``
53
-must be used. It takes the name, a callback and an opaque parameter
54
-for the callback (this will be explained in a following section).
55
+must be used. It takes the name, a callback, an opaque parameter
56
+for the callback and a mask of events when the callback should be
57
+called (this will be explained in a following section).
58
Output is simpler; only the name is required. Typically::
59
60
- qdev_init_clock_in(DEVICE(dev), "clk_in", clk_in_callback, dev);
61
+ qdev_init_clock_in(DEVICE(dev), "clk_in", clk_in_callback, dev, ClockUpdate);
62
qdev_init_clock_out(DEVICE(dev), "clk_out");
63
64
Both functions return the created Clock pointer, which should be saved in the
65
@@ -XXX,XX +XXX,XX @@ output.
66
* callback for the input clock (see "Callback on input clock
67
* change" section below for more information).
68
*/
69
- static void clk_in_callback(void *opaque);
70
+ static void clk_in_callback(void *opaque, ClockEvent event);
71
72
/*
73
* static array describing clocks:
74
@@ -XXX,XX +XXX,XX @@ output.
75
* the clk_out field of a MyDeviceState structure.
76
*/
77
static const ClockPortInitArray mydev_clocks = {
78
- QDEV_CLOCK_IN(MyDeviceState, clk_in, clk_in_callback),
79
+ QDEV_CLOCK_IN(MyDeviceState, clk_in, clk_in_callback, ClockUpdate),
80
QDEV_CLOCK_OUT(MyDeviceState, clk_out),
81
QDEV_CLOCK_END
82
};
83
@@ -XXX,XX +XXX,XX @@ nothing else to do. This value will be propagated to other clocks when
84
connecting the clocks together and devices will fetch the right value during
85
the first reset.
86
87
+Clock callbacks
88
+---------------
89
+
90
+You can give a clock a callback function in several ways:
91
+
92
+ * by passing it as an argument to ``qdev_init_clock_in()``
93
+ * as an argument to the ``QDEV_CLOCK_IN()`` macro initializing an
94
+ array to be passed to ``qdev_init_clocks()``
95
+ * by directly calling the ``clock_set_callback()`` function
96
+
97
+The callback function must be of this type:
98
+
99
+.. code-block:: c
100
+
101
+ typedef void ClockCallback(void *opaque, ClockEvent event);
102
+
103
+The ``opaque`` argument is the pointer passed to ``qdev_init_clock_in()``
104
+or ``clock_set_callback()``; for ``qdev_init_clocks()`` it is the
105
+``dev`` device pointer.
106
+
107
+The ``event`` argument specifies why the callback has been called.
108
+When you register the callback you specify a mask of ClockEvent values
109
+that you are interested in. The callback will only be called for those
110
+events.
111
+
112
+The events currently supported are:
113
+
114
+ * ``ClockUpdate`` : called after the input clock's period has changed
115
+
116
+Note that a clock only has one callback: it is not possible to register
117
+different functions for different events. You must register a single
118
+callback which listens for all of the events you are interested in,
119
+and use the ``event`` argument to identify which event has happened.
120
+
121
Retrieving clocks from a device
122
-------------------------------
123
124
@@ -XXX,XX +XXX,XX @@ object during device instance init. For example:
125
.. code-block:: c
126
127
clk = qdev_init_clock_in(DEVICE(dev), "clk-in", clk_in_callback,
128
- dev);
129
+ dev, ClockUpdate);
130
/* set initial value to 10ns / 100MHz */
131
clock_set_ns(clk, 10);
132
133
@@ -XXX,XX +XXX,XX @@ next lowest integer. This implies some inaccuracy due to the rounding,
134
so be cautious about using it in calculations.
135
136
It is also possible to register a callback on clock frequency changes.
137
-Here is an example:
138
+Here is an example, which assumes that ``clock_callback`` has been
139
+specified as the callback for the ``ClockUpdate`` event:
140
141
.. code-block:: c
142
143
- void clock_callback(void *opaque) {
144
+ void clock_callback(void *opaque, ClockEvent event) {
145
MyDeviceState *s = (MyDeviceState *) opaque;
146
/*
147
* 'opaque' is the argument passed to qdev_init_clock_in();
148
diff --git a/include/hw/clock.h b/include/hw/clock.h
149
index XXXXXXX..XXXXXXX 100644
150
--- a/include/hw/clock.h
151
+++ b/include/hw/clock.h
152
@@ -XXX,XX +XXX,XX @@
153
#define TYPE_CLOCK "clock"
154
OBJECT_DECLARE_SIMPLE_TYPE(Clock, CLOCK)
155
156
-typedef void ClockCallback(void *opaque);
157
+/*
158
+ * Argument to ClockCallback functions indicating why the callback
159
+ * has been called. A mask of these values logically ORed together
160
+ * is used to specify which events are interesting when the callback
161
+ * is registered, so these values must all be different bit values.
162
+ */
163
+typedef enum ClockEvent {
164
+ ClockUpdate = 1, /* Clock period has just updated */
165
+} ClockEvent;
166
+
167
+typedef void ClockCallback(void *opaque, ClockEvent event);
168
169
/*
170
* clock store a value representing the clock's period in 2^-32ns unit.
171
@@ -XXX,XX +XXX,XX @@ typedef void ClockCallback(void *opaque);
172
* @canonical_path: clock path string cache (used for trace purpose)
173
* @callback: called when clock changes
174
* @callback_opaque: argument for @callback
175
+ * @callback_events: mask of events when callback should be called
176
* @source: source (or parent in clock tree) of the clock
177
* @children: list of clocks connected to this one (it is their source)
178
* @sibling: structure used to form a clock list
179
@@ -XXX,XX +XXX,XX @@ struct Clock {
180
char *canonical_path;
181
ClockCallback *callback;
182
void *callback_opaque;
183
+ unsigned int callback_events;
184
185
/* Clocks are organized in a clock tree */
186
Clock *source;
187
@@ -XXX,XX +XXX,XX @@ Clock *clock_new(Object *parent, const char *name);
188
* @clk: the clock to register the callback into
189
* @cb: the callback function
190
* @opaque: the argument to the callback
191
+ * @events: the events the callback should be called for
192
+ * (logical OR of ClockEvent enum values)
193
*
194
* Register a callback called on every clock update.
195
+ * Note that a clock has only one callback: you cannot register
196
+ * different callback functions for different events.
197
*/
198
-void clock_set_callback(Clock *clk, ClockCallback *cb, void *opaque);
199
+void clock_set_callback(Clock *clk, ClockCallback *cb,
200
+ void *opaque, unsigned int events);
201
202
/**
203
* clock_clear_callback:
204
diff --git a/include/hw/qdev-clock.h b/include/hw/qdev-clock.h
205
index XXXXXXX..XXXXXXX 100644
206
--- a/include/hw/qdev-clock.h
207
+++ b/include/hw/qdev-clock.h
208
@@ -XXX,XX +XXX,XX @@
209
* @name: the name of the clock (can't be NULL).
210
* @callback: optional callback to be called on update or NULL.
211
* @opaque: argument for the callback
212
+ * @events: the events the callback should be called for
213
+ * (logical OR of ClockEvent enum values)
214
* @returns: a pointer to the newly added clock
215
*
216
* Add an input clock to device @dev as a clock named @name.
217
@@ -XXX,XX +XXX,XX @@
218
* The callback will be called with @opaque as opaque parameter.
219
*/
220
Clock *qdev_init_clock_in(DeviceState *dev, const char *name,
221
- ClockCallback *callback, void *opaque);
222
+ ClockCallback *callback, void *opaque,
223
+ unsigned int events);
224
225
/**
226
* qdev_init_clock_out:
227
@@ -XXX,XX +XXX,XX @@ void qdev_finalize_clocklist(DeviceState *dev);
228
* @output: indicates whether the clock is input or output
229
* @callback: for inputs, optional callback to be called on clock's update
230
* with device as opaque
231
+ * @callback_events: mask of ClockEvent values for when callback is called
232
* @offset: optional offset to store the ClockIn or ClockOut pointer in device
233
* state structure (0 means unused)
234
*/
235
@@ -XXX,XX +XXX,XX @@ struct ClockPortInitElem {
236
const char *name;
237
bool is_output;
238
ClockCallback *callback;
239
+ unsigned int callback_events;
240
size_t offset;
241
};
242
243
@@ -XXX,XX +XXX,XX @@ struct ClockPortInitElem {
244
(offsetof(devstate, field) + \
245
type_check(Clock *, typeof_field(devstate, field)))
246
247
-#define QDEV_CLOCK(out_not_in, devstate, field, cb) { \
248
+#define QDEV_CLOCK(out_not_in, devstate, field, cb, cbevents) { \
249
.name = (stringify(field)), \
250
.is_output = out_not_in, \
251
.callback = cb, \
252
+ .callback_events = cbevents, \
253
.offset = clock_offset_value(devstate, field), \
254
}
255
256
@@ -XXX,XX +XXX,XX @@ struct ClockPortInitElem {
257
* @field: a field in @_devstate (must be Clock*)
258
* @callback: (for input only) callback (or NULL) to be called with the device
259
* state as argument
260
+ * @cbevents: (for input only) ClockEvent mask for when callback is called
261
*
262
* The name of the clock will be derived from @field
263
*/
264
-#define QDEV_CLOCK_IN(devstate, field, callback) \
265
- QDEV_CLOCK(false, devstate, field, callback)
266
+#define QDEV_CLOCK_IN(devstate, field, callback, cbevents) \
267
+ QDEV_CLOCK(false, devstate, field, callback, cbevents)
268
269
#define QDEV_CLOCK_OUT(devstate, field) \
270
- QDEV_CLOCK(true, devstate, field, NULL)
271
+ QDEV_CLOCK(true, devstate, field, NULL, 0)
272
273
#define QDEV_CLOCK_END { .name = NULL }
274
275
diff --git a/hw/adc/npcm7xx_adc.c b/hw/adc/npcm7xx_adc.c
276
index XXXXXXX..XXXXXXX 100644
277
--- a/hw/adc/npcm7xx_adc.c
278
+++ b/hw/adc/npcm7xx_adc.c
279
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_adc_init(Object *obj)
280
memory_region_init_io(&s->iomem, obj, &npcm7xx_adc_ops, s,
281
TYPE_NPCM7XX_ADC, 4 * KiB);
282
sysbus_init_mmio(sbd, &s->iomem);
283
- s->clock = qdev_init_clock_in(DEVICE(s), "clock", NULL, NULL);
284
+ s->clock = qdev_init_clock_in(DEVICE(s), "clock", NULL, NULL, 0);
285
286
for (i = 0; i < NPCM7XX_ADC_NUM_INPUTS; ++i) {
287
object_property_add_uint32_ptr(obj, "adci[*]",
288
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
289
index XXXXXXX..XXXXXXX 100644
290
--- a/hw/arm/armsse.c
291
+++ b/hw/arm/armsse.c
292
@@ -XXX,XX +XXX,XX @@ static void armsse_forward_sec_resp_cfg(ARMSSE *s)
293
qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
294
}
295
296
-static void armsse_mainclk_update(void *opaque)
297
+static void armsse_mainclk_update(void *opaque, ClockEvent event)
298
{
299
ARMSSE *s = ARM_SSE(opaque);
300
+
301
/*
302
* Set system_clock_scale from our Clock input; this is what
303
* controls the tick rate of the CPU SysTick timer.
304
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
305
assert(info->num_cpus <= SSE_MAX_CPUS);
306
307
s->mainclk = qdev_init_clock_in(DEVICE(s), "MAINCLK",
308
- armsse_mainclk_update, s);
309
- s->s32kclk = qdev_init_clock_in(DEVICE(s), "S32KCLK", NULL, NULL);
310
+ armsse_mainclk_update, s, ClockUpdate);
311
+ s->s32kclk = qdev_init_clock_in(DEVICE(s), "S32KCLK", NULL, NULL, 0);
312
313
memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
314
315
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
316
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
317
318
/* Set initial system_clock_scale from MAINCLK */
319
- armsse_mainclk_update(s);
320
+ armsse_mainclk_update(s, ClockUpdate);
321
}
322
323
static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
324
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
325
index XXXXXXX..XXXXXXX 100644
326
--- a/hw/char/cadence_uart.c
327
+++ b/hw/char/cadence_uart.c
328
@@ -XXX,XX +XXX,XX @@ static void cadence_uart_realize(DeviceState *dev, Error **errp)
329
uart_event, NULL, s, NULL, true);
330
}
331
332
-static void cadence_uart_refclk_update(void *opaque)
333
+static void cadence_uart_refclk_update(void *opaque, ClockEvent event)
334
{
335
CadenceUARTState *s = opaque;
336
337
@@ -XXX,XX +XXX,XX @@ static void cadence_uart_init(Object *obj)
338
sysbus_init_irq(sbd, &s->irq);
339
340
s->refclk = qdev_init_clock_in(DEVICE(obj), "refclk",
341
- cadence_uart_refclk_update, s);
342
+ cadence_uart_refclk_update, s, ClockUpdate);
343
/* initialize the frequency in case the clock remains unconnected */
344
clock_set_hz(s->refclk, UART_DEFAULT_REF_CLK);
345
346
diff --git a/hw/char/ibex_uart.c b/hw/char/ibex_uart.c
347
index XXXXXXX..XXXXXXX 100644
348
--- a/hw/char/ibex_uart.c
349
+++ b/hw/char/ibex_uart.c
350
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_write(void *opaque, hwaddr addr,
351
}
352
}
353
354
-static void ibex_uart_clk_update(void *opaque)
355
+static void ibex_uart_clk_update(void *opaque, ClockEvent event)
356
{
357
IbexUartState *s = opaque;
358
359
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_init(Object *obj)
360
IbexUartState *s = IBEX_UART(obj);
361
362
s->f_clk = qdev_init_clock_in(DEVICE(obj), "f_clock",
363
- ibex_uart_clk_update, s);
364
+ ibex_uart_clk_update, s, ClockUpdate);
365
clock_set_hz(s->f_clk, IBEX_UART_CLOCK);
366
367
sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->tx_watermark);
368
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
369
index XXXXXXX..XXXXXXX 100644
370
--- a/hw/char/pl011.c
371
+++ b/hw/char/pl011.c
372
@@ -XXX,XX +XXX,XX @@ static void pl011_event(void *opaque, QEMUChrEvent event)
373
pl011_put_fifo(opaque, 0x400);
374
}
375
376
-static void pl011_clock_update(void *opaque)
377
+static void pl011_clock_update(void *opaque, ClockEvent event)
378
{
379
PL011State *s = PL011(opaque);
380
381
@@ -XXX,XX +XXX,XX @@ static void pl011_init(Object *obj)
382
sysbus_init_irq(sbd, &s->irq[i]);
383
}
384
385
- s->clk = qdev_init_clock_in(DEVICE(obj), "clk", pl011_clock_update, s);
386
+ s->clk = qdev_init_clock_in(DEVICE(obj), "clk", pl011_clock_update, s,
387
+ ClockUpdate);
388
389
s->read_trigger = 1;
390
s->ifl = 0x12;
391
diff --git a/hw/core/clock.c b/hw/core/clock.c
392
index XXXXXXX..XXXXXXX 100644
393
--- a/hw/core/clock.c
394
+++ b/hw/core/clock.c
395
@@ -XXX,XX +XXX,XX @@ Clock *clock_new(Object *parent, const char *name)
396
return clk;
397
}
398
399
-void clock_set_callback(Clock *clk, ClockCallback *cb, void *opaque)
400
+void clock_set_callback(Clock *clk, ClockCallback *cb, void *opaque,
401
+ unsigned int events)
402
{
403
clk->callback = cb;
404
clk->callback_opaque = opaque;
405
+ clk->callback_events = events;
406
}
407
408
void clock_clear_callback(Clock *clk)
409
{
410
- clock_set_callback(clk, NULL, NULL);
411
+ clock_set_callback(clk, NULL, NULL, 0);
412
}
413
414
bool clock_set(Clock *clk, uint64_t period)
415
@@ -XXX,XX +XXX,XX @@ bool clock_set(Clock *clk, uint64_t period)
416
return true;
417
}
418
419
+static void clock_call_callback(Clock *clk, ClockEvent event)
420
+{
421
+ /*
422
+ * Call the Clock's callback for this event, if it has one and
423
+ * is interested in this event.
424
+ */
425
+ if (clk->callback && (clk->callback_events & event)) {
426
+ clk->callback(clk->callback_opaque, event);
427
+ }
428
+}
429
+
430
static void clock_propagate_period(Clock *clk, bool call_callbacks)
431
{
432
Clock *child;
433
@@ -XXX,XX +XXX,XX @@ static void clock_propagate_period(Clock *clk, bool call_callbacks)
434
trace_clock_update(CLOCK_PATH(child), CLOCK_PATH(clk),
435
CLOCK_PERIOD_TO_HZ(clk->period),
436
call_callbacks);
437
- if (call_callbacks && child->callback) {
438
- child->callback(child->callback_opaque);
439
+ if (call_callbacks) {
440
+ clock_call_callback(child, ClockUpdate);
441
}
442
clock_propagate_period(child, call_callbacks);
443
}
444
diff --git a/hw/core/qdev-clock.c b/hw/core/qdev-clock.c
445
index XXXXXXX..XXXXXXX 100644
446
--- a/hw/core/qdev-clock.c
447
+++ b/hw/core/qdev-clock.c
448
@@ -XXX,XX +XXX,XX @@ Clock *qdev_init_clock_out(DeviceState *dev, const char *name)
449
}
450
451
Clock *qdev_init_clock_in(DeviceState *dev, const char *name,
452
- ClockCallback *callback, void *opaque)
453
+ ClockCallback *callback, void *opaque,
454
+ unsigned int events)
455
{
456
NamedClockList *ncl;
457
458
@@ -XXX,XX +XXX,XX @@ Clock *qdev_init_clock_in(DeviceState *dev, const char *name,
459
ncl = qdev_init_clocklist(dev, name, false, NULL);
460
461
if (callback) {
462
- clock_set_callback(ncl->clock, callback, opaque);
463
+ clock_set_callback(ncl->clock, callback, opaque, events);
464
}
465
return ncl->clock;
466
}
467
@@ -XXX,XX +XXX,XX @@ void qdev_init_clocks(DeviceState *dev, const ClockPortInitArray clocks)
468
if (elem->is_output) {
469
*clkp = qdev_init_clock_out(dev, elem->name);
470
} else {
471
- *clkp = qdev_init_clock_in(dev, elem->name, elem->callback, dev);
472
+ *clkp = qdev_init_clock_in(dev, elem->name, elem->callback, dev,
473
+ elem->callback_events);
474
}
475
}
476
}
477
diff --git a/hw/mips/cps.c b/hw/mips/cps.c
478
index XXXXXXX..XXXXXXX 100644
479
--- a/hw/mips/cps.c
480
+++ b/hw/mips/cps.c
481
@@ -XXX,XX +XXX,XX @@ static void mips_cps_init(Object *obj)
482
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
483
MIPSCPSState *s = MIPS_CPS(obj);
484
485
- s->clock = qdev_init_clock_in(DEVICE(obj), "clk-in", NULL, NULL);
486
+ s->clock = qdev_init_clock_in(DEVICE(obj), "clk-in", NULL, NULL, 0);
487
/*
488
* Cover entire address space as there do not seem to be any
489
* constraints for the base address of CPC and GIC.
490
diff --git a/hw/misc/bcm2835_cprman.c b/hw/misc/bcm2835_cprman.c
491
index XXXXXXX..XXXXXXX 100644
492
--- a/hw/misc/bcm2835_cprman.c
493
+++ b/hw/misc/bcm2835_cprman.c
494
@@ -XXX,XX +XXX,XX @@ static void pll_update(CprmanPllState *pll)
495
clock_update_hz(pll->out, freq);
496
}
497
498
-static void pll_xosc_update(void *opaque)
499
+static void pll_xosc_update(void *opaque, ClockEvent event)
500
{
501
pll_update(CPRMAN_PLL(opaque));
502
}
503
@@ -XXX,XX +XXX,XX @@ static void pll_init(Object *obj)
504
{
505
CprmanPllState *s = CPRMAN_PLL(obj);
506
507
- s->xosc_in = qdev_init_clock_in(DEVICE(s), "xosc-in", pll_xosc_update, s);
508
+ s->xosc_in = qdev_init_clock_in(DEVICE(s), "xosc-in", pll_xosc_update,
509
+ s, ClockUpdate);
510
s->out = qdev_init_clock_out(DEVICE(s), "out");
511
}
512
513
@@ -XXX,XX +XXX,XX @@ static void pll_update_all_channels(BCM2835CprmanState *s,
514
}
515
}
516
517
-static void pll_channel_pll_in_update(void *opaque)
518
+static void pll_channel_pll_in_update(void *opaque, ClockEvent event)
519
{
520
pll_channel_update(CPRMAN_PLL_CHANNEL(opaque));
521
}
522
@@ -XXX,XX +XXX,XX @@ static void pll_channel_init(Object *obj)
523
CprmanPllChannelState *s = CPRMAN_PLL_CHANNEL(obj);
524
525
s->pll_in = qdev_init_clock_in(DEVICE(s), "pll-in",
526
- pll_channel_pll_in_update, s);
527
+ pll_channel_pll_in_update, s,
528
+ ClockUpdate);
529
s->out = qdev_init_clock_out(DEVICE(s), "out");
530
}
531
532
@@ -XXX,XX +XXX,XX @@ static void clock_mux_update(CprmanClockMuxState *mux)
533
clock_update_hz(mux->out, freq);
534
}
535
536
-static void clock_mux_src_update(void *opaque)
537
+static void clock_mux_src_update(void *opaque, ClockEvent event)
538
{
539
CprmanClockMuxState **backref = opaque;
540
CprmanClockMuxState *s = *backref;
541
@@ -XXX,XX +XXX,XX @@ static void clock_mux_init(Object *obj)
542
s->backref[i] = s;
543
s->srcs[i] = qdev_init_clock_in(DEVICE(s), name,
544
clock_mux_src_update,
545
- &s->backref[i]);
546
+ &s->backref[i],
547
+ ClockUpdate);
548
g_free(name);
549
}
550
551
@@ -XXX,XX +XXX,XX @@ static void dsi0hsck_mux_update(CprmanDsi0HsckMuxState *s)
552
clock_update(s->out, clock_get(src));
553
}
554
555
-static void dsi0hsck_mux_in_update(void *opaque)
556
+static void dsi0hsck_mux_in_update(void *opaque, ClockEvent event)
557
{
558
dsi0hsck_mux_update(CPRMAN_DSI0HSCK_MUX(opaque));
559
}
560
@@ -XXX,XX +XXX,XX @@ static void dsi0hsck_mux_init(Object *obj)
561
CprmanDsi0HsckMuxState *s = CPRMAN_DSI0HSCK_MUX(obj);
562
DeviceState *dev = DEVICE(obj);
563
564
- s->plla_in = qdev_init_clock_in(dev, "plla-in", dsi0hsck_mux_in_update, s);
565
- s->plld_in = qdev_init_clock_in(dev, "plld-in", dsi0hsck_mux_in_update, s);
566
+ s->plla_in = qdev_init_clock_in(dev, "plla-in", dsi0hsck_mux_in_update,
567
+ s, ClockUpdate);
568
+ s->plld_in = qdev_init_clock_in(dev, "plld-in", dsi0hsck_mux_in_update,
569
+ s, ClockUpdate);
570
s->out = qdev_init_clock_out(DEVICE(s), "out");
571
}
572
573
diff --git a/hw/misc/npcm7xx_clk.c b/hw/misc/npcm7xx_clk.c
574
index XXXXXXX..XXXXXXX 100644
575
--- a/hw/misc/npcm7xx_clk.c
576
+++ b/hw/misc/npcm7xx_clk.c
577
@@ -XXX,XX +XXX,XX @@ static const DividerInitInfo divider_init_info_list[] = {
578
},
579
};
580
581
+static void npcm7xx_clk_update_pll_cb(void *opaque, ClockEvent event)
582
+{
583
+ npcm7xx_clk_update_pll(opaque);
584
+}
585
+
586
static void npcm7xx_clk_pll_init(Object *obj)
587
{
588
NPCM7xxClockPLLState *pll = NPCM7XX_CLOCK_PLL(obj);
589
590
pll->clock_in = qdev_init_clock_in(DEVICE(pll), "clock-in",
591
- npcm7xx_clk_update_pll, pll);
592
+ npcm7xx_clk_update_pll_cb, pll,
593
+ ClockUpdate);
594
pll->clock_out = qdev_init_clock_out(DEVICE(pll), "clock-out");
595
}
596
597
+static void npcm7xx_clk_update_sel_cb(void *opaque, ClockEvent event)
598
+{
599
+ npcm7xx_clk_update_sel(opaque);
600
+}
601
+
602
static void npcm7xx_clk_sel_init(Object *obj)
603
{
604
int i;
605
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_clk_sel_init(Object *obj)
606
for (i = 0; i < NPCM7XX_CLK_SEL_MAX_INPUT; ++i) {
607
sel->clock_in[i] = qdev_init_clock_in(DEVICE(sel),
608
g_strdup_printf("clock-in[%d]", i),
609
- npcm7xx_clk_update_sel, sel);
610
+ npcm7xx_clk_update_sel_cb, sel, ClockUpdate);
611
}
612
sel->clock_out = qdev_init_clock_out(DEVICE(sel), "clock-out");
613
}
614
+
615
+static void npcm7xx_clk_update_divider_cb(void *opaque, ClockEvent event)
616
+{
617
+ npcm7xx_clk_update_divider(opaque);
618
+}
619
+
620
static void npcm7xx_clk_divider_init(Object *obj)
621
{
622
NPCM7xxClockDividerState *div = NPCM7XX_CLOCK_DIVIDER(obj);
623
624
div->clock_in = qdev_init_clock_in(DEVICE(div), "clock-in",
625
- npcm7xx_clk_update_divider, div);
626
+ npcm7xx_clk_update_divider_cb,
627
+ div, ClockUpdate);
628
div->clock_out = qdev_init_clock_out(DEVICE(div), "clock-out");
629
}
630
631
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_clk_init_clock_hierarchy(NPCM7xxCLKState *s)
632
{
633
int i;
634
635
- s->clkref = qdev_init_clock_in(DEVICE(s), "clkref", NULL, NULL);
636
+ s->clkref = qdev_init_clock_in(DEVICE(s), "clkref", NULL, NULL, 0);
637
638
/* First pass: init all converter modules */
639
QEMU_BUILD_BUG_ON(ARRAY_SIZE(pll_init_info_list) != NPCM7XX_CLOCK_NR_PLLS);
640
diff --git a/hw/misc/npcm7xx_pwm.c b/hw/misc/npcm7xx_pwm.c
641
index XXXXXXX..XXXXXXX 100644
642
--- a/hw/misc/npcm7xx_pwm.c
643
+++ b/hw/misc/npcm7xx_pwm.c
644
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_pwm_init(Object *obj)
645
memory_region_init_io(&s->iomem, obj, &npcm7xx_pwm_ops, s,
646
TYPE_NPCM7XX_PWM, 4 * KiB);
647
sysbus_init_mmio(sbd, &s->iomem);
648
- s->clock = qdev_init_clock_in(DEVICE(s), "clock", NULL, NULL);
649
+ s->clock = qdev_init_clock_in(DEVICE(s), "clock", NULL, NULL, 0);
650
651
for (i = 0; i < NPCM7XX_PWM_PER_MODULE; ++i) {
652
object_property_add_uint32_ptr(obj, "freq[*]",
653
diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c
654
index XXXXXXX..XXXXXXX 100644
655
--- a/hw/misc/zynq_slcr.c
656
+++ b/hw/misc/zynq_slcr.c
657
@@ -XXX,XX +XXX,XX @@ static void zynq_slcr_propagate_clocks(ZynqSLCRState *s)
658
clock_propagate(s->uart1_ref_clk);
659
}
660
661
-static void zynq_slcr_ps_clk_callback(void *opaque)
662
+static void zynq_slcr_ps_clk_callback(void *opaque, ClockEvent event)
663
{
664
ZynqSLCRState *s = (ZynqSLCRState *) opaque;
665
+
666
zynq_slcr_compute_clocks(s);
667
zynq_slcr_propagate_clocks(s);
668
}
669
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps slcr_ops = {
670
};
671
672
static const ClockPortInitArray zynq_slcr_clocks = {
673
- QDEV_CLOCK_IN(ZynqSLCRState, ps_clk, zynq_slcr_ps_clk_callback),
674
+ QDEV_CLOCK_IN(ZynqSLCRState, ps_clk, zynq_slcr_ps_clk_callback, ClockUpdate),
675
QDEV_CLOCK_OUT(ZynqSLCRState, uart0_ref_clk),
676
QDEV_CLOCK_OUT(ZynqSLCRState, uart1_ref_clk),
677
QDEV_CLOCK_END
678
diff --git a/hw/timer/cmsdk-apb-dualtimer.c b/hw/timer/cmsdk-apb-dualtimer.c
679
index XXXXXXX..XXXXXXX 100644
680
--- a/hw/timer/cmsdk-apb-dualtimer.c
681
+++ b/hw/timer/cmsdk-apb-dualtimer.c
682
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_dualtimer_reset(DeviceState *dev)
683
s->timeritop = 0;
684
}
685
686
-static void cmsdk_apb_dualtimer_clk_update(void *opaque)
687
+static void cmsdk_apb_dualtimer_clk_update(void *opaque, ClockEvent event)
688
{
689
CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(opaque);
690
int i;
691
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_dualtimer_init(Object *obj)
692
sysbus_init_irq(sbd, &s->timermod[i].timerint);
693
}
694
s->timclk = qdev_init_clock_in(DEVICE(s), "TIMCLK",
695
- cmsdk_apb_dualtimer_clk_update, s);
696
+ cmsdk_apb_dualtimer_clk_update, s,
697
+ ClockUpdate);
698
}
699
700
static void cmsdk_apb_dualtimer_realize(DeviceState *dev, Error **errp)
701
diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c
702
index XXXXXXX..XXXXXXX 100644
703
--- a/hw/timer/cmsdk-apb-timer.c
704
+++ b/hw/timer/cmsdk-apb-timer.c
705
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_reset(DeviceState *dev)
706
ptimer_transaction_commit(s->timer);
707
}
708
709
-static void cmsdk_apb_timer_clk_update(void *opaque)
710
+static void cmsdk_apb_timer_clk_update(void *opaque, ClockEvent event)
711
{
712
CMSDKAPBTimer *s = CMSDK_APB_TIMER(opaque);
713
714
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_init(Object *obj)
715
sysbus_init_mmio(sbd, &s->iomem);
716
sysbus_init_irq(sbd, &s->timerint);
717
s->pclk = qdev_init_clock_in(DEVICE(s), "pclk",
718
- cmsdk_apb_timer_clk_update, s);
719
+ cmsdk_apb_timer_clk_update, s, ClockUpdate);
720
}
721
722
static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
723
diff --git a/hw/timer/npcm7xx_timer.c b/hw/timer/npcm7xx_timer.c
724
index XXXXXXX..XXXXXXX 100644
725
--- a/hw/timer/npcm7xx_timer.c
726
+++ b/hw/timer/npcm7xx_timer.c
727
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_timer_init(Object *obj)
728
sysbus_init_mmio(sbd, &s->iomem);
729
qdev_init_gpio_out_named(dev, &w->reset_signal,
730
NPCM7XX_WATCHDOG_RESET_GPIO_OUT, 1);
731
- s->clock = qdev_init_clock_in(dev, "clock", NULL, NULL);
732
+ s->clock = qdev_init_clock_in(dev, "clock", NULL, NULL, 0);
733
}
734
735
static const VMStateDescription vmstate_npcm7xx_base_timer = {
736
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
737
index XXXXXXX..XXXXXXX 100644
738
--- a/hw/watchdog/cmsdk-apb-watchdog.c
739
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
740
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_reset(DeviceState *dev)
741
ptimer_transaction_commit(s->timer);
742
}
743
744
-static void cmsdk_apb_watchdog_clk_update(void *opaque)
745
+static void cmsdk_apb_watchdog_clk_update(void *opaque, ClockEvent event)
746
{
747
CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque);
748
749
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_init(Object *obj)
750
sysbus_init_mmio(sbd, &s->iomem);
751
sysbus_init_irq(sbd, &s->wdogint);
752
s->wdogclk = qdev_init_clock_in(DEVICE(s), "WDOGCLK",
753
- cmsdk_apb_watchdog_clk_update, s);
754
+ cmsdk_apb_watchdog_clk_update, s,
755
+ ClockUpdate);
756
757
s->is_luminary = false;
758
s->id = cmsdk_apb_watchdog_id;
759
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
760
index XXXXXXX..XXXXXXX 100644
761
--- a/target/mips/cpu.c
762
+++ b/target/mips/cpu.c
763
@@ -XXX,XX +XXX,XX @@ static void mips_cpu_initfn(Object *obj)
764
MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(obj);
765
766
cpu_set_cpustate_pointers(cpu);
767
- cpu->clock = qdev_init_clock_in(DEVICE(obj), "clk-in", NULL, cpu);
768
+ cpu->clock = qdev_init_clock_in(DEVICE(obj), "clk-in", NULL, cpu, 0);
769
env->cpu_model = mcc->cpu_def;
770
}
771
772
--
773
2.20.1
774
775
diff view generated by jsdifflib
New patch
1
Add a new callback event type ClockPreUpdate, which is called on
2
period changes before the period is updated.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Luc Michel <luc@lmichel.fr>
6
Reviewed-by: Hao Wu <wuhaotsh@google.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20210219144617.4782-3-peter.maydell@linaro.org
10
---
11
docs/devel/clocks.rst | 9 ++++++++-
12
include/hw/clock.h | 1 +
13
hw/core/clock.c | 3 +++
14
3 files changed, 12 insertions(+), 1 deletion(-)
15
16
diff --git a/docs/devel/clocks.rst b/docs/devel/clocks.rst
17
index XXXXXXX..XXXXXXX 100644
18
--- a/docs/devel/clocks.rst
19
+++ b/docs/devel/clocks.rst
20
@@ -XXX,XX +XXX,XX @@ events.
21
22
The events currently supported are:
23
24
- * ``ClockUpdate`` : called after the input clock's period has changed
25
+ * ``ClockPreUpdate`` : called when the input clock's period is about to
26
+ update. This is useful if the device needs to do some action for
27
+ which it needs to know the old value of the clock period. During
28
+ this callback, Clock API functions like ``clock_get()`` or
29
+ ``clock_ticks_to_ns()`` will use the old period.
30
+ * ``ClockUpdate`` : called after the input clock's period has changed.
31
+ During this callback, Clock API functions like ``clock_ticks_to_ns()``
32
+ will use the new period.
33
34
Note that a clock only has one callback: it is not possible to register
35
different functions for different events. You must register a single
36
diff --git a/include/hw/clock.h b/include/hw/clock.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/include/hw/clock.h
39
+++ b/include/hw/clock.h
40
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Clock, CLOCK)
41
*/
42
typedef enum ClockEvent {
43
ClockUpdate = 1, /* Clock period has just updated */
44
+ ClockPreUpdate = 2, /* Clock period is about to update */
45
} ClockEvent;
46
47
typedef void ClockCallback(void *opaque, ClockEvent event);
48
diff --git a/hw/core/clock.c b/hw/core/clock.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/core/clock.c
51
+++ b/hw/core/clock.c
52
@@ -XXX,XX +XXX,XX @@ static void clock_propagate_period(Clock *clk, bool call_callbacks)
53
54
QLIST_FOREACH(child, &clk->children, sibling) {
55
if (child->period != clk->period) {
56
+ if (call_callbacks) {
57
+ clock_call_callback(child, ClockPreUpdate);
58
+ }
59
child->period = clk->period;
60
trace_clock_update(CLOCK_PATH(child), CLOCK_PATH(clk),
61
CLOCK_PERIOD_TO_HZ(clk->period),
62
--
63
2.20.1
64
65
diff view generated by jsdifflib
New patch
1
Add a clock_ns_to_ticks() function which does the opposite of
2
clock_ticks_to_ns(): given a duration in nanoseconds, it returns the
3
number of clock ticks that would happen in that time. This is useful
4
for devices that have a free running counter register whose value can
5
be calculated when it is read.
1
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Luc Michel <luc@lmichel.fr>
9
Reviewed-by: Hao Wu <wuhaotsh@google.com>
10
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20210219144617.4782-4-peter.maydell@linaro.org
12
---
13
docs/devel/clocks.rst | 12 ++++++++++++
14
include/hw/clock.h | 41 +++++++++++++++++++++++++++++++++++++++++
15
2 files changed, 53 insertions(+)
16
17
diff --git a/docs/devel/clocks.rst b/docs/devel/clocks.rst
18
index XXXXXXX..XXXXXXX 100644
19
--- a/docs/devel/clocks.rst
20
+++ b/docs/devel/clocks.rst
21
@@ -XXX,XX +XXX,XX @@ rather than simply passing it to a QEMUTimer function like
22
``timer_mod_ns()`` then you should be careful to avoid overflow
23
in those calculations, of course.)
24
25
+Obtaining tick counts
26
+---------------------
27
+
28
+For calculations where you need to know the number of ticks in
29
+a given duration, use ``clock_ns_to_ticks()``. This function handles
30
+possible non-whole-number-of-nanoseconds periods and avoids
31
+potential rounding errors. It will return '0' if the clock is stopped
32
+(i.e. it has period zero). If the inputs imply a tick count that
33
+overflows a 64-bit value (a very long duration for a clock with a
34
+very short period) the output value is truncated, so effectively
35
+the 64-bit output wraps around.
36
+
37
Changing a clock period
38
-----------------------
39
40
diff --git a/include/hw/clock.h b/include/hw/clock.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/include/hw/clock.h
43
+++ b/include/hw/clock.h
44
@@ -XXX,XX +XXX,XX @@ static inline uint64_t clock_ticks_to_ns(const Clock *clk, uint64_t ticks)
45
return ns_low >> 32 | ns_high << 32;
46
}
47
48
+/**
49
+ * clock_ns_to_ticks:
50
+ * @clk: the clock to query
51
+ * @ns: duration in nanoseconds
52
+ *
53
+ * Returns the number of ticks this clock would make in the given
54
+ * number of nanoseconds. Because a clock can have a period which
55
+ * is not a whole number of nanoseconds, it is important to use this
56
+ * function rather than attempting to obtain a "period in nanoseconds"
57
+ * value and then dividing the duration by that value.
58
+ *
59
+ * If the clock is stopped (ie it has period zero), returns 0.
60
+ *
61
+ * For some inputs the result could overflow a 64-bit value (because
62
+ * the clock's period is short and the duration is long). In these
63
+ * cases we truncate the result to a 64-bit value. This is on the
64
+ * assumption that generally the result is going to be used to report
65
+ * a 32-bit or 64-bit guest register value, so wrapping either cannot
66
+ * happen or is the desired behaviour.
67
+ */
68
+static inline uint64_t clock_ns_to_ticks(const Clock *clk, uint64_t ns)
69
+{
70
+ /*
71
+ * ticks = duration_in_ns / period_in_ns
72
+ * = ns / (period / 2^32)
73
+ * = (ns * 2^32) / period
74
+ * The hi, lo inputs to divu128() are (ns << 32) as a 128 bit value.
75
+ */
76
+ uint64_t lo = ns << 32;
77
+ uint64_t hi = ns >> 32;
78
+ if (clk->period == 0) {
79
+ return 0;
80
+ }
81
+ /*
82
+ * Ignore divu128() return value as we've caught div-by-zero and don't
83
+ * need different behaviour for overflow.
84
+ */
85
+ divu128(&lo, &hi, clk->period);
86
+ return lo;
87
+}
88
+
89
/**
90
* clock_is_enabled:
91
* @clk: a clock
92
--
93
2.20.1
94
95
diff view generated by jsdifflib
New patch
1
Use the new clock_ns_to_ticks() function in npcm7xx_timer where
2
appropriate.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Luc Michel <luc@lmichel.fr>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Hao Wu <wuhaotsh@google.com>
8
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20210219144617.4782-5-peter.maydell@linaro.org
10
---
11
hw/timer/npcm7xx_timer.c | 4 ++--
12
1 file changed, 2 insertions(+), 2 deletions(-)
13
14
diff --git a/hw/timer/npcm7xx_timer.c b/hw/timer/npcm7xx_timer.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/timer/npcm7xx_timer.c
17
+++ b/hw/timer/npcm7xx_timer.c
18
@@ -XXX,XX +XXX,XX @@ static int64_t npcm7xx_timer_count_to_ns(NPCM7xxTimer *t, uint32_t count)
19
/* Convert a time interval in nanoseconds to a timer cycle count. */
20
static uint32_t npcm7xx_timer_ns_to_count(NPCM7xxTimer *t, int64_t ns)
21
{
22
- return ns / clock_ticks_to_ns(t->ctrl->clock,
23
- npcm7xx_tcsr_prescaler(t->tcsr));
24
+ return clock_ns_to_ticks(t->ctrl->clock, ns) /
25
+ npcm7xx_tcsr_prescaler(t->tcsr);
26
}
27
28
static uint32_t npcm7xx_watchdog_timer_prescaler(const NPCM7xxWatchdogTimer *t)
29
--
30
2.20.1
31
32
diff view generated by jsdifflib
New patch
1
1
We model Arm "Subsystems for Embedded" SoC subsystems using generic
2
code which is split into various sub-devices which are configurable
3
by QOM properties to handle the behaviour differences between the SSE
4
subsystems we implement. Currently the only sub-device which needs
5
to change is the IOTKIT_SYSCTL device, and we do this with a mix of
6
properties that directly specify divergent behaviours (eg
7
CPUWAIT_RST) and passing it the SYS_VERSION register value as a way
8
for it to distinguish IoTKit from SSE-200.
9
10
The "pass SYS_VERSION" approach is already a bit hacky, since the
11
IOTKIT_SYSCTL device has to know that the different part of the
12
register value happens to be bits [31:28]. For SSE-300 this register
13
is renamed SOC_IDENTITY and has a different format entirely, all of
14
whose fields can be configured by the SoC integrator when they
15
integrate the SSE into their SoC, and so "pass SYS_VERSION" breaks
16
down completely.
17
18
Switch to using a simple integer property representing an
19
internal-to-QEMU enumeration of the SSE flavour. For the moment we
20
only need this in IOTKIT_SYSCTL, but as we add SSE-300 support a few
21
of the other devices will also need to know.
22
23
We define and permit a value for the SSE-300 so we can start using
24
it in subsequent commits which add SSE-300 support.
25
26
The now-redundant is_sse200 flag in IoTKitSysCtl will be removed
27
in the following commit.
28
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
32
Message-id: 20210219144617.4782-6-peter.maydell@linaro.org
33
---
34
include/hw/arm/armsse-version.h | 42 +++++++++++++++++++++++++++++++++
35
include/hw/misc/iotkit-sysctl.h | 7 +++---
36
hw/arm/armsse.c | 8 +++++--
37
hw/misc/iotkit-sysctl.c | 11 +++++----
38
4 files changed, 58 insertions(+), 10 deletions(-)
39
create mode 100644 include/hw/arm/armsse-version.h
40
41
diff --git a/include/hw/arm/armsse-version.h b/include/hw/arm/armsse-version.h
42
new file mode 100644
43
index XXXXXXX..XXXXXXX
44
--- /dev/null
45
+++ b/include/hw/arm/armsse-version.h
46
@@ -XXX,XX +XXX,XX @@
47
+/*
48
+ * ARM SSE (Subsystems for Embedded): IoTKit, SSE-200
49
+ *
50
+ * Copyright (c) 2020 Linaro Limited
51
+ * Written by Peter Maydell
52
+ *
53
+ * This program is free software; you can redistribute it and/or modify
54
+ * it under the terms of the GNU General Public License version 2 or
55
+ * (at your option) any later version.
56
+ */
57
+
58
+#ifndef ARMSSE_VERSION_H
59
+#define ARMSSE_VERSION_H
60
+
61
+
62
+/*
63
+ * Define an enumeration of the possible values of the sse-version
64
+ * property implemented by various sub-devices of the SSE, and
65
+ * a validation function that checks that a valid value has been passed.
66
+ * These are arbitrary QEMU-internal values (nobody should be creating
67
+ * the sub-devices of the SSE except for the SSE object itself), but
68
+ * we pick obvious numbers for the benefit of people debugging with gdb.
69
+ */
70
+enum {
71
+ ARMSSE_IOTKIT = 0,
72
+ ARMSSE_SSE200 = 200,
73
+ ARMSSE_SSE300 = 300,
74
+};
75
+
76
+static inline bool armsse_version_valid(uint32_t sse_version)
77
+{
78
+ switch (sse_version) {
79
+ case ARMSSE_IOTKIT:
80
+ case ARMSSE_SSE200:
81
+ case ARMSSE_SSE300:
82
+ return true;
83
+ default:
84
+ return false;
85
+ }
86
+}
87
+
88
+#endif
89
diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
90
index XXXXXXX..XXXXXXX 100644
91
--- a/include/hw/misc/iotkit-sysctl.h
92
+++ b/include/hw/misc/iotkit-sysctl.h
93
@@ -XXX,XX +XXX,XX @@
94
* "system control register" blocks.
95
*
96
* QEMU interface:
97
- * + QOM property "SYS_VERSION": value of the SYS_VERSION register of the
98
- * system information block of the SSE
99
- * (used to identify whether to provide SSE-200-only registers)
100
+ * + QOM property "sse-version": indicates which SSE version this is part of
101
+ * (used to identify whether to provide SSE-200-only registers, etc)
102
* + sysbus MMIO region 0: the system information register bank
103
* + sysbus MMIO region 1: the system control register bank
104
*/
105
@@ -XXX,XX +XXX,XX @@ struct IoTKitSysCtl {
106
uint32_t pdcm_pd_sram3_sense;
107
108
/* Properties */
109
- uint32_t sys_version;
110
+ uint32_t sse_version;
111
uint32_t cpuwait_rst;
112
uint32_t initsvtor0_rst;
113
uint32_t initsvtor1_rst;
114
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/hw/arm/armsse.c
117
+++ b/hw/arm/armsse.c
118
@@ -XXX,XX +XXX,XX @@
119
#include "migration/vmstate.h"
120
#include "hw/registerfields.h"
121
#include "hw/arm/armsse.h"
122
+#include "hw/arm/armsse-version.h"
123
#include "hw/arm/boot.h"
124
#include "hw/irq.h"
125
#include "hw/qdev-clock.h"
126
@@ -XXX,XX +XXX,XX @@ typedef enum SysConfigFormat {
127
128
struct ARMSSEInfo {
129
const char *name;
130
+ uint32_t sse_version;
131
int sram_banks;
132
int num_cpus;
133
uint32_t sys_version;
134
@@ -XXX,XX +XXX,XX @@ static Property armsse_properties[] = {
135
static const ARMSSEInfo armsse_variants[] = {
136
{
137
.name = TYPE_IOTKIT,
138
+ .sse_version = ARMSSE_IOTKIT,
139
.sram_banks = 1,
140
.num_cpus = 1,
141
.sys_version = 0x41743,
142
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
143
},
144
{
145
.name = TYPE_SSE200,
146
+ .sse_version = ARMSSE_SSE200,
147
.sram_banks = 4,
148
.num_cpus = 2,
149
.sys_version = 0x22041743,
150
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
151
/* System information registers */
152
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysinfo), 0, 0x40020000);
153
/* System control registers */
154
- object_property_set_int(OBJECT(&s->sysctl), "SYS_VERSION",
155
- info->sys_version, &error_abort);
156
+ object_property_set_int(OBJECT(&s->sysctl), "sse-version",
157
+ info->sse_version, &error_abort);
158
object_property_set_int(OBJECT(&s->sysctl), "CPUWAIT_RST",
159
info->cpuwait_rst, &error_abort);
160
object_property_set_int(OBJECT(&s->sysctl), "INITSVTOR0_RST",
161
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
162
index XXXXXXX..XXXXXXX 100644
163
--- a/hw/misc/iotkit-sysctl.c
164
+++ b/hw/misc/iotkit-sysctl.c
165
@@ -XXX,XX +XXX,XX @@
166
#include "hw/registerfields.h"
167
#include "hw/misc/iotkit-sysctl.h"
168
#include "hw/qdev-properties.h"
169
+#include "hw/arm/armsse-version.h"
170
#include "target/arm/arm-powerctl.h"
171
#include "target/arm/cpu.h"
172
173
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_realize(DeviceState *dev, Error **errp)
174
{
175
IoTKitSysCtl *s = IOTKIT_SYSCTL(dev);
176
177
- /* The top 4 bits of the SYS_VERSION register tell us if we're an SSE-200 */
178
- if (extract32(s->sys_version, 28, 4) == 2) {
179
- s->is_sse200 = true;
180
+ if (!armsse_version_valid(s->sse_version)) {
181
+ error_setg(errp, "invalid sse-version value %d", s->sse_version);
182
+ return;
183
}
184
+
185
+ s->is_sse200 = s->sse_version == ARMSSE_SSE200;
186
}
187
188
static bool sse200_needed(void *opaque)
189
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription iotkit_sysctl_vmstate = {
190
};
191
192
static Property iotkit_sysctl_props[] = {
193
- DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysCtl, sys_version, 0),
194
+ DEFINE_PROP_UINT32("sse-version", IoTKitSysCtl, sse_version, 0),
195
DEFINE_PROP_UINT32("CPUWAIT_RST", IoTKitSysCtl, cpuwait_rst, 0),
196
DEFINE_PROP_UINT32("INITSVTOR0_RST", IoTKitSysCtl, initsvtor0_rst,
197
0x10000000),
198
--
199
2.20.1
200
201
diff view generated by jsdifflib
New patch
1
1
Remove the is_sse200 flag in favour of just directly testing the new
2
sse_version field.
3
4
Since some of these registers exist in the SSE-300 but some do not or
5
have different behaviour, we expand out the if() statements in the
6
read and write functions into switch()es, so we have an easy place to
7
put SSE-300 specific behaviour.
8
9
(Until we do add the SSE-300 behaviour, the thing preventing us
10
reaching the "unreachable" default cases is that armsse.c doesn't
11
yet pass us an ARMSSE_SSE300 version.)
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20210219144617.4782-7-peter.maydell@linaro.org
17
---
18
include/hw/misc/iotkit-sysctl.h | 2 -
19
hw/misc/iotkit-sysctl.c | 256 +++++++++++++++++++++++---------
20
2 files changed, 187 insertions(+), 71 deletions(-)
21
22
diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/misc/iotkit-sysctl.h
25
+++ b/include/hw/misc/iotkit-sysctl.h
26
@@ -XXX,XX +XXX,XX @@ struct IoTKitSysCtl {
27
uint32_t cpuwait_rst;
28
uint32_t initsvtor0_rst;
29
uint32_t initsvtor1_rst;
30
-
31
- bool is_sse200;
32
};
33
34
#endif
35
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/misc/iotkit-sysctl.c
38
+++ b/hw/misc/iotkit-sysctl.c
39
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
40
r = s->secure_debug;
41
break;
42
case A_SCSECCTRL:
43
- if (!s->is_sse200) {
44
+ switch (s->sse_version) {
45
+ case ARMSSE_IOTKIT:
46
goto bad_offset;
47
+ case ARMSSE_SSE200:
48
+ r = s->scsecctrl;
49
+ break;
50
+ default:
51
+ g_assert_not_reached();
52
}
53
- r = s->scsecctrl;
54
break;
55
case A_FCLK_DIV:
56
- if (!s->is_sse200) {
57
+ switch (s->sse_version) {
58
+ case ARMSSE_IOTKIT:
59
goto bad_offset;
60
+ case ARMSSE_SSE200:
61
+ r = s->fclk_div;
62
+ break;
63
+ default:
64
+ g_assert_not_reached();
65
}
66
- r = s->fclk_div;
67
break;
68
case A_SYSCLK_DIV:
69
- if (!s->is_sse200) {
70
+ switch (s->sse_version) {
71
+ case ARMSSE_IOTKIT:
72
goto bad_offset;
73
+ case ARMSSE_SSE200:
74
+ r = s->sysclk_div;
75
+ break;
76
+ default:
77
+ g_assert_not_reached();
78
}
79
- r = s->sysclk_div;
80
break;
81
case A_CLOCK_FORCE:
82
- if (!s->is_sse200) {
83
+ switch (s->sse_version) {
84
+ case ARMSSE_IOTKIT:
85
goto bad_offset;
86
+ case ARMSSE_SSE200:
87
+ r = s->clock_force;
88
+ break;
89
+ default:
90
+ g_assert_not_reached();
91
}
92
- r = s->clock_force;
93
break;
94
case A_RESET_SYNDROME:
95
r = s->reset_syndrome;
96
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
97
r = s->initsvtor0;
98
break;
99
case A_INITSVTOR1:
100
- if (!s->is_sse200) {
101
+ switch (s->sse_version) {
102
+ case ARMSSE_IOTKIT:
103
goto bad_offset;
104
+ case ARMSSE_SSE200:
105
+ r = s->initsvtor1;
106
+ break;
107
+ default:
108
+ g_assert_not_reached();
109
}
110
- r = s->initsvtor1;
111
break;
112
case A_CPUWAIT:
113
r = s->cpuwait;
114
break;
115
case A_NMI_ENABLE:
116
- /* In IoTKit this is named BUSWAIT but is marked reserved, R/O, zero */
117
- if (!s->is_sse200) {
118
+ switch (s->sse_version) {
119
+ case ARMSSE_IOTKIT:
120
+ /* In IoTKit this is named BUSWAIT but marked reserved, R/O, zero */
121
r = 0;
122
break;
123
+ case ARMSSE_SSE200:
124
+ r = s->nmi_enable;
125
+ break;
126
+ default:
127
+ g_assert_not_reached();
128
}
129
- r = s->nmi_enable;
130
break;
131
case A_WICCTRL:
132
r = s->wicctrl;
133
break;
134
case A_EWCTRL:
135
- if (!s->is_sse200) {
136
+ switch (s->sse_version) {
137
+ case ARMSSE_IOTKIT:
138
goto bad_offset;
139
+ case ARMSSE_SSE200:
140
+ r = s->ewctrl;
141
+ break;
142
+ default:
143
+ g_assert_not_reached();
144
}
145
- r = s->ewctrl;
146
break;
147
case A_PDCM_PD_SYS_SENSE:
148
- if (!s->is_sse200) {
149
+ switch (s->sse_version) {
150
+ case ARMSSE_IOTKIT:
151
goto bad_offset;
152
+ case ARMSSE_SSE200:
153
+ r = s->pdcm_pd_sys_sense;
154
+ break;
155
+ default:
156
+ g_assert_not_reached();
157
}
158
- r = s->pdcm_pd_sys_sense;
159
break;
160
case A_PDCM_PD_SRAM0_SENSE:
161
- if (!s->is_sse200) {
162
+ switch (s->sse_version) {
163
+ case ARMSSE_IOTKIT:
164
goto bad_offset;
165
+ case ARMSSE_SSE200:
166
+ r = s->pdcm_pd_sram0_sense;
167
+ break;
168
+ default:
169
+ g_assert_not_reached();
170
}
171
- r = s->pdcm_pd_sram0_sense;
172
break;
173
case A_PDCM_PD_SRAM1_SENSE:
174
- if (!s->is_sse200) {
175
+ switch (s->sse_version) {
176
+ case ARMSSE_IOTKIT:
177
goto bad_offset;
178
+ case ARMSSE_SSE200:
179
+ r = s->pdcm_pd_sram1_sense;
180
+ break;
181
+ default:
182
+ g_assert_not_reached();
183
}
184
- r = s->pdcm_pd_sram1_sense;
185
break;
186
case A_PDCM_PD_SRAM2_SENSE:
187
- if (!s->is_sse200) {
188
+ switch (s->sse_version) {
189
+ case ARMSSE_IOTKIT:
190
goto bad_offset;
191
+ case ARMSSE_SSE200:
192
+ r = s->pdcm_pd_sram2_sense;
193
+ break;
194
+ default:
195
+ g_assert_not_reached();
196
}
197
- r = s->pdcm_pd_sram2_sense;
198
break;
199
case A_PDCM_PD_SRAM3_SENSE:
200
- if (!s->is_sse200) {
201
+ switch (s->sse_version) {
202
+ case ARMSSE_IOTKIT:
203
goto bad_offset;
204
+ case ARMSSE_SSE200:
205
+ r = s->pdcm_pd_sram3_sense;
206
+ break;
207
+ default:
208
+ g_assert_not_reached();
209
}
210
- r = s->pdcm_pd_sram3_sense;
211
break;
212
case A_PID4 ... A_CID3:
213
r = sysctl_id[(offset - A_PID4) / 4];
214
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
215
}
216
break;
217
case A_SCSECCTRL:
218
- if (!s->is_sse200) {
219
+ switch (s->sse_version) {
220
+ case ARMSSE_IOTKIT:
221
goto bad_offset;
222
+ case ARMSSE_SSE200:
223
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SCSECCTRL unimplemented\n");
224
+ s->scsecctrl = value;
225
+ break;
226
+ default:
227
+ g_assert_not_reached();
228
}
229
- qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SCSECCTRL unimplemented\n");
230
- s->scsecctrl = value;
231
break;
232
case A_FCLK_DIV:
233
- if (!s->is_sse200) {
234
+ switch (s->sse_version) {
235
+ case ARMSSE_IOTKIT:
236
goto bad_offset;
237
+ case ARMSSE_SSE200:
238
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl FCLK_DIV unimplemented\n");
239
+ s->fclk_div = value;
240
+ break;
241
+ default:
242
+ g_assert_not_reached();
243
}
244
- qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl FCLK_DIV unimplemented\n");
245
- s->fclk_div = value;
246
break;
247
case A_SYSCLK_DIV:
248
- if (!s->is_sse200) {
249
+ switch (s->sse_version) {
250
+ case ARMSSE_IOTKIT:
251
goto bad_offset;
252
+ case ARMSSE_SSE200:
253
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SYSCLK_DIV unimplemented\n");
254
+ s->sysclk_div = value;
255
+ break;
256
+ default:
257
+ g_assert_not_reached();
258
}
259
- qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SYSCLK_DIV unimplemented\n");
260
- s->sysclk_div = value;
261
break;
262
case A_CLOCK_FORCE:
263
- if (!s->is_sse200) {
264
+ switch (s->sse_version) {
265
+ case ARMSSE_IOTKIT:
266
goto bad_offset;
267
+ case ARMSSE_SSE200:
268
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CLOCK_FORCE unimplemented\n");
269
+ s->clock_force = value;
270
+ break;
271
+ default:
272
+ g_assert_not_reached();
273
}
274
- qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CLOCK_FORCE unimplemented\n");
275
- s->clock_force = value;
276
break;
277
case A_INITSVTOR1:
278
- if (!s->is_sse200) {
279
+ switch (s->sse_version) {
280
+ case ARMSSE_IOTKIT:
281
goto bad_offset;
282
+ case ARMSSE_SSE200:
283
+ s->initsvtor1 = value;
284
+ set_init_vtor(1, s->initsvtor1);
285
+ break;
286
+ default:
287
+ g_assert_not_reached();
288
}
289
- s->initsvtor1 = value;
290
- set_init_vtor(1, s->initsvtor1);
291
break;
292
case A_EWCTRL:
293
- if (!s->is_sse200) {
294
+ switch (s->sse_version) {
295
+ case ARMSSE_IOTKIT:
296
goto bad_offset;
297
+ case ARMSSE_SSE200:
298
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl EWCTRL unimplemented\n");
299
+ s->ewctrl = value;
300
+ break;
301
+ default:
302
+ g_assert_not_reached();
303
}
304
- qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl EWCTRL unimplemented\n");
305
- s->ewctrl = value;
306
break;
307
case A_PDCM_PD_SYS_SENSE:
308
- if (!s->is_sse200) {
309
+ switch (s->sse_version) {
310
+ case ARMSSE_IOTKIT:
311
goto bad_offset;
312
+ case ARMSSE_SSE200:
313
+ qemu_log_mask(LOG_UNIMP,
314
+ "IoTKit SysCtl PDCM_PD_SYS_SENSE unimplemented\n");
315
+ s->pdcm_pd_sys_sense = value;
316
+ break;
317
+ default:
318
+ g_assert_not_reached();
319
}
320
- qemu_log_mask(LOG_UNIMP,
321
- "IoTKit SysCtl PDCM_PD_SYS_SENSE unimplemented\n");
322
- s->pdcm_pd_sys_sense = value;
323
break;
324
case A_PDCM_PD_SRAM0_SENSE:
325
- if (!s->is_sse200) {
326
+ switch (s->sse_version) {
327
+ case ARMSSE_IOTKIT:
328
goto bad_offset;
329
+ case ARMSSE_SSE200:
330
+ qemu_log_mask(LOG_UNIMP,
331
+ "IoTKit SysCtl PDCM_PD_SRAM0_SENSE unimplemented\n");
332
+ s->pdcm_pd_sram0_sense = value;
333
+ break;
334
+ default:
335
+ g_assert_not_reached();
336
}
337
- qemu_log_mask(LOG_UNIMP,
338
- "IoTKit SysCtl PDCM_PD_SRAM0_SENSE unimplemented\n");
339
- s->pdcm_pd_sram0_sense = value;
340
break;
341
case A_PDCM_PD_SRAM1_SENSE:
342
- if (!s->is_sse200) {
343
+ switch (s->sse_version) {
344
+ case ARMSSE_IOTKIT:
345
goto bad_offset;
346
+ case ARMSSE_SSE200:
347
+ qemu_log_mask(LOG_UNIMP,
348
+ "IoTKit SysCtl PDCM_PD_SRAM1_SENSE unimplemented\n");
349
+ s->pdcm_pd_sram1_sense = value;
350
+ break;
351
+ default:
352
+ g_assert_not_reached();
353
}
354
- qemu_log_mask(LOG_UNIMP,
355
- "IoTKit SysCtl PDCM_PD_SRAM1_SENSE unimplemented\n");
356
- s->pdcm_pd_sram1_sense = value;
357
break;
358
case A_PDCM_PD_SRAM2_SENSE:
359
- if (!s->is_sse200) {
360
+ switch (s->sse_version) {
361
+ case ARMSSE_IOTKIT:
362
goto bad_offset;
363
+ case ARMSSE_SSE200:
364
+ qemu_log_mask(LOG_UNIMP,
365
+ "IoTKit SysCtl PDCM_PD_SRAM2_SENSE unimplemented\n");
366
+ s->pdcm_pd_sram2_sense = value;
367
+ break;
368
+ default:
369
+ g_assert_not_reached();
370
}
371
- qemu_log_mask(LOG_UNIMP,
372
- "IoTKit SysCtl PDCM_PD_SRAM2_SENSE unimplemented\n");
373
- s->pdcm_pd_sram2_sense = value;
374
break;
375
case A_PDCM_PD_SRAM3_SENSE:
376
- if (!s->is_sse200) {
377
+ switch (s->sse_version) {
378
+ case ARMSSE_IOTKIT:
379
goto bad_offset;
380
+ case ARMSSE_SSE200:
381
+ qemu_log_mask(LOG_UNIMP,
382
+ "IoTKit SysCtl PDCM_PD_SRAM3_SENSE unimplemented\n");
383
+ s->pdcm_pd_sram3_sense = value;
384
+ break;
385
+ default:
386
+ g_assert_not_reached();
387
}
388
- qemu_log_mask(LOG_UNIMP,
389
- "IoTKit SysCtl PDCM_PD_SRAM3_SENSE unimplemented\n");
390
- s->pdcm_pd_sram3_sense = value;
391
break;
392
case A_NMI_ENABLE:
393
/* In IoTKit this is BUSWAIT: reserved, R/O, zero */
394
- if (!s->is_sse200) {
395
+ switch (s->sse_version) {
396
+ case ARMSSE_IOTKIT:
397
goto ro_offset;
398
+ case ARMSSE_SSE200:
399
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
400
+ s->nmi_enable = value;
401
+ break;
402
+ default:
403
+ g_assert_not_reached();
404
}
405
- qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
406
- s->nmi_enable = value;
407
break;
408
case A_SECDBGSTAT:
409
case A_PID4 ... A_CID3:
410
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_realize(DeviceState *dev, Error **errp)
411
error_setg(errp, "invalid sse-version value %d", s->sse_version);
412
return;
413
}
414
-
415
- s->is_sse200 = s->sse_version == ARMSSE_SSE200;
416
}
417
418
static bool sse200_needed(void *opaque)
419
{
420
IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
421
422
- return s->is_sse200;
423
+ return s->sse_version == ARMSSE_SSE200;
424
}
425
426
static const VMStateDescription iotkit_sysctl_sse200_vmstate = {
427
--
428
2.20.1
429
430
diff view generated by jsdifflib
New patch
1
The versions of the Secure Access Configuration Register Block
2
and Non-secure Access Configuration Register Block in the SSE-300
3
are the same as those in the SSE-200, but the CIDR/PIDR ID
4
register values are different.
1
5
6
Plumb through the sse-version property and use it to select
7
the correct ID register values.
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210219144617.4782-8-peter.maydell@linaro.org
13
---
14
include/hw/misc/iotkit-secctl.h | 2 ++
15
hw/arm/armsse.c | 2 ++
16
hw/misc/iotkit-secctl.c | 50 +++++++++++++++++++++++++++++++--
17
3 files changed, 52 insertions(+), 2 deletions(-)
18
19
diff --git a/include/hw/misc/iotkit-secctl.h b/include/hw/misc/iotkit-secctl.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/misc/iotkit-secctl.h
22
+++ b/include/hw/misc/iotkit-secctl.h
23
@@ -XXX,XX +XXX,XX @@ struct IoTKitSecCtl {
24
IoTKitSecCtlPPC apb[IOTS_NUM_APB_PPC];
25
IoTKitSecCtlPPC apbexp[IOTS_NUM_APB_EXP_PPC];
26
IoTKitSecCtlPPC ahbexp[IOTS_NUM_APB_EXP_PPC];
27
+
28
+ uint32_t sse_version;
29
};
30
31
#endif
32
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/arm/armsse.c
35
+++ b/hw/arm/armsse.c
36
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
37
}
38
39
/* Security controller */
40
+ object_property_set_int(OBJECT(&s->secctl), "sse-version",
41
+ info->sse_version, &error_abort);
42
if (!sysbus_realize(SYS_BUS_DEVICE(&s->secctl), errp)) {
43
return;
44
}
45
diff --git a/hw/misc/iotkit-secctl.c b/hw/misc/iotkit-secctl.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/misc/iotkit-secctl.c
48
+++ b/hw/misc/iotkit-secctl.c
49
@@ -XXX,XX +XXX,XX @@
50
#include "hw/registerfields.h"
51
#include "hw/irq.h"
52
#include "hw/misc/iotkit-secctl.h"
53
+#include "hw/arm/armsse-version.h"
54
+#include "hw/qdev-properties.h"
55
56
/* Registers in the secure privilege control block */
57
REG32(SECRESPCFG, 0x10)
58
@@ -XXX,XX +XXX,XX @@ static const uint8_t iotkit_secctl_ns_idregs[] = {
59
0x0d, 0xf0, 0x05, 0xb1,
60
};
61
62
+static const uint8_t iotkit_secctl_s_sse300_idregs[] = {
63
+ 0x04, 0x00, 0x00, 0x00,
64
+ 0x52, 0xb8, 0x2b, 0x00,
65
+ 0x0d, 0xf0, 0x05, 0xb1,
66
+};
67
+
68
+static const uint8_t iotkit_secctl_ns_sse300_idregs[] = {
69
+ 0x04, 0x00, 0x00, 0x00,
70
+ 0x53, 0xb8, 0x2b, 0x00,
71
+ 0x0d, 0xf0, 0x05, 0xb1,
72
+};
73
+
74
+
75
/* The register sets for the various PPCs (AHB internal, APB internal,
76
* AHB expansion, APB expansion) are all set up so that they are
77
* in 16-aligned blocks so offsets 0xN0, 0xN4, 0xN8, 0xNC are PPCs
78
@@ -XXX,XX +XXX,XX @@ static MemTxResult iotkit_secctl_s_read(void *opaque, hwaddr addr,
79
case A_CID1:
80
case A_CID2:
81
case A_CID3:
82
- r = iotkit_secctl_s_idregs[(offset - A_PID4) / 4];
83
+ switch (s->sse_version) {
84
+ case ARMSSE_SSE300:
85
+ r = iotkit_secctl_s_sse300_idregs[(offset - A_PID4) / 4];
86
+ break;
87
+ default:
88
+ r = iotkit_secctl_s_idregs[(offset - A_PID4) / 4];
89
+ break;
90
+ }
91
break;
92
case A_SECPPCINTCLR:
93
case A_SECMSCINTCLR:
94
@@ -XXX,XX +XXX,XX @@ static MemTxResult iotkit_secctl_ns_read(void *opaque, hwaddr addr,
95
case A_CID1:
96
case A_CID2:
97
case A_CID3:
98
- r = iotkit_secctl_ns_idregs[(offset - A_PID4) / 4];
99
+ switch (s->sse_version) {
100
+ case ARMSSE_SSE300:
101
+ r = iotkit_secctl_ns_sse300_idregs[(offset - A_PID4) / 4];
102
+ break;
103
+ default:
104
+ r = iotkit_secctl_ns_idregs[(offset - A_PID4) / 4];
105
+ break;
106
+ }
107
break;
108
default:
109
qemu_log_mask(LOG_GUEST_ERROR,
110
@@ -XXX,XX +XXX,XX @@ static void iotkit_secctl_init(Object *obj)
111
sysbus_init_mmio(sbd, &s->ns_regs);
112
}
113
114
+static void iotkit_secctl_realize(DeviceState *dev, Error **errp)
115
+{
116
+ IoTKitSecCtl *s = IOTKIT_SECCTL(dev);
117
+
118
+ if (!armsse_version_valid(s->sse_version)) {
119
+ error_setg(errp, "invalid sse-version value %d", s->sse_version);
120
+ return;
121
+ }
122
+}
123
+
124
static const VMStateDescription iotkit_secctl_ppc_vmstate = {
125
.name = "iotkit-secctl-ppc",
126
.version_id = 1,
127
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription iotkit_secctl_vmstate = {
128
},
129
};
130
131
+static Property iotkit_secctl_props[] = {
132
+ DEFINE_PROP_UINT32("sse-version", IoTKitSecCtl, sse_version, 0),
133
+ DEFINE_PROP_END_OF_LIST()
134
+};
135
+
136
static void iotkit_secctl_class_init(ObjectClass *klass, void *data)
137
{
138
DeviceClass *dc = DEVICE_CLASS(klass);
139
140
dc->vmsd = &iotkit_secctl_vmstate;
141
dc->reset = iotkit_secctl_reset;
142
+ dc->realize = iotkit_secctl_realize;
143
+ device_class_set_props(dc, iotkit_secctl_props);
144
}
145
146
static const TypeInfo iotkit_secctl_info = {
147
--
148
2.20.1
149
150
diff view generated by jsdifflib
New patch
1
The version of the SYSINFO Register Block in the SSE-300 has
2
different CIDR/PIDR register values to the SSE-200; pass in
3
the sse-version property and use it to select the correct
4
ID register values.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210219144617.4782-9-peter.maydell@linaro.org
10
---
11
include/hw/misc/iotkit-sysinfo.h | 1 +
12
hw/arm/armsse.c | 2 ++
13
hw/misc/iotkit-sysinfo.c | 29 +++++++++++++++++++++++++++--
14
3 files changed, 30 insertions(+), 2 deletions(-)
15
16
diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/misc/iotkit-sysinfo.h
19
+++ b/include/hw/misc/iotkit-sysinfo.h
20
@@ -XXX,XX +XXX,XX @@ struct IoTKitSysInfo {
21
/* Properties */
22
uint32_t sys_version;
23
uint32_t sys_config;
24
+ uint32_t sse_version;
25
};
26
27
#endif
28
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/armsse.c
31
+++ b/hw/arm/armsse.c
32
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
33
armsse_sys_config_value(s, info), errp)) {
34
return;
35
}
36
+ object_property_set_int(OBJECT(&s->sysinfo), "sse-version",
37
+ info->sse_version, &error_abort);
38
if (!sysbus_realize(SYS_BUS_DEVICE(&s->sysinfo), errp)) {
39
return;
40
}
41
diff --git a/hw/misc/iotkit-sysinfo.c b/hw/misc/iotkit-sysinfo.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/misc/iotkit-sysinfo.c
44
+++ b/hw/misc/iotkit-sysinfo.c
45
@@ -XXX,XX +XXX,XX @@
46
#include "hw/registerfields.h"
47
#include "hw/misc/iotkit-sysinfo.h"
48
#include "hw/qdev-properties.h"
49
+#include "hw/arm/armsse-version.h"
50
51
REG32(SYS_VERSION, 0x0)
52
REG32(SYS_CONFIG, 0x4)
53
@@ -XXX,XX +XXX,XX @@ static const int sysinfo_id[] = {
54
0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
55
};
56
57
+static const int sysinfo_sse300_id[] = {
58
+ 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
59
+ 0x58, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
60
+ 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
61
+};
62
+
63
static uint64_t iotkit_sysinfo_read(void *opaque, hwaddr offset,
64
unsigned size)
65
{
66
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysinfo_read(void *opaque, hwaddr offset,
67
r = s->sys_config;
68
break;
69
case A_PID4 ... A_CID3:
70
- r = sysinfo_id[(offset - A_PID4) / 4];
71
+ switch (s->sse_version) {
72
+ case ARMSSE_SSE300:
73
+ r = sysinfo_sse300_id[(offset - A_PID4) / 4];
74
+ break;
75
+ default:
76
+ r = sysinfo_id[(offset - A_PID4) / 4];
77
+ break;
78
+ }
79
break;
80
default:
81
qemu_log_mask(LOG_GUEST_ERROR,
82
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps iotkit_sysinfo_ops = {
83
static Property iotkit_sysinfo_props[] = {
84
DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysInfo, sys_version, 0),
85
DEFINE_PROP_UINT32("SYS_CONFIG", IoTKitSysInfo, sys_config, 0),
86
+ DEFINE_PROP_UINT32("sse-version", IoTKitSysInfo, sse_version, 0),
87
DEFINE_PROP_END_OF_LIST()
88
};
89
90
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysinfo_init(Object *obj)
91
sysbus_init_mmio(sbd, &s->iomem);
92
}
93
94
+static void iotkit_sysinfo_realize(DeviceState *dev, Error **errp)
95
+{
96
+ IoTKitSysInfo *s = IOTKIT_SYSINFO(dev);
97
+
98
+ if (!armsse_version_valid(s->sse_version)) {
99
+ error_setg(errp, "invalid sse-version value %d", s->sse_version);
100
+ return;
101
+ }
102
+}
103
+
104
static void iotkit_sysinfo_class_init(ObjectClass *klass, void *data)
105
{
106
DeviceClass *dc = DEVICE_CLASS(klass);
107
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysinfo_class_init(ObjectClass *klass, void *data)
108
* This device has no guest-modifiable state and so it
109
* does not need a reset function or VMState.
110
*/
111
-
112
+ dc->realize = iotkit_sysinfo_realize;
113
device_class_set_props(dc, iotkit_sysinfo_props);
114
}
115
116
--
117
2.20.1
118
119
diff view generated by jsdifflib
New patch
1
In the SSE-300, the format of the SYS_CONFIG0 register has changed again;
2
pass through the correct value to the SYSINFO register block device.
1
3
4
We drop the old SysConfigFormat enum, which was implemented in the
5
hope that different flavours of SSE would share the same format;
6
since they all seem to be different and we now have an sse_version
7
enum to key off, just use that.
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210219144617.4782-10-peter.maydell@linaro.org
13
---
14
hw/arm/armsse.c | 21 +++++++++------------
15
1 file changed, 9 insertions(+), 12 deletions(-)
16
17
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/armsse.c
20
+++ b/hw/arm/armsse.c
21
@@ -XXX,XX +XXX,XX @@
22
#include "hw/irq.h"
23
#include "hw/qdev-clock.h"
24
25
-/* Format of the System Information block SYS_CONFIG register */
26
-typedef enum SysConfigFormat {
27
- IoTKitFormat,
28
- SSE200Format,
29
-} SysConfigFormat;
30
-
31
struct ARMSSEInfo {
32
const char *name;
33
uint32_t sse_version;
34
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
35
int num_cpus;
36
uint32_t sys_version;
37
uint32_t cpuwait_rst;
38
- SysConfigFormat sys_config_format;
39
bool has_mhus;
40
bool has_ppus;
41
bool has_cachectrl;
42
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
43
.num_cpus = 1,
44
.sys_version = 0x41743,
45
.cpuwait_rst = 0,
46
- .sys_config_format = IoTKitFormat,
47
.has_mhus = false,
48
.has_ppus = false,
49
.has_cachectrl = false,
50
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
51
.num_cpus = 2,
52
.sys_version = 0x22041743,
53
.cpuwait_rst = 2,
54
- .sys_config_format = SSE200Format,
55
.has_mhus = true,
56
.has_ppus = true,
57
.has_cachectrl = true,
58
@@ -XXX,XX +XXX,XX @@ static uint32_t armsse_sys_config_value(ARMSSE *s, const ARMSSEInfo *info)
59
/* Return the SYS_CONFIG value for this SSE */
60
uint32_t sys_config;
61
62
- switch (info->sys_config_format) {
63
- case IoTKitFormat:
64
+ switch (info->sse_version) {
65
+ case ARMSSE_IOTKIT:
66
sys_config = 0;
67
sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
68
sys_config = deposit32(sys_config, 4, 4, s->sram_addr_width - 12);
69
break;
70
- case SSE200Format:
71
+ case ARMSSE_SSE200:
72
sys_config = 0;
73
sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
74
sys_config = deposit32(sys_config, 4, 5, s->sram_addr_width);
75
@@ -XXX,XX +XXX,XX @@ static uint32_t armsse_sys_config_value(ARMSSE *s, const ARMSSEInfo *info)
76
sys_config = deposit32(sys_config, 28, 4, 2);
77
}
78
break;
79
+ case ARMSSE_SSE300:
80
+ sys_config = 0;
81
+ sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
82
+ sys_config = deposit32(sys_config, 4, 5, s->sram_addr_width);
83
+ sys_config = deposit32(sys_config, 16, 3, 3); /* CPU0 = Cortex-M55 */
84
+ break;
85
default:
86
g_assert_not_reached();
87
}
88
--
89
2.20.1
90
91
diff view generated by jsdifflib
New patch
1
For SSE-300, the SYSINFO register block has two new registers:
1
2
3
* SYS_CONFIG1 indicates the config for a potential CPU2 and CPU3;
4
since the SSE-300 can only be configured with a single CPU it
5
is always zero
6
7
* IIDR is the subsystem implementation identity register;
8
its value is set by the SoC integrator, so we plumb this in from
9
the armsse.c code as we do with SYS_VERSION and SYS_CONFIG
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20210219144617.4782-11-peter.maydell@linaro.org
15
---
16
include/hw/misc/iotkit-sysinfo.h | 1 +
17
hw/arm/armsse.c | 5 +++++
18
hw/misc/iotkit-sysinfo.c | 22 ++++++++++++++++++++++
19
3 files changed, 28 insertions(+)
20
21
diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/misc/iotkit-sysinfo.h
24
+++ b/include/hw/misc/iotkit-sysinfo.h
25
@@ -XXX,XX +XXX,XX @@ struct IoTKitSysInfo {
26
uint32_t sys_version;
27
uint32_t sys_config;
28
uint32_t sse_version;
29
+ uint32_t iidr;
30
};
31
32
#endif
33
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/armsse.c
36
+++ b/hw/arm/armsse.c
37
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
38
int sram_banks;
39
int num_cpus;
40
uint32_t sys_version;
41
+ uint32_t iidr;
42
uint32_t cpuwait_rst;
43
bool has_mhus;
44
bool has_ppus;
45
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
46
.sram_banks = 1,
47
.num_cpus = 1,
48
.sys_version = 0x41743,
49
+ .iidr = 0,
50
.cpuwait_rst = 0,
51
.has_mhus = false,
52
.has_ppus = false,
53
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
54
.sram_banks = 4,
55
.num_cpus = 2,
56
.sys_version = 0x22041743,
57
+ .iidr = 0,
58
.cpuwait_rst = 2,
59
.has_mhus = true,
60
.has_ppus = true,
61
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
62
}
63
object_property_set_int(OBJECT(&s->sysinfo), "sse-version",
64
info->sse_version, &error_abort);
65
+ object_property_set_int(OBJECT(&s->sysinfo), "IIDR",
66
+ info->iidr, &error_abort);
67
if (!sysbus_realize(SYS_BUS_DEVICE(&s->sysinfo), errp)) {
68
return;
69
}
70
diff --git a/hw/misc/iotkit-sysinfo.c b/hw/misc/iotkit-sysinfo.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/hw/misc/iotkit-sysinfo.c
73
+++ b/hw/misc/iotkit-sysinfo.c
74
@@ -XXX,XX +XXX,XX @@
75
76
REG32(SYS_VERSION, 0x0)
77
REG32(SYS_CONFIG, 0x4)
78
+REG32(SYS_CONFIG1, 0x8)
79
+REG32(IIDR, 0xfc8)
80
REG32(PID4, 0xfd0)
81
REG32(PID5, 0xfd4)
82
REG32(PID6, 0xfd8)
83
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysinfo_read(void *opaque, hwaddr offset,
84
case A_SYS_CONFIG:
85
r = s->sys_config;
86
break;
87
+ case A_SYS_CONFIG1:
88
+ switch (s->sse_version) {
89
+ case ARMSSE_SSE300:
90
+ return 0;
91
+ break;
92
+ default:
93
+ goto bad_read;
94
+ }
95
+ break;
96
+ case A_IIDR:
97
+ switch (s->sse_version) {
98
+ case ARMSSE_SSE300:
99
+ return s->iidr;
100
+ break;
101
+ default:
102
+ goto bad_read;
103
+ }
104
+ break;
105
case A_PID4 ... A_CID3:
106
switch (s->sse_version) {
107
case ARMSSE_SSE300:
108
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysinfo_read(void *opaque, hwaddr offset,
109
}
110
break;
111
default:
112
+ bad_read:
113
qemu_log_mask(LOG_GUEST_ERROR,
114
"IoTKit SysInfo read: bad offset %x\n", (int)offset);
115
r = 0;
116
@@ -XXX,XX +XXX,XX @@ static Property iotkit_sysinfo_props[] = {
117
DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysInfo, sys_version, 0),
118
DEFINE_PROP_UINT32("SYS_CONFIG", IoTKitSysInfo, sys_config, 0),
119
DEFINE_PROP_UINT32("sse-version", IoTKitSysInfo, sse_version, 0),
120
+ DEFINE_PROP_UINT32("IIDR", IoTKitSysInfo, iidr, 0),
121
DEFINE_PROP_END_OF_LIST()
122
};
123
124
--
125
2.20.1
126
127
diff view generated by jsdifflib
New patch
1
The SSE-300 includes a counter module; implement a model of it.
1
2
3
This counter is documented in the SSE-123 Example Subsystem
4
Technical Reference Manual:
5
https://developer.arm.com/documentation/101370/latest/
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210219144617.4782-12-peter.maydell@linaro.org
11
---
12
include/hw/timer/sse-counter.h | 105 ++++++++
13
hw/timer/sse-counter.c | 474 +++++++++++++++++++++++++++++++++
14
MAINTAINERS | 2 +
15
hw/arm/Kconfig | 1 +
16
hw/timer/Kconfig | 3 +
17
hw/timer/meson.build | 1 +
18
hw/timer/trace-events | 7 +
19
7 files changed, 593 insertions(+)
20
create mode 100644 include/hw/timer/sse-counter.h
21
create mode 100644 hw/timer/sse-counter.c
22
23
diff --git a/include/hw/timer/sse-counter.h b/include/hw/timer/sse-counter.h
24
new file mode 100644
25
index XXXXXXX..XXXXXXX
26
--- /dev/null
27
+++ b/include/hw/timer/sse-counter.h
28
@@ -XXX,XX +XXX,XX @@
29
+/*
30
+ * Arm SSE Subsystem System Counter
31
+ *
32
+ * Copyright (c) 2020 Linaro Limited
33
+ * Written by Peter Maydell
34
+ *
35
+ * This program is free software; you can redistribute it and/or modify
36
+ * it under the terms of the GNU General Public License version 2 or
37
+ * (at your option) any later version.
38
+ */
39
+
40
+/*
41
+ * This is a model of the "System counter" which is documented in
42
+ * the Arm SSE-123 Example Subsystem Technical Reference Manual:
43
+ * https://developer.arm.com/documentation/101370/latest/
44
+ *
45
+ * QEMU interface:
46
+ * + Clock input "CLK": clock
47
+ * + sysbus MMIO region 0: the control register frame
48
+ * + sysbus MMIO region 1: the status register frame
49
+ *
50
+ * Consumers of the system counter's timestamp, such as the SSE
51
+ * System Timer device, can also use the APIs sse_counter_for_timestamp(),
52
+ * sse_counter_tick_to_time() and sse_counter_register_consumer() to
53
+ * interact with an instance of the System Counter. Generally the
54
+ * consumer device should have a QOM link property which the board
55
+ * code can set to the appropriate instance of the system counter.
56
+ */
57
+
58
+#ifndef SSE_COUNTER_H
59
+#define SSE_COUNTER_H
60
+
61
+#include "hw/sysbus.h"
62
+#include "qom/object.h"
63
+#include "qemu/notify.h"
64
+
65
+#define TYPE_SSE_COUNTER "sse-counter"
66
+OBJECT_DECLARE_SIMPLE_TYPE(SSECounter, SSE_COUNTER)
67
+
68
+struct SSECounter {
69
+ /*< private >*/
70
+ SysBusDevice parent_obj;
71
+
72
+ /*< public >*/
73
+ MemoryRegion control_mr;
74
+ MemoryRegion status_mr;
75
+ Clock *clk;
76
+ NotifierList notifier_list;
77
+
78
+ uint32_t cntcr;
79
+ uint32_t cntscr0;
80
+
81
+ /*
82
+ * These are used for handling clock frequency changes: they are a
83
+ * tuple of (QEMU_CLOCK_VIRTUAL timestamp, CNTCV at that time),
84
+ * taken when the clock frequency changes. sse_cntcv() needs them
85
+ * to calculate the current CNTCV.
86
+ */
87
+ uint64_t ns_then;
88
+ uint64_t ticks_then;
89
+};
90
+
91
+/*
92
+ * These functions are the interface by which a consumer of
93
+ * the system timestamp (such as the SSE system timer device)
94
+ * can communicate with the SSECounter.
95
+ */
96
+
97
+/**
98
+ * sse_counter_for_timestamp:
99
+ * @counter: SSECounter
100
+ * @ns: timestamp of QEMU_CLOCK_VIRTUAL in nanoseconds
101
+ *
102
+ * Returns the value of the timestamp counter at the specified
103
+ * point in time (assuming that no changes to scale factor, enable, etc
104
+ * happen in the meantime).
105
+ */
106
+uint64_t sse_counter_for_timestamp(SSECounter *counter, uint64_t ns);
107
+
108
+/**
109
+ * sse_counter_tick_to_time:
110
+ * @counter: SSECounter
111
+ * @tick: tick value
112
+ *
113
+ * Returns the time (a QEMU_CLOCK_VIRTUAL timestamp in nanoseconds)
114
+ * when the timestamp counter will reach the specified tick count.
115
+ * If the counter is not currently running, returns UINT64_MAX.
116
+ */
117
+uint64_t sse_counter_tick_to_time(SSECounter *counter, uint64_t tick);
118
+
119
+/**
120
+ * sse_counter_register_consumer:
121
+ * @counter: SSECounter
122
+ * @notifier: Notifier which is notified on counter changes
123
+ *
124
+ * Registers @notifier with the SSECounter. When the counter's
125
+ * configuration changes in a way that might invalidate information
126
+ * previously returned via sse_counter_for_timestamp() or
127
+ * sse_counter_tick_to_time(), the notifier will be called.
128
+ * Devices which consume the timestamp counter can use this as
129
+ * a cue to recalculate timer events.
130
+ */
131
+void sse_counter_register_consumer(SSECounter *counter, Notifier *notifier);
132
+
133
+#endif
134
diff --git a/hw/timer/sse-counter.c b/hw/timer/sse-counter.c
135
new file mode 100644
136
index XXXXXXX..XXXXXXX
137
--- /dev/null
138
+++ b/hw/timer/sse-counter.c
139
@@ -XXX,XX +XXX,XX @@
140
+/*
141
+ * Arm SSE Subsystem System Counter
142
+ *
143
+ * Copyright (c) 2020 Linaro Limited
144
+ * Written by Peter Maydell
145
+ *
146
+ * This program is free software; you can redistribute it and/or modify
147
+ * it under the terms of the GNU General Public License version 2 or
148
+ * (at your option) any later version.
149
+ */
150
+
151
+/*
152
+ * This is a model of the "System counter" which is documented in
153
+ * the Arm SSE-123 Example Subsystem Technical Reference Manual:
154
+ * https://developer.arm.com/documentation/101370/latest/
155
+ *
156
+ * The system counter is a non-stop 64-bit up-counter. It provides
157
+ * this count value to other devices like the SSE system timer,
158
+ * which are driven by this system timestamp rather than directly
159
+ * from a clock. Internally to the counter the count is actually
160
+ * 88-bit precision (64.24 fixed point), with a programmable scale factor.
161
+ *
162
+ * The hardware has the optional feature that it supports dynamic
163
+ * clock switching, where two clock inputs are connected, and which
164
+ * one is used is selected via a CLKSEL input signal. Since the
165
+ * users of this device in QEMU don't use this feature, we only model
166
+ * the HWCLKSW=0 configuration.
167
+ */
168
+#include "qemu/osdep.h"
169
+#include "qemu/log.h"
170
+#include "qemu/timer.h"
171
+#include "qapi/error.h"
172
+#include "trace.h"
173
+#include "hw/timer/sse-counter.h"
174
+#include "hw/sysbus.h"
175
+#include "hw/irq.h"
176
+#include "hw/registerfields.h"
177
+#include "hw/clock.h"
178
+#include "hw/qdev-clock.h"
179
+#include "migration/vmstate.h"
180
+
181
+/* Registers in the control frame */
182
+REG32(CNTCR, 0x0)
183
+ FIELD(CNTCR, EN, 0, 1)
184
+ FIELD(CNTCR, HDBG, 1, 1)
185
+ FIELD(CNTCR, SCEN, 2, 1)
186
+ FIELD(CNTCR, INTRMASK, 3, 1)
187
+ FIELD(CNTCR, PSLVERRDIS, 4, 1)
188
+ FIELD(CNTCR, INTRCLR, 5, 1)
189
+/*
190
+ * Although CNTCR defines interrupt-related bits, the counter doesn't
191
+ * appear to actually have an interrupt output. So INTRCLR is
192
+ * effectively a RAZ/WI bit, as are the reserved bits [31:6].
193
+ */
194
+#define CNTCR_VALID_MASK (R_CNTCR_EN_MASK | R_CNTCR_HDBG_MASK | \
195
+ R_CNTCR_SCEN_MASK | R_CNTCR_INTRMASK_MASK | \
196
+ R_CNTCR_PSLVERRDIS_MASK)
197
+REG32(CNTSR, 0x4)
198
+REG32(CNTCV_LO, 0x8)
199
+REG32(CNTCV_HI, 0xc)
200
+REG32(CNTSCR, 0x10) /* Aliased with CNTSCR0 */
201
+REG32(CNTID, 0x1c)
202
+ FIELD(CNTID, CNTSC, 0, 4)
203
+ FIELD(CNTID, CNTCS, 16, 1)
204
+ FIELD(CNTID, CNTSELCLK, 17, 2)
205
+ FIELD(CNTID, CNTSCR_OVR, 19, 1)
206
+REG32(CNTSCR0, 0xd0)
207
+REG32(CNTSCR1, 0xd4)
208
+
209
+/* Registers in the status frame */
210
+REG32(STATUS_CNTCV_LO, 0x0)
211
+REG32(STATUS_CNTCV_HI, 0x4)
212
+
213
+/* Standard ID registers, present in both frames */
214
+REG32(PID4, 0xFD0)
215
+REG32(PID5, 0xFD4)
216
+REG32(PID6, 0xFD8)
217
+REG32(PID7, 0xFDC)
218
+REG32(PID0, 0xFE0)
219
+REG32(PID1, 0xFE4)
220
+REG32(PID2, 0xFE8)
221
+REG32(PID3, 0xFEC)
222
+REG32(CID0, 0xFF0)
223
+REG32(CID1, 0xFF4)
224
+REG32(CID2, 0xFF8)
225
+REG32(CID3, 0xFFC)
226
+
227
+/* PID/CID values */
228
+static const int control_id[] = {
229
+ 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
230
+ 0xba, 0xb0, 0x0b, 0x00, /* PID0..PID3 */
231
+ 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
232
+};
233
+
234
+static const int status_id[] = {
235
+ 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
236
+ 0xbb, 0xb0, 0x0b, 0x00, /* PID0..PID3 */
237
+ 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
238
+};
239
+
240
+static void sse_counter_notify_users(SSECounter *s)
241
+{
242
+ /*
243
+ * Notify users of the count timestamp that they may
244
+ * need to recalculate.
245
+ */
246
+ notifier_list_notify(&s->notifier_list, NULL);
247
+}
248
+
249
+static bool sse_counter_enabled(SSECounter *s)
250
+{
251
+ return (s->cntcr & R_CNTCR_EN_MASK) != 0;
252
+}
253
+
254
+uint64_t sse_counter_tick_to_time(SSECounter *s, uint64_t tick)
255
+{
256
+ if (!sse_counter_enabled(s)) {
257
+ return UINT64_MAX;
258
+ }
259
+
260
+ tick -= s->ticks_then;
261
+
262
+ if (s->cntcr & R_CNTCR_SCEN_MASK) {
263
+ /* Adjust the tick count to account for the scale factor */
264
+ tick = muldiv64(tick, 0x01000000, s->cntscr0);
265
+ }
266
+
267
+ return s->ns_then + clock_ticks_to_ns(s->clk, tick);
268
+}
269
+
270
+void sse_counter_register_consumer(SSECounter *s, Notifier *notifier)
271
+{
272
+ /*
273
+ * For the moment we assume that both we and the devices
274
+ * which consume us last for the life of the simulation,
275
+ * and so there is no mechanism for removing a notifier.
276
+ */
277
+ notifier_list_add(&s->notifier_list, notifier);
278
+}
279
+
280
+uint64_t sse_counter_for_timestamp(SSECounter *s, uint64_t now)
281
+{
282
+ /* Return the CNTCV value for a particular timestamp (clock ns value). */
283
+ uint64_t ticks;
284
+
285
+ if (!sse_counter_enabled(s)) {
286
+ /* Counter is disabled and does not increment */
287
+ return s->ticks_then;
288
+ }
289
+
290
+ ticks = clock_ns_to_ticks(s->clk, now - s->ns_then);
291
+ if (s->cntcr & R_CNTCR_SCEN_MASK) {
292
+ /*
293
+ * Scaling is enabled. The CNTSCR value is the amount added to
294
+ * the underlying 88-bit counter for every tick of the
295
+ * underlying clock; CNTCV is the top 64 bits of that full
296
+ * 88-bit value. Multiplying the tick count by CNTSCR tells us
297
+ * how much the full 88-bit counter has moved on; we then
298
+ * divide that by 0x01000000 to find out how much the 64-bit
299
+ * visible portion has advanced. muldiv64() gives us the
300
+ * necessary at-least-88-bit precision for the intermediate
301
+ * result.
302
+ */
303
+ ticks = muldiv64(ticks, s->cntscr0, 0x01000000);
304
+ }
305
+ return s->ticks_then + ticks;
306
+}
307
+
308
+static uint64_t sse_cntcv(SSECounter *s)
309
+{
310
+ /* Return the CNTCV value for the current time */
311
+ return sse_counter_for_timestamp(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
312
+}
313
+
314
+static void sse_write_cntcv(SSECounter *s, uint32_t value, unsigned startbit)
315
+{
316
+ /*
317
+ * Write one 32-bit half of the counter value; startbit is the
318
+ * bit position of this half in the 64-bit word, either 0 or 32.
319
+ */
320
+ uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
321
+ uint64_t cntcv = sse_counter_for_timestamp(s, now);
322
+
323
+ cntcv = deposit64(cntcv, startbit, 32, value);
324
+ s->ticks_then = cntcv;
325
+ s->ns_then = now;
326
+ sse_counter_notify_users(s);
327
+}
328
+
329
+static uint64_t sse_counter_control_read(void *opaque, hwaddr offset,
330
+ unsigned size)
331
+{
332
+ SSECounter *s = SSE_COUNTER(opaque);
333
+ uint64_t r;
334
+
335
+ switch (offset) {
336
+ case A_CNTCR:
337
+ r = s->cntcr;
338
+ break;
339
+ case A_CNTSR:
340
+ /*
341
+ * The only bit here is DBGH, indicating that the counter has been
342
+ * halted via the Halt-on-Debug signal. We don't implement halting
343
+ * debug, so the whole register always reads as zero.
344
+ */
345
+ r = 0;
346
+ break;
347
+ case A_CNTCV_LO:
348
+ r = extract64(sse_cntcv(s), 0, 32);
349
+ break;
350
+ case A_CNTCV_HI:
351
+ r = extract64(sse_cntcv(s), 32, 32);
352
+ break;
353
+ case A_CNTID:
354
+ /*
355
+ * For our implementation:
356
+ * - CNTSCR can only be written when CNTCR.EN == 0
357
+ * - HWCLKSW=0, so selected clock is always CLK0
358
+ * - counter scaling is implemented
359
+ */
360
+ r = (1 << R_CNTID_CNTSELCLK_SHIFT) | (1 << R_CNTID_CNTSC_SHIFT);
361
+ break;
362
+ case A_CNTSCR:
363
+ case A_CNTSCR0:
364
+ r = s->cntscr0;
365
+ break;
366
+ case A_CNTSCR1:
367
+ /* If HWCLKSW == 0, CNTSCR1 is RAZ/WI */
368
+ r = 0;
369
+ break;
370
+ case A_PID4 ... A_CID3:
371
+ r = control_id[(offset - A_PID4) / 4];
372
+ break;
373
+ default:
374
+ qemu_log_mask(LOG_GUEST_ERROR,
375
+ "SSE System Counter control frame read: bad offset 0x%x",
376
+ (unsigned)offset);
377
+ r = 0;
378
+ break;
379
+ }
380
+
381
+ trace_sse_counter_control_read(offset, r, size);
382
+ return r;
383
+}
384
+
385
+static void sse_counter_control_write(void *opaque, hwaddr offset,
386
+ uint64_t value, unsigned size)
387
+{
388
+ SSECounter *s = SSE_COUNTER(opaque);
389
+
390
+ trace_sse_counter_control_write(offset, value, size);
391
+
392
+ switch (offset) {
393
+ case A_CNTCR:
394
+ /*
395
+ * Although CNTCR defines interrupt-related bits, the counter doesn't
396
+ * appear to actually have an interrupt output. So INTRCLR is
397
+ * effectively a RAZ/WI bit, as are the reserved bits [31:6].
398
+ * The documentation does not explicitly say so, but we assume
399
+ * that changing the scale factor while the counter is enabled
400
+ * by toggling CNTCR.SCEN has the same behaviour (making the counter
401
+ * value UNKNOWN) as changing it by writing to CNTSCR, and so we
402
+ * don't need to try to recalculate for that case.
403
+ */
404
+ value &= CNTCR_VALID_MASK;
405
+ if ((value ^ s->cntcr) & R_CNTCR_EN_MASK) {
406
+ /*
407
+ * Whether the counter is being enabled or disabled, the
408
+ * required action is the same: sync the (ns_then, ticks_then)
409
+ * tuple.
410
+ */
411
+ uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
412
+ s->ticks_then = sse_counter_for_timestamp(s, now);
413
+ s->ns_then = now;
414
+ sse_counter_notify_users(s);
415
+ }
416
+ s->cntcr = value;
417
+ break;
418
+ case A_CNTCV_LO:
419
+ sse_write_cntcv(s, value, 0);
420
+ break;
421
+ case A_CNTCV_HI:
422
+ sse_write_cntcv(s, value, 32);
423
+ break;
424
+ case A_CNTSCR:
425
+ case A_CNTSCR0:
426
+ /*
427
+ * If the scale registers are changed when the counter is enabled,
428
+ * the count value becomes UNKNOWN. So we don't try to recalculate
429
+ * anything here but only do it on a write to CNTCR.EN.
430
+ */
431
+ s->cntscr0 = value;
432
+ break;
433
+ case A_CNTSCR1:
434
+ /* If HWCLKSW == 0, CNTSCR1 is RAZ/WI */
435
+ break;
436
+ case A_CNTSR:
437
+ case A_CNTID:
438
+ case A_PID4 ... A_CID3:
439
+ qemu_log_mask(LOG_GUEST_ERROR,
440
+ "SSE System Counter control frame: write to RO offset 0x%x\n",
441
+ (unsigned)offset);
442
+ break;
443
+ default:
444
+ qemu_log_mask(LOG_GUEST_ERROR,
445
+ "SSE System Counter control frame: write to bad offset 0x%x\n",
446
+ (unsigned)offset);
447
+ break;
448
+ }
449
+}
450
+
451
+static uint64_t sse_counter_status_read(void *opaque, hwaddr offset,
452
+ unsigned size)
453
+{
454
+ SSECounter *s = SSE_COUNTER(opaque);
455
+ uint64_t r;
456
+
457
+ switch (offset) {
458
+ case A_STATUS_CNTCV_LO:
459
+ r = extract64(sse_cntcv(s), 0, 32);
460
+ break;
461
+ case A_STATUS_CNTCV_HI:
462
+ r = extract64(sse_cntcv(s), 32, 32);
463
+ break;
464
+ case A_PID4 ... A_CID3:
465
+ r = status_id[(offset - A_PID4) / 4];
466
+ break;
467
+ default:
468
+ qemu_log_mask(LOG_GUEST_ERROR,
469
+ "SSE System Counter status frame read: bad offset 0x%x",
470
+ (unsigned)offset);
471
+ r = 0;
472
+ break;
473
+ }
474
+
475
+ trace_sse_counter_status_read(offset, r, size);
476
+ return r;
477
+}
478
+
479
+static void sse_counter_status_write(void *opaque, hwaddr offset,
480
+ uint64_t value, unsigned size)
481
+{
482
+ trace_sse_counter_status_write(offset, value, size);
483
+
484
+ switch (offset) {
485
+ case A_STATUS_CNTCV_LO:
486
+ case A_STATUS_CNTCV_HI:
487
+ case A_PID4 ... A_CID3:
488
+ qemu_log_mask(LOG_GUEST_ERROR,
489
+ "SSE System Counter status frame: write to RO offset 0x%x\n",
490
+ (unsigned)offset);
491
+ break;
492
+ default:
493
+ qemu_log_mask(LOG_GUEST_ERROR,
494
+ "SSE System Counter status frame: write to bad offset 0x%x\n",
495
+ (unsigned)offset);
496
+ break;
497
+ }
498
+}
499
+
500
+static const MemoryRegionOps sse_counter_control_ops = {
501
+ .read = sse_counter_control_read,
502
+ .write = sse_counter_control_write,
503
+ .endianness = DEVICE_LITTLE_ENDIAN,
504
+ .valid.min_access_size = 4,
505
+ .valid.max_access_size = 4,
506
+};
507
+
508
+static const MemoryRegionOps sse_counter_status_ops = {
509
+ .read = sse_counter_status_read,
510
+ .write = sse_counter_status_write,
511
+ .endianness = DEVICE_LITTLE_ENDIAN,
512
+ .valid.min_access_size = 4,
513
+ .valid.max_access_size = 4,
514
+};
515
+
516
+static void sse_counter_reset(DeviceState *dev)
517
+{
518
+ SSECounter *s = SSE_COUNTER(dev);
519
+
520
+ trace_sse_counter_reset();
521
+
522
+ s->cntcr = 0;
523
+ s->cntscr0 = 0x01000000;
524
+ s->ns_then = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
525
+ s->ticks_then = 0;
526
+}
527
+
528
+static void sse_clk_callback(void *opaque, ClockEvent event)
529
+{
530
+ SSECounter *s = SSE_COUNTER(opaque);
531
+ uint64_t now;
532
+
533
+ switch (event) {
534
+ case ClockPreUpdate:
535
+ /*
536
+ * Before the clock period updates, set (ticks_then, ns_then)
537
+ * to the current time and tick count (as calculated with
538
+ * the old clock period).
539
+ */
540
+ if (sse_counter_enabled(s)) {
541
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
542
+ s->ticks_then = sse_counter_for_timestamp(s, now);
543
+ s->ns_then = now;
544
+ }
545
+ break;
546
+ case ClockUpdate:
547
+ sse_counter_notify_users(s);
548
+ break;
549
+ default:
550
+ break;
551
+ }
552
+}
553
+
554
+static void sse_counter_init(Object *obj)
555
+{
556
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
557
+ SSECounter *s = SSE_COUNTER(obj);
558
+
559
+ notifier_list_init(&s->notifier_list);
560
+
561
+ s->clk = qdev_init_clock_in(DEVICE(obj), "CLK", sse_clk_callback, s,
562
+ ClockPreUpdate | ClockUpdate);
563
+ memory_region_init_io(&s->control_mr, obj, &sse_counter_control_ops,
564
+ s, "sse-counter-control", 0x1000);
565
+ memory_region_init_io(&s->status_mr, obj, &sse_counter_status_ops,
566
+ s, "sse-counter-status", 0x1000);
567
+ sysbus_init_mmio(sbd, &s->control_mr);
568
+ sysbus_init_mmio(sbd, &s->status_mr);
569
+}
570
+
571
+static void sse_counter_realize(DeviceState *dev, Error **errp)
572
+{
573
+ SSECounter *s = SSE_COUNTER(dev);
574
+
575
+ if (!clock_has_source(s->clk)) {
576
+ error_setg(errp, "SSE system counter: CLK must be connected");
577
+ return;
578
+ }
579
+}
580
+
581
+static const VMStateDescription sse_counter_vmstate = {
582
+ .name = "sse-counter",
583
+ .version_id = 1,
584
+ .minimum_version_id = 1,
585
+ .fields = (VMStateField[]) {
586
+ VMSTATE_CLOCK(clk, SSECounter),
587
+ VMSTATE_END_OF_LIST()
588
+ }
589
+};
590
+
591
+static void sse_counter_class_init(ObjectClass *klass, void *data)
592
+{
593
+ DeviceClass *dc = DEVICE_CLASS(klass);
594
+
595
+ dc->realize = sse_counter_realize;
596
+ dc->vmsd = &sse_counter_vmstate;
597
+ dc->reset = sse_counter_reset;
598
+}
599
+
600
+static const TypeInfo sse_counter_info = {
601
+ .name = TYPE_SSE_COUNTER,
602
+ .parent = TYPE_SYS_BUS_DEVICE,
603
+ .instance_size = sizeof(SSECounter),
604
+ .instance_init = sse_counter_init,
605
+ .class_init = sse_counter_class_init,
606
+};
607
+
608
+static void sse_counter_register_types(void)
609
+{
610
+ type_register_static(&sse_counter_info);
611
+}
612
+
613
+type_init(sse_counter_register_types);
614
diff --git a/MAINTAINERS b/MAINTAINERS
615
index XXXXXXX..XXXXXXX 100644
616
--- a/MAINTAINERS
617
+++ b/MAINTAINERS
618
@@ -XXX,XX +XXX,XX @@ F: hw/misc/armsse-cpuid.c
619
F: include/hw/misc/armsse-cpuid.h
620
F: hw/misc/armsse-mhu.c
621
F: include/hw/misc/armsse-mhu.h
622
+F: hw/timer/sse-counter.c
623
+F: include/hw/timer/sse-counter.h
624
F: docs/system/arm/mps2.rst
625
626
Musca
627
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
628
index XXXXXXX..XXXXXXX 100644
629
--- a/hw/arm/Kconfig
630
+++ b/hw/arm/Kconfig
631
@@ -XXX,XX +XXX,XX @@ config ARMSSE
632
select TZ_MSC
633
select TZ_PPC
634
select UNIMP
635
+ select SSE_COUNTER
636
637
config ARMSSE_CPUID
638
bool
639
diff --git a/hw/timer/Kconfig b/hw/timer/Kconfig
640
index XXXXXXX..XXXXXXX 100644
641
--- a/hw/timer/Kconfig
642
+++ b/hw/timer/Kconfig
643
@@ -XXX,XX +XXX,XX @@ config RENESAS_TMR
644
config RENESAS_CMT
645
bool
646
647
+config SSE_COUNTER
648
+ bool
649
+
650
config AVR_TIMER16
651
bool
652
diff --git a/hw/timer/meson.build b/hw/timer/meson.build
653
index XXXXXXX..XXXXXXX 100644
654
--- a/hw/timer/meson.build
655
+++ b/hw/timer/meson.build
656
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_timer.c'))
657
softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_systmr.c'))
658
softmmu_ss.add(when: 'CONFIG_SH4', if_true: files('sh_timer.c'))
659
softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_timer.c'))
660
+softmmu_ss.add(when: 'CONFIG_SSE_COUNTER', if_true: files('sse-counter.c'))
661
softmmu_ss.add(when: 'CONFIG_STM32F2XX_TIMER', if_true: files('stm32f2xx_timer.c'))
662
softmmu_ss.add(when: 'CONFIG_XILINX', if_true: files('xilinx_timer.c'))
663
664
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
665
index XXXXXXX..XXXXXXX 100644
666
--- a/hw/timer/trace-events
667
+++ b/hw/timer/trace-events
668
@@ -XXX,XX +XXX,XX @@ avr_timer16_interrupt_count(uint8_t cnt) "count: %u"
669
avr_timer16_interrupt_overflow(const char *reason) "overflow: %s"
670
avr_timer16_next_alarm(uint64_t delay_ns) "next alarm: %" PRIu64 " ns from now"
671
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)"
672
+
673
+# sse_counter.c
674
+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"
675
+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"
676
+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"
677
+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"
678
+sse_counter_reset(void) "SSE system counter: reset"
679
--
680
2.20.1
681
682
diff view generated by jsdifflib
New patch
1
The SSE-300 includes some timers which are a different kind to
2
those in the SSE-200. Model them.
1
3
4
These timers are documented in the SSE-123 Example Subsystem
5
Technical Reference Manual:
6
https://developer.arm.com/documentation/101370/latest/
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20210219144617.4782-13-peter.maydell@linaro.org
12
---
13
include/hw/timer/sse-timer.h | 53 ++++
14
hw/timer/sse-timer.c | 470 +++++++++++++++++++++++++++++++++++
15
MAINTAINERS | 2 +
16
hw/arm/Kconfig | 1 +
17
hw/timer/Kconfig | 3 +
18
hw/timer/meson.build | 1 +
19
hw/timer/trace-events | 5 +
20
7 files changed, 535 insertions(+)
21
create mode 100644 include/hw/timer/sse-timer.h
22
create mode 100644 hw/timer/sse-timer.c
23
24
diff --git a/include/hw/timer/sse-timer.h b/include/hw/timer/sse-timer.h
25
new file mode 100644
26
index XXXXXXX..XXXXXXX
27
--- /dev/null
28
+++ b/include/hw/timer/sse-timer.h
29
@@ -XXX,XX +XXX,XX @@
30
+/*
31
+ * Arm SSE Subsystem System Timer
32
+ *
33
+ * Copyright (c) 2020 Linaro Limited
34
+ * Written by Peter Maydell
35
+ *
36
+ * This program is free software; you can redistribute it and/or modify
37
+ * it under the terms of the GNU General Public License version 2 or
38
+ * (at your option) any later version.
39
+ */
40
+
41
+/*
42
+ * This is a model of the "System timer" which is documented in
43
+ * the Arm SSE-123 Example Subsystem Technical Reference Manual:
44
+ * https://developer.arm.com/documentation/101370/latest/
45
+ *
46
+ * QEMU interface:
47
+ * + QOM property "counter": link property to be set to the
48
+ * TYPE_SSE_COUNTER timestamp counter device this timer runs off
49
+ * + sysbus MMIO region 0: the register bank
50
+ * + sysbus IRQ 0: timer interrupt
51
+ */
52
+
53
+#ifndef SSE_TIMER_H
54
+#define SSE_TIMER_H
55
+
56
+#include "hw/sysbus.h"
57
+#include "qom/object.h"
58
+#include "hw/timer/sse-counter.h"
59
+
60
+#define TYPE_SSE_TIMER "sse-timer"
61
+OBJECT_DECLARE_SIMPLE_TYPE(SSETimer, SSE_TIMER)
62
+
63
+struct SSETimer {
64
+ /*< private >*/
65
+ SysBusDevice parent_obj;
66
+
67
+ /*< public >*/
68
+ MemoryRegion iomem;
69
+ qemu_irq irq;
70
+ SSECounter *counter;
71
+ QEMUTimer timer;
72
+ Notifier counter_notifier;
73
+
74
+ uint32_t cntfrq;
75
+ uint32_t cntp_ctl;
76
+ uint64_t cntp_cval;
77
+ uint64_t cntp_aival;
78
+ uint32_t cntp_aival_ctl;
79
+ uint32_t cntp_aival_reload;
80
+};
81
+
82
+#endif
83
diff --git a/hw/timer/sse-timer.c b/hw/timer/sse-timer.c
84
new file mode 100644
85
index XXXXXXX..XXXXXXX
86
--- /dev/null
87
+++ b/hw/timer/sse-timer.c
88
@@ -XXX,XX +XXX,XX @@
89
+/*
90
+ * Arm SSE Subsystem System Timer
91
+ *
92
+ * Copyright (c) 2020 Linaro Limited
93
+ * Written by Peter Maydell
94
+ *
95
+ * This program is free software; you can redistribute it and/or modify
96
+ * it under the terms of the GNU General Public License version 2 or
97
+ * (at your option) any later version.
98
+ */
99
+
100
+/*
101
+ * This is a model of the "System timer" which is documented in
102
+ * the Arm SSE-123 Example Subsystem Technical Reference Manual:
103
+ * https://developer.arm.com/documentation/101370/latest/
104
+ *
105
+ * The timer is based around a simple 64-bit incrementing counter
106
+ * (readable from CNTPCT_HI/LO). The timer fires when
107
+ * Counter - CompareValue >= 0.
108
+ * The CompareValue is guest-writable, via CNTP_CVAL_HI/LO.
109
+ * CNTP_TVAL is an alternative view of the CompareValue defined by
110
+ * TimerValue = CompareValue[31:0] - Counter[31:0]
111
+ * which can be both read and written.
112
+ * This part is similar to the generic timer in an Arm A-class CPU.
113
+ *
114
+ * The timer also has a separate auto-increment timer. When this
115
+ * timer is enabled, then the AutoIncrValue is set to:
116
+ * AutoIncrValue = Reload + Counter
117
+ * and this timer fires when
118
+ * Counter - AutoIncrValue >= 0
119
+ * at which point, an interrupt is generated and the new AutoIncrValue
120
+ * is calculated.
121
+ * When the auto-increment timer is enabled, interrupt generation
122
+ * via the compare/timervalue registers is disabled.
123
+ */
124
+#include "qemu/osdep.h"
125
+#include "qemu/log.h"
126
+#include "qemu/timer.h"
127
+#include "qapi/error.h"
128
+#include "trace.h"
129
+#include "hw/timer/sse-timer.h"
130
+#include "hw/timer/sse-counter.h"
131
+#include "hw/sysbus.h"
132
+#include "hw/irq.h"
133
+#include "hw/registerfields.h"
134
+#include "hw/clock.h"
135
+#include "hw/qdev-clock.h"
136
+#include "hw/qdev-properties.h"
137
+#include "migration/vmstate.h"
138
+
139
+REG32(CNTPCT_LO, 0x0)
140
+REG32(CNTPCT_HI, 0x4)
141
+REG32(CNTFRQ, 0x10)
142
+REG32(CNTP_CVAL_LO, 0x20)
143
+REG32(CNTP_CVAL_HI, 0x24)
144
+REG32(CNTP_TVAL, 0x28)
145
+REG32(CNTP_CTL, 0x2c)
146
+ FIELD(CNTP_CTL, ENABLE, 0, 1)
147
+ FIELD(CNTP_CTL, IMASK, 1, 1)
148
+ FIELD(CNTP_CTL, ISTATUS, 2, 1)
149
+REG32(CNTP_AIVAL_LO, 0x40)
150
+REG32(CNTP_AIVAL_HI, 0x44)
151
+REG32(CNTP_AIVAL_RELOAD, 0x48)
152
+REG32(CNTP_AIVAL_CTL, 0x4c)
153
+ FIELD(CNTP_AIVAL_CTL, EN, 0, 1)
154
+ FIELD(CNTP_AIVAL_CTL, CLR, 1, 1)
155
+REG32(CNTP_CFG, 0x50)
156
+ FIELD(CNTP_CFG, AIVAL, 0, 4)
157
+#define R_CNTP_CFG_AIVAL_IMPLEMENTED 1
158
+REG32(PID4, 0xFD0)
159
+REG32(PID5, 0xFD4)
160
+REG32(PID6, 0xFD8)
161
+REG32(PID7, 0xFDC)
162
+REG32(PID0, 0xFE0)
163
+REG32(PID1, 0xFE4)
164
+REG32(PID2, 0xFE8)
165
+REG32(PID3, 0xFEC)
166
+REG32(CID0, 0xFF0)
167
+REG32(CID1, 0xFF4)
168
+REG32(CID2, 0xFF8)
169
+REG32(CID3, 0xFFC)
170
+
171
+/* PID/CID values */
172
+static const int timer_id[] = {
173
+ 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
174
+ 0xb7, 0xb0, 0x0b, 0x00, /* PID0..PID3 */
175
+ 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
176
+};
177
+
178
+static bool sse_is_autoinc(SSETimer *s)
179
+{
180
+ return (s->cntp_aival_ctl & R_CNTP_AIVAL_CTL_EN_MASK) != 0;
181
+}
182
+
183
+static bool sse_enabled(SSETimer *s)
184
+{
185
+ return (s->cntp_ctl & R_CNTP_CTL_ENABLE_MASK) != 0;
186
+}
187
+
188
+static uint64_t sse_cntpct(SSETimer *s)
189
+{
190
+ /* Return the CNTPCT value for the current time */
191
+ return sse_counter_for_timestamp(s->counter,
192
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
193
+}
194
+
195
+static bool sse_timer_status(SSETimer *s)
196
+{
197
+ /*
198
+ * Return true if timer condition is met. This is used for both
199
+ * the CNTP_CTL.ISTATUS bit and for whether (unless masked) we
200
+ * assert our IRQ.
201
+ * The documentation is unclear about the behaviour of ISTATUS when
202
+ * in autoincrement mode; we assume that it follows CNTP_AIVAL_CTL.CLR
203
+ * (ie whether the autoincrement timer is asserting the interrupt).
204
+ */
205
+ if (!sse_enabled(s)) {
206
+ return false;
207
+ }
208
+
209
+ if (sse_is_autoinc(s)) {
210
+ return s->cntp_aival_ctl & R_CNTP_AIVAL_CTL_CLR_MASK;
211
+ } else {
212
+ return sse_cntpct(s) >= s->cntp_cval;
213
+ }
214
+}
215
+
216
+static void sse_update_irq(SSETimer *s)
217
+{
218
+ bool irqstate = (!(s->cntp_ctl & R_CNTP_CTL_IMASK_MASK) &&
219
+ sse_timer_status(s));
220
+
221
+ qemu_set_irq(s->irq, irqstate);
222
+}
223
+
224
+static void sse_set_timer(SSETimer *s, uint64_t nexttick)
225
+{
226
+ /* Set the timer to expire at nexttick */
227
+ uint64_t expiry = sse_counter_tick_to_time(s->counter, nexttick);
228
+
229
+ if (expiry <= INT64_MAX) {
230
+ timer_mod_ns(&s->timer, expiry);
231
+ } else {
232
+ /*
233
+ * nexttick is so far in the future that it would overflow the
234
+ * signed 64-bit range of a QEMUTimer. Since timer_mod_ns()
235
+ * expiry times are absolute, not relative, we are never going
236
+ * to be able to set the timer to this value, so we must just
237
+ * assume that guest execution can never run so long that it
238
+ * reaches the theoretical point when the timer fires.
239
+ * This is also the code path for "counter is not running",
240
+ * which is signalled by expiry == UINT64_MAX.
241
+ */
242
+ timer_del(&s->timer);
243
+ }
244
+}
245
+
246
+static void sse_recalc_timer(SSETimer *s)
247
+{
248
+ /* Recalculate the normal timer */
249
+ uint64_t count, nexttick;
250
+
251
+ if (sse_is_autoinc(s)) {
252
+ return;
253
+ }
254
+
255
+ if (!sse_enabled(s)) {
256
+ timer_del(&s->timer);
257
+ return;
258
+ }
259
+
260
+ count = sse_cntpct(s);
261
+
262
+ if (count >= s->cntp_cval) {
263
+ /*
264
+ * Timer condition already met. In theory we have a transition when
265
+ * the count rolls back over to 0, but that is so far in the future
266
+ * that it is not representable as a timer_mod() expiry, so in
267
+ * fact sse_set_timer() will always just delete the timer.
268
+ */
269
+ nexttick = UINT64_MAX;
270
+ } else {
271
+ /* Next transition is when count hits cval */
272
+ nexttick = s->cntp_cval;
273
+ }
274
+ sse_set_timer(s, nexttick);
275
+ sse_update_irq(s);
276
+}
277
+
278
+static void sse_autoinc(SSETimer *s)
279
+{
280
+ /* Auto-increment the AIVAL, and set the timer accordingly */
281
+ s->cntp_aival = sse_cntpct(s) + s->cntp_aival_reload;
282
+ sse_set_timer(s, s->cntp_aival);
283
+}
284
+
285
+static void sse_timer_cb(void *opaque)
286
+{
287
+ SSETimer *s = SSE_TIMER(opaque);
288
+
289
+ if (sse_is_autoinc(s)) {
290
+ uint64_t count = sse_cntpct(s);
291
+
292
+ if (count >= s->cntp_aival) {
293
+ /* Timer condition met, set CLR and do another autoinc */
294
+ s->cntp_aival_ctl |= R_CNTP_AIVAL_CTL_CLR_MASK;
295
+ s->cntp_aival = count + s->cntp_aival_reload;
296
+ }
297
+ sse_set_timer(s, s->cntp_aival);
298
+ sse_update_irq(s);
299
+ } else {
300
+ sse_recalc_timer(s);
301
+ }
302
+}
303
+
304
+static uint64_t sse_timer_read(void *opaque, hwaddr offset, unsigned size)
305
+{
306
+ SSETimer *s = SSE_TIMER(opaque);
307
+ uint64_t r;
308
+
309
+ switch (offset) {
310
+ case A_CNTPCT_LO:
311
+ r = extract64(sse_cntpct(s), 0, 32);
312
+ break;
313
+ case A_CNTPCT_HI:
314
+ r = extract64(sse_cntpct(s), 32, 32);
315
+ break;
316
+ case A_CNTFRQ:
317
+ r = s->cntfrq;
318
+ break;
319
+ case A_CNTP_CVAL_LO:
320
+ r = extract64(s->cntp_cval, 0, 32);
321
+ break;
322
+ case A_CNTP_CVAL_HI:
323
+ r = extract64(s->cntp_cval, 32, 32);
324
+ break;
325
+ case A_CNTP_TVAL:
326
+ r = extract64(s->cntp_cval - sse_cntpct(s), 0, 32);
327
+ break;
328
+ case A_CNTP_CTL:
329
+ r = s->cntp_ctl;
330
+ if (sse_timer_status(s)) {
331
+ r |= R_CNTP_CTL_ISTATUS_MASK;
332
+ }
333
+ break;
334
+ case A_CNTP_AIVAL_LO:
335
+ r = extract64(s->cntp_aival, 0, 32);
336
+ break;
337
+ case A_CNTP_AIVAL_HI:
338
+ r = extract64(s->cntp_aival, 32, 32);
339
+ break;
340
+ case A_CNTP_AIVAL_RELOAD:
341
+ r = s->cntp_aival_reload;
342
+ break;
343
+ case A_CNTP_AIVAL_CTL:
344
+ /*
345
+ * All the bits of AIVAL_CTL are documented as WO, but this is probably
346
+ * a documentation error. We implement them as readable.
347
+ */
348
+ r = s->cntp_aival_ctl;
349
+ break;
350
+ case A_CNTP_CFG:
351
+ r = R_CNTP_CFG_AIVAL_IMPLEMENTED << R_CNTP_CFG_AIVAL_SHIFT;
352
+ break;
353
+ case A_PID4 ... A_CID3:
354
+ r = timer_id[(offset - A_PID4) / 4];
355
+ break;
356
+ default:
357
+ qemu_log_mask(LOG_GUEST_ERROR,
358
+ "SSE System Timer read: bad offset 0x%x",
359
+ (unsigned) offset);
360
+ r = 0;
361
+ break;
362
+ }
363
+
364
+ trace_sse_timer_read(offset, r, size);
365
+ return r;
366
+}
367
+
368
+static void sse_timer_write(void *opaque, hwaddr offset, uint64_t value,
369
+ unsigned size)
370
+{
371
+ SSETimer *s = SSE_TIMER(opaque);
372
+
373
+ trace_sse_timer_write(offset, value, size);
374
+
375
+ switch (offset) {
376
+ case A_CNTFRQ:
377
+ s->cntfrq = value;
378
+ break;
379
+ case A_CNTP_CVAL_LO:
380
+ s->cntp_cval = deposit64(s->cntp_cval, 0, 32, value);
381
+ sse_recalc_timer(s);
382
+ break;
383
+ case A_CNTP_CVAL_HI:
384
+ s->cntp_cval = deposit64(s->cntp_cval, 32, 32, value);
385
+ sse_recalc_timer(s);
386
+ break;
387
+ case A_CNTP_TVAL:
388
+ s->cntp_cval = sse_cntpct(s) + sextract64(value, 0, 32);
389
+ sse_recalc_timer(s);
390
+ break;
391
+ case A_CNTP_CTL:
392
+ {
393
+ uint32_t old_ctl = s->cntp_ctl;
394
+ value &= R_CNTP_CTL_ENABLE_MASK | R_CNTP_CTL_IMASK_MASK;
395
+ s->cntp_ctl = value;
396
+ if ((old_ctl ^ s->cntp_ctl) & R_CNTP_CTL_ENABLE_MASK) {
397
+ if (sse_enabled(s)) {
398
+ if (sse_is_autoinc(s)) {
399
+ sse_autoinc(s);
400
+ } else {
401
+ sse_recalc_timer(s);
402
+ }
403
+ }
404
+ }
405
+ sse_update_irq(s);
406
+ break;
407
+ }
408
+ case A_CNTP_AIVAL_RELOAD:
409
+ s->cntp_aival_reload = value;
410
+ break;
411
+ case A_CNTP_AIVAL_CTL:
412
+ {
413
+ uint32_t old_ctl = s->cntp_aival_ctl;
414
+
415
+ /* EN bit is writeable; CLR bit is write-0-to-clear, write-1-ignored */
416
+ s->cntp_aival_ctl &= ~R_CNTP_AIVAL_CTL_EN_MASK;
417
+ s->cntp_aival_ctl |= value & R_CNTP_AIVAL_CTL_EN_MASK;
418
+ if (!(value & R_CNTP_AIVAL_CTL_CLR_MASK)) {
419
+ s->cntp_aival_ctl &= ~R_CNTP_AIVAL_CTL_CLR_MASK;
420
+ }
421
+ if ((old_ctl ^ s->cntp_aival_ctl) & R_CNTP_AIVAL_CTL_EN_MASK) {
422
+ /* Auto-increment toggled on/off */
423
+ if (sse_enabled(s)) {
424
+ if (sse_is_autoinc(s)) {
425
+ sse_autoinc(s);
426
+ } else {
427
+ sse_recalc_timer(s);
428
+ }
429
+ }
430
+ }
431
+ sse_update_irq(s);
432
+ break;
433
+ }
434
+ case A_CNTPCT_LO:
435
+ case A_CNTPCT_HI:
436
+ case A_CNTP_CFG:
437
+ case A_CNTP_AIVAL_LO:
438
+ case A_CNTP_AIVAL_HI:
439
+ case A_PID4 ... A_CID3:
440
+ qemu_log_mask(LOG_GUEST_ERROR,
441
+ "SSE System Timer write: write to RO offset 0x%x\n",
442
+ (unsigned)offset);
443
+ break;
444
+ default:
445
+ qemu_log_mask(LOG_GUEST_ERROR,
446
+ "SSE System Timer write: bad offset 0x%x\n",
447
+ (unsigned)offset);
448
+ break;
449
+ }
450
+}
451
+
452
+static const MemoryRegionOps sse_timer_ops = {
453
+ .read = sse_timer_read,
454
+ .write = sse_timer_write,
455
+ .endianness = DEVICE_LITTLE_ENDIAN,
456
+ .valid.min_access_size = 4,
457
+ .valid.max_access_size = 4,
458
+};
459
+
460
+static void sse_timer_reset(DeviceState *dev)
461
+{
462
+ SSETimer *s = SSE_TIMER(dev);
463
+
464
+ trace_sse_timer_reset();
465
+
466
+ timer_del(&s->timer);
467
+ s->cntfrq = 0;
468
+ s->cntp_ctl = 0;
469
+ s->cntp_cval = 0;
470
+ s->cntp_aival = 0;
471
+ s->cntp_aival_ctl = 0;
472
+ s->cntp_aival_reload = 0;
473
+}
474
+
475
+static void sse_timer_counter_callback(Notifier *notifier, void *data)
476
+{
477
+ SSETimer *s = container_of(notifier, SSETimer, counter_notifier);
478
+
479
+ /* System counter told us we need to recalculate */
480
+ if (sse_enabled(s)) {
481
+ if (sse_is_autoinc(s)) {
482
+ sse_set_timer(s, s->cntp_aival);
483
+ } else {
484
+ sse_recalc_timer(s);
485
+ }
486
+ }
487
+}
488
+
489
+static void sse_timer_init(Object *obj)
490
+{
491
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
492
+ SSETimer *s = SSE_TIMER(obj);
493
+
494
+ memory_region_init_io(&s->iomem, obj, &sse_timer_ops,
495
+ s, "sse-timer", 0x1000);
496
+ sysbus_init_mmio(sbd, &s->iomem);
497
+ sysbus_init_irq(sbd, &s->irq);
498
+}
499
+
500
+static void sse_timer_realize(DeviceState *dev, Error **errp)
501
+{
502
+ SSETimer *s = SSE_TIMER(dev);
503
+
504
+ if (!s->counter) {
505
+ error_setg(errp, "counter property was not set");
506
+ }
507
+
508
+ s->counter_notifier.notify = sse_timer_counter_callback;
509
+ sse_counter_register_consumer(s->counter, &s->counter_notifier);
510
+
511
+ timer_init_ns(&s->timer, QEMU_CLOCK_VIRTUAL, sse_timer_cb, s);
512
+}
513
+
514
+static const VMStateDescription sse_timer_vmstate = {
515
+ .name = "sse-timer",
516
+ .version_id = 1,
517
+ .minimum_version_id = 1,
518
+ .fields = (VMStateField[]) {
519
+ VMSTATE_TIMER(timer, SSETimer),
520
+ VMSTATE_UINT32(cntfrq, SSETimer),
521
+ VMSTATE_UINT32(cntp_ctl, SSETimer),
522
+ VMSTATE_UINT64(cntp_cval, SSETimer),
523
+ VMSTATE_UINT64(cntp_aival, SSETimer),
524
+ VMSTATE_UINT32(cntp_aival_ctl, SSETimer),
525
+ VMSTATE_UINT32(cntp_aival_reload, SSETimer),
526
+ VMSTATE_END_OF_LIST()
527
+ }
528
+};
529
+
530
+static Property sse_timer_properties[] = {
531
+ DEFINE_PROP_LINK("counter", SSETimer, counter, TYPE_SSE_COUNTER, SSECounter *),
532
+ DEFINE_PROP_END_OF_LIST(),
533
+};
534
+
535
+static void sse_timer_class_init(ObjectClass *klass, void *data)
536
+{
537
+ DeviceClass *dc = DEVICE_CLASS(klass);
538
+
539
+ dc->realize = sse_timer_realize;
540
+ dc->vmsd = &sse_timer_vmstate;
541
+ dc->reset = sse_timer_reset;
542
+ device_class_set_props(dc, sse_timer_properties);
543
+}
544
+
545
+static const TypeInfo sse_timer_info = {
546
+ .name = TYPE_SSE_TIMER,
547
+ .parent = TYPE_SYS_BUS_DEVICE,
548
+ .instance_size = sizeof(SSETimer),
549
+ .instance_init = sse_timer_init,
550
+ .class_init = sse_timer_class_init,
551
+};
552
+
553
+static void sse_timer_register_types(void)
554
+{
555
+ type_register_static(&sse_timer_info);
556
+}
557
+
558
+type_init(sse_timer_register_types);
559
diff --git a/MAINTAINERS b/MAINTAINERS
560
index XXXXXXX..XXXXXXX 100644
561
--- a/MAINTAINERS
562
+++ b/MAINTAINERS
563
@@ -XXX,XX +XXX,XX @@ F: hw/misc/armsse-mhu.c
564
F: include/hw/misc/armsse-mhu.h
565
F: hw/timer/sse-counter.c
566
F: include/hw/timer/sse-counter.h
567
+F: hw/timer/sse-timer.c
568
+F: include/hw/timer/sse-timer.h
569
F: docs/system/arm/mps2.rst
570
571
Musca
572
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
573
index XXXXXXX..XXXXXXX 100644
574
--- a/hw/arm/Kconfig
575
+++ b/hw/arm/Kconfig
576
@@ -XXX,XX +XXX,XX @@ config ARMSSE
577
select TZ_PPC
578
select UNIMP
579
select SSE_COUNTER
580
+ select SSE_TIMER
581
582
config ARMSSE_CPUID
583
bool
584
diff --git a/hw/timer/Kconfig b/hw/timer/Kconfig
585
index XXXXXXX..XXXXXXX 100644
586
--- a/hw/timer/Kconfig
587
+++ b/hw/timer/Kconfig
588
@@ -XXX,XX +XXX,XX @@ config RENESAS_CMT
589
config SSE_COUNTER
590
bool
591
592
+config SSE_TIMER
593
+ bool
594
+
595
config AVR_TIMER16
596
bool
597
diff --git a/hw/timer/meson.build b/hw/timer/meson.build
598
index XXXXXXX..XXXXXXX 100644
599
--- a/hw/timer/meson.build
600
+++ b/hw/timer/meson.build
601
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_systmr.c'))
602
softmmu_ss.add(when: 'CONFIG_SH4', if_true: files('sh_timer.c'))
603
softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_timer.c'))
604
softmmu_ss.add(when: 'CONFIG_SSE_COUNTER', if_true: files('sse-counter.c'))
605
+softmmu_ss.add(when: 'CONFIG_SSE_TIMER', if_true: files('sse-timer.c'))
606
softmmu_ss.add(when: 'CONFIG_STM32F2XX_TIMER', if_true: files('stm32f2xx_timer.c'))
607
softmmu_ss.add(when: 'CONFIG_XILINX', if_true: files('xilinx_timer.c'))
608
609
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
610
index XXXXXXX..XXXXXXX 100644
611
--- a/hw/timer/trace-events
612
+++ b/hw/timer/trace-events
613
@@ -XXX,XX +XXX,XX @@ sse_counter_control_write(uint64_t offset, uint64_t data, unsigned size) "SSE sy
614
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"
615
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"
616
sse_counter_reset(void) "SSE system counter: reset"
617
+
618
+# sse_timer.c
619
+sse_timer_read(uint64_t offset, uint64_t data, unsigned size) "SSE system timer read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
620
+sse_timer_write(uint64_t offset, uint64_t data, unsigned size) "SSE system timer write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
621
+sse_timer_reset(void) "SSE system timer: reset"
622
--
623
2.20.1
624
625
diff view generated by jsdifflib
New patch
1
The SSE-300's iokit-sysctl device is similar to the SSE-200, but
2
some registers have moved address or have different behaviours.
3
In this commit we add case statements for the registers where
4
the SSE-300 and SSE-200 have the same behaviour. Some registers
5
are the same on all SSE versions and so need no code change at all.
6
Putting both of these categories together covers:
1
7
8
0x0 SECDBGSTAT
9
0x4 SECDBGSET
10
0x8 SECDBGCLR
11
0xc SCSECCTRL
12
0x10 CLK_CFG0 -- this is like SSE-200 FCLK_DIV but with a
13
different set of clocks being controlled; our implementation
14
is a dummy reads-as-written anyway
15
0x14 CLK_CFG1 -- similar to SSE-200 SYSCLK_DIV; our implementation
16
is a dummy
17
0x18 CLK_FORCE -- similar to SSE-200 but different bit allocations;
18
we have a dummy implementation
19
0x100 RESET_SYNDROME -- bit allocation differs from SSE-200 but our
20
implementation is a dummy
21
0x104 RESET_MASK -- bit allocation differs from SSE-200 but our
22
implementation is a dummy
23
0x108 SWRESET
24
0x10c GRETREG
25
0x200 PDCM_PD_SYS_SENSE -- some bit allocations differ, but our
26
implementation is a dummy
27
28
We also need to migrate the state of these registers which are shared
29
between the SSE-200 and SSE-300, so update the vmstate 'needed'
30
function to do this.
31
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
34
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
35
Message-id: 20210219144617.4782-14-peter.maydell@linaro.org
36
---
37
hw/misc/iotkit-sysctl.c | 12 +++++++++++-
38
1 file changed, 11 insertions(+), 1 deletion(-)
39
40
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/misc/iotkit-sysctl.c
43
+++ b/hw/misc/iotkit-sysctl.c
44
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
45
case ARMSSE_IOTKIT:
46
goto bad_offset;
47
case ARMSSE_SSE200:
48
+ case ARMSSE_SSE300:
49
r = s->scsecctrl;
50
break;
51
default:
52
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
53
case ARMSSE_IOTKIT:
54
goto bad_offset;
55
case ARMSSE_SSE200:
56
+ case ARMSSE_SSE300:
57
r = s->fclk_div;
58
break;
59
default:
60
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
61
case ARMSSE_IOTKIT:
62
goto bad_offset;
63
case ARMSSE_SSE200:
64
+ case ARMSSE_SSE300:
65
r = s->sysclk_div;
66
break;
67
default:
68
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
69
case ARMSSE_IOTKIT:
70
goto bad_offset;
71
case ARMSSE_SSE200:
72
+ case ARMSSE_SSE300:
73
r = s->clock_force;
74
break;
75
default:
76
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
77
case ARMSSE_IOTKIT:
78
goto bad_offset;
79
case ARMSSE_SSE200:
80
+ case ARMSSE_SSE300:
81
r = s->pdcm_pd_sys_sense;
82
break;
83
default:
84
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
85
case ARMSSE_IOTKIT:
86
goto bad_offset;
87
case ARMSSE_SSE200:
88
+ case ARMSSE_SSE300:
89
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SCSECCTRL unimplemented\n");
90
s->scsecctrl = value;
91
break;
92
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
93
case ARMSSE_IOTKIT:
94
goto bad_offset;
95
case ARMSSE_SSE200:
96
+ case ARMSSE_SSE300:
97
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl FCLK_DIV unimplemented\n");
98
s->fclk_div = value;
99
break;
100
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
101
case ARMSSE_IOTKIT:
102
goto bad_offset;
103
case ARMSSE_SSE200:
104
+ case ARMSSE_SSE300:
105
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SYSCLK_DIV unimplemented\n");
106
s->sysclk_div = value;
107
break;
108
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
109
case ARMSSE_IOTKIT:
110
goto bad_offset;
111
case ARMSSE_SSE200:
112
+ case ARMSSE_SSE300:
113
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CLOCK_FORCE unimplemented\n");
114
s->clock_force = value;
115
break;
116
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
117
case ARMSSE_IOTKIT:
118
goto bad_offset;
119
case ARMSSE_SSE200:
120
+ case ARMSSE_SSE300:
121
qemu_log_mask(LOG_UNIMP,
122
"IoTKit SysCtl PDCM_PD_SYS_SENSE unimplemented\n");
123
s->pdcm_pd_sys_sense = value;
124
@@ -XXX,XX +XXX,XX @@ static bool sse200_needed(void *opaque)
125
{
126
IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
127
128
- return s->sse_version == ARMSSE_SSE200;
129
+ return s->sse_version != ARMSSE_IOTKIT;
130
}
131
132
static const VMStateDescription iotkit_sysctl_sse200_vmstate = {
133
--
134
2.20.1
135
136
diff view generated by jsdifflib
New patch
1
In the SSE-300 the CPU_WAIT and NMI_ENABLE registers have
2
moved offsets, so they are now where the SSE-200's WICCTRL
3
and EWCTRL were. The SSE-300 does not have WICCTLR or EWCTRL
4
at all, and the old offsets are reserved:
1
5
6
Offset SSE-200 SSE-300
7
-----------------------------------
8
0x118 CPUWAIT reserved
9
0x118 NMI_ENABLE reserved
10
0x120 WICCTRL CPUWAIT
11
0x124 EWCTRL NMI_ENABLE
12
13
Handle this reshuffle, and the fact that SSE-300 has only
14
one CPU and so only one active bit in CPUWAIT.
15
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20210219144617.4782-15-peter.maydell@linaro.org
20
---
21
hw/misc/iotkit-sysctl.c | 88 +++++++++++++++++++++++++++++++++++------
22
1 file changed, 76 insertions(+), 12 deletions(-)
23
24
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/misc/iotkit-sysctl.c
27
+++ b/hw/misc/iotkit-sysctl.c
28
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
29
}
30
break;
31
case A_CPUWAIT:
32
- r = s->cpuwait;
33
+ switch (s->sse_version) {
34
+ case ARMSSE_IOTKIT:
35
+ case ARMSSE_SSE200:
36
+ r = s->cpuwait;
37
+ break;
38
+ case ARMSSE_SSE300:
39
+ /* In SSE300 this is reserved (for INITSVTOR2) */
40
+ goto bad_offset;
41
+ default:
42
+ g_assert_not_reached();
43
+ }
44
break;
45
case A_NMI_ENABLE:
46
switch (s->sse_version) {
47
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
48
case ARMSSE_SSE200:
49
r = s->nmi_enable;
50
break;
51
+ case ARMSSE_SSE300:
52
+ /* In SSE300 this is reserved (for INITSVTOR3) */
53
+ goto bad_offset;
54
default:
55
g_assert_not_reached();
56
}
57
break;
58
case A_WICCTRL:
59
- r = s->wicctrl;
60
+ switch (s->sse_version) {
61
+ case ARMSSE_IOTKIT:
62
+ case ARMSSE_SSE200:
63
+ r = s->wicctrl;
64
+ break;
65
+ case ARMSSE_SSE300:
66
+ /* In SSE300 this offset is CPUWAIT */
67
+ r = s->cpuwait;
68
+ break;
69
+ default:
70
+ g_assert_not_reached();
71
+ }
72
break;
73
case A_EWCTRL:
74
switch (s->sse_version) {
75
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
76
case ARMSSE_SSE200:
77
r = s->ewctrl;
78
break;
79
+ case ARMSSE_SSE300:
80
+ /* In SSE300 this offset is is NMI_ENABLE */
81
+ r = s->nmi_enable;
82
+ break;
83
default:
84
g_assert_not_reached();
85
}
86
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
87
return r;
88
}
89
90
+static void cpuwait_write(IoTKitSysCtl *s, uint32_t value)
91
+{
92
+ int num_cpus = (s->sse_version == ARMSSE_SSE300) ? 1 : 2;
93
+ int i;
94
+
95
+ for (i = 0; i < num_cpus; i++) {
96
+ uint32_t mask = 1 << i;
97
+ if ((s->cpuwait & mask) && !(value & mask)) {
98
+ /* Powering up CPU 0 */
99
+ arm_set_cpu_on_and_reset(i);
100
+ }
101
+ }
102
+ s->cpuwait = value;
103
+}
104
+
105
static void iotkit_sysctl_write(void *opaque, hwaddr offset,
106
uint64_t value, unsigned size)
107
{
108
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
109
set_init_vtor(0, s->initsvtor0);
110
break;
111
case A_CPUWAIT:
112
- if ((s->cpuwait & 1) && !(value & 1)) {
113
- /* Powering up CPU 0 */
114
- arm_set_cpu_on_and_reset(0);
115
+ switch (s->sse_version) {
116
+ case ARMSSE_IOTKIT:
117
+ case ARMSSE_SSE200:
118
+ cpuwait_write(s, value);
119
+ break;
120
+ case ARMSSE_SSE300:
121
+ /* In SSE300 this is reserved (for INITSVTOR2) */
122
+ goto bad_offset;
123
+ default:
124
+ g_assert_not_reached();
125
}
126
- if ((s->cpuwait & 2) && !(value & 2)) {
127
- /* Powering up CPU 1 */
128
- arm_set_cpu_on_and_reset(1);
129
- }
130
- s->cpuwait = value;
131
break;
132
case A_WICCTRL:
133
- qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl WICCTRL unimplemented\n");
134
- s->wicctrl = value;
135
+ switch (s->sse_version) {
136
+ case ARMSSE_IOTKIT:
137
+ case ARMSSE_SSE200:
138
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl WICCTRL unimplemented\n");
139
+ s->wicctrl = value;
140
+ break;
141
+ case ARMSSE_SSE300:
142
+ /* In SSE300 this offset is CPUWAIT */
143
+ cpuwait_write(s, value);
144
+ break;
145
+ default:
146
+ g_assert_not_reached();
147
+ }
148
break;
149
case A_SECDBGSET:
150
/* write-1-to-set */
151
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
152
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl EWCTRL unimplemented\n");
153
s->ewctrl = value;
154
break;
155
+ case ARMSSE_SSE300:
156
+ /* In SSE300 this offset is is NMI_ENABLE */
157
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
158
+ s->nmi_enable = value;
159
+ break;
160
default:
161
g_assert_not_reached();
162
}
163
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
164
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
165
s->nmi_enable = value;
166
break;
167
+ case ARMSSE_SSE300:
168
+ /* In SSE300 this is reserved (for INITSVTOR3) */
169
+ goto bad_offset;
170
default:
171
g_assert_not_reached();
172
}
173
--
174
2.20.1
175
176
diff view generated by jsdifflib
New patch
1
The SSE-300 has only one CPU and so no INITSVTOR1. It does
2
have INITSVTOR0, but unlike the SSE-200 this register now
3
has a LOCK bit which can be set to 1 to prevent any further
4
writes to the register. Implement these differences.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210219144617.4782-16-peter.maydell@linaro.org
10
---
11
hw/misc/iotkit-sysctl.c | 27 +++++++++++++++++++++++++--
12
1 file changed, 25 insertions(+), 2 deletions(-)
13
14
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/misc/iotkit-sysctl.c
17
+++ b/hw/misc/iotkit-sysctl.c
18
@@ -XXX,XX +XXX,XX @@ REG32(SWRESET, 0x108)
19
FIELD(SWRESET, SWRESETREQ, 9, 1)
20
REG32(GRETREG, 0x10c)
21
REG32(INITSVTOR0, 0x110)
22
+ FIELD(INITSVTOR0, LOCK, 0, 1)
23
+ FIELD(INITSVTOR0, VTOR, 7, 25)
24
REG32(INITSVTOR1, 0x114)
25
REG32(CPUWAIT, 0x118)
26
REG32(NMI_ENABLE, 0x11c) /* BUSWAIT in IoTKit */
27
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
28
case ARMSSE_SSE200:
29
r = s->initsvtor1;
30
break;
31
+ case ARMSSE_SSE300:
32
+ goto bad_offset;
33
default:
34
g_assert_not_reached();
35
}
36
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
37
s->gretreg = value;
38
break;
39
case A_INITSVTOR0:
40
- s->initsvtor0 = value;
41
- set_init_vtor(0, s->initsvtor0);
42
+ switch (s->sse_version) {
43
+ case ARMSSE_SSE300:
44
+ /* SSE300 has a LOCK bit which prevents further writes when set */
45
+ if (s->initsvtor0 & R_INITSVTOR0_LOCK_MASK) {
46
+ qemu_log_mask(LOG_GUEST_ERROR,
47
+ "IoTKit INITSVTOR0 write when register locked\n");
48
+ break;
49
+ }
50
+ s->initsvtor0 = value;
51
+ set_init_vtor(0, s->initsvtor0 & R_INITSVTOR0_VTOR_MASK);
52
+ break;
53
+ case ARMSSE_IOTKIT:
54
+ case ARMSSE_SSE200:
55
+ s->initsvtor0 = value;
56
+ set_init_vtor(0, s->initsvtor0);
57
+ break;
58
+ default:
59
+ g_assert_not_reached();
60
+ }
61
break;
62
case A_CPUWAIT:
63
switch (s->sse_version) {
64
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
65
s->initsvtor1 = value;
66
set_init_vtor(1, s->initsvtor1);
67
break;
68
+ case ARMSSE_SSE300:
69
+ goto bad_offset;
70
default:
71
g_assert_not_reached();
72
}
73
--
74
2.20.1
75
76
diff view generated by jsdifflib
New patch
1
The SSE-300 has a new PWRCTRL register at offset 0x1fc (previously
2
reserved). This register controls accessibility of some registers
3
in the Power Policy Units (PPUs). Since QEMU doesn't implement
4
the PPUs, we don't need to implement any real behaviour for this
5
register, so we just handle the UNLOCK bit which controls whether
6
writes to the register itself are permitted and otherwise make it
7
be reads-as-written.
1
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210219144617.4782-17-peter.maydell@linaro.org
13
---
14
include/hw/misc/iotkit-sysctl.h | 1 +
15
hw/misc/iotkit-sysctl.c | 52 +++++++++++++++++++++++++++++++++
16
2 files changed, 53 insertions(+)
17
18
diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/misc/iotkit-sysctl.h
21
+++ b/include/hw/misc/iotkit-sysctl.h
22
@@ -XXX,XX +XXX,XX @@ struct IoTKitSysCtl {
23
uint32_t initsvtor1;
24
uint32_t nmi_enable;
25
uint32_t ewctrl;
26
+ uint32_t pwrctrl;
27
uint32_t pdcm_pd_sys_sense;
28
uint32_t pdcm_pd_sram0_sense;
29
uint32_t pdcm_pd_sram1_sense;
30
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/misc/iotkit-sysctl.c
33
+++ b/hw/misc/iotkit-sysctl.c
34
@@ -XXX,XX +XXX,XX @@ REG32(CPUWAIT, 0x118)
35
REG32(NMI_ENABLE, 0x11c) /* BUSWAIT in IoTKit */
36
REG32(WICCTRL, 0x120)
37
REG32(EWCTRL, 0x124)
38
+REG32(PWRCTRL, 0x1fc)
39
+ FIELD(PWRCTRL, PPU_ACCESS_UNLOCK, 0, 1)
40
+ FIELD(PWRCTRL, PPU_ACCESS_FILTER, 1, 1)
41
REG32(PDCM_PD_SYS_SENSE, 0x200)
42
REG32(PDCM_PD_SRAM0_SENSE, 0x20c)
43
REG32(PDCM_PD_SRAM1_SENSE, 0x210)
44
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
45
g_assert_not_reached();
46
}
47
break;
48
+ case A_PWRCTRL:
49
+ switch (s->sse_version) {
50
+ case ARMSSE_IOTKIT:
51
+ case ARMSSE_SSE200:
52
+ goto bad_offset;
53
+ case ARMSSE_SSE300:
54
+ r = s->pwrctrl;
55
+ break;
56
+ default:
57
+ g_assert_not_reached();
58
+ }
59
+ break;
60
case A_PDCM_PD_SYS_SENSE:
61
switch (s->sse_version) {
62
case ARMSSE_IOTKIT:
63
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
64
g_assert_not_reached();
65
}
66
break;
67
+ case A_PWRCTRL:
68
+ switch (s->sse_version) {
69
+ case ARMSSE_IOTKIT:
70
+ case ARMSSE_SSE200:
71
+ goto bad_offset;
72
+ case ARMSSE_SSE300:
73
+ if (!(s->pwrctrl & R_PWRCTRL_PPU_ACCESS_UNLOCK_MASK)) {
74
+ qemu_log_mask(LOG_GUEST_ERROR,
75
+ "IoTKit PWRCTRL write when register locked\n");
76
+ break;
77
+ }
78
+ s->pwrctrl = value;
79
+ break;
80
+ default:
81
+ g_assert_not_reached();
82
+ }
83
+ break;
84
case A_PDCM_PD_SYS_SENSE:
85
switch (s->sse_version) {
86
case ARMSSE_IOTKIT:
87
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_reset(DeviceState *dev)
88
s->clock_force = 0;
89
s->nmi_enable = 0;
90
s->ewctrl = 0;
91
+ s->pwrctrl = 0x3;
92
s->pdcm_pd_sys_sense = 0x7f;
93
s->pdcm_pd_sram0_sense = 0;
94
s->pdcm_pd_sram1_sense = 0;
95
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_realize(DeviceState *dev, Error **errp)
96
}
97
}
98
99
+static bool sse300_needed(void *opaque)
100
+{
101
+ IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
102
+
103
+ return s->sse_version == ARMSSE_SSE300;
104
+}
105
+
106
+static const VMStateDescription iotkit_sysctl_sse300_vmstate = {
107
+ .name = "iotkit-sysctl/sse-300",
108
+ .version_id = 1,
109
+ .minimum_version_id = 1,
110
+ .needed = sse300_needed,
111
+ .fields = (VMStateField[]) {
112
+ VMSTATE_UINT32(pwrctrl, IoTKitSysCtl),
113
+ VMSTATE_END_OF_LIST()
114
+ }
115
+};
116
+
117
static bool sse200_needed(void *opaque)
118
{
119
IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
120
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription iotkit_sysctl_vmstate = {
121
},
122
.subsections = (const VMStateDescription*[]) {
123
&iotkit_sysctl_sse200_vmstate,
124
+ &iotkit_sysctl_sse300_vmstate,
125
NULL
126
}
127
};
128
--
129
2.20.1
130
131
diff view generated by jsdifflib
New patch
1
1
The sysctl PDCM_PD_*_SENSE registers control various power domains in
2
the system and allow the guest to configure which conditions keep a
3
power domain awake and what power state to use when the domain is in
4
a low power state. QEMU doesn't model power domains, so for us these
5
registers are dummy reads-as-written implementations.
6
7
The SSE-300 has a different power domain setup, so the set of
8
registers is slightly different:
9
10
Offset SSE-200 SSE-300
11
---------------------------------------------------
12
0x200 PDCM_PD_SYS_SENSE PDCM_PD_SYS_SENSE
13
0x204 reserved PDCM_PD_CPU0_SENSE
14
0x208 reserved reserved
15
0x20c PDCM_PD_SRAM0_SENSE reserved
16
0x210 PDCM_PD_SRAM1_SENSE reserved
17
0x214 PDCM_PD_SRAM2_SENSE PDCM_PD_VMR0_SENSE
18
0x218 PDCM_PD_SRAM3_SENSE PDCM_PD_VMR1_SENSE
19
20
Offsets 0x200 and 0x208 are the same for both, so handled in a
21
previous commit; here we deal with 0x204, 0x20c, 0x210, 0x214, 0x218.
22
23
(We can safely add new lines to the SSE300 vmstate because no board
24
uses this device in an SSE300 yet.)
25
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
28
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Message-id: 20210219144617.4782-18-peter.maydell@linaro.org
30
---
31
include/hw/misc/iotkit-sysctl.h | 3 ++
32
hw/misc/iotkit-sysctl.c | 61 +++++++++++++++++++++++++++++++--
33
2 files changed, 62 insertions(+), 2 deletions(-)
34
35
diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/include/hw/misc/iotkit-sysctl.h
38
+++ b/include/hw/misc/iotkit-sysctl.h
39
@@ -XXX,XX +XXX,XX @@ struct IoTKitSysCtl {
40
uint32_t pdcm_pd_sram1_sense;
41
uint32_t pdcm_pd_sram2_sense;
42
uint32_t pdcm_pd_sram3_sense;
43
+ uint32_t pdcm_pd_cpu0_sense;
44
+ uint32_t pdcm_pd_vmr0_sense;
45
+ uint32_t pdcm_pd_vmr1_sense;
46
47
/* Properties */
48
uint32_t sse_version;
49
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/misc/iotkit-sysctl.c
52
+++ b/hw/misc/iotkit-sysctl.c
53
@@ -XXX,XX +XXX,XX @@ REG32(PWRCTRL, 0x1fc)
54
FIELD(PWRCTRL, PPU_ACCESS_UNLOCK, 0, 1)
55
FIELD(PWRCTRL, PPU_ACCESS_FILTER, 1, 1)
56
REG32(PDCM_PD_SYS_SENSE, 0x200)
57
+REG32(PDCM_PD_CPU0_SENSE, 0x204)
58
REG32(PDCM_PD_SRAM0_SENSE, 0x20c)
59
REG32(PDCM_PD_SRAM1_SENSE, 0x210)
60
-REG32(PDCM_PD_SRAM2_SENSE, 0x214)
61
-REG32(PDCM_PD_SRAM3_SENSE, 0x218)
62
+REG32(PDCM_PD_SRAM2_SENSE, 0x214) /* PDCM_PD_VMR0_SENSE on SSE300 */
63
+REG32(PDCM_PD_SRAM3_SENSE, 0x218) /* PDCM_PD_VMR1_SENSE on SSE300 */
64
REG32(PID4, 0xfd0)
65
REG32(PID5, 0xfd4)
66
REG32(PID6, 0xfd8)
67
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
68
g_assert_not_reached();
69
}
70
break;
71
+ case A_PDCM_PD_CPU0_SENSE:
72
+ switch (s->sse_version) {
73
+ case ARMSSE_IOTKIT:
74
+ case ARMSSE_SSE200:
75
+ goto bad_offset;
76
+ case ARMSSE_SSE300:
77
+ r = s->pdcm_pd_cpu0_sense;
78
+ break;
79
+ default:
80
+ g_assert_not_reached();
81
+ }
82
+ break;
83
case A_PDCM_PD_SRAM0_SENSE:
84
switch (s->sse_version) {
85
case ARMSSE_IOTKIT:
86
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
87
case ARMSSE_SSE200:
88
r = s->pdcm_pd_sram0_sense;
89
break;
90
+ case ARMSSE_SSE300:
91
+ goto bad_offset;
92
default:
93
g_assert_not_reached();
94
}
95
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
96
case ARMSSE_SSE200:
97
r = s->pdcm_pd_sram1_sense;
98
break;
99
+ case ARMSSE_SSE300:
100
+ goto bad_offset;
101
default:
102
g_assert_not_reached();
103
}
104
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
105
case ARMSSE_SSE200:
106
r = s->pdcm_pd_sram2_sense;
107
break;
108
+ case ARMSSE_SSE300:
109
+ r = s->pdcm_pd_vmr0_sense;
110
+ break;
111
default:
112
g_assert_not_reached();
113
}
114
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
115
case ARMSSE_SSE200:
116
r = s->pdcm_pd_sram3_sense;
117
break;
118
+ case ARMSSE_SSE300:
119
+ r = s->pdcm_pd_vmr1_sense;
120
+ break;
121
default:
122
g_assert_not_reached();
123
}
124
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
125
g_assert_not_reached();
126
}
127
break;
128
+ case A_PDCM_PD_CPU0_SENSE:
129
+ switch (s->sse_version) {
130
+ case ARMSSE_IOTKIT:
131
+ case ARMSSE_SSE200:
132
+ goto bad_offset;
133
+ case ARMSSE_SSE300:
134
+ qemu_log_mask(LOG_UNIMP,
135
+ "IoTKit SysCtl PDCM_PD_CPU0_SENSE unimplemented\n");
136
+ s->pdcm_pd_cpu0_sense = value;
137
+ break;
138
+ default:
139
+ g_assert_not_reached();
140
+ }
141
+ break;
142
case A_PDCM_PD_SRAM0_SENSE:
143
switch (s->sse_version) {
144
case ARMSSE_IOTKIT:
145
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
146
"IoTKit SysCtl PDCM_PD_SRAM0_SENSE unimplemented\n");
147
s->pdcm_pd_sram0_sense = value;
148
break;
149
+ case ARMSSE_SSE300:
150
+ goto bad_offset;
151
default:
152
g_assert_not_reached();
153
}
154
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
155
"IoTKit SysCtl PDCM_PD_SRAM1_SENSE unimplemented\n");
156
s->pdcm_pd_sram1_sense = value;
157
break;
158
+ case ARMSSE_SSE300:
159
+ goto bad_offset;
160
default:
161
g_assert_not_reached();
162
}
163
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
164
"IoTKit SysCtl PDCM_PD_SRAM2_SENSE unimplemented\n");
165
s->pdcm_pd_sram2_sense = value;
166
break;
167
+ case ARMSSE_SSE300:
168
+ qemu_log_mask(LOG_UNIMP,
169
+ "IoTKit SysCtl PDCM_PD_VMR0_SENSE unimplemented\n");
170
+ s->pdcm_pd_vmr0_sense = value;
171
+ break;
172
default:
173
g_assert_not_reached();
174
}
175
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
176
"IoTKit SysCtl PDCM_PD_SRAM3_SENSE unimplemented\n");
177
s->pdcm_pd_sram3_sense = value;
178
break;
179
+ case ARMSSE_SSE300:
180
+ qemu_log_mask(LOG_UNIMP,
181
+ "IoTKit SysCtl PDCM_PD_VMR1_SENSE unimplemented\n");
182
+ s->pdcm_pd_vmr1_sense = value;
183
+ break;
184
default:
185
g_assert_not_reached();
186
}
187
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_reset(DeviceState *dev)
188
s->pdcm_pd_sram1_sense = 0;
189
s->pdcm_pd_sram2_sense = 0;
190
s->pdcm_pd_sram3_sense = 0;
191
+ s->pdcm_pd_cpu0_sense = 0;
192
+ s->pdcm_pd_vmr0_sense = 0;
193
+ s->pdcm_pd_vmr1_sense = 0;
194
}
195
196
static void iotkit_sysctl_init(Object *obj)
197
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription iotkit_sysctl_sse300_vmstate = {
198
.needed = sse300_needed,
199
.fields = (VMStateField[]) {
200
VMSTATE_UINT32(pwrctrl, IoTKitSysCtl),
201
+ VMSTATE_UINT32(pdcm_pd_cpu0_sense, IoTKitSysCtl),
202
+ VMSTATE_UINT32(pdcm_pd_vmr0_sense, IoTKitSysCtl),
203
+ VMSTATE_UINT32(pdcm_pd_vmr1_sense, IoTKitSysCtl),
204
VMSTATE_END_OF_LIST()
205
}
206
};
207
--
208
2.20.1
209
210
diff view generated by jsdifflib
New patch
1
The SSE-200 and SSE-300 have different PID register values from the
2
IoTKit for the sysctl register block. We incorrectly implemented the
3
SSE-200 with the same PID values as IoTKit. Fix the SSE-200 bug and
4
report these register values for SSE-300.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210219144617.4782-19-peter.maydell@linaro.org
10
---
11
hw/misc/iotkit-sysctl.c | 21 +++++++++++++++++++--
12
1 file changed, 19 insertions(+), 2 deletions(-)
13
14
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/misc/iotkit-sysctl.c
17
+++ b/hw/misc/iotkit-sysctl.c
18
@@ -XXX,XX +XXX,XX @@ REG32(CID2, 0xff8)
19
REG32(CID3, 0xffc)
20
21
/* PID/CID values */
22
-static const int sysctl_id[] = {
23
+static const int iotkit_sysctl_id[] = {
24
0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
25
0x54, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
26
0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
27
};
28
29
+/* Also used by the SSE300 */
30
+static const int sse200_sysctl_id[] = {
31
+ 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
32
+ 0x54, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
33
+ 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
34
+};
35
+
36
/*
37
* Set the initial secure vector table offset address for the core.
38
* This will take effect when the CPU next resets.
39
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
40
}
41
break;
42
case A_PID4 ... A_CID3:
43
- r = sysctl_id[(offset - A_PID4) / 4];
44
+ switch (s->sse_version) {
45
+ case ARMSSE_IOTKIT:
46
+ r = iotkit_sysctl_id[(offset - A_PID4) / 4];
47
+ break;
48
+ case ARMSSE_SSE200:
49
+ case ARMSSE_SSE300:
50
+ r = sse200_sysctl_id[(offset - A_PID4) / 4];
51
+ break;
52
+ default:
53
+ g_assert_not_reached();
54
+ }
55
break;
56
case A_SECDBGSET:
57
case A_SECDBGCLR:
58
--
59
2.20.1
60
61
diff view generated by jsdifflib
New patch
1
The ARMSSE_CPUID and ARMSSE_MHU Kconfig stanzas are for the devices
2
implemented by hw/misc/cpuid.c and hw/misc/armsse-mhu.c. Move them
3
to hw/misc/Kconfig where they belong.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210219144617.4782-20-peter.maydell@linaro.org
10
---
11
hw/arm/Kconfig | 6 ------
12
hw/misc/Kconfig | 6 ++++++
13
2 files changed, 6 insertions(+), 6 deletions(-)
14
15
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/Kconfig
18
+++ b/hw/arm/Kconfig
19
@@ -XXX,XX +XXX,XX @@ config ARMSSE
20
select UNIMP
21
select SSE_COUNTER
22
select SSE_TIMER
23
-
24
-config ARMSSE_CPUID
25
- bool
26
-
27
-config ARMSSE_MHU
28
- bool
29
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/misc/Kconfig
32
+++ b/hw/misc/Kconfig
33
@@ -XXX,XX +XXX,XX @@ config APPLESMC
34
bool
35
depends on ISA_BUS
36
37
+config ARMSSE_CPUID
38
+ bool
39
+
40
+config ARMSSE_MHU
41
+ bool
42
+
43
config MAX111X
44
bool
45
46
--
47
2.20.1
48
49
diff view generated by jsdifflib
New patch
1
1
The SSE-300 has a new register block CPU<N>_PWRCTRL. There is one
2
instance of this per CPU in the system (so just one for the SSE-300),
3
and as well as the usual CIDR/PIDR ID registers it has just one
4
register, CPUPWRCFG. This register allows the guest to configure
5
behaviour of the system in power-down and deep-sleep states. Since
6
QEMU does not model those, we make the register a dummy
7
reads-as-written implementation.
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210219144617.4782-21-peter.maydell@linaro.org
13
---
14
include/hw/misc/armsse-cpu-pwrctrl.h | 40 +++++++
15
hw/misc/armsse-cpu-pwrctrl.c | 149 +++++++++++++++++++++++++++
16
MAINTAINERS | 2 +
17
hw/arm/Kconfig | 1 +
18
hw/misc/Kconfig | 3 +
19
hw/misc/meson.build | 1 +
20
hw/misc/trace-events | 4 +
21
7 files changed, 200 insertions(+)
22
create mode 100644 include/hw/misc/armsse-cpu-pwrctrl.h
23
create mode 100644 hw/misc/armsse-cpu-pwrctrl.c
24
25
diff --git a/include/hw/misc/armsse-cpu-pwrctrl.h b/include/hw/misc/armsse-cpu-pwrctrl.h
26
new file mode 100644
27
index XXXXXXX..XXXXXXX
28
--- /dev/null
29
+++ b/include/hw/misc/armsse-cpu-pwrctrl.h
30
@@ -XXX,XX +XXX,XX @@
31
+/*
32
+ * ARM SSE CPU PWRCTRL register block
33
+ *
34
+ * Copyright (c) 2021 Linaro Limited
35
+ * Written by Peter Maydell
36
+ *
37
+ * This program is free software; you can redistribute it and/or modify
38
+ * it under the terms of the GNU General Public License version 2 or
39
+ * (at your option) any later version.
40
+ */
41
+
42
+/*
43
+ * This is a model of the "CPU<N>_PWRCTRL block" which is part of the
44
+ * Arm Corstone SSE-300 Example Subsystem and documented in
45
+ * https://developer.arm.com/documentation/101773/0000
46
+ *
47
+ * QEMU interface:
48
+ * + sysbus MMIO region 0: the register bank
49
+ */
50
+
51
+#ifndef HW_MISC_ARMSSE_CPU_PWRCTRL_H
52
+#define HW_MISC_ARMSSE_CPU_PWRCTRL_H
53
+
54
+#include "hw/sysbus.h"
55
+#include "qom/object.h"
56
+
57
+#define TYPE_ARMSSE_CPU_PWRCTRL "armsse-cpu-pwrctrl"
58
+OBJECT_DECLARE_SIMPLE_TYPE(ARMSSECPUPwrCtrl, ARMSSE_CPU_PWRCTRL)
59
+
60
+struct ARMSSECPUPwrCtrl {
61
+ /*< private >*/
62
+ SysBusDevice parent_obj;
63
+
64
+ /*< public >*/
65
+ MemoryRegion iomem;
66
+
67
+ uint32_t cpupwrcfg;
68
+};
69
+
70
+#endif
71
diff --git a/hw/misc/armsse-cpu-pwrctrl.c b/hw/misc/armsse-cpu-pwrctrl.c
72
new file mode 100644
73
index XXXXXXX..XXXXXXX
74
--- /dev/null
75
+++ b/hw/misc/armsse-cpu-pwrctrl.c
76
@@ -XXX,XX +XXX,XX @@
77
+/*
78
+ * Arm SSE CPU PWRCTRL register block
79
+ *
80
+ * Copyright (c) 2021 Linaro Limited
81
+ * Written by Peter Maydell
82
+ *
83
+ * This program is free software; you can redistribute it and/or modify
84
+ * it under the terms of the GNU General Public License version 2 or
85
+ * (at your option) any later version.
86
+ */
87
+
88
+/*
89
+ * This is a model of the "CPU<N>_PWRCTRL block" which is part of the
90
+ * Arm Corstone SSE-300 Example Subsystem and documented in
91
+ * https://developer.arm.com/documentation/101773/0000
92
+ */
93
+
94
+#include "qemu/osdep.h"
95
+#include "qemu/log.h"
96
+#include "qemu/module.h"
97
+#include "trace.h"
98
+#include "qapi/error.h"
99
+#include "migration/vmstate.h"
100
+#include "hw/sysbus.h"
101
+#include "hw/registerfields.h"
102
+#include "hw/misc/armsse-cpu-pwrctrl.h"
103
+
104
+REG32(CPUPWRCFG, 0x0)
105
+REG32(PID4, 0xfd0)
106
+REG32(PID5, 0xfd4)
107
+REG32(PID6, 0xfd8)
108
+REG32(PID7, 0xfdc)
109
+REG32(PID0, 0xfe0)
110
+REG32(PID1, 0xfe4)
111
+REG32(PID2, 0xfe8)
112
+REG32(PID3, 0xfec)
113
+REG32(CID0, 0xff0)
114
+REG32(CID1, 0xff4)
115
+REG32(CID2, 0xff8)
116
+REG32(CID3, 0xffc)
117
+
118
+/* PID/CID values */
119
+static const int cpu_pwrctrl_id[] = {
120
+ 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
121
+ 0x5a, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
122
+ 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
123
+};
124
+
125
+static uint64_t pwrctrl_read(void *opaque, hwaddr offset, unsigned size)
126
+{
127
+ ARMSSECPUPwrCtrl *s = ARMSSE_CPU_PWRCTRL(opaque);
128
+ uint64_t r;
129
+
130
+ switch (offset) {
131
+ case A_CPUPWRCFG:
132
+ r = s->cpupwrcfg;
133
+ break;
134
+ case A_PID4 ... A_CID3:
135
+ r = cpu_pwrctrl_id[(offset - A_PID4) / 4];
136
+ break;
137
+ default:
138
+ qemu_log_mask(LOG_GUEST_ERROR,
139
+ "SSE CPU_PWRCTRL read: bad offset %x\n", (int)offset);
140
+ r = 0;
141
+ break;
142
+ }
143
+ trace_armsse_cpu_pwrctrl_read(offset, r, size);
144
+ return r;
145
+}
146
+
147
+static void pwrctrl_write(void *opaque, hwaddr offset,
148
+ uint64_t value, unsigned size)
149
+{
150
+ ARMSSECPUPwrCtrl *s = ARMSSE_CPU_PWRCTRL(opaque);
151
+
152
+ trace_armsse_cpu_pwrctrl_write(offset, value, size);
153
+
154
+ switch (offset) {
155
+ case A_CPUPWRCFG:
156
+ qemu_log_mask(LOG_UNIMP,
157
+ "SSE CPU_PWRCTRL: CPUPWRCFG unimplemented\n");
158
+ s->cpupwrcfg = value;
159
+ break;
160
+ default:
161
+ qemu_log_mask(LOG_GUEST_ERROR,
162
+ "SSE CPU_PWRCTRL write: bad offset 0x%x\n", (int)offset);
163
+ break;
164
+ }
165
+}
166
+
167
+static const MemoryRegionOps pwrctrl_ops = {
168
+ .read = pwrctrl_read,
169
+ .write = pwrctrl_write,
170
+ .endianness = DEVICE_LITTLE_ENDIAN,
171
+ .impl.min_access_size = 4,
172
+ .impl.max_access_size = 4,
173
+ .valid.min_access_size = 4,
174
+ .valid.max_access_size = 4,
175
+};
176
+
177
+static void pwrctrl_reset(DeviceState *dev)
178
+{
179
+ ARMSSECPUPwrCtrl *s = ARMSSE_CPU_PWRCTRL(dev);
180
+
181
+ s->cpupwrcfg = 0;
182
+}
183
+
184
+static const VMStateDescription pwrctrl_vmstate = {
185
+ .name = "armsse-cpu-pwrctrl",
186
+ .version_id = 1,
187
+ .minimum_version_id = 1,
188
+ .fields = (VMStateField[]) {
189
+ VMSTATE_UINT32(cpupwrcfg, ARMSSECPUPwrCtrl),
190
+ VMSTATE_END_OF_LIST()
191
+ },
192
+};
193
+
194
+static void pwrctrl_init(Object *obj)
195
+{
196
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
197
+ ARMSSECPUPwrCtrl *s = ARMSSE_CPU_PWRCTRL(obj);
198
+
199
+ memory_region_init_io(&s->iomem, obj, &pwrctrl_ops,
200
+ s, "armsse-cpu-pwrctrl", 0x1000);
201
+ sysbus_init_mmio(sbd, &s->iomem);
202
+}
203
+
204
+static void pwrctrl_class_init(ObjectClass *klass, void *data)
205
+{
206
+ DeviceClass *dc = DEVICE_CLASS(klass);
207
+
208
+ dc->reset = pwrctrl_reset;
209
+ dc->vmsd = &pwrctrl_vmstate;
210
+}
211
+
212
+static const TypeInfo pwrctrl_info = {
213
+ .name = TYPE_ARMSSE_CPU_PWRCTRL,
214
+ .parent = TYPE_SYS_BUS_DEVICE,
215
+ .instance_size = sizeof(ARMSSECPUPwrCtrl),
216
+ .instance_init = pwrctrl_init,
217
+ .class_init = pwrctrl_class_init,
218
+};
219
+
220
+static void pwrctrl_register_types(void)
221
+{
222
+ type_register_static(&pwrctrl_info);
223
+}
224
+
225
+type_init(pwrctrl_register_types);
226
diff --git a/MAINTAINERS b/MAINTAINERS
227
index XXXXXXX..XXXXXXX 100644
228
--- a/MAINTAINERS
229
+++ b/MAINTAINERS
230
@@ -XXX,XX +XXX,XX @@ F: hw/misc/iotkit-sysctl.c
231
F: include/hw/misc/iotkit-sysctl.h
232
F: hw/misc/iotkit-sysinfo.c
233
F: include/hw/misc/iotkit-sysinfo.h
234
+F: hw/misc/armsse-cpu-pwrctrl.c
235
+F: include/hw/misc/armsse-cpu-pwrctrl.h
236
F: hw/misc/armsse-cpuid.c
237
F: include/hw/misc/armsse-cpuid.h
238
F: hw/misc/armsse-mhu.c
239
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
240
index XXXXXXX..XXXXXXX 100644
241
--- a/hw/arm/Kconfig
242
+++ b/hw/arm/Kconfig
243
@@ -XXX,XX +XXX,XX @@ config ARM11MPCORE
244
config ARMSSE
245
bool
246
select ARM_V7M
247
+ select ARMSSE_CPU_PWRCTRL
248
select ARMSSE_CPUID
249
select ARMSSE_MHU
250
select CMSDK_APB_TIMER
251
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
252
index XXXXXXX..XXXXXXX 100644
253
--- a/hw/misc/Kconfig
254
+++ b/hw/misc/Kconfig
255
@@ -XXX,XX +XXX,XX @@ config ARMSSE_CPUID
256
config ARMSSE_MHU
257
bool
258
259
+config ARMSSE_CPU_PWRCTRL
260
+ bool
261
+
262
config MAX111X
263
bool
264
265
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
266
index XXXXXXX..XXXXXXX 100644
267
--- a/hw/misc/meson.build
268
+++ b/hw/misc/meson.build
269
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_TZ_MSC', if_true: files('tz-msc.c'))
270
softmmu_ss.add(when: 'CONFIG_TZ_PPC', if_true: files('tz-ppc.c'))
271
softmmu_ss.add(when: 'CONFIG_IOTKIT_SECCTL', if_true: files('iotkit-secctl.c'))
272
softmmu_ss.add(when: 'CONFIG_IOTKIT_SYSINFO', if_true: files('iotkit-sysinfo.c'))
273
+softmmu_ss.add(when: 'CONFIG_ARMSSE_CPU_PWRCTRL', if_true: files('armsse-cpu-pwrctrl.c'))
274
softmmu_ss.add(when: 'CONFIG_ARMSSE_CPUID', if_true: files('armsse-cpuid.c'))
275
softmmu_ss.add(when: 'CONFIG_ARMSSE_MHU', if_true: files('armsse-mhu.c'))
276
277
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
278
index XXXXXXX..XXXXXXX 100644
279
--- a/hw/misc/trace-events
280
+++ b/hw/misc/trace-events
281
@@ -XXX,XX +XXX,XX @@ iotkit_sysctl_read(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysCtl
282
iotkit_sysctl_write(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysCtl write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
283
iotkit_sysctl_reset(void) "IoTKit SysCtl: reset"
284
285
+# armsse-cpu-pwrctrl.c
286
+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"
287
+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"
288
+
289
# armsse-cpuid.c
290
armsse_cpuid_read(uint64_t offset, uint64_t data, unsigned size) "SSE-200 CPU_IDENTITY read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
291
armsse_cpuid_write(uint64_t offset, uint64_t data, unsigned size) "SSE-200 CPU_IDENTITY write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
292
--
293
2.20.1
294
295
diff view generated by jsdifflib
New patch
1
Convert the apb_ppc0 and apb_ppc1 fields in the ARMSSE state struct
2
to use an array instead of two separate fields. We already had one
3
place in the code that wanted to be able to refer to the PPC by
4
index, and we're about to add more code like that.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210219144617.4782-22-peter.maydell@linaro.org
11
---
12
include/hw/arm/armsse.h | 6 +++---
13
hw/arm/armsse.c | 32 ++++++++++++++++++--------------
14
2 files changed, 21 insertions(+), 17 deletions(-)
15
16
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/armsse.h
19
+++ b/include/hw/arm/armsse.h
20
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(ARMSSE, ARMSSEClass,
21
/* We have an IRQ splitter and an OR gate input for each external PPC
22
* and the 2 internal PPCs
23
*/
24
+#define NUM_INTERNAL_PPCS 2
25
#define NUM_EXTERNAL_PPCS (IOTS_NUM_AHB_EXP_PPC + IOTS_NUM_APB_EXP_PPC)
26
-#define NUM_PPCS (NUM_EXTERNAL_PPCS + 2)
27
+#define NUM_PPCS (NUM_EXTERNAL_PPCS + NUM_INTERNAL_PPCS)
28
29
#define MAX_SRAM_BANKS 4
30
#if MAX_SRAM_BANKS > IOTS_NUM_MPC
31
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
32
ARMv7MState armv7m[SSE_MAX_CPUS];
33
CPUClusterState cluster[SSE_MAX_CPUS];
34
IoTKitSecCtl secctl;
35
- TZPPC apb_ppc0;
36
- TZPPC apb_ppc1;
37
+ TZPPC apb_ppc[NUM_INTERNAL_PPCS];
38
TZMPC mpc[IOTS_NUM_MPC];
39
CMSDKAPBTimer timer0;
40
CMSDKAPBTimer timer1;
41
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/arm/armsse.c
44
+++ b/hw/arm/armsse.c
45
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
46
}
47
48
object_initialize_child(obj, "secctl", &s->secctl, TYPE_IOTKIT_SECCTL);
49
- object_initialize_child(obj, "apb-ppc0", &s->apb_ppc0, TYPE_TZ_PPC);
50
- object_initialize_child(obj, "apb-ppc1", &s->apb_ppc1, TYPE_TZ_PPC);
51
+
52
+ for (i = 0; i < ARRAY_SIZE(s->apb_ppc); i++) {
53
+ g_autofree char *name = g_strdup_printf("apb-ppc%d", i);
54
+ object_initialize_child(obj, name, &s->apb_ppc[i], TYPE_TZ_PPC);
55
+ }
56
+
57
for (i = 0; i < info->sram_banks; i++) {
58
char *name = g_strdup_printf("mpc%d", i);
59
object_initialize_child(obj, name, &s->mpc[i], TYPE_TZ_MPC);
60
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
61
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer0), 0,
62
armsse_get_common_irq_in(s, 3));
63
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer0), 0);
64
- object_property_set_link(OBJECT(&s->apb_ppc0), "port[0]", OBJECT(mr),
65
+ object_property_set_link(OBJECT(&s->apb_ppc[0]), "port[0]", OBJECT(mr),
66
&error_abort);
67
68
qdev_connect_clock_in(DEVICE(&s->timer1), "pclk", s->mainclk);
69
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
70
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer1), 0,
71
armsse_get_common_irq_in(s, 4));
72
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer1), 0);
73
- object_property_set_link(OBJECT(&s->apb_ppc0), "port[1]", OBJECT(mr),
74
+ object_property_set_link(OBJECT(&s->apb_ppc[0]), "port[1]", OBJECT(mr),
75
&error_abort);
76
77
qdev_connect_clock_in(DEVICE(&s->dualtimer), "TIMCLK", s->mainclk);
78
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
79
sysbus_connect_irq(SYS_BUS_DEVICE(&s->dualtimer), 0,
80
armsse_get_common_irq_in(s, 5));
81
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dualtimer), 0);
82
- object_property_set_link(OBJECT(&s->apb_ppc0), "port[2]", OBJECT(mr),
83
+ object_property_set_link(OBJECT(&s->apb_ppc[0]), "port[2]", OBJECT(mr),
84
&error_abort);
85
86
if (info->has_mhus) {
87
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
88
}
89
port = g_strdup_printf("port[%d]", i + 3);
90
mr = sysbus_mmio_get_region(mhu_sbd, 0);
91
- object_property_set_link(OBJECT(&s->apb_ppc0), port, OBJECT(mr),
92
+ object_property_set_link(OBJECT(&s->apb_ppc[0]), port, OBJECT(mr),
93
&error_abort);
94
g_free(port);
95
96
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
97
}
98
}
99
100
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc0), errp)) {
101
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc[0]), errp)) {
102
return;
103
}
104
105
- sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc0);
106
- dev_apb_ppc0 = DEVICE(&s->apb_ppc0);
107
+ sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc[0]);
108
+ dev_apb_ppc0 = DEVICE(&s->apb_ppc[0]);
109
110
mr = sysbus_mmio_get_region(sbd_apb_ppc0, 0);
111
memory_region_add_subregion(&s->container, 0x40000000, mr);
112
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
113
sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32ktimer), 0,
114
armsse_get_common_irq_in(s, 2));
115
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->s32ktimer), 0);
116
- object_property_set_link(OBJECT(&s->apb_ppc1), "port[0]", OBJECT(mr),
117
+ object_property_set_link(OBJECT(&s->apb_ppc[1]), "port[0]", OBJECT(mr),
118
&error_abort);
119
120
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc1), errp)) {
121
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc[1]), errp)) {
122
return;
123
}
124
- mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->apb_ppc1), 0);
125
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->apb_ppc[1]), 0);
126
memory_region_add_subregion(&s->container, 0x4002f000, mr);
127
128
- dev_apb_ppc1 = DEVICE(&s->apb_ppc1);
129
+ dev_apb_ppc1 = DEVICE(&s->apb_ppc[1]);
130
qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_nonsec", 0,
131
qdev_get_gpio_in_named(dev_apb_ppc1,
132
"cfg_nonsec", 0));
133
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
134
DeviceState *devs = DEVICE(&s->ppc_irq_splitter[i]);
135
char *gpioname = g_strdup_printf("apb_ppc%d_irq_status",
136
i - NUM_EXTERNAL_PPCS);
137
- TZPPC *ppc = (i == NUM_EXTERNAL_PPCS) ? &s->apb_ppc0 : &s->apb_ppc1;
138
+ TZPPC *ppc = &s->apb_ppc[i - NUM_EXTERNAL_PPCS];
139
140
qdev_connect_gpio_out(devs, 0,
141
qdev_get_gpio_in_named(dev_secctl, gpioname, 0));
142
--
143
2.20.1
144
145
diff view generated by jsdifflib
New patch
1
The SSE uses 32 interrupts for its own devices, and then passes through
2
its expansion IRQ inputs to the CPU's interrupts 33 and upward.
3
Add a define for the number of IRQs the SSE uses for itself, instead
4
of hardcoding 32.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210219144617.4782-23-peter.maydell@linaro.org
11
---
12
include/hw/arm/armsse.h | 5 ++++-
13
hw/arm/armsse.c | 4 ++--
14
2 files changed, 6 insertions(+), 3 deletions(-)
15
16
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/armsse.h
19
+++ b/include/hw/arm/armsse.h
20
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(ARMSSE, ARMSSEClass,
21
#define RAM3_PPU 6
22
#define NUM_PPUS 7
23
24
+/* Number of CPU IRQs used by the SSE itself */
25
+#define NUM_SSE_IRQS 32
26
+
27
struct ARMSSE {
28
/*< private >*/
29
SysBusDevice parent_obj;
30
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
31
qemu_or_irq mpc_irq_orgate;
32
qemu_or_irq nmi_orgate;
33
34
- SplitIRQ cpu_irq_splitter[32];
35
+ SplitIRQ cpu_irq_splitter[NUM_SSE_IRQS];
36
37
CMSDKAPBDualTimer dualtimer;
38
39
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/arm/armsse.c
42
+++ b/hw/arm/armsse.c
43
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
44
int j;
45
char *gpioname;
46
47
- qdev_prop_set_uint32(cpudev, "num-irq", s->exp_numirq + 32);
48
+ qdev_prop_set_uint32(cpudev, "num-irq", s->exp_numirq + NUM_SSE_IRQS);
49
/*
50
* In real hardware the initial Secure VTOR is set from the INITSVTOR*
51
* registers in the IoT Kit System Control Register block. In QEMU
52
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
53
/* Connect EXP_IRQ/EXP_CPUn_IRQ GPIOs to the NVIC's lines 32 and up */
54
s->exp_irqs[i] = g_new(qemu_irq, s->exp_numirq);
55
for (j = 0; j < s->exp_numirq; j++) {
56
- s->exp_irqs[i][j] = qdev_get_gpio_in(cpudev, j + 32);
57
+ s->exp_irqs[i][j] = qdev_get_gpio_in(cpudev, j + NUM_SSE_IRQS);
58
}
59
if (i == 0) {
60
gpioname = g_strdup("EXP_IRQ");
61
--
62
2.20.1
63
64
diff view generated by jsdifflib
New patch
1
1
The SSE-300 is mostly the same as the SSE-200, but it has moved some
2
of the devices in the memory map and uses different device types in
3
some cases. To accommodate this, add a framework where the placement
4
and wiring of some devices can be specified in a data table.
5
6
This commit adds the framework for this data-driven device placement,
7
and makes the CMSDK APB timer devices use it. Subsequent commits
8
will convert the other devices which differ between SSE-200 and
9
SSE-300.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20210219144617.4782-24-peter.maydell@linaro.org
15
---
16
include/hw/arm/armsse.h | 3 +-
17
hw/arm/armsse.c | 147 +++++++++++++++++++++++++++++++++-------
18
2 files changed, 125 insertions(+), 25 deletions(-)
19
20
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/arm/armsse.h
23
+++ b/include/hw/arm/armsse.h
24
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
25
IoTKitSecCtl secctl;
26
TZPPC apb_ppc[NUM_INTERNAL_PPCS];
27
TZMPC mpc[IOTS_NUM_MPC];
28
- CMSDKAPBTimer timer0;
29
- CMSDKAPBTimer timer1;
30
+ CMSDKAPBTimer timer[2];
31
CMSDKAPBTimer s32ktimer;
32
qemu_or_irq ppc_irq_orgate;
33
SplitIRQ sec_resp_splitter;
34
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/arm/armsse.c
37
+++ b/hw/arm/armsse.c
38
@@ -XXX,XX +XXX,XX @@
39
#include "hw/irq.h"
40
#include "hw/qdev-clock.h"
41
42
+/*
43
+ * The SSE-300 puts some devices in different places to the
44
+ * SSE-200 (and original IoTKit). We use an array of these structs
45
+ * to define how each variant lays out these devices. (Parts of the
46
+ * SoC that are the same for all variants aren't handled via these
47
+ * data structures.)
48
+ */
49
+
50
+#define NO_IRQ -1
51
+#define NO_PPC -1
52
+
53
+typedef struct ARMSSEDeviceInfo {
54
+ const char *name; /* name to use for the QOM object; NULL terminates list */
55
+ const char *type; /* QOM type name */
56
+ unsigned int index; /* Which of the N devices of this type is this ? */
57
+ hwaddr addr;
58
+ int ppc; /* Index of APB PPC this device is wired up to, or NO_PPC */
59
+ int ppc_port; /* Port number of this device on the PPC */
60
+ int irq; /* NO_IRQ, or 0..NUM_SSE_IRQS-1 */
61
+} ARMSSEDeviceInfo;
62
+
63
struct ARMSSEInfo {
64
const char *name;
65
uint32_t sse_version;
66
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
67
bool has_cpusecctrl;
68
bool has_cpuid;
69
Property *props;
70
+ const ARMSSEDeviceInfo *devinfo;
71
};
72
73
static Property iotkit_properties[] = {
74
@@ -XXX,XX +XXX,XX @@ static Property armsse_properties[] = {
75
DEFINE_PROP_END_OF_LIST()
76
};
77
78
+static const ARMSSEDeviceInfo sse200_devices[] = {
79
+ {
80
+ .name = "timer0",
81
+ .type = TYPE_CMSDK_APB_TIMER,
82
+ .index = 0,
83
+ .addr = 0x40000000,
84
+ .ppc = 0,
85
+ .ppc_port = 0,
86
+ .irq = 3,
87
+ },
88
+ {
89
+ .name = "timer1",
90
+ .type = TYPE_CMSDK_APB_TIMER,
91
+ .index = 1,
92
+ .addr = 0x40001000,
93
+ .ppc = 0,
94
+ .ppc_port = 1,
95
+ .irq = 4,
96
+ },
97
+ {
98
+ .name = NULL,
99
+ }
100
+};
101
+
102
static const ARMSSEInfo armsse_variants[] = {
103
{
104
.name = TYPE_IOTKIT,
105
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
106
.has_cpusecctrl = false,
107
.has_cpuid = false,
108
.props = iotkit_properties,
109
+ .devinfo = sse200_devices,
110
},
111
{
112
.name = TYPE_SSE200,
113
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
114
.has_cpusecctrl = true,
115
.has_cpuid = true,
116
.props = armsse_properties,
117
+ .devinfo = sse200_devices,
118
},
119
};
120
121
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
122
ARMSSE *s = ARM_SSE(obj);
123
ARMSSEClass *asc = ARM_SSE_GET_CLASS(obj);
124
const ARMSSEInfo *info = asc->info;
125
+ const ARMSSEDeviceInfo *devinfo;
126
int i;
127
128
assert(info->sram_banks <= MAX_SRAM_BANKS);
129
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
130
}
131
}
132
133
+ for (devinfo = info->devinfo; devinfo->name; devinfo++) {
134
+ assert(devinfo->ppc == NO_PPC || devinfo->ppc < ARRAY_SIZE(s->apb_ppc));
135
+ if (!strcmp(devinfo->type, TYPE_CMSDK_APB_TIMER)) {
136
+ assert(devinfo->index < ARRAY_SIZE(s->timer));
137
+ object_initialize_child(obj, devinfo->name,
138
+ &s->timer[devinfo->index],
139
+ TYPE_CMSDK_APB_TIMER);
140
+ } else {
141
+ g_assert_not_reached();
142
+ }
143
+ }
144
+
145
object_initialize_child(obj, "secctl", &s->secctl, TYPE_IOTKIT_SECCTL);
146
147
for (i = 0; i < ARRAY_SIZE(s->apb_ppc); i++) {
148
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
149
object_initialize_child(obj, name, splitter, TYPE_SPLIT_IRQ);
150
g_free(name);
151
}
152
- object_initialize_child(obj, "timer0", &s->timer0, TYPE_CMSDK_APB_TIMER);
153
- object_initialize_child(obj, "timer1", &s->timer1, TYPE_CMSDK_APB_TIMER);
154
object_initialize_child(obj, "s32ktimer", &s->s32ktimer,
155
TYPE_CMSDK_APB_TIMER);
156
object_initialize_child(obj, "dualtimer", &s->dualtimer,
157
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
158
ARMSSE *s = ARM_SSE(dev);
159
ARMSSEClass *asc = ARM_SSE_GET_CLASS(dev);
160
const ARMSSEInfo *info = asc->info;
161
+ const ARMSSEDeviceInfo *devinfo;
162
int i;
163
MemoryRegion *mr;
164
Error *err = NULL;
165
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
166
* it to the appropriate PPC port; then we can realize the PPC and
167
* map its upstream ends to the right place in the container.
168
*/
169
- qdev_connect_clock_in(DEVICE(&s->timer0), "pclk", s->mainclk);
170
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer0), errp)) {
171
- return;
172
- }
173
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer0), 0,
174
- armsse_get_common_irq_in(s, 3));
175
- mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer0), 0);
176
- object_property_set_link(OBJECT(&s->apb_ppc[0]), "port[0]", OBJECT(mr),
177
- &error_abort);
178
+ for (devinfo = info->devinfo; devinfo->name; devinfo++) {
179
+ SysBusDevice *sbd;
180
+ qemu_irq irq;
181
182
- qdev_connect_clock_in(DEVICE(&s->timer1), "pclk", s->mainclk);
183
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer1), errp)) {
184
- return;
185
+ if (!strcmp(devinfo->type, TYPE_CMSDK_APB_TIMER)) {
186
+ sbd = SYS_BUS_DEVICE(&s->timer[devinfo->index]);
187
+
188
+ qdev_connect_clock_in(DEVICE(sbd), "pclk", s->mainclk);
189
+ if (!sysbus_realize(sbd, errp)) {
190
+ return;
191
+ }
192
+ mr = sysbus_mmio_get_region(sbd, 0);
193
+ } else {
194
+ g_assert_not_reached();
195
+ }
196
+
197
+ switch (devinfo->irq) {
198
+ case NO_IRQ:
199
+ irq = NULL;
200
+ break;
201
+ case 0 ... NUM_SSE_IRQS - 1:
202
+ irq = armsse_get_common_irq_in(s, devinfo->irq);
203
+ break;
204
+ default:
205
+ g_assert_not_reached();
206
+ }
207
+
208
+ if (irq) {
209
+ sysbus_connect_irq(sbd, 0, irq);
210
+ }
211
+
212
+ /*
213
+ * Devices connected to a PPC are connected to the port here;
214
+ * we will map the upstream end of that port to the right address
215
+ * in the container later after the PPC has been realized.
216
+ * Devices not connected to a PPC can be mapped immediately.
217
+ */
218
+ if (devinfo->ppc != NO_PPC) {
219
+ TZPPC *ppc = &s->apb_ppc[devinfo->ppc];
220
+ g_autofree char *portname = g_strdup_printf("port[%d]",
221
+ devinfo->ppc_port);
222
+ object_property_set_link(OBJECT(ppc), portname, OBJECT(mr),
223
+ &error_abort);
224
+ } else {
225
+ memory_region_add_subregion(&s->container, devinfo->addr, mr);
226
+ }
227
}
228
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer1), 0,
229
- armsse_get_common_irq_in(s, 4));
230
- mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer1), 0);
231
- object_property_set_link(OBJECT(&s->apb_ppc[0]), "port[1]", OBJECT(mr),
232
- &error_abort);
233
234
qdev_connect_clock_in(DEVICE(&s->dualtimer), "TIMCLK", s->mainclk);
235
if (!sysbus_realize(SYS_BUS_DEVICE(&s->dualtimer), errp)) {
236
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
237
sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc[0]);
238
dev_apb_ppc0 = DEVICE(&s->apb_ppc[0]);
239
240
- mr = sysbus_mmio_get_region(sbd_apb_ppc0, 0);
241
- memory_region_add_subregion(&s->container, 0x40000000, mr);
242
- mr = sysbus_mmio_get_region(sbd_apb_ppc0, 1);
243
- memory_region_add_subregion(&s->container, 0x40001000, mr);
244
mr = sysbus_mmio_get_region(sbd_apb_ppc0, 2);
245
memory_region_add_subregion(&s->container, 0x40002000, mr);
246
if (info->has_mhus) {
247
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
248
qdev_get_gpio_in_named(dev_apb_ppc1,
249
"cfg_sec_resp", 0));
250
251
+ /*
252
+ * Now both PPCs are realized we can map the upstream ends of
253
+ * ports which correspond to entries in the devinfo array.
254
+ * The ports which are connected to non-devinfo devices have
255
+ * already been mapped.
256
+ */
257
+ for (devinfo = info->devinfo; devinfo->name; devinfo++) {
258
+ SysBusDevice *ppc_sbd;
259
+
260
+ if (devinfo->ppc == NO_PPC) {
261
+ continue;
262
+ }
263
+ ppc_sbd = SYS_BUS_DEVICE(&s->apb_ppc[devinfo->ppc]);
264
+ mr = sysbus_mmio_get_region(ppc_sbd, devinfo->ppc_port);
265
+ memory_region_add_subregion(&s->container, devinfo->addr, mr);
266
+ }
267
+
268
if (!object_property_set_int(OBJECT(&s->sysinfo), "SYS_VERSION",
269
info->sys_version, errp)) {
270
return;
271
--
272
2.20.1
273
274
diff view generated by jsdifflib
New patch
1
Move the CMSDK dualtimer device handling into the data-driven
2
device placement framework.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210219144617.4782-25-peter.maydell@linaro.org
8
---
9
hw/arm/armsse.c | 35 +++++++++++++++++++++--------------
10
1 file changed, 21 insertions(+), 14 deletions(-)
11
12
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/armsse.c
15
+++ b/hw/arm/armsse.c
16
@@ -XXX,XX +XXX,XX @@ static const ARMSSEDeviceInfo sse200_devices[] = {
17
.ppc_port = 1,
18
.irq = 4,
19
},
20
+ {
21
+ .name = "dualtimer",
22
+ .type = TYPE_CMSDK_APB_DUALTIMER,
23
+ .index = 0,
24
+ .addr = 0x40002000,
25
+ .ppc = 0,
26
+ .ppc_port = 2,
27
+ .irq = 5,
28
+ },
29
{
30
.name = NULL,
31
}
32
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
33
object_initialize_child(obj, devinfo->name,
34
&s->timer[devinfo->index],
35
TYPE_CMSDK_APB_TIMER);
36
+ } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_DUALTIMER)) {
37
+ assert(devinfo->index == 0);
38
+ object_initialize_child(obj, devinfo->name, &s->dualtimer,
39
+ TYPE_CMSDK_APB_DUALTIMER);
40
} else {
41
g_assert_not_reached();
42
}
43
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
44
}
45
object_initialize_child(obj, "s32ktimer", &s->s32ktimer,
46
TYPE_CMSDK_APB_TIMER);
47
- object_initialize_child(obj, "dualtimer", &s->dualtimer,
48
- TYPE_CMSDK_APB_DUALTIMER);
49
object_initialize_child(obj, "s32kwatchdog", &s->s32kwatchdog,
50
TYPE_CMSDK_APB_WATCHDOG);
51
object_initialize_child(obj, "nswatchdog", &s->nswatchdog,
52
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
53
return;
54
}
55
mr = sysbus_mmio_get_region(sbd, 0);
56
+ } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_DUALTIMER)) {
57
+ sbd = SYS_BUS_DEVICE(&s->dualtimer);
58
+
59
+ qdev_connect_clock_in(DEVICE(sbd), "TIMCLK", s->mainclk);
60
+ if (!sysbus_realize(sbd, errp)) {
61
+ return;
62
+ }
63
+ mr = sysbus_mmio_get_region(sbd, 0);
64
} else {
65
g_assert_not_reached();
66
}
67
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
68
}
69
}
70
71
- qdev_connect_clock_in(DEVICE(&s->dualtimer), "TIMCLK", s->mainclk);
72
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->dualtimer), errp)) {
73
- return;
74
- }
75
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->dualtimer), 0,
76
- armsse_get_common_irq_in(s, 5));
77
- mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dualtimer), 0);
78
- object_property_set_link(OBJECT(&s->apb_ppc[0]), "port[2]", OBJECT(mr),
79
- &error_abort);
80
-
81
if (info->has_mhus) {
82
/*
83
* An SSE-200 with only one CPU should have only one MHU created,
84
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
85
sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc[0]);
86
dev_apb_ppc0 = DEVICE(&s->apb_ppc[0]);
87
88
- mr = sysbus_mmio_get_region(sbd_apb_ppc0, 2);
89
- memory_region_add_subregion(&s->container, 0x40002000, mr);
90
if (info->has_mhus) {
91
mr = sysbus_mmio_get_region(sbd_apb_ppc0, 3);
92
memory_region_add_subregion(&s->container, 0x40003000, mr);
93
--
94
2.20.1
95
96
diff view generated by jsdifflib
1
The target_flat.h file is a QEMU header, so we should include it using
1
Move the CMSDK watchdog device handling into the data-driven device
2
quotes, not angle brackets.
2
placement framework. This is slightly more complicated because these
3
3
devices might wire their IRQs up to the NMI line, and because one of
4
Coverity otherwise is unable to find the header:
4
them uses the slow 32KHz clock rather than the main clock.
5
6
"../linux-user/flatload.c", line 40: error #1712: cannot open source file
7
"target_flat.h"
8
#include <target_flat.h>
9
^
10
11
because the relevant directory is only on the -iquote path, not the -I path.
12
5
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20210219144617.4782-26-peter.maydell@linaro.org
16
Message-id: 20200319193323.2038-5-peter.maydell@linaro.org
17
---
10
---
18
linux-user/flatload.c | 2 +-
11
include/hw/arm/armsse.h | 4 +-
19
1 file changed, 1 insertion(+), 1 deletion(-)
12
hw/arm/armsse.c | 109 ++++++++++++++++++++++++----------------
20
13
2 files changed, 66 insertions(+), 47 deletions(-)
21
diff --git a/linux-user/flatload.c b/linux-user/flatload.c
14
15
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
22
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
23
--- a/linux-user/flatload.c
17
--- a/include/hw/arm/armsse.h
24
+++ b/linux-user/flatload.c
18
+++ b/include/hw/arm/armsse.h
19
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
20
21
CMSDKAPBDualTimer dualtimer;
22
23
- CMSDKAPBWatchdog s32kwatchdog;
24
- CMSDKAPBWatchdog nswatchdog;
25
- CMSDKAPBWatchdog swatchdog;
26
+ CMSDKAPBWatchdog cmsdk_watchdog[3];
27
28
IoTKitSysCtl sysctl;
29
IoTKitSysCtl sysinfo;
30
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/arm/armsse.c
33
+++ b/hw/arm/armsse.c
25
@@ -XXX,XX +XXX,XX @@
34
@@ -XXX,XX +XXX,XX @@
26
35
27
#include "qemu.h"
36
#define NO_IRQ -1
28
#include "flat.h"
37
#define NO_PPC -1
29
-#include <target_flat.h>
38
+/*
30
+#include "target_flat.h"
39
+ * Special values for ARMSSEDeviceInfo::irq to indicate that this
31
40
+ * device uses one of the inputs to the OR gate that feeds into the
32
//#define DEBUG
41
+ * CPU NMI input.
42
+ */
43
+#define NMI_0 10000
44
+#define NMI_1 10001
45
46
typedef struct ARMSSEDeviceInfo {
47
const char *name; /* name to use for the QOM object; NULL terminates list */
48
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSEDeviceInfo {
49
hwaddr addr;
50
int ppc; /* Index of APB PPC this device is wired up to, or NO_PPC */
51
int ppc_port; /* Port number of this device on the PPC */
52
- int irq; /* NO_IRQ, or 0..NUM_SSE_IRQS-1 */
53
+ int irq; /* NO_IRQ, or 0..NUM_SSE_IRQS-1, or NMI_0 or NMI_1 */
54
+ bool slowclk; /* true if device uses the slow 32KHz clock */
55
} ARMSSEDeviceInfo;
56
57
struct ARMSSEInfo {
58
@@ -XXX,XX +XXX,XX @@ static const ARMSSEDeviceInfo sse200_devices[] = {
59
.ppc_port = 2,
60
.irq = 5,
61
},
62
+ {
63
+ .name = "s32kwatchdog",
64
+ .type = TYPE_CMSDK_APB_WATCHDOG,
65
+ .index = 0,
66
+ .addr = 0x5002e000,
67
+ .ppc = NO_PPC,
68
+ .irq = NMI_0,
69
+ .slowclk = true,
70
+ },
71
+ {
72
+ .name = "nswatchdog",
73
+ .type = TYPE_CMSDK_APB_WATCHDOG,
74
+ .index = 1,
75
+ .addr = 0x40081000,
76
+ .ppc = NO_PPC,
77
+ .irq = 1,
78
+ },
79
+ {
80
+ .name = "swatchdog",
81
+ .type = TYPE_CMSDK_APB_WATCHDOG,
82
+ .index = 2,
83
+ .addr = 0x50081000,
84
+ .ppc = NO_PPC,
85
+ .irq = NMI_1,
86
+ },
87
{
88
.name = NULL,
89
}
90
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
91
assert(devinfo->index == 0);
92
object_initialize_child(obj, devinfo->name, &s->dualtimer,
93
TYPE_CMSDK_APB_DUALTIMER);
94
+ } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_WATCHDOG)) {
95
+ assert(devinfo->index < ARRAY_SIZE(s->cmsdk_watchdog));
96
+ object_initialize_child(obj, devinfo->name,
97
+ &s->cmsdk_watchdog[devinfo->index],
98
+ TYPE_CMSDK_APB_WATCHDOG);
99
} else {
100
g_assert_not_reached();
101
}
102
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
103
object_initialize_child(obj, name, splitter, TYPE_SPLIT_IRQ);
104
g_free(name);
105
}
106
+
107
object_initialize_child(obj, "s32ktimer", &s->s32ktimer,
108
TYPE_CMSDK_APB_TIMER);
109
- object_initialize_child(obj, "s32kwatchdog", &s->s32kwatchdog,
110
- TYPE_CMSDK_APB_WATCHDOG);
111
- object_initialize_child(obj, "nswatchdog", &s->nswatchdog,
112
- TYPE_CMSDK_APB_WATCHDOG);
113
- object_initialize_child(obj, "swatchdog", &s->swatchdog,
114
- TYPE_CMSDK_APB_WATCHDOG);
115
object_initialize_child(obj, "armsse-sysctl", &s->sysctl,
116
TYPE_IOTKIT_SYSCTL);
117
object_initialize_child(obj, "armsse-sysinfo", &s->sysinfo,
118
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
119
qdev_connect_gpio_out(DEVICE(&s->mpc_irq_orgate), 0,
120
armsse_get_common_irq_in(s, 9));
121
122
+ /* This OR gate wires together outputs from the secure watchdogs to NMI */
123
+ if (!object_property_set_int(OBJECT(&s->nmi_orgate), "num-lines", 2,
124
+ errp)) {
125
+ return;
126
+ }
127
+ if (!qdev_realize(DEVICE(&s->nmi_orgate), NULL, errp)) {
128
+ return;
129
+ }
130
+ qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
131
+ qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
132
+
133
/* Devices behind APB PPC0:
134
* 0x40000000: timer0
135
* 0x40001000: timer1
136
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
137
return;
138
}
139
mr = sysbus_mmio_get_region(sbd, 0);
140
+ } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_WATCHDOG)) {
141
+ sbd = SYS_BUS_DEVICE(&s->cmsdk_watchdog[devinfo->index]);
142
+
143
+ qdev_connect_clock_in(DEVICE(sbd), "WDOGCLK",
144
+ devinfo->slowclk ? s->s32kclk : s->mainclk);
145
+ if (!sysbus_realize(sbd, errp)) {
146
+ return;
147
+ }
148
+ mr = sysbus_mmio_get_region(sbd, 0);
149
} else {
150
g_assert_not_reached();
151
}
152
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
153
case 0 ... NUM_SSE_IRQS - 1:
154
irq = armsse_get_common_irq_in(s, devinfo->irq);
155
break;
156
+ case NMI_0:
157
+ case NMI_1:
158
+ irq = qdev_get_gpio_in(DEVICE(&s->nmi_orgate),
159
+ devinfo->irq - NMI_0);
160
+ break;
161
default:
162
g_assert_not_reached();
163
}
164
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
165
}
166
}
167
168
- /* This OR gate wires together outputs from the secure watchdogs to NMI */
169
- if (!object_property_set_int(OBJECT(&s->nmi_orgate), "num-lines", 2,
170
- errp)) {
171
- return;
172
- }
173
- if (!qdev_realize(DEVICE(&s->nmi_orgate), NULL, errp)) {
174
- return;
175
- }
176
- qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
177
- qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
178
-
179
- qdev_connect_clock_in(DEVICE(&s->s32kwatchdog), "WDOGCLK", s->s32kclk);
180
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->s32kwatchdog), errp)) {
181
- return;
182
- }
183
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32kwatchdog), 0,
184
- qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 0));
185
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->s32kwatchdog), 0, 0x5002e000);
186
-
187
- /* 0x40080000 .. 0x4008ffff : ARMSSE second Base peripheral region */
188
-
189
- qdev_connect_clock_in(DEVICE(&s->nswatchdog), "WDOGCLK", s->mainclk);
190
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->nswatchdog), errp)) {
191
- return;
192
- }
193
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->nswatchdog), 0,
194
- armsse_get_common_irq_in(s, 1));
195
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->nswatchdog), 0, 0x40081000);
196
-
197
- qdev_connect_clock_in(DEVICE(&s->swatchdog), "WDOGCLK", s->mainclk);
198
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->swatchdog), errp)) {
199
- return;
200
- }
201
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->swatchdog), 0,
202
- qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 1));
203
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->swatchdog), 0, 0x50081000);
204
-
205
for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
206
Object *splitter = OBJECT(&s->ppc_irq_splitter[i]);
33
207
34
--
208
--
35
2.20.1
209
2.20.1
36
210
37
211
diff view generated by jsdifflib
New patch
1
Move the CMSDK timer that uses the S32K slow clock into the data-driven
2
device placement framework.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210219144617.4782-27-peter.maydell@linaro.org
8
---
9
include/hw/arm/armsse.h | 3 +--
10
hw/arm/armsse.c | 31 ++++++++++++-------------------
11
2 files changed, 13 insertions(+), 21 deletions(-)
12
13
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/arm/armsse.h
16
+++ b/include/hw/arm/armsse.h
17
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
18
IoTKitSecCtl secctl;
19
TZPPC apb_ppc[NUM_INTERNAL_PPCS];
20
TZMPC mpc[IOTS_NUM_MPC];
21
- CMSDKAPBTimer timer[2];
22
- CMSDKAPBTimer s32ktimer;
23
+ CMSDKAPBTimer timer[3];
24
qemu_or_irq ppc_irq_orgate;
25
SplitIRQ sec_resp_splitter;
26
SplitIRQ ppc_irq_splitter[NUM_PPCS];
27
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/armsse.c
30
+++ b/hw/arm/armsse.c
31
@@ -XXX,XX +XXX,XX @@ static const ARMSSEDeviceInfo sse200_devices[] = {
32
.ppc_port = 1,
33
.irq = 4,
34
},
35
+ {
36
+ .name = "s32ktimer",
37
+ .type = TYPE_CMSDK_APB_TIMER,
38
+ .index = 2,
39
+ .addr = 0x4002f000,
40
+ .ppc = 1,
41
+ .ppc_port = 0,
42
+ .irq = 2,
43
+ .slowclk = true,
44
+ },
45
{
46
.name = "dualtimer",
47
.type = TYPE_CMSDK_APB_DUALTIMER,
48
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
49
g_free(name);
50
}
51
52
- object_initialize_child(obj, "s32ktimer", &s->s32ktimer,
53
- TYPE_CMSDK_APB_TIMER);
54
object_initialize_child(obj, "armsse-sysctl", &s->sysctl,
55
TYPE_IOTKIT_SYSCTL);
56
object_initialize_child(obj, "armsse-sysinfo", &s->sysinfo,
57
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
58
if (!strcmp(devinfo->type, TYPE_CMSDK_APB_TIMER)) {
59
sbd = SYS_BUS_DEVICE(&s->timer[devinfo->index]);
60
61
- qdev_connect_clock_in(DEVICE(sbd), "pclk", s->mainclk);
62
+ qdev_connect_clock_in(DEVICE(sbd), "pclk",
63
+ devinfo->slowclk ? s->s32kclk : s->mainclk);
64
if (!sysbus_realize(sbd, errp)) {
65
return;
66
}
67
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
68
}
69
}
70
71
- /* 0x40020000 .. 0x4002ffff : ARMSSE system control peripheral region */
72
- /* Devices behind APB PPC1:
73
- * 0x4002f000: S32K timer
74
- */
75
- qdev_connect_clock_in(DEVICE(&s->s32ktimer), "pclk", s->s32kclk);
76
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->s32ktimer), errp)) {
77
- return;
78
- }
79
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32ktimer), 0,
80
- armsse_get_common_irq_in(s, 2));
81
- mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->s32ktimer), 0);
82
- object_property_set_link(OBJECT(&s->apb_ppc[1]), "port[0]", OBJECT(mr),
83
- &error_abort);
84
-
85
if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc[1]), errp)) {
86
return;
87
}
88
- mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->apb_ppc[1]), 0);
89
- memory_region_add_subregion(&s->container, 0x4002f000, mr);
90
91
dev_apb_ppc1 = DEVICE(&s->apb_ppc[1]);
92
qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_nonsec", 0,
93
--
94
2.20.1
95
96
diff view generated by jsdifflib
New patch
1
Move the sysinfo register block into the data-driven framework.
1
2
3
While we are moving the code for configuring this device around,
4
regularize on using &error_abortw when setting the integer
5
properties: they are all simple DEFINE_PROP_UINT32 properties so the
6
setting can never fail.
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20210219144617.4782-28-peter.maydell@linaro.org
12
---
13
hw/arm/armsse.c | 47 ++++++++++++++++++++++++++++-------------------
14
1 file changed, 28 insertions(+), 19 deletions(-)
15
16
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/armsse.c
19
+++ b/hw/arm/armsse.c
20
@@ -XXX,XX +XXX,XX @@ static const ARMSSEDeviceInfo sse200_devices[] = {
21
.ppc = NO_PPC,
22
.irq = NMI_1,
23
},
24
+ {
25
+ .name = "armsse-sysinfo",
26
+ .type = TYPE_IOTKIT_SYSINFO,
27
+ .index = 0,
28
+ .addr = 0x40020000,
29
+ .ppc = NO_PPC,
30
+ .irq = NO_IRQ,
31
+ },
32
{
33
.name = NULL,
34
}
35
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
36
object_initialize_child(obj, devinfo->name,
37
&s->cmsdk_watchdog[devinfo->index],
38
TYPE_CMSDK_APB_WATCHDOG);
39
+ } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSINFO)) {
40
+ assert(devinfo->index == 0);
41
+ object_initialize_child(obj, devinfo->name, &s->sysinfo,
42
+ TYPE_IOTKIT_SYSINFO);
43
} else {
44
g_assert_not_reached();
45
}
46
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
47
48
object_initialize_child(obj, "armsse-sysctl", &s->sysctl,
49
TYPE_IOTKIT_SYSCTL);
50
- object_initialize_child(obj, "armsse-sysinfo", &s->sysinfo,
51
- TYPE_IOTKIT_SYSINFO);
52
if (info->has_mhus) {
53
object_initialize_child(obj, "mhu0", &s->mhu[0], TYPE_ARMSSE_MHU);
54
object_initialize_child(obj, "mhu1", &s->mhu[1], TYPE_ARMSSE_MHU);
55
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
56
return;
57
}
58
mr = sysbus_mmio_get_region(sbd, 0);
59
+ } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSINFO)) {
60
+ sbd = SYS_BUS_DEVICE(&s->sysinfo);
61
+
62
+ object_property_set_int(OBJECT(&s->sysinfo), "SYS_VERSION",
63
+ info->sys_version, &error_abort);
64
+ object_property_set_int(OBJECT(&s->sysinfo), "SYS_CONFIG",
65
+ armsse_sys_config_value(s, info),
66
+ &error_abort);
67
+ object_property_set_int(OBJECT(&s->sysinfo), "sse-version",
68
+ info->sse_version, &error_abort);
69
+ object_property_set_int(OBJECT(&s->sysinfo), "IIDR",
70
+ info->iidr, &error_abort);
71
+ if (!sysbus_realize(sbd, errp)) {
72
+ return;
73
+ }
74
+ mr = sysbus_mmio_get_region(sbd, 0);
75
} else {
76
g_assert_not_reached();
77
}
78
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
79
memory_region_add_subregion(&s->container, devinfo->addr, mr);
80
}
81
82
- if (!object_property_set_int(OBJECT(&s->sysinfo), "SYS_VERSION",
83
- info->sys_version, errp)) {
84
- return;
85
- }
86
- if (!object_property_set_int(OBJECT(&s->sysinfo), "SYS_CONFIG",
87
- armsse_sys_config_value(s, info), errp)) {
88
- return;
89
- }
90
- object_property_set_int(OBJECT(&s->sysinfo), "sse-version",
91
- info->sse_version, &error_abort);
92
- object_property_set_int(OBJECT(&s->sysinfo), "IIDR",
93
- info->iidr, &error_abort);
94
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->sysinfo), errp)) {
95
- return;
96
- }
97
- /* System information registers */
98
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysinfo), 0, 0x40020000);
99
/* System control registers */
100
object_property_set_int(OBJECT(&s->sysctl), "sse-version",
101
info->sse_version, &error_abort);
102
--
103
2.20.1
104
105
diff view generated by jsdifflib
New patch
1
Move the sysctl register block into the data-driven device placement
2
framework.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210219144617.4782-29-peter.maydell@linaro.org
8
---
9
hw/arm/armsse.c | 44 ++++++++++++++++++++++++++++----------------
10
1 file changed, 28 insertions(+), 16 deletions(-)
11
12
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/armsse.c
15
+++ b/hw/arm/armsse.c
16
@@ -XXX,XX +XXX,XX @@ static const ARMSSEDeviceInfo sse200_devices[] = {
17
.ppc = NO_PPC,
18
.irq = NO_IRQ,
19
},
20
+ {
21
+ .name = "armsse-sysctl",
22
+ .type = TYPE_IOTKIT_SYSCTL,
23
+ .index = 0,
24
+ .addr = 0x50021000,
25
+ .ppc = NO_PPC,
26
+ .irq = NO_IRQ,
27
+ },
28
{
29
.name = NULL,
30
}
31
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
32
assert(devinfo->index == 0);
33
object_initialize_child(obj, devinfo->name, &s->sysinfo,
34
TYPE_IOTKIT_SYSINFO);
35
+ } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSCTL)) {
36
+ assert(devinfo->index == 0);
37
+ object_initialize_child(obj, devinfo->name, &s->sysctl,
38
+ TYPE_IOTKIT_SYSCTL);
39
} else {
40
g_assert_not_reached();
41
}
42
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
43
g_free(name);
44
}
45
46
- object_initialize_child(obj, "armsse-sysctl", &s->sysctl,
47
- TYPE_IOTKIT_SYSCTL);
48
if (info->has_mhus) {
49
object_initialize_child(obj, "mhu0", &s->mhu[0], TYPE_ARMSSE_MHU);
50
object_initialize_child(obj, "mhu1", &s->mhu[1], TYPE_ARMSSE_MHU);
51
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
52
return;
53
}
54
mr = sysbus_mmio_get_region(sbd, 0);
55
+ } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSCTL)) {
56
+ /* System control registers */
57
+ sbd = SYS_BUS_DEVICE(&s->sysctl);
58
+
59
+ object_property_set_int(OBJECT(&s->sysctl), "sse-version",
60
+ info->sse_version, &error_abort);
61
+ object_property_set_int(OBJECT(&s->sysctl), "CPUWAIT_RST",
62
+ info->cpuwait_rst, &error_abort);
63
+ object_property_set_int(OBJECT(&s->sysctl), "INITSVTOR0_RST",
64
+ s->init_svtor, &error_abort);
65
+ object_property_set_int(OBJECT(&s->sysctl), "INITSVTOR1_RST",
66
+ s->init_svtor, &error_abort);
67
+ if (!sysbus_realize(sbd, errp)) {
68
+ return;
69
+ }
70
+ mr = sysbus_mmio_get_region(sbd, 0);
71
} else {
72
g_assert_not_reached();
73
}
74
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
75
memory_region_add_subregion(&s->container, devinfo->addr, mr);
76
}
77
78
- /* System control registers */
79
- object_property_set_int(OBJECT(&s->sysctl), "sse-version",
80
- info->sse_version, &error_abort);
81
- object_property_set_int(OBJECT(&s->sysctl), "CPUWAIT_RST",
82
- info->cpuwait_rst, &error_abort);
83
- object_property_set_int(OBJECT(&s->sysctl), "INITSVTOR0_RST",
84
- s->init_svtor, &error_abort);
85
- object_property_set_int(OBJECT(&s->sysctl), "INITSVTOR1_RST",
86
- s->init_svtor, &error_abort);
87
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->sysctl), errp)) {
88
- return;
89
- }
90
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysctl), 0, 0x50021000);
91
-
92
if (info->has_ppus) {
93
/* CPUnCORE_PPU for each CPU */
94
for (i = 0; i < info->num_cpus; i++) {
95
--
96
2.20.1
97
98
diff view generated by jsdifflib
New patch
1
1
Move the PPUs into the data-driven device placement framework.
2
We don't implement them, so they are just TYPE_UNIMPLEMENTED stubs.
3
4
Because the SSE-200 and the IotKit diverge here (the IoTKit does
5
not have the PPUs) we need to separate out the ARMSSEDeviceInfo
6
for the two variants, and only add the PPUs to the SSE-200.
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20210219144617.4782-30-peter.maydell@linaro.org
12
---
13
include/hw/arm/armsse.h | 10 +-
14
hw/arm/armsse.c | 222 +++++++++++++++++++++++++++++-----------
15
2 files changed, 165 insertions(+), 67 deletions(-)
16
17
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/armsse.h
20
+++ b/include/hw/arm/armsse.h
21
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(ARMSSE, ARMSSEClass,
22
23
#define SSE_MAX_CPUS 2
24
25
-/* These define what each PPU in the ppu[] index is for */
26
-#define CPU0CORE_PPU 0
27
-#define CPU1CORE_PPU 1
28
-#define DBG_PPU 2
29
-#define RAM0_PPU 3
30
-#define RAM1_PPU 4
31
-#define RAM2_PPU 5
32
-#define RAM3_PPU 6
33
#define NUM_PPUS 7
34
35
/* Number of CPU IRQs used by the SSE itself */
36
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
37
IoTKitSysCtl sysinfo;
38
39
ARMSSEMHU mhu[2];
40
- UnimplementedDeviceState ppu[NUM_PPUS];
41
+ UnimplementedDeviceState unimp[NUM_PPUS];
42
UnimplementedDeviceState cachectrl[SSE_MAX_CPUS];
43
UnimplementedDeviceState cpusecctrl[SSE_MAX_CPUS];
44
45
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/arm/armsse.c
48
+++ b/hw/arm/armsse.c
49
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSEDeviceInfo {
50
const char *type; /* QOM type name */
51
unsigned int index; /* Which of the N devices of this type is this ? */
52
hwaddr addr;
53
+ hwaddr size; /* only needed for TYPE_UNIMPLEMENTED_DEVICE */
54
int ppc; /* Index of APB PPC this device is wired up to, or NO_PPC */
55
int ppc_port; /* Port number of this device on the PPC */
56
int irq; /* NO_IRQ, or 0..NUM_SSE_IRQS-1, or NMI_0 or NMI_1 */
57
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
58
uint32_t iidr;
59
uint32_t cpuwait_rst;
60
bool has_mhus;
61
- bool has_ppus;
62
bool has_cachectrl;
63
bool has_cpusecctrl;
64
bool has_cpuid;
65
@@ -XXX,XX +XXX,XX @@ static Property armsse_properties[] = {
66
DEFINE_PROP_END_OF_LIST()
67
};
68
69
-static const ARMSSEDeviceInfo sse200_devices[] = {
70
+static const ARMSSEDeviceInfo iotkit_devices[] = {
71
{
72
.name = "timer0",
73
.type = TYPE_CMSDK_APB_TIMER,
74
@@ -XXX,XX +XXX,XX @@ static const ARMSSEDeviceInfo sse200_devices[] = {
75
}
76
};
77
78
+static const ARMSSEDeviceInfo sse200_devices[] = {
79
+ {
80
+ .name = "timer0",
81
+ .type = TYPE_CMSDK_APB_TIMER,
82
+ .index = 0,
83
+ .addr = 0x40000000,
84
+ .ppc = 0,
85
+ .ppc_port = 0,
86
+ .irq = 3,
87
+ },
88
+ {
89
+ .name = "timer1",
90
+ .type = TYPE_CMSDK_APB_TIMER,
91
+ .index = 1,
92
+ .addr = 0x40001000,
93
+ .ppc = 0,
94
+ .ppc_port = 1,
95
+ .irq = 4,
96
+ },
97
+ {
98
+ .name = "s32ktimer",
99
+ .type = TYPE_CMSDK_APB_TIMER,
100
+ .index = 2,
101
+ .addr = 0x4002f000,
102
+ .ppc = 1,
103
+ .ppc_port = 0,
104
+ .irq = 2,
105
+ .slowclk = true,
106
+ },
107
+ {
108
+ .name = "dualtimer",
109
+ .type = TYPE_CMSDK_APB_DUALTIMER,
110
+ .index = 0,
111
+ .addr = 0x40002000,
112
+ .ppc = 0,
113
+ .ppc_port = 2,
114
+ .irq = 5,
115
+ },
116
+ {
117
+ .name = "s32kwatchdog",
118
+ .type = TYPE_CMSDK_APB_WATCHDOG,
119
+ .index = 0,
120
+ .addr = 0x5002e000,
121
+ .ppc = NO_PPC,
122
+ .irq = NMI_0,
123
+ .slowclk = true,
124
+ },
125
+ {
126
+ .name = "nswatchdog",
127
+ .type = TYPE_CMSDK_APB_WATCHDOG,
128
+ .index = 1,
129
+ .addr = 0x40081000,
130
+ .ppc = NO_PPC,
131
+ .irq = 1,
132
+ },
133
+ {
134
+ .name = "swatchdog",
135
+ .type = TYPE_CMSDK_APB_WATCHDOG,
136
+ .index = 2,
137
+ .addr = 0x50081000,
138
+ .ppc = NO_PPC,
139
+ .irq = NMI_1,
140
+ },
141
+ {
142
+ .name = "armsse-sysinfo",
143
+ .type = TYPE_IOTKIT_SYSINFO,
144
+ .index = 0,
145
+ .addr = 0x40020000,
146
+ .ppc = NO_PPC,
147
+ .irq = NO_IRQ,
148
+ },
149
+ {
150
+ .name = "armsse-sysctl",
151
+ .type = TYPE_IOTKIT_SYSCTL,
152
+ .index = 0,
153
+ .addr = 0x50021000,
154
+ .ppc = NO_PPC,
155
+ .irq = NO_IRQ,
156
+ },
157
+ {
158
+ .name = "CPU0CORE_PPU",
159
+ .type = TYPE_UNIMPLEMENTED_DEVICE,
160
+ .index = 0,
161
+ .addr = 0x50023000,
162
+ .size = 0x1000,
163
+ .ppc = NO_PPC,
164
+ .irq = NO_IRQ,
165
+ },
166
+ {
167
+ .name = "CPU1CORE_PPU",
168
+ .type = TYPE_UNIMPLEMENTED_DEVICE,
169
+ .index = 1,
170
+ .addr = 0x50025000,
171
+ .size = 0x1000,
172
+ .ppc = NO_PPC,
173
+ .irq = NO_IRQ,
174
+ },
175
+ {
176
+ .name = "DBG_PPU",
177
+ .type = TYPE_UNIMPLEMENTED_DEVICE,
178
+ .index = 2,
179
+ .addr = 0x50029000,
180
+ .size = 0x1000,
181
+ .ppc = NO_PPC,
182
+ .irq = NO_IRQ,
183
+ },
184
+ {
185
+ .name = "RAM0_PPU",
186
+ .type = TYPE_UNIMPLEMENTED_DEVICE,
187
+ .index = 3,
188
+ .addr = 0x5002a000,
189
+ .size = 0x1000,
190
+ .ppc = NO_PPC,
191
+ .irq = NO_IRQ,
192
+ },
193
+ {
194
+ .name = "RAM1_PPU",
195
+ .type = TYPE_UNIMPLEMENTED_DEVICE,
196
+ .index = 4,
197
+ .addr = 0x5002b000,
198
+ .size = 0x1000,
199
+ .ppc = NO_PPC,
200
+ .irq = NO_IRQ,
201
+ },
202
+ {
203
+ .name = "RAM2_PPU",
204
+ .type = TYPE_UNIMPLEMENTED_DEVICE,
205
+ .index = 5,
206
+ .addr = 0x5002c000,
207
+ .size = 0x1000,
208
+ .ppc = NO_PPC,
209
+ .irq = NO_IRQ,
210
+ },
211
+ {
212
+ .name = "RAM3_PPU",
213
+ .type = TYPE_UNIMPLEMENTED_DEVICE,
214
+ .index = 6,
215
+ .addr = 0x5002d000,
216
+ .size = 0x1000,
217
+ .ppc = NO_PPC,
218
+ .irq = NO_IRQ,
219
+ },
220
+ {
221
+ .name = NULL,
222
+ }
223
+};
224
+
225
static const ARMSSEInfo armsse_variants[] = {
226
{
227
.name = TYPE_IOTKIT,
228
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
229
.iidr = 0,
230
.cpuwait_rst = 0,
231
.has_mhus = false,
232
- .has_ppus = false,
233
.has_cachectrl = false,
234
.has_cpusecctrl = false,
235
.has_cpuid = false,
236
.props = iotkit_properties,
237
- .devinfo = sse200_devices,
238
+ .devinfo = iotkit_devices,
239
},
240
{
241
.name = TYPE_SSE200,
242
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
243
.iidr = 0,
244
.cpuwait_rst = 2,
245
.has_mhus = true,
246
- .has_ppus = true,
247
.has_cachectrl = true,
248
.has_cpusecctrl = true,
249
.has_cpuid = true,
250
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
251
assert(devinfo->index == 0);
252
object_initialize_child(obj, devinfo->name, &s->sysctl,
253
TYPE_IOTKIT_SYSCTL);
254
+ } else if (!strcmp(devinfo->type, TYPE_UNIMPLEMENTED_DEVICE)) {
255
+ assert(devinfo->index < ARRAY_SIZE(s->unimp));
256
+ object_initialize_child(obj, devinfo->name,
257
+ &s->unimp[devinfo->index],
258
+ TYPE_UNIMPLEMENTED_DEVICE);
259
} else {
260
g_assert_not_reached();
261
}
262
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
263
object_initialize_child(obj, "mhu0", &s->mhu[0], TYPE_ARMSSE_MHU);
264
object_initialize_child(obj, "mhu1", &s->mhu[1], TYPE_ARMSSE_MHU);
265
}
266
- if (info->has_ppus) {
267
- for (i = 0; i < info->num_cpus; i++) {
268
- char *name = g_strdup_printf("CPU%dCORE_PPU", i);
269
- int ppuidx = CPU0CORE_PPU + i;
270
-
271
- object_initialize_child(obj, name, &s->ppu[ppuidx],
272
- TYPE_UNIMPLEMENTED_DEVICE);
273
- g_free(name);
274
- }
275
- object_initialize_child(obj, "DBG_PPU", &s->ppu[DBG_PPU],
276
- TYPE_UNIMPLEMENTED_DEVICE);
277
- for (i = 0; i < info->sram_banks; i++) {
278
- char *name = g_strdup_printf("RAM%d_PPU", i);
279
- int ppuidx = RAM0_PPU + i;
280
-
281
- object_initialize_child(obj, name, &s->ppu[ppuidx],
282
- TYPE_UNIMPLEMENTED_DEVICE);
283
- g_free(name);
284
- }
285
- }
286
if (info->has_cachectrl) {
287
for (i = 0; i < info->num_cpus; i++) {
288
char *name = g_strdup_printf("cachectrl%d", i);
289
@@ -XXX,XX +XXX,XX @@ static qemu_irq armsse_get_common_irq_in(ARMSSE *s, int irqno)
290
}
291
}
292
293
-static void map_ppu(ARMSSE *s, int ppuidx, const char *name, hwaddr addr)
294
-{
295
- /* Map a PPU unimplemented device stub */
296
- DeviceState *dev = DEVICE(&s->ppu[ppuidx]);
297
-
298
- qdev_prop_set_string(dev, "name", name);
299
- qdev_prop_set_uint64(dev, "size", 0x1000);
300
- sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
301
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->ppu[ppuidx]), 0, addr);
302
-}
303
-
304
static void armsse_realize(DeviceState *dev, Error **errp)
305
{
306
ARMSSE *s = ARM_SSE(dev);
307
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
308
return;
309
}
310
mr = sysbus_mmio_get_region(sbd, 0);
311
+ } else if (!strcmp(devinfo->type, TYPE_UNIMPLEMENTED_DEVICE)) {
312
+ sbd = SYS_BUS_DEVICE(&s->unimp[devinfo->index]);
313
+
314
+ qdev_prop_set_string(DEVICE(sbd), "name", devinfo->name);
315
+ qdev_prop_set_uint64(DEVICE(sbd), "size", devinfo->size);
316
+ if (!sysbus_realize(sbd, errp)) {
317
+ return;
318
+ }
319
+ mr = sysbus_mmio_get_region(sbd, 0);
320
} else {
321
g_assert_not_reached();
322
}
323
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
324
memory_region_add_subregion(&s->container, devinfo->addr, mr);
325
}
326
327
- if (info->has_ppus) {
328
- /* CPUnCORE_PPU for each CPU */
329
- for (i = 0; i < info->num_cpus; i++) {
330
- char *name = g_strdup_printf("CPU%dCORE_PPU", i);
331
-
332
- map_ppu(s, CPU0CORE_PPU + i, name, 0x50023000 + i * 0x2000);
333
- /*
334
- * We don't support CPU debug so don't create the
335
- * CPU0DEBUG_PPU at 0x50024000 and 0x50026000.
336
- */
337
- g_free(name);
338
- }
339
- map_ppu(s, DBG_PPU, "DBG_PPU", 0x50029000);
340
-
341
- for (i = 0; i < info->sram_banks; i++) {
342
- char *name = g_strdup_printf("RAM%d_PPU", i);
343
-
344
- map_ppu(s, RAM0_PPU + i, name, 0x5002a000 + i * 0x1000);
345
- g_free(name);
346
- }
347
- }
348
-
349
for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
350
Object *splitter = OBJECT(&s->ppc_irq_splitter[i]);
351
352
--
353
2.20.1
354
355
diff view generated by jsdifflib
New patch
1
We forgot to implement a TYPE_UNIMPLEMENTED_DEVICE stub
2
for the SYS_PPU in the SSE-200, which is at 0x50022000.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210219144617.4782-31-peter.maydell@linaro.org
8
---
9
include/hw/arm/armsse.h | 2 +-
10
hw/arm/armsse.c | 9 +++++++++
11
2 files changed, 10 insertions(+), 1 deletion(-)
12
13
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/arm/armsse.h
16
+++ b/include/hw/arm/armsse.h
17
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(ARMSSE, ARMSSEClass,
18
19
#define SSE_MAX_CPUS 2
20
21
-#define NUM_PPUS 7
22
+#define NUM_PPUS 8
23
24
/* Number of CPU IRQs used by the SSE itself */
25
#define NUM_SSE_IRQS 32
26
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/arm/armsse.c
29
+++ b/hw/arm/armsse.c
30
@@ -XXX,XX +XXX,XX @@ static const ARMSSEDeviceInfo sse200_devices[] = {
31
.ppc = NO_PPC,
32
.irq = NO_IRQ,
33
},
34
+ {
35
+ .name = "SYS_PPU",
36
+ .type = TYPE_UNIMPLEMENTED_DEVICE,
37
+ .index = 7,
38
+ .addr = 0x50022000,
39
+ .size = 0x1000,
40
+ .ppc = NO_PPC,
41
+ .irq = NO_IRQ,
42
+ },
43
{
44
.name = NULL,
45
}
46
--
47
2.20.1
48
49
diff view generated by jsdifflib
New patch
1
The SSE-300 has a slightly different set of shared-per-CPU interrupts,
2
allow the irq_is_common[] array to be different per SSE variant.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210219144617.4782-32-peter.maydell@linaro.org
9
---
10
hw/arm/armsse.c | 39 +++++++++++++++++++++------------------
11
1 file changed, 21 insertions(+), 18 deletions(-)
12
13
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/armsse.c
16
+++ b/hw/arm/armsse.c
17
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
18
bool has_cpuid;
19
Property *props;
20
const ARMSSEDeviceInfo *devinfo;
21
+ const bool *irq_is_common;
22
};
23
24
static Property iotkit_properties[] = {
25
@@ -XXX,XX +XXX,XX @@ static const ARMSSEDeviceInfo sse200_devices[] = {
26
}
27
};
28
29
+/* Is internal IRQ n shared between CPUs in a multi-core SSE ? */
30
+static const bool sse200_irq_is_common[32] = {
31
+ [0 ... 5] = true,
32
+ /* 6, 7: per-CPU MHU interrupts */
33
+ [8 ... 12] = true,
34
+ /* 13: per-CPU icache interrupt */
35
+ /* 14: reserved */
36
+ [15 ... 20] = true,
37
+ /* 21: reserved */
38
+ [22 ... 26] = true,
39
+ /* 27: reserved */
40
+ /* 28, 29: per-CPU CTI interrupts */
41
+ /* 30, 31: reserved */
42
+};
43
+
44
static const ARMSSEInfo armsse_variants[] = {
45
{
46
.name = TYPE_IOTKIT,
47
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
48
.has_cpuid = false,
49
.props = iotkit_properties,
50
.devinfo = iotkit_devices,
51
+ .irq_is_common = sse200_irq_is_common,
52
},
53
{
54
.name = TYPE_SSE200,
55
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
56
.has_cpuid = true,
57
.props = armsse_properties,
58
.devinfo = sse200_devices,
59
+ .irq_is_common = sse200_irq_is_common,
60
},
61
};
62
63
@@ -XXX,XX +XXX,XX @@ static uint32_t armsse_sys_config_value(ARMSSE *s, const ARMSSEInfo *info)
64
/* Clock frequency in HZ of the 32KHz "slow clock" */
65
#define S32KCLK (32 * 1000)
66
67
-/* Is internal IRQ n shared between CPUs in a multi-core SSE ? */
68
-static bool irq_is_common[32] = {
69
- [0 ... 5] = true,
70
- /* 6, 7: per-CPU MHU interrupts */
71
- [8 ... 12] = true,
72
- /* 13: per-CPU icache interrupt */
73
- /* 14: reserved */
74
- [15 ... 20] = true,
75
- /* 21: reserved */
76
- [22 ... 26] = true,
77
- /* 27: reserved */
78
- /* 28, 29: per-CPU CTI interrupts */
79
- /* 30, 31: reserved */
80
-};
81
-
82
/*
83
* Create an alias region in @container of @size bytes starting at @base
84
* which mirrors the memory starting at @orig.
85
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
86
}
87
if (info->num_cpus > 1) {
88
for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
89
- if (irq_is_common[i]) {
90
+ if (info->irq_is_common[i]) {
91
char *name = g_strdup_printf("cpu-irq-splitter%d", i);
92
SplitIRQ *splitter = &s->cpu_irq_splitter[i];
93
94
@@ -XXX,XX +XXX,XX @@ static qemu_irq armsse_get_common_irq_in(ARMSSE *s, int irqno)
95
ARMSSEClass *asc = ARM_SSE_GET_CLASS(s);
96
const ARMSSEInfo *info = asc->info;
97
98
- assert(irq_is_common[irqno]);
99
+ assert(info->irq_is_common[irqno]);
100
101
if (info->num_cpus == 1) {
102
/* Only one CPU -- just connect directly to it */
103
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
104
/* Wire up the splitters that connect common IRQs to all CPUs */
105
if (info->num_cpus > 1) {
106
for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
107
- if (irq_is_common[i]) {
108
+ if (info->irq_is_common[i]) {
109
Object *splitter = OBJECT(&s->cpu_irq_splitter[i]);
110
DeviceState *devs = DEVICE(splitter);
111
int cpunum;
112
--
113
2.20.1
114
115
diff view generated by jsdifflib
New patch
1
The SSE-300 has a system counter device; add support for SSE
2
variants having this device.
1
3
4
As with the existing devices like the cache control block, CPUID
5
block, etc, we don't try to make the MMIO addresses configurable. We
6
can do that if and when we need to model a future SSE variant which
7
has the counter in a different location.
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210219144617.4782-33-peter.maydell@linaro.org
13
---
14
include/hw/arm/armsse.h | 3 +++
15
hw/arm/armsse.c | 27 +++++++++++++++++++++++++++
16
2 files changed, 30 insertions(+)
17
18
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/armsse.h
21
+++ b/include/hw/arm/armsse.h
22
@@ -XXX,XX +XXX,XX @@
23
#include "hw/misc/tz-mpc.h"
24
#include "hw/timer/cmsdk-apb-timer.h"
25
#include "hw/timer/cmsdk-apb-dualtimer.h"
26
+#include "hw/timer/sse-counter.h"
27
#include "hw/watchdog/cmsdk-apb-watchdog.h"
28
#include "hw/misc/iotkit-sysctl.h"
29
#include "hw/misc/iotkit-sysinfo.h"
30
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
31
32
CMSDKAPBWatchdog cmsdk_watchdog[3];
33
34
+ SSECounter sse_counter;
35
+
36
IoTKitSysCtl sysctl;
37
IoTKitSysCtl sysinfo;
38
39
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/arm/armsse.c
42
+++ b/hw/arm/armsse.c
43
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
44
bool has_cachectrl;
45
bool has_cpusecctrl;
46
bool has_cpuid;
47
+ bool has_sse_counter;
48
Property *props;
49
const ARMSSEDeviceInfo *devinfo;
50
const bool *irq_is_common;
51
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
52
.has_cachectrl = false,
53
.has_cpusecctrl = false,
54
.has_cpuid = false,
55
+ .has_sse_counter = false,
56
.props = iotkit_properties,
57
.devinfo = iotkit_devices,
58
.irq_is_common = sse200_irq_is_common,
59
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
60
.has_cachectrl = true,
61
.has_cpusecctrl = true,
62
.has_cpuid = true,
63
+ .has_sse_counter = false,
64
.props = armsse_properties,
65
.devinfo = sse200_devices,
66
.irq_is_common = sse200_irq_is_common,
67
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
68
g_free(name);
69
}
70
}
71
+ if (info->has_sse_counter) {
72
+ object_initialize_child(obj, "sse-counter", &s->sse_counter,
73
+ TYPE_SSE_COUNTER);
74
+ }
75
+
76
object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate, TYPE_OR_IRQ);
77
object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate,
78
TYPE_OR_IRQ);
79
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
80
qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
81
qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
82
83
+ /* The SSE-300 has a System Counter / System Timestamp Generator */
84
+ if (info->has_sse_counter) {
85
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->sse_counter);
86
+
87
+ qdev_connect_clock_in(DEVICE(sbd), "CLK", s->mainclk);
88
+ if (!sysbus_realize(sbd, errp)) {
89
+ return;
90
+ }
91
+ /*
92
+ * The control frame is only in the Secure region;
93
+ * the status frame is in the NS region (and visible in the
94
+ * S region via the alias mapping).
95
+ */
96
+ memory_region_add_subregion(&s->container, 0x58100000,
97
+ sysbus_mmio_get_region(sbd, 0));
98
+ memory_region_add_subregion(&s->container, 0x48101000,
99
+ sysbus_mmio_get_region(sbd, 1));
100
+ }
101
+
102
/* Devices behind APB PPC0:
103
* 0x40000000: timer0
104
* 0x40001000: timer1
105
--
106
2.20.1
107
108
diff view generated by jsdifflib
New patch
1
The SSE-300 has four timers of type TYPE_SSE_TIMER; add support in
2
the code for having these in an ARMSSEDeviceInfo array.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210219144617.4782-34-peter.maydell@linaro.org
9
---
10
include/hw/arm/armsse.h | 2 ++
11
hw/arm/armsse.c | 15 +++++++++++++++
12
2 files changed, 17 insertions(+)
13
14
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/armsse.h
17
+++ b/include/hw/arm/armsse.h
18
@@ -XXX,XX +XXX,XX @@
19
#include "hw/timer/cmsdk-apb-timer.h"
20
#include "hw/timer/cmsdk-apb-dualtimer.h"
21
#include "hw/timer/sse-counter.h"
22
+#include "hw/timer/sse-timer.h"
23
#include "hw/watchdog/cmsdk-apb-watchdog.h"
24
#include "hw/misc/iotkit-sysctl.h"
25
#include "hw/misc/iotkit-sysinfo.h"
26
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
27
CMSDKAPBWatchdog cmsdk_watchdog[3];
28
29
SSECounter sse_counter;
30
+ SSETimer sse_timer[4];
31
32
IoTKitSysCtl sysctl;
33
IoTKitSysCtl sysinfo;
34
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/arm/armsse.c
37
+++ b/hw/arm/armsse.c
38
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
39
assert(devinfo->index == 0);
40
object_initialize_child(obj, devinfo->name, &s->dualtimer,
41
TYPE_CMSDK_APB_DUALTIMER);
42
+ } else if (!strcmp(devinfo->type, TYPE_SSE_TIMER)) {
43
+ assert(devinfo->index < ARRAY_SIZE(s->sse_timer));
44
+ object_initialize_child(obj, devinfo->name,
45
+ &s->sse_timer[devinfo->index],
46
+ TYPE_SSE_TIMER);
47
} else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_WATCHDOG)) {
48
assert(devinfo->index < ARRAY_SIZE(s->cmsdk_watchdog));
49
object_initialize_child(obj, devinfo->name,
50
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
51
return;
52
}
53
mr = sysbus_mmio_get_region(sbd, 0);
54
+ } else if (!strcmp(devinfo->type, TYPE_SSE_TIMER)) {
55
+ sbd = SYS_BUS_DEVICE(&s->sse_timer[devinfo->index]);
56
+
57
+ assert(info->has_sse_counter);
58
+ object_property_set_link(OBJECT(sbd), "counter",
59
+ OBJECT(&s->sse_counter), &error_abort);
60
+ if (!sysbus_realize(sbd, errp)) {
61
+ return;
62
+ }
63
+ mr = sysbus_mmio_get_region(sbd, 0);
64
} else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_WATCHDOG)) {
65
sbd = SYS_BUS_DEVICE(&s->cmsdk_watchdog[devinfo->index]);
66
67
--
68
2.20.1
69
70
diff view generated by jsdifflib
New patch
1
Support SSE variants like the SSE-300 with an ARMSSE_CPU_PWRCTRL register
2
block. Because this block is per-CPU and does not clash with any of the
3
SSE-200 devices, we handle it with a has_cpu_pwrctrl flag like the
4
existing has_cachectrl, has_cpusectrl and has_cpuid, rather than
5
trying to add per-CPU-device support to the devinfo array handling code.
1
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210219144617.4782-35-peter.maydell@linaro.org
11
---
12
include/hw/arm/armsse.h | 3 +++
13
hw/arm/armsse.c | 26 ++++++++++++++++++++++++++
14
2 files changed, 29 insertions(+)
15
16
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/armsse.h
19
+++ b/include/hw/arm/armsse.h
20
@@ -XXX,XX +XXX,XX @@
21
#include "hw/misc/iotkit-sysinfo.h"
22
#include "hw/misc/armsse-cpuid.h"
23
#include "hw/misc/armsse-mhu.h"
24
+#include "hw/misc/armsse-cpu-pwrctrl.h"
25
#include "hw/misc/unimp.h"
26
#include "hw/or-irq.h"
27
#include "hw/clock.h"
28
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
29
30
ARMSSECPUID cpuid[SSE_MAX_CPUS];
31
32
+ ARMSSECPUPwrCtrl cpu_pwrctrl[SSE_MAX_CPUS];
33
+
34
/*
35
* 'container' holds all devices seen by all CPUs.
36
* 'cpu_container[i]' is the view that CPU i has: this has the
37
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/arm/armsse.c
40
+++ b/hw/arm/armsse.c
41
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
42
bool has_cachectrl;
43
bool has_cpusecctrl;
44
bool has_cpuid;
45
+ bool has_cpu_pwrctrl;
46
bool has_sse_counter;
47
Property *props;
48
const ARMSSEDeviceInfo *devinfo;
49
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
50
.has_cachectrl = false,
51
.has_cpusecctrl = false,
52
.has_cpuid = false,
53
+ .has_cpu_pwrctrl = false,
54
.has_sse_counter = false,
55
.props = iotkit_properties,
56
.devinfo = iotkit_devices,
57
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
58
.has_cachectrl = true,
59
.has_cpusecctrl = true,
60
.has_cpuid = true,
61
+ .has_cpu_pwrctrl = false,
62
.has_sse_counter = false,
63
.props = armsse_properties,
64
.devinfo = sse200_devices,
65
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
66
g_free(name);
67
}
68
}
69
+ if (info->has_cpu_pwrctrl) {
70
+ for (i = 0; i < info->num_cpus; i++) {
71
+ char *name = g_strdup_printf("cpu_pwrctrl%d", i);
72
+
73
+ object_initialize_child(obj, name, &s->cpu_pwrctrl[i],
74
+ TYPE_ARMSSE_CPU_PWRCTRL);
75
+ g_free(name);
76
+ }
77
+ }
78
if (info->has_sse_counter) {
79
object_initialize_child(obj, "sse-counter", &s->sse_counter,
80
TYPE_SSE_COUNTER);
81
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
82
* 0x50010000: L1 icache control registers
83
* 0x50011000: CPUSECCTRL (CPU local security control registers)
84
* 0x4001f000 and 0x5001f000: CPU_IDENTITY register block
85
+ * The SSE-300 has an extra:
86
+ * 0x40012000 and 0x50012000: CPU_PWRCTRL register block
87
*/
88
if (info->has_cachectrl) {
89
for (i = 0; i < info->num_cpus; i++) {
90
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
91
memory_region_add_subregion(&s->cpu_container[i], 0x4001F000, mr);
92
}
93
}
94
+ if (info->has_cpu_pwrctrl) {
95
+ for (i = 0; i < info->num_cpus; i++) {
96
+ MemoryRegion *mr;
97
+
98
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpu_pwrctrl[i]), errp)) {
99
+ return;
100
+ }
101
+
102
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpu_pwrctrl[i]), 0);
103
+ memory_region_add_subregion(&s->cpu_container[i], 0x40012000, mr);
104
+ }
105
+ }
106
107
if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc[1]), errp)) {
108
return;
109
--
110
2.20.1
111
112
diff view generated by jsdifflib
New patch
1
1
Now we have sufficiently parameterised the code, we can add SSE-300
2
support by adding a new entry to the armsse_variants[] array.
3
4
Note that the main watchdog (unlike the s32k watchdog) in the SSE-300
5
is a different device from the CMSDK watchdog; we don't have a model
6
of it so we leave it as a TYPE_UNIMPLEMENTED_DEVICE stub.
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20210219144617.4782-36-peter.maydell@linaro.org
12
---
13
include/hw/arm/armsse.h | 1 +
14
hw/arm/armsse.c | 152 ++++++++++++++++++++++++++++++++++++++++
15
2 files changed, 153 insertions(+)
16
17
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/armsse.h
20
+++ b/include/hw/arm/armsse.h
21
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(ARMSSE, ARMSSEClass,
22
*/
23
#define TYPE_IOTKIT "iotkit"
24
#define TYPE_SSE200 "sse-200"
25
+#define TYPE_SSE300 "sse-300"
26
27
/* We have an IRQ splitter and an OR gate input for each external PPC
28
* and the 2 internal PPCs
29
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/armsse.c
32
+++ b/hw/arm/armsse.c
33
@@ -XXX,XX +XXX,XX @@ static const ARMSSEDeviceInfo sse200_devices[] = {
34
}
35
};
36
37
+static const ARMSSEDeviceInfo sse300_devices[] = {
38
+ {
39
+ .name = "timer0",
40
+ .type = TYPE_SSE_TIMER,
41
+ .index = 0,
42
+ .addr = 0x48000000,
43
+ .ppc = 0,
44
+ .ppc_port = 0,
45
+ .irq = 3,
46
+ },
47
+ {
48
+ .name = "timer1",
49
+ .type = TYPE_SSE_TIMER,
50
+ .index = 1,
51
+ .addr = 0x48001000,
52
+ .ppc = 0,
53
+ .ppc_port = 1,
54
+ .irq = 4,
55
+ },
56
+ {
57
+ .name = "timer2",
58
+ .type = TYPE_SSE_TIMER,
59
+ .index = 2,
60
+ .addr = 0x48002000,
61
+ .ppc = 0,
62
+ .ppc_port = 2,
63
+ .irq = 5,
64
+ },
65
+ {
66
+ .name = "timer3",
67
+ .type = TYPE_SSE_TIMER,
68
+ .index = 3,
69
+ .addr = 0x48003000,
70
+ .ppc = 0,
71
+ .ppc_port = 5,
72
+ .irq = 27,
73
+ },
74
+ {
75
+ .name = "s32ktimer",
76
+ .type = TYPE_CMSDK_APB_TIMER,
77
+ .index = 0,
78
+ .addr = 0x4802f000,
79
+ .ppc = 1,
80
+ .ppc_port = 0,
81
+ .irq = 2,
82
+ .slowclk = true,
83
+ },
84
+ {
85
+ .name = "s32kwatchdog",
86
+ .type = TYPE_CMSDK_APB_WATCHDOG,
87
+ .index = 0,
88
+ .addr = 0x4802e000,
89
+ .ppc = NO_PPC,
90
+ .irq = NMI_0,
91
+ .slowclk = true,
92
+ },
93
+ {
94
+ .name = "watchdog",
95
+ .type = TYPE_UNIMPLEMENTED_DEVICE,
96
+ .index = 0,
97
+ .addr = 0x48040000,
98
+ .size = 0x2000,
99
+ .ppc = NO_PPC,
100
+ .irq = NO_IRQ,
101
+ },
102
+ {
103
+ .name = "armsse-sysinfo",
104
+ .type = TYPE_IOTKIT_SYSINFO,
105
+ .index = 0,
106
+ .addr = 0x48020000,
107
+ .ppc = NO_PPC,
108
+ .irq = NO_IRQ,
109
+ },
110
+ {
111
+ .name = "armsse-sysctl",
112
+ .type = TYPE_IOTKIT_SYSCTL,
113
+ .index = 0,
114
+ .addr = 0x58021000,
115
+ .ppc = NO_PPC,
116
+ .irq = NO_IRQ,
117
+ },
118
+ {
119
+ .name = "SYS_PPU",
120
+ .type = TYPE_UNIMPLEMENTED_DEVICE,
121
+ .index = 1,
122
+ .addr = 0x58022000,
123
+ .size = 0x1000,
124
+ .ppc = NO_PPC,
125
+ .irq = NO_IRQ,
126
+ },
127
+ {
128
+ .name = "CPU0CORE_PPU",
129
+ .type = TYPE_UNIMPLEMENTED_DEVICE,
130
+ .index = 2,
131
+ .addr = 0x50023000,
132
+ .size = 0x1000,
133
+ .ppc = NO_PPC,
134
+ .irq = NO_IRQ,
135
+ },
136
+ {
137
+ .name = "MGMT_PPU",
138
+ .type = TYPE_UNIMPLEMENTED_DEVICE,
139
+ .index = 3,
140
+ .addr = 0x50028000,
141
+ .size = 0x1000,
142
+ .ppc = NO_PPC,
143
+ .irq = NO_IRQ,
144
+ },
145
+ {
146
+ .name = "DEBUG_PPU",
147
+ .type = TYPE_UNIMPLEMENTED_DEVICE,
148
+ .index = 4,
149
+ .addr = 0x50029000,
150
+ .size = 0x1000,
151
+ .ppc = NO_PPC,
152
+ .irq = NO_IRQ,
153
+ },
154
+ {
155
+ .name = NULL,
156
+ }
157
+};
158
+
159
/* Is internal IRQ n shared between CPUs in a multi-core SSE ? */
160
static const bool sse200_irq_is_common[32] = {
161
[0 ... 5] = true,
162
@@ -XXX,XX +XXX,XX @@ static const bool sse200_irq_is_common[32] = {
163
/* 30, 31: reserved */
164
};
165
166
+static const bool sse300_irq_is_common[32] = {
167
+ [0 ... 5] = true,
168
+ /* 6, 7: per-CPU MHU interrupts */
169
+ [8 ... 12] = true,
170
+ /* 13: reserved */
171
+ [14 ... 16] = true,
172
+ /* 17-25: reserved */
173
+ [26 ... 27] = true,
174
+ /* 28, 29: per-CPU CTI interrupts */
175
+ /* 30, 31: reserved */
176
+};
177
+
178
static const ARMSSEInfo armsse_variants[] = {
179
{
180
.name = TYPE_IOTKIT,
181
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
182
.devinfo = sse200_devices,
183
.irq_is_common = sse200_irq_is_common,
184
},
185
+ {
186
+ .name = TYPE_SSE300,
187
+ .sse_version = ARMSSE_SSE300,
188
+ .sram_banks = 2,
189
+ .num_cpus = 1,
190
+ .sys_version = 0x7e00043b,
191
+ .iidr = 0x74a0043b,
192
+ .cpuwait_rst = 0,
193
+ .has_mhus = false,
194
+ .has_cachectrl = false,
195
+ .has_cpusecctrl = true,
196
+ .has_cpuid = true,
197
+ .has_cpu_pwrctrl = true,
198
+ .has_sse_counter = true,
199
+ .props = armsse_properties,
200
+ .devinfo = sse300_devices,
201
+ .irq_is_common = sse300_irq_is_common,
202
+ },
203
};
204
205
static uint32_t armsse_sys_config_value(ARMSSE *s, const ARMSSEInfo *info)
206
--
207
2.20.1
208
209
diff view generated by jsdifflib
New patch
1
The AN547 puts the combined UART overflow IRQ at 48, not 47 like the
2
other images. Make this setting board-specific.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210219144617.4782-37-peter.maydell@linaro.org
9
---
10
hw/arm/mps2-tz.c | 6 +++++-
11
1 file changed, 5 insertions(+), 1 deletion(-)
12
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/mps2-tz.c
16
+++ b/hw/arm/mps2-tz.c
17
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
18
uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
19
bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
20
int numirq; /* Number of external interrupts */
21
+ int uart_overflow_irq; /* number of the combined UART overflow IRQ */
22
const RAMInfo *raminfo;
23
const char *armsse_type;
24
};
25
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
26
&error_fatal);
27
qdev_realize(DEVICE(&mms->uart_irq_orgate), NULL, &error_fatal);
28
qdev_connect_gpio_out(DEVICE(&mms->uart_irq_orgate), 0,
29
- get_sse_irq_in(mms, 47));
30
+ get_sse_irq_in(mms, mmc->uart_overflow_irq));
31
32
/* Most of the devices in the FPGA are behind Peripheral Protection
33
* Controllers. The required order for initializing things is:
34
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
35
mmc->fpgaio_num_leds = 2;
36
mmc->fpgaio_has_switches = false;
37
mmc->numirq = 92;
38
+ mmc->uart_overflow_irq = 47;
39
mmc->raminfo = an505_raminfo;
40
mmc->armsse_type = TYPE_IOTKIT;
41
mps2tz_set_default_ram_info(mmc);
42
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
43
mmc->fpgaio_num_leds = 2;
44
mmc->fpgaio_has_switches = false;
45
mmc->numirq = 92;
46
+ mmc->uart_overflow_irq = 47;
47
mmc->raminfo = an505_raminfo; /* AN521 is the same as AN505 here */
48
mmc->armsse_type = TYPE_SSE200;
49
mps2tz_set_default_ram_info(mmc);
50
@@ -XXX,XX +XXX,XX @@ static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
51
mmc->fpgaio_num_leds = 10;
52
mmc->fpgaio_has_switches = true;
53
mmc->numirq = 95;
54
+ mmc->uart_overflow_irq = 47;
55
mmc->raminfo = an524_raminfo;
56
mmc->armsse_type = TYPE_SSE200;
57
mps2tz_set_default_ram_info(mmc);
58
--
59
2.20.1
60
61
diff view generated by jsdifflib
New patch
1
We've already broken migration compatibility for all the MPS
2
boards, so we might as well take advantage of this to simplify
3
the vmstate for the FPGAIO device by folding the counters
4
subsection into the main vmstate description.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210219144617.4782-38-peter.maydell@linaro.org
10
---
11
hw/misc/mps2-fpgaio.c | 30 +++++-------------------------
12
1 file changed, 5 insertions(+), 25 deletions(-)
13
14
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/misc/mps2-fpgaio.c
17
+++ b/hw/misc/mps2-fpgaio.c
18
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_realize(DeviceState *dev, Error **errp)
19
}
20
}
21
22
-static bool mps2_fpgaio_counters_needed(void *opaque)
23
-{
24
- /* Currently vmstate.c insists all subsections have a 'needed' function */
25
- return true;
26
-}
27
-
28
-static const VMStateDescription mps2_fpgaio_counters_vmstate = {
29
- .name = "mps2-fpgaio/counters",
30
+static const VMStateDescription mps2_fpgaio_vmstate = {
31
+ .name = "mps2-fpgaio",
32
.version_id = 2,
33
.minimum_version_id = 2,
34
- .needed = mps2_fpgaio_counters_needed,
35
.fields = (VMStateField[]) {
36
+ VMSTATE_UINT32(led0, MPS2FPGAIO),
37
+ VMSTATE_UINT32(prescale, MPS2FPGAIO),
38
+ VMSTATE_UINT32(misc, MPS2FPGAIO),
39
VMSTATE_INT64(clk1hz_tick_offset, MPS2FPGAIO),
40
VMSTATE_INT64(clk100hz_tick_offset, MPS2FPGAIO),
41
VMSTATE_UINT32(counter, MPS2FPGAIO),
42
VMSTATE_UINT32(pscntr, MPS2FPGAIO),
43
VMSTATE_INT64(pscntr_sync_ticks, MPS2FPGAIO),
44
VMSTATE_END_OF_LIST()
45
- }
46
-};
47
-
48
-static const VMStateDescription mps2_fpgaio_vmstate = {
49
- .name = "mps2-fpgaio",
50
- .version_id = 1,
51
- .minimum_version_id = 1,
52
- .fields = (VMStateField[]) {
53
- VMSTATE_UINT32(led0, MPS2FPGAIO),
54
- VMSTATE_UINT32(prescale, MPS2FPGAIO),
55
- VMSTATE_UINT32(misc, MPS2FPGAIO),
56
- VMSTATE_END_OF_LIST()
57
},
58
- .subsections = (const VMStateDescription*[]) {
59
- &mps2_fpgaio_counters_vmstate,
60
- NULL
61
- }
62
};
63
64
static Property mps2_fpgaio_properties[] = {
65
--
66
2.20.1
67
68
diff view generated by jsdifflib
1
The Linux kernel has dropped support for allowing 32-bit Arm systems
1
For the AN547 image, the FPGAIO block has an extra DBGCTRL register,
2
to host KVM guests (kernel commit 541ad0150ca4aa663a2, which just
2
which is used to control the SPNIDEN, SPIDEN, NPIDEN and DBGEN inputs
3
landed upstream in the 5.7 merge window). Mark QEMU's support for
3
to the CPU. These signals control when the CPU permits use of the
4
this configuration as deprecated, so that we can delete that support
4
external debug interface. Our CPU models don't implement the
5
code in 5.2.
5
external debug interface, so we model the register as
6
reads-as-written.
7
8
Implement the register, with a property defining whether it is
9
present, and allow mps2-tz boards to specify that it is present.
6
10
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Andrew Jones <drjones@redhat.com>
12
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20210219144617.4782-39-peter.maydell@linaro.org
9
---
16
---
10
docs/system/deprecated.rst | 8 ++++++++
17
include/hw/misc/mps2-fpgaio.h | 2 ++
11
1 file changed, 8 insertions(+)
18
hw/arm/mps2-tz.c | 5 +++++
19
hw/misc/mps2-fpgaio.c | 22 ++++++++++++++++++++--
20
3 files changed, 27 insertions(+), 2 deletions(-)
12
21
13
diff --git a/docs/system/deprecated.rst b/docs/system/deprecated.rst
22
diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
14
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
15
--- a/docs/system/deprecated.rst
24
--- a/include/hw/misc/mps2-fpgaio.h
16
+++ b/docs/system/deprecated.rst
25
+++ b/include/hw/misc/mps2-fpgaio.h
17
@@ -XXX,XX +XXX,XX @@ The ``compat`` property used to set backwards compatibility modes for
26
@@ -XXX,XX +XXX,XX @@ struct MPS2FPGAIO {
18
the processor has been deprecated. The ``max-cpu-compat`` property of
27
LEDState *led[MPS2FPGAIO_MAX_LEDS];
19
the ``pseries`` machine type should be used instead.
28
uint32_t num_leds;
20
29
bool has_switches;
21
+KVM guest support on 32-bit Arm hosts (since 5.0)
30
+ bool has_dbgctrl;
22
+'''''''''''''''''''''''''''''''''''''''''''''''''
31
23
+
32
uint32_t led0;
24
+The Linux kernel has dropped support for allowing 32-bit Arm systems
33
uint32_t prescale;
25
+to host KVM guests as of the 5.7 kernel. Accordingly, QEMU is deprecating
34
uint32_t misc;
26
+its support for this configuration and will remove it in a future version.
35
+ uint32_t dbgctrl;
27
+Running 32-bit guests on a 64-bit Arm host remains supported.
36
28
+
37
/* QEMU_CLOCK_VIRTUAL time at which counter and pscntr were last synced */
29
System emulator devices
38
int64_t pscntr_sync_ticks;
30
-----------------------
39
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/arm/mps2-tz.c
42
+++ b/hw/arm/mps2-tz.c
43
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
44
const uint32_t *oscclk;
45
uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
46
bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
47
+ bool fpgaio_has_dbgctrl; /* Does FPGAIO have DBGCTRL register? */
48
int numirq; /* Number of external interrupts */
49
int uart_overflow_irq; /* number of the combined UART overflow IRQ */
50
const RAMInfo *raminfo;
51
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
52
object_initialize_child(OBJECT(mms), "fpgaio", fpgaio, TYPE_MPS2_FPGAIO);
53
qdev_prop_set_uint32(DEVICE(fpgaio), "num-leds", mmc->fpgaio_num_leds);
54
qdev_prop_set_bit(DEVICE(fpgaio), "has-switches", mmc->fpgaio_has_switches);
55
+ qdev_prop_set_bit(DEVICE(fpgaio), "has-dbgctrl", mmc->fpgaio_has_dbgctrl);
56
sysbus_realize(SYS_BUS_DEVICE(fpgaio), &error_fatal);
57
return sysbus_mmio_get_region(SYS_BUS_DEVICE(fpgaio), 0);
58
}
59
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
60
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
61
mmc->fpgaio_num_leds = 2;
62
mmc->fpgaio_has_switches = false;
63
+ mmc->fpgaio_has_dbgctrl = false;
64
mmc->numirq = 92;
65
mmc->uart_overflow_irq = 47;
66
mmc->raminfo = an505_raminfo;
67
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
68
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
69
mmc->fpgaio_num_leds = 2;
70
mmc->fpgaio_has_switches = false;
71
+ mmc->fpgaio_has_dbgctrl = false;
72
mmc->numirq = 92;
73
mmc->uart_overflow_irq = 47;
74
mmc->raminfo = an505_raminfo; /* AN521 is the same as AN505 here */
75
@@ -XXX,XX +XXX,XX @@ static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
76
mmc->len_oscclk = ARRAY_SIZE(an524_oscclk);
77
mmc->fpgaio_num_leds = 10;
78
mmc->fpgaio_has_switches = true;
79
+ mmc->fpgaio_has_dbgctrl = false;
80
mmc->numirq = 95;
81
mmc->uart_overflow_irq = 47;
82
mmc->raminfo = an524_raminfo;
83
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/hw/misc/mps2-fpgaio.c
86
+++ b/hw/misc/mps2-fpgaio.c
87
@@ -XXX,XX +XXX,XX @@
88
#include "qemu/timer.h"
89
90
REG32(LED0, 0)
91
+REG32(DBGCTRL, 4)
92
REG32(BUTTON, 8)
93
REG32(CLK1HZ, 0x10)
94
REG32(CLK100HZ, 0x14)
95
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_fpgaio_read(void *opaque, hwaddr offset, unsigned size)
96
case A_LED0:
97
r = s->led0;
98
break;
99
+ case A_DBGCTRL:
100
+ if (!s->has_dbgctrl) {
101
+ goto bad_offset;
102
+ }
103
+ r = s->dbgctrl;
104
+ break;
105
case A_BUTTON:
106
/* User-pressable board buttons. We don't model that, so just return
107
* zeroes.
108
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_write(void *opaque, hwaddr offset, uint64_t value,
109
}
110
}
111
break;
112
+ case A_DBGCTRL:
113
+ if (!s->has_dbgctrl) {
114
+ goto bad_offset;
115
+ }
116
+ qemu_log_mask(LOG_UNIMP,
117
+ "MPS2 FPGAIO: DBGCTRL unimplemented\n");
118
+ s->dbgctrl = value;
119
+ break;
120
case A_PRESCALE:
121
resync_counter(s);
122
s->prescale = value;
123
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_write(void *opaque, hwaddr offset, uint64_t value,
124
s->pscntr = value;
125
break;
126
default:
127
+ bad_offset:
128
qemu_log_mask(LOG_GUEST_ERROR,
129
"MPS2 FPGAIO write: bad offset 0x%x\n", (int) offset);
130
break;
131
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_realize(DeviceState *dev, Error **errp)
132
133
static const VMStateDescription mps2_fpgaio_vmstate = {
134
.name = "mps2-fpgaio",
135
- .version_id = 2,
136
- .minimum_version_id = 2,
137
+ .version_id = 3,
138
+ .minimum_version_id = 3,
139
.fields = (VMStateField[]) {
140
VMSTATE_UINT32(led0, MPS2FPGAIO),
141
VMSTATE_UINT32(prescale, MPS2FPGAIO),
142
VMSTATE_UINT32(misc, MPS2FPGAIO),
143
+ VMSTATE_UINT32(dbgctrl, MPS2FPGAIO),
144
VMSTATE_INT64(clk1hz_tick_offset, MPS2FPGAIO),
145
VMSTATE_INT64(clk100hz_tick_offset, MPS2FPGAIO),
146
VMSTATE_UINT32(counter, MPS2FPGAIO),
147
@@ -XXX,XX +XXX,XX @@ static Property mps2_fpgaio_properties[] = {
148
/* Number of LEDs controlled by LED0 register */
149
DEFINE_PROP_UINT32("num-leds", MPS2FPGAIO, num_leds, 2),
150
DEFINE_PROP_BOOL("has-switches", MPS2FPGAIO, has_switches, false),
151
+ DEFINE_PROP_BOOL("has-dbgctrl", MPS2FPGAIO, has_dbgctrl, false),
152
DEFINE_PROP_END_OF_LIST(),
153
};
31
154
32
--
155
--
33
2.20.1
156
2.20.1
34
157
35
158
diff view generated by jsdifflib
New patch
1
Implement the minor changes required to the SCC block for AN547 images:
2
* CFG2 and CFG5 exist (like AN524)
3
* CFG3 is reserved (like AN524)
4
* CFG0 bit 1 is CPU_WAIT; we don't implement it, but note this
5
in the TODO comment
1
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210219144617.4782-40-peter.maydell@linaro.org
11
---
12
hw/misc/mps2-scc.c | 15 +++++++++------
13
1 file changed, 9 insertions(+), 6 deletions(-)
14
15
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/misc/mps2-scc.c
18
+++ b/hw/misc/mps2-scc.c
19
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
20
r = s->cfg1;
21
break;
22
case A_CFG2:
23
- if (scc_partno(s) != 0x524) {
24
+ if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
25
/* CFG2 reserved on other boards */
26
goto bad_offset;
27
}
28
r = s->cfg2;
29
break;
30
case A_CFG3:
31
- if (scc_partno(s) == 0x524) {
32
+ if (scc_partno(s) == 0x524 && scc_partno(s) == 0x547) {
33
/* CFG3 reserved on AN524 */
34
goto bad_offset;
35
}
36
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
37
r = s->cfg4;
38
break;
39
case A_CFG5:
40
- if (scc_partno(s) != 0x524) {
41
+ if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
42
/* CFG5 reserved on other boards */
43
goto bad_offset;
44
}
45
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
46
47
switch (offset) {
48
case A_CFG0:
49
- /* TODO on some boards bit 0 controls RAM remapping */
50
+ /*
51
+ * TODO on some boards bit 0 controls RAM remapping;
52
+ * on others bit 1 is CPU_WAIT.
53
+ */
54
s->cfg0 = value;
55
break;
56
case A_CFG1:
57
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
58
}
59
break;
60
case A_CFG2:
61
- if (scc_partno(s) != 0x524) {
62
+ if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
63
/* CFG2 reserved on other boards */
64
goto bad_offset;
65
}
66
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
67
s->cfg2 = value;
68
break;
69
case A_CFG5:
70
- if (scc_partno(s) != 0x524) {
71
+ if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
72
/* CFG5 reserved on other boards */
73
goto bad_offset;
74
}
75
--
76
2.20.1
77
78
diff view generated by jsdifflib
1
When kernel-doc generates a 'c:function' directive for a function
1
The AN547 runs the APB peripherals outside the SSE-300 on a different
2
one of whose arguments is a function pointer, it fails to print
2
and slightly slower clock than it runs the SSE-300 with. Support
3
the close-paren after the argument list of the function pointer
3
making the APB peripheral clock frequency board-specific. (For our
4
argument, for instance in the memory API documentation:
4
implementation only the UARTs actually take a clock.)
5
.. c:function:: void memory_region_init_resizeable_ram (MemoryRegion * mr, struct Object * owner, const char * name, uint64_t size, uint64_t max_size, void (*resized) (const char*, uint64_t length, void *host, Error ** errp)
6
7
which should have a ')' after the 'void *host' which is the
8
last argument to 'resized'.
9
10
Older versions of Sphinx don't try to parse the argumnet
11
to c:function, but Sphinx 3.0 does do this and will complain:
12
13
/home/petmay01/linaro/qemu-from-laptop/qemu/docs/../include/exec/memory.h:834: WARNING: Error in declarator or parameters
14
Invalid C declaration: Expecting "," or ")" in parameters, got "EOF". [error at 208]
15
void memory_region_init_resizeable_ram (MemoryRegion * mr, struct Object * owner, const char * name, uint64_t size, uint64_t max_size, void (*resized) (const char*, uint64_t length, void *host, Error ** errp)
16
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------^
17
18
Add the missing close-paren.
19
5
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Message-id: 20200411182934.28678-3-peter.maydell@linaro.org
10
Message-id: 20210219144617.4782-41-peter.maydell@linaro.org
23
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
24
---
11
---
25
scripts/kernel-doc | 2 +-
12
hw/arm/mps2-tz.c | 6 +++++-
26
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 5 insertions(+), 1 deletion(-)
27
14
28
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
15
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
29
index XXXXXXX..XXXXXXX 100755
16
index XXXXXXX..XXXXXXX 100644
30
--- a/scripts/kernel-doc
17
--- a/hw/arm/mps2-tz.c
31
+++ b/scripts/kernel-doc
18
+++ b/hw/arm/mps2-tz.c
32
@@ -XXX,XX +XXX,XX @@ sub output_function_rst(%) {
19
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
33
20
MPS2TZFPGAType fpga_type;
34
    if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
21
uint32_t scc_id;
35
     # pointer-to-function
22
uint32_t sysclk_frq; /* Main SYSCLK frequency in Hz */
36
-     print $1 . $parameter . ") (" . $2;
23
+ uint32_t apb_periph_frq; /* APB peripheral frequency in Hz */
37
+     print $1 . $parameter . ") (" . $2 . ")";
24
uint32_t len_oscclk;
38
    } else {
25
const uint32_t *oscclk;
39
     print $type . " " . $parameter;
26
uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
40
    }
27
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
28
29
object_initialize_child(OBJECT(mms), name, uart, TYPE_CMSDK_APB_UART);
30
qdev_prop_set_chr(DEVICE(uart), "chardev", serial_hd(i));
31
- qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", mmc->sysclk_frq);
32
+ qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", mmc->apb_periph_frq);
33
sysbus_realize(SYS_BUS_DEVICE(uart), &error_fatal);
34
s = SYS_BUS_DEVICE(uart);
35
sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
36
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
37
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
38
mmc->scc_id = 0x41045050;
39
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
40
+ mmc->apb_periph_frq = mmc->sysclk_frq;
41
mmc->oscclk = an505_oscclk;
42
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
43
mmc->fpgaio_num_leds = 2;
44
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
45
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
46
mmc->scc_id = 0x41045210;
47
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
48
+ mmc->apb_periph_frq = mmc->sysclk_frq;
49
mmc->oscclk = an505_oscclk; /* AN521 is the same as AN505 here */
50
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
51
mmc->fpgaio_num_leds = 2;
52
@@ -XXX,XX +XXX,XX @@ static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
53
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
54
mmc->scc_id = 0x41045240;
55
mmc->sysclk_frq = 32 * 1000 * 1000; /* 32MHz */
56
+ mmc->apb_periph_frq = mmc->sysclk_frq;
57
mmc->oscclk = an524_oscclk;
58
mmc->len_oscclk = ARRAY_SIZE(an524_oscclk);
59
mmc->fpgaio_num_leds = 10;
41
--
60
--
42
2.20.1
61
2.20.1
43
62
44
63
diff view generated by jsdifflib
1
All the Coverity-specific definitions of qemu_mutex_lock() and friends
1
The AN547 configures the SSE-300 with a different initsvtor0
2
have a trailing semicolon. This works fine almost everywhere because
2
setting from its default; make this a board-specific setting.
3
of QEMU's mandatory-braces coding style and because most callsites are
4
simple, but target/s390x/sigp.c has a use of qemu_mutex_trylock() as
5
an if() statement, which makes the ';' a syntax error:
6
"../target/s390x/sigp.c", line 461: warning #18: expected a ")"
7
if (qemu_mutex_trylock(&qemu_sigp_mutex)) {
8
^
9
10
Remove the bogus semicolons from the macro definitions.
11
3
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20210219144617.4782-42-peter.maydell@linaro.org
15
Message-id: 20200319193323.2038-4-peter.maydell@linaro.org
16
---
9
---
17
include/qemu/thread.h | 12 ++++++------
10
hw/arm/mps2-tz.c | 5 +++++
18
1 file changed, 6 insertions(+), 6 deletions(-)
11
1 file changed, 5 insertions(+)
19
12
20
diff --git a/include/qemu/thread.h b/include/qemu/thread.h
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
21
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
22
--- a/include/qemu/thread.h
15
--- a/hw/arm/mps2-tz.c
23
+++ b/include/qemu/thread.h
16
+++ b/hw/arm/mps2-tz.c
24
@@ -XXX,XX +XXX,XX @@ extern QemuCondTimedWaitFunc qemu_cond_timedwait_func;
17
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
25
* hide them.
18
bool fpgaio_has_dbgctrl; /* Does FPGAIO have DBGCTRL register? */
26
*/
19
int numirq; /* Number of external interrupts */
27
#define qemu_mutex_lock(m) \
20
int uart_overflow_irq; /* number of the combined UART overflow IRQ */
28
- qemu_mutex_lock_impl(m, __FILE__, __LINE__);
21
+ uint32_t init_svtor; /* init-svtor setting for SSE */
29
+ qemu_mutex_lock_impl(m, __FILE__, __LINE__)
22
const RAMInfo *raminfo;
30
#define qemu_mutex_trylock(m) \
23
const char *armsse_type;
31
- qemu_mutex_trylock_impl(m, __FILE__, __LINE__);
24
};
32
+ qemu_mutex_trylock_impl(m, __FILE__, __LINE__)
25
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
33
#define qemu_rec_mutex_lock(m) \
26
object_property_set_link(OBJECT(&mms->iotkit), "memory",
34
- qemu_rec_mutex_lock_impl(m, __FILE__, __LINE__);
27
OBJECT(system_memory), &error_abort);
35
+ qemu_rec_mutex_lock_impl(m, __FILE__, __LINE__)
28
qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", mmc->numirq);
36
#define qemu_rec_mutex_trylock(m) \
29
+ qdev_prop_set_uint32(iotkitdev, "init-svtor", mmc->init_svtor);
37
- qemu_rec_mutex_trylock_impl(m, __FILE__, __LINE__);
30
qdev_connect_clock_in(iotkitdev, "MAINCLK", mms->sysclk);
38
+ qemu_rec_mutex_trylock_impl(m, __FILE__, __LINE__)
31
qdev_connect_clock_in(iotkitdev, "S32KCLK", mms->s32kclk);
39
#define qemu_cond_wait(c, m) \
32
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
40
- qemu_cond_wait_impl(c, m, __FILE__, __LINE__);
33
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
41
+ qemu_cond_wait_impl(c, m, __FILE__, __LINE__)
34
mmc->fpgaio_has_dbgctrl = false;
42
#define qemu_cond_timedwait(c, m, ms) \
35
mmc->numirq = 92;
43
- qemu_cond_timedwait_impl(c, m, ms, __FILE__, __LINE__);
36
mmc->uart_overflow_irq = 47;
44
+ qemu_cond_timedwait_impl(c, m, ms, __FILE__, __LINE__)
37
+ mmc->init_svtor = 0x10000000;
45
#else
38
mmc->raminfo = an505_raminfo;
46
#define qemu_mutex_lock(m) ({ \
39
mmc->armsse_type = TYPE_IOTKIT;
47
QemuMutexLockFunc _f = atomic_read(&qemu_mutex_lock_func); \
40
mps2tz_set_default_ram_info(mmc);
41
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
42
mmc->fpgaio_has_dbgctrl = false;
43
mmc->numirq = 92;
44
mmc->uart_overflow_irq = 47;
45
+ mmc->init_svtor = 0x10000000;
46
mmc->raminfo = an505_raminfo; /* AN521 is the same as AN505 here */
47
mmc->armsse_type = TYPE_SSE200;
48
mps2tz_set_default_ram_info(mmc);
49
@@ -XXX,XX +XXX,XX @@ static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
50
mmc->fpgaio_has_dbgctrl = false;
51
mmc->numirq = 95;
52
mmc->uart_overflow_irq = 47;
53
+ mmc->init_svtor = 0x10000000;
54
mmc->raminfo = an524_raminfo;
55
mmc->armsse_type = TYPE_SSE200;
56
mps2tz_set_default_ram_info(mmc);
48
--
57
--
49
2.20.1
58
2.20.1
50
59
51
60
diff view generated by jsdifflib
1
If we are not making warnings fatal for compilation, make them
1
Add support for the mps3-an547 board; this is an SSE-300 based
2
non-fatal when building the Sphinx documentation also. (For instance
2
FPGA image that runs on the MPS3.
3
Sphinx 3.0 warns about some constructs that older versions were happy
4
with, which is a build failure if we use the warnings-as-errors
5
flag.)
6
7
This provides a workaround at least for LP:1872113.
8
3
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20200411182934.28678-2-peter.maydell@linaro.org
7
Message-id: 20210219144617.4782-43-peter.maydell@linaro.org
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
---
8
---
14
configure | 9 ++++++++-
9
hw/arm/mps2-tz.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++-
15
Makefile | 2 +-
10
1 file changed, 144 insertions(+), 2 deletions(-)
16
2 files changed, 9 insertions(+), 2 deletions(-)
11
17
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
18
diff --git a/configure b/configure
13
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100755
14
--- a/hw/arm/mps2-tz.c
20
--- a/configure
15
+++ b/hw/arm/mps2-tz.c
21
+++ b/configure
16
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ if check_include sys/kcov.h ; then
17
* "mps2-an505" -- Cortex-M33 as documented in ARM Application Note AN505
23
kcov=yes
18
* "mps2-an521" -- Dual Cortex-M33 as documented in Application Note AN521
24
fi
19
* "mps2-an524" -- Dual Cortex-M33 as documented in Application Note AN524
25
20
+ * "mps2-an547" -- Single Cortex-M55 as documented in Application Note AN547
26
+# If we're making warnings fatal, apply this to Sphinx runs as well
21
*
27
+sphinx_werror=""
22
* Links to the TRM for the board itself and to the various Application
28
+if test "$werror" = "yes"; then
23
* Notes which document the FPGA images can be found here:
29
+ sphinx_werror="-W"
24
@@ -XXX,XX +XXX,XX @@
30
+fi
25
* https://developer.arm.com/documentation/dai0521/latest/
31
+
26
* Application Note AN524:
32
# Check we have a new enough version of sphinx-build
27
* https://developer.arm.com/documentation/dai0524/latest/
33
has_sphinx_build() {
28
+ * Application Note AN547:
34
# This is a bit awkward but works: create a trivial document and
29
+ * https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/DAI0547B_SSE300_PLUS_U55_FPGA_for_mps3.pdf
35
@@ -XXX,XX +XXX,XX @@ has_sphinx_build() {
30
*
36
# sphinx-build doesn't exist at all or if it is too old.
31
* The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
37
mkdir -p "$TMPDIR1/sphinx"
32
* (ARM ECM0601256) for the details of some of the device layout:
38
touch "$TMPDIR1/sphinx/index.rst"
33
@@ -XXX,XX +XXX,XX @@
39
- "$sphinx_build" -c "$source_path/docs" -b html "$TMPDIR1/sphinx" "$TMPDIR1/sphinx/out" >/dev/null 2>&1
34
* Similarly, the AN521 and AN524 use the SSE-200, and the SSE-200 TRM defines
40
+ "$sphinx_build" $sphinx_werror -c "$source_path/docs" -b html "$TMPDIR1/sphinx" "$TMPDIR1/sphinx/out" >/dev/null 2>&1
35
* most of the device layout:
36
* https://developer.arm.com/documentation/101104/latest/
37
+ * and the AN547 uses the SSE-300, whose layout is in the SSE-300 TRM:
38
+ * https://developer.arm.com/documentation/101773/latest/
39
*/
40
41
#include "qemu/osdep.h"
42
@@ -XXX,XX +XXX,XX @@
43
#include "hw/qdev-clock.h"
44
#include "qom/object.h"
45
46
-#define MPS2TZ_NUMIRQ_MAX 95
47
-#define MPS2TZ_RAM_MAX 4
48
+#define MPS2TZ_NUMIRQ_MAX 96
49
+#define MPS2TZ_RAM_MAX 5
50
51
typedef enum MPS2TZFPGAType {
52
FPGA_AN505,
53
FPGA_AN521,
54
FPGA_AN524,
55
+ FPGA_AN547,
56
} MPS2TZFPGAType;
57
58
/*
59
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
60
#define TYPE_MPS2TZ_AN505_MACHINE MACHINE_TYPE_NAME("mps2-an505")
61
#define TYPE_MPS2TZ_AN521_MACHINE MACHINE_TYPE_NAME("mps2-an521")
62
#define TYPE_MPS3TZ_AN524_MACHINE MACHINE_TYPE_NAME("mps3-an524")
63
+#define TYPE_MPS3TZ_AN547_MACHINE MACHINE_TYPE_NAME("mps3-an547")
64
65
OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
66
67
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an524_raminfo[] = { {
68
},
69
};
70
71
+static const RAMInfo an547_raminfo[] = { {
72
+ .name = "itcm",
73
+ .base = 0x00000000,
74
+ .size = 512 * KiB,
75
+ .mpc = -1,
76
+ .mrindex = 0,
77
+ }, {
78
+ .name = "sram",
79
+ .base = 0x01000000,
80
+ .size = 2 * MiB,
81
+ .mpc = 0,
82
+ .mrindex = 1,
83
+ }, {
84
+ .name = "dtcm",
85
+ .base = 0x20000000,
86
+ .size = 4 * 128 * KiB,
87
+ .mpc = -1,
88
+ .mrindex = 2,
89
+ }, {
90
+ .name = "sram 2",
91
+ .base = 0x21000000,
92
+ .size = 4 * MiB,
93
+ .mpc = -1,
94
+ .mrindex = 3,
95
+ }, {
96
+ /* We don't model QSPI flash yet; for now expose it as simple ROM */
97
+ .name = "QSPI",
98
+ .base = 0x28000000,
99
+ .size = 8 * MiB,
100
+ .mpc = 1,
101
+ .mrindex = 4,
102
+ .flags = IS_ROM,
103
+ }, {
104
+ .name = "DDR",
105
+ .base = 0x60000000,
106
+ .size = MPS3_DDR_SIZE,
107
+ .mpc = 2,
108
+ .mrindex = -1,
109
+ }, {
110
+ .name = NULL,
111
+ },
112
+};
113
+
114
static const RAMInfo *find_raminfo_for_mpc(MPS2TZMachineState *mms, int mpc)
115
{
116
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
117
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
118
},
119
};
120
121
+ const PPCInfo an547_ppcs[] = { {
122
+ .name = "apb_ppcexp0",
123
+ .ports = {
124
+ { "ssram-mpc", make_mpc, &mms->mpc[0], 0x57000000, 0x1000 },
125
+ { "qspi-mpc", make_mpc, &mms->mpc[1], 0x57001000, 0x1000 },
126
+ { "ddr-mpc", make_mpc, &mms->mpc[2], 0x57002000, 0x1000 },
127
+ },
128
+ }, {
129
+ .name = "apb_ppcexp1",
130
+ .ports = {
131
+ { "i2c0", make_i2c, &mms->i2c[0], 0x49200000, 0x1000 },
132
+ { "i2c1", make_i2c, &mms->i2c[1], 0x49201000, 0x1000 },
133
+ { "spi0", make_spi, &mms->spi[0], 0x49202000, 0x1000, { 53 } },
134
+ { "spi1", make_spi, &mms->spi[1], 0x49203000, 0x1000, { 54 } },
135
+ { "spi2", make_spi, &mms->spi[2], 0x49204000, 0x1000, { 55 } },
136
+ { "i2c2", make_i2c, &mms->i2c[2], 0x49205000, 0x1000 },
137
+ { "i2c3", make_i2c, &mms->i2c[3], 0x49206000, 0x1000 },
138
+ { /* port 7 reserved */ },
139
+ { "i2c4", make_i2c, &mms->i2c[4], 0x49208000, 0x1000 },
140
+ },
141
+ }, {
142
+ .name = "apb_ppcexp2",
143
+ .ports = {
144
+ { "scc", make_scc, &mms->scc, 0x49300000, 0x1000 },
145
+ { "i2s-audio", make_unimp_dev, &mms->i2s_audio, 0x49301000, 0x1000 },
146
+ { "fpgaio", make_fpgaio, &mms->fpgaio, 0x49302000, 0x1000 },
147
+ { "uart0", make_uart, &mms->uart[0], 0x49303000, 0x1000, { 33, 34, 43 } },
148
+ { "uart1", make_uart, &mms->uart[1], 0x49304000, 0x1000, { 35, 36, 44 } },
149
+ { "uart2", make_uart, &mms->uart[2], 0x49305000, 0x1000, { 37, 38, 45 } },
150
+ { "uart3", make_uart, &mms->uart[3], 0x49306000, 0x1000, { 39, 40, 46 } },
151
+ { "uart4", make_uart, &mms->uart[4], 0x49307000, 0x1000, { 41, 42, 47 } },
152
+ { "uart5", make_uart, &mms->uart[5], 0x49308000, 0x1000, { 125, 126, 127 } },
153
+
154
+ { /* port 9 reserved */ },
155
+ { "clcd", make_unimp_dev, &mms->cldc, 0x4930a000, 0x1000 },
156
+ { "rtc", make_rtc, &mms->rtc, 0x4930b000, 0x1000 },
157
+ },
158
+ }, {
159
+ .name = "ahb_ppcexp0",
160
+ .ports = {
161
+ { "gpio0", make_unimp_dev, &mms->gpio[0], 0x41100000, 0x1000 },
162
+ { "gpio1", make_unimp_dev, &mms->gpio[1], 0x41101000, 0x1000 },
163
+ { "gpio2", make_unimp_dev, &mms->gpio[2], 0x41102000, 0x1000 },
164
+ { "gpio3", make_unimp_dev, &mms->gpio[3], 0x41103000, 0x1000 },
165
+ { "eth-usb", make_eth_usb, NULL, 0x41400000, 0x200000, { 49 } },
166
+ },
167
+ },
168
+ };
169
+
170
switch (mmc->fpga_type) {
171
case FPGA_AN505:
172
case FPGA_AN521:
173
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
174
ppcs = an524_ppcs;
175
num_ppcs = ARRAY_SIZE(an524_ppcs);
176
break;
177
+ case FPGA_AN547:
178
+ ppcs = an547_ppcs;
179
+ num_ppcs = ARRAY_SIZE(an547_ppcs);
180
+ break;
181
default:
182
g_assert_not_reached();
183
}
184
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
185
186
create_unimplemented_device("FPGA NS PC", 0x48007000, 0x1000);
187
188
+ if (mmc->fpga_type == FPGA_AN547) {
189
+ create_unimplemented_device("U55 timing adapter 0", 0x48102000, 0x1000);
190
+ create_unimplemented_device("U55 timing adapter 1", 0x48103000, 0x1000);
191
+ }
192
+
193
create_non_mpc_ram(mms);
194
195
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
196
@@ -XXX,XX +XXX,XX @@ static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
197
mps2tz_set_default_ram_info(mmc);
41
}
198
}
42
199
43
# Check if tools are available to build documentation.
200
+static void mps3tz_an547_class_init(ObjectClass *oc, void *data)
44
@@ -XXX,XX +XXX,XX @@ echo "INSTALL_PROG=$install -c -m 0755" >> $config_host_mak
201
+{
45
echo "INSTALL_LIB=$install -c -m 0644" >> $config_host_mak
202
+ MachineClass *mc = MACHINE_CLASS(oc);
46
echo "PYTHON=$python" >> $config_host_mak
203
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc);
47
echo "SPHINX_BUILD=$sphinx_build" >> $config_host_mak
204
+
48
+echo "SPHINX_WERROR=$sphinx_werror" >> $config_host_mak
205
+ mc->desc = "ARM MPS3 with AN547 FPGA image for Cortex-M55";
49
echo "GENISOIMAGE=$genisoimage" >> $config_host_mak
206
+ mc->default_cpus = 1;
50
echo "CC=$cc" >> $config_host_mak
207
+ mc->min_cpus = mc->default_cpus;
51
if $iasl -h > /dev/null 2>&1; then
208
+ mc->max_cpus = mc->default_cpus;
52
diff --git a/Makefile b/Makefile
209
+ mmc->fpga_type = FPGA_AN547;
53
index XXXXXXX..XXXXXXX 100644
210
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m55");
54
--- a/Makefile
211
+ mmc->scc_id = 0x41055470;
55
+++ b/Makefile
212
+ mmc->sysclk_frq = 32 * 1000 * 1000; /* 32MHz */
56
@@ -XXX,XX +XXX,XX @@ sphinxdocs: $(MANUAL_BUILDDIR)/devel/index.html \
213
+ mmc->apb_periph_frq = 25 * 1000 * 1000; /* 25MHz */
57
# Note the use of different doctree for each (manual, builder) tuple;
214
+ mmc->oscclk = an524_oscclk; /* same as AN524 */
58
# this works around Sphinx not handling parallel invocation on
215
+ mmc->len_oscclk = ARRAY_SIZE(an524_oscclk);
59
# a single doctree: https://github.com/sphinx-doc/sphinx/issues/2946
216
+ mmc->fpgaio_num_leds = 10;
60
-build-manual = $(call quiet-command,CONFDIR="$(qemu_confdir)" $(SPHINX_BUILD) $(if $(V),,-q) -W -b $2 -D version=$(VERSION) -D release="$(FULL_VERSION)" -d .doctrees/$1-$2 $(SRC_PATH)/docs/$1 $(MANUAL_BUILDDIR)/$1 ,"SPHINX","$(MANUAL_BUILDDIR)/$1")
217
+ mmc->fpgaio_has_switches = true;
61
+build-manual = $(call quiet-command,CONFDIR="$(qemu_confdir)" $(SPHINX_BUILD) $(if $(V),,-q) $(SPHINX_WERROR) -b $2 -D version=$(VERSION) -D release="$(FULL_VERSION)" -d .doctrees/$1-$2 $(SRC_PATH)/docs/$1 $(MANUAL_BUILDDIR)/$1 ,"SPHINX","$(MANUAL_BUILDDIR)/$1")
218
+ mmc->fpgaio_has_dbgctrl = true;
62
# We assume all RST files in the manual's directory are used in it
219
+ mmc->numirq = 96;
63
manual-deps = $(wildcard $(SRC_PATH)/docs/$1/*.rst $(SRC_PATH)/docs/$1/*/*.rst) \
220
+ mmc->uart_overflow_irq = 48;
64
$(SRC_PATH)/docs/defs.rst.inc \
221
+ mmc->init_svtor = 0x00000000;
222
+ mmc->raminfo = an547_raminfo;
223
+ mmc->armsse_type = TYPE_SSE300;
224
+ mps2tz_set_default_ram_info(mmc);
225
+}
226
+
227
static const TypeInfo mps2tz_info = {
228
.name = TYPE_MPS2TZ_MACHINE,
229
.parent = TYPE_MACHINE,
230
@@ -XXX,XX +XXX,XX @@ static const TypeInfo mps3tz_an524_info = {
231
.class_init = mps3tz_an524_class_init,
232
};
233
234
+static const TypeInfo mps3tz_an547_info = {
235
+ .name = TYPE_MPS3TZ_AN547_MACHINE,
236
+ .parent = TYPE_MPS2TZ_MACHINE,
237
+ .class_init = mps3tz_an547_class_init,
238
+};
239
+
240
static void mps2tz_machine_init(void)
241
{
242
type_register_static(&mps2tz_info);
243
type_register_static(&mps2tz_an505_info);
244
type_register_static(&mps2tz_an521_info);
245
type_register_static(&mps3tz_an524_info);
246
+ type_register_static(&mps3tz_an547_info);
247
}
248
249
type_init(mps2tz_machine_init);
65
--
250
--
66
2.20.1
251
2.20.1
67
252
68
253
diff view generated by jsdifflib
1
Versions of Sphinx older than 1.6 can't build all of our documentation,
1
Add brief documentation of the new mps3-an547 board.
2
because they are too picky about the syntax of the argument to the
3
option:: directive; see Sphinx bugs #646, #3366:
4
5
https://github.com/sphinx-doc/sphinx/issues/646
6
https://github.com/sphinx-doc/sphinx/issues/3366
7
8
Trying to build with a 1.4.x Sphinx fails with
9
docs/system/images.rst:4: SEVERE: Duplicate ID: "cmdoption-qcow2-arg-encrypt"
10
and a 1.5.x Sphinx fails with
11
docs/system/invocation.rst:544: WARNING: Malformed option description '[enable=]PATTERN', should look like "opt", "-opt
12
args", "--opt args", "/opt args" or "+opt args"
13
14
Update our needs_sphinx setting to indicate that we require at least
15
1.6. This will allow configure to fall back to "don't build the
16
docs" rather than causing the build to fail entirely, which is
17
probably what most users building on a host old enough to have such
18
an old Sphinx would want; if they do want the docs then they'll have
19
a useful indication of what they need to do (upgrade Sphinx!) rather
20
than a confusing error message.
21
22
In theory our distro support policy would suggest that we should
23
support building on the Sphinx shipped in those distros, but:
24
* EPEL7 has Sphinx 1.2.3 (which we've never supported!)
25
* Debian Stretch has Sphinx 1.4.8
26
27
Trying to get our docs to work with Sphinx 1.4 is not tractable
28
for the 5.0 release and I'm not sure it's worthwhile effort anyway;
29
at least with this change the build as a whole now succeeds.
30
31
Thanks to John Snow for doing the investigation and testing to
32
confirm what Sphinx versions fail in what ways and what distros
33
shipped what.
34
2
35
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
36
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20210219144617.4782-44-peter.maydell@linaro.org
37
---
7
---
38
docs/conf.py | 6 ++++--
8
docs/system/arm/mps2.rst | 6 ++++--
39
1 file changed, 4 insertions(+), 2 deletions(-)
9
1 file changed, 4 insertions(+), 2 deletions(-)
40
10
41
diff --git a/docs/conf.py b/docs/conf.py
11
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
42
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
43
--- a/docs/conf.py
13
--- a/docs/system/arm/mps2.rst
44
+++ b/docs/conf.py
14
+++ b/docs/system/arm/mps2.rst
45
@@ -XXX,XX +XXX,XX @@ sys.path.insert(0, os.path.join(qemu_docdir, "sphinx"))
15
@@ -XXX,XX +XXX,XX @@
46
16
-Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``)
47
# If your documentation needs a minimal Sphinx version, state it here.
17
-=========================================================================================================================================
48
#
18
+Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an547``)
49
-# 1.3 is where the 'alabaster' theme was shipped with Sphinx.
19
+=========================================================================================================================================================
50
-needs_sphinx = '1.3'
20
51
+# Sphinx 1.5 and earlier can't build our docs because they are too
21
These board models all use Arm M-profile CPUs.
52
+# picky about the syntax of the argument to the option:: directive
22
53
+# (see Sphinx bugs #646, #3366).
23
@@ -XXX,XX +XXX,XX @@ QEMU models the following FPGA images:
54
+needs_sphinx = '1.6'
24
Dual Cortex-M33 as documented in Arm Application Note AN521
55
25
``mps3-an524``
56
# Add any Sphinx extension module names here, as strings. They can be
26
Dual Cortex-M33 on an MPS3, as documented in Arm Application Note AN524
57
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
27
+``mps3-an547``
28
+ Cortex-M55 on an MPS3, as documented in Arm Application Note AN547
29
30
Differences between QEMU and real hardware:
31
58
--
32
--
59
2.20.1
33
2.20.1
60
34
61
35
diff view generated by jsdifflib
1
Add a new script to automate the process of running the Coverity
1
Add a simple qtest to exercise the new system counter device in the
2
Scan build tools and uploading the resulting tarball to the
2
SSE-300.
3
website.
4
3
5
This is intended eventually to be driven from Travis,
4
We'll add tests of the system timer device here too, so this includes
6
but it can be run locally, if you are a maintainer of the
5
scaffolding (register definitions, etc) for those.
7
QEMU project on the Coverity Scan website and have the secret
8
upload token.
9
6
10
The script must be run on a Fedora 30 system. Support for using a
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Docker container is added in a following commit.
8
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20210219144617.4782-45-peter.maydell@linaro.org
11
---
12
tests/qtest/sse-timer-test.c | 117 +++++++++++++++++++++++++++++++++++
13
MAINTAINERS | 1 +
14
tests/qtest/meson.build | 1 +
15
3 files changed, 119 insertions(+)
16
create mode 100644 tests/qtest/sse-timer-test.c
12
17
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
18
diff --git a/tests/qtest/sse-timer-test.c b/tests/qtest/sse-timer-test.c
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
new file mode 100644
15
Message-id: 20200319193323.2038-6-peter.maydell@linaro.org
20
index XXXXXXX..XXXXXXX
16
---
21
--- /dev/null
17
MAINTAINERS | 5 +
22
+++ b/tests/qtest/sse-timer-test.c
18
scripts/coverity-scan/run-coverity-scan | 311 ++++++++++++++++++++++++
23
@@ -XXX,XX +XXX,XX @@
19
2 files changed, 316 insertions(+)
24
+/*
20
create mode 100755 scripts/coverity-scan/run-coverity-scan
25
+ * QTest testcase for the SSE timer device
21
26
+ *
27
+ * Copyright (c) 2021 Linaro Limited
28
+ *
29
+ * This program is free software; you can redistribute it and/or modify it
30
+ * under the terms of the GNU General Public License as published by the
31
+ * Free Software Foundation; either version 2 of the License, or
32
+ * (at your option) any later version.
33
+ *
34
+ * This program is distributed in the hope that it will be useful, but WITHOUT
35
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
36
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
37
+ * for more details.
38
+ */
39
+
40
+#include "qemu/osdep.h"
41
+#include "libqtest-single.h"
42
+
43
+/*
44
+ * SSE-123/SSE-300 timer in the mps3-an547 board, where it is driven
45
+ * at 32MHz, so 31.25ns per tick.
46
+ */
47
+#define TIMER_BASE 0x48000000
48
+
49
+/* PERIPHNSPPC0 register in the SSE-300 Secure Access Configuration block */
50
+#define PERIPHNSPPC0 (0x50080000 + 0x70)
51
+
52
+/* Base of the System Counter control frame */
53
+#define COUNTER_BASE 0x58100000
54
+
55
+/* SSE counter register offsets in the control frame */
56
+#define CNTCR 0
57
+#define CNTSR 0x4
58
+#define CNTCV_LO 0x8
59
+#define CNTCV_HI 0xc
60
+#define CNTSCR 0x10
61
+
62
+/* SSE timer register offsets */
63
+#define CNTPCT_LO 0
64
+#define CNTPCT_HI 4
65
+#define CNTFRQ 0x10
66
+#define CNTP_CVAL_LO 0x20
67
+#define CNTP_CVAL_HI 0x24
68
+#define CNTP_TVAL 0x28
69
+#define CNTP_CTL 0x2c
70
+#define CNTP_AIVAL_LO 0x40
71
+#define CNTP_AIVAL_HI 0x44
72
+#define CNTP_AIVAL_RELOAD 0x48
73
+#define CNTP_AIVAL_CTL 0x4c
74
+
75
+/* 4 ticks in nanoseconds (so we can work in integers) */
76
+#define FOUR_TICKS 125
77
+
78
+static void clock_step_ticks(uint64_t ticks)
79
+{
80
+ /*
81
+ * Advance the qtest clock by however many nanoseconds we
82
+ * need to move the timer forward the specified number of ticks.
83
+ * ticks must be a multiple of 4, so we get a whole number of ns.
84
+ */
85
+ assert(!(ticks & 3));
86
+ clock_step(FOUR_TICKS * (ticks >> 2));
87
+}
88
+
89
+static void reset_counter_and_timer(void)
90
+{
91
+ /*
92
+ * Reset the system counter and the timer between tests. This
93
+ * isn't a full reset, but it's sufficient for what the tests check.
94
+ */
95
+ writel(COUNTER_BASE + CNTCR, 0);
96
+ writel(TIMER_BASE + CNTP_CTL, 0);
97
+ writel(TIMER_BASE + CNTP_AIVAL_CTL, 0);
98
+ writel(COUNTER_BASE + CNTCV_LO, 0);
99
+ writel(COUNTER_BASE + CNTCV_HI, 0);
100
+}
101
+
102
+static void test_counter(void)
103
+{
104
+ /* Basic counter functionality test */
105
+
106
+ reset_counter_and_timer();
107
+ /* The counter should start disabled: check that it doesn't move */
108
+ clock_step_ticks(100);
109
+ g_assert_cmpuint(readl(COUNTER_BASE + CNTCV_LO), ==, 0);
110
+ g_assert_cmpuint(readl(COUNTER_BASE + CNTCV_HI), ==, 0);
111
+ /* Now enable it and check that it does count */
112
+ writel(COUNTER_BASE + CNTCR, 1);
113
+ clock_step_ticks(100);
114
+ g_assert_cmpuint(readl(COUNTER_BASE + CNTCV_LO), ==, 100);
115
+ g_assert_cmpuint(readl(COUNTER_BASE + CNTCV_HI), ==, 0);
116
+ /* Check the counter scaling functionality */
117
+ writel(COUNTER_BASE + CNTCR, 0);
118
+ writel(COUNTER_BASE + CNTSCR, 0x00100000); /* 1/16th normal speed */
119
+ writel(COUNTER_BASE + CNTCR, 5); /* EN, SCEN */
120
+ clock_step_ticks(160);
121
+ g_assert_cmpuint(readl(COUNTER_BASE + CNTCV_LO), ==, 110);
122
+ g_assert_cmpuint(readl(COUNTER_BASE + CNTCV_HI), ==, 0);
123
+}
124
+
125
+int main(int argc, char **argv)
126
+{
127
+ int r;
128
+
129
+ g_test_init(&argc, &argv, NULL);
130
+
131
+ qtest_start("-machine mps3-an547");
132
+
133
+ qtest_add_func("/sse-timer/counter", test_counter);
134
+
135
+ r = g_test_run();
136
+
137
+ qtest_end();
138
+
139
+ return r;
140
+}
22
diff --git a/MAINTAINERS b/MAINTAINERS
141
diff --git a/MAINTAINERS b/MAINTAINERS
23
index XXXXXXX..XXXXXXX 100644
142
index XXXXXXX..XXXXXXX 100644
24
--- a/MAINTAINERS
143
--- a/MAINTAINERS
25
+++ b/MAINTAINERS
144
+++ b/MAINTAINERS
26
@@ -XXX,XX +XXX,XX @@ M: Markus Armbruster <armbru@redhat.com>
145
@@ -XXX,XX +XXX,XX @@ F: hw/timer/sse-counter.c
27
S: Supported
146
F: include/hw/timer/sse-counter.h
28
F: scripts/coverity-model.c
147
F: hw/timer/sse-timer.c
29
148
F: include/hw/timer/sse-timer.h
30
+Coverity Scan integration
149
+F: tests/qtest/sse-timer-test.c
31
+M: Peter Maydell <peter.maydell@linaro.org>
150
F: docs/system/arm/mps2.rst
32
+S: Maintained
151
33
+F: scripts/coverity-scan/
152
Musca
34
+
153
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
35
Device Tree
154
index XXXXXXX..XXXXXXX 100644
36
M: Alistair Francis <alistair.francis@wdc.com>
155
--- a/tests/qtest/meson.build
37
R: David Gibson <david@gibson.dropbear.id.au>
156
+++ b/tests/qtest/meson.build
38
diff --git a/scripts/coverity-scan/run-coverity-scan b/scripts/coverity-scan/run-coverity-scan
157
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
39
new file mode 100755
158
'npcm7xx_watchdog_timer-test'] + \
40
index XXXXXXX..XXXXXXX
159
(slirp.found() ? ['npcm7xx_emc-test'] : [])
41
--- /dev/null
160
qtests_arm = \
42
+++ b/scripts/coverity-scan/run-coverity-scan
161
+ (config_all_devices.has_key('CONFIG_MPS2') ? ['sse-timer-test'] : []) + \
43
@@ -XXX,XX +XXX,XX @@
162
(config_all_devices.has_key('CONFIG_CMSDK_APB_DUALTIMER') ? ['cmsdk-apb-dualtimer-test'] : []) + \
44
+#!/bin/sh -e
163
(config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
45
+
164
(config_all_devices.has_key('CONFIG_CMSDK_APB_WATCHDOG') ? ['cmsdk-apb-watchdog-test'] : []) + \
46
+# Upload a created tarball to Coverity Scan, as per
47
+# https://scan.coverity.com/projects/qemu/builds/new
48
+
49
+# This work is licensed under the terms of the GNU GPL version 2,
50
+# or (at your option) any later version.
51
+# See the COPYING file in the top-level directory.
52
+#
53
+# Copyright (c) 2017-2020 Linaro Limited
54
+# Written by Peter Maydell
55
+
56
+# Note that this script will automatically download and
57
+# run the (closed-source) coverity build tools, so don't
58
+# use it if you don't trust them!
59
+
60
+# This script assumes that you're running it from a QEMU source
61
+# tree, and that tree is a fresh clean one, because we do an in-tree
62
+# build. (This is necessary so that the filenames that the Coverity
63
+# Scan server sees are relative paths that match up with the component
64
+# regular expressions it uses; an out-of-tree build won't work for this.)
65
+# The host machine should have as many of QEMU's dependencies
66
+# installed as possible, for maximum coverity coverage.
67
+
68
+# To do an upload you need to be a maintainer in the Coverity online
69
+# service, and you will need to know the "Coverity token", which is a
70
+# secret 8 digit hex string. You can find that from the web UI in the
71
+# project settings, if you have maintainer access there.
72
+
73
+# Command line options:
74
+# --dry-run : run the tools, but don't actually do the upload
75
+# --update-tools-only : update the cached copy of the tools, but don't run them
76
+# --tokenfile : file to read Coverity token from
77
+# --version ver : specify version being analyzed (default: ask git)
78
+# --description desc : specify description of this version (default: ask git)
79
+# --srcdir : QEMU source tree to analyze (default: current working dir)
80
+# --results-tarball : path to copy the results tarball to (default: don't
81
+# copy it anywhere, just upload it)
82
+#
83
+# User-specifiable environment variables:
84
+# COVERITY_TOKEN -- Coverity token
85
+# COVERITY_EMAIL -- the email address to use for uploads (default:
86
+# looks at your git user.email config)
87
+# COVERITY_BUILD_CMD -- make command (default: 'make -jN' where N is
88
+# number of CPUs as determined by 'nproc')
89
+# COVERITY_TOOL_BASE -- set to directory to put coverity tools
90
+# (default: /tmp/coverity-tools)
91
+#
92
+# You must specify the token, either by environment variable or by
93
+# putting it in a file and using --tokenfile. Everything else has
94
+# a reasonable default if this is run from a git tree.
95
+
96
+check_upload_permissions() {
97
+ # Check whether we can do an upload to the server; will exit the script
98
+ # with status 1 if the check failed (usually a bad token);
99
+ # will exit the script with status 0 if the check indicated that we
100
+ # can't upload yet (ie we are at quota)
101
+ # Assumes that PROJTOKEN, PROJNAME and DRYRUN have been initialized.
102
+
103
+ echo "Checking upload permissions..."
104
+
105
+ if ! up_perm="$(wget https://scan.coverity.com/api/upload_permitted --post-data "token=$PROJTOKEN&project=$PROJNAME" -q -O -)"; then
106
+ echo "Coverity Scan API access denied: bad token?"
107
+ exit 1
108
+ fi
109
+
110
+ # Really up_perm is a JSON response with either
111
+ # {upload_permitted:true} or {next_upload_permitted_at:<date>}
112
+ # We do some hacky string parsing instead of properly parsing it.
113
+ case "$up_perm" in
114
+ *upload_permitted*true*)
115
+ echo "Coverity Scan: upload permitted"
116
+ ;;
117
+ *next_upload_permitted_at*)
118
+ if [ "$DRYRUN" = yes ]; then
119
+ echo "Coverity Scan: upload quota reached, continuing dry run"
120
+ else
121
+ echo "Coverity Scan: upload quota reached; stopping here"
122
+ # Exit success as this isn't a build error.
123
+ exit 0
124
+ fi
125
+ ;;
126
+ *)
127
+ echo "Coverity Scan upload check: unexpected result $up_perm"
128
+ exit 1
129
+ ;;
130
+ esac
131
+}
132
+
133
+
134
+update_coverity_tools () {
135
+ # Check for whether we need to download the Coverity tools
136
+ # (either because we don't have a copy, or because it's out of date)
137
+ # Assumes that COVERITY_TOOL_BASE, PROJTOKEN and PROJNAME are set.
138
+
139
+ mkdir -p "$COVERITY_TOOL_BASE"
140
+ cd "$COVERITY_TOOL_BASE"
141
+
142
+ echo "Checking for new version of coverity build tools..."
143
+ wget https://scan.coverity.com/download/linux64 --post-data "token=$PROJTOKEN&project=$PROJNAME&md5=1" -O coverity_tool.md5.new
144
+
145
+ if ! cmp -s coverity_tool.md5 coverity_tool.md5.new; then
146
+ # out of date md5 or no md5: download new build tool
147
+ # blow away the old build tool
148
+ echo "Downloading coverity build tools..."
149
+ rm -rf coverity_tool coverity_tool.tgz
150
+ wget https://scan.coverity.com/download/linux64 --post-data "token=$PROJTOKEN&project=$PROJNAME" -O coverity_tool.tgz
151
+ if ! (cat coverity_tool.md5.new; echo " coverity_tool.tgz") | md5sum -c --status; then
152
+ echo "Downloaded tarball didn't match md5sum!"
153
+ exit 1
154
+ fi
155
+ # extract the new one, keeping it corralled in a 'coverity_tool' directory
156
+ echo "Unpacking coverity build tools..."
157
+ mkdir -p coverity_tool
158
+ cd coverity_tool
159
+ tar xf ../coverity_tool.tgz
160
+ cd ..
161
+ mv coverity_tool.md5.new coverity_tool.md5
162
+ fi
163
+
164
+ rm -f coverity_tool.md5.new
165
+}
166
+
167
+
168
+# Check user-provided environment variables and arguments
169
+DRYRUN=no
170
+UPDATE_ONLY=no
171
+
172
+while [ "$#" -ge 1 ]; do
173
+ case "$1" in
174
+ --dry-run)
175
+ shift
176
+ DRYRUN=yes
177
+ ;;
178
+ --update-tools-only)
179
+ shift
180
+ UPDATE_ONLY=yes
181
+ ;;
182
+ --version)
183
+ shift
184
+ if [ $# -eq 0 ]; then
185
+ echo "--version needs an argument"
186
+ exit 1
187
+ fi
188
+ VERSION="$1"
189
+ shift
190
+ ;;
191
+ --description)
192
+ shift
193
+ if [ $# -eq 0 ]; then
194
+ echo "--description needs an argument"
195
+ exit 1
196
+ fi
197
+ DESCRIPTION="$1"
198
+ shift
199
+ ;;
200
+ --tokenfile)
201
+ shift
202
+ if [ $# -eq 0 ]; then
203
+ echo "--tokenfile needs an argument"
204
+ exit 1
205
+ fi
206
+ COVERITY_TOKEN="$(cat "$1")"
207
+ shift
208
+ ;;
209
+ --srcdir)
210
+ shift
211
+ if [ $# -eq 0 ]; then
212
+ echo "--srcdir needs an argument"
213
+ exit 1
214
+ fi
215
+ SRCDIR="$1"
216
+ shift
217
+ ;;
218
+ --results-tarball)
219
+ shift
220
+ if [ $# -eq 0 ]; then
221
+ echo "--results-tarball needs an argument"
222
+ exit 1
223
+ fi
224
+ RESULTSTARBALL="$1"
225
+ shift
226
+ ;;
227
+ *)
228
+ echo "Unexpected argument '$1'"
229
+ exit 1
230
+ ;;
231
+ esac
232
+done
233
+
234
+if [ -z "$COVERITY_TOKEN" ]; then
235
+ echo "COVERITY_TOKEN environment variable not set"
236
+ exit 1
237
+fi
238
+
239
+if [ -z "$COVERITY_BUILD_CMD" ]; then
240
+ NPROC=$(nproc)
241
+ COVERITY_BUILD_CMD="make -j$NPROC"
242
+ echo "COVERITY_BUILD_CMD: using default '$COVERITY_BUILD_CMD'"
243
+fi
244
+
245
+if [ -z "$COVERITY_TOOL_BASE" ]; then
246
+ echo "COVERITY_TOOL_BASE: using default /tmp/coverity-tools"
247
+ COVERITY_TOOL_BASE=/tmp/coverity-tools
248
+fi
249
+
250
+if [ -z "$SRCDIR" ]; then
251
+ SRCDIR="$PWD"
252
+fi
253
+
254
+PROJTOKEN="$COVERITY_TOKEN"
255
+PROJNAME=QEMU
256
+TARBALL=cov-int.tar.xz
257
+
258
+
259
+if [ "$UPDATE_ONLY" = yes ]; then
260
+ # Just do the tools update; we don't need to check whether
261
+ # we are in a source tree or have upload rights for this,
262
+ # so do it before some of the command line and source tree checks.
263
+ update_coverity_tools
264
+ exit 0
265
+fi
266
+
267
+cd "$SRCDIR"
268
+
269
+echo "Checking this is a QEMU source tree..."
270
+if ! [ -e "$SRCDIR/VERSION" ]; then
271
+ echo "Not in a QEMU source tree?"
272
+ exit 1
273
+fi
274
+
275
+# Fill in defaults used by the non-update-only process
276
+if [ -z "$VERSION" ]; then
277
+ VERSION="$(git describe --always HEAD)"
278
+fi
279
+
280
+if [ -z "$DESCRIPTION" ]; then
281
+ DESCRIPTION="$(git rev-parse HEAD)"
282
+fi
283
+
284
+if [ -z "$COVERITY_EMAIL" ]; then
285
+ COVERITY_EMAIL="$(git config user.email)"
286
+fi
287
+
288
+check_upload_permissions
289
+
290
+update_coverity_tools
291
+
292
+TOOLBIN="$(cd "$COVERITY_TOOL_BASE" && echo $PWD/coverity_tool/cov-analysis-*/bin)"
293
+
294
+if ! test -x "$TOOLBIN/cov-build"; then
295
+ echo "Couldn't find cov-build in the coverity build-tool directory??"
296
+ exit 1
297
+fi
298
+
299
+export PATH="$TOOLBIN:$PATH"
300
+
301
+cd "$SRCDIR"
302
+
303
+echo "Doing make distclean..."
304
+make distclean
305
+
306
+echo "Configuring..."
307
+# We configure with a fixed set of enables here to ensure that we don't
308
+# accidentally reduce the scope of the analysis by doing the build on
309
+# the system that's missing a dependency that we need to build part of
310
+# the codebase.
311
+./configure --disable-modules --enable-sdl --enable-gtk \
312
+ --enable-opengl --enable-vte --enable-gnutls \
313
+ --enable-nettle --enable-curses --enable-curl \
314
+ --audio-drv-list=oss,alsa,sdl,pa --enable-virtfs \
315
+ --enable-vnc --enable-vnc-sasl --enable-vnc-jpeg --enable-vnc-png \
316
+ --enable-xen --enable-brlapi \
317
+ --enable-linux-aio --enable-attr \
318
+ --enable-cap-ng --enable-trace-backends=log --enable-spice --enable-rbd \
319
+ --enable-xfsctl --enable-libusb --enable-usb-redir \
320
+ --enable-libiscsi --enable-libnfs --enable-seccomp \
321
+ --enable-tpm --enable-libssh --enable-lzo --enable-snappy --enable-bzip2 \
322
+ --enable-numa --enable-rdma --enable-smartcard --enable-virglrenderer \
323
+ --enable-mpath --enable-libxml2 --enable-glusterfs \
324
+ --enable-virtfs --enable-zstd
325
+
326
+echo "Making libqemustub.a..."
327
+make libqemustub.a
328
+
329
+echo "Running cov-build..."
330
+rm -rf cov-int
331
+mkdir cov-int
332
+cov-build --dir cov-int $COVERITY_BUILD_CMD
333
+
334
+echo "Creating results tarball..."
335
+tar cvf - cov-int | xz > "$TARBALL"
336
+
337
+if [ ! -z "$RESULTSTARBALL" ]; then
338
+ echo "Copying results tarball to $RESULTSTARBALL..."
339
+ cp "$TARBALL" "$RESULTSTARBALL"
340
+fi
341
+
342
+echo "Uploading results tarball..."
343
+
344
+if [ "$DRYRUN" = yes ]; then
345
+ echo "Dry run only, not uploading $TARBALL"
346
+ exit 0
347
+fi
348
+
349
+curl --form token="$PROJTOKEN" --form email="$COVERITY_EMAIL" \
350
+ --form file=@"$TARBALL" --form version="$VERSION" \
351
+ --form description="$DESCRIPTION" \
352
+ https://scan.coverity.com/builds?project="$PROJNAME"
353
+
354
+echo "Done."
355
--
165
--
356
2.20.1
166
2.20.1
357
167
358
168
diff view generated by jsdifflib
1
The documentation of our -s and -gdb options is quite old; in
1
Add a test which tests various parts of the functionality of the
2
particular it still claims that it will cause QEMU to stop and wait
2
SSE system timer.
3
for the gdb connection, when this has not been true for some time:
4
you also need to pass -S if you want to make QEMU not launch the
5
guest on startup.
6
7
Improve the documentation to mention this requirement in the
8
executable's --help output, the documentation of the -gdb option in
9
the manual, and in the "GDB usage" chapter.
10
11
Includes some minor tweaks to these paragraphs of documentation
12
since I was editing them anyway (such as dropping the description
13
of our gdb support as "primitive").
14
3
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
19
Message-id: 20200403094014.9589-1-peter.maydell@linaro.org
20
---
7
---
21
docs/system/gdb.rst | 22 +++++++++++++++-------
8
tests/qtest/sse-timer-test.c | 91 ++++++++++++++++++++++++++++++++++++
22
qemu-options.hx | 24 ++++++++++++++++++------
9
1 file changed, 91 insertions(+)
23
2 files changed, 33 insertions(+), 13 deletions(-)
24
10
25
diff --git a/docs/system/gdb.rst b/docs/system/gdb.rst
11
diff --git a/tests/qtest/sse-timer-test.c b/tests/qtest/sse-timer-test.c
26
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
27
--- a/docs/system/gdb.rst
13
--- a/tests/qtest/sse-timer-test.c
28
+++ b/docs/system/gdb.rst
14
+++ b/tests/qtest/sse-timer-test.c
29
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static void test_counter(void)
30
GDB usage
16
g_assert_cmpuint(readl(COUNTER_BASE + CNTCV_HI), ==, 0);
31
---------
17
}
32
18
33
-QEMU has a primitive support to work with gdb, so that you can do
19
+static void test_timer(void)
34
-'Ctrl-C' while the virtual machine is running and inspect its state.
20
+{
35
+QEMU supports working with gdb via gdb's remote-connection facility
21
+ /* Basic timer functionality test */
36
+(the "gdbstub"). This allows you to debug guest code in the same
37
+way that you might with a low-level debug facility like JTAG
38
+on real hardware. You can stop and start the virtual machine,
39
+examine state like registers and memory, and set breakpoints and
40
+watchpoints.
41
42
-In order to use gdb, launch QEMU with the '-s' option. It will wait for
43
-a gdb connection:
44
+In order to use gdb, launch QEMU with the ``-s`` and ``-S`` options.
45
+The ``-s`` option will make QEMU listen for an incoming connection
46
+from gdb on TCP port 1234, and ``-S`` will make QEMU not start the
47
+guest until you tell it to from gdb. (If you want to specify which
48
+TCP port to use or to use something other than TCP for the gdbstub
49
+connection, use the ``-gdb dev`` option instead of ``-s``.)
50
51
.. parsed-literal::
52
53
- |qemu_system| -s -kernel bzImage -hda rootdisk.img -append "root=/dev/hda"
54
- Connected to host network interface: tun0
55
- Waiting gdb connection on port 1234
56
+ |qemu_system| -s -S -kernel bzImage -hda rootdisk.img -append "root=/dev/hda"
57
+
22
+
58
+QEMU will launch but will silently wait for gdb to connect.
23
+ reset_counter_and_timer();
59
24
+ /*
60
Then launch gdb on the 'vmlinux' executable::
25
+ * The timer is behind a Peripheral Protection Controller, and
61
26
+ * qtest accesses are always non-secure (no memory attributes),
62
diff --git a/qemu-options.hx b/qemu-options.hx
27
+ * so we must program the PPC to accept NS transactions. TIMER0
63
index XXXXXXX..XXXXXXX 100644
28
+ * is on port 0 of PPC0, controlled by bit 0 of this register.
64
--- a/qemu-options.hx
29
+ */
65
+++ b/qemu-options.hx
30
+ writel(PERIPHNSPPC0, 1);
66
@@ -XXX,XX +XXX,XX @@ SRST
31
+ /* We must enable the System Counter or the timer won't run. */
67
ERST
32
+ writel(COUNTER_BASE + CNTCR, 1);
68
69
DEF("gdb", HAS_ARG, QEMU_OPTION_gdb, \
70
- "-gdb dev wait for gdb connection on 'dev'\n", QEMU_ARCH_ALL)
71
+ "-gdb dev accept gdb connection on 'dev'. (QEMU defaults to starting\n"
72
+ " the guest without waiting for gdb to connect; use -S too\n"
73
+ " if you want it to not start execution.)\n",
74
+ QEMU_ARCH_ALL)
75
SRST
76
``-gdb dev``
77
- Wait for gdb connection on device dev (see
78
- :ref:`gdb_005fusage`). Typical connections will likely be
79
- TCP-based, but also UDP, pseudo TTY, or even stdio are reasonable
80
- use case. The latter is allowing to start QEMU from within gdb and
81
- establish the connection via a pipe:
82
+ Accept a gdb connection on device dev (see
83
+ :ref:`gdb_005fusage`). Note that this option does not pause QEMU
84
+ execution -- if you want QEMU to not start the guest until you
85
+ connect with gdb and issue a ``continue`` command, you will need to
86
+ also pass the ``-S`` option to QEMU.
87
+
33
+
88
+ The most usual configuration is to listen on a local TCP socket::
34
+ /* Timer starts disabled and with a counter of 0 */
35
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 0);
36
+ g_assert_cmpuint(readl(TIMER_BASE + CNTPCT_LO), ==, 0);
37
+ g_assert_cmpuint(readl(TIMER_BASE + CNTPCT_HI), ==, 0);
89
+
38
+
90
+ -gdb tcp::3117
39
+ /* Turn it on */
40
+ writel(TIMER_BASE + CNTP_CTL, 1);
91
+
41
+
92
+ but you can specify other backends; UDP, pseudo TTY, or even stdio
42
+ /* Is the timer ticking? */
93
+ are all reasonable use cases. For example, a stdio connection
43
+ clock_step_ticks(100);
94
+ allows you to start QEMU from within gdb and establish the
44
+ g_assert_cmpuint(readl(TIMER_BASE + CNTPCT_LO), ==, 100);
95
+ connection via a pipe:
45
+ g_assert_cmpuint(readl(TIMER_BASE + CNTPCT_HI), ==, 0);
96
46
+
97
.. parsed-literal::
47
+ /* Set the CompareValue to 4000 ticks */
48
+ writel(TIMER_BASE + CNTP_CVAL_LO, 4000);
49
+ writel(TIMER_BASE + CNTP_CVAL_HI, 0);
50
+
51
+ /* Check TVAL view of the counter */
52
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_TVAL), ==, 3900);
53
+
54
+ /* Advance to the CompareValue mark and check ISTATUS is set */
55
+ clock_step_ticks(3900);
56
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_TVAL), ==, 0);
57
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 5);
58
+
59
+ /* Now exercise the auto-reload part of the timer */
60
+ writel(TIMER_BASE + CNTP_AIVAL_RELOAD, 200);
61
+ writel(TIMER_BASE + CNTP_AIVAL_CTL, 1);
62
+
63
+ /* Check AIVAL was reloaded and that ISTATUS is now clear */
64
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_AIVAL_LO), ==, 4200);
65
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_AIVAL_HI), ==, 0);
66
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 1);
67
+
68
+ /*
69
+ * Check that when we advance forward to the reload time the interrupt
70
+ * fires and the value reloads
71
+ */
72
+ clock_step_ticks(100);
73
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 1);
74
+ clock_step_ticks(100);
75
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 5);
76
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_AIVAL_LO), ==, 4400);
77
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_AIVAL_HI), ==, 0);
78
+
79
+ clock_step_ticks(100);
80
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 5);
81
+ /* Check that writing 0 to CLR clears the interrupt */
82
+ writel(TIMER_BASE + CNTP_AIVAL_CTL, 1);
83
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 1);
84
+ /* Check that when we move forward to the reload time it fires again */
85
+ clock_step_ticks(100);
86
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 5);
87
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_AIVAL_LO), ==, 4600);
88
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_AIVAL_HI), ==, 0);
89
+
90
+ /*
91
+ * Step the clock far enough that we overflow the low half of the
92
+ * CNTPCT and AIVAL registers, and check that their high halves
93
+ * give the right values. We do the forward movement in
94
+ * non-autoinc mode because otherwise it takes forever as the
95
+ * timer has to emulate all the 'reload at t + N, t + 2N, etc'
96
+ * steps.
97
+ */
98
+ writel(TIMER_BASE + CNTP_AIVAL_CTL, 0);
99
+ clock_step_ticks(0x42ULL << 32);
100
+ g_assert_cmpuint(readl(TIMER_BASE + CNTPCT_LO), ==, 4400);
101
+ g_assert_cmpuint(readl(TIMER_BASE + CNTPCT_HI), ==, 0x42);
102
+
103
+ /* Turn on the autoinc again to check AIVAL_HI */
104
+ writel(TIMER_BASE + CNTP_AIVAL_CTL, 1);
105
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_AIVAL_LO), ==, 4600);
106
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_AIVAL_HI), ==, 0x42);
107
+}
108
+
109
int main(int argc, char **argv)
110
{
111
int r;
112
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
113
qtest_start("-machine mps3-an547");
114
115
qtest_add_func("/sse-timer/counter", test_counter);
116
+ qtest_add_func("/sse-timer/timer", test_timer);
117
118
r = g_test_run();
98
119
99
--
120
--
100
2.20.1
121
2.20.1
101
122
102
123
diff view generated by jsdifflib
1
In commit a1a98357e3fd in 2018 we added some workarounds for Coverity
1
Test that when we change the scaling of the system counter that the
2
not being able to handle the _Float* types introduced by recent
2
system timer responds appropriately.
3
glibc. Newer versions of the Coverity scan tools have support for
4
these types, and will fail with errors about duplicate typedefs if we
5
have our workaround. Remove our copy of the typedefs.
6
3
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20200319193323.2038-2-peter.maydell@linaro.org
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
---
7
---
11
include/qemu/osdep.h | 14 --------------
8
tests/qtest/sse-timer-test.c | 32 ++++++++++++++++++++++++++++++++
12
1 file changed, 14 deletions(-)
9
1 file changed, 32 insertions(+)
13
10
14
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
11
diff --git a/tests/qtest/sse-timer-test.c b/tests/qtest/sse-timer-test.c
15
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
16
--- a/include/qemu/osdep.h
13
--- a/tests/qtest/sse-timer-test.c
17
+++ b/include/qemu/osdep.h
14
+++ b/tests/qtest/sse-timer-test.c
18
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static void test_timer(void)
19
#else
16
g_assert_cmpuint(readl(TIMER_BASE + CNTP_AIVAL_HI), ==, 0x42);
20
#include "exec/poison.h"
17
}
21
#endif
18
22
-#ifdef __COVERITY__
19
+static void test_timer_scale_change(void)
23
-/* Coverity does not like the new _Float* types that are used by
20
+{
24
- * recent glibc, and croaks on every single file that includes
21
+ /*
25
- * stdlib.h. These typedefs are enough to please it.
22
+ * Test that the timer responds correctly to counter
26
- *
23
+ * scaling changes while it has an active timer.
27
- * Note that these fix parse errors so they cannot be placed in
24
+ */
28
- * scripts/coverity-model.c.
25
+ reset_counter_and_timer();
29
- */
26
+ /* Give ourselves access to the timer, and enable the counter and timer */
30
-typedef float _Float32;
27
+ writel(PERIPHNSPPC0, 1);
31
-typedef double _Float32x;
28
+ writel(COUNTER_BASE + CNTCR, 1);
32
-typedef double _Float64;
29
+ writel(TIMER_BASE + CNTP_CTL, 1);
33
-typedef __float80 _Float64x;
30
+ /* Set the CompareValue to 4000 ticks */
34
-typedef __float128 _Float128;
31
+ writel(TIMER_BASE + CNTP_CVAL_LO, 4000);
35
-#endif
32
+ writel(TIMER_BASE + CNTP_CVAL_HI, 0);
36
33
+ /* Advance halfway and check ISTATUS is not set */
37
#include "qemu/compiler.h"
34
+ clock_step_ticks(2000);
35
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 1);
36
+ /* Reprogram the counter to run at 1/16th speed */
37
+ writel(COUNTER_BASE + CNTCR, 0);
38
+ writel(COUNTER_BASE + CNTSCR, 0x00100000); /* 1/16th normal speed */
39
+ writel(COUNTER_BASE + CNTCR, 5); /* EN, SCEN */
40
+ /* Advance to where the timer would have fired and check it has not */
41
+ clock_step_ticks(2000);
42
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 1);
43
+ /* Advance to where the timer must fire at the new clock rate */
44
+ clock_step_ticks(29996);
45
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 1);
46
+ clock_step_ticks(4);
47
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 5);
48
+}
49
+
50
int main(int argc, char **argv)
51
{
52
int r;
53
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
54
55
qtest_add_func("/sse-timer/counter", test_counter);
56
qtest_add_func("/sse-timer/timer", test_timer);
57
+ qtest_add_func("/sse-timer/timer-scale-change", test_timer_scale_change);
58
59
r = g_test_run();
38
60
39
--
61
--
40
2.20.1
62
2.20.1
41
63
42
64
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
2
3
KVM requires the target cpu to be at least ARMv8 architecture
4
(support on ARMv7 has been dropped in commit 82bf7ae84ce:
5
"target/arm: Remove KVM support for 32-bit Arm hosts").
6
7
A KVM-only build won't be able to run TCG cpus, move the
8
v7A CPU definitions to cpu_tcg.c.
9
10
Reported-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20210306151801.2388182-1-f4bug@amsat.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
target/arm/cpu.c | 335 -------------------------------------------
17
target/arm/cpu_tcg.c | 318 ++++++++++++++++++++++++++++++++++++++++
18
2 files changed, 318 insertions(+), 335 deletions(-)
19
20
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.c
23
+++ b/target/arm/cpu.c
24
@@ -XXX,XX +XXX,XX @@ static ObjectClass *arm_cpu_class_by_name(const char *cpu_model)
25
return oc;
26
}
27
28
-/* CPU models. These are not needed for the AArch64 linux-user build. */
29
-#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
30
-
31
-static const ARMCPRegInfo cortexa8_cp_reginfo[] = {
32
- { .name = "L2LOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 0,
33
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
34
- { .name = "L2AUXCR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 2,
35
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
36
- REGINFO_SENTINEL
37
-};
38
-
39
-static void cortex_a8_initfn(Object *obj)
40
-{
41
- ARMCPU *cpu = ARM_CPU(obj);
42
-
43
- cpu->dtb_compatible = "arm,cortex-a8";
44
- set_feature(&cpu->env, ARM_FEATURE_V7);
45
- set_feature(&cpu->env, ARM_FEATURE_NEON);
46
- set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
47
- set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
48
- set_feature(&cpu->env, ARM_FEATURE_EL3);
49
- cpu->midr = 0x410fc080;
50
- cpu->reset_fpsid = 0x410330c0;
51
- cpu->isar.mvfr0 = 0x11110222;
52
- cpu->isar.mvfr1 = 0x00011111;
53
- cpu->ctr = 0x82048004;
54
- cpu->reset_sctlr = 0x00c50078;
55
- cpu->isar.id_pfr0 = 0x1031;
56
- cpu->isar.id_pfr1 = 0x11;
57
- cpu->isar.id_dfr0 = 0x400;
58
- cpu->id_afr0 = 0;
59
- cpu->isar.id_mmfr0 = 0x31100003;
60
- cpu->isar.id_mmfr1 = 0x20000000;
61
- cpu->isar.id_mmfr2 = 0x01202000;
62
- cpu->isar.id_mmfr3 = 0x11;
63
- cpu->isar.id_isar0 = 0x00101111;
64
- cpu->isar.id_isar1 = 0x12112111;
65
- cpu->isar.id_isar2 = 0x21232031;
66
- cpu->isar.id_isar3 = 0x11112131;
67
- cpu->isar.id_isar4 = 0x00111142;
68
- cpu->isar.dbgdidr = 0x15141000;
69
- cpu->clidr = (1 << 27) | (2 << 24) | 3;
70
- cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */
71
- cpu->ccsidr[1] = 0x2007e01a; /* 16k L1 icache. */
72
- cpu->ccsidr[2] = 0xf0000000; /* No L2 icache. */
73
- cpu->reset_auxcr = 2;
74
- define_arm_cp_regs(cpu, cortexa8_cp_reginfo);
75
-}
76
-
77
-static const ARMCPRegInfo cortexa9_cp_reginfo[] = {
78
- /*
79
- * power_control should be set to maximum latency. Again,
80
- * default to 0 and set by private hook
81
- */
82
- { .name = "A9_PWRCTL", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
83
- .access = PL1_RW, .resetvalue = 0,
84
- .fieldoffset = offsetof(CPUARMState, cp15.c15_power_control) },
85
- { .name = "A9_DIAG", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 1,
86
- .access = PL1_RW, .resetvalue = 0,
87
- .fieldoffset = offsetof(CPUARMState, cp15.c15_diagnostic) },
88
- { .name = "A9_PWRDIAG", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 2,
89
- .access = PL1_RW, .resetvalue = 0,
90
- .fieldoffset = offsetof(CPUARMState, cp15.c15_power_diagnostic) },
91
- { .name = "NEONBUSY", .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0,
92
- .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
93
- /* TLB lockdown control */
94
- { .name = "TLB_LOCKR", .cp = 15, .crn = 15, .crm = 4, .opc1 = 5, .opc2 = 2,
95
- .access = PL1_W, .resetvalue = 0, .type = ARM_CP_NOP },
96
- { .name = "TLB_LOCKW", .cp = 15, .crn = 15, .crm = 4, .opc1 = 5, .opc2 = 4,
97
- .access = PL1_W, .resetvalue = 0, .type = ARM_CP_NOP },
98
- { .name = "TLB_VA", .cp = 15, .crn = 15, .crm = 5, .opc1 = 5, .opc2 = 2,
99
- .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
100
- { .name = "TLB_PA", .cp = 15, .crn = 15, .crm = 6, .opc1 = 5, .opc2 = 2,
101
- .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
102
- { .name = "TLB_ATTR", .cp = 15, .crn = 15, .crm = 7, .opc1 = 5, .opc2 = 2,
103
- .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
104
- REGINFO_SENTINEL
105
-};
106
-
107
-static void cortex_a9_initfn(Object *obj)
108
-{
109
- ARMCPU *cpu = ARM_CPU(obj);
110
-
111
- cpu->dtb_compatible = "arm,cortex-a9";
112
- set_feature(&cpu->env, ARM_FEATURE_V7);
113
- set_feature(&cpu->env, ARM_FEATURE_NEON);
114
- set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
115
- set_feature(&cpu->env, ARM_FEATURE_EL3);
116
- /*
117
- * Note that A9 supports the MP extensions even for
118
- * A9UP and single-core A9MP (which are both different
119
- * and valid configurations; we don't model A9UP).
120
- */
121
- set_feature(&cpu->env, ARM_FEATURE_V7MP);
122
- set_feature(&cpu->env, ARM_FEATURE_CBAR);
123
- cpu->midr = 0x410fc090;
124
- cpu->reset_fpsid = 0x41033090;
125
- cpu->isar.mvfr0 = 0x11110222;
126
- cpu->isar.mvfr1 = 0x01111111;
127
- cpu->ctr = 0x80038003;
128
- cpu->reset_sctlr = 0x00c50078;
129
- cpu->isar.id_pfr0 = 0x1031;
130
- cpu->isar.id_pfr1 = 0x11;
131
- cpu->isar.id_dfr0 = 0x000;
132
- cpu->id_afr0 = 0;
133
- cpu->isar.id_mmfr0 = 0x00100103;
134
- cpu->isar.id_mmfr1 = 0x20000000;
135
- cpu->isar.id_mmfr2 = 0x01230000;
136
- cpu->isar.id_mmfr3 = 0x00002111;
137
- cpu->isar.id_isar0 = 0x00101111;
138
- cpu->isar.id_isar1 = 0x13112111;
139
- cpu->isar.id_isar2 = 0x21232041;
140
- cpu->isar.id_isar3 = 0x11112131;
141
- cpu->isar.id_isar4 = 0x00111142;
142
- cpu->isar.dbgdidr = 0x35141000;
143
- cpu->clidr = (1 << 27) | (1 << 24) | 3;
144
- cpu->ccsidr[0] = 0xe00fe019; /* 16k L1 dcache. */
145
- cpu->ccsidr[1] = 0x200fe019; /* 16k L1 icache. */
146
- define_arm_cp_regs(cpu, cortexa9_cp_reginfo);
147
-}
148
-
149
-#ifndef CONFIG_USER_ONLY
150
-static uint64_t a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
151
-{
152
- MachineState *ms = MACHINE(qdev_get_machine());
153
-
154
- /*
155
- * Linux wants the number of processors from here.
156
- * Might as well set the interrupt-controller bit too.
157
- */
158
- return ((ms->smp.cpus - 1) << 24) | (1 << 23);
159
-}
160
-#endif
161
-
162
-static const ARMCPRegInfo cortexa15_cp_reginfo[] = {
163
-#ifndef CONFIG_USER_ONLY
164
- { .name = "L2CTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 2,
165
- .access = PL1_RW, .resetvalue = 0, .readfn = a15_l2ctlr_read,
166
- .writefn = arm_cp_write_ignore, },
167
-#endif
168
- { .name = "L2ECTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 3,
169
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
170
- REGINFO_SENTINEL
171
-};
172
-
173
-static void cortex_a7_initfn(Object *obj)
174
-{
175
- ARMCPU *cpu = ARM_CPU(obj);
176
-
177
- cpu->dtb_compatible = "arm,cortex-a7";
178
- set_feature(&cpu->env, ARM_FEATURE_V7VE);
179
- set_feature(&cpu->env, ARM_FEATURE_NEON);
180
- set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
181
- set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
182
- set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
183
- set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
184
- set_feature(&cpu->env, ARM_FEATURE_EL2);
185
- set_feature(&cpu->env, ARM_FEATURE_EL3);
186
- set_feature(&cpu->env, ARM_FEATURE_PMU);
187
- cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A7;
188
- cpu->midr = 0x410fc075;
189
- cpu->reset_fpsid = 0x41023075;
190
- cpu->isar.mvfr0 = 0x10110222;
191
- cpu->isar.mvfr1 = 0x11111111;
192
- cpu->ctr = 0x84448003;
193
- cpu->reset_sctlr = 0x00c50078;
194
- cpu->isar.id_pfr0 = 0x00001131;
195
- cpu->isar.id_pfr1 = 0x00011011;
196
- cpu->isar.id_dfr0 = 0x02010555;
197
- cpu->id_afr0 = 0x00000000;
198
- cpu->isar.id_mmfr0 = 0x10101105;
199
- cpu->isar.id_mmfr1 = 0x40000000;
200
- cpu->isar.id_mmfr2 = 0x01240000;
201
- cpu->isar.id_mmfr3 = 0x02102211;
202
- /*
203
- * a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
204
- * table 4-41 gives 0x02101110, which includes the arm div insns.
205
- */
206
- cpu->isar.id_isar0 = 0x02101110;
207
- cpu->isar.id_isar1 = 0x13112111;
208
- cpu->isar.id_isar2 = 0x21232041;
209
- cpu->isar.id_isar3 = 0x11112131;
210
- cpu->isar.id_isar4 = 0x10011142;
211
- cpu->isar.dbgdidr = 0x3515f005;
212
- cpu->clidr = 0x0a200023;
213
- cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
214
- cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */
215
- cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */
216
- define_arm_cp_regs(cpu, cortexa15_cp_reginfo); /* Same as A15 */
217
-}
218
-
219
-static void cortex_a15_initfn(Object *obj)
220
-{
221
- ARMCPU *cpu = ARM_CPU(obj);
222
-
223
- cpu->dtb_compatible = "arm,cortex-a15";
224
- set_feature(&cpu->env, ARM_FEATURE_V7VE);
225
- set_feature(&cpu->env, ARM_FEATURE_NEON);
226
- set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
227
- set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
228
- set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
229
- set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
230
- set_feature(&cpu->env, ARM_FEATURE_EL2);
231
- set_feature(&cpu->env, ARM_FEATURE_EL3);
232
- set_feature(&cpu->env, ARM_FEATURE_PMU);
233
- cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15;
234
- cpu->midr = 0x412fc0f1;
235
- cpu->reset_fpsid = 0x410430f0;
236
- cpu->isar.mvfr0 = 0x10110222;
237
- cpu->isar.mvfr1 = 0x11111111;
238
- cpu->ctr = 0x8444c004;
239
- cpu->reset_sctlr = 0x00c50078;
240
- cpu->isar.id_pfr0 = 0x00001131;
241
- cpu->isar.id_pfr1 = 0x00011011;
242
- cpu->isar.id_dfr0 = 0x02010555;
243
- cpu->id_afr0 = 0x00000000;
244
- cpu->isar.id_mmfr0 = 0x10201105;
245
- cpu->isar.id_mmfr1 = 0x20000000;
246
- cpu->isar.id_mmfr2 = 0x01240000;
247
- cpu->isar.id_mmfr3 = 0x02102211;
248
- cpu->isar.id_isar0 = 0x02101110;
249
- cpu->isar.id_isar1 = 0x13112111;
250
- cpu->isar.id_isar2 = 0x21232041;
251
- cpu->isar.id_isar3 = 0x11112131;
252
- cpu->isar.id_isar4 = 0x10011142;
253
- cpu->isar.dbgdidr = 0x3515f021;
254
- cpu->clidr = 0x0a200023;
255
- cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
256
- cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */
257
- cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */
258
- define_arm_cp_regs(cpu, cortexa15_cp_reginfo);
259
-}
260
-
261
-#ifndef TARGET_AARCH64
262
-/*
263
- * -cpu max: a CPU with as many features enabled as our emulation supports.
264
- * The version of '-cpu max' for qemu-system-aarch64 is defined in cpu64.c;
265
- * this only needs to handle 32 bits, and need not care about KVM.
266
- */
267
-static void arm_max_initfn(Object *obj)
268
-{
269
- ARMCPU *cpu = ARM_CPU(obj);
270
-
271
- cortex_a15_initfn(obj);
272
-
273
- /* old-style VFP short-vector support */
274
- cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
275
-
276
-#ifdef CONFIG_USER_ONLY
277
- /*
278
- * We don't set these in system emulation mode for the moment,
279
- * since we don't correctly set (all of) the ID registers to
280
- * advertise them.
281
- */
282
- set_feature(&cpu->env, ARM_FEATURE_V8);
283
- {
284
- uint32_t t;
285
-
286
- t = cpu->isar.id_isar5;
287
- t = FIELD_DP32(t, ID_ISAR5, AES, 2);
288
- t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
289
- t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
290
- t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
291
- t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
292
- t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
293
- cpu->isar.id_isar5 = t;
294
-
295
- t = cpu->isar.id_isar6;
296
- t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
297
- t = FIELD_DP32(t, ID_ISAR6, DP, 1);
298
- t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
299
- t = FIELD_DP32(t, ID_ISAR6, SB, 1);
300
- t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
301
- cpu->isar.id_isar6 = t;
302
-
303
- t = cpu->isar.mvfr1;
304
- t = FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */
305
- t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
306
- cpu->isar.mvfr1 = t;
307
-
308
- t = cpu->isar.mvfr2;
309
- t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
310
- t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
311
- cpu->isar.mvfr2 = t;
312
-
313
- t = cpu->isar.id_mmfr3;
314
- t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
315
- cpu->isar.id_mmfr3 = t;
316
-
317
- t = cpu->isar.id_mmfr4;
318
- t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
319
- t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
320
- t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
321
- t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
322
- cpu->isar.id_mmfr4 = t;
323
-
324
- t = cpu->isar.id_pfr0;
325
- t = FIELD_DP32(t, ID_PFR0, DIT, 1);
326
- cpu->isar.id_pfr0 = t;
327
-
328
- t = cpu->isar.id_pfr2;
329
- t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
330
- cpu->isar.id_pfr2 = t;
331
- }
332
-#endif
333
-}
334
-#endif
335
-
336
-#endif /* !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) */
337
-
338
-static const ARMCPUInfo arm_cpus[] = {
339
-#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
340
- { .name = "cortex-a7", .initfn = cortex_a7_initfn },
341
- { .name = "cortex-a8", .initfn = cortex_a8_initfn },
342
- { .name = "cortex-a9", .initfn = cortex_a9_initfn },
343
- { .name = "cortex-a15", .initfn = cortex_a15_initfn },
344
-#ifndef TARGET_AARCH64
345
- { .name = "max", .initfn = arm_max_initfn },
346
-#endif
347
-#ifdef CONFIG_USER_ONLY
348
- { .name = "any", .initfn = arm_max_initfn },
349
-#endif
350
-#endif
351
-};
352
-
353
static Property arm_cpu_properties[] = {
354
DEFINE_PROP_UINT32("psci-conduit", ARMCPU, psci_conduit, 0),
355
DEFINE_PROP_UINT64("midr", ARMCPU, midr, 0),
356
@@ -XXX,XX +XXX,XX @@ static const TypeInfo arm_cpu_type_info = {
357
358
static void arm_cpu_register_types(void)
359
{
360
- const size_t cpu_count = ARRAY_SIZE(arm_cpus);
361
-
362
type_register_static(&arm_cpu_type_info);
363
364
#ifdef CONFIG_KVM
365
type_register_static(&host_arm_cpu_type_info);
366
#endif
367
-
368
- if (cpu_count) {
369
- size_t i;
370
-
371
- for (i = 0; i < cpu_count; ++i) {
372
- arm_cpu_register(&arm_cpus[i]);
373
- }
374
- }
375
}
376
377
type_init(arm_cpu_register_types)
378
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
379
index XXXXXXX..XXXXXXX 100644
380
--- a/target/arm/cpu_tcg.c
381
+++ b/target/arm/cpu_tcg.c
382
@@ -XXX,XX +XXX,XX @@
383
#endif /* CONFIG_TCG */
384
#include "internals.h"
385
#include "target/arm/idau.h"
386
+#if !defined(CONFIG_USER_ONLY)
387
+#include "hw/boards.h"
388
+#endif
389
390
/* CPU models. These are not needed for the AArch64 linux-user build. */
391
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
392
@@ -XXX,XX +XXX,XX @@ static void arm11mpcore_initfn(Object *obj)
393
cpu->reset_auxcr = 1;
394
}
395
396
+static const ARMCPRegInfo cortexa8_cp_reginfo[] = {
397
+ { .name = "L2LOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 0,
398
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
399
+ { .name = "L2AUXCR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 2,
400
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
401
+ REGINFO_SENTINEL
402
+};
403
+
404
+static void cortex_a8_initfn(Object *obj)
405
+{
406
+ ARMCPU *cpu = ARM_CPU(obj);
407
+
408
+ cpu->dtb_compatible = "arm,cortex-a8";
409
+ set_feature(&cpu->env, ARM_FEATURE_V7);
410
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
411
+ set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
412
+ set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
413
+ set_feature(&cpu->env, ARM_FEATURE_EL3);
414
+ cpu->midr = 0x410fc080;
415
+ cpu->reset_fpsid = 0x410330c0;
416
+ cpu->isar.mvfr0 = 0x11110222;
417
+ cpu->isar.mvfr1 = 0x00011111;
418
+ cpu->ctr = 0x82048004;
419
+ cpu->reset_sctlr = 0x00c50078;
420
+ cpu->isar.id_pfr0 = 0x1031;
421
+ cpu->isar.id_pfr1 = 0x11;
422
+ cpu->isar.id_dfr0 = 0x400;
423
+ cpu->id_afr0 = 0;
424
+ cpu->isar.id_mmfr0 = 0x31100003;
425
+ cpu->isar.id_mmfr1 = 0x20000000;
426
+ cpu->isar.id_mmfr2 = 0x01202000;
427
+ cpu->isar.id_mmfr3 = 0x11;
428
+ cpu->isar.id_isar0 = 0x00101111;
429
+ cpu->isar.id_isar1 = 0x12112111;
430
+ cpu->isar.id_isar2 = 0x21232031;
431
+ cpu->isar.id_isar3 = 0x11112131;
432
+ cpu->isar.id_isar4 = 0x00111142;
433
+ cpu->isar.dbgdidr = 0x15141000;
434
+ cpu->clidr = (1 << 27) | (2 << 24) | 3;
435
+ cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */
436
+ cpu->ccsidr[1] = 0x2007e01a; /* 16k L1 icache. */
437
+ cpu->ccsidr[2] = 0xf0000000; /* No L2 icache. */
438
+ cpu->reset_auxcr = 2;
439
+ define_arm_cp_regs(cpu, cortexa8_cp_reginfo);
440
+}
441
+
442
+static const ARMCPRegInfo cortexa9_cp_reginfo[] = {
443
+ /*
444
+ * power_control should be set to maximum latency. Again,
445
+ * default to 0 and set by private hook
446
+ */
447
+ { .name = "A9_PWRCTL", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
448
+ .access = PL1_RW, .resetvalue = 0,
449
+ .fieldoffset = offsetof(CPUARMState, cp15.c15_power_control) },
450
+ { .name = "A9_DIAG", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 1,
451
+ .access = PL1_RW, .resetvalue = 0,
452
+ .fieldoffset = offsetof(CPUARMState, cp15.c15_diagnostic) },
453
+ { .name = "A9_PWRDIAG", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 2,
454
+ .access = PL1_RW, .resetvalue = 0,
455
+ .fieldoffset = offsetof(CPUARMState, cp15.c15_power_diagnostic) },
456
+ { .name = "NEONBUSY", .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0,
457
+ .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
458
+ /* TLB lockdown control */
459
+ { .name = "TLB_LOCKR", .cp = 15, .crn = 15, .crm = 4, .opc1 = 5, .opc2 = 2,
460
+ .access = PL1_W, .resetvalue = 0, .type = ARM_CP_NOP },
461
+ { .name = "TLB_LOCKW", .cp = 15, .crn = 15, .crm = 4, .opc1 = 5, .opc2 = 4,
462
+ .access = PL1_W, .resetvalue = 0, .type = ARM_CP_NOP },
463
+ { .name = "TLB_VA", .cp = 15, .crn = 15, .crm = 5, .opc1 = 5, .opc2 = 2,
464
+ .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
465
+ { .name = "TLB_PA", .cp = 15, .crn = 15, .crm = 6, .opc1 = 5, .opc2 = 2,
466
+ .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
467
+ { .name = "TLB_ATTR", .cp = 15, .crn = 15, .crm = 7, .opc1 = 5, .opc2 = 2,
468
+ .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
469
+ REGINFO_SENTINEL
470
+};
471
+
472
+static void cortex_a9_initfn(Object *obj)
473
+{
474
+ ARMCPU *cpu = ARM_CPU(obj);
475
+
476
+ cpu->dtb_compatible = "arm,cortex-a9";
477
+ set_feature(&cpu->env, ARM_FEATURE_V7);
478
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
479
+ set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
480
+ set_feature(&cpu->env, ARM_FEATURE_EL3);
481
+ /*
482
+ * Note that A9 supports the MP extensions even for
483
+ * A9UP and single-core A9MP (which are both different
484
+ * and valid configurations; we don't model A9UP).
485
+ */
486
+ set_feature(&cpu->env, ARM_FEATURE_V7MP);
487
+ set_feature(&cpu->env, ARM_FEATURE_CBAR);
488
+ cpu->midr = 0x410fc090;
489
+ cpu->reset_fpsid = 0x41033090;
490
+ cpu->isar.mvfr0 = 0x11110222;
491
+ cpu->isar.mvfr1 = 0x01111111;
492
+ cpu->ctr = 0x80038003;
493
+ cpu->reset_sctlr = 0x00c50078;
494
+ cpu->isar.id_pfr0 = 0x1031;
495
+ cpu->isar.id_pfr1 = 0x11;
496
+ cpu->isar.id_dfr0 = 0x000;
497
+ cpu->id_afr0 = 0;
498
+ cpu->isar.id_mmfr0 = 0x00100103;
499
+ cpu->isar.id_mmfr1 = 0x20000000;
500
+ cpu->isar.id_mmfr2 = 0x01230000;
501
+ cpu->isar.id_mmfr3 = 0x00002111;
502
+ cpu->isar.id_isar0 = 0x00101111;
503
+ cpu->isar.id_isar1 = 0x13112111;
504
+ cpu->isar.id_isar2 = 0x21232041;
505
+ cpu->isar.id_isar3 = 0x11112131;
506
+ cpu->isar.id_isar4 = 0x00111142;
507
+ cpu->isar.dbgdidr = 0x35141000;
508
+ cpu->clidr = (1 << 27) | (1 << 24) | 3;
509
+ cpu->ccsidr[0] = 0xe00fe019; /* 16k L1 dcache. */
510
+ cpu->ccsidr[1] = 0x200fe019; /* 16k L1 icache. */
511
+ define_arm_cp_regs(cpu, cortexa9_cp_reginfo);
512
+}
513
+
514
+#ifndef CONFIG_USER_ONLY
515
+static uint64_t a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
516
+{
517
+ MachineState *ms = MACHINE(qdev_get_machine());
518
+
519
+ /*
520
+ * Linux wants the number of processors from here.
521
+ * Might as well set the interrupt-controller bit too.
522
+ */
523
+ return ((ms->smp.cpus - 1) << 24) | (1 << 23);
524
+}
525
+#endif
526
+
527
+static const ARMCPRegInfo cortexa15_cp_reginfo[] = {
528
+#ifndef CONFIG_USER_ONLY
529
+ { .name = "L2CTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 2,
530
+ .access = PL1_RW, .resetvalue = 0, .readfn = a15_l2ctlr_read,
531
+ .writefn = arm_cp_write_ignore, },
532
+#endif
533
+ { .name = "L2ECTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 3,
534
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
535
+ REGINFO_SENTINEL
536
+};
537
+
538
+static void cortex_a7_initfn(Object *obj)
539
+{
540
+ ARMCPU *cpu = ARM_CPU(obj);
541
+
542
+ cpu->dtb_compatible = "arm,cortex-a7";
543
+ set_feature(&cpu->env, ARM_FEATURE_V7VE);
544
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
545
+ set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
546
+ set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
547
+ set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
548
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
549
+ set_feature(&cpu->env, ARM_FEATURE_EL2);
550
+ set_feature(&cpu->env, ARM_FEATURE_EL3);
551
+ set_feature(&cpu->env, ARM_FEATURE_PMU);
552
+ cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A7;
553
+ cpu->midr = 0x410fc075;
554
+ cpu->reset_fpsid = 0x41023075;
555
+ cpu->isar.mvfr0 = 0x10110222;
556
+ cpu->isar.mvfr1 = 0x11111111;
557
+ cpu->ctr = 0x84448003;
558
+ cpu->reset_sctlr = 0x00c50078;
559
+ cpu->isar.id_pfr0 = 0x00001131;
560
+ cpu->isar.id_pfr1 = 0x00011011;
561
+ cpu->isar.id_dfr0 = 0x02010555;
562
+ cpu->id_afr0 = 0x00000000;
563
+ cpu->isar.id_mmfr0 = 0x10101105;
564
+ cpu->isar.id_mmfr1 = 0x40000000;
565
+ cpu->isar.id_mmfr2 = 0x01240000;
566
+ cpu->isar.id_mmfr3 = 0x02102211;
567
+ /*
568
+ * a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
569
+ * table 4-41 gives 0x02101110, which includes the arm div insns.
570
+ */
571
+ cpu->isar.id_isar0 = 0x02101110;
572
+ cpu->isar.id_isar1 = 0x13112111;
573
+ cpu->isar.id_isar2 = 0x21232041;
574
+ cpu->isar.id_isar3 = 0x11112131;
575
+ cpu->isar.id_isar4 = 0x10011142;
576
+ cpu->isar.dbgdidr = 0x3515f005;
577
+ cpu->clidr = 0x0a200023;
578
+ cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
579
+ cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */
580
+ cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */
581
+ define_arm_cp_regs(cpu, cortexa15_cp_reginfo); /* Same as A15 */
582
+}
583
+
584
+static void cortex_a15_initfn(Object *obj)
585
+{
586
+ ARMCPU *cpu = ARM_CPU(obj);
587
+
588
+ cpu->dtb_compatible = "arm,cortex-a15";
589
+ set_feature(&cpu->env, ARM_FEATURE_V7VE);
590
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
591
+ set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
592
+ set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
593
+ set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
594
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
595
+ set_feature(&cpu->env, ARM_FEATURE_EL2);
596
+ set_feature(&cpu->env, ARM_FEATURE_EL3);
597
+ set_feature(&cpu->env, ARM_FEATURE_PMU);
598
+ cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15;
599
+ cpu->midr = 0x412fc0f1;
600
+ cpu->reset_fpsid = 0x410430f0;
601
+ cpu->isar.mvfr0 = 0x10110222;
602
+ cpu->isar.mvfr1 = 0x11111111;
603
+ cpu->ctr = 0x8444c004;
604
+ cpu->reset_sctlr = 0x00c50078;
605
+ cpu->isar.id_pfr0 = 0x00001131;
606
+ cpu->isar.id_pfr1 = 0x00011011;
607
+ cpu->isar.id_dfr0 = 0x02010555;
608
+ cpu->id_afr0 = 0x00000000;
609
+ cpu->isar.id_mmfr0 = 0x10201105;
610
+ cpu->isar.id_mmfr1 = 0x20000000;
611
+ cpu->isar.id_mmfr2 = 0x01240000;
612
+ cpu->isar.id_mmfr3 = 0x02102211;
613
+ cpu->isar.id_isar0 = 0x02101110;
614
+ cpu->isar.id_isar1 = 0x13112111;
615
+ cpu->isar.id_isar2 = 0x21232041;
616
+ cpu->isar.id_isar3 = 0x11112131;
617
+ cpu->isar.id_isar4 = 0x10011142;
618
+ cpu->isar.dbgdidr = 0x3515f021;
619
+ cpu->clidr = 0x0a200023;
620
+ cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
621
+ cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */
622
+ cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */
623
+ define_arm_cp_regs(cpu, cortexa15_cp_reginfo);
624
+}
625
+
626
static void cortex_m0_initfn(Object *obj)
627
{
628
ARMCPU *cpu = ARM_CPU(obj);
629
@@ -XXX,XX +XXX,XX @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
630
cc->gdb_core_xml_file = "arm-m-profile.xml";
631
}
632
633
+#ifndef TARGET_AARCH64
634
+/*
635
+ * -cpu max: a CPU with as many features enabled as our emulation supports.
636
+ * The version of '-cpu max' for qemu-system-aarch64 is defined in cpu64.c;
637
+ * this only needs to handle 32 bits, and need not care about KVM.
638
+ */
639
+static void arm_max_initfn(Object *obj)
640
+{
641
+ ARMCPU *cpu = ARM_CPU(obj);
642
+
643
+ cortex_a15_initfn(obj);
644
+
645
+ /* old-style VFP short-vector support */
646
+ cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
647
+
648
+#ifdef CONFIG_USER_ONLY
649
+ /*
650
+ * We don't set these in system emulation mode for the moment,
651
+ * since we don't correctly set (all of) the ID registers to
652
+ * advertise them.
653
+ */
654
+ set_feature(&cpu->env, ARM_FEATURE_V8);
655
+ {
656
+ uint32_t t;
657
+
658
+ t = cpu->isar.id_isar5;
659
+ t = FIELD_DP32(t, ID_ISAR5, AES, 2);
660
+ t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
661
+ t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
662
+ t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
663
+ t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
664
+ t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
665
+ cpu->isar.id_isar5 = t;
666
+
667
+ t = cpu->isar.id_isar6;
668
+ t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
669
+ t = FIELD_DP32(t, ID_ISAR6, DP, 1);
670
+ t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
671
+ t = FIELD_DP32(t, ID_ISAR6, SB, 1);
672
+ t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
673
+ cpu->isar.id_isar6 = t;
674
+
675
+ t = cpu->isar.mvfr1;
676
+ t = FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */
677
+ t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
678
+ cpu->isar.mvfr1 = t;
679
+
680
+ t = cpu->isar.mvfr2;
681
+ t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
682
+ t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
683
+ cpu->isar.mvfr2 = t;
684
+
685
+ t = cpu->isar.id_mmfr3;
686
+ t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
687
+ cpu->isar.id_mmfr3 = t;
688
+
689
+ t = cpu->isar.id_mmfr4;
690
+ t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
691
+ t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
692
+ t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
693
+ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
694
+ cpu->isar.id_mmfr4 = t;
695
+
696
+ t = cpu->isar.id_pfr0;
697
+ t = FIELD_DP32(t, ID_PFR0, DIT, 1);
698
+ cpu->isar.id_pfr0 = t;
699
+
700
+ t = cpu->isar.id_pfr2;
701
+ t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
702
+ cpu->isar.id_pfr2 = t;
703
+ }
704
+#endif /* CONFIG_USER_ONLY */
705
+}
706
+#endif /* !TARGET_AARCH64 */
707
+
708
static const ARMCPUInfo arm_tcg_cpus[] = {
709
{ .name = "arm926", .initfn = arm926_initfn },
710
{ .name = "arm946", .initfn = arm946_initfn },
711
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_tcg_cpus[] = {
712
{ .name = "arm1136", .initfn = arm1136_initfn },
713
{ .name = "arm1176", .initfn = arm1176_initfn },
714
{ .name = "arm11mpcore", .initfn = arm11mpcore_initfn },
715
+ { .name = "cortex-a7", .initfn = cortex_a7_initfn },
716
+ { .name = "cortex-a8", .initfn = cortex_a8_initfn },
717
+ { .name = "cortex-a9", .initfn = cortex_a9_initfn },
718
+ { .name = "cortex-a15", .initfn = cortex_a15_initfn },
719
{ .name = "cortex-m0", .initfn = cortex_m0_initfn,
720
.class_init = arm_v7m_class_init },
721
{ .name = "cortex-m3", .initfn = cortex_m3_initfn,
722
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_tcg_cpus[] = {
723
{ .name = "pxa270-b1", .initfn = pxa270b1_initfn },
724
{ .name = "pxa270-c0", .initfn = pxa270c0_initfn },
725
{ .name = "pxa270-c5", .initfn = pxa270c5_initfn },
726
+#ifndef TARGET_AARCH64
727
+ { .name = "max", .initfn = arm_max_initfn },
728
+#endif
729
+#ifdef CONFIG_USER_ONLY
730
+ { .name = "any", .initfn = arm_max_initfn },
731
+#endif
732
};
733
734
static const TypeInfo idau_interface_type_info = {
735
--
736
2.20.1
737
738
diff view generated by jsdifflib
1
Add support for running the Coverity Scan tools inside a Docker
1
From: Xuzhou Cheng <xuzhou.cheng@windriver.com>
2
container rather than directly on the host system.
3
2
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
3
ZynqMP QSPI supports SPI transfer using DMA mode, but currently this
4
is unimplemented. When QSPI is programmed to use DMA mode, QEMU will
5
crash. This is observed when testing VxWorks 7.
6
7
This adds a Xilinx CSU DMA model and the implementation is based on
8
https://github.com/Xilinx/qemu/blob/master/hw/dma/csu_stream_dma.c.
9
The DST part of the model is verified along with ZynqMP GQSPI model.
10
11
Signed-off-by: Xuzhou Cheng <xuzhou.cheng@windriver.com>
12
Signed-off-by: Bin Meng <bin.meng@windriver.com>
13
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
14
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
15
Message-id: 20210303135254.3970-2-bmeng.cn@gmail.com
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Message-id: 20200319193323.2038-7-peter.maydell@linaro.org
7
---
17
---
8
scripts/coverity-scan/coverity-scan.docker | 131 +++++++++++++++++++++
18
include/hw/dma/xlnx_csu_dma.h | 52 +++
9
scripts/coverity-scan/run-coverity-scan | 90 ++++++++++++++
19
hw/dma/xlnx_csu_dma.c | 745 ++++++++++++++++++++++++++++++++++
10
2 files changed, 221 insertions(+)
20
hw/dma/Kconfig | 4 +
11
create mode 100644 scripts/coverity-scan/coverity-scan.docker
21
hw/dma/meson.build | 1 +
22
4 files changed, 802 insertions(+)
23
create mode 100644 include/hw/dma/xlnx_csu_dma.h
24
create mode 100644 hw/dma/xlnx_csu_dma.c
12
25
13
diff --git a/scripts/coverity-scan/coverity-scan.docker b/scripts/coverity-scan/coverity-scan.docker
26
diff --git a/include/hw/dma/xlnx_csu_dma.h b/include/hw/dma/xlnx_csu_dma.h
14
new file mode 100644
27
new file mode 100644
15
index XXXXXXX..XXXXXXX
28
index XXXXXXX..XXXXXXX
16
--- /dev/null
29
--- /dev/null
17
+++ b/scripts/coverity-scan/coverity-scan.docker
30
+++ b/include/hw/dma/xlnx_csu_dma.h
18
@@ -XXX,XX +XXX,XX @@
31
@@ -XXX,XX +XXX,XX @@
19
+# syntax=docker/dockerfile:1.0.0-experimental
32
+/*
20
+#
33
+ * Xilinx Platform CSU Stream DMA emulation
21
+# Docker setup for running the "Coverity Scan" tools over the source
34
+ *
22
+# tree and uploading them to the website, as per
35
+ * This implementation is based on
23
+# https://scan.coverity.com/projects/qemu/builds/new
36
+ * https://github.com/Xilinx/qemu/blob/master/hw/dma/csu_stream_dma.c
24
+# We do this on a fixed config (currently Fedora 30 with a known
37
+ *
25
+# set of dependencies and a configure command that enables a specific
38
+ * This program is free software; you can redistribute it and/or
26
+# set of options) so that random changes don't result in our accidentally
39
+ * modify it under the terms of the GNU General Public License as
27
+# dropping some files from the scan.
40
+ * published by the Free Software Foundation; either version 2 or
28
+#
41
+ * (at your option) version 3 of the License.
29
+# We don't build on top of the fedora.docker file because we don't
42
+ *
30
+# want to accidentally change or break the scan config when that
43
+ * This program is distributed in the hope that it will be useful,
31
+# is updated.
44
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32
+
45
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33
+# The work of actually doing the build is handled by the
46
+ * GNU General Public License for more details.
34
+# run-coverity-scan script.
47
+ *
35
+
48
+ * You should have received a copy of the GNU General Public License along
36
+FROM fedora:30
49
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
37
+ENV PACKAGES \
50
+ */
38
+ alsa-lib-devel \
51
+
39
+ bc \
52
+#ifndef XLNX_CSU_DMA_H
40
+ bison \
53
+#define XLNX_CSU_DMA_H
41
+ brlapi-devel \
54
+
42
+ bzip2 \
55
+#define TYPE_XLNX_CSU_DMA "xlnx.csu_dma"
43
+ bzip2-devel \
56
+
44
+ ccache \
57
+#define XLNX_CSU_DMA_R_MAX (0x2c / 4)
45
+ clang \
58
+
46
+ curl \
59
+typedef struct XlnxCSUDMA {
47
+ cyrus-sasl-devel \
60
+ SysBusDevice busdev;
48
+ dbus-daemon \
61
+ MemoryRegion iomem;
49
+ device-mapper-multipath-devel \
62
+ MemTxAttrs attr;
50
+ findutils \
63
+ MemoryRegion *dma_mr;
51
+ flex \
64
+ AddressSpace *dma_as;
52
+ gcc \
65
+ qemu_irq irq;
53
+ gcc-c++ \
66
+ StreamSink *tx_dev; /* Used as generic StreamSink */
54
+ gettext \
67
+ ptimer_state *src_timer;
55
+ git \
68
+
56
+ glib2-devel \
69
+ uint16_t width;
57
+ glusterfs-api-devel \
70
+ bool is_dst;
58
+ gnutls-devel \
71
+ bool r_size_last_word;
59
+ gtk3-devel \
72
+
60
+ hostname \
73
+ StreamCanPushNotifyFn notify;
61
+ libaio-devel \
74
+ void *notify_opaque;
62
+ libasan \
75
+
63
+ libattr-devel \
76
+ uint32_t regs[XLNX_CSU_DMA_R_MAX];
64
+ libblockdev-mpath-devel \
77
+ RegisterInfo regs_info[XLNX_CSU_DMA_R_MAX];
65
+ libcap-devel \
78
+} XlnxCSUDMA;
66
+ libcap-ng-devel \
79
+
67
+ libcurl-devel \
80
+#define XLNX_CSU_DMA(obj) \
68
+ libepoxy-devel \
81
+ OBJECT_CHECK(XlnxCSUDMA, (obj), TYPE_XLNX_CSU_DMA)
69
+ libfdt-devel \
82
+
70
+ libgbm-devel \
83
+#endif
71
+ libiscsi-devel \
84
diff --git a/hw/dma/xlnx_csu_dma.c b/hw/dma/xlnx_csu_dma.c
72
+ libjpeg-devel \
85
new file mode 100644
73
+ libpmem-devel \
86
index XXXXXXX..XXXXXXX
74
+ libnfs-devel \
87
--- /dev/null
75
+ libpng-devel \
88
+++ b/hw/dma/xlnx_csu_dma.c
76
+ librbd-devel \
77
+ libseccomp-devel \
78
+ libssh-devel \
79
+ libubsan \
80
+ libudev-devel \
81
+ libusbx-devel \
82
+ libxml2-devel \
83
+ libzstd-devel \
84
+ llvm \
85
+ lzo-devel \
86
+ make \
87
+ mingw32-bzip2 \
88
+ mingw32-curl \
89
+ mingw32-glib2 \
90
+ mingw32-gmp \
91
+ mingw32-gnutls \
92
+ mingw32-gtk3 \
93
+ mingw32-libjpeg-turbo \
94
+ mingw32-libpng \
95
+ mingw32-libtasn1 \
96
+ mingw32-nettle \
97
+ mingw32-nsis \
98
+ mingw32-pixman \
99
+ mingw32-pkg-config \
100
+ mingw32-SDL2 \
101
+ mingw64-bzip2 \
102
+ mingw64-curl \
103
+ mingw64-glib2 \
104
+ mingw64-gmp \
105
+ mingw64-gnutls \
106
+ mingw64-gtk3 \
107
+ mingw64-libjpeg-turbo \
108
+ mingw64-libpng \
109
+ mingw64-libtasn1 \
110
+ mingw64-nettle \
111
+ mingw64-pixman \
112
+ mingw64-pkg-config \
113
+ mingw64-SDL2 \
114
+ ncurses-devel \
115
+ nettle-devel \
116
+ nss-devel \
117
+ numactl-devel \
118
+ perl \
119
+ perl-Test-Harness \
120
+ pixman-devel \
121
+ pulseaudio-libs-devel \
122
+ python3 \
123
+ python3-sphinx \
124
+ PyYAML \
125
+ rdma-core-devel \
126
+ SDL2-devel \
127
+ snappy-devel \
128
+ sparse \
129
+ spice-server-devel \
130
+ systemd-devel \
131
+ systemtap-sdt-devel \
132
+ tar \
133
+ texinfo \
134
+ usbredir-devel \
135
+ virglrenderer-devel \
136
+ vte291-devel \
137
+ wget \
138
+ which \
139
+ xen-devel \
140
+ xfsprogs-devel \
141
+ zlib-devel
142
+ENV QEMU_CONFIGURE_OPTS --python=/usr/bin/python3
143
+
144
+RUN dnf install -y $PACKAGES
145
+RUN rpm -q $PACKAGES | sort > /packages.txt
146
+ENV PATH $PATH:/usr/libexec/python3-sphinx/
147
+ENV COVERITY_TOOL_BASE=/coverity-tools
148
+COPY run-coverity-scan run-coverity-scan
149
+RUN --mount=type=secret,id=coverity.token,required ./run-coverity-scan --update-tools-only --tokenfile /run/secrets/coverity.token
150
diff --git a/scripts/coverity-scan/run-coverity-scan b/scripts/coverity-scan/run-coverity-scan
151
index XXXXXXX..XXXXXXX 100755
152
--- a/scripts/coverity-scan/run-coverity-scan
153
+++ b/scripts/coverity-scan/run-coverity-scan
154
@@ -XXX,XX +XXX,XX @@
89
@@ -XXX,XX +XXX,XX @@
155
90
+/*
156
# Command line options:
91
+ * Xilinx Platform CSU Stream DMA emulation
157
# --dry-run : run the tools, but don't actually do the upload
92
+ *
158
+# --docker : create and work inside a docker container
93
+ * This implementation is based on
159
# --update-tools-only : update the cached copy of the tools, but don't run them
94
+ * https://github.com/Xilinx/qemu/blob/master/hw/dma/csu_stream_dma.c
160
# --tokenfile : file to read Coverity token from
95
+ *
161
# --version ver : specify version being analyzed (default: ask git)
96
+ * This program is free software; you can redistribute it and/or
162
@@ -XXX,XX +XXX,XX @@
97
+ * modify it under the terms of the GNU General Public License as
163
# --srcdir : QEMU source tree to analyze (default: current working dir)
98
+ * published by the Free Software Foundation; either version 2 or
164
# --results-tarball : path to copy the results tarball to (default: don't
99
+ * (at your option) version 3 of the License.
165
# copy it anywhere, just upload it)
100
+ *
166
+# --src-tarball : tarball to untar into src dir (default: none); this
101
+ * This program is distributed in the hope that it will be useful,
167
+# is intended mainly for internal use by the Docker support
102
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
168
#
103
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
169
# User-specifiable environment variables:
104
+ * GNU General Public License for more details.
170
# COVERITY_TOKEN -- Coverity token
105
+ *
171
@@ -XXX,XX +XXX,XX @@ update_coverity_tools () {
106
+ * You should have received a copy of the GNU General Public License along
172
# Check user-provided environment variables and arguments
107
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
173
DRYRUN=no
108
+ */
174
UPDATE_ONLY=no
109
+
175
+DOCKER=no
110
+#include "qemu/osdep.h"
176
111
+#include "qemu/log.h"
177
while [ "$#" -ge 1 ]; do
112
+#include "qapi/error.h"
178
case "$1" in
113
+#include "hw/hw.h"
179
@@ -XXX,XX +XXX,XX @@ while [ "$#" -ge 1 ]; do
114
+#include "hw/irq.h"
180
RESULTSTARBALL="$1"
115
+#include "hw/qdev-properties.h"
181
shift
116
+#include "hw/sysbus.h"
182
;;
117
+#include "migration/vmstate.h"
183
+ --src-tarball)
118
+#include "sysemu/dma.h"
184
+ shift
119
+#include "hw/ptimer.h"
185
+ if [ $# -eq 0 ]; then
120
+#include "hw/stream.h"
186
+ echo "--src-tarball needs an argument"
121
+#include "hw/register.h"
187
+ exit 1
122
+#include "hw/dma/xlnx_csu_dma.h"
188
+ fi
123
+
189
+ SRCTARBALL="$1"
124
+/*
190
+ shift
125
+ * Ref: UG1087 (v1.7) February 8, 2019
191
+ ;;
126
+ * https://www.xilinx.com/html_docs/registers/ug1087/ug1087-zynq-ultrascale-registers.html
192
+ --docker)
127
+ * CSUDMA Module section
193
+ DOCKER=yes
128
+ */
194
+ shift
129
+REG32(ADDR, 0x0)
195
+ ;;
130
+ FIELD(ADDR, ADDR, 2, 30) /* wo */
196
*)
131
+REG32(SIZE, 0x4)
197
echo "Unexpected argument '$1'"
132
+ FIELD(SIZE, SIZE, 2, 27) /* wo */
198
exit 1
133
+ FIELD(SIZE, LAST_WORD, 0, 1) /* rw, only exists in SRC */
199
@@ -XXX,XX +XXX,XX @@ PROJTOKEN="$COVERITY_TOKEN"
134
+REG32(STATUS, 0x8)
200
PROJNAME=QEMU
135
+ FIELD(STATUS, DONE_CNT, 13, 3) /* wtc */
201
TARBALL=cov-int.tar.xz
136
+ FIELD(STATUS, FIFO_LEVEL, 5, 8) /* ro */
202
137
+ FIELD(STATUS, OUTSTANDING, 1, 4) /* ro */
203
+if [ "$UPDATE_ONLY" = yes ] && [ "$DOCKER" = yes ]; then
138
+ FIELD(STATUS, BUSY, 0, 1) /* ro */
204
+ echo "Combining --docker and --update-only is not supported"
139
+REG32(CTRL, 0xc)
205
+ exit 1
140
+ FIELD(CTRL, FIFOTHRESH, 25, 7) /* rw, only exists in DST, reset 0x40 */
206
+fi
141
+ FIELD(CTRL, APB_ERR_RESP, 24, 1) /* rw */
207
142
+ FIELD(CTRL, ENDIANNESS, 23, 1) /* rw */
208
if [ "$UPDATE_ONLY" = yes ]; then
143
+ FIELD(CTRL, AXI_BRST_TYPE, 22, 1) /* rw */
209
# Just do the tools update; we don't need to check whether
144
+ FIELD(CTRL, TIMEOUT_VAL, 10, 12) /* rw, reset: 0xFFE */
210
@@ -XXX,XX +XXX,XX @@ if [ "$UPDATE_ONLY" = yes ]; then
145
+ FIELD(CTRL, FIFO_THRESH, 2, 8) /* rw, reset: 0x80 */
211
exit 0
146
+ FIELD(CTRL, PAUSE_STRM, 1, 1) /* rw */
212
fi
147
+ FIELD(CTRL, PAUSE_MEM, 0, 1) /* rw */
213
148
+REG32(CRC, 0x10)
214
+if [ ! -e "$SRCDIR" ]; then
149
+REG32(INT_STATUS, 0x14)
215
+ mkdir "$SRCDIR"
150
+ FIELD(INT_STATUS, FIFO_OVERFLOW, 7, 1) /* wtc */
216
+fi
151
+ FIELD(INT_STATUS, INVALID_APB, 6, 1) /* wtc */
217
+
152
+ FIELD(INT_STATUS, THRESH_HIT, 5, 1) /* wtc */
218
cd "$SRCDIR"
153
+ FIELD(INT_STATUS, TIMEOUT_MEM, 4, 1) /* wtc */
219
154
+ FIELD(INT_STATUS, TIMEOUT_STRM, 3, 1) /* wtc */
220
+if [ ! -z "$SRCTARBALL" ]; then
155
+ FIELD(INT_STATUS, AXI_BRESP_ERR, 2, 1) /* wtc, SRC: AXI_RDERR */
221
+ echo "Untarring source tarball into $SRCDIR..."
156
+ FIELD(INT_STATUS, DONE, 1, 1) /* wtc */
222
+ tar xvf "$SRCTARBALL"
157
+ FIELD(INT_STATUS, MEM_DONE, 0, 1) /* wtc */
223
+fi
158
+REG32(INT_ENABLE, 0x18)
224
+
159
+ FIELD(INT_ENABLE, FIFO_OVERFLOW, 7, 1) /* wtc */
225
echo "Checking this is a QEMU source tree..."
160
+ FIELD(INT_ENABLE, INVALID_APB, 6, 1) /* wtc */
226
if ! [ -e "$SRCDIR/VERSION" ]; then
161
+ FIELD(INT_ENABLE, THRESH_HIT, 5, 1) /* wtc */
227
echo "Not in a QEMU source tree?"
162
+ FIELD(INT_ENABLE, TIMEOUT_MEM, 4, 1) /* wtc */
228
@@ -XXX,XX +XXX,XX @@ if [ -z "$COVERITY_EMAIL" ]; then
163
+ FIELD(INT_ENABLE, TIMEOUT_STRM, 3, 1) /* wtc */
229
COVERITY_EMAIL="$(git config user.email)"
164
+ FIELD(INT_ENABLE, AXI_BRESP_ERR, 2, 1) /* wtc, SRC: AXI_RDERR */
230
fi
165
+ FIELD(INT_ENABLE, DONE, 1, 1) /* wtc */
231
166
+ FIELD(INT_ENABLE, MEM_DONE, 0, 1) /* wtc */
232
+# Run ourselves inside docker if that's what the user wants
167
+REG32(INT_DISABLE, 0x1c)
233
+if [ "$DOCKER" = yes ]; then
168
+ FIELD(INT_DISABLE, FIFO_OVERFLOW, 7, 1) /* wtc */
234
+ # build docker container including the coverity-scan tools
169
+ FIELD(INT_DISABLE, INVALID_APB, 6, 1) /* wtc */
235
+ # Put the Coverity token into a temporary file that only
170
+ FIELD(INT_DISABLE, THRESH_HIT, 5, 1) /* wtc */
236
+ # we have read access to, and then pass it to docker build
171
+ FIELD(INT_DISABLE, TIMEOUT_MEM, 4, 1) /* wtc */
237
+ # using --secret. This requires at least Docker 18.09.
172
+ FIELD(INT_DISABLE, TIMEOUT_STRM, 3, 1) /* wtc */
238
+ # Mostly what we are trying to do here is ensure we don't leak
173
+ FIELD(INT_DISABLE, AXI_BRESP_ERR, 2, 1) /* wtc, SRC: AXI_RDERR */
239
+ # the token into the Docker image.
174
+ FIELD(INT_DISABLE, DONE, 1, 1) /* wtc */
240
+ umask 077
175
+ FIELD(INT_DISABLE, MEM_DONE, 0, 1) /* wtc */
241
+ SECRETDIR=$(mktemp -d)
176
+REG32(INT_MASK, 0x20)
242
+ if [ -z "$SECRETDIR" ]; then
177
+ FIELD(INT_MASK, FIFO_OVERFLOW, 7, 1) /* ro, reset: 0x1 */
243
+ echo "Failed to create temporary directory"
178
+ FIELD(INT_MASK, INVALID_APB, 6, 1) /* ro, reset: 0x1 */
244
+ exit 1
179
+ FIELD(INT_MASK, THRESH_HIT, 5, 1) /* ro, reset: 0x1 */
245
+ fi
180
+ FIELD(INT_MASK, TIMEOUT_MEM, 4, 1) /* ro, reset: 0x1 */
246
+ trap 'rm -rf "$SECRETDIR"' INT TERM EXIT
181
+ FIELD(INT_MASK, TIMEOUT_STRM, 3, 1) /* ro, reset: 0x1 */
247
+ echo "Created temporary directory $SECRETDIR"
182
+ FIELD(INT_MASK, AXI_BRESP_ERR, 2, 1) /* ro, reset: 0x1, SRC: AXI_RDERR */
248
+ SECRET="$SECRETDIR/token"
183
+ FIELD(INT_MASK, DONE, 1, 1) /* ro, reset: 0x1 */
249
+ echo "$COVERITY_TOKEN" > "$SECRET"
184
+ FIELD(INT_MASK, MEM_DONE, 0, 1) /* ro, reset: 0x1 */
250
+ echo "Building docker container..."
185
+REG32(CTRL2, 0x24)
251
+ # TODO: This re-downloads the tools every time, rather than
186
+ FIELD(CTRL2, ARCACHE, 24, 3) /* rw */
252
+ # caching and reusing the image produced with the downloaded tools.
187
+ FIELD(CTRL2, ROUTE_BIT, 23, 1) /* rw */
253
+ # Not sure why.
188
+ FIELD(CTRL2, TIMEOUT_EN, 22, 1) /* rw */
254
+ # TODO: how do you get 'docker build' to print the output of the
189
+ FIELD(CTRL2, TIMEOUT_PRE, 4, 12) /* rw, reset: 0xFFF */
255
+ # commands it is running to its stdout? This would be useful for debug.
190
+ FIELD(CTRL2, MAX_OUTS_CMDS, 0, 4) /* rw, reset: 0x8 */
256
+ DOCKER_BUILDKIT=1 docker build -t coverity-scanner \
191
+REG32(ADDR_MSB, 0x28)
257
+ --secret id=coverity.token,src="$SECRET" \
192
+ FIELD(ADDR_MSB, ADDR_MSB, 0, 17) /* wo */
258
+ -f scripts/coverity-scan/coverity-scan.docker \
193
+
259
+ scripts/coverity-scan
194
+#define R_CTRL_TIMEOUT_VAL_RESET (0xFFE)
260
+ echo "Archiving sources to be analyzed..."
195
+#define R_CTRL_FIFO_THRESH_RESET (0x80)
261
+ ./scripts/archive-source.sh "$SECRETDIR/qemu-sources.tgz"
196
+#define R_CTRL_FIFOTHRESH_RESET (0x40)
262
+ if [ "$DRYRUN" = yes ]; then
197
+
263
+ DRYRUNARG=--dry-run
198
+#define R_CTRL2_TIMEOUT_PRE_RESET (0xFFF)
264
+ fi
199
+#define R_CTRL2_MAX_OUTS_CMDS_RESET (0x8)
265
+ echo "Running scanner..."
200
+
266
+ # If we need to capture the output tarball, get the inner run to
201
+#define XLNX_CSU_DMA_ERR_DEBUG (0)
267
+ # save it to the secrets directory so we can copy it out before the
202
+#define XLNX_CSU_DMA_INT_R_MASK (0xff)
268
+ # directory is cleaned up.
203
+
269
+ if [ ! -z "$RESULTSTARBALL" ]; then
204
+/* UG1807: Set the prescaler value for the timeout in clk (~2.5ns) cycles */
270
+ RTARGS="--results-tarball /work/cov-int.tar.xz"
205
+#define XLNX_CSU_DMA_TIMER_FREQ (400 * 1000 * 1000)
271
+ else
206
+
272
+ RTARGS=""
207
+static bool xlnx_csu_dma_is_paused(XlnxCSUDMA *s)
273
+ fi
208
+{
274
+ # Arrange for this docker run to get access to the sources with -v.
209
+ bool paused;
275
+ # We pass through all the configuration from the outer script to the inner.
210
+
276
+ export COVERITY_EMAIL COVERITY_BUILD_CMD
211
+ paused = !!(s->regs[R_CTRL] & R_CTRL_PAUSE_STRM_MASK);
277
+ docker run -it --env COVERITY_EMAIL --env COVERITY_BUILD_CMD \
212
+ paused |= !!(s->regs[R_CTRL] & R_CTRL_PAUSE_MEM_MASK);
278
+ -v "$SECRETDIR:/work" coverity-scanner \
213
+
279
+ ./run-coverity-scan --version "$VERSION" \
214
+ return paused;
280
+ --description "$DESCRIPTION" $DRYRUNARG --tokenfile /work/token \
215
+}
281
+ --srcdir /qemu --src-tarball /work/qemu-sources.tgz $RTARGS
216
+
282
+ if [ ! -z "$RESULTSTARBALL" ]; then
217
+static bool xlnx_csu_dma_get_eop(XlnxCSUDMA *s)
283
+ echo "Copying results tarball to $RESULTSTARBALL..."
218
+{
284
+ cp "$SECRETDIR/cov-int.tar.xz" "$RESULTSTARBALL"
219
+ return s->r_size_last_word;
285
+ fi
220
+}
286
+ echo "Docker work complete."
221
+
287
+ exit 0
222
+static bool xlnx_csu_dma_burst_is_fixed(XlnxCSUDMA *s)
288
+fi
223
+{
289
+
224
+ return !!(s->regs[R_CTRL] & R_CTRL_AXI_BRST_TYPE_MASK);
290
+# Otherwise, continue with the full build and upload process.
225
+}
291
+
226
+
292
check_upload_permissions
227
+static bool xlnx_csu_dma_timeout_enabled(XlnxCSUDMA *s)
293
228
+{
294
update_coverity_tools
229
+ return !!(s->regs[R_CTRL2] & R_CTRL2_TIMEOUT_EN_MASK);
230
+}
231
+
232
+static void xlnx_csu_dma_update_done_cnt(XlnxCSUDMA *s, int a)
233
+{
234
+ int cnt;
235
+
236
+ /* Increase DONE_CNT */
237
+ cnt = ARRAY_FIELD_EX32(s->regs, STATUS, DONE_CNT) + a;
238
+ ARRAY_FIELD_DP32(s->regs, STATUS, DONE_CNT, cnt);
239
+}
240
+
241
+static void xlnx_csu_dma_data_process(XlnxCSUDMA *s, uint8_t *buf, uint32_t len)
242
+{
243
+ uint32_t bswap;
244
+ uint32_t i;
245
+
246
+ bswap = s->regs[R_CTRL] & R_CTRL_ENDIANNESS_MASK;
247
+ if (s->is_dst && !bswap) {
248
+ /* Fast when ENDIANNESS cleared */
249
+ return;
250
+ }
251
+
252
+ for (i = 0; i < len; i += 4) {
253
+ uint8_t *b = &buf[i];
254
+ union {
255
+ uint8_t u8[4];
256
+ uint32_t u32;
257
+ } v = {
258
+ .u8 = { b[0], b[1], b[2], b[3] }
259
+ };
260
+
261
+ if (!s->is_dst) {
262
+ s->regs[R_CRC] += v.u32;
263
+ }
264
+ if (bswap) {
265
+ /*
266
+ * No point using bswap, we need to writeback
267
+ * into a potentially unaligned pointer.
268
+ */
269
+ b[0] = v.u8[3];
270
+ b[1] = v.u8[2];
271
+ b[2] = v.u8[1];
272
+ b[3] = v.u8[0];
273
+ }
274
+ }
275
+}
276
+
277
+static void xlnx_csu_dma_update_irq(XlnxCSUDMA *s)
278
+{
279
+ qemu_set_irq(s->irq, !!(s->regs[R_INT_STATUS] & ~s->regs[R_INT_MASK]));
280
+}
281
+
282
+/* len is in bytes */
283
+static uint32_t xlnx_csu_dma_read(XlnxCSUDMA *s, uint8_t *buf, uint32_t len)
284
+{
285
+ hwaddr addr = (hwaddr)s->regs[R_ADDR_MSB] << 32 | s->regs[R_ADDR];
286
+ MemTxResult result = MEMTX_OK;
287
+
288
+ if (xlnx_csu_dma_burst_is_fixed(s)) {
289
+ uint32_t i;
290
+
291
+ for (i = 0; i < len && (result == MEMTX_OK); i += s->width) {
292
+ uint32_t mlen = MIN(len - i, s->width);
293
+
294
+ result = address_space_rw(s->dma_as, addr, s->attr,
295
+ buf + i, mlen, false);
296
+ }
297
+ } else {
298
+ result = address_space_rw(s->dma_as, addr, s->attr, buf, len, false);
299
+ }
300
+
301
+ if (result == MEMTX_OK) {
302
+ xlnx_csu_dma_data_process(s, buf, len);
303
+ } else {
304
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address 0x%lx for mem read",
305
+ __func__, addr);
306
+ s->regs[R_INT_STATUS] |= R_INT_STATUS_AXI_BRESP_ERR_MASK;
307
+ xlnx_csu_dma_update_irq(s);
308
+ }
309
+ return len;
310
+}
311
+
312
+/* len is in bytes */
313
+static uint32_t xlnx_csu_dma_write(XlnxCSUDMA *s, uint8_t *buf, uint32_t len)
314
+{
315
+ hwaddr addr = (hwaddr)s->regs[R_ADDR_MSB] << 32 | s->regs[R_ADDR];
316
+ MemTxResult result = MEMTX_OK;
317
+
318
+ xlnx_csu_dma_data_process(s, buf, len);
319
+ if (xlnx_csu_dma_burst_is_fixed(s)) {
320
+ uint32_t i;
321
+
322
+ for (i = 0; i < len && (result == MEMTX_OK); i += s->width) {
323
+ uint32_t mlen = MIN(len - i, s->width);
324
+
325
+ result = address_space_rw(s->dma_as, addr, s->attr,
326
+ buf, mlen, true);
327
+ buf += mlen;
328
+ }
329
+ } else {
330
+ result = address_space_rw(s->dma_as, addr, s->attr, buf, len, true);
331
+ }
332
+
333
+ if (result != MEMTX_OK) {
334
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address 0x%lx for mem write",
335
+ __func__, addr);
336
+ s->regs[R_INT_STATUS] |= R_INT_STATUS_AXI_BRESP_ERR_MASK;
337
+ xlnx_csu_dma_update_irq(s);
338
+ }
339
+ return len;
340
+}
341
+
342
+static void xlnx_csu_dma_done(XlnxCSUDMA *s)
343
+{
344
+ s->regs[R_STATUS] &= ~R_STATUS_BUSY_MASK;
345
+ s->regs[R_INT_STATUS] |= R_INT_STATUS_DONE_MASK;
346
+
347
+ if (!s->is_dst) {
348
+ s->regs[R_INT_STATUS] |= R_INT_STATUS_MEM_DONE_MASK;
349
+ }
350
+
351
+ xlnx_csu_dma_update_done_cnt(s, 1);
352
+}
353
+
354
+static uint32_t xlnx_csu_dma_advance(XlnxCSUDMA *s, uint32_t len)
355
+{
356
+ uint32_t size = s->regs[R_SIZE];
357
+ hwaddr dst = (hwaddr)s->regs[R_ADDR_MSB] << 32 | s->regs[R_ADDR];
358
+
359
+ assert(len <= size);
360
+
361
+ size -= len;
362
+ s->regs[R_SIZE] = size;
363
+
364
+ if (!xlnx_csu_dma_burst_is_fixed(s)) {
365
+ dst += len;
366
+ s->regs[R_ADDR] = (uint32_t) dst;
367
+ s->regs[R_ADDR_MSB] = dst >> 32;
368
+ }
369
+
370
+ if (size == 0) {
371
+ xlnx_csu_dma_done(s);
372
+ }
373
+
374
+ return size;
375
+}
376
+
377
+static void xlnx_csu_dma_src_notify(void *opaque)
378
+{
379
+ XlnxCSUDMA *s = XLNX_CSU_DMA(opaque);
380
+ unsigned char buf[4 * 1024];
381
+ size_t rlen = 0;
382
+
383
+ ptimer_transaction_begin(s->src_timer);
384
+ /* Stop the backpreassure timer */
385
+ ptimer_stop(s->src_timer);
386
+
387
+ while (s->regs[R_SIZE] && !xlnx_csu_dma_is_paused(s) &&
388
+ stream_can_push(s->tx_dev, xlnx_csu_dma_src_notify, s)) {
389
+ uint32_t plen = MIN(s->regs[R_SIZE], sizeof buf);
390
+ bool eop = false;
391
+
392
+ /* Did we fit it all? */
393
+ if (s->regs[R_SIZE] == plen && xlnx_csu_dma_get_eop(s)) {
394
+ eop = true;
395
+ }
396
+
397
+ /* DMA transfer */
398
+ xlnx_csu_dma_read(s, buf, plen);
399
+ rlen = stream_push(s->tx_dev, buf, plen, eop);
400
+ xlnx_csu_dma_advance(s, rlen);
401
+ }
402
+
403
+ if (xlnx_csu_dma_timeout_enabled(s) && s->regs[R_SIZE] &&
404
+ !stream_can_push(s->tx_dev, xlnx_csu_dma_src_notify, s)) {
405
+ uint32_t timeout = ARRAY_FIELD_EX32(s->regs, CTRL, TIMEOUT_VAL);
406
+ uint32_t div = ARRAY_FIELD_EX32(s->regs, CTRL2, TIMEOUT_PRE) + 1;
407
+ uint32_t freq = XLNX_CSU_DMA_TIMER_FREQ;
408
+
409
+ freq /= div;
410
+ ptimer_set_freq(s->src_timer, freq);
411
+ ptimer_set_count(s->src_timer, timeout);
412
+ ptimer_run(s->src_timer, 1);
413
+ }
414
+
415
+ ptimer_transaction_commit(s->src_timer);
416
+ xlnx_csu_dma_update_irq(s);
417
+}
418
+
419
+static uint64_t addr_pre_write(RegisterInfo *reg, uint64_t val)
420
+{
421
+ /* Address is word aligned */
422
+ return val & R_ADDR_ADDR_MASK;
423
+}
424
+
425
+static uint64_t size_pre_write(RegisterInfo *reg, uint64_t val)
426
+{
427
+ XlnxCSUDMA *s = XLNX_CSU_DMA(reg->opaque);
428
+
429
+ if (s->regs[R_SIZE] != 0) {
430
+ qemu_log_mask(LOG_GUEST_ERROR,
431
+ "%s: Starting DMA while already running.\n", __func__);
432
+ }
433
+
434
+ if (!s->is_dst) {
435
+ s->r_size_last_word = !!(val & R_SIZE_LAST_WORD_MASK);
436
+ }
437
+
438
+ /* Size is word aligned */
439
+ return val & R_SIZE_SIZE_MASK;
440
+}
441
+
442
+static uint64_t size_post_read(RegisterInfo *reg, uint64_t val)
443
+{
444
+ XlnxCSUDMA *s = XLNX_CSU_DMA(reg->opaque);
445
+
446
+ return val | s->r_size_last_word;
447
+}
448
+
449
+static void size_post_write(RegisterInfo *reg, uint64_t val)
450
+{
451
+ XlnxCSUDMA *s = XLNX_CSU_DMA(reg->opaque);
452
+
453
+ s->regs[R_STATUS] |= R_STATUS_BUSY_MASK;
454
+
455
+ /*
456
+ * Note that if SIZE is programmed to 0, and the DMA is started,
457
+ * the interrupts DONE and MEM_DONE will be asserted.
458
+ */
459
+ if (s->regs[R_SIZE] == 0) {
460
+ xlnx_csu_dma_done(s);
461
+ xlnx_csu_dma_update_irq(s);
462
+ return;
463
+ }
464
+
465
+ /* Set SIZE is considered the last step in transfer configuration */
466
+ if (!s->is_dst) {
467
+ xlnx_csu_dma_src_notify(s);
468
+ } else {
469
+ if (s->notify) {
470
+ s->notify(s->notify_opaque);
471
+ }
472
+ }
473
+}
474
+
475
+static uint64_t status_pre_write(RegisterInfo *reg, uint64_t val)
476
+{
477
+ return val & (R_STATUS_DONE_CNT_MASK | R_STATUS_BUSY_MASK);
478
+}
479
+
480
+static void ctrl_post_write(RegisterInfo *reg, uint64_t val)
481
+{
482
+ XlnxCSUDMA *s = XLNX_CSU_DMA(reg->opaque);
483
+
484
+ if (!s->is_dst) {
485
+ if (!xlnx_csu_dma_is_paused(s)) {
486
+ xlnx_csu_dma_src_notify(s);
487
+ }
488
+ } else {
489
+ if (!xlnx_csu_dma_is_paused(s) && s->notify) {
490
+ s->notify(s->notify_opaque);
491
+ }
492
+ }
493
+}
494
+
495
+static uint64_t int_status_pre_write(RegisterInfo *reg, uint64_t val)
496
+{
497
+ XlnxCSUDMA *s = XLNX_CSU_DMA(reg->opaque);
498
+
499
+ /* DMA counter decrements when flag 'DONE' is cleared */
500
+ if ((val & s->regs[R_INT_STATUS] & R_INT_STATUS_DONE_MASK)) {
501
+ xlnx_csu_dma_update_done_cnt(s, -1);
502
+ }
503
+
504
+ return s->regs[R_INT_STATUS] & ~val;
505
+}
506
+
507
+static void int_status_post_write(RegisterInfo *reg, uint64_t val)
508
+{
509
+ XlnxCSUDMA *s = XLNX_CSU_DMA(reg->opaque);
510
+
511
+ xlnx_csu_dma_update_irq(s);
512
+}
513
+
514
+static uint64_t int_enable_pre_write(RegisterInfo *reg, uint64_t val)
515
+{
516
+ XlnxCSUDMA *s = XLNX_CSU_DMA(reg->opaque);
517
+ uint32_t v32 = val;
518
+
519
+ /*
520
+ * R_INT_ENABLE doesn't have its own state.
521
+ * It is used to indirectly modify R_INT_MASK.
522
+ *
523
+ * 1: Enable this interrupt field (the mask bit will be cleared to 0)
524
+ * 0: No effect
525
+ */
526
+ s->regs[R_INT_MASK] &= ~v32;
527
+ return 0;
528
+}
529
+
530
+static void int_enable_post_write(RegisterInfo *reg, uint64_t val)
531
+{
532
+ XlnxCSUDMA *s = XLNX_CSU_DMA(reg->opaque);
533
+
534
+ xlnx_csu_dma_update_irq(s);
535
+}
536
+
537
+static uint64_t int_disable_pre_write(RegisterInfo *reg, uint64_t val)
538
+{
539
+ XlnxCSUDMA *s = XLNX_CSU_DMA(reg->opaque);
540
+ uint32_t v32 = val;
541
+
542
+ /*
543
+ * R_INT_DISABLE doesn't have its own state.
544
+ * It is used to indirectly modify R_INT_MASK.
545
+ *
546
+ * 1: Disable this interrupt field (the mask bit will be set to 1)
547
+ * 0: No effect
548
+ */
549
+ s->regs[R_INT_MASK] |= v32;
550
+ return 0;
551
+}
552
+
553
+static void int_disable_post_write(RegisterInfo *reg, uint64_t val)
554
+{
555
+ XlnxCSUDMA *s = XLNX_CSU_DMA(reg->opaque);
556
+
557
+ xlnx_csu_dma_update_irq(s);
558
+}
559
+
560
+static uint64_t addr_msb_pre_write(RegisterInfo *reg, uint64_t val)
561
+{
562
+ return val & R_ADDR_MSB_ADDR_MSB_MASK;
563
+}
564
+
565
+static const RegisterAccessInfo *xlnx_csu_dma_regs_info[] = {
566
+#define DMACH_REGINFO(NAME, snd) \
567
+ (const RegisterAccessInfo []) { \
568
+ { \
569
+ .name = #NAME "_ADDR", \
570
+ .addr = A_ADDR, \
571
+ .pre_write = addr_pre_write \
572
+ }, { \
573
+ .name = #NAME "_SIZE", \
574
+ .addr = A_SIZE, \
575
+ .pre_write = size_pre_write, \
576
+ .post_write = size_post_write, \
577
+ .post_read = size_post_read \
578
+ }, { \
579
+ .name = #NAME "_STATUS", \
580
+ .addr = A_STATUS, \
581
+ .pre_write = status_pre_write, \
582
+ .w1c = R_STATUS_DONE_CNT_MASK, \
583
+ .ro = (R_STATUS_BUSY_MASK \
584
+ | R_STATUS_FIFO_LEVEL_MASK \
585
+ | R_STATUS_OUTSTANDING_MASK) \
586
+ }, { \
587
+ .name = #NAME "_CTRL", \
588
+ .addr = A_CTRL, \
589
+ .post_write = ctrl_post_write, \
590
+ .reset = ((R_CTRL_TIMEOUT_VAL_RESET << R_CTRL_TIMEOUT_VAL_SHIFT) \
591
+ | (R_CTRL_FIFO_THRESH_RESET << R_CTRL_FIFO_THRESH_SHIFT)\
592
+ | (snd ? 0 : R_CTRL_FIFOTHRESH_RESET \
593
+ << R_CTRL_FIFOTHRESH_SHIFT)) \
594
+ }, { \
595
+ .name = #NAME "_CRC", \
596
+ .addr = A_CRC, \
597
+ }, { \
598
+ .name = #NAME "_INT_STATUS", \
599
+ .addr = A_INT_STATUS, \
600
+ .pre_write = int_status_pre_write, \
601
+ .post_write = int_status_post_write \
602
+ }, { \
603
+ .name = #NAME "_INT_ENABLE", \
604
+ .addr = A_INT_ENABLE, \
605
+ .pre_write = int_enable_pre_write, \
606
+ .post_write = int_enable_post_write \
607
+ }, { \
608
+ .name = #NAME "_INT_DISABLE", \
609
+ .addr = A_INT_DISABLE, \
610
+ .pre_write = int_disable_pre_write, \
611
+ .post_write = int_disable_post_write \
612
+ }, { \
613
+ .name = #NAME "_INT_MASK", \
614
+ .addr = A_INT_MASK, \
615
+ .ro = ~0, \
616
+ .reset = XLNX_CSU_DMA_INT_R_MASK \
617
+ }, { \
618
+ .name = #NAME "_CTRL2", \
619
+ .addr = A_CTRL2, \
620
+ .reset = ((R_CTRL2_TIMEOUT_PRE_RESET \
621
+ << R_CTRL2_TIMEOUT_PRE_SHIFT) \
622
+ | (R_CTRL2_MAX_OUTS_CMDS_RESET \
623
+ << R_CTRL2_MAX_OUTS_CMDS_SHIFT)) \
624
+ }, { \
625
+ .name = #NAME "_ADDR_MSB", \
626
+ .addr = A_ADDR_MSB, \
627
+ .pre_write = addr_msb_pre_write \
628
+ } \
629
+ }
630
+
631
+ DMACH_REGINFO(DMA_SRC, true),
632
+ DMACH_REGINFO(DMA_DST, false)
633
+};
634
+
635
+static const MemoryRegionOps xlnx_csu_dma_ops = {
636
+ .read = register_read_memory,
637
+ .write = register_write_memory,
638
+ .endianness = DEVICE_LITTLE_ENDIAN,
639
+ .valid = {
640
+ .min_access_size = 4,
641
+ .max_access_size = 4,
642
+ }
643
+};
644
+
645
+static void xlnx_csu_dma_src_timeout_hit(void *opaque)
646
+{
647
+ XlnxCSUDMA *s = XLNX_CSU_DMA(opaque);
648
+
649
+ /* Ignore if the timeout is masked */
650
+ if (!xlnx_csu_dma_timeout_enabled(s)) {
651
+ return;
652
+ }
653
+
654
+ s->regs[R_INT_STATUS] |= R_INT_STATUS_TIMEOUT_STRM_MASK;
655
+ xlnx_csu_dma_update_irq(s);
656
+}
657
+
658
+static size_t xlnx_csu_dma_stream_push(StreamSink *obj, uint8_t *buf,
659
+ size_t len, bool eop)
660
+{
661
+ XlnxCSUDMA *s = XLNX_CSU_DMA(obj);
662
+ uint32_t size = s->regs[R_SIZE];
663
+ uint32_t mlen = MIN(size, len) & (~3); /* Size is word aligned */
664
+
665
+ /* Be called when it's DST */
666
+ assert(s->is_dst);
667
+
668
+ if (size == 0 || len <= 0) {
669
+ return 0;
670
+ }
671
+
672
+ if (len && (xlnx_csu_dma_is_paused(s) || mlen == 0)) {
673
+ qemu_log_mask(LOG_GUEST_ERROR,
674
+ "csu-dma: DST channel dropping %zd b of data.\n", len);
675
+ s->regs[R_INT_STATUS] |= R_INT_STATUS_FIFO_OVERFLOW_MASK;
676
+ return len;
677
+ }
678
+
679
+ if (xlnx_csu_dma_write(s, buf, mlen) != mlen) {
680
+ return 0;
681
+ }
682
+
683
+ xlnx_csu_dma_advance(s, mlen);
684
+ xlnx_csu_dma_update_irq(s);
685
+
686
+ return mlen;
687
+}
688
+
689
+static bool xlnx_csu_dma_stream_can_push(StreamSink *obj,
690
+ StreamCanPushNotifyFn notify,
691
+ void *notify_opaque)
692
+{
693
+ XlnxCSUDMA *s = XLNX_CSU_DMA(obj);
694
+
695
+ if (s->regs[R_SIZE] != 0) {
696
+ return true;
697
+ } else {
698
+ s->notify = notify;
699
+ s->notify_opaque = notify_opaque;
700
+ return false;
701
+ }
702
+}
703
+
704
+static void xlnx_csu_dma_reset(DeviceState *dev)
705
+{
706
+ XlnxCSUDMA *s = XLNX_CSU_DMA(dev);
707
+ unsigned int i;
708
+
709
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
710
+ register_reset(&s->regs_info[i]);
711
+ }
712
+}
713
+
714
+static void xlnx_csu_dma_realize(DeviceState *dev, Error **errp)
715
+{
716
+ XlnxCSUDMA *s = XLNX_CSU_DMA(dev);
717
+ RegisterInfoArray *reg_array;
718
+
719
+ reg_array =
720
+ register_init_block32(dev, xlnx_csu_dma_regs_info[!!s->is_dst],
721
+ XLNX_CSU_DMA_R_MAX,
722
+ s->regs_info, s->regs,
723
+ &xlnx_csu_dma_ops,
724
+ XLNX_CSU_DMA_ERR_DEBUG,
725
+ XLNX_CSU_DMA_R_MAX * 4);
726
+ memory_region_add_subregion(&s->iomem,
727
+ 0x0,
728
+ &reg_array->mem);
729
+
730
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
731
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
732
+
733
+ if (!s->is_dst && !s->tx_dev) {
734
+ error_setg(errp, "zynqmp.csu-dma: Stream not connected");
735
+ return;
736
+ }
737
+
738
+ s->src_timer = ptimer_init(xlnx_csu_dma_src_timeout_hit,
739
+ s, PTIMER_POLICY_DEFAULT);
740
+
741
+ if (s->dma_mr) {
742
+ s->dma_as = g_malloc0(sizeof(AddressSpace));
743
+ address_space_init(s->dma_as, s->dma_mr, NULL);
744
+ } else {
745
+ s->dma_as = &address_space_memory;
746
+ }
747
+
748
+ s->attr = MEMTXATTRS_UNSPECIFIED;
749
+
750
+ s->r_size_last_word = 0;
751
+}
752
+
753
+static const VMStateDescription vmstate_xlnx_csu_dma = {
754
+ .name = TYPE_XLNX_CSU_DMA,
755
+ .version_id = 0,
756
+ .minimum_version_id = 0,
757
+ .minimum_version_id_old = 0,
758
+ .fields = (VMStateField[]) {
759
+ VMSTATE_PTIMER(src_timer, XlnxCSUDMA),
760
+ VMSTATE_UINT16(width, XlnxCSUDMA),
761
+ VMSTATE_BOOL(is_dst, XlnxCSUDMA),
762
+ VMSTATE_BOOL(r_size_last_word, XlnxCSUDMA),
763
+ VMSTATE_UINT32_ARRAY(regs, XlnxCSUDMA, XLNX_CSU_DMA_R_MAX),
764
+ VMSTATE_END_OF_LIST(),
765
+ }
766
+};
767
+
768
+static Property xlnx_csu_dma_properties[] = {
769
+ /*
770
+ * Ref PG021, Stream Data Width:
771
+ * Data width in bits of the AXI S2MM AXI4-Stream Data bus.
772
+ * This value must be equal or less than the Memory Map Data Width.
773
+ * Valid values are 8, 16, 32, 64, 128, 512 and 1024.
774
+ * "dma-width" is the byte value of the "Stream Data Width".
775
+ */
776
+ DEFINE_PROP_UINT16("dma-width", XlnxCSUDMA, width, 4),
777
+ /*
778
+ * The CSU DMA is a two-channel, simple DMA, allowing separate control of
779
+ * the SRC (read) channel and DST (write) channel. "is-dst" is used to mark
780
+ * which channel the device is connected to.
781
+ */
782
+ DEFINE_PROP_BOOL("is-dst", XlnxCSUDMA, is_dst, true),
783
+ DEFINE_PROP_END_OF_LIST(),
784
+};
785
+
786
+static void xlnx_csu_dma_class_init(ObjectClass *klass, void *data)
787
+{
788
+ DeviceClass *dc = DEVICE_CLASS(klass);
789
+ StreamSinkClass *ssc = STREAM_SINK_CLASS(klass);
790
+
791
+ dc->reset = xlnx_csu_dma_reset;
792
+ dc->realize = xlnx_csu_dma_realize;
793
+ dc->vmsd = &vmstate_xlnx_csu_dma;
794
+ device_class_set_props(dc, xlnx_csu_dma_properties);
795
+
796
+ ssc->push = xlnx_csu_dma_stream_push;
797
+ ssc->can_push = xlnx_csu_dma_stream_can_push;
798
+}
799
+
800
+static void xlnx_csu_dma_init(Object *obj)
801
+{
802
+ XlnxCSUDMA *s = XLNX_CSU_DMA(obj);
803
+
804
+ memory_region_init(&s->iomem, obj, TYPE_XLNX_CSU_DMA,
805
+ XLNX_CSU_DMA_R_MAX * 4);
806
+
807
+ object_property_add_link(obj, "stream-connected-dma", TYPE_STREAM_SINK,
808
+ (Object **)&s->tx_dev,
809
+ qdev_prop_allow_set_link_before_realize,
810
+ OBJ_PROP_LINK_STRONG);
811
+ object_property_add_link(obj, "dma", TYPE_MEMORY_REGION,
812
+ (Object **)&s->dma_mr,
813
+ qdev_prop_allow_set_link_before_realize,
814
+ OBJ_PROP_LINK_STRONG);
815
+}
816
+
817
+static const TypeInfo xlnx_csu_dma_info = {
818
+ .name = TYPE_XLNX_CSU_DMA,
819
+ .parent = TYPE_SYS_BUS_DEVICE,
820
+ .instance_size = sizeof(XlnxCSUDMA),
821
+ .class_init = xlnx_csu_dma_class_init,
822
+ .instance_init = xlnx_csu_dma_init,
823
+ .interfaces = (InterfaceInfo[]) {
824
+ { TYPE_STREAM_SINK },
825
+ { }
826
+ }
827
+};
828
+
829
+static void xlnx_csu_dma_register_types(void)
830
+{
831
+ type_register_static(&xlnx_csu_dma_info);
832
+}
833
+
834
+type_init(xlnx_csu_dma_register_types)
835
diff --git a/hw/dma/Kconfig b/hw/dma/Kconfig
836
index XXXXXXX..XXXXXXX 100644
837
--- a/hw/dma/Kconfig
838
+++ b/hw/dma/Kconfig
839
@@ -XXX,XX +XXX,XX @@ config STP2000
840
841
config SIFIVE_PDMA
842
bool
843
+
844
+config XLNX_CSU_DMA
845
+ bool
846
+ select REGISTER
847
diff --git a/hw/dma/meson.build b/hw/dma/meson.build
848
index XXXXXXX..XXXXXXX 100644
849
--- a/hw/dma/meson.build
850
+++ b/hw/dma/meson.build
851
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_dma.c', 'soc_dma.c'))
852
softmmu_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_dma.c'))
853
softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_dma.c'))
854
softmmu_ss.add(when: 'CONFIG_SIFIVE_PDMA', if_true: files('sifive_pdma.c'))
855
+softmmu_ss.add(when: 'CONFIG_XLNX_CSU_DMA', if_true: files('xlnx_csu_dma.c'))
295
--
856
--
296
2.20.1
857
2.20.1
297
858
298
859
diff view generated by jsdifflib
New patch
1
From: Xuzhou Cheng <xuzhou.cheng@windriver.com>
1
2
3
There are some coding convention warnings in xlnx-zynqmp.c and
4
xlnx-zynqmp.h, as reported by:
5
6
$ ./scripts/checkpatch.pl include/hw/arm/xlnx-zynqmp.h
7
$ ./scripts/checkpatch.pl hw/arm/xlnx-zynqmp.c
8
9
Let's clean them up.
10
11
Signed-off-by: Xuzhou Cheng <xuzhou.cheng@windriver.com>
12
Signed-off-by: Bin Meng <bin.meng@windriver.com>
13
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
14
Message-id: 20210303135254.3970-3-bmeng.cn@gmail.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
include/hw/arm/xlnx-zynqmp.h | 3 ++-
18
hw/arm/xlnx-zynqmp.c | 9 ++++++---
19
2 files changed, 8 insertions(+), 4 deletions(-)
20
21
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/xlnx-zynqmp.h
24
+++ b/include/hw/arm/xlnx-zynqmp.h
25
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
26
27
#define XLNX_ZYNQMP_GIC_REGIONS 6
28
29
-/* ZynqMP maps the ARM GIC regions (GICC, GICD ...) at consecutive 64k offsets
30
+/*
31
+ * ZynqMP maps the ARM GIC regions (GICC, GICD ...) at consecutive 64k offsets
32
* and under-decodes the 64k region. This mirrors the 4k regions to every 4k
33
* aligned address in the 64k region. To implement each GIC region needs a
34
* number of memory region aliases.
35
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/arm/xlnx-zynqmp.c
38
+++ b/hw/arm/xlnx-zynqmp.c
39
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
40
41
ram_size = memory_region_size(s->ddr_ram);
42
43
- /* Create the DDR Memory Regions. User friendly checks should happen at
44
+ /*
45
+ * Create the DDR Memory Regions. User friendly checks should happen at
46
* the board level
47
*/
48
if (ram_size > XLNX_ZYNQMP_MAX_LOW_RAM_SIZE) {
49
- /* The RAM size is above the maximum available for the low DDR.
50
+ /*
51
+ * The RAM size is above the maximum available for the low DDR.
52
* Create the high DDR memory region as well.
53
*/
54
assert(ram_size <= XLNX_ZYNQMP_MAX_RAM_SIZE);
55
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
56
SysBusDevice *sbd = SYS_BUS_DEVICE(&s->sdhci[i]);
57
Object *sdhci = OBJECT(&s->sdhci[i]);
58
59
- /* Compatible with:
60
+ /*
61
+ * Compatible with:
62
* - SD Host Controller Specification Version 3.00
63
* - SDIO Specification Version 3.0
64
* - eMMC Specification Version 4.51
65
--
66
2.20.1
67
68
diff view generated by jsdifflib
New patch
1
From: Xuzhou Cheng <xuzhou.cheng@windriver.com>
1
2
3
Add a Xilinx CSU DMA module to ZynqMP SoC, and connent the stream
4
link of GQSPI to CSU DMA.
5
6
Signed-off-by: Xuzhou Cheng <xuzhou.cheng@windriver.com>
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Message-id: 20210303135254.3970-4-bmeng.cn@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/arm/xlnx-zynqmp.h | 2 ++
13
hw/arm/xlnx-zynqmp.c | 12 ++++++++++++
14
hw/arm/Kconfig | 1 +
15
3 files changed, 15 insertions(+)
16
17
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-zynqmp.h
20
+++ b/include/hw/arm/xlnx-zynqmp.h
21
@@ -XXX,XX +XXX,XX @@
22
#include "target/arm/cpu.h"
23
#include "qom/object.h"
24
#include "net/can_emu.h"
25
+#include "hw/dma/xlnx_csu_dma.h"
26
27
#define TYPE_XLNX_ZYNQMP "xlnx,zynqmp"
28
OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
29
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
30
XlnxZynqMPRTC rtc;
31
XlnxZDMA gdma[XLNX_ZYNQMP_NUM_GDMA_CH];
32
XlnxZDMA adma[XLNX_ZYNQMP_NUM_ADMA_CH];
33
+ XlnxCSUDMA qspi_dma;
34
35
char *boot_cpu;
36
ARMCPU *boot_cpu_ptr;
37
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/arm/xlnx-zynqmp.c
40
+++ b/hw/arm/xlnx-zynqmp.c
41
@@ -XXX,XX +XXX,XX @@
42
#define QSPI_ADDR 0xff0f0000
43
#define LQSPI_ADDR 0xc0000000
44
#define QSPI_IRQ 15
45
+#define QSPI_DMA_ADDR 0xff0f0800
46
47
#define DP_ADDR 0xfd4a0000
48
#define DP_IRQ 113
49
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_init(Object *obj)
50
for (i = 0; i < XLNX_ZYNQMP_NUM_ADMA_CH; i++) {
51
object_initialize_child(obj, "adma[*]", &s->adma[i], TYPE_XLNX_ZDMA);
52
}
53
+
54
+ object_initialize_child(obj, "qspi-dma", &s->qspi_dma, TYPE_XLNX_CSU_DMA);
55
}
56
57
static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
58
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
59
sysbus_connect_irq(SYS_BUS_DEVICE(&s->adma[i]), 0,
60
gic_spi[adma_ch_intr[i]]);
61
}
62
+
63
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->qspi_dma), errp)) {
64
+ return;
65
+ }
66
+
67
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->qspi_dma), 0, QSPI_DMA_ADDR);
68
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->qspi_dma), 0, gic_spi[QSPI_IRQ]);
69
+ object_property_set_link(OBJECT(&s->qspi), "stream-connected-dma",
70
+ OBJECT(&s->qspi_dma), errp);
71
}
72
73
static Property xlnx_zynqmp_props[] = {
74
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
75
index XXXXXXX..XXXXXXX 100644
76
--- a/hw/arm/Kconfig
77
+++ b/hw/arm/Kconfig
78
@@ -XXX,XX +XXX,XX @@ config XLNX_ZYNQMP_ARM
79
select SSI_M25P80
80
select XILINX_AXI
81
select XILINX_SPIPS
82
+ select XLNX_CSU_DMA
83
select XLNX_ZYNQMP
84
select XLNX_ZDMA
85
86
--
87
2.20.1
88
89
diff view generated by jsdifflib
New patch
1
From: Xuzhou Cheng <xuzhou.cheng@windriver.com>
1
2
3
There are some coding convention warnings in xilinx_spips.c,
4
as reported by:
5
6
$ ./scripts/checkpatch.pl hw/ssi/xilinx_spips.c
7
8
Let's clean them up.
9
10
Signed-off-by: Xuzhou Cheng <xuzhou.cheng@windriver.com>
11
Signed-off-by: Bin Meng <bin.meng@windriver.com>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
15
Message-id: 20210303135254.3970-5-bmeng.cn@gmail.com
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
hw/ssi/xilinx_spips.c | 23 ++++++++++++++---------
19
1 file changed, 14 insertions(+), 9 deletions(-)
20
21
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/ssi/xilinx_spips.c
24
+++ b/hw/ssi/xilinx_spips.c
25
@@ -XXX,XX +XXX,XX @@
26
FIELD(GQSPI_FIFO_CTRL, GENERIC_FIFO_RESET, 0, 1)
27
#define R_GQSPI_GFIFO_THRESH (0x150 / 4)
28
#define R_GQSPI_DATA_STS (0x15c / 4)
29
-/* We use the snapshot register to hold the core state for the currently
30
+/*
31
+ * We use the snapshot register to hold the core state for the currently
32
* or most recently executed command. So the generic fifo format is defined
33
* for the snapshot register
34
*/
35
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_reset(DeviceState *d)
36
xlnx_zynqmp_qspips_update_ixr(s);
37
}
38
39
-/* N way (num) in place bit striper. Lay out row wise bits (MSB to LSB)
40
+/*
41
+ * N way (num) in place bit striper. Lay out row wise bits (MSB to LSB)
42
* column wise (from element 0 to N-1). num is the length of x, and dir
43
* reverses the direction of the transform. Best illustrated by example:
44
* Each digit in the below array is a single bit (num == 3):
45
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
46
tx_rx[i] = tx;
47
}
48
} else {
49
- /* Extract a dummy byte and generate dummy cycles according to the
50
- * link state */
51
+ /*
52
+ * Extract a dummy byte and generate dummy cycles according to the
53
+ * link state
54
+ */
55
tx = fifo8_pop(&s->tx_fifo);
56
dummy_cycles = 8 / s->link_state;
57
}
58
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
59
}
60
break;
61
case (SNOOP_ADDR):
62
- /* Address has been transmitted, transmit dummy cycles now if
63
- * needed */
64
+ /*
65
+ * Address has been transmitted, transmit dummy cycles now if needed
66
+ */
67
if (s->cmd_dummies < 0) {
68
s->snoop_state = SNOOP_NONE;
69
} else {
70
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_notify(void *opaque)
71
}
72
73
static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
74
- unsigned size)
75
+ unsigned size)
76
{
77
XilinxSPIPS *s = opaque;
78
uint32_t mask = ~0;
79
@@ -XXX,XX +XXX,XX @@ static uint64_t xlnx_zynqmp_qspips_read(void *opaque,
80
}
81
82
static void xilinx_spips_write(void *opaque, hwaddr addr,
83
- uint64_t value, unsigned size)
84
+ uint64_t value, unsigned size)
85
{
86
int mask = ~0;
87
XilinxSPIPS *s = opaque;
88
@@ -XXX,XX +XXX,XX @@ static void xilinx_qspips_write(void *opaque, hwaddr addr,
89
}
90
91
static void xlnx_zynqmp_qspips_write(void *opaque, hwaddr addr,
92
- uint64_t value, unsigned size)
93
+ uint64_t value, unsigned size)
94
{
95
XlnxZynqMPQSPIPS *s = XLNX_ZYNQMP_QSPIPS(opaque);
96
uint32_t reg = addr / 4;
97
--
98
2.20.1
99
100
diff view generated by jsdifflib
New patch
1
From: Xuzhou Cheng <xuzhou.cheng@windriver.com>
1
2
3
Now that the Xilinx CSU DMA model is implemented, the existing
4
DMA related dead codes in the ZynqMP QSPI are useless and should
5
be removed. The maximum register number is also updated to only
6
include the QSPI registers.
7
8
Signed-off-by: Xuzhou Cheng <xuzhou.cheng@windriver.com>
9
Signed-off-by: Bin Meng <bin.meng@windriver.com>
10
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
Message-id: 20210303135254.3970-6-bmeng.cn@gmail.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
include/hw/ssi/xilinx_spips.h | 2 +-
15
hw/ssi/xilinx_spips.c | 10 ----------
16
2 files changed, 1 insertion(+), 11 deletions(-)
17
18
diff --git a/include/hw/ssi/xilinx_spips.h b/include/hw/ssi/xilinx_spips.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/ssi/xilinx_spips.h
21
+++ b/include/hw/ssi/xilinx_spips.h
22
@@ -XXX,XX +XXX,XX @@
23
typedef struct XilinxSPIPS XilinxSPIPS;
24
25
#define XLNX_SPIPS_R_MAX (0x100 / 4)
26
-#define XLNX_ZYNQMP_SPIPS_R_MAX (0x830 / 4)
27
+#define XLNX_ZYNQMP_SPIPS_R_MAX (0x200 / 4)
28
29
/* Bite off 4k chunks at a time */
30
#define LQSPI_CACHE_SIZE 1024
31
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/ssi/xilinx_spips.c
34
+++ b/hw/ssi/xilinx_spips.c
35
@@ -XXX,XX +XXX,XX @@
36
#define R_GQSPI_MOD_ID (0x1fc / 4)
37
#define R_GQSPI_MOD_ID_RESET (0x10a0000)
38
39
-#define R_QSPIDMA_DST_CTRL (0x80c / 4)
40
-#define R_QSPIDMA_DST_CTRL_RESET (0x803ffa00)
41
-#define R_QSPIDMA_DST_I_MASK (0x820 / 4)
42
-#define R_QSPIDMA_DST_I_MASK_RESET (0xfe)
43
-#define R_QSPIDMA_DST_CTRL2 (0x824 / 4)
44
-#define R_QSPIDMA_DST_CTRL2_RESET (0x081bfff8)
45
-
46
/* size of TXRX FIFOs */
47
#define RXFF_A (128)
48
#define TXFF_A (128)
49
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_reset(DeviceState *d)
50
s->regs[R_GQSPI_GPIO] = 1;
51
s->regs[R_GQSPI_LPBK_DLY_ADJ] = R_GQSPI_LPBK_DLY_ADJ_RESET;
52
s->regs[R_GQSPI_MOD_ID] = R_GQSPI_MOD_ID_RESET;
53
- s->regs[R_QSPIDMA_DST_CTRL] = R_QSPIDMA_DST_CTRL_RESET;
54
- s->regs[R_QSPIDMA_DST_I_MASK] = R_QSPIDMA_DST_I_MASK_RESET;
55
- s->regs[R_QSPIDMA_DST_CTRL2] = R_QSPIDMA_DST_CTRL2_RESET;
56
s->man_start_com_g = false;
57
s->gqspi_irqline = 0;
58
xlnx_zynqmp_qspips_update_ixr(s);
59
--
60
2.20.1
61
62
diff view generated by jsdifflib
1
For Coverity's benefit, we provide simpler versions of functions like
1
The #defines INTERNAL and CASCADING represent different possible
2
qemu_mutex_lock(), qemu_cond_wait() and qemu_cond_timedwait(). When
2
values for the TCCR.CSS register field; prefix them with CSS_ to make
3
we added qemu_cond_timedwait() in commit 3dcc9c6ec4ea, a cut and
3
this more obvious, before we add more defines to represent the
4
paste error meant that the Coverity version of qemu_cond_timedwait()
4
other possible values of the field in the next commit.
5
was using the wrong _impl function, which makes the Coverity parser
6
complain:
7
8
"/qemu/include/qemu/thread.h", line 159: warning #140: too many arguments in
9
function call
10
return qemu_cond_timedwait(cond, mutex, ms);
11
^
12
13
"/qemu/include/qemu/thread.h", line 159: warning #120: return value type does
14
not match the function type
15
return qemu_cond_timedwait(cond, mutex, ms);
16
^
17
18
"/qemu/include/qemu/thread.h", line 156: warning #1563: function
19
"qemu_cond_timedwait" not emitted, consider modeling it or review
20
parse diagnostics to improve fidelity
21
static inline bool (qemu_cond_timedwait)(QemuCond *cond, QemuMutex *mutex,
22
^
23
24
These aren't fatal, but reduce the scope of the analysis. Fix the error.
25
5
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
28
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20210219223241.16344-2-peter.maydell@linaro.org
29
Message-id: 20200319193323.2038-3-peter.maydell@linaro.org
30
---
9
---
31
include/qemu/thread.h | 2 +-
10
hw/timer/renesas_tmr.c | 16 ++++++++--------
32
1 file changed, 1 insertion(+), 1 deletion(-)
11
1 file changed, 8 insertions(+), 8 deletions(-)
33
12
34
diff --git a/include/qemu/thread.h b/include/qemu/thread.h
13
diff --git a/hw/timer/renesas_tmr.c b/hw/timer/renesas_tmr.c
35
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
36
--- a/include/qemu/thread.h
15
--- a/hw/timer/renesas_tmr.c
37
+++ b/include/qemu/thread.h
16
+++ b/hw/timer/renesas_tmr.c
38
@@ -XXX,XX +XXX,XX @@ extern QemuCondTimedWaitFunc qemu_cond_timedwait_func;
17
@@ -XXX,XX +XXX,XX @@ REG8(TCCR, 10)
39
#define qemu_cond_wait(c, m) \
18
FIELD(TCCR, CSS, 3, 2)
40
qemu_cond_wait_impl(c, m, __FILE__, __LINE__);
19
FIELD(TCCR, TMRIS, 7, 1)
41
#define qemu_cond_timedwait(c, m, ms) \
20
42
- qemu_cond_wait_impl(c, m, ms, __FILE__, __LINE__);
21
-#define INTERNAL 0x01
43
+ qemu_cond_timedwait_impl(c, m, ms, __FILE__, __LINE__);
22
-#define CASCADING 0x03
44
#else
23
+#define CSS_INTERNAL 0x01
45
#define qemu_mutex_lock(m) ({ \
24
+#define CSS_CASCADING 0x03
46
QemuMutexLockFunc _f = atomic_read(&qemu_mutex_lock_func); \
25
#define CCLR_A 0x01
26
#define CCLR_B 0x02
27
28
@@ -XXX,XX +XXX,XX @@ static void update_events(RTMRState *tmr, int ch)
29
/* event not happened */
30
return ;
31
}
32
- if (FIELD_EX8(tmr->tccr[0], TCCR, CSS) == CASCADING) {
33
+ if (FIELD_EX8(tmr->tccr[0], TCCR, CSS) == CSS_CASCADING) {
34
/* cascading mode */
35
if (ch == 1) {
36
tmr->next[ch] = none;
37
@@ -XXX,XX +XXX,XX @@ static uint16_t read_tcnt(RTMRState *tmr, unsigned size, int ch)
38
if (delta > 0) {
39
tmr->tick = now;
40
41
- if (FIELD_EX8(tmr->tccr[1], TCCR, CSS) == INTERNAL) {
42
+ if (FIELD_EX8(tmr->tccr[1], TCCR, CSS) == CSS_INTERNAL) {
43
/* timer1 count update */
44
elapsed = elapsed_time(tmr, 1, delta);
45
if (elapsed >= 0x100) {
46
@@ -XXX,XX +XXX,XX @@ static uint16_t read_tcnt(RTMRState *tmr, unsigned size, int ch)
47
tcnt[1] = tmr->tcnt[1] + (elapsed & 0xff);
48
}
49
switch (FIELD_EX8(tmr->tccr[0], TCCR, CSS)) {
50
- case INTERNAL:
51
+ case CSS_INTERNAL:
52
elapsed = elapsed_time(tmr, 0, delta);
53
tcnt[0] = tmr->tcnt[0] + elapsed;
54
break;
55
- case CASCADING:
56
+ case CSS_CASCADING:
57
if (ovf > 0) {
58
tcnt[0] = tmr->tcnt[0] + ovf;
59
}
60
@@ -XXX,XX +XXX,XX @@ static uint16_t issue_event(RTMRState *tmr, int ch, int sz,
61
qemu_irq_pulse(tmr->cmia[ch]);
62
}
63
if (sz == 8 && ch == 0 &&
64
- FIELD_EX8(tmr->tccr[1], TCCR, CSS) == CASCADING) {
65
+ FIELD_EX8(tmr->tccr[1], TCCR, CSS) == CSS_CASCADING) {
66
tmr->tcnt[1]++;
67
timer_events(tmr, 1);
68
}
69
@@ -XXX,XX +XXX,XX @@ static void timer_events(RTMRState *tmr, int ch)
70
uint16_t tcnt;
71
72
tmr->tcnt[ch] = read_tcnt(tmr, 1, ch);
73
- if (FIELD_EX8(tmr->tccr[0], TCCR, CSS) != CASCADING) {
74
+ if (FIELD_EX8(tmr->tccr[0], TCCR, CSS) != CSS_CASCADING) {
75
tmr->tcnt[ch] = issue_event(tmr, ch, 8,
76
tmr->tcnt[ch],
77
tmr->tcora[ch],
47
--
78
--
48
2.20.1
79
2.20.1
49
80
50
81
diff view generated by jsdifflib
1
The kernel-doc Sphinx plugin and associated script currently emit
1
The read_tcnt() function calculates the TCNT register values for the
2
'c:type' directives for "struct foo" documentation.
2
two channels of the timer module; it sets these up in the local
3
tcnt[] array, and eventually returns either one or both of them,
4
depending on whether the access is 8 or 16 bits. However, not all of
5
the code paths through this function set both elements of this array:
6
if the guest has programmed the TCCR.CSS register fields to values
7
which are either documented as not to be used or which QEMU does not
8
implement, then the function will return uninitialized data. (This
9
was spotted by Coverity.)
3
10
4
Sphinx 3.0 warns about this:
11
Add the missing CSS cases to this code, so that we return a
5
/home/petmay01/linaro/qemu-from-laptop/qemu/docs/../include/exec/memory.h:3: WARNING: Type must be either just a name or a typedef-like declaration.
12
consistent value instead of uninitialized data, and so the code
6
If just a name:
13
structure indicates what's happening.
7
Error in declarator or parameters
8
Invalid C declaration: Expected identifier in nested name, got keyword: struct [error at 6]
9
struct MemoryListener
10
------^
11
If typedef-like declaration:
12
Error in declarator or parameters
13
Invalid C declaration: Expected identifier in nested name. [error at 21]
14
struct MemoryListener
15
---------------------^
16
14
17
because it wants us to use the new-in-3.0 'c:struct' instead.
15
Fixes: CID 1429976
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Message-id: 20210219223241.16344-3-peter.maydell@linaro.org
19
---
20
hw/timer/renesas_tmr.c | 19 +++++++++++++++----
21
1 file changed, 15 insertions(+), 4 deletions(-)
18
22
19
Plumb the Sphinx version through to the kernel-doc script
23
diff --git a/hw/timer/renesas_tmr.c b/hw/timer/renesas_tmr.c
20
and use it to select 'c:struct' for newer versions than 3.0.
21
22
Fixes: LP:1872113
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
25
---
26
docs/sphinx/kerneldoc.py | 1 +
27
scripts/kernel-doc | 16 +++++++++++++++-
28
2 files changed, 16 insertions(+), 1 deletion(-)
29
30
diff --git a/docs/sphinx/kerneldoc.py b/docs/sphinx/kerneldoc.py
31
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
32
--- a/docs/sphinx/kerneldoc.py
25
--- a/hw/timer/renesas_tmr.c
33
+++ b/docs/sphinx/kerneldoc.py
26
+++ b/hw/timer/renesas_tmr.c
34
@@ -XXX,XX +XXX,XX @@ class KernelDocDirective(Directive):
27
@@ -XXX,XX +XXX,XX @@ REG8(TCCR, 10)
35
env.note_dependency(os.path.abspath(f))
28
FIELD(TCCR, CSS, 3, 2)
36
cmd += ['-export-file', f]
29
FIELD(TCCR, TMRIS, 7, 1)
37
30
38
+ cmd += ['-sphinx-version', sphinx.__version__]
31
+#define CSS_EXTERNAL 0x00
39
cmd += [filename]
32
#define CSS_INTERNAL 0x01
40
33
+#define CSS_INVALID 0x02
41
try:
34
#define CSS_CASCADING 0x03
42
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
35
#define CCLR_A 0x01
43
index XXXXXXX..XXXXXXX 100755
36
#define CCLR_B 0x02
44
--- a/scripts/kernel-doc
37
@@ -XXX,XX +XXX,XX @@ static uint16_t read_tcnt(RTMRState *tmr, unsigned size, int ch)
45
+++ b/scripts/kernel-doc
38
if (delta > 0) {
46
@@ -XXX,XX +XXX,XX @@ Output selection (mutually exclusive):
39
tmr->tick = now;
47
            DOC: sections. May be specified multiple times.
40
48
41
- if (FIELD_EX8(tmr->tccr[1], TCCR, CSS) == CSS_INTERNAL) {
49
Output selection modifiers:
42
+ switch (FIELD_EX8(tmr->tccr[1], TCCR, CSS)) {
50
+ -sphinx-version VER Generate rST syntax for the specified Sphinx version.
43
+ case CSS_INTERNAL:
51
+ Only works with reStructuredTextFormat.
44
/* timer1 count update */
52
-no-doc-sections    Do not output DOC: sections.
45
elapsed = elapsed_time(tmr, 1, delta);
53
-enable-lineno Enable output of #define LINENO lines. Only works with
46
if (elapsed >= 0x100) {
54
reStructuredText format.
47
ovf = elapsed >> 8;
55
@@ -XXX,XX +XXX,XX @@ use constant {
48
}
56
};
49
tcnt[1] = tmr->tcnt[1] + (elapsed & 0xff);
57
my $output_selection = OUTPUT_ALL;
50
+ break;
58
my $show_not_found = 0;    # No longer used
51
+ case CSS_INVALID: /* guest error to have set this */
59
+my $sphinx_version = "0.0"; # if not specified, assume old
52
+ case CSS_EXTERNAL: /* QEMU doesn't implement these */
60
53
+ case CSS_CASCADING:
61
my @export_file_list;
54
+ tcnt[1] = tmr->tcnt[1];
62
55
+ break;
63
@@ -XXX,XX +XXX,XX @@ while ($ARGV[0] =~ m/^--?(.*)/) {
56
}
64
     $enable_lineno = 1;
57
switch (FIELD_EX8(tmr->tccr[0], TCCR, CSS)) {
65
} elsif ($cmd eq 'show-not-found') {
58
case CSS_INTERNAL:
66
    $show_not_found = 1; # A no-op but don't fail
59
@@ -XXX,XX +XXX,XX @@ static uint16_t read_tcnt(RTMRState *tmr, unsigned size, int ch)
67
+ } elsif ($cmd eq 'sphinx-version') {
60
tcnt[0] = tmr->tcnt[0] + elapsed;
68
+ $sphinx_version = shift @ARGV;
61
break;
62
case CSS_CASCADING:
63
- if (ovf > 0) {
64
- tcnt[0] = tmr->tcnt[0] + ovf;
65
- }
66
+ tcnt[0] = tmr->tcnt[0] + ovf;
67
+ break;
68
+ case CSS_INVALID: /* guest error to have set this */
69
+ case CSS_EXTERNAL: /* QEMU doesn't implement this */
70
+ tcnt[0] = tmr->tcnt[0];
71
break;
72
}
69
} else {
73
} else {
70
    # Unknown argument
71
usage();
72
@@ -XXX,XX +XXX,XX @@ sub output_struct_rst(%) {
73
my $oldprefix = $lineprefix;
74
my $name = $args{'type'} . " " . $args{'struct'};
75
76
- print "\n\n.. c:type:: " . $name . "\n\n";
77
+ # Sphinx 3.0 and up will emit warnings for "c:type:: struct Foo".
78
+ # It wants to see "c:struct:: Foo" (and will add the word 'struct' in
79
+ # the rendered output).
80
+ if ((split(/\./, $sphinx_version))[0] >= 3) {
81
+ my $sname = $name;
82
+ $sname =~ s/^struct //;
83
+ print "\n\n.. c:struct:: " . $sname . "\n\n";
84
+ } else {
85
+ print "\n\n.. c:type:: " . $name . "\n\n";
86
+ }
87
print_lineno($declaration_start_line);
88
$lineprefix = " ";
89
output_highlight_rst($args{'purpose'});
90
--
74
--
91
2.20.1
75
2.20.1
92
76
93
77
diff view generated by jsdifflib