1
The following changes since commit ad10b4badc1dd5b28305f9b9f1168cf0aa3ae946:
1
From: Alistair Francis <alistair.francis@wdc.com>
2
2
3
Merge tag 'pull-error-2024-05-27' of https://repo.or.cz/qemu/armbru into staging (2024-05-27 06:40:42 -0700)
3
The following changes since commit da5006445a92bb7801f54a93452fac63ca2f634c:
4
5
Merge tag 'python-pull-request' of https://gitlab.com/jsnow/qemu into staging (2022-04-21 15:16:52 -0700)
4
6
5
are available in the Git repository at:
7
are available in the Git repository at:
6
8
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20240528
9
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20220422-1
8
10
9
for you to fetch changes up to 1806da76cb81088ea026ca3441551782b850e393:
11
for you to fetch changes up to faee5441a038898f64b335dbaecab102ba406552:
10
12
11
target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR (2024-05-28 12:20:27 +1000)
13
hw/riscv: boot: Support 64bit fdt address. (2022-04-22 10:35:16 +1000)
12
14
13
----------------------------------------------------------------
15
----------------------------------------------------------------
14
RISC-V PR for 9.1
16
First RISC-V PR for QEMU 7.1
15
17
16
* APLICs add child earlier than realize
18
* Add support for Ibex SPI to OpenTitan
17
* Fix exposure of Zkr
19
* Add support for privileged spec version 1.12.0
18
* Raise exceptions on wrs.nto
20
* Use privileged spec version 1.12.0 for virt machine by default
19
* Implement SBI debug console (DBCN) calls for KVM
21
* Allow software access to MIP SEIP
20
* Support 64-bit addresses for initrd
22
* Add initial support for the Sdtrig extension
21
* Change RISCV_EXCP_SEMIHOST exception number to 63
23
* Optimisations for vector extensions
22
* Tolerate KVM disable ext errors
24
* Improvements to the misa ISA string
23
* Set tval in breakpoints
25
* Add isa extenstion strings to the device tree
24
* Add support for Zve32x extension
26
* Don't allow `-bios` options with KVM machines
25
* Add support for Zve64x extension
27
* Fix NAPOT range computation overflow
26
* Relax vector register check in RISCV gdbstub
28
* Fix DT property mmu-type when CPU mmu option is disabled
27
* Fix the element agnostic Vector function problem
29
* Make RISC-V ACLINT mtime MMIO register writable
28
* Fix Zvkb extension config
30
* Add and enable native debug feature
29
* Implement dynamic establishment of custom decoder
31
* Support 64bit fdt address.
30
* Add th.sxstatus CSR emulation
31
* Fix Zvfhmin checking for vfwcvt.f.f.v and vfncvt.f.f.w instructions
32
* Check single width operator for vector fp widen instructions
33
* Check single width operator for vfncvt.rod.f.f.w
34
* Remove redudant SEW checking for vector fp narrow/widen instructions
35
* Prioritize pmp errors in raise_mmu_exception()
36
* Do not set mtval2 for non guest-page faults
37
* Remove experimental prefix from "B" extension
38
* Fixup CBO extension register calculation
39
* Fix the hart bit setting of AIA
40
* Fix reg_width in ricsv_gen_dynamic_vector_feature()
41
* Decode all of the pmpcfg and pmpaddr CSRs
42
* Raise an exception when CSRRS/CSRRC writes a read-only CSR
43
32
44
----------------------------------------------------------------
33
----------------------------------------------------------------
45
Alexei Filippov (1):
34
Alistair Francis (2):
46
target/riscv: do not set mtval2 for non guest-page faults
35
target/riscv: cpu: Fixup indentation
36
target/riscv: Allow software access to MIP SEIP
47
37
48
Alistair Francis (2):
38
Atish Patra (7):
49
target/riscv: rvzicbo: Fixup CBO extension register calculation
39
target/riscv: Define simpler privileged spec version numbering
50
disas/riscv: Decode all of the pmpcfg and pmpaddr CSRs
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
51
46
52
Andrew Jones (2):
47
Bin Meng (7):
53
target/riscv/kvm: Fix exposure of Zkr
48
target/riscv: Add initial support for the Sdtrig extension
54
target/riscv: Raise exceptions on wrs.nto
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()
55
55
56
Cheng Yang (1):
56
Dylan Jhong (1):
57
hw/riscv/boot.c: Support 64-bit address for initrd
57
hw/riscv: boot: Support 64bit fdt address.
58
58
59
Christoph Müllner (1):
59
Frank Chang (3):
60
riscv: thead: Add th.sxstatus CSR emulation
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
61
63
62
Clément Léger (1):
64
Jim Shu (1):
63
target/riscv: change RISCV_EXCP_SEMIHOST exception number to 63
65
hw/intc: riscv_aclint: Add reset function of ACLINT devices
64
66
65
Daniel Henrique Barboza (6):
67
Nicolas Pitre (1):
66
target/riscv/kvm: implement SBI debug console (DBCN) calls
68
target/riscv/pmp: fix NAPOT range computation overflow
67
target/riscv/kvm: tolerate KVM disable ext errors
68
target/riscv/debug: set tval=pc in breakpoint exceptions
69
trans_privileged.c.inc: set (m|s)tval on ebreak breakpoint
70
target/riscv: prioritize pmp errors in raise_mmu_exception()
71
riscv, gdbstub.c: fix reg_width in ricsv_gen_dynamic_vector_feature()
72
69
73
Huang Tao (2):
70
Niklas Cassel (1):
74
target/riscv: Fix the element agnostic function problem
71
hw/riscv: virt: fix DT property mmu-type when CPU mmu option is disabled
75
target/riscv: Implement dynamic establishment of custom decoder
76
72
77
Jason Chien (3):
73
Ralf Ramsauer (1):
78
target/riscv: Add support for Zve32x extension
74
hw/riscv: virt: Exit if the user provided -bios in combination with KVM
79
target/riscv: Add support for Zve64x extension
80
target/riscv: Relax vector register check in RISCV gdbstub
81
75
82
Max Chou (4):
76
Richard Henderson (1):
83
target/riscv: rvv: Fix Zvfhmin checking for vfwcvt.f.f.v and vfncvt.f.f.w instructions
77
target/riscv: Use cpu_loop_exit_restore directly from mmu faults
84
target/riscv: rvv: Check single width operator for vector fp widen instructions
85
target/riscv: rvv: Check single width operator for vfncvt.rod.f.f.w
86
target/riscv: rvv: Remove redudant SEW checking for vector fp narrow/widen instructions
87
78
88
Rob Bradford (1):
79
Tsukasa OI (1):
89
target/riscv: Remove experimental prefix from "B" extension
80
target/riscv: misa to ISA string conversion fix
90
81
91
Yangyu Chen (1):
82
Weiwei Li (3):
92
target/riscv/cpu.c: fix Zvkb extension config
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
93
86
94
Yong-Xuan Wang (1):
87
Wilfred Mallawa (2):
95
target/riscv/kvm.c: Fix the hart bit setting of AIA
88
hw/ssi: Add Ibex SPI device model
89
riscv: opentitan: Connect opentitan SPI Host
96
90
97
Yu-Ming Chang (1):
91
include/hw/core/tcg-cpu-ops.h | 1 +
98
target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR
92
include/hw/intc/riscv_aclint.h | 1 +
99
93
include/hw/riscv/boot.h | 4 +-
100
yang.zhang (1):
94
include/hw/riscv/opentitan.h | 30 +-
101
hw/intc/riscv_aplic: APLICs should add child earlier than realize
95
include/hw/ssi/ibex_spi_host.h | 94 +++++
102
96
target/riscv/cpu.h | 40 ++-
103
MAINTAINERS | 1 +
97
target/riscv/cpu_bits.h | 40 +++
104
target/riscv/cpu.h | 11 ++
98
target/riscv/debug.h | 114 ++++++
105
target/riscv/cpu_bits.h | 2 +-
99
target/riscv/helper.h | 5 +-
106
target/riscv/cpu_cfg.h | 2 +
100
hw/intc/riscv_aclint.c | 144 ++++++--
107
target/riscv/helper.h | 1 +
101
hw/riscv/boot.c | 12 +-
108
target/riscv/sbi_ecall_interface.h | 17 +++
102
hw/riscv/opentitan.c | 36 +-
109
target/riscv/tcg/tcg-cpu.h | 15 +++
103
hw/riscv/virt.c | 24 +-
110
disas/riscv.c | 65 +++++++++-
104
hw/ssi/ibex_spi_host.c | 612 ++++++++++++++++++++++++++++++++
111
hw/intc/riscv_aplic.c | 8 +-
105
target/riscv/cpu.c | 120 ++++++-
112
hw/riscv/boot.c | 4 +-
106
target/riscv/cpu_helper.c | 10 +-
113
target/riscv/cpu.c | 10 +-
107
target/riscv/csr.c | 282 +++++++++++++--
114
target/riscv/cpu_helper.c | 37 +++---
108
target/riscv/debug.c | 441 +++++++++++++++++++++++
115
target/riscv/csr.c | 71 +++++++++--
109
target/riscv/machine.c | 55 +++
116
target/riscv/debug.c | 3 +
110
target/riscv/pmp.c | 14 +-
117
target/riscv/gdbstub.c | 8 +-
111
target/riscv/vector_helper.c | 31 +-
118
target/riscv/kvm/kvm-cpu.c | 157 ++++++++++++++++++++++++-
112
target/riscv/insn_trans/trans_rvv.c.inc | 25 +-
119
target/riscv/op_helper.c | 17 ++-
113
hw/ssi/meson.build | 1 +
120
target/riscv/tcg/tcg-cpu.c | 50 +++++---
114
hw/ssi/trace-events | 7 +
121
target/riscv/th_csr.c | 79 +++++++++++++
115
target/riscv/meson.build | 1 +
122
target/riscv/translate.c | 31 +++--
116
25 files changed, 1971 insertions(+), 173 deletions(-)
123
target/riscv/vector_internals.c | 22 ++++
117
create mode 100644 include/hw/ssi/ibex_spi_host.h
124
target/riscv/insn_trans/trans_privileged.c.inc | 2 +
118
create mode 100644 target/riscv/debug.h
125
target/riscv/insn_trans/trans_rvv.c.inc | 46 +++++---
119
create mode 100644 hw/ssi/ibex_spi_host.c
126
target/riscv/insn_trans/trans_rvzawrs.c.inc | 29 +++--
120
create mode 100644 target/riscv/debug.c
127
target/riscv/insn_trans/trans_rvzicbo.c.inc | 16 ++-
128
target/riscv/meson.build | 1 +
129
26 files changed, 596 insertions(+), 109 deletions(-)
130
create mode 100644 target/riscv/th_csr.c
131
diff view generated by jsdifflib
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
2
2
3
In AIA spec, each hart (or each hart within a group) has a unique hart
3
Adds the SPI_HOST device model for ibex. The device specification is as per
4
number to locate the memory pages of interrupt files in the address
4
[1]. The model has been tested on opentitan with spi_host unit tests
5
space. The number of bits required to represent any hart number is equal
5
written for TockOS.
6
to ceil(log2(hmax + 1)), where hmax is the largest hart number among
7
groups.
8
6
9
However, if the largest hart number among groups is a power of 2, QEMU
7
[1] https://docs.opentitan.org/hw/ip/spi_host/doc/
10
will pass an inaccurate hart-index-bit setting to Linux. For example, when
11
the guest OS has 4 harts, only ceil(log2(3 + 1)) = 2 bits are sufficient
12
to represent 4 harts, but we passes 3 to Linux. The code needs to be
13
updated to ensure accurate hart-index-bit settings.
14
8
15
Additionally, a Linux patch[1] is necessary to correctly recover the hart
9
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
16
index when the guest OS has only 1 hart, where the hart-index-bit is 0.
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
[1] https://lore.kernel.org/lkml/20240415064905.25184-1-yongxuan.wang@sifive.com/t/
12
Message-Id: <20220303045426.511588-1-alistair.francis@opensource.wdc.com>
19
20
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
21
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
22
Cc: qemu-stable <qemu-stable@nongnu.org>
23
Message-ID: <20240515091129.28116-1-yongxuan.wang@sifive.com>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
---
14
---
26
target/riscv/kvm/kvm-cpu.c | 9 ++++++++-
15
include/hw/ssi/ibex_spi_host.h | 94 +++++
27
1 file changed, 8 insertions(+), 1 deletion(-)
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
28
22
29
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
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
30
index XXXXXXX..XXXXXXX 100644
742
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/kvm/kvm-cpu.c
743
--- a/hw/ssi/meson.build
32
+++ b/target/riscv/kvm/kvm-cpu.c
744
+++ b/hw/ssi/meson.build
33
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
745
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_XILINX_SPIPS', if_true: files('xilinx_spips.c'))
34
}
746
softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-ospi.c'))
35
}
747
softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_spi.c'))
36
748
softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_spi.c'))
37
- hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
749
+softmmu_ss.add(when: 'CONFIG_IBEX', if_true: files('ibex_spi_host.c'))
38
+
750
diff --git a/hw/ssi/trace-events b/hw/ssi/trace-events
39
+ if (max_hart_per_socket > 1) {
751
index XXXXXXX..XXXXXXX 100644
40
+ max_hart_per_socket--;
752
--- a/hw/ssi/trace-events
41
+ hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
753
+++ b/hw/ssi/trace-events
42
+ } else {
754
@@ -XXX,XX +XXX,XX @@ npcm7xx_fiu_ctrl_read(const char *id, uint64_t addr, uint32_t data) "%s offset:
43
+ hart_bits = 0;
755
npcm7xx_fiu_ctrl_write(const char *id, uint64_t addr, uint32_t data) "%s offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
44
+ }
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
45
+
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
46
ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
758
+
47
KVM_DEV_RISCV_AIA_CONFIG_HART_BITS,
759
+# ibex_spi_host.c
48
&hart_bits, true, NULL);
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:"
49
--
765
--
50
2.45.1
766
2.35.1
diff view generated by jsdifflib
1
From: "yang.zhang" <yang.zhang@hexintek.com>
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
2
2
3
Since only root APLICs can have hw IRQ lines, aplic->parent should
3
Connect spi host[1/0] to opentitan.
4
be initialized first.
5
4
6
Fixes: e8f79343cf ("hw/intc: Add RISC-V AIA APLIC device emulation")
5
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: yang.zhang <yang.zhang@hexintek.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Cc: qemu-stable <qemu-stable@nongnu.org>
8
Message-Id: <20220303045426.511588-2-alistair.francis@opensource.wdc.com>
10
Message-ID: <20240409014445.278-1-gaoshanliukou@163.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
10
---
13
hw/intc/riscv_aplic.c | 8 ++++----
11
include/hw/riscv/opentitan.h | 30 +++++++++++++++++++++---------
14
1 file changed, 4 insertions(+), 4 deletions(-)
12
hw/riscv/opentitan.c | 36 ++++++++++++++++++++++++++++++++----
13
2 files changed, 53 insertions(+), 13 deletions(-)
15
14
16
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
15
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/intc/riscv_aplic.c
17
--- a/include/hw/riscv/opentitan.h
19
+++ b/hw/intc/riscv_aplic.c
18
+++ b/include/hw/riscv/opentitan.h
20
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
19
@@ -XXX,XX +XXX,XX @@
21
qdev_prop_set_bit(dev, "msimode", msimode);
20
#include "hw/intc/sifive_plic.h"
22
qdev_prop_set_bit(dev, "mmode", mmode);
21
#include "hw/char/ibex_uart.h"
23
22
#include "hw/timer/ibex_timer.h"
24
+ if (parent) {
23
+#include "hw/ssi/ibex_spi_host.h"
25
+ riscv_aplic_add_child(parent, dev);
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
+ }
26
+ }
125
+ }
27
+
126
+
28
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
127
create_unimplemented_device("riscv.lowrisc.ibex.gpio",
29
128
memmap[IBEX_DEV_GPIO].base, memmap[IBEX_DEV_GPIO].size);
30
if (!is_kvm_aia(msimode)) {
129
create_unimplemented_device("riscv.lowrisc.ibex.spi_device",
31
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
130
memmap[IBEX_DEV_SPI_DEVICE].base, memmap[IBEX_DEV_SPI_DEVICE].size);
32
}
131
- create_unimplemented_device("riscv.lowrisc.ibex.spi_host0",
33
132
- memmap[IBEX_DEV_SPI_HOST0].base, memmap[IBEX_DEV_SPI_HOST0].size);
34
- if (parent) {
133
- create_unimplemented_device("riscv.lowrisc.ibex.spi_host1",
35
- riscv_aplic_add_child(parent, dev);
134
- memmap[IBEX_DEV_SPI_HOST1].base, memmap[IBEX_DEV_SPI_HOST1].size);
36
- }
135
create_unimplemented_device("riscv.lowrisc.ibex.i2c",
37
-
136
memmap[IBEX_DEV_I2C].base, memmap[IBEX_DEV_I2C].size);
38
if (!msimode) {
137
create_unimplemented_device("riscv.lowrisc.ibex.pattgen",
39
for (i = 0; i < num_harts; i++) {
40
CPUState *cpu = cpu_by_arch_id(hartid_base + i);
41
--
138
--
42
2.45.1
139
2.35.1
diff view generated by jsdifflib
1
From: Jason Chien <jason.chien@sifive.com>
1
From: Atish Patra <atishp@rivosinc.com>
2
2
3
In current implementation, the gdbstub allows reading vector registers
3
Currently, the privileged specification version are defined in
4
only if V extension is supported. However, all vector extensions and
4
a complex manner for no benefit.
5
vector crypto extensions have the vector registers and they all depend
6
on Zve32x. The gdbstub should check for Zve32x instead.
7
5
8
Signed-off-by: Jason Chien <jason.chien@sifive.com>
6
Simplify it by changing it to a simple enum based on.
9
Reviewed-by: Frank Chang <frank.chang@sifive.com>
7
10
Reviewed-by: Max Chou <max.chou@sifive.com>
8
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-ID: <20240328022343.6871-4-jason.chien@sifive.com>
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>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
13
---
14
target/riscv/gdbstub.c | 2 +-
14
target/riscv/cpu.h | 7 +++++--
15
1 file changed, 1 insertion(+), 1 deletion(-)
15
1 file changed, 5 insertions(+), 2 deletions(-)
16
16
17
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
17
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/gdbstub.c
19
--- a/target/riscv/cpu.h
20
+++ b/target/riscv/gdbstub.c
20
+++ b/target/riscv/cpu.h
21
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
21
@@ -XXX,XX +XXX,XX @@ enum {
22
gdb_find_static_feature("riscv-32bit-fpu.xml"),
22
RISCV_FEATURE_AIA
23
0);
23
};
24
}
24
25
- if (env->misa_ext & RVV) {
25
-#define PRIV_VERSION_1_10_0 0x00011000
26
+ if (cpu->cfg.ext_zve32x) {
26
-#define PRIV_VERSION_1_11_0 0x00011100
27
gdb_register_coprocessor(cs, riscv_gdb_get_vector,
27
+/* Privileged specification version */
28
riscv_gdb_set_vector,
28
+enum {
29
ricsv_gen_dynamic_vector_feature(cs, cs->gdb_num_regs),
29
+ PRIV_VERSION_1_10_0 = 0,
30
+ PRIV_VERSION_1_11_0,
31
+};
32
33
#define VEXT_VERSION_1_00_0 0x00010000
34
30
--
35
--
31
2.45.1
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
1
From: Clément Léger <cleger@rivosinc.com>
1
From: Atish Patra <atishp@rivosinc.com>
2
2
3
The current semihost exception number (16) is a reserved number (range
3
RISC-V privileged specification v1.12 introduced a mconfigptr
4
[16-17]). The upcoming double trap specification uses that number for
4
which will hold the physical address of a configuration data
5
the double trap exception. Since the privileged spec (Table 22) defines
5
structure. As Qemu doesn't have a configuration data structure,
6
ranges for custom uses change the semihosting exception number to 63
6
is read as zero which is valid as per the priv spec.
7
which belongs to the range [48-63] in order to avoid any future
8
collisions with reserved exception.
9
10
Signed-off-by: Clément Léger <cleger@rivosinc.com>
11
7
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-ID: <20240422135840.1959967-1-cleger@rivosinc.com>
9
Signed-off-by: Atish Patra <atishp@rivosinc.com>
10
Message-Id: <20220303185440.512391-5-atishp@rivosinc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
12
---
16
target/riscv/cpu_bits.h | 2 +-
13
target/riscv/cpu_bits.h | 1 +
17
1 file changed, 1 insertion(+), 1 deletion(-)
14
target/riscv/csr.c | 2 ++
15
2 files changed, 3 insertions(+)
18
16
19
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
17
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu_bits.h
19
--- a/target/riscv/cpu_bits.h
22
+++ b/target/riscv/cpu_bits.h
20
+++ b/target/riscv/cpu_bits.h
23
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
21
@@ -XXX,XX +XXX,XX @@
24
RISCV_EXCP_INST_PAGE_FAULT = 0xc, /* since: priv-1.10.0 */
22
#define CSR_MARCHID 0xf12
25
RISCV_EXCP_LOAD_PAGE_FAULT = 0xd, /* since: priv-1.10.0 */
23
#define CSR_MIMPID 0xf13
26
RISCV_EXCP_STORE_PAGE_FAULT = 0xf, /* since: priv-1.10.0 */
24
#define CSR_MHARTID 0xf14
27
- RISCV_EXCP_SEMIHOST = 0x10,
25
+#define CSR_MCONFIGPTR 0xf15
28
RISCV_EXCP_INST_GUEST_PAGE_FAULT = 0x14,
26
29
RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT = 0x15,
27
/* Machine Trap Setup */
30
RISCV_EXCP_VIRT_INSTRUCTION_FAULT = 0x16,
28
#define CSR_MSTATUS 0x300
31
RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT = 0x17,
29
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
32
+ RISCV_EXCP_SEMIHOST = 0x3f,
30
index XXXXXXX..XXXXXXX 100644
33
} RISCVException;
31
--- a/target/riscv/csr.c
34
32
+++ b/target/riscv/csr.c
35
#define RISCV_EXCP_INT_FLAG 0x80000000
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 },
36
--
42
--
37
2.45.1
43
2.35.1
38
39
diff view generated by jsdifflib
1
From: Yu-Ming Chang <yumin686@andestech.com>
1
From: Atish Patra <atishp@rivosinc.com>
2
2
3
Both CSRRS and CSRRC always read the addressed CSR and cause any read side
3
The RISC-V privileged specification v1.12 defines few execution
4
effects regardless of rs1 and rd fields. Note that if rs1 specifies a register
4
environment configuration CSRs that can be used enable/disable
5
holding a zero value other than x0, the instruction will still attempt to write
5
extensions per privilege levels.
6
the unmodified value back to the CSR and will cause any attendant side effects.
6
7
7
Add the basic support for these CSRs.
8
So if CSRRS or CSRRC tries to write a read-only CSR with rs1 which specifies
8
9
a register holding a zero value, an illegal instruction exception should be
10
raised.
11
12
Signed-off-by: Yu-Ming Chang <yumin686@andestech.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-ID: <20240403070823.80897-1-yumin686@andestech.com>
10
Signed-off-by: Atish Patra <atishp@rivosinc.com>
11
Message-Id: <20220303185440.512391-6-atishp@rivosinc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
13
---
17
target/riscv/cpu.h | 4 ++++
14
target/riscv/cpu.h | 5 ++
18
target/riscv/csr.c | 51 ++++++++++++++++++++++++++++++++++++----
15
target/riscv/cpu_bits.h | 39 +++++++++++++++
19
target/riscv/op_helper.c | 6 ++---
16
target/riscv/csr.c | 107 ++++++++++++++++++++++++++++++++++++++++
20
3 files changed, 53 insertions(+), 8 deletions(-)
17
target/riscv/machine.c | 23 +++++++++
18
4 files changed, 174 insertions(+)
21
19
22
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
20
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
23
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
24
--- a/target/riscv/cpu.h
22
--- a/target/riscv/cpu.h
25
+++ b/target/riscv/cpu.h
23
+++ b/target/riscv/cpu.h
26
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
24
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
27
void riscv_cpu_update_mask(CPURISCVState *env);
25
target_ulong spmbase;
28
bool riscv_cpu_is_32bit(RISCVCPU *cpu);
26
target_ulong upmmask;
29
27
target_ulong upmbase;
30
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,
28
+
31
+ target_ulong *ret_value);
29
+ /* CSRs for execution enviornment configuration */
32
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
30
+ uint64_t menvcfg;
33
target_ulong *ret_value,
31
+ target_ulong senvcfg;
34
target_ulong new_value, target_ulong write_mask);
32
+ uint64_t henvcfg;
35
@@ -XXX,XX +XXX,XX @@ typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
33
#endif
36
target_ulong new_value,
34
target_ulong cur_pmmask;
37
target_ulong write_mask);
35
target_ulong cur_pmbase;
38
36
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
39
+RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
37
index XXXXXXX..XXXXXXX 100644
40
+ Int128 *ret_value);
38
--- a/target/riscv/cpu_bits.h
41
RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
39
+++ b/target/riscv/cpu_bits.h
42
Int128 *ret_value,
40
@@ -XXX,XX +XXX,XX @@
43
Int128 new_value, Int128 write_mask);
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 (1ULL << 62)
82
+#define MENVCFG_STCE (1ULL << 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
44
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
107
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
45
index XXXXXXX..XXXXXXX 100644
108
index XXXXXXX..XXXXXXX 100644
46
--- a/target/riscv/csr.c
109
--- a/target/riscv/csr.c
47
+++ b/target/riscv/csr.c
110
+++ b/target/riscv/csr.c
48
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno,
111
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mtval(CPURISCVState *env, int csrno,
49
50
static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
51
int csrno,
52
- bool write_mask)
53
+ bool write)
54
{
55
/* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
56
bool read_only = get_field(csrno, 0xC00) == 3;
57
@@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
58
}
59
60
/* read / write check */
61
- if (write_mask && read_only) {
62
+ if (write && read_only) {
63
return RISCV_EXCP_ILLEGAL_INST;
64
}
65
66
@@ -XXX,XX +XXX,XX @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
67
return RISCV_EXCP_NONE;
112
return RISCV_EXCP_NONE;
68
}
113
}
69
114
70
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,
115
+/* Execution environment configuration setup */
71
+ target_ulong *ret_value)
116
+static RISCVException read_menvcfg(CPURISCVState *env, int csrno,
72
+{
117
+ target_ulong *val)
73
+ RISCVException ret = riscv_csrrw_check(env, csrno, false);
118
+{
74
+ if (ret != RISCV_EXCP_NONE) {
119
+ *val = env->menvcfg;
75
+ return ret;
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;
76
+ }
130
+ }
77
+
131
+ env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
78
+ return riscv_csrrw_do64(env, csrno, ret_value, 0, 0);
132
+
79
+}
133
+ return RISCV_EXCP_NONE;
80
+
134
+}
81
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
135
+
82
target_ulong *ret_value,
136
+static RISCVException read_menvcfgh(CPURISCVState *env, int csrno,
83
target_ulong new_value, target_ulong write_mask)
137
+ target_ulong *val)
84
{
138
+{
85
- RISCVException ret = riscv_csrrw_check(env, csrno, write_mask);
139
+ *val = env->menvcfg >> 32;
86
+ RISCVException ret = riscv_csrrw_check(env, csrno, true);
140
+ return RISCV_EXCP_NONE;
87
if (ret != RISCV_EXCP_NONE) {
141
+}
88
return ret;
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
89
}
271
}
90
@@ -XXX,XX +XXX,XX @@ static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
272
};
91
return RISCV_EXCP_NONE;
92
}
93
94
+RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
95
+ Int128 *ret_value)
96
+{
97
+ RISCVException ret;
98
+
99
+ ret = riscv_csrrw_check(env, csrno, false);
100
+ if (ret != RISCV_EXCP_NONE) {
101
+ return ret;
102
+ }
103
+
104
+ if (csr_ops[csrno].read128) {
105
+ return riscv_csrrw_do128(env, csrno, ret_value,
106
+ int128_zero(), int128_zero());
107
+ }
108
+
109
+ /*
110
+ * Fall back to 64-bit version for now, if the 128-bit alternative isn't
111
+ * at all defined.
112
+ * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
113
+ * significant), for those, this fallback is correctly handling the
114
+ * accesses
115
+ */
116
+ target_ulong old_value;
117
+ ret = riscv_csrrw_do64(env, csrno, &old_value,
118
+ (target_ulong)0,
119
+ (target_ulong)0);
120
+ if (ret == RISCV_EXCP_NONE && ret_value) {
121
+ *ret_value = int128_make64(old_value);
122
+ }
123
+ return ret;
124
+}
125
+
126
RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
127
Int128 *ret_value,
128
Int128 new_value, Int128 write_mask)
129
{
130
RISCVException ret;
131
132
- ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask));
133
+ ret = riscv_csrrw_check(env, csrno, true);
134
if (ret != RISCV_EXCP_NONE) {
135
return ret;
136
}
137
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
138
index XXXXXXX..XXXXXXX 100644
139
--- a/target/riscv/op_helper.c
140
+++ b/target/riscv/op_helper.c
141
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrr(CPURISCVState *env, int csr)
142
}
143
144
target_ulong val = 0;
145
- RISCVException ret = riscv_csrrw(env, csr, &val, 0, 0);
146
+ RISCVException ret = riscv_csrr(env, csr, &val);
147
148
if (ret != RISCV_EXCP_NONE) {
149
riscv_raise_exception(env, ret, GETPC());
150
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrrw(CPURISCVState *env, int csr,
151
target_ulong helper_csrr_i128(CPURISCVState *env, int csr)
152
{
153
Int128 rv = int128_zero();
154
- RISCVException ret = riscv_csrrw_i128(env, csr, &rv,
155
- int128_zero(),
156
- int128_zero());
157
+ RISCVException ret = riscv_csrr_i128(env, csr, &rv);
158
159
if (ret != RISCV_EXCP_NONE) {
160
riscv_raise_exception(env, ret, GETPC());
161
--
273
--
162
2.45.1
274
2.35.1
diff view generated by jsdifflib
1
From: Jason Chien <jason.chien@sifive.com>
1
From: Atish Patra <atishp@rivosinc.com>
2
2
3
Add support for Zve32x extension and replace some checks for Zve32f with
3
Virt machine uses privileged specification version 1.12 now.
4
Zve32x, since Zve32f depends on Zve32x.
4
All other machine continue to use the default one defined for that
5
machine unless changed to 1.12 by the user explicitly.
5
6
6
Signed-off-by: Jason Chien <jason.chien@sifive.com>
7
This commit enforces the privilege version for csrs introduced in
7
Reviewed-by: Frank Chang <frank.chang@sifive.com>
8
v1.12 or after.
8
Reviewed-by: Max Chou <max.chou@sifive.com>
9
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-ID: <20240328022343.6871-2-jason.chien@sifive.com>
11
Signed-off-by: Atish Patra <atishp@rivosinc.com>
12
Message-Id: <20220303185440.512391-7-atishp@rivosinc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
14
---
13
target/riscv/cpu_cfg.h | 1 +
15
target/riscv/cpu.c | 8 +++++---
14
target/riscv/cpu.c | 2 ++
16
target/riscv/csr.c | 5 +++++
15
target/riscv/cpu_helper.c | 2 +-
17
2 files changed, 10 insertions(+), 3 deletions(-)
16
target/riscv/csr.c | 2 +-
17
target/riscv/tcg/tcg-cpu.c | 16 ++++++++--------
18
target/riscv/insn_trans/trans_rvv.c.inc | 4 ++--
19
6 files changed, 15 insertions(+), 12 deletions(-)
20
18
21
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/cpu_cfg.h
24
+++ b/target/riscv/cpu_cfg.h
25
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
26
bool ext_zhinx;
27
bool ext_zhinxmin;
28
bool ext_zve32f;
29
+ bool ext_zve32x;
30
bool ext_zve64f;
31
bool ext_zve64d;
32
bool ext_zvbb;
33
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
19
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
34
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
35
--- a/target/riscv/cpu.c
21
--- a/target/riscv/cpu.c
36
+++ b/target/riscv/cpu.c
22
+++ b/target/riscv/cpu.c
37
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
23
@@ -XXX,XX +XXX,XX @@ static void riscv_any_cpu_init(Object *obj)
38
ISA_EXT_DATA_ENTRY(zvbb, PRIV_VERSION_1_12_0, ext_zvbb),
24
#elif defined(TARGET_RISCV64)
39
ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
25
set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
40
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
26
#endif
41
+ ISA_EXT_DATA_ENTRY(zve32x, PRIV_VERSION_1_10_0, ext_zve32x),
27
- set_priv_version(env, PRIV_VERSION_1_11_0);
42
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
28
+ set_priv_version(env, PRIV_VERSION_1_12_0);
43
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
29
}
44
ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
30
45
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
31
#if defined(TARGET_RISCV64)
46
MULTI_EXT_CFG_BOOL("zfh", ext_zfh, false),
32
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
47
MULTI_EXT_CFG_BOOL("zfhmin", ext_zfhmin, false),
33
}
48
MULTI_EXT_CFG_BOOL("zve32f", ext_zve32f, false),
34
49
+ MULTI_EXT_CFG_BOOL("zve32x", ext_zve32x, false),
35
if (cpu->cfg.priv_spec) {
50
MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false),
36
- if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) {
51
MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false),
37
+ if (!g_strcmp0(cpu->cfg.priv_spec, "v1.12.0")) {
52
MULTI_EXT_CFG_BOOL("zvfbfmin", ext_zvfbfmin, false),
38
+ priv_version = PRIV_VERSION_1_12_0;
53
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
39
+ } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) {
54
index XXXXXXX..XXXXXXX 100644
40
priv_version = PRIV_VERSION_1_11_0;
55
--- a/target/riscv/cpu_helper.c
41
} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) {
56
+++ b/target/riscv/cpu_helper.c
42
priv_version = PRIV_VERSION_1_10_0;
57
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
43
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
58
*pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
44
if (priv_version) {
59
*cs_base = 0;
45
set_priv_version(env, priv_version);
60
46
} else if (!env->priv_ver) {
61
- if (cpu->cfg.ext_zve32f) {
47
- set_priv_version(env, PRIV_VERSION_1_11_0);
62
+ if (cpu->cfg.ext_zve32x) {
48
+ set_priv_version(env, PRIV_VERSION_1_12_0);
63
/*
49
}
64
* If env->vl equals to VLMAX, we can use generic vector operation
50
65
* expanders (GVEC) to accerlate the vector operations.
51
if (cpu->cfg.mmu) {
66
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
52
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
67
index XXXXXXX..XXXXXXX 100644
53
index XXXXXXX..XXXXXXX 100644
68
--- a/target/riscv/csr.c
54
--- a/target/riscv/csr.c
69
+++ b/target/riscv/csr.c
55
+++ b/target/riscv/csr.c
70
@@ -XXX,XX +XXX,XX @@ static RISCVException fs(CPURISCVState *env, int csrno)
56
@@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
71
72
static RISCVException vs(CPURISCVState *env, int csrno)
73
{
57
{
74
- if (riscv_cpu_cfg(env)->ext_zve32f) {
58
/* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
75
+ if (riscv_cpu_cfg(env)->ext_zve32x) {
59
int read_only = get_field(csrno, 0xC00) == 3;
60
+ int csr_min_priv = csr_ops[csrno].min_priv_ver;
76
#if !defined(CONFIG_USER_ONLY)
61
#if !defined(CONFIG_USER_ONLY)
77
if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
62
int effective_priv = env->priv;
78
return RISCV_EXCP_ILLEGAL_INST;
63
79
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
64
@@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
80
index XXXXXXX..XXXXXXX 100644
65
return RISCV_EXCP_ILLEGAL_INST;
81
--- a/target/riscv/tcg/tcg-cpu.c
82
+++ b/target/riscv/tcg/tcg-cpu.c
83
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
84
return;
85
}
66
}
86
67
87
- if (cpu->cfg.ext_zve32f && !riscv_has_ext(env, RVF)) {
68
+ if (env->priv_ver < csr_min_priv) {
88
- error_setg(errp, "Zve32f/Zve64f extensions require F extension");
69
+ return RISCV_EXCP_ILLEGAL_INST;
89
- return;
70
+ }
90
+ /* The Zve32f extension depends on the Zve32x extension */
71
+
91
+ if (cpu->cfg.ext_zve32f) {
72
return csr_ops[csrno].predicate(env, csrno);
92
+ if (!riscv_has_ext(env, RVF)) {
73
}
93
+ error_setg(errp, "Zve32f/Zve64f extensions require F extension");
94
+ return;
95
+ }
96
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32x), true);
97
}
98
99
if (cpu->cfg.ext_zvfh) {
100
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
101
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zvbc), true);
102
}
103
104
- /*
105
- * In principle Zve*x would also suffice here, were they supported
106
- * in qemu
107
- */
108
if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkb || cpu->cfg.ext_zvkg ||
109
cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksed ||
110
- cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
111
+ cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32x) {
112
error_setg(errp,
113
"Vector crypto extensions require V or Zve* extensions");
114
return;
115
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
116
index XXXXXXX..XXXXXXX 100644
117
--- a/target/riscv/insn_trans/trans_rvv.c.inc
118
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
119
@@ -XXX,XX +XXX,XX @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
120
{
121
TCGv s1, dst;
122
123
- if (!require_rvv(s) || !s->cfg_ptr->ext_zve32f) {
124
+ if (!require_rvv(s) || !s->cfg_ptr->ext_zve32x) {
125
return false;
126
}
127
128
@@ -XXX,XX +XXX,XX @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
129
{
130
TCGv dst;
131
132
- if (!require_rvv(s) || !s->cfg_ptr->ext_zve32f) {
133
+ if (!require_rvv(s) || !s->cfg_ptr->ext_zve32x) {
134
return false;
135
}
136
74
137
--
75
--
138
2.45.1
76
2.35.1
diff view generated by jsdifflib
1
From: Jason Chien <jason.chien@sifive.com>
1
From: Alistair Francis <alistair.francis@wdc.com>
2
2
3
Add support for Zve64x extension. Enabling Zve64f enables Zve64x and
3
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
4
enabling Zve64x enables Zve32x according to their dependency.
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(-)
5
10
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2107
7
Signed-off-by: Jason Chien <jason.chien@sifive.com>
8
Reviewed-by: Frank Chang <frank.chang@sifive.com>
9
Reviewed-by: Max Chou <max.chou@sifive.com>
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Message-ID: <20240328022343.6871-3-jason.chien@sifive.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
target/riscv/cpu_cfg.h | 1 +
15
target/riscv/cpu.c | 2 ++
16
target/riscv/tcg/tcg-cpu.c | 17 +++++++++++------
17
3 files changed, 14 insertions(+), 6 deletions(-)
18
19
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu_cfg.h
22
+++ b/target/riscv/cpu_cfg.h
23
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
24
bool ext_zve32x;
25
bool ext_zve64f;
26
bool ext_zve64d;
27
+ bool ext_zve64x;
28
bool ext_zvbb;
29
bool ext_zvbc;
30
bool ext_zvkb;
31
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
11
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
32
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/cpu.c
13
--- a/target/riscv/cpu.c
34
+++ b/target/riscv/cpu.c
14
+++ b/target/riscv/cpu.c
35
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
15
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
36
ISA_EXT_DATA_ENTRY(zve32x, PRIV_VERSION_1_10_0, ext_zve32x),
16
if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
37
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
17
error_setg(errp,
38
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
18
"I and E extensions are incompatible");
39
+ ISA_EXT_DATA_ENTRY(zve64x, PRIV_VERSION_1_10_0, ext_zve64x),
19
- return;
40
ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
20
- }
41
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
42
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
43
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
44
MULTI_EXT_CFG_BOOL("zve32x", ext_zve32x, false),
45
MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false),
46
MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false),
47
+ MULTI_EXT_CFG_BOOL("zve64x", ext_zve64x, false),
48
MULTI_EXT_CFG_BOOL("zvfbfmin", ext_zvfbfmin, false),
49
MULTI_EXT_CFG_BOOL("zvfbfwma", ext_zvfbfwma, false),
50
MULTI_EXT_CFG_BOOL("zvfh", ext_zvfh, false),
51
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/riscv/tcg/tcg-cpu.c
54
+++ b/target/riscv/tcg/tcg-cpu.c
55
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
56
57
/* The Zve64d extension depends on the Zve64f extension */
58
if (cpu->cfg.ext_zve64d) {
59
+ if (!riscv_has_ext(env, RVD)) {
60
+ error_setg(errp, "Zve64d/V extensions require D extension");
61
+ return;
21
+ return;
62
+ }
22
+ }
63
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve64f), true);
23
64
}
24
if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) {
65
25
error_setg(errp,
66
- /* The Zve64f extension depends on the Zve32f extension */
26
"Either I or E extension must be set");
67
+ /* The Zve64f extension depends on the Zve64x and Zve32f extensions */
27
- return;
68
if (cpu->cfg.ext_zve64f) {
28
- }
69
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve64x), true);
29
+ return;
70
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32f), true);
30
+ }
71
}
31
72
32
- if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m &
73
- if (cpu->cfg.ext_zve64d && !riscv_has_ext(env, RVD)) {
33
- cpu->cfg.ext_a & cpu->cfg.ext_f &
74
- error_setg(errp, "Zve64d/V extensions require D extension");
34
- cpu->cfg.ext_d)) {
75
- return;
35
+ if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m &
76
+ /* The Zve64x extension depends on the Zve32x extension */
36
+ cpu->cfg.ext_a & cpu->cfg.ext_f &
77
+ if (cpu->cfg.ext_zve64x) {
37
+ cpu->cfg.ext_d)) {
78
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32x), true);
38
warn_report("Setting G will also set IMAFD");
79
}
39
cpu->cfg.ext_i = true;
80
40
cpu->cfg.ext_m = true;
81
/* The Zve32f extension depends on the Zve32x extension */
41
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_set_irq(void *opaque, int irq, int level)
82
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
42
case IRQ_S_EXT:
83
return;
43
case IRQ_VS_EXT:
84
}
44
case IRQ_M_EXT:
85
45
- if (kvm_enabled()) {
86
- if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64f) {
46
+ if (kvm_enabled()) {
87
+ if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64x) {
47
kvm_riscv_set_irq(cpu, irq, level);
88
error_setg(
48
- } else {
89
errp,
49
+ } else {
90
- "Zvbc and Zvknhb extensions require V or Zve64{f,d} extensions");
50
riscv_cpu_update_mip(cpu, 1 << irq, BOOL_TO_MASK(level));
91
+ "Zvbc and Zvknhb extensions require V or Zve64x extensions");
51
- }
92
return;
52
+ }
93
}
53
break;
94
54
default:
55
g_assert_not_reached();
95
--
56
--
96
2.45.1
57
2.35.1
diff view generated by jsdifflib
1
From: Andrew Jones <ajones@ventanamicro.com>
1
From: Alistair Francis <alistair.francis@wdc.com>
2
2
3
The Zkr extension may only be exposed to KVM guests if the VMM
3
The RISC-V specification states that:
4
implements the SEED CSR. Use the same implementation as TCG.
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."
5
7
6
Without this patch, running with a KVM which does not forward the
8
We currently only allow either the interrupt controller or software to
7
SEED CSR access to QEMU will result in an ILL exception being
9
set the bit, which is incorrect.
8
injected into the guest (this results in Linux guests crashing on
9
boot). And, when running with a KVM which does forward the access,
10
QEMU will crash, since QEMU doesn't know what to do with the exit.
11
10
12
Fixes: 3108e2f1c69d ("target/riscv/kvm: update KVM exts to Linux 6.8")
11
This patch removes the miclaim mask when writing MIP to allow M-mode
13
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
12
software to inject interrupts, even with an interrupt controller.
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
15
Cc: qemu-stable <qemu-stable@nongnu.org>
14
We then also need to keep track of which source is setting MIP_SEIP. The
16
Message-ID: <20240422134605.534207-2-ajones@ventanamicro.com>
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
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
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>
18
---
24
---
19
target/riscv/cpu.h | 3 +++
25
target/riscv/cpu.h | 8 ++++++++
20
target/riscv/csr.c | 18 ++++++++++++++----
26
target/riscv/cpu.c | 10 +++++++++-
21
target/riscv/kvm/kvm-cpu.c | 25 +++++++++++++++++++++++++
27
target/riscv/csr.c | 8 ++++++--
22
3 files changed, 42 insertions(+), 4 deletions(-)
28
3 files changed, 23 insertions(+), 3 deletions(-)
23
29
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
30
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
25
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/cpu.h
32
--- a/target/riscv/cpu.h
27
+++ b/target/riscv/cpu.h
33
+++ b/target/riscv/cpu.h
28
@@ -XXX,XX +XXX,XX @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
34
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
29
35
uint64_t mstatus;
30
void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
36
31
37
uint64_t mip;
32
+target_ulong riscv_new_csr_seed(target_ulong new_value,
38
+ /*
33
+ target_ulong write_mask);
39
+ * MIP contains the software writable version of SEIP ORed with the
34
+
40
+ * external interrupt value. The MIP register is always up-to-date.
35
uint8_t satp_mode_max_from_map(uint32_t map);
41
+ * To keep track of the current source, we also save booleans of the values
36
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
42
+ * here.
37
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
}
38
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
77
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
39
index XXXXXXX..XXXXXXX 100644
78
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/csr.c
79
--- a/target/riscv/csr.c
41
+++ b/target/riscv/csr.c
80
+++ b/target/riscv/csr.c
42
@@ -XXX,XX +XXX,XX @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno,
81
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
43
#endif
82
uint64_t new_val, uint64_t wr_mask)
44
45
/* Crypto Extension */
46
-static RISCVException rmw_seed(CPURISCVState *env, int csrno,
47
- target_ulong *ret_value,
48
- target_ulong new_value,
49
- target_ulong write_mask)
50
+target_ulong riscv_new_csr_seed(target_ulong new_value,
51
+ target_ulong write_mask)
52
{
83
{
53
uint16_t random_v;
84
RISCVCPU *cpu = env_archcpu(env);
54
Error *random_e = NULL;
85
- /* Allow software control of delegable interrupts not claimed by hardware */
55
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno,
86
- uint64_t old_mip, mask = wr_mask & delegable_ints & ~env->miclaim;
56
rval = random_v | SEED_OPST_ES16;
87
+ uint64_t old_mip, mask = wr_mask & delegable_ints;
57
}
88
uint32_t gin;
58
89
59
+ return rval;
90
+ if (mask & MIP_SEIP) {
60
+}
91
+ env->software_seip = new_val & MIP_SEIP;
61
+
92
+ new_val |= env->external_seip * MIP_SEIP;
62
+static RISCVException rmw_seed(CPURISCVState *env, int csrno,
63
+ target_ulong *ret_value,
64
+ target_ulong new_value,
65
+ target_ulong write_mask)
66
+{
67
+ target_ulong rval;
68
+
69
+ rval = riscv_new_csr_seed(new_value, write_mask);
70
+
71
if (ret_value) {
72
*ret_value = rval;
73
}
74
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/riscv/kvm/kvm-cpu.c
77
+++ b/target/riscv/kvm/kvm-cpu.c
78
@@ -XXX,XX +XXX,XX @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
79
return ret;
80
}
81
82
+static int kvm_riscv_handle_csr(CPUState *cs, struct kvm_run *run)
83
+{
84
+ target_ulong csr_num = run->riscv_csr.csr_num;
85
+ target_ulong new_value = run->riscv_csr.new_value;
86
+ target_ulong write_mask = run->riscv_csr.write_mask;
87
+ int ret = 0;
88
+
89
+ switch (csr_num) {
90
+ case CSR_SEED:
91
+ run->riscv_csr.ret_value = riscv_new_csr_seed(new_value, write_mask);
92
+ break;
93
+ default:
94
+ qemu_log_mask(LOG_UNIMP,
95
+ "%s: un-handled CSR EXIT for CSR %lx\n",
96
+ __func__, csr_num);
97
+ ret = -1;
98
+ break;
99
+ }
93
+ }
100
+
94
+
101
+ return ret;
95
if (mask) {
102
+}
96
old_mip = riscv_cpu_update_mip(cpu, mask, (new_val & mask));
103
+
97
} else {
104
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
105
{
106
int ret = 0;
107
@@ -XXX,XX +XXX,XX @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
108
case KVM_EXIT_RISCV_SBI:
109
ret = kvm_riscv_handle_sbi(cs, run);
110
break;
111
+ case KVM_EXIT_RISCV_CSR:
112
+ ret = kvm_riscv_handle_csr(cs, run);
113
+ break;
114
default:
115
qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n",
116
__func__, run->exit_reason);
117
--
98
--
118
2.45.1
99
2.35.1
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
The th.sxstatus CSR can be used to identify available custom extension
3
This adds initial support for the Sdtrig extension via the Trigger
4
on T-Head CPUs. The CSR is documented here:
4
Module, as defined in the RISC-V Debug Specification [1].
5
https://github.com/T-head-Semi/thead-extension-spec/blob/master/xtheadsxstatus.adoc
6
5
7
An important property of this patch is, that the th.sxstatus MAEE field
6
Only "Address / Data Match" trigger (type 2) is implemented as of now,
8
is not set (indicating that XTheadMae is not available).
7
which is mainly used for hardware breakpoint and watchpoint. The number
9
XTheadMae is a memory attribute extension (similar to Svpbmt) which is
8
of type 2 triggers implemented is 2, which is the number that we can
10
implemented in many T-Head CPUs (C906, C910, etc.) and utilizes bits
9
find in the SiFive U54/U74 cores.
11
in PTEs that are marked as reserved. QEMU maintainers prefer to not
12
implement XTheadMae, so we need give kernels a mechanism to identify
13
if XTheadMae is available in a system or not. And this patch introduces
14
this mechanism in QEMU in a way that's compatible with real HW
15
(i.e., probing the th.sxstatus.MAEE bit).
16
10
17
Further context can be found on the list:
11
[1] https://github.com/riscv/riscv-debug-spec/raw/master/riscv-debug-stable.pdf
18
https://lists.gnu.org/archive/html/qemu-devel/2024-02/msg00775.html
19
12
20
Reviewed-by: LIU Zhiwei <zhiwe_liu@linux.alibaba.com>
13
Signed-off-by: Bin Meng <bin.meng@windriver.com>
21
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
22
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
15
Message-Id: <20220315065529.62198-2-bmeng.cn@gmail.com>
23
Message-ID: <20240429073656.2486732-1-christoph.muellner@vrull.eu>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
---
17
---
26
MAINTAINERS | 1 +
18
target/riscv/cpu.h | 5 +
27
target/riscv/cpu.h | 3 ++
19
target/riscv/debug.h | 108 +++++++++++++
28
target/riscv/cpu.c | 1 +
20
target/riscv/debug.c | 339 +++++++++++++++++++++++++++++++++++++++
29
target/riscv/th_csr.c | 79 ++++++++++++++++++++++++++++++++++++++++
21
target/riscv/meson.build | 1 +
30
target/riscv/meson.build | 1 +
22
4 files changed, 453 insertions(+)
31
5 files changed, 85 insertions(+)
23
create mode 100644 target/riscv/debug.h
32
create mode 100644 target/riscv/th_csr.c
24
create mode 100644 target/riscv/debug.c
33
25
34
diff --git a/MAINTAINERS b/MAINTAINERS
35
index XXXXXXX..XXXXXXX 100644
36
--- a/MAINTAINERS
37
+++ b/MAINTAINERS
38
@@ -XXX,XX +XXX,XX @@ L: qemu-riscv@nongnu.org
39
S: Supported
40
F: target/riscv/insn_trans/trans_xthead.c.inc
41
F: target/riscv/xthead*.decode
42
+F: target/riscv/th_*
43
F: disas/riscv-xthead*
44
45
RISC-V XVentanaCondOps extension
46
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
26
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
47
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
48
--- a/target/riscv/cpu.h
28
--- a/target/riscv/cpu.h
49
+++ b/target/riscv/cpu.h
29
+++ b/target/riscv/cpu.h
50
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_new_csr_seed(target_ulong new_value,
30
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState CPURISCVState;
51
uint8_t satp_mode_max_from_map(uint32_t map);
31
52
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
32
#if !defined(CONFIG_USER_ONLY)
53
33
#include "pmp.h"
54
+/* Implemented in th_csr.c */
34
+#include "debug.h"
55
+void th_register_custom_csrs(RISCVCPU *cpu);
56
+
57
#endif /* RISCV_CPU_H */
58
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/riscv/cpu.c
61
+++ b/target/riscv/cpu.c
62
@@ -XXX,XX +XXX,XX @@ static void rv64_thead_c906_cpu_init(Object *obj)
63
cpu->cfg.mvendorid = THEAD_VENDOR_ID;
64
#ifndef CONFIG_USER_ONLY
65
set_satp_mode_max_supported(cpu, VM_1_10_SV39);
66
+ th_register_custom_csrs(cpu);
67
#endif
35
#endif
68
36
69
/* inherited from parent obj via riscv_cpu_init() */
37
#define RV_VLEN_MAX 1024
70
diff --git a/target/riscv/th_csr.c b/target/riscv/th_csr.c
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
71
new file mode 100644
50
new file mode 100644
72
index XXXXXXX..XXXXXXX
51
index XXXXXXX..XXXXXXX
73
--- /dev/null
52
--- /dev/null
74
+++ b/target/riscv/th_csr.c
53
+++ b/target/riscv/debug.h
75
@@ -XXX,XX +XXX,XX @@
54
@@ -XXX,XX +XXX,XX @@
76
+/*
55
+/*
77
+ * T-Head-specific CSRs.
56
+ * QEMU RISC-V Native Debug Support
78
+ *
57
+ *
79
+ * Copyright (c) 2024 VRULL GmbH
58
+ * Copyright (c) 2022 Wind River Systems, Inc.
59
+ *
60
+ * Author:
61
+ * Bin Meng <bin.meng@windriver.com>
80
+ *
62
+ *
81
+ * This program is free software; you can redistribute it and/or modify it
63
+ * This program is free software; you can redistribute it and/or modify it
82
+ * under the terms and conditions of the GNU General Public License,
64
+ * under the terms and conditions of the GNU General Public License,
83
+ * version 2 or later, as published by the Free Software Foundation.
65
+ * version 2 or later, as published by the Free Software Foundation.
84
+ *
66
+ *
...
...
89
+ *
71
+ *
90
+ * You should have received a copy of the GNU General Public License along with
72
+ * You should have received a copy of the GNU General Public License along with
91
+ * this program. If not, see <http://www.gnu.org/licenses/>.
73
+ * this program. If not, see <http://www.gnu.org/licenses/>.
92
+ */
74
+ */
93
+
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
+
94
+#include "qemu/osdep.h"
194
+#include "qemu/osdep.h"
195
+#include "qemu/log.h"
196
+#include "qapi/error.h"
95
+#include "cpu.h"
197
+#include "cpu.h"
96
+#include "cpu_vendorid.h"
198
+#include "trace.h"
97
+
199
+#include "exec/exec-all.h"
98
+#define CSR_TH_SXSTATUS 0x5c0
200
+
99
+
201
+/*
100
+/* TH_SXSTATUS bits */
202
+ * The following M-mode trigger CSRs are implemented:
101
+#define TH_SXSTATUS_UCME BIT(16)
203
+ *
102
+#define TH_SXSTATUS_MAEE BIT(21)
204
+ * - tselect
103
+#define TH_SXSTATUS_THEADISAEE BIT(22)
205
+ * - tdata1
104
+
206
+ * - tdata2
105
+typedef struct {
207
+ * - tdata3
106
+ int csrno;
208
+ *
107
+ int (*insertion_test)(RISCVCPU *cpu);
209
+ * We don't support writable 'type' field in the tdata1 register, so there is
108
+ riscv_csr_operations csr_ops;
210
+ * no need to implement the "tinfo" CSR.
109
+} riscv_csr;
211
+ *
110
+
212
+ * The following triggers are implemented:
111
+static RISCVException smode(CPURISCVState *env, int csrno)
213
+ *
112
+{
214
+ * Index | Type | tdata mapping | Description
113
+ if (riscv_has_ext(env, RVS)) {
215
+ * ------+------+------------------------+------------
114
+ return RISCV_EXCP_NONE;
216
+ * 0 | 2 | tdata1, tdata2 | Address / Data Match
115
+ }
217
+ * 1 | 2 | tdata1, tdata2 | Address / Data Match
116
+
218
+ */
117
+ return RISCV_EXCP_ILLEGAL_INST;
219
+
118
+}
220
+/* tdata availability of a trigger */
119
+
221
+typedef bool tdata_avail[TDATA_NUM];
120
+static int test_thead_mvendorid(RISCVCPU *cpu)
222
+
121
+{
223
+static tdata_avail tdata_mapping[TRIGGER_NUM] = {
122
+ if (cpu->cfg.mvendorid != THEAD_VENDOR_ID) {
224
+ [TRIGGER_TYPE2_IDX_0 ... TRIGGER_TYPE2_IDX_1] = { true, true, false },
123
+ return -1;
225
+};
124
+ }
226
+
125
+
227
+/* only breakpoint size 1/2/4/8 supported */
126
+ return 0;
228
+static int access_size[SIZE_NUM] = {
127
+}
229
+ [SIZE_ANY] = 0,
128
+
230
+ [SIZE_1B] = 1,
129
+static RISCVException read_th_sxstatus(CPURISCVState *env, int csrno,
231
+ [SIZE_2B] = 2,
130
+ target_ulong *val)
232
+ [SIZE_4B] = 4,
131
+{
233
+ [SIZE_6B] = -1,
132
+ /* We don't set MAEE here, because QEMU does not implement MAEE. */
234
+ [SIZE_8B] = 8,
133
+ *val = TH_SXSTATUS_UCME | TH_SXSTATUS_THEADISAEE;
235
+ [6 ... 15] = -1,
134
+ return RISCV_EXCP_NONE;
236
+};
135
+}
237
+
136
+
238
+static inline target_ulong trigger_type(CPURISCVState *env,
137
+static riscv_csr th_csr_list[] = {
239
+ trigger_type_t type)
138
+ {
240
+{
139
+ .csrno = CSR_TH_SXSTATUS,
241
+ target_ulong tdata1;
140
+ .insertion_test = test_thead_mvendorid,
242
+
141
+ .csr_ops = { "th.sxstatus", smode, read_th_sxstatus }
243
+ switch (riscv_cpu_mxl(env)) {
142
+ }
244
+ case MXL_RV32:
143
+};
245
+ tdata1 = RV32_TYPE(type);
144
+
246
+ break;
145
+void th_register_custom_csrs(RISCVCPU *cpu)
247
+ case MXL_RV64:
146
+{
248
+ tdata1 = RV64_TYPE(type);
147
+ for (size_t i = 0; i < ARRAY_SIZE(th_csr_list); i++) {
249
+ break;
148
+ int csrno = th_csr_list[i].csrno;
250
+ default:
149
+ riscv_csr_operations *csr_ops = &th_csr_list[i].csr_ops;
251
+ g_assert_not_reached();
150
+ if (!th_csr_list[i].insertion_test(cpu)) {
252
+ }
151
+ riscv_set_csr_ops(csrno, csr_ops);
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);
152
+ }
368
+ }
153
+ }
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);
154
+}
507
+}
155
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
508
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
156
index XXXXXXX..XXXXXXX 100644
509
index XXXXXXX..XXXXXXX 100644
157
--- a/target/riscv/meson.build
510
--- a/target/riscv/meson.build
158
+++ b/target/riscv/meson.build
511
+++ b/target/riscv/meson.build
159
@@ -XXX,XX +XXX,XX @@ riscv_system_ss.add(files(
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',
160
'monitor.c',
517
'monitor.c',
161
'machine.c',
518
'machine.c'
162
'pmu.c',
163
+ 'th_csr.c',
164
'time_helper.c',
165
'riscv-qmp-cmds.c',
166
))
519
))
167
--
520
--
168
2.45.1
521
2.35.1
169
170
diff view generated by jsdifflib
1
From: Max Chou <max.chou@sifive.com>
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
2
2
3
If the checking functions check both the single and double width
3
for some cases, scale is always equal or less than 0, since lmul is not larger than 3
4
operators at the same time, then the single width operator checking
5
functions (require_rvf[min]) will check whether the SEW is 8.
6
4
7
Signed-off-by: Max Chou <max.chou@sifive.com>
5
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
6
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
9
Cc: qemu-stable <qemu-stable@nongnu.org>
7
Reviewed-by: Frank Chang <frank.chang@sifive.com>
10
Message-ID: <20240322092600.1198921-5-max.chou@sifive.com>
8
Acked-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-Id: <20220325085902.29500-1-liweiwei@iscas.ac.cn>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
11
---
13
target/riscv/insn_trans/trans_rvv.c.inc | 16 ++++------------
12
target/riscv/insn_trans/trans_rvv.c.inc | 8 +++-----
14
1 file changed, 4 insertions(+), 12 deletions(-)
13
1 file changed, 3 insertions(+), 5 deletions(-)
15
14
16
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
15
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/insn_trans/trans_rvv.c.inc
17
--- a/target/riscv/insn_trans/trans_rvv.c.inc
19
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
18
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
20
@@ -XXX,XX +XXX,XX @@ static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
19
@@ -XXX,XX +XXX,XX @@ GEN_LDST_WHOLE_TRANS(vs8r_v, 8, true)
21
return require_rvv(s) &&
20
static inline uint32_t MAXSZ(DisasContext *s)
22
require_rvf(s) &&
21
{
23
require_scale_rvf(s) &&
22
int scale = s->lmul - 3;
24
- (s->sew != MO_8) &&
23
- return scale < 0 ? s->cfg_ptr->vlen >> -scale : s->cfg_ptr->vlen << scale;
25
vext_check_isa_ill(s) &&
24
+ return s->cfg_ptr->vlen >> -scale;
26
vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm);
27
}
25
}
28
@@ -XXX,XX +XXX,XX @@ static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
26
29
return require_rvv(s) &&
27
static bool opivv_check(DisasContext *s, arg_rmrr *a)
30
require_rvf(s) &&
28
@@ -XXX,XX +XXX,XX @@ static bool trans_vrgather_vx(DisasContext *s, arg_rmrr *a)
31
require_scale_rvf(s) &&
29
32
- (s->sew != MO_8) &&
30
if (a->vm && s->vl_eq_vlmax) {
33
vext_check_isa_ill(s) &&
31
int scale = s->lmul - (s->sew + 3);
34
vext_check_ds(s, a->rd, a->rs2, a->vm);
32
- int vlmax = scale < 0 ?
35
}
33
- s->cfg_ptr->vlen >> -scale : s->cfg_ptr->vlen << scale;
36
@@ -XXX,XX +XXX,XX @@ static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
34
+ int vlmax = s->cfg_ptr->vlen >> -scale;
37
return require_rvv(s) &&
35
TCGv_i64 dest = tcg_temp_new_i64();
38
require_rvf(s) &&
36
39
require_scale_rvf(s) &&
37
if (a->rs1 == 0) {
40
- (s->sew != MO_8) &&
38
@@ -XXX,XX +XXX,XX @@ static bool trans_vrgather_vi(DisasContext *s, arg_rmrr *a)
41
vext_check_isa_ill(s) &&
39
42
vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm);
40
if (a->vm && s->vl_eq_vlmax) {
43
}
41
int scale = s->lmul - (s->sew + 3);
44
@@ -XXX,XX +XXX,XX @@ static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
42
- int vlmax = scale < 0 ?
45
return require_rvv(s) &&
43
- s->cfg_ptr->vlen >> -scale : s->cfg_ptr->vlen << scale;
46
require_rvf(s) &&
44
+ int vlmax = s->cfg_ptr->vlen >> -scale;
47
require_scale_rvf(s) &&
45
if (a->rs1 >= vlmax) {
48
- (s->sew != MO_8) &&
46
tcg_gen_gvec_dup_imm(MO_64, vreg_ofs(s, a->rd),
49
vext_check_isa_ill(s) &&
47
MAXSZ(s), MAXSZ(s), 0);
50
vext_check_dd(s, a->rd, a->rs2, a->vm);
51
}
52
@@ -XXX,XX +XXX,XX @@ static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
53
{
54
return opfv_widen_check(s, a) &&
55
require_rvfmin(s) &&
56
- require_scale_rvfmin(s) &&
57
- (s->sew != MO_8);
58
+ require_scale_rvfmin(s);
59
}
60
61
#define GEN_OPFV_WIDEN_TRANS(NAME, CHECK, HELPER, FRM) \
62
@@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
63
{
64
return opfv_narrow_check(s, a) &&
65
require_rvfmin(s) &&
66
- require_scale_rvfmin(s) &&
67
- (s->sew != MO_8);
68
+ require_scale_rvfmin(s);
69
}
70
71
static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
72
{
73
return opfv_narrow_check(s, a) &&
74
require_rvf(s) &&
75
- require_scale_rvf(s) &&
76
- (s->sew != MO_8);
77
+ require_scale_rvf(s);
78
}
79
80
#define GEN_OPFV_NARROW_TRANS(NAME, CHECK, HELPER, FRM) \
81
@@ -XXX,XX +XXX,XX @@ static bool freduction_widen_check(DisasContext *s, arg_rmrr *a)
82
{
83
return reduction_widen_check(s, a) &&
84
require_rvf(s) &&
85
- require_scale_rvf(s) &&
86
- (s->sew != MO_8);
87
+ require_scale_rvf(s);
88
}
89
90
GEN_OPFVV_WIDEN_TRANS(vfwredusum_vs, freduction_widen_check)
91
--
48
--
92
2.45.1
49
2.35.1
diff view generated by jsdifflib
1
From: Max Chou <max.chou@sifive.com>
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
2
2
3
The require_scale_rvf function only checks the double width operator for
3
LEN is not used for GEN_VEXT_VMV_WHOLE macro, so vmv<nr>r.v can share
4
the vector floating point widen instructions, so most of the widen
4
the same helper
5
checking functions need to add require_rvf for single width operator.
6
5
7
The vfwcvt.f.x.v and vfwcvt.f.xu.v instructions convert single width
6
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
8
integer to double width float, so the opfxv_widen_check function doesn’t
7
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
9
need require_rvf for the single width operator(integer).
8
Reviewed-by: Frank Chang <frank.chang@sifive.com>
10
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Max Chou <max.chou@sifive.com>
10
Message-Id: <20220325085902.29500-2-liweiwei@iscas.ac.cn>
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Message-ID: <20240322092600.1198921-3-max.chou@sifive.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
12
---
17
target/riscv/insn_trans/trans_rvv.c.inc | 5 +++++
13
target/riscv/helper.h | 5 +----
18
1 file changed, 5 insertions(+)
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(-)
19
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) \
20
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
75
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
21
index XXXXXXX..XXXXXXX 100644
76
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/insn_trans/trans_rvv.c.inc
77
--- a/target/riscv/insn_trans/trans_rvv.c.inc
23
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
78
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
24
@@ -XXX,XX +XXX,XX @@ GEN_OPFVF_TRANS(vfrsub_vf, opfvf_check)
79
@@ -XXX,XX +XXX,XX @@ static bool trans_vcompress_vm(DisasContext *s, arg_r *a)
25
static bool opfvv_widen_check(DisasContext *s, arg_rmrr *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)
26
{
117
{
27
return require_rvv(s) &&
28
+ require_rvf(s) &&
29
require_scale_rvf(s) &&
30
(s->sew != MO_8) &&
31
vext_check_isa_ill(s) &&
32
@@ -XXX,XX +XXX,XX @@ GEN_OPFVV_WIDEN_TRANS(vfwsub_vv, opfvv_widen_check)
33
static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
34
{
35
return require_rvv(s) &&
36
+ require_rvf(s) &&
37
require_scale_rvf(s) &&
38
(s->sew != MO_8) &&
39
vext_check_isa_ill(s) &&
40
@@ -XXX,XX +XXX,XX @@ GEN_OPFVF_WIDEN_TRANS(vfwsub_vf)
41
static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
42
{
43
return require_rvv(s) &&
44
+ require_rvf(s) &&
45
require_scale_rvf(s) &&
46
(s->sew != MO_8) &&
47
vext_check_isa_ill(s) &&
48
@@ -XXX,XX +XXX,XX @@ GEN_OPFWV_WIDEN_TRANS(vfwsub_wv)
49
static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
50
{
51
return require_rvv(s) &&
52
+ require_rvf(s) &&
53
require_scale_rvf(s) &&
54
(s->sew != MO_8) &&
55
vext_check_isa_ill(s) &&
56
@@ -XXX,XX +XXX,XX @@ GEN_OPFVV_TRANS(vfredmin_vs, freduction_check)
57
static bool freduction_widen_check(DisasContext *s, arg_rmrr *a)
58
{
59
return reduction_widen_check(s, a) &&
60
+ require_rvf(s) &&
61
require_scale_rvf(s) &&
62
(s->sew != MO_8);
63
}
64
--
118
--
65
2.45.1
119
2.35.1
66
67
diff view generated by jsdifflib
1
From: Rob Bradford <rbradford@rivosinc.com>
1
From: Tsukasa OI <research_trasio@irq.a4lg.com>
2
2
3
This extension has now been ratified:
3
Some bits in RISC-V `misa' CSR should not be reflected in the ISA
4
https://jira.riscv.org/browse/RVS-2006 so the "x-" prefix can be
4
string. For instance, `S' and `U' (represents existence of supervisor
5
removed.
5
and user mode, respectively) in `misa' CSR must not be copied since
6
neither `S' nor `U' are valid single-letter extensions.
6
7
7
Since this is now a ratified extension add it to the list of extensions
8
This commit also removes all reserved/dropped single-letter "extensions"
8
included in the "max" CPU variant.
9
from the list.
9
10
10
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
11
- "B": Not going to be a single-letter extension (misa.B is reserved).
11
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
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>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
22
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
23
Message-Id: <4a4c11213a161a7eedabe46abe58b351bb0e2ef2.1648473008.git.research_trasio@irq.a4lg.com>
14
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
15
Message-ID: <20240514110217.22516-1-rbradford@rivosinc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
25
---
18
target/riscv/cpu.c | 2 +-
26
target/riscv/cpu.c | 10 +++++-----
19
target/riscv/tcg/tcg-cpu.c | 2 +-
27
1 file changed, 5 insertions(+), 5 deletions(-)
20
2 files changed, 2 insertions(+), 2 deletions(-)
21
28
22
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
29
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
23
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
24
--- a/target/riscv/cpu.c
31
--- a/target/riscv/cpu.c
25
+++ b/target/riscv/cpu.c
32
+++ b/target/riscv/cpu.c
26
@@ -XXX,XX +XXX,XX @@ static const MISAExtInfo misa_ext_info_arr[] = {
33
@@ -XXX,XX +XXX,XX @@
27
MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"),
34
28
MISA_EXT_INFO(RVV, "v", "Vector operations"),
35
/* RISC-V CPU definitions */
29
MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"),
36
30
- MISA_EXT_INFO(RVB, "x-b", "Bit manipulation (Zba_Zbb_Zbs)")
37
-static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
31
+ MISA_EXT_INFO(RVB, "b", "Bit manipulation (Zba_Zbb_Zbs)")
38
+static const char riscv_single_letter_exts[] = "IEMAFDQCPVH";
32
};
39
33
40
const char * const riscv_int_regnames[] = {
34
static void riscv_cpu_validate_misa_mxl(RISCVCPUClass *mcc)
41
"x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1",
35
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
42
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
36
index XXXXXXX..XXXXXXX 100644
43
char *riscv_isa_string(RISCVCPU *cpu)
37
--- a/target/riscv/tcg/tcg-cpu.c
44
{
38
+++ b/target/riscv/tcg/tcg-cpu.c
45
int i;
39
@@ -XXX,XX +XXX,XX @@ static void riscv_init_max_cpu_extensions(Object *obj)
46
- const size_t maxlen = sizeof("rv128") + sizeof(riscv_exts) + 1;
40
const RISCVCPUMultiExtConfig *prop;
47
+ const size_t maxlen = sizeof("rv128") + sizeof(riscv_single_letter_exts);
41
48
char *isa_str = g_new(char, maxlen);
42
/* Enable RVG, RVJ and RVV that are disabled by default */
49
char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", TARGET_LONG_BITS);
43
- riscv_cpu_set_misa_ext(env, env->misa_ext | RVG | RVJ | RVV);
50
- for (i = 0; i < sizeof(riscv_exts); i++) {
44
+ riscv_cpu_set_misa_ext(env, env->misa_ext | RVB | RVG | RVJ | RVV);
51
- if (cpu->env.misa_ext & RV(riscv_exts[i])) {
45
52
- *p++ = qemu_tolower(riscv_exts[i]);
46
for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
53
+ for (i = 0; i < sizeof(riscv_single_letter_exts) - 1; i++) {
47
isa_ext_update_enabled(cpu, prop->offset, true);
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';
48
--
59
--
49
2.45.1
60
2.35.1
diff view generated by jsdifflib
1
From: Max Chou <max.chou@sifive.com>
1
From: Atish Patra <atishp@rivosinc.com>
2
2
3
According v spec 18.4, only the vfwcvt.f.f.v and vfncvt.f.f.w
3
The Linux kernel parses the ISA extensions from "riscv,isa" DT
4
instructions will be affected by Zvfhmin extension.
4
property. It used to parse only the single letter base extensions
5
And the vfwcvt.f.f.v and vfncvt.f.f.w instructions only support the
5
until now. A generic ISA extension parsing framework was proposed[1]
6
conversions of
6
recently that can parse multi-letter ISA extensions as well.
7
7
8
* From 1*SEW(16/32) to 2*SEW(32/64)
8
Generate the extended ISA string by appending the available ISA extensions
9
* From 2*SEW(32/64) to 1*SEW(16/32)
9
to the "riscv,isa" string if it is enabled so that kernel can process it.
10
10
11
Signed-off-by: Max Chou <max.chou@sifive.com>
11
[1] https://lkml.org/lkml/2022/2/15/263
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
12
13
Cc: qemu-stable <qemu-stable@nongnu.org>
13
Reviewed-by: Anup Patel <anup@brainfault.org>
14
Message-ID: <20240322092600.1198921-2-max.chou@sifive.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
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>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
23
---
17
target/riscv/insn_trans/trans_rvv.c.inc | 20 ++++++++++++++++++--
24
target/riscv/cpu.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++
18
1 file changed, 18 insertions(+), 2 deletions(-)
25
1 file changed, 60 insertions(+)
19
26
20
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
27
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
21
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/insn_trans/trans_rvv.c.inc
29
--- a/target/riscv/cpu.c
23
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
30
+++ b/target/riscv/cpu.c
24
@@ -XXX,XX +XXX,XX @@ static bool require_rvf(DisasContext *s)
31
@@ -XXX,XX +XXX,XX @@
25
}
32
33
static const char riscv_single_letter_exts[] = "IEMAFDQCPVH";
34
35
+struct isa_ext_data {
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);
26
}
45
}
27
46
28
+static bool require_rvfmin(DisasContext *s)
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)
29
+{
50
+{
30
+ if (s->mstatus_fs == EXT_STATUS_DISABLED) {
51
+ char *old = *isa_str;
31
+ return false;
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
+ }
32
+ }
96
+ }
33
+
97
+
34
+ switch (s->sew) {
98
+ *isa_str = new;
35
+ case MO_16:
36
+ return s->cfg_ptr->ext_zvfhmin;
37
+ case MO_32:
38
+ return s->cfg_ptr->ext_zve32f;
39
+ default:
40
+ return false;
41
+ }
42
+}
99
+}
43
+
100
+
44
static bool require_scale_rvf(DisasContext *s)
101
char *riscv_isa_string(RISCVCPU *cpu)
45
{
102
{
46
if (s->mstatus_fs == EXT_STATUS_DISABLED) {
103
int i;
47
@@ -XXX,XX +XXX,XX @@ static bool require_scale_rvfmin(DisasContext *s)
104
@@ -XXX,XX +XXX,XX @@ char *riscv_isa_string(RISCVCPU *cpu)
105
}
48
}
106
}
49
107
*p = '\0';
50
switch (s->sew) {
108
+ riscv_isa_string_ext(cpu, &isa_str, maxlen);
51
- case MO_8:
109
return isa_str;
52
- return s->cfg_ptr->ext_zvfhmin;
53
case MO_16:
54
return s->cfg_ptr->ext_zve32f;
55
case MO_32:
56
@@ -XXX,XX +XXX,XX @@ static bool opxfv_widen_check(DisasContext *s, arg_rmr *a)
57
static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
58
{
59
return opfv_widen_check(s, a) &&
60
+ require_rvfmin(s) &&
61
require_scale_rvfmin(s) &&
62
(s->sew != MO_8);
63
}
110
}
64
@@ -XXX,XX +XXX,XX @@ static bool opfxv_narrow_check(DisasContext *s, arg_rmr *a)
111
65
static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
66
{
67
return opfv_narrow_check(s, a) &&
68
+ require_rvfmin(s) &&
69
require_scale_rvfmin(s) &&
70
(s->sew != MO_8);
71
}
72
--
112
--
73
2.45.1
113
2.35.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
2
2
3
Running a KVM guest using a 6.9-rc3 kernel, in a 6.8 host that has zkr
3
The spec for vmv<nf>r.v says: 'the instructions operate as if EEW=SEW,
4
enabled, will fail with a kernel oops SIGILL right at the start. The
4
EMUL = NREG, effective length evl= EMUL * VLEN/SEW.'
5
reason is that we can't expose zkr without implementing the SEED CSR.
6
Disabling zkr in the guest would be a workaround, but if the KVM doesn't
7
allow it we'll error out and never boot.
8
5
9
In hindsight this is too strict. If we keep proceeding, despite not
6
So the start byte for vstart != 0 should take sew into account
10
disabling the extension in the KVM vcpu, we'll not add the extension in
11
the riscv,isa. The guest kernel will be unaware of the extension, i.e.
12
it doesn't matter if the KVM vcpu has it enabled underneath or not. So
13
it's ok to keep booting in this case.
14
7
15
Change our current logic to not error out if we fail to disable an
8
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
16
extension in kvm_set_one_reg(), but show a warning and keep booting. It
9
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
17
is important to throw a warning because we must make the user aware that
10
Acked-by: Alistair Francis <alistair.francis@wdc.com>
18
the extension is still available in the vcpu, meaning that an
11
Message-Id: <20220330021316.18223-1-liweiwei@iscas.ac.cn>
19
ill-behaved guest can ignore the riscv,isa settings and use the
20
extension.
21
22
The case we're handling happens with an EINVAL error code. If we fail to
23
disable the extension in KVM for any other reason, error out.
24
25
We'll also keep erroring out when we fail to enable an extension in KVM,
26
since adding the extension in riscv,isa at this point will cause a guest
27
malfunction because the extension isn't enabled in the vcpu.
28
29
Suggested-by: Andrew Jones <ajones@ventanamicro.com>
30
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
31
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
32
Cc: qemu-stable <qemu-stable@nongnu.org>
33
Message-ID: <20240422171425.333037-2-dbarboza@ventanamicro.com>
34
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
35
---
13
---
36
target/riscv/kvm/kvm-cpu.c | 12 ++++++++----
14
target/riscv/vector_helper.c | 8 +++++---
37
1 file changed, 8 insertions(+), 4 deletions(-)
15
1 file changed, 5 insertions(+), 3 deletions(-)
38
16
39
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
17
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
40
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
41
--- a/target/riscv/kvm/kvm-cpu.c
19
--- a/target/riscv/vector_helper.c
42
+++ b/target/riscv/kvm/kvm-cpu.c
20
+++ b/target/riscv/vector_helper.c
43
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
21
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_VCOMPRESS_VM(vcompress_vm_d, uint64_t, H8)
44
reg = kvm_cpu_cfg_get(cpu, multi_ext_cfg);
22
/* Vector Whole Register Move */
45
ret = kvm_set_one_reg(cs, id, &reg);
23
void HELPER(vmvr_v)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc)
46
if (ret != 0) {
24
{
47
- error_report("Unable to %s extension %s in KVM, error %d",
25
- /* EEW = 8 */
48
- reg ? "enable" : "disable",
26
+ /* EEW = SEW */
49
- multi_ext_cfg->name, ret);
27
uint32_t maxsz = simd_maxsz(desc);
50
- exit(EXIT_FAILURE);
28
- uint32_t i = env->vstart;
51
+ if (!reg && ret == -EINVAL) {
29
+ uint32_t sewb = 1 << FIELD_EX64(env->vtype, VTYPE, VSEW);
52
+ warn_report("KVM cannot disable extension %s",
30
+ uint32_t startb = env->vstart * sewb;
53
+ multi_ext_cfg->name);
31
+ uint32_t i = startb;
54
+ } else {
32
55
+ error_report("Unable to enable extension %s in KVM, error %d",
33
memcpy((uint8_t *)vd + H1(i),
56
+ multi_ext_cfg->name, ret);
34
(uint8_t *)vs2 + H1(i),
57
+ exit(EXIT_FAILURE);
35
- maxsz - env->vstart);
58
+ }
36
+ maxsz - startb);
59
}
37
60
}
38
env->vstart = 0;
61
}
39
}
62
--
40
--
63
2.45.1
41
2.35.1
diff view generated by jsdifflib
1
From: Alexei Filippov <alexei.filippov@syntacore.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Previous patch fixed the PMP priority in raise_mmu_exception() but we're still
3
The riscv_raise_exception function stores its argument into
4
setting mtval2 incorrectly. In riscv_cpu_tlb_fill(), after pmp check in 2 stage
4
exception_index and then exits to the main loop. When we
5
translation part, mtval2 will be set in case of successes 2 stage translation but
5
have already set exception_index, we can just exit directly.
6
failed pmp check.
7
6
8
In this case we gonna set mtval2 via env->guest_phys_fault_addr in context of
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
riscv_cpu_tlb_fill(), as this was a guest-page-fault, but it didn't and mtval2
10
should be zero, according to RISCV privileged spec sect. 9.4.4: When a guest
11
page-fault is taken into M-mode, mtval2 is written with either zero or guest
12
physical address that faulted, shifted by 2 bits. *For other traps, mtval2
13
is set to zero...*
14
15
Signed-off-by: Alexei Filippov <alexei.filippov@syntacore.com>
16
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Message-ID: <20240503103052.6819-1-alexei.filippov@syntacore.com>
9
Message-Id: <20220401125948.79292-2-richard.henderson@linaro.org>
19
Cc: qemu-stable <qemu-stable@nongnu.org>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
---
11
---
22
target/riscv/cpu_helper.c | 12 ++++++------
12
target/riscv/cpu_helper.c | 6 +++---
23
1 file changed, 6 insertions(+), 6 deletions(-)
13
1 file changed, 3 insertions(+), 3 deletions(-)
24
14
25
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
15
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
26
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
27
--- a/target/riscv/cpu_helper.c
17
--- a/target/riscv/cpu_helper.c
28
+++ b/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,
29
@@ -XXX,XX +XXX,XX @@ 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,
30
__func__, pa, ret, prot_pmp, tlb_size);
38
first_stage_error,
31
39
riscv_cpu_virt_enabled(env) ||
32
prot &= prot_pmp;
40
riscv_cpu_two_stage_lookup(mmu_idx));
33
- }
41
- riscv_raise_exception(env, cs->exception_index, retaddr);
34
-
42
+ cpu_loop_exit_restore(cs, retaddr);
35
- if (ret != TRANSLATE_SUCCESS) {
43
}
36
+ } else {
44
37
/*
45
return true;
38
* Guest physical address translation failed, this is a HS
39
* level exception
40
*/
41
first_stage_error = false;
42
- env->guest_phys_fault_addr = (im_address |
43
- (address &
44
- (TARGET_PAGE_SIZE - 1))) >> 2;
45
+ if (ret != TRANSLATE_PMP_FAIL) {
46
+ env->guest_phys_fault_addr = (im_address |
47
+ (address &
48
+ (TARGET_PAGE_SIZE - 1))) >> 2;
49
+ }
50
}
51
}
52
} else {
53
--
46
--
54
2.45.1
47
2.35.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Ralf Ramsauer <ralf.ramsauer@oth-regensburg.de>
2
2
3
Commit 33a24910ae changed 'reg_width' to use 'vlenb', i.e. vector length
3
The -bios option is silently ignored if used in combination with -enable-kvm.
4
in bytes, when in this context we want 'reg_width' as the length in
4
The reason is that the machine starts in S-Mode, and the bios typically runs in
5
bits.
5
M-Mode.
6
6
7
Fix 'reg_width' back to the value in bits like 7cb59921c05a
7
Better exit in that case to not confuse the user.
8
("target/riscv/gdbstub.c: use 'vlenb' instead of shifting 'vlen'") set
9
beforehand.
10
8
11
While we're at it, rename 'reg_width' to 'bitsize' to provide a bit more
9
Signed-off-by: Ralf Ramsauer <ralf.ramsauer@oth-regensburg.de>
12
clarity about what the variable represents. 'bitsize' is also used in
13
riscv_gen_dynamic_csr_feature() with the same purpose, i.e. as an input to
14
gdb_feature_builder_append_reg().
15
16
Cc: Akihiko Odaki <akihiko.odaki@daynix.com>
17
Cc: Alex Bennée <alex.bennee@linaro.org>
18
Reported-by: Robin Dapp <rdapp.gcc@gmail.com>
19
Fixes: 33a24910ae ("target/riscv: Use GDBFeature for dynamic XML")
20
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
21
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
22
Acked-by: Alex Bennée <alex.bennee@linaro.org>
23
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
24
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
25
Cc: qemu-stable <qemu-stable@nongnu.org>
11
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
26
Message-ID: <20240517203054.880861-2-dbarboza@ventanamicro.com>
12
Reviewed-by: Anup Patel <anup@brainfault.org>
13
Message-Id: <20220401121842.2791796-1-ralf.ramsauer@oth-regensburg.de>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
---
15
---
29
target/riscv/gdbstub.c | 6 +++---
16
hw/riscv/virt.c | 14 ++++++++++----
30
1 file changed, 3 insertions(+), 3 deletions(-)
17
1 file changed, 10 insertions(+), 4 deletions(-)
31
18
32
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
19
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
33
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/gdbstub.c
21
--- a/hw/riscv/virt.c
35
+++ b/target/riscv/gdbstub.c
22
+++ b/hw/riscv/virt.c
36
@@ -XXX,XX +XXX,XX @@ static GDBFeature *riscv_gen_dynamic_csr_feature(CPUState *cs, int base_reg)
23
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
37
static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
24
38
{
25
/*
39
RISCVCPU *cpu = RISCV_CPU(cs);
26
* Only direct boot kernel is currently supported for KVM VM,
40
- int reg_width = cpu->cfg.vlenb;
27
- * so the "-bios" parameter is ignored and treated like "-bios none"
41
+ int bitsize = cpu->cfg.vlenb << 3;
28
- * when KVM is enabled.
42
GDBFeatureBuilder builder;
29
+ * so the "-bios" parameter is not supported when KVM is enabled.
43
int i;
30
*/
44
31
if (kvm_enabled()) {
45
@@ -XXX,XX +XXX,XX @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
32
- g_free(machine->firmware);
46
33
- machine->firmware = g_strdup("none");
47
/* First define types and totals in a whole VL */
34
+ if (machine->firmware) {
48
for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
35
+ if (strcmp(machine->firmware, "none")) {
49
- int count = reg_width / vec_lanes[i].size;
36
+ error_report("Machine mode firmware is not supported in "
50
+ int count = bitsize / vec_lanes[i].size;
37
+ "combination with KVM.");
51
gdb_feature_builder_append_tag(
38
+ exit(1);
52
&builder, "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
39
+ }
53
vec_lanes[i].id, vec_lanes[i].gdb_type, count);
40
+ } else {
54
@@ -XXX,XX +XXX,XX @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
41
+ machine->firmware = g_strdup("none");
55
/* Define vector registers */
42
+ }
56
for (i = 0; i < 32; i++) {
57
gdb_feature_builder_append_reg(&builder, g_strdup_printf("v%d", i),
58
- reg_width, i, "riscv_vector", "vector");
59
+ bitsize, i, "riscv_vector", "vector");
60
}
43
}
61
44
62
gdb_feature_builder_end(&builder);
45
if (riscv_is_32bit(&s->soc[0])) {
63
--
46
--
64
2.45.1
47
2.35.1
65
66
diff view generated by jsdifflib
1
From: Alistair Francis <alistair23@gmail.com>
1
From: Nicolas Pitre <nico@fluxnic.net>
2
2
3
When running the instruction
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.
4
6
5
```
7
Fix that by simplifying the computation. There is in fact no need for
6
cbo.flush 0(x0)
8
ctz64() nor special case for -1 to achieve proper results.
7
```
8
9
9
QEMU would segfault.
10
Signed-off-by: Nicolas Pitre <nico@fluxnic.net>
10
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
The issue was in cpu_gpr[a->rs1] as QEMU does not have cpu_gpr[0]
12
Message-Id: <rq81o86n-17ps-92no-p65o-79o88476266@syhkavp.arg>
12
allocated.
13
14
In order to fix this let's use the existing get_address()
15
helper. This also has the benefit of performing pointer mask
16
calculations on the address specified in rs1.
17
18
The pointer masking specificiation specifically states:
19
20
"""
21
Cache Management Operations: All instructions in Zicbom, Zicbop and Zicboz
22
"""
23
24
So this is the correct behaviour and we previously have been incorrectly
25
not masking the address.
26
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
Reported-by: Fabian Thomas <fabian.thomas@cispa.de>
29
Fixes: e05da09b7cfd ("target/riscv: implement Zicbom extension")
30
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
31
Cc: qemu-stable <qemu-stable@nongnu.org>
32
Message-ID: <20240514023910.301766-1-alistair.francis@wdc.com>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
34
---
14
---
35
target/riscv/insn_trans/trans_rvzicbo.c.inc | 16 ++++++++++++----
15
target/riscv/pmp.c | 14 +++-----------
36
1 file changed, 12 insertions(+), 4 deletions(-)
16
1 file changed, 3 insertions(+), 11 deletions(-)
37
17
38
diff --git a/target/riscv/insn_trans/trans_rvzicbo.c.inc b/target/riscv/insn_trans/trans_rvzicbo.c.inc
18
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
39
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/insn_trans/trans_rvzicbo.c.inc
20
--- a/target/riscv/pmp.c
41
+++ b/target/riscv/insn_trans/trans_rvzicbo.c.inc
21
+++ b/target/riscv/pmp.c
42
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ static void pmp_decode_napot(target_ulong a, target_ulong *sa, target_ulong *ea)
43
static bool trans_cbo_clean(DisasContext *ctx, arg_cbo_clean *a)
23
0111...1111 2^(XLEN+2)-byte NAPOT range
44
{
24
1111...1111 Reserved
45
REQUIRE_ZICBOM(ctx);
25
*/
46
- gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
26
- if (a == -1) {
47
+ TCGv src = get_address(ctx, a->rs1, 0);
27
- *sa = 0u;
48
+
28
- *ea = -1;
49
+ gen_helper_cbo_clean_flush(tcg_env, src);
29
- return;
50
return true;
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);
51
}
40
}
52
41
53
static bool trans_cbo_flush(DisasContext *ctx, arg_cbo_flush *a)
42
void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index)
54
{
55
REQUIRE_ZICBOM(ctx);
56
- gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
57
+ TCGv src = get_address(ctx, a->rs1, 0);
58
+
59
+ gen_helper_cbo_clean_flush(tcg_env, src);
60
return true;
61
}
62
63
static bool trans_cbo_inval(DisasContext *ctx, arg_cbo_inval *a)
64
{
65
REQUIRE_ZICBOM(ctx);
66
- gen_helper_cbo_inval(tcg_env, cpu_gpr[a->rs1]);
67
+ TCGv src = get_address(ctx, a->rs1, 0);
68
+
69
+ gen_helper_cbo_inval(tcg_env, src);
70
return true;
71
}
72
73
static bool trans_cbo_zero(DisasContext *ctx, arg_cbo_zero *a)
74
{
75
REQUIRE_ZICBOZ(ctx);
76
- gen_helper_cbo_zero(tcg_env, cpu_gpr[a->rs1]);
77
+ TCGv src = get_address(ctx, a->rs1, 0);
78
+
79
+ gen_helper_cbo_zero(tcg_env, src);
80
return true;
81
}
82
--
43
--
83
2.45.1
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
1
From: Huang Tao <eric.huang@linux.alibaba.com>
1
From: Frank Chang <frank.chang@sifive.com>
2
2
3
In RVV and vcrypto instructions, the masked and tail elements are set to 1s
3
If device's MemoryRegion doesn't have .impl.[min|max]_access_size
4
using vext_set_elems_1s function if the vma/vta bit is set. It is the element
4
declaration, the default access_size_min would be 1 byte and
5
agnostic policy.
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.
6
8
7
However, this function can't deal the big endian situation. This patch fixes
9
Signed-off-by: Frank Chang <frank.chang@sifive.com>
8
the problem by adding handling of such case.
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
11
Reviewed-by: Jim Shu <jim.shu@sifive.com>
10
Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
12
Message-Id: <20220420080901.14655-2-frank.chang@sifive.com>
11
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Message-ID: <20240325021654.6594-1-eric.huang@linux.alibaba.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
14
---
17
target/riscv/vector_internals.c | 22 ++++++++++++++++++++++
15
hw/intc/riscv_aclint.c | 4 ++++
18
1 file changed, 22 insertions(+)
16
1 file changed, 4 insertions(+)
19
17
20
diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
18
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
21
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/vector_internals.c
20
--- a/hw/intc/riscv_aclint.c
23
+++ b/target/riscv/vector_internals.c
21
+++ b/hw/intc/riscv_aclint.c
24
@@ -XXX,XX +XXX,XX @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
22
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps riscv_aclint_mtimer_ops = {
25
if (tot - cnt == 0) {
23
.valid = {
26
return ;
24
.min_access_size = 4,
25
.max_access_size = 8
26
+ },
27
+ .impl = {
28
+ .min_access_size = 4,
29
+ .max_access_size = 8,
27
}
30
}
28
+
31
};
29
+ if (HOST_BIG_ENDIAN) {
30
+ /*
31
+ * Deal the situation when the elements are insdie
32
+ * only one uint64 block including setting the
33
+ * masked-off element.
34
+ */
35
+ if (((tot - 1) ^ cnt) < 8) {
36
+ memset(base + H1(tot - 1), -1, tot - cnt);
37
+ return;
38
+ }
39
+ /*
40
+ * Otherwise, at least cross two uint64_t blocks.
41
+ * Set first unaligned block.
42
+ */
43
+ if (cnt % 8 != 0) {
44
+ uint32_t j = ROUND_UP(cnt, 8);
45
+ memset(base + H1(j - 1), -1, j - cnt);
46
+ cnt = j;
47
+ }
48
+ /* Set other 64bit aligend blocks */
49
+ }
50
memset(base + cnt, -1, tot - cnt);
51
}
52
32
53
--
33
--
54
2.45.1
34
2.35.1
diff view generated by jsdifflib
1
From: Alistair Francis <alistair23@gmail.com>
1
From: Frank Chang <frank.chang@sifive.com>
2
2
3
Previously we only listed a single pmpcfg CSR and the first 16 pmpaddr
3
RISC-V privilege spec defines that:
4
CSRs. This patch fixes this to list all 16 pmpcfg and all 64 pmpaddr
5
CSRs are part of the disassembly.
6
4
7
Reported-by: Eric DeVolder <eric_devolder@yahoo.com>
5
* In RV32, memory-mapped writes to mtimecmp modify only one 32-bit part
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
6
of the register.
9
Fixes: ea10325917 ("RISC-V Disassembler")
7
* For RV64, naturally aligned 64-bit memory accesses to the mtime and
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
mtimecmp registers are additionally supported and are atomic.
11
Cc: qemu-stable <qemu-stable@nongnu.org>
9
12
Message-ID: <20240514051615.330979-1-alistair.francis@wdc.com>
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>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
18
---
15
disas/riscv.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++-
19
hw/intc/riscv_aclint.c | 42 +++++++++++++++++++++++++++---------------
16
1 file changed, 64 insertions(+), 1 deletion(-)
20
1 file changed, 27 insertions(+), 15 deletions(-)
17
21
18
diff --git a/disas/riscv.c b/disas/riscv.c
22
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
19
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
20
--- a/disas/riscv.c
24
--- a/hw/intc/riscv_aclint.c
21
+++ b/disas/riscv.c
25
+++ b/hw/intc/riscv_aclint.c
22
@@ -XXX,XX +XXX,XX @@ static const char *csr_name(int csrno)
26
@@ -XXX,XX +XXX,XX @@ static uint64_t riscv_aclint_mtimer_read(void *opaque, hwaddr addr,
23
case 0x0383: return "mibound";
27
qemu_log_mask(LOG_GUEST_ERROR,
24
case 0x0384: return "mdbase";
28
"aclint-mtimer: invalid hartid: %zu", hartid);
25
case 0x0385: return "mdbound";
29
} else if ((addr & 0x7) == 0) {
26
- case 0x03a0: return "pmpcfg3";
30
- /* timecmp_lo */
27
+ case 0x03a0: return "pmpcfg0";
31
+ /* timecmp_lo for RV32/RV64 or timecmp for RV64 */
28
+ case 0x03a1: return "pmpcfg1";
32
uint64_t timecmp = env->timecmp;
29
+ case 0x03a2: return "pmpcfg2";
33
- return timecmp & 0xFFFFFFFF;
30
+ case 0x03a3: return "pmpcfg3";
34
+ return (size == 4) ? (timecmp & 0xFFFFFFFF) : timecmp;
31
+ case 0x03a4: return "pmpcfg4";
35
} else if ((addr & 0x7) == 4) {
32
+ case 0x03a5: return "pmpcfg5";
36
/* timecmp_hi */
33
+ case 0x03a6: return "pmpcfg6";
37
uint64_t timecmp = env->timecmp;
34
+ case 0x03a7: return "pmpcfg7";
38
@@ -XXX,XX +XXX,XX @@ static uint64_t riscv_aclint_mtimer_read(void *opaque, hwaddr addr,
35
+ case 0x03a8: return "pmpcfg8";
39
return 0;
36
+ case 0x03a9: return "pmpcfg9";
40
}
37
+ case 0x03aa: return "pmpcfg10";
41
} else if (addr == mtimer->time_base) {
38
+ case 0x03ab: return "pmpcfg11";
42
- /* time_lo */
39
+ case 0x03ac: return "pmpcfg12";
43
- return cpu_riscv_read_rtc(mtimer->timebase_freq) & 0xFFFFFFFF;
40
+ case 0x03ad: return "pmpcfg13";
44
+ /* time_lo for RV32/RV64 or timecmp for RV64 */
41
+ case 0x03ae: return "pmpcfg14";
45
+ uint64_t rtc = cpu_riscv_read_rtc(mtimer->timebase_freq);
42
+ case 0x03af: return "pmpcfg15";
46
+ return (size == 4) ? (rtc & 0xFFFFFFFF) : rtc;
43
case 0x03b0: return "pmpaddr0";
47
} else if (addr == mtimer->time_base + 4) {
44
case 0x03b1: return "pmpaddr1";
48
/* time_hi */
45
case 0x03b2: return "pmpaddr2";
49
return (cpu_riscv_read_rtc(mtimer->timebase_freq) >> 32) & 0xFFFFFFFF;
46
@@ -XXX,XX +XXX,XX @@ static const char *csr_name(int csrno)
50
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
47
case 0x03bd: return "pmpaddr13";
51
qemu_log_mask(LOG_GUEST_ERROR,
48
case 0x03be: return "pmpaddr14";
52
"aclint-mtimer: invalid hartid: %zu", hartid);
49
case 0x03bf: return "pmpaddr15";
53
} else if ((addr & 0x7) == 0) {
50
+ case 0x03c0: return "pmpaddr16";
54
- /* timecmp_lo */
51
+ case 0x03c1: return "pmpaddr17";
55
- uint64_t timecmp_hi = env->timecmp >> 32;
52
+ case 0x03c2: return "pmpaddr18";
56
- riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
53
+ case 0x03c3: return "pmpaddr19";
57
- timecmp_hi << 32 | (value & 0xFFFFFFFF),
54
+ case 0x03c4: return "pmpaddr20";
58
- mtimer->timebase_freq);
55
+ case 0x03c5: return "pmpaddr21";
59
- return;
56
+ case 0x03c6: return "pmpaddr22";
60
+ if (size == 4) {
57
+ case 0x03c7: return "pmpaddr23";
61
+ /* timecmp_lo for RV32/RV64 */
58
+ case 0x03c8: return "pmpaddr24";
62
+ uint64_t timecmp_hi = env->timecmp >> 32;
59
+ case 0x03c9: return "pmpaddr25";
63
+ riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
60
+ case 0x03ca: return "pmpaddr26";
64
+ timecmp_hi << 32 | (value & 0xFFFFFFFF),
61
+ case 0x03cb: return "pmpaddr27";
65
+ mtimer->timebase_freq);
62
+ case 0x03cc: return "pmpaddr28";
66
+ } else {
63
+ case 0x03cd: return "pmpaddr29";
67
+ /* timecmp for RV64 */
64
+ case 0x03ce: return "pmpaddr30";
68
+ riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
65
+ case 0x03cf: return "pmpaddr31";
69
+ value, mtimer->timebase_freq);
66
+ case 0x03d0: return "pmpaddr32";
70
+ }
67
+ case 0x03d1: return "pmpaddr33";
71
} else if ((addr & 0x7) == 4) {
68
+ case 0x03d2: return "pmpaddr34";
72
- /* timecmp_hi */
69
+ case 0x03d3: return "pmpaddr35";
73
- uint64_t timecmp_lo = env->timecmp;
70
+ case 0x03d4: return "pmpaddr36";
74
- riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
71
+ case 0x03d5: return "pmpaddr37";
75
- value << 32 | (timecmp_lo & 0xFFFFFFFF),
72
+ case 0x03d6: return "pmpaddr38";
76
- mtimer->timebase_freq);
73
+ case 0x03d7: return "pmpaddr39";
77
+ if (size == 4) {
74
+ case 0x03d8: return "pmpaddr40";
78
+ /* timecmp_hi for RV32/RV64 */
75
+ case 0x03d9: return "pmpaddr41";
79
+ uint64_t timecmp_lo = env->timecmp;
76
+ case 0x03da: return "pmpaddr42";
80
+ riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
77
+ case 0x03db: return "pmpaddr43";
81
+ value << 32 | (timecmp_lo & 0xFFFFFFFF),
78
+ case 0x03dc: return "pmpaddr44";
82
+ mtimer->timebase_freq);
79
+ case 0x03dd: return "pmpaddr45";
83
+ } else {
80
+ case 0x03de: return "pmpaddr46";
84
+ qemu_log_mask(LOG_GUEST_ERROR,
81
+ case 0x03df: return "pmpaddr47";
85
+ "aclint-mtimer: invalid timecmp_hi write: %08x",
82
+ case 0x03e0: return "pmpaddr48";
86
+ (uint32_t)addr);
83
+ case 0x03e1: return "pmpaddr49";
87
+ }
84
+ case 0x03e2: return "pmpaddr50";
88
} else {
85
+ case 0x03e3: return "pmpaddr51";
89
qemu_log_mask(LOG_UNIMP,
86
+ case 0x03e4: return "pmpaddr52";
90
"aclint-mtimer: invalid timecmp write: %08x",
87
+ case 0x03e5: return "pmpaddr53";
88
+ case 0x03e6: return "pmpaddr54";
89
+ case 0x03e7: return "pmpaddr55";
90
+ case 0x03e8: return "pmpaddr56";
91
+ case 0x03e9: return "pmpaddr57";
92
+ case 0x03ea: return "pmpaddr58";
93
+ case 0x03eb: return "pmpaddr59";
94
+ case 0x03ec: return "pmpaddr60";
95
+ case 0x03ed: return "pmpaddr61";
96
+ case 0x03ee: return "pmpaddr62";
97
+ case 0x03ef: return "pmpaddr63";
98
case 0x0780: return "mtohost";
99
case 0x0781: return "mfromhost";
100
case 0x0782: return "mreset";
101
--
91
--
102
2.45.1
92
2.35.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Frank Chang <frank.chang@sifive.com>
2
2
3
raise_mmu_exception(), as is today, is prioritizing guest page faults by
3
RISC-V privilege spec defines that mtime is exposed as a memory-mapped
4
checking first if virt_enabled && !first_stage, and then considering the
4
machine-mode read-write register. However, as QEMU uses host monotonic
5
regular inst/load/store faults.
5
timer as timer source, this makes mtime to be read-only in RISC-V
6
6
ACLINT.
7
There's no mention in the spec about guest page fault being a higher
7
8
priority that PMP faults. In fact, privileged spec section 3.7.1 says:
8
This patch makes mtime to be writable by recording the time delta value
9
9
between the mtime value to be written and the timer value at the time
10
"Attempting to fetch an instruction from a PMP region that does not have
10
mtime is written. Time delta value is then added back whenever the timer
11
execute permissions raises an instruction access-fault exception.
11
value is retrieved.
12
Attempting to execute a load or load-reserved instruction which accesses
12
13
a physical address within a PMP region without read permissions raises a
13
Signed-off-by: Frank Chang <frank.chang@sifive.com>
14
load access-fault exception. Attempting to execute a store,
14
Reviewed-by: Jim Shu <jim.shu@sifive.com>
15
store-conditional, or AMO instruction which accesses a physical address
16
within a PMP region without write permissions raises a store
17
access-fault exception."
18
19
So, in fact, we're doing it wrong - PMP faults should always be thrown,
20
regardless of also being a first or second stage fault.
21
22
The way riscv_cpu_tlb_fill() and get_physical_address() work is
23
adequate: a TRANSLATE_PMP_FAIL error is immediately reported and
24
reflected in the 'pmp_violation' flag. What we need is to change
25
raise_mmu_exception() to prioritize it.
26
27
Reported-by: Joseph Chan <jchan@ventanamicro.com>
28
Fixes: 82d53adfbb ("target/riscv/cpu_helper.c: Invalid exception on MMU translation stage")
29
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
30
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
31
Message-ID: <20240413105929.7030-1-alexei.filippov@syntacore.com>
16
Message-Id: <20220420080901.14655-4-frank.chang@sifive.com>
32
Cc: qemu-stable <qemu-stable@nongnu.org>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
34
---
18
---
35
target/riscv/cpu_helper.c | 22 ++++++++++++----------
19
include/hw/intc/riscv_aclint.h | 1 +
36
1 file changed, 12 insertions(+), 10 deletions(-)
20
target/riscv/cpu.h | 8 ++--
37
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);
38
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
208
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
39
index XXXXXXX..XXXXXXX 100644
209
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/cpu_helper.c
210
--- a/target/riscv/cpu_helper.c
41
+++ b/target/riscv/cpu_helper.c
211
+++ b/target/riscv/cpu_helper.c
42
@@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
212
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value)
43
213
return old;
44
switch (access_type) {
214
}
45
case MMU_INST_FETCH:
215
46
- if (env->virt_enabled && !first_stage) {
216
-void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(uint32_t),
47
+ if (pmp_violation) {
217
- uint32_t arg)
48
+ cs->exception_index = RISCV_EXCP_INST_ACCESS_FAULT;
218
+void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(void *),
49
+ } else if (env->virt_enabled && !first_stage) {
219
+ void *arg)
50
cs->exception_index = RISCV_EXCP_INST_GUEST_PAGE_FAULT;
220
{
51
} else {
221
env->rdtime_fn = fn;
52
- cs->exception_index = pmp_violation ?
222
env->rdtime_fn_arg = arg;
53
- RISCV_EXCP_INST_ACCESS_FAULT : RISCV_EXCP_INST_PAGE_FAULT;
54
+ cs->exception_index = RISCV_EXCP_INST_PAGE_FAULT;
55
}
56
break;
57
case MMU_DATA_LOAD:
58
- if (two_stage && !first_stage) {
59
+ if (pmp_violation) {
60
+ cs->exception_index = RISCV_EXCP_LOAD_ACCESS_FAULT;
61
+ } else if (two_stage && !first_stage) {
62
cs->exception_index = RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT;
63
} else {
64
- cs->exception_index = pmp_violation ?
65
- RISCV_EXCP_LOAD_ACCESS_FAULT : RISCV_EXCP_LOAD_PAGE_FAULT;
66
+ cs->exception_index = RISCV_EXCP_LOAD_PAGE_FAULT;
67
}
68
break;
69
case MMU_DATA_STORE:
70
- if (two_stage && !first_stage) {
71
+ if (pmp_violation) {
72
+ cs->exception_index = RISCV_EXCP_STORE_AMO_ACCESS_FAULT;
73
+ } else if (two_stage && !first_stage) {
74
cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT;
75
} else {
76
- cs->exception_index = pmp_violation ?
77
- RISCV_EXCP_STORE_AMO_ACCESS_FAULT :
78
- RISCV_EXCP_STORE_PAGE_FAULT;
79
+ cs->exception_index = RISCV_EXCP_STORE_PAGE_FAULT;
80
}
81
break;
82
default:
83
--
223
--
84
2.45.1
224
2.35.1
diff view generated by jsdifflib
1
From: Andrew Jones <ajones@ventanamicro.com>
1
From: Jim Shu <jim.shu@sifive.com>
2
2
3
Implementing wrs.nto to always just return is consistent with the
3
This commit implements reset function of all ACLINT devices.
4
specification, as the instruction is permitted to terminate the
4
ACLINT device reset will clear MTIME and MSIP register to 0.
5
stall for any reason, but it's not useful for virtualization, where
6
we'd like the guest to trap to the hypervisor in order to allow
7
scheduling of the lock holding VCPU. Change to always immediately
8
raise exceptions when the appropriate conditions are present,
9
otherwise continue to just return. Note, immediately raising
10
exceptions is also consistent with the specification since the
11
time limit that should expire prior to the exception is
12
implementation-specific.
13
5
14
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
6
Depend on RISC-V ACLINT spec v1.0-rc4:
15
Reviewed-by: Christoph Müllner <christoph.muellner@vrull.eu>
7
https://github.com/riscv/riscv-aclint/blob/v1.0-rc4/riscv-aclint.adoc
16
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
9
Signed-off-by: Jim Shu <jim.shu@sifive.com>
10
Reviewed-by: Frank Chang <frank.chang@sifive.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Message-ID: <20240424142808.62936-2-ajones@ventanamicro.com>
12
Message-Id: <20220420080901.14655-5-frank.chang@sifive.com>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
---
14
---
21
target/riscv/helper.h | 1 +
15
hw/intc/riscv_aclint.c | 39 +++++++++++++++++++++++++++++++++++++++
22
target/riscv/op_helper.c | 11 ++++++++
16
1 file changed, 39 insertions(+)
23
target/riscv/insn_trans/trans_rvzawrs.c.inc | 29 ++++++++++++++-------
24
3 files changed, 32 insertions(+), 9 deletions(-)
25
17
26
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
18
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
27
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
28
--- a/target/riscv/helper.h
20
--- a/hw/intc/riscv_aclint.c
29
+++ b/target/riscv/helper.h
21
+++ b/hw/intc/riscv_aclint.c
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(csrrw_i128, tl, env, int, tl, tl, tl, tl)
22
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_realize(DeviceState *dev, Error **errp)
31
DEF_HELPER_1(sret, tl, env)
32
DEF_HELPER_1(mret, tl, env)
33
DEF_HELPER_1(wfi, void, env)
34
+DEF_HELPER_1(wrs_nto, void, env)
35
DEF_HELPER_1(tlb_flush, void, env)
36
DEF_HELPER_1(tlb_flush_all, void, env)
37
/* Native Debug */
38
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/op_helper.c
41
+++ b/target/riscv/op_helper.c
42
@@ -XXX,XX +XXX,XX @@ void helper_wfi(CPURISCVState *env)
43
}
23
}
44
}
24
}
45
25
46
+void helper_wrs_nto(CPURISCVState *env)
26
+static void riscv_aclint_mtimer_reset_enter(Object *obj, ResetType type)
47
+{
27
+{
48
+ if (env->virt_enabled && (env->priv == PRV_S || env->priv == PRV_U) &&
28
+ /*
49
+ get_field(env->hstatus, HSTATUS_VTW) &&
29
+ * According to RISC-V ACLINT spec:
50
+ !get_field(env->mstatus, MSTATUS_TW)) {
30
+ * - On MTIMER device reset, the MTIME register is cleared to zero.
51
+ riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
31
+ * - On MTIMER device reset, the MTIMECMP registers are in unknown state.
52
+ } else if (env->priv != PRV_M && get_field(env->mstatus, MSTATUS_TW)) {
32
+ */
53
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
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
+ }
54
+ }
72
+ }
55
+}
73
+}
56
+
74
+
57
void helper_tlb_flush(CPURISCVState *env)
75
static void riscv_aclint_swi_class_init(ObjectClass *klass, void *data)
58
{
76
{
59
CPUState *cs = env_cpu(env);
77
DeviceClass *dc = DEVICE_CLASS(klass);
60
diff --git a/target/riscv/insn_trans/trans_rvzawrs.c.inc b/target/riscv/insn_trans/trans_rvzawrs.c.inc
78
dc->realize = riscv_aclint_swi_realize;
61
index XXXXXXX..XXXXXXX 100644
79
device_class_set_props(dc, riscv_aclint_swi_properties);
62
--- a/target/riscv/insn_trans/trans_rvzawrs.c.inc
80
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
63
+++ b/target/riscv/insn_trans/trans_rvzawrs.c.inc
81
+ rc->phases.enter = riscv_aclint_swi_reset_enter;
64
@@ -XXX,XX +XXX,XX @@
65
* this program. If not, see <http://www.gnu.org/licenses/>.
66
*/
67
68
-static bool trans_wrs(DisasContext *ctx)
69
+static bool trans_wrs_sto(DisasContext *ctx, arg_wrs_sto *a)
70
{
71
if (!ctx->cfg_ptr->ext_zawrs) {
72
return false;
73
@@ -XXX,XX +XXX,XX @@ static bool trans_wrs(DisasContext *ctx)
74
return true;
75
}
82
}
76
83
77
-#define GEN_TRANS_WRS(insn) \
84
static const TypeInfo riscv_aclint_swi_info = {
78
-static bool trans_ ## insn(DisasContext *ctx, arg_ ## insn *a) \
79
-{ \
80
- (void)a; \
81
- return trans_wrs(ctx); \
82
-}
83
+static bool trans_wrs_nto(DisasContext *ctx, arg_wrs_nto *a)
84
+{
85
+ if (!ctx->cfg_ptr->ext_zawrs) {
86
+ return false;
87
+ }
88
89
-GEN_TRANS_WRS(wrs_nto)
90
-GEN_TRANS_WRS(wrs_sto)
91
+ /*
92
+ * Depending on the mode of execution, mstatus.TW and hstatus.VTW, wrs.nto
93
+ * should raise an exception when the implementation-specific bounded time
94
+ * limit has expired. Our time limit is zero, so we either return
95
+ * immediately, as does our implementation of wrs.sto, or raise an
96
+ * exception, as handled by the wrs.nto helper.
97
+ */
98
+#ifndef CONFIG_USER_ONLY
99
+ gen_helper_wrs_nto(tcg_env);
100
+#endif
101
+
102
+ /* We only get here when helper_wrs_nto() doesn't raise an exception. */
103
+ return trans_wrs_sto(ctx, NULL);
104
+}
105
--
85
--
106
2.45.1
86
2.35.1
107
108
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
SBI defines a Debug Console extension "DBCN" that will, in time, replace
3
Implement .debug_excp_handler, .debug_check_{breakpoint, watchpoint}
4
the legacy console putchar and getchar SBI extensions.
4
TCGCPUOps and hook them into riscv_tcg_ops.
5
5
6
The appeal of the DBCN extension is that it allows multiple bytes to be
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
read/written in the SBI console in a single SBI call.
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
8
Message-Id: <20220421003324.1134983-2-bmeng.cn@gmail.com>
9
As far as KVM goes, the DBCN calls are forwarded by an in-kernel KVM
10
module to userspace. But this will only happens if the KVM module
11
actually supports this SBI extension and we activate it.
12
13
We'll check for DBCN support during init time, checking if get-reg-list
14
is advertising KVM_RISCV_SBI_EXT_DBCN. In that case, we'll enable it via
15
kvm_set_one_reg() during kvm_arch_init_vcpu().
16
17
Finally, change kvm_riscv_handle_sbi() to handle the incoming calls for
18
SBI_EXT_DBCN, reading and writing as required.
19
20
A simple KVM guest with 'earlycon=sbi', running in an emulated RISC-V
21
host, takes around 20 seconds to boot without using DBCN. With this
22
patch we're taking around 14 seconds to boot due to the speed-up in the
23
terminal output. There's no change in boot time if the guest isn't
24
using earlycon.
25
26
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
27
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
28
Message-ID: <20240425155012.581366-1-dbarboza@ventanamicro.com>
29
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
---
10
---
31
target/riscv/sbi_ecall_interface.h | 17 +++++
11
target/riscv/debug.h | 4 +++
32
target/riscv/kvm/kvm-cpu.c | 111 +++++++++++++++++++++++++++++
12
target/riscv/cpu.c | 3 ++
33
2 files changed, 128 insertions(+)
13
target/riscv/debug.c | 75 ++++++++++++++++++++++++++++++++++++++++++++
14
3 files changed, 82 insertions(+)
34
15
35
diff --git a/target/riscv/sbi_ecall_interface.h b/target/riscv/sbi_ecall_interface.h
16
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
36
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/sbi_ecall_interface.h
18
--- a/target/riscv/debug.h
38
+++ b/target/riscv/sbi_ecall_interface.h
19
+++ b/target/riscv/debug.h
39
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ void tselect_csr_write(CPURISCVState *env, target_ulong val);
40
21
target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index);
41
/* clang-format off */
22
void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val);
42
23
43
+#define SBI_SUCCESS 0
24
+void riscv_cpu_debug_excp_handler(CPUState *cs);
44
+#define SBI_ERR_FAILED -1
25
+bool riscv_cpu_debug_check_breakpoint(CPUState *cs);
45
+#define SBI_ERR_NOT_SUPPORTED -2
26
+bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
46
+#define SBI_ERR_INVALID_PARAM -3
47
+#define SBI_ERR_DENIED -4
48
+#define SBI_ERR_INVALID_ADDRESS -5
49
+#define SBI_ERR_ALREADY_AVAILABLE -6
50
+#define SBI_ERR_ALREADY_STARTED -7
51
+#define SBI_ERR_ALREADY_STOPPED -8
52
+#define SBI_ERR_NO_SHMEM -9
53
+
27
+
54
/* SBI Extension IDs */
28
#endif /* RISCV_DEBUG_H */
55
#define SBI_EXT_0_1_SET_TIMER 0x0
29
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
56
#define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1
30
index XXXXXXX..XXXXXXX 100644
57
@@ -XXX,XX +XXX,XX @@
31
--- a/target/riscv/cpu.c
58
#define SBI_EXT_IPI 0x735049
32
+++ b/target/riscv/cpu.c
59
#define SBI_EXT_RFENCE 0x52464E43
33
@@ -XXX,XX +XXX,XX @@ static const struct TCGCPUOps riscv_tcg_ops = {
60
#define SBI_EXT_HSM 0x48534D
34
.do_interrupt = riscv_cpu_do_interrupt,
61
+#define SBI_EXT_DBCN 0x4442434E
35
.do_transaction_failed = riscv_cpu_do_transaction_failed,
62
36
.do_unaligned_access = riscv_cpu_do_unaligned_access,
63
/* SBI function IDs for BASE extension */
37
+ .debug_excp_handler = riscv_cpu_debug_excp_handler,
64
#define SBI_EXT_BASE_GET_SPEC_VERSION 0x0
38
+ .debug_check_breakpoint = riscv_cpu_debug_check_breakpoint,
65
@@ -XXX,XX +XXX,XX @@
39
+ .debug_check_watchpoint = riscv_cpu_debug_check_watchpoint,
66
#define SBI_EXT_HSM_HART_STOP 0x1
40
#endif /* !CONFIG_USER_ONLY */
67
#define SBI_EXT_HSM_HART_GET_STATUS 0x2
41
};
68
42
69
+/* SBI function IDs for DBCN extension */
43
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
70
+#define SBI_EXT_DBCN_CONSOLE_WRITE 0x0
44
index XXXXXXX..XXXXXXX 100644
71
+#define SBI_EXT_DBCN_CONSOLE_READ 0x1
45
--- a/target/riscv/debug.c
72
+#define SBI_EXT_DBCN_CONSOLE_WRITE_BYTE 0x2
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
}
73
+
51
+
74
#define SBI_HSM_HART_STATUS_STARTED 0x0
52
+void riscv_cpu_debug_excp_handler(CPUState *cs)
75
#define SBI_HSM_HART_STATUS_STOPPED 0x1
53
+{
76
#define SBI_HSM_HART_STATUS_START_PENDING 0x2
54
+ RISCVCPU *cpu = RISCV_CPU(cs);
77
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
55
+ CPURISCVState *env = &cpu->env;
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/riscv/kvm/kvm-cpu.c
80
+++ b/target/riscv/kvm/kvm-cpu.c
81
@@ -XXX,XX +XXX,XX @@ static KVMCPUConfig kvm_v_vlenb = {
82
KVM_REG_RISCV_VECTOR_CSR_REG(vlenb)
83
};
84
85
+static KVMCPUConfig kvm_sbi_dbcn = {
86
+ .name = "sbi_dbcn",
87
+ .kvm_reg_id = KVM_REG_RISCV | KVM_REG_SIZE_U64 |
88
+ KVM_REG_RISCV_SBI_EXT | KVM_RISCV_SBI_EXT_DBCN
89
+};
90
+
56
+
91
static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
57
+ if (cs->watchpoint_hit) {
92
{
58
+ if (cs->watchpoint_hit->flags & BP_CPU) {
93
CPURISCVState *env = &cpu->env;
59
+ cs->watchpoint_hit = NULL;
94
@@ -XXX,XX +XXX,XX @@ static int uint64_cmp(const void *a, const void *b)
60
+ riscv_raise_exception(env, RISCV_EXCP_BREAKPOINT, 0);
95
return 0;
61
+ }
96
}
62
+ } else {
97
63
+ if (cpu_breakpoint_test(cs, env->pc, BP_CPU)) {
98
+static void kvm_riscv_check_sbi_dbcn_support(RISCVCPU *cpu,
64
+ riscv_raise_exception(env, RISCV_EXCP_BREAKPOINT, 0);
99
+ KVMScratchCPU *kvmcpu,
65
+ }
100
+ struct kvm_reg_list *reglist)
101
+{
102
+ struct kvm_reg_list *reg_search;
103
+
104
+ reg_search = bsearch(&kvm_sbi_dbcn.kvm_reg_id, reglist->reg, reglist->n,
105
+ sizeof(uint64_t), uint64_cmp);
106
+
107
+ if (reg_search) {
108
+ kvm_sbi_dbcn.supported = true;
109
+ }
66
+ }
110
+}
67
+}
111
+
68
+
112
static void kvm_riscv_read_vlenb(RISCVCPU *cpu, KVMScratchCPU *kvmcpu,
69
+bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
113
struct kvm_reg_list *reglist)
70
+{
114
{
71
+ RISCVCPU *cpu = RISCV_CPU(cs);
115
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
72
+ CPURISCVState *env = &cpu->env;
116
if (riscv_has_ext(&cpu->env, RVV)) {
73
+ CPUBreakpoint *bp;
117
kvm_riscv_read_vlenb(cpu, kvmcpu, reglist);
74
+ target_ulong ctrl;
118
}
75
+ target_ulong pc;
76
+ int i;
119
+
77
+
120
+ kvm_riscv_check_sbi_dbcn_support(cpu, kvmcpu, reglist);
78
+ QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
121
}
79
+ for (i = 0; i < TRIGGER_TYPE2_NUM; i++) {
122
80
+ ctrl = env->type2_trig[i].mcontrol;
123
static void riscv_init_kvm_registers(Object *cpu_obj)
81
+ pc = env->type2_trig[i].maddress;
124
@@ -XXX,XX +XXX,XX @@ static int kvm_vcpu_set_machine_ids(RISCVCPU *cpu, CPUState *cs)
125
return ret;
126
}
127
128
+static int kvm_vcpu_enable_sbi_dbcn(RISCVCPU *cpu, CPUState *cs)
129
+{
130
+ target_ulong reg = 1;
131
+
82
+
132
+ if (!kvm_sbi_dbcn.supported) {
83
+ if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) {
133
+ return 0;
84
+ /* check U/S/M bit against current privilege level */
85
+ if ((ctrl >> 3) & BIT(env->priv)) {
86
+ return true;
87
+ }
88
+ }
89
+ }
134
+ }
90
+ }
135
+
91
+
136
+ return kvm_set_one_reg(cs, kvm_sbi_dbcn.kvm_reg_id, &reg);
92
+ return false;
137
+}
93
+}
138
+
94
+
139
int kvm_arch_init_vcpu(CPUState *cs)
95
+bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
140
{
96
+{
141
int ret = 0;
97
+ RISCVCPU *cpu = RISCV_CPU(cs);
142
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
98
+ CPURISCVState *env = &cpu->env;
143
kvm_riscv_update_cpu_misa_ext(cpu, cs);
99
+ target_ulong ctrl;
144
kvm_riscv_update_cpu_cfg_isa_ext(cpu, cs);
100
+ target_ulong addr;
145
101
+ int flags;
146
+ ret = kvm_vcpu_enable_sbi_dbcn(cpu, cs);
102
+ int i;
147
+
103
+
148
return ret;
104
+ for (i = 0; i < TRIGGER_TYPE2_NUM; i++) {
149
}
105
+ ctrl = env->type2_trig[i].mcontrol;
150
106
+ addr = env->type2_trig[i].maddress;
151
@@ -XXX,XX +XXX,XX @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs)
107
+ flags = 0;
152
return true;
153
}
154
155
+static void kvm_riscv_handle_sbi_dbcn(CPUState *cs, struct kvm_run *run)
156
+{
157
+ g_autofree uint8_t *buf = NULL;
158
+ RISCVCPU *cpu = RISCV_CPU(cs);
159
+ target_ulong num_bytes;
160
+ uint64_t addr;
161
+ unsigned char ch;
162
+ int ret;
163
+
108
+
164
+ switch (run->riscv_sbi.function_id) {
109
+ if (ctrl & TYPE2_LOAD) {
165
+ case SBI_EXT_DBCN_CONSOLE_READ:
110
+ flags |= BP_MEM_READ;
166
+ case SBI_EXT_DBCN_CONSOLE_WRITE:
111
+ }
167
+ num_bytes = run->riscv_sbi.args[0];
112
+ if (ctrl & TYPE2_STORE) {
168
+
113
+ flags |= BP_MEM_WRITE;
169
+ if (num_bytes == 0) {
170
+ run->riscv_sbi.ret[0] = SBI_SUCCESS;
171
+ run->riscv_sbi.ret[1] = 0;
172
+ break;
173
+ }
114
+ }
174
+
115
+
175
+ addr = run->riscv_sbi.args[1];
116
+ if ((wp->flags & flags) && (wp->vaddr == addr)) {
176
+
117
+ /* check U/S/M bit against current privilege level */
177
+ /*
118
+ if ((ctrl >> 3) & BIT(env->priv)) {
178
+ * Handle the case where a 32 bit CPU is running in a
119
+ return true;
179
+ * 64 bit addressing env.
180
+ */
181
+ if (riscv_cpu_mxl(&cpu->env) == MXL_RV32) {
182
+ addr |= (uint64_t)run->riscv_sbi.args[2] << 32;
183
+ }
184
+
185
+ buf = g_malloc0(num_bytes);
186
+
187
+ if (run->riscv_sbi.function_id == SBI_EXT_DBCN_CONSOLE_READ) {
188
+ ret = qemu_chr_fe_read_all(serial_hd(0)->be, buf, num_bytes);
189
+ if (ret < 0) {
190
+ error_report("SBI_EXT_DBCN_CONSOLE_READ: error when "
191
+ "reading chardev");
192
+ exit(1);
193
+ }
194
+
195
+ cpu_physical_memory_write(addr, buf, ret);
196
+ } else {
197
+ cpu_physical_memory_read(addr, buf, num_bytes);
198
+
199
+ ret = qemu_chr_fe_write_all(serial_hd(0)->be, buf, num_bytes);
200
+ if (ret < 0) {
201
+ error_report("SBI_EXT_DBCN_CONSOLE_WRITE: error when "
202
+ "writing chardev");
203
+ exit(1);
204
+ }
120
+ }
205
+ }
121
+ }
122
+ }
206
+
123
+
207
+ run->riscv_sbi.ret[0] = SBI_SUCCESS;
124
+ return false;
208
+ run->riscv_sbi.ret[1] = ret;
209
+ break;
210
+ case SBI_EXT_DBCN_CONSOLE_WRITE_BYTE:
211
+ ch = run->riscv_sbi.args[0];
212
+ ret = qemu_chr_fe_write(serial_hd(0)->be, &ch, sizeof(ch));
213
+
214
+ if (ret < 0) {
215
+ error_report("SBI_EXT_DBCN_CONSOLE_WRITE_BYTE: error when "
216
+ "writing chardev");
217
+ exit(1);
218
+ }
219
+
220
+ run->riscv_sbi.ret[0] = SBI_SUCCESS;
221
+ run->riscv_sbi.ret[1] = 0;
222
+ break;
223
+ default:
224
+ run->riscv_sbi.ret[0] = SBI_ERR_NOT_SUPPORTED;
225
+ }
226
+}
125
+}
227
+
228
static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
229
{
230
int ret = 0;
231
@@ -XXX,XX +XXX,XX @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
232
}
233
ret = 0;
234
break;
235
+ case SBI_EXT_DBCN:
236
+ kvm_riscv_handle_sbi_dbcn(cs, run);
237
+ break;
238
default:
239
qemu_log_mask(LOG_UNIMP,
240
"%s: un-handled SBI EXIT, specific reasons is %lu\n",
241
--
126
--
242
2.45.1
127
2.35.1
diff view generated by jsdifflib
1
From: Huang Tao <eric.huang@linux.alibaba.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
In this patch, we modify the decoder to be a freely composable data
3
Add a config option to enable support for native M-mode debug.
4
structure instead of a hardcoded one. It can be dynamically builded up
4
This is disabled by default and can be enabled with 'debug=true'.
5
according to the extensions.
6
This approach has several benefits:
7
1. Provides support for heterogeneous cpu architectures. As we add decoder in
8
RISCVCPU, each cpu can have their own decoder, and the decoders can be
9
different due to cpu's features.
10
2. Improve the decoding efficiency. We run the guard_func to see if the decoder
11
can be added to the dynamic_decoder when building up the decoder. Therefore,
12
there is no need to run the guard_func when decoding each instruction. It can
13
improve the decoding efficiency
14
3. For vendor or dynamic cpus, it allows them to customize their own decoder
15
functions to improve decoding efficiency, especially when vendor-defined
16
instruction sets increase. Because of dynamic building up, it can skip the other
17
decoder guard functions when decoding.
18
4. Pre patch for allowing adding a vendor decoder before decode_insn32() with minimal
19
overhead for users that don't need this particular vendor decoder.
20
5
21
Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
22
Suggested-by: Christoph Muellner <christoph.muellner@vrull.eu>
23
Co-authored-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
26
Message-ID: <20240506023607.29544-1-eric.huang@linux.alibaba.com>
8
Message-Id: <20220421003324.1134983-3-bmeng.cn@gmail.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
---
10
---
29
target/riscv/cpu.h | 1 +
11
target/riscv/cpu.h | 4 +++-
30
target/riscv/tcg/tcg-cpu.h | 15 +++++++++++++++
12
target/riscv/cpu.c | 5 +++++
31
target/riscv/cpu.c | 1 +
13
2 files changed, 8 insertions(+), 1 deletion(-)
32
target/riscv/tcg/tcg-cpu.c | 15 +++++++++++++++
33
target/riscv/translate.c | 31 +++++++++++++++----------------
34
5 files changed, 47 insertions(+), 16 deletions(-)
35
14
36
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
15
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
37
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
38
--- a/target/riscv/cpu.h
17
--- a/target/riscv/cpu.h
39
+++ b/target/riscv/cpu.h
18
+++ b/target/riscv/cpu.h
40
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
19
@@ -XXX,XX +XXX,XX @@ enum {
41
uint32_t pmu_avail_ctrs;
20
RISCV_FEATURE_PMP,
42
/* Mapping of events to counters */
21
RISCV_FEATURE_EPMP,
43
GHashTable *pmu_event_ctr_map;
22
RISCV_FEATURE_MISA,
44
+ const GPtrArray *decoders;
23
- RISCV_FEATURE_AIA
24
+ RISCV_FEATURE_AIA,
25
+ RISCV_FEATURE_DEBUG
45
};
26
};
46
27
47
/**
28
/* Privileged specification version */
48
diff --git a/target/riscv/tcg/tcg-cpu.h b/target/riscv/tcg/tcg-cpu.h
29
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
49
index XXXXXXX..XXXXXXX 100644
30
bool pmp;
50
--- a/target/riscv/tcg/tcg-cpu.h
31
bool epmp;
51
+++ b/target/riscv/tcg/tcg-cpu.h
32
bool aia;
52
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp);
33
+ bool debug;
53
void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
34
uint64_t resetvec;
54
bool riscv_cpu_tcg_compatible(RISCVCPU *cpu);
35
};
55
36
56
+struct DisasContext;
57
+struct RISCVCPUConfig;
58
+typedef struct RISCVDecoder {
59
+ bool (*guard_func)(const struct RISCVCPUConfig *);
60
+ bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
61
+} RISCVDecoder;
62
+
63
+typedef bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
64
+
65
+extern const size_t decoder_table_size;
66
+
67
+extern const RISCVDecoder decoder_table[];
68
+
69
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu);
70
+
71
#endif
72
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
37
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
73
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
74
--- a/target/riscv/cpu.c
39
--- a/target/riscv/cpu.c
75
+++ b/target/riscv/cpu.c
40
+++ b/target/riscv/cpu.c
76
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
41
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
77
error_propagate(errp, local_err);
42
riscv_set_feature(env, RISCV_FEATURE_AIA);
78
return;
79
}
80
+ riscv_tcg_cpu_finalize_dynamic_decoder(cpu);
81
} else if (kvm_enabled()) {
82
riscv_kvm_cpu_finalize_features(cpu, &local_err);
83
if (local_err != NULL) {
84
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/target/riscv/tcg/tcg-cpu.c
87
+++ b/target/riscv/tcg/tcg-cpu.c
88
@@ -XXX,XX +XXX,XX @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
89
}
43
}
90
}
44
91
45
+ if (cpu->cfg.debug) {
92
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu)
46
+ riscv_set_feature(env, RISCV_FEATURE_DEBUG);
93
+{
94
+ GPtrArray *dynamic_decoders;
95
+ dynamic_decoders = g_ptr_array_sized_new(decoder_table_size);
96
+ for (size_t i = 0; i < decoder_table_size; ++i) {
97
+ if (decoder_table[i].guard_func &&
98
+ decoder_table[i].guard_func(&cpu->cfg)) {
99
+ g_ptr_array_add(dynamic_decoders,
100
+ (gpointer)decoder_table[i].riscv_cpu_decode_fn);
101
+ }
102
+ }
47
+ }
103
+
48
+
104
+ cpu->decoders = dynamic_decoders;
49
set_resetvec(env, cpu->cfg.resetvec);
105
+}
50
106
+
51
/* Validate that MISA_MXL is set properly. */
107
bool riscv_cpu_tcg_compatible(RISCVCPU *cpu)
52
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = {
108
{
53
DEFINE_PROP_BOOL("Zve64f", RISCVCPU, cfg.ext_zve64f, false),
109
return object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST) == NULL;
54
DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
110
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
55
DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
111
index XXXXXXX..XXXXXXX 100644
56
+ DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, false),
112
--- a/target/riscv/translate.c
57
113
+++ b/target/riscv/translate.c
58
DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
114
@@ -XXX,XX +XXX,XX @@
59
DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
115
#include "exec/helper-info.c.inc"
116
#undef HELPER_H
117
118
+#include "tcg/tcg-cpu.h"
119
+
120
/* global register indices */
121
static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc, cpu_vl, cpu_vstart;
122
static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
123
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
124
/* FRM is known to contain a valid value. */
125
bool frm_valid;
126
bool insn_start_updated;
127
+ const GPtrArray *decoders;
128
} DisasContext;
129
130
static inline bool has_ext(DisasContext *ctx, uint32_t ext)
131
@@ -XXX,XX +XXX,XX @@ static inline int insn_len(uint16_t first_word)
132
return (first_word & 3) == 3 ? 4 : 2;
133
}
134
135
+const RISCVDecoder decoder_table[] = {
136
+ { always_true_p, decode_insn32 },
137
+ { has_xthead_p, decode_xthead},
138
+ { has_XVentanaCondOps_p, decode_XVentanaCodeOps},
139
+};
140
+
141
+const size_t decoder_table_size = ARRAY_SIZE(decoder_table);
142
+
143
static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
144
{
145
- /*
146
- * A table with predicate (i.e., guard) functions and decoder functions
147
- * that are tested in-order until a decoder matches onto the opcode.
148
- */
149
- static const struct {
150
- bool (*guard_func)(const RISCVCPUConfig *);
151
- bool (*decode_func)(DisasContext *, uint32_t);
152
- } decoders[] = {
153
- { always_true_p, decode_insn32 },
154
- { has_xthead_p, decode_xthead },
155
- { has_XVentanaCondOps_p, decode_XVentanaCodeOps },
156
- };
157
-
158
ctx->virt_inst_excp = false;
159
ctx->cur_insn_len = insn_len(opcode);
160
/* Check for compressed insn */
161
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
162
ctx->base.pc_next + 2));
163
ctx->opcode = opcode32;
164
165
- for (size_t i = 0; i < ARRAY_SIZE(decoders); ++i) {
166
- if (decoders[i].guard_func(ctx->cfg_ptr) &&
167
- decoders[i].decode_func(ctx, opcode32)) {
168
+ for (guint i = 0; i < ctx->decoders->len; ++i) {
169
+ riscv_cpu_decode_fn func = g_ptr_array_index(ctx->decoders, i);
170
+ if (func(ctx, opcode32)) {
171
return;
172
}
173
}
174
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
175
ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER);
176
ctx->zero = tcg_constant_tl(0);
177
ctx->virt_inst_excp = false;
178
+ ctx->decoders = cpu->decoders;
179
}
180
181
static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
182
--
60
--
183
2.45.1
61
2.35.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
We're not setting (s/m)tval when triggering breakpoints of type 2
3
This adds debug CSR read/write support to the RISC-V CSR RW table.
4
(mcontrol) and 6 (mcontrol6). According to the debug spec section
5
5.7.12, "Match Control Type 6":
6
4
7
"The Privileged Spec says that breakpoint exceptions that occur on
5
Signed-off-by: Bin Meng <bin.meng@windriver.com>
8
instruction fetches, loads, or stores update the tval CSR with either
9
zero or the faulting virtual address. The faulting virtual address for
10
an mcontrol6 trigger with action = 0 is the address being accessed and
11
which caused that trigger to fire."
12
13
A similar text is also found in the Debug spec section 5.7.11 w.r.t.
14
mcontrol.
15
16
Note that what we're doing ATM is not violating the spec, but it's
17
simple enough to set mtval/stval and it makes life easier for any
18
software that relies on this info.
19
20
Given that we always use action = 0, save the faulting address for the
21
mcontrol and mcontrol6 trigger breakpoints into env->badaddr, which is
22
used as as scratch area for traps with address information. 'tval' is
23
then set during riscv_cpu_do_interrupt().
24
25
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
26
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
27
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
7
Message-Id: <20220421003324.1134983-4-bmeng.cn@gmail.com>
28
Message-ID: <20240416230437.1869024-2-dbarboza@ventanamicro.com>
29
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
---
9
---
31
target/riscv/cpu_helper.c | 1 +
10
target/riscv/debug.h | 2 ++
32
target/riscv/debug.c | 3 +++
11
target/riscv/cpu.c | 4 ++++
33
2 files changed, 4 insertions(+)
12
target/riscv/csr.c | 57 ++++++++++++++++++++++++++++++++++++++++++++
13
target/riscv/debug.c | 27 +++++++++++++++++++++
14
4 files changed, 90 insertions(+)
34
15
35
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
16
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
36
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/cpu_helper.c
18
--- a/target/riscv/debug.h
38
+++ b/target/riscv/cpu_helper.c
19
+++ b/target/riscv/debug.h
39
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
20
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_debug_excp_handler(CPUState *cs);
40
tval = env->bins;
21
bool riscv_cpu_debug_check_breakpoint(CPUState *cs);
41
break;
22
bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
42
case RISCV_EXCP_BREAKPOINT:
23
43
+ tval = env->badaddr;
24
+void riscv_trigger_init(CPURISCVState *env);
44
if (cs->watchpoint_hit) {
25
+
45
tval = cs->watchpoint_hit->hitaddr;
26
#endif /* RISCV_DEBUG_H */
46
cs->watchpoint_hit = NULL;
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 },
47
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
124
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
48
index XXXXXXX..XXXXXXX 100644
125
index XXXXXXX..XXXXXXX 100644
49
--- a/target/riscv/debug.c
126
--- a/target/riscv/debug.c
50
+++ b/target/riscv/debug.c
127
+++ b/target/riscv/debug.c
51
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
128
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
52
if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) {
129
53
/* check U/S/M bit against current privilege level */
130
return false;
54
if ((ctrl >> 3) & BIT(env->priv)) {
131
}
55
+ env->badaddr = pc;
132
+
56
return true;
133
+void riscv_trigger_init(CPURISCVState *env)
57
}
134
+{
58
}
135
+ target_ulong type2 = trigger_type(env, TRIGGER_TYPE_AD_MATCH);
59
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
136
+ int i;
60
if (env->virt_enabled) {
137
+
61
/* check VU/VS bit against current privilege level */
138
+ /* type 2 triggers */
62
if ((ctrl >> 23) & BIT(env->priv)) {
139
+ for (i = 0; i < TRIGGER_TYPE2_NUM; i++) {
63
+ env->badaddr = pc;
140
+ /*
64
return true;
141
+ * type = TRIGGER_TYPE_AD_MATCH
65
}
142
+ * dmode = 0 (both debug and M-mode can write tdata)
66
} else {
143
+ * maskmax = 0 (unimplemented, always 0)
67
/* check U/S/M bit against current privilege level */
144
+ * sizehi = 0 (match against any size, RV64 only)
68
if ((ctrl >> 3) & BIT(env->priv)) {
145
+ * hit = 0 (unimplemented, always 0)
69
+ env->badaddr = pc;
146
+ * select = 0 (always 0, perform match on address)
70
return true;
147
+ * timing = 0 (always 0, trigger before instruction)
71
}
148
+ * sizelo = 0 (match against any size)
72
}
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
+}
73
--
159
--
74
2.45.1
160
2.35.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
Privileged spec section 4.1.9 mentions:
3
Add a subsection to machine.c to migrate debug CSR state.
4
4
5
"When a trap is taken into S-mode, stval is written with
5
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
exception-specific information to assist software in handling the trap.
7
(...)
8
9
If stval is written with a nonzero value when a breakpoint,
10
address-misaligned, access-fault, or page-fault exception occurs on an
11
instruction fetch, load, or store, then stval will contain the faulting
12
virtual address."
13
14
A similar text is found for mtval in section 3.1.16.
15
16
Setting mtval/stval in this scenario is optional, but some softwares read
17
these regs when handling ebreaks.
18
19
Write 'badaddr' in all ebreak breakpoints to write the appropriate
20
'tval' during riscv_do_cpu_interrrupt().
21
22
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
23
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
24
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
7
Message-Id: <20220421003324.1134983-5-bmeng.cn@gmail.com>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-ID: <20240416230437.1869024-3-dbarboza@ventanamicro.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
---
9
---
29
target/riscv/insn_trans/trans_privileged.c.inc | 2 ++
10
target/riscv/machine.c | 32 ++++++++++++++++++++++++++++++++
30
1 file changed, 2 insertions(+)
11
1 file changed, 32 insertions(+)
31
12
32
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
13
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
33
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/insn_trans/trans_privileged.c.inc
15
--- a/target/riscv/machine.c
35
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
16
+++ b/target/riscv/machine.c
36
@@ -XXX,XX +XXX,XX @@ static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a)
17
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_kvmtimer = {
37
if (pre == 0x01f01013 && ebreak == 0x00100073 && post == 0x40705013) {
18
VMSTATE_UINT64(env.kvm_timer_time, RISCVCPU),
38
generate_exception(ctx, RISCV_EXCP_SEMIHOST);
19
VMSTATE_UINT64(env.kvm_timer_compare, RISCVCPU),
39
} else {
20
VMSTATE_UINT64(env.kvm_timer_state, RISCVCPU),
40
+ tcg_gen_st_tl(tcg_constant_tl(ebreak_addr), tcg_env,
21
+ VMSTATE_END_OF_LIST()
41
+ offsetof(CPURISCVState, badaddr));
22
+ }
42
generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
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()
43
}
54
}
44
return true;
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
};
45
--
64
--
46
2.45.1
65
2.35.1
diff view generated by jsdifflib
1
From: Yangyu Chen <cyy@cyyself.name>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
This code has a typo that writes zvkb to zvkg, causing users can't
3
Turn on native debug feature by default for all CPUs.
4
enable zvkb through the config. This patch gets this fixed.
5
4
6
Signed-off-by: Yangyu Chen <cyy@cyyself.name>
5
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Fixes: ea61ef7097d0 ("target/riscv: Move vector crypto extensions to riscv_cpu_extensions")
8
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Max Chou <max.chou@sifive.com>
7
Message-Id: <20220421003324.1134983-6-bmeng.cn@gmail.com>
11
Reviewed-by:  Weiwei Li <liwei1518@gmail.com>
12
Message-ID: <tencent_7E34EEF0F90B9A68BF38BEE09EC6D4877C0A@qq.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
9
---
16
target/riscv/cpu.c | 2 +-
10
target/riscv/cpu.c | 2 +-
17
1 file changed, 1 insertion(+), 1 deletion(-)
11
1 file changed, 1 insertion(+), 1 deletion(-)
18
12
19
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
13
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
20
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu.c
15
--- a/target/riscv/cpu.c
22
+++ b/target/riscv/cpu.c
16
+++ b/target/riscv/cpu.c
23
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
17
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = {
24
/* Vector cryptography extensions */
18
DEFINE_PROP_BOOL("Zve64f", RISCVCPU, cfg.ext_zve64f, false),
25
MULTI_EXT_CFG_BOOL("zvbb", ext_zvbb, false),
19
DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
26
MULTI_EXT_CFG_BOOL("zvbc", ext_zvbc, false),
20
DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
27
- MULTI_EXT_CFG_BOOL("zvkb", ext_zvkg, false),
21
- DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, false),
28
+ MULTI_EXT_CFG_BOOL("zvkb", ext_zvkb, false),
22
+ DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
29
MULTI_EXT_CFG_BOOL("zvkg", ext_zvkg, false),
23
30
MULTI_EXT_CFG_BOOL("zvkned", ext_zvkned, false),
24
DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
31
MULTI_EXT_CFG_BOOL("zvknha", ext_zvknha, false),
25
DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
32
--
26
--
33
2.45.1
27
2.35.1
34
35
diff view generated by jsdifflib
1
From: Max Chou <max.chou@sifive.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
The opfv_narrow_check needs to check the single width float operator by
3
This is now used by RISC-V as well. Update the comments.
4
require_rvf.
5
4
6
Signed-off-by: Max Chou <max.chou@sifive.com>
5
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Cc: qemu-stable <qemu-stable@nongnu.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-ID: <20240322092600.1198921-4-max.chou@sifive.com>
8
Message-Id: <20220421003324.1134983-7-bmeng.cn@gmail.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
10
---
12
target/riscv/insn_trans/trans_rvv.c.inc | 1 +
11
include/hw/core/tcg-cpu-ops.h | 1 +
13
1 file changed, 1 insertion(+)
12
1 file changed, 1 insertion(+)
14
13
15
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
14
diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/insn_trans/trans_rvv.c.inc
16
--- a/include/hw/core/tcg-cpu-ops.h
18
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
17
+++ b/include/hw/core/tcg-cpu-ops.h
19
@@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
18
@@ -XXX,XX +XXX,XX @@ struct TCGCPUOps {
20
static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
19
/**
21
{
20
* @debug_check_watchpoint: return true if the architectural
22
return opfv_narrow_check(s, a) &&
21
* watchpoint whose address has matched should really fire, used by ARM
23
+ require_rvf(s) &&
22
+ * and RISC-V
24
require_scale_rvf(s) &&
23
*/
25
(s->sew != MO_8);
24
bool (*debug_check_watchpoint)(CPUState *cpu, CPUWatchpoint *wp);
26
}
25
27
--
26
--
28
2.45.1
27
2.35.1
diff view generated by jsdifflib
1
From: Cheng Yang <yangcheng.work@foxmail.com>
1
From: Dylan Jhong <dylan@andestech.com>
2
2
3
Use qemu_fdt_setprop_u64() instead of qemu_fdt_setprop_cell()
3
The current riscv_load_fdt() forces fdt_load_addr to be placed at a dram address within 3GB,
4
to set the address of initrd in FDT to support 64-bit address.
4
but not all platforms have dram_base within 3GB.
5
5
6
Signed-off-by: Cheng Yang <yangcheng.work@foxmail.com>
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>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-ID: <tencent_A4482251DD0890F312758FA6B33F60815609@qq.com>
13
Message-Id: <20220419115945.37945-1-dylan@andestech.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
15
---
11
hw/riscv/boot.c | 4 ++--
16
include/hw/riscv/boot.h | 4 ++--
12
1 file changed, 2 insertions(+), 2 deletions(-)
17
hw/riscv/boot.c | 12 +++++++-----
18
2 files changed, 9 insertions(+), 7 deletions(-)
13
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,
14
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
39
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
15
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/boot.c
41
--- a/hw/riscv/boot.c
17
+++ b/hw/riscv/boot.c
42
+++ b/hw/riscv/boot.c
18
@@ -XXX,XX +XXX,XX @@ static void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
43
@@ -XXX,XX +XXX,XX @@ hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
19
/* Some RISC-V machines (e.g. opentitan) don't have a fdt. */
44
return *start + size;
20
if (fdt) {
45
}
21
end = start + size;
46
22
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start", start);
47
-uint32_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
23
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end", end);
48
+uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
24
+ qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-start", start);
49
{
25
+ qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-end", end);
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;
26
}
78
}
27
}
79
/* reset vector */
28
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)) {
29
--
90
--
30
2.45.1
91
2.35.1
diff view generated by jsdifflib