1
Most of this is the Neon decodetree patches, followed by Edgar's versal cleanups.
1
This is almost all the mps3-an547 series, but there are a few
2
other bits in there too.
2
3
3
thanks
4
thanks
4
-- PMM
5
-- PMM
5
6
6
7
7
The following changes since commit 2ef486e76d64436be90f7359a3071fb2a56ce835:
8
The following changes since commit 0436c55edf6b357ff56e2a5bf688df8636f83456:
8
9
9
Merge remote-tracking branch 'remotes/marcel/tags/rdma-pull-request' into staging (2020-05-03 14:12:56 +0100)
10
Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging (2021-03-08 13:51:41 +0000)
10
11
11
are available in the Git repository at:
12
are available in the Git repository at:
12
13
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200504
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210308-1
14
15
15
for you to fetch changes up to 9aefc6cf9b73f66062d2f914a0136756e7a28211:
16
for you to fetch changes up to da2140183ac3a04b1ccb861aeac1f2c048c71b66:
16
17
17
target/arm: Move gen_ function typedefs to translate.h (2020-05-04 12:59:26 +0100)
18
hw/timer/renesas_tmr: Fix use of uninitialized data in read_tcnt() (2021-03-08 17:20:04 +0000)
18
19
19
----------------------------------------------------------------
20
----------------------------------------------------------------
20
target-arm queue:
21
* Add new mps3-an547 board
21
* Start of conversion of Neon insns to decodetree
22
* target/arm: Restrict v7A TCG cpus to TCG accel
22
* versal board: support SD and RTC
23
* Implement a Xilinx CSU DMA model
23
* Implement ARMv8.2-TTS2UXN
24
* hw/timer/renesas_tmr: Fix use of uninitialized data in read_tcnt()
24
* Make VQDMULL undefined when U=1
25
* Some minor code cleanups
26
25
27
----------------------------------------------------------------
26
----------------------------------------------------------------
28
Edgar E. Iglesias (11):
27
Peter Maydell (48):
29
hw/arm: versal: Remove inclusion of arm_gicv3_common.h
28
clock: Add ClockEvent parameter to callbacks
30
hw/arm: versal: Move misplaced comment
29
clock: Add ClockPreUpdate callback event type
31
hw/arm: versal-virt: Fix typo xlnx-ve -> xlnx-versal
30
clock: Add clock_ns_to_ticks() function
32
hw/arm: versal: Embed the UARTs into the SoC type
31
hw/timer/npcm7xx_timer: Use new clock_ns_to_ticks()
33
hw/arm: versal: Embed the GEMs into the SoC type
32
hw/arm/armsse: Introduce SSE subsystem version property
34
hw/arm: versal: Embed the ADMAs into the SoC type
33
hw/misc/iotkit-sysctl: Remove is_sse200 flag
35
hw/arm: versal: Embed the APUs into the SoC type
34
hw/misc/iotkit-secctl.c: Implement SSE-300 PID register values
36
hw/arm: versal: Add support for SD
35
hw/misc/iotkit-sysinfo.c: Implement SSE-300 PID register values
37
hw/arm: versal: Add support for the RTC
36
hw/arm/armsse.c: Use correct SYS_CONFIG0 register value for SSE-300
38
hw/arm: versal-virt: Add support for SD
37
hw/misc/iotkit-sysinfo.c: Implement SYS_CONFIG1 and IIDR
39
hw/arm: versal-virt: Add support for the RTC
38
hw/timer/sse-counter: Model the SSE Subsystem System Counter
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()
40
76
41
Fredrik Strupe (1):
77
Philippe Mathieu-Daudé (1):
42
target/arm: Make VQDMULL undefined when U=1
78
target/arm: Restrict v7A TCG cpus to TCG accel
43
79
44
Peter Maydell (25):
80
Xuzhou Cheng (5):
45
target/arm: Don't use a TLB for ARMMMUIdx_Stage2
81
hw/dma: Implement a Xilinx CSU DMA model
46
target/arm: Use enum constant in get_phys_addr_lpae() call
82
hw/arm: xlnx-zynqmp: Clean up coding convention issues
47
target/arm: Add new 's1_is_el0' argument to get_phys_addr_lpae()
83
hw/arm: xlnx-zynqmp: Connect a Xilinx CSU DMA module for QSPI
48
target/arm: Implement ARMv8.2-TTS2UXN
84
hw/ssi: xilinx_spips: Clean up coding convention issues
49
target/arm: Use correct variable for setting 'max' cpu's ID_AA64DFR0
85
hw/ssi: xilinx_spips: Remove DMA related dead codes from zynqmp_spips
50
target/arm/translate-vfp.inc.c: Remove duplicate simd_r32 check
51
target/arm: Don't allow Thumb Neon insns without FEATURE_NEON
52
target/arm: Add stubs for AArch32 Neon decodetree
53
target/arm: Convert VCMLA (vector) to decodetree
54
target/arm: Convert VCADD (vector) to decodetree
55
target/arm: Convert V[US]DOT (vector) to decodetree
56
target/arm: Convert VFM[AS]L (vector) to decodetree
57
target/arm: Convert VCMLA (scalar) to decodetree
58
target/arm: Convert V[US]DOT (scalar) to decodetree
59
target/arm: Convert VFM[AS]L (scalar) to decodetree
60
target/arm: Convert Neon load/store multiple structures to decodetree
61
target/arm: Convert Neon 'load single structure to all lanes' to decodetree
62
target/arm: Convert Neon 'load/store single structure' to decodetree
63
target/arm: Convert Neon 3-reg-same VADD/VSUB to decodetree
64
target/arm: Convert Neon 3-reg-same logic ops to decodetree
65
target/arm: Convert Neon 3-reg-same VMAX/VMIN to decodetree
66
target/arm: Convert Neon 3-reg-same comparisons to decodetree
67
target/arm: Convert Neon 3-reg-same VQADD/VQSUB to decodetree
68
target/arm: Convert Neon 3-reg-same VMUL, VMLA, VMLS, VSHL to decodetree
69
target/arm: Move gen_ function typedefs to translate.h
70
86
71
Philippe Mathieu-Daudé (2):
87
docs/devel/clocks.rst | 71 ++-
72
hw/arm/mps2-tz: Use TYPE_IOTKIT instead of hardcoded string
88
docs/system/arm/mps2.rst | 6 +-
73
target/arm: Use uint64_t for midr field in CPU state struct
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
74
158
75
include/hw/arm/xlnx-versal.h | 31 +-
76
target/arm/cpu-param.h | 2 +-
77
target/arm/cpu.h | 38 ++-
78
target/arm/translate-a64.h | 9 -
79
target/arm/translate.h | 26 ++
80
target/arm/neon-dp.decode | 86 +++++
81
target/arm/neon-ls.decode | 52 +++
82
target/arm/neon-shared.decode | 66 ++++
83
hw/arm/mps2-tz.c | 2 +-
84
hw/arm/xlnx-versal-virt.c | 74 ++++-
85
hw/arm/xlnx-versal.c | 115 +++++--
86
target/arm/cpu.c | 3 +-
87
target/arm/cpu64.c | 8 +-
88
target/arm/helper.c | 183 ++++------
89
target/arm/translate-a64.c | 17 -
90
target/arm/translate-neon.inc.c | 714 +++++++++++++++++++++++++++++++++++++++
91
target/arm/translate-vfp.inc.c | 6 -
92
target/arm/translate.c | 716 +++-------------------------------------
93
target/arm/Makefile.objs | 18 +
94
19 files changed, 1302 insertions(+), 864 deletions(-)
95
create mode 100644 target/arm/neon-dp.decode
96
create mode 100644 target/arm/neon-ls.decode
97
create mode 100644 target/arm/neon-shared.decode
98
create mode 100644 target/arm/translate-neon.inc.c
99
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
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.
2
5
3
Add support for SD.
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.
4
11
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Note that the documentation update renders correct the previously
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
incorrect claim in 'Adding a new clock' that callbacks "will be
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
14
explained in a following section".
8
Message-id: 20200427181649.26851-11-edgar.iglesias@gmail.com
15
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
10
---
22
---
11
hw/arm/xlnx-versal-virt.c | 46 +++++++++++++++++++++++++++++++++++++++
23
docs/devel/clocks.rst | 52 +++++++++++++++++++++++++++-----
12
1 file changed, 46 insertions(+)
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(-)
13
44
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
45
diff --git a/docs/devel/clocks.rst b/docs/devel/clocks.rst
15
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/xlnx-versal-virt.c
47
--- a/docs/devel/clocks.rst
17
+++ b/hw/arm/xlnx-versal-virt.c
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
18
@@ -XXX,XX +XXX,XX @@
152
@@ -XXX,XX +XXX,XX @@
19
#include "hw/arm/sysbus-fdt.h"
153
#define TYPE_CLOCK "clock"
20
#include "hw/arm/fdt.h"
154
OBJECT_DECLARE_SIMPLE_TYPE(Clock, CLOCK)
21
#include "cpu.h"
155
22
+#include "hw/qdev-properties.h"
156
-typedef void ClockCallback(void *opaque);
23
#include "hw/arm/xlnx-versal.h"
157
+/*
24
158
+ * Argument to ClockCallback functions indicating why the callback
25
#define TYPE_XLNX_VERSAL_VIRT_MACHINE MACHINE_TYPE_NAME("xlnx-versal-virt")
159
+ * has been called. A mask of these values logically ORed together
26
@@ -XXX,XX +XXX,XX @@ static void fdt_add_zdma_nodes(VersalVirt *s)
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,
27
}
351
}
28
}
352
}
29
353
30
+static void fdt_add_sd_nodes(VersalVirt *s)
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)
31
+{
420
+{
32
+ const char clocknames[] = "clk_xin\0clk_ahb";
421
+ /*
33
+ const char compat[] = "arasan,sdhci-8.9a";
422
+ * Call the Clock's callback for this event, if it has one and
34
+ int i;
423
+ * is interested in this event.
35
+
424
+ */
36
+ for (i = ARRAY_SIZE(s->soc.pmc.iou.sd) - 1; i >= 0; i--) {
425
+ if (clk->callback && (clk->callback_events & event)) {
37
+ uint64_t addr = MM_PMC_SD0 + MM_PMC_SD0_SIZE * i;
426
+ clk->callback(clk->callback_opaque, event);
38
+ char *name = g_strdup_printf("/sdhci@%" PRIx64, addr);
39
+
40
+ qemu_fdt_add_subnode(s->fdt, name);
41
+
42
+ qemu_fdt_setprop_cells(s->fdt, name, "clocks",
43
+ s->phandle.clk_25Mhz, s->phandle.clk_25Mhz);
44
+ qemu_fdt_setprop(s->fdt, name, "clock-names",
45
+ clocknames, sizeof(clocknames));
46
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
47
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_SD0_IRQ_0 + i * 2,
48
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
49
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
50
+ 2, addr, 2, MM_PMC_SD0_SIZE);
51
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
52
+ g_free(name);
53
+ }
427
+ }
54
+}
428
+}
55
+
429
+
56
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
430
static void clock_propagate_period(Clock *clk, bool call_callbacks)
57
{
431
{
58
Error *err = NULL;
432
Clock *child;
59
@@ -XXX,XX +XXX,XX @@ static void create_virtio_regions(VersalVirt *s)
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);
60
}
464
}
61
}
465
return ncl->clock;
62
466
}
63
+static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
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)
64
+{
582
+{
65
+ BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
583
+ npcm7xx_clk_update_pll(opaque);
66
+ DeviceState *card;
67
+
68
+ card = qdev_create(qdev_get_child_bus(DEVICE(sd), "sd-bus"), TYPE_SD_CARD);
69
+ object_property_add_child(OBJECT(sd), "card[*]", OBJECT(card),
70
+ &error_fatal);
71
+ qdev_prop_set_drive(card, "drive", blk, &error_fatal);
72
+ object_property_set_bool(OBJECT(card), true, "realized", &error_fatal);
73
+}
584
+}
74
+
585
+
75
static void versal_virt_init(MachineState *machine)
586
static void npcm7xx_clk_pll_init(Object *obj)
76
{
587
{
77
VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(machine);
588
NPCM7xxClockPLLState *pll = NPCM7XX_CLOCK_PLL(obj);
78
int psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
589
79
+ int i;
590
pll->clock_in = qdev_init_clock_in(DEVICE(pll), "clock-in",
80
591
- npcm7xx_clk_update_pll, pll);
81
/*
592
+ npcm7xx_clk_update_pll_cb, pll,
82
* If the user provides an Operating System to be loaded, we expect them
593
+ ClockUpdate);
83
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
594
pll->clock_out = qdev_init_clock_out(DEVICE(pll), "clock-out");
84
fdt_add_gic_nodes(s);
595
}
85
fdt_add_timer_nodes(s);
596
86
fdt_add_zdma_nodes(s);
597
+static void npcm7xx_clk_update_sel_cb(void *opaque, ClockEvent event)
87
+ fdt_add_sd_nodes(s);
598
+{
88
fdt_add_cpu_nodes(s, psci_conduit);
599
+ npcm7xx_clk_update_sel(opaque);
89
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
600
+}
90
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
601
+
91
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
602
static void npcm7xx_clk_sel_init(Object *obj)
92
memory_region_add_subregion_overlap(get_system_memory(),
603
{
93
0, &s->soc.fpd.apu.mr, 0);
604
int i;
94
605
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_clk_sel_init(Object *obj)
95
+ /* Plugin SD cards. */
606
for (i = 0; i < NPCM7XX_CLK_SEL_MAX_INPUT; ++i) {
96
+ for (i = 0; i < ARRAY_SIZE(s->soc.pmc.iou.sd); i++) {
607
sel->clock_in[i] = qdev_init_clock_in(DEVICE(sel),
97
+ sd_plugin_card(&s->soc.pmc.iou.sd[i], drive_get_next(IF_SD));
608
g_strdup_printf("clock-in[%d]", i),
98
+ }
609
- npcm7xx_clk_update_sel, sel);
99
+
610
+ npcm7xx_clk_update_sel_cb, sel, ClockUpdate);
100
s->binfo.ram_size = machine->ram_size;
611
}
101
s->binfo.loader_start = 0x0;
612
sel->clock_out = qdev_init_clock_out(DEVICE(sel), "clock-out");
102
s->binfo.get_dtb = versal_virt_get_dtb;
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
103
--
772
--
104
2.20.1
773
2.20.1
105
774
106
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
1
For ARMv8.2-TTS2UXN, the stage 2 page table walk wants to know
1
Add a clock_ns_to_ticks() function which does the opposite of
2
whether the stage 1 access is for EL0 or not, because whether
2
clock_ticks_to_ns(): given a duration in nanoseconds, it returns the
3
exec permission is given can depend on whether this is an EL0
3
number of clock ticks that would happen in that time. This is useful
4
or EL1 access. Add a new argument to get_phys_addr_lpae() so
4
for devices that have a free running counter register whose value can
5
the call sites can pass this information in.
5
be calculated when it is read.
6
7
Since get_phys_addr_lpae() doesn't already have a doc comment,
8
add one so we have a place to put the documentation of the
9
semantics of the new s1_is_el0 argument.
10
6
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Reviewed-by: Luc Michel <luc@lmichel.fr>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Hao Wu <wuhaotsh@google.com>
14
Message-id: 20200330210400.11724-4-peter.maydell@linaro.org
10
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20210219144617.4782-4-peter.maydell@linaro.org
15
---
12
---
16
target/arm/helper.c | 29 ++++++++++++++++++++++++++++-
13
docs/devel/clocks.rst | 12 ++++++++++++
17
1 file changed, 28 insertions(+), 1 deletion(-)
14
include/hw/clock.h | 41 +++++++++++++++++++++++++++++++++++++++++
15
2 files changed, 53 insertions(+)
18
16
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
diff --git a/docs/devel/clocks.rst b/docs/devel/clocks.rst
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
19
--- a/docs/devel/clocks.rst
22
+++ b/target/arm/helper.c
20
+++ b/docs/devel/clocks.rst
23
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ rather than simply passing it to a QEMUTimer function like
24
22
``timer_mod_ns()`` then you should be careful to avoid overflow
25
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
23
in those calculations, of course.)
26
MMUAccessType access_type, ARMMMUIdx mmu_idx,
24
27
+ bool s1_is_el0,
25
+Obtaining tick counts
28
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
26
+---------------------
29
target_ulong *page_size_ptr,
27
+
30
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs);
28
+For calculations where you need to know the number of ticks in
31
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
29
+a given duration, use ``clock_ns_to_ticks()``. This function handles
32
}
30
+possible non-whole-number-of-nanoseconds periods and avoids
33
31
+potential rounding errors. It will return '0' if the clock is stopped
34
ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
32
+(i.e. it has period zero). If the inputs imply a tick count that
35
+ false,
33
+overflows a 64-bit value (a very long duration for a clock with a
36
&s2pa, &txattrs, &s2prot, &s2size, fi,
34
+very short period) the output value is truncated, so effectively
37
pcacheattrs);
35
+the 64-bit output wraps around.
38
if (ret) {
36
+
39
@@ -XXX,XX +XXX,XX @@ static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
37
Changing a clock period
40
};
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;
41
}
46
}
42
47
43
+/**
48
+/**
44
+ * get_phys_addr_lpae: perform one stage of page table walk, LPAE format
49
+ * clock_ns_to_ticks:
50
+ * @clk: the clock to query
51
+ * @ns: duration in nanoseconds
45
+ *
52
+ *
46
+ * Returns false if the translation was successful. Otherwise, phys_ptr, attrs,
53
+ * Returns the number of ticks this clock would make in the given
47
+ * prot and page_size may not be filled in, and the populated fsr value provides
54
+ * number of nanoseconds. Because a clock can have a period which
48
+ * information on why the translation aborted, in the format of a long-format
55
+ * is not a whole number of nanoseconds, it is important to use this
49
+ * DFSR/IFSR fault register, with the following caveats:
56
+ * function rather than attempting to obtain a "period in nanoseconds"
50
+ * * the WnR bit is never set (the caller must do this).
57
+ * value and then dividing the duration by that value.
51
+ *
58
+ *
52
+ * @env: CPUARMState
59
+ * If the clock is stopped (ie it has period zero), returns 0.
53
+ * @address: virtual address to get physical address for
60
+ *
54
+ * @access_type: MMU_DATA_LOAD, MMU_DATA_STORE or MMU_INST_FETCH
61
+ * For some inputs the result could overflow a 64-bit value (because
55
+ * @mmu_idx: MMU index indicating required translation regime
62
+ * the clock's period is short and the duration is long). In these
56
+ * @s1_is_el0: if @mmu_idx is ARMMMUIdx_Stage2 (so this is a stage 2 page table
63
+ * cases we truncate the result to a 64-bit value. This is on the
57
+ * walk), must be true if this is stage 2 of a stage 1+2 walk for an
64
+ * assumption that generally the result is going to be used to report
58
+ * EL0 access). If @mmu_idx is anything else, @s1_is_el0 is ignored.
65
+ * a 32-bit or 64-bit guest register value, so wrapping either cannot
59
+ * @phys_ptr: set to the physical address corresponding to the virtual address
66
+ * happen or is the desired behaviour.
60
+ * @attrs: set to the memory transaction attributes to use
61
+ * @prot: set to the permissions for the page containing phys_ptr
62
+ * @page_size_ptr: set to the size of the page containing phys_ptr
63
+ * @fi: set to fault info if the translation fails
64
+ * @cacheattrs: (if non-NULL) set to the cacheability/shareability attributes
65
+ */
67
+ */
66
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
68
+static inline uint64_t clock_ns_to_ticks(const Clock *clk, uint64_t ns)
67
MMUAccessType access_type, ARMMMUIdx mmu_idx,
69
+{
68
+ bool s1_is_el0,
70
+ /*
69
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
71
+ * ticks = duration_in_ns / period_in_ns
70
target_ulong *page_size_ptr,
72
+ * = ns / (period / 2^32)
71
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
73
+ * = (ns * 2^32) / period
72
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
74
+ * The hi, lo inputs to divu128() are (ns << 32) as a 128 bit value.
73
75
+ */
74
/* S1 is done. Now do S2 translation. */
76
+ uint64_t lo = ns << 32;
75
ret = get_phys_addr_lpae(env, ipa, access_type, ARMMMUIdx_Stage2,
77
+ uint64_t hi = ns >> 32;
76
+ mmu_idx == ARMMMUIdx_E10_0,
78
+ if (clk->period == 0) {
77
phys_ptr, attrs, &s2_prot,
79
+ return 0;
78
page_size, fi,
80
+ }
79
cacheattrs != NULL ? &cacheattrs2 : NULL);
81
+ /*
80
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
82
+ * Ignore divu128() return value as we've caught div-by-zero and don't
81
}
83
+ * need different behaviour for overflow.
82
84
+ */
83
if (regime_using_lpae_format(env, mmu_idx)) {
85
+ divu128(&lo, &hi, clk->period);
84
- return get_phys_addr_lpae(env, address, access_type, mmu_idx,
86
+ return lo;
85
+ return get_phys_addr_lpae(env, address, access_type, mmu_idx, false,
87
+}
86
phys_ptr, attrs, prot, page_size,
88
+
87
fi, cacheattrs);
89
/**
88
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
90
* clock_is_enabled:
91
* @clk: a clock
89
--
92
--
90
2.20.1
93
2.20.1
91
94
92
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
1
Convert the VFM[AS]L (scalar) insns in the 2reg-scalar-ext group
1
We model Arm "Subsystems for Embedded" SoC subsystems using generic
2
to decodetree. These are the last ones in the group so we can remove
2
code which is split into various sub-devices which are configurable
3
all the legacy decode for the group.
3
by QOM properties to handle the behaviour differences between the SSE
4
4
subsystems we implement. Currently the only sub-device which needs
5
Note that in disas_thumb2_insn() the parts of this encoding space
5
to change is the IOTKIT_SYSCTL device, and we do this with a mix of
6
where the decodetree decoder returns false will correctly be directed
6
properties that directly specify divergent behaviours (eg
7
to illegal_op by the "(insn & (1 << 28))" check so they won't fall
7
CPUWAIT_RST) and passing it the SYS_VERSION register value as a way
8
into disas_coproc_insn() by mistake.
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.
9
28
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200430181003.21682-11-peter.maydell@linaro.org
32
Message-id: 20210219144617.4782-6-peter.maydell@linaro.org
13
---
33
---
14
target/arm/neon-shared.decode | 7 +++
34
include/hw/arm/armsse-version.h | 42 +++++++++++++++++++++++++++++++++
15
target/arm/translate-neon.inc.c | 32 ++++++++++
35
include/hw/misc/iotkit-sysctl.h | 7 +++---
16
target/arm/translate.c | 107 +-------------------------------
36
hw/arm/armsse.c | 8 +++++--
17
3 files changed, 40 insertions(+), 106 deletions(-)
37
hw/misc/iotkit-sysctl.c | 11 +++++----
18
38
4 files changed, 58 insertions(+), 10 deletions(-)
19
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
39
create mode 100644 include/hw/arm/armsse-version.h
20
index XXXXXXX..XXXXXXX 100644
40
21
--- a/target/arm/neon-shared.decode
41
diff --git a/include/hw/arm/armsse-version.h b/include/hw/arm/armsse-version.h
22
+++ b/target/arm/neon-shared.decode
42
new file mode 100644
23
@@ -XXX,XX +XXX,XX @@ VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
43
index XXXXXXX..XXXXXXX
24
44
--- /dev/null
25
VDOT_scalar 1111 1110 0 . 10 .... .... 1101 . q:1 index:1 u:1 rm:4 \
45
+++ b/include/hw/arm/armsse-version.h
26
vm=%vm_dp vn=%vn_dp vd=%vd_dp
46
@@ -XXX,XX +XXX,XX @@
27
+
47
+/*
28
+%vfml_scalar_q0_rm 0:3 5:1
48
+ * ARM SSE (Subsystems for Embedded): IoTKit, SSE-200
29
+%vfml_scalar_q1_index 5:1 3:1
49
+ *
30
+VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 0 . 1 index:1 ... \
50
+ * Copyright (c) 2020 Linaro Limited
31
+ rm=%vfml_scalar_q0_rm vn=%vn_sp vd=%vd_dp q=0
51
+ * Written by Peter Maydell
32
+VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 1 . 1 . rm:3 \
52
+ *
33
+ index=%vfml_scalar_q1_index vn=%vn_dp vd=%vd_dp q=1
53
+ * This program is free software; you can redistribute it and/or modify
34
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
54
+ * it under the terms of the GNU General Public License version 2 or
35
index XXXXXXX..XXXXXXX 100644
55
+ * (at your option) any later version.
36
--- a/target/arm/translate-neon.inc.c
56
+ */
37
+++ b/target/arm/translate-neon.inc.c
57
+
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
58
+#ifndef ARMSSE_VERSION_H
39
tcg_temp_free_ptr(fpst);
59
+#define ARMSSE_VERSION_H
40
return true;
60
+
41
}
61
+
42
+
62
+/*
43
+static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
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)
44
+{
77
+{
45
+ int opr_sz;
78
+ switch (sse_version) {
46
+
79
+ case ARMSSE_IOTKIT:
47
+ if (!dc_isar_feature(aa32_fhm, s)) {
80
+ case ARMSSE_SSE200:
81
+ case ARMSSE_SSE300:
82
+ return true;
83
+ default:
48
+ return false;
84
+ return false;
49
+ }
85
+ }
50
+
51
+ /* UNDEF accesses to D16-D31 if they don't exist. */
52
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
53
+ ((a->vd & 0x10) || (a->q && (a->vn & 0x10)))) {
54
+ return false;
55
+ }
56
+
57
+ if (a->vd & a->q) {
58
+ return false;
59
+ }
60
+
61
+ if (!vfp_access_check(s)) {
62
+ return true;
63
+ }
64
+
65
+ opr_sz = (1 + a->q) * 8;
66
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
67
+ vfp_reg_offset(a->q, a->vn),
68
+ vfp_reg_offset(a->q, a->rm),
69
+ cpu_env, opr_sz, opr_sz,
70
+ (a->index << 2) | a->s, /* is_2 == 0 */
71
+ gen_helper_gvec_fmlal_idx_a32);
72
+ return true;
73
+}
86
+}
74
diff --git a/target/arm/translate.c b/target/arm/translate.c
87
+
88
+#endif
89
diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
75
index XXXXXXX..XXXXXXX 100644
90
index XXXXXXX..XXXXXXX 100644
76
--- a/target/arm/translate.c
91
--- a/include/hw/misc/iotkit-sysctl.h
77
+++ b/target/arm/translate.c
92
+++ b/include/hw/misc/iotkit-sysctl.h
78
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
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;
79
}
186
}
80
187
81
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
188
static bool sse200_needed(void *opaque)
82
-#define VFP_SREG(insn, bigbit, smallbit) \
189
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription iotkit_sysctl_vmstate = {
83
- ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
190
};
84
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
191
85
if (dc_isar_feature(aa32_simd_r32, s)) { \
192
static Property iotkit_sysctl_props[] = {
86
reg = (((insn) >> (bigbit)) & 0x0f) \
193
- DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysCtl, sys_version, 0),
87
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
194
+ DEFINE_PROP_UINT32("sse-version", IoTKitSysCtl, sse_version, 0),
88
reg = ((insn) >> (bigbit)) & 0x0f; \
195
DEFINE_PROP_UINT32("CPUWAIT_RST", IoTKitSysCtl, cpuwait_rst, 0),
89
}} while (0)
196
DEFINE_PROP_UINT32("INITSVTOR0_RST", IoTKitSysCtl, initsvtor0_rst,
90
197
0x10000000),
91
-#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
92
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
93
-#define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
94
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
95
-#define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
96
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
97
98
static void gen_neon_dup_low16(TCGv_i32 var)
99
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
100
return 0;
101
}
102
103
-/* Advanced SIMD two registers and a scalar extension.
104
- * 31 24 23 22 20 16 12 11 10 9 8 3 0
105
- * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
106
- * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
107
- * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
108
- *
109
- */
110
-
111
-static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
112
-{
113
- gen_helper_gvec_3 *fn_gvec = NULL;
114
- gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
115
- int rd, rn, rm, opr_sz, data;
116
- int off_rn, off_rm;
117
- bool is_long = false, q = extract32(insn, 6, 1);
118
- bool ptr_is_env = false;
119
-
120
- if ((insn & 0xffa00f10) == 0xfe000810) {
121
- /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
122
- int is_s = extract32(insn, 20, 1);
123
- int vm20 = extract32(insn, 0, 3);
124
- int vm3 = extract32(insn, 3, 1);
125
- int m = extract32(insn, 5, 1);
126
- int index;
127
-
128
- if (!dc_isar_feature(aa32_fhm, s)) {
129
- return 1;
130
- }
131
- if (q) {
132
- rm = vm20;
133
- index = m * 2 + vm3;
134
- } else {
135
- rm = vm20 * 2 + m;
136
- index = vm3;
137
- }
138
- is_long = true;
139
- data = (index << 2) | is_s; /* is_2 == 0 */
140
- fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
141
- ptr_is_env = true;
142
- } else {
143
- return 1;
144
- }
145
-
146
- VFP_DREG_D(rd, insn);
147
- if (rd & q) {
148
- return 1;
149
- }
150
- if (q || !is_long) {
151
- VFP_DREG_N(rn, insn);
152
- if (rn & q & !is_long) {
153
- return 1;
154
- }
155
- off_rn = vfp_reg_offset(1, rn);
156
- off_rm = vfp_reg_offset(1, rm);
157
- } else {
158
- rn = VFP_SREG_N(insn);
159
- off_rn = vfp_reg_offset(0, rn);
160
- off_rm = vfp_reg_offset(0, rm);
161
- }
162
- if (s->fp_excp_el) {
163
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
164
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
165
- return 0;
166
- }
167
- if (!s->vfp_enabled) {
168
- return 1;
169
- }
170
-
171
- opr_sz = (1 + q) * 8;
172
- if (fn_gvec_ptr) {
173
- TCGv_ptr ptr;
174
- if (ptr_is_env) {
175
- ptr = cpu_env;
176
- } else {
177
- ptr = get_fpstatus_ptr(1);
178
- }
179
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
180
- opr_sz, opr_sz, data, fn_gvec_ptr);
181
- if (!ptr_is_env) {
182
- tcg_temp_free_ptr(ptr);
183
- }
184
- } else {
185
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
186
- opr_sz, opr_sz, data, fn_gvec);
187
- }
188
- return 0;
189
-}
190
-
191
static int disas_coproc_insn(DisasContext *s, uint32_t insn)
192
{
193
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
194
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
195
}
196
}
197
}
198
- } else if ((insn & 0x0f000a00) == 0x0e000800
199
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
200
- if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
201
- goto illegal_op;
202
- }
203
- return;
204
}
205
goto illegal_op;
206
}
207
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
208
}
209
break;
210
}
211
- if ((insn & 0xff000a00) == 0xfe000800
212
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
213
- /* The Thumb2 and ARM encodings are identical. */
214
- if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
215
- goto illegal_op;
216
- }
217
- } else if (((insn >> 24) & 3) == 3) {
218
+ if (((insn >> 24) & 3) == 3) {
219
/* Translate into the equivalent ARM encoding. */
220
insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
221
if (disas_neon_data_insn(s, insn)) {
222
--
198
--
223
2.20.1
199
2.20.1
224
200
225
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
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
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.
2
5
3
Add support for SD.
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(-)
4
15
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
16
diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-9-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/arm/xlnx-versal.h | 12 ++++++++++++
13
hw/arm/xlnx-versal.c | 31 +++++++++++++++++++++++++++++++
14
2 files changed, 43 insertions(+)
15
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
18
--- a/include/hw/misc/iotkit-sysinfo.h
19
+++ b/include/hw/arm/xlnx-versal.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
20
@@ -XXX,XX +XXX,XX @@
45
@@ -XXX,XX +XXX,XX @@
21
46
#include "hw/registerfields.h"
22
#include "hw/sysbus.h"
47
#include "hw/misc/iotkit-sysinfo.h"
23
#include "hw/arm/boot.h"
48
#include "hw/qdev-properties.h"
24
+#include "hw/sd/sdhci.h"
49
+#include "hw/arm/armsse-version.h"
25
#include "hw/intc/arm_gicv3.h"
50
26
#include "hw/char/pl011.h"
51
REG32(SYS_VERSION, 0x0)
27
#include "hw/dma/xlnx-zdma.h"
52
REG32(SYS_CONFIG, 0x4)
28
@@ -XXX,XX +XXX,XX @@
53
@@ -XXX,XX +XXX,XX @@ static const int sysinfo_id[] = {
29
#define XLNX_VERSAL_NR_UARTS 2
54
0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
30
#define XLNX_VERSAL_NR_GEMS 2
55
};
31
#define XLNX_VERSAL_NR_ADMAS 8
56
32
+#define XLNX_VERSAL_NR_SDS 2
57
+static const int sysinfo_sse300_id[] = {
33
#define XLNX_VERSAL_NR_IRQS 192
58
+ 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
34
59
+ 0x58, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
35
typedef struct Versal {
60
+ 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
36
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
61
+};
37
} iou;
38
} lpd;
39
40
+ /* The Platform Management Controller subsystem. */
41
+ struct {
42
+ struct {
43
+ SDHCIState sd[XLNX_VERSAL_NR_SDS];
44
+ } iou;
45
+ } pmc;
46
+
62
+
47
struct {
63
static uint64_t iotkit_sysinfo_read(void *opaque, hwaddr offset,
48
MemoryRegion *mr_ddr;
64
unsigned size)
49
uint32_t psci_conduit;
65
{
50
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
66
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysinfo_read(void *opaque, hwaddr offset,
51
#define VERSAL_GEM1_IRQ_0 58
67
r = s->sys_config;
52
#define VERSAL_GEM1_WAKE_IRQ_0 59
68
break;
53
#define VERSAL_ADMA_IRQ_0 60
69
case A_PID4 ... A_CID3:
54
+#define VERSAL_SD0_IRQ_0 126
70
- r = sysinfo_id[(offset - A_PID4) / 4];
55
71
+ switch (s->sse_version) {
56
/* Architecturally reserved IRQs suitable for virtualization. */
72
+ case ARMSSE_SSE300:
57
#define VERSAL_RSVD_IRQ_FIRST 111
73
+ r = sysinfo_sse300_id[(offset - A_PID4) / 4];
58
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
74
+ break;
59
#define MM_FPD_CRF 0xfd1a0000U
75
+ default:
60
#define MM_FPD_CRF_SIZE 0x140000
76
+ r = sysinfo_id[(offset - A_PID4) / 4];
61
77
+ break;
62
+#define MM_PMC_SD0 0xf1040000U
78
+ }
63
+#define MM_PMC_SD0_SIZE 0x10000
79
break;
64
#define MM_PMC_CRP 0xf1260000U
80
default:
65
#define MM_PMC_CRP_SIZE 0x10000
81
qemu_log_mask(LOG_GUEST_ERROR,
66
#endif
82
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps iotkit_sysinfo_ops = {
67
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
83
static Property iotkit_sysinfo_props[] = {
68
index XXXXXXX..XXXXXXX 100644
84
DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysInfo, sys_version, 0),
69
--- a/hw/arm/xlnx-versal.c
85
DEFINE_PROP_UINT32("SYS_CONFIG", IoTKitSysInfo, sys_config, 0),
70
+++ b/hw/arm/xlnx-versal.c
86
+ DEFINE_PROP_UINT32("sse-version", IoTKitSysInfo, sse_version, 0),
71
@@ -XXX,XX +XXX,XX @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
87
DEFINE_PROP_END_OF_LIST()
72
}
88
};
89
90
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysinfo_init(Object *obj)
91
sysbus_init_mmio(sbd, &s->iomem);
73
}
92
}
74
93
75
+#define SDHCI_CAPABILITIES 0x280737ec6481 /* Same as on ZynqMP. */
94
+static void iotkit_sysinfo_realize(DeviceState *dev, Error **errp)
76
+static void versal_create_sds(Versal *s, qemu_irq *pic)
77
+{
95
+{
78
+ int i;
96
+ IoTKitSysInfo *s = IOTKIT_SYSINFO(dev);
79
+
97
+
80
+ for (i = 0; i < ARRAY_SIZE(s->pmc.iou.sd); i++) {
98
+ if (!armsse_version_valid(s->sse_version)) {
81
+ DeviceState *dev;
99
+ error_setg(errp, "invalid sse-version value %d", s->sse_version);
82
+ MemoryRegion *mr;
100
+ return;
83
+
84
+ sysbus_init_child_obj(OBJECT(s), "sd[*]",
85
+ &s->pmc.iou.sd[i], sizeof(s->pmc.iou.sd[i]),
86
+ TYPE_SYSBUS_SDHCI);
87
+ dev = DEVICE(&s->pmc.iou.sd[i]);
88
+
89
+ object_property_set_uint(OBJECT(dev),
90
+ 3, "sd-spec-version", &error_fatal);
91
+ object_property_set_uint(OBJECT(dev), SDHCI_CAPABILITIES, "capareg",
92
+ &error_fatal);
93
+ object_property_set_uint(OBJECT(dev), UHS_I, "uhs", &error_fatal);
94
+ qdev_init_nofail(dev);
95
+
96
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
97
+ memory_region_add_subregion(&s->mr_ps,
98
+ MM_PMC_SD0 + i * MM_PMC_SD0_SIZE, mr);
99
+
100
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
101
+ pic[VERSAL_SD0_IRQ_0 + i * 2]);
102
+ }
101
+ }
103
+}
102
+}
104
+
103
+
105
/* This takes the board allocated linear DDR memory and creates aliases
104
static void iotkit_sysinfo_class_init(ObjectClass *klass, void *data)
106
* for each split DDR range/aperture on the Versal address map.
105
{
107
*/
106
DeviceClass *dc = DEVICE_CLASS(klass);
108
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
107
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysinfo_class_init(ObjectClass *klass, void *data)
109
versal_create_uarts(s, pic);
108
* This device has no guest-modifiable state and so it
110
versal_create_gems(s, pic);
109
* does not need a reset function or VMState.
111
versal_create_admas(s, pic);
110
*/
112
+ versal_create_sds(s, pic);
111
-
113
versal_map_ddr(s);
112
+ dc->realize = iotkit_sysinfo_realize;
114
versal_unimp(s);
113
device_class_set_props(dc, iotkit_sysinfo_props);
114
}
115
115
116
--
116
--
117
2.20.1
117
2.20.1
118
118
119
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
1
Convert the Neon "load single structure to all lanes" insns to
1
For SSE-300, the SYSINFO register block has two new registers:
2
decodetree.
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
3
10
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-13-peter.maydell@linaro.org
14
Message-id: 20210219144617.4782-11-peter.maydell@linaro.org
7
---
15
---
8
target/arm/neon-ls.decode | 5 +++
16
include/hw/misc/iotkit-sysinfo.h | 1 +
9
target/arm/translate-neon.inc.c | 73 +++++++++++++++++++++++++++++++++
17
hw/arm/armsse.c | 5 +++++
10
target/arm/translate.c | 55 +------------------------
18
hw/misc/iotkit-sysinfo.c | 22 ++++++++++++++++++++++
11
3 files changed, 80 insertions(+), 53 deletions(-)
19
3 files changed, 28 insertions(+)
12
20
13
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
21
diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h
14
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-ls.decode
23
--- a/include/hw/misc/iotkit-sysinfo.h
16
+++ b/target/arm/neon-ls.decode
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
17
@@ -XXX,XX +XXX,XX @@
74
@@ -XXX,XX +XXX,XX @@
18
75
19
VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
76
REG32(SYS_VERSION, 0x0)
20
vd=%vd_dp
77
REG32(SYS_CONFIG, 0x4)
21
+
78
+REG32(SYS_CONFIG1, 0x8)
22
+# Neon load single element to all lanes
79
+REG32(IIDR, 0xfc8)
23
+
80
REG32(PID4, 0xfd0)
24
+VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
81
REG32(PID5, 0xfd4)
25
+ vd=%vd_dp
82
REG32(PID6, 0xfd8)
26
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
83
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysinfo_read(void *opaque, hwaddr offset,
27
index XXXXXXX..XXXXXXX 100644
84
case A_SYS_CONFIG:
28
--- a/target/arm/translate-neon.inc.c
85
r = s->sys_config;
29
+++ b/target/arm/translate-neon.inc.c
86
break;
30
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
87
+ case A_SYS_CONFIG1:
31
gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
88
+ switch (s->sse_version) {
32
return true;
89
+ case ARMSSE_SSE300:
33
}
90
+ return 0;
34
+
91
+ break;
35
+static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
92
+ default:
36
+{
93
+ goto bad_read;
37
+ /* Neon load single structure to all lanes */
38
+ int reg, stride, vec_size;
39
+ int vd = a->vd;
40
+ int size = a->size;
41
+ int nregs = a->n + 1;
42
+ TCGv_i32 addr, tmp;
43
+
44
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
45
+ return false;
46
+ }
47
+
48
+ /* UNDEF accesses to D16-D31 if they don't exist */
49
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
50
+ return false;
51
+ }
52
+
53
+ if (size == 3) {
54
+ if (nregs != 4 || a->a == 0) {
55
+ return false;
56
+ }
94
+ }
57
+ /* For VLD4 size == 3 a == 1 means 32 bits at 16 byte alignment */
95
+ break;
58
+ size = 2;
96
+ case A_IIDR:
59
+ }
97
+ switch (s->sse_version) {
60
+ if (nregs == 1 && a->a == 1 && size == 0) {
98
+ case ARMSSE_SSE300:
61
+ return false;
99
+ return s->iidr;
62
+ }
100
+ break;
63
+ if (nregs == 3 && a->a == 1) {
101
+ default:
64
+ return false;
102
+ goto bad_read;
65
+ }
66
+
67
+ if (!vfp_access_check(s)) {
68
+ return true;
69
+ }
70
+
71
+ /*
72
+ * VLD1 to all lanes: T bit indicates how many Dregs to write.
73
+ * VLD2/3/4 to all lanes: T bit indicates register stride.
74
+ */
75
+ stride = a->t ? 2 : 1;
76
+ vec_size = nregs == 1 ? stride * 8 : 8;
77
+
78
+ tmp = tcg_temp_new_i32();
79
+ addr = tcg_temp_new_i32();
80
+ load_reg_var(s, addr, a->rn);
81
+ for (reg = 0; reg < nregs; reg++) {
82
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
83
+ s->be_data | size);
84
+ if ((vd & 1) && vec_size == 16) {
85
+ /*
86
+ * We cannot write 16 bytes at once because the
87
+ * destination is unaligned.
88
+ */
89
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
90
+ 8, 8, tmp);
91
+ tcg_gen_gvec_mov(0, neon_reg_offset(vd + 1, 0),
92
+ neon_reg_offset(vd, 0), 8, 8);
93
+ } else {
94
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
95
+ vec_size, vec_size, tmp);
96
+ }
103
+ }
97
+ tcg_gen_addi_i32(addr, addr, 1 << size);
104
+ break;
98
+ vd += stride;
105
case A_PID4 ... A_CID3:
99
+ }
106
switch (s->sse_version) {
100
+ tcg_temp_free_i32(tmp);
107
case ARMSSE_SSE300:
101
+ tcg_temp_free_i32(addr);
108
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysinfo_read(void *opaque, hwaddr offset,
102
+
109
}
103
+ gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << size) * nregs);
110
break;
104
+
111
default:
105
+ return true;
112
+ bad_read:
106
+}
113
qemu_log_mask(LOG_GUEST_ERROR,
107
diff --git a/target/arm/translate.c b/target/arm/translate.c
114
"IoTKit SysInfo read: bad offset %x\n", (int)offset);
108
index XXXXXXX..XXXXXXX 100644
115
r = 0;
109
--- a/target/arm/translate.c
116
@@ -XXX,XX +XXX,XX @@ static Property iotkit_sysinfo_props[] = {
110
+++ b/target/arm/translate.c
117
DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysInfo, sys_version, 0),
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
118
DEFINE_PROP_UINT32("SYS_CONFIG", IoTKitSysInfo, sys_config, 0),
112
int size;
119
DEFINE_PROP_UINT32("sse-version", IoTKitSysInfo, sse_version, 0),
113
int reg;
120
+ DEFINE_PROP_UINT32("IIDR", IoTKitSysInfo, iidr, 0),
114
int load;
121
DEFINE_PROP_END_OF_LIST()
115
- int vec_size;
122
};
116
TCGv_i32 addr;
123
117
TCGv_i32 tmp;
118
119
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
120
} else {
121
size = (insn >> 10) & 3;
122
if (size == 3) {
123
- /* Load single element to all lanes. */
124
- int a = (insn >> 4) & 1;
125
- if (!load) {
126
- return 1;
127
- }
128
- size = (insn >> 6) & 3;
129
- nregs = ((insn >> 8) & 3) + 1;
130
-
131
- if (size == 3) {
132
- if (nregs != 4 || a == 0) {
133
- return 1;
134
- }
135
- /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
136
- size = 2;
137
- }
138
- if (nregs == 1 && a == 1 && size == 0) {
139
- return 1;
140
- }
141
- if (nregs == 3 && a == 1) {
142
- return 1;
143
- }
144
- addr = tcg_temp_new_i32();
145
- load_reg_var(s, addr, rn);
146
-
147
- /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
148
- * VLD2/3/4 to all lanes: bit 5 indicates register stride.
149
- */
150
- stride = (insn & (1 << 5)) ? 2 : 1;
151
- vec_size = nregs == 1 ? stride * 8 : 8;
152
-
153
- tmp = tcg_temp_new_i32();
154
- for (reg = 0; reg < nregs; reg++) {
155
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
156
- s->be_data | size);
157
- if ((rd & 1) && vec_size == 16) {
158
- /* We cannot write 16 bytes at once because the
159
- * destination is unaligned.
160
- */
161
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
162
- 8, 8, tmp);
163
- tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
164
- neon_reg_offset(rd, 0), 8, 8);
165
- } else {
166
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
167
- vec_size, vec_size, tmp);
168
- }
169
- tcg_gen_addi_i32(addr, addr, 1 << size);
170
- rd += stride;
171
- }
172
- tcg_temp_free_i32(tmp);
173
- tcg_temp_free_i32(addr);
174
- stride = (1 << size) * nregs;
175
+ /* Load single element to all lanes -- handled by decodetree */
176
+ return 1;
177
} else {
178
/* Single element. */
179
int idx = (insn >> 4) & 0xf;
180
--
124
--
181
2.20.1
125
2.20.1
182
126
183
127
diff view generated by jsdifflib
1
Add the infrastructure for building and invoking a decodetree decoder
1
The SSE-300 includes a counter module; implement a model of it.
2
for the AArch32 Neon encodings. At the moment the new decoder covers
3
nothing, so we always fall back to the existing hand-written decode.
4
2
5
We follow the same pattern we did for the VFP decodetree conversion
3
This counter is documented in the SSE-123 Example Subsystem
6
(commit 78e138bc1f672c145ef6ace74617d and following): code that deals
4
Technical Reference Manual:
7
with Neon will be moving gradually out to translate-neon.vfp.inc,
5
https://developer.arm.com/documentation/101370/latest/
8
which we #include into translate.c.
9
10
In order to share the decode files between A32 and T32, we
11
split Neon into 3 parts:
12
* data-processing
13
* load-store
14
* 'shared' encodings
15
16
The first two groups of instructions have similar but not identical
17
A32 and T32 encodings, so we need to manually transform the T32
18
encoding into the A32 one before calling the decoder; the third group
19
covers the Neon instructions which are identical in A32 and T32.
20
6
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 20200430181003.21682-4-peter.maydell@linaro.org
10
Message-id: 20210219144617.4782-12-peter.maydell@linaro.org
24
---
11
---
25
target/arm/neon-dp.decode | 29 ++++++++++++++++++++++++++
12
include/hw/timer/sse-counter.h | 105 ++++++++
26
target/arm/neon-ls.decode | 29 ++++++++++++++++++++++++++
13
hw/timer/sse-counter.c | 474 +++++++++++++++++++++++++++++++++
27
target/arm/neon-shared.decode | 27 +++++++++++++++++++++++++
14
MAINTAINERS | 2 +
28
target/arm/translate-neon.inc.c | 32 +++++++++++++++++++++++++++++
15
hw/arm/Kconfig | 1 +
29
target/arm/translate.c | 36 +++++++++++++++++++++++++++++++--
16
hw/timer/Kconfig | 3 +
30
target/arm/Makefile.objs | 18 +++++++++++++++++
17
hw/timer/meson.build | 1 +
31
6 files changed, 169 insertions(+), 2 deletions(-)
18
hw/timer/trace-events | 7 +
32
create mode 100644 target/arm/neon-dp.decode
19
7 files changed, 593 insertions(+)
33
create mode 100644 target/arm/neon-ls.decode
20
create mode 100644 include/hw/timer/sse-counter.h
34
create mode 100644 target/arm/neon-shared.decode
21
create mode 100644 hw/timer/sse-counter.c
35
create mode 100644 target/arm/translate-neon.inc.c
36
22
37
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
23
diff --git a/include/hw/timer/sse-counter.h b/include/hw/timer/sse-counter.h
38
new file mode 100644
24
new file mode 100644
39
index XXXXXXX..XXXXXXX
25
index XXXXXXX..XXXXXXX
40
--- /dev/null
26
--- /dev/null
41
+++ b/target/arm/neon-dp.decode
27
+++ b/include/hw/timer/sse-counter.h
42
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@
43
+# AArch32 Neon data-processing instruction descriptions
29
+/*
44
+#
30
+ * Arm SSE Subsystem System Counter
45
+# Copyright (c) 2020 Linaro, Ltd
31
+ *
46
+#
32
+ * Copyright (c) 2020 Linaro Limited
47
+# This library is free software; you can redistribute it and/or
33
+ * Written by Peter Maydell
48
+# modify it under the terms of the GNU Lesser General Public
34
+ *
49
+# License as published by the Free Software Foundation; either
35
+ * This program is free software; you can redistribute it and/or modify
50
+# version 2 of the License, or (at your option) any later version.
36
+ * it under the terms of the GNU General Public License version 2 or
51
+#
37
+ * (at your option) any later version.
52
+# This library is distributed in the hope that it will be useful,
38
+ */
53
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
39
+
54
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
40
+/*
55
+# Lesser General Public License for more details.
41
+ * This is a model of the "System counter" which is documented in
56
+#
42
+ * the Arm SSE-123 Example Subsystem Technical Reference Manual:
57
+# You should have received a copy of the GNU Lesser General Public
43
+ * https://developer.arm.com/documentation/101370/latest/
58
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
44
+ *
59
+
45
+ * QEMU interface:
60
+#
46
+ * + Clock input "CLK": clock
61
+# This file is processed by scripts/decodetree.py
47
+ * + sysbus MMIO region 0: the control register frame
62
+#
48
+ * + sysbus MMIO region 1: the status register frame
63
+
49
+ *
64
+# Encodings for Neon data processing instructions where the T32 encoding
50
+ * Consumers of the system counter's timestamp, such as the SSE
65
+# is a simple transformation of the A32 encoding.
51
+ * System Timer device, can also use the APIs sse_counter_for_timestamp(),
66
+# More specifically, this file covers instructions where the A32 encoding is
52
+ * sse_counter_tick_to_time() and sse_counter_register_consumer() to
67
+# 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
53
+ * interact with an instance of the System Counter. Generally the
68
+# and the T32 encoding is
54
+ * consumer device should have a QOM link property which the board
69
+# 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
55
+ * code can set to the appropriate instance of the system counter.
70
+# This file works on the A32 encoding only; calling code for T32 has to
56
+ */
71
+# transform the insn into the A32 version first.
57
+
72
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
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
73
new file mode 100644
135
new file mode 100644
74
index XXXXXXX..XXXXXXX
136
index XXXXXXX..XXXXXXX
75
--- /dev/null
137
--- /dev/null
76
+++ b/target/arm/neon-ls.decode
138
+++ b/hw/timer/sse-counter.c
77
@@ -XXX,XX +XXX,XX @@
78
+# AArch32 Neon load/store instruction descriptions
79
+#
80
+# Copyright (c) 2020 Linaro, Ltd
81
+#
82
+# This library is free software; you can redistribute it and/or
83
+# modify it under the terms of the GNU Lesser General Public
84
+# License as published by the Free Software Foundation; either
85
+# version 2 of the License, or (at your option) any later version.
86
+#
87
+# This library is distributed in the hope that it will be useful,
88
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
89
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
90
+# Lesser General Public License for more details.
91
+#
92
+# You should have received a copy of the GNU Lesser General Public
93
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
94
+
95
+#
96
+# This file is processed by scripts/decodetree.py
97
+#
98
+
99
+# Encodings for Neon load/store instructions where the T32 encoding
100
+# is a simple transformation of the A32 encoding.
101
+# More specifically, this file covers instructions where the A32 encoding is
102
+# 0b1111_0100_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
103
+# and the T32 encoding is
104
+# 0b1111_1001_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
105
+# This file works on the A32 encoding only; calling code for T32 has to
106
+# transform the insn into the A32 version first.
107
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
108
new file mode 100644
109
index XXXXXXX..XXXXXXX
110
--- /dev/null
111
+++ b/target/arm/neon-shared.decode
112
@@ -XXX,XX +XXX,XX @@
113
+# AArch32 Neon instruction descriptions
114
+#
115
+# Copyright (c) 2020 Linaro, Ltd
116
+#
117
+# This library is free software; you can redistribute it and/or
118
+# modify it under the terms of the GNU Lesser General Public
119
+# License as published by the Free Software Foundation; either
120
+# version 2 of the License, or (at your option) any later version.
121
+#
122
+# This library is distributed in the hope that it will be useful,
123
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
124
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
125
+# Lesser General Public License for more details.
126
+#
127
+# You should have received a copy of the GNU Lesser General Public
128
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
129
+
130
+#
131
+# This file is processed by scripts/decodetree.py
132
+#
133
+
134
+# Encodings for Neon instructions whose encoding is the same for
135
+# both A32 and T32.
136
+
137
+# More specifically, this covers:
138
+# 2reg scalar ext: 0b1111_1110_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
139
+# 3same ext: 0b1111_110x_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
140
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
141
new file mode 100644
142
index XXXXXXX..XXXXXXX
143
--- /dev/null
144
+++ b/target/arm/translate-neon.inc.c
145
@@ -XXX,XX +XXX,XX @@
139
@@ -XXX,XX +XXX,XX @@
146
+/*
140
+/*
147
+ * ARM translation: AArch32 Neon instructions
141
+ * Arm SSE Subsystem System Counter
148
+ *
142
+ *
149
+ * Copyright (c) 2003 Fabrice Bellard
143
+ * Copyright (c) 2020 Linaro Limited
150
+ * Copyright (c) 2005-2007 CodeSourcery
144
+ * Written by Peter Maydell
151
+ * Copyright (c) 2007 OpenedHand, Ltd.
145
+ *
152
+ * Copyright (c) 2020 Linaro, Ltd.
146
+ * This program is free software; you can redistribute it and/or modify
153
+ *
147
+ * it under the terms of the GNU General Public License version 2 or
154
+ * This library is free software; you can redistribute it and/or
148
+ * (at your option) any later version.
155
+ * modify it under the terms of the GNU Lesser General Public
156
+ * License as published by the Free Software Foundation; either
157
+ * version 2 of the License, or (at your option) any later version.
158
+ *
159
+ * This library is distributed in the hope that it will be useful,
160
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
161
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
162
+ * Lesser General Public License for more details.
163
+ *
164
+ * You should have received a copy of the GNU Lesser General Public
165
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
166
+ */
149
+ */
167
+
150
+
168
+/*
151
+/*
169
+ * This file is intended to be included from translate.c; it uses
152
+ * This is a model of the "System counter" which is documented in
170
+ * some macros and definitions provided by that file.
153
+ * the Arm SSE-123 Example Subsystem Technical Reference Manual:
171
+ * It might be possible to convert it to a standalone .c file eventually.
154
+ * https://developer.arm.com/documentation/101370/latest/
172
+ */
155
+ *
173
+
156
+ * The system counter is a non-stop 64-bit up-counter. It provides
174
+/* Include the generated Neon decoder */
157
+ * this count value to other devices like the SSE system timer,
175
+#include "decode-neon-dp.inc.c"
158
+ * which are driven by this system timestamp rather than directly
176
+#include "decode-neon-ls.inc.c"
159
+ * from a clock. Internally to the counter the count is actually
177
+#include "decode-neon-shared.inc.c"
160
+ * 88-bit precision (64.24 fixed point), with a programmable scale factor.
178
diff --git a/target/arm/translate.c b/target/arm/translate.c
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
179
index XXXXXXX..XXXXXXX 100644
615
index XXXXXXX..XXXXXXX 100644
180
--- a/target/arm/translate.c
616
--- a/MAINTAINERS
181
+++ b/target/arm/translate.c
617
+++ b/MAINTAINERS
182
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
618
@@ -XXX,XX +XXX,XX @@ F: hw/misc/armsse-cpuid.c
183
619
F: include/hw/misc/armsse-cpuid.h
184
#define ARM_CP_RW_BIT (1 << 20)
620
F: hw/misc/armsse-mhu.c
185
621
F: include/hw/misc/armsse-mhu.h
186
-/* Include the VFP decoder */
622
+F: hw/timer/sse-counter.c
187
+/* Include the VFP and Neon decoders */
623
+F: include/hw/timer/sse-counter.h
188
#include "translate-vfp.inc.c"
624
F: docs/system/arm/mps2.rst
189
+#include "translate-neon.inc.c"
625
190
626
Musca
191
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
627
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
192
{
193
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
194
/* Unconditional instructions. */
195
/* TODO: Perhaps merge these into one decodetree output file. */
196
if (disas_a32_uncond(s, insn) ||
197
- disas_vfp_uncond(s, insn)) {
198
+ disas_vfp_uncond(s, insn) ||
199
+ disas_neon_dp(s, insn) ||
200
+ disas_neon_ls(s, insn) ||
201
+ disas_neon_shared(s, insn)) {
202
return;
203
}
204
/* fall back to legacy decoder */
205
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
206
ARCH(6T2);
207
}
208
209
+ if ((insn & 0xef000000) == 0xef000000) {
210
+ /*
211
+ * T32 encodings 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
212
+ * transform into
213
+ * A32 encodings 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
214
+ */
215
+ uint32_t a32_insn = (insn & 0xe2ffffff) |
216
+ ((insn & (1 << 28)) >> 4) | (1 << 28);
217
+
218
+ if (disas_neon_dp(s, a32_insn)) {
219
+ return;
220
+ }
221
+ }
222
+
223
+ if ((insn & 0xff100000) == 0xf9000000) {
224
+ /*
225
+ * T32 encodings 0b1111_1001_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
226
+ * transform into
227
+ * A32 encodings 0b1111_0100_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
228
+ */
229
+ uint32_t a32_insn = (insn & 0x00ffffff) | 0xf4000000;
230
+
231
+ if (disas_neon_ls(s, a32_insn)) {
232
+ return;
233
+ }
234
+ }
235
+
236
/*
237
* TODO: Perhaps merge these into one decodetree output file.
238
* Note disas_vfp is written for a32 with cond field in the
239
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
240
*/
241
if (disas_t32(s, insn) ||
242
disas_vfp_uncond(s, insn) ||
243
+ disas_neon_shared(s, insn) ||
244
((insn >> 28) == 0xe && disas_vfp(s, insn))) {
245
return;
246
}
247
diff --git a/target/arm/Makefile.objs b/target/arm/Makefile.objs
248
index XXXXXXX..XXXXXXX 100644
628
index XXXXXXX..XXXXXXX 100644
249
--- a/target/arm/Makefile.objs
629
--- a/hw/arm/Kconfig
250
+++ b/target/arm/Makefile.objs
630
+++ b/hw/arm/Kconfig
251
@@ -XXX,XX +XXX,XX @@ target/arm/decode-sve.inc.c: $(SRC_PATH)/target/arm/sve.decode $(DECODETREE)
631
@@ -XXX,XX +XXX,XX @@ config ARMSSE
252
     $(PYTHON) $(DECODETREE) --decode disas_sve -o $@ $<,\
632
select TZ_MSC
253
     "GEN", $(TARGET_DIR)$@)
