1
From: Alistair Francis <alistair.francis@wdc.com>
1
From: Alistair Francis <alistair.francis@wdc.com>
2
2
3
The following changes since commit c5fbdd60cf1fb52f01bdfe342b6fa65d5343e1b1:
3
The following changes since commit 9c125d17e9402c232c46610802e5931b3639d77b:
4
4
5
Merge tag 'qemu-sparc-20211121' of git://github.com/mcayland/qemu into staging (2021-11-21 14:12:25 +0100)
5
Merge tag 'pull-tcg-20220420' of https://gitlab.com/rth7680/qemu into staging (2022-04-20 16:43:11 -0700)
6
6
7
are available in the Git repository at:
7
are available in the Git repository at:
8
8
9
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20211122
9
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20220421
10
10
11
for you to fetch changes up to 526e7443027c71fe7b04c29df529e1f9f425f9e3:
11
for you to fetch changes up to e63e7b6cca93242a4d037610caba5626c980b990:
12
12
13
hw/misc/sifive_u_otp: Do not reset OTP content on hardware reset (2021-11-22 10:46:22 +1000)
13
hw/riscv: boot: Support 64bit fdt address. (2022-04-21 16:29:57 +1000)
14
14
15
----------------------------------------------------------------
15
----------------------------------------------------------------
16
Seventh RISC-V PR for QEMU 6.2
16
First RISC-V PR for QEMU 7.1
17
17
18
- Deprecate IF_NONE for SiFive OTP
18
* Add support for Ibex SPI to OpenTitan
19
- Don't reset SiFive OTP content
19
* Add support for privileged spec version 1.12.0
20
* Use privileged spec version 1.12.0 for virt machine by default
21
* Allow software access to MIP SEIP
22
* Add initial support for the Sdtrig extension
23
* Optimisations for vector extensions
24
* Improvements to the misa ISA string
25
* Add isa extenstion strings to the device tree
26
* Don't allow `-bios` options with KVM machines
27
* Fix NAPOT range computation overflow
28
* Fix DT property mmu-type when CPU mmu option is disabled
29
* Make RISC-V ACLINT mtime MMIO register writable
30
* Add and enable native debug feature
31
* Support 64bit fdt address.
20
32
21
----------------------------------------------------------------
33
----------------------------------------------------------------
22
Philippe Mathieu-Daudé (1):
34
Alistair Francis (2):
23
hw/misc/sifive_u_otp: Do not reset OTP content on hardware reset
35
target/riscv: cpu: Fixup indentation
36
target/riscv: Allow software access to MIP SEIP
24
37
25
Thomas Huth (1):
38
Atish Patra (7):
26
hw/misc/sifive_u_otp: Use IF_PFLASH for the OTP device instead of IF_NONE
39
target/riscv: Define simpler privileged spec version numbering
40
target/riscv: Add the privileged spec version 1.12.0
41
target/riscv: Introduce privilege version field in the CSR ops.
42
target/riscv: Add support for mconfigptr
43
target/riscv: Add *envcfg* CSRs support
44
target/riscv: Enable privileged spec version 1.12
45
target/riscv: Add isa extenstion strings to the device tree
27
46
28
docs/about/deprecated.rst | 6 ++++++
47
Bin Meng (7):
29
hw/misc/sifive_u_otp.c | 22 +++++++++++++---------
48
target/riscv: Add initial support for the Sdtrig extension
30
2 files changed, 19 insertions(+), 9 deletions(-)
49
target/riscv: debug: Implement debug related TCGCPUOps
50
target/riscv: cpu: Add a config option for native debug
51
target/riscv: csr: Hook debug CSR read/write
52
target/riscv: machine: Add debug state description
53
target/riscv: cpu: Enable native debug feature
54
hw/core: tcg-cpu-ops.h: Update comments of debug_check_watchpoint()
31
55
56
Dylan Jhong (1):
57
hw/riscv: boot: Support 64bit fdt address.
58
59
Frank Chang (3):
60
hw/intc: Add .impl.[min|max]_access_size declaration in RISC-V ACLINT
61
hw/intc: Support 32/64-bit mtimecmp and mtime accesses in RISC-V ACLINT
62
hw/intc: Make RISC-V ACLINT mtime MMIO register writable
63
64
Jim Shu (1):
65
hw/intc: riscv_aclint: Add reset function of ACLINT devices
66
67
Nicolas Pitre (1):
68
target/riscv/pmp: fix NAPOT range computation overflow
69
70
Niklas Cassel (1):
71
hw/riscv: virt: fix DT property mmu-type when CPU mmu option is disabled
72
73
Ralf Ramsauer (1):
74
hw/riscv: virt: Exit if the user provided -bios in combination with KVM
75
76
Richard Henderson (1):
77
target/riscv: Use cpu_loop_exit_restore directly from mmu faults
78
79
Tsukasa OI (1):
80
target/riscv: misa to ISA string conversion fix
81
82
Weiwei Li (3):
83
target/riscv: optimize condition assign for scale < 0
84
target/riscv: optimize helper for vmv<nr>r.v
85
target/riscv: fix start byte for vmv<nf>r.v when vstart != 0
86
87
Wilfred Mallawa (2):
88
hw/ssi: Add Ibex SPI device model
89
riscv: opentitan: Connect opentitan SPI Host
90
91
include/hw/core/tcg-cpu-ops.h | 1 +
92
include/hw/intc/riscv_aclint.h | 1 +
93
include/hw/riscv/boot.h | 4 +-
94
include/hw/riscv/opentitan.h | 30 +-
95
include/hw/ssi/ibex_spi_host.h | 94 +++++
96
target/riscv/cpu.h | 40 ++-
97
target/riscv/cpu_bits.h | 40 +++
98
target/riscv/debug.h | 114 ++++++
99
target/riscv/helper.h | 5 +-
100
hw/intc/riscv_aclint.c | 144 ++++++--
101
hw/riscv/boot.c | 12 +-
102
hw/riscv/opentitan.c | 36 +-
103
hw/riscv/virt.c | 24 +-
104
hw/ssi/ibex_spi_host.c | 612 ++++++++++++++++++++++++++++++++
105
target/riscv/cpu.c | 120 ++++++-
106
target/riscv/cpu_helper.c | 10 +-
107
target/riscv/csr.c | 282 +++++++++++++--
108
target/riscv/debug.c | 441 +++++++++++++++++++++++
109
target/riscv/machine.c | 55 +++
110
target/riscv/pmp.c | 14 +-
111
target/riscv/vector_helper.c | 31 +-
112
target/riscv/insn_trans/trans_rvv.c.inc | 25 +-
113
hw/ssi/meson.build | 1 +
114
hw/ssi/trace-events | 7 +
115
target/riscv/meson.build | 1 +
116
25 files changed, 1971 insertions(+), 173 deletions(-)
117
create mode 100644 include/hw/ssi/ibex_spi_host.h
118
create mode 100644 target/riscv/debug.h
119
create mode 100644 hw/ssi/ibex_spi_host.c
120
create mode 100644 target/riscv/debug.c
diff view generated by jsdifflib
New patch
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
1
2
3
Adds the SPI_HOST device model for ibex. The device specification is as per
4
[1]. The model has been tested on opentitan with spi_host unit tests
5
written for TockOS.
6
7
[1] https://docs.opentitan.org/hw/ip/spi_host/doc/
8
9
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Message-Id: <20220303045426.511588-1-alistair.francis@opensource.wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
include/hw/ssi/ibex_spi_host.h | 94 +++++
16
hw/ssi/ibex_spi_host.c | 612 +++++++++++++++++++++++++++++++++
17
hw/ssi/meson.build | 1 +
18
hw/ssi/trace-events | 7 +
19
4 files changed, 714 insertions(+)
20
create mode 100644 include/hw/ssi/ibex_spi_host.h
21
create mode 100644 hw/ssi/ibex_spi_host.c
22
23
diff --git a/include/hw/ssi/ibex_spi_host.h b/include/hw/ssi/ibex_spi_host.h
24
new file mode 100644
25
index XXXXXXX..XXXXXXX
26
--- /dev/null
27
+++ b/include/hw/ssi/ibex_spi_host.h
28
@@ -XXX,XX +XXX,XX @@
29
+
30
+/*
31
+ * QEMU model of the Ibex SPI Controller
32
+ * SPEC Reference: https://docs.opentitan.org/hw/ip/spi_host/doc/
33
+ *
34
+ * Copyright (C) 2022 Western Digital
35
+ *
36
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
37
+ * of this software and associated documentation files (the "Software"), to deal
38
+ * in the Software without restriction, including without limitation the rights
39
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
40
+ * copies of the Software, and to permit persons to whom the Software is
41
+ * furnished to do so, subject to the following conditions:
42
+ *
43
+ * The above copyright notice and this permission notice shall be included in
44
+ * all copies or substantial portions of the Software.
45
+ *
46
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
47
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
48
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
49
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
50
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
51
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
52
+ * THE SOFTWARE.
53
+ */
54
+
55
+#ifndef IBEX_SPI_HOST_H
56
+#define IBEX_SPI_HOST_H
57
+
58
+#include "hw/sysbus.h"
59
+#include "hw/hw.h"
60
+#include "hw/ssi/ssi.h"
61
+#include "qemu/fifo8.h"
62
+#include "qom/object.h"
63
+#include "hw/registerfields.h"
64
+#include "qemu/timer.h"
65
+
66
+#define TYPE_IBEX_SPI_HOST "ibex-spi"
67
+#define IBEX_SPI_HOST(obj) \
68
+ OBJECT_CHECK(IbexSPIHostState, (obj), TYPE_IBEX_SPI_HOST)
69
+
70
+/* SPI Registers */
71
+#define IBEX_SPI_HOST_INTR_STATE (0x00 / 4) /* rw */
72
+#define IBEX_SPI_HOST_INTR_ENABLE (0x04 / 4) /* rw */
73
+#define IBEX_SPI_HOST_INTR_TEST (0x08 / 4) /* wo */
74
+#define IBEX_SPI_HOST_ALERT_TEST (0x0c / 4) /* wo */
75
+#define IBEX_SPI_HOST_CONTROL (0x10 / 4) /* rw */
76
+#define IBEX_SPI_HOST_STATUS (0x14 / 4) /* ro */
77
+#define IBEX_SPI_HOST_CONFIGOPTS (0x18 / 4) /* rw */
78
+#define IBEX_SPI_HOST_CSID (0x1c / 4) /* rw */
79
+#define IBEX_SPI_HOST_COMMAND (0x20 / 4) /* wo */
80
+/* RX/TX Modelled by FIFO */
81
+#define IBEX_SPI_HOST_RXDATA (0x24 / 4)
82
+#define IBEX_SPI_HOST_TXDATA (0x28 / 4)
83
+
84
+#define IBEX_SPI_HOST_ERROR_ENABLE (0x2c / 4) /* rw */
85
+#define IBEX_SPI_HOST_ERROR_STATUS (0x30 / 4) /* rw */
86
+#define IBEX_SPI_HOST_EVENT_ENABLE (0x34 / 4) /* rw */
87
+
88
+/* FIFO Len in Bytes */
89
+#define IBEX_SPI_HOST_TXFIFO_LEN 288
90
+#define IBEX_SPI_HOST_RXFIFO_LEN 256
91
+
92
+/* Max Register (Based on addr) */
93
+#define IBEX_SPI_HOST_MAX_REGS (IBEX_SPI_HOST_EVENT_ENABLE + 1)
94
+
95
+/* MISC */
96
+#define TX_INTERRUPT_TRIGGER_DELAY_NS 100
97
+#define BIDIRECTIONAL_TRANSFER 3
98
+
99
+typedef struct {
100
+ /* <private> */
101
+ SysBusDevice parent_obj;
102
+
103
+ /* <public> */
104
+ MemoryRegion mmio;
105
+ uint32_t regs[IBEX_SPI_HOST_MAX_REGS];
106
+ /* Multi-reg that sets config opts per CS */
107
+ uint32_t *config_opts;
108
+ Fifo8 rx_fifo;
109
+ Fifo8 tx_fifo;
110
+ QEMUTimer *fifo_trigger_handle;
111
+
112
+ qemu_irq event;
113
+ qemu_irq host_err;
114
+ uint32_t num_cs;
115
+ qemu_irq *cs_lines;
116
+ SSIBus *ssi;
117
+
118
+ /* Used to track the init status, for replicating TXDATA ghost writes */
119
+ bool init_status;
120
+} IbexSPIHostState;
121
+
122
+#endif
123
diff --git a/hw/ssi/ibex_spi_host.c b/hw/ssi/ibex_spi_host.c
124
new file mode 100644
125
index XXXXXXX..XXXXXXX
126
--- /dev/null
127
+++ b/hw/ssi/ibex_spi_host.c
128
@@ -XXX,XX +XXX,XX @@
129
+/*
130
+ * QEMU model of the Ibex SPI Controller
131
+ * SPEC Reference: https://docs.opentitan.org/hw/ip/spi_host/doc/
132
+ *
133
+ * Copyright (C) 2022 Western Digital
134
+ *
135
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
136
+ * of this software and associated documentation files (the "Software"), to deal
137
+ * in the Software without restriction, including without limitation the rights
138
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
139
+ * copies of the Software, and to permit persons to whom the Software is
140
+ * furnished to do so, subject to the following conditions:
141
+ *
142
+ * The above copyright notice and this permission notice shall be included in
143
+ * all copies or substantial portions of the Software.
144
+ *
145
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
146
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
147
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
148
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
149
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
150
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
151
+ * THE SOFTWARE.
152
+ */
153
+
154
+#include "qemu/osdep.h"
155
+#include "qemu/log.h"
156
+#include "qemu/module.h"
157
+#include "hw/ssi/ibex_spi_host.h"
158
+#include "hw/irq.h"
159
+#include "hw/qdev-properties.h"
160
+#include "hw/qdev-properties-system.h"
161
+#include "migration/vmstate.h"
162
+#include "trace.h"
163
+
164
+REG32(INTR_STATE, 0x00)
165
+ FIELD(INTR_STATE, ERROR, 0, 1)
166
+ FIELD(INTR_STATE, SPI_EVENT, 1, 1)
167
+REG32(INTR_ENABLE, 0x04)
168
+ FIELD(INTR_ENABLE, ERROR, 0, 1)
169
+ FIELD(INTR_ENABLE, SPI_EVENT, 1, 1)
170
+REG32(INTR_TEST, 0x08)
171
+ FIELD(INTR_TEST, ERROR, 0, 1)
172
+ FIELD(INTR_TEST, SPI_EVENT, 1, 1)
173
+REG32(ALERT_TEST, 0x0c)
174
+ FIELD(ALERT_TEST, FETAL_TEST, 0, 1)
175
+REG32(CONTROL, 0x10)
176
+ FIELD(CONTROL, RX_WATERMARK, 0, 8)
177
+ FIELD(CONTROL, TX_WATERMARK, 1, 8)
178
+ FIELD(CONTROL, OUTPUT_EN, 29, 1)
179
+ FIELD(CONTROL, SW_RST, 30, 1)
180
+ FIELD(CONTROL, SPIEN, 31, 1)
181
+REG32(STATUS, 0x14)
182
+ FIELD(STATUS, TXQD, 0, 8)
183
+ FIELD(STATUS, RXQD, 18, 8)
184
+ FIELD(STATUS, CMDQD, 16, 3)
185
+ FIELD(STATUS, RXWM, 20, 1)
186
+ FIELD(STATUS, BYTEORDER, 22, 1)
187
+ FIELD(STATUS, RXSTALL, 23, 1)
188
+ FIELD(STATUS, RXEMPTY, 24, 1)
189
+ FIELD(STATUS, RXFULL, 25, 1)
190
+ FIELD(STATUS, TXWM, 26, 1)
191
+ FIELD(STATUS, TXSTALL, 27, 1)
192
+ FIELD(STATUS, TXEMPTY, 28, 1)
193
+ FIELD(STATUS, TXFULL, 29, 1)
194
+ FIELD(STATUS, ACTIVE, 30, 1)
195
+ FIELD(STATUS, READY, 31, 1)
196
+REG32(CONFIGOPTS, 0x18)
197
+ FIELD(CONFIGOPTS, CLKDIV_0, 0, 16)
198
+ FIELD(CONFIGOPTS, CSNIDLE_0, 16, 4)
199
+ FIELD(CONFIGOPTS, CSNTRAIL_0, 20, 4)
200
+ FIELD(CONFIGOPTS, CSNLEAD_0, 24, 4)
201
+ FIELD(CONFIGOPTS, FULLCYC_0, 29, 1)
202
+ FIELD(CONFIGOPTS, CPHA_0, 30, 1)
203
+ FIELD(CONFIGOPTS, CPOL_0, 31, 1)
204
+REG32(CSID, 0x1c)
205
+ FIELD(CSID, CSID, 0, 32)
206
+REG32(COMMAND, 0x20)
207
+ FIELD(COMMAND, LEN, 0, 8)
208
+ FIELD(COMMAND, CSAAT, 9, 1)
209
+ FIELD(COMMAND, SPEED, 10, 2)
210
+ FIELD(COMMAND, DIRECTION, 12, 2)
211
+REG32(ERROR_ENABLE, 0x2c)
212
+ FIELD(ERROR_ENABLE, CMDBUSY, 0, 1)
213
+ FIELD(ERROR_ENABLE, OVERFLOW, 1, 1)
214
+ FIELD(ERROR_ENABLE, UNDERFLOW, 2, 1)
215
+ FIELD(ERROR_ENABLE, CMDINVAL, 3, 1)
216
+ FIELD(ERROR_ENABLE, CSIDINVAL, 4, 1)
217
+REG32(ERROR_STATUS, 0x30)
218
+ FIELD(ERROR_STATUS, CMDBUSY, 0, 1)
219
+ FIELD(ERROR_STATUS, OVERFLOW, 1, 1)
220
+ FIELD(ERROR_STATUS, UNDERFLOW, 2, 1)
221
+ FIELD(ERROR_STATUS, CMDINVAL, 3, 1)
222
+ FIELD(ERROR_STATUS, CSIDINVAL, 4, 1)
223
+ FIELD(ERROR_STATUS, ACCESSINVAL, 5, 1)
224
+REG32(EVENT_ENABLE, 0x30)
225
+ FIELD(EVENT_ENABLE, RXFULL, 0, 1)
226
+ FIELD(EVENT_ENABLE, TXEMPTY, 1, 1)
227
+ FIELD(EVENT_ENABLE, RXWM, 2, 1)
228
+ FIELD(EVENT_ENABLE, TXWM, 3, 1)
229
+ FIELD(EVENT_ENABLE, READY, 4, 1)
230
+ FIELD(EVENT_ENABLE, IDLE, 5, 1)
231
+
232
+static inline uint8_t div4_round_up(uint8_t dividend)
233
+{
234
+ return (dividend + 3) / 4;
235
+}
236
+
237
+static void ibex_spi_rxfifo_reset(IbexSPIHostState *s)
238
+{
239
+ /* Empty the RX FIFO and assert RXEMPTY */
240
+ fifo8_reset(&s->rx_fifo);
241
+ s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_RXFULL_MASK;
242
+ s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_RXEMPTY_MASK;
243
+}
244
+
245
+static void ibex_spi_txfifo_reset(IbexSPIHostState *s)
246
+{
247
+ /* Empty the TX FIFO and assert TXEMPTY */
248
+ fifo8_reset(&s->tx_fifo);
249
+ s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_TXFULL_MASK;
250
+ s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_TXEMPTY_MASK;
251
+}
252
+
253
+static void ibex_spi_host_reset(DeviceState *dev)
254
+{
255
+ IbexSPIHostState *s = IBEX_SPI_HOST(dev);
256
+ trace_ibex_spi_host_reset("Resetting Ibex SPI");
257
+
258
+ /* SPI Host Register Reset */
259
+ s->regs[IBEX_SPI_HOST_INTR_STATE] = 0x00;
260
+ s->regs[IBEX_SPI_HOST_INTR_ENABLE] = 0x00;
261
+ s->regs[IBEX_SPI_HOST_INTR_TEST] = 0x00;
262
+ s->regs[IBEX_SPI_HOST_ALERT_TEST] = 0x00;
263
+ s->regs[IBEX_SPI_HOST_CONTROL] = 0x7f;
264
+ s->regs[IBEX_SPI_HOST_STATUS] = 0x00;
265
+ s->regs[IBEX_SPI_HOST_CONFIGOPTS] = 0x00;
266
+ s->regs[IBEX_SPI_HOST_CSID] = 0x00;
267
+ s->regs[IBEX_SPI_HOST_COMMAND] = 0x00;
268
+ /* RX/TX Modelled by FIFO */
269
+ s->regs[IBEX_SPI_HOST_RXDATA] = 0x00;
270
+ s->regs[IBEX_SPI_HOST_TXDATA] = 0x00;
271
+
272
+ s->regs[IBEX_SPI_HOST_ERROR_ENABLE] = 0x1F;
273
+ s->regs[IBEX_SPI_HOST_ERROR_STATUS] = 0x00;
274
+ s->regs[IBEX_SPI_HOST_EVENT_ENABLE] = 0x00;
275
+
276
+ ibex_spi_rxfifo_reset(s);
277
+ ibex_spi_txfifo_reset(s);
278
+
279
+ s->init_status = true;
280
+ return;
281
+}
282
+
283
+/*
284
+ * Check if we need to trigger an interrupt.
285
+ * The two interrupts lines (host_err and event) can
286
+ * be enabled separately in 'IBEX_SPI_HOST_INTR_ENABLE'.
287
+ *
288
+ * Interrupts are triggered based on the ones
289
+ * enabled in the `IBEX_SPI_HOST_EVENT_ENABLE` and `IBEX_SPI_HOST_ERROR_ENABLE`.
290
+ */
291
+static void ibex_spi_host_irq(IbexSPIHostState *s)
292
+{
293
+ bool error_en = s->regs[IBEX_SPI_HOST_INTR_ENABLE]
294
+ & R_INTR_ENABLE_ERROR_MASK;
295
+ bool event_en = s->regs[IBEX_SPI_HOST_INTR_ENABLE]
296
+ & R_INTR_ENABLE_SPI_EVENT_MASK;
297
+ bool err_pending = s->regs[IBEX_SPI_HOST_INTR_STATE]
298
+ & R_INTR_STATE_ERROR_MASK;
299
+ bool status_pending = s->regs[IBEX_SPI_HOST_INTR_STATE]
300
+ & R_INTR_STATE_SPI_EVENT_MASK;
301
+ int err_irq = 0, event_irq = 0;
302
+
303
+ /* Error IRQ enabled and Error IRQ Cleared*/
304
+ if (error_en && !err_pending) {
305
+ /* Event enabled, Interrupt Test Error */
306
+ if (s->regs[IBEX_SPI_HOST_INTR_TEST] & R_INTR_TEST_ERROR_MASK) {
307
+ err_irq = 1;
308
+ } else if ((s->regs[IBEX_SPI_HOST_ERROR_ENABLE]
309
+ & R_ERROR_ENABLE_CMDBUSY_MASK) &&
310
+ s->regs[IBEX_SPI_HOST_ERROR_STATUS]
311
+ & R_ERROR_STATUS_CMDBUSY_MASK) {
312
+ /* Wrote to COMMAND when not READY */
313
+ err_irq = 1;
314
+ } else if ((s->regs[IBEX_SPI_HOST_ERROR_ENABLE]
315
+ & R_ERROR_ENABLE_CMDINVAL_MASK) &&
316
+ s->regs[IBEX_SPI_HOST_ERROR_STATUS]
317
+ & R_ERROR_STATUS_CMDINVAL_MASK) {
318
+ /* Invalid command segment */
319
+ err_irq = 1;
320
+ } else if ((s->regs[IBEX_SPI_HOST_ERROR_ENABLE]
321
+ & R_ERROR_ENABLE_CSIDINVAL_MASK) &&
322
+ s->regs[IBEX_SPI_HOST_ERROR_STATUS]
323
+ & R_ERROR_STATUS_CSIDINVAL_MASK) {
324
+ /* Invalid value for CSID */
325
+ err_irq = 1;
326
+ }
327
+ if (err_irq) {
328
+ s->regs[IBEX_SPI_HOST_INTR_STATE] |= R_INTR_STATE_ERROR_MASK;
329
+ }
330
+ qemu_set_irq(s->host_err, err_irq);
331
+ }
332
+
333
+ /* Event IRQ Enabled and Event IRQ Cleared */
334
+ if (event_en && !status_pending) {
335
+ if (s->regs[IBEX_SPI_HOST_INTR_TEST] & R_INTR_TEST_SPI_EVENT_MASK) {
336
+ /* Event enabled, Interrupt Test Event */
337
+ event_irq = 1;
338
+ } else if ((s->regs[IBEX_SPI_HOST_EVENT_ENABLE]
339
+ & R_EVENT_ENABLE_READY_MASK) &&
340
+ (s->regs[IBEX_SPI_HOST_STATUS] & R_STATUS_READY_MASK)) {
341
+ /* SPI Host ready for next command */
342
+ event_irq = 1;
343
+ } else if ((s->regs[IBEX_SPI_HOST_EVENT_ENABLE]
344
+ & R_EVENT_ENABLE_TXEMPTY_MASK) &&
345
+ (s->regs[IBEX_SPI_HOST_STATUS] & R_STATUS_TXEMPTY_MASK)) {
346
+ /* SPI TXEMPTY, TXFIFO drained */
347
+ event_irq = 1;
348
+ } else if ((s->regs[IBEX_SPI_HOST_EVENT_ENABLE]
349
+ & R_EVENT_ENABLE_RXFULL_MASK) &&
350
+ (s->regs[IBEX_SPI_HOST_STATUS] & R_STATUS_RXFULL_MASK)) {
351
+ /* SPI RXFULL, RXFIFO full */
352
+ event_irq = 1;
353
+ }
354
+ if (event_irq) {
355
+ s->regs[IBEX_SPI_HOST_INTR_STATE] |= R_INTR_STATE_SPI_EVENT_MASK;
356
+ }
357
+ qemu_set_irq(s->event, event_irq);
358
+ }
359
+}
360
+
361
+static void ibex_spi_host_transfer(IbexSPIHostState *s)
362
+{
363
+ uint32_t rx, tx;
364
+ /* Get num of one byte transfers */
365
+ uint8_t segment_len = ((s->regs[IBEX_SPI_HOST_COMMAND] & R_COMMAND_LEN_MASK)
366
+ >> R_COMMAND_LEN_SHIFT);
367
+ while (segment_len > 0) {
368
+ if (fifo8_is_empty(&s->tx_fifo)) {
369
+ /* Assert Stall */
370
+ s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_TXSTALL_MASK;
371
+ break;
372
+ } else if (fifo8_is_full(&s->rx_fifo)) {
373
+ /* Assert Stall */
374
+ s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_RXSTALL_MASK;
375
+ break;
376
+ } else {
377
+ tx = fifo8_pop(&s->tx_fifo);
378
+ }
379
+
380
+ rx = ssi_transfer(s->ssi, tx);
381
+
382
+ trace_ibex_spi_host_transfer(tx, rx);
383
+
384
+ if (!fifo8_is_full(&s->rx_fifo)) {
385
+ fifo8_push(&s->rx_fifo, rx);
386
+ } else {
387
+ /* Assert RXFULL */
388
+ s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_RXFULL_MASK;
389
+ }
390
+ --segment_len;
391
+ }
392
+
393
+ /* Assert Ready */
394
+ s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_READY_MASK;
395
+ /* Set RXQD */
396
+ s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_RXQD_MASK;
397
+ s->regs[IBEX_SPI_HOST_STATUS] |= (R_STATUS_RXQD_MASK
398
+ & div4_round_up(segment_len));
399
+ /* Set TXQD */
400
+ s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_TXQD_MASK;
401
+ s->regs[IBEX_SPI_HOST_STATUS] |= (fifo8_num_used(&s->tx_fifo) / 4)
402
+ & R_STATUS_TXQD_MASK;
403
+ /* Clear TXFULL */
404
+ s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_TXFULL_MASK;
405
+ /* Assert TXEMPTY and drop remaining bytes that exceed segment_len */
406
+ ibex_spi_txfifo_reset(s);
407
+ /* Reset RXEMPTY */
408
+ s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_RXEMPTY_MASK;
409
+
410
+ ibex_spi_host_irq(s);
411
+}
412
+
413
+static uint64_t ibex_spi_host_read(void *opaque, hwaddr addr,
414
+ unsigned int size)
415
+{
416
+ IbexSPIHostState *s = opaque;
417
+ uint32_t rc = 0;
418
+ uint8_t rx_byte = 0;
419
+
420
+ trace_ibex_spi_host_read(addr, size);
421
+
422
+ /* Match reg index */
423
+ addr = addr >> 2;
424
+ switch (addr) {
425
+ /* Skipping any W/O registers */
426
+ case IBEX_SPI_HOST_INTR_STATE...IBEX_SPI_HOST_INTR_ENABLE:
427
+ case IBEX_SPI_HOST_CONTROL...IBEX_SPI_HOST_STATUS:
428
+ rc = s->regs[addr];
429
+ break;
430
+ case IBEX_SPI_HOST_CSID:
431
+ rc = s->regs[addr];
432
+ break;
433
+ case IBEX_SPI_HOST_CONFIGOPTS:
434
+ rc = s->config_opts[s->regs[IBEX_SPI_HOST_CSID]];
435
+ break;
436
+ case IBEX_SPI_HOST_TXDATA:
437
+ rc = s->regs[addr];
438
+ break;
439
+ case IBEX_SPI_HOST_RXDATA:
440
+ /* Clear RXFULL */
441
+ s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_RXFULL_MASK;
442
+
443
+ for (int i = 0; i < 4; ++i) {
444
+ if (fifo8_is_empty(&s->rx_fifo)) {
445
+ /* Assert RXEMPTY, no IRQ */
446
+ s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_RXEMPTY_MASK;
447
+ s->regs[IBEX_SPI_HOST_ERROR_STATUS] |=
448
+ R_ERROR_STATUS_UNDERFLOW_MASK;
449
+ return rc;
450
+ }
451
+ rx_byte = fifo8_pop(&s->rx_fifo);
452
+ rc |= rx_byte << (i * 8);
453
+ }
454
+ break;
455
+ case IBEX_SPI_HOST_ERROR_ENABLE...IBEX_SPI_HOST_EVENT_ENABLE:
456
+ rc = s->regs[addr];
457
+ break;
458
+ default:
459
+ qemu_log_mask(LOG_GUEST_ERROR, "Bad offset 0x%" HWADDR_PRIx "\n",
460
+ addr << 2);
461
+ }
462
+ return rc;
463
+}
464
+
465
+
466
+static void ibex_spi_host_write(void *opaque, hwaddr addr,
467
+ uint64_t val64, unsigned int size)
468
+{
469
+ IbexSPIHostState *s = opaque;
470
+ uint32_t val32 = val64;
471
+ uint32_t shift_mask = 0xff;
472
+ uint8_t txqd_len;
473
+
474
+ trace_ibex_spi_host_write(addr, size, val64);
475
+
476
+ /* Match reg index */
477
+ addr = addr >> 2;
478
+
479
+ switch (addr) {
480
+ /* Skipping any R/O registers */
481
+ case IBEX_SPI_HOST_INTR_STATE...IBEX_SPI_HOST_INTR_ENABLE:
482
+ s->regs[addr] = val32;
483
+ break;
484
+ case IBEX_SPI_HOST_INTR_TEST:
485
+ s->regs[addr] = val32;
486
+ ibex_spi_host_irq(s);
487
+ break;
488
+ case IBEX_SPI_HOST_ALERT_TEST:
489
+ s->regs[addr] = val32;
490
+ qemu_log_mask(LOG_UNIMP,
491
+ "%s: SPI_ALERT_TEST is not supported\n", __func__);
492
+ break;
493
+ case IBEX_SPI_HOST_CONTROL:
494
+ s->regs[addr] = val32;
495
+
496
+ if (val32 & R_CONTROL_SW_RST_MASK) {
497
+ ibex_spi_host_reset((DeviceState *)s);
498
+ /* Clear active if any */
499
+ s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_ACTIVE_MASK;
500
+ }
501
+
502
+ if (val32 & R_CONTROL_OUTPUT_EN_MASK) {
503
+ qemu_log_mask(LOG_UNIMP,
504
+ "%s: CONTROL_OUTPUT_EN is not supported\n", __func__);
505
+ }
506
+ break;
507
+ case IBEX_SPI_HOST_CONFIGOPTS:
508
+ /* Update the respective config-opts register based on CSIDth index */
509
+ s->config_opts[s->regs[IBEX_SPI_HOST_CSID]] = val32;
510
+ qemu_log_mask(LOG_UNIMP,
511
+ "%s: CONFIGOPTS Hardware settings not supported\n",
512
+ __func__);
513
+ break;
514
+ case IBEX_SPI_HOST_CSID:
515
+ if (val32 >= s->num_cs) {
516
+ /* CSID exceeds max num_cs */
517
+ s->regs[IBEX_SPI_HOST_ERROR_STATUS] |=
518
+ R_ERROR_STATUS_CSIDINVAL_MASK;
519
+ ibex_spi_host_irq(s);
520
+ return;
521
+ }
522
+ s->regs[addr] = val32;
523
+ break;
524
+ case IBEX_SPI_HOST_COMMAND:
525
+ s->regs[addr] = val32;
526
+
527
+ /* STALL, IP not enabled */
528
+ if (!(s->regs[IBEX_SPI_HOST_CONTROL] & R_CONTROL_SPIEN_MASK)) {
529
+ return;
530
+ }
531
+
532
+ /* SPI not ready, IRQ Error */
533
+ if (!(s->regs[IBEX_SPI_HOST_STATUS] & R_STATUS_READY_MASK)) {
534
+ s->regs[IBEX_SPI_HOST_ERROR_STATUS] |= R_ERROR_STATUS_CMDBUSY_MASK;
535
+ ibex_spi_host_irq(s);
536
+ return;
537
+ }
538
+ /* Assert Not Ready */
539
+ s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_READY_MASK;
540
+
541
+ if (((val32 & R_COMMAND_DIRECTION_MASK) >> R_COMMAND_DIRECTION_SHIFT)
542
+ != BIDIRECTIONAL_TRANSFER) {
543
+ qemu_log_mask(LOG_UNIMP,
544
+ "%s: Rx Only/Tx Only are not supported\n", __func__);
545
+ }
546
+
547
+ if (val32 & R_COMMAND_CSAAT_MASK) {
548
+ qemu_log_mask(LOG_UNIMP,
549
+ "%s: CSAAT is not supported\n", __func__);
550
+ }
551
+ if (val32 & R_COMMAND_SPEED_MASK) {
552
+ qemu_log_mask(LOG_UNIMP,
553
+ "%s: SPEED is not supported\n", __func__);
554
+ }
555
+
556
+ /* Set Transfer Callback */
557
+ timer_mod(s->fifo_trigger_handle,
558
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
559
+ (TX_INTERRUPT_TRIGGER_DELAY_NS));
560
+
561
+ break;
562
+ case IBEX_SPI_HOST_TXDATA:
563
+ /*
564
+ * This is a hardware `feature` where
565
+ * the first word written TXDATA after init is omitted entirely
566
+ */
567
+ if (s->init_status) {
568
+ s->init_status = false;
569
+ return;
570
+ }
571
+
572
+ for (int i = 0; i < 4; ++i) {
573
+ /* Attempting to write when TXFULL */
574
+ if (fifo8_is_full(&s->tx_fifo)) {
575
+ /* Assert RXEMPTY, no IRQ */
576
+ s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_TXFULL_MASK;
577
+ s->regs[IBEX_SPI_HOST_ERROR_STATUS] |=
578
+ R_ERROR_STATUS_OVERFLOW_MASK;
579
+ ibex_spi_host_irq(s);
580
+ return;
581
+ }
582
+ /* Byte ordering is set by the IP */
583
+ if ((s->regs[IBEX_SPI_HOST_STATUS] &
584
+ R_STATUS_BYTEORDER_MASK) == 0) {
585
+ /* LE: LSB transmitted first (default for ibex processor) */
586
+ shift_mask = 0xff << (i * 8);
587
+ } else {
588
+ /* BE: MSB transmitted first */
589
+ qemu_log_mask(LOG_UNIMP,
590
+ "%s: Big endian is not supported\n", __func__);
591
+ }
592
+
593
+ fifo8_push(&s->tx_fifo, (val32 & shift_mask) >> (i * 8));
594
+ }
595
+
596
+ /* Reset TXEMPTY */
597
+ s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_TXEMPTY_MASK;
598
+ /* Update TXQD */
599
+ txqd_len = (s->regs[IBEX_SPI_HOST_STATUS] &
600
+ R_STATUS_TXQD_MASK) >> R_STATUS_TXQD_SHIFT;
601
+ /* Partial bytes (size < 4) are padded, in words. */
602
+ txqd_len += 1;
603
+ s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_TXQD_MASK;
604
+ s->regs[IBEX_SPI_HOST_STATUS] |= txqd_len;
605
+ /* Assert Ready */
606
+ s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_READY_MASK;
607
+ break;
608
+ case IBEX_SPI_HOST_ERROR_ENABLE:
609
+ s->regs[addr] = val32;
610
+
611
+ if (val32 & R_ERROR_ENABLE_CMDINVAL_MASK) {
612
+ qemu_log_mask(LOG_UNIMP,
613
+ "%s: Segment Length is not supported\n", __func__);
614
+ }
615
+ break;
616
+ case IBEX_SPI_HOST_ERROR_STATUS:
617
+ /*
618
+ * Indicates that any errors that have occurred.
619
+ * When an error occurs, the corresponding bit must be cleared
620
+ * here before issuing any further commands
621
+ */
622
+ s->regs[addr] = val32;
623
+ break;
624
+ case IBEX_SPI_HOST_EVENT_ENABLE:
625
+ /* Controls which classes of SPI events raise an interrupt. */
626
+ s->regs[addr] = val32;
627
+
628
+ if (val32 & R_EVENT_ENABLE_RXWM_MASK) {
629
+ qemu_log_mask(LOG_UNIMP,
630
+ "%s: RXWM is not supported\n", __func__);
631
+ }
632
+ if (val32 & R_EVENT_ENABLE_TXWM_MASK) {
633
+ qemu_log_mask(LOG_UNIMP,
634
+ "%s: TXWM is not supported\n", __func__);
635
+ }
636
+
637
+ if (val32 & R_EVENT_ENABLE_IDLE_MASK) {
638
+ qemu_log_mask(LOG_UNIMP,
639
+ "%s: IDLE is not supported\n", __func__);
640
+ }
641
+ break;
642
+ default:
643
+ qemu_log_mask(LOG_GUEST_ERROR, "Bad offset 0x%" HWADDR_PRIx "\n",
644
+ addr << 2);
645
+ }
646
+}
647
+
648
+static const MemoryRegionOps ibex_spi_ops = {
649
+ .read = ibex_spi_host_read,
650
+ .write = ibex_spi_host_write,
651
+ /* Ibex default LE */
652
+ .endianness = DEVICE_LITTLE_ENDIAN,
653
+};
654
+
655
+static Property ibex_spi_properties[] = {
656
+ DEFINE_PROP_UINT32("num_cs", IbexSPIHostState, num_cs, 1),
657
+ DEFINE_PROP_END_OF_LIST(),
658
+};
659
+
660
+static const VMStateDescription vmstate_ibex = {
661
+ .name = TYPE_IBEX_SPI_HOST,
662
+ .version_id = 1,
663
+ .minimum_version_id = 1,
664
+ .fields = (VMStateField[]) {
665
+ VMSTATE_UINT32_ARRAY(regs, IbexSPIHostState, IBEX_SPI_HOST_MAX_REGS),
666
+ VMSTATE_VARRAY_UINT32(config_opts, IbexSPIHostState,
667
+ num_cs, 0, vmstate_info_uint32, uint32_t),
668
+ VMSTATE_FIFO8(rx_fifo, IbexSPIHostState),
669
+ VMSTATE_FIFO8(tx_fifo, IbexSPIHostState),
670
+ VMSTATE_TIMER_PTR(fifo_trigger_handle, IbexSPIHostState),
671
+ VMSTATE_BOOL(init_status, IbexSPIHostState),
672
+ VMSTATE_END_OF_LIST()
673
+ }
674
+};
675
+
676
+static void fifo_trigger_update(void *opaque)
677
+{
678
+ IbexSPIHostState *s = opaque;
679
+ ibex_spi_host_transfer(s);
680
+}
681
+
682
+static void ibex_spi_host_realize(DeviceState *dev, Error **errp)
683
+{
684
+ IbexSPIHostState *s = IBEX_SPI_HOST(dev);
685
+ int i;
686
+
687
+ s->ssi = ssi_create_bus(dev, "ssi");
688
+ s->cs_lines = g_new0(qemu_irq, s->num_cs);
689
+
690
+ for (i = 0; i < s->num_cs; ++i) {
691
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cs_lines[i]);
692
+ }
693
+
694
+ /* Setup CONFIGOPTS Multi-register */
695
+ s->config_opts = g_new0(uint32_t, s->num_cs);
696
+
697
+ /* Setup FIFO Interrupt Timer */
698
+ s->fifo_trigger_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL,
699
+ fifo_trigger_update, s);
700
+
701
+ /* FIFO sizes as per OT Spec */
702
+ fifo8_create(&s->tx_fifo, IBEX_SPI_HOST_TXFIFO_LEN);
703
+ fifo8_create(&s->rx_fifo, IBEX_SPI_HOST_RXFIFO_LEN);
704
+}
705
+
706
+static void ibex_spi_host_init(Object *obj)
707
+{
708
+ IbexSPIHostState *s = IBEX_SPI_HOST(obj);
709
+
710
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->host_err);
711
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->event);
712
+
713
+ memory_region_init_io(&s->mmio, obj, &ibex_spi_ops, s,
714
+ TYPE_IBEX_SPI_HOST, 0x1000);
715
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
716
+}
717
+
718
+static void ibex_spi_host_class_init(ObjectClass *klass, void *data)
719
+{
720
+ DeviceClass *dc = DEVICE_CLASS(klass);
721
+ dc->realize = ibex_spi_host_realize;
722
+ dc->reset = ibex_spi_host_reset;
723
+ dc->vmsd = &vmstate_ibex;
724
+ device_class_set_props(dc, ibex_spi_properties);
725
+}
726
+
727
+static const TypeInfo ibex_spi_host_info = {
728
+ .name = TYPE_IBEX_SPI_HOST,
729
+ .parent = TYPE_SYS_BUS_DEVICE,
730
+ .instance_size = sizeof(IbexSPIHostState),
731
+ .instance_init = ibex_spi_host_init,
732
+ .class_init = ibex_spi_host_class_init,
733
+};
734
+
735
+static void ibex_spi_host_register_types(void)
736
+{
737
+ type_register_static(&ibex_spi_host_info);
738
+}
739
+
740
+type_init(ibex_spi_host_register_types)
741
diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build
742
index XXXXXXX..XXXXXXX 100644
743
--- a/hw/ssi/meson.build
744
+++ b/hw/ssi/meson.build
745
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_XILINX_SPIPS', if_true: files('xilinx_spips.c'))
746
softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-ospi.c'))
747
softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_spi.c'))
748
softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_spi.c'))
749
+softmmu_ss.add(when: 'CONFIG_IBEX', if_true: files('ibex_spi_host.c'))
750
diff --git a/hw/ssi/trace-events b/hw/ssi/trace-events
751
index XXXXXXX..XXXXXXX 100644
752
--- a/hw/ssi/trace-events
753
+++ b/hw/ssi/trace-events
754
@@ -XXX,XX +XXX,XX @@ npcm7xx_fiu_ctrl_read(const char *id, uint64_t addr, uint32_t data) "%s offset:
755
npcm7xx_fiu_ctrl_write(const char *id, uint64_t addr, uint32_t data) "%s offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
756
npcm7xx_fiu_flash_read(const char *id, int cs, uint64_t addr, unsigned int size, uint64_t value) "%s[%d] offset: 0x%08" PRIx64 " size: %u value: 0x%" PRIx64
757
npcm7xx_fiu_flash_write(const char *id, unsigned cs, uint64_t addr, unsigned int size, uint64_t value) "%s[%d] offset: 0x%08" PRIx64 " size: %u value: 0x%" PRIx64
758
+
759
+# ibex_spi_host.c
760
+
761
+ibex_spi_host_reset(const char *msg) "%s"
762
+ibex_spi_host_transfer(uint32_t tx_data, uint32_t rx_data) "tx_data: 0x%" PRIx32 " rx_data: @0x%" PRIx32
763
+ibex_spi_host_write(uint64_t addr, uint32_t size, uint64_t data) "@0x%" PRIx64 " size %u: 0x%" PRIx64
764
+ibex_spi_host_read(uint64_t addr, uint32_t size) "@0x%" PRIx64 " size %u:"
765
--
766
2.35.1
diff view generated by jsdifflib
New patch
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
1
2
3
Connect spi host[1/0] to opentitan.
4
5
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-Id: <20220303045426.511588-2-alistair.francis@opensource.wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
include/hw/riscv/opentitan.h | 30 +++++++++++++++++++++---------
12
hw/riscv/opentitan.c | 36 ++++++++++++++++++++++++++++++++----
13
2 files changed, 53 insertions(+), 13 deletions(-)
14
15
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/riscv/opentitan.h
18
+++ b/include/hw/riscv/opentitan.h
19
@@ -XXX,XX +XXX,XX @@
20
#include "hw/intc/sifive_plic.h"
21
#include "hw/char/ibex_uart.h"
22
#include "hw/timer/ibex_timer.h"
23
+#include "hw/ssi/ibex_spi_host.h"
24
#include "qom/object.h"
25
26
#define TYPE_RISCV_IBEX_SOC "riscv.lowrisc.ibex.soc"
27
OBJECT_DECLARE_SIMPLE_TYPE(LowRISCIbexSoCState, RISCV_IBEX_SOC)
28
29
+enum {
30
+ OPENTITAN_SPI_HOST0,
31
+ OPENTITAN_SPI_HOST1,
32
+ OPENTITAN_NUM_SPI_HOSTS,
33
+};
34
+
35
struct LowRISCIbexSoCState {
36
/*< private >*/
37
SysBusDevice parent_obj;
38
@@ -XXX,XX +XXX,XX @@ struct LowRISCIbexSoCState {
39
SiFivePLICState plic;
40
IbexUartState uart;
41
IbexTimerState timer;
42
+ IbexSPIHostState spi_host[OPENTITAN_NUM_SPI_HOSTS];
43
44
MemoryRegion flash_mem;
45
MemoryRegion rom;
46
@@ -XXX,XX +XXX,XX @@ enum {
47
};
48
49
enum {
50
- IBEX_TIMER_TIMEREXPIRED0_0 = 126,
51
- IBEX_UART0_RX_PARITY_ERR_IRQ = 8,
52
- IBEX_UART0_RX_TIMEOUT_IRQ = 7,
53
- IBEX_UART0_RX_BREAK_ERR_IRQ = 6,
54
- IBEX_UART0_RX_FRAME_ERR_IRQ = 5,
55
- IBEX_UART0_RX_OVERFLOW_IRQ = 4,
56
- IBEX_UART0_TX_EMPTY_IRQ = 3,
57
- IBEX_UART0_RX_WATERMARK_IRQ = 2,
58
- IBEX_UART0_TX_WATERMARK_IRQ = 1,
59
+ IBEX_UART0_TX_WATERMARK_IRQ = 1,
60
+ IBEX_UART0_RX_WATERMARK_IRQ = 2,
61
+ IBEX_UART0_TX_EMPTY_IRQ = 3,
62
+ IBEX_UART0_RX_OVERFLOW_IRQ = 4,
63
+ IBEX_UART0_RX_FRAME_ERR_IRQ = 5,
64
+ IBEX_UART0_RX_BREAK_ERR_IRQ = 6,
65
+ IBEX_UART0_RX_TIMEOUT_IRQ = 7,
66
+ IBEX_UART0_RX_PARITY_ERR_IRQ = 8,
67
+ IBEX_TIMER_TIMEREXPIRED0_0 = 126,
68
+ IBEX_SPI_HOST0_ERR_IRQ = 150,
69
+ IBEX_SPI_HOST0_SPI_EVENT_IRQ = 151,
70
+ IBEX_SPI_HOST1_ERR_IRQ = 152,
71
+ IBEX_SPI_HOST1_SPI_EVENT_IRQ = 153,
72
};
73
74
#endif
75
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/hw/riscv/opentitan.c
78
+++ b/hw/riscv/opentitan.c
79
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_init(Object *obj)
80
object_initialize_child(obj, "uart", &s->uart, TYPE_IBEX_UART);
81
82
object_initialize_child(obj, "timer", &s->timer, TYPE_IBEX_TIMER);
83
+
84
+ for (int i = 0; i < OPENTITAN_NUM_SPI_HOSTS; i++) {
85
+ object_initialize_child(obj, "spi_host[*]", &s->spi_host[i],
86
+ TYPE_IBEX_SPI_HOST);
87
+ }
88
}
89
90
static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
91
{
92
const MemMapEntry *memmap = ibex_memmap;
93
+ DeviceState *dev;
94
+ SysBusDevice *busdev;
95
MachineState *ms = MACHINE(qdev_get_machine());
96
LowRISCIbexSoCState *s = RISCV_IBEX_SOC(dev_soc);
97
MemoryRegion *sys_mem = get_system_memory();
98
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
99
qdev_get_gpio_in(DEVICE(qemu_get_cpu(0)),
100
IRQ_M_TIMER));
101
102
+ /* SPI-Hosts */
103
+ for (int i = 0; i < OPENTITAN_NUM_SPI_HOSTS; ++i) {
104
+ dev = DEVICE(&(s->spi_host[i]));
105
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi_host[i]), errp)) {
106
+ return;
107
+ }
108
+ busdev = SYS_BUS_DEVICE(dev);
109
+ sysbus_mmio_map(busdev, 0, memmap[IBEX_DEV_SPI_HOST0 + i].base);
110
+
111
+ switch (i) {
112
+ case OPENTITAN_SPI_HOST0:
113
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(DEVICE(&s->plic),
114
+ IBEX_SPI_HOST0_ERR_IRQ));
115
+ sysbus_connect_irq(busdev, 1, qdev_get_gpio_in(DEVICE(&s->plic),
116
+ IBEX_SPI_HOST0_SPI_EVENT_IRQ));
117
+ break;
118
+ case OPENTITAN_SPI_HOST1:
119
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(DEVICE(&s->plic),
120
+ IBEX_SPI_HOST1_ERR_IRQ));
121
+ sysbus_connect_irq(busdev, 1, qdev_get_gpio_in(DEVICE(&s->plic),
122
+ IBEX_SPI_HOST1_SPI_EVENT_IRQ));
123
+ break;
124
+ }
125
+ }
126
+
127
create_unimplemented_device("riscv.lowrisc.ibex.gpio",
128
memmap[IBEX_DEV_GPIO].base, memmap[IBEX_DEV_GPIO].size);
129
create_unimplemented_device("riscv.lowrisc.ibex.spi_device",
130
memmap[IBEX_DEV_SPI_DEVICE].base, memmap[IBEX_DEV_SPI_DEVICE].size);
131
- create_unimplemented_device("riscv.lowrisc.ibex.spi_host0",
132
- memmap[IBEX_DEV_SPI_HOST0].base, memmap[IBEX_DEV_SPI_HOST0].size);
133
- create_unimplemented_device("riscv.lowrisc.ibex.spi_host1",
134
- memmap[IBEX_DEV_SPI_HOST1].base, memmap[IBEX_DEV_SPI_HOST1].size);
135
create_unimplemented_device("riscv.lowrisc.ibex.i2c",
136
memmap[IBEX_DEV_I2C].base, memmap[IBEX_DEV_I2C].size);
137
create_unimplemented_device("riscv.lowrisc.ibex.pattgen",
138
--
139
2.35.1
diff view generated by jsdifflib
New patch
1
From: Atish Patra <atishp@rivosinc.com>
1
2
3
Currently, the privileged specification version are defined in
4
a complex manner for no benefit.
5
6
Simplify it by changing it to a simple enum based on.
7
8
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Atish Patra <atishp@rivosinc.com>
11
Message-Id: <20220303185440.512391-2-atishp@rivosinc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
target/riscv/cpu.h | 7 +++++--
15
1 file changed, 5 insertions(+), 2 deletions(-)
16
17
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/cpu.h
20
+++ b/target/riscv/cpu.h
21
@@ -XXX,XX +XXX,XX @@ enum {
22
RISCV_FEATURE_AIA
23
};
24
25
-#define PRIV_VERSION_1_10_0 0x00011000
26
-#define PRIV_VERSION_1_11_0 0x00011100
27
+/* Privileged specification version */
28
+enum {
29
+ PRIV_VERSION_1_10_0 = 0,
30
+ PRIV_VERSION_1_11_0,
31
+};
32
33
#define VEXT_VERSION_1_00_0 0x00010000
34
35
--
36
2.35.1
diff view generated by jsdifflib
New patch
1
From: Atish Patra <atishp@rivosinc.com>
1
2
3
Add the definition for ratified privileged specification version v1.12
4
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Signed-off-by: Atish Patra <atishp@rivosinc.com>
7
Message-Id: <20220303185440.512391-3-atishp@rivosinc.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
10
target/riscv/cpu.h | 1 +
11
1 file changed, 1 insertion(+)
12
13
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/cpu.h
16
+++ b/target/riscv/cpu.h
17
@@ -XXX,XX +XXX,XX @@ enum {
18
enum {
19
PRIV_VERSION_1_10_0 = 0,
20
PRIV_VERSION_1_11_0,
21
+ PRIV_VERSION_1_12_0,
22
};
23
24
#define VEXT_VERSION_1_00_0 0x00010000
25
--
26
2.35.1
diff view generated by jsdifflib
New patch
1
From: Atish Patra <atishp@rivosinc.com>
1
2
3
To allow/disallow the CSR access based on the privilege spec, a new field
4
in the csr_ops is introduced. It also adds the privileged specification
5
version (v1.12) for the CSRs introduced in the v1.12. This includes the
6
new ratified extensions such as Vector, Hypervisor and secconfig CSR.
7
However, it doesn't enforce the privilege version in this commit.
8
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Atish Patra <atishp@rivosinc.com>
11
Message-Id: <20220303185440.512391-4-atishp@rivosinc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
target/riscv/cpu.h | 2 +
15
target/riscv/csr.c | 103 ++++++++++++++++++++++++++++++---------------
16
2 files changed, 70 insertions(+), 35 deletions(-)
17
18
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/cpu.h
21
+++ b/target/riscv/cpu.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct {
23
riscv_csr_op_fn op;
24
riscv_csr_read128_fn read128;
25
riscv_csr_write128_fn write128;
26
+ /* The default priv spec version should be PRIV_VERSION_1_10_0 (i.e 0) */
27
+ uint32_t min_priv_ver;
28
} riscv_csr_operations;
29
30
/* CSR function table constants */
31
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/csr.c
34
+++ b/target/riscv/csr.c
35
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
36
[CSR_FRM] = { "frm", fs, read_frm, write_frm },
37
[CSR_FCSR] = { "fcsr", fs, read_fcsr, write_fcsr },
38
/* Vector CSRs */
39
- [CSR_VSTART] = { "vstart", vs, read_vstart, write_vstart },
40
- [CSR_VXSAT] = { "vxsat", vs, read_vxsat, write_vxsat },
41
- [CSR_VXRM] = { "vxrm", vs, read_vxrm, write_vxrm },
42
- [CSR_VCSR] = { "vcsr", vs, read_vcsr, write_vcsr },
43
- [CSR_VL] = { "vl", vs, read_vl },
44
- [CSR_VTYPE] = { "vtype", vs, read_vtype },
45
- [CSR_VLENB] = { "vlenb", vs, read_vlenb },
46
+ [CSR_VSTART] = { "vstart", vs, read_vstart, write_vstart,
47
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
48
+ [CSR_VXSAT] = { "vxsat", vs, read_vxsat, write_vxsat,
49
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
50
+ [CSR_VXRM] = { "vxrm", vs, read_vxrm, write_vxrm,
51
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
52
+ [CSR_VCSR] = { "vcsr", vs, read_vcsr, write_vcsr,
53
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
54
+ [CSR_VL] = { "vl", vs, read_vl,
55
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
56
+ [CSR_VTYPE] = { "vtype", vs, read_vtype,
57
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
58
+ [CSR_VLENB] = { "vlenb", vs, read_vlenb,
59
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
60
/* User Timers and Counters */
61
[CSR_CYCLE] = { "cycle", ctr, read_instret },
62
[CSR_INSTRET] = { "instret", ctr, read_instret },
63
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
64
[CSR_SIEH] = { "sieh", aia_smode32, NULL, NULL, rmw_sieh },
65
[CSR_SIPH] = { "siph", aia_smode32, NULL, NULL, rmw_siph },
66
67
- [CSR_HSTATUS] = { "hstatus", hmode, read_hstatus, write_hstatus },
68
- [CSR_HEDELEG] = { "hedeleg", hmode, read_hedeleg, write_hedeleg },
69
- [CSR_HIDELEG] = { "hideleg", hmode, NULL, NULL, rmw_hideleg },
70
- [CSR_HVIP] = { "hvip", hmode, NULL, NULL, rmw_hvip },
71
- [CSR_HIP] = { "hip", hmode, NULL, NULL, rmw_hip },
72
- [CSR_HIE] = { "hie", hmode, NULL, NULL, rmw_hie },
73
- [CSR_HCOUNTEREN] = { "hcounteren", hmode, read_hcounteren, write_hcounteren },
74
- [CSR_HGEIE] = { "hgeie", hmode, read_hgeie, write_hgeie },
75
- [CSR_HTVAL] = { "htval", hmode, read_htval, write_htval },
76
- [CSR_HTINST] = { "htinst", hmode, read_htinst, write_htinst },
77
- [CSR_HGEIP] = { "hgeip", hmode, read_hgeip, NULL },
78
- [CSR_HGATP] = { "hgatp", hmode, read_hgatp, write_hgatp },
79
- [CSR_HTIMEDELTA] = { "htimedelta", hmode, read_htimedelta, write_htimedelta },
80
- [CSR_HTIMEDELTAH] = { "htimedeltah", hmode32, read_htimedeltah, write_htimedeltah },
81
-
82
- [CSR_VSSTATUS] = { "vsstatus", hmode, read_vsstatus, write_vsstatus },
83
- [CSR_VSIP] = { "vsip", hmode, NULL, NULL, rmw_vsip },
84
- [CSR_VSIE] = { "vsie", hmode, NULL, NULL, rmw_vsie },
85
- [CSR_VSTVEC] = { "vstvec", hmode, read_vstvec, write_vstvec },
86
- [CSR_VSSCRATCH] = { "vsscratch", hmode, read_vsscratch, write_vsscratch },
87
- [CSR_VSEPC] = { "vsepc", hmode, read_vsepc, write_vsepc },
88
- [CSR_VSCAUSE] = { "vscause", hmode, read_vscause, write_vscause },
89
- [CSR_VSTVAL] = { "vstval", hmode, read_vstval, write_vstval },
90
- [CSR_VSATP] = { "vsatp", hmode, read_vsatp, write_vsatp },
91
-
92
- [CSR_MTVAL2] = { "mtval2", hmode, read_mtval2, write_mtval2 },
93
- [CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst },
94
+ [CSR_HSTATUS] = { "hstatus", hmode, read_hstatus, write_hstatus,
95
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
96
+ [CSR_HEDELEG] = { "hedeleg", hmode, read_hedeleg, write_hedeleg,
97
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
98
+ [CSR_HIDELEG] = { "hideleg", hmode, NULL, NULL, rmw_hideleg,
99
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
100
+ [CSR_HVIP] = { "hvip", hmode, NULL, NULL, rmw_hvip,
101
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
102
+ [CSR_HIP] = { "hip", hmode, NULL, NULL, rmw_hip,
103
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
104
+ [CSR_HIE] = { "hie", hmode, NULL, NULL, rmw_hie,
105
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
106
+ [CSR_HCOUNTEREN] = { "hcounteren", hmode, read_hcounteren, write_hcounteren,
107
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
108
+ [CSR_HGEIE] = { "hgeie", hmode, read_hgeie, write_hgeie,
109
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
110
+ [CSR_HTVAL] = { "htval", hmode, read_htval, write_htval,
111
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
112
+ [CSR_HTINST] = { "htinst", hmode, read_htinst, write_htinst,
113
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
114
+ [CSR_HGEIP] = { "hgeip", hmode, read_hgeip,
115
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
116
+ [CSR_HGATP] = { "hgatp", hmode, read_hgatp, write_hgatp,
117
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
118
+ [CSR_HTIMEDELTA] = { "htimedelta", hmode, read_htimedelta, write_htimedelta,
119
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
120
+ [CSR_HTIMEDELTAH] = { "htimedeltah", hmode32, read_htimedeltah, write_htimedeltah,
121
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
122
+
123
+ [CSR_VSSTATUS] = { "vsstatus", hmode, read_vsstatus, write_vsstatus,
124
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
125
+ [CSR_VSIP] = { "vsip", hmode, NULL, NULL, rmw_vsip,
126
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
127
+ [CSR_VSIE] = { "vsie", hmode, NULL, NULL, rmw_vsie ,
128
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
129
+ [CSR_VSTVEC] = { "vstvec", hmode, read_vstvec, write_vstvec,
130
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
131
+ [CSR_VSSCRATCH] = { "vsscratch", hmode, read_vsscratch, write_vsscratch,
132
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
133
+ [CSR_VSEPC] = { "vsepc", hmode, read_vsepc, write_vsepc,
134
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
135
+ [CSR_VSCAUSE] = { "vscause", hmode, read_vscause, write_vscause,
136
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
137
+ [CSR_VSTVAL] = { "vstval", hmode, read_vstval, write_vstval,
138
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
139
+ [CSR_VSATP] = { "vsatp", hmode, read_vsatp, write_vsatp,
140
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
141
+
142
+ [CSR_MTVAL2] = { "mtval2", hmode, read_mtval2, write_mtval2,
143
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
144
+ [CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst,
145
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
146
147
/* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */
148
[CSR_HVIEN] = { "hvien", aia_hmode, read_zero, write_ignore },
149
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
150
[CSR_VSIPH] = { "vsiph", aia_hmode32, NULL, NULL, rmw_vsiph },
151
152
/* Physical Memory Protection */
153
- [CSR_MSECCFG] = { "mseccfg", epmp, read_mseccfg, write_mseccfg },
154
+ [CSR_MSECCFG] = { "mseccfg", epmp, read_mseccfg, write_mseccfg,
155
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
156
[CSR_PMPCFG0] = { "pmpcfg0", pmp, read_pmpcfg, write_pmpcfg },
157
[CSR_PMPCFG1] = { "pmpcfg1", pmp, read_pmpcfg, write_pmpcfg },
158
[CSR_PMPCFG2] = { "pmpcfg2", pmp, read_pmpcfg, write_pmpcfg },
159
--
160
2.35.1
diff view generated by jsdifflib
New patch
1
From: Atish Patra <atishp@rivosinc.com>
1
2
3
RISC-V privileged specification v1.12 introduced a mconfigptr
4
which will hold the physical address of a configuration data
5
structure. As Qemu doesn't have a configuration data structure,
6
is read as zero which is valid as per the priv spec.
7
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Atish Patra <atishp@rivosinc.com>
10
Message-Id: <20220303185440.512391-5-atishp@rivosinc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/cpu_bits.h | 1 +
14
target/riscv/csr.c | 2 ++
15
2 files changed, 3 insertions(+)
16
17
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/cpu_bits.h
20
+++ b/target/riscv/cpu_bits.h
21
@@ -XXX,XX +XXX,XX @@
22
#define CSR_MARCHID 0xf12
23
#define CSR_MIMPID 0xf13
24
#define CSR_MHARTID 0xf14
25
+#define CSR_MCONFIGPTR 0xf15
26
27
/* Machine Trap Setup */
28
#define CSR_MSTATUS 0x300
29
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/csr.c
32
+++ b/target/riscv/csr.c
33
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
34
[CSR_MIMPID] = { "mimpid", any, read_zero },
35
[CSR_MHARTID] = { "mhartid", any, read_mhartid },
36
37
+ [CSR_MCONFIGPTR] = { "mconfigptr", any, read_zero,
38
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
39
/* Machine Trap Setup */
40
[CSR_MSTATUS] = { "mstatus", any, read_mstatus, write_mstatus, NULL,
41
read_mstatus_i128 },
42
--
43
2.35.1
diff view generated by jsdifflib
New patch
1
1
From: Atish Patra <atishp@rivosinc.com>
2
3
The RISC-V privileged specification v1.12 defines few execution
4
environment configuration CSRs that can be used enable/disable
5
extensions per privilege levels.
6
7
Add the basic support for these CSRs.
8
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Atish Patra <atishp@rivosinc.com>
11
Message-Id: <20220303185440.512391-6-atishp@rivosinc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
target/riscv/cpu.h | 5 ++
15
target/riscv/cpu_bits.h | 39 +++++++++++++++
16
target/riscv/csr.c | 107 ++++++++++++++++++++++++++++++++++++++++
17
target/riscv/machine.c | 23 +++++++++
18
4 files changed, 174 insertions(+)
19
20
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/cpu.h
23
+++ b/target/riscv/cpu.h
24
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
25
target_ulong spmbase;
26
target_ulong upmmask;
27
target_ulong upmbase;
28
+
29
+ /* CSRs for execution enviornment configuration */
30
+ uint64_t menvcfg;
31
+ target_ulong senvcfg;
32
+ uint64_t henvcfg;
33
#endif
34
target_ulong cur_pmmask;
35
target_ulong cur_pmbase;
36
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/riscv/cpu_bits.h
39
+++ b/target/riscv/cpu_bits.h
40
@@ -XXX,XX +XXX,XX @@
41
#define CSR_STVEC 0x105
42
#define CSR_SCOUNTEREN 0x106
43
44
+/* Supervisor Configuration CSRs */
45
+#define CSR_SENVCFG 0x10A
46
+
47
/* Supervisor Trap Handling */
48
#define CSR_SSCRATCH 0x140
49
#define CSR_SEPC 0x141
50
@@ -XXX,XX +XXX,XX @@
51
#define CSR_HTIMEDELTA 0x605
52
#define CSR_HTIMEDELTAH 0x615
53
54
+/* Hypervisor Configuration CSRs */
55
+#define CSR_HENVCFG 0x60A
56
+#define CSR_HENVCFGH 0x61A
57
+
58
/* Virtual CSRs */
59
#define CSR_VSSTATUS 0x200
60
#define CSR_VSIE 0x204
61
@@ -XXX,XX +XXX,XX @@
62
#define CSR_VSIEH 0x214
63
#define CSR_VSIPH 0x254
64
65
+/* Machine Configuration CSRs */
66
+#define CSR_MENVCFG 0x30A
67
+#define CSR_MENVCFGH 0x31A
68
+
69
/* Enhanced Physical Memory Protection (ePMP) */
70
#define CSR_MSECCFG 0x747
71
#define CSR_MSECCFGH 0x757
72
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
73
#define PM_EXT_CLEAN 0x00000002ULL
74
#define PM_EXT_DIRTY 0x00000003ULL
75
76
+/* Execution enviornment configuration bits */
77
+#define MENVCFG_FIOM BIT(0)
78
+#define MENVCFG_CBIE (3UL << 4)
79
+#define MENVCFG_CBCFE BIT(6)
80
+#define MENVCFG_CBZE BIT(7)
81
+#define MENVCFG_PBMTE BIT(62)
82
+#define MENVCFG_STCE BIT(63)
83
+
84
+/* For RV32 */
85
+#define MENVCFGH_PBMTE BIT(30)
86
+#define MENVCFGH_STCE BIT(31)
87
+
88
+#define SENVCFG_FIOM MENVCFG_FIOM
89
+#define SENVCFG_CBIE MENVCFG_CBIE
90
+#define SENVCFG_CBCFE MENVCFG_CBCFE
91
+#define SENVCFG_CBZE MENVCFG_CBZE
92
+
93
+#define HENVCFG_FIOM MENVCFG_FIOM
94
+#define HENVCFG_CBIE MENVCFG_CBIE
95
+#define HENVCFG_CBCFE MENVCFG_CBCFE
96
+#define HENVCFG_CBZE MENVCFG_CBZE
97
+#define HENVCFG_PBMTE MENVCFG_PBMTE
98
+#define HENVCFG_STCE MENVCFG_STCE
99
+
100
+/* For RV32 */
101
+#define HENVCFGH_PBMTE MENVCFGH_PBMTE
102
+#define HENVCFGH_STCE MENVCFGH_STCE
103
+
104
/* Offsets for every pair of control bits per each priv level */
105
#define XS_OFFSET 0ULL
106
#define U_OFFSET 2ULL
107
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/target/riscv/csr.c
110
+++ b/target/riscv/csr.c
111
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mtval(CPURISCVState *env, int csrno,
112
return RISCV_EXCP_NONE;
113
}
114
115
+/* Execution environment configuration setup */
116
+static RISCVException read_menvcfg(CPURISCVState *env, int csrno,
117
+ target_ulong *val)
118
+{
119
+ *val = env->menvcfg;
120
+ return RISCV_EXCP_NONE;
121
+}
122
+
123
+static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
124
+ target_ulong val)
125
+{
126
+ uint64_t mask = MENVCFG_FIOM | MENVCFG_CBIE | MENVCFG_CBCFE | MENVCFG_CBZE;
127
+
128
+ if (riscv_cpu_mxl(env) == MXL_RV64) {
129
+ mask |= MENVCFG_PBMTE | MENVCFG_STCE;
130
+ }
131
+ env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
132
+
133
+ return RISCV_EXCP_NONE;
134
+}
135
+
136
+static RISCVException read_menvcfgh(CPURISCVState *env, int csrno,
137
+ target_ulong *val)
138
+{
139
+ *val = env->menvcfg >> 32;
140
+ return RISCV_EXCP_NONE;
141
+}
142
+
143
+static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
144
+ target_ulong val)
145
+{
146
+ uint64_t mask = MENVCFG_PBMTE | MENVCFG_STCE;
147
+ uint64_t valh = (uint64_t)val << 32;
148
+
149
+ env->menvcfg = (env->menvcfg & ~mask) | (valh & mask);
150
+
151
+ return RISCV_EXCP_NONE;
152
+}
153
+
154
+static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
155
+ target_ulong *val)
156
+{
157
+ *val = env->senvcfg;
158
+ return RISCV_EXCP_NONE;
159
+}
160
+
161
+static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
162
+ target_ulong val)
163
+{
164
+ uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE;
165
+
166
+ env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
167
+
168
+ return RISCV_EXCP_NONE;
169
+}
170
+
171
+static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
172
+ target_ulong *val)
173
+{
174
+ *val = env->henvcfg;
175
+ return RISCV_EXCP_NONE;
176
+}
177
+
178
+static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
179
+ target_ulong val)
180
+{
181
+ uint64_t mask = HENVCFG_FIOM | HENVCFG_CBIE | HENVCFG_CBCFE | HENVCFG_CBZE;
182
+
183
+ if (riscv_cpu_mxl(env) == MXL_RV64) {
184
+ mask |= HENVCFG_PBMTE | HENVCFG_STCE;
185
+ }
186
+
187
+ env->henvcfg = (env->henvcfg & ~mask) | (val & mask);
188
+
189
+ return RISCV_EXCP_NONE;
190
+}
191
+
192
+static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
193
+ target_ulong *val)
194
+{
195
+ *val = env->henvcfg >> 32;
196
+ return RISCV_EXCP_NONE;
197
+}
198
+
199
+static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
200
+ target_ulong val)
201
+{
202
+ uint64_t mask = HENVCFG_PBMTE | HENVCFG_STCE;
203
+ uint64_t valh = (uint64_t)val << 32;
204
+
205
+ env->henvcfg = (env->henvcfg & ~mask) | (valh & mask);
206
+
207
+ return RISCV_EXCP_NONE;
208
+}
209
+
210
static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
211
uint64_t *ret_val,
212
uint64_t new_val, uint64_t wr_mask)
213
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
214
[CSR_MVIPH] = { "mviph", aia_any32, read_zero, write_ignore },
215
[CSR_MIPH] = { "miph", aia_any32, NULL, NULL, rmw_miph },
216
217
+ /* Execution environment configuration */
218
+ [CSR_MENVCFG] = { "menvcfg", any, read_menvcfg, write_menvcfg,
219
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
220
+ [CSR_MENVCFGH] = { "menvcfgh", any32, read_menvcfgh, write_menvcfgh,
221
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
222
+ [CSR_SENVCFG] = { "senvcfg", smode, read_senvcfg, write_senvcfg,
223
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
224
+ [CSR_HENVCFG] = { "henvcfg", hmode, read_henvcfg, write_henvcfg,
225
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
226
+ [CSR_HENVCFGH] = { "henvcfgh", hmode32, read_henvcfgh, write_henvcfgh,
227
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
228
+
229
/* Supervisor Trap Setup */
230
[CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus, NULL,
231
read_sstatus_i128 },
232
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
233
index XXXXXXX..XXXXXXX 100644
234
--- a/target/riscv/machine.c
235
+++ b/target/riscv/machine.c
236
@@ -XXX,XX +XXX,XX @@ static int riscv_cpu_post_load(void *opaque, int version_id)
237
return 0;
238
}
239
240
+static bool envcfg_needed(void *opaque)
241
+{
242
+ RISCVCPU *cpu = opaque;
243
+ CPURISCVState *env = &cpu->env;
244
+
245
+ return (env->priv_ver >= PRIV_VERSION_1_12_0 ? 1 : 0);
246
+}
247
+
248
+static const VMStateDescription vmstate_envcfg = {
249
+ .name = "cpu/envcfg",
250
+ .version_id = 1,
251
+ .minimum_version_id = 1,
252
+ .needed = envcfg_needed,
253
+ .fields = (VMStateField[]) {
254
+ VMSTATE_UINT64(env.menvcfg, RISCVCPU),
255
+ VMSTATE_UINTTL(env.senvcfg, RISCVCPU),
256
+ VMSTATE_UINT64(env.henvcfg, RISCVCPU),
257
+
258
+ VMSTATE_END_OF_LIST()
259
+ }
260
+};
261
+
262
const VMStateDescription vmstate_riscv_cpu = {
263
.name = "cpu",
264
.version_id = 3,
265
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = {
266
&vmstate_pointermasking,
267
&vmstate_rv128,
268
&vmstate_kvmtimer,
269
+ &vmstate_envcfg,
270
NULL
271
}
272
};
273
--
274
2.35.1
diff view generated by jsdifflib
New patch
1
From: Atish Patra <atishp@rivosinc.com>
1
2
3
Virt machine uses privileged specification version 1.12 now.
4
All other machine continue to use the default one defined for that
5
machine unless changed to 1.12 by the user explicitly.
6
7
This commit enforces the privilege version for csrs introduced in
8
v1.12 or after.
9
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Atish Patra <atishp@rivosinc.com>
12
Message-Id: <20220303185440.512391-7-atishp@rivosinc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
target/riscv/cpu.c | 8 +++++---
16
target/riscv/csr.c | 5 +++++
17
2 files changed, 10 insertions(+), 3 deletions(-)
18
19
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu.c
22
+++ b/target/riscv/cpu.c
23
@@ -XXX,XX +XXX,XX @@ static void riscv_any_cpu_init(Object *obj)
24
#elif defined(TARGET_RISCV64)
25
set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
26
#endif
27
- set_priv_version(env, PRIV_VERSION_1_11_0);
28
+ set_priv_version(env, PRIV_VERSION_1_12_0);
29
}
30
31
#if defined(TARGET_RISCV64)
32
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
33
}
34
35
if (cpu->cfg.priv_spec) {
36
- if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) {
37
+ if (!g_strcmp0(cpu->cfg.priv_spec, "v1.12.0")) {
38
+ priv_version = PRIV_VERSION_1_12_0;
39
+ } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) {
40
priv_version = PRIV_VERSION_1_11_0;
41
} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) {
42
priv_version = PRIV_VERSION_1_10_0;
43
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
44
if (priv_version) {
45
set_priv_version(env, priv_version);
46
} else if (!env->priv_ver) {
47
- set_priv_version(env, PRIV_VERSION_1_11_0);
48
+ set_priv_version(env, PRIV_VERSION_1_12_0);
49
}
50
51
if (cpu->cfg.mmu) {
52
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/riscv/csr.c
55
+++ b/target/riscv/csr.c
56
@@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
57
{
58
/* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
59
int read_only = get_field(csrno, 0xC00) == 3;
60
+ int csr_min_priv = csr_ops[csrno].min_priv_ver;
61
#if !defined(CONFIG_USER_ONLY)
62
int effective_priv = env->priv;
63
64
@@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
65
return RISCV_EXCP_ILLEGAL_INST;
66
}
67
68
+ if (env->priv_ver < csr_min_priv) {
69
+ return RISCV_EXCP_ILLEGAL_INST;
70
+ }
71
+
72
return csr_ops[csrno].predicate(env, csrno);
73
}
74
75
--
76
2.35.1
diff view generated by jsdifflib
New patch
1
From: Alistair Francis <alistair.francis@wdc.com>
1
2
3
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
4
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-Id: <20220317061817.3856850-2-alistair.francis@opensource.wdc.com>
7
---
8
target/riscv/cpu.c | 20 ++++++++++----------
9
1 file changed, 10 insertions(+), 10 deletions(-)
10
11
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/riscv/cpu.c
14
+++ b/target/riscv/cpu.c
15
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
16
if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
17
error_setg(errp,
18
"I and E extensions are incompatible");
19
- return;
20
- }
21
+ return;
22
+ }
23
24
if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) {
25
error_setg(errp,
26
"Either I or E extension must be set");
27
- return;
28
- }
29
+ return;
30
+ }
31
32
- if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m &
33
- cpu->cfg.ext_a & cpu->cfg.ext_f &
34
- cpu->cfg.ext_d)) {
35
+ if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m &
36
+ cpu->cfg.ext_a & cpu->cfg.ext_f &
37
+ cpu->cfg.ext_d)) {
38
warn_report("Setting G will also set IMAFD");
39
cpu->cfg.ext_i = true;
40
cpu->cfg.ext_m = true;
41
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_set_irq(void *opaque, int irq, int level)
42
case IRQ_S_EXT:
43
case IRQ_VS_EXT:
44
case IRQ_M_EXT:
45
- if (kvm_enabled()) {
46
+ if (kvm_enabled()) {
47
kvm_riscv_set_irq(cpu, irq, level);
48
- } else {
49
+ } else {
50
riscv_cpu_update_mip(cpu, 1 << irq, BOOL_TO_MASK(level));
51
- }
52
+ }
53
break;
54
default:
55
g_assert_not_reached();
56
--
57
2.35.1
diff view generated by jsdifflib
New patch
1
From: Alistair Francis <alistair.francis@wdc.com>
1
2
3
The RISC-V specification states that:
4
"Supervisor-level external interrupts are made pending based on the
5
logical-OR of the software-writable SEIP bit and the signal from the
6
external interrupt controller."
7
8
We currently only allow either the interrupt controller or software to
9
set the bit, which is incorrect.
10
11
This patch removes the miclaim mask when writing MIP to allow M-mode
12
software to inject interrupts, even with an interrupt controller.
13
14
We then also need to keep track of which source is setting MIP_SEIP. The
15
final value is a OR of both, so we add two bools and use that to keep
16
track of the current state. This way either source can change without
17
losing the correct value.
18
19
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/904
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-Id: <20220317061817.3856850-3-alistair.francis@opensource.wdc.com>
24
---
25
target/riscv/cpu.h | 8 ++++++++
26
target/riscv/cpu.c | 10 +++++++++-
27
target/riscv/csr.c | 8 ++++++--
28
3 files changed, 23 insertions(+), 3 deletions(-)
29
30
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/riscv/cpu.h
33
+++ b/target/riscv/cpu.h
34
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
35
uint64_t mstatus;
36
37
uint64_t mip;
38
+ /*
39
+ * MIP contains the software writable version of SEIP ORed with the
40
+ * external interrupt value. The MIP register is always up-to-date.
41
+ * To keep track of the current source, we also save booleans of the values
42
+ * here.
43
+ */
44
+ bool external_seip;
45
+ bool software_seip;
46
47
uint64_t miclaim;
48
49
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/riscv/cpu.c
52
+++ b/target/riscv/cpu.c
53
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_set_irq(void *opaque, int irq, int level)
54
case IRQ_VS_TIMER:
55
case IRQ_M_TIMER:
56
case IRQ_U_EXT:
57
- case IRQ_S_EXT:
58
case IRQ_VS_EXT:
59
case IRQ_M_EXT:
60
if (kvm_enabled()) {
61
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_set_irq(void *opaque, int irq, int level)
62
riscv_cpu_update_mip(cpu, 1 << irq, BOOL_TO_MASK(level));
63
}
64
break;
65
+ case IRQ_S_EXT:
66
+ if (kvm_enabled()) {
67
+ kvm_riscv_set_irq(cpu, irq, level);
68
+ } else {
69
+ env->external_seip = level;
70
+ riscv_cpu_update_mip(cpu, 1 << irq,
71
+ BOOL_TO_MASK(level | env->software_seip));
72
+ }
73
+ break;
74
default:
75
g_assert_not_reached();
76
}
77
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/riscv/csr.c
80
+++ b/target/riscv/csr.c
81
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
82
uint64_t new_val, uint64_t wr_mask)
83
{
84
RISCVCPU *cpu = env_archcpu(env);
85
- /* Allow software control of delegable interrupts not claimed by hardware */
86
- uint64_t old_mip, mask = wr_mask & delegable_ints & ~env->miclaim;
87
+ uint64_t old_mip, mask = wr_mask & delegable_ints;
88
uint32_t gin;
89
90
+ if (mask & MIP_SEIP) {
91
+ env->software_seip = new_val & MIP_SEIP;
92
+ new_val |= env->external_seip * MIP_SEIP;
93
+ }
94
+
95
if (mask) {
96
old_mip = riscv_cpu_update_mip(cpu, mask, (new_val & mask));
97
} else {
98
--
99
2.35.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
This adds initial support for the Sdtrig extension via the Trigger
4
Module, as defined in the RISC-V Debug Specification [1].
5
6
Only "Address / Data Match" trigger (type 2) is implemented as of now,
7
which is mainly used for hardware breakpoint and watchpoint. The number
8
of type 2 triggers implemented is 2, which is the number that we can
9
find in the SiFive U54/U74 cores.
10
11
[1] https://github.com/riscv/riscv-debug-spec/raw/master/riscv-debug-stable.pdf
12
13
Signed-off-by: Bin Meng <bin.meng@windriver.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-Id: <20220315065529.62198-2-bmeng.cn@gmail.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
18
target/riscv/cpu.h | 5 +
19
target/riscv/debug.h | 108 +++++++++++++
20
target/riscv/debug.c | 339 +++++++++++++++++++++++++++++++++++++++
21
target/riscv/meson.build | 1 +
22
4 files changed, 453 insertions(+)
23
create mode 100644 target/riscv/debug.h
24
create mode 100644 target/riscv/debug.c
25
26
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/riscv/cpu.h
29
+++ b/target/riscv/cpu.h
30
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState CPURISCVState;
31
32
#if !defined(CONFIG_USER_ONLY)
33
#include "pmp.h"
34
+#include "debug.h"
35
#endif
36
37
#define RV_VLEN_MAX 1024
38
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
39
pmp_table_t pmp_state;
40
target_ulong mseccfg;
41
42
+ /* trigger module */
43
+ target_ulong trigger_cur;
44
+ type2_trigger_t type2_trig[TRIGGER_TYPE2_NUM];
45
+
46
/* machine specific rdtime callback */
47
uint64_t (*rdtime_fn)(uint32_t);
48
uint32_t rdtime_fn_arg;
49
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
50
new file mode 100644
51
index XXXXXXX..XXXXXXX
52
--- /dev/null
53
+++ b/target/riscv/debug.h
54
@@ -XXX,XX +XXX,XX @@
55
+/*
56
+ * QEMU RISC-V Native Debug Support
57
+ *
58
+ * Copyright (c) 2022 Wind River Systems, Inc.
59
+ *
60
+ * Author:
61
+ * Bin Meng <bin.meng@windriver.com>
62
+ *
63
+ * This program is free software; you can redistribute it and/or modify it
64
+ * under the terms and conditions of the GNU General Public License,
65
+ * version 2 or later, as published by the Free Software Foundation.
66
+ *
67
+ * This program is distributed in the hope it will be useful, but WITHOUT
68
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
69
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
70
+ * more details.
71
+ *
72
+ * You should have received a copy of the GNU General Public License along with
73
+ * this program. If not, see <http://www.gnu.org/licenses/>.
74
+ */
75
+
76
+#ifndef RISCV_DEBUG_H
77
+#define RISCV_DEBUG_H
78
+
79
+/* trigger indexes implemented */
80
+enum {
81
+ TRIGGER_TYPE2_IDX_0 = 0,
82
+ TRIGGER_TYPE2_IDX_1,
83
+ TRIGGER_TYPE2_NUM,
84
+ TRIGGER_NUM = TRIGGER_TYPE2_NUM
85
+};
86
+
87
+/* register index of tdata CSRs */
88
+enum {
89
+ TDATA1 = 0,
90
+ TDATA2,
91
+ TDATA3,
92
+ TDATA_NUM
93
+};
94
+
95
+typedef enum {
96
+ TRIGGER_TYPE_NO_EXIST = 0, /* trigger does not exist */
97
+ TRIGGER_TYPE_AD_MATCH = 2, /* address/data match trigger */
98
+ TRIGGER_TYPE_INST_CNT = 3, /* instruction count trigger */
99
+ TRIGGER_TYPE_INT = 4, /* interrupt trigger */
100
+ TRIGGER_TYPE_EXCP = 5, /* exception trigger */
101
+ TRIGGER_TYPE_AD_MATCH6 = 6, /* new address/data match trigger */
102
+ TRIGGER_TYPE_EXT_SRC = 7, /* external source trigger */
103
+ TRIGGER_TYPE_UNAVAIL = 15 /* trigger exists, but unavailable */
104
+} trigger_type_t;
105
+
106
+typedef struct {
107
+ target_ulong mcontrol;
108
+ target_ulong maddress;
109
+ struct CPUBreakpoint *bp;
110
+ struct CPUWatchpoint *wp;
111
+} type2_trigger_t;
112
+
113
+/* tdata field masks */
114
+
115
+#define RV32_TYPE(t) ((uint32_t)(t) << 28)
116
+#define RV32_TYPE_MASK (0xf << 28)
117
+#define RV32_DMODE BIT(27)
118
+#define RV64_TYPE(t) ((uint64_t)(t) << 60)
119
+#define RV64_TYPE_MASK (0xfULL << 60)
120
+#define RV64_DMODE BIT_ULL(59)
121
+
122
+/* mcontrol field masks */
123
+
124
+#define TYPE2_LOAD BIT(0)
125
+#define TYPE2_STORE BIT(1)
126
+#define TYPE2_EXEC BIT(2)
127
+#define TYPE2_U BIT(3)
128
+#define TYPE2_S BIT(4)
129
+#define TYPE2_M BIT(6)
130
+#define TYPE2_MATCH (0xf << 7)
131
+#define TYPE2_CHAIN BIT(11)
132
+#define TYPE2_ACTION (0xf << 12)
133
+#define TYPE2_SIZELO (0x3 << 16)
134
+#define TYPE2_TIMING BIT(18)
135
+#define TYPE2_SELECT BIT(19)
136
+#define TYPE2_HIT BIT(20)
137
+#define TYPE2_SIZEHI (0x3 << 21) /* RV64 only */
138
+
139
+/* access size */
140
+enum {
141
+ SIZE_ANY = 0,
142
+ SIZE_1B,
143
+ SIZE_2B,
144
+ SIZE_4B,
145
+ SIZE_6B,
146
+ SIZE_8B,
147
+ SIZE_10B,
148
+ SIZE_12B,
149
+ SIZE_14B,
150
+ SIZE_16B,
151
+ SIZE_NUM = 16
152
+};
153
+
154
+bool tdata_available(CPURISCVState *env, int tdata_index);
155
+
156
+target_ulong tselect_csr_read(CPURISCVState *env);
157
+void tselect_csr_write(CPURISCVState *env, target_ulong val);
158
+
159
+target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index);
160
+void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val);
161
+
162
+#endif /* RISCV_DEBUG_H */
163
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
164
new file mode 100644
165
index XXXXXXX..XXXXXXX
166
--- /dev/null
167
+++ b/target/riscv/debug.c
168
@@ -XXX,XX +XXX,XX @@
169
+/*
170
+ * QEMU RISC-V Native Debug Support
171
+ *
172
+ * Copyright (c) 2022 Wind River Systems, Inc.
173
+ *
174
+ * Author:
175
+ * Bin Meng <bin.meng@windriver.com>
176
+ *
177
+ * This provides the native debug support via the Trigger Module, as defined
178
+ * in the RISC-V Debug Specification:
179
+ * https://github.com/riscv/riscv-debug-spec/raw/master/riscv-debug-stable.pdf
180
+ *
181
+ * This program is free software; you can redistribute it and/or modify it
182
+ * under the terms and conditions of the GNU General Public License,
183
+ * version 2 or later, as published by the Free Software Foundation.
184
+ *
185
+ * This program is distributed in the hope it will be useful, but WITHOUT
186
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
187
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
188
+ * more details.
189
+ *
190
+ * You should have received a copy of the GNU General Public License along with
191
+ * this program. If not, see <http://www.gnu.org/licenses/>.
192
+ */
193
+
194
+#include "qemu/osdep.h"
195
+#include "qemu/log.h"
196
+#include "qapi/error.h"
197
+#include "cpu.h"
198
+#include "trace.h"
199
+#include "exec/exec-all.h"
200
+
201
+/*
202
+ * The following M-mode trigger CSRs are implemented:
203
+ *
204
+ * - tselect
205
+ * - tdata1
206
+ * - tdata2
207
+ * - tdata3
208
+ *
209
+ * We don't support writable 'type' field in the tdata1 register, so there is
210
+ * no need to implement the "tinfo" CSR.
211
+ *
212
+ * The following triggers are implemented:
213
+ *
214
+ * Index | Type | tdata mapping | Description
215
+ * ------+------+------------------------+------------
216
+ * 0 | 2 | tdata1, tdata2 | Address / Data Match
217
+ * 1 | 2 | tdata1, tdata2 | Address / Data Match
218
+ */
219
+
220
+/* tdata availability of a trigger */
221
+typedef bool tdata_avail[TDATA_NUM];
222
+
223
+static tdata_avail tdata_mapping[TRIGGER_NUM] = {
224
+ [TRIGGER_TYPE2_IDX_0 ... TRIGGER_TYPE2_IDX_1] = { true, true, false },
225
+};
226
+
227
+/* only breakpoint size 1/2/4/8 supported */
228
+static int access_size[SIZE_NUM] = {
229
+ [SIZE_ANY] = 0,
230
+ [SIZE_1B] = 1,
231
+ [SIZE_2B] = 2,
232
+ [SIZE_4B] = 4,
233
+ [SIZE_6B] = -1,
234
+ [SIZE_8B] = 8,
235
+ [6 ... 15] = -1,
236
+};
237
+
238
+static inline target_ulong trigger_type(CPURISCVState *env,
239
+ trigger_type_t type)
240
+{
241
+ target_ulong tdata1;
242
+
243
+ switch (riscv_cpu_mxl(env)) {
244
+ case MXL_RV32:
245
+ tdata1 = RV32_TYPE(type);
246
+ break;
247
+ case MXL_RV64:
248
+ tdata1 = RV64_TYPE(type);
249
+ break;
250
+ default:
251
+ g_assert_not_reached();
252
+ }
253
+
254
+ return tdata1;
255
+}
256
+
257
+bool tdata_available(CPURISCVState *env, int tdata_index)
258
+{
259
+ if (unlikely(tdata_index >= TDATA_NUM)) {
260
+ return false;
261
+ }
262
+
263
+ if (unlikely(env->trigger_cur >= TRIGGER_NUM)) {
264
+ return false;
265
+ }
266
+
267
+ return tdata_mapping[env->trigger_cur][tdata_index];
268
+}
269
+
270
+target_ulong tselect_csr_read(CPURISCVState *env)
271
+{
272
+ return env->trigger_cur;
273
+}
274
+
275
+void tselect_csr_write(CPURISCVState *env, target_ulong val)
276
+{
277
+ /* all target_ulong bits of tselect are implemented */
278
+ env->trigger_cur = val;
279
+}
280
+
281
+static target_ulong tdata1_validate(CPURISCVState *env, target_ulong val,
282
+ trigger_type_t t)
283
+{
284
+ uint32_t type, dmode;
285
+ target_ulong tdata1;
286
+
287
+ switch (riscv_cpu_mxl(env)) {
288
+ case MXL_RV32:
289
+ type = extract32(val, 28, 4);
290
+ dmode = extract32(val, 27, 1);
291
+ tdata1 = RV32_TYPE(t);
292
+ break;
293
+ case MXL_RV64:
294
+ type = extract64(val, 60, 4);
295
+ dmode = extract64(val, 59, 1);
296
+ tdata1 = RV64_TYPE(t);
297
+ break;
298
+ default:
299
+ g_assert_not_reached();
300
+ }
301
+
302
+ if (type != t) {
303
+ qemu_log_mask(LOG_GUEST_ERROR,
304
+ "ignoring type write to tdata1 register\n");
305
+ }
306
+ if (dmode != 0) {
307
+ qemu_log_mask(LOG_UNIMP, "debug mode is not supported\n");
308
+ }
309
+
310
+ return tdata1;
311
+}
312
+
313
+static inline void warn_always_zero_bit(target_ulong val, target_ulong mask,
314
+ const char *msg)
315
+{
316
+ if (val & mask) {
317
+ qemu_log_mask(LOG_UNIMP, "%s bit is always zero\n", msg);
318
+ }
319
+}
320
+
321
+static uint32_t type2_breakpoint_size(CPURISCVState *env, target_ulong ctrl)
322
+{
323
+ uint32_t size, sizelo, sizehi = 0;
324
+
325
+ if (riscv_cpu_mxl(env) == MXL_RV64) {
326
+ sizehi = extract32(ctrl, 21, 2);
327
+ }
328
+ sizelo = extract32(ctrl, 16, 2);
329
+ size = (sizehi << 2) | sizelo;
330
+
331
+ return size;
332
+}
333
+
334
+static inline bool type2_breakpoint_enabled(target_ulong ctrl)
335
+{
336
+ bool mode = !!(ctrl & (TYPE2_U | TYPE2_S | TYPE2_M));
337
+ bool rwx = !!(ctrl & (TYPE2_LOAD | TYPE2_STORE | TYPE2_EXEC));
338
+
339
+ return mode && rwx;
340
+}
341
+
342
+static target_ulong type2_mcontrol_validate(CPURISCVState *env,
343
+ target_ulong ctrl)
344
+{
345
+ target_ulong val;
346
+ uint32_t size;
347
+
348
+ /* validate the generic part first */
349
+ val = tdata1_validate(env, ctrl, TRIGGER_TYPE_AD_MATCH);
350
+
351
+ /* validate unimplemented (always zero) bits */
352
+ warn_always_zero_bit(ctrl, TYPE2_MATCH, "match");
353
+ warn_always_zero_bit(ctrl, TYPE2_CHAIN, "chain");
354
+ warn_always_zero_bit(ctrl, TYPE2_ACTION, "action");
355
+ warn_always_zero_bit(ctrl, TYPE2_TIMING, "timing");
356
+ warn_always_zero_bit(ctrl, TYPE2_SELECT, "select");
357
+ warn_always_zero_bit(ctrl, TYPE2_HIT, "hit");
358
+
359
+ /* validate size encoding */
360
+ size = type2_breakpoint_size(env, ctrl);
361
+ if (access_size[size] == -1) {
362
+ qemu_log_mask(LOG_UNIMP, "access size %d is not supported, using SIZE_ANY\n",
363
+ size);
364
+ } else {
365
+ val |= (ctrl & TYPE2_SIZELO);
366
+ if (riscv_cpu_mxl(env) == MXL_RV64) {
367
+ val |= (ctrl & TYPE2_SIZEHI);
368
+ }
369
+ }
370
+
371
+ /* keep the mode and attribute bits */
372
+ val |= (ctrl & (TYPE2_U | TYPE2_S | TYPE2_M |
373
+ TYPE2_LOAD | TYPE2_STORE | TYPE2_EXEC));
374
+
375
+ return val;
376
+}
377
+
378
+static void type2_breakpoint_insert(CPURISCVState *env, target_ulong index)
379
+{
380
+ target_ulong ctrl = env->type2_trig[index].mcontrol;
381
+ target_ulong addr = env->type2_trig[index].maddress;
382
+ bool enabled = type2_breakpoint_enabled(ctrl);
383
+ CPUState *cs = env_cpu(env);
384
+ int flags = BP_CPU | BP_STOP_BEFORE_ACCESS;
385
+ uint32_t size;
386
+
387
+ if (!enabled) {
388
+ return;
389
+ }
390
+
391
+ if (ctrl & TYPE2_EXEC) {
392
+ cpu_breakpoint_insert(cs, addr, flags, &env->type2_trig[index].bp);
393
+ }
394
+
395
+ if (ctrl & TYPE2_LOAD) {
396
+ flags |= BP_MEM_READ;
397
+ }
398
+ if (ctrl & TYPE2_STORE) {
399
+ flags |= BP_MEM_WRITE;
400
+ }
401
+
402
+ if (flags & BP_MEM_ACCESS) {
403
+ size = type2_breakpoint_size(env, ctrl);
404
+ if (size != 0) {
405
+ cpu_watchpoint_insert(cs, addr, size, flags,
406
+ &env->type2_trig[index].wp);
407
+ } else {
408
+ cpu_watchpoint_insert(cs, addr, 8, flags,
409
+ &env->type2_trig[index].wp);
410
+ }
411
+ }
412
+}
413
+
414
+static void type2_breakpoint_remove(CPURISCVState *env, target_ulong index)
415
+{
416
+ CPUState *cs = env_cpu(env);
417
+
418
+ if (env->type2_trig[index].bp) {
419
+ cpu_breakpoint_remove_by_ref(cs, env->type2_trig[index].bp);
420
+ env->type2_trig[index].bp = NULL;
421
+ }
422
+
423
+ if (env->type2_trig[index].wp) {
424
+ cpu_watchpoint_remove_by_ref(cs, env->type2_trig[index].wp);
425
+ env->type2_trig[index].wp = NULL;
426
+ }
427
+}
428
+
429
+static target_ulong type2_reg_read(CPURISCVState *env,
430
+ target_ulong trigger_index, int tdata_index)
431
+{
432
+ uint32_t index = trigger_index - TRIGGER_TYPE2_IDX_0;
433
+ target_ulong tdata;
434
+
435
+ switch (tdata_index) {
436
+ case TDATA1:
437
+ tdata = env->type2_trig[index].mcontrol;
438
+ break;
439
+ case TDATA2:
440
+ tdata = env->type2_trig[index].maddress;
441
+ break;
442
+ default:
443
+ g_assert_not_reached();
444
+ }
445
+
446
+ return tdata;
447
+}
448
+
449
+static void type2_reg_write(CPURISCVState *env, target_ulong trigger_index,
450
+ int tdata_index, target_ulong val)
451
+{
452
+ uint32_t index = trigger_index - TRIGGER_TYPE2_IDX_0;
453
+ target_ulong new_val;
454
+
455
+ switch (tdata_index) {
456
+ case TDATA1:
457
+ new_val = type2_mcontrol_validate(env, val);
458
+ if (new_val != env->type2_trig[index].mcontrol) {
459
+ env->type2_trig[index].mcontrol = new_val;
460
+ type2_breakpoint_remove(env, index);
461
+ type2_breakpoint_insert(env, index);
462
+ }
463
+ break;
464
+ case TDATA2:
465
+ if (val != env->type2_trig[index].maddress) {
466
+ env->type2_trig[index].maddress = val;
467
+ type2_breakpoint_remove(env, index);
468
+ type2_breakpoint_insert(env, index);
469
+ }
470
+ break;
471
+ default:
472
+ g_assert_not_reached();
473
+ }
474
+
475
+ return;
476
+}
477
+
478
+typedef target_ulong (*tdata_read_func)(CPURISCVState *env,
479
+ target_ulong trigger_index,
480
+ int tdata_index);
481
+
482
+static tdata_read_func trigger_read_funcs[TRIGGER_NUM] = {
483
+ [TRIGGER_TYPE2_IDX_0 ... TRIGGER_TYPE2_IDX_1] = type2_reg_read,
484
+};
485
+
486
+typedef void (*tdata_write_func)(CPURISCVState *env,
487
+ target_ulong trigger_index,
488
+ int tdata_index,
489
+ target_ulong val);
490
+
491
+static tdata_write_func trigger_write_funcs[TRIGGER_NUM] = {
492
+ [TRIGGER_TYPE2_IDX_0 ... TRIGGER_TYPE2_IDX_1] = type2_reg_write,
493
+};
494
+
495
+target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index)
496
+{
497
+ tdata_read_func read_func = trigger_read_funcs[env->trigger_cur];
498
+
499
+ return read_func(env, env->trigger_cur, tdata_index);
500
+}
501
+
502
+void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val)
503
+{
504
+ tdata_write_func write_func = trigger_write_funcs[env->trigger_cur];
505
+
506
+ return write_func(env, env->trigger_cur, tdata_index, val);
507
+}
508
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
509
index XXXXXXX..XXXXXXX 100644
510
--- a/target/riscv/meson.build
511
+++ b/target/riscv/meson.build
512
@@ -XXX,XX +XXX,XX @@ riscv_softmmu_ss = ss.source_set()
513
riscv_softmmu_ss.add(files(
514
'arch_dump.c',
515
'pmp.c',
516
+ 'debug.c',
517
'monitor.c',
518
'machine.c'
519
))
520
--
521
2.35.1
diff view generated by jsdifflib
New patch
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
2
3
for some cases, scale is always equal or less than 0, since lmul is not larger than 3
4
5
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
7
Reviewed-by: Frank Chang <frank.chang@sifive.com>
8
Acked-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-Id: <20220325085902.29500-1-liweiwei@iscas.ac.cn>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/insn_trans/trans_rvv.c.inc | 8 +++-----
13
1 file changed, 3 insertions(+), 5 deletions(-)
14
15
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/insn_trans/trans_rvv.c.inc
18
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
19
@@ -XXX,XX +XXX,XX @@ GEN_LDST_WHOLE_TRANS(vs8r_v, 8, true)
20
static inline uint32_t MAXSZ(DisasContext *s)
21
{
22
int scale = s->lmul - 3;
23
- return scale < 0 ? s->cfg_ptr->vlen >> -scale : s->cfg_ptr->vlen << scale;
24
+ return s->cfg_ptr->vlen >> -scale;
25
}
26
27
static bool opivv_check(DisasContext *s, arg_rmrr *a)
28
@@ -XXX,XX +XXX,XX @@ static bool trans_vrgather_vx(DisasContext *s, arg_rmrr *a)
29
30
if (a->vm && s->vl_eq_vlmax) {
31
int scale = s->lmul - (s->sew + 3);
32
- int vlmax = scale < 0 ?
33
- s->cfg_ptr->vlen >> -scale : s->cfg_ptr->vlen << scale;
34
+ int vlmax = s->cfg_ptr->vlen >> -scale;
35
TCGv_i64 dest = tcg_temp_new_i64();
36
37
if (a->rs1 == 0) {
38
@@ -XXX,XX +XXX,XX @@ static bool trans_vrgather_vi(DisasContext *s, arg_rmrr *a)
39
40
if (a->vm && s->vl_eq_vlmax) {
41
int scale = s->lmul - (s->sew + 3);
42
- int vlmax = scale < 0 ?
43
- s->cfg_ptr->vlen >> -scale : s->cfg_ptr->vlen << scale;
44
+ int vlmax = s->cfg_ptr->vlen >> -scale;
45
if (a->rs1 >= vlmax) {
46
tcg_gen_gvec_dup_imm(MO_64, vreg_ofs(s, a->rd),
47
MAXSZ(s), MAXSZ(s), 0);
48
--
49
2.35.1
diff view generated by jsdifflib
New patch
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
2
3
LEN is not used for GEN_VEXT_VMV_WHOLE macro, so vmv<nr>r.v can share
4
the same helper
5
6
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
7
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
8
Reviewed-by: Frank Chang <frank.chang@sifive.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20220325085902.29500-2-liweiwei@iscas.ac.cn>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/helper.h | 5 +----
14
target/riscv/vector_helper.c | 29 ++++++++++---------------
15
target/riscv/insn_trans/trans_rvv.c.inc | 17 +++++----------
16
3 files changed, 18 insertions(+), 33 deletions(-)
17
18
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/helper.h
21
+++ b/target/riscv/helper.h
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vcompress_vm_h, void, ptr, ptr, ptr, ptr, env, i32)
23
DEF_HELPER_6(vcompress_vm_w, void, ptr, ptr, ptr, ptr, env, i32)
24
DEF_HELPER_6(vcompress_vm_d, void, ptr, ptr, ptr, ptr, env, i32)
25
26
-DEF_HELPER_4(vmv1r_v, void, ptr, ptr, env, i32)
27
-DEF_HELPER_4(vmv2r_v, void, ptr, ptr, env, i32)
28
-DEF_HELPER_4(vmv4r_v, void, ptr, ptr, env, i32)
29
-DEF_HELPER_4(vmv8r_v, void, ptr, ptr, env, i32)
30
+DEF_HELPER_4(vmvr_v, void, ptr, ptr, env, i32)
31
32
DEF_HELPER_5(vzext_vf2_h, void, ptr, ptr, ptr, env, i32)
33
DEF_HELPER_5(vzext_vf2_w, void, ptr, ptr, ptr, env, i32)
34
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/riscv/vector_helper.c
37
+++ b/target/riscv/vector_helper.c
38
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_VCOMPRESS_VM(vcompress_vm_w, uint32_t, H4)
39
GEN_VEXT_VCOMPRESS_VM(vcompress_vm_d, uint64_t, H8)
40
41
/* Vector Whole Register Move */
42
-#define GEN_VEXT_VMV_WHOLE(NAME, LEN) \
43
-void HELPER(NAME)(void *vd, void *vs2, CPURISCVState *env, \
44
- uint32_t desc) \
45
-{ \
46
- /* EEW = 8 */ \
47
- uint32_t maxsz = simd_maxsz(desc); \
48
- uint32_t i = env->vstart; \
49
- \
50
- memcpy((uint8_t *)vd + H1(i), \
51
- (uint8_t *)vs2 + H1(i), \
52
- maxsz - env->vstart); \
53
- \
54
- env->vstart = 0; \
55
-}
56
+void HELPER(vmvr_v)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc)
57
+{
58
+ /* EEW = 8 */
59
+ uint32_t maxsz = simd_maxsz(desc);
60
+ uint32_t i = env->vstart;
61
+
62
+ memcpy((uint8_t *)vd + H1(i),
63
+ (uint8_t *)vs2 + H1(i),
64
+ maxsz - env->vstart);
65
66
-GEN_VEXT_VMV_WHOLE(vmv1r_v, 1)
67
-GEN_VEXT_VMV_WHOLE(vmv2r_v, 2)
68
-GEN_VEXT_VMV_WHOLE(vmv4r_v, 4)
69
-GEN_VEXT_VMV_WHOLE(vmv8r_v, 8)
70
+ env->vstart = 0;
71
+}
72
73
/* Vector Integer Extension */
74
#define GEN_VEXT_INT_EXT(NAME, ETYPE, DTYPE, HD, HS1) \
75
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/riscv/insn_trans/trans_rvv.c.inc
78
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
79
@@ -XXX,XX +XXX,XX @@ static bool trans_vcompress_vm(DisasContext *s, arg_r *a)
80
* Whole Vector Register Move Instructions ignore vtype and vl setting.
81
* Thus, we don't need to check vill bit. (Section 16.6)
82
*/
83
-#define GEN_VMV_WHOLE_TRANS(NAME, LEN, SEQ) \
84
+#define GEN_VMV_WHOLE_TRANS(NAME, LEN) \
85
static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \
86
{ \
87
if (require_rvv(s) && \
88
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \
89
} else { \
90
TCGLabel *over = gen_new_label(); \
91
tcg_gen_brcondi_tl(TCG_COND_GEU, cpu_vstart, maxsz, over); \
92
- \
93
- static gen_helper_gvec_2_ptr * const fns[4] = { \
94
- gen_helper_vmv1r_v, gen_helper_vmv2r_v, \
95
- gen_helper_vmv4r_v, gen_helper_vmv8r_v, \
96
- }; \
97
tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2), \
98
- cpu_env, maxsz, maxsz, 0, fns[SEQ]); \
99
+ cpu_env, maxsz, maxsz, 0, gen_helper_vmvr_v); \
100
mark_vs_dirty(s); \
101
gen_set_label(over); \
102
} \
103
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \
104
return false; \
105
}
106
107
-GEN_VMV_WHOLE_TRANS(vmv1r_v, 1, 0)
108
-GEN_VMV_WHOLE_TRANS(vmv2r_v, 2, 1)
109
-GEN_VMV_WHOLE_TRANS(vmv4r_v, 4, 2)
110
-GEN_VMV_WHOLE_TRANS(vmv8r_v, 8, 3)
111
+GEN_VMV_WHOLE_TRANS(vmv1r_v, 1)
112
+GEN_VMV_WHOLE_TRANS(vmv2r_v, 2)
113
+GEN_VMV_WHOLE_TRANS(vmv4r_v, 4)
114
+GEN_VMV_WHOLE_TRANS(vmv8r_v, 8)
115
116
static bool int_ext_check(DisasContext *s, arg_rmr *a, uint8_t div)
117
{
118
--
119
2.35.1
diff view generated by jsdifflib
New patch
1
From: Tsukasa OI <research_trasio@irq.a4lg.com>
1
2
3
Some bits in RISC-V `misa' CSR should not be reflected in the ISA
4
string. For instance, `S' and `U' (represents existence of supervisor
5
and user mode, respectively) in `misa' CSR must not be copied since
6
neither `S' nor `U' are valid single-letter extensions.
7
8
This commit also removes all reserved/dropped single-letter "extensions"
9
from the list.
10
11
- "B": Not going to be a single-letter extension (misa.B is reserved).
12
- "J": Not going to be a single-letter extension (misa.J is reserved).
13
- "K": Not going to be a single-letter extension (misa.K is reserved).
14
- "L": Dropped.
15
- "N": Dropped.
16
- "T": Dropped.
17
18
It also clarifies that the variable `riscv_single_letter_exts' is a
19
single-letter extension order list.
20
21
Signed-off-by: Tsukasa OI <research_trasio@irq.a4lg.com>
22
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
23
Message-Id: <4a4c11213a161a7eedabe46abe58b351bb0e2ef2.1648473008.git.research_trasio@irq.a4lg.com>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
---
26
target/riscv/cpu.c | 10 +++++-----
27
1 file changed, 5 insertions(+), 5 deletions(-)
28
29
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/cpu.c
32
+++ b/target/riscv/cpu.c
33
@@ -XXX,XX +XXX,XX @@
34
35
/* RISC-V CPU definitions */
36
37
-static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
38
+static const char riscv_single_letter_exts[] = "IEMAFDQCPVH";
39
40
const char * const riscv_int_regnames[] = {
41
"x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1",
42
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
43
char *riscv_isa_string(RISCVCPU *cpu)
44
{
45
int i;
46
- const size_t maxlen = sizeof("rv128") + sizeof(riscv_exts) + 1;
47
+ const size_t maxlen = sizeof("rv128") + sizeof(riscv_single_letter_exts);
48
char *isa_str = g_new(char, maxlen);
49
char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", TARGET_LONG_BITS);
50
- for (i = 0; i < sizeof(riscv_exts); i++) {
51
- if (cpu->env.misa_ext & RV(riscv_exts[i])) {
52
- *p++ = qemu_tolower(riscv_exts[i]);
53
+ for (i = 0; i < sizeof(riscv_single_letter_exts) - 1; i++) {
54
+ if (cpu->env.misa_ext & RV(riscv_single_letter_exts[i])) {
55
+ *p++ = qemu_tolower(riscv_single_letter_exts[i]);
56
}
57
}
58
*p = '\0';
59
--
60
2.35.1
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Atish Patra <atishp@rivosinc.com>
2
2
3
Once a "One Time Programmable" is programmed, it shouldn't be reset.
3
The Linux kernel parses the ISA extensions from "riscv,isa" DT
4
property. It used to parse only the single letter base extensions
5
until now. A generic ISA extension parsing framework was proposed[1]
6
recently that can parse multi-letter ISA extensions as well.
4
7
5
Do not re-initialize the OTP content in the DeviceReset handler,
8
Generate the extended ISA string by appending the available ISA extensions
6
initialize it once in the DeviceRealize one.
9
to the "riscv,isa" string if it is enabled so that kernel can process it.
7
10
8
Fixes: 9fb45c62ae8 ("riscv: sifive: Implement a model for SiFive FU540 OTP")
11
[1] https://lkml.org/lkml/2022/2/15/263
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
13
Reviewed-by: Anup Patel <anup@brainfault.org>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-Id: <20211119104757.331579-1-f4bug@amsat.org>
15
Reviewed-by: Frank Chang <frank.chang@sifive.com>
16
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
17
Tested-by: Bin Meng <bmeng.cn@gmail.com>
18
Signed-off-by: Atish Patra <atishp@rivosinc.com>
19
Suggested-by: Heiko Stubner <heiko@sntech.de>
20
Signed-off-by: Atish Patra <atishp@rivosinc.com>
21
Message-Id: <20220329195657.1725425-1-atishp@rivosinc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
23
---
14
hw/misc/sifive_u_otp.c | 13 +++++--------
24
target/riscv/cpu.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++
15
1 file changed, 5 insertions(+), 8 deletions(-)
25
1 file changed, 60 insertions(+)
16
26
17
diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c
27
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
18
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/misc/sifive_u_otp.c
29
--- a/target/riscv/cpu.c
20
+++ b/hw/misc/sifive_u_otp.c
30
+++ b/target/riscv/cpu.c
21
@@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_realize(DeviceState *dev, Error **errp)
31
@@ -XXX,XX +XXX,XX @@
22
32
23
if (blk_pread(s->blk, 0, s->fuse, filesize) != filesize) {
33
static const char riscv_single_letter_exts[] = "IEMAFDQCPVH";
24
error_setg(errp, "failed to read the initial flash content");
34
25
+ return;
35
+struct isa_ext_data {
26
}
36
+ const char *name;
37
+ bool enabled;
38
+};
39
+
40
const char * const riscv_int_regnames[] = {
41
"x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1",
42
"x7/t2", "x8/s0", "x9/s1", "x10/a0", "x11/a1", "x12/a2", "x13/a3",
43
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
44
device_class_set_props(dc, riscv_cpu_properties);
45
}
46
47
+#define ISA_EDATA_ENTRY(name, prop) {#name, cpu->cfg.prop}
48
+
49
+static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str, int max_str_len)
50
+{
51
+ char *old = *isa_str;
52
+ char *new = *isa_str;
53
+ int i;
54
+
55
+ /**
56
+ * Here are the ordering rules of extension naming defined by RISC-V
57
+ * specification :
58
+ * 1. All extensions should be separated from other multi-letter extensions
59
+ * by an underscore.
60
+ * 2. The first letter following the 'Z' conventionally indicates the most
61
+ * closely related alphabetical extension category, IMAFDQLCBKJTPVH.
62
+ * If multiple 'Z' extensions are named, they should be ordered first
63
+ * by category, then alphabetically within a category.
64
+ * 3. Standard supervisor-level extensions (starts with 'S') should be
65
+ * listed after standard unprivileged extensions. If multiple
66
+ * supervisor-level extensions are listed, they should be ordered
67
+ * alphabetically.
68
+ * 4. Non-standard extensions (starts with 'X') must be listed after all
69
+ * standard extensions. They must be separated from other multi-letter
70
+ * extensions by an underscore.
71
+ */
72
+ struct isa_ext_data isa_edata_arr[] = {
73
+ ISA_EDATA_ENTRY(zfh, ext_zfh),
74
+ ISA_EDATA_ENTRY(zfhmin, ext_zfhmin),
75
+ ISA_EDATA_ENTRY(zfinx, ext_zfinx),
76
+ ISA_EDATA_ENTRY(zhinx, ext_zhinx),
77
+ ISA_EDATA_ENTRY(zhinxmin, ext_zhinxmin),
78
+ ISA_EDATA_ENTRY(zdinx, ext_zdinx),
79
+ ISA_EDATA_ENTRY(zba, ext_zba),
80
+ ISA_EDATA_ENTRY(zbb, ext_zbb),
81
+ ISA_EDATA_ENTRY(zbc, ext_zbc),
82
+ ISA_EDATA_ENTRY(zbs, ext_zbs),
83
+ ISA_EDATA_ENTRY(zve32f, ext_zve32f),
84
+ ISA_EDATA_ENTRY(zve64f, ext_zve64f),
85
+ ISA_EDATA_ENTRY(svinval, ext_svinval),
86
+ ISA_EDATA_ENTRY(svnapot, ext_svnapot),
87
+ ISA_EDATA_ENTRY(svpbmt, ext_svpbmt),
88
+ };
89
+
90
+ for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
91
+ if (isa_edata_arr[i].enabled) {
92
+ new = g_strconcat(old, "_", isa_edata_arr[i].name, NULL);
93
+ g_free(old);
94
+ old = new;
95
+ }
96
+ }
97
+
98
+ *isa_str = new;
99
+}
100
+
101
char *riscv_isa_string(RISCVCPU *cpu)
102
{
103
int i;
104
@@ -XXX,XX +XXX,XX @@ char *riscv_isa_string(RISCVCPU *cpu)
27
}
105
}
28
}
106
}
29
-}
107
*p = '\0';
30
-
108
+ riscv_isa_string_ext(cpu, &isa_str, maxlen);
31
-static void sifive_u_otp_reset(DeviceState *dev)
109
return isa_str;
32
-{
33
- SiFiveUOTPState *s = SIFIVE_U_OTP(dev);
34
35
/* Initialize all fuses' initial value to 0xFFs */
36
memset(s->fuse, 0xff, sizeof(s->fuse));
37
@@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_reset(DeviceState *dev)
38
serial_data = s->serial;
39
if (blk_pwrite(s->blk, index * SIFIVE_U_OTP_FUSE_WORD,
40
&serial_data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) {
41
- error_report("write error index<%d>", index);
42
+ error_setg(errp, "failed to write index<%d>", index);
43
+ return;
44
}
45
46
serial_data = ~(s->serial);
47
if (blk_pwrite(s->blk, (index + 1) * SIFIVE_U_OTP_FUSE_WORD,
48
&serial_data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) {
49
- error_report("write error index<%d>", index + 1);
50
+ error_setg(errp, "failed to write index<%d>", index + 1);
51
+ return;
52
}
53
}
54
55
@@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_class_init(ObjectClass *klass, void *data)
56
57
device_class_set_props(dc, sifive_u_otp_properties);
58
dc->realize = sifive_u_otp_realize;
59
- dc->reset = sifive_u_otp_reset;
60
}
110
}
61
111
62
static const TypeInfo sifive_u_otp_info = {
63
--
112
--
64
2.31.1
113
2.35.1
65
66
diff view generated by jsdifflib
New patch
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
2
3
The spec for vmv<nf>r.v says: 'the instructions operate as if EEW=SEW,
4
EMUL = NREG, effective length evl= EMUL * VLEN/SEW.'
5
6
So the start byte for vstart != 0 should take sew into account
7
8
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
9
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
10
Acked-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-Id: <20220330021316.18223-1-liweiwei@iscas.ac.cn>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
target/riscv/vector_helper.c | 8 +++++---
15
1 file changed, 5 insertions(+), 3 deletions(-)
16
17
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/vector_helper.c
20
+++ b/target/riscv/vector_helper.c
21
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_VCOMPRESS_VM(vcompress_vm_d, uint64_t, H8)
22
/* Vector Whole Register Move */
23
void HELPER(vmvr_v)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc)
24
{
25
- /* EEW = 8 */
26
+ /* EEW = SEW */
27
uint32_t maxsz = simd_maxsz(desc);
28
- uint32_t i = env->vstart;
29
+ uint32_t sewb = 1 << FIELD_EX64(env->vtype, VTYPE, VSEW);
30
+ uint32_t startb = env->vstart * sewb;
31
+ uint32_t i = startb;
32
33
memcpy((uint8_t *)vd + H1(i),
34
(uint8_t *)vs2 + H1(i),
35
- maxsz - env->vstart);
36
+ maxsz - startb);
37
38
env->vstart = 0;
39
}
40
--
41
2.35.1
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
The riscv_raise_exception function stores its argument into
4
exception_index and then exits to the main loop. When we
5
have already set exception_index, we can just exit directly.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-Id: <20220401125948.79292-2-richard.henderson@linaro.org>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/cpu_helper.c | 6 +++---
13
1 file changed, 3 insertions(+), 3 deletions(-)
14
15
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu_helper.c
18
+++ b/target/riscv/cpu_helper.c
19
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
20
env->badaddr = addr;
21
env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
22
riscv_cpu_two_stage_lookup(mmu_idx);
23
- riscv_raise_exception(&cpu->env, cs->exception_index, retaddr);
24
+ cpu_loop_exit_restore(cs, retaddr);
25
}
26
27
void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
28
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
29
env->badaddr = addr;
30
env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
31
riscv_cpu_two_stage_lookup(mmu_idx);
32
- riscv_raise_exception(env, cs->exception_index, retaddr);
33
+ cpu_loop_exit_restore(cs, retaddr);
34
}
35
36
bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
37
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
38
first_stage_error,
39
riscv_cpu_virt_enabled(env) ||
40
riscv_cpu_two_stage_lookup(mmu_idx));
41
- riscv_raise_exception(env, cs->exception_index, retaddr);
42
+ cpu_loop_exit_restore(cs, retaddr);
43
}
44
45
return true;
46
--
47
2.35.1
diff view generated by jsdifflib
New patch
1
From: Ralf Ramsauer <ralf.ramsauer@oth-regensburg.de>
1
2
3
The -bios option is silently ignored if used in combination with -enable-kvm.
4
The reason is that the machine starts in S-Mode, and the bios typically runs in
5
M-Mode.
6
7
Better exit in that case to not confuse the user.
8
9
Signed-off-by: Ralf Ramsauer <ralf.ramsauer@oth-regensburg.de>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
12
Reviewed-by: Anup Patel <anup@brainfault.org>
13
Message-Id: <20220401121842.2791796-1-ralf.ramsauer@oth-regensburg.de>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
hw/riscv/virt.c | 14 ++++++++++----
17
1 file changed, 10 insertions(+), 4 deletions(-)
18
19
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/riscv/virt.c
22
+++ b/hw/riscv/virt.c
23
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
24
25
/*
26
* Only direct boot kernel is currently supported for KVM VM,
27
- * so the "-bios" parameter is ignored and treated like "-bios none"
28
- * when KVM is enabled.
29
+ * so the "-bios" parameter is not supported when KVM is enabled.
30
*/
31
if (kvm_enabled()) {
32
- g_free(machine->firmware);
33
- machine->firmware = g_strdup("none");
34
+ if (machine->firmware) {
35
+ if (strcmp(machine->firmware, "none")) {
36
+ error_report("Machine mode firmware is not supported in "
37
+ "combination with KVM.");
38
+ exit(1);
39
+ }
40
+ } else {
41
+ machine->firmware = g_strdup("none");
42
+ }
43
}
44
45
if (riscv_is_32bit(&s->soc[0])) {
46
--
47
2.35.1
diff view generated by jsdifflib
New patch
1
From: Nicolas Pitre <nico@fluxnic.net>
1
2
3
There is an overflow with the current code where a pmpaddr value of
4
0x1fffffff is decoded as sa=0 and ea=0 whereas it should be sa=0 and
5
ea=0xffffffff.
6
7
Fix that by simplifying the computation. There is in fact no need for
8
ctz64() nor special case for -1 to achieve proper results.
9
10
Signed-off-by: Nicolas Pitre <nico@fluxnic.net>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Message-Id: <rq81o86n-17ps-92no-p65o-79o88476266@syhkavp.arg>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
target/riscv/pmp.c | 14 +++-----------
16
1 file changed, 3 insertions(+), 11 deletions(-)
17
18
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/pmp.c
21
+++ b/target/riscv/pmp.c
22
@@ -XXX,XX +XXX,XX @@ static void pmp_decode_napot(target_ulong a, target_ulong *sa, target_ulong *ea)
23
0111...1111 2^(XLEN+2)-byte NAPOT range
24
1111...1111 Reserved
25
*/
26
- if (a == -1) {
27
- *sa = 0u;
28
- *ea = -1;
29
- return;
30
- } else {
31
- target_ulong t1 = ctz64(~a);
32
- target_ulong base = (a & ~(((target_ulong)1 << t1) - 1)) << 2;
33
- target_ulong range = ((target_ulong)1 << (t1 + 3)) - 1;
34
- *sa = base;
35
- *ea = base + range;
36
- }
37
+ a = (a << 2) | 0x3;
38
+ *sa = a & (a + 1);
39
+ *ea = a | (a + 1);
40
}
41
42
void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index)
43
--
44
2.35.1
diff view generated by jsdifflib
New patch
1
From: Niklas Cassel <niklas.cassel@wdc.com>
1
2
3
The device tree property "mmu-type" is currently exported as either
4
"riscv,sv32" or "riscv,sv48".
5
6
However, the riscv cpu device tree binding [1] has a specific value
7
"riscv,none" for a HART without a MMU.
8
9
Set the device tree property "mmu-type" to "riscv,none" when the CPU mmu
10
option is disabled using rv32,mmu=off or rv64,mmu=off.
11
12
[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/riscv/cpus.yaml?h=v5.17
13
14
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
15
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
16
Reviewed-by: Frank Chang <frank.chang@sifive.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Message-Id: <20220414155510.1364147-1-niklas.cassel@wdc.com>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
---
21
hw/riscv/virt.c | 10 ++++++++--
22
1 file changed, 8 insertions(+), 2 deletions(-)
23
24
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/riscv/virt.c
27
+++ b/hw/riscv/virt.c
28
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket,
29
cpu_name = g_strdup_printf("/cpus/cpu@%d",
30
s->soc[socket].hartid_base + cpu);
31
qemu_fdt_add_subnode(mc->fdt, cpu_name);
32
- qemu_fdt_setprop_string(mc->fdt, cpu_name, "mmu-type",
33
- (is_32_bit) ? "riscv,sv32" : "riscv,sv48");
34
+ if (riscv_feature(&s->soc[socket].harts[cpu].env,
35
+ RISCV_FEATURE_MMU)) {
36
+ qemu_fdt_setprop_string(mc->fdt, cpu_name, "mmu-type",
37
+ (is_32_bit) ? "riscv,sv32" : "riscv,sv48");
38
+ } else {
39
+ qemu_fdt_setprop_string(mc->fdt, cpu_name, "mmu-type",
40
+ "riscv,none");
41
+ }
42
name = riscv_isa_string(&s->soc[socket].harts[cpu]);
43
qemu_fdt_setprop_string(mc->fdt, cpu_name, "riscv,isa", name);
44
g_free(name);
45
--
46
2.35.1
diff view generated by jsdifflib
New patch
1
From: Frank Chang <frank.chang@sifive.com>
1
2
3
If device's MemoryRegion doesn't have .impl.[min|max]_access_size
4
declaration, the default access_size_min would be 1 byte and
5
access_size_max would be 4 bytes (see: softmmu/memory.c).
6
This will cause a 64-bit memory access to ACLINT to be splitted into
7
two 32-bit memory accesses.
8
9
Signed-off-by: Frank Chang <frank.chang@sifive.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Jim Shu <jim.shu@sifive.com>
12
Message-Id: <20220420080901.14655-2-frank.chang@sifive.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
hw/intc/riscv_aclint.c | 4 ++++
16
1 file changed, 4 insertions(+)
17
18
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/intc/riscv_aclint.c
21
+++ b/hw/intc/riscv_aclint.c
22
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps riscv_aclint_mtimer_ops = {
23
.valid = {
24
.min_access_size = 4,
25
.max_access_size = 8
26
+ },
27
+ .impl = {
28
+ .min_access_size = 4,
29
+ .max_access_size = 8,
30
}
31
};
32
33
--
34
2.35.1
diff view generated by jsdifflib
New patch
1
From: Frank Chang <frank.chang@sifive.com>
1
2
3
RISC-V privilege spec defines that:
4
5
* In RV32, memory-mapped writes to mtimecmp modify only one 32-bit part
6
of the register.
7
* For RV64, naturally aligned 64-bit memory accesses to the mtime and
8
mtimecmp registers are additionally supported and are atomic.
9
10
It's possible to perform both 32/64-bit read/write accesses to both
11
mtimecmp and mtime registers.
12
13
Signed-off-by: Frank Chang <frank.chang@sifive.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Reviewed-by: Jim Shu <jim.shu@sifive.com>
16
Message-Id: <20220420080901.14655-3-frank.chang@sifive.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
19
hw/intc/riscv_aclint.c | 42 +++++++++++++++++++++++++++---------------
20
1 file changed, 27 insertions(+), 15 deletions(-)
21
22
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/intc/riscv_aclint.c
25
+++ b/hw/intc/riscv_aclint.c
26
@@ -XXX,XX +XXX,XX @@ static uint64_t riscv_aclint_mtimer_read(void *opaque, hwaddr addr,
27
qemu_log_mask(LOG_GUEST_ERROR,
28
"aclint-mtimer: invalid hartid: %zu", hartid);
29
} else if ((addr & 0x7) == 0) {
30
- /* timecmp_lo */
31
+ /* timecmp_lo for RV32/RV64 or timecmp for RV64 */
32
uint64_t timecmp = env->timecmp;
33
- return timecmp & 0xFFFFFFFF;
34
+ return (size == 4) ? (timecmp & 0xFFFFFFFF) : timecmp;
35
} else if ((addr & 0x7) == 4) {
36
/* timecmp_hi */
37
uint64_t timecmp = env->timecmp;
38
@@ -XXX,XX +XXX,XX @@ static uint64_t riscv_aclint_mtimer_read(void *opaque, hwaddr addr,
39
return 0;
40
}
41
} else if (addr == mtimer->time_base) {
42
- /* time_lo */
43
- return cpu_riscv_read_rtc(mtimer->timebase_freq) & 0xFFFFFFFF;
44
+ /* time_lo for RV32/RV64 or timecmp for RV64 */
45
+ uint64_t rtc = cpu_riscv_read_rtc(mtimer->timebase_freq);
46
+ return (size == 4) ? (rtc & 0xFFFFFFFF) : rtc;
47
} else if (addr == mtimer->time_base + 4) {
48
/* time_hi */
49
return (cpu_riscv_read_rtc(mtimer->timebase_freq) >> 32) & 0xFFFFFFFF;
50
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
51
qemu_log_mask(LOG_GUEST_ERROR,
52
"aclint-mtimer: invalid hartid: %zu", hartid);
53
} else if ((addr & 0x7) == 0) {
54
- /* timecmp_lo */
55
- uint64_t timecmp_hi = env->timecmp >> 32;
56
- riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
57
- timecmp_hi << 32 | (value & 0xFFFFFFFF),
58
- mtimer->timebase_freq);
59
- return;
60
+ if (size == 4) {
61
+ /* timecmp_lo for RV32/RV64 */
62
+ uint64_t timecmp_hi = env->timecmp >> 32;
63
+ riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
64
+ timecmp_hi << 32 | (value & 0xFFFFFFFF),
65
+ mtimer->timebase_freq);
66
+ } else {
67
+ /* timecmp for RV64 */
68
+ riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
69
+ value, mtimer->timebase_freq);
70
+ }
71
} else if ((addr & 0x7) == 4) {
72
- /* timecmp_hi */
73
- uint64_t timecmp_lo = env->timecmp;
74
- riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
75
- value << 32 | (timecmp_lo & 0xFFFFFFFF),
76
- mtimer->timebase_freq);
77
+ if (size == 4) {
78
+ /* timecmp_hi for RV32/RV64 */
79
+ uint64_t timecmp_lo = env->timecmp;
80
+ riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
81
+ value << 32 | (timecmp_lo & 0xFFFFFFFF),
82
+ mtimer->timebase_freq);
83
+ } else {
84
+ qemu_log_mask(LOG_GUEST_ERROR,
85
+ "aclint-mtimer: invalid timecmp_hi write: %08x",
86
+ (uint32_t)addr);
87
+ }
88
} else {
89
qemu_log_mask(LOG_UNIMP,
90
"aclint-mtimer: invalid timecmp write: %08x",
91
--
92
2.35.1
diff view generated by jsdifflib
New patch
1
1
From: Frank Chang <frank.chang@sifive.com>
2
3
RISC-V privilege spec defines that mtime is exposed as a memory-mapped
4
machine-mode read-write register. However, as QEMU uses host monotonic
5
timer as timer source, this makes mtime to be read-only in RISC-V
6
ACLINT.
7
8
This patch makes mtime to be writable by recording the time delta value
9
between the mtime value to be written and the timer value at the time
10
mtime is written. Time delta value is then added back whenever the timer
11
value is retrieved.
12
13
Signed-off-by: Frank Chang <frank.chang@sifive.com>
14
Reviewed-by: Jim Shu <jim.shu@sifive.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Message-Id: <20220420080901.14655-4-frank.chang@sifive.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
19
include/hw/intc/riscv_aclint.h | 1 +
20
target/riscv/cpu.h | 8 ++--
21
hw/intc/riscv_aclint.c | 71 ++++++++++++++++++++++++----------
22
target/riscv/cpu_helper.c | 4 +-
23
4 files changed, 57 insertions(+), 27 deletions(-)
24
25
diff --git a/include/hw/intc/riscv_aclint.h b/include/hw/intc/riscv_aclint.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/intc/riscv_aclint.h
28
+++ b/include/hw/intc/riscv_aclint.h
29
@@ -XXX,XX +XXX,XX @@
30
typedef struct RISCVAclintMTimerState {
31
/*< private >*/
32
SysBusDevice parent_obj;
33
+ uint64_t time_delta;
34
35
/*< public >*/
36
MemoryRegion mmio;
37
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/riscv/cpu.h
40
+++ b/target/riscv/cpu.h
41
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
42
type2_trigger_t type2_trig[TRIGGER_TYPE2_NUM];
43
44
/* machine specific rdtime callback */
45
- uint64_t (*rdtime_fn)(uint32_t);
46
- uint32_t rdtime_fn_arg;
47
+ uint64_t (*rdtime_fn)(void *);
48
+ void *rdtime_fn_arg;
49
50
/* machine specific AIA ireg read-modify-write callback */
51
#define AIA_MAKE_IREG(__isel, __priv, __virt, __vgein, __xlen) \
52
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env);
53
int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts);
54
uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value);
55
#define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */
56
-void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(uint32_t),
57
- uint32_t arg);
58
+void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(void *),
59
+ void *arg);
60
void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, uint32_t priv,
61
int (*rmw_fn)(void *arg,
62
target_ulong reg,
63
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/intc/riscv_aclint.c
66
+++ b/hw/intc/riscv_aclint.c
67
@@ -XXX,XX +XXX,XX @@ typedef struct riscv_aclint_mtimer_callback {
68
int num;
69
} riscv_aclint_mtimer_callback;
70
71
-static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq)
72
+static uint64_t cpu_riscv_read_rtc_raw(uint32_t timebase_freq)
73
{
74
return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
75
timebase_freq, NANOSECONDS_PER_SECOND);
76
}
77
78
+static uint64_t cpu_riscv_read_rtc(void *opaque)
79
+{
80
+ RISCVAclintMTimerState *mtimer = opaque;
81
+ return cpu_riscv_read_rtc_raw(mtimer->timebase_freq) + mtimer->time_delta;
82
+}
83
+
84
/*
85
* Called when timecmp is written to update the QEMU timer or immediately
86
* trigger timer interrupt if mtimecmp <= current timer value.
87
@@ -XXX,XX +XXX,XX @@ static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq)
88
static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
89
RISCVCPU *cpu,
90
int hartid,
91
- uint64_t value,
92
- uint32_t timebase_freq)
93
+ uint64_t value)
94
{
95
+ uint32_t timebase_freq = mtimer->timebase_freq;
96
uint64_t next;
97
uint64_t diff;
98
99
- uint64_t rtc_r = cpu_riscv_read_rtc(timebase_freq);
100
+ uint64_t rtc_r = cpu_riscv_read_rtc(mtimer);
101
102
cpu->env.timecmp = value;
103
if (cpu->env.timecmp <= rtc_r) {
104
@@ -XXX,XX +XXX,XX @@ static uint64_t riscv_aclint_mtimer_read(void *opaque, hwaddr addr,
105
}
106
} else if (addr == mtimer->time_base) {
107
/* time_lo for RV32/RV64 or timecmp for RV64 */
108
- uint64_t rtc = cpu_riscv_read_rtc(mtimer->timebase_freq);
109
+ uint64_t rtc = cpu_riscv_read_rtc(mtimer);
110
return (size == 4) ? (rtc & 0xFFFFFFFF) : rtc;
111
} else if (addr == mtimer->time_base + 4) {
112
/* time_hi */
113
- return (cpu_riscv_read_rtc(mtimer->timebase_freq) >> 32) & 0xFFFFFFFF;
114
+ return (cpu_riscv_read_rtc(mtimer) >> 32) & 0xFFFFFFFF;
115
}
116
117
qemu_log_mask(LOG_UNIMP,
118
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
119
uint64_t value, unsigned size)
120
{
121
RISCVAclintMTimerState *mtimer = opaque;
122
+ int i;
123
124
if (addr >= mtimer->timecmp_base &&
125
addr < (mtimer->timecmp_base + (mtimer->num_harts << 3))) {
126
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
127
/* timecmp_lo for RV32/RV64 */
128
uint64_t timecmp_hi = env->timecmp >> 32;
129
riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
130
- timecmp_hi << 32 | (value & 0xFFFFFFFF),
131
- mtimer->timebase_freq);
132
+ timecmp_hi << 32 | (value & 0xFFFFFFFF));
133
} else {
134
/* timecmp for RV64 */
135
riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
136
- value, mtimer->timebase_freq);
137
+ value);
138
}
139
} else if ((addr & 0x7) == 4) {
140
if (size == 4) {
141
/* timecmp_hi for RV32/RV64 */
142
uint64_t timecmp_lo = env->timecmp;
143
riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
144
- value << 32 | (timecmp_lo & 0xFFFFFFFF),
145
- mtimer->timebase_freq);
146
+ value << 32 | (timecmp_lo & 0xFFFFFFFF));
147
} else {
148
qemu_log_mask(LOG_GUEST_ERROR,
149
"aclint-mtimer: invalid timecmp_hi write: %08x",
150
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
151
(uint32_t)addr);
152
}
153
return;
154
- } else if (addr == mtimer->time_base) {
155
- /* time_lo */
156
- qemu_log_mask(LOG_UNIMP,
157
- "aclint-mtimer: time_lo write not implemented");
158
- return;
159
- } else if (addr == mtimer->time_base + 4) {
160
- /* time_hi */
161
- qemu_log_mask(LOG_UNIMP,
162
- "aclint-mtimer: time_hi write not implemented");
163
+ } else if (addr == mtimer->time_base || addr == mtimer->time_base + 4) {
164
+ uint64_t rtc_r = cpu_riscv_read_rtc_raw(mtimer->timebase_freq);
165
+
166
+ if (addr == mtimer->time_base) {
167
+ if (size == 4) {
168
+ /* time_lo for RV32/RV64 */
169
+ mtimer->time_delta = ((rtc_r & ~0xFFFFFFFFULL) | value) - rtc_r;
170
+ } else {
171
+ /* time for RV64 */
172
+ mtimer->time_delta = value - rtc_r;
173
+ }
174
+ } else {
175
+ if (size == 4) {
176
+ /* time_hi for RV32/RV64 */
177
+ mtimer->time_delta = (value << 32 | (rtc_r & 0xFFFFFFFF)) - rtc_r;
178
+ } else {
179
+ qemu_log_mask(LOG_GUEST_ERROR,
180
+ "aclint-mtimer: invalid time_hi write: %08x",
181
+ (uint32_t)addr);
182
+ return;
183
+ }
184
+ }
185
+
186
+ /* Check if timer interrupt is triggered for each hart. */
187
+ for (i = 0; i < mtimer->num_harts; i++) {
188
+ CPUState *cpu = qemu_get_cpu(mtimer->hartid_base + i);
189
+ CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
190
+ if (!env) {
191
+ continue;
192
+ }
193
+ riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu),
194
+ i, env->timecmp);
195
+ }
196
return;
197
}
198
199
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size,
200
continue;
201
}
202
if (provide_rdtime) {
203
- riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc, timebase_freq);
204
+ riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc, dev);
205
}
206
207
cb->s = RISCV_ACLINT_MTIMER(dev);
208
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
209
index XXXXXXX..XXXXXXX 100644
210
--- a/target/riscv/cpu_helper.c
211
+++ b/target/riscv/cpu_helper.c
212
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value)
213
return old;
214
}
215
216
-void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(uint32_t),
217
- uint32_t arg)
218
+void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(void *),
219
+ void *arg)
220
{
221
env->rdtime_fn = fn;
222
env->rdtime_fn_arg = arg;
223
--
224
2.35.1
diff view generated by jsdifflib
New patch
1
From: Jim Shu <jim.shu@sifive.com>
1
2
3
This commit implements reset function of all ACLINT devices.
4
ACLINT device reset will clear MTIME and MSIP register to 0.
5
6
Depend on RISC-V ACLINT spec v1.0-rc4:
7
https://github.com/riscv/riscv-aclint/blob/v1.0-rc4/riscv-aclint.adoc
8
9
Signed-off-by: Jim Shu <jim.shu@sifive.com>
10
Reviewed-by: Frank Chang <frank.chang@sifive.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Message-Id: <20220420080901.14655-5-frank.chang@sifive.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
hw/intc/riscv_aclint.c | 39 +++++++++++++++++++++++++++++++++++++++
16
1 file changed, 39 insertions(+)
17
18
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/intc/riscv_aclint.c
21
+++ b/hw/intc/riscv_aclint.c
22
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_realize(DeviceState *dev, Error **errp)
23
}
24
}
25
26
+static void riscv_aclint_mtimer_reset_enter(Object *obj, ResetType type)
27
+{
28
+ /*
29
+ * According to RISC-V ACLINT spec:
30
+ * - On MTIMER device reset, the MTIME register is cleared to zero.
31
+ * - On MTIMER device reset, the MTIMECMP registers are in unknown state.
32
+ */
33
+ RISCVAclintMTimerState *mtimer = RISCV_ACLINT_MTIMER(obj);
34
+
35
+ /*
36
+ * Clear mtime register by writing to 0 it.
37
+ * Pending mtime interrupts will also be cleared at the same time.
38
+ */
39
+ riscv_aclint_mtimer_write(mtimer, mtimer->time_base, 0, 8);
40
+}
41
+
42
static void riscv_aclint_mtimer_class_init(ObjectClass *klass, void *data)
43
{
44
DeviceClass *dc = DEVICE_CLASS(klass);
45
dc->realize = riscv_aclint_mtimer_realize;
46
device_class_set_props(dc, riscv_aclint_mtimer_properties);
47
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
48
+ rc->phases.enter = riscv_aclint_mtimer_reset_enter;
49
}
50
51
static const TypeInfo riscv_aclint_mtimer_info = {
52
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_swi_realize(DeviceState *dev, Error **errp)
53
}
54
}
55
56
+static void riscv_aclint_swi_reset_enter(Object *obj, ResetType type)
57
+{
58
+ /*
59
+ * According to RISC-V ACLINT spec:
60
+ * - On MSWI device reset, each MSIP register is cleared to zero.
61
+ *
62
+ * p.s. SSWI device reset does nothing since SETSIP register always reads 0.
63
+ */
64
+ RISCVAclintSwiState *swi = RISCV_ACLINT_SWI(obj);
65
+ int i;
66
+
67
+ if (!swi->sswi) {
68
+ for (i = 0; i < swi->num_harts; i++) {
69
+ /* Clear MSIP registers by lowering software interrupts. */
70
+ qemu_irq_lower(swi->soft_irqs[i]);
71
+ }
72
+ }
73
+}
74
+
75
static void riscv_aclint_swi_class_init(ObjectClass *klass, void *data)
76
{
77
DeviceClass *dc = DEVICE_CLASS(klass);
78
dc->realize = riscv_aclint_swi_realize;
79
device_class_set_props(dc, riscv_aclint_swi_properties);
80
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
81
+ rc->phases.enter = riscv_aclint_swi_reset_enter;
82
}
83
84
static const TypeInfo riscv_aclint_swi_info = {
85
--
86
2.35.1
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
Configuring a drive with "if=none" is meant for creation of a backend
3
Implement .debug_excp_handler, .debug_check_{breakpoint, watchpoint}
4
only, it should not get automatically assigned to a device frontend.
4
TCGCPUOps and hook them into riscv_tcg_ops.
5
Use "if=pflash" for the One-Time-Programmable device instead (like
6
it is e.g. also done for the efuse device in hw/arm/xlnx-zcu102.c).
7
5
8
Since the old way of configuring the device has already been published
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
9
with the previous QEMU versions, we cannot remove this immediately, but
10
have to deprecate it and support it for at least two more releases.
11
12
Signed-off-by: Thomas Huth <thuth@redhat.com>
13
Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
Reviewed-by: Markus Armbruster <armbru@redhat.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Message-id: 20211119102549.217755-1-thuth@redhat.com
8
Message-Id: <20220421003324.1134983-2-bmeng.cn@gmail.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
10
---
19
docs/about/deprecated.rst | 6 ++++++
11
target/riscv/debug.h | 4 +++
20
hw/misc/sifive_u_otp.c | 9 ++++++++-
12
target/riscv/cpu.c | 3 ++
21
2 files changed, 14 insertions(+), 1 deletion(-)
13
target/riscv/debug.c | 75 ++++++++++++++++++++++++++++++++++++++++++++
14
3 files changed, 82 insertions(+)
22
15
23
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
16
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
24
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
25
--- a/docs/about/deprecated.rst
18
--- a/target/riscv/debug.h
26
+++ b/docs/about/deprecated.rst
19
+++ b/target/riscv/debug.h
27
@@ -XXX,XX +XXX,XX @@ as short-form boolean values, and passed to plugins as ``arg_name=on``.
20
@@ -XXX,XX +XXX,XX @@ void tselect_csr_write(CPURISCVState *env, target_ulong val);
28
However, short-form booleans are deprecated and full explicit ``arg_name=on``
21
target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index);
29
form is preferred.
22
void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val);
30
23
31
+``-drive if=none`` for the sifive_u OTP device (since 6.2)
24
+void riscv_cpu_debug_excp_handler(CPUState *cs);
32
+''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
25
+bool riscv_cpu_debug_check_breakpoint(CPUState *cs);
26
+bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
33
+
27
+
34
+Using ``-drive if=none`` to configure the OTP device of the sifive_u
28
#endif /* RISCV_DEBUG_H */
35
+RISC-V machine is deprecated. Use ``-drive if=pflash`` instead.
29
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/cpu.c
32
+++ b/target/riscv/cpu.c
33
@@ -XXX,XX +XXX,XX @@ static const struct TCGCPUOps riscv_tcg_ops = {
34
.do_interrupt = riscv_cpu_do_interrupt,
35
.do_transaction_failed = riscv_cpu_do_transaction_failed,
36
.do_unaligned_access = riscv_cpu_do_unaligned_access,
37
+ .debug_excp_handler = riscv_cpu_debug_excp_handler,
38
+ .debug_check_breakpoint = riscv_cpu_debug_check_breakpoint,
39
+ .debug_check_watchpoint = riscv_cpu_debug_check_watchpoint,
40
#endif /* !CONFIG_USER_ONLY */
41
};
42
43
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/riscv/debug.c
46
+++ b/target/riscv/debug.c
47
@@ -XXX,XX +XXX,XX @@ void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val)
48
49
return write_func(env, env->trigger_cur, tdata_index, val);
50
}
36
+
51
+
37
52
+void riscv_cpu_debug_excp_handler(CPUState *cs)
38
QEMU Machine Protocol (QMP) commands
53
+{
39
------------------------------------
54
+ RISCVCPU *cpu = RISCV_CPU(cs);
40
diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c
55
+ CPURISCVState *env = &cpu->env;
41
index XXXXXXX..XXXXXXX 100644
56
+
42
--- a/hw/misc/sifive_u_otp.c
57
+ if (cs->watchpoint_hit) {
43
+++ b/hw/misc/sifive_u_otp.c
58
+ if (cs->watchpoint_hit->flags & BP_CPU) {
44
@@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_realize(DeviceState *dev, Error **errp)
59
+ cs->watchpoint_hit = NULL;
45
TYPE_SIFIVE_U_OTP, SIFIVE_U_OTP_REG_SIZE);
60
+ riscv_raise_exception(env, RISCV_EXCP_BREAKPOINT, 0);
46
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
61
+ }
47
62
+ } else {
48
- dinfo = drive_get_next(IF_NONE);
63
+ if (cpu_breakpoint_test(cs, env->pc, BP_CPU)) {
49
+ dinfo = drive_get_next(IF_PFLASH);
64
+ riscv_raise_exception(env, RISCV_EXCP_BREAKPOINT, 0);
50
+ if (!dinfo) {
51
+ dinfo = drive_get_next(IF_NONE);
52
+ if (dinfo) {
53
+ warn_report("using \"-drive if=none\" for the OTP is deprecated, "
54
+ "use \"-drive if=pflash\" instead.");
55
+ }
65
+ }
56
+ }
66
+ }
57
if (dinfo) {
67
+}
58
int ret;
68
+
59
uint64_t perm;
69
+bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
70
+{
71
+ RISCVCPU *cpu = RISCV_CPU(cs);
72
+ CPURISCVState *env = &cpu->env;
73
+ CPUBreakpoint *bp;
74
+ target_ulong ctrl;
75
+ target_ulong pc;
76
+ int i;
77
+
78
+ QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
79
+ for (i = 0; i < TRIGGER_TYPE2_NUM; i++) {
80
+ ctrl = env->type2_trig[i].mcontrol;
81
+ pc = env->type2_trig[i].maddress;
82
+
83
+ if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) {
84
+ /* check U/S/M bit against current privilege level */
85
+ if ((ctrl >> 3) & BIT(env->priv)) {
86
+ return true;
87
+ }
88
+ }
89
+ }
90
+ }
91
+
92
+ return false;
93
+}
94
+
95
+bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
96
+{
97
+ RISCVCPU *cpu = RISCV_CPU(cs);
98
+ CPURISCVState *env = &cpu->env;
99
+ target_ulong ctrl;
100
+ target_ulong addr;
101
+ int flags;
102
+ int i;
103
+
104
+ for (i = 0; i < TRIGGER_TYPE2_NUM; i++) {
105
+ ctrl = env->type2_trig[i].mcontrol;
106
+ addr = env->type2_trig[i].maddress;
107
+ flags = 0;
108
+
109
+ if (ctrl & TYPE2_LOAD) {
110
+ flags |= BP_MEM_READ;
111
+ }
112
+ if (ctrl & TYPE2_STORE) {
113
+ flags |= BP_MEM_WRITE;
114
+ }
115
+
116
+ if ((wp->flags & flags) && (wp->vaddr == addr)) {
117
+ /* check U/S/M bit against current privilege level */
118
+ if ((ctrl >> 3) & BIT(env->priv)) {
119
+ return true;
120
+ }
121
+ }
122
+ }
123
+
124
+ return false;
125
+}
60
--
126
--
61
2.31.1
127
2.35.1
62
63
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
Add a config option to enable support for native M-mode debug.
4
This is disabled by default and can be enabled with 'debug=true'.
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <20220421003324.1134983-3-bmeng.cn@gmail.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
target/riscv/cpu.h | 4 +++-
12
target/riscv/cpu.c | 5 +++++
13
2 files changed, 8 insertions(+), 1 deletion(-)
14
15
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu.h
18
+++ b/target/riscv/cpu.h
19
@@ -XXX,XX +XXX,XX @@ enum {
20
RISCV_FEATURE_PMP,
21
RISCV_FEATURE_EPMP,
22
RISCV_FEATURE_MISA,
23
- RISCV_FEATURE_AIA
24
+ RISCV_FEATURE_AIA,
25
+ RISCV_FEATURE_DEBUG
26
};
27
28
/* Privileged specification version */
29
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
30
bool pmp;
31
bool epmp;
32
bool aia;
33
+ bool debug;
34
uint64_t resetvec;
35
};
36
37
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/riscv/cpu.c
40
+++ b/target/riscv/cpu.c
41
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
42
riscv_set_feature(env, RISCV_FEATURE_AIA);
43
}
44
45
+ if (cpu->cfg.debug) {
46
+ riscv_set_feature(env, RISCV_FEATURE_DEBUG);
47
+ }
48
+
49
set_resetvec(env, cpu->cfg.resetvec);
50
51
/* Validate that MISA_MXL is set properly. */
52
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = {
53
DEFINE_PROP_BOOL("Zve64f", RISCVCPU, cfg.ext_zve64f, false),
54
DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
55
DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
56
+ DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, false),
57
58
DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
59
DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
60
--
61
2.35.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
This adds debug CSR read/write support to the RISC-V CSR RW table.
4
5
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-Id: <20220421003324.1134983-4-bmeng.cn@gmail.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
10
target/riscv/debug.h | 2 ++
11
target/riscv/cpu.c | 4 ++++
12
target/riscv/csr.c | 57 ++++++++++++++++++++++++++++++++++++++++++++
13
target/riscv/debug.c | 27 +++++++++++++++++++++
14
4 files changed, 90 insertions(+)
15
16
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/debug.h
19
+++ b/target/riscv/debug.h
20
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_debug_excp_handler(CPUState *cs);
21
bool riscv_cpu_debug_check_breakpoint(CPUState *cs);
22
bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
23
24
+void riscv_trigger_init(CPURISCVState *env);
25
+
26
#endif /* RISCV_DEBUG_H */
27
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/riscv/cpu.c
30
+++ b/target/riscv/cpu.c
31
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset(DeviceState *dev)
32
set_default_nan_mode(1, &env->fp_status);
33
34
#ifndef CONFIG_USER_ONLY
35
+ if (riscv_feature(env, RISCV_FEATURE_DEBUG)) {
36
+ riscv_trigger_init(env);
37
+ }
38
+
39
if (kvm_enabled()) {
40
kvm_riscv_reset_vcpu(cpu);
41
}
42
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/riscv/csr.c
45
+++ b/target/riscv/csr.c
46
@@ -XXX,XX +XXX,XX @@ static RISCVException epmp(CPURISCVState *env, int csrno)
47
48
return RISCV_EXCP_ILLEGAL_INST;
49
}
50
+
51
+static RISCVException debug(CPURISCVState *env, int csrno)
52
+{
53
+ if (riscv_feature(env, RISCV_FEATURE_DEBUG)) {
54
+ return RISCV_EXCP_NONE;
55
+ }
56
+
57
+ return RISCV_EXCP_ILLEGAL_INST;
58
+}
59
#endif
60
61
/* User Floating-Point CSRs */
62
@@ -XXX,XX +XXX,XX @@ static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
63
return RISCV_EXCP_NONE;
64
}
65
66
+static RISCVException read_tselect(CPURISCVState *env, int csrno,
67
+ target_ulong *val)
68
+{
69
+ *val = tselect_csr_read(env);
70
+ return RISCV_EXCP_NONE;
71
+}
72
+
73
+static RISCVException write_tselect(CPURISCVState *env, int csrno,
74
+ target_ulong val)
75
+{
76
+ tselect_csr_write(env, val);
77
+ return RISCV_EXCP_NONE;
78
+}
79
+
80
+static RISCVException read_tdata(CPURISCVState *env, int csrno,
81
+ target_ulong *val)
82
+{
83
+ /* return 0 in tdata1 to end the trigger enumeration */
84
+ if (env->trigger_cur >= TRIGGER_NUM && csrno == CSR_TDATA1) {
85
+ *val = 0;
86
+ return RISCV_EXCP_NONE;
87
+ }
88
+
89
+ if (!tdata_available(env, csrno - CSR_TDATA1)) {
90
+ return RISCV_EXCP_ILLEGAL_INST;
91
+ }
92
+
93
+ *val = tdata_csr_read(env, csrno - CSR_TDATA1);
94
+ return RISCV_EXCP_NONE;
95
+}
96
+
97
+static RISCVException write_tdata(CPURISCVState *env, int csrno,
98
+ target_ulong val)
99
+{
100
+ if (!tdata_available(env, csrno - CSR_TDATA1)) {
101
+ return RISCV_EXCP_ILLEGAL_INST;
102
+ }
103
+
104
+ tdata_csr_write(env, csrno - CSR_TDATA1, val);
105
+ return RISCV_EXCP_NONE;
106
+}
107
+
108
/*
109
* Functions to access Pointer Masking feature registers
110
* We have to check if current priv lvl could modify
111
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
112
[CSR_PMPADDR14] = { "pmpaddr14", pmp, read_pmpaddr, write_pmpaddr },
113
[CSR_PMPADDR15] = { "pmpaddr15", pmp, read_pmpaddr, write_pmpaddr },
114
115
+ /* Debug CSRs */
116
+ [CSR_TSELECT] = { "tselect", debug, read_tselect, write_tselect },
117
+ [CSR_TDATA1] = { "tdata1", debug, read_tdata, write_tdata },
118
+ [CSR_TDATA2] = { "tdata2", debug, read_tdata, write_tdata },
119
+ [CSR_TDATA3] = { "tdata3", debug, read_tdata, write_tdata },
120
+
121
/* User Pointer Masking */
122
[CSR_UMTE] = { "umte", pointer_masking, read_umte, write_umte },
123
[CSR_UPMMASK] = { "upmmask", pointer_masking, read_upmmask, write_upmmask },
124
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
125
index XXXXXXX..XXXXXXX 100644
126
--- a/target/riscv/debug.c
127
+++ b/target/riscv/debug.c
128
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
129
130
return false;
131
}
132
+
133
+void riscv_trigger_init(CPURISCVState *env)
134
+{
135
+ target_ulong type2 = trigger_type(env, TRIGGER_TYPE_AD_MATCH);
136
+ int i;
137
+
138
+ /* type 2 triggers */
139
+ for (i = 0; i < TRIGGER_TYPE2_NUM; i++) {
140
+ /*
141
+ * type = TRIGGER_TYPE_AD_MATCH
142
+ * dmode = 0 (both debug and M-mode can write tdata)
143
+ * maskmax = 0 (unimplemented, always 0)
144
+ * sizehi = 0 (match against any size, RV64 only)
145
+ * hit = 0 (unimplemented, always 0)
146
+ * select = 0 (always 0, perform match on address)
147
+ * timing = 0 (always 0, trigger before instruction)
148
+ * sizelo = 0 (match against any size)
149
+ * action = 0 (always 0, raise a breakpoint exception)
150
+ * chain = 0 (unimplemented, always 0)
151
+ * match = 0 (always 0, when any compare value equals tdata2)
152
+ */
153
+ env->type2_trig[i].mcontrol = type2;
154
+ env->type2_trig[i].maddress = 0;
155
+ env->type2_trig[i].bp = NULL;
156
+ env->type2_trig[i].wp = NULL;
157
+ }
158
+}
159
--
160
2.35.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
Add a subsection to machine.c to migrate debug CSR state.
4
5
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-Id: <20220421003324.1134983-5-bmeng.cn@gmail.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
10
target/riscv/machine.c | 32 ++++++++++++++++++++++++++++++++
11
1 file changed, 32 insertions(+)
12
13
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/machine.c
16
+++ b/target/riscv/machine.c
17
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_kvmtimer = {
18
VMSTATE_UINT64(env.kvm_timer_time, RISCVCPU),
19
VMSTATE_UINT64(env.kvm_timer_compare, RISCVCPU),
20
VMSTATE_UINT64(env.kvm_timer_state, RISCVCPU),
21
+ VMSTATE_END_OF_LIST()
22
+ }
23
+};
24
+
25
+static bool debug_needed(void *opaque)
26
+{
27
+ RISCVCPU *cpu = opaque;
28
+ CPURISCVState *env = &cpu->env;
29
+
30
+ return riscv_feature(env, RISCV_FEATURE_DEBUG);
31
+}
32
33
+static const VMStateDescription vmstate_debug_type2 = {
34
+ .name = "cpu/debug/type2",
35
+ .version_id = 1,
36
+ .minimum_version_id = 1,
37
+ .fields = (VMStateField[]) {
38
+ VMSTATE_UINTTL(mcontrol, type2_trigger_t),
39
+ VMSTATE_UINTTL(maddress, type2_trigger_t),
40
+ VMSTATE_END_OF_LIST()
41
+ }
42
+};
43
+
44
+static const VMStateDescription vmstate_debug = {
45
+ .name = "cpu/debug",
46
+ .version_id = 1,
47
+ .minimum_version_id = 1,
48
+ .needed = debug_needed,
49
+ .fields = (VMStateField[]) {
50
+ VMSTATE_UINTTL(env.trigger_cur, RISCVCPU),
51
+ VMSTATE_STRUCT_ARRAY(env.type2_trig, RISCVCPU, TRIGGER_TYPE2_NUM,
52
+ 0, vmstate_debug_type2, type2_trigger_t),
53
VMSTATE_END_OF_LIST()
54
}
55
};
56
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = {
57
&vmstate_rv128,
58
&vmstate_kvmtimer,
59
&vmstate_envcfg,
60
+ &vmstate_debug,
61
NULL
62
}
63
};
64
--
65
2.35.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
Turn on native debug feature by default for all CPUs.
4
5
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-Id: <20220421003324.1134983-6-bmeng.cn@gmail.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
10
target/riscv/cpu.c | 2 +-
11
1 file changed, 1 insertion(+), 1 deletion(-)
12
13
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/cpu.c
16
+++ b/target/riscv/cpu.c
17
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = {
18
DEFINE_PROP_BOOL("Zve64f", RISCVCPU, cfg.ext_zve64f, false),
19
DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
20
DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
21
- DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, false),
22
+ DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
23
24
DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
25
DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
26
--
27
2.35.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
This is now used by RISC-V as well. Update the comments.
4
5
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <20220421003324.1134983-7-bmeng.cn@gmail.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
include/hw/core/tcg-cpu-ops.h | 1 +
12
1 file changed, 1 insertion(+)
13
14
diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/core/tcg-cpu-ops.h
17
+++ b/include/hw/core/tcg-cpu-ops.h
18
@@ -XXX,XX +XXX,XX @@ struct TCGCPUOps {
19
/**
20
* @debug_check_watchpoint: return true if the architectural
21
* watchpoint whose address has matched should really fire, used by ARM
22
+ * and RISC-V
23
*/
24
bool (*debug_check_watchpoint)(CPUState *cpu, CPUWatchpoint *wp);
25
26
--
27
2.35.1
diff view generated by jsdifflib
New patch
1
From: Dylan Jhong <dylan@andestech.com>
1
2
3
The current riscv_load_fdt() forces fdt_load_addr to be placed at a dram address within 3GB,
4
but not all platforms have dram_base within 3GB.
5
6
This patch adds an exception for dram base not within 3GB,
7
which will place fdt at dram_end align 16MB.
8
9
riscv_setup_rom_reset_vec() also needs to be modified
10
11
Signed-off-by: Dylan Jhong <dylan@andestech.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-Id: <20220419115945.37945-1-dylan@andestech.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
include/hw/riscv/boot.h | 4 ++--
17
hw/riscv/boot.c | 12 +++++++-----
18
2 files changed, 9 insertions(+), 7 deletions(-)
19
20
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/riscv/boot.h
23
+++ b/include/hw/riscv/boot.h
24
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_kernel(const char *kernel_filename,
25
symbol_fn_t sym_cb);
26
hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
27
uint64_t kernel_entry, hwaddr *start);
28
-uint32_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt);
29
+uint64_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt);
30
void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts,
31
hwaddr saddr,
32
hwaddr rom_base, hwaddr rom_size,
33
uint64_t kernel_entry,
34
- uint32_t fdt_load_addr, void *fdt);
35
+ uint64_t fdt_load_addr, void *fdt);
36
void riscv_rom_copy_firmware_info(MachineState *machine, hwaddr rom_base,
37
hwaddr rom_size,
38
uint32_t reset_vec_size,
39
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/riscv/boot.c
42
+++ b/hw/riscv/boot.c
43
@@ -XXX,XX +XXX,XX @@ hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
44
return *start + size;
45
}
46
47
-uint32_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
48
+uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
49
{
50
- uint32_t temp, fdt_addr;
51
+ uint64_t temp, fdt_addr;
52
hwaddr dram_end = dram_base + mem_size;
53
int ret, fdtsize = fdt_totalsize(fdt);
54
55
@@ -XXX,XX +XXX,XX @@ uint32_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
56
* Thus, put it at an 16MB aligned address that less than fdt size from the
57
* end of dram or 3GB whichever is lesser.
58
*/
59
- temp = MIN(dram_end, 3072 * MiB);
60
+ temp = (dram_base < 3072 * MiB) ? MIN(dram_end, 3072 * MiB) : dram_end;
61
fdt_addr = QEMU_ALIGN_DOWN(temp - fdtsize, 16 * MiB);
62
63
ret = fdt_pack(fdt);
64
@@ -XXX,XX +XXX,XX @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts
65
hwaddr start_addr,
66
hwaddr rom_base, hwaddr rom_size,
67
uint64_t kernel_entry,
68
- uint32_t fdt_load_addr, void *fdt)
69
+ uint64_t fdt_load_addr, void *fdt)
70
{
71
int i;
72
uint32_t start_addr_hi32 = 0x00000000;
73
+ uint32_t fdt_load_addr_hi32 = 0x00000000;
74
75
if (!riscv_is_32bit(harts)) {
76
start_addr_hi32 = start_addr >> 32;
77
+ fdt_load_addr_hi32 = fdt_load_addr >> 32;
78
}
79
/* reset vector */
80
uint32_t reset_vec[10] = {
81
@@ -XXX,XX +XXX,XX @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts
82
start_addr, /* start: .dword */
83
start_addr_hi32,
84
fdt_load_addr, /* fdt_laddr: .dword */
85
- 0x00000000,
86
+ fdt_load_addr_hi32,
87
/* fw_dyn: */
88
};
89
if (riscv_is_32bit(harts)) {
90
--
91
2.35.1
diff view generated by jsdifflib