633
select TZ_PPC
254
634
select UNIMP
255
+target/arm/decode-neon-shared.inc.c: $(SRC_PATH)/target/arm/neon-shared.decode $(DECODETREE)
635
+ select SSE_COUNTER
256
+    $(call quiet-command,\
636
257
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_shared -o $@ $<,\
637
config ARMSSE_CPUID
258
+     "GEN", $(TARGET_DIR)$@)
638
bool
259
+
639
diff --git a/hw/timer/Kconfig b/hw/timer/Kconfig
260
+target/arm/decode-neon-dp.inc.c: $(SRC_PATH)/target/arm/neon-dp.decode $(DECODETREE)
640
index XXXXXXX..XXXXXXX 100644
261
+    $(call quiet-command,\
641
--- a/hw/timer/Kconfig
262
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_dp -o $@ $<,\
642
+++ b/hw/timer/Kconfig
263
+     "GEN", $(TARGET_DIR)$@)
643
@@ -XXX,XX +XXX,XX @@ config RENESAS_TMR
264
+
644
config RENESAS_CMT
265
+target/arm/decode-neon-ls.inc.c: $(SRC_PATH)/target/arm/neon-ls.decode $(DECODETREE)
645
bool
266
+    $(call quiet-command,\
646
267
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_ls -o $@ $<,\
647
+config SSE_COUNTER
268
+     "GEN", $(TARGET_DIR)$@)
648
+ bool
269
+
649
+
270
target/arm/decode-vfp.inc.c: $(SRC_PATH)/target/arm/vfp.decode $(DECODETREE)
650
config AVR_TIMER16
271
    $(call quiet-command,\
651
bool
272
     $(PYTHON) $(DECODETREE) --static-decode disas_vfp -o $@ $<,\
652
diff --git a/hw/timer/meson.build b/hw/timer/meson.build
273
@@ -XXX,XX +XXX,XX @@ target/arm/decode-t16.inc.c: $(SRC_PATH)/target/arm/t16.decode $(DECODETREE)
653
index XXXXXXX..XXXXXXX 100644
274
     "GEN", $(TARGET_DIR)$@)
654
--- a/hw/timer/meson.build
275
655
+++ b/hw/timer/meson.build
276
target/arm/translate-sve.o: target/arm/decode-sve.inc.c
656
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_timer.c'))
277
+target/arm/translate.o: target/arm/decode-neon-shared.inc.c
657
softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_systmr.c'))
278
+target/arm/translate.o: target/arm/decode-neon-dp.inc.c
658
softmmu_ss.add(when: 'CONFIG_SH4', if_true: files('sh_timer.c'))
279
+target/arm/translate.o: target/arm/decode-neon-ls.inc.c
659
softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_timer.c'))
280
target/arm/translate.o: target/arm/decode-vfp.inc.c
660
+softmmu_ss.add(when: 'CONFIG_SSE_COUNTER', if_true: files('sse-counter.c'))
281
target/arm/translate.o: target/arm/decode-vfp-uncond.inc.c
661
softmmu_ss.add(when: 'CONFIG_STM32F2XX_TIMER', if_true: files('stm32f2xx_timer.c'))
282
target/arm/translate.o: target/arm/decode-a32.inc.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"
283
--
679
--
284
2.20.1
680
2.20.1
285
681
286
682
diff view generated by jsdifflib
1
Convert the Neon "load/store multiple structures" insns to decodetree.
1
The SSE-300 includes some timers which are a different kind to
2
those in the SSE-200. Model them.
3
4
These timers are documented in the SSE-123 Example Subsystem
5
Technical Reference Manual:
6
https://developer.arm.com/documentation/101370/latest/
2
7
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-12-peter.maydell@linaro.org
11
Message-id: 20210219144617.4782-13-peter.maydell@linaro.org
6
---
12
---
7
target/arm/neon-ls.decode | 7 ++
13
include/hw/timer/sse-timer.h | 53 ++++
8
target/arm/translate-neon.inc.c | 124 ++++++++++++++++++++++++++++++++
14
hw/timer/sse-timer.c | 470 +++++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 91 +----------------------
15
MAINTAINERS | 2 +
10
3 files changed, 133 insertions(+), 89 deletions(-)
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
11
23
12
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
24
diff --git a/include/hw/timer/sse-timer.h b/include/hw/timer/sse-timer.h
13
index XXXXXXX..XXXXXXX 100644
25
new file mode 100644
14
--- a/target/arm/neon-ls.decode
26
index XXXXXXX..XXXXXXX
15
+++ b/target/arm/neon-ls.decode
27
--- /dev/null
28
+++ b/include/hw/timer/sse-timer.h
16
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@
17
# 0b1111_1001_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
30
+/*
18
# This file works on the A32 encoding only; calling code for T32 has to
31
+ * Arm SSE Subsystem System Timer
19
# transform the insn into the A32 version first.
32
+ *
20
+
33
+ * Copyright (c) 2020 Linaro Limited
21
+%vd_dp 22:1 12:4
34
+ * Written by Peter Maydell
22
+
35
+ *
23
+# Neon load/store multiple structures
36
+ * This program is free software; you can redistribute it and/or modify
24
+
37
+ * it under the terms of the GNU General Public License version 2 or
25
+VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
38
+ * (at your option) any later version.
26
+ vd=%vd_dp
39
+ */
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
40
+
28
index XXXXXXX..XXXXXXX 100644
41
+/*
29
--- a/target/arm/translate-neon.inc.c
42
+ * This is a model of the "System timer" which is documented in
30
+++ b/target/arm/translate-neon.inc.c
43
+ * the Arm SSE-123 Example Subsystem Technical Reference Manual:
31
@@ -XXX,XX +XXX,XX @@ static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
44
+ * https://developer.arm.com/documentation/101370/latest/
32
gen_helper_gvec_fmlal_idx_a32);
45
+ *
33
return true;
46
+ * QEMU interface:
34
}
47
+ * + QOM property "counter": link property to be set to the
35
+
48
+ * TYPE_SSE_COUNTER timestamp counter device this timer runs off
36
+static struct {
49
+ * + sysbus MMIO region 0: the register bank
37
+ int nregs;
50
+ * + sysbus IRQ 0: timer interrupt
38
+ int interleave;
51
+ */
39
+ int spacing;
52
+
40
+} const neon_ls_element_type[11] = {
53
+#ifndef SSE_TIMER_H
41
+ {1, 4, 1},
54
+#define SSE_TIMER_H
42
+ {1, 4, 2},
55
+
43
+ {4, 1, 1},
56
+#include "hw/sysbus.h"
44
+ {2, 2, 2},
57
+#include "qom/object.h"
45
+ {1, 3, 1},
58
+#include "hw/timer/sse-counter.h"
46
+ {1, 3, 2},
59
+
47
+ {3, 1, 1},
60
+#define TYPE_SSE_TIMER "sse-timer"
48
+ {1, 1, 1},
61
+OBJECT_DECLARE_SIMPLE_TYPE(SSETimer, SSE_TIMER)
49
+ {1, 2, 1},
62
+
50
+ {1, 2, 2},
63
+struct SSETimer {
51
+ {2, 1, 1}
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;
52
+};
80
+};
53
+
81
+
54
+static void gen_neon_ldst_base_update(DisasContext *s, int rm, int rn,
82
+#endif
55
+ int stride)
83
diff --git a/hw/timer/sse-timer.c b/hw/timer/sse-timer.c
56
+{
84
new file mode 100644
57
+ if (rm != 15) {
85
index XXXXXXX..XXXXXXX
58
+ TCGv_i32 base;
86
--- /dev/null
59
+
87
+++ b/hw/timer/sse-timer.c
60
+ base = load_reg(s, rn);
88
@@ -XXX,XX +XXX,XX @@
61
+ if (rm == 13) {
89
+/*
62
+ tcg_gen_addi_i32(base, base, stride);
90
+ * Arm SSE Subsystem System Timer
63
+ } else {
91
+ *
64
+ TCGv_i32 index;
92
+ * Copyright (c) 2020 Linaro Limited
65
+ index = load_reg(s, rm);
93
+ * Written by Peter Maydell
66
+ tcg_gen_add_i32(base, base, index);
94
+ *
67
+ tcg_temp_free_i32(index);
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;
68
+ }
296
+ }
69
+ store_reg(s, rn, base);
297
+ sse_set_timer(s, s->cntp_aival);
70
+ }
298
+ sse_update_irq(s);
71
+}
299
+ } else {
72
+
300
+ sse_recalc_timer(s);
73
+static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
301
+ }
74
+{
302
+}
75
+ /* Neon load/store multiple structures */
303
+
76
+ int nregs, interleave, spacing, reg, n;
304
+static uint64_t sse_timer_read(void *opaque, hwaddr offset, unsigned size)
77
+ MemOp endian = s->be_data;
305
+{
78
+ int mmu_idx = get_mem_index(s);
306
+ SSETimer *s = SSE_TIMER(opaque);
79
+ int size = a->size;
307
+ uint64_t r;
80
+ TCGv_i64 tmp64;
308
+
81
+ TCGv_i32 addr, tmp;
309
+ switch (offset) {
82
+
310
+ case A_CNTPCT_LO:
83
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
311
+ r = extract64(sse_cntpct(s), 0, 32);
84
+ return false;
312
+ break;
85
+ }
313
+ case A_CNTPCT_HI:
86
+
314
+ r = extract64(sse_cntpct(s), 32, 32);
87
+ /* UNDEF accesses to D16-D31 if they don't exist */
315
+ break;
88
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
316
+ case A_CNTFRQ:
89
+ return false;
317
+ r = s->cntfrq;
90
+ }
318
+ break;
91
+ if (a->itype > 10) {
319
+ case A_CNTP_CVAL_LO:
92
+ return false;
320
+ r = extract64(s->cntp_cval, 0, 32);
93
+ }
321
+ break;
94
+ /* Catch UNDEF cases for bad values of align field */
322
+ case A_CNTP_CVAL_HI:
95
+ switch (a->itype & 0xc) {
323
+ r = extract64(s->cntp_cval, 32, 32);
96
+ case 4:
324
+ break;
97
+ if (a->align >= 2) {
325
+ case A_CNTP_TVAL:
98
+ return false;
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;
99
+ }
332
+ }
100
+ break;
333
+ break;
101
+ case 8:
334
+ case A_CNTP_AIVAL_LO:
102
+ if (a->align == 3) {
335
+ r = extract64(s->cntp_aival, 0, 32);
103
+ return false;
336
+ break;
104
+ }
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];
105
+ break;
355
+ break;
106
+ default:
356
+ default:
107
+ break;
357
+ qemu_log_mask(LOG_GUEST_ERROR,
108
+ }
358
+ "SSE System Timer read: bad offset 0x%x",
109
+ nregs = neon_ls_element_type[a->itype].nregs;
359
+ (unsigned) offset);
110
+ interleave = neon_ls_element_type[a->itype].interleave;
360
+ r = 0;
111
+ spacing = neon_ls_element_type[a->itype].spacing;
361
+ break;
112
+ if (size == 3 && (interleave | spacing) != 1) {
362
+ }
113
+ return false;
363
+
114
+ }
364
+ trace_sse_timer_read(offset, r, size);
115
+
365
+ return r;
116
+ if (!vfp_access_check(s)) {
366
+}
117
+ return true;
367
+
118
+ }
368
+static void sse_timer_write(void *opaque, hwaddr offset, uint64_t value,
119
+
369
+ unsigned size)
120
+ /* For our purposes, bytes are always little-endian. */
370
+{
121
+ if (size == 0) {
371
+ SSETimer *s = SSE_TIMER(opaque);
122
+ endian = MO_LE;
372
+
123
+ }
373
+ trace_sse_timer_write(offset, value, size);
124
+ /*
374
+
125
+ * Consecutive little-endian elements from a single register
375
+ switch (offset) {
126
+ * can be promoted to a larger little-endian operation.
376
+ case A_CNTFRQ:
127
+ */
377
+ s->cntfrq = value;
128
+ if (interleave == 1 && endian == MO_LE) {
378
+ break;
129
+ size = 3;
379
+ case A_CNTP_CVAL_LO:
130
+ }
380
+ s->cntp_cval = deposit64(s->cntp_cval, 0, 32, value);
131
+ tmp64 = tcg_temp_new_i64();
381
+ sse_recalc_timer(s);
132
+ addr = tcg_temp_new_i32();
382
+ break;
133
+ tmp = tcg_const_i32(1 << size);
383
+ case A_CNTP_CVAL_HI:
134
+ load_reg_var(s, addr, a->rn);
384
+ s->cntp_cval = deposit64(s->cntp_cval, 32, 32, value);
135
+ for (reg = 0; reg < nregs; reg++) {
385
+ sse_recalc_timer(s);
136
+ for (n = 0; n < 8 >> size; n++) {
386
+ break;
137
+ int xs;
387
+ case A_CNTP_TVAL:
138
+ for (xs = 0; xs < interleave; xs++) {
388
+ s->cntp_cval = sse_cntpct(s) + sextract64(value, 0, 32);
139
+ int tt = a->vd + reg + spacing * xs;
389
+ sse_recalc_timer(s);
140
+
390
+ break;
141
+ if (a->l) {
391
+ case A_CNTP_CTL:
142
+ gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
392
+ {
143
+ neon_store_element64(tt, n, size, tmp64);
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);
144
+ } else {
400
+ } else {
145
+ neon_load_element64(tmp64, tt, n, size);
401
+ sse_recalc_timer(s);
146
+ gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
147
+ }
402
+ }
148
+ tcg_gen_add_i32(addr, addr, tmp);
149
+ }
403
+ }
150
+ }
404
+ }
151
+ }
405
+ sse_update_irq(s);
152
+ tcg_temp_free_i32(addr);
406
+ break;
153
+ tcg_temp_free_i32(tmp);
407
+ }
154
+ tcg_temp_free_i64(tmp64);
408
+ case A_CNTP_AIVAL_RELOAD:
155
+
409
+ s->cntp_aival_reload = value;
156
+ gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
410
+ break;
157
+ return true;
411
+ case A_CNTP_AIVAL_CTL:
158
+}
412
+ {
159
diff --git a/target/arm/translate.c b/target/arm/translate.c
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
160
index XXXXXXX..XXXXXXX 100644
560
index XXXXXXX..XXXXXXX 100644
161
--- a/target/arm/translate.c
561
--- a/MAINTAINERS
162
+++ b/target/arm/translate.c
562
+++ b/MAINTAINERS
163
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
563
@@ -XXX,XX +XXX,XX @@ F: hw/misc/armsse-mhu.c
164
}
564
F: include/hw/misc/armsse-mhu.h
165
565
F: hw/timer/sse-counter.c
166
566
F: include/hw/timer/sse-counter.h
167
-static struct {
567
+F: hw/timer/sse-timer.c
168
- int nregs;
568
+F: include/hw/timer/sse-timer.h
169
- int interleave;
569
F: docs/system/arm/mps2.rst
170
- int spacing;
570
171
-} const neon_ls_element_type[11] = {
571
Musca
172
- {1, 4, 1},
572
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
173
- {1, 4, 2},
573
index XXXXXXX..XXXXXXX 100644
174
- {4, 1, 1},
574
--- a/hw/arm/Kconfig
175
- {2, 2, 2},
575
+++ b/hw/arm/Kconfig
176
- {1, 3, 1},
576
@@ -XXX,XX +XXX,XX @@ config ARMSSE
177
- {1, 3, 2},
577
select TZ_PPC
178
- {3, 1, 1},
578
select UNIMP
179
- {1, 1, 1},
579
select SSE_COUNTER
180
- {1, 2, 1},
580
+ select SSE_TIMER
181
- {1, 2, 2},
581
182
- {2, 1, 1}
582
config ARMSSE_CPUID
183
-};
583
bool
184
-
584
diff --git a/hw/timer/Kconfig b/hw/timer/Kconfig
185
/* Translate a NEON load/store element instruction. Return nonzero if the
585
index XXXXXXX..XXXXXXX 100644
186
instruction is invalid. */
586
--- a/hw/timer/Kconfig
187
static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
587
+++ b/hw/timer/Kconfig
188
{
588
@@ -XXX,XX +XXX,XX @@ config RENESAS_CMT
189
int rd, rn, rm;
589
config SSE_COUNTER
190
- int op;
590
bool
191
int nregs;
591
192
- int interleave;
592
+config SSE_TIMER
193
- int spacing;
593
+ bool
194
int stride;
594
+
195
int size;
595
config AVR_TIMER16
196
int reg;
596
bool
197
int load;
597
diff --git a/hw/timer/meson.build b/hw/timer/meson.build
198
- int n;
598
index XXXXXXX..XXXXXXX 100644
199
int vec_size;
599
--- a/hw/timer/meson.build
200
- int mmu_idx;
600
+++ b/hw/timer/meson.build
201
- MemOp endian;
601
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_systmr.c'))
202
TCGv_i32 addr;
602
softmmu_ss.add(when: 'CONFIG_SH4', if_true: files('sh_timer.c'))
203
TCGv_i32 tmp;
603
softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_timer.c'))
204
- TCGv_i32 tmp2;
604
softmmu_ss.add(when: 'CONFIG_SSE_COUNTER', if_true: files('sse-counter.c'))
205
- TCGv_i64 tmp64;
605
+softmmu_ss.add(when: 'CONFIG_SSE_TIMER', if_true: files('sse-timer.c'))
206
606
softmmu_ss.add(when: 'CONFIG_STM32F2XX_TIMER', if_true: files('stm32f2xx_timer.c'))
207
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
607
softmmu_ss.add(when: 'CONFIG_XILINX', if_true: files('xilinx_timer.c'))
208
return 1;
608
209
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
609
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
210
rn = (insn >> 16) & 0xf;
610
index XXXXXXX..XXXXXXX 100644
211
rm = insn & 0xf;
611
--- a/hw/timer/trace-events
212
load = (insn & (1 << 21)) != 0;
612
+++ b/hw/timer/trace-events
213
- endian = s->be_data;
613
@@ -XXX,XX +XXX,XX @@ sse_counter_control_write(uint64_t offset, uint64_t data, unsigned size) "SSE sy
214
- mmu_idx = get_mem_index(s);
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"
215
if ((insn & (1 << 23)) == 0) {
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"
216
- /* Load store all elements. */
616
sse_counter_reset(void) "SSE system counter: reset"
217
- op = (insn >> 8) & 0xf;
617
+
218
- size = (insn >> 6) & 3;
618
+# sse_timer.c
219
- if (op > 10)
619
+sse_timer_read(uint64_t offset, uint64_t data, unsigned size) "SSE system timer read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
220
- return 1;
620
+sse_timer_write(uint64_t offset, uint64_t data, unsigned size) "SSE system timer write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
221
- /* Catch UNDEF cases for bad values of align field */
621
+sse_timer_reset(void) "SSE system timer: reset"
222
- switch (op & 0xc) {
223
- case 4:
224
- if (((insn >> 5) & 1) == 1) {
225
- return 1;
226
- }
227
- break;
228
- case 8:
229
- if (((insn >> 4) & 3) == 3) {
230
- return 1;
231
- }
232
- break;
233
- default:
234
- break;
235
- }
236
- nregs = neon_ls_element_type[op].nregs;
237
- interleave = neon_ls_element_type[op].interleave;
238
- spacing = neon_ls_element_type[op].spacing;
239
- if (size == 3 && (interleave | spacing) != 1) {
240
- return 1;
241
- }
242
- /* For our purposes, bytes are always little-endian. */
243
- if (size == 0) {
244
- endian = MO_LE;
245
- }
246
- /* Consecutive little-endian elements from a single register
247
- * can be promoted to a larger little-endian operation.
248
- */
249
- if (interleave == 1 && endian == MO_LE) {
250
- size = 3;
251
- }
252
- tmp64 = tcg_temp_new_i64();
253
- addr = tcg_temp_new_i32();
254
- tmp2 = tcg_const_i32(1 << size);
255
- load_reg_var(s, addr, rn);
256
- for (reg = 0; reg < nregs; reg++) {
257
- for (n = 0; n < 8 >> size; n++) {
258
- int xs;
259
- for (xs = 0; xs < interleave; xs++) {
260
- int tt = rd + reg + spacing * xs;
261
-
262
- if (load) {
263
- gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
264
- neon_store_element64(tt, n, size, tmp64);
265
- } else {
266
- neon_load_element64(tmp64, tt, n, size);
267
- gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
268
- }
269
- tcg_gen_add_i32(addr, addr, tmp2);
270
- }
271
- }
272
- }
273
- tcg_temp_free_i32(addr);
274
- tcg_temp_free_i32(tmp2);
275
- tcg_temp_free_i64(tmp64);
276
- stride = nregs * interleave * 8;
277
+ /* Load store all elements -- handled already by decodetree */
278
+ return 1;
279
} else {
280
size = (insn >> 10) & 3;
281
if (size == 3) {
282
--
622
--
283
2.20.1
623
2.20.1
284
624
285
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
1
Convert the Neon comparison ops in the 3-reg-same grouping
1
In the SSE-300 the CPU_WAIT and NMI_ENABLE registers have
2
to decodetree.
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:
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.
3
15
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-18-peter.maydell@linaro.org
19
Message-id: 20210219144617.4782-15-peter.maydell@linaro.org
7
---
20
---
8
target/arm/neon-dp.decode | 8 ++++++++
21
hw/misc/iotkit-sysctl.c | 88 +++++++++++++++++++++++++++++++++++------
9
target/arm/translate-neon.inc.c | 22 ++++++++++++++++++++++
22
1 file changed, 76 insertions(+), 12 deletions(-)
10
target/arm/translate.c | 23 +++--------------------
11
3 files changed, 33 insertions(+), 20 deletions(-)
12
23
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
24
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
14
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
26
--- a/hw/misc/iotkit-sysctl.c
16
+++ b/target/arm/neon-dp.decode
27
+++ b/hw/misc/iotkit-sysctl.c
17
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
28
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
18
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
29
}
19
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
30
break;
20
31
case A_CPUWAIT:
21
+VCGT_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 0 .... @3same
32
- r = s->cpuwait;
22
+VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
33
+ switch (s->sse_version) {
23
+VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
34
+ case ARMSSE_IOTKIT:
24
+VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
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;
25
+
94
+
26
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
95
+ for (i = 0; i < num_cpus; i++) {
27
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
96
+ uint32_t mask = 1 << i;
28
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
97
+ if ((s->cpuwait & mask) && !(value & mask)) {
29
@@ -XXX,XX +XXX,XX @@ VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
98
+ /* Powering up CPU 0 */
30
99
+ arm_set_cpu_on_and_reset(i);
31
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
100
+ }
32
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
101
+ }
102
+ s->cpuwait = value;
103
+}
33
+
104
+
34
+VTST_3s 1111 001 0 0 . .. .... .... 1000 . . . 1 .... @3same
105
static void iotkit_sysctl_write(void *opaque, hwaddr offset,
35
+VCEQ_3s 1111 001 1 0 . .. .... .... 1000 . . . 1 .... @3same
106
uint64_t value, unsigned size)
36
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
107
{
37
index XXXXXXX..XXXXXXX 100644
108
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
38
--- a/target/arm/translate-neon.inc.c
109
set_init_vtor(0, s->initsvtor0);
39
+++ b/target/arm/translate-neon.inc.c
110
break;
40
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
111
case A_CPUWAIT:
41
DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
112
- if ((s->cpuwait & 1) && !(value & 1)) {
42
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
113
- /* Powering up CPU 0 */
43
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
114
- arm_set_cpu_on_and_reset(0);
44
+
115
+ switch (s->sse_version) {
45
+#define DO_3SAME_CMP(INSN, COND) \
116
+ case ARMSSE_IOTKIT:
46
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
117
+ case ARMSSE_SSE200:
47
+ uint32_t rn_ofs, uint32_t rm_ofs, \
118
+ cpuwait_write(s, value);
48
+ uint32_t oprsz, uint32_t maxsz) \
119
+ break;
49
+ { \
120
+ case ARMSSE_SSE300:
50
+ tcg_gen_gvec_cmp(COND, vece, rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz); \
121
+ /* In SSE300 this is reserved (for INITSVTOR2) */
51
+ } \
122
+ goto bad_offset;
52
+ DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
123
+ default:
53
+
124
+ g_assert_not_reached();
54
+DO_3SAME_CMP(VCGT_S, TCG_COND_GT)
125
}
55
+DO_3SAME_CMP(VCGT_U, TCG_COND_GTU)
126
- if ((s->cpuwait & 2) && !(value & 2)) {
56
+DO_3SAME_CMP(VCGE_S, TCG_COND_GE)
127
- /* Powering up CPU 1 */
57
+DO_3SAME_CMP(VCGE_U, TCG_COND_GEU)
128
- arm_set_cpu_on_and_reset(1);
58
+DO_3SAME_CMP(VCEQ, TCG_COND_EQ)
129
- }
59
+
130
- s->cpuwait = value;
60
+static void gen_VTST_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
131
break;
61
+ uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
132
case A_WICCTRL:
62
+{
133
- qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl WICCTRL unimplemented\n");
63
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &cmtst_op[vece]);
134
- s->wicctrl = value;
64
+}
135
+ switch (s->sse_version) {
65
+DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
136
+ case ARMSSE_IOTKIT:
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
137
+ case ARMSSE_SSE200:
67
index XXXXXXX..XXXXXXX 100644
138
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl WICCTRL unimplemented\n");
68
--- a/target/arm/translate.c
139
+ s->wicctrl = value;
69
+++ b/target/arm/translate.c
140
+ break;
70
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
141
+ case ARMSSE_SSE300:
71
u ? &mls_op[size] : &mla_op[size]);
142
+ /* In SSE300 this offset is CPUWAIT */
72
return 0;
143
+ cpuwait_write(s, value);
73
144
+ break;
74
- case NEON_3R_VTST_VCEQ:
145
+ default:
75
- if (u) { /* VCEQ */
146
+ g_assert_not_reached();
76
- tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
147
+ }
77
- vec_size, vec_size);
148
break;
78
- } else { /* VTST */
149
case A_SECDBGSET:
79
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
150
/* write-1-to-set */
80
- vec_size, vec_size, &cmtst_op[size]);
151
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
81
- }
152
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl EWCTRL unimplemented\n");
82
- return 0;
153
s->ewctrl = value;
83
-
154
break;
84
- case NEON_3R_VCGT:
155
+ case ARMSSE_SSE300:
85
- tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
156
+ /* In SSE300 this offset is is NMI_ENABLE */
86
- rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
157
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
87
- return 0;
158
+ s->nmi_enable = value;
88
-
159
+ break;
89
- case NEON_3R_VCGE:
160
default:
90
- tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
161
g_assert_not_reached();
91
- rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
162
}
92
- return 0;
163
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
93
-
164
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
94
case NEON_3R_VSHL:
165
s->nmi_enable = value;
95
/* Note the operation is vshl vd,vm,vn */
166
break;
96
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
167
+ case ARMSSE_SSE300:
97
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
168
+ /* In SSE300 this is reserved (for INITSVTOR3) */
98
case NEON_3R_LOGIC:
169
+ goto bad_offset;
99
case NEON_3R_VMAX:
170
default:
100
case NEON_3R_VMIN:
171
g_assert_not_reached();
101
+ case NEON_3R_VTST_VCEQ:
102
+ case NEON_3R_VCGT:
103
+ case NEON_3R_VCGE:
104
/* Already handled by decodetree */
105
return 1;
106
}
172
}
107
--
173
--
108
2.20.1
174
2.20.1
109
175
110
176
diff view generated by jsdifflib
1
Convert the Neon VQADD/VQSUB insns in the 3-reg-same grouping
1
The SSE-300 has only one CPU and so no INITSVTOR1. It does
2
to decodetree.
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.
3
5
4
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>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-19-peter.maydell@linaro.org
9
Message-id: 20210219144617.4782-16-peter.maydell@linaro.org
7
---
10
---
8
target/arm/neon-dp.decode | 6 ++++++
11
hw/misc/iotkit-sysctl.c | 27 +++++++++++++++++++++++++--
9
target/arm/translate-neon.inc.c | 15 +++++++++++++++
12
1 file changed, 25 insertions(+), 2 deletions(-)
10
target/arm/translate.c | 14 ++------------
11
3 files changed, 23 insertions(+), 12 deletions(-)
12
13
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
16
--- a/hw/misc/iotkit-sysctl.c
16
+++ b/target/arm/neon-dp.decode
17
+++ b/hw/misc/iotkit-sysctl.c
17
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ REG32(SWRESET, 0x108)
18
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
19
FIELD(SWRESET, SWRESETREQ, 9, 1)
19
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
20
REG32(GRETREG, 0x10c)
20
21
REG32(INITSVTOR0, 0x110)
21
+VQADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 1 .... @3same
22
+ FIELD(INITSVTOR0, LOCK, 0, 1)
22
+VQADD_U_3s 1111 001 1 0 . .. .... .... 0000 . . . 1 .... @3same
23
+ FIELD(INITSVTOR0, VTOR, 7, 25)
23
+
24
REG32(INITSVTOR1, 0x114)
24
@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
25
REG32(CPUWAIT, 0x118)
25
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0
26
REG32(NMI_ENABLE, 0x11c) /* BUSWAIT in IoTKit */
26
27
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
27
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
28
case ARMSSE_SSE200:
28
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
29
r = s->initsvtor1;
29
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
30
break;
30
31
+ case ARMSSE_SSE300:
31
+VQSUB_S_3s 1111 001 0 0 . .. .... .... 0010 . . . 1 .... @3same
32
+ goto bad_offset;
32
+VQSUB_U_3s 1111 001 1 0 . .. .... .... 0010 . . . 1 .... @3same
33
default:
33
+
34
g_assert_not_reached();
34
VCGT_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 0 .... @3same
35
}
35
VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
36
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
36
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
37
s->gretreg = value;
37
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
38
break;
38
index XXXXXXX..XXXXXXX 100644
39
case A_INITSVTOR0:
39
--- a/target/arm/translate-neon.inc.c
40
- s->initsvtor0 = value;
40
+++ b/target/arm/translate-neon.inc.c
41
- set_init_vtor(0, s->initsvtor0);
41
@@ -XXX,XX +XXX,XX @@ static void gen_VTST_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
42
+ switch (s->sse_version) {
42
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &cmtst_op[vece]);
43
+ case ARMSSE_SSE300:
43
}
44
+ /* SSE300 has a LOCK bit which prevents further writes when set */
44
DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
45
+ if (s->initsvtor0 & R_INITSVTOR0_LOCK_MASK) {
45
+
46
+ qemu_log_mask(LOG_GUEST_ERROR,
46
+#define DO_3SAME_GVEC4(INSN, OPARRAY) \
47
+ "IoTKit INITSVTOR0 write when register locked\n");
47
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
48
+ break;
48
+ uint32_t rn_ofs, uint32_t rm_ofs, \
49
+ }
49
+ uint32_t oprsz, uint32_t maxsz) \
50
+ s->initsvtor0 = value;
50
+ { \
51
+ set_init_vtor(0, s->initsvtor0 & R_INITSVTOR0_VTOR_MASK);
51
+ tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc), \
52
+ break;
52
+ rn_ofs, rm_ofs, oprsz, maxsz, &OPARRAY[vece]); \
53
+ case ARMSSE_IOTKIT:
53
+ } \
54
+ case ARMSSE_SSE200:
54
+ DO_3SAME(INSN, gen_##INSN##_3s)
55
+ s->initsvtor0 = value;
55
+
56
+ set_init_vtor(0, s->initsvtor0);
56
+DO_3SAME_GVEC4(VQADD_S, sqadd_op)
57
+ break;
57
+DO_3SAME_GVEC4(VQADD_U, uqadd_op)
58
+ default:
58
+DO_3SAME_GVEC4(VQSUB_S, sqsub_op)
59
+ g_assert_not_reached();
59
+DO_3SAME_GVEC4(VQSUB_U, uqsub_op)
60
+ }
60
diff --git a/target/arm/translate.c b/target/arm/translate.c
61
break;
61
index XXXXXXX..XXXXXXX 100644
62
case A_CPUWAIT:
62
--- a/target/arm/translate.c
63
switch (s->sse_version) {
63
+++ b/target/arm/translate.c
64
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
64
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
65
s->initsvtor1 = value;
65
}
66
set_init_vtor(1, s->initsvtor1);
66
return 1;
67
break;
67
68
+ case ARMSSE_SSE300:
68
- case NEON_3R_VQADD:
69
+ goto bad_offset;
69
- tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
70
default:
70
- rn_ofs, rm_ofs, vec_size, vec_size,
71
g_assert_not_reached();
71
- (u ? uqadd_op : sqadd_op) + size);
72
- return 0;
73
-
74
- case NEON_3R_VQSUB:
75
- tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
76
- rn_ofs, rm_ofs, vec_size, vec_size,
77
- (u ? uqsub_op : sqsub_op) + size);
78
- return 0;
79
-
80
case NEON_3R_VMUL: /* VMUL */
81
if (u) {
82
/* Polynomial case allows only P8. */
83
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
84
case NEON_3R_VTST_VCEQ:
85
case NEON_3R_VCGT:
86
case NEON_3R_VCGE:
87
+ case NEON_3R_VQADD:
88
+ case NEON_3R_VQSUB:
89
/* Already handled by decodetree */
90
return 1;
91
}
72
}
92
--
73
--
93
2.20.1
74
2.20.1
94
75
95
76
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
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.
2
8
3
Add support for the RTC.
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(+)
4
17
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
18
diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Message-id: 20200427181649.26851-12-edgar.iglesias@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/arm/xlnx-versal-virt.c | 22 ++++++++++++++++++++++
12
1 file changed, 22 insertions(+)
13
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/xlnx-versal-virt.c
20
--- a/include/hw/misc/iotkit-sysctl.h
17
+++ b/hw/arm/xlnx-versal-virt.c
21
+++ b/include/hw/misc/iotkit-sysctl.h
18
@@ -XXX,XX +XXX,XX @@ static void fdt_add_sd_nodes(VersalVirt *s)
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)
19
}
96
}
20
}
97
}
21
98
22
+static void fdt_add_rtc_node(VersalVirt *s)
99
+static bool sse300_needed(void *opaque)
23
+{
100
+{
24
+ const char compat[] = "xlnx,zynqmp-rtc";
101
+ IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
25
+ const char interrupt_names[] = "alarm\0sec";
26
+ char *name = g_strdup_printf("/rtc@%x", MM_PMC_RTC);
27
+
102
+
28
+ qemu_fdt_add_subnode(s->fdt, name);
103
+ return s->sse_version == ARMSSE_SSE300;
29
+
30
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
31
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_RTC_ALARM_IRQ,
32
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI,
33
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_RTC_SECONDS_IRQ,
34
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
35
+ qemu_fdt_setprop(s->fdt, name, "interrupt-names",
36
+ interrupt_names, sizeof(interrupt_names));
37
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
38
+ 2, MM_PMC_RTC, 2, MM_PMC_RTC_SIZE);
39
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
40
+ g_free(name);
41
+}
104
+}
42
+
105
+
43
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
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)
44
{
118
{
45
Error *err = NULL;
119
IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
46
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
120
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription iotkit_sysctl_vmstate = {
47
fdt_add_timer_nodes(s);
121
},
48
fdt_add_zdma_nodes(s);
122
.subsections = (const VMStateDescription*[]) {
49
fdt_add_sd_nodes(s);
123
&iotkit_sysctl_sse200_vmstate,
50
+ fdt_add_rtc_node(s);
124
+ &iotkit_sysctl_sse300_vmstate,
51
fdt_add_cpu_nodes(s, psci_conduit);
125
NULL
52
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
126
}
53
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
127
};
54
--
128
--
55
2.20.1
129
2.20.1
56
130
57
131
diff view generated by jsdifflib
1
Convert the Neon "load/store single structure to one lane" insns to
1
The sysctl PDCM_PD_*_SENSE registers control various power domains in
2
decodetree.
2
the system and allow the guest to configure which conditions keep a
3
3
power domain awake and what power state to use when the domain is in
4
As this is the last set of insns in the neon load/store group,
4
a low power state. QEMU doesn't model power domains, so for us these
5
we can remove the whole disas_neon_ls_insn() function.
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.)
6
25
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
28
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200430181003.21682-14-peter.maydell@linaro.org
29
Message-id: 20210219144617.4782-18-peter.maydell@linaro.org
10
---
30
---
11
target/arm/neon-ls.decode | 11 +++
31
include/hw/misc/iotkit-sysctl.h | 3 ++
12
target/arm/translate-neon.inc.c | 89 +++++++++++++++++++
32
hw/misc/iotkit-sysctl.c | 61 +++++++++++++++++++++++++++++++--
13
target/arm/translate.c | 147 --------------------------------
33
2 files changed, 62 insertions(+), 2 deletions(-)
14
3 files changed, 100 insertions(+), 147 deletions(-)
34
15
35
diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
16
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
17
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/neon-ls.decode
37
--- a/include/hw/misc/iotkit-sysctl.h
19
+++ b/target/arm/neon-ls.decode
38
+++ b/include/hw/misc/iotkit-sysctl.h
20
@@ -XXX,XX +XXX,XX @@ VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
39
@@ -XXX,XX +XXX,XX @@ struct IoTKitSysCtl {
21
40
uint32_t pdcm_pd_sram1_sense;
22
VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
41
uint32_t pdcm_pd_sram2_sense;
23
vd=%vd_dp
42
uint32_t pdcm_pd_sram3_sense;
24
+
43
+ uint32_t pdcm_pd_cpu0_sense;
25
+# Neon load/store single structure to one lane
44
+ uint32_t pdcm_pd_vmr0_sense;
26
+%imm1_5_p1 5:1 !function=plus1
45
+ uint32_t pdcm_pd_vmr1_sense;
27
+%imm1_6_p1 6:1 !function=plus1
46
28
+
47
/* Properties */
29
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 00 n:2 reg_idx:3 align:1 rm:4 \
48
uint32_t sse_version;
30
+ vd=%vd_dp size=0 stride=1
49
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
31
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 01 n:2 reg_idx:2 align:2 rm:4 \
32
+ vd=%vd_dp size=1 stride=%imm1_5_p1
33
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 10 n:2 reg_idx:1 align:3 rm:4 \
34
+ vd=%vd_dp size=2 stride=%imm1_6_p1
35
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
36
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/translate-neon.inc.c
51
--- a/hw/misc/iotkit-sysctl.c
38
+++ b/target/arm/translate-neon.inc.c
52
+++ b/hw/misc/iotkit-sysctl.c
39
@@ -XXX,XX +XXX,XX @@
53
@@ -XXX,XX +XXX,XX @@ REG32(PWRCTRL, 0x1fc)
40
* It might be possible to convert it to a standalone .c file eventually.
54
FIELD(PWRCTRL, PPU_ACCESS_UNLOCK, 0, 1)
41
*/
55
FIELD(PWRCTRL, PPU_ACCESS_FILTER, 1, 1)
42
56
REG32(PDCM_PD_SYS_SENSE, 0x200)
43
+static inline int plus1(DisasContext *s, int x)
57
+REG32(PDCM_PD_CPU0_SENSE, 0x204)
44
+{
58
REG32(PDCM_PD_SRAM0_SENSE, 0x20c)
45
+ return x + 1;
59
REG32(PDCM_PD_SRAM1_SENSE, 0x210)
46
+}
60
-REG32(PDCM_PD_SRAM2_SENSE, 0x214)
47
+
61
-REG32(PDCM_PD_SRAM3_SENSE, 0x218)
48
/* Include the generated Neon decoder */
62
+REG32(PDCM_PD_SRAM2_SENSE, 0x214) /* PDCM_PD_VMR0_SENSE on SSE300 */
49
#include "decode-neon-dp.inc.c"
63
+REG32(PDCM_PD_SRAM3_SENSE, 0x218) /* PDCM_PD_VMR1_SENSE on SSE300 */
50
#include "decode-neon-ls.inc.c"
64
REG32(PID4, 0xfd0)
51
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
65
REG32(PID5, 0xfd4)
52
66
REG32(PID6, 0xfd8)
53
return true;
67
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
54
}
68
g_assert_not_reached();
55
+
69
}
56
+static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
70
break;
57
+{
71
+ case A_PDCM_PD_CPU0_SENSE:
58
+ /* Neon load/store single structure to one lane */
72
+ switch (s->sse_version) {
59
+ int reg;
73
+ case ARMSSE_IOTKIT:
60
+ int nregs = a->n + 1;
74
+ case ARMSSE_SSE200:
61
+ int vd = a->vd;
75
+ goto bad_offset;
62
+ TCGv_i32 addr, tmp;
76
+ case ARMSSE_SSE300:
63
+
77
+ r = s->pdcm_pd_cpu0_sense;
64
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
78
+ break;
65
+ return false;
79
+ default:
66
+ }
80
+ g_assert_not_reached();
67
+
68
+ /* UNDEF accesses to D16-D31 if they don't exist */
69
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
70
+ return false;
71
+ }
72
+
73
+ /* Catch the UNDEF cases. This is unavoidably a bit messy. */
74
+ switch (nregs) {
75
+ case 1:
76
+ if (((a->align & (1 << a->size)) != 0) ||
77
+ (a->size == 2 && ((a->align & 3) == 1 || (a->align & 3) == 2))) {
78
+ return false;
79
+ }
81
+ }
80
+ break;
82
+ break;
81
+ case 3:
83
case A_PDCM_PD_SRAM0_SENSE:
82
+ if ((a->align & 1) != 0) {
84
switch (s->sse_version) {
83
+ return false;
85
case ARMSSE_IOTKIT:
84
+ }
86
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
85
+ /* fall through */
87
case ARMSSE_SSE200:
86
+ case 2:
88
r = s->pdcm_pd_sram0_sense;
87
+ if (a->size == 2 && (a->align & 2) != 0) {
89
break;
88
+ return false;
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();
89
+ }
140
+ }
90
+ break;
141
+ break;
91
+ case 4:
142
case A_PDCM_PD_SRAM0_SENSE:
92
+ if ((a->size == 2) && ((a->align & 3) == 3)) {
143
switch (s->sse_version) {
93
+ return false;
144
case ARMSSE_IOTKIT:
94
+ }
145
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
95
+ break;
146
"IoTKit SysCtl PDCM_PD_SRAM0_SENSE unimplemented\n");
96
+ default:
147
s->pdcm_pd_sram0_sense = value;
97
+ abort();
148
break;
98
+ }
149
+ case ARMSSE_SSE300:
99
+ if ((vd + a->stride * (nregs - 1)) > 31) {
150
+ goto bad_offset;
100
+ /*
151
default:
101
+ * Attempts to write off the end of the register file are
152
g_assert_not_reached();
102
+ * UNPREDICTABLE; we choose to UNDEF because otherwise we would
153
}
103
+ * access off the end of the array that holds the register data.
154
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
104
+ */
155
"IoTKit SysCtl PDCM_PD_SRAM1_SENSE unimplemented\n");
105
+ return false;
156
s->pdcm_pd_sram1_sense = value;
106
+ }
157
break;
107
+
158
+ case ARMSSE_SSE300:
108
+ if (!vfp_access_check(s)) {
159
+ goto bad_offset;
109
+ return true;
160
default:
110
+ }
161
g_assert_not_reached();
111
+
162
}
112
+ tmp = tcg_temp_new_i32();
163
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
113
+ addr = tcg_temp_new_i32();
164
"IoTKit SysCtl PDCM_PD_SRAM2_SENSE unimplemented\n");
114
+ load_reg_var(s, addr, a->rn);
165
s->pdcm_pd_sram2_sense = value;
115
+ /*
166
break;
116
+ * TODO: if we implemented alignment exceptions, we should check
167
+ case ARMSSE_SSE300:
117
+ * addr against the alignment encoded in a->align here.
168
+ qemu_log_mask(LOG_UNIMP,
118
+ */
169
+ "IoTKit SysCtl PDCM_PD_VMR0_SENSE unimplemented\n");
119
+ for (reg = 0; reg < nregs; reg++) {
170
+ s->pdcm_pd_vmr0_sense = value;
120
+ if (a->l) {
171
+ break;
121
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
172
default:
122
+ s->be_data | a->size);
173
g_assert_not_reached();
123
+ neon_store_element(vd, a->reg_idx, a->size, tmp);
174
}
124
+ } else { /* Store */
175
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
125
+ neon_load_element(tmp, vd, a->reg_idx, a->size);
176
"IoTKit SysCtl PDCM_PD_SRAM3_SENSE unimplemented\n");
126
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
177
s->pdcm_pd_sram3_sense = value;
127
+ s->be_data | a->size);
178
break;
128
+ }
179
+ case ARMSSE_SSE300:
129
+ vd += a->stride;
180
+ qemu_log_mask(LOG_UNIMP,
130
+ tcg_gen_addi_i32(addr, addr, 1 << a->size);
181
+ "IoTKit SysCtl PDCM_PD_VMR1_SENSE unimplemented\n");
131
+ }
182
+ s->pdcm_pd_vmr1_sense = value;
132
+ tcg_temp_free_i32(addr);
183
+ break;
133
+ tcg_temp_free_i32(tmp);
184
default:
134
+
185
g_assert_not_reached();
135
+ gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << a->size) * nregs);
186
}
136
+
187
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_reset(DeviceState *dev)
137
+ return true;
188
s->pdcm_pd_sram1_sense = 0;
138
+}
189
s->pdcm_pd_sram2_sense = 0;
139
diff --git a/target/arm/translate.c b/target/arm/translate.c
190
s->pdcm_pd_sram3_sense = 0;
140
index XXXXXXX..XXXXXXX 100644
191
+ s->pdcm_pd_cpu0_sense = 0;
141
--- a/target/arm/translate.c
192
+ s->pdcm_pd_vmr0_sense = 0;
142
+++ b/target/arm/translate.c
193
+ s->pdcm_pd_vmr1_sense = 0;
143
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
144
tcg_temp_free_i32(rd);
145
}
194
}
146
195
147
-
196
static void iotkit_sysctl_init(Object *obj)
148
-/* Translate a NEON load/store element instruction. Return nonzero if the
197
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription iotkit_sysctl_sse300_vmstate = {
149
- instruction is invalid. */
198
.needed = sse300_needed,
150
-static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
199
.fields = (VMStateField[]) {
151
-{
200
VMSTATE_UINT32(pwrctrl, IoTKitSysCtl),
152
- int rd, rn, rm;
201
+ VMSTATE_UINT32(pdcm_pd_cpu0_sense, IoTKitSysCtl),
153
- int nregs;
202
+ VMSTATE_UINT32(pdcm_pd_vmr0_sense, IoTKitSysCtl),
154
- int stride;
203
+ VMSTATE_UINT32(pdcm_pd_vmr1_sense, IoTKitSysCtl),
155
- int size;
204
VMSTATE_END_OF_LIST()
156
- int reg;
205
}
157
- int load;
206
};
158
- TCGv_i32 addr;
159
- TCGv_i32 tmp;
160
-
161
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
162
- return 1;
163
- }
164
-
165
- /* FIXME: this access check should not take precedence over UNDEF
166
- * for invalid encodings; we will generate incorrect syndrome information
167
- * for attempts to execute invalid vfp/neon encodings with FP disabled.
168
- */
169
- if (s->fp_excp_el) {
170
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
171
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
172
- return 0;
173
- }
174
-
175
- if (!s->vfp_enabled)
176
- return 1;
177
- VFP_DREG_D(rd, insn);
178
- rn = (insn >> 16) & 0xf;
179
- rm = insn & 0xf;
180
- load = (insn & (1 << 21)) != 0;
181
- if ((insn & (1 << 23)) == 0) {
182
- /* Load store all elements -- handled already by decodetree */
183
- return 1;
184
- } else {
185
- size = (insn >> 10) & 3;
186
- if (size == 3) {
187
- /* Load single element to all lanes -- handled by decodetree */
188
- return 1;
189
- } else {
190
- /* Single element. */
191
- int idx = (insn >> 4) & 0xf;
192
- int reg_idx;
193
- switch (size) {
194
- case 0:
195
- reg_idx = (insn >> 5) & 7;
196
- stride = 1;
197
- break;
198
- case 1:
199
- reg_idx = (insn >> 6) & 3;
200
- stride = (insn & (1 << 5)) ? 2 : 1;
201
- break;
202
- case 2:
203
- reg_idx = (insn >> 7) & 1;
204
- stride = (insn & (1 << 6)) ? 2 : 1;
205
- break;
206
- default:
207
- abort();
208
- }
209
- nregs = ((insn >> 8) & 3) + 1;
210
- /* Catch the UNDEF cases. This is unavoidably a bit messy. */
211
- switch (nregs) {
212
- case 1:
213
- if (((idx & (1 << size)) != 0) ||
214
- (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
215
- return 1;
216
- }
217
- break;
218
- case 3:
219
- if ((idx & 1) != 0) {
220
- return 1;
221
- }
222
- /* fall through */
223
- case 2:
224
- if (size == 2 && (idx & 2) != 0) {
225
- return 1;
226
- }
227
- break;
228
- case 4:
229
- if ((size == 2) && ((idx & 3) == 3)) {
230
- return 1;
231
- }
232
- break;
233
- default:
234
- abort();
235
- }
236
- if ((rd + stride * (nregs - 1)) > 31) {
237
- /* Attempts to write off the end of the register file
238
- * are UNPREDICTABLE; we choose to UNDEF because otherwise
239
- * the neon_load_reg() would write off the end of the array.
240
- */
241
- return 1;
242
- }
243
- tmp = tcg_temp_new_i32();
244
- addr = tcg_temp_new_i32();
245
- load_reg_var(s, addr, rn);
246
- for (reg = 0; reg < nregs; reg++) {
247
- if (load) {
248
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
249
- s->be_data | size);
250
- neon_store_element(rd, reg_idx, size, tmp);
251
- } else { /* Store */
252
- neon_load_element(tmp, rd, reg_idx, size);
253
- gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
254
- s->be_data | size);
255
- }
256
- rd += stride;
257
- tcg_gen_addi_i32(addr, addr, 1 << size);
258
- }
259
- tcg_temp_free_i32(addr);
260
- tcg_temp_free_i32(tmp);
261
- stride = nregs * (1 << size);
262
- }
263
- }
264
- if (rm != 15) {
265
- TCGv_i32 base;
266
-
267
- base = load_reg(s, rn);
268
- if (rm == 13) {
269
- tcg_gen_addi_i32(base, base, stride);
270
- } else {
271
- TCGv_i32 index;
272
- index = load_reg(s, rm);
273
- tcg_gen_add_i32(base, base, index);
274
- tcg_temp_free_i32(index);
275
- }
276
- store_reg(s, rn, base);
277
- }
278
- return 0;
279
-}
280
-
281
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
282
{
283
switch (size) {
284
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
285
}
286
return;
287
}
288
- if ((insn & 0x0f100000) == 0x04000000) {
289
- /* NEON load/store. */
290
- if (disas_neon_ls_insn(s, insn)) {
291
- goto illegal_op;
292
- }
293
- return;
294
- }
295
if ((insn & 0x0e000f00) == 0x0c000100) {
296
if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
297
/* iWMMXt register transfer. */
298
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
299
}
300
break;
301
case 12:
302
- if ((insn & 0x01100000) == 0x01000000) {
303
- if (disas_neon_ls_insn(s, insn)) {
304
- goto illegal_op;
305
- }
306
- break;
307
- }
308
goto illegal_op;
309
default:
310
illegal_op:
311
--
207
--
312
2.20.1
208
2.20.1
313
209
314
210
diff view generated by jsdifflib
1
The ARMv8.2-TTS2UXN feature extends the XN field in stage 2
1
The SSE-200 and SSE-300 have different PID register values from the
2
translation table descriptors from just bit [54] to bits [54:53],
2
IoTKit for the sysctl register block. We incorrectly implemented the
3
allowing stage 2 to control execution permissions separately for EL0
3
SSE-200 with the same PID values as IoTKit. Fix the SSE-200 bug and
4
and EL1. Implement the new semantics of the XN field and enable
4
report these register values for SSE-300.
5
the feature for our 'max' CPU.
6
5
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20200330210400.11724-5-peter.maydell@linaro.org
9
Message-id: 20210219144617.4782-19-peter.maydell@linaro.org
11
---
10
---
12
target/arm/cpu.h | 15 +++++++++++++++
11
hw/misc/iotkit-sysctl.c | 21 +++++++++++++++++++--
13
target/arm/cpu.c | 1 +
12
1 file changed, 19 insertions(+), 2 deletions(-)
14
target/arm/cpu64.c | 2 ++
15
target/arm/helper.c | 37 +++++++++++++++++++++++++++++++------
16
4 files changed, 49 insertions(+), 6 deletions(-)
17
13
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
16
--- a/hw/misc/iotkit-sysctl.c
21
+++ b/target/arm/cpu.h
17
+++ b/hw/misc/iotkit-sysctl.c
22
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_ccidx(const ARMISARegisters *id)
18
@@ -XXX,XX +XXX,XX @@ REG32(CID2, 0xff8)
23
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, CCIDX) != 0;
19
REG32(CID3, 0xffc)
24
}
20
25
21
/* PID/CID values */
26
+static inline bool isar_feature_aa32_tts2uxn(const ARMISARegisters *id)
22
-static const int sysctl_id[] = {
27
+{
23
+static const int iotkit_sysctl_id[] = {
28
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, XNX) != 0;
24
0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
29
+}
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
+};
30
+
35
+
31
/*
36
/*
32
* 64-bit feature tests via id registers.
37
* Set the initial secure vector table offset address for the core.
33
*/
38
* This will take effect when the CPU next resets.
34
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
39
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
35
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
36
}
37
38
+static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
39
+{
40
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
41
+}
42
+
43
/*
44
* Feature tests for "does this exist in either 32-bit or 64-bit?"
45
*/
46
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_ccidx(const ARMISARegisters *id)
47
return isar_feature_aa64_ccidx(id) || isar_feature_aa32_ccidx(id);
48
}
49
50
+static inline bool isar_feature_any_tts2uxn(const ARMISARegisters *id)
51
+{
52
+ return isar_feature_aa64_tts2uxn(id) || isar_feature_aa32_tts2uxn(id);
53
+}
54
+
55
/*
56
* Forward to the above feature tests given an ARMCPU pointer.
57
*/
58
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/cpu.c
61
+++ b/target/arm/cpu.c
62
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
63
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
64
t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
65
t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
66
+ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
67
cpu->isar.id_mmfr4 = t;
68
}
40
}
69
#endif
41
break;
70
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
42
case A_PID4 ... A_CID3:
71
index XXXXXXX..XXXXXXX 100644
43
- r = sysctl_id[(offset - A_PID4) / 4];
72
--- a/target/arm/cpu64.c
44
+ switch (s->sse_version) {
73
+++ b/target/arm/cpu64.c
45
+ case ARMSSE_IOTKIT:
74
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
46
+ r = iotkit_sysctl_id[(offset - A_PID4) / 4];
75
t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1);
76
t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */
77
t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* VMID16 */
78
+ t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* TTS2UXN */
79
cpu->isar.id_aa64mmfr1 = t;
80
81
t = cpu->isar.id_aa64mmfr2;
82
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
83
u = FIELD_DP32(u, ID_MMFR4, HPDS, 1); /* AA32HPD */
84
u = FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
85
u = FIELD_DP32(u, ID_MMFR4, CNP, 1); /* TTCNP */
86
+ u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
87
cpu->isar.id_mmfr4 = u;
88
89
u = cpu->isar.id_aa64dfr0;
90
diff --git a/target/arm/helper.c b/target/arm/helper.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/helper.c
93
+++ b/target/arm/helper.c
94
@@ -XXX,XX +XXX,XX @@ simple_ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, int ap)
95
*
96
* @env: CPUARMState
97
* @s2ap: The 2-bit stage2 access permissions (S2AP)
98
- * @xn: XN (execute-never) bit
99
+ * @xn: XN (execute-never) bits
100
+ * @s1_is_el0: true if this is S2 of an S1+2 walk for EL0
101
*/
102
-static int get_S2prot(CPUARMState *env, int s2ap, int xn)
103
+static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
104
{
105
int prot = 0;
106
107
@@ -XXX,XX +XXX,XX @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn)
108
if (s2ap & 2) {
109
prot |= PAGE_WRITE;
110
}
111
- if (!xn) {
112
- if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
113
+
114
+ if (cpu_isar_feature(any_tts2uxn, env_archcpu(env))) {
115
+ switch (xn) {
116
+ case 0:
117
prot |= PAGE_EXEC;
118
+ break;
47
+ break;
119
+ case 1:
48
+ case ARMSSE_SSE200:
120
+ if (s1_is_el0) {
49
+ case ARMSSE_SSE300:
121
+ prot |= PAGE_EXEC;
50
+ r = sse200_sysctl_id[(offset - A_PID4) / 4];
122
+ }
123
+ break;
124
+ case 2:
125
+ break;
126
+ case 3:
127
+ if (!s1_is_el0) {
128
+ prot |= PAGE_EXEC;
129
+ }
130
+ break;
51
+ break;
131
+ default:
52
+ default:
132
+ g_assert_not_reached();
53
+ g_assert_not_reached();
133
+ }
54
+ }
134
+ } else {
55
break;
135
+ if (!extract32(xn, 1, 1)) {
56
case A_SECDBGSET:
136
+ if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
57
case A_SECDBGCLR:
137
+ prot |= PAGE_EXEC;
138
+ }
139
}
140
}
141
return prot;
142
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
143
}
144
145
ap = extract32(attrs, 4, 2);
146
- xn = extract32(attrs, 12, 1);
147
148
if (mmu_idx == ARMMMUIdx_Stage2) {
149
ns = true;
150
- *prot = get_S2prot(env, ap, xn);
151
+ xn = extract32(attrs, 11, 2);
152
+ *prot = get_S2prot(env, ap, xn, s1_is_el0);
153
} else {
154
ns = extract32(attrs, 3, 1);
155
+ xn = extract32(attrs, 12, 1);
156
pxn = extract32(attrs, 11, 1);
157
*prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
158
}
159
--
58
--
160
2.20.1
59
2.20.1
161
60
162
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
1
Convert the VCMLA (vector) insns in the 3same extension group to
1
Convert the apb_ppc0 and apb_ppc1 fields in the ARMSSE state struct
2
decodetree.
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.
3
5
4
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>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-5-peter.maydell@linaro.org
10
Message-id: 20210219144617.4782-22-peter.maydell@linaro.org
7
---
11
---
8
target/arm/neon-shared.decode | 11 ++++++++++
12
include/hw/arm/armsse.h | 6 +++---
9
target/arm/translate-neon.inc.c | 37 +++++++++++++++++++++++++++++++++
13
hw/arm/armsse.c | 32 ++++++++++++++++++--------------
10
target/arm/translate.c | 11 +---------
14
2 files changed, 21 insertions(+), 17 deletions(-)
11
3 files changed, 49 insertions(+), 10 deletions(-)
12
15
13
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
16
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-shared.decode
18
--- a/include/hw/arm/armsse.h
16
+++ b/target/arm/neon-shared.decode
19
+++ b/include/hw/arm/armsse.h
17
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(ARMSSE, ARMSSEClass,
18
# More specifically, this covers:
21
/* We have an IRQ splitter and an OR gate input for each external PPC
19
# 2reg scalar ext: 0b1111_1110_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
22
* and the 2 internal PPCs
20
# 3same ext: 0b1111_110x_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
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);
21
+
51
+
22
+# VFP/Neon register fields; same as vfp.decode
52
+ for (i = 0; i < ARRAY_SIZE(s->apb_ppc); i++) {
23
+%vm_dp 5:1 0:4
53
+ g_autofree char *name = g_strdup_printf("apb-ppc%d", i);
24
+%vm_sp 0:4 5:1
54
+ object_initialize_child(obj, name, &s->apb_ppc[i], TYPE_TZ_PPC);
25
+%vn_dp 7:1 16:4
26
+%vn_sp 16:4 7:1
27
+%vd_dp 22:1 12:4
28
+%vd_sp 12:4 22:1
29
+
30
+VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
31
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
32
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate-neon.inc.c
35
+++ b/target/arm/translate-neon.inc.c
36
@@ -XXX,XX +XXX,XX @@
37
#include "decode-neon-dp.inc.c"
38
#include "decode-neon-ls.inc.c"
39
#include "decode-neon-shared.inc.c"
40
+
41
+static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
42
+{
43
+ int opr_sz;
44
+ TCGv_ptr fpst;
45
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
46
+
47
+ if (!dc_isar_feature(aa32_vcma, s)
48
+ || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
49
+ return false;
50
+ }
55
+ }
51
+
56
+
52
+ /* UNDEF accesses to D16-D31 if they don't exist. */
57
for (i = 0; i < info->sram_banks; i++) {
53
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
58
char *name = g_strdup_printf("mpc%d", i);
54
+ ((a->vd | a->vn | a->vm) & 0x10)) {
59
object_initialize_child(obj, name, &s->mpc[i], TYPE_TZ_MPC);
55
+ return false;
60
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
56
+ }
61
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer0), 0,
57
+
62
armsse_get_common_irq_in(s, 3));
58
+ if ((a->vn | a->vm | a->vd) & a->q) {
63
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer0), 0);
59
+ return false;
64
- object_property_set_link(OBJECT(&s->apb_ppc0), "port[0]", OBJECT(mr),
60
+ }
65
+ object_property_set_link(OBJECT(&s->apb_ppc[0]), "port[0]", OBJECT(mr),
61
+
66
&error_abort);
62
+ if (!vfp_access_check(s)) {
67
63
+ return true;
68
qdev_connect_clock_in(DEVICE(&s->timer1), "pclk", s->mainclk);
64
+ }
69
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
65
+
70
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer1), 0,
66
+ opr_sz = (1 + a->q) * 8;
71
armsse_get_common_irq_in(s, 4));
67
+ fpst = get_fpstatus_ptr(1);
72
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer1), 0);
68
+ fn_gvec_ptr = a->size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
73
- object_property_set_link(OBJECT(&s->apb_ppc0), "port[1]", OBJECT(mr),
69
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
74
+ object_property_set_link(OBJECT(&s->apb_ppc[0]), "port[1]", OBJECT(mr),
70
+ vfp_reg_offset(1, a->vn),
75
&error_abort);
71
+ vfp_reg_offset(1, a->vm),
76
72
+ fpst, opr_sz, opr_sz, a->rot,
77
qdev_connect_clock_in(DEVICE(&s->dualtimer), "TIMCLK", s->mainclk);
73
+ fn_gvec_ptr);
78
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
74
+ tcg_temp_free_ptr(fpst);
79
sysbus_connect_irq(SYS_BUS_DEVICE(&s->dualtimer), 0,
75
+ return true;
80
armsse_get_common_irq_in(s, 5));
76
+}
81
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dualtimer), 0);
77
diff --git a/target/arm/translate.c b/target/arm/translate.c
82
- object_property_set_link(OBJECT(&s->apb_ppc0), "port[2]", OBJECT(mr),
78
index XXXXXXX..XXXXXXX 100644
83
+ object_property_set_link(OBJECT(&s->apb_ppc[0]), "port[2]", OBJECT(mr),
79
--- a/target/arm/translate.c
84
&error_abort);
80
+++ b/target/arm/translate.c
85
81
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
86
if (info->has_mhus) {
82
bool is_long = false, q = extract32(insn, 6, 1);
87
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
83
bool ptr_is_env = false;
88
}
84
89
port = g_strdup_printf("port[%d]", i + 3);
85
- if ((insn & 0xfe200f10) == 0xfc200800) {
90
mr = sysbus_mmio_get_region(mhu_sbd, 0);
86
- /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
91
- object_property_set_link(OBJECT(&s->apb_ppc0), port, OBJECT(mr),
87
- int size = extract32(insn, 20, 1);
92
+ object_property_set_link(OBJECT(&s->apb_ppc[0]), port, OBJECT(mr),
88
- data = extract32(insn, 23, 2); /* rot */
93
&error_abort);
89
- if (!dc_isar_feature(aa32_vcma, s)
94
g_free(port);
90
- || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
95
91
- return 1;
96
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
92
- }
97
}
93
- fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
98
}
94
- } else if ((insn & 0xfea00f10) == 0xfc800800) {
99
95
+ if ((insn & 0xfea00f10) == 0xfc800800) {
100
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc0), errp)) {
96
/* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
101
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc[0]), errp)) {
97
int size = extract32(insn, 20, 1);
102
return;
98
data = extract32(insn, 24, 1); /* rot */
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));
99
--
142
--
100
2.20.1
143
2.20.1
101
144
102
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
1
Convert the V[US]DOT (scalar) insns in the 2reg-scalar-ext group
1
The SSE-300 is mostly the same as the SSE-200, but it has moved some
2
to decodetree.
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.
3
10
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-10-peter.maydell@linaro.org
14
Message-id: 20210219144617.4782-24-peter.maydell@linaro.org
7
---
15
---
8
target/arm/neon-shared.decode | 3 +++
16
include/hw/arm/armsse.h | 3 +-
9
target/arm/translate-neon.inc.c | 35 +++++++++++++++++++++++++++++++++
17
hw/arm/armsse.c | 147 +++++++++++++++++++++++++++++++++-------
10
target/arm/translate.c | 13 +-----------
18
2 files changed, 125 insertions(+), 25 deletions(-)
11
3 files changed, 39 insertions(+), 12 deletions(-)
19
12
20
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
13
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
14
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-shared.decode
22
--- a/include/hw/arm/armsse.h
16
+++ b/target/arm/neon-shared.decode
23
+++ b/include/hw/arm/armsse.h
17
@@ -XXX,XX +XXX,XX @@ VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
24
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
18
vn=%vn_dp vd=%vd_dp size=0
25
IoTKitSecCtl secctl;
19
VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
26
TZPPC apb_ppc[NUM_INTERNAL_PPCS];
20
vm=%vm_dp vn=%vn_dp vd=%vd_dp size=1 index=0
27
TZMPC mpc[IOTS_NUM_MPC];
21
+
28
- CMSDKAPBTimer timer0;
22
+VDOT_scalar 1111 1110 0 . 10 .... .... 1101 . q:1 index:1 u:1 rm:4 \
29
- CMSDKAPBTimer timer1;
23
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
30
+ CMSDKAPBTimer timer[2];
24
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
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
25
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/translate-neon.inc.c
36
--- a/hw/arm/armsse.c
27
+++ b/target/arm/translate-neon.inc.c
37
+++ b/hw/arm/armsse.c
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
38
@@ -XXX,XX +XXX,XX @@
29
tcg_temp_free_ptr(fpst);
39
#include "hw/irq.h"
30
return true;
40
#include "hw/qdev-clock.h"
31
}
41
32
+
42
+/*
33
+static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
43
+ * The SSE-300 puts some devices in different places to the
34
+{
44
+ * SSE-200 (and original IoTKit). We use an array of these structs
35
+ gen_helper_gvec_3 *fn_gvec;
45
+ * to define how each variant lays out these devices. (Parts of the
36
+ int opr_sz;
46
+ * SoC that are the same for all variants aren't handled via these
37
+ TCGv_ptr fpst;
47
+ * data structures.)
38
+
48
+ */
39
+ if (!dc_isar_feature(aa32_dp, s)) {
49
+
40
+ return false;
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,
41
+ }
99
+ }
42
+
100
+};
43
+ /* UNDEF accesses to D16-D31 if they don't exist. */
101
+
44
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
102
static const ARMSSEInfo armsse_variants[] = {
45
+ ((a->vd | a->vn) & 0x10)) {
103
{
46
+ return false;
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
+ }
47
+ }
143
+ }
48
+
144
+
49
+ if ((a->vd | a->vn) & a->q) {
145
object_initialize_child(obj, "secctl", &s->secctl, TYPE_IOTKIT_SECCTL);
50
+ return false;
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);
51
+ }
266
+ }
52
+
267
+
53
+ if (!vfp_access_check(s)) {
268
if (!object_property_set_int(OBJECT(&s->sysinfo), "SYS_VERSION",
54
+ return true;
269
info->sys_version, errp)) {
55
+ }
270
return;
56
+
57
+ fn_gvec = a->u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
58
+ opr_sz = (1 + a->q) * 8;
59
+ fpst = get_fpstatus_ptr(1);
60
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
61
+ vfp_reg_offset(1, a->vn),
62
+ vfp_reg_offset(1, a->rm),
63
+ opr_sz, opr_sz, a->index, fn_gvec);
64
+ tcg_temp_free_ptr(fpst);
65
+ return true;
66
+}
67
diff --git a/target/arm/translate.c b/target/arm/translate.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/arm/translate.c
70
+++ b/target/arm/translate.c
71
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
72
bool is_long = false, q = extract32(insn, 6, 1);
73
bool ptr_is_env = false;
74
75
- if ((insn & 0xffb00f00) == 0xfe200d00) {
76
- /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
77
- int u = extract32(insn, 4, 1);
78
-
79
- if (!dc_isar_feature(aa32_dp, s)) {
80
- return 1;
81
- }
82
- fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
83
- /* rm is just Vm, and index is M. */
84
- data = extract32(insn, 5, 1); /* index */
85
- rm = extract32(insn, 0, 4);
86
- } else if ((insn & 0xffa00f10) == 0xfe000810) {
87
+ if ((insn & 0xffa00f10) == 0xfe000810) {
88
/* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
89
int is_s = extract32(insn, 20, 1);
90
int vm20 = extract32(insn, 0, 3);
91
--
271
--
92
2.20.1
272
2.20.1
93
273
94
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
Convert the VCADD (vector) insns to decodetree.
1
Move the CMSDK watchdog device handling into the data-driven device
2
placement framework. This is slightly more complicated because these
3
devices might wire their IRQs up to the NMI line, and because one of
4
them uses the slow 32KHz clock rather than the main clock.
2
5
3
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>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-6-peter.maydell@linaro.org
9
Message-id: 20210219144617.4782-26-peter.maydell@linaro.org
6
---
10
---
7
target/arm/neon-shared.decode | 3 +++
11
include/hw/arm/armsse.h | 4 +-
8
target/arm/translate-neon.inc.c | 37 +++++++++++++++++++++++++++++++++
12
hw/arm/armsse.c | 109 ++++++++++++++++++++++++----------------
9
target/arm/translate.c | 11 +---------
13
2 files changed, 66 insertions(+), 47 deletions(-)
10
3 files changed, 41 insertions(+), 10 deletions(-)
14
11
15
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
17
--- a/include/hw/arm/armsse.h
15
+++ b/target/arm/neon-shared.decode
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
16
@@ -XXX,XX +XXX,XX @@
34
@@ -XXX,XX +XXX,XX @@
17
35
18
VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
36
#define NO_IRQ -1
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp
37
#define NO_PPC -1
38
+/*
39
+ * Special values for ARMSSEDeviceInfo::irq to indicate that this
40
+ * device uses one of the inputs to the OR gate that feeds into the
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
}
20
+
106
+
21
+VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
107
object_initialize_child(obj, "s32ktimer", &s->s32ktimer,
22
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
108
TYPE_CMSDK_APB_TIMER);
23
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
109
- object_initialize_child(obj, "s32kwatchdog", &s->s32kwatchdog,
24
index XXXXXXX..XXXXXXX 100644
110
- TYPE_CMSDK_APB_WATCHDOG);
25
--- a/target/arm/translate-neon.inc.c
111
- object_initialize_child(obj, "nswatchdog", &s->nswatchdog,
26
+++ b/target/arm/translate-neon.inc.c
112
- TYPE_CMSDK_APB_WATCHDOG);
27
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
113
- object_initialize_child(obj, "swatchdog", &s->swatchdog,
28
tcg_temp_free_ptr(fpst);
114
- TYPE_CMSDK_APB_WATCHDOG);
29
return true;
115
object_initialize_child(obj, "armsse-sysctl", &s->sysctl,
30
}
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));
31
+
132
+
32
+static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
133
/* Devices behind APB PPC0:
33
+{
134
* 0x40000000: timer0
34
+ int opr_sz;
135
* 0x40001000: timer1
35
+ TCGv_ptr fpst;
136
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
36
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
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]);
37
+
142
+
38
+ if (!dc_isar_feature(aa32_vcma, s)
143
+ qdev_connect_clock_in(DEVICE(sbd), "WDOGCLK",
39
+ || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
144
+ devinfo->slowclk ? s->s32kclk : s->mainclk);
40
+ return false;
145
+ if (!sysbus_realize(sbd, errp)) {
41
+ }
146
+ return;
42
+
147
+ }
43
+ /* UNDEF accesses to D16-D31 if they don't exist. */
148
+ mr = sysbus_mmio_get_region(sbd, 0);
44
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
149
} else {
45
+ ((a->vd | a->vn | a->vm) & 0x10)) {
150
g_assert_not_reached();
46
+ return false;
151
}
47
+ }
152
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
48
+
153
case 0 ... NUM_SSE_IRQS - 1:
49
+ if ((a->vn | a->vm | a->vd) & a->q) {
154
irq = armsse_get_common_irq_in(s, devinfo->irq);
50
+ return false;
155
break;
51
+ }
156
+ case NMI_0:
52
+
157
+ case NMI_1:
53
+ if (!vfp_access_check(s)) {
158
+ irq = qdev_get_gpio_in(DEVICE(&s->nmi_orgate),
54
+ return true;
159
+ devinfo->irq - NMI_0);
55
+ }
160
+ break;
56
+
161
default:
57
+ opr_sz = (1 + a->q) * 8;
162
g_assert_not_reached();
58
+ fpst = get_fpstatus_ptr(1);
163
}
59
+ fn_gvec_ptr = a->size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
164
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
60
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
165
}
61
+ vfp_reg_offset(1, a->vn),
166
}
62
+ vfp_reg_offset(1, a->vm),
167
63
+ fpst, opr_sz, opr_sz, a->rot,
168
- /* This OR gate wires together outputs from the secure watchdogs to NMI */
64
+ fn_gvec_ptr);
169
- if (!object_property_set_int(OBJECT(&s->nmi_orgate), "num-lines", 2,
65
+ tcg_temp_free_ptr(fpst);
170
- errp)) {
66
+ return true;
171
- return;
67
+}
172
- }
68
diff --git a/target/arm/translate.c b/target/arm/translate.c
173
- if (!qdev_realize(DEVICE(&s->nmi_orgate), NULL, errp)) {
69
index XXXXXXX..XXXXXXX 100644
174
- return;
70
--- a/target/arm/translate.c
175
- }
71
+++ b/target/arm/translate.c
176
- qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
72
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
177
- qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
73
bool is_long = false, q = extract32(insn, 6, 1);
178
-
74
bool ptr_is_env = false;
179
- qdev_connect_clock_in(DEVICE(&s->s32kwatchdog), "WDOGCLK", s->s32kclk);
75
180
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->s32kwatchdog), errp)) {
76
- if ((insn & 0xfea00f10) == 0xfc800800) {
181
- return;
77
- /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
182
- }
78
- int size = extract32(insn, 20, 1);
183
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32kwatchdog), 0,
79
- data = extract32(insn, 24, 1); /* rot */
184
- qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 0));
80
- if (!dc_isar_feature(aa32_vcma, s)
185
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->s32kwatchdog), 0, 0x5002e000);
81
- || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
186
-
82
- return 1;
187
- /* 0x40080000 .. 0x4008ffff : ARMSSE second Base peripheral region */
83
- }
188
-
84
- fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
189
- qdev_connect_clock_in(DEVICE(&s->nswatchdog), "WDOGCLK", s->mainclk);
85
- } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
190
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->nswatchdog), errp)) {
86
+ if ((insn & 0xfeb00f00) == 0xfc200d00) {
191
- return;
87
/* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
192
- }
88
bool u = extract32(insn, 4, 1);
193
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->nswatchdog), 0,
89
if (!dc_isar_feature(aa32_dp, s)) {
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]);
207
90
--
208
--
91
2.20.1
209
2.20.1
92
210
93
211
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
Move the CMSDK timer that uses the S32K slow clock into the data-driven
2
device placement framework.
2
3
3
Embed the ADMAs into the SoC type.
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(-)
4
12
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
13
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-7-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
14
hw/arm/xlnx-versal.c | 14 +++++++-------
15
2 files changed, 9 insertions(+), 8 deletions(-)
16
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
15
--- a/include/hw/arm/armsse.h
20
+++ b/include/hw/arm/xlnx-versal.h
16
+++ b/include/hw/arm/armsse.h
21
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
22
#include "hw/arm/boot.h"
18
IoTKitSecCtl secctl;
23
#include "hw/intc/arm_gicv3.h"
19
TZPPC apb_ppc[NUM_INTERNAL_PPCS];
24
#include "hw/char/pl011.h"
20
TZMPC mpc[IOTS_NUM_MPC];
25
+#include "hw/dma/xlnx-zdma.h"
21
- CMSDKAPBTimer timer[2];
26
#include "hw/net/cadence_gem.h"
22
- CMSDKAPBTimer s32ktimer;
27
23
+ CMSDKAPBTimer timer[3];
28
#define TYPE_XLNX_VERSAL "xlnx-versal"
24
qemu_or_irq ppc_irq_orgate;
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
25
SplitIRQ sec_resp_splitter;
30
struct {
26
SplitIRQ ppc_irq_splitter[NUM_PPCS];
31
PL011State uart[XLNX_VERSAL_NR_UARTS];
27
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
32
CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
33
- SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
34
+ XlnxZDMA adma[XLNX_VERSAL_NR_ADMAS];
35
} iou;
36
} lpd;
37
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
39
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/xlnx-versal.c
29
--- a/hw/arm/armsse.c
41
+++ b/hw/arm/xlnx-versal.c
30
+++ b/hw/arm/armsse.c
42
@@ -XXX,XX +XXX,XX @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
31
@@ -XXX,XX +XXX,XX @@ static const ARMSSEDeviceInfo sse200_devices[] = {
43
DeviceState *dev;
32
.ppc_port = 1,
44
MemoryRegion *mr;
33
.irq = 4,
45
34
},
46
- dev = qdev_create(NULL, "xlnx.zdma");
35
+ {
47
- s->lpd.iou.adma[i] = SYS_BUS_DEVICE(dev);
36
+ .name = "s32ktimer",
48
- object_property_set_int(OBJECT(s->lpd.iou.adma[i]), 128, "bus-width",
37
+ .type = TYPE_CMSDK_APB_TIMER,
49
- &error_abort);
38
+ .index = 2,
50
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
39
+ .addr = 0x4002f000,
51
+ sysbus_init_child_obj(OBJECT(s), name,
40
+ .ppc = 1,
52
+ &s->lpd.iou.adma[i], sizeof(s->lpd.iou.adma[i]),
41
+ .ppc_port = 0,
53
+ TYPE_XLNX_ZDMA);
42
+ .irq = 2,
54
+ dev = DEVICE(&s->lpd.iou.adma[i]);
43
+ .slowclk = true,
55
+ object_property_set_int(OBJECT(dev), 128, "bus-width", &error_abort);
44
+ },
56
qdev_init_nofail(dev);
45
{
57
46
.name = "dualtimer",
58
- mr = sysbus_mmio_get_region(s->lpd.iou.adma[i], 0);
47
.type = TYPE_CMSDK_APB_DUALTIMER,
59
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
48
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
60
memory_region_add_subregion(&s->mr_ps,
61
MM_ADMA_CH0 + i * MM_ADMA_CH0_SIZE, mr);
62
63
- sysbus_connect_irq(s->lpd.iou.adma[i], 0, pic[VERSAL_ADMA_IRQ_0 + i]);
64
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_ADMA_IRQ_0 + i]);
65
g_free(name);
49
g_free(name);
66
}
50
}
67
}
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,
68
--
93
--
69
2.20.1
94
2.20.1
70
95
71
96
diff view generated by jsdifflib
1
We define ARMMMUIdx_Stage2 as being an MMU index which uses a QEMU
1
Move the sysinfo register block into the data-driven framework.
2
TLB. However we never actually use the TLB -- all stage 2 lookups
3
are done by direct calls to get_phys_addr_lpae() followed by a
4
physical address load via address_space_ld*().
5
2
6
Remove Stage2 from the list of ARM MMU indexes which correspond to
3
While we are moving the code for configuring this device around,
7
real core MMU indexes, and instead put it in the set of "NOTLB" ARM
4
regularize on using &error_abortw when setting the integer
8
MMU indexes.
5
properties: they are all simple DEFINE_PROP_UINT32 properties so the
9
6
setting can never fail.
10
This allows us to drop NB_MMU_MODES to 11. It also means we can
11
safely add support for the ARMv8.3-TTS2UXN extension, which adds
12
permission bits to the stage 2 descriptors which define execute
13
permission separatel for EL0 and EL1; supporting that while keeping
14
Stage2 in a QEMU TLB would require us to use separate TLBs for
15
"Stage2 for an EL0 access" and "Stage2 for an EL1 access", which is a
16
lot of extra complication given we aren't even using the QEMU TLB.
17
18
In the process of updating the comment on our MMU index use,
19
fix a couple of other minor errors:
20
* NS EL2 EL2&0 was missing from the list in the comment
21
* some text hadn't been updated from when we bumped NB_MMU_MODES
22
above 8
23
7
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Message-id: 20200330210400.11724-2-peter.maydell@linaro.org
11
Message-id: 20210219144617.4782-28-peter.maydell@linaro.org
28
---
12
---
29
target/arm/cpu-param.h | 2 +-
13
hw/arm/armsse.c | 47 ++++++++++++++++++++++++++++-------------------
30
target/arm/cpu.h | 21 +++++---
14
1 file changed, 28 insertions(+), 19 deletions(-)
31
target/arm/helper.c | 112 ++++-------------------------------------
32
3 files changed, 27 insertions(+), 108 deletions(-)
33
15
34
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
16
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
35
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/cpu-param.h
18
--- a/hw/arm/armsse.c
37
+++ b/target/arm/cpu-param.h
19
+++ b/hw/arm/armsse.c
38
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static const ARMSSEDeviceInfo sse200_devices[] = {
39
# define TARGET_PAGE_BITS_MIN 10
21
.ppc = NO_PPC,
40
#endif
22
.irq = NMI_1,
41
23
},
42
-#define NB_MMU_MODES 12
24
+ {
43
+#define NB_MMU_MODES 11
25
+ .name = "armsse-sysinfo",
44
26
+ .type = TYPE_IOTKIT_SYSINFO,
45
#endif
27
+ .index = 0,
46
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
28
+ .addr = 0x40020000,
47
index XXXXXXX..XXXXXXX 100644
29
+ .ppc = NO_PPC,
48
--- a/target/arm/cpu.h
30
+ .irq = NO_IRQ,
49
+++ b/target/arm/cpu.h
31
+ },
50
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
32
{
51
* handling via the TLB. The only way to do a stage 1 translation without
33
.name = NULL,
52
* the immediate stage 2 translation is via the ATS or AT system insns,
34
}
53
* which can be slow-pathed and always do a page table walk.
35
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
54
+ * The only use of stage 2 translations is either as part of an s1+2
36
object_initialize_child(obj, devinfo->name,
55
+ * lookup or when loading the descriptors during a stage 1 page table walk,
37
&s->cmsdk_watchdog[devinfo->index],
56
+ * and in both those cases we don't use the TLB.
38
TYPE_CMSDK_APB_WATCHDOG);
57
* 4. we can also safely fold together the "32 bit EL3" and "64 bit EL3"
39
+ } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSINFO)) {
58
* translation regimes, because they map reasonably well to each other
40
+ assert(devinfo->index == 0);
59
* and they can't both be active at the same time.
41
+ object_initialize_child(obj, devinfo->name, &s->sysinfo,
60
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
42
+ TYPE_IOTKIT_SYSINFO);
61
* NS EL1 EL1&0 stage 1+2 (aka NS PL1)
43
} else {
62
* NS EL1 EL1&0 stage 1+2 +PAN
44
g_assert_not_reached();
63
* NS EL0 EL2&0
45
}
64
+ * NS EL2 EL2&0
46
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
65
* NS EL2 EL2&0 +PAN
47
66
* NS EL2 (aka NS PL2)
48
object_initialize_child(obj, "armsse-sysctl", &s->sysctl,
67
* S EL0 EL1&0 (aka S PL0)
49
TYPE_IOTKIT_SYSCTL);
68
* S EL1 EL1&0 (not used if EL3 is 32 bit)
50
- object_initialize_child(obj, "armsse-sysinfo", &s->sysinfo,
69
* S EL1 EL1&0 +PAN
51
- TYPE_IOTKIT_SYSINFO);
70
* S EL3 (aka S PL1)
52
if (info->has_mhus) {
71
- * NS EL1&0 stage 2
53
object_initialize_child(obj, "mhu0", &s->mhu[0], TYPE_ARMSSE_MHU);
72
*
54
object_initialize_child(obj, "mhu1", &s->mhu[1], TYPE_ARMSSE_MHU);
73
- * for a total of 12 different mmu_idx.
55
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
74
+ * for a total of 11 different mmu_idx.
56
return;
75
*
57
}
76
* R profile CPUs have an MPU, but can use the same set of MMU indexes
58
mr = sysbus_mmio_get_region(sbd, 0);
77
* as A profile. They only need to distinguish NS EL0 and NS EL1 (and
59
+ } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSINFO)) {
78
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
60
+ sbd = SYS_BUS_DEVICE(&s->sysinfo);
79
* are not quite the same -- different CPU types (most notably M profile
61
+
80
* vs A/R profile) would like to use MMU indexes with different semantics,
62
+ object_property_set_int(OBJECT(&s->sysinfo), "SYS_VERSION",
81
* but since we don't ever need to use all of those in a single CPU we
63
+ info->sys_version, &error_abort);
82
- * can avoid setting NB_MMU_MODES to more than 8. The lower bits of
64
+ object_property_set_int(OBJECT(&s->sysinfo), "SYS_CONFIG",
83
+ * can avoid having to set NB_MMU_MODES to "total number of A profile MMU
65
+ armsse_sys_config_value(s, info),
84
+ * modes + total number of M profile MMU modes". The lower bits of
66
+ &error_abort);
85
* ARMMMUIdx are the core TLB mmu index, and the higher bits are always
67
+ object_property_set_int(OBJECT(&s->sysinfo), "sse-version",
86
* the same for any particular CPU.
68
+ info->sse_version, &error_abort);
87
* Variables of type ARMMUIdx are always full values, and the core
69
+ object_property_set_int(OBJECT(&s->sysinfo), "IIDR",
88
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
70
+ info->iidr, &error_abort);
89
ARMMMUIdx_SE10_1_PAN = 9 | ARM_MMU_IDX_A,
71
+ if (!sysbus_realize(sbd, errp)) {
90
ARMMMUIdx_SE3 = 10 | ARM_MMU_IDX_A,
72
+ return;
91
73
+ }
92
- ARMMMUIdx_Stage2 = 11 | ARM_MMU_IDX_A,
74
+ mr = sysbus_mmio_get_region(sbd, 0);
93
-
75
} else {
94
/*
76
g_assert_not_reached();
95
* These are not allocated TLBs and are used only for AT system
77
}
96
* instructions or for the first stage of an S12 page table walk.
78
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
97
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
79
memory_region_add_subregion(&s->container, devinfo->addr, mr);
98
ARMMMUIdx_Stage1_E0 = 0 | ARM_MMU_IDX_NOTLB,
80
}
99
ARMMMUIdx_Stage1_E1 = 1 | ARM_MMU_IDX_NOTLB,
81
100
ARMMMUIdx_Stage1_E1_PAN = 2 | ARM_MMU_IDX_NOTLB,
82
- if (!object_property_set_int(OBJECT(&s->sysinfo), "SYS_VERSION",
101
+ /*
83
- info->sys_version, errp)) {
102
+ * Not allocated a TLB: used only for second stage of an S12 page
103
+ * table walk, or for descriptor loads during first stage of an S1
104
+ * page table walk. Note that if we ever want to have a TLB for this
105
+ * then various TLB flush insns which currently are no-ops or flush
106
+ * only stage 1 MMU indexes will need to change to flush stage 2.
107
+ */
108
+ ARMMMUIdx_Stage2 = 3 | ARM_MMU_IDX_NOTLB,
109
110
/*
111
* M-profile.
112
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdxBit {
113
TO_CORE_BIT(SE10_1),
114
TO_CORE_BIT(SE10_1_PAN),
115
TO_CORE_BIT(SE3),
116
- TO_CORE_BIT(Stage2),
117
118
TO_CORE_BIT(MUser),
119
TO_CORE_BIT(MPriv),
120
diff --git a/target/arm/helper.c b/target/arm/helper.c
121
index XXXXXXX..XXXXXXX 100644
122
--- a/target/arm/helper.c
123
+++ b/target/arm/helper.c
124
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri,
125
tlb_flush_by_mmuidx(cs,
126
ARMMMUIdxBit_E10_1 |
127
ARMMMUIdxBit_E10_1_PAN |
128
- ARMMMUIdxBit_E10_0 |
129
- ARMMMUIdxBit_Stage2);
130
+ ARMMMUIdxBit_E10_0);
131
}
132
133
static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
134
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
135
tlb_flush_by_mmuidx_all_cpus_synced(cs,
136
ARMMMUIdxBit_E10_1 |
137
ARMMMUIdxBit_E10_1_PAN |
138
- ARMMMUIdxBit_E10_0 |
139
- ARMMMUIdxBit_Stage2);
140
+ ARMMMUIdxBit_E10_0);
141
}
142
143
-static void tlbiipas2_write(CPUARMState *env, const ARMCPRegInfo *ri,
144
- uint64_t value)
145
-{
146
- /* Invalidate by IPA. This has to invalidate any structures that
147
- * contain only stage 2 translation information, but does not need
148
- * to apply to structures that contain combined stage 1 and stage 2
149
- * translation information.
150
- * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
151
- */
152
- CPUState *cs = env_cpu(env);
153
- uint64_t pageaddr;
154
-
155
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
156
- return;
84
- return;
157
- }
85
- }
158
-
86
- if (!object_property_set_int(OBJECT(&s->sysinfo), "SYS_CONFIG",
159
- pageaddr = sextract64(value << 12, 0, 40);
87
- armsse_sys_config_value(s, info), errp)) {
160
-
161
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2);
162
-}
163
-
164
-static void tlbiipas2_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
165
- uint64_t value)
166
-{
167
- CPUState *cs = env_cpu(env);
168
- uint64_t pageaddr;
169
-
170
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
171
- return;
88
- return;
172
- }
89
- }
173
-
90
- object_property_set_int(OBJECT(&s->sysinfo), "sse-version",
174
- pageaddr = sextract64(value << 12, 0, 40);
91
- info->sse_version, &error_abort);
175
-
92
- object_property_set_int(OBJECT(&s->sysinfo), "IIDR",
176
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
93
- info->iidr, &error_abort);
177
- ARMMMUIdxBit_Stage2);
94
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->sysinfo), errp)) {
178
-}
179
180
static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
181
uint64_t value)
182
@@ -XXX,XX +XXX,XX @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
183
tlb_flush_by_mmuidx(cs,
184
ARMMMUIdxBit_E10_1 |
185
ARMMMUIdxBit_E10_1_PAN |
186
- ARMMMUIdxBit_E10_0 |
187
- ARMMMUIdxBit_Stage2);
188
+ ARMMMUIdxBit_E10_0);
189
raw_write(env, ri, value);
190
}
191
}
192
@@ -XXX,XX +XXX,XX @@ static int alle1_tlbmask(CPUARMState *env)
193
return ARMMMUIdxBit_SE10_1 |
194
ARMMMUIdxBit_SE10_1_PAN |
195
ARMMMUIdxBit_SE10_0;
196
- } else if (arm_feature(env, ARM_FEATURE_EL2)) {
197
- return ARMMMUIdxBit_E10_1 |
198
- ARMMMUIdxBit_E10_1_PAN |
199
- ARMMMUIdxBit_E10_0 |
200
- ARMMMUIdxBit_Stage2;
201
} else {
202
return ARMMMUIdxBit_E10_1 |
203
ARMMMUIdxBit_E10_1_PAN |
204
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
205
ARMMMUIdxBit_SE3);
206
}
207
208
-static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri,
209
- uint64_t value)
210
-{
211
- /* Invalidate by IPA. This has to invalidate any structures that
212
- * contain only stage 2 translation information, but does not need
213
- * to apply to structures that contain combined stage 1 and stage 2
214
- * translation information.
215
- * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
216
- */
217
- ARMCPU *cpu = env_archcpu(env);
218
- CPUState *cs = CPU(cpu);
219
- uint64_t pageaddr;
220
-
221
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
222
- return;
95
- return;
223
- }
96
- }
224
-
97
- /* System information registers */
225
- pageaddr = sextract64(value << 12, 0, 48);
98
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysinfo), 0, 0x40020000);
226
-
99
/* System control registers */
227
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2);
100
object_property_set_int(OBJECT(&s->sysctl), "sse-version",
228
-}
101
info->sse_version, &error_abort);
229
-
230
-static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
231
- uint64_t value)
232
-{
233
- CPUState *cs = env_cpu(env);
234
- uint64_t pageaddr;
235
-
236
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
237
- return;
238
- }
239
-
240
- pageaddr = sextract64(value << 12, 0, 48);
241
-
242
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
243
- ARMMMUIdxBit_Stage2);
244
-}
245
-
246
static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri,
247
bool isread)
248
{
249
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
250
.writefn = tlbi_aa64_vae1_write },
251
{ .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64,
252
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
253
- .access = PL2_W, .type = ARM_CP_NO_RAW,
254
- .writefn = tlbi_aa64_ipas2e1is_write },
255
+ .access = PL2_W, .type = ARM_CP_NOP },
256
{ .name = "TLBI_IPAS2LE1IS", .state = ARM_CP_STATE_AA64,
257
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
258
- .access = PL2_W, .type = ARM_CP_NO_RAW,
259
- .writefn = tlbi_aa64_ipas2e1is_write },
260
+ .access = PL2_W, .type = ARM_CP_NOP },
261
{ .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64,
262
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
263
.access = PL2_W, .type = ARM_CP_NO_RAW,
264
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
265
.writefn = tlbi_aa64_alle1is_write },
266
{ .name = "TLBI_IPAS2E1", .state = ARM_CP_STATE_AA64,
267
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
268
- .access = PL2_W, .type = ARM_CP_NO_RAW,
269
- .writefn = tlbi_aa64_ipas2e1_write },
270
+ .access = PL2_W, .type = ARM_CP_NOP },
271
{ .name = "TLBI_IPAS2LE1", .state = ARM_CP_STATE_AA64,
272
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
273
- .access = PL2_W, .type = ARM_CP_NO_RAW,
274
- .writefn = tlbi_aa64_ipas2e1_write },
275
+ .access = PL2_W, .type = ARM_CP_NOP },
276
{ .name = "TLBI_ALLE1", .state = ARM_CP_STATE_AA64,
277
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4,
278
.access = PL2_W, .type = ARM_CP_NO_RAW,
279
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
280
.writefn = tlbimva_hyp_is_write },
281
{ .name = "TLBIIPAS2",
282
.cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
283
- .type = ARM_CP_NO_RAW, .access = PL2_W,
284
- .writefn = tlbiipas2_write },
285
+ .type = ARM_CP_NOP, .access = PL2_W },
286
{ .name = "TLBIIPAS2IS",
287
.cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
288
- .type = ARM_CP_NO_RAW, .access = PL2_W,
289
- .writefn = tlbiipas2_is_write },
290
+ .type = ARM_CP_NOP, .access = PL2_W },
291
{ .name = "TLBIIPAS2L",
292
.cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
293
- .type = ARM_CP_NO_RAW, .access = PL2_W,
294
- .writefn = tlbiipas2_write },
295
+ .type = ARM_CP_NOP, .access = PL2_W },
296
{ .name = "TLBIIPAS2LIS",
297
.cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
298
- .type = ARM_CP_NO_RAW, .access = PL2_W,
299
- .writefn = tlbiipas2_is_write },
300
+ .type = ARM_CP_NOP, .access = PL2_W },
301
/* 32 bit cache operations */
302
{ .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
303
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
304
--
102
--
305
2.20.1
103
2.20.1
306
104
307
105
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
Move the sysctl register block into the data-driven device placement
2
framework.
2
3
3
Embed the GEMs into the SoC type.
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(-)
4
11
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
12
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-6-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
14
hw/arm/xlnx-versal.c | 15 ++++++++-------
15
2 files changed, 10 insertions(+), 8 deletions(-)
16
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
18
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
14
--- a/hw/arm/armsse.c
20
+++ b/include/hw/arm/xlnx-versal.h
15
+++ b/hw/arm/armsse.c
21
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static const ARMSSEDeviceInfo sse200_devices[] = {
22
#include "hw/arm/boot.h"
17
.ppc = NO_PPC,
23
#include "hw/intc/arm_gicv3.h"
18
.irq = NO_IRQ,
24
#include "hw/char/pl011.h"
19
},
25
+#include "hw/net/cadence_gem.h"
20
+ {
26
21
+ .name = "armsse-sysctl",
27
#define TYPE_XLNX_VERSAL "xlnx-versal"
22
+ .type = TYPE_IOTKIT_SYSCTL,
28
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
23
+ .index = 0,
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
24
+ .addr = 0x50021000,
30
25
+ .ppc = NO_PPC,
31
struct {
26
+ .irq = NO_IRQ,
32
PL011State uart[XLNX_VERSAL_NR_UARTS];
27
+ },
33
- SysBusDevice *gem[XLNX_VERSAL_NR_GEMS];
28
{
34
+ CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
29
.name = NULL,
35
SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
30
}
36
} iou;
31
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
37
} lpd;
32
assert(devinfo->index == 0);
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
33
object_initialize_child(obj, devinfo->name, &s->sysinfo,
39
index XXXXXXX..XXXXXXX 100644
34
TYPE_IOTKIT_SYSINFO);
40
--- a/hw/arm/xlnx-versal.c
35
+ } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSCTL)) {
41
+++ b/hw/arm/xlnx-versal.c
36
+ assert(devinfo->index == 0);
42
@@ -XXX,XX +XXX,XX @@ static void versal_create_gems(Versal *s, qemu_irq *pic)
37
+ object_initialize_child(obj, devinfo->name, &s->sysctl,
43
DeviceState *dev;
38
+ TYPE_IOTKIT_SYSCTL);
44
MemoryRegion *mr;
39
} else {
45
40
g_assert_not_reached();
46
- dev = qdev_create(NULL, "cadence_gem");
47
- s->lpd.iou.gem[i] = SYS_BUS_DEVICE(dev);
48
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
49
+ sysbus_init_child_obj(OBJECT(s), name,
50
+ &s->lpd.iou.gem[i], sizeof(s->lpd.iou.gem[i]),
51
+ TYPE_CADENCE_GEM);
52
+ dev = DEVICE(&s->lpd.iou.gem[i]);
53
if (nd->used) {
54
qemu_check_nic_model(nd, "cadence_gem");
55
qdev_set_nic_properties(dev, nd);
56
}
41
}
57
- object_property_set_int(OBJECT(s->lpd.iou.gem[i]),
42
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
58
+ object_property_set_int(OBJECT(dev),
59
2, "num-priority-queues",
60
&error_abort);
61
- object_property_set_link(OBJECT(s->lpd.iou.gem[i]),
62
+ object_property_set_link(OBJECT(dev),
63
OBJECT(&s->mr_ps), "dma",
64
&error_abort);
65
qdev_init_nofail(dev);
66
67
- mr = sysbus_mmio_get_region(s->lpd.iou.gem[i], 0);
68
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
69
memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
70
71
- sysbus_connect_irq(s->lpd.iou.gem[i], 0, pic[irqs[i]]);
72
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
73
g_free(name);
43
g_free(name);
74
}
44
}
75
}
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++) {
76
--
95
--
77
2.20.1
96
2.20.1
78
97
79
98
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
Move the PPUs into the data-driven device placement framework.
2
2
We don't implement them, so they are just TYPE_UNIMPLEMENTED stubs.
3
Embed the APUs into the SoC type.
3
4
4
Because the SSE-200 and the IotKit diverge here (the IoTKit does
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
5
not have the PPUs) we need to separate out the ARMSSEDeviceInfo
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
for the two variants, and only add the PPUs to the SSE-200.
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-8-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
---
12
---
13
include/hw/arm/xlnx-versal.h | 2 +-
13
include/hw/arm/armsse.h | 10 +-
14
hw/arm/xlnx-versal-virt.c | 4 ++--
14
hw/arm/armsse.c | 222 +++++++++++++++++++++++++++++-----------
15
hw/arm/xlnx-versal.c | 19 +++++--------------
15
2 files changed, 165 insertions(+), 67 deletions(-)
16
3 files changed, 8 insertions(+), 17 deletions(-)
16
17
17
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
18
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
19
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/xlnx-versal.h
19
--- a/include/hw/arm/armsse.h
21
+++ b/include/hw/arm/xlnx-versal.h
20
+++ b/include/hw/arm/armsse.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
21
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(ARMSSE, ARMSSEClass,
23
struct {
22
24
struct {
23
#define SSE_MAX_CPUS 2
25
MemoryRegion mr;
24
26
- ARMCPU *cpu[XLNX_VERSAL_NR_ACPUS];
25
-/* These define what each PPU in the ppu[] index is for */
27
+ ARMCPU cpu[XLNX_VERSAL_NR_ACPUS];
26
-#define CPU0CORE_PPU 0
28
GICv3State gic;
27
-#define CPU1CORE_PPU 1
29
} apu;
28
-#define DBG_PPU 2
30
} fpd;
29
-#define RAM0_PPU 3
31
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
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
32
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/arm/xlnx-versal-virt.c
47
--- a/hw/arm/armsse.c
34
+++ b/hw/arm/xlnx-versal-virt.c
48
+++ b/hw/arm/armsse.c
35
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
49
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSEDeviceInfo {
36
s->binfo.get_dtb = versal_virt_get_dtb;
50
const char *type; /* QOM type name */
37
s->binfo.modify_dtb = versal_virt_modify_dtb;
51
unsigned int index; /* Which of the N devices of this type is this ? */
38
if (machine->kernel_filename) {
52
hwaddr addr;
39
- arm_load_kernel(s->soc.fpd.apu.cpu[0], machine, &s->binfo);
53
+ hwaddr size; /* only needed for TYPE_UNIMPLEMENTED_DEVICE */
40
+ arm_load_kernel(&s->soc.fpd.apu.cpu[0], machine, &s->binfo);
54
int ppc; /* Index of APB PPC this device is wired up to, or NO_PPC */
41
} else {
55
int ppc_port; /* Port number of this device on the PPC */
42
- AddressSpace *as = arm_boot_address_space(s->soc.fpd.apu.cpu[0],
56
int irq; /* NO_IRQ, or 0..NUM_SSE_IRQS-1, or NMI_0 or NMI_1 */
43
+ AddressSpace *as = arm_boot_address_space(&s->soc.fpd.apu.cpu[0],
57
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
44
&s->binfo);
58
uint32_t iidr;
45
/* Some boot-loaders (e.g u-boot) don't like blobs at address 0 (NULL).
59
uint32_t cpuwait_rst;
46
* Offset things by 4K. */
60
bool has_mhus;
47
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
61
- bool has_ppus;
48
index XXXXXXX..XXXXXXX 100644
62
bool has_cachectrl;
49
--- a/hw/arm/xlnx-versal.c
63
bool has_cpusecctrl;
50
+++ b/hw/arm/xlnx-versal.c
64
bool has_cpuid;
51
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
65
@@ -XXX,XX +XXX,XX @@ static Property armsse_properties[] = {
52
66
DEFINE_PROP_END_OF_LIST()
53
for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
67
};
54
Object *obj;
68
55
- char *name;
69
-static const ARMSSEDeviceInfo sse200_devices[] = {
56
-
70
+static const ARMSSEDeviceInfo iotkit_devices[] = {
57
- obj = object_new(XLNX_VERSAL_ACPU_TYPE);
71
{
58
- if (!obj) {
72
.name = "timer0",
59
- error_report("Unable to create apu.cpu[%d] of type %s",
73
.type = TYPE_CMSDK_APB_TIMER,
60
- i, XLNX_VERSAL_ACPU_TYPE);
74
@@ -XXX,XX +XXX,XX @@ static const ARMSSEDeviceInfo sse200_devices[] = {
61
- exit(EXIT_FAILURE);
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);
62
- }
274
- }
63
-
275
- object_initialize_child(obj, "DBG_PPU", &s->ppu[DBG_PPU],
64
- name = g_strdup_printf("apu-cpu[%d]", i);
276
- TYPE_UNIMPLEMENTED_DEVICE);
65
- object_property_add_child(OBJECT(s), name, obj, &error_fatal);
277
- for (i = 0; i < info->sram_banks; i++) {
66
- g_free(name);
278
- char *name = g_strdup_printf("RAM%d_PPU", i);
67
279
- int ppuidx = RAM0_PPU + i;
68
+ object_initialize_child(OBJECT(s), "apu-cpu[*]",
280
-
69
+ &s->fpd.apu.cpu[i], sizeof(s->fpd.apu.cpu[i]),
281
- object_initialize_child(obj, name, &s->ppu[ppuidx],
70
+ XLNX_VERSAL_ACPU_TYPE, &error_abort, NULL);
282
- TYPE_UNIMPLEMENTED_DEVICE);
71
+ obj = OBJECT(&s->fpd.apu.cpu[i]);
283
- g_free(name);
72
object_property_set_int(obj, s->cfg.psci_conduit,
284
- }
73
"psci-conduit", &error_abort);
285
- }
74
if (i) {
286
if (info->has_cachectrl) {
75
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
287
for (i = 0; i < info->num_cpus; i++) {
76
object_property_set_link(obj, OBJECT(&s->fpd.apu.mr), "memory",
288
char *name = g_strdup_printf("cachectrl%d", i);
77
&error_abort);
289
@@ -XXX,XX +XXX,XX @@ static qemu_irq armsse_get_common_irq_in(ARMSSE *s, int irqno)
78
object_property_set_bool(obj, true, "realized", &error_fatal);
79
- s->fpd.apu.cpu[i] = ARM_CPU(obj);
80
}
290
}
81
}
291
}
82
292
83
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
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);
84
}
325
}
85
326
86
for (i = 0; i < nr_apu_cpus; i++) {
327
- if (info->has_ppus) {
87
- DeviceState *cpudev = DEVICE(s->fpd.apu.cpu[i]);
328
- /* CPUnCORE_PPU for each CPU */
88
+ DeviceState *cpudev = DEVICE(&s->fpd.apu.cpu[i]);
329
- for (i = 0; i < info->num_cpus; i++) {
89
int ppibase = XLNX_VERSAL_NR_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
330
- char *name = g_strdup_printf("CPU%dCORE_PPU", i);
90
qemu_irq maint_irq;
331
-
91
int ti;
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
92
--
352
--
93
2.20.1
353
2.20.1
94
354
95
355
diff view generated by jsdifflib
1
Somewhere along theline we accidentally added a duplicate
1
We forgot to implement a TYPE_UNIMPLEMENTED_DEVICE stub
2
"using D16-D31 when they don't exist" check to do_vfm_dp()
2
for the SYS_PPU in the SSE-200, which is at 0x50022000.
3
(probably an artifact of a patchseries rebase). Remove it.
4
3
5
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: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210219144617.4782-31-peter.maydell@linaro.org
8
Message-id: 20200430181003.21682-2-peter.maydell@linaro.org
9
---
8
---
10
target/arm/translate-vfp.inc.c | 6 ------
9
include/hw/arm/armsse.h | 2 +-
11
1 file changed, 6 deletions(-)
10
hw/arm/armsse.c | 9 +++++++++
11
2 files changed, 10 insertions(+), 1 deletion(-)
12
12
13
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
13
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-vfp.inc.c
15
--- a/include/hw/arm/armsse.h
16
+++ b/target/arm/translate-vfp.inc.c
16
+++ b/include/hw/arm/armsse.h
17
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_dp(DisasContext *s, arg_VFMA_dp *a, bool neg_n, bool neg_d)
17
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(ARMSSE, ARMSSEClass,
18
return false;
18
19
}
19
#define SSE_MAX_CPUS 2
20
20
21
- /* UNDEF accesses to D16-D31 if they don't exist. */
21
-#define NUM_PPUS 7
22
- if (!dc_isar_feature(aa32_simd_r32, s) &&
22
+#define NUM_PPUS 8
23
- ((a->vd | a->vn | a->vm) & 0x10)) {
23
24
- return false;
24
/* Number of CPU IRQs used by the SSE itself */
25
- }
25
#define NUM_SSE_IRQS 32
26
-
26
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
27
if (!vfp_access_check(s)) {
27
index XXXXXXX..XXXXXXX 100644
28
return true;
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,
29
}
45
}
30
--
46
--
31
2.20.1
47
2.20.1
32
48
33
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
1
Convert the V[US]DOT (vector) insns to decodetree.
1
The SSE-300 has a system counter device; add support for SSE
2
variants having this device.
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.
2
8
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-7-peter.maydell@linaro.org
12
Message-id: 20210219144617.4782-33-peter.maydell@linaro.org
6
---
13
---
7
target/arm/neon-shared.decode | 4 ++++
14
include/hw/arm/armsse.h | 3 +++
8
target/arm/translate-neon.inc.c | 32 ++++++++++++++++++++++++++++++++
15
hw/arm/armsse.c | 27 +++++++++++++++++++++++++++
9
target/arm/translate.c | 9 +--------
16
2 files changed, 30 insertions(+)
10
3 files changed, 37 insertions(+), 8 deletions(-)
11
17
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
18
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
13
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
20
--- a/include/hw/arm/armsse.h
15
+++ b/target/arm/neon-shared.decode
21
+++ b/include/hw/arm/armsse.h
16
@@ -XXX,XX +XXX,XX @@ VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
22
@@ -XXX,XX +XXX,XX @@
17
23
#include "hw/misc/tz-mpc.h"
18
VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
24
#include "hw/timer/cmsdk-apb-timer.h"
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp
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;
20
+
35
+
21
+# VUDOT and VSDOT
36
IoTKitSysCtl sysctl;
22
+VDOT 1111 110 00 . 10 .... .... 1101 . q:1 . u:1 .... \
37
IoTKitSysCtl sysinfo;
23
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
38
24
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
39
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
25
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/translate-neon.inc.c
41
--- a/hw/arm/armsse.c
27
+++ b/target/arm/translate-neon.inc.c
42
+++ b/hw/arm/armsse.c
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
43
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
29
tcg_temp_free_ptr(fpst);
44
bool has_cachectrl;
30
return true;
45
bool has_cpusecctrl;
31
}
46
bool has_cpuid;
32
+
47
+ bool has_sse_counter;
33
+static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
48
Property *props;
34
+{
49
const ARMSSEDeviceInfo *devinfo;
35
+ int opr_sz;
50
const bool *irq_is_common;
36
+ gen_helper_gvec_3 *fn_gvec;
51
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
37
+
52
.has_cachectrl = false,
38
+ if (!dc_isar_feature(aa32_dp, s)) {
53
.has_cpusecctrl = false,
39
+ return 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);
40
+ }
74
+ }
41
+
75
+
42
+ /* UNDEF accesses to D16-D31 if they don't exist. */
76
object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate, TYPE_OR_IRQ);
43
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
77
object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate,
44
+ ((a->vd | a->vn | a->vm) & 0x10)) {
78
TYPE_OR_IRQ);
45
+ return false;
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));
46
+ }
100
+ }
47
+
101
+
48
+ if ((a->vn | a->vm | a->vd) & a->q) {
102
/* Devices behind APB PPC0:
49
+ return false;
103
* 0x40000000: timer0
50
+ }
104
* 0x40001000: timer1
51
+
52
+ if (!vfp_access_check(s)) {
53
+ return true;
54
+ }
55
+
56
+ opr_sz = (1 + a->q) * 8;
57
+ fn_gvec = a->u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
58
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
59
+ vfp_reg_offset(1, a->vn),
60
+ vfp_reg_offset(1, a->vm),
61
+ opr_sz, opr_sz, 0, fn_gvec);
62
+ return true;
63
+}
64
diff --git a/target/arm/translate.c b/target/arm/translate.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/translate.c
67
+++ b/target/arm/translate.c
68
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
69
bool is_long = false, q = extract32(insn, 6, 1);
70
bool ptr_is_env = false;
71
72
- if ((insn & 0xfeb00f00) == 0xfc200d00) {
73
- /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
74
- bool u = extract32(insn, 4, 1);
75
- if (!dc_isar_feature(aa32_dp, s)) {
76
- return 1;
77
- }
78
- fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
79
- } else if ((insn & 0xff300f10) == 0xfc200810) {
80
+ if ((insn & 0xff300f10) == 0xfc200810) {
81
/* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
82
int is_s = extract32(insn, 23, 1);
83
if (!dc_isar_feature(aa32_fhm, s)) {
84
--
105
--
85
2.20.1
106
2.20.1
86
107
87
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
1
Convert the VFM[AS]L (vector) insns to decodetree. This is the last
1
We've already broken migration compatibility for all the MPS
2
insn in the legacy decoder for the 3same_ext group, so we can
2
boards, so we might as well take advantage of this to simplify
3
delete the legacy decoder function for the group entirely.
3
the vmstate for the FPGAIO device by folding the counters
4
4
subsection into the main vmstate description.
5
Note that in disas_thumb2_insn() the parts of this encoding space
6
where the decodetree decoder returns false will correctly be directed
7
to illegal_op by the "(insn & (1 << 28))" check so they won't fall
8
into disas_coproc_insn() by mistake.
9
5
10
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>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200430181003.21682-8-peter.maydell@linaro.org
9
Message-id: 20210219144617.4782-38-peter.maydell@linaro.org
13
---
10
---
14
target/arm/neon-shared.decode | 6 +++
11
hw/misc/mps2-fpgaio.c | 30 +++++-------------------------
15
target/arm/translate-neon.inc.c | 31 +++++++++++
12
1 file changed, 5 insertions(+), 25 deletions(-)
16
target/arm/translate.c | 92 +--------------------------------
17
3 files changed, 38 insertions(+), 91 deletions(-)
18
13
19
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
14
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/neon-shared.decode
16
--- a/hw/misc/mps2-fpgaio.c
22
+++ b/target/arm/neon-shared.decode
17
+++ b/hw/misc/mps2-fpgaio.c
23
@@ -XXX,XX +XXX,XX @@ VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
18
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_realize(DeviceState *dev, Error **errp)
24
# VUDOT and VSDOT
19
}
25
VDOT 1111 110 00 . 10 .... .... 1101 . q:1 . u:1 .... \
26
vm=%vm_dp vn=%vn_dp vd=%vd_dp
27
+
28
+# VFM[AS]L
29
+VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
30
+ vm=%vm_sp vn=%vn_sp vd=%vd_dp q=0
31
+VFML 1111 110 0 s:1 . 10 .... .... 1000 . 1 . 1 .... \
32
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp q=1
33
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-neon.inc.c
36
+++ b/target/arm/translate-neon.inc.c
37
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
38
opr_sz, opr_sz, 0, fn_gvec);
39
return true;
40
}
20
}
41
+
21
42
+static bool trans_VFML(DisasContext *s, arg_VFML *a)
22
-static bool mps2_fpgaio_counters_needed(void *opaque)
43
+{
44
+ int opr_sz;
45
+
46
+ if (!dc_isar_feature(aa32_fhm, s)) {
47
+ return false;
48
+ }
49
+
50
+ /* UNDEF accesses to D16-D31 if they don't exist. */
51
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
52
+ (a->vd & 0x10)) {
53
+ return false;
54
+ }
55
+
56
+ if (a->vd & a->q) {
57
+ return false;
58
+ }
59
+
60
+ if (!vfp_access_check(s)) {
61
+ return true;
62
+ }
63
+
64
+ opr_sz = (1 + a->q) * 8;
65
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
66
+ vfp_reg_offset(a->q, a->vn),
67
+ vfp_reg_offset(a->q, a->vm),
68
+ cpu_env, opr_sz, opr_sz, a->s, /* is_2 == 0 */
69
+ gen_helper_gvec_fmlal_a32);
70
+ return true;
71
+}
72
diff --git a/target/arm/translate.c b/target/arm/translate.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/translate.c
75
+++ b/target/arm/translate.c
76
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
77
return 0;
78
}
79
80
-/* Advanced SIMD three registers of the same length extension.
81
- * 31 25 23 22 20 16 12 11 10 9 8 3 0
82
- * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
83
- * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
84
- * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
85
- */
86
-static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
87
-{
23
-{
88
- gen_helper_gvec_3 *fn_gvec = NULL;
24
- /* Currently vmstate.c insists all subsections have a 'needed' function */
89
- gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
25
- return true;
90
- int rd, rn, rm, opr_sz;
91
- int data = 0;
92
- int off_rn, off_rm;
93
- bool is_long = false, q = extract32(insn, 6, 1);
94
- bool ptr_is_env = false;
95
-
96
- if ((insn & 0xff300f10) == 0xfc200810) {
97
- /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
98
- int is_s = extract32(insn, 23, 1);
99
- if (!dc_isar_feature(aa32_fhm, s)) {
100
- return 1;
101
- }
102
- is_long = true;
103
- data = is_s; /* is_2 == 0 */
104
- fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
105
- ptr_is_env = true;
106
- } else {
107
- return 1;
108
- }
109
-
110
- VFP_DREG_D(rd, insn);
111
- if (rd & q) {
112
- return 1;
113
- }
114
- if (q || !is_long) {
115
- VFP_DREG_N(rn, insn);
116
- VFP_DREG_M(rm, insn);
117
- if ((rn | rm) & q & !is_long) {
118
- return 1;
119
- }
120
- off_rn = vfp_reg_offset(1, rn);
121
- off_rm = vfp_reg_offset(1, rm);
122
- } else {
123
- rn = VFP_SREG_N(insn);
124
- rm = VFP_SREG_M(insn);
125
- off_rn = vfp_reg_offset(0, rn);
126
- off_rm = vfp_reg_offset(0, rm);
127
- }
128
-
129
- if (s->fp_excp_el) {
130
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
131
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
132
- return 0;
133
- }
134
- if (!s->vfp_enabled) {
135
- return 1;
136
- }
137
-
138
- opr_sz = (1 + q) * 8;
139
- if (fn_gvec_ptr) {
140
- TCGv_ptr ptr;
141
- if (ptr_is_env) {
142
- ptr = cpu_env;
143
- } else {
144
- ptr = get_fpstatus_ptr(1);
145
- }
146
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
147
- opr_sz, opr_sz, data, fn_gvec_ptr);
148
- if (!ptr_is_env) {
149
- tcg_temp_free_ptr(ptr);
150
- }
151
- } else {
152
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
153
- opr_sz, opr_sz, data, fn_gvec);
154
- }
155
- return 0;
156
-}
26
-}
157
-
27
-
158
/* Advanced SIMD two registers and a scalar extension.
28
-static const VMStateDescription mps2_fpgaio_counters_vmstate = {
159
* 31 24 23 22 20 16 12 11 10 9 8 3 0
29
- .name = "mps2-fpgaio/counters",
160
* +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
30
+static const VMStateDescription mps2_fpgaio_vmstate = {
161
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
31
+ .name = "mps2-fpgaio",
162
}
32
.version_id = 2,
163
}
33
.minimum_version_id = 2,
164
}
34
- .needed = mps2_fpgaio_counters_needed,
165
- } else if ((insn & 0x0e000a00) == 0x0c000800
35
.fields = (VMStateField[]) {
166
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
36
+ VMSTATE_UINT32(led0, MPS2FPGAIO),
167
- if (disas_neon_insn_3same_ext(s, insn)) {
37
+ VMSTATE_UINT32(prescale, MPS2FPGAIO),
168
- goto illegal_op;
38
+ VMSTATE_UINT32(misc, MPS2FPGAIO),
169
- }
39
VMSTATE_INT64(clk1hz_tick_offset, MPS2FPGAIO),
170
- return;
40
VMSTATE_INT64(clk100hz_tick_offset, MPS2FPGAIO),
171
} else if ((insn & 0x0f000a00) == 0x0e000800
41
VMSTATE_UINT32(counter, MPS2FPGAIO),
172
&& arm_dc_feature(s, ARM_FEATURE_V8)) {
42
VMSTATE_UINT32(pscntr, MPS2FPGAIO),
173
if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
43
VMSTATE_INT64(pscntr_sync_ticks, MPS2FPGAIO),
174
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
44
VMSTATE_END_OF_LIST()
175
}
45
- }
176
break;
46
-};
177
}
47
-
178
- if ((insn & 0xfe000a00) == 0xfc000800
48
-static const VMStateDescription mps2_fpgaio_vmstate = {
179
+ if ((insn & 0xff000a00) == 0xfe000800
49
- .name = "mps2-fpgaio",
180
&& arm_dc_feature(s, ARM_FEATURE_V8)) {
50
- .version_id = 1,
181
/* The Thumb2 and ARM encodings are identical. */
51
- .minimum_version_id = 1,
182
- if (disas_neon_insn_3same_ext(s, insn)) {
52
- .fields = (VMStateField[]) {
183
- goto illegal_op;
53
- VMSTATE_UINT32(led0, MPS2FPGAIO),
184
- }
54
- VMSTATE_UINT32(prescale, MPS2FPGAIO),
185
- } else if ((insn & 0xff000a00) == 0xfe000800
55
- VMSTATE_UINT32(misc, MPS2FPGAIO),
186
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
56
- VMSTATE_END_OF_LIST()
187
- /* The Thumb2 and ARM encodings are identical. */
57
},
188
if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
58
- .subsections = (const VMStateDescription*[]) {
189
goto illegal_op;
59
- &mps2_fpgaio_counters_vmstate,
190
}
60
- NULL
61
- }
62
};
63
64
static Property mps2_fpgaio_properties[] = {
191
--
65
--
192
2.20.1
66
2.20.1
193
67
194
68
diff view generated by jsdifflib
1
We're going to want at least some of the NeonGen* typedefs
1
For the AN547 image, the FPGAIO block has an extra DBGCTRL register,
2
for the refactored 32-bit Neon decoder, so move them all
2
which is used to control the SPNIDEN, SPIDEN, NPIDEN and DBGEN inputs
3
to translate.h since it makes more sense to keep them in
3
to the CPU. These signals control when the CPU permits use of the
4
one group.
4
external debug interface. Our CPU models don't implement the
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.
5
10
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200430181003.21682-23-peter.maydell@linaro.org
15
Message-id: 20210219144617.4782-39-peter.maydell@linaro.org
9
---
16
---
10
target/arm/translate.h | 17 +++++++++++++++++
17
include/hw/misc/mps2-fpgaio.h | 2 ++
11
target/arm/translate-a64.c | 17 -----------------
18
hw/arm/mps2-tz.c | 5 +++++
12
2 files changed, 17 insertions(+), 17 deletions(-)
19
hw/misc/mps2-fpgaio.c | 22 ++++++++++++++++++++--
20
3 files changed, 27 insertions(+), 2 deletions(-)
13
21
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
22
diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
15
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.h
24
--- a/include/hw/misc/mps2-fpgaio.h
17
+++ b/target/arm/translate.h
25
+++ b/include/hw/misc/mps2-fpgaio.h
18
@@ -XXX,XX +XXX,XX @@ typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
26
@@ -XXX,XX +XXX,XX @@ struct MPS2FPGAIO {
19
typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
27
LEDState *led[MPS2FPGAIO_MAX_LEDS];
20
uint32_t, uint32_t, uint32_t);
28
uint32_t num_leds;
21
29
bool has_switches;
22
+/* Function prototype for gen_ functions for calling Neon helpers */
30
+ bool has_dbgctrl;
23
+typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
31
24
+typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
32
uint32_t led0;
25
+typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
33
uint32_t prescale;
26
+typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
34
uint32_t misc;
27
+typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
35
+ uint32_t dbgctrl;
28
+typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
36
29
+typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
37
/* QEMU_CLOCK_VIRTUAL time at which counter and pscntr were last synced */
30
+typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
38
int64_t pscntr_sync_ticks;
31
+typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
39
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
32
+typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
33
+typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
34
+typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
35
+typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
36
+typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
37
+typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
38
+
39
#endif /* TARGET_ARM_TRANSLATE_H */
40
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
41
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate-a64.c
41
--- a/hw/arm/mps2-tz.c
43
+++ b/target/arm/translate-a64.c
42
+++ b/hw/arm/mps2-tz.c
44
@@ -XXX,XX +XXX,XX @@ typedef struct AArch64DecodeTable {
43
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
45
AArch64DecodeFn *disas_fn;
44
const uint32_t *oscclk;
46
} AArch64DecodeTable;
45
uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
47
46
bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
48
-/* Function prototype for gen_ functions for calling Neon helpers */
47
+ bool fpgaio_has_dbgctrl; /* Does FPGAIO have DBGCTRL register? */
49
-typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
48
int numirq; /* Number of external interrupts */
50
-typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
49
int uart_overflow_irq; /* number of the combined UART overflow IRQ */
51
-typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
50
const RAMInfo *raminfo;
52
-typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
51
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
53
-typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
52
object_initialize_child(OBJECT(mms), "fpgaio", fpgaio, TYPE_MPS2_FPGAIO);
54
-typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
53
qdev_prop_set_uint32(DEVICE(fpgaio), "num-leds", mmc->fpgaio_num_leds);
55
-typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
54
qdev_prop_set_bit(DEVICE(fpgaio), "has-switches", mmc->fpgaio_has_switches);
56
-typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
55
+ qdev_prop_set_bit(DEVICE(fpgaio), "has-dbgctrl", mmc->fpgaio_has_dbgctrl);
57
-typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
56
sysbus_realize(SYS_BUS_DEVICE(fpgaio), &error_fatal);
58
-typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
57
return sysbus_mmio_get_region(SYS_BUS_DEVICE(fpgaio), 0);
59
-typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
58
}
60
-typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
59
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
61
-typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
60
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
62
-typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
61
mmc->fpgaio_num_leds = 2;
63
-typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
62
mmc->fpgaio_has_switches = false;
64
-
63
+ mmc->fpgaio_has_dbgctrl = false;
65
/* initialize TCG globals. */
64
mmc->numirq = 92;
66
void a64_translate_init(void)
65
mmc->uart_overflow_irq = 47;
67
{
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
};
154
68
--
155
--
69
2.20.1
156
2.20.1
70
157
71
158
diff view generated by jsdifflib
1
Convert the Neon logic ops in the 3-reg-same grouping to decodetree.
1
Implement the minor changes required to the SCC block for AN547 images:
2
Note that for the logic ops the 'size' field forms part of their
2
* CFG2 and CFG5 exist (like AN524)
3
decode and the actual operations are always bitwise.
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
4
6
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200430181003.21682-16-peter.maydell@linaro.org
10
Message-id: 20210219144617.4782-40-peter.maydell@linaro.org
8
---
11
---
9
target/arm/neon-dp.decode | 12 +++++++++++
12
hw/misc/mps2-scc.c | 15 +++++++++------
10
target/arm/translate-neon.inc.c | 19 +++++++++++++++++
13
1 file changed, 9 insertions(+), 6 deletions(-)
11
target/arm/translate.c | 38 +--------------------------------
12
3 files changed, 32 insertions(+), 37 deletions(-)
13
14
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
15
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/neon-dp.decode
17
--- a/hw/misc/mps2-scc.c
17
+++ b/target/arm/neon-dp.decode
18
+++ b/hw/misc/mps2-scc.c
18
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
19
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
20
r = s->cfg1;
20
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
21
break;
21
22
case A_CFG2:
22
+@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
23
- if (scc_partno(s) != 0x524) {
23
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0
24
+ if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
24
+
25
/* CFG2 reserved on other boards */
25
+VAND_3s 1111 001 0 0 . 00 .... .... 0001 ... 1 .... @3same_logic
26
goto bad_offset;
26
+VBIC_3s 1111 001 0 0 . 01 .... .... 0001 ... 1 .... @3same_logic
27
}
27
+VORR_3s 1111 001 0 0 . 10 .... .... 0001 ... 1 .... @3same_logic
28
r = s->cfg2;
28
+VORN_3s 1111 001 0 0 . 11 .... .... 0001 ... 1 .... @3same_logic
29
break;
29
+VEOR_3s 1111 001 1 0 . 00 .... .... 0001 ... 1 .... @3same_logic
30
case A_CFG3:
30
+VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
31
- if (scc_partno(s) == 0x524) {
31
+VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
32
+ if (scc_partno(s) == 0x524 && scc_partno(s) == 0x547) {
32
+VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
33
/* CFG3 reserved on AN524 */
33
+
34
goto bad_offset;
34
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
35
}
35
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
36
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
36
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
37
r = s->cfg4;
37
index XXXXXXX..XXXXXXX 100644
38
break;
38
--- a/target/arm/translate-neon.inc.c
39
case A_CFG5:
39
+++ b/target/arm/translate-neon.inc.c
40
- if (scc_partno(s) != 0x524) {
40
@@ -XXX,XX +XXX,XX @@ static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
41
+ if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
41
42
/* CFG5 reserved on other boards */
42
DO_3SAME(VADD, tcg_gen_gvec_add)
43
goto bad_offset;
43
DO_3SAME(VSUB, tcg_gen_gvec_sub)
44
}
44
+DO_3SAME(VAND, tcg_gen_gvec_and)
45
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
45
+DO_3SAME(VBIC, tcg_gen_gvec_andc)
46
46
+DO_3SAME(VORR, tcg_gen_gvec_or)
47
switch (offset) {
47
+DO_3SAME(VORN, tcg_gen_gvec_orc)
48
case A_CFG0:
48
+DO_3SAME(VEOR, tcg_gen_gvec_xor)
49
- /* TODO on some boards bit 0 controls RAM remapping */
49
+
50
+ /*
50
+/* These insns are all gvec_bitsel but with the inputs in various orders. */
51
+ * TODO on some boards bit 0 controls RAM remapping;
51
+#define DO_3SAME_BITSEL(INSN, O1, O2, O3) \
52
+ * on others bit 1 is CPU_WAIT.
52
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
53
+ */
53
+ uint32_t rn_ofs, uint32_t rm_ofs, \
54
s->cfg0 = value;
54
+ uint32_t oprsz, uint32_t maxsz) \
55
break;
55
+ { \
56
case A_CFG1:
56
+ tcg_gen_gvec_bitsel(vece, rd_ofs, O1, O2, O3, oprsz, maxsz); \
57
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
57
+ } \
58
}
58
+ DO_3SAME(INSN, gen_##INSN##_3s)
59
break;
59
+
60
case A_CFG2:
60
+DO_3SAME_BITSEL(VBSL, rd_ofs, rn_ofs, rm_ofs)
61
- if (scc_partno(s) != 0x524) {
61
+DO_3SAME_BITSEL(VBIT, rm_ofs, rn_ofs, rd_ofs)
62
+ if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
62
+DO_3SAME_BITSEL(VBIF, rm_ofs, rd_ofs, rn_ofs)
63
/* CFG2 reserved on other boards */
63
diff --git a/target/arm/translate.c b/target/arm/translate.c
64
goto bad_offset;
64
index XXXXXXX..XXXXXXX 100644
65
}
65
--- a/target/arm/translate.c
66
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
66
+++ b/target/arm/translate.c
67
s->cfg2 = value;
67
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
68
break;
68
}
69
case A_CFG5:
69
return 1;
70
- if (scc_partno(s) != 0x524) {
70
71
+ if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
71
- case NEON_3R_LOGIC: /* Logic ops. */
72
/* CFG5 reserved on other boards */
72
- switch ((u << 2) | size) {
73
goto bad_offset;
73
- case 0: /* VAND */
74
- tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
75
- vec_size, vec_size);
76
- break;
77
- case 1: /* VBIC */
78
- tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
79
- vec_size, vec_size);
80
- break;
81
- case 2: /* VORR */
82
- tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
83
- vec_size, vec_size);
84
- break;
85
- case 3: /* VORN */
86
- tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
87
- vec_size, vec_size);
88
- break;
89
- case 4: /* VEOR */
90
- tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
91
- vec_size, vec_size);
92
- break;
93
- case 5: /* VBSL */
94
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
95
- vec_size, vec_size);
96
- break;
97
- case 6: /* VBIT */
98
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
99
- vec_size, vec_size);
100
- break;
101
- case 7: /* VBIF */
102
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
103
- vec_size, vec_size);
104
- break;
105
- }
106
- return 0;
107
-
108
case NEON_3R_VQADD:
109
tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
110
rn_ofs, rm_ofs, vec_size, vec_size,
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
112
return 0;
113
114
case NEON_3R_VADD_VSUB:
115
+ case NEON_3R_LOGIC:
116
/* Already handled by decodetree */
117
return 1;
118
}
74
}
119
--
75
--
120
2.20.1
76
2.20.1
121
77
122
78
diff view generated by jsdifflib
1
The access_type argument to get_phys_addr_lpae() is an MMUAccessType;
1
The AN547 runs the APB peripherals outside the SSE-300 on a different
2
use the enum constant MMU_DATA_LOAD rather than a literal 0 when we
2
and slightly slower clock than it runs the SSE-300 with. Support
3
call it in S1_ptw_translate().
3
making the APB peripheral clock frequency board-specific. (For our
4
implementation only the UARTs actually take a clock.)
4
5
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200330210400.11724-3-peter.maydell@linaro.org
10
Message-id: 20210219144617.4782-41-peter.maydell@linaro.org
9
---
11
---
10
target/arm/helper.c | 5 +++--
12
hw/arm/mps2-tz.c | 6 +++++-
11
1 file changed, 3 insertions(+), 2 deletions(-)
13
1 file changed, 5 insertions(+), 1 deletion(-)
12
14
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
17
--- a/hw/arm/mps2-tz.c
16
+++ b/target/arm/helper.c
18
+++ b/hw/arm/mps2-tz.c
17
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
19
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
18
pcacheattrs = &cacheattrs;
20
MPS2TZFPGAType fpga_type;
19
}
21
uint32_t scc_id;
20
22
uint32_t sysclk_frq; /* Main SYSCLK frequency in Hz */
21
- ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_Stage2, &s2pa,
23
+ uint32_t apb_periph_frq; /* APB peripheral frequency in Hz */
22
- &txattrs, &s2prot, &s2size, fi, pcacheattrs);
24
uint32_t len_oscclk;
23
+ ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
25
const uint32_t *oscclk;
24
+ &s2pa, &txattrs, &s2prot, &s2size, fi,
26
uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
25
+ pcacheattrs);
27
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
26
if (ret) {
28
27
assert(fi->type != ARMFault_None);
29
object_initialize_child(OBJECT(mms), name, uart, TYPE_CMSDK_APB_UART);
28
fi->s2addr = addr;
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;
29
--
60
--
30
2.20.1
61
2.20.1
31
62
32
63
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
The AN547 configures the SSE-300 with a different initsvtor0
2
setting from its default; make this a board-specific setting.
2
3
3
By using the TYPE_* definitions for devices, we can:
4
- quickly find where devices are used with 'git-grep'
5
- easily rename a device (one-line change).
6
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20200428154650.21991-1-f4bug@amsat.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
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>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210219144617.4782-42-peter.maydell@linaro.org
11
---
9
---
12
hw/arm/mps2-tz.c | 2 +-
10
hw/arm/mps2-tz.c | 5 +++++
13
1 file changed, 1 insertion(+), 1 deletion(-)
11
1 file changed, 5 insertions(+)
14
12
15
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/mps2-tz.c
15
--- a/hw/arm/mps2-tz.c
18
+++ b/hw/arm/mps2-tz.c
16
+++ b/hw/arm/mps2-tz.c
17
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
18
bool fpgaio_has_dbgctrl; /* Does FPGAIO have DBGCTRL register? */
19
int numirq; /* Number of external interrupts */
20
int uart_overflow_irq; /* number of the combined UART overflow IRQ */
21
+ uint32_t init_svtor; /* init-svtor setting for SSE */
22
const RAMInfo *raminfo;
23
const char *armsse_type;
24
};
19
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
25
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
20
exit(EXIT_FAILURE);
26
object_property_set_link(OBJECT(&mms->iotkit), "memory",
21
}
27
OBJECT(system_memory), &error_abort);
22
28
qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", mmc->numirq);
23
- sysbus_init_child_obj(OBJECT(machine), "iotkit", &mms->iotkit,
29
+ qdev_prop_set_uint32(iotkitdev, "init-svtor", mmc->init_svtor);
24
+ sysbus_init_child_obj(OBJECT(machine), TYPE_IOTKIT, &mms->iotkit,
30
qdev_connect_clock_in(iotkitdev, "MAINCLK", mms->sysclk);
25
sizeof(mms->iotkit), mmc->armsse_type);
31
qdev_connect_clock_in(iotkitdev, "S32KCLK", mms->s32kclk);
26
iotkitdev = DEVICE(&mms->iotkit);
32
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
27
object_property_set_link(OBJECT(&mms->iotkit), OBJECT(system_memory),
33
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
34
mmc->fpgaio_has_dbgctrl = false;
35
mmc->numirq = 92;
36
mmc->uart_overflow_irq = 47;
37
+ mmc->init_svtor = 0x10000000;
38
mmc->raminfo = an505_raminfo;
39
mmc->armsse_type = TYPE_IOTKIT;
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);
28
--
57
--
29
2.20.1
58
2.20.1
30
59
31
60
diff view generated by jsdifflib
1
Convert the Neon 3-reg-same VMAX and VMIN insns to decodetree.
1
Add support for the mps3-an547 board; this is an SSE-300 based
2
FPGA image that runs on the MPS3.
2
3
3
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>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-17-peter.maydell@linaro.org
7
Message-id: 20210219144617.4782-43-peter.maydell@linaro.org
6
---
8
---
7
target/arm/neon-dp.decode | 5 +++++
9
hw/arm/mps2-tz.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++-
8
target/arm/translate-neon.inc.c | 14 ++++++++++++++
10
1 file changed, 144 insertions(+), 2 deletions(-)
9
target/arm/translate.c | 21 ++-------------------
11
10
3 files changed, 21 insertions(+), 19 deletions(-)
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
11
12
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
13
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-dp.decode
14
--- a/hw/arm/mps2-tz.c
15
+++ b/target/arm/neon-dp.decode
15
+++ b/hw/arm/mps2-tz.c
16
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
16
@@ -XXX,XX +XXX,XX @@
17
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
17
* "mps2-an505" -- Cortex-M33 as documented in ARM Application Note AN505
18
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
18
* "mps2-an521" -- Dual Cortex-M33 as documented in Application Note AN521
19
19
* "mps2-an524" -- Dual Cortex-M33 as documented in Application Note AN524
20
+VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
20
+ * "mps2-an547" -- Single Cortex-M55 as documented in Application Note AN547
21
+VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
21
*
22
+VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
22
* Links to the TRM for the board itself and to the various Application
23
+VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
23
* Notes which document the FPGA images can be found here:
24
+
24
@@ -XXX,XX +XXX,XX @@
25
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
25
* https://developer.arm.com/documentation/dai0521/latest/
26
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
26
* Application Note AN524:
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
27
* https://developer.arm.com/documentation/dai0524/latest/
28
index XXXXXXX..XXXXXXX 100644
28
+ * Application Note AN547:
29
--- a/target/arm/translate-neon.inc.c
29
+ * https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/DAI0547B_SSE300_PLUS_U55_FPGA_for_mps3.pdf
30
+++ b/target/arm/translate-neon.inc.c
30
*
31
@@ -XXX,XX +XXX,XX @@ DO_3SAME(VEOR, tcg_gen_gvec_xor)
31
* The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
32
DO_3SAME_BITSEL(VBSL, rd_ofs, rn_ofs, rm_ofs)
32
* (ARM ECM0601256) for the details of some of the device layout:
33
DO_3SAME_BITSEL(VBIT, rm_ofs, rn_ofs, rd_ofs)
33
@@ -XXX,XX +XXX,XX @@
34
DO_3SAME_BITSEL(VBIF, rm_ofs, rd_ofs, rn_ofs)
34
* Similarly, the AN521 and AN524 use the SSE-200, and the SSE-200 TRM defines
35
+
35
* most of the device layout:
36
+#define DO_3SAME_NO_SZ_3(INSN, FUNC) \
36
* https://developer.arm.com/documentation/101104/latest/
37
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
37
+ * and the AN547 uses the SSE-300, whose layout is in the SSE-300 TRM:
38
+ { \
38
+ * https://developer.arm.com/documentation/101773/latest/
39
+ if (a->size == 3) { \
39
*/
40
+ return false; \
40
41
+ } \
41
#include "qemu/osdep.h"
42
+ return do_3same(s, a, FUNC); \
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);
43
+ }
191
+ }
44
+
192
+
45
+DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
193
create_non_mpc_ram(mms);
46
+DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
194
47
+DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
195
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
48
+DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
196
@@ -XXX,XX +XXX,XX @@ static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
49
diff --git a/target/arm/translate.c b/target/arm/translate.c
197
mps2tz_set_default_ram_info(mmc);
50
index XXXXXXX..XXXXXXX 100644
198
}
51
--- a/target/arm/translate.c
199
52
+++ b/target/arm/translate.c
200
+static void mps3tz_an547_class_init(ObjectClass *oc, void *data)
53
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
201
+{
54
rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
202
+ MachineClass *mc = MACHINE_CLASS(oc);
55
return 0;
203
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc);
56
204
+
57
- case NEON_3R_VMAX:
205
+ mc->desc = "ARM MPS3 with AN547 FPGA image for Cortex-M55";
58
- if (u) {
206
+ mc->default_cpus = 1;
59
- tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
207
+ mc->min_cpus = mc->default_cpus;
60
- vec_size, vec_size);
208
+ mc->max_cpus = mc->default_cpus;
61
- } else {
209
+ mmc->fpga_type = FPGA_AN547;
62
- tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
210
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m55");
63
- vec_size, vec_size);
211
+ mmc->scc_id = 0x41055470;
64
- }
212
+ mmc->sysclk_frq = 32 * 1000 * 1000; /* 32MHz */
65
- return 0;
213
+ mmc->apb_periph_frq = 25 * 1000 * 1000; /* 25MHz */
66
- case NEON_3R_VMIN:
214
+ mmc->oscclk = an524_oscclk; /* same as AN524 */
67
- if (u) {
215
+ mmc->len_oscclk = ARRAY_SIZE(an524_oscclk);
68
- tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
216
+ mmc->fpgaio_num_leds = 10;
69
- vec_size, vec_size);
217
+ mmc->fpgaio_has_switches = true;
70
- } else {
218
+ mmc->fpgaio_has_dbgctrl = true;
71
- tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
219
+ mmc->numirq = 96;
72
- vec_size, vec_size);
220
+ mmc->uart_overflow_irq = 48;
73
- }
221
+ mmc->init_svtor = 0x00000000;
74
- return 0;
222
+ mmc->raminfo = an547_raminfo;
75
-
223
+ mmc->armsse_type = TYPE_SSE300;
76
case NEON_3R_VSHL:
224
+ mps2tz_set_default_ram_info(mmc);
77
/* Note the operation is vshl vd,vm,vn */
225
+}
78
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
226
+
79
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
227
static const TypeInfo mps2tz_info = {
80
228
.name = TYPE_MPS2TZ_MACHINE,
81
case NEON_3R_VADD_VSUB:
229
.parent = TYPE_MACHINE,
82
case NEON_3R_LOGIC:
230
@@ -XXX,XX +XXX,XX @@ static const TypeInfo mps3tz_an524_info = {
83
+ case NEON_3R_VMAX:
231
.class_init = mps3tz_an524_class_init,
84
+ case NEON_3R_VMIN:
232
};
85
/* Already handled by decodetree */
233
86
return 1;
234
+static const TypeInfo mps3tz_an547_info = {
87
}
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);
88
--
250
--
89
2.20.1
251
2.20.1
90
252
91
253
diff view generated by jsdifflib
1
Convert VCMLA (scalar) in the 2reg-scalar-ext group to decodetree.
1
Add brief documentation of the new mps3-an547 board.
2
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Message-id: 20200430181003.21682-9-peter.maydell@linaro.org
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20210219144617.4782-44-peter.maydell@linaro.org
6
---
7
---
7
target/arm/neon-shared.decode | 5 +++++
8
docs/system/arm/mps2.rst | 6 ++++--
8
target/arm/translate-neon.inc.c | 40 +++++++++++++++++++++++++++++++++
9
1 file changed, 4 insertions(+), 2 deletions(-)
9
target/arm/translate.c | 26 +--------------------
10
3 files changed, 46 insertions(+), 25 deletions(-)
11
10
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
11
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
13
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
13
--- a/docs/system/arm/mps2.rst
15
+++ b/target/arm/neon-shared.decode
14
+++ b/docs/system/arm/mps2.rst
16
@@ -XXX,XX +XXX,XX @@ VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
15
@@ -XXX,XX +XXX,XX @@
17
vm=%vm_sp vn=%vn_sp vd=%vd_dp q=0
16
-Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``)
18
VFML 1111 110 0 s:1 . 10 .... .... 1000 . 1 . 1 .... \
17
-=========================================================================================================================================
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp q=1
18
+Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an547``)
20
+
19
+=========================================================================================================================================================
21
+VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
20
22
+ vn=%vn_dp vd=%vd_dp size=0
21
These board models all use Arm M-profile CPUs.
23
+VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
22
24
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp size=1 index=0
23
@@ -XXX,XX +XXX,XX @@ QEMU models the following FPGA images:
25
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
24
Dual Cortex-M33 as documented in Arm Application Note AN521
26
index XXXXXXX..XXXXXXX 100644
25
``mps3-an524``
27
--- a/target/arm/translate-neon.inc.c
26
Dual Cortex-M33 on an MPS3, as documented in Arm Application Note AN524
28
+++ b/target/arm/translate-neon.inc.c
27
+``mps3-an547``
29
@@ -XXX,XX +XXX,XX @@ static bool trans_VFML(DisasContext *s, arg_VFML *a)
28
+ Cortex-M55 on an MPS3, as documented in Arm Application Note AN547
30
gen_helper_gvec_fmlal_a32);
29
31
return true;
30
Differences between QEMU and real hardware:
32
}
33
+
34
+static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
35
+{
36
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
37
+ int opr_sz;
38
+ TCGv_ptr fpst;
39
+
40
+ if (!dc_isar_feature(aa32_vcma, s)) {
41
+ return false;
42
+ }
43
+ if (a->size == 0 && !dc_isar_feature(aa32_fp16_arith, s)) {
44
+ return false;
45
+ }
46
+
47
+ /* UNDEF accesses to D16-D31 if they don't exist. */
48
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
49
+ ((a->vd | a->vn | a->vm) & 0x10)) {
50
+ return false;
51
+ }
52
+
53
+ if ((a->vd | a->vn) & a->q) {
54
+ return false;
55
+ }
56
+
57
+ if (!vfp_access_check(s)) {
58
+ return true;
59
+ }
60
+
61
+ fn_gvec_ptr = (a->size ? gen_helper_gvec_fcmlas_idx
62
+ : gen_helper_gvec_fcmlah_idx);
63
+ opr_sz = (1 + a->q) * 8;
64
+ fpst = get_fpstatus_ptr(1);
65
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
66
+ vfp_reg_offset(1, a->vn),
67
+ vfp_reg_offset(1, a->vm),
68
+ fpst, opr_sz, opr_sz,
69
+ (a->index << 2) | a->rot, fn_gvec_ptr);
70
+ tcg_temp_free_ptr(fpst);
71
+ return true;
72
+}
73
diff --git a/target/arm/translate.c b/target/arm/translate.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/target/arm/translate.c
76
+++ b/target/arm/translate.c
77
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
78
bool is_long = false, q = extract32(insn, 6, 1);
79
bool ptr_is_env = false;
80
81
- if ((insn & 0xff000f10) == 0xfe000800) {
82
- /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
83
- int rot = extract32(insn, 20, 2);
84
- int size = extract32(insn, 23, 1);
85
- int index;
86
-
87
- if (!dc_isar_feature(aa32_vcma, s)) {
88
- return 1;
89
- }
90
- if (size == 0) {
91
- if (!dc_isar_feature(aa32_fp16_arith, s)) {
92
- return 1;
93
- }
94
- /* For fp16, rm is just Vm, and index is M. */
95
- rm = extract32(insn, 0, 4);
96
- index = extract32(insn, 5, 1);
97
- } else {
98
- /* For fp32, rm is the usual M:Vm, and index is 0. */
99
- VFP_DREG_M(rm, insn);
100
- index = 0;
101
- }
102
- data = (index << 2) | rot;
103
- fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
104
- : gen_helper_gvec_fcmlah_idx);
105
- } else if ((insn & 0xffb00f00) == 0xfe200d00) {
106
+ if ((insn & 0xffb00f00) == 0xfe200d00) {
107
/* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
108
int u = extract32(insn, 4, 1);
109
31
110
--
32
--
111
2.20.1
33
2.20.1
112
34
113
35
diff view generated by jsdifflib
1
Convert the Neon VMUL, VMLA, VMLS and VSHL insns in the
1
Add a simple qtest to exercise the new system counter device in the
2
3-reg-same grouping to decodetree.
2
SSE-300.
3
4
We'll add tests of the system timer device here too, so this includes
5
scaffolding (register definitions, etc) for those.
3
6
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20200430181003.21682-20-peter.maydell@linaro.org
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20210219144617.4782-45-peter.maydell@linaro.org
7
---
11
---
8
target/arm/neon-dp.decode | 9 +++++++
12
tests/qtest/sse-timer-test.c | 117 +++++++++++++++++++++++++++++++++++
9
target/arm/translate-neon.inc.c | 44 +++++++++++++++++++++++++++++++++
13
MAINTAINERS | 1 +
10
target/arm/translate.c | 28 +++------------------
14
tests/qtest/meson.build | 1 +
11
3 files changed, 56 insertions(+), 25 deletions(-)
15
3 files changed, 119 insertions(+)
16
create mode 100644 tests/qtest/sse-timer-test.c
12
17
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
18
diff --git a/tests/qtest/sse-timer-test.c b/tests/qtest/sse-timer-test.c
14
index XXXXXXX..XXXXXXX 100644
19
new file mode 100644
15
--- a/target/arm/neon-dp.decode
20
index XXXXXXX..XXXXXXX
16
+++ b/target/arm/neon-dp.decode
21
--- /dev/null
17
@@ -XXX,XX +XXX,XX @@ VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
22
+++ b/tests/qtest/sse-timer-test.c
18
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
23
@@ -XXX,XX +XXX,XX @@
19
VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
24
+/*
20
25
+ * QTest testcase for the SSE timer device
21
+VSHL_S_3s 1111 001 0 0 . .. .... .... 0100 . . . 0 .... @3same
26
+ *
22
+VSHL_U_3s 1111 001 1 0 . .. .... .... 0100 . . . 0 .... @3same
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
+ */
23
+
39
+
24
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
40
+#include "qemu/osdep.h"
25
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
41
+#include "libqtest-single.h"
26
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
27
@@ -XXX,XX +XXX,XX @@ VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
28
29
VTST_3s 1111 001 0 0 . .. .... .... 1000 . . . 1 .... @3same
30
VCEQ_3s 1111 001 1 0 . .. .... .... 1000 . . . 1 .... @3same
31
+
42
+
32
+VMLA_3s 1111 001 0 0 . .. .... .... 1001 . . . 0 .... @3same
43
+/*
33
+VMLS_3s 1111 001 1 0 . .. .... .... 1001 . . . 0 .... @3same
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
34
+
48
+
35
+VMUL_3s 1111 001 0 0 . .. .... .... 1001 . . . 1 .... @3same
49
+/* PERIPHNSPPC0 register in the SSE-300 Secure Access Configuration block */
36
+VMUL_p_3s 1111 001 1 0 . .. .... .... 1001 . . . 1 .... @3same
50
+#define PERIPHNSPPC0 (0x50080000 + 0x70)
37
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate-neon.inc.c
40
+++ b/target/arm/translate-neon.inc.c
41
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
42
DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
43
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
44
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
45
+DO_3SAME_NO_SZ_3(VMUL, tcg_gen_gvec_mul)
46
47
#define DO_3SAME_CMP(INSN, COND) \
48
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
49
@@ -XXX,XX +XXX,XX @@ DO_3SAME_GVEC4(VQADD_S, sqadd_op)
50
DO_3SAME_GVEC4(VQADD_U, uqadd_op)
51
DO_3SAME_GVEC4(VQSUB_S, sqsub_op)
52
DO_3SAME_GVEC4(VQSUB_U, uqsub_op)
53
+
51
+
54
+static void gen_VMUL_p_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
52
+/* Base of the System Counter control frame */
55
+ uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
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)
56
+{
79
+{
57
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz,
80
+ /*
58
+ 0, gen_helper_gvec_pmul_b);
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));
59
+}
87
+}
60
+
88
+
61
+static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
89
+static void reset_counter_and_timer(void)
62
+{
90
+{
63
+ if (a->size != 0) {
91
+ /*
64
+ return false;
92
+ * Reset the system counter and the timer between tests. This
65
+ }
93
+ * isn't a full reset, but it's sufficient for what the tests check.
66
+ return do_3same(s, a, gen_VMUL_p_3s);
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);
67
+}
100
+}
68
+
101
+
69
+#define DO_3SAME_GVEC3_NO_SZ_3(INSN, OPARRAY) \
102
+static void test_counter(void)
70
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
103
+{
71
+ uint32_t rn_ofs, uint32_t rm_ofs, \
104
+ /* Basic counter functionality test */
72
+ uint32_t oprsz, uint32_t maxsz) \
73
+ { \
74
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, \
75
+ oprsz, maxsz, &OPARRAY[vece]); \
76
+ } \
77
+ DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
78
+
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
+}
79
+
124
+
80
+DO_3SAME_GVEC3_NO_SZ_3(VMLA, mla_op)
125
+int main(int argc, char **argv)
81
+DO_3SAME_GVEC3_NO_SZ_3(VMLS, mls_op)
126
+{
127
+ int r;
82
+
128
+
83
+#define DO_3SAME_GVEC3_SHIFT(INSN, OPARRAY) \
129
+ g_test_init(&argc, &argv, NULL);
84
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
85
+ uint32_t rn_ofs, uint32_t rm_ofs, \
86
+ uint32_t oprsz, uint32_t maxsz) \
87
+ { \
88
+ /* Note the operation is vshl vd,vm,vn */ \
89
+ tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, \
90
+ oprsz, maxsz, &OPARRAY[vece]); \
91
+ } \
92
+ DO_3SAME(INSN, gen_##INSN##_3s)
93
+
130
+
94
+DO_3SAME_GVEC3_SHIFT(VSHL_S, sshl_op)
131
+ qtest_start("-machine mps3-an547");
95
+DO_3SAME_GVEC3_SHIFT(VSHL_U, ushl_op)
132
+
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
133
+ qtest_add_func("/sse-timer/counter", test_counter);
134
+
135
+ r = g_test_run();
136
+
137
+ qtest_end();
138
+
139
+ return r;
140
+}
141
diff --git a/MAINTAINERS b/MAINTAINERS
97
index XXXXXXX..XXXXXXX 100644
142
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/translate.c
143
--- a/MAINTAINERS
99
+++ b/target/arm/translate.c
144
+++ b/MAINTAINERS
100
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
145
@@ -XXX,XX +XXX,XX @@ F: hw/timer/sse-counter.c
101
}
146
F: include/hw/timer/sse-counter.h
102
return 1;
147
F: hw/timer/sse-timer.c
103
148
F: include/hw/timer/sse-timer.h
104
- case NEON_3R_VMUL: /* VMUL */
149
+F: tests/qtest/sse-timer-test.c
105
- if (u) {
150
F: docs/system/arm/mps2.rst
106
- /* Polynomial case allows only P8. */
151
107
- if (size != 0) {
152
Musca
108
- return 1;
153
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
109
- }
154
index XXXXXXX..XXXXXXX 100644
110
- tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
155
--- a/tests/qtest/meson.build
111
- 0, gen_helper_gvec_pmul_b);
156
+++ b/tests/qtest/meson.build
112
- } else {
157
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
113
- tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
158
'npcm7xx_watchdog_timer-test'] + \
114
- vec_size, vec_size);
159
(slirp.found() ? ['npcm7xx_emc-test'] : [])
115
- }
160
qtests_arm = \
116
- return 0;
161
+ (config_all_devices.has_key('CONFIG_MPS2') ? ['sse-timer-test'] : []) + \
117
-
162
(config_all_devices.has_key('CONFIG_CMSDK_APB_DUALTIMER') ? ['cmsdk-apb-dualtimer-test'] : []) + \
118
- case NEON_3R_VML: /* VMLA, VMLS */
163
(config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
119
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
164
(config_all_devices.has_key('CONFIG_CMSDK_APB_WATCHDOG') ? ['cmsdk-apb-watchdog-test'] : []) + \
120
- u ? &mls_op[size] : &mla_op[size]);
121
- return 0;
122
-
123
- case NEON_3R_VSHL:
124
- /* Note the operation is vshl vd,vm,vn */
125
- tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
126
- u ? &ushl_op[size] : &sshl_op[size]);
127
- return 0;
128
-
129
case NEON_3R_VADD_VSUB:
130
case NEON_3R_LOGIC:
131
case NEON_3R_VMAX:
132
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
133
case NEON_3R_VCGE:
134
case NEON_3R_VQADD:
135
case NEON_3R_VQSUB:
136
+ case NEON_3R_VMUL:
137
+ case NEON_3R_VML:
138
+ case NEON_3R_VSHL:
139
/* Already handled by decodetree */
140
return 1;
141
}
142
--
165
--
143
2.20.1
166
2.20.1
144
167
145
168
diff view generated by jsdifflib
1
Convert the Neon 3-reg-same VADD and VSUB insns to decodetree.
1
Add a test which tests various parts of the functionality of the
2
2
SSE system timer.
3
Note that we don't need the neon_3r_sizes[op] check here because all
4
size values are OK for VADD and VSUB; we'll add this when we convert
5
the first insn that has size restrictions.
6
7
For this we need one of the GVecGen*Fn typedefs currently in
8
translate-a64.h; move them all to translate.h as a block so they
9
are visible to the 32-bit decoder.
10
3
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20200430181003.21682-15-peter.maydell@linaro.org
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
---
7
---
15
target/arm/translate-a64.h | 9 --------
8
tests/qtest/sse-timer-test.c | 91 ++++++++++++++++++++++++++++++++++++
16
target/arm/translate.h | 9 ++++++++
9
1 file changed, 91 insertions(+)
17
target/arm/neon-dp.decode | 17 +++++++++++++++
18
target/arm/translate-neon.inc.c | 38 +++++++++++++++++++++++++++++++++
19
target/arm/translate.c | 14 ++++--------
20
5 files changed, 68 insertions(+), 19 deletions(-)
21
10
22
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
11
diff --git a/tests/qtest/sse-timer-test.c b/tests/qtest/sse-timer-test.c
23
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/translate-a64.h
13
--- a/tests/qtest/sse-timer-test.c
25
+++ b/target/arm/translate-a64.h
14
+++ b/tests/qtest/sse-timer-test.c
26
@@ -XXX,XX +XXX,XX @@ static inline int vec_full_reg_size(DisasContext *s)
15
@@ -XXX,XX +XXX,XX @@ static void test_counter(void)
27
16
g_assert_cmpuint(readl(COUNTER_BASE + CNTCV_HI), ==, 0);
28
bool disas_sve(DisasContext *, uint32_t);
17
}
29
18
30
-/* Note that the gvec expanders operate on offsets + sizes. */
19
+static void test_timer(void)
31
-typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
20
+{
32
-typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
21
+ /* Basic timer functionality test */
33
- uint32_t, uint32_t);
34
-typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
35
- uint32_t, uint32_t, uint32_t);
36
-typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
37
- uint32_t, uint32_t, uint32_t);
38
-
39
#endif /* TARGET_ARM_TRANSLATE_A64_H */
40
diff --git a/target/arm/translate.h b/target/arm/translate.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate.h
43
+++ b/target/arm/translate.h
44
@@ -XXX,XX +XXX,XX @@ void gen_sshl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
45
#define dc_isar_feature(name, ctx) \
46
({ DisasContext *ctx_ = (ctx); isar_feature_##name(ctx_->isar); })
47
48
+/* Note that the gvec expanders operate on offsets + sizes. */
49
+typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
50
+typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
51
+ uint32_t, uint32_t);
52
+typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
53
+ uint32_t, uint32_t, uint32_t);
54
+typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
55
+ uint32_t, uint32_t, uint32_t);
56
+
22
+
57
#endif /* TARGET_ARM_TRANSLATE_H */
23
+ reset_counter_and_timer();
58
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
24
+ /*
59
index XXXXXXX..XXXXXXX 100644
25
+ * The timer is behind a Peripheral Protection Controller, and
60
--- a/target/arm/neon-dp.decode
26
+ * qtest accesses are always non-secure (no memory attributes),
61
+++ b/target/arm/neon-dp.decode
27
+ * so we must program the PPC to accept NS transactions. TIMER0
62
@@ -XXX,XX +XXX,XX @@
28
+ * is on port 0 of PPC0, controlled by bit 0 of this register.
63
#
29
+ */
64
# This file is processed by scripts/decodetree.py
30
+ writel(PERIPHNSPPC0, 1);
65
#
31
+ /* We must enable the System Counter or the timer won't run. */
66
+# VFP/Neon register fields; same as vfp.decode
32
+ writel(COUNTER_BASE + CNTCR, 1);
67
+%vm_dp 5:1 0:4
68
+%vn_dp 7:1 16:4
69
+%vd_dp 22:1 12:4
70
71
# Encodings for Neon data processing instructions where the T32 encoding
72
# is a simple transformation of the A32 encoding.
73
@@ -XXX,XX +XXX,XX @@
74
# 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
75
# This file works on the A32 encoding only; calling code for T32 has to
76
# transform the insn into the A32 version first.
77
+
33
+
78
+######################################################################
34
+ /* Timer starts disabled and with a counter of 0 */
79
+# 3-reg-same grouping:
35
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 0);
80
+# 1111 001 U 0 D sz:2 Vn:4 Vd:4 opc:4 N Q M op Vm:4
36
+ g_assert_cmpuint(readl(TIMER_BASE + CNTPCT_LO), ==, 0);
81
+######################################################################
37
+ g_assert_cmpuint(readl(TIMER_BASE + CNTPCT_HI), ==, 0);
82
+
38
+
83
+&3same vm vn vd q size
39
+ /* Turn it on */
40
+ writel(TIMER_BASE + CNTP_CTL, 1);
84
+
41
+
85
+@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
42
+ /* Is the timer ticking? */
86
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
43
+ clock_step_ticks(100);
44
+ g_assert_cmpuint(readl(TIMER_BASE + CNTPCT_LO), ==, 100);
45
+ g_assert_cmpuint(readl(TIMER_BASE + CNTPCT_HI), ==, 0);
87
+
46
+
88
+VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
47
+ /* Set the CompareValue to 4000 ticks */
89
+VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
48
+ writel(TIMER_BASE + CNTP_CVAL_LO, 4000);
90
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
49
+ writel(TIMER_BASE + CNTP_CVAL_HI, 0);
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/translate-neon.inc.c
93
+++ b/target/arm/translate-neon.inc.c
94
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
95
96
return true;
97
}
98
+
50
+
99
+static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
51
+ /* Check TVAL view of the counter */
100
+{
52
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_TVAL), ==, 3900);
101
+ int vec_size = a->q ? 16 : 8;
102
+ int rd_ofs = neon_reg_offset(a->vd, 0);
103
+ int rn_ofs = neon_reg_offset(a->vn, 0);
104
+ int rm_ofs = neon_reg_offset(a->vm, 0);
105
+
53
+
106
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
54
+ /* Advance to the CompareValue mark and check ISTATUS is set */
107
+ return false;
55
+ clock_step_ticks(3900);
108
+ }
56
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_TVAL), ==, 0);
57
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 5);
109
+
58
+
110
+ /* UNDEF accesses to D16-D31 if they don't exist. */
59
+ /* Now exercise the auto-reload part of the timer */
111
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
60
+ writel(TIMER_BASE + CNTP_AIVAL_RELOAD, 200);
112
+ ((a->vd | a->vn | a->vm) & 0x10)) {
61
+ writel(TIMER_BASE + CNTP_AIVAL_CTL, 1);
113
+ return false;
114
+ }
115
+
62
+
116
+ if ((a->vn | a->vm | a->vd) & a->q) {
63
+ /* Check AIVAL was reloaded and that ISTATUS is now clear */
117
+ return false;
64
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_AIVAL_LO), ==, 4200);
118
+ }
65
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_AIVAL_HI), ==, 0);
66
+ g_assert_cmpuint(readl(TIMER_BASE + CNTP_CTL), ==, 1);
119
+
67
+
120
+ if (!vfp_access_check(s)) {
68
+ /*
121
+ return true;
69
+ * Check that when we advance forward to the reload time the interrupt
122
+ }
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);
123
+
78
+
124
+ fn(a->size, rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
79
+ clock_step_ticks(100);
125
+ return true;
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);
126
+}
107
+}
127
+
108
+
128
+#define DO_3SAME(INSN, FUNC) \
109
int main(int argc, char **argv)
129
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
110
{
130
+ { \
111
int r;
131
+ return do_3same(s, a, FUNC); \
112
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
132
+ }
113
qtest_start("-machine mps3-an547");
133
+
114
134
+DO_3SAME(VADD, tcg_gen_gvec_add)
115
qtest_add_func("/sse-timer/counter", test_counter);
135
+DO_3SAME(VSUB, tcg_gen_gvec_sub)
116
+ qtest_add_func("/sse-timer/timer", test_timer);
136
diff --git a/target/arm/translate.c b/target/arm/translate.c
117
137
index XXXXXXX..XXXXXXX 100644
118
r = g_test_run();
138
--- a/target/arm/translate.c
119
139
+++ b/target/arm/translate.c
140
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
141
}
142
return 0;
143
144
- case NEON_3R_VADD_VSUB:
145
- if (u) {
146
- tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
147
- vec_size, vec_size);
148
- } else {
149
- tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
150
- vec_size, vec_size);
151
- }
152
- return 0;
153
-
154
case NEON_3R_VQADD:
155
tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
156
rn_ofs, rm_ofs, vec_size, vec_size,
157
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
158
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
159
u ? &ushl_op[size] : &sshl_op[size]);
160
return 0;
161
+
162
+ case NEON_3R_VADD_VSUB:
163
+ /* Already handled by decodetree */
164
+ return 1;
165
}
166
167
if (size == 3) {
168
--
120
--
169
2.20.1
121
2.20.1
170
122
171
123
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
Test that when we change the scaling of the system counter that the
2
system timer responds appropriately.
2
3
3
hw/arm: versal: Add support for the RTC.
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
---
8
tests/qtest/sse-timer-test.c | 32 ++++++++++++++++++++++++++++++++
9
1 file changed, 32 insertions(+)
4
10
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
diff --git a/tests/qtest/sse-timer-test.c b/tests/qtest/sse-timer-test.c
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-10-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/arm/xlnx-versal.h | 8 ++++++++
13
hw/arm/xlnx-versal.c | 21 +++++++++++++++++++++
14
2 files changed, 29 insertions(+)
15
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
17
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
13
--- a/tests/qtest/sse-timer-test.c
19
+++ b/include/hw/arm/xlnx-versal.h
14
+++ b/tests/qtest/sse-timer-test.c
20
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static void test_timer(void)
21
#include "hw/char/pl011.h"
16
g_assert_cmpuint(readl(TIMER_BASE + CNTP_AIVAL_HI), ==, 0x42);
22
#include "hw/dma/xlnx-zdma.h"
23
#include "hw/net/cadence_gem.h"
24
+#include "hw/rtc/xlnx-zynqmp-rtc.h"
25
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
27
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
28
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
29
struct {
30
SDHCIState sd[XLNX_VERSAL_NR_SDS];
31
} iou;
32
+
33
+ XlnxZynqMPRTC rtc;
34
} pmc;
35
36
struct {
37
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
38
#define VERSAL_GEM1_IRQ_0 58
39
#define VERSAL_GEM1_WAKE_IRQ_0 59
40
#define VERSAL_ADMA_IRQ_0 60
41
+#define VERSAL_RTC_APB_ERR_IRQ 121
42
#define VERSAL_SD0_IRQ_0 126
43
+#define VERSAL_RTC_ALARM_IRQ 142
44
+#define VERSAL_RTC_SECONDS_IRQ 143
45
46
/* Architecturally reserved IRQs suitable for virtualization. */
47
#define VERSAL_RSVD_IRQ_FIRST 111
48
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
49
#define MM_PMC_SD0_SIZE 0x10000
50
#define MM_PMC_CRP 0xf1260000U
51
#define MM_PMC_CRP_SIZE 0x10000
52
+#define MM_PMC_RTC 0xf12a0000
53
+#define MM_PMC_RTC_SIZE 0x10000
54
#endif
55
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/xlnx-versal.c
58
+++ b/hw/arm/xlnx-versal.c
59
@@ -XXX,XX +XXX,XX @@ static void versal_create_sds(Versal *s, qemu_irq *pic)
60
}
61
}
17
}
62
18
63
+static void versal_create_rtc(Versal *s, qemu_irq *pic)
19
+static void test_timer_scale_change(void)
64
+{
20
+{
65
+ SysBusDevice *sbd;
66
+ MemoryRegion *mr;
67
+
68
+ sysbus_init_child_obj(OBJECT(s), "rtc", &s->pmc.rtc, sizeof(s->pmc.rtc),
69
+ TYPE_XLNX_ZYNQMP_RTC);
70
+ sbd = SYS_BUS_DEVICE(&s->pmc.rtc);
71
+ qdev_init_nofail(DEVICE(sbd));
72
+
73
+ mr = sysbus_mmio_get_region(sbd, 0);
74
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_RTC, mr);
75
+
76
+ /*
21
+ /*
77
+ * TODO: Connect the ALARM and SECONDS interrupts once our RTC model
22
+ * Test that the timer responds correctly to counter
78
+ * supports them.
23
+ * scaling changes while it has an active timer.
79
+ */
24
+ */
80
+ sysbus_connect_irq(sbd, 1, pic[VERSAL_RTC_APB_ERR_IRQ]);
25
+ reset_counter_and_timer();
26
+ /* Give ourselves access to the timer, and enable the counter and timer */
27
+ writel(PERIPHNSPPC0, 1);
28
+ writel(COUNTER_BASE + CNTCR, 1);
29
+ writel(TIMER_BASE + CNTP_CTL, 1);
30
+ /* Set the CompareValue to 4000 ticks */
31
+ writel(TIMER_BASE + CNTP_CVAL_LO, 4000);
32
+ writel(TIMER_BASE + CNTP_CVAL_HI, 0);
33
+ /* Advance halfway and check ISTATUS is not set */
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);
81
+}
48
+}
82
+
49
+
83
/* This takes the board allocated linear DDR memory and creates aliases
50
int main(int argc, char **argv)
84
* for each split DDR range/aperture on the Versal address map.
51
{
85
*/
52
int r;
86
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
53
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
87
versal_create_gems(s, pic);
54
88
versal_create_admas(s, pic);
55
qtest_add_func("/sse-timer/counter", test_counter);
89
versal_create_sds(s, pic);
56
qtest_add_func("/sse-timer/timer", test_timer);
90
+ versal_create_rtc(s, pic);
57
+ qtest_add_func("/sse-timer/timer-scale-change", test_timer_scale_change);
91
versal_map_ddr(s);
58
92
versal_unimp(s);
59
r = g_test_run();
93
60
94
--
61
--
95
2.20.1
62
2.20.1
96
63
97
64
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
MIDR_EL1 is a 64-bit system register with the top 32-bit being RES0.
3
KVM requires the target cpu to be at least ARMv8 architecture
4
Represent it in QEMU's ARMCPU struct with a uint64_t, not a
4
(support on ARMv7 has been dropped in commit 82bf7ae84ce:
5
uint32_t.
5
"target/arm: Remove KVM support for 32-bit Arm hosts").
6
6
7
This fixes an error when compiling with -Werror=conversion
7
A KVM-only build won't be able to run TCG cpus, move the
8
because we were manipulating the register value using a
8
v7A CPU definitions to cpu_tcg.c.
9
local uint64_t variable:
10
9
11
target/arm/cpu64.c: In function ‘aarch64_max_initfn’:
10
Reported-by: Peter Maydell <peter.maydell@linaro.org>
12
target/arm/cpu64.c:628:21: error: conversion from ‘uint64_t’ {aka ‘long unsigned int’} to ‘uint32_t’ {aka ‘unsigned int’} may change value [-Werror=conversion]
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
628 | cpu->midr = t;
14
| ^
15
16
and future-proofs us against a possible future architecture
17
change using some of the top 32 bits.
18
19
Suggested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
20
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
22
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
13
Message-id: 20210306151801.2388182-1-f4bug@amsat.org
23
Message-id: 20200428172634.29707-1-f4bug@amsat.org
24
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
---
15
---
27
target/arm/cpu.h | 2 +-
16
target/arm/cpu.c | 335 -------------------------------------------
28
target/arm/cpu.c | 2 +-
17
target/arm/cpu_tcg.c | 318 ++++++++++++++++++++++++++++++++++++++++
29
2 files changed, 2 insertions(+), 2 deletions(-)
18
2 files changed, 318 insertions(+), 335 deletions(-)
30
19
31
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/cpu.h
34
+++ b/target/arm/cpu.h
35
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
36
uint64_t id_aa64dfr0;
37
uint64_t id_aa64dfr1;
38
} isar;
39
- uint32_t midr;
40
+ uint64_t midr;
41
uint32_t revidr;
42
uint32_t reset_fpsid;
43
uint32_t ctr;
44
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
20
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
45
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/cpu.c
22
--- a/target/arm/cpu.c
47
+++ b/target/arm/cpu.c
23
+++ b/target/arm/cpu.c
48
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
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
-
49
static Property arm_cpu_properties[] = {
353
static Property arm_cpu_properties[] = {
50
DEFINE_PROP_BOOL("start-powered-off", ARMCPU, start_powered_off, false),
51
DEFINE_PROP_UINT32("psci-conduit", ARMCPU, psci_conduit, 0),
354
DEFINE_PROP_UINT32("psci-conduit", ARMCPU, psci_conduit, 0),
52
- DEFINE_PROP_UINT32("midr", ARMCPU, midr, 0),
355
DEFINE_PROP_UINT64("midr", ARMCPU, midr, 0),
53
+ DEFINE_PROP_UINT64("midr", ARMCPU, midr, 0),
356
@@ -XXX,XX +XXX,XX @@ static const TypeInfo arm_cpu_type_info = {
54
DEFINE_PROP_UINT64("mp-affinity", ARMCPU,
357
55
mp_affinity, ARM64_AFFINITY_INVALID),
358
static void arm_cpu_register_types(void)
56
DEFINE_PROP_INT32("node-id", ARMCPU, node_id, CPU_UNSET_NUMA_NODE_ID),
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 = {
57
--
735
--
58
2.20.1
736
2.20.1
59
737
60
738
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Xuzhou Cheng <xuzhou.cheng@windriver.com>
2
2
3
Embed the UARTs into the SoC type.
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.
4
6
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
7
This adds a Xilinx CSU DMA model and the implementation is based on
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
https://github.com/Xilinx/qemu/blob/master/hw/dma/csu_stream_dma.c.
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
The DST part of the model is verified along with ZynqMP GQSPI model.
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
11
Signed-off-by: Xuzhou Cheng <xuzhou.cheng@windriver.com>
10
Message-id: 20200427181649.26851-5-edgar.iglesias@gmail.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
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
17
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
18
include/hw/dma/xlnx_csu_dma.h | 52 +++
14
hw/arm/xlnx-versal.c | 12 ++++++------
19
hw/dma/xlnx_csu_dma.c | 745 ++++++++++++++++++++++++++++++++++
15
2 files changed, 8 insertions(+), 7 deletions(-)
20
hw/dma/Kconfig | 4 +
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
16
25
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
26
diff --git a/include/hw/dma/xlnx_csu_dma.h b/include/hw/dma/xlnx_csu_dma.h
27
new file mode 100644
28
index XXXXXXX..XXXXXXX
29
--- /dev/null
30
+++ b/include/hw/dma/xlnx_csu_dma.h
31
@@ -XXX,XX +XXX,XX @@
32
+/*
33
+ * Xilinx Platform CSU Stream DMA emulation
34
+ *
35
+ * This implementation is based on
36
+ * https://github.com/Xilinx/qemu/blob/master/hw/dma/csu_stream_dma.c
37
+ *
38
+ * This program is free software; you can redistribute it and/or
39
+ * modify it under the terms of the GNU General Public License as
40
+ * published by the Free Software Foundation; either version 2 or
41
+ * (at your option) version 3 of the License.
42
+ *
43
+ * This program is distributed in the hope that it will be useful,
44
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
45
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
46
+ * GNU General Public License for more details.
47
+ *
48
+ * You should have received a copy of the GNU General Public License along
49
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
50
+ */
51
+
52
+#ifndef XLNX_CSU_DMA_H
53
+#define XLNX_CSU_DMA_H
54
+
55
+#define TYPE_XLNX_CSU_DMA "xlnx.csu_dma"
56
+
57
+#define XLNX_CSU_DMA_R_MAX (0x2c / 4)
58
+
59
+typedef struct XlnxCSUDMA {
60
+ SysBusDevice busdev;
61
+ MemoryRegion iomem;
62
+ MemTxAttrs attr;
63
+ MemoryRegion *dma_mr;
64
+ AddressSpace *dma_as;
65
+ qemu_irq irq;
66
+ StreamSink *tx_dev; /* Used as generic StreamSink */
67
+ ptimer_state *src_timer;
68
+
69
+ uint16_t width;
70
+ bool is_dst;
71
+ bool r_size_last_word;
72
+
73
+ StreamCanPushNotifyFn notify;
74
+ void *notify_opaque;
75
+
76
+ uint32_t regs[XLNX_CSU_DMA_R_MAX];
77
+ RegisterInfo regs_info[XLNX_CSU_DMA_R_MAX];
78
+} XlnxCSUDMA;
79
+
80
+#define XLNX_CSU_DMA(obj) \
81
+ OBJECT_CHECK(XlnxCSUDMA, (obj), TYPE_XLNX_CSU_DMA)
82
+
83
+#endif
84
diff --git a/hw/dma/xlnx_csu_dma.c b/hw/dma/xlnx_csu_dma.c
85
new file mode 100644
86
index XXXXXXX..XXXXXXX
87
--- /dev/null
88
+++ b/hw/dma/xlnx_csu_dma.c
89
@@ -XXX,XX +XXX,XX @@
90
+/*
91
+ * Xilinx Platform CSU Stream DMA emulation
92
+ *
93
+ * This implementation is based on
94
+ * https://github.com/Xilinx/qemu/blob/master/hw/dma/csu_stream_dma.c
95
+ *
96
+ * This program is free software; you can redistribute it and/or
97
+ * modify it under the terms of the GNU General Public License as
98
+ * published by the Free Software Foundation; either version 2 or
99
+ * (at your option) version 3 of the License.
100
+ *
101
+ * This program is distributed in the hope that it will be useful,
102
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
103
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
104
+ * GNU General Public License for more details.
105
+ *
106
+ * You should have received a copy of the GNU General Public License along
107
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
108
+ */
109
+
110
+#include "qemu/osdep.h"
111
+#include "qemu/log.h"
112
+#include "qapi/error.h"
113
+#include "hw/hw.h"
114
+#include "hw/irq.h"
115
+#include "hw/qdev-properties.h"
116
+#include "hw/sysbus.h"
117
+#include "migration/vmstate.h"
118
+#include "sysemu/dma.h"
119
+#include "hw/ptimer.h"
120
+#include "hw/stream.h"
121
+#include "hw/register.h"
122
+#include "hw/dma/xlnx_csu_dma.h"
123
+
124
+/*
125
+ * Ref: UG1087 (v1.7) February 8, 2019
126
+ * https://www.xilinx.com/html_docs/registers/ug1087/ug1087-zynq-ultrascale-registers.html
127
+ * CSUDMA Module section
128
+ */
129
+REG32(ADDR, 0x0)
130
+ FIELD(ADDR, ADDR, 2, 30) /* wo */
131
+REG32(SIZE, 0x4)
132
+ FIELD(SIZE, SIZE, 2, 27) /* wo */
133
+ FIELD(SIZE, LAST_WORD, 0, 1) /* rw, only exists in SRC */
134
+REG32(STATUS, 0x8)
135
+ FIELD(STATUS, DONE_CNT, 13, 3) /* wtc */
136
+ FIELD(STATUS, FIFO_LEVEL, 5, 8) /* ro */
137
+ FIELD(STATUS, OUTSTANDING, 1, 4) /* ro */
138
+ FIELD(STATUS, BUSY, 0, 1) /* ro */
139
+REG32(CTRL, 0xc)
140
+ FIELD(CTRL, FIFOTHRESH, 25, 7) /* rw, only exists in DST, reset 0x40 */
141
+ FIELD(CTRL, APB_ERR_RESP, 24, 1) /* rw */
142
+ FIELD(CTRL, ENDIANNESS, 23, 1) /* rw */
143
+ FIELD(CTRL, AXI_BRST_TYPE, 22, 1) /* rw */
144
+ FIELD(CTRL, TIMEOUT_VAL, 10, 12) /* rw, reset: 0xFFE */
145
+ FIELD(CTRL, FIFO_THRESH, 2, 8) /* rw, reset: 0x80 */
146
+ FIELD(CTRL, PAUSE_STRM, 1, 1) /* rw */
147
+ FIELD(CTRL, PAUSE_MEM, 0, 1) /* rw */
148
+REG32(CRC, 0x10)
149
+REG32(INT_STATUS, 0x14)
150
+ FIELD(INT_STATUS, FIFO_OVERFLOW, 7, 1) /* wtc */
151
+ FIELD(INT_STATUS, INVALID_APB, 6, 1) /* wtc */
152
+ FIELD(INT_STATUS, THRESH_HIT, 5, 1) /* wtc */
153
+ FIELD(INT_STATUS, TIMEOUT_MEM, 4, 1) /* wtc */
154
+ FIELD(INT_STATUS, TIMEOUT_STRM, 3, 1) /* wtc */
155
+ FIELD(INT_STATUS, AXI_BRESP_ERR, 2, 1) /* wtc, SRC: AXI_RDERR */
156
+ FIELD(INT_STATUS, DONE, 1, 1) /* wtc */
157
+ FIELD(INT_STATUS, MEM_DONE, 0, 1) /* wtc */
158
+REG32(INT_ENABLE, 0x18)
159
+ FIELD(INT_ENABLE, FIFO_OVERFLOW, 7, 1) /* wtc */
160
+ FIELD(INT_ENABLE, INVALID_APB, 6, 1) /* wtc */
161
+ FIELD(INT_ENABLE, THRESH_HIT, 5, 1) /* wtc */
162
+ FIELD(INT_ENABLE, TIMEOUT_MEM, 4, 1) /* wtc */
163
+ FIELD(INT_ENABLE, TIMEOUT_STRM, 3, 1) /* wtc */
164
+ FIELD(INT_ENABLE, AXI_BRESP_ERR, 2, 1) /* wtc, SRC: AXI_RDERR */
165
+ FIELD(INT_ENABLE, DONE, 1, 1) /* wtc */
166
+ FIELD(INT_ENABLE, MEM_DONE, 0, 1) /* wtc */
167
+REG32(INT_DISABLE, 0x1c)
168
+ FIELD(INT_DISABLE, FIFO_OVERFLOW, 7, 1) /* wtc */
169
+ FIELD(INT_DISABLE, INVALID_APB, 6, 1) /* wtc */
170
+ FIELD(INT_DISABLE, THRESH_HIT, 5, 1) /* wtc */
171
+ FIELD(INT_DISABLE, TIMEOUT_MEM, 4, 1) /* wtc */
172
+ FIELD(INT_DISABLE, TIMEOUT_STRM, 3, 1) /* wtc */
173
+ FIELD(INT_DISABLE, AXI_BRESP_ERR, 2, 1) /* wtc, SRC: AXI_RDERR */
174
+ FIELD(INT_DISABLE, DONE, 1, 1) /* wtc */
175
+ FIELD(INT_DISABLE, MEM_DONE, 0, 1) /* wtc */
176
+REG32(INT_MASK, 0x20)
177
+ FIELD(INT_MASK, FIFO_OVERFLOW, 7, 1) /* ro, reset: 0x1 */
178
+ FIELD(INT_MASK, INVALID_APB, 6, 1) /* ro, reset: 0x1 */
179
+ FIELD(INT_MASK, THRESH_HIT, 5, 1) /* ro, reset: 0x1 */
180
+ FIELD(INT_MASK, TIMEOUT_MEM, 4, 1) /* ro, reset: 0x1 */
181
+ FIELD(INT_MASK, TIMEOUT_STRM, 3, 1) /* ro, reset: 0x1 */
182
+ FIELD(INT_MASK, AXI_BRESP_ERR, 2, 1) /* ro, reset: 0x1, SRC: AXI_RDERR */
183
+ FIELD(INT_MASK, DONE, 1, 1) /* ro, reset: 0x1 */
184
+ FIELD(INT_MASK, MEM_DONE, 0, 1) /* ro, reset: 0x1 */
185
+REG32(CTRL2, 0x24)
186
+ FIELD(CTRL2, ARCACHE, 24, 3) /* rw */
187
+ FIELD(CTRL2, ROUTE_BIT, 23, 1) /* rw */
188
+ FIELD(CTRL2, TIMEOUT_EN, 22, 1) /* rw */
189
+ FIELD(CTRL2, TIMEOUT_PRE, 4, 12) /* rw, reset: 0xFFF */
190
+ FIELD(CTRL2, MAX_OUTS_CMDS, 0, 4) /* rw, reset: 0x8 */
191
+REG32(ADDR_MSB, 0x28)
192
+ FIELD(ADDR_MSB, ADDR_MSB, 0, 17) /* wo */
193
+
194
+#define R_CTRL_TIMEOUT_VAL_RESET (0xFFE)
195
+#define R_CTRL_FIFO_THRESH_RESET (0x80)
196
+#define R_CTRL_FIFOTHRESH_RESET (0x40)
197
+
198
+#define R_CTRL2_TIMEOUT_PRE_RESET (0xFFF)
199
+#define R_CTRL2_MAX_OUTS_CMDS_RESET (0x8)
200
+
201
+#define XLNX_CSU_DMA_ERR_DEBUG (0)
202
+#define XLNX_CSU_DMA_INT_R_MASK (0xff)
203
+
204
+/* UG1807: Set the prescaler value for the timeout in clk (~2.5ns) cycles */
205
+#define XLNX_CSU_DMA_TIMER_FREQ (400 * 1000 * 1000)
206
+
207
+static bool xlnx_csu_dma_is_paused(XlnxCSUDMA *s)
208
+{
209
+ bool paused;
210
+
211
+ paused = !!(s->regs[R_CTRL] & R_CTRL_PAUSE_STRM_MASK);
212
+ paused |= !!(s->regs[R_CTRL] & R_CTRL_PAUSE_MEM_MASK);
213
+
214
+ return paused;
215
+}
216
+
217
+static bool xlnx_csu_dma_get_eop(XlnxCSUDMA *s)
218
+{
219
+ return s->r_size_last_word;
220
+}
221
+
222
+static bool xlnx_csu_dma_burst_is_fixed(XlnxCSUDMA *s)
223
+{
224
+ return !!(s->regs[R_CTRL] & R_CTRL_AXI_BRST_TYPE_MASK);
225
+}
226
+
227
+static bool xlnx_csu_dma_timeout_enabled(XlnxCSUDMA *s)
228
+{
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
18
index XXXXXXX..XXXXXXX 100644
836
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
837
--- a/hw/dma/Kconfig
20
+++ b/include/hw/arm/xlnx-versal.h
838
+++ b/hw/dma/Kconfig
21
@@ -XXX,XX +XXX,XX @@
839
@@ -XXX,XX +XXX,XX @@ config STP2000
22
#include "hw/sysbus.h"
840
23
#include "hw/arm/boot.h"
841
config SIFIVE_PDMA
24
#include "hw/intc/arm_gicv3.h"
842
bool
25
+#include "hw/char/pl011.h"
843
+
26
844
+config XLNX_CSU_DMA
27
#define TYPE_XLNX_VERSAL "xlnx-versal"
845
+ bool
28
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
846
+ select REGISTER
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
847
diff --git a/hw/dma/meson.build b/hw/dma/meson.build
30
MemoryRegion mr_ocm;
31
32
struct {
33
- SysBusDevice *uart[XLNX_VERSAL_NR_UARTS];
34
+ PL011State uart[XLNX_VERSAL_NR_UARTS];
35
SysBusDevice *gem[XLNX_VERSAL_NR_GEMS];
36
SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
37
} iou;
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
39
index XXXXXXX..XXXXXXX 100644
848
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/xlnx-versal.c
849
--- a/hw/dma/meson.build
41
+++ b/hw/arm/xlnx-versal.c
850
+++ b/hw/dma/meson.build
42
@@ -XXX,XX +XXX,XX @@
851
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_dma.c', 'soc_dma.c'))
43
#include "kvm_arm.h"
852
softmmu_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_dma.c'))
44
#include "hw/misc/unimp.h"
853
softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_dma.c'))
45
#include "hw/arm/xlnx-versal.h"
854
softmmu_ss.add(when: 'CONFIG_SIFIVE_PDMA', if_true: files('sifive_pdma.c'))
46
-#include "hw/char/pl011.h"
855
+softmmu_ss.add(when: 'CONFIG_XLNX_CSU_DMA', if_true: files('xlnx_csu_dma.c'))
47
48
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
49
#define GEM_REVISION 0x40070106
50
@@ -XXX,XX +XXX,XX @@ static void versal_create_uarts(Versal *s, qemu_irq *pic)
51
DeviceState *dev;
52
MemoryRegion *mr;
53
54
- dev = qdev_create(NULL, TYPE_PL011);
55
- s->lpd.iou.uart[i] = SYS_BUS_DEVICE(dev);
56
+ sysbus_init_child_obj(OBJECT(s), name,
57
+ &s->lpd.iou.uart[i], sizeof(s->lpd.iou.uart[i]),
58
+ TYPE_PL011);
59
+ dev = DEVICE(&s->lpd.iou.uart[i]);
60
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
61
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
62
qdev_init_nofail(dev);
63
64
- mr = sysbus_mmio_get_region(s->lpd.iou.uart[i], 0);
65
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
66
memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
67
68
- sysbus_connect_irq(s->lpd.iou.uart[i], 0, pic[irqs[i]]);
69
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
70
g_free(name);
71
}
72
}
73
--
856
--
74
2.20.1
857
2.20.1
75
858
76
859
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Xuzhou Cheng <xuzhou.cheng@windriver.com>
2
2
3
Fix typo xlnx-ve -> xlnx-versal.
3
There are some coding convention warnings in xlnx-zynqmp.c and
4
xlnx-zynqmp.h, as reported by:
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
$ ./scripts/checkpatch.pl include/hw/arm/xlnx-zynqmp.h
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
$ ./scripts/checkpatch.pl hw/arm/xlnx-zynqmp.c
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Let's clean them up.
9
Message-id: 20200427181649.26851-4-edgar.iglesias@gmail.com
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
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
16
---
12
hw/arm/xlnx-versal-virt.c | 2 +-
17
include/hw/arm/xlnx-zynqmp.h | 3 ++-
13
1 file changed, 1 insertion(+), 1 deletion(-)
18
hw/arm/xlnx-zynqmp.c | 9 ++++++---
19
2 files changed, 8 insertions(+), 4 deletions(-)
14
20
15
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
21
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
16
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal-virt.c
23
--- a/include/hw/arm/xlnx-zynqmp.h
18
+++ b/hw/arm/xlnx-versal-virt.c
24
+++ b/include/hw/arm/xlnx-zynqmp.h
19
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
25
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
20
psci_conduit = QEMU_PSCI_CONDUIT_SMC;
26
21
}
27
#define XLNX_ZYNQMP_GIC_REGIONS 6
22
28
23
- sysbus_init_child_obj(OBJECT(machine), "xlnx-ve", &s->soc,
29
-/* ZynqMP maps the ARM GIC regions (GICC, GICD ...) at consecutive 64k offsets
24
+ sysbus_init_child_obj(OBJECT(machine), "xlnx-versal", &s->soc,
30
+/*
25
sizeof(s->soc), TYPE_XLNX_VERSAL);
31
+ * ZynqMP maps the ARM GIC regions (GICC, GICD ...) at consecutive 64k offsets
26
object_property_set_link(OBJECT(&s->soc), OBJECT(machine->ram),
32
* and under-decodes the 64k region. This mirrors the 4k regions to every 4k
27
"ddr", &error_abort);
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
28
--
65
--
29
2.20.1
66
2.20.1
30
67
31
68
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Xuzhou Cheng <xuzhou.cheng@windriver.com>
2
2
3
Remove inclusion of arm_gicv3_common.h, this already gets
3
Add a Xilinx CSU DMA module to ZynqMP SoC, and connent the stream
4
included via xlnx-versal.h.
4
link of GQSPI to CSU DMA.
5
5
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Signed-off-by: Xuzhou Cheng <xuzhou.cheng@windriver.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Message-id: 20200427181649.26851-2-edgar.iglesias@gmail.com
9
Message-id: 20210303135254.3970-4-bmeng.cn@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
hw/arm/xlnx-versal.c | 1 -
12
include/hw/arm/xlnx-zynqmp.h | 2 ++
13
1 file changed, 1 deletion(-)
13
hw/arm/xlnx-zynqmp.c | 12 ++++++++++++
14
hw/arm/Kconfig | 1 +
15
3 files changed, 15 insertions(+)
14
16
15
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
17
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal.c
19
--- a/include/hw/arm/xlnx-zynqmp.h
18
+++ b/hw/arm/xlnx-versal.c
20
+++ b/include/hw/arm/xlnx-zynqmp.h
19
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
20
#include "hw/arm/boot.h"
22
#include "target/arm/cpu.h"
21
#include "kvm_arm.h"
23
#include "qom/object.h"
22
#include "hw/misc/unimp.h"
24
#include "net/can_emu.h"
23
-#include "hw/intc/arm_gicv3_common.h"
25
+#include "hw/dma/xlnx_csu_dma.h"
24
#include "hw/arm/xlnx-versal.h"
26
25
#include "hw/char/pl011.h"
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
26
85
27
--
86
--
28
2.20.1
87
2.20.1
29
88
30
89
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Xuzhou Cheng <xuzhou.cheng@windriver.com>
2
2
3
Move misplaced comment.
3
There are some coding convention warnings in xilinx_spips.c,
4
as reported by:
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
$ ./scripts/checkpatch.pl hw/ssi/xilinx_spips.c
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
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>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20200427181649.26851-3-edgar.iglesias@gmail.com
14
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
15
Message-id: 20210303135254.3970-5-bmeng.cn@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
17
---
12
hw/arm/xlnx-versal.c | 2 +-
18
hw/ssi/xilinx_spips.c | 23 ++++++++++++++---------
13
1 file changed, 1 insertion(+), 1 deletion(-)
19
1 file changed, 14 insertions(+), 9 deletions(-)
14
20
15
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
21
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
16
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal.c
23
--- a/hw/ssi/xilinx_spips.c
18
+++ b/hw/arm/xlnx-versal.c
24
+++ b/hw/ssi/xilinx_spips.c
19
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
25
@@ -XXX,XX +XXX,XX @@
20
26
FIELD(GQSPI_FIFO_CTRL, GENERIC_FIFO_RESET, 0, 1)
21
obj = object_new(XLNX_VERSAL_ACPU_TYPE);
27
#define R_GQSPI_GFIFO_THRESH (0x150 / 4)
22
if (!obj) {
28
#define R_GQSPI_DATA_STS (0x15c / 4)
23
- /* Secondary CPUs start in PSCI powered-down state */
29
-/* We use the snapshot register to hold the core state for the currently
24
error_report("Unable to create apu.cpu[%d] of type %s",
30
+/*
25
i, XLNX_VERSAL_ACPU_TYPE);
31
+ * We use the snapshot register to hold the core state for the currently
26
exit(EXIT_FAILURE);
32
* or most recently executed command. So the generic fifo format is defined
27
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
33
* for the snapshot register
28
object_property_set_int(obj, s->cfg.psci_conduit,
34
*/
29
"psci-conduit", &error_abort);
35
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_reset(DeviceState *d)
30
if (i) {
36
xlnx_zynqmp_qspips_update_ixr(s);
31
+ /* Secondary CPUs start in PSCI powered-down state */
37
}
32
object_property_set_bool(obj, true,
38
33
"start-powered-off", &error_abort);
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;
34
}
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;
35
--
97
--
36
2.20.1
98
2.20.1
37
99
38
100
diff view generated by jsdifflib
1
From: Fredrik Strupe <fredrik@strupe.net>
1
From: Xuzhou Cheng <xuzhou.cheng@windriver.com>
2
2
3
According to Arm ARM, VQDMULL is only valid when U=0, while having
3
Now that the Xilinx CSU DMA model is implemented, the existing
4
U=1 is unallocated.
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.
5
7
6
Signed-off-by: Fredrik Strupe <fredrik@strupe.net>
8
Signed-off-by: Xuzhou Cheng <xuzhou.cheng@windriver.com>
7
Fixes: 695272dcb976 ("target-arm: Handle UNDEF cases for Neon 3-regs-different-widths")
9
Signed-off-by: Bin Meng <bin.meng@windriver.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
Message-id: 20210303135254.3970-6-bmeng.cn@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
target/arm/translate.c | 2 +-
14
include/hw/ssi/xilinx_spips.h | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
15
hw/ssi/xilinx_spips.c | 10 ----------
16
2 files changed, 1 insertion(+), 11 deletions(-)
13
17
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
18
diff --git a/include/hw/ssi/xilinx_spips.h b/include/hw/ssi/xilinx_spips.h
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
20
--- a/include/hw/ssi/xilinx_spips.h
17
+++ b/target/arm/translate.c
21
+++ b/include/hw/ssi/xilinx_spips.h
18
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
22
@@ -XXX,XX +XXX,XX @@
19
{0, 0, 0, 0}, /* VMLSL */
23
typedef struct XilinxSPIPS XilinxSPIPS;
20
{0, 0, 0, 9}, /* VQDMLSL */
24
21
{0, 0, 0, 0}, /* Integer VMULL */
25
#define XLNX_SPIPS_R_MAX (0x100 / 4)
22
- {0, 0, 0, 1}, /* VQDMULL */
26
-#define XLNX_ZYNQMP_SPIPS_R_MAX (0x830 / 4)
23
+ {0, 0, 0, 9}, /* VQDMULL */
27
+#define XLNX_ZYNQMP_SPIPS_R_MAX (0x200 / 4)
24
{0, 0, 0, 0xa}, /* Polynomial VMULL */
28
25
{0, 0, 0, 7}, /* Reserved: always UNDEF */
29
/* Bite off 4k chunks at a time */
26
};
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);
27
--
59
--
28
2.20.1
60
2.20.1
29
61
30
62
diff view generated by jsdifflib
1
We were accidentally permitting decode of Thumb Neon insns even if
1
The #defines INTERNAL and CASCADING represent different possible
2
the CPU didn't have the FEATURE_NEON bit set, because the feature
2
values for the TCCR.CSS register field; prefix them with CSS_ to make
3
check was being done before the call to disas_neon_data_insn() and
3
this more obvious, before we add more defines to represent the
4
disas_neon_ls_insn() in the Arm decoder but was omitted from the
4
other possible values of the field in the next commit.
5
Thumb decoder. Push the feature bit check down into the called
6
functions so it is done for both Arm and Thumb encodings.
7
5
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20200430181003.21682-3-peter.maydell@linaro.org
8
Message-id: 20210219223241.16344-2-peter.maydell@linaro.org
12
---
9
---
13
target/arm/translate.c | 16 ++++++++--------
10
hw/timer/renesas_tmr.c | 16 ++++++++--------
14
1 file changed, 8 insertions(+), 8 deletions(-)
11
1 file changed, 8 insertions(+), 8 deletions(-)
15
12
16
diff --git a/target/arm/translate.c b/target/arm/translate.c
13
diff --git a/hw/timer/renesas_tmr.c b/hw/timer/renesas_tmr.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate.c
15
--- a/hw/timer/renesas_tmr.c
19
+++ b/target/arm/translate.c
16
+++ b/hw/timer/renesas_tmr.c
20
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
17
@@ -XXX,XX +XXX,XX @@ REG8(TCCR, 10)
21
TCGv_i32 tmp2;
18
FIELD(TCCR, CSS, 3, 2)
22
TCGv_i64 tmp64;
19
FIELD(TCCR, TMRIS, 7, 1)
23
20
24
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
21
-#define INTERNAL 0x01
25
+ return 1;
22
-#define CASCADING 0x03
26
+ }
23
+#define CSS_INTERNAL 0x01
27
+
24
+#define CSS_CASCADING 0x03
28
/* FIXME: this access check should not take precedence over UNDEF
25
#define CCLR_A 0x01
29
* for invalid encodings; we will generate incorrect syndrome information
26
#define CCLR_B 0x02
30
* for attempts to execute invalid vfp/neon encodings with FP disabled.
27
31
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
28
@@ -XXX,XX +XXX,XX @@ static void update_events(RTMRState *tmr, int ch)
32
TCGv_ptr ptr1, ptr2, ptr3;
29
/* event not happened */
33
TCGv_i64 tmp64;
30
return ;
34
31
}
35
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
32
- if (FIELD_EX8(tmr->tccr[0], TCCR, CSS) == CASCADING) {
36
+ return 1;
33
+ if (FIELD_EX8(tmr->tccr[0], TCCR, CSS) == CSS_CASCADING) {
37
+ }
34
/* cascading mode */
38
+
35
if (ch == 1) {
39
/* FIXME: this access check should not take precedence over UNDEF
36
tmr->next[ch] = none;
40
* for invalid encodings; we will generate incorrect syndrome information
37
@@ -XXX,XX +XXX,XX @@ static uint16_t read_tcnt(RTMRState *tmr, unsigned size, int ch)
41
* for attempts to execute invalid vfp/neon encodings with FP disabled.
38
if (delta > 0) {
42
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
39
tmr->tick = now;
43
40
44
if (((insn >> 25) & 7) == 1) {
41
- if (FIELD_EX8(tmr->tccr[1], TCCR, CSS) == INTERNAL) {
45
/* NEON Data processing. */
42
+ if (FIELD_EX8(tmr->tccr[1], TCCR, CSS) == CSS_INTERNAL) {
46
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
43
/* timer1 count update */
47
- goto illegal_op;
44
elapsed = elapsed_time(tmr, 1, delta);
48
- }
45
if (elapsed >= 0x100) {
49
-
46
@@ -XXX,XX +XXX,XX @@ static uint16_t read_tcnt(RTMRState *tmr, unsigned size, int ch)
50
if (disas_neon_data_insn(s, insn)) {
47
tcnt[1] = tmr->tcnt[1] + (elapsed & 0xff);
51
goto illegal_op;
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;
52
}
59
}
53
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
60
@@ -XXX,XX +XXX,XX @@ static uint16_t issue_event(RTMRState *tmr, int ch, int sz,
54
}
61
qemu_irq_pulse(tmr->cmia[ch]);
55
if ((insn & 0x0f100000) == 0x04000000) {
56
/* NEON load/store. */
57
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
58
- goto illegal_op;
59
- }
60
-
61
if (disas_neon_ls_insn(s, insn)) {
62
goto illegal_op;
63
}
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],
64
--
78
--
65
2.20.1
79
2.20.1
66
80
67
81
diff view generated by jsdifflib
1
In aarch64_max_initfn() we update both 32-bit and 64-bit ID
1
The read_tcnt() function calculates the TCNT register values for the
2
registers. The intended pattern is that for 64-bit ID registers we
2
two channels of the timer module; it sets these up in the local
3
use FIELD_DP64 and the uint64_t 't' register, while 32-bit ID
3
tcnt[] array, and eventually returns either one or both of them,
4
registers use FIELD_DP32 and the uint32_t 'u' register. For
4
depending on whether the access is 8 or 16 bits. However, not all of
5
ID_AA64DFR0 we accidentally used 'u', meaning that the top 32 bits of
5
the code paths through this function set both elements of this array:
6
this 64-bit ID register would end up always zero. Luckily at the
6
if the guest has programmed the TCCR.CSS register fields to values
7
moment that's what they should be anyway, so this bug has no visible
7
which are either documented as not to be used or which QEMU does not
8
effects.
8
implement, then the function will return uninitialized data. (This
9
was spotted by Coverity.)
9
10
10
Use the right-sized variable.
11
Add the missing CSS cases to this code, so that we return a
12
consistent value instead of uninitialized data, and so the code
13
structure indicates what's happening.
11
14
12
Fixes: 3bec78447a958d481991
15
Fixes: CID 1429976
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Message-id: 20200423110915.10527-1-peter.maydell@linaro.org
18
Message-id: 20210219223241.16344-3-peter.maydell@linaro.org
17
---
19
---
18
target/arm/cpu64.c | 6 +++---
20
hw/timer/renesas_tmr.c | 19 +++++++++++++++----
19
1 file changed, 3 insertions(+), 3 deletions(-)
21
1 file changed, 15 insertions(+), 4 deletions(-)
20
22
21
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
23
diff --git a/hw/timer/renesas_tmr.c b/hw/timer/renesas_tmr.c
22
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu64.c
25
--- a/hw/timer/renesas_tmr.c
24
+++ b/target/arm/cpu64.c
26
+++ b/hw/timer/renesas_tmr.c
25
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
27
@@ -XXX,XX +XXX,XX @@ REG8(TCCR, 10)
26
u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
28
FIELD(TCCR, CSS, 3, 2)
27
cpu->isar.id_mmfr4 = u;
29
FIELD(TCCR, TMRIS, 7, 1)
28
30
29
- u = cpu->isar.id_aa64dfr0;
31
+#define CSS_EXTERNAL 0x00
30
- u = FIELD_DP64(u, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
32
#define CSS_INTERNAL 0x01
31
- cpu->isar.id_aa64dfr0 = u;
33
+#define CSS_INVALID 0x02
32
+ t = cpu->isar.id_aa64dfr0;
34
#define CSS_CASCADING 0x03
33
+ t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
35
#define CCLR_A 0x01
34
+ cpu->isar.id_aa64dfr0 = t;
36
#define CCLR_B 0x02
35
37
@@ -XXX,XX +XXX,XX @@ static uint16_t read_tcnt(RTMRState *tmr, unsigned size, int ch)
36
u = cpu->isar.id_dfr0;
38
if (delta > 0) {
37
u = FIELD_DP32(u, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
39
tmr->tick = now;
40
41
- if (FIELD_EX8(tmr->tccr[1], TCCR, CSS) == CSS_INTERNAL) {
42
+ switch (FIELD_EX8(tmr->tccr[1], TCCR, CSS)) {
43
+ case CSS_INTERNAL:
44
/* timer1 count update */
45
elapsed = elapsed_time(tmr, 1, delta);
46
if (elapsed >= 0x100) {
47
ovf = elapsed >> 8;
48
}
49
tcnt[1] = tmr->tcnt[1] + (elapsed & 0xff);
50
+ break;
51
+ case CSS_INVALID: /* guest error to have set this */
52
+ case CSS_EXTERNAL: /* QEMU doesn't implement these */
53
+ case CSS_CASCADING:
54
+ tcnt[1] = tmr->tcnt[1];
55
+ break;
56
}
57
switch (FIELD_EX8(tmr->tccr[0], TCCR, CSS)) {
58
case CSS_INTERNAL:
59
@@ -XXX,XX +XXX,XX @@ static uint16_t read_tcnt(RTMRState *tmr, unsigned size, int ch)
60
tcnt[0] = tmr->tcnt[0] + elapsed;
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
}
73
} else {
38
--
74
--
39
2.20.1
75
2.20.1
40
76
41
77
diff view generated by jsdifflib