1
From: Alistair Francis <alistair.francis@wdc.com>
1
The following changes since commit 946e9bccf12f2bcc3ca471b820738fb22d14fc80:
2
2
3
The following changes since commit c5fbdd60cf1fb52f01bdfe342b6fa65d5343e1b1:
3
Merge tag 'samuel-thibault' of https://people.debian.org/~sthibault/qemu into staging (2022-09-06 08:31:24 -0400)
4
5
Merge tag 'qemu-sparc-20211121' of git://github.com/mcayland/qemu into staging (2021-11-21 14:12:25 +0100)
6
4
7
are available in the Git repository at:
5
are available in the Git repository at:
8
6
9
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20211122
7
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20220907
10
8
11
for you to fetch changes up to 526e7443027c71fe7b04c29df529e1f9f425f9e3:
9
for you to fetch changes up to f0551560b5c01b1dcbed1ac46ca0bd1155330f5f:
12
10
13
hw/misc/sifive_u_otp: Do not reset OTP content on hardware reset (2021-11-22 10:46:22 +1000)
11
target/riscv: Update the privilege field for sscofpmf CSRs (2022-09-07 09:19:15 +0200)
14
12
15
----------------------------------------------------------------
13
----------------------------------------------------------------
16
Seventh RISC-V PR for QEMU 6.2
14
First RISC-V PR for QEMU 7.2
17
15
18
- Deprecate IF_NONE for SiFive OTP
16
* Update [m|h]tinst CSR in interrupt handling
19
- Don't reset SiFive OTP content
17
* Force disable extensions if priv spec version does not match
18
* fix shifts shamt value for rv128c
19
* move zmmul out of the experimental
20
* virt: pass random seed to fdt
21
* Add checks for supported extension combinations
22
* Upgrade OpenSBI to v1.1
23
* Fix typo and restore Pointer Masking functionality for RISC-V
24
* Add mask agnostic behaviour (rvv_ma_all_1s) for vector extension
25
* Add Zihintpause support
26
* opentitan: bump opentitan version
27
* microchip_pfsoc: fix kernel panics due to missing peripherals
28
* Remove additional priv version check for mcountinhibit
29
* virt machine device tree improvements
30
* Add xicondops in ISA entry
31
* Use official extension names for AIA CSRs
20
32
21
----------------------------------------------------------------
33
----------------------------------------------------------------
22
Philippe Mathieu-Daudé (1):
34
Alexey Baturo (1):
23
hw/misc/sifive_u_otp: Do not reset OTP content on hardware reset
35
target/riscv: Fix typo and restore Pointer Masking functionality for RISC-V
24
36
25
Thomas Huth (1):
37
Anup Patel (3):
26
hw/misc/sifive_u_otp: Use IF_PFLASH for the OTP device instead of IF_NONE
38
target/riscv: Update [m|h]tinst CSR in riscv_cpu_do_interrupt()
39
target/riscv: Force disable extensions if priv spec version does not match
40
target/riscv: Use official extension names for AIA CSRs
27
41
28
docs/about/deprecated.rst | 6 ++++++
42
Atish Patra (9):
29
hw/misc/sifive_u_otp.c | 22 +++++++++++++---------
43
target/riscv: Remove additional priv version check for mcountinhibit
30
2 files changed, 19 insertions(+), 9 deletions(-)
44
hw/intc: Move mtimer/mtimecmp to aclint
45
target/riscv: Add stimecmp support
46
target/riscv: Add vstimecmp support
47
target/riscv: Add sscofpmf extension support
48
target/riscv: Simplify counter predicate function
49
target/riscv: Add few cache related PMU events
50
hw/riscv: virt: Add PMU DT node to the device tree
51
target/riscv: Update the privilege field for sscofpmf CSRs
31
52
53
Bin Meng (2):
54
roms/opensbi: Upgrade from v1.0 to v1.1
55
docs: List kvm as a supported accelerator on RISC-V
56
57
Conor Dooley (5):
58
hw/riscv: microchip_pfsoc: fix kernel panics due to missing peripherals
59
hw/riscv: virt: fix uart node name
60
hw/riscv: virt: fix the plic's address cells
61
hw/riscv: virt: fix syscon subnode paths
62
hw/core: fix platform bus node name
63
64
Daniel Henrique Barboza (1):
65
hw/riscv: remove 'fdt' param from riscv_setup_rom_reset_vec()
66
67
Dao Lu (1):
68
target/riscv: Add Zihintpause support
69
70
Frédéric Pétrot (1):
71
target/riscv: fix shifts shamt value for rv128c
72
73
Jason A. Donenfeld (1):
74
hw/riscv: virt: pass random seed to fdt
75
76
Rahul Pathak (1):
77
target/riscv: Add xicondops in ISA entry
78
79
Weiwei Li (8):
80
target/riscv: move zmmul out of the experimental properties
81
target/riscv: Add check for supported privilege mode combinations
82
target/riscv: H extension depends on I extension
83
target/riscv: Fix checkpatch warning may triggered in csr_ops table
84
target/riscv: Add check for csrs existed with U extension
85
target/riscv: Fix checks in hmode/hmode32
86
target/riscv: Simplify the check in hmode to reuse the check in riscv_csrrw_check
87
target/riscv: Fix priority of csr related check in riscv_csrrw_check
88
89
Wilfred Mallawa (1):
90
hw/riscv: opentitan: bump opentitan version
91
92
Yueh-Ting (eop) Chen (9):
93
target/riscv: rvv: Add mask agnostic for vv instructions
94
target/riscv: rvv: Add mask agnostic for vector load / store instructions
95
target/riscv: rvv: Add mask agnostic for vx instructions
96
target/riscv: rvv: Add mask agnostic for vector integer shift instructions
97
target/riscv: rvv: Add mask agnostic for vector integer comparison instructions
98
target/riscv: rvv: Add mask agnostic for vector fix-point arithmetic instructions
99
target/riscv: rvv: Add mask agnostic for vector floating-point instructions
100
target/riscv: rvv: Add mask agnostic for vector mask instructions
101
target/riscv: rvv: Add mask agnostic for vector permutation instructions
102
103
eopXD (1):
104
target/riscv: rvv: Add option 'rvv_ma_all_1s' to enable optional mask agnostic behavior
105
106
docs/about/build-platforms.rst | 2 +-
107
include/hw/intc/riscv_aclint.h | 2 +
108
include/hw/riscv/boot.h | 2 +-
109
include/hw/riscv/microchip_pfsoc.h | 14 +-
110
include/hw/riscv/opentitan.h | 11 +-
111
include/hw/riscv/virt.h | 1 +
112
include/hw/timer/ibex_timer.h | 2 +
113
target/riscv/cpu.h | 48 +-
114
target/riscv/cpu_bits.h | 63 ++
115
target/riscv/instmap.h | 45 +
116
target/riscv/internals.h | 5 +-
117
target/riscv/pmu.h | 8 +
118
target/riscv/time_helper.h | 30 +
119
target/riscv/insn16.decode | 7 +-
120
target/riscv/insn32.decode | 7 +-
121
disas/riscv.c | 27 +-
122
hw/core/sysbus-fdt.c | 2 +-
123
hw/intc/riscv_aclint.c | 48 +-
124
hw/intc/riscv_imsic.c | 4 +-
125
hw/riscv/boot.c | 4 +-
126
hw/riscv/microchip_pfsoc.c | 69 +-
127
hw/riscv/opentitan.c | 12 +-
128
hw/riscv/shakti_c.c | 3 +-
129
hw/riscv/spike.c | 2 +-
130
hw/riscv/virt.c | 45 +-
131
hw/timer/ibex_timer.c | 18 +-
132
target/riscv/cpu.c | 204 +++--
133
target/riscv/cpu_helper.c | 293 ++++++-
134
target/riscv/csr.c | 1038 +++++++++++++++---------
135
target/riscv/machine.c | 8 +-
136
target/riscv/pmu.c | 425 +++++++++-
137
target/riscv/time_helper.c | 114 +++
138
target/riscv/translate.c | 24 +-
139
target/riscv/vector_helper.c | 152 +++-
140
target/riscv/insn_trans/trans_rvi.c.inc | 16 +
141
target/riscv/insn_trans/trans_rvv.c.inc | 28 +
142
pc-bios/opensbi-riscv32-generic-fw_dynamic.bin | Bin 108504 -> 117704 bytes
143
pc-bios/opensbi-riscv64-generic-fw_dynamic.bin | Bin 105296 -> 115344 bytes
144
roms/opensbi | 2 +-
145
target/riscv/meson.build | 3 +-
146
40 files changed, 2229 insertions(+), 559 deletions(-)
147
create mode 100644 target/riscv/time_helper.h
148
create mode 100644 target/riscv/time_helper.c
149
diff view generated by jsdifflib
New patch
1
From: Anup Patel <apatel@ventanamicro.com>
1
2
3
We should write transformed instruction encoding of the trapped
4
instruction in [m|h]tinst CSR at time of taking trap as defined
5
by the RISC-V privileged specification v1.12.
6
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
9
Acked-by: dramforever <dramforever@live.com>
10
Message-Id: <20220630061150.905174-2-apatel@ventanamicro.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/cpu.h | 5 +
14
target/riscv/instmap.h | 45 +++++++
15
target/riscv/cpu_helper.c | 252 +++++++++++++++++++++++++++++++++++++-
16
3 files changed, 296 insertions(+), 6 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 @@ struct CPUArchState {
23
/* Signals whether the current exception occurred with two-stage address
24
translation active. */
25
bool two_stage_lookup;
26
+ /*
27
+ * Signals whether the current exception occurred while doing two-stage
28
+ * address translation for the VS-stage page table walk.
29
+ */
30
+ bool two_stage_indirect_lookup;
31
32
target_ulong scounteren;
33
target_ulong mcounteren;
34
diff --git a/target/riscv/instmap.h b/target/riscv/instmap.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/riscv/instmap.h
37
+++ b/target/riscv/instmap.h
38
@@ -XXX,XX +XXX,XX @@ enum {
39
OPC_RISC_CSRRWI = OPC_RISC_SYSTEM | (0x5 << 12),
40
OPC_RISC_CSRRSI = OPC_RISC_SYSTEM | (0x6 << 12),
41
OPC_RISC_CSRRCI = OPC_RISC_SYSTEM | (0x7 << 12),
42
+
43
+ OPC_RISC_HLVHSV = OPC_RISC_SYSTEM | (0x4 << 12),
44
};
45
46
#define MASK_OP_FP_LOAD(op) (MASK_OP_MAJOR(op) | (op & (0x7 << 12)))
47
@@ -XXX,XX +XXX,XX @@ enum {
48
| (extract32(inst, 12, 8) << 12) \
49
| (sextract64(inst, 31, 1) << 20))
50
51
+#define GET_FUNCT3(inst) extract32(inst, 12, 3)
52
+#define GET_FUNCT7(inst) extract32(inst, 25, 7)
53
#define GET_RM(inst) extract32(inst, 12, 3)
54
#define GET_RS3(inst) extract32(inst, 27, 5)
55
#define GET_RS1(inst) extract32(inst, 15, 5)
56
#define GET_RS2(inst) extract32(inst, 20, 5)
57
#define GET_RD(inst) extract32(inst, 7, 5)
58
#define GET_IMM(inst) sextract64(inst, 20, 12)
59
+#define SET_RS1(inst, val) deposit32(inst, 15, 5, val)
60
+#define SET_RS2(inst, val) deposit32(inst, 20, 5, val)
61
+#define SET_RD(inst, val) deposit32(inst, 7, 5, val)
62
+#define SET_I_IMM(inst, val) deposit32(inst, 20, 12, val)
63
+#define SET_S_IMM(inst, val) \
64
+ deposit32(deposit32(inst, 7, 5, val), 25, 7, (val) >> 5)
65
66
/* RVC decoding macros */
67
#define GET_C_IMM(inst) (extract32(inst, 2, 5) \
68
@@ -XXX,XX +XXX,XX @@ enum {
69
| (extract32(inst, 5, 1) << 6))
70
#define GET_C_LD_IMM(inst) ((extract16(inst, 10, 3) << 3) \
71
| (extract16(inst, 5, 2) << 6))
72
+#define GET_C_SW_IMM(inst) GET_C_LW_IMM(inst)
73
+#define GET_C_SD_IMM(inst) GET_C_LD_IMM(inst)
74
#define GET_C_J_IMM(inst) ((extract32(inst, 3, 3) << 1) \
75
| (extract32(inst, 11, 1) << 4) \
76
| (extract32(inst, 2, 1) << 5) \
77
@@ -XXX,XX +XXX,XX @@ enum {
78
#define GET_C_RS1S(inst) (8 + extract16(inst, 7, 3))
79
#define GET_C_RS2S(inst) (8 + extract16(inst, 2, 3))
80
81
+#define GET_C_FUNC(inst) extract32(inst, 13, 3)
82
+#define GET_C_OP(inst) extract32(inst, 0, 2)
83
+
84
+enum {
85
+ /* RVC Quadrants */
86
+ OPC_RISC_C_OP_QUAD0 = 0x0,
87
+ OPC_RISC_C_OP_QUAD1 = 0x1,
88
+ OPC_RISC_C_OP_QUAD2 = 0x2
89
+};
90
+
91
+enum {
92
+ /* RVC Quadrant 0 */
93
+ OPC_RISC_C_FUNC_ADDI4SPN = 0x0,
94
+ OPC_RISC_C_FUNC_FLD_LQ = 0x1,
95
+ OPC_RISC_C_FUNC_LW = 0x2,
96
+ OPC_RISC_C_FUNC_FLW_LD = 0x3,
97
+ OPC_RISC_C_FUNC_FSD_SQ = 0x5,
98
+ OPC_RISC_C_FUNC_SW = 0x6,
99
+ OPC_RISC_C_FUNC_FSW_SD = 0x7
100
+};
101
+
102
+enum {
103
+ /* RVC Quadrant 2 */
104
+ OPC_RISC_C_FUNC_SLLI_SLLI64 = 0x0,
105
+ OPC_RISC_C_FUNC_FLDSP_LQSP = 0x1,
106
+ OPC_RISC_C_FUNC_LWSP = 0x2,
107
+ OPC_RISC_C_FUNC_FLWSP_LDSP = 0x3,
108
+ OPC_RISC_C_FUNC_JR_MV_EBREAK_JALR_ADD = 0x4,
109
+ OPC_RISC_C_FUNC_FSDSP_SQSP = 0x5,
110
+ OPC_RISC_C_FUNC_SWSP = 0x6,
111
+ OPC_RISC_C_FUNC_FSWSP_SDSP = 0x7
112
+};
113
+
114
#endif
115
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
116
index XXXXXXX..XXXXXXX 100644
117
--- a/target/riscv/cpu_helper.c
118
+++ b/target/riscv/cpu_helper.c
119
@@ -XXX,XX +XXX,XX @@
120
#include "qemu/main-loop.h"
121
#include "cpu.h"
122
#include "exec/exec-all.h"
123
+#include "instmap.h"
124
#include "tcg/tcg-op.h"
125
#include "trace.h"
126
#include "semihosting/common-semi.h"
127
@@ -XXX,XX +XXX,XX @@ restart:
128
129
static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
130
MMUAccessType access_type, bool pmp_violation,
131
- bool first_stage, bool two_stage)
132
+ bool first_stage, bool two_stage,
133
+ bool two_stage_indirect)
134
{
135
CPUState *cs = env_cpu(env);
136
int page_fault_exceptions, vm;
137
@@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
138
}
139
env->badaddr = address;
140
env->two_stage_lookup = two_stage;
141
+ env->two_stage_indirect_lookup = two_stage_indirect;
142
}
143
144
hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
145
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
146
env->badaddr = addr;
147
env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
148
riscv_cpu_two_stage_lookup(mmu_idx);
149
+ env->two_stage_indirect_lookup = false;
150
cpu_loop_exit_restore(cs, retaddr);
151
}
152
153
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
154
env->badaddr = addr;
155
env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
156
riscv_cpu_two_stage_lookup(mmu_idx);
157
+ env->two_stage_indirect_lookup = false;
158
cpu_loop_exit_restore(cs, retaddr);
159
}
160
161
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
162
bool pmp_violation = false;
163
bool first_stage_error = true;
164
bool two_stage_lookup = false;
165
+ bool two_stage_indirect_error = false;
166
int ret = TRANSLATE_FAIL;
167
int mode = mmu_idx;
168
/* default TLB page size */
169
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
170
*/
171
if (ret == TRANSLATE_G_STAGE_FAIL) {
172
first_stage_error = false;
173
+ two_stage_indirect_error = true;
174
access_type = MMU_DATA_LOAD;
175
}
176
177
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
178
raise_mmu_exception(env, address, access_type, pmp_violation,
179
first_stage_error,
180
riscv_cpu_virt_enabled(env) ||
181
- riscv_cpu_two_stage_lookup(mmu_idx));
182
+ riscv_cpu_two_stage_lookup(mmu_idx),
183
+ two_stage_indirect_error);
184
cpu_loop_exit_restore(cs, retaddr);
185
}
186
187
return true;
188
}
189
+
190
+static target_ulong riscv_transformed_insn(CPURISCVState *env,
191
+ target_ulong insn,
192
+ target_ulong taddr)
193
+{
194
+ target_ulong xinsn = 0;
195
+ target_ulong access_rs1 = 0, access_imm = 0, access_size = 0;
196
+
197
+ /*
198
+ * Only Quadrant 0 and Quadrant 2 of RVC instruction space need to
199
+ * be uncompressed. The Quadrant 1 of RVC instruction space need
200
+ * not be transformed because these instructions won't generate
201
+ * any load/store trap.
202
+ */
203
+
204
+ if ((insn & 0x3) != 0x3) {
205
+ /* Transform 16bit instruction into 32bit instruction */
206
+ switch (GET_C_OP(insn)) {
207
+ case OPC_RISC_C_OP_QUAD0: /* Quadrant 0 */
208
+ switch (GET_C_FUNC(insn)) {
209
+ case OPC_RISC_C_FUNC_FLD_LQ:
210
+ if (riscv_cpu_xlen(env) != 128) { /* C.FLD (RV32/64) */
211
+ xinsn = OPC_RISC_FLD;
212
+ xinsn = SET_RD(xinsn, GET_C_RS2S(insn));
213
+ access_rs1 = GET_C_RS1S(insn);
214
+ access_imm = GET_C_LD_IMM(insn);
215
+ access_size = 8;
216
+ }
217
+ break;
218
+ case OPC_RISC_C_FUNC_LW: /* C.LW */
219
+ xinsn = OPC_RISC_LW;
220
+ xinsn = SET_RD(xinsn, GET_C_RS2S(insn));
221
+ access_rs1 = GET_C_RS1S(insn);
222
+ access_imm = GET_C_LW_IMM(insn);
223
+ access_size = 4;
224
+ break;
225
+ case OPC_RISC_C_FUNC_FLW_LD:
226
+ if (riscv_cpu_xlen(env) == 32) { /* C.FLW (RV32) */
227
+ xinsn = OPC_RISC_FLW;
228
+ xinsn = SET_RD(xinsn, GET_C_RS2S(insn));
229
+ access_rs1 = GET_C_RS1S(insn);
230
+ access_imm = GET_C_LW_IMM(insn);
231
+ access_size = 4;
232
+ } else { /* C.LD (RV64/RV128) */
233
+ xinsn = OPC_RISC_LD;
234
+ xinsn = SET_RD(xinsn, GET_C_RS2S(insn));
235
+ access_rs1 = GET_C_RS1S(insn);
236
+ access_imm = GET_C_LD_IMM(insn);
237
+ access_size = 8;
238
+ }
239
+ break;
240
+ case OPC_RISC_C_FUNC_FSD_SQ:
241
+ if (riscv_cpu_xlen(env) != 128) { /* C.FSD (RV32/64) */
242
+ xinsn = OPC_RISC_FSD;
243
+ xinsn = SET_RS2(xinsn, GET_C_RS2S(insn));
244
+ access_rs1 = GET_C_RS1S(insn);
245
+ access_imm = GET_C_SD_IMM(insn);
246
+ access_size = 8;
247
+ }
248
+ break;
249
+ case OPC_RISC_C_FUNC_SW: /* C.SW */
250
+ xinsn = OPC_RISC_SW;
251
+ xinsn = SET_RS2(xinsn, GET_C_RS2S(insn));
252
+ access_rs1 = GET_C_RS1S(insn);
253
+ access_imm = GET_C_SW_IMM(insn);
254
+ access_size = 4;
255
+ break;
256
+ case OPC_RISC_C_FUNC_FSW_SD:
257
+ if (riscv_cpu_xlen(env) == 32) { /* C.FSW (RV32) */
258
+ xinsn = OPC_RISC_FSW;
259
+ xinsn = SET_RS2(xinsn, GET_C_RS2S(insn));
260
+ access_rs1 = GET_C_RS1S(insn);
261
+ access_imm = GET_C_SW_IMM(insn);
262
+ access_size = 4;
263
+ } else { /* C.SD (RV64/RV128) */
264
+ xinsn = OPC_RISC_SD;
265
+ xinsn = SET_RS2(xinsn, GET_C_RS2S(insn));
266
+ access_rs1 = GET_C_RS1S(insn);
267
+ access_imm = GET_C_SD_IMM(insn);
268
+ access_size = 8;
269
+ }
270
+ break;
271
+ default:
272
+ break;
273
+ }
274
+ break;
275
+ case OPC_RISC_C_OP_QUAD2: /* Quadrant 2 */
276
+ switch (GET_C_FUNC(insn)) {
277
+ case OPC_RISC_C_FUNC_FLDSP_LQSP:
278
+ if (riscv_cpu_xlen(env) != 128) { /* C.FLDSP (RV32/64) */
279
+ xinsn = OPC_RISC_FLD;
280
+ xinsn = SET_RD(xinsn, GET_C_RD(insn));
281
+ access_rs1 = 2;
282
+ access_imm = GET_C_LDSP_IMM(insn);
283
+ access_size = 8;
284
+ }
285
+ break;
286
+ case OPC_RISC_C_FUNC_LWSP: /* C.LWSP */
287
+ xinsn = OPC_RISC_LW;
288
+ xinsn = SET_RD(xinsn, GET_C_RD(insn));
289
+ access_rs1 = 2;
290
+ access_imm = GET_C_LWSP_IMM(insn);
291
+ access_size = 4;
292
+ break;
293
+ case OPC_RISC_C_FUNC_FLWSP_LDSP:
294
+ if (riscv_cpu_xlen(env) == 32) { /* C.FLWSP (RV32) */
295
+ xinsn = OPC_RISC_FLW;
296
+ xinsn = SET_RD(xinsn, GET_C_RD(insn));
297
+ access_rs1 = 2;
298
+ access_imm = GET_C_LWSP_IMM(insn);
299
+ access_size = 4;
300
+ } else { /* C.LDSP (RV64/RV128) */
301
+ xinsn = OPC_RISC_LD;
302
+ xinsn = SET_RD(xinsn, GET_C_RD(insn));
303
+ access_rs1 = 2;
304
+ access_imm = GET_C_LDSP_IMM(insn);
305
+ access_size = 8;
306
+ }
307
+ break;
308
+ case OPC_RISC_C_FUNC_FSDSP_SQSP:
309
+ if (riscv_cpu_xlen(env) != 128) { /* C.FSDSP (RV32/64) */
310
+ xinsn = OPC_RISC_FSD;
311
+ xinsn = SET_RS2(xinsn, GET_C_RS2(insn));
312
+ access_rs1 = 2;
313
+ access_imm = GET_C_SDSP_IMM(insn);
314
+ access_size = 8;
315
+ }
316
+ break;
317
+ case OPC_RISC_C_FUNC_SWSP: /* C.SWSP */
318
+ xinsn = OPC_RISC_SW;
319
+ xinsn = SET_RS2(xinsn, GET_C_RS2(insn));
320
+ access_rs1 = 2;
321
+ access_imm = GET_C_SWSP_IMM(insn);
322
+ access_size = 4;
323
+ break;
324
+ case 7:
325
+ if (riscv_cpu_xlen(env) == 32) { /* C.FSWSP (RV32) */
326
+ xinsn = OPC_RISC_FSW;
327
+ xinsn = SET_RS2(xinsn, GET_C_RS2(insn));
328
+ access_rs1 = 2;
329
+ access_imm = GET_C_SWSP_IMM(insn);
330
+ access_size = 4;
331
+ } else { /* C.SDSP (RV64/RV128) */
332
+ xinsn = OPC_RISC_SD;
333
+ xinsn = SET_RS2(xinsn, GET_C_RS2(insn));
334
+ access_rs1 = 2;
335
+ access_imm = GET_C_SDSP_IMM(insn);
336
+ access_size = 8;
337
+ }
338
+ break;
339
+ default:
340
+ break;
341
+ }
342
+ break;
343
+ default:
344
+ break;
345
+ }
346
+
347
+ /*
348
+ * Clear Bit1 of transformed instruction to indicate that
349
+ * original insruction was a 16bit instruction
350
+ */
351
+ xinsn &= ~((target_ulong)0x2);
352
+ } else {
353
+ /* Transform 32bit (or wider) instructions */
354
+ switch (MASK_OP_MAJOR(insn)) {
355
+ case OPC_RISC_ATOMIC:
356
+ xinsn = insn;
357
+ access_rs1 = GET_RS1(insn);
358
+ access_size = 1 << GET_FUNCT3(insn);
359
+ break;
360
+ case OPC_RISC_LOAD:
361
+ case OPC_RISC_FP_LOAD:
362
+ xinsn = SET_I_IMM(insn, 0);
363
+ access_rs1 = GET_RS1(insn);
364
+ access_imm = GET_IMM(insn);
365
+ access_size = 1 << GET_FUNCT3(insn);
366
+ break;
367
+ case OPC_RISC_STORE:
368
+ case OPC_RISC_FP_STORE:
369
+ xinsn = SET_S_IMM(insn, 0);
370
+ access_rs1 = GET_RS1(insn);
371
+ access_imm = GET_STORE_IMM(insn);
372
+ access_size = 1 << GET_FUNCT3(insn);
373
+ break;
374
+ case OPC_RISC_SYSTEM:
375
+ if (MASK_OP_SYSTEM(insn) == OPC_RISC_HLVHSV) {
376
+ xinsn = insn;
377
+ access_rs1 = GET_RS1(insn);
378
+ access_size = 1 << ((GET_FUNCT7(insn) >> 1) & 0x3);
379
+ access_size = 1 << access_size;
380
+ }
381
+ break;
382
+ default:
383
+ break;
384
+ }
385
+ }
386
+
387
+ if (access_size) {
388
+ xinsn = SET_RS1(xinsn, (taddr - (env->gpr[access_rs1] + access_imm)) &
389
+ (access_size - 1));
390
+ }
391
+
392
+ return xinsn;
393
+}
394
#endif /* !CONFIG_USER_ONLY */
395
396
/*
397
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
398
target_ulong cause = cs->exception_index & RISCV_EXCP_INT_MASK;
399
uint64_t deleg = async ? env->mideleg : env->medeleg;
400
target_ulong tval = 0;
401
+ target_ulong tinst = 0;
402
target_ulong htval = 0;
403
target_ulong mtval2 = 0;
404
405
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
406
if (!async) {
407
/* set tval to badaddr for traps with address information */
408
switch (cause) {
409
- case RISCV_EXCP_INST_GUEST_PAGE_FAULT:
410
case RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT:
411
case RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT:
412
- case RISCV_EXCP_INST_ADDR_MIS:
413
- case RISCV_EXCP_INST_ACCESS_FAULT:
414
case RISCV_EXCP_LOAD_ADDR_MIS:
415
case RISCV_EXCP_STORE_AMO_ADDR_MIS:
416
case RISCV_EXCP_LOAD_ACCESS_FAULT:
417
case RISCV_EXCP_STORE_AMO_ACCESS_FAULT:
418
- case RISCV_EXCP_INST_PAGE_FAULT:
419
case RISCV_EXCP_LOAD_PAGE_FAULT:
420
case RISCV_EXCP_STORE_PAGE_FAULT:
421
write_gva = env->two_stage_lookup;
422
tval = env->badaddr;
423
+ if (env->two_stage_indirect_lookup) {
424
+ /*
425
+ * special pseudoinstruction for G-stage fault taken while
426
+ * doing VS-stage page table walk.
427
+ */
428
+ tinst = (riscv_cpu_xlen(env) == 32) ? 0x00002000 : 0x00003000;
429
+ } else {
430
+ /*
431
+ * The "Addr. Offset" field in transformed instruction is
432
+ * non-zero only for misaligned access.
433
+ */
434
+ tinst = riscv_transformed_insn(env, env->bins, tval);
435
+ }
436
+ break;
437
+ case RISCV_EXCP_INST_GUEST_PAGE_FAULT:
438
+ case RISCV_EXCP_INST_ADDR_MIS:
439
+ case RISCV_EXCP_INST_ACCESS_FAULT:
440
+ case RISCV_EXCP_INST_PAGE_FAULT:
441
+ write_gva = env->two_stage_lookup;
442
+ tval = env->badaddr;
443
+ if (env->two_stage_indirect_lookup) {
444
+ /*
445
+ * special pseudoinstruction for G-stage fault taken while
446
+ * doing VS-stage page table walk.
447
+ */
448
+ tinst = (riscv_cpu_xlen(env) == 32) ? 0x00002000 : 0x00003000;
449
+ }
450
break;
451
case RISCV_EXCP_ILLEGAL_INST:
452
case RISCV_EXCP_VIRT_INSTRUCTION_FAULT:
453
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
454
env->sepc = env->pc;
455
env->stval = tval;
456
env->htval = htval;
457
+ env->htinst = tinst;
458
env->pc = (env->stvec >> 2 << 2) +
459
((async && (env->stvec & 3) == 1) ? cause * 4 : 0);
460
riscv_cpu_set_mode(env, PRV_S);
461
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
462
env->mepc = env->pc;
463
env->mtval = tval;
464
env->mtval2 = mtval2;
465
+ env->mtinst = tinst;
466
env->pc = (env->mtvec >> 2 << 2) +
467
((async && (env->mtvec & 3) == 1) ? cause * 4 : 0);
468
riscv_cpu_set_mode(env, PRV_M);
469
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
470
*/
471
472
env->two_stage_lookup = false;
473
+ env->two_stage_indirect_lookup = false;
474
#endif
475
cs->exception_index = RISCV_EXCP_NONE; /* mark handled to qemu */
476
}
477
--
478
2.37.2
diff view generated by jsdifflib
New patch
1
From: Anup Patel <apatel@ventanamicro.com>
1
2
3
We should disable extensions in riscv_cpu_realize() if minimum required
4
priv spec version is not satisfied. This also ensures that machines with
5
priv spec v1.11 (or lower) cannot enable H, V, and various multi-letter
6
extensions.
7
8
Fixes: a775398be2e9 ("target/riscv: Add isa extenstion strings to the device tree")
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
11
Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
12
Message-Id: <20220630061150.905174-3-apatel@ventanamicro.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
target/riscv/cpu.c | 150 ++++++++++++++++++++++++++++-----------------
16
1 file changed, 94 insertions(+), 56 deletions(-)
17
18
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/cpu.c
21
+++ b/target/riscv/cpu.c
22
@@ -XXX,XX +XXX,XX @@ static const char riscv_single_letter_exts[] = "IEMAFDQCPVH";
23
24
struct isa_ext_data {
25
const char *name;
26
- bool enabled;
27
+ bool multi_letter;
28
+ int min_version;
29
+ int ext_enable_offset;
30
};
31
32
+#define ISA_EXT_DATA_ENTRY(_name, _m_letter, _min_ver, _prop) \
33
+{#_name, _m_letter, _min_ver, offsetof(struct RISCVCPUConfig, _prop)}
34
+
35
+/**
36
+ * Here are the ordering rules of extension naming defined by RISC-V
37
+ * specification :
38
+ * 1. All extensions should be separated from other multi-letter extensions
39
+ * by an underscore.
40
+ * 2. The first letter following the 'Z' conventionally indicates the most
41
+ * closely related alphabetical extension category, IMAFDQLCBKJTPVH.
42
+ * If multiple 'Z' extensions are named, they should be ordered first
43
+ * by category, then alphabetically within a category.
44
+ * 3. Standard supervisor-level extensions (starts with 'S') should be
45
+ * listed after standard unprivileged extensions. If multiple
46
+ * supervisor-level extensions are listed, they should be ordered
47
+ * alphabetically.
48
+ * 4. Non-standard extensions (starts with 'X') must be listed after all
49
+ * standard extensions. They must be separated from other multi-letter
50
+ * extensions by an underscore.
51
+ */
52
+static const struct isa_ext_data isa_edata_arr[] = {
53
+ ISA_EXT_DATA_ENTRY(h, false, PRIV_VERSION_1_12_0, ext_h),
54
+ ISA_EXT_DATA_ENTRY(v, false, PRIV_VERSION_1_12_0, ext_v),
55
+ ISA_EXT_DATA_ENTRY(zicsr, true, PRIV_VERSION_1_10_0, ext_icsr),
56
+ ISA_EXT_DATA_ENTRY(zifencei, true, PRIV_VERSION_1_10_0, ext_ifencei),
57
+ ISA_EXT_DATA_ENTRY(zfh, true, PRIV_VERSION_1_12_0, ext_zfh),
58
+ ISA_EXT_DATA_ENTRY(zfhmin, true, PRIV_VERSION_1_12_0, ext_zfhmin),
59
+ ISA_EXT_DATA_ENTRY(zfinx, true, PRIV_VERSION_1_12_0, ext_zfinx),
60
+ ISA_EXT_DATA_ENTRY(zdinx, true, PRIV_VERSION_1_12_0, ext_zdinx),
61
+ ISA_EXT_DATA_ENTRY(zba, true, PRIV_VERSION_1_12_0, ext_zba),
62
+ ISA_EXT_DATA_ENTRY(zbb, true, PRIV_VERSION_1_12_0, ext_zbb),
63
+ ISA_EXT_DATA_ENTRY(zbc, true, PRIV_VERSION_1_12_0, ext_zbc),
64
+ ISA_EXT_DATA_ENTRY(zbkb, true, PRIV_VERSION_1_12_0, ext_zbkb),
65
+ ISA_EXT_DATA_ENTRY(zbkc, true, PRIV_VERSION_1_12_0, ext_zbkc),
66
+ ISA_EXT_DATA_ENTRY(zbkx, true, PRIV_VERSION_1_12_0, ext_zbkx),
67
+ ISA_EXT_DATA_ENTRY(zbs, true, PRIV_VERSION_1_12_0, ext_zbs),
68
+ ISA_EXT_DATA_ENTRY(zk, true, PRIV_VERSION_1_12_0, ext_zk),
69
+ ISA_EXT_DATA_ENTRY(zkn, true, PRIV_VERSION_1_12_0, ext_zkn),
70
+ ISA_EXT_DATA_ENTRY(zknd, true, PRIV_VERSION_1_12_0, ext_zknd),
71
+ ISA_EXT_DATA_ENTRY(zkne, true, PRIV_VERSION_1_12_0, ext_zkne),
72
+ ISA_EXT_DATA_ENTRY(zknh, true, PRIV_VERSION_1_12_0, ext_zknh),
73
+ ISA_EXT_DATA_ENTRY(zkr, true, PRIV_VERSION_1_12_0, ext_zkr),
74
+ ISA_EXT_DATA_ENTRY(zks, true, PRIV_VERSION_1_12_0, ext_zks),
75
+ ISA_EXT_DATA_ENTRY(zksed, true, PRIV_VERSION_1_12_0, ext_zksed),
76
+ ISA_EXT_DATA_ENTRY(zksh, true, PRIV_VERSION_1_12_0, ext_zksh),
77
+ ISA_EXT_DATA_ENTRY(zkt, true, PRIV_VERSION_1_12_0, ext_zkt),
78
+ ISA_EXT_DATA_ENTRY(zve32f, true, PRIV_VERSION_1_12_0, ext_zve32f),
79
+ ISA_EXT_DATA_ENTRY(zve64f, true, PRIV_VERSION_1_12_0, ext_zve64f),
80
+ ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
81
+ ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
82
+ ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval),
83
+ ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
84
+ ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
85
+};
86
+
87
+static bool isa_ext_is_enabled(RISCVCPU *cpu,
88
+ const struct isa_ext_data *edata)
89
+{
90
+ bool *ext_enabled = (void *)&cpu->cfg + edata->ext_enable_offset;
91
+
92
+ return *ext_enabled;
93
+}
94
+
95
+static void isa_ext_update_enabled(RISCVCPU *cpu,
96
+ const struct isa_ext_data *edata, bool en)
97
+{
98
+ bool *ext_enabled = (void *)&cpu->cfg + edata->ext_enable_offset;
99
+
100
+ *ext_enabled = en;
101
+}
102
+
103
const char * const riscv_int_regnames[] = {
104
"x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1",
105
"x7/t2", "x8/s0", "x9/s1", "x10/a0", "x11/a1", "x12/a2", "x13/a3",
106
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
107
CPURISCVState *env = &cpu->env;
108
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
109
CPUClass *cc = CPU_CLASS(mcc);
110
- int priv_version = -1;
111
+ int i, priv_version = -1;
112
Error *local_err = NULL;
113
114
cpu_exec_realizefn(cs, &local_err);
115
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
116
set_priv_version(env, priv_version);
117
}
118
119
+ /* Force disable extensions if priv spec version does not match */
120
+ for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
121
+ if (isa_ext_is_enabled(cpu, &isa_edata_arr[i]) &&
122
+ (env->priv_ver < isa_edata_arr[i].min_version)) {
123
+ isa_ext_update_enabled(cpu, &isa_edata_arr[i], false);
124
+#ifndef CONFIG_USER_ONLY
125
+ warn_report("disabling %s extension for hart 0x%lx because "
126
+ "privilege spec version does not match",
127
+ isa_edata_arr[i].name, (unsigned long)env->mhartid);
128
+#else
129
+ warn_report("disabling %s extension because "
130
+ "privilege spec version does not match",
131
+ isa_edata_arr[i].name);
132
+#endif
133
+ }
134
+ }
135
+
136
if (cpu->cfg.mmu) {
137
riscv_set_feature(env, RISCV_FEATURE_MMU);
138
}
139
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
140
device_class_set_props(dc, riscv_cpu_properties);
141
}
142
143
-#define ISA_EDATA_ENTRY(name, prop) {#name, cpu->cfg.prop}
144
-
145
static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str, int max_str_len)
146
{
147
char *old = *isa_str;
148
char *new = *isa_str;
149
int i;
150
151
- /**
152
- * Here are the ordering rules of extension naming defined by RISC-V
153
- * specification :
154
- * 1. All extensions should be separated from other multi-letter extensions
155
- * by an underscore.
156
- * 2. The first letter following the 'Z' conventionally indicates the most
157
- * closely related alphabetical extension category, IMAFDQLCBKJTPVH.
158
- * If multiple 'Z' extensions are named, they should be ordered first
159
- * by category, then alphabetically within a category.
160
- * 3. Standard supervisor-level extensions (starts with 'S') should be
161
- * listed after standard unprivileged extensions. If multiple
162
- * supervisor-level extensions are listed, they should be ordered
163
- * alphabetically.
164
- * 4. Non-standard extensions (starts with 'X') must be listed after all
165
- * standard extensions. They must be separated from other multi-letter
166
- * extensions by an underscore.
167
- */
168
- struct isa_ext_data isa_edata_arr[] = {
169
- ISA_EDATA_ENTRY(zicsr, ext_icsr),
170
- ISA_EDATA_ENTRY(zifencei, ext_ifencei),
171
- ISA_EDATA_ENTRY(zmmul, ext_zmmul),
172
- ISA_EDATA_ENTRY(zfh, ext_zfh),
173
- ISA_EDATA_ENTRY(zfhmin, ext_zfhmin),
174
- ISA_EDATA_ENTRY(zfinx, ext_zfinx),
175
- ISA_EDATA_ENTRY(zdinx, ext_zdinx),
176
- ISA_EDATA_ENTRY(zba, ext_zba),
177
- ISA_EDATA_ENTRY(zbb, ext_zbb),
178
- ISA_EDATA_ENTRY(zbc, ext_zbc),
179
- ISA_EDATA_ENTRY(zbkb, ext_zbkb),
180
- ISA_EDATA_ENTRY(zbkc, ext_zbkc),
181
- ISA_EDATA_ENTRY(zbkx, ext_zbkx),
182
- ISA_EDATA_ENTRY(zbs, ext_zbs),
183
- ISA_EDATA_ENTRY(zk, ext_zk),
184
- ISA_EDATA_ENTRY(zkn, ext_zkn),
185
- ISA_EDATA_ENTRY(zknd, ext_zknd),
186
- ISA_EDATA_ENTRY(zkne, ext_zkne),
187
- ISA_EDATA_ENTRY(zknh, ext_zknh),
188
- ISA_EDATA_ENTRY(zkr, ext_zkr),
189
- ISA_EDATA_ENTRY(zks, ext_zks),
190
- ISA_EDATA_ENTRY(zksed, ext_zksed),
191
- ISA_EDATA_ENTRY(zksh, ext_zksh),
192
- ISA_EDATA_ENTRY(zkt, ext_zkt),
193
- ISA_EDATA_ENTRY(zve32f, ext_zve32f),
194
- ISA_EDATA_ENTRY(zve64f, ext_zve64f),
195
- ISA_EDATA_ENTRY(zhinx, ext_zhinx),
196
- ISA_EDATA_ENTRY(zhinxmin, ext_zhinxmin),
197
- ISA_EDATA_ENTRY(svinval, ext_svinval),
198
- ISA_EDATA_ENTRY(svnapot, ext_svnapot),
199
- ISA_EDATA_ENTRY(svpbmt, ext_svpbmt),
200
- };
201
-
202
for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
203
- if (isa_edata_arr[i].enabled) {
204
+ if (isa_edata_arr[i].multi_letter &&
205
+ isa_ext_is_enabled(cpu, &isa_edata_arr[i])) {
206
new = g_strconcat(old, "_", isa_edata_arr[i].name, NULL);
207
g_free(old);
208
old = new;
209
--
210
2.37.2
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr>
2
2
3
Once a "One Time Programmable" is programmed, it shouldn't be reset.
3
For rv128c shifts, a shamt of 0 is a shamt of 64, while for rv32c/rv64c
4
it stays 0 and is a hint instruction that does not change processor state.
5
For rv128c right shifts, the 6-bit shamt is in addition sign extended to
6
7 bits.
4
7
5
Do not re-initialize the OTP content in the DeviceReset handler,
8
Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr>
6
initialize it once in the DeviceRealize one.
9
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
7
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Fixes: 9fb45c62ae8 ("riscv: sifive: Implement a model for SiFive FU540 OTP")
11
Message-Id: <20220710110451.245567-1-frederic.petrot@univ-grenoble-alpes.fr>
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-Id: <20211119104757.331579-1-f4bug@amsat.org>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
13
---
14
hw/misc/sifive_u_otp.c | 13 +++++--------
14
target/riscv/insn16.decode | 7 ++++---
15
1 file changed, 5 insertions(+), 8 deletions(-)
15
disas/riscv.c | 27 +++++++++++++++++++++------
16
target/riscv/translate.c | 20 ++++++++++++++++++--
17
3 files changed, 43 insertions(+), 11 deletions(-)
16
18
17
diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c
19
diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
18
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/misc/sifive_u_otp.c
21
--- a/target/riscv/insn16.decode
20
+++ b/hw/misc/sifive_u_otp.c
22
+++ b/target/riscv/insn16.decode
21
@@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_realize(DeviceState *dev, Error **errp)
23
@@ -XXX,XX +XXX,XX @@
22
24
%imm_cb 12:s1 5:2 2:1 10:2 3:2 !function=ex_shift_1
23
if (blk_pread(s->blk, 0, s->fuse, filesize) != filesize) {
25
%imm_cj 12:s1 8:1 9:2 6:1 7:1 2:1 11:1 3:3 !function=ex_shift_1
24
error_setg(errp, "failed to read the initial flash content");
26
25
+ return;
27
-%shimm_6bit 12:1 2:5 !function=ex_rvc_shifti
26
}
28
+%shlimm_6bit 12:1 2:5 !function=ex_rvc_shiftli
27
}
29
+%shrimm_6bit 12:1 2:5 !function=ex_rvc_shiftri
28
}
30
%uimm_6bit_lq 2:4 12:1 6:1 !function=ex_shift_4
29
-}
31
%uimm_6bit_ld 2:3 12:1 5:2 !function=ex_shift_3
30
-
32
%uimm_6bit_lw 2:2 12:1 4:3 !function=ex_shift_2
31
-static void sifive_u_otp_reset(DeviceState *dev)
33
@@ -XXX,XX +XXX,XX @@
32
-{
34
@c_addi16sp ... . ..... ..... .. &i imm=%imm_addi16sp rs1=2 rd=2
33
- SiFiveUOTPState *s = SIFIVE_U_OTP(dev);
35
34
36
@c_shift ... . .. ... ..... .. \
35
/* Initialize all fuses' initial value to 0xFFs */
37
- &shift rd=%rs1_3 rs1=%rs1_3 shamt=%shimm_6bit
36
memset(s->fuse, 0xff, sizeof(s->fuse));
38
+ &shift rd=%rs1_3 rs1=%rs1_3 shamt=%shrimm_6bit
37
@@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_reset(DeviceState *dev)
39
@c_shift2 ... . .. ... ..... .. \
38
serial_data = s->serial;
40
- &shift rd=%rd rs1=%rd shamt=%shimm_6bit
39
if (blk_pwrite(s->blk, index * SIFIVE_U_OTP_FUSE_WORD,
41
+ &shift rd=%rd rs1=%rd shamt=%shlimm_6bit
40
&serial_data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) {
42
41
- error_report("write error index<%d>", index);
43
@c_andi ... . .. ... ..... .. &i imm=%imm_ci rs1=%rs1_3 rd=%rs1_3
42
+ error_setg(errp, "failed to write index<%d>", index);
44
43
+ return;
45
diff --git a/disas/riscv.c b/disas/riscv.c
44
}
46
index XXXXXXX..XXXXXXX 100644
45
47
--- a/disas/riscv.c
46
serial_data = ~(s->serial);
48
+++ b/disas/riscv.c
47
if (blk_pwrite(s->blk, (index + 1) * SIFIVE_U_OTP_FUSE_WORD,
49
@@ -XXX,XX +XXX,XX @@ static int32_t operand_sbimm12(rv_inst inst)
48
&serial_data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) {
50
((inst << 56) >> 63) << 11;
49
- error_report("write error index<%d>", index + 1);
50
+ error_setg(errp, "failed to write index<%d>", index + 1);
51
+ return;
52
}
53
}
54
55
@@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_class_init(ObjectClass *klass, void *data)
56
57
device_class_set_props(dc, sifive_u_otp_properties);
58
dc->realize = sifive_u_otp_realize;
59
- dc->reset = sifive_u_otp_reset;
60
}
51
}
61
52
62
static const TypeInfo sifive_u_otp_info = {
53
-static uint32_t operand_cimmsh6(rv_inst inst)
54
+static uint32_t operand_cimmshl6(rv_inst inst, rv_isa isa)
55
{
56
- return ((inst << 51) >> 63) << 5 |
57
+ int imm = ((inst << 51) >> 63) << 5 |
58
(inst << 57) >> 59;
59
+ if (isa == rv128) {
60
+ imm = imm ? imm : 64;
61
+ }
62
+ return imm;
63
+}
64
+
65
+static uint32_t operand_cimmshr6(rv_inst inst, rv_isa isa)
66
+{
67
+ int imm = ((inst << 51) >> 63) << 5 |
68
+ (inst << 57) >> 59;
69
+ if (isa == rv128) {
70
+ imm = imm | (imm & 32) << 1;
71
+ imm = imm ? imm : 64;
72
+ }
73
+ return imm;
74
}
75
76
static int32_t operand_cimmi(rv_inst inst)
77
@@ -XXX,XX +XXX,XX @@ static uint32_t operand_rnum(rv_inst inst)
78
79
/* decode operands */
80
81
-static void decode_inst_operands(rv_decode *dec)
82
+static void decode_inst_operands(rv_decode *dec, rv_isa isa)
83
{
84
rv_inst inst = dec->inst;
85
dec->codec = opcode_data[dec->op].codec;
86
@@ -XXX,XX +XXX,XX @@ static void decode_inst_operands(rv_decode *dec)
87
case rv_codec_cb_sh6:
88
dec->rd = dec->rs1 = operand_crs1rdq(inst) + 8;
89
dec->rs2 = rv_ireg_zero;
90
- dec->imm = operand_cimmsh6(inst);
91
+ dec->imm = operand_cimmshr6(inst, isa);
92
break;
93
case rv_codec_ci:
94
dec->rd = dec->rs1 = operand_crs1rd(inst);
95
@@ -XXX,XX +XXX,XX @@ static void decode_inst_operands(rv_decode *dec)
96
case rv_codec_ci_sh6:
97
dec->rd = dec->rs1 = operand_crs1rd(inst);
98
dec->rs2 = rv_ireg_zero;
99
- dec->imm = operand_cimmsh6(inst);
100
+ dec->imm = operand_cimmshl6(inst, isa);
101
break;
102
case rv_codec_ci_16sp:
103
dec->rd = rv_ireg_sp;
104
@@ -XXX,XX +XXX,XX @@ disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst)
105
dec.pc = pc;
106
dec.inst = inst;
107
decode_inst_opcode(&dec, isa);
108
- decode_inst_operands(&dec);
109
+ decode_inst_operands(&dec, isa);
110
decode_inst_decompress(&dec, isa);
111
decode_inst_lift_pseudo(&dec);
112
format_inst(buf, buflen, 16, &dec);
113
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/target/riscv/translate.c
116
+++ b/target/riscv/translate.c
117
@@ -XXX,XX +XXX,XX @@ static int ex_rvc_register(DisasContext *ctx, int reg)
118
return 8 + reg;
119
}
120
121
-static int ex_rvc_shifti(DisasContext *ctx, int imm)
122
+static int ex_rvc_shiftli(DisasContext *ctx, int imm)
123
{
124
/* For RV128 a shamt of 0 means a shift by 64. */
125
- return imm ? imm : 64;
126
+ if (get_ol(ctx) == MXL_RV128) {
127
+ imm = imm ? imm : 64;
128
+ }
129
+ return imm;
130
+}
131
+
132
+static int ex_rvc_shiftri(DisasContext *ctx, int imm)
133
+{
134
+ /*
135
+ * For RV128 a shamt of 0 means a shift by 64, furthermore, for right
136
+ * shifts, the shamt is sign-extended.
137
+ */
138
+ if (get_ol(ctx) == MXL_RV128) {
139
+ imm = imm | (imm & 32) << 1;
140
+ imm = imm ? imm : 64;
141
+ }
142
+ return imm;
143
}
144
145
/* Include the auto-generated decoder for 32 bit insn */
63
--
146
--
64
2.31.1
147
2.37.2
65
148
66
149
diff view generated by jsdifflib
New patch
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
2
3
- Zmmul is ratified and is now version 1.0
4
5
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <20220710101546.3907-1-liweiwei@iscas.ac.cn>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
target/riscv/cpu.c | 3 ++-
12
1 file changed, 2 insertions(+), 1 deletion(-)
13
14
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/cpu.c
17
+++ b/target/riscv/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
19
DEFINE_PROP_BOOL("zhinx", RISCVCPU, cfg.ext_zhinx, false),
20
DEFINE_PROP_BOOL("zhinxmin", RISCVCPU, cfg.ext_zhinxmin, false),
21
22
+ DEFINE_PROP_BOOL("zmmul", RISCVCPU, cfg.ext_zmmul, false),
23
+
24
/* Vendor-specific custom extensions */
25
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
26
27
/* These are experimental so mark with 'x-' */
28
DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
29
- DEFINE_PROP_BOOL("x-zmmul", RISCVCPU, cfg.ext_zmmul, false),
30
/* ePMP 0.9.3 */
31
DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
32
DEFINE_PROP_BOOL("x-aia", RISCVCPU, cfg.aia, false),
33
--
34
2.37.2
diff view generated by jsdifflib
New patch
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
1
2
3
If the FDT contains /chosen/rng-seed, then the Linux RNG will use it to
4
initialize early. Set this using the usual guest random number
5
generation function. This is confirmed to successfully initialize the
6
RNG on Linux 5.19-rc2.
7
8
Cc: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
10
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
11
Message-Id: <20220613115810.178210-1-Jason@zx2c4.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
hw/riscv/virt.c | 6 ++++++
15
1 file changed, 6 insertions(+)
16
17
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/riscv/virt.c
20
+++ b/hw/riscv/virt.c
21
@@ -XXX,XX +XXX,XX @@
22
#include "qemu/osdep.h"
23
#include "qemu/units.h"
24
#include "qemu/error-report.h"
25
+#include "qemu/guest-random.h"
26
#include "qapi/error.h"
27
#include "hw/boards.h"
28
#include "hw/loader.h"
29
@@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap,
30
MachineState *mc = MACHINE(s);
31
uint32_t phandle = 1, irq_mmio_phandle = 1, msi_pcie_phandle = 1;
32
uint32_t irq_pcie_phandle = 1, irq_virtio_phandle = 1;
33
+ uint8_t rng_seed[32];
34
35
if (mc->dtb) {
36
mc->fdt = load_device_tree(mc->dtb, &s->fdt_size);
37
@@ -XXX,XX +XXX,XX @@ update_bootargs:
38
if (cmdline && *cmdline) {
39
qemu_fdt_setprop_string(mc->fdt, "/chosen", "bootargs", cmdline);
40
}
41
+
42
+ /* Pass seed to RNG */
43
+ qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed));
44
+ qemu_fdt_setprop(mc->fdt, "/chosen", "rng-seed", rng_seed, sizeof(rng_seed));
45
}
46
47
static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
48
--
49
2.37.2
diff view generated by jsdifflib
New patch
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
2
3
There are 3 suggested privilege mode combinations listed in section 1.2
4
of the riscv-privileged spec(draft-20220717):
5
1) M, 2) M, U 3) M, S, U
6
7
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
8
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
11
Message-Id: <20220718130955.11899-2-liweiwei@iscas.ac.cn>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
target/riscv/cpu.c | 6 ++++++
15
1 file changed, 6 insertions(+)
16
17
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/cpu.c
20
+++ b/target/riscv/cpu.c
21
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
22
return;
23
}
24
25
+ if (cpu->cfg.ext_s && !cpu->cfg.ext_u) {
26
+ error_setg(errp,
27
+ "Setting S extension without U extension is illegal");
28
+ return;
29
+ }
30
+
31
if (cpu->cfg.ext_f && !cpu->cfg.ext_icsr) {
32
error_setg(errp, "F extension requires Zicsr");
33
return;
34
--
35
2.37.2
diff view generated by jsdifflib
New patch
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
2
3
Add check for "H depends on an I base integer ISA with 32 x registers"
4
which is stated at the beginning of chapter 8 of the riscv-privileged
5
spec(draft-20220717)
6
7
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
8
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
11
Message-Id: <20220718130955.11899-3-liweiwei@iscas.ac.cn>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
target/riscv/cpu.c | 6 ++++++
15
1 file changed, 6 insertions(+)
16
17
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/cpu.c
20
+++ b/target/riscv/cpu.c
21
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
22
return;
23
}
24
25
+ if (cpu->cfg.ext_h && !cpu->cfg.ext_i) {
26
+ error_setg(errp,
27
+ "H depends on an I base integer ISA with 32 x registers");
28
+ return;
29
+ }
30
+
31
if (cpu->cfg.ext_f && !cpu->cfg.ext_icsr) {
32
error_setg(errp, "F extension requires Zicsr");
33
return;
34
--
35
2.37.2
diff view generated by jsdifflib
New patch
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
2
3
Fix the lines with over 80 characters
4
5
Fix the lines which are obviously misalgined with other lines in the
6
same group
7
8
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
9
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
12
Message-Id: <20220718130955.11899-4-liweiwei@iscas.ac.cn>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
target/riscv/csr.c | 441 ++++++++++++++++++++++++---------------------
16
1 file changed, 234 insertions(+), 207 deletions(-)
17
18
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/csr.c
21
+++ b/target/riscv/csr.c
22
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
23
[CSR_FRM] = { "frm", fs, read_frm, write_frm },
24
[CSR_FCSR] = { "fcsr", fs, read_fcsr, write_fcsr },
25
/* Vector CSRs */
26
- [CSR_VSTART] = { "vstart", vs, read_vstart, write_vstart,
27
- .min_priv_ver = PRIV_VERSION_1_12_0 },
28
- [CSR_VXSAT] = { "vxsat", vs, read_vxsat, write_vxsat,
29
- .min_priv_ver = PRIV_VERSION_1_12_0 },
30
- [CSR_VXRM] = { "vxrm", vs, read_vxrm, write_vxrm,
31
- .min_priv_ver = PRIV_VERSION_1_12_0 },
32
- [CSR_VCSR] = { "vcsr", vs, read_vcsr, write_vcsr,
33
- .min_priv_ver = PRIV_VERSION_1_12_0 },
34
- [CSR_VL] = { "vl", vs, read_vl,
35
- .min_priv_ver = PRIV_VERSION_1_12_0 },
36
- [CSR_VTYPE] = { "vtype", vs, read_vtype,
37
- .min_priv_ver = PRIV_VERSION_1_12_0 },
38
- [CSR_VLENB] = { "vlenb", vs, read_vlenb,
39
- .min_priv_ver = PRIV_VERSION_1_12_0 },
40
+ [CSR_VSTART] = { "vstart", vs, read_vstart, write_vstart,
41
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
42
+ [CSR_VXSAT] = { "vxsat", vs, read_vxsat, write_vxsat,
43
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
44
+ [CSR_VXRM] = { "vxrm", vs, read_vxrm, write_vxrm,
45
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
46
+ [CSR_VCSR] = { "vcsr", vs, read_vcsr, write_vcsr,
47
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
48
+ [CSR_VL] = { "vl", vs, read_vl,
49
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
50
+ [CSR_VTYPE] = { "vtype", vs, read_vtype,
51
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
52
+ [CSR_VLENB] = { "vlenb", vs, read_vlenb,
53
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
54
/* User Timers and Counters */
55
[CSR_CYCLE] = { "cycle", ctr, read_hpmcounter },
56
[CSR_INSTRET] = { "instret", ctr, read_hpmcounter },
57
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
58
59
#if !defined(CONFIG_USER_ONLY)
60
/* Machine Timers and Counters */
61
- [CSR_MCYCLE] = { "mcycle", any, read_hpmcounter, write_mhpmcounter},
62
- [CSR_MINSTRET] = { "minstret", any, read_hpmcounter, write_mhpmcounter},
63
- [CSR_MCYCLEH] = { "mcycleh", any32, read_hpmcounterh, write_mhpmcounterh},
64
- [CSR_MINSTRETH] = { "minstreth", any32, read_hpmcounterh, write_mhpmcounterh},
65
+ [CSR_MCYCLE] = { "mcycle", any, read_hpmcounter,
66
+ write_mhpmcounter },
67
+ [CSR_MINSTRET] = { "minstret", any, read_hpmcounter,
68
+ write_mhpmcounter },
69
+ [CSR_MCYCLEH] = { "mcycleh", any32, read_hpmcounterh,
70
+ write_mhpmcounterh },
71
+ [CSR_MINSTRETH] = { "minstreth", any32, read_hpmcounterh,
72
+ write_mhpmcounterh },
73
74
/* Machine Information Registers */
75
[CSR_MVENDORID] = { "mvendorid", any, read_mvendorid },
76
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
77
[CSR_MHARTID] = { "mhartid", any, read_mhartid },
78
79
[CSR_MCONFIGPTR] = { "mconfigptr", any, read_zero,
80
- .min_priv_ver = PRIV_VERSION_1_12_0 },
81
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
82
/* Machine Trap Setup */
83
- [CSR_MSTATUS] = { "mstatus", any, read_mstatus, write_mstatus, NULL,
84
- read_mstatus_i128 },
85
- [CSR_MISA] = { "misa", any, read_misa, write_misa, NULL,
86
- read_misa_i128 },
87
- [CSR_MIDELEG] = { "mideleg", any, NULL, NULL, rmw_mideleg },
88
- [CSR_MEDELEG] = { "medeleg", any, read_medeleg, write_medeleg },
89
- [CSR_MIE] = { "mie", any, NULL, NULL, rmw_mie },
90
- [CSR_MTVEC] = { "mtvec", any, read_mtvec, write_mtvec },
91
- [CSR_MCOUNTEREN] = { "mcounteren", any, read_mcounteren, write_mcounteren },
92
-
93
- [CSR_MSTATUSH] = { "mstatush", any32, read_mstatush, write_mstatush },
94
+ [CSR_MSTATUS] = { "mstatus", any, read_mstatus, write_mstatus,
95
+ NULL, read_mstatus_i128 },
96
+ [CSR_MISA] = { "misa", any, read_misa, write_misa,
97
+ NULL, read_misa_i128 },
98
+ [CSR_MIDELEG] = { "mideleg", any, NULL, NULL, rmw_mideleg },
99
+ [CSR_MEDELEG] = { "medeleg", any, read_medeleg, write_medeleg },
100
+ [CSR_MIE] = { "mie", any, NULL, NULL, rmw_mie },
101
+ [CSR_MTVEC] = { "mtvec", any, read_mtvec, write_mtvec },
102
+ [CSR_MCOUNTEREN] = { "mcounteren", any, read_mcounteren,
103
+ write_mcounteren },
104
+
105
+ [CSR_MSTATUSH] = { "mstatush", any32, read_mstatush,
106
+ write_mstatush },
107
108
/* Machine Trap Handling */
109
- [CSR_MSCRATCH] = { "mscratch", any, read_mscratch, write_mscratch, NULL,
110
- read_mscratch_i128, write_mscratch_i128 },
111
+ [CSR_MSCRATCH] = { "mscratch", any, read_mscratch, write_mscratch,
112
+ NULL, read_mscratch_i128, write_mscratch_i128 },
113
[CSR_MEPC] = { "mepc", any, read_mepc, write_mepc },
114
[CSR_MCAUSE] = { "mcause", any, read_mcause, write_mcause },
115
[CSR_MTVAL] = { "mtval", any, read_mtval, write_mtval },
116
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
117
[CSR_MIREG] = { "mireg", aia_any, NULL, NULL, rmw_xireg },
118
119
/* Machine-Level Interrupts (AIA) */
120
- [CSR_MTOPEI] = { "mtopei", aia_any, NULL, NULL, rmw_xtopei },
121
- [CSR_MTOPI] = { "mtopi", aia_any, read_mtopi },
122
+ [CSR_MTOPEI] = { "mtopei", aia_any, NULL, NULL, rmw_xtopei },
123
+ [CSR_MTOPI] = { "mtopi", aia_any, read_mtopi },
124
125
/* Virtual Interrupts for Supervisor Level (AIA) */
126
- [CSR_MVIEN] = { "mvien", aia_any, read_zero, write_ignore },
127
- [CSR_MVIP] = { "mvip", aia_any, read_zero, write_ignore },
128
+ [CSR_MVIEN] = { "mvien", aia_any, read_zero, write_ignore },
129
+ [CSR_MVIP] = { "mvip", aia_any, read_zero, write_ignore },
130
131
/* Machine-Level High-Half CSRs (AIA) */
132
[CSR_MIDELEGH] = { "midelegh", aia_any32, NULL, NULL, rmw_midelegh },
133
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
134
135
/* Execution environment configuration */
136
[CSR_MENVCFG] = { "menvcfg", any, read_menvcfg, write_menvcfg,
137
- .min_priv_ver = PRIV_VERSION_1_12_0 },
138
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
139
[CSR_MENVCFGH] = { "menvcfgh", any32, read_menvcfgh, write_menvcfgh,
140
- .min_priv_ver = PRIV_VERSION_1_12_0 },
141
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
142
[CSR_SENVCFG] = { "senvcfg", smode, read_senvcfg, write_senvcfg,
143
- .min_priv_ver = PRIV_VERSION_1_12_0 },
144
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
145
[CSR_HENVCFG] = { "henvcfg", hmode, read_henvcfg, write_henvcfg,
146
- .min_priv_ver = PRIV_VERSION_1_12_0 },
147
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
148
[CSR_HENVCFGH] = { "henvcfgh", hmode32, read_henvcfgh, write_henvcfgh,
149
- .min_priv_ver = PRIV_VERSION_1_12_0 },
150
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
151
152
/* Supervisor Trap Setup */
153
- [CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus, NULL,
154
- read_sstatus_i128 },
155
- [CSR_SIE] = { "sie", smode, NULL, NULL, rmw_sie },
156
- [CSR_STVEC] = { "stvec", smode, read_stvec, write_stvec },
157
- [CSR_SCOUNTEREN] = { "scounteren", smode, read_scounteren, write_scounteren },
158
+ [CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus,
159
+ NULL, read_sstatus_i128 },
160
+ [CSR_SIE] = { "sie", smode, NULL, NULL, rmw_sie },
161
+ [CSR_STVEC] = { "stvec", smode, read_stvec, write_stvec },
162
+ [CSR_SCOUNTEREN] = { "scounteren", smode, read_scounteren,
163
+ write_scounteren },
164
165
/* Supervisor Trap Handling */
166
- [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch, NULL,
167
- read_sscratch_i128, write_sscratch_i128 },
168
+ [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch,
169
+ NULL, read_sscratch_i128, write_sscratch_i128 },
170
[CSR_SEPC] = { "sepc", smode, read_sepc, write_sepc },
171
[CSR_SCAUSE] = { "scause", smode, read_scause, write_scause },
172
- [CSR_STVAL] = { "stval", smode, read_stval, write_stval },
173
+ [CSR_STVAL] = { "stval", smode, read_stval, write_stval },
174
[CSR_SIP] = { "sip", smode, NULL, NULL, rmw_sip },
175
176
/* Supervisor Protection and Translation */
177
- [CSR_SATP] = { "satp", smode, read_satp, write_satp },
178
+ [CSR_SATP] = { "satp", smode, read_satp, write_satp },
179
180
/* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
181
[CSR_SISELECT] = { "siselect", aia_smode, NULL, NULL, rmw_xiselect },
182
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
183
[CSR_SIEH] = { "sieh", aia_smode32, NULL, NULL, rmw_sieh },
184
[CSR_SIPH] = { "siph", aia_smode32, NULL, NULL, rmw_siph },
185
186
- [CSR_HSTATUS] = { "hstatus", hmode, read_hstatus, write_hstatus,
187
- .min_priv_ver = PRIV_VERSION_1_12_0 },
188
- [CSR_HEDELEG] = { "hedeleg", hmode, read_hedeleg, write_hedeleg,
189
- .min_priv_ver = PRIV_VERSION_1_12_0 },
190
+ [CSR_HSTATUS] = { "hstatus", hmode, read_hstatus, write_hstatus,
191
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
192
+ [CSR_HEDELEG] = { "hedeleg", hmode, read_hedeleg, write_hedeleg,
193
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
194
[CSR_HIDELEG] = { "hideleg", hmode, NULL, NULL, rmw_hideleg,
195
- .min_priv_ver = PRIV_VERSION_1_12_0 },
196
- [CSR_HVIP] = { "hvip", hmode, NULL, NULL, rmw_hvip,
197
- .min_priv_ver = PRIV_VERSION_1_12_0 },
198
- [CSR_HIP] = { "hip", hmode, NULL, NULL, rmw_hip,
199
- .min_priv_ver = PRIV_VERSION_1_12_0 },
200
- [CSR_HIE] = { "hie", hmode, NULL, NULL, rmw_hie,
201
- .min_priv_ver = PRIV_VERSION_1_12_0 },
202
- [CSR_HCOUNTEREN] = { "hcounteren", hmode, read_hcounteren, write_hcounteren,
203
- .min_priv_ver = PRIV_VERSION_1_12_0 },
204
- [CSR_HGEIE] = { "hgeie", hmode, read_hgeie, write_hgeie,
205
- .min_priv_ver = PRIV_VERSION_1_12_0 },
206
- [CSR_HTVAL] = { "htval", hmode, read_htval, write_htval,
207
- .min_priv_ver = PRIV_VERSION_1_12_0 },
208
- [CSR_HTINST] = { "htinst", hmode, read_htinst, write_htinst,
209
- .min_priv_ver = PRIV_VERSION_1_12_0 },
210
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
211
+ [CSR_HVIP] = { "hvip", hmode, NULL, NULL, rmw_hvip,
212
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
213
+ [CSR_HIP] = { "hip", hmode, NULL, NULL, rmw_hip,
214
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
215
+ [CSR_HIE] = { "hie", hmode, NULL, NULL, rmw_hie,
216
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
217
+ [CSR_HCOUNTEREN] = { "hcounteren", hmode, read_hcounteren,
218
+ write_hcounteren,
219
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
220
+ [CSR_HGEIE] = { "hgeie", hmode, read_hgeie, write_hgeie,
221
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
222
+ [CSR_HTVAL] = { "htval", hmode, read_htval, write_htval,
223
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
224
+ [CSR_HTINST] = { "htinst", hmode, read_htinst, write_htinst,
225
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
226
[CSR_HGEIP] = { "hgeip", hmode, read_hgeip,
227
- .min_priv_ver = PRIV_VERSION_1_12_0 },
228
- [CSR_HGATP] = { "hgatp", hmode, read_hgatp, write_hgatp,
229
- .min_priv_ver = PRIV_VERSION_1_12_0 },
230
- [CSR_HTIMEDELTA] = { "htimedelta", hmode, read_htimedelta, write_htimedelta,
231
- .min_priv_ver = PRIV_VERSION_1_12_0 },
232
- [CSR_HTIMEDELTAH] = { "htimedeltah", hmode32, read_htimedeltah, write_htimedeltah,
233
- .min_priv_ver = PRIV_VERSION_1_12_0 },
234
-
235
- [CSR_VSSTATUS] = { "vsstatus", hmode, read_vsstatus, write_vsstatus,
236
- .min_priv_ver = PRIV_VERSION_1_12_0 },
237
- [CSR_VSIP] = { "vsip", hmode, NULL, NULL, rmw_vsip,
238
- .min_priv_ver = PRIV_VERSION_1_12_0 },
239
- [CSR_VSIE] = { "vsie", hmode, NULL, NULL, rmw_vsie ,
240
- .min_priv_ver = PRIV_VERSION_1_12_0 },
241
- [CSR_VSTVEC] = { "vstvec", hmode, read_vstvec, write_vstvec,
242
- .min_priv_ver = PRIV_VERSION_1_12_0 },
243
- [CSR_VSSCRATCH] = { "vsscratch", hmode, read_vsscratch, write_vsscratch,
244
- .min_priv_ver = PRIV_VERSION_1_12_0 },
245
- [CSR_VSEPC] = { "vsepc", hmode, read_vsepc, write_vsepc,
246
- .min_priv_ver = PRIV_VERSION_1_12_0 },
247
- [CSR_VSCAUSE] = { "vscause", hmode, read_vscause, write_vscause,
248
- .min_priv_ver = PRIV_VERSION_1_12_0 },
249
- [CSR_VSTVAL] = { "vstval", hmode, read_vstval, write_vstval,
250
- .min_priv_ver = PRIV_VERSION_1_12_0 },
251
- [CSR_VSATP] = { "vsatp", hmode, read_vsatp, write_vsatp,
252
- .min_priv_ver = PRIV_VERSION_1_12_0 },
253
-
254
- [CSR_MTVAL2] = { "mtval2", hmode, read_mtval2, write_mtval2,
255
- .min_priv_ver = PRIV_VERSION_1_12_0 },
256
- [CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst,
257
- .min_priv_ver = PRIV_VERSION_1_12_0 },
258
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
259
+ [CSR_HGATP] = { "hgatp", hmode, read_hgatp, write_hgatp,
260
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
261
+ [CSR_HTIMEDELTA] = { "htimedelta", hmode, read_htimedelta,
262
+ write_htimedelta,
263
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
264
+ [CSR_HTIMEDELTAH] = { "htimedeltah", hmode32, read_htimedeltah,
265
+ write_htimedeltah,
266
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
267
+
268
+ [CSR_VSSTATUS] = { "vsstatus", hmode, read_vsstatus,
269
+ write_vsstatus,
270
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
271
+ [CSR_VSIP] = { "vsip", hmode, NULL, NULL, rmw_vsip,
272
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
273
+ [CSR_VSIE] = { "vsie", hmode, NULL, NULL, rmw_vsie ,
274
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
275
+ [CSR_VSTVEC] = { "vstvec", hmode, read_vstvec, write_vstvec,
276
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
277
+ [CSR_VSSCRATCH] = { "vsscratch", hmode, read_vsscratch,
278
+ write_vsscratch,
279
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
280
+ [CSR_VSEPC] = { "vsepc", hmode, read_vsepc, write_vsepc,
281
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
282
+ [CSR_VSCAUSE] = { "vscause", hmode, read_vscause, write_vscause,
283
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
284
+ [CSR_VSTVAL] = { "vstval", hmode, read_vstval, write_vstval,
285
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
286
+ [CSR_VSATP] = { "vsatp", hmode, read_vsatp, write_vsatp,
287
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
288
+
289
+ [CSR_MTVAL2] = { "mtval2", hmode, read_mtval2, write_mtval2,
290
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
291
+ [CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst,
292
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
293
294
/* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */
295
[CSR_HVIEN] = { "hvien", aia_hmode, read_zero, write_ignore },
296
- [CSR_HVICTL] = { "hvictl", aia_hmode, read_hvictl, write_hvictl },
297
- [CSR_HVIPRIO1] = { "hviprio1", aia_hmode, read_hviprio1, write_hviprio1 },
298
- [CSR_HVIPRIO2] = { "hviprio2", aia_hmode, read_hviprio2, write_hviprio2 },
299
+ [CSR_HVICTL] = { "hvictl", aia_hmode, read_hvictl,
300
+ write_hvictl },
301
+ [CSR_HVIPRIO1] = { "hviprio1", aia_hmode, read_hviprio1,
302
+ write_hviprio1 },
303
+ [CSR_HVIPRIO2] = { "hviprio2", aia_hmode, read_hviprio2,
304
+ write_hviprio2 },
305
306
/*
307
* VS-Level Window to Indirectly Accessed Registers (H-extension with AIA)
308
*/
309
- [CSR_VSISELECT] = { "vsiselect", aia_hmode, NULL, NULL, rmw_xiselect },
310
- [CSR_VSIREG] = { "vsireg", aia_hmode, NULL, NULL, rmw_xireg },
311
+ [CSR_VSISELECT] = { "vsiselect", aia_hmode, NULL, NULL,
312
+ rmw_xiselect },
313
+ [CSR_VSIREG] = { "vsireg", aia_hmode, NULL, NULL, rmw_xireg },
314
315
/* VS-Level Interrupts (H-extension with AIA) */
316
[CSR_VSTOPEI] = { "vstopei", aia_hmode, NULL, NULL, rmw_xtopei },
317
[CSR_VSTOPI] = { "vstopi", aia_hmode, read_vstopi },
318
319
/* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
320
- [CSR_HIDELEGH] = { "hidelegh", aia_hmode32, NULL, NULL, rmw_hidelegh },
321
- [CSR_HVIENH] = { "hvienh", aia_hmode32, read_zero, write_ignore },
322
+ [CSR_HIDELEGH] = { "hidelegh", aia_hmode32, NULL, NULL,
323
+ rmw_hidelegh },
324
+ [CSR_HVIENH] = { "hvienh", aia_hmode32, read_zero,
325
+ write_ignore },
326
[CSR_HVIPH] = { "hviph", aia_hmode32, NULL, NULL, rmw_hviph },
327
- [CSR_HVIPRIO1H] = { "hviprio1h", aia_hmode32, read_hviprio1h, write_hviprio1h },
328
- [CSR_HVIPRIO2H] = { "hviprio2h", aia_hmode32, read_hviprio2h, write_hviprio2h },
329
+ [CSR_HVIPRIO1H] = { "hviprio1h", aia_hmode32, read_hviprio1h,
330
+ write_hviprio1h },
331
+ [CSR_HVIPRIO2H] = { "hviprio2h", aia_hmode32, read_hviprio2h,
332
+ write_hviprio2h },
333
[CSR_VSIEH] = { "vsieh", aia_hmode32, NULL, NULL, rmw_vsieh },
334
[CSR_VSIPH] = { "vsiph", aia_hmode32, NULL, NULL, rmw_vsiph },
335
336
/* Physical Memory Protection */
337
[CSR_MSECCFG] = { "mseccfg", epmp, read_mseccfg, write_mseccfg,
338
- .min_priv_ver = PRIV_VERSION_1_11_0 },
339
+ .min_priv_ver = PRIV_VERSION_1_11_0 },
340
[CSR_PMPCFG0] = { "pmpcfg0", pmp, read_pmpcfg, write_pmpcfg },
341
[CSR_PMPCFG1] = { "pmpcfg1", pmp, read_pmpcfg, write_pmpcfg },
342
[CSR_PMPCFG2] = { "pmpcfg2", pmp, read_pmpcfg, write_pmpcfg },
343
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
344
[CSR_TDATA3] = { "tdata3", debug, read_tdata, write_tdata },
345
346
/* User Pointer Masking */
347
- [CSR_UMTE] = { "umte", pointer_masking, read_umte, write_umte },
348
- [CSR_UPMMASK] = { "upmmask", pointer_masking, read_upmmask, write_upmmask },
349
- [CSR_UPMBASE] = { "upmbase", pointer_masking, read_upmbase, write_upmbase },
350
+ [CSR_UMTE] = { "umte", pointer_masking, read_umte, write_umte },
351
+ [CSR_UPMMASK] = { "upmmask", pointer_masking, read_upmmask,
352
+ write_upmmask },
353
+ [CSR_UPMBASE] = { "upmbase", pointer_masking, read_upmbase,
354
+ write_upmbase },
355
/* Machine Pointer Masking */
356
- [CSR_MMTE] = { "mmte", pointer_masking, read_mmte, write_mmte },
357
- [CSR_MPMMASK] = { "mpmmask", pointer_masking, read_mpmmask, write_mpmmask },
358
- [CSR_MPMBASE] = { "mpmbase", pointer_masking, read_mpmbase, write_mpmbase },
359
+ [CSR_MMTE] = { "mmte", pointer_masking, read_mmte, write_mmte },
360
+ [CSR_MPMMASK] = { "mpmmask", pointer_masking, read_mpmmask,
361
+ write_mpmmask },
362
+ [CSR_MPMBASE] = { "mpmbase", pointer_masking, read_mpmbase,
363
+ write_mpmbase },
364
/* Supervisor Pointer Masking */
365
- [CSR_SMTE] = { "smte", pointer_masking, read_smte, write_smte },
366
- [CSR_SPMMASK] = { "spmmask", pointer_masking, read_spmmask, write_spmmask },
367
- [CSR_SPMBASE] = { "spmbase", pointer_masking, read_spmbase, write_spmbase },
368
+ [CSR_SMTE] = { "smte", pointer_masking, read_smte, write_smte },
369
+ [CSR_SPMMASK] = { "spmmask", pointer_masking, read_spmmask,
370
+ write_spmmask },
371
+ [CSR_SPMBASE] = { "spmbase", pointer_masking, read_spmbase,
372
+ write_spmbase },
373
374
/* Performance Counters */
375
[CSR_HPMCOUNTER3] = { "hpmcounter3", ctr, read_hpmcounter },
376
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
377
[CSR_HPMCOUNTER31] = { "hpmcounter31", ctr, read_hpmcounter },
378
379
[CSR_MHPMCOUNTER3] = { "mhpmcounter3", mctr, read_hpmcounter,
380
- write_mhpmcounter },
381
+ write_mhpmcounter },
382
[CSR_MHPMCOUNTER4] = { "mhpmcounter4", mctr, read_hpmcounter,
383
- write_mhpmcounter },
384
+ write_mhpmcounter },
385
[CSR_MHPMCOUNTER5] = { "mhpmcounter5", mctr, read_hpmcounter,
386
- write_mhpmcounter },
387
+ write_mhpmcounter },
388
[CSR_MHPMCOUNTER6] = { "mhpmcounter6", mctr, read_hpmcounter,
389
- write_mhpmcounter },
390
+ write_mhpmcounter },
391
[CSR_MHPMCOUNTER7] = { "mhpmcounter7", mctr, read_hpmcounter,
392
- write_mhpmcounter },
393
+ write_mhpmcounter },
394
[CSR_MHPMCOUNTER8] = { "mhpmcounter8", mctr, read_hpmcounter,
395
- write_mhpmcounter },
396
+ write_mhpmcounter },
397
[CSR_MHPMCOUNTER9] = { "mhpmcounter9", mctr, read_hpmcounter,
398
- write_mhpmcounter },
399
+ write_mhpmcounter },
400
[CSR_MHPMCOUNTER10] = { "mhpmcounter10", mctr, read_hpmcounter,
401
- write_mhpmcounter },
402
+ write_mhpmcounter },
403
[CSR_MHPMCOUNTER11] = { "mhpmcounter11", mctr, read_hpmcounter,
404
- write_mhpmcounter },
405
+ write_mhpmcounter },
406
[CSR_MHPMCOUNTER12] = { "mhpmcounter12", mctr, read_hpmcounter,
407
- write_mhpmcounter },
408
+ write_mhpmcounter },
409
[CSR_MHPMCOUNTER13] = { "mhpmcounter13", mctr, read_hpmcounter,
410
- write_mhpmcounter },
411
+ write_mhpmcounter },
412
[CSR_MHPMCOUNTER14] = { "mhpmcounter14", mctr, read_hpmcounter,
413
- write_mhpmcounter },
414
+ write_mhpmcounter },
415
[CSR_MHPMCOUNTER15] = { "mhpmcounter15", mctr, read_hpmcounter,
416
- write_mhpmcounter },
417
+ write_mhpmcounter },
418
[CSR_MHPMCOUNTER16] = { "mhpmcounter16", mctr, read_hpmcounter,
419
- write_mhpmcounter },
420
+ write_mhpmcounter },
421
[CSR_MHPMCOUNTER17] = { "mhpmcounter17", mctr, read_hpmcounter,
422
- write_mhpmcounter },
423
+ write_mhpmcounter },
424
[CSR_MHPMCOUNTER18] = { "mhpmcounter18", mctr, read_hpmcounter,
425
- write_mhpmcounter },
426
+ write_mhpmcounter },
427
[CSR_MHPMCOUNTER19] = { "mhpmcounter19", mctr, read_hpmcounter,
428
- write_mhpmcounter },
429
+ write_mhpmcounter },
430
[CSR_MHPMCOUNTER20] = { "mhpmcounter20", mctr, read_hpmcounter,
431
- write_mhpmcounter },
432
+ write_mhpmcounter },
433
[CSR_MHPMCOUNTER21] = { "mhpmcounter21", mctr, read_hpmcounter,
434
- write_mhpmcounter },
435
+ write_mhpmcounter },
436
[CSR_MHPMCOUNTER22] = { "mhpmcounter22", mctr, read_hpmcounter,
437
- write_mhpmcounter },
438
+ write_mhpmcounter },
439
[CSR_MHPMCOUNTER23] = { "mhpmcounter23", mctr, read_hpmcounter,
440
- write_mhpmcounter },
441
+ write_mhpmcounter },
442
[CSR_MHPMCOUNTER24] = { "mhpmcounter24", mctr, read_hpmcounter,
443
- write_mhpmcounter },
444
+ write_mhpmcounter },
445
[CSR_MHPMCOUNTER25] = { "mhpmcounter25", mctr, read_hpmcounter,
446
- write_mhpmcounter },
447
+ write_mhpmcounter },
448
[CSR_MHPMCOUNTER26] = { "mhpmcounter26", mctr, read_hpmcounter,
449
- write_mhpmcounter },
450
+ write_mhpmcounter },
451
[CSR_MHPMCOUNTER27] = { "mhpmcounter27", mctr, read_hpmcounter,
452
- write_mhpmcounter },
453
+ write_mhpmcounter },
454
[CSR_MHPMCOUNTER28] = { "mhpmcounter28", mctr, read_hpmcounter,
455
- write_mhpmcounter },
456
+ write_mhpmcounter },
457
[CSR_MHPMCOUNTER29] = { "mhpmcounter29", mctr, read_hpmcounter,
458
- write_mhpmcounter },
459
+ write_mhpmcounter },
460
[CSR_MHPMCOUNTER30] = { "mhpmcounter30", mctr, read_hpmcounter,
461
- write_mhpmcounter },
462
+ write_mhpmcounter },
463
[CSR_MHPMCOUNTER31] = { "mhpmcounter31", mctr, read_hpmcounter,
464
- write_mhpmcounter },
465
+ write_mhpmcounter },
466
467
[CSR_MCOUNTINHIBIT] = { "mcountinhibit", any, read_mcountinhibit,
468
- write_mcountinhibit, .min_priv_ver = PRIV_VERSION_1_11_0 },
469
+ write_mcountinhibit,
470
+ .min_priv_ver = PRIV_VERSION_1_11_0 },
471
472
[CSR_MHPMEVENT3] = { "mhpmevent3", any, read_mhpmevent,
473
- write_mhpmevent },
474
+ write_mhpmevent },
475
[CSR_MHPMEVENT4] = { "mhpmevent4", any, read_mhpmevent,
476
- write_mhpmevent },
477
+ write_mhpmevent },
478
[CSR_MHPMEVENT5] = { "mhpmevent5", any, read_mhpmevent,
479
- write_mhpmevent },
480
+ write_mhpmevent },
481
[CSR_MHPMEVENT6] = { "mhpmevent6", any, read_mhpmevent,
482
- write_mhpmevent },
483
+ write_mhpmevent },
484
[CSR_MHPMEVENT7] = { "mhpmevent7", any, read_mhpmevent,
485
- write_mhpmevent },
486
+ write_mhpmevent },
487
[CSR_MHPMEVENT8] = { "mhpmevent8", any, read_mhpmevent,
488
- write_mhpmevent },
489
+ write_mhpmevent },
490
[CSR_MHPMEVENT9] = { "mhpmevent9", any, read_mhpmevent,
491
- write_mhpmevent },
492
+ write_mhpmevent },
493
[CSR_MHPMEVENT10] = { "mhpmevent10", any, read_mhpmevent,
494
- write_mhpmevent },
495
+ write_mhpmevent },
496
[CSR_MHPMEVENT11] = { "mhpmevent11", any, read_mhpmevent,
497
- write_mhpmevent },
498
+ write_mhpmevent },
499
[CSR_MHPMEVENT12] = { "mhpmevent12", any, read_mhpmevent,
500
- write_mhpmevent },
501
+ write_mhpmevent },
502
[CSR_MHPMEVENT13] = { "mhpmevent13", any, read_mhpmevent,
503
- write_mhpmevent },
504
+ write_mhpmevent },
505
[CSR_MHPMEVENT14] = { "mhpmevent14", any, read_mhpmevent,
506
- write_mhpmevent },
507
+ write_mhpmevent },
508
[CSR_MHPMEVENT15] = { "mhpmevent15", any, read_mhpmevent,
509
- write_mhpmevent },
510
+ write_mhpmevent },
511
[CSR_MHPMEVENT16] = { "mhpmevent16", any, read_mhpmevent,
512
- write_mhpmevent },
513
+ write_mhpmevent },
514
[CSR_MHPMEVENT17] = { "mhpmevent17", any, read_mhpmevent,
515
- write_mhpmevent },
516
+ write_mhpmevent },
517
[CSR_MHPMEVENT18] = { "mhpmevent18", any, read_mhpmevent,
518
- write_mhpmevent },
519
+ write_mhpmevent },
520
[CSR_MHPMEVENT19] = { "mhpmevent19", any, read_mhpmevent,
521
- write_mhpmevent },
522
+ write_mhpmevent },
523
[CSR_MHPMEVENT20] = { "mhpmevent20", any, read_mhpmevent,
524
- write_mhpmevent },
525
+ write_mhpmevent },
526
[CSR_MHPMEVENT21] = { "mhpmevent21", any, read_mhpmevent,
527
- write_mhpmevent },
528
+ write_mhpmevent },
529
[CSR_MHPMEVENT22] = { "mhpmevent22", any, read_mhpmevent,
530
- write_mhpmevent },
531
+ write_mhpmevent },
532
[CSR_MHPMEVENT23] = { "mhpmevent23", any, read_mhpmevent,
533
- write_mhpmevent },
534
+ write_mhpmevent },
535
[CSR_MHPMEVENT24] = { "mhpmevent24", any, read_mhpmevent,
536
- write_mhpmevent },
537
+ write_mhpmevent },
538
[CSR_MHPMEVENT25] = { "mhpmevent25", any, read_mhpmevent,
539
- write_mhpmevent },
540
+ write_mhpmevent },
541
[CSR_MHPMEVENT26] = { "mhpmevent26", any, read_mhpmevent,
542
- write_mhpmevent },
543
+ write_mhpmevent },
544
[CSR_MHPMEVENT27] = { "mhpmevent27", any, read_mhpmevent,
545
- write_mhpmevent },
546
+ write_mhpmevent },
547
[CSR_MHPMEVENT28] = { "mhpmevent28", any, read_mhpmevent,
548
- write_mhpmevent },
549
+ write_mhpmevent },
550
[CSR_MHPMEVENT29] = { "mhpmevent29", any, read_mhpmevent,
551
- write_mhpmevent },
552
+ write_mhpmevent },
553
[CSR_MHPMEVENT30] = { "mhpmevent30", any, read_mhpmevent,
554
- write_mhpmevent },
555
+ write_mhpmevent },
556
[CSR_MHPMEVENT31] = { "mhpmevent31", any, read_mhpmevent,
557
- write_mhpmevent },
558
+ write_mhpmevent },
559
560
[CSR_HPMCOUNTER3H] = { "hpmcounter3h", ctr32, read_hpmcounterh },
561
[CSR_HPMCOUNTER4H] = { "hpmcounter4h", ctr32, read_hpmcounterh },
562
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
563
[CSR_HPMCOUNTER31H] = { "hpmcounter31h", ctr32, read_hpmcounterh },
564
565
[CSR_MHPMCOUNTER3H] = { "mhpmcounter3h", mctr32, read_hpmcounterh,
566
- write_mhpmcounterh },
567
+ write_mhpmcounterh },
568
[CSR_MHPMCOUNTER4H] = { "mhpmcounter4h", mctr32, read_hpmcounterh,
569
- write_mhpmcounterh },
570
+ write_mhpmcounterh },
571
[CSR_MHPMCOUNTER5H] = { "mhpmcounter5h", mctr32, read_hpmcounterh,
572
- write_mhpmcounterh },
573
+ write_mhpmcounterh },
574
[CSR_MHPMCOUNTER6H] = { "mhpmcounter6h", mctr32, read_hpmcounterh,
575
- write_mhpmcounterh },
576
+ write_mhpmcounterh },
577
[CSR_MHPMCOUNTER7H] = { "mhpmcounter7h", mctr32, read_hpmcounterh,
578
- write_mhpmcounterh },
579
+ write_mhpmcounterh },
580
[CSR_MHPMCOUNTER8H] = { "mhpmcounter8h", mctr32, read_hpmcounterh,
581
- write_mhpmcounterh },
582
+ write_mhpmcounterh },
583
[CSR_MHPMCOUNTER9H] = { "mhpmcounter9h", mctr32, read_hpmcounterh,
584
- write_mhpmcounterh },
585
+ write_mhpmcounterh },
586
[CSR_MHPMCOUNTER10H] = { "mhpmcounter10h", mctr32, read_hpmcounterh,
587
- write_mhpmcounterh },
588
+ write_mhpmcounterh },
589
[CSR_MHPMCOUNTER11H] = { "mhpmcounter11h", mctr32, read_hpmcounterh,
590
- write_mhpmcounterh },
591
+ write_mhpmcounterh },
592
[CSR_MHPMCOUNTER12H] = { "mhpmcounter12h", mctr32, read_hpmcounterh,
593
- write_mhpmcounterh },
594
+ write_mhpmcounterh },
595
[CSR_MHPMCOUNTER13H] = { "mhpmcounter13h", mctr32, read_hpmcounterh,
596
- write_mhpmcounterh },
597
+ write_mhpmcounterh },
598
[CSR_MHPMCOUNTER14H] = { "mhpmcounter14h", mctr32, read_hpmcounterh,
599
- write_mhpmcounterh },
600
+ write_mhpmcounterh },
601
[CSR_MHPMCOUNTER15H] = { "mhpmcounter15h", mctr32, read_hpmcounterh,
602
- write_mhpmcounterh },
603
+ write_mhpmcounterh },
604
[CSR_MHPMCOUNTER16H] = { "mhpmcounter16h", mctr32, read_hpmcounterh,
605
- write_mhpmcounterh },
606
+ write_mhpmcounterh },
607
[CSR_MHPMCOUNTER17H] = { "mhpmcounter17h", mctr32, read_hpmcounterh,
608
- write_mhpmcounterh },
609
+ write_mhpmcounterh },
610
[CSR_MHPMCOUNTER18H] = { "mhpmcounter18h", mctr32, read_hpmcounterh,
611
- write_mhpmcounterh },
612
+ write_mhpmcounterh },
613
[CSR_MHPMCOUNTER19H] = { "mhpmcounter19h", mctr32, read_hpmcounterh,
614
- write_mhpmcounterh },
615
+ write_mhpmcounterh },
616
[CSR_MHPMCOUNTER20H] = { "mhpmcounter20h", mctr32, read_hpmcounterh,
617
- write_mhpmcounterh },
618
+ write_mhpmcounterh },
619
[CSR_MHPMCOUNTER21H] = { "mhpmcounter21h", mctr32, read_hpmcounterh,
620
- write_mhpmcounterh },
621
+ write_mhpmcounterh },
622
[CSR_MHPMCOUNTER22H] = { "mhpmcounter22h", mctr32, read_hpmcounterh,
623
- write_mhpmcounterh },
624
+ write_mhpmcounterh },
625
[CSR_MHPMCOUNTER23H] = { "mhpmcounter23h", mctr32, read_hpmcounterh,
626
- write_mhpmcounterh },
627
+ write_mhpmcounterh },
628
[CSR_MHPMCOUNTER24H] = { "mhpmcounter24h", mctr32, read_hpmcounterh,
629
- write_mhpmcounterh },
630
+ write_mhpmcounterh },
631
[CSR_MHPMCOUNTER25H] = { "mhpmcounter25h", mctr32, read_hpmcounterh,
632
- write_mhpmcounterh },
633
+ write_mhpmcounterh },
634
[CSR_MHPMCOUNTER26H] = { "mhpmcounter26h", mctr32, read_hpmcounterh,
635
- write_mhpmcounterh },
636
+ write_mhpmcounterh },
637
[CSR_MHPMCOUNTER27H] = { "mhpmcounter27h", mctr32, read_hpmcounterh,
638
- write_mhpmcounterh },
639
+ write_mhpmcounterh },
640
[CSR_MHPMCOUNTER28H] = { "mhpmcounter28h", mctr32, read_hpmcounterh,
641
- write_mhpmcounterh },
642
+ write_mhpmcounterh },
643
[CSR_MHPMCOUNTER29H] = { "mhpmcounter29h", mctr32, read_hpmcounterh,
644
- write_mhpmcounterh },
645
+ write_mhpmcounterh },
646
[CSR_MHPMCOUNTER30H] = { "mhpmcounter30h", mctr32, read_hpmcounterh,
647
- write_mhpmcounterh },
648
+ write_mhpmcounterh },
649
[CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", mctr32, read_hpmcounterh,
650
- write_mhpmcounterh },
651
+ write_mhpmcounterh },
652
#endif /* !CONFIG_USER_ONLY */
653
};
654
--
655
2.37.2
diff view generated by jsdifflib
New patch
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
2
3
Add umode/umode32 predicate for mcounteren, menvcfg/menvcfgh
4
5
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
9
Message-Id: <20220718130955.11899-5-liweiwei@iscas.ac.cn>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/csr.c | 24 +++++++++++++++++++++---
13
1 file changed, 21 insertions(+), 3 deletions(-)
14
15
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/csr.c
18
+++ b/target/riscv/csr.c
19
@@ -XXX,XX +XXX,XX @@ static RISCVException hmode32(CPURISCVState *env, int csrno)
20
21
}
22
23
+static RISCVException umode(CPURISCVState *env, int csrno)
24
+{
25
+ if (riscv_has_ext(env, RVU)) {
26
+ return RISCV_EXCP_NONE;
27
+ }
28
+
29
+ return RISCV_EXCP_ILLEGAL_INST;
30
+}
31
+
32
+static RISCVException umode32(CPURISCVState *env, int csrno)
33
+{
34
+ if (riscv_cpu_mxl(env) != MXL_RV32) {
35
+ return RISCV_EXCP_ILLEGAL_INST;
36
+ }
37
+
38
+ return umode(env, csrno);
39
+}
40
+
41
/* Checks if PointerMasking registers could be accessed */
42
static RISCVException pointer_masking(CPURISCVState *env, int csrno)
43
{
44
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
45
[CSR_MEDELEG] = { "medeleg", any, read_medeleg, write_medeleg },
46
[CSR_MIE] = { "mie", any, NULL, NULL, rmw_mie },
47
[CSR_MTVEC] = { "mtvec", any, read_mtvec, write_mtvec },
48
- [CSR_MCOUNTEREN] = { "mcounteren", any, read_mcounteren,
49
+ [CSR_MCOUNTEREN] = { "mcounteren", umode, read_mcounteren,
50
write_mcounteren },
51
52
[CSR_MSTATUSH] = { "mstatush", any32, read_mstatush,
53
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
54
[CSR_MIPH] = { "miph", aia_any32, NULL, NULL, rmw_miph },
55
56
/* Execution environment configuration */
57
- [CSR_MENVCFG] = { "menvcfg", any, read_menvcfg, write_menvcfg,
58
+ [CSR_MENVCFG] = { "menvcfg", umode, read_menvcfg, write_menvcfg,
59
.min_priv_ver = PRIV_VERSION_1_12_0 },
60
- [CSR_MENVCFGH] = { "menvcfgh", any32, read_menvcfgh, write_menvcfgh,
61
+ [CSR_MENVCFGH] = { "menvcfgh", umode32, read_menvcfgh, write_menvcfgh,
62
.min_priv_ver = PRIV_VERSION_1_12_0 },
63
[CSR_SENVCFG] = { "senvcfg", smode, read_senvcfg, write_senvcfg,
64
.min_priv_ver = PRIV_VERSION_1_12_0 },
65
--
66
2.37.2
diff view generated by jsdifflib
New patch
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
2
3
Add check for the implicit dependence between H and S
4
5
Csrs only existed in RV32 will not trigger virtual instruction fault
6
when not in RV32 based on section 8.6.1 of riscv-privileged spec
7
(draft-20220717)
8
9
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
10
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
11
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-Id: <20220718130955.11899-6-liweiwei@iscas.ac.cn>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
target/riscv/cpu.c | 5 +++++
17
target/riscv/csr.c | 9 ++-------
18
2 files changed, 7 insertions(+), 7 deletions(-)
19
20
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/cpu.c
23
+++ b/target/riscv/cpu.c
24
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
25
return;
26
}
27
28
+ if (cpu->cfg.ext_h && !cpu->cfg.ext_s) {
29
+ error_setg(errp, "H extension implicitly requires S-mode");
30
+ return;
31
+ }
32
+
33
if (cpu->cfg.ext_f && !cpu->cfg.ext_icsr) {
34
error_setg(errp, "F extension requires Zicsr");
35
return;
36
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/riscv/csr.c
39
+++ b/target/riscv/csr.c
40
@@ -XXX,XX +XXX,XX @@ static int aia_smode32(CPURISCVState *env, int csrno)
41
42
static RISCVException hmode(CPURISCVState *env, int csrno)
43
{
44
- if (riscv_has_ext(env, RVS) &&
45
- riscv_has_ext(env, RVH)) {
46
+ if (riscv_has_ext(env, RVH)) {
47
/* Hypervisor extension is supported */
48
if ((env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
49
env->priv == PRV_M) {
50
@@ -XXX,XX +XXX,XX @@ static RISCVException hmode(CPURISCVState *env, int csrno)
51
static RISCVException hmode32(CPURISCVState *env, int csrno)
52
{
53
if (riscv_cpu_mxl(env) != MXL_RV32) {
54
- if (!riscv_cpu_virt_enabled(env)) {
55
- return RISCV_EXCP_ILLEGAL_INST;
56
- } else {
57
- return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
58
- }
59
+ return RISCV_EXCP_ILLEGAL_INST;
60
}
61
62
return hmode(env, csrno);
63
--
64
2.37.2
diff view generated by jsdifflib
New patch
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
2
3
Just add 1 to the effective privledge level when in HS mode, then reuse
4
the check of 'effective_priv < csr_priv' in riscv_csrrw_check to replace
5
the privilege level related check in hmode. Then, hmode will only check
6
whether H extension is supported.
7
8
When accessing Hypervior CSRs:
9
1) If accessing from M privilege level, the check of
10
'effective_priv< csr_priv' passes, returns hmode(...) which will return
11
RISCV_EXCP_ILLEGAL_INST when H extension is not supported and return
12
RISCV_EXCP_NONE otherwise.
13
2) If accessing from HS privilege level, effective_priv will add 1,
14
the check passes and also returns hmode(...) too.
15
3) If accessing from VS/VU privilege level, the check fails, and
16
returns RISCV_EXCP_VIRT_INSTRUCTION_FAULT
17
4) If accessing from U privilege level, the check fails, and returns
18
RISCV_EXCP_ILLEGAL_INST
19
20
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
21
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
22
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
23
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
24
Message-Id: <20220718130955.11899-7-liweiwei@iscas.ac.cn>
25
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
26
---
27
target/riscv/csr.c | 18 +++++-------------
28
1 file changed, 5 insertions(+), 13 deletions(-)
29
30
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/riscv/csr.c
33
+++ b/target/riscv/csr.c
34
@@ -XXX,XX +XXX,XX @@ static int aia_smode32(CPURISCVState *env, int csrno)
35
static RISCVException hmode(CPURISCVState *env, int csrno)
36
{
37
if (riscv_has_ext(env, RVH)) {
38
- /* Hypervisor extension is supported */
39
- if ((env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
40
- env->priv == PRV_M) {
41
- return RISCV_EXCP_NONE;
42
- } else {
43
- return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
44
- }
45
+ return RISCV_EXCP_NONE;
46
}
47
48
return RISCV_EXCP_ILLEGAL_INST;
49
@@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
50
#if !defined(CONFIG_USER_ONLY)
51
int csr_priv, effective_priv = env->priv;
52
53
- if (riscv_has_ext(env, RVH) && env->priv == PRV_S) {
54
+ if (riscv_has_ext(env, RVH) && env->priv == PRV_S &&
55
+ !riscv_cpu_virt_enabled(env)) {
56
/*
57
- * We are in either HS or VS mode.
58
- * Add 1 to the effective privledge level to allow us to access the
59
- * Hypervisor CSRs. The `hmode` predicate will determine if access
60
- * should be allowed(HS) or if a virtual instruction exception should be
61
- * raised(VS).
62
+ * We are in HS mode. Add 1 to the effective privledge level to
63
+ * allow us to access the Hypervisor CSRs.
64
*/
65
effective_priv++;
66
}
67
--
68
2.37.2
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng.cn@gmail.com>
1
2
3
Upgrade OpenSBI from v1.0 to v1.1 and the pre-built bios images.
4
5
The v1.1 release includes the following commits:
6
7
5b99603 lib: utils/ipi: Fix size check in aclint_mswi_cold_init()
8
6dde435 lib: utils/sys: Extend HTIF library to allow custom base address
9
8257262 platform: sifive_fu740: do not use a global in da9063_reset/shutdown
10
fb688d9 platform: sifive_fu740: fix reset when watchdog is running
11
5d025eb lib: fix pointer of type 'void *' used in arithmetic
12
632f593 lib: sbi: Map only the counters enabled in hardware
13
3b7c204 lib: sbi: Disable interrupt during config matching
14
a26dc60 lib: sbi: Disable interrupt and inhibit counting in M-mode during init
15
5d53b55 Makefile: fix build with binutils 2.38
16
6ad8917 lib: fix compilation when strings.h is included
17
ce4c018 lib: utils/serial: Round UART8250 baud rate divisor to nearest integer
18
01250d0 include: sbi: Add AIA related CSR defines
19
8f96070 lib: sbi: Detect AIA CSRs at boot-time
20
65b4c7c lib: sbi: Use AIA CSRs for local interrupts when available
21
222132f lib: sbi: Add sbi_trap_set_external_irqfn() API
22
5f56314 lib: utils/irqchip: Allow multiple FDT irqchip drivers
23
1050940 include: sbi: Introduce nascent_init() platform callback
24
55e79f8 lib: sbi: Enable mie.MEIE bit for IPIs based on external interrupts.
25
9f73669 lib: utils/irqchip: Add IMSIC library
26
811da5c lib: utils/irqchip: Add FDT based driver for IMSIC
27
7127aaa lib: utils: Disable appropriate IMSIC DT nodes in fdt_fixups()
28
9979265 lib: utils/irqchip: Add APLIC initialization library
29
3461219 lib: utils/irqchip: Add FDT based driver for APLIC
30
8e2ef4f lib: utils: Disable appropriate APLIC DT nodes in fdt_fixups()
31
3a69cc1 lib: sbi: fix typo in is_region_subset
32
f2ccf2f lib: sbi: verbose sbi_domain_root_add_memregion
33
f3f4604 lib: sbi: Add a simple external interrupt handling framework
34
4998a71 lib: utils: serial: Initial commit of xlnx-uartlite
35
2dfbd3c lib: pmp_set/pmp_get moved errors from runtime to compile time
36
b6b7220 firmware: Fix code for accessing hart_count and stack_size
37
d552fc8 lib: Add error messages via conditional compilation for the future
38
555bdb1 include: Use static asserts for SBI_PLATFORM_xxx_OFFSET defines
39
1b42d3a include: Use static asserts for SBI_SCRATCH_xxx_OFFSET defines
40
7924a0b include: Use static asserts for FW_DYNAMIC_INFO_xxx_OFFSET defines
41
722f80d include: Add defines for [m|h|s]envcfg CSRs
42
31fecad lib: sbi: Detect menvcfg CSR at boot time
43
47d6765 lib: sbi: Enable Zicbo[m|z] extensions in the menvcfg CSR
44
794986f lib: sbi: Enable Svpbmt extension in the menvcfg CSR
45
499601a lib: sbi: Add Smstateen extension defines
46
d44568a lib: sbi: Detect Smstateen CSRs at boot-time
47
3383d6a lib: irqchip/imsic: configure mstateen
48
5c5cbb5 lib: utils/serial: support 'reg-offset' property
49
c1e47d0 include: correct the definition of MSTATUS_VS
50
9cd95e1 lib: sbi/hart: preserve csr validation value
51
4035ae9 docs: pmu: Improve the PMU DT bindings
52
d62f6da lib: sbi: Implement Sstc extension
53
474a9d4 lib: sbi: Fix mstatus_init() for RV32 when Sscofpmf is not available
54
e576b3e include: sbi: Define SBI_PMU_HW_EVENT_MAX to 256
55
b0c9df5 lib: sbi: Fix mhpmeventh access for rv32 in absence of sscofpmf
56
1a754bb lib: sbi: Detect and print privileged spec version
57
5a6be99 lib: sbi: Remove 's' and 'u' from misa_string() output
58
5b8b377 lib: sbi: Update the name of ISA string printed at boot time
59
d4b563c lib: sbi: Remove MCOUNTEREN and SCOUNTEREN hart features
60
dbc3d8f lib: sbi: Remove MCOUNTINHIBT hart feature
61
97a17c2 lib: sbi: Remove MENVCFG hart feature
62
a6ab94f lib: sbi: Fix AIA feature detection
63
cad6c91 lib: sbi: Convert hart features into hart extensions
64
be4903a lib: sbi: Detect hart features only once for each hart
65
994ace3 lib: sbi: Add sbi_hart_update_extension() function
66
023f0ad lib: sbi_platform: Add callback to populate HART extensions
67
f726f2d Makefile: Allow generated C source to be anywhere in build directory
68
7fb474b Makefile: Add support for generating C array at compile time
69
73cf511 lib: utils/reset: Generate FDT reset driver list at compile-time
70
1e62705 lib: utils/serial: Generate FDT serial driver list at compile-time
71
bfeb305 lib: utils/timer: Generate FDT timer driver list at compile-time
72
3a69d12 lib: utils/irqchip: Generate FDT irqchip driver list at compile-time
73
4ee0c57 lib: utils/ipi: Generate FDT ipi driver list at compile-time
74
998ed43 lib: utils/i2c: Generate FDT i2c adapter driver list at compile-time
75
4eacd82 lib: utils/gpio: Generate FDT gpio driver list at compile-time
76
a3a3c60 platform: generic: Generate platform override module list at compile-time
77
9a7a677 platform: generic: Move Sifive platform overrides into own directory
78
851c14d lib: utils/irqchip: fix typo when checking for CPU node
79
90a9dd2 lib: utils/fdt: introduce fdt_node_is_enabled()
80
616da52 lib: utils: check if CPU node is enabled
81
575bb4e platform: generic: check if CPU node is enabled
82
1bc67db lib: utils/fdt: rename fdt_parse_max_hart_id
83
f067bb8 lib: sbi: fix system_opcode_insn
84
fab0379 lib: utils/fdt: Require match data to be const
85
295e5f3 lib: sbi_timer: Drop unnecessary get_platform_ticks wrapper
86
ff65bfe lib: sbi_illegal_insn: Constify illegal_insn_table
87
cb8271c lib: sbi_illegal_insn: Add emulation for fence.tso
88
adc3388 lib: sbi_trap: Redirect exception based on hedeleg
89
ce1d618 platform: generic: add overrides for vendor extensions
90
b20ed9f lib: sbi_hsm: Call a device hook during hart resume
91
79e42eb lib: sbi_hsm: Assume a consistent resume address
92
2ea7799 lib: irqchip/plic: Constify plic_data pointers
93
8c362e7 lib: irqchip/plic: Factor out a context init function
94
415ecf2 lib: irqchip/plic: Add context save/restore helpers
95
2b79b69 lib: irqchip/plic: Add priority save/restore helpers
96
69be3df lib: utils/irqchip: Add FDT wrappers for PLIC save/restore functions
97
5e56758 lib: utils/irqchip: Add wrapper for T-HEAD PLIC delegation
98
9dc5ec5 platform: Add HSM implementation for Allwinner D1
99
551c70c include: sbi: Add mtinst/htinst psuedoinstructions
100
187127f lib: sbi: Fixup tinst for exceptions in sbi_misaligned_*()
101
a07402a lib: sbi: Fix tval and tinst for sbi_get_insn()
102
c653001 lib: utils: Remove CSRs that set/clear an IMSIC interrupt file bits
103
7738345 lib: utils/timer: Add a separate compatible for the D1 CLINT
104
d76a196 lib: irqchip/plic: fix typo in plic_warm_irqchip_init
105
6f1fe98 lib: utils/timer: Remove Allwinner D1 CLINT compatibles
106
c6fdbcf include: sbi: Change spec version to 1.0
107
3f66465 lib: pmu: allow to use the highest available counter
108
4489876 include: Bump-up version to 1.1
109
110
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
111
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
112
Message-Id: <20220713090613.204046-1-bmeng.cn@gmail.com>
113
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
114
---
115
.../opensbi-riscv32-generic-fw_dynamic.bin | Bin 108504 -> 117704 bytes
116
.../opensbi-riscv64-generic-fw_dynamic.bin | Bin 105296 -> 115344 bytes
117
roms/opensbi | 2 +-
118
3 files changed, 1 insertion(+), 1 deletion(-)
119
120
diff --git a/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin b/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin
121
index XXXXXXX..XXXXXXX 100644
122
Binary files a/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin and b/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin differ
123
diff --git a/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin b/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin
124
index XXXXXXX..XXXXXXX 100644
125
Binary files a/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin and b/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin differ
126
diff --git a/roms/opensbi b/roms/opensbi
127
index XXXXXXX..XXXXXXX 160000
128
--- a/roms/opensbi
129
+++ b/roms/opensbi
130
@@ -1 +1 @@
131
-Subproject commit 48f91ee9c960f048c4a7d1da4447d31e04931e38
132
+Subproject commit 4489876e933d8ba0d8bc6c64bae71e295d45faac
133
--
134
2.37.2
diff view generated by jsdifflib
New patch
1
From: Alexey Baturo <baturo.alexey@gmail.com>
1
2
3
Fixes: 4302bef9e178 ("target/riscv: Calculate address according to XLEN")
4
Signed-off-by: Alexey Baturo <baturo.alexey@gmail.com>
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Message-Id: <20220717101543.478533-2-space.monkey.delivers@gmail.com>
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
---
9
target/riscv/translate.c | 2 +-
10
1 file changed, 1 insertion(+), 1 deletion(-)
11
12
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/riscv/translate.c
15
+++ b/target/riscv/translate.c
16
@@ -XXX,XX +XXX,XX @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm)
17
18
tcg_gen_addi_tl(addr, src1, imm);
19
if (ctx->pm_mask_enabled) {
20
- tcg_gen_and_tl(addr, addr, pm_mask);
21
+ tcg_gen_andc_tl(addr, addr, pm_mask);
22
} else if (get_xl(ctx) == MXL_RV32) {
23
tcg_gen_ext32u_tl(addr, addr);
24
}
25
--
26
2.37.2
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
Since commit fbf43c7dbf18 ("target/riscv: enable riscv kvm accel"),
4
KVM accelerator is supported on RISC-V. Let's document it.
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-Id: <20220719082635.3741878-1-bin.meng@windriver.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
docs/about/build-platforms.rst | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/docs/about/build-platforms.rst b/docs/about/build-platforms.rst
16
index XXXXXXX..XXXXXXX 100644
17
--- a/docs/about/build-platforms.rst
18
+++ b/docs/about/build-platforms.rst
19
@@ -XXX,XX +XXX,XX @@ Those hosts are officially supported, with various accelerators:
20
* - PPC
21
- kvm, tcg
22
* - RISC-V
23
- - tcg
24
+ - kvm, tcg
25
* - s390x
26
- kvm, tcg
27
* - SPARC
28
--
29
2.37.2
diff view generated by jsdifflib
New patch
1
From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com>
1
2
3
According to v-spec, mask agnostic behavior can be either kept as
4
undisturbed or set elements' bits to all 1s. To distinguish the
5
difference of mask policies, QEMU should be able to simulate the mask
6
agnostic behavior as "set mask elements' bits to all 1s".
7
8
There are multiple possibility for agnostic elements according to
9
v-spec. The main intent of this patch-set tries to add option that
10
can distinguish between mask policies. Setting agnostic elements to
11
all 1s allows QEMU to express this.
12
13
This is the first commit regarding the optional mask agnostic
14
behavior. Follow-up commits will add this optional behavior
15
for all rvv instructions.
16
17
Signed-off-by: eop Chen <eop.chen@sifive.com>
18
Reviewed-by: Frank Chang <frank.chang@sifive.com>
19
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
21
Message-Id: <165570784143.17634.35095816584573691-1@git.sr.ht>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
23
---
24
target/riscv/cpu.h | 2 ++
25
target/riscv/internals.h | 5 +++--
26
target/riscv/cpu_helper.c | 2 ++
27
target/riscv/translate.c | 2 ++
28
target/riscv/vector_helper.c | 8 ++++++++
29
target/riscv/insn_trans/trans_rvv.c.inc | 3 +++
30
6 files changed, 20 insertions(+), 2 deletions(-)
31
32
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/cpu.h
35
+++ b/target/riscv/cpu.h
36
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
37
bool ext_zve64f;
38
bool ext_zmmul;
39
bool rvv_ta_all_1s;
40
+ bool rvv_ma_all_1s;
41
42
uint32_t mvendorid;
43
uint64_t marchid;
44
@@ -XXX,XX +XXX,XX @@ FIELD(TB_FLAGS, XL, 20, 2)
45
FIELD(TB_FLAGS, PM_MASK_ENABLED, 22, 1)
46
FIELD(TB_FLAGS, PM_BASE_ENABLED, 23, 1)
47
FIELD(TB_FLAGS, VTA, 24, 1)
48
+FIELD(TB_FLAGS, VMA, 25, 1)
49
50
#ifdef TARGET_RISCV32
51
#define riscv_cpu_mxl(env) ((void)(env), MXL_RV32)
52
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/riscv/internals.h
55
+++ b/target/riscv/internals.h
56
@@ -XXX,XX +XXX,XX @@ FIELD(VDATA, VM, 0, 1)
57
FIELD(VDATA, LMUL, 1, 3)
58
FIELD(VDATA, VTA, 4, 1)
59
FIELD(VDATA, VTA_ALL_1S, 5, 1)
60
-FIELD(VDATA, NF, 6, 4)
61
-FIELD(VDATA, WD, 6, 1)
62
+FIELD(VDATA, VMA, 6, 1)
63
+FIELD(VDATA, NF, 7, 4)
64
+FIELD(VDATA, WD, 7, 1)
65
66
/* float point classify helpers */
67
target_ulong fclass_h(uint64_t frs1);
68
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/riscv/cpu_helper.c
71
+++ b/target/riscv/cpu_helper.c
72
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
73
flags = FIELD_DP32(flags, TB_FLAGS, VL_EQ_VLMAX, vl_eq_vlmax);
74
flags = FIELD_DP32(flags, TB_FLAGS, VTA,
75
FIELD_EX64(env->vtype, VTYPE, VTA));
76
+ flags = FIELD_DP32(flags, TB_FLAGS, VMA,
77
+ FIELD_EX64(env->vtype, VTYPE, VMA));
78
} else {
79
flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1);
80
}
81
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/riscv/translate.c
84
+++ b/target/riscv/translate.c
85
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
86
int8_t lmul;
87
uint8_t sew;
88
uint8_t vta;
89
+ uint8_t vma;
90
bool cfg_vta_all_1s;
91
target_ulong vstart;
92
bool vl_eq_vlmax;
93
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
94
ctx->sew = FIELD_EX32(tb_flags, TB_FLAGS, SEW);
95
ctx->lmul = sextract32(FIELD_EX32(tb_flags, TB_FLAGS, LMUL), 0, 3);
96
ctx->vta = FIELD_EX32(tb_flags, TB_FLAGS, VTA) && cpu->cfg.rvv_ta_all_1s;
97
+ ctx->vma = FIELD_EX32(tb_flags, TB_FLAGS, VMA) && cpu->cfg.rvv_ma_all_1s;
98
ctx->cfg_vta_all_1s = cpu->cfg.rvv_ta_all_1s;
99
ctx->vstart = env->vstart;
100
ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
101
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
102
index XXXXXXX..XXXXXXX 100644
103
--- a/target/riscv/vector_helper.c
104
+++ b/target/riscv/vector_helper.c
105
@@ -XXX,XX +XXX,XX @@ static inline uint32_t vext_vta(uint32_t desc)
106
return FIELD_EX32(simd_data(desc), VDATA, VTA);
107
}
108
109
+static inline uint32_t vext_vma(uint32_t desc)
110
+{
111
+ return FIELD_EX32(simd_data(desc), VDATA, VMA);
112
+}
113
+
114
static inline uint32_t vext_vta_all_1s(uint32_t desc)
115
{
116
return FIELD_EX32(simd_data(desc), VDATA, VTA_ALL_1S);
117
@@ -XXX,XX +XXX,XX @@ static void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2,
118
uint32_t vl = env->vl;
119
uint32_t total_elems = vext_get_total_elems(env, desc, esz);
120
uint32_t vta = vext_vta(desc);
121
+ uint32_t vma = vext_vma(desc);
122
uint32_t i;
123
124
for (i = env->vstart; i < vl; i++) {
125
if (!vm && !vext_elem_mask(v0, i)) {
126
+ /* set masked-off elements to 1s */
127
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
128
continue;
129
}
130
fn(vd, vs1, vs2, i);
131
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
132
index XXXXXXX..XXXXXXX 100644
133
--- a/target/riscv/insn_trans/trans_rvv.c.inc
134
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
135
@@ -XXX,XX +XXX,XX @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn,
136
data = FIELD_DP32(data, VDATA, VM, a->vm);
137
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
138
data = FIELD_DP32(data, VDATA, VTA, s->vta);
139
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
140
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
141
vreg_ofs(s, a->rs1), vreg_ofs(s, a->rs2),
142
cpu_env, s->cfg_ptr->vlen / 8,
143
@@ -XXX,XX +XXX,XX @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
144
data = FIELD_DP32(data, VDATA, VM, a->vm);
145
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
146
data = FIELD_DP32(data, VDATA, VTA, s->vta);
147
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
148
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
149
vreg_ofs(s, a->rs1),
150
vreg_ofs(s, a->rs2),
151
@@ -XXX,XX +XXX,XX @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a,
152
data = FIELD_DP32(data, VDATA, VM, a->vm);
153
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
154
data = FIELD_DP32(data, VDATA, VTA, s->vta);
155
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
156
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
157
vreg_ofs(s, a->rs1),
158
vreg_ofs(s, a->rs2),
159
--
160
2.37.2
diff view generated by jsdifflib
New patch
1
From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com>
1
2
3
Signed-off-by: eop Chen <eop.chen@sifive.com>
4
Reviewed-by: Frank Chang <frank.chang@sifive.com>
5
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-Id: <165570784143.17634.35095816584573691-2@git.sr.ht>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
10
target/riscv/vector_helper.c | 35 +++++++++++++++++--------
11
target/riscv/insn_trans/trans_rvv.c.inc | 5 ++++
12
2 files changed, 29 insertions(+), 11 deletions(-)
13
14
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/vector_helper.c
17
+++ b/target/riscv/vector_helper.c
18
@@ -XXX,XX +XXX,XX @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
19
uint32_t esz = 1 << log2_esz;
20
uint32_t total_elems = vext_get_total_elems(env, desc, esz);
21
uint32_t vta = vext_vta(desc);
22
+ uint32_t vma = vext_vma(desc);
23
24
for (i = env->vstart; i < env->vl; i++, env->vstart++) {
25
- if (!vm && !vext_elem_mask(v0, i)) {
26
- continue;
27
- }
28
-
29
k = 0;
30
while (k < nf) {
31
+ if (!vm && !vext_elem_mask(v0, i)) {
32
+ /* set masked-off elements to 1s */
33
+ vext_set_elems_1s(vd, vma, (i + k * max_elems) * esz,
34
+ (i + k * max_elems + 1) * esz);
35
+ k++;
36
+ continue;
37
+ }
38
target_ulong addr = base + stride * i + (k << log2_esz);
39
ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
40
k++;
41
@@ -XXX,XX +XXX,XX @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
42
uint32_t esz = 1 << log2_esz;
43
uint32_t total_elems = vext_get_total_elems(env, desc, esz);
44
uint32_t vta = vext_vta(desc);
45
+ uint32_t vma = vext_vma(desc);
46
47
/* load bytes from guest memory */
48
for (i = env->vstart; i < env->vl; i++, env->vstart++) {
49
- if (!vm && !vext_elem_mask(v0, i)) {
50
- continue;
51
- }
52
-
53
k = 0;
54
while (k < nf) {
55
+ if (!vm && !vext_elem_mask(v0, i)) {
56
+ /* set masked-off elements to 1s */
57
+ vext_set_elems_1s(vd, vma, (i + k * max_elems) * esz,
58
+ (i + k * max_elems + 1) * esz);
59
+ k++;
60
+ continue;
61
+ }
62
abi_ptr addr = get_index_addr(base, i, vs2) + (k << log2_esz);
63
ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
64
k++;
65
@@ -XXX,XX +XXX,XX @@ vext_ldff(void *vd, void *v0, target_ulong base,
66
uint32_t esz = 1 << log2_esz;
67
uint32_t total_elems = vext_get_total_elems(env, desc, esz);
68
uint32_t vta = vext_vta(desc);
69
+ uint32_t vma = vext_vma(desc);
70
target_ulong addr, offset, remain;
71
72
/* probe every access*/
73
@@ -XXX,XX +XXX,XX @@ ProbeSuccess:
74
}
75
for (i = env->vstart; i < env->vl; i++) {
76
k = 0;
77
- if (!vm && !vext_elem_mask(v0, i)) {
78
- continue;
79
- }
80
while (k < nf) {
81
+ if (!vm && !vext_elem_mask(v0, i)) {
82
+ /* set masked-off elements to 1s */
83
+ vext_set_elems_1s(vd, vma, (i + k * max_elems) * esz,
84
+ (i + k * max_elems + 1) * esz);
85
+ k++;
86
+ continue;
87
+ }
88
target_ulong addr = base + ((i * nf + k) << log2_esz);
89
ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
90
k++;
91
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
92
index XXXXXXX..XXXXXXX 100644
93
--- a/target/riscv/insn_trans/trans_rvv.c.inc
94
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
95
@@ -XXX,XX +XXX,XX @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t eew)
96
data = FIELD_DP32(data, VDATA, LMUL, emul);
97
data = FIELD_DP32(data, VDATA, NF, a->nf);
98
data = FIELD_DP32(data, VDATA, VTA, s->vta);
99
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
100
return ldst_us_trans(a->rd, a->rs1, data, fn, s, false);
101
}
102
103
@@ -XXX,XX +XXX,XX @@ static bool ld_us_mask_op(DisasContext *s, arg_vlm_v *a, uint8_t eew)
104
data = FIELD_DP32(data, VDATA, NF, 1);
105
/* Mask destination register are always tail-agnostic */
106
data = FIELD_DP32(data, VDATA, VTA, s->cfg_vta_all_1s);
107
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
108
return ldst_us_trans(a->rd, a->rs1, data, fn, s, false);
109
}
110
111
@@ -XXX,XX +XXX,XX @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t eew)
112
data = FIELD_DP32(data, VDATA, LMUL, emul);
113
data = FIELD_DP32(data, VDATA, NF, a->nf);
114
data = FIELD_DP32(data, VDATA, VTA, s->vta);
115
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
116
return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s, false);
117
}
118
119
@@ -XXX,XX +XXX,XX @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a, uint8_t eew)
120
data = FIELD_DP32(data, VDATA, LMUL, emul);
121
data = FIELD_DP32(data, VDATA, NF, a->nf);
122
data = FIELD_DP32(data, VDATA, VTA, s->vta);
123
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
124
return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s, false);
125
}
126
127
@@ -XXX,XX +XXX,XX @@ static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t eew)
128
data = FIELD_DP32(data, VDATA, LMUL, emul);
129
data = FIELD_DP32(data, VDATA, NF, a->nf);
130
data = FIELD_DP32(data, VDATA, VTA, s->vta);
131
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
132
return ldff_trans(a->rd, a->rs1, data, fn, s);
133
}
134
135
--
136
2.37.2
diff view generated by jsdifflib
New patch
1
From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com>
1
2
3
Signed-off-by: eop Chen <eop.chen@sifive.com>
4
Reviewed-by: Frank Chang <frank.chang@sifive.com>
5
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-Id: <165570784143.17634.35095816584573691-3@git.sr.ht>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
10
target/riscv/vector_helper.c | 3 +++
11
target/riscv/insn_trans/trans_rvv.c.inc | 2 ++
12
2 files changed, 5 insertions(+)
13
14
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/vector_helper.c
17
+++ b/target/riscv/vector_helper.c
18
@@ -XXX,XX +XXX,XX @@ static void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2,
19
uint32_t vl = env->vl;
20
uint32_t total_elems = vext_get_total_elems(env, desc, esz);
21
uint32_t vta = vext_vta(desc);
22
+ uint32_t vma = vext_vma(desc);
23
uint32_t i;
24
25
for (i = env->vstart; i < vl; i++) {
26
if (!vm && !vext_elem_mask(v0, i)) {
27
+ /* set masked-off elements to 1s */
28
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
29
continue;
30
}
31
fn(vd, s1, vs2, i);
32
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/insn_trans/trans_rvv.c.inc
35
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
36
@@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
37
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
38
data = FIELD_DP32(data, VDATA, VTA, s->vta);
39
data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
40
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
41
desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlen / 8,
42
s->cfg_ptr->vlen / 8, data));
43
44
@@ -XXX,XX +XXX,XX @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
45
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
46
data = FIELD_DP32(data, VDATA, VTA, s->vta);
47
data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
48
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
49
desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlen / 8,
50
s->cfg_ptr->vlen / 8, data));
51
52
--
53
2.37.2
diff view generated by jsdifflib
New patch
1
From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com>
1
2
3
Signed-off-by: eop Chen <eop.chen@sifive.com>
4
Reviewed-by: Frank Chang <frank.chang@sifive.com>
5
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-Id: <165570784143.17634.35095816584573691-4@git.sr.ht>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
10
target/riscv/vector_helper.c | 7 +++++++
11
target/riscv/insn_trans/trans_rvv.c.inc | 1 +
12
2 files changed, 8 insertions(+)
13
14
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/vector_helper.c
17
+++ b/target/riscv/vector_helper.c
18
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \
19
uint32_t esz = sizeof(TS1); \
20
uint32_t total_elems = vext_get_total_elems(env, desc, esz); \
21
uint32_t vta = vext_vta(desc); \
22
+ uint32_t vma = vext_vma(desc); \
23
uint32_t i; \
24
\
25
for (i = env->vstart; i < vl; i++) { \
26
if (!vm && !vext_elem_mask(v0, i)) { \
27
+ /* set masked-off elements to 1s */ \
28
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \
29
continue; \
30
} \
31
TS1 s1 = *((TS1 *)vs1 + HS1(i)); \
32
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \
33
uint32_t total_elems = \
34
vext_get_total_elems(env, desc, esz); \
35
uint32_t vta = vext_vta(desc); \
36
+ uint32_t vma = vext_vma(desc); \
37
uint32_t i; \
38
\
39
for (i = env->vstart; i < vl; i++) { \
40
if (!vm && !vext_elem_mask(v0, i)) { \
41
+ /* set masked-off elements to 1s */ \
42
+ vext_set_elems_1s(vd, vma, i * esz, \
43
+ (i + 1) * esz); \
44
continue; \
45
} \
46
TS2 s2 = *((TS2 *)vs2 + HS2(i)); \
47
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/riscv/insn_trans/trans_rvv.c.inc
50
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
51
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
52
data = FIELD_DP32(data, VDATA, VM, a->vm); \
53
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
54
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
55
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
56
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
57
vreg_ofs(s, a->rs1), \
58
vreg_ofs(s, a->rs2), cpu_env, \
59
--
60
2.37.2
diff view generated by jsdifflib
New patch
1
From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com>
1
2
3
Signed-off-by: eop Chen <eop.chen@sifive.com>
4
Reviewed-by: Frank Chang <frank.chang@sifive.com>
5
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-Id: <165570784143.17634.35095816584573691-5@git.sr.ht>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
10
target/riscv/vector_helper.c | 10 ++++++++++
11
target/riscv/insn_trans/trans_rvv.c.inc | 1 +
12
2 files changed, 11 insertions(+)
13
14
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/vector_helper.c
17
+++ b/target/riscv/vector_helper.c
18
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \
19
uint32_t vl = env->vl; \
20
uint32_t total_elems = env_archcpu(env)->cfg.vlen; \
21
uint32_t vta_all_1s = vext_vta_all_1s(desc); \
22
+ uint32_t vma = vext_vma(desc); \
23
uint32_t i; \
24
\
25
for (i = env->vstart; i < vl; i++) { \
26
ETYPE s1 = *((ETYPE *)vs1 + H(i)); \
27
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
28
if (!vm && !vext_elem_mask(v0, i)) { \
29
+ /* set masked-off elements to 1s */ \
30
+ if (vma) { \
31
+ vext_set_elem_mask(vd, i, 1); \
32
+ } \
33
continue; \
34
} \
35
vext_set_elem_mask(vd, i, DO_OP(s2, s1)); \
36
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
37
uint32_t vl = env->vl; \
38
uint32_t total_elems = env_archcpu(env)->cfg.vlen; \
39
uint32_t vta_all_1s = vext_vta_all_1s(desc); \
40
+ uint32_t vma = vext_vma(desc); \
41
uint32_t i; \
42
\
43
for (i = env->vstart; i < vl; i++) { \
44
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
45
if (!vm && !vext_elem_mask(v0, i)) { \
46
+ /* set masked-off elements to 1s */ \
47
+ if (vma) { \
48
+ vext_set_elem_mask(vd, i, 1); \
49
+ } \
50
continue; \
51
} \
52
vext_set_elem_mask(vd, i, \
53
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/riscv/insn_trans/trans_rvv.c.inc
56
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
57
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
58
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
59
data = \
60
FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\
61
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
62
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
63
vreg_ofs(s, a->rs1), \
64
vreg_ofs(s, a->rs2), cpu_env, \
65
--
66
2.37.2
diff view generated by jsdifflib
New patch
1
From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com>
1
2
3
Signed-off-by: eop Chen <eop.chen@sifive.com>
4
Reviewed-by: Frank Chang <frank.chang@sifive.com>
5
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-Id: <165570784143.17634.35095816584573691-6@git.sr.ht>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
10
target/riscv/vector_helper.c | 26 ++++++++++++++++----------
11
1 file changed, 16 insertions(+), 10 deletions(-)
12
13
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/vector_helper.c
16
+++ b/target/riscv/vector_helper.c
17
@@ -XXX,XX +XXX,XX @@ static inline void
18
vext_vv_rm_1(void *vd, void *v0, void *vs1, void *vs2,
19
CPURISCVState *env,
20
uint32_t vl, uint32_t vm, int vxrm,
21
- opivv2_rm_fn *fn)
22
+ opivv2_rm_fn *fn, uint32_t vma, uint32_t esz)
23
{
24
for (uint32_t i = env->vstart; i < vl; i++) {
25
if (!vm && !vext_elem_mask(v0, i)) {
26
+ /* set masked-off elements to 1s */
27
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
28
continue;
29
}
30
fn(vd, vs1, vs2, i, env, vxrm);
31
@@ -XXX,XX +XXX,XX @@ vext_vv_rm_2(void *vd, void *v0, void *vs1, void *vs2,
32
uint32_t vl = env->vl;
33
uint32_t total_elems = vext_get_total_elems(env, desc, esz);
34
uint32_t vta = vext_vta(desc);
35
+ uint32_t vma = vext_vma(desc);
36
37
switch (env->vxrm) {
38
case 0: /* rnu */
39
vext_vv_rm_1(vd, v0, vs1, vs2,
40
- env, vl, vm, 0, fn);
41
+ env, vl, vm, 0, fn, vma, esz);
42
break;
43
case 1: /* rne */
44
vext_vv_rm_1(vd, v0, vs1, vs2,
45
- env, vl, vm, 1, fn);
46
+ env, vl, vm, 1, fn, vma, esz);
47
break;
48
case 2: /* rdn */
49
vext_vv_rm_1(vd, v0, vs1, vs2,
50
- env, vl, vm, 2, fn);
51
+ env, vl, vm, 2, fn, vma, esz);
52
break;
53
default: /* rod */
54
vext_vv_rm_1(vd, v0, vs1, vs2,
55
- env, vl, vm, 3, fn);
56
+ env, vl, vm, 3, fn, vma, esz);
57
break;
58
}
59
/* set tail elements to 1s */
60
@@ -XXX,XX +XXX,XX @@ static inline void
61
vext_vx_rm_1(void *vd, void *v0, target_long s1, void *vs2,
62
CPURISCVState *env,
63
uint32_t vl, uint32_t vm, int vxrm,
64
- opivx2_rm_fn *fn)
65
+ opivx2_rm_fn *fn, uint32_t vma, uint32_t esz)
66
{
67
for (uint32_t i = env->vstart; i < vl; i++) {
68
if (!vm && !vext_elem_mask(v0, i)) {
69
+ /* set masked-off elements to 1s */
70
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
71
continue;
72
}
73
fn(vd, s1, vs2, i, env, vxrm);
74
@@ -XXX,XX +XXX,XX @@ vext_vx_rm_2(void *vd, void *v0, target_long s1, void *vs2,
75
uint32_t vl = env->vl;
76
uint32_t total_elems = vext_get_total_elems(env, desc, esz);
77
uint32_t vta = vext_vta(desc);
78
+ uint32_t vma = vext_vma(desc);
79
80
switch (env->vxrm) {
81
case 0: /* rnu */
82
vext_vx_rm_1(vd, v0, s1, vs2,
83
- env, vl, vm, 0, fn);
84
+ env, vl, vm, 0, fn, vma, esz);
85
break;
86
case 1: /* rne */
87
vext_vx_rm_1(vd, v0, s1, vs2,
88
- env, vl, vm, 1, fn);
89
+ env, vl, vm, 1, fn, vma, esz);
90
break;
91
case 2: /* rdn */
92
vext_vx_rm_1(vd, v0, s1, vs2,
93
- env, vl, vm, 2, fn);
94
+ env, vl, vm, 2, fn, vma, esz);
95
break;
96
default: /* rod */
97
vext_vx_rm_1(vd, v0, s1, vs2,
98
- env, vl, vm, 3, fn);
99
+ env, vl, vm, 3, fn, vma, esz);
100
break;
101
}
102
/* set tail elements to 1s */
103
--
104
2.37.2
diff view generated by jsdifflib
New patch
1
From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com>
1
2
3
Signed-off-by: eop Chen <eop.chen@sifive.com>
4
Reviewed-by: Frank Chang <frank.chang@sifive.com>
5
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-Id: <165570784143.17634.35095816584573691-7@git.sr.ht>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
10
target/riscv/vector_helper.c | 26 +++++++++++++++++++++++++
11
target/riscv/insn_trans/trans_rvv.c.inc | 12 ++++++++++++
12
2 files changed, 38 insertions(+)
13
14
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/vector_helper.c
17
+++ b/target/riscv/vector_helper.c
18
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \
19
uint32_t total_elems = \
20
vext_get_total_elems(env, desc, ESZ); \
21
uint32_t vta = vext_vta(desc); \
22
+ uint32_t vma = vext_vma(desc); \
23
uint32_t i; \
24
\
25
for (i = env->vstart; i < vl; i++) { \
26
if (!vm && !vext_elem_mask(v0, i)) { \
27
+ /* set masked-off elements to 1s */ \
28
+ vext_set_elems_1s(vd, vma, i * ESZ, \
29
+ (i + 1) * ESZ); \
30
continue; \
31
} \
32
do_##NAME(vd, vs1, vs2, i, env); \
33
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, \
34
uint32_t total_elems = \
35
vext_get_total_elems(env, desc, ESZ); \
36
uint32_t vta = vext_vta(desc); \
37
+ uint32_t vma = vext_vma(desc); \
38
uint32_t i; \
39
\
40
for (i = env->vstart; i < vl; i++) { \
41
if (!vm && !vext_elem_mask(v0, i)) { \
42
+ /* set masked-off elements to 1s */ \
43
+ vext_set_elems_1s(vd, vma, i * ESZ, \
44
+ (i + 1) * ESZ); \
45
continue; \
46
} \
47
do_##NAME(vd, s1, vs2, i, env); \
48
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \
49
uint32_t total_elems = \
50
vext_get_total_elems(env, desc, ESZ); \
51
uint32_t vta = vext_vta(desc); \
52
+ uint32_t vma = vext_vma(desc); \
53
uint32_t i; \
54
\
55
if (vl == 0) { \
56
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \
57
} \
58
for (i = env->vstart; i < vl; i++) { \
59
if (!vm && !vext_elem_mask(v0, i)) { \
60
+ /* set masked-off elements to 1s */ \
61
+ vext_set_elems_1s(vd, vma, i * ESZ, \
62
+ (i + 1) * ESZ); \
63
continue; \
64
} \
65
do_##NAME(vd, vs2, i, env); \
66
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \
67
uint32_t vl = env->vl; \
68
uint32_t total_elems = env_archcpu(env)->cfg.vlen; \
69
uint32_t vta_all_1s = vext_vta_all_1s(desc); \
70
+ uint32_t vma = vext_vma(desc); \
71
uint32_t i; \
72
\
73
for (i = env->vstart; i < vl; i++) { \
74
ETYPE s1 = *((ETYPE *)vs1 + H(i)); \
75
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
76
if (!vm && !vext_elem_mask(v0, i)) { \
77
+ /* set masked-off elements to 1s */ \
78
+ if (vma) { \
79
+ vext_set_elem_mask(vd, i, 1); \
80
+ } \
81
continue; \
82
} \
83
vext_set_elem_mask(vd, i, \
84
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \
85
uint32_t vl = env->vl; \
86
uint32_t total_elems = env_archcpu(env)->cfg.vlen; \
87
uint32_t vta_all_1s = vext_vta_all_1s(desc); \
88
+ uint32_t vma = vext_vma(desc); \
89
uint32_t i; \
90
\
91
for (i = env->vstart; i < vl; i++) { \
92
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
93
if (!vm && !vext_elem_mask(v0, i)) { \
94
+ /* set masked-off elements to 1s */ \
95
+ if (vma) { \
96
+ vext_set_elem_mask(vd, i, 1); \
97
+ } \
98
continue; \
99
} \
100
vext_set_elem_mask(vd, i, \
101
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \
102
uint32_t total_elems = \
103
vext_get_total_elems(env, desc, ESZ); \
104
uint32_t vta = vext_vta(desc); \
105
+ uint32_t vma = vext_vma(desc); \
106
uint32_t i; \
107
\
108
for (i = env->vstart; i < vl; i++) { \
109
if (!vm && !vext_elem_mask(v0, i)) { \
110
+ /* set masked-off elements to 1s */ \
111
+ vext_set_elems_1s(vd, vma, i * ESZ, \
112
+ (i + 1) * ESZ); \
113
continue; \
114
} \
115
do_##NAME(vd, vs2, i); \
116
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
117
index XXXXXXX..XXXXXXX 100644
118
--- a/target/riscv/insn_trans/trans_rvv.c.inc
119
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
120
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
121
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
122
data = \
123
FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\
124
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
125
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
126
vreg_ofs(s, a->rs1), \
127
vreg_ofs(s, a->rs2), cpu_env, \
128
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
129
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
130
data = FIELD_DP32(data, VDATA, VTA_ALL_1S, \
131
s->cfg_vta_all_1s); \
132
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
133
return opfvf_trans(a->rd, a->rs1, a->rs2, data, \
134
fns[s->sew - 1], s); \
135
} \
136
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
137
data = FIELD_DP32(data, VDATA, VM, a->vm); \
138
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
139
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
140
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
141
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
142
vreg_ofs(s, a->rs1), \
143
vreg_ofs(s, a->rs2), cpu_env, \
144
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
145
data = FIELD_DP32(data, VDATA, VM, a->vm); \
146
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
147
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
148
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
149
return opfvf_trans(a->rd, a->rs1, a->rs2, data, \
150
fns[s->sew - 1], s); \
151
} \
152
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
153
data = FIELD_DP32(data, VDATA, VM, a->vm); \
154
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
155
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
156
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
157
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
158
vreg_ofs(s, a->rs1), \
159
vreg_ofs(s, a->rs2), cpu_env, \
160
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
161
data = FIELD_DP32(data, VDATA, VM, a->vm); \
162
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
163
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
164
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
165
return opfvf_trans(a->rd, a->rs1, a->rs2, data, \
166
fns[s->sew - 1], s); \
167
} \
168
@@ -XXX,XX +XXX,XX @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
169
data = FIELD_DP32(data, VDATA, VM, a->vm);
170
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
171
data = FIELD_DP32(data, VDATA, VTA, s->vta);
172
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
173
tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
174
vreg_ofs(s, a->rs2), cpu_env,
175
s->cfg_ptr->vlen / 8,
176
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
177
TCGv_i32 desc;
178
uint32_t data = FIELD_DP32(0, VDATA, LMUL, s->lmul);
179
data = FIELD_DP32(data, VDATA, VTA, s->vta);
180
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
181
static gen_helper_vmv_vx * const fns[3] = {
182
gen_helper_vmv_v_x_h,
183
gen_helper_vmv_v_x_w,
184
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
185
data = FIELD_DP32(data, VDATA, VM, a->vm); \
186
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
187
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
188
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
189
tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
190
vreg_ofs(s, a->rs2), cpu_env, \
191
s->cfg_ptr->vlen / 8, \
192
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
193
data = FIELD_DP32(data, VDATA, VM, a->vm); \
194
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
195
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
196
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
197
tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
198
vreg_ofs(s, a->rs2), cpu_env, \
199
s->cfg_ptr->vlen / 8, \
200
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
201
data = FIELD_DP32(data, VDATA, VM, a->vm); \
202
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
203
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
204
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
205
tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
206
vreg_ofs(s, a->rs2), cpu_env, \
207
s->cfg_ptr->vlen / 8, \
208
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
209
data = FIELD_DP32(data, VDATA, VM, a->vm); \
210
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
211
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
212
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
213
tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
214
vreg_ofs(s, a->rs2), cpu_env, \
215
s->cfg_ptr->vlen / 8, \
216
--
217
2.37.2
diff view generated by jsdifflib
New patch
1
From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com>
1
2
3
Signed-off-by: eop Chen <eop.chen@sifive.com>
4
Reviewed-by: Frank Chang <frank.chang@sifive.com>
5
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-Id: <165570784143.17634.35095816584573691-8@git.sr.ht>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
10
target/riscv/vector_helper.c | 11 +++++++++++
11
target/riscv/insn_trans/trans_rvv.c.inc | 3 +++
12
2 files changed, 14 insertions(+)
13
14
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/vector_helper.c
17
+++ b/target/riscv/vector_helper.c
18
@@ -XXX,XX +XXX,XX @@ static void vmsetm(void *vd, void *v0, void *vs2, CPURISCVState *env,
19
uint32_t vl = env->vl;
20
uint32_t total_elems = env_archcpu(env)->cfg.vlen;
21
uint32_t vta_all_1s = vext_vta_all_1s(desc);
22
+ uint32_t vma = vext_vma(desc);
23
int i;
24
bool first_mask_bit = false;
25
26
for (i = env->vstart; i < vl; i++) {
27
if (!vm && !vext_elem_mask(v0, i)) {
28
+ /* set masked-off elements to 1s */
29
+ if (vma) {
30
+ vext_set_elem_mask(vd, i, 1);
31
+ }
32
continue;
33
}
34
/* write a zero to all following active elements */
35
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, CPURISCVState *env, \
36
uint32_t esz = sizeof(ETYPE); \
37
uint32_t total_elems = vext_get_total_elems(env, desc, esz); \
38
uint32_t vta = vext_vta(desc); \
39
+ uint32_t vma = vext_vma(desc); \
40
uint32_t sum = 0; \
41
int i; \
42
\
43
for (i = env->vstart; i < vl; i++) { \
44
if (!vm && !vext_elem_mask(v0, i)) { \
45
+ /* set masked-off elements to 1s */ \
46
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \
47
continue; \
48
} \
49
*((ETYPE *)vd + H(i)) = sum; \
50
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, CPURISCVState *env, uint32_t desc) \
51
uint32_t esz = sizeof(ETYPE); \
52
uint32_t total_elems = vext_get_total_elems(env, desc, esz); \
53
uint32_t vta = vext_vta(desc); \
54
+ uint32_t vma = vext_vma(desc); \
55
int i; \
56
\
57
for (i = env->vstart; i < vl; i++) { \
58
if (!vm && !vext_elem_mask(v0, i)) { \
59
+ /* set masked-off elements to 1s */ \
60
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \
61
continue; \
62
} \
63
*((ETYPE *)vd + H(i)) = i; \
64
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/riscv/insn_trans/trans_rvv.c.inc
67
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
68
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
69
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
70
data = \
71
FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\
72
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
73
tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), \
74
vreg_ofs(s, 0), vreg_ofs(s, a->rs2), \
75
cpu_env, s->cfg_ptr->vlen / 8, \
76
@@ -XXX,XX +XXX,XX @@ static bool trans_viota_m(DisasContext *s, arg_viota_m *a)
77
data = FIELD_DP32(data, VDATA, VM, a->vm);
78
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
79
data = FIELD_DP32(data, VDATA, VTA, s->vta);
80
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
81
static gen_helper_gvec_3_ptr * const fns[4] = {
82
gen_helper_viota_m_b, gen_helper_viota_m_h,
83
gen_helper_viota_m_w, gen_helper_viota_m_d,
84
@@ -XXX,XX +XXX,XX @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
85
data = FIELD_DP32(data, VDATA, VM, a->vm);
86
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
87
data = FIELD_DP32(data, VDATA, VTA, s->vta);
88
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
89
static gen_helper_gvec_2_ptr * const fns[4] = {
90
gen_helper_vid_v_b, gen_helper_vid_v_h,
91
gen_helper_vid_v_w, gen_helper_vid_v_d,
92
--
93
2.37.2
diff view generated by jsdifflib
New patch
1
From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com>
1
2
3
Signed-off-by: eop Chen <eop.chen@sifive.com>
4
Reviewed-by: Frank Chang <frank.chang@sifive.com>
5
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-Id: <165570784143.17634.35095816584573691-9@git.sr.ht>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
10
target/riscv/vector_helper.c | 26 +++++++++++++++++++++++--
11
target/riscv/insn_trans/trans_rvv.c.inc | 1 +
12
2 files changed, 25 insertions(+), 2 deletions(-)
13
14
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/vector_helper.c
17
+++ b/target/riscv/vector_helper.c
18
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
19
uint32_t esz = sizeof(ETYPE); \
20
uint32_t total_elems = vext_get_total_elems(env, desc, esz); \
21
uint32_t vta = vext_vta(desc); \
22
+ uint32_t vma = vext_vma(desc); \
23
target_ulong offset = s1, i_min, i; \
24
\
25
i_min = MAX(env->vstart, offset); \
26
for (i = i_min; i < vl; i++) { \
27
if (!vm && !vext_elem_mask(v0, i)) { \
28
+ /* set masked-off elements to 1s */ \
29
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \
30
continue; \
31
} \
32
*((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - offset)); \
33
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
34
uint32_t esz = sizeof(ETYPE); \
35
uint32_t total_elems = vext_get_total_elems(env, desc, esz); \
36
uint32_t vta = vext_vta(desc); \
37
+ uint32_t vma = vext_vma(desc); \
38
target_ulong i_max, i; \
39
\
40
i_max = MAX(MIN(s1 < vlmax ? vlmax - s1 : 0, vl), env->vstart); \
41
for (i = env->vstart; i < i_max; ++i) { \
42
- if (vm || vext_elem_mask(v0, i)) { \
43
- *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i + s1)); \
44
+ if (!vm && !vext_elem_mask(v0, i)) { \
45
+ /* set masked-off elements to 1s */ \
46
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \
47
+ continue; \
48
} \
49
+ *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i + s1)); \
50
} \
51
\
52
for (i = i_max; i < vl; ++i) { \
53
@@ -XXX,XX +XXX,XX @@ static void vslide1up_##BITWIDTH(void *vd, void *v0, target_ulong s1, \
54
uint32_t esz = sizeof(ETYPE); \
55
uint32_t total_elems = vext_get_total_elems(env, desc, esz); \
56
uint32_t vta = vext_vta(desc); \
57
+ uint32_t vma = vext_vma(desc); \
58
uint32_t i; \
59
\
60
for (i = env->vstart; i < vl; i++) { \
61
if (!vm && !vext_elem_mask(v0, i)) { \
62
+ /* set masked-off elements to 1s */ \
63
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \
64
continue; \
65
} \
66
if (i == 0) { \
67
@@ -XXX,XX +XXX,XX @@ static void vslide1down_##BITWIDTH(void *vd, void *v0, target_ulong s1, \
68
uint32_t esz = sizeof(ETYPE); \
69
uint32_t total_elems = vext_get_total_elems(env, desc, esz); \
70
uint32_t vta = vext_vta(desc); \
71
+ uint32_t vma = vext_vma(desc); \
72
uint32_t i; \
73
\
74
for (i = env->vstart; i < vl; i++) { \
75
if (!vm && !vext_elem_mask(v0, i)) { \
76
+ /* set masked-off elements to 1s */ \
77
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \
78
continue; \
79
} \
80
if (i == vl - 1) { \
81
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \
82
uint32_t esz = sizeof(TS2); \
83
uint32_t total_elems = vext_get_total_elems(env, desc, esz); \
84
uint32_t vta = vext_vta(desc); \
85
+ uint32_t vma = vext_vma(desc); \
86
uint64_t index; \
87
uint32_t i; \
88
\
89
for (i = env->vstart; i < vl; i++) { \
90
if (!vm && !vext_elem_mask(v0, i)) { \
91
+ /* set masked-off elements to 1s */ \
92
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \
93
continue; \
94
} \
95
index = *((TS1 *)vs1 + HS1(i)); \
96
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
97
uint32_t esz = sizeof(ETYPE); \
98
uint32_t total_elems = vext_get_total_elems(env, desc, esz); \
99
uint32_t vta = vext_vta(desc); \
100
+ uint32_t vma = vext_vma(desc); \
101
uint64_t index = s1; \
102
uint32_t i; \
103
\
104
for (i = env->vstart; i < vl; i++) { \
105
if (!vm && !vext_elem_mask(v0, i)) { \
106
+ /* set masked-off elements to 1s */ \
107
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \
108
continue; \
109
} \
110
if (index >= vlmax) { \
111
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \
112
uint32_t esz = sizeof(ETYPE); \
113
uint32_t total_elems = vext_get_total_elems(env, desc, esz); \
114
uint32_t vta = vext_vta(desc); \
115
+ uint32_t vma = vext_vma(desc); \
116
uint32_t i; \
117
\
118
for (i = env->vstart; i < vl; i++) { \
119
if (!vm && !vext_elem_mask(v0, i)) { \
120
+ /* set masked-off elements to 1s */ \
121
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \
122
continue; \
123
} \
124
*((ETYPE *)vd + HD(i)) = *((DTYPE *)vs2 + HS1(i)); \
125
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
126
index XXXXXXX..XXXXXXX 100644
127
--- a/target/riscv/insn_trans/trans_rvv.c.inc
128
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
129
@@ -XXX,XX +XXX,XX @@ static bool int_ext_op(DisasContext *s, arg_rmr *a, uint8_t seq)
130
data = FIELD_DP32(data, VDATA, VM, a->vm);
131
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
132
data = FIELD_DP32(data, VDATA, VTA, s->vta);
133
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
134
135
tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
136
vreg_ofs(s, a->rs2), cpu_env,
137
--
138
2.37.2
diff view generated by jsdifflib
New patch
1
From: eopXD <eop.chen@sifive.com>
1
2
3
According to v-spec, mask agnostic behavior can be either kept as
4
undisturbed or set elements' bits to all 1s. To distinguish the
5
difference of mask policies, QEMU should be able to simulate the mask
6
agnostic behavior as "set mask elements' bits to all 1s".
7
8
There are multiple possibility for agnostic elements according to
9
v-spec. The main intent of this patch-set tries to add option that
10
can distinguish between mask policies. Setting agnostic elements to
11
all 1s allows QEMU to express this.
12
13
This commit adds option 'rvv_ma_all_1s' is added to enable the
14
behavior, it is default as disabled.
15
16
Signed-off-by: eop Chen <eop.chen@sifive.com>
17
Reviewed-by: Frank Chang <frank.chang@sifive.com>
18
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
19
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
20
Message-Id: <165570784143.17634.35095816584573691-10@git.sr.ht>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
---
23
target/riscv/cpu.c | 1 +
24
1 file changed, 1 insertion(+)
25
26
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/riscv/cpu.c
29
+++ b/target/riscv/cpu.c
30
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = {
31
DEFINE_PROP_BOOL("short-isa-string", RISCVCPU, cfg.short_isa_string, false),
32
33
DEFINE_PROP_BOOL("rvv_ta_all_1s", RISCVCPU, cfg.rvv_ta_all_1s, false),
34
+ DEFINE_PROP_BOOL("rvv_ma_all_1s", RISCVCPU, cfg.rvv_ma_all_1s, false),
35
DEFINE_PROP_END_OF_LIST(),
36
};
37
38
--
39
2.37.2
diff view generated by jsdifflib
New patch
1
From: Dao Lu <daolu@rivosinc.com>
1
2
3
Added support for RISC-V PAUSE instruction from Zihintpause extension,
4
enabled by default.
5
6
Tested-by: Heiko Stuebner <heiko@sntech.de>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Dao Lu <daolu@rivosinc.com>
9
Message-Id: <20220725034728.2620750-2-daolu@rivosinc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/cpu.h | 1 +
13
target/riscv/insn32.decode | 7 ++++++-
14
target/riscv/cpu.c | 2 ++
15
target/riscv/insn_trans/trans_rvi.c.inc | 16 ++++++++++++++++
16
4 files changed, 25 insertions(+), 1 deletion(-)
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 @@ struct RISCVCPUConfig {
23
bool ext_zkt;
24
bool ext_ifencei;
25
bool ext_icsr;
26
+ bool ext_zihintpause;
27
bool ext_svinval;
28
bool ext_svnapot;
29
bool ext_svpbmt;
30
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/riscv/insn32.decode
33
+++ b/target/riscv/insn32.decode
34
@@ -XXX,XX +XXX,XX @@ srl 0000000 ..... ..... 101 ..... 0110011 @r
35
sra 0100000 ..... ..... 101 ..... 0110011 @r
36
or 0000000 ..... ..... 110 ..... 0110011 @r
37
and 0000000 ..... ..... 111 ..... 0110011 @r
38
-fence ---- pred:4 succ:4 ----- 000 ----- 0001111
39
+
40
+{
41
+ pause 0000 0001 0000 00000 000 00000 0001111
42
+ fence ---- pred:4 succ:4 ----- 000 ----- 0001111
43
+}
44
+
45
fence_i ---- ---- ---- ----- 001 ----- 0001111
46
csrrw ............ ..... 001 ..... 1110011 @csr
47
csrrs ............ ..... 010 ..... 1110011 @csr
48
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/riscv/cpu.c
51
+++ b/target/riscv/cpu.c
52
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
53
ISA_EXT_DATA_ENTRY(v, false, PRIV_VERSION_1_12_0, ext_v),
54
ISA_EXT_DATA_ENTRY(zicsr, true, PRIV_VERSION_1_10_0, ext_icsr),
55
ISA_EXT_DATA_ENTRY(zifencei, true, PRIV_VERSION_1_10_0, ext_ifencei),
56
+ ISA_EXT_DATA_ENTRY(zihintpause, true, PRIV_VERSION_1_10_0, ext_zihintpause),
57
ISA_EXT_DATA_ENTRY(zfh, true, PRIV_VERSION_1_12_0, ext_zfh),
58
ISA_EXT_DATA_ENTRY(zfhmin, true, PRIV_VERSION_1_12_0, ext_zfhmin),
59
ISA_EXT_DATA_ENTRY(zfinx, true, PRIV_VERSION_1_12_0, ext_zfinx),
60
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
61
DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
62
DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
63
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
64
+ DEFINE_PROP_BOOL("Zihintpause", RISCVCPU, cfg.ext_zihintpause, true),
65
DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
66
DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
67
DEFINE_PROP_BOOL("Zve32f", RISCVCPU, cfg.ext_zve32f, false),
68
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/riscv/insn_trans/trans_rvi.c.inc
71
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
72
@@ -XXX,XX +XXX,XX @@ static bool trans_srad(DisasContext *ctx, arg_srad *a)
73
return gen_shift(ctx, a, EXT_SIGN, tcg_gen_sar_tl, NULL);
74
}
75
76
+static bool trans_pause(DisasContext *ctx, arg_pause *a)
77
+{
78
+ if (!ctx->cfg_ptr->ext_zihintpause) {
79
+ return false;
80
+ }
81
+
82
+ /*
83
+ * PAUSE is a no-op in QEMU,
84
+ * end the TB and return to main loop
85
+ */
86
+ gen_set_pc_imm(ctx, ctx->pc_succ_insn);
87
+ tcg_gen_exit_tb(NULL, 0);
88
+ ctx->base.is_jmp = DISAS_NORETURN;
89
+
90
+ return true;
91
+}
92
93
static bool trans_fence(DisasContext *ctx, arg_fence *a)
94
{
95
--
96
2.37.2
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <danielhb413@gmail.com>
1
2
3
The 'fdt' param is not being used in riscv_setup_rom_reset_vec().
4
Simplify the API by removing it. While we're at it, remove the redundant
5
'return' statement at the end of function.
6
7
Cc: Palmer Dabbelt <palmer@dabbelt.com>
8
Cc: Alistair Francis <alistair.francis@wdc.com>
9
Cc: Bin Meng <bin.meng@windriver.com>
10
Cc: Vijai Kumar K <vijai@behindbytes.com>
11
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
12
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-Id: <20220728181926.2123771-1-danielhb413@gmail.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
17
include/hw/riscv/boot.h | 2 +-
18
hw/riscv/boot.c | 4 +---
19
hw/riscv/microchip_pfsoc.c | 2 +-
20
hw/riscv/shakti_c.c | 3 +--
21
hw/riscv/spike.c | 2 +-
22
hw/riscv/virt.c | 2 +-
23
6 files changed, 6 insertions(+), 9 deletions(-)
24
25
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/riscv/boot.h
28
+++ b/include/hw/riscv/boot.h
29
@@ -XXX,XX +XXX,XX @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts
30
hwaddr saddr,
31
hwaddr rom_base, hwaddr rom_size,
32
uint64_t kernel_entry,
33
- uint64_t fdt_load_addr, void *fdt);
34
+ uint64_t fdt_load_addr);
35
void riscv_rom_copy_firmware_info(MachineState *machine, hwaddr rom_base,
36
hwaddr rom_size,
37
uint32_t reset_vec_size,
38
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/riscv/boot.c
41
+++ b/hw/riscv/boot.c
42
@@ -XXX,XX +XXX,XX @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts
43
hwaddr start_addr,
44
hwaddr rom_base, hwaddr rom_size,
45
uint64_t kernel_entry,
46
- uint64_t fdt_load_addr, void *fdt)
47
+ uint64_t fdt_load_addr)
48
{
49
int i;
50
uint32_t start_addr_hi32 = 0x00000000;
51
@@ -XXX,XX +XXX,XX @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts
52
rom_base, &address_space_memory);
53
riscv_rom_copy_firmware_info(machine, rom_base, rom_size, sizeof(reset_vec),
54
kernel_entry);
55
-
56
- return;
57
}
58
59
void riscv_setup_direct_kernel(hwaddr kernel_addr, hwaddr fdt_addr)
60
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/hw/riscv/microchip_pfsoc.c
63
+++ b/hw/riscv/microchip_pfsoc.c
64
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
65
riscv_setup_rom_reset_vec(machine, &s->soc.u_cpus, firmware_load_addr,
66
memmap[MICROCHIP_PFSOC_ENVM_DATA].base,
67
memmap[MICROCHIP_PFSOC_ENVM_DATA].size,
68
- kernel_entry, fdt_load_addr, machine->fdt);
69
+ kernel_entry, fdt_load_addr);
70
}
71
}
72
73
diff --git a/hw/riscv/shakti_c.c b/hw/riscv/shakti_c.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/hw/riscv/shakti_c.c
76
+++ b/hw/riscv/shakti_c.c
77
@@ -XXX,XX +XXX,XX @@ static void shakti_c_machine_state_init(MachineState *mstate)
78
riscv_setup_rom_reset_vec(mstate, &sms->soc.cpus,
79
shakti_c_memmap[SHAKTI_C_RAM].base,
80
shakti_c_memmap[SHAKTI_C_ROM].base,
81
- shakti_c_memmap[SHAKTI_C_ROM].size, 0, 0,
82
- NULL);
83
+ shakti_c_memmap[SHAKTI_C_ROM].size, 0, 0);
84
if (mstate->firmware) {
85
riscv_load_firmware(mstate->firmware,
86
shakti_c_memmap[SHAKTI_C_RAM].base,
87
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/hw/riscv/spike.c
90
+++ b/hw/riscv/spike.c
91
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
92
riscv_setup_rom_reset_vec(machine, &s->soc[0], memmap[SPIKE_DRAM].base,
93
memmap[SPIKE_MROM].base,
94
memmap[SPIKE_MROM].size, kernel_entry,
95
- fdt_load_addr, s->fdt);
96
+ fdt_load_addr);
97
98
/* initialize HTIF using symbols found in load_kernel */
99
htif_mm_init(system_memory, mask_rom,
100
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/hw/riscv/virt.c
103
+++ b/hw/riscv/virt.c
104
@@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data)
105
riscv_setup_rom_reset_vec(machine, &s->soc[0], start_addr,
106
virt_memmap[VIRT_MROM].base,
107
virt_memmap[VIRT_MROM].size, kernel_entry,
108
- fdt_load_addr, machine->fdt);
109
+ fdt_load_addr);
110
111
/*
112
* Only direct boot kernel is currently supported for KVM VM,
113
--
114
2.37.2
diff view generated by jsdifflib
New patch
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
2
3
Normally, riscv_csrrw_check is called when executing Zicsr instructions.
4
And we can only do access control for existed CSRs. So the priority of
5
CSR related check, from highest to lowest, should be as follows:
6
1) check whether Zicsr is supported: raise RISCV_EXCP_ILLEGAL_INST if not
7
2) check whether csr is existed: raise RISCV_EXCP_ILLEGAL_INST if not
8
3) do access control: raise RISCV_EXCP_ILLEGAL_INST or RISCV_EXCP_VIRT_
9
INSTRUCTION_FAULT if not allowed
10
11
The predicates contain parts of function of both 2) and 3), So they need
12
to be placed in the middle of riscv_csrrw_check
13
14
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
15
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Message-Id: <20220803123652.3700-1-liweiwei@iscas.ac.cn>
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
---
20
target/riscv/csr.c | 44 +++++++++++++++++++++++++-------------------
21
1 file changed, 25 insertions(+), 19 deletions(-)
22
23
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/riscv/csr.c
26
+++ b/target/riscv/csr.c
27
@@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
28
/* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
29
int read_only = get_field(csrno, 0xC00) == 3;
30
int csr_min_priv = csr_ops[csrno].min_priv_ver;
31
+
32
+ /* ensure the CSR extension is enabled. */
33
+ if (!cpu->cfg.ext_icsr) {
34
+ return RISCV_EXCP_ILLEGAL_INST;
35
+ }
36
+
37
+ if (env->priv_ver < csr_min_priv) {
38
+ return RISCV_EXCP_ILLEGAL_INST;
39
+ }
40
+
41
+ /* check predicate */
42
+ if (!csr_ops[csrno].predicate) {
43
+ return RISCV_EXCP_ILLEGAL_INST;
44
+ }
45
+
46
+ if (write_mask && read_only) {
47
+ return RISCV_EXCP_ILLEGAL_INST;
48
+ }
49
+
50
+ RISCVException ret = csr_ops[csrno].predicate(env, csrno);
51
+ if (ret != RISCV_EXCP_NONE) {
52
+ return ret;
53
+ }
54
+
55
#if !defined(CONFIG_USER_ONLY)
56
int csr_priv, effective_priv = env->priv;
57
58
@@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
59
return RISCV_EXCP_ILLEGAL_INST;
60
}
61
#endif
62
- if (write_mask && read_only) {
63
- return RISCV_EXCP_ILLEGAL_INST;
64
- }
65
-
66
- /* ensure the CSR extension is enabled. */
67
- if (!cpu->cfg.ext_icsr) {
68
- return RISCV_EXCP_ILLEGAL_INST;
69
- }
70
-
71
- /* check predicate */
72
- if (!csr_ops[csrno].predicate) {
73
- return RISCV_EXCP_ILLEGAL_INST;
74
- }
75
-
76
- if (env->priv_ver < csr_min_priv) {
77
- return RISCV_EXCP_ILLEGAL_INST;
78
- }
79
-
80
- return csr_ops[csrno].predicate(env, csrno);
81
+ return RISCV_EXCP_NONE;
82
}
83
84
static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
85
--
86
2.37.2
diff view generated by jsdifflib
New patch
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
1
2
3
The following patch updates opentitan to match the new configuration,
4
as per, lowRISC/opentitan@217a0168ba118503c166a9587819e3811eeb0c0c
5
6
Note: with this patch we now skip the usage of the opentitan
7
`boot_rom`. The Opentitan boot rom contains hw verification
8
for devies which we are currently not supporting in qemu. As of now,
9
the `boot_rom` has no major significance, however, would be good to
10
support in the future.
11
12
Tested by running utests from the latest tock [1]
13
(that supports this version of OT).
14
15
[1] https://github.com/tock/tock/pull/3056
16
17
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
18
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
19
Message-Id: <20220812005229.358850-1-wilfred.mallawa@opensource.wdc.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
---
22
include/hw/riscv/opentitan.h | 11 ++++++-----
23
hw/riscv/opentitan.c | 12 ++++++++----
24
2 files changed, 14 insertions(+), 9 deletions(-)
25
26
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/riscv/opentitan.h
29
+++ b/include/hw/riscv/opentitan.h
30
@@ -XXX,XX +XXX,XX @@ enum {
31
IBEX_DEV_TIMER,
32
IBEX_DEV_SENSOR_CTRL,
33
IBEX_DEV_OTP_CTRL,
34
+ IBEX_DEV_LC_CTRL,
35
IBEX_DEV_PWRMGR,
36
IBEX_DEV_RSTMGR,
37
IBEX_DEV_CLKMGR,
38
@@ -XXX,XX +XXX,XX @@ enum {
39
IBEX_UART0_RX_BREAK_ERR_IRQ = 6,
40
IBEX_UART0_RX_TIMEOUT_IRQ = 7,
41
IBEX_UART0_RX_PARITY_ERR_IRQ = 8,
42
- IBEX_TIMER_TIMEREXPIRED0_0 = 126,
43
- IBEX_SPI_HOST0_ERR_IRQ = 150,
44
- IBEX_SPI_HOST0_SPI_EVENT_IRQ = 151,
45
- IBEX_SPI_HOST1_ERR_IRQ = 152,
46
- IBEX_SPI_HOST1_SPI_EVENT_IRQ = 153,
47
+ IBEX_TIMER_TIMEREXPIRED0_0 = 127,
48
+ IBEX_SPI_HOST0_ERR_IRQ = 151,
49
+ IBEX_SPI_HOST0_SPI_EVENT_IRQ = 152,
50
+ IBEX_SPI_HOST1_ERR_IRQ = 153,
51
+ IBEX_SPI_HOST1_SPI_EVENT_IRQ = 154,
52
};
53
54
#endif
55
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/riscv/opentitan.c
58
+++ b/hw/riscv/opentitan.c
59
@@ -XXX,XX +XXX,XX @@
60
#include "sysemu/sysemu.h"
61
62
static const MemMapEntry ibex_memmap[] = {
63
- [IBEX_DEV_ROM] = { 0x00008000, 16 * KiB },
64
- [IBEX_DEV_RAM] = { 0x10000000, 0x10000 },
65
- [IBEX_DEV_FLASH] = { 0x20000000, 0x80000 },
66
+ [IBEX_DEV_ROM] = { 0x00008000, 0x8000 },
67
+ [IBEX_DEV_RAM] = { 0x10000000, 0x20000 },
68
+ [IBEX_DEV_FLASH] = { 0x20000000, 0x100000 },
69
[IBEX_DEV_UART] = { 0x40000000, 0x1000 },
70
[IBEX_DEV_GPIO] = { 0x40040000, 0x1000 },
71
[IBEX_DEV_SPI_DEVICE] = { 0x40050000, 0x1000 },
72
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry ibex_memmap[] = {
73
[IBEX_DEV_TIMER] = { 0x40100000, 0x1000 },
74
[IBEX_DEV_SENSOR_CTRL] = { 0x40110000, 0x1000 },
75
[IBEX_DEV_OTP_CTRL] = { 0x40130000, 0x4000 },
76
+ [IBEX_DEV_LC_CTRL] = { 0x40140000, 0x1000 },
77
[IBEX_DEV_USBDEV] = { 0x40150000, 0x1000 },
78
[IBEX_DEV_SPI_HOST0] = { 0x40300000, 0x1000 },
79
[IBEX_DEV_SPI_HOST1] = { 0x40310000, 0x1000 },
80
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
81
&error_abort);
82
object_property_set_int(OBJECT(&s->cpus), "num-harts", ms->smp.cpus,
83
&error_abort);
84
- object_property_set_int(OBJECT(&s->cpus), "resetvec", 0x8080, &error_abort);
85
+ object_property_set_int(OBJECT(&s->cpus), "resetvec", 0x20000490,
86
+ &error_abort);
87
sysbus_realize(SYS_BUS_DEVICE(&s->cpus), &error_fatal);
88
89
/* Boot ROM */
90
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
91
memmap[IBEX_DEV_SENSOR_CTRL].base, memmap[IBEX_DEV_SENSOR_CTRL].size);
92
create_unimplemented_device("riscv.lowrisc.ibex.otp_ctrl",
93
memmap[IBEX_DEV_OTP_CTRL].base, memmap[IBEX_DEV_OTP_CTRL].size);
94
+ create_unimplemented_device("riscv.lowrisc.ibex.lc_ctrl",
95
+ memmap[IBEX_DEV_LC_CTRL].base, memmap[IBEX_DEV_LC_CTRL].size);
96
create_unimplemented_device("riscv.lowrisc.ibex.pwrmgr",
97
memmap[IBEX_DEV_PWRMGR].base, memmap[IBEX_DEV_PWRMGR].size);
98
create_unimplemented_device("riscv.lowrisc.ibex.rstmgr",
99
--
100
2.37.2
diff view generated by jsdifflib
New patch
1
1
From: Conor Dooley <conor.dooley@microchip.com>
2
3
Booting using "Direct Kernel Boot" for PolarFire SoC & skipping u-boot
4
entirely is probably not advisable, but it does at least show signs of
5
life. Recent Linux kernel versions make use of peripherals that are
6
missing definitions in QEMU and lead to kernel panics. These issues
7
almost certain rear their head for other methods of booting, but I was
8
unable to figure out a suitable HSS version that is recent enough to
9
support these peripherals & works with QEMU.
10
11
With these peripherals added, booting a kernel with the following hangs
12
hangs waiting for the system controller's hwrng, but the kernel no
13
longer panics. With the Linux driver for hwrng disabled, it boots to
14
console.
15
16
qemu-system-riscv64 -M microchip-icicle-kit \
17
    -m 2G -smp 5 \
18
    -kernel $(vmlinux_bin) \
19
    -dtb $(dtb)\
20
    -initrd $(initramfs) \
21
    -display none -serial null \
22
    -serial stdio
23
24
More peripherals are added than strictly required to fix the panics in
25
the hopes of avoiding a replication of this problem in the future.
26
Some of the peripherals which are in the device tree for recent kernels
27
are implemented in the FPGA fabric. The eMMC/SD mux, which exists as
28
an unimplemented device is replaced by a wider entry. This updated
29
entry covers both the mux & the remainder of the FPGA fabric connected
30
to the MSS using Fabric Interrconnect (FIC) 3.
31
32
Link: https://github.com/polarfire-soc/icicle-kit-reference-design#fabric-memory-map
33
Link: https://ww1.microchip.com/downloads/aemDocuments/documents/FPGA/ProductDocuments/SupportingCollateral/V1_4_Register_Map.zip
34
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
35
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
36
Message-Id: <20220813135127.2971754-1-mail@conchuod.ie>
37
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
38
---
39
include/hw/riscv/microchip_pfsoc.h | 14 ++++++-
40
hw/riscv/microchip_pfsoc.c | 67 +++++++++++++++++++++++++++---
41
2 files changed, 74 insertions(+), 7 deletions(-)
42
43
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/include/hw/riscv/microchip_pfsoc.h
46
+++ b/include/hw/riscv/microchip_pfsoc.h
47
@@ -XXX,XX +XXX,XX @@ enum {
48
MICROCHIP_PFSOC_L2LIM,
49
MICROCHIP_PFSOC_PLIC,
50
MICROCHIP_PFSOC_MMUART0,
51
+ MICROCHIP_PFSOC_WDOG0,
52
MICROCHIP_PFSOC_SYSREG,
53
+ MICROCHIP_PFSOC_AXISW,
54
MICROCHIP_PFSOC_MPUCFG,
55
+ MICROCHIP_PFSOC_FMETER,
56
MICROCHIP_PFSOC_DDR_SGMII_PHY,
57
MICROCHIP_PFSOC_EMMC_SD,
58
MICROCHIP_PFSOC_DDR_CFG,
59
@@ -XXX,XX +XXX,XX @@ enum {
60
MICROCHIP_PFSOC_MMUART2,
61
MICROCHIP_PFSOC_MMUART3,
62
MICROCHIP_PFSOC_MMUART4,
63
+ MICROCHIP_PFSOC_WDOG1,
64
+ MICROCHIP_PFSOC_WDOG2,
65
+ MICROCHIP_PFSOC_WDOG3,
66
+ MICROCHIP_PFSOC_WDOG4,
67
MICROCHIP_PFSOC_SPI0,
68
MICROCHIP_PFSOC_SPI1,
69
+ MICROCHIP_PFSOC_I2C0,
70
MICROCHIP_PFSOC_I2C1,
71
+ MICROCHIP_PFSOC_CAN0,
72
+ MICROCHIP_PFSOC_CAN1,
73
MICROCHIP_PFSOC_GEM0,
74
MICROCHIP_PFSOC_GEM1,
75
MICROCHIP_PFSOC_GPIO0,
76
MICROCHIP_PFSOC_GPIO1,
77
MICROCHIP_PFSOC_GPIO2,
78
+ MICROCHIP_PFSOC_RTC,
79
MICROCHIP_PFSOC_ENVM_CFG,
80
MICROCHIP_PFSOC_ENVM_DATA,
81
+ MICROCHIP_PFSOC_USB,
82
MICROCHIP_PFSOC_QSPI_XIP,
83
MICROCHIP_PFSOC_IOSCB,
84
- MICROCHIP_PFSOC_EMMC_SD_MUX,
85
+ MICROCHIP_PFSOC_FABRIC_FIC3,
86
MICROCHIP_PFSOC_DRAM_LO,
87
MICROCHIP_PFSOC_DRAM_LO_ALIAS,
88
MICROCHIP_PFSOC_DRAM_HI,
89
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/hw/riscv/microchip_pfsoc.c
92
+++ b/hw/riscv/microchip_pfsoc.c
93
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry microchip_pfsoc_memmap[] = {
94
[MICROCHIP_PFSOC_L2LIM] = { 0x8000000, 0x2000000 },
95
[MICROCHIP_PFSOC_PLIC] = { 0xc000000, 0x4000000 },
96
[MICROCHIP_PFSOC_MMUART0] = { 0x20000000, 0x1000 },
97
+ [MICROCHIP_PFSOC_WDOG0] = { 0x20001000, 0x1000 },
98
[MICROCHIP_PFSOC_SYSREG] = { 0x20002000, 0x2000 },
99
+ [MICROCHIP_PFSOC_AXISW] = { 0x20004000, 0x1000 },
100
[MICROCHIP_PFSOC_MPUCFG] = { 0x20005000, 0x1000 },
101
+ [MICROCHIP_PFSOC_FMETER] = { 0x20006000, 0x1000 },
102
[MICROCHIP_PFSOC_DDR_SGMII_PHY] = { 0x20007000, 0x1000 },
103
[MICROCHIP_PFSOC_EMMC_SD] = { 0x20008000, 0x1000 },
104
[MICROCHIP_PFSOC_DDR_CFG] = { 0x20080000, 0x40000 },
105
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry microchip_pfsoc_memmap[] = {
106
[MICROCHIP_PFSOC_MMUART2] = { 0x20102000, 0x1000 },
107
[MICROCHIP_PFSOC_MMUART3] = { 0x20104000, 0x1000 },
108
[MICROCHIP_PFSOC_MMUART4] = { 0x20106000, 0x1000 },
109
+ [MICROCHIP_PFSOC_WDOG1] = { 0x20101000, 0x1000 },
110
+ [MICROCHIP_PFSOC_WDOG2] = { 0x20103000, 0x1000 },
111
+ [MICROCHIP_PFSOC_WDOG3] = { 0x20105000, 0x1000 },
112
+ [MICROCHIP_PFSOC_WDOG4] = { 0x20106000, 0x1000 },
113
[MICROCHIP_PFSOC_SPI0] = { 0x20108000, 0x1000 },
114
[MICROCHIP_PFSOC_SPI1] = { 0x20109000, 0x1000 },
115
+ [MICROCHIP_PFSOC_I2C0] = { 0x2010a000, 0x1000 },
116
[MICROCHIP_PFSOC_I2C1] = { 0x2010b000, 0x1000 },
117
+ [MICROCHIP_PFSOC_CAN0] = { 0x2010c000, 0x1000 },
118
+ [MICROCHIP_PFSOC_CAN1] = { 0x2010d000, 0x1000 },
119
[MICROCHIP_PFSOC_GEM0] = { 0x20110000, 0x2000 },
120
[MICROCHIP_PFSOC_GEM1] = { 0x20112000, 0x2000 },
121
[MICROCHIP_PFSOC_GPIO0] = { 0x20120000, 0x1000 },
122
[MICROCHIP_PFSOC_GPIO1] = { 0x20121000, 0x1000 },
123
[MICROCHIP_PFSOC_GPIO2] = { 0x20122000, 0x1000 },
124
+ [MICROCHIP_PFSOC_RTC] = { 0x20124000, 0x1000 },
125
[MICROCHIP_PFSOC_ENVM_CFG] = { 0x20200000, 0x1000 },
126
[MICROCHIP_PFSOC_ENVM_DATA] = { 0x20220000, 0x20000 },
127
+ [MICROCHIP_PFSOC_USB] = { 0x20201000, 0x1000 },
128
[MICROCHIP_PFSOC_QSPI_XIP] = { 0x21000000, 0x1000000 },
129
[MICROCHIP_PFSOC_IOSCB] = { 0x30000000, 0x10000000 },
130
- [MICROCHIP_PFSOC_EMMC_SD_MUX] = { 0x4f000000, 0x4 },
131
+ [MICROCHIP_PFSOC_FABRIC_FIC3] = { 0x40000000, 0x20000000 },
132
[MICROCHIP_PFSOC_DRAM_LO] = { 0x80000000, 0x40000000 },
133
[MICROCHIP_PFSOC_DRAM_LO_ALIAS] = { 0xc0000000, 0x40000000 },
134
[MICROCHIP_PFSOC_DRAM_HI] = { 0x1000000000, 0x0 },
135
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
136
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysreg), 0,
137
memmap[MICROCHIP_PFSOC_SYSREG].base);
138
139
+ /* AXISW */
140
+ create_unimplemented_device("microchip.pfsoc.axisw",
141
+ memmap[MICROCHIP_PFSOC_AXISW].base,
142
+ memmap[MICROCHIP_PFSOC_AXISW].size);
143
+
144
/* MPUCFG */
145
create_unimplemented_device("microchip.pfsoc.mpucfg",
146
memmap[MICROCHIP_PFSOC_MPUCFG].base,
147
memmap[MICROCHIP_PFSOC_MPUCFG].size);
148
149
+ /* FMETER */
150
+ create_unimplemented_device("microchip.pfsoc.fmeter",
151
+ memmap[MICROCHIP_PFSOC_FMETER].base,
152
+ memmap[MICROCHIP_PFSOC_FMETER].size);
153
+
154
/* DDR SGMII PHY */
155
sysbus_realize(SYS_BUS_DEVICE(&s->ddr_sgmii_phy), errp);
156
sysbus_mmio_map(SYS_BUS_DEVICE(&s->ddr_sgmii_phy), 0,
157
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
158
qdev_get_gpio_in(DEVICE(s->plic), MICROCHIP_PFSOC_MMUART4_IRQ),
159
serial_hd(4));
160
161
+ /* Watchdogs */
162
+ create_unimplemented_device("microchip.pfsoc.watchdog0",
163
+ memmap[MICROCHIP_PFSOC_WDOG0].base,
164
+ memmap[MICROCHIP_PFSOC_WDOG0].size);
165
+ create_unimplemented_device("microchip.pfsoc.watchdog1",
166
+ memmap[MICROCHIP_PFSOC_WDOG1].base,
167
+ memmap[MICROCHIP_PFSOC_WDOG1].size);
168
+ create_unimplemented_device("microchip.pfsoc.watchdog2",
169
+ memmap[MICROCHIP_PFSOC_WDOG2].base,
170
+ memmap[MICROCHIP_PFSOC_WDOG2].size);
171
+ create_unimplemented_device("microchip.pfsoc.watchdog3",
172
+ memmap[MICROCHIP_PFSOC_WDOG3].base,
173
+ memmap[MICROCHIP_PFSOC_WDOG3].size);
174
+ create_unimplemented_device("microchip.pfsoc.watchdog4",
175
+ memmap[MICROCHIP_PFSOC_WDOG4].base,
176
+ memmap[MICROCHIP_PFSOC_WDOG4].size);
177
+
178
/* SPI */
179
create_unimplemented_device("microchip.pfsoc.spi0",
180
memmap[MICROCHIP_PFSOC_SPI0].base,
181
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
182
memmap[MICROCHIP_PFSOC_SPI1].base,
183
memmap[MICROCHIP_PFSOC_SPI1].size);
184
185
- /* I2C1 */
186
+ /* I2C */
187
+ create_unimplemented_device("microchip.pfsoc.i2c0",
188
+ memmap[MICROCHIP_PFSOC_I2C0].base,
189
+ memmap[MICROCHIP_PFSOC_I2C0].size);
190
create_unimplemented_device("microchip.pfsoc.i2c1",
191
memmap[MICROCHIP_PFSOC_I2C1].base,
192
memmap[MICROCHIP_PFSOC_I2C1].size);
193
194
+ /* CAN */
195
+ create_unimplemented_device("microchip.pfsoc.can0",
196
+ memmap[MICROCHIP_PFSOC_CAN0].base,
197
+ memmap[MICROCHIP_PFSOC_CAN0].size);
198
+ create_unimplemented_device("microchip.pfsoc.can1",
199
+ memmap[MICROCHIP_PFSOC_CAN1].base,
200
+ memmap[MICROCHIP_PFSOC_CAN1].size);
201
+
202
+ /* USB */
203
+ create_unimplemented_device("microchip.pfsoc.usb",
204
+ memmap[MICROCHIP_PFSOC_USB].base,
205
+ memmap[MICROCHIP_PFSOC_USB].size);
206
+
207
/* GEMs */
208
209
nd = &nd_table[0];
210
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
211
sysbus_mmio_map(SYS_BUS_DEVICE(&s->ioscb), 0,
212
memmap[MICROCHIP_PFSOC_IOSCB].base);
213
214
- /* eMMC/SD mux */
215
- create_unimplemented_device("microchip.pfsoc.emmc_sd_mux",
216
- memmap[MICROCHIP_PFSOC_EMMC_SD_MUX].base,
217
- memmap[MICROCHIP_PFSOC_EMMC_SD_MUX].size);
218
+ /* FPGA Fabric */
219
+ create_unimplemented_device("microchip.pfsoc.fabricfic3",
220
+ memmap[MICROCHIP_PFSOC_FABRIC_FIC3].base,
221
+ memmap[MICROCHIP_PFSOC_FABRIC_FIC3].size);
222
223
/* QSPI Flash */
224
memory_region_init_rom(qspi_xip_mem, OBJECT(dev),
225
--
226
2.37.2
diff view generated by jsdifflib
New patch
1
From: Atish Patra <atishp@rivosinc.com>
1
2
3
With .min_priv_version, additiona priv version check is uncessary
4
for mcountinhibit read/write functions.
5
6
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
7
Tested-by: Heiko Stuebner <heiko@sntech.de>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Atish Patra <atishp@rivosinc.com>
10
Message-Id: <20220816232321.558250-7-atishp@rivosinc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/csr.c | 8 --------
14
1 file changed, 8 deletions(-)
15
16
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/csr.c
19
+++ b/target/riscv/csr.c
20
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mtvec(CPURISCVState *env, int csrno,
21
static RISCVException read_mcountinhibit(CPURISCVState *env, int csrno,
22
target_ulong *val)
23
{
24
- if (env->priv_ver < PRIV_VERSION_1_11_0) {
25
- return RISCV_EXCP_ILLEGAL_INST;
26
- }
27
-
28
*val = env->mcountinhibit;
29
return RISCV_EXCP_NONE;
30
}
31
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
32
int cidx;
33
PMUCTRState *counter;
34
35
- if (env->priv_ver < PRIV_VERSION_1_11_0) {
36
- return RISCV_EXCP_ILLEGAL_INST;
37
- }
38
-
39
env->mcountinhibit = val;
40
41
/* Check if any other counter is also monitoring cycles/instructions */
42
--
43
2.37.2
diff view generated by jsdifflib
New patch
1
From: Conor Dooley <conor.dooley@microchip.com>
1
2
3
"uart" is not a node name that complies with the dt-schema.
4
Change the node name to "serial" to ix warnings seen during
5
dt-validate on a dtbdump of the virt machine such as:
6
/stuff/qemu/qemu.dtb: uart@10000000: $nodename:0: 'uart@10000000' does not match '^serial(@.*)?$'
7
From schema: /stuff/linux/Documentation/devicetree/bindings/serial/8250.yaml
8
9
Reported-by: Rob Herring <robh@kernel.org>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
12
Message-id: 20220810184612.157317-2-mail@conchuod.ie
13
Link: https://lore.kernel.org/linux-riscv/20220803170552.GA2250266-robh@kernel.org/
14
Fixes: 04331d0b56 ("RISC-V VirtIO Machine")
15
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
18
hw/riscv/virt.c | 2 +-
19
1 file changed, 1 insertion(+), 1 deletion(-)
20
21
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/riscv/virt.c
24
+++ b/hw/riscv/virt.c
25
@@ -XXX,XX +XXX,XX @@ static void create_fdt_uart(RISCVVirtState *s, const MemMapEntry *memmap,
26
char *name;
27
MachineState *mc = MACHINE(s);
28
29
- name = g_strdup_printf("/soc/uart@%lx", (long)memmap[VIRT_UART0].base);
30
+ name = g_strdup_printf("/soc/serial@%lx", (long)memmap[VIRT_UART0].base);
31
qemu_fdt_add_subnode(mc->fdt, name);
32
qemu_fdt_setprop_string(mc->fdt, name, "compatible", "ns16550a");
33
qemu_fdt_setprop_cells(mc->fdt, name, "reg",
34
--
35
2.37.2
diff view generated by jsdifflib
New patch
1
From: Conor Dooley <conor.dooley@microchip.com>
1
2
3
When optional AIA PLIC support was added the to the virt machine, the
4
address cells property was removed leading the issues with dt-validate
5
on a dump from the virt machine:
6
/stuff/qemu/qemu.dtb: plic@c000000: '#address-cells' is a required property
7
From schema: /stuff/linux/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
8
Add back the property to suppress the warning.
9
10
Reported-by: Rob Herring <robh@kernel.org>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
13
Message-id: 20220810184612.157317-3-mail@conchuod.ie
14
Link: https://lore.kernel.org/linux-riscv/20220803170552.GA2250266-robh@kernel.org/
15
Fixes: e6faee6585 ("hw/riscv: virt: Add optional AIA APLIC support to virt machine")
16
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
19
include/hw/riscv/virt.h | 1 +
20
hw/riscv/virt.c | 2 ++
21
2 files changed, 3 insertions(+)
22
23
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/riscv/virt.h
26
+++ b/include/hw/riscv/virt.h
27
@@ -XXX,XX +XXX,XX @@ enum {
28
29
#define FDT_PCI_ADDR_CELLS 3
30
#define FDT_PCI_INT_CELLS 1
31
+#define FDT_PLIC_ADDR_CELLS 0
32
#define FDT_PLIC_INT_CELLS 1
33
#define FDT_APLIC_INT_CELLS 2
34
#define FDT_IMSIC_INT_CELLS 0
35
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/riscv/virt.c
38
+++ b/hw/riscv/virt.c
39
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_plic(RISCVVirtState *s,
40
qemu_fdt_add_subnode(mc->fdt, plic_name);
41
qemu_fdt_setprop_cell(mc->fdt, plic_name,
42
"#interrupt-cells", FDT_PLIC_INT_CELLS);
43
+ qemu_fdt_setprop_cell(mc->fdt, plic_name,
44
+ "#address-cells", FDT_PLIC_ADDR_CELLS);
45
qemu_fdt_setprop_string_array(mc->fdt, plic_name, "compatible",
46
(char **)&plic_compat,
47
ARRAY_SIZE(plic_compat));
48
--
49
2.37.2
diff view generated by jsdifflib
New patch
1
From: Conor Dooley <conor.dooley@microchip.com>
1
2
3
The reset and poweroff features of the syscon were originally added to
4
top level, which is a valid path for a syscon subnode. Subsequently a
5
reorganisation was carried out while implementing NUMA in which the
6
subnodes were moved into the /soc node. As /soc is a "simple-bus", this
7
path is invalid, and so dt-validate produces the following warnings:
8
9
/stuff/qemu/qemu.dtb: soc: poweroff: {'value': [[21845]], 'offset': [[0]], 'regmap': [[4]], 'compatible': ['syscon-poweroff']} should not be valid under {'type': 'object'}
10
From schema: /home/conor/.local/lib/python3.9/site-packages/dtschema/schemas/simple-bus.yaml
11
/stuff/qemu/qemu.dtb: soc: reboot: {'value': [[30583]], 'offset': [[0]], 'regmap': [[4]], 'compatible': ['syscon-reboot']} should not be valid under {'type': 'object'}
12
From schema: /home/conor/.local/lib/python3.9/site-packages/dtschema/schemas/simple-bus.yaml
13
14
Move the syscon subnodes back to the top level and silence the warnings.
15
16
Reported-by: Rob Herring <robh@kernel.org>
17
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
18
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
19
Message-id: 20220810184612.157317-4-mail@conchuod.ie
20
Link: https://lore.kernel.org/linux-riscv/20220803170552.GA2250266-robh@kernel.org/
21
Fixes: 18df0b4695 ("hw/riscv: virt: Allow creating multiple NUMA sockets")
22
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
23
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
24
---
25
hw/riscv/virt.c | 4 ++--
26
1 file changed, 2 insertions(+), 2 deletions(-)
27
28
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/riscv/virt.c
31
+++ b/hw/riscv/virt.c
32
@@ -XXX,XX +XXX,XX @@ static void create_fdt_reset(RISCVVirtState *s, const MemMapEntry *memmap,
33
test_phandle = qemu_fdt_get_phandle(mc->fdt, name);
34
g_free(name);
35
36
- name = g_strdup_printf("/soc/reboot");
37
+ name = g_strdup_printf("/reboot");
38
qemu_fdt_add_subnode(mc->fdt, name);
39
qemu_fdt_setprop_string(mc->fdt, name, "compatible", "syscon-reboot");
40
qemu_fdt_setprop_cell(mc->fdt, name, "regmap", test_phandle);
41
@@ -XXX,XX +XXX,XX @@ static void create_fdt_reset(RISCVVirtState *s, const MemMapEntry *memmap,
42
qemu_fdt_setprop_cell(mc->fdt, name, "value", FINISHER_RESET);
43
g_free(name);
44
45
- name = g_strdup_printf("/soc/poweroff");
46
+ name = g_strdup_printf("/poweroff");
47
qemu_fdt_add_subnode(mc->fdt, name);
48
qemu_fdt_setprop_string(mc->fdt, name, "compatible", "syscon-poweroff");
49
qemu_fdt_setprop_cell(mc->fdt, name, "regmap", test_phandle);
50
--
51
2.37.2
diff view generated by jsdifflib
New patch
1
From: Conor Dooley <conor.dooley@microchip.com>
1
2
3
"platform" is not a valid name for a bus node in dt-schema, so warnings
4
can be see in dt-validate on a dump of the riscv virt dtb:
5
6
/stuff/qemu/qemu.dtb: platform@4000000: $nodename:0: 'platform@4000000' does not match '^([a-z][a-z0-9\\-]+-bus|bus|soc|axi|ahb|apb)(@[0-9a-f]+)?$'
7
From schema: /home/conor/.local/lib/python3.9/site-packages/dtschema/schemas/simple-bus.yaml
8
"platform-bus" is a valid name, so use that instead.
9
10
CC: Rob Herring <robh@kernel.org>
11
Fixes: 11d306b9df ("hw/arm/sysbus-fdt: helpers for platform bus nodes addition")
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
14
Message-id: 20220810184612.157317-5-mail@conchuod.ie
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
17
hw/core/sysbus-fdt.c | 2 +-
18
1 file changed, 1 insertion(+), 1 deletion(-)
19
20
diff --git a/hw/core/sysbus-fdt.c b/hw/core/sysbus-fdt.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/core/sysbus-fdt.c
23
+++ b/hw/core/sysbus-fdt.c
24
@@ -XXX,XX +XXX,XX @@ void platform_bus_add_all_fdt_nodes(void *fdt, const char *intc, hwaddr addr,
25
26
assert(fdt);
27
28
- node = g_strdup_printf("/platform@%"PRIx64, addr);
29
+ node = g_strdup_printf("/platform-bus@%"PRIx64, addr);
30
31
/* Create a /platform node that we can put all devices into */
32
qemu_fdt_add_subnode(fdt, node);
33
--
34
2.37.2
diff view generated by jsdifflib
New patch
1
From: Rahul Pathak <rpathak@ventanamicro.com>
1
2
3
XVentanaCondOps is Ventana custom extension. Add
4
its extension entry in the ISA Ext array
5
6
Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20220816045408.1231135-1-rpathak@ventanamicro.com
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
target/riscv/cpu.c | 1 +
12
1 file changed, 1 insertion(+)
13
14
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/cpu.c
17
+++ b/target/riscv/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
19
ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval),
20
ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
21
ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
22
+ ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
23
};
24
25
static bool isa_ext_is_enabled(RISCVCPU *cpu,
26
--
27
2.37.2
diff view generated by jsdifflib
New patch
1
1
From: Anup Patel <apatel@ventanamicro.com>
2
3
The arch review of AIA spec is completed and we now have official
4
extension names for AIA: Smaia (M-mode AIA CSRs) and Ssaia (S-mode
5
AIA CSRs).
6
7
Refer, section 1.6 of the latest AIA v0.3.1 stable specification at
8
https://github.com/riscv/riscv-aia/releases/download/0.3.1-draft.32/riscv-interrupts-032.pdf)
9
10
Based on above, we update QEMU RISC-V to:
11
1) Have separate config options for Smaia and Ssaia extensions
12
which replace RISCV_FEATURE_AIA in CPU features
13
2) Not generate AIA INTC compatible string in virt machine
14
15
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
16
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Message-id: 20220820042958.377018-1-apatel@ventanamicro.com
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
---
21
target/riscv/cpu.h | 4 ++--
22
hw/intc/riscv_imsic.c | 4 +++-
23
hw/riscv/virt.c | 13 ++-----------
24
target/riscv/cpu.c | 9 ++++-----
25
target/riscv/cpu_helper.c | 3 ++-
26
target/riscv/csr.c | 24 ++++++++++++++++++------
27
6 files changed, 31 insertions(+), 26 deletions(-)
28
29
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/cpu.h
32
+++ b/target/riscv/cpu.h
33
@@ -XXX,XX +XXX,XX @@ enum {
34
RISCV_FEATURE_PMP,
35
RISCV_FEATURE_EPMP,
36
RISCV_FEATURE_MISA,
37
- RISCV_FEATURE_AIA,
38
RISCV_FEATURE_DEBUG
39
};
40
41
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
42
bool ext_zve32f;
43
bool ext_zve64f;
44
bool ext_zmmul;
45
+ bool ext_smaia;
46
+ bool ext_ssaia;
47
bool rvv_ta_all_1s;
48
bool rvv_ma_all_1s;
49
50
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
51
bool mmu;
52
bool pmp;
53
bool epmp;
54
- bool aia;
55
bool debug;
56
uint64_t resetvec;
57
58
diff --git a/hw/intc/riscv_imsic.c b/hw/intc/riscv_imsic.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/hw/intc/riscv_imsic.c
61
+++ b/hw/intc/riscv_imsic.c
62
@@ -XXX,XX +XXX,XX @@ static void riscv_imsic_realize(DeviceState *dev, Error **errp)
63
64
/* Force select AIA feature and setup CSR read-modify-write callback */
65
if (env) {
66
- riscv_set_feature(env, RISCV_FEATURE_AIA);
67
if (!imsic->mmode) {
68
+ rcpu->cfg.ext_ssaia = true;
69
riscv_cpu_set_geilen(env, imsic->num_pages - 1);
70
+ } else {
71
+ rcpu->cfg.ext_smaia = true;
72
}
73
riscv_cpu_set_aia_ireg_rmw_fn(env, (imsic->mmode) ? PRV_M : PRV_S,
74
riscv_imsic_rmw, imsic);
75
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/hw/riscv/virt.c
78
+++ b/hw/riscv/virt.c
79
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket,
80
qemu_fdt_add_subnode(mc->fdt, intc_name);
81
qemu_fdt_setprop_cell(mc->fdt, intc_name, "phandle",
82
intc_phandles[cpu]);
83
- if (riscv_feature(&s->soc[socket].harts[cpu].env,
84
- RISCV_FEATURE_AIA)) {
85
- static const char * const compat[2] = {
86
- "riscv,cpu-intc-aia", "riscv,cpu-intc"
87
- };
88
- qemu_fdt_setprop_string_array(mc->fdt, intc_name, "compatible",
89
- (char **)&compat, ARRAY_SIZE(compat));
90
- } else {
91
- qemu_fdt_setprop_string(mc->fdt, intc_name, "compatible",
92
- "riscv,cpu-intc");
93
- }
94
+ qemu_fdt_setprop_string(mc->fdt, intc_name, "compatible",
95
+ "riscv,cpu-intc");
96
qemu_fdt_setprop(mc->fdt, intc_name, "interrupt-controller", NULL, 0);
97
qemu_fdt_setprop_cell(mc->fdt, intc_name, "#interrupt-cells", 1);
98
99
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/target/riscv/cpu.c
102
+++ b/target/riscv/cpu.c
103
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
104
ISA_EXT_DATA_ENTRY(zve64f, true, PRIV_VERSION_1_12_0, ext_zve64f),
105
ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
106
ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
107
+ ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia),
108
+ ISA_EXT_DATA_ENTRY(ssaia, true, PRIV_VERSION_1_12_0, ext_ssaia),
109
ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval),
110
ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
111
ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
112
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
113
}
114
}
115
116
- if (cpu->cfg.aia) {
117
- riscv_set_feature(env, RISCV_FEATURE_AIA);
118
- }
119
-
120
if (cpu->cfg.debug) {
121
riscv_set_feature(env, RISCV_FEATURE_DEBUG);
122
}
123
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
124
DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
125
/* ePMP 0.9.3 */
126
DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
127
- DEFINE_PROP_BOOL("x-aia", RISCVCPU, cfg.aia, false),
128
+ DEFINE_PROP_BOOL("x-smaia", RISCVCPU, cfg.ext_smaia, false),
129
+ DEFINE_PROP_BOOL("x-ssaia", RISCVCPU, cfg.ext_ssaia, false),
130
131
DEFINE_PROP_END_OF_LIST(),
132
};
133
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/target/riscv/cpu_helper.c
136
+++ b/target/riscv/cpu_helper.c
137
@@ -XXX,XX +XXX,XX @@ static int riscv_cpu_pending_to_irq(CPURISCVState *env,
138
int extirq, unsigned int extirq_def_prio,
139
uint64_t pending, uint8_t *iprio)
140
{
141
+ RISCVCPU *cpu = env_archcpu(env);
142
int irq, best_irq = RISCV_EXCP_NONE;
143
unsigned int prio, best_prio = UINT_MAX;
144
145
@@ -XXX,XX +XXX,XX @@ static int riscv_cpu_pending_to_irq(CPURISCVState *env,
146
}
147
148
irq = ctz64(pending);
149
- if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
150
+ if (!((extirq == IRQ_M_EXT) ? cpu->cfg.ext_smaia : cpu->cfg.ext_ssaia)) {
151
return irq;
152
}
153
154
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
155
index XXXXXXX..XXXXXXX 100644
156
--- a/target/riscv/csr.c
157
+++ b/target/riscv/csr.c
158
@@ -XXX,XX +XXX,XX @@ static RISCVException any32(CPURISCVState *env, int csrno)
159
160
static int aia_any(CPURISCVState *env, int csrno)
161
{
162
- if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
163
+ RISCVCPU *cpu = env_archcpu(env);
164
+
165
+ if (!cpu->cfg.ext_smaia) {
166
return RISCV_EXCP_ILLEGAL_INST;
167
}
168
169
@@ -XXX,XX +XXX,XX @@ static int aia_any(CPURISCVState *env, int csrno)
170
171
static int aia_any32(CPURISCVState *env, int csrno)
172
{
173
- if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
174
+ RISCVCPU *cpu = env_archcpu(env);
175
+
176
+ if (!cpu->cfg.ext_smaia) {
177
return RISCV_EXCP_ILLEGAL_INST;
178
}
179
180
@@ -XXX,XX +XXX,XX @@ static int smode32(CPURISCVState *env, int csrno)
181
182
static int aia_smode(CPURISCVState *env, int csrno)
183
{
184
- if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
185
+ RISCVCPU *cpu = env_archcpu(env);
186
+
187
+ if (!cpu->cfg.ext_ssaia) {
188
return RISCV_EXCP_ILLEGAL_INST;
189
}
190
191
@@ -XXX,XX +XXX,XX @@ static int aia_smode(CPURISCVState *env, int csrno)
192
193
static int aia_smode32(CPURISCVState *env, int csrno)
194
{
195
- if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
196
+ RISCVCPU *cpu = env_archcpu(env);
197
+
198
+ if (!cpu->cfg.ext_ssaia) {
199
return RISCV_EXCP_ILLEGAL_INST;
200
}
201
202
@@ -XXX,XX +XXX,XX @@ static RISCVException pointer_masking(CPURISCVState *env, int csrno)
203
204
static int aia_hmode(CPURISCVState *env, int csrno)
205
{
206
- if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
207
+ RISCVCPU *cpu = env_archcpu(env);
208
+
209
+ if (!cpu->cfg.ext_ssaia) {
210
return RISCV_EXCP_ILLEGAL_INST;
211
}
212
213
@@ -XXX,XX +XXX,XX @@ static int aia_hmode(CPURISCVState *env, int csrno)
214
215
static int aia_hmode32(CPURISCVState *env, int csrno)
216
{
217
- if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
218
+ RISCVCPU *cpu = env_archcpu(env);
219
+
220
+ if (!cpu->cfg.ext_ssaia) {
221
return RISCV_EXCP_ILLEGAL_INST;
222
}
223
224
--
225
2.37.2
diff view generated by jsdifflib
New patch
1
From: Atish Patra <atishp@rivosinc.com>
1
2
3
Historically, The mtime/mtimecmp has been part of the CPU because
4
they are per hart entities. However, they actually belong to aclint
5
which is a MMIO device.
6
7
Move them to the ACLINT device. This also emulates the real hardware
8
more closely.
9
10
Reviewed-by: Anup Patel <anup@brainfault.org>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
13
Signed-off-by: Atish Patra <atishp@rivosinc.com>
14
Message-Id: <20220824221357.41070-2-atishp@rivosinc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
17
include/hw/intc/riscv_aclint.h | 2 ++
18
include/hw/timer/ibex_timer.h | 2 ++
19
target/riscv/cpu.h | 2 --
20
hw/intc/riscv_aclint.c | 48 ++++++++++++++++++++++++----------
21
hw/timer/ibex_timer.c | 18 +++++--------
22
target/riscv/machine.c | 5 ++--
23
6 files changed, 47 insertions(+), 30 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 @@ typedef struct RISCVAclintMTimerState {
30
/*< private >*/
31
SysBusDevice parent_obj;
32
uint64_t time_delta;
33
+ uint64_t *timecmp;
34
+ QEMUTimer **timers;
35
36
/*< public >*/
37
MemoryRegion mmio;
38
diff --git a/include/hw/timer/ibex_timer.h b/include/hw/timer/ibex_timer.h
39
index XXXXXXX..XXXXXXX 100644
40
--- a/include/hw/timer/ibex_timer.h
41
+++ b/include/hw/timer/ibex_timer.h
42
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(IbexTimerState, IBEX_TIMER)
43
struct IbexTimerState {
44
/* <private> */
45
SysBusDevice parent_obj;
46
+ uint64_t mtimecmp;
47
+ QEMUTimer *mtimer; /* Internal timer for M-mode interrupt */
48
49
/* <public> */
50
MemoryRegion mmio;
51
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/riscv/cpu.h
54
+++ b/target/riscv/cpu.h
55
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
56
/* temporary htif regs */
57
uint64_t mfromhost;
58
uint64_t mtohost;
59
- uint64_t timecmp;
60
61
/* physical memory protection */
62
pmp_table_t pmp_state;
63
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
64
float_status fp_status;
65
66
/* Fields from here on are preserved across CPU reset. */
67
- QEMUTimer *timer; /* Internal timer */
68
69
hwaddr kernel_addr;
70
hwaddr fdt_addr;
71
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/hw/intc/riscv_aclint.c
74
+++ b/hw/intc/riscv_aclint.c
75
@@ -XXX,XX +XXX,XX @@
76
#include "hw/intc/riscv_aclint.h"
77
#include "qemu/timer.h"
78
#include "hw/irq.h"
79
+#include "migration/vmstate.h"
80
81
typedef struct riscv_aclint_mtimer_callback {
82
RISCVAclintMTimerState *s;
83
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
84
85
uint64_t rtc_r = cpu_riscv_read_rtc(mtimer);
86
87
- cpu->env.timecmp = value;
88
- if (cpu->env.timecmp <= rtc_r) {
89
+ /* Compute the relative hartid w.r.t the socket */
90
+ hartid = hartid - mtimer->hartid_base;
91
+
92
+ mtimer->timecmp[hartid] = value;
93
+ if (mtimer->timecmp[hartid] <= rtc_r) {
94
/*
95
* If we're setting an MTIMECMP value in the "past",
96
* immediately raise the timer interrupt
97
*/
98
- qemu_irq_raise(mtimer->timer_irqs[hartid - mtimer->hartid_base]);
99
+ qemu_irq_raise(mtimer->timer_irqs[hartid]);
100
return;
101
}
102
103
/* otherwise, set up the future timer interrupt */
104
- qemu_irq_lower(mtimer->timer_irqs[hartid - mtimer->hartid_base]);
105
- diff = cpu->env.timecmp - rtc_r;
106
+ qemu_irq_lower(mtimer->timer_irqs[hartid]);
107
+ diff = mtimer->timecmp[hartid] - rtc_r;
108
/* back to ns (note args switched in muldiv64) */
109
uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq);
110
111
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
112
next = MIN(next, INT64_MAX);
113
}
114
115
- timer_mod(cpu->env.timer, next);
116
+ timer_mod(mtimer->timers[hartid], next);
117
}
118
119
/*
120
@@ -XXX,XX +XXX,XX @@ static uint64_t riscv_aclint_mtimer_read(void *opaque, hwaddr addr,
121
"aclint-mtimer: invalid hartid: %zu", hartid);
122
} else if ((addr & 0x7) == 0) {
123
/* timecmp_lo for RV32/RV64 or timecmp for RV64 */
124
- uint64_t timecmp = env->timecmp;
125
+ uint64_t timecmp = mtimer->timecmp[hartid];
126
return (size == 4) ? (timecmp & 0xFFFFFFFF) : timecmp;
127
} else if ((addr & 0x7) == 4) {
128
/* timecmp_hi */
129
- uint64_t timecmp = env->timecmp;
130
+ uint64_t timecmp = mtimer->timecmp[hartid];
131
return (timecmp >> 32) & 0xFFFFFFFF;
132
} else {
133
qemu_log_mask(LOG_UNIMP,
134
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
135
} else if ((addr & 0x7) == 0) {
136
if (size == 4) {
137
/* timecmp_lo for RV32/RV64 */
138
- uint64_t timecmp_hi = env->timecmp >> 32;
139
+ uint64_t timecmp_hi = mtimer->timecmp[hartid] >> 32;
140
riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
141
timecmp_hi << 32 | (value & 0xFFFFFFFF));
142
} else {
143
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
144
} else if ((addr & 0x7) == 4) {
145
if (size == 4) {
146
/* timecmp_hi for RV32/RV64 */
147
- uint64_t timecmp_lo = env->timecmp;
148
+ uint64_t timecmp_lo = mtimer->timecmp[hartid];
149
riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
150
value << 32 | (timecmp_lo & 0xFFFFFFFF));
151
} else {
152
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
153
}
154
riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu),
155
mtimer->hartid_base + i,
156
- env->timecmp);
157
+ mtimer->timecmp[i]);
158
}
159
return;
160
}
161
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_realize(DeviceState *dev, Error **errp)
162
s->timer_irqs = g_new(qemu_irq, s->num_harts);
163
qdev_init_gpio_out(dev, s->timer_irqs, s->num_harts);
164
165
+ s->timers = g_new0(QEMUTimer *, s->num_harts);
166
+ s->timecmp = g_new0(uint64_t, s->num_harts);
167
/* Claim timer interrupt bits */
168
for (i = 0; i < s->num_harts; i++) {
169
RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(s->hartid_base + i));
170
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_reset_enter(Object *obj, ResetType type)
171
riscv_aclint_mtimer_write(mtimer, mtimer->time_base, 0, 8);
172
}
173
174
+static const VMStateDescription vmstate_riscv_mtimer = {
175
+ .name = "riscv_mtimer",
176
+ .version_id = 1,
177
+ .minimum_version_id = 1,
178
+ .fields = (VMStateField[]) {
179
+ VMSTATE_VARRAY_UINT32(timecmp, RISCVAclintMTimerState,
180
+ num_harts, 0,
181
+ vmstate_info_uint64, uint64_t),
182
+ VMSTATE_END_OF_LIST()
183
+ }
184
+};
185
+
186
static void riscv_aclint_mtimer_class_init(ObjectClass *klass, void *data)
187
{
188
DeviceClass *dc = DEVICE_CLASS(klass);
189
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_class_init(ObjectClass *klass, void *data)
190
device_class_set_props(dc, riscv_aclint_mtimer_properties);
191
ResettableClass *rc = RESETTABLE_CLASS(klass);
192
rc->phases.enter = riscv_aclint_mtimer_reset_enter;
193
+ dc->vmsd = &vmstate_riscv_mtimer;
194
}
195
196
static const TypeInfo riscv_aclint_mtimer_info = {
197
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size,
198
{
199
int i;
200
DeviceState *dev = qdev_new(TYPE_RISCV_ACLINT_MTIMER);
201
+ RISCVAclintMTimerState *s = RISCV_ACLINT_MTIMER(dev);
202
203
assert(num_harts <= RISCV_ACLINT_MAX_HARTS);
204
assert(!(addr & 0x7));
205
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size,
206
riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc, dev);
207
}
208
209
- cb->s = RISCV_ACLINT_MTIMER(dev);
210
+ cb->s = s;
211
cb->num = i;
212
- env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
213
+ s->timers[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
214
&riscv_aclint_mtimer_cb, cb);
215
- env->timecmp = 0;
216
+ s->timecmp[i] = 0;
217
218
qdev_connect_gpio_out(dev, i,
219
qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_TIMER));
220
diff --git a/hw/timer/ibex_timer.c b/hw/timer/ibex_timer.c
221
index XXXXXXX..XXXXXXX 100644
222
--- a/hw/timer/ibex_timer.c
223
+++ b/hw/timer/ibex_timer.c
224
@@ -XXX,XX +XXX,XX @@ static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq)
225
226
static void ibex_timer_update_irqs(IbexTimerState *s)
227
{
228
- CPUState *cs = qemu_get_cpu(0);
229
- RISCVCPU *cpu = RISCV_CPU(cs);
230
uint64_t value = s->timer_compare_lower0 |
231
((uint64_t)s->timer_compare_upper0 << 32);
232
uint64_t next, diff;
233
@@ -XXX,XX +XXX,XX @@ static void ibex_timer_update_irqs(IbexTimerState *s)
234
}
235
236
/* Update the CPUs mtimecmp */
237
- cpu->env.timecmp = value;
238
+ s->mtimecmp = value;
239
240
- if (cpu->env.timecmp <= now) {
241
+ if (s->mtimecmp <= now) {
242
/*
243
* If the mtimecmp was in the past raise the interrupt now.
244
*/
245
@@ -XXX,XX +XXX,XX @@ static void ibex_timer_update_irqs(IbexTimerState *s)
246
qemu_irq_lower(s->m_timer_irq);
247
qemu_set_irq(s->irq, false);
248
249
- diff = cpu->env.timecmp - now;
250
+ diff = s->mtimecmp - now;
251
next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
252
muldiv64(diff,
253
NANOSECONDS_PER_SECOND,
254
@@ -XXX,XX +XXX,XX @@ static void ibex_timer_update_irqs(IbexTimerState *s)
255
256
if (next < qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)) {
257
/* We overflowed the timer, just set it as large as we can */
258
- timer_mod(cpu->env.timer, 0x7FFFFFFFFFFFFFFF);
259
+ timer_mod(s->mtimer, 0x7FFFFFFFFFFFFFFF);
260
} else {
261
- timer_mod(cpu->env.timer, next);
262
+ timer_mod(s->mtimer, next);
263
}
264
}
265
266
@@ -XXX,XX +XXX,XX @@ static void ibex_timer_reset(DeviceState *dev)
267
{
268
IbexTimerState *s = IBEX_TIMER(dev);
269
270
- CPUState *cpu = qemu_get_cpu(0);
271
- CPURISCVState *env = cpu->env_ptr;
272
- env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
273
+ s->mtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
274
&ibex_timer_cb, s);
275
- env->timecmp = 0;
276
+ s->mtimecmp = 0;
277
278
s->timer_ctrl = 0x00000000;
279
s->timer_cfg0 = 0x00010000;
280
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
281
index XXXXXXX..XXXXXXX 100644
282
--- a/target/riscv/machine.c
283
+++ b/target/riscv/machine.c
284
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pmu_ctr_state = {
285
286
const VMStateDescription vmstate_riscv_cpu = {
287
.name = "cpu",
288
- .version_id = 3,
289
- .minimum_version_id = 3,
290
+ .version_id = 4,
291
+ .minimum_version_id = 4,
292
.post_load = riscv_cpu_post_load,
293
.fields = (VMStateField[]) {
294
VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
295
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = {
296
VMSTATE_UINTTL(env.mscratch, RISCVCPU),
297
VMSTATE_UINT64(env.mfromhost, RISCVCPU),
298
VMSTATE_UINT64(env.mtohost, RISCVCPU),
299
- VMSTATE_UINT64(env.timecmp, RISCVCPU),
300
301
VMSTATE_END_OF_LIST()
302
},
303
--
304
2.37.2
diff view generated by jsdifflib
New patch
1
From: Atish Patra <atishp@rivosinc.com>
1
2
3
stimecmp allows the supervisor mode to update stimecmp CSR directly
4
to program the next timer interrupt. This CSR is part of the Sstc
5
extension which was ratified recently.
6
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Atish Patra <atishp@rivosinc.com>
9
Message-Id: <20220824221357.41070-3-atishp@rivosinc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/cpu.h | 5 ++
13
target/riscv/cpu_bits.h | 4 ++
14
target/riscv/time_helper.h | 30 ++++++++++++
15
target/riscv/cpu.c | 9 ++++
16
target/riscv/csr.c | 86 +++++++++++++++++++++++++++++++++
17
target/riscv/machine.c | 1 +
18
target/riscv/time_helper.c | 98 ++++++++++++++++++++++++++++++++++++++
19
target/riscv/meson.build | 3 +-
20
8 files changed, 235 insertions(+), 1 deletion(-)
21
create mode 100644 target/riscv/time_helper.h
22
create mode 100644 target/riscv/time_helper.c
23
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/cpu.h
27
+++ b/target/riscv/cpu.h
28
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
29
uint64_t mfromhost;
30
uint64_t mtohost;
31
32
+ /* Sstc CSRs */
33
+ uint64_t stimecmp;
34
+
35
/* physical memory protection */
36
pmp_table_t pmp_state;
37
target_ulong mseccfg;
38
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
39
float_status fp_status;
40
41
/* Fields from here on are preserved across CPU reset. */
42
+ QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
43
44
hwaddr kernel_addr;
45
hwaddr fdt_addr;
46
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
47
bool ext_ifencei;
48
bool ext_icsr;
49
bool ext_zihintpause;
50
+ bool ext_sstc;
51
bool ext_svinval;
52
bool ext_svnapot;
53
bool ext_svpbmt;
54
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/riscv/cpu_bits.h
57
+++ b/target/riscv/cpu_bits.h
58
@@ -XXX,XX +XXX,XX @@
59
#define CSR_STVAL 0x143
60
#define CSR_SIP 0x144
61
62
+/* Sstc supervisor CSRs */
63
+#define CSR_STIMECMP 0x14D
64
+#define CSR_STIMECMPH 0x15D
65
+
66
/* Supervisor Protection and Translation */
67
#define CSR_SPTBR 0x180
68
#define CSR_SATP 0x180
69
diff --git a/target/riscv/time_helper.h b/target/riscv/time_helper.h
70
new file mode 100644
71
index XXXXXXX..XXXXXXX
72
--- /dev/null
73
+++ b/target/riscv/time_helper.h
74
@@ -XXX,XX +XXX,XX @@
75
+/*
76
+ * RISC-V timer header file.
77
+ *
78
+ * Copyright (c) 2022 Rivos Inc.
79
+ *
80
+ * This program is free software; you can redistribute it and/or modify it
81
+ * under the terms and conditions of the GNU General Public License,
82
+ * version 2 or later, as published by the Free Software Foundation.
83
+ *
84
+ * This program is distributed in the hope it will be useful, but WITHOUT
85
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
86
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
87
+ * more details.
88
+ *
89
+ * You should have received a copy of the GNU General Public License along with
90
+ * this program. If not, see <http://www.gnu.org/licenses/>.
91
+ */
92
+
93
+#ifndef RISCV_TIME_HELPER_H
94
+#define RISCV_TIME_HELPER_H
95
+
96
+#include "cpu.h"
97
+#include "qemu/timer.h"
98
+
99
+void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer *timer,
100
+ uint64_t timecmp, uint64_t delta,
101
+ uint32_t timer_irq);
102
+void riscv_timer_init(RISCVCPU *cpu);
103
+
104
+#endif
105
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/target/riscv/cpu.c
108
+++ b/target/riscv/cpu.c
109
@@ -XXX,XX +XXX,XX @@
110
#include "qemu/log.h"
111
#include "cpu.h"
112
#include "internals.h"
113
+#include "time_helper.h"
114
#include "exec/exec-all.h"
115
#include "qapi/error.h"
116
#include "qemu/error-report.h"
117
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
118
ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
119
ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia),
120
ISA_EXT_DATA_ENTRY(ssaia, true, PRIV_VERSION_1_12_0, ext_ssaia),
121
+ ISA_EXT_DATA_ENTRY(sstc, true, PRIV_VERSION_1_12_0, ext_sstc),
122
ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval),
123
ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
124
ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
125
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
126
127
set_resetvec(env, cpu->cfg.resetvec);
128
129
+#ifndef CONFIG_USER_ONLY
130
+ if (cpu->cfg.ext_sstc) {
131
+ riscv_timer_init(cpu);
132
+ }
133
+#endif /* CONFIG_USER_ONLY */
134
+
135
/* Validate that MISA_MXL is set properly. */
136
switch (env->misa_mxl_max) {
137
#ifdef TARGET_RISCV64
138
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
139
DEFINE_PROP_BOOL("Zve64f", RISCVCPU, cfg.ext_zve64f, false),
140
DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
141
DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
142
+ DEFINE_PROP_BOOL("sstc", RISCVCPU, cfg.ext_sstc, true),
143
144
DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
145
DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
146
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
147
index XXXXXXX..XXXXXXX 100644
148
--- a/target/riscv/csr.c
149
+++ b/target/riscv/csr.c
150
@@ -XXX,XX +XXX,XX @@
151
#include "qemu/timer.h"
152
#include "cpu.h"
153
#include "pmu.h"
154
+#include "time_helper.h"
155
#include "qemu/main-loop.h"
156
#include "exec/exec-all.h"
157
#include "sysemu/cpu-timers.h"
158
@@ -XXX,XX +XXX,XX @@ static RISCVException read_timeh(CPURISCVState *env, int csrno,
159
return RISCV_EXCP_NONE;
160
}
161
162
+static RISCVException sstc(CPURISCVState *env, int csrno)
163
+{
164
+ CPUState *cs = env_cpu(env);
165
+ RISCVCPU *cpu = RISCV_CPU(cs);
166
+
167
+ if (!cpu->cfg.ext_sstc || !env->rdtime_fn) {
168
+ return RISCV_EXCP_ILLEGAL_INST;
169
+ }
170
+
171
+ if (env->priv == PRV_M) {
172
+ return RISCV_EXCP_NONE;
173
+ }
174
+
175
+ /*
176
+ * No need of separate function for rv32 as menvcfg stores both menvcfg
177
+ * menvcfgh for RV32.
178
+ */
179
+ if (!(get_field(env->mcounteren, COUNTEREN_TM) &&
180
+ get_field(env->menvcfg, MENVCFG_STCE))) {
181
+ return RISCV_EXCP_ILLEGAL_INST;
182
+ }
183
+
184
+ return smode(env, csrno);
185
+}
186
+
187
+static RISCVException sstc_32(CPURISCVState *env, int csrno)
188
+{
189
+ if (riscv_cpu_mxl(env) != MXL_RV32) {
190
+ return RISCV_EXCP_ILLEGAL_INST;
191
+ }
192
+
193
+ return sstc(env, csrno);
194
+}
195
+
196
+static RISCVException read_stimecmp(CPURISCVState *env, int csrno,
197
+ target_ulong *val)
198
+{
199
+ *val = env->stimecmp;
200
+ return RISCV_EXCP_NONE;
201
+}
202
+
203
+static RISCVException read_stimecmph(CPURISCVState *env, int csrno,
204
+ target_ulong *val)
205
+{
206
+ *val = env->stimecmp >> 32;
207
+ return RISCV_EXCP_NONE;
208
+}
209
+
210
+static RISCVException write_stimecmp(CPURISCVState *env, int csrno,
211
+ target_ulong val)
212
+{
213
+ RISCVCPU *cpu = env_archcpu(env);
214
+
215
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
216
+ env->stimecmp = deposit64(env->stimecmp, 0, 32, (uint64_t)val);
217
+ } else {
218
+ env->stimecmp = val;
219
+ }
220
+
221
+ riscv_timer_write_timecmp(cpu, env->stimer, env->stimecmp, 0, MIP_STIP);
222
+
223
+ return RISCV_EXCP_NONE;
224
+}
225
+
226
+static RISCVException write_stimecmph(CPURISCVState *env, int csrno,
227
+ target_ulong val)
228
+{
229
+ RISCVCPU *cpu = env_archcpu(env);
230
+
231
+ env->stimecmp = deposit64(env->stimecmp, 32, 32, (uint64_t)val);
232
+ riscv_timer_write_timecmp(cpu, env->stimer, env->stimecmp, 0, MIP_STIP);
233
+
234
+ return RISCV_EXCP_NONE;
235
+}
236
+
237
/* Machine constants */
238
239
#define M_MODE_INTERRUPTS ((uint64_t)(MIP_MSIP | MIP_MTIP | MIP_MEIP))
240
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
241
new_val |= env->external_seip * MIP_SEIP;
242
}
243
244
+ if (cpu->cfg.ext_sstc && (env->priv == PRV_M) &&
245
+ get_field(env->menvcfg, MENVCFG_STCE)) {
246
+ /* sstc extension forbids STIP & VSTIP to be writeable in mip */
247
+ mask = mask & ~(MIP_STIP | MIP_VSTIP);
248
+ }
249
+
250
if (mask) {
251
old_mip = riscv_cpu_update_mip(cpu, mask, (new_val & mask));
252
} else {
253
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
254
[CSR_SCAUSE] = { "scause", smode, read_scause, write_scause },
255
[CSR_STVAL] = { "stval", smode, read_stval, write_stval },
256
[CSR_SIP] = { "sip", smode, NULL, NULL, rmw_sip },
257
+ [CSR_STIMECMP] = { "stimecmp", sstc, read_stimecmp, write_stimecmp,
258
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
259
+ [CSR_STIMECMPH] = { "stimecmph", sstc_32, read_stimecmph, write_stimecmph,
260
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
261
262
/* Supervisor Protection and Translation */
263
[CSR_SATP] = { "satp", smode, read_satp, write_satp },
264
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
265
index XXXXXXX..XXXXXXX 100644
266
--- a/target/riscv/machine.c
267
+++ b/target/riscv/machine.c
268
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = {
269
VMSTATE_UINTTL(env.mscratch, RISCVCPU),
270
VMSTATE_UINT64(env.mfromhost, RISCVCPU),
271
VMSTATE_UINT64(env.mtohost, RISCVCPU),
272
+ VMSTATE_UINT64(env.stimecmp, RISCVCPU),
273
274
VMSTATE_END_OF_LIST()
275
},
276
diff --git a/target/riscv/time_helper.c b/target/riscv/time_helper.c
277
new file mode 100644
278
index XXXXXXX..XXXXXXX
279
--- /dev/null
280
+++ b/target/riscv/time_helper.c
281
@@ -XXX,XX +XXX,XX @@
282
+/*
283
+ * RISC-V timer helper implementation.
284
+ *
285
+ * Copyright (c) 2022 Rivos Inc.
286
+ *
287
+ * This program is free software; you can redistribute it and/or modify it
288
+ * under the terms and conditions of the GNU General Public License,
289
+ * version 2 or later, as published by the Free Software Foundation.
290
+ *
291
+ * This program is distributed in the hope it will be useful, but WITHOUT
292
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
293
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
294
+ * more details.
295
+ *
296
+ * You should have received a copy of the GNU General Public License along with
297
+ * this program. If not, see <http://www.gnu.org/licenses/>.
298
+ */
299
+
300
+#include "qemu/osdep.h"
301
+#include "qemu/log.h"
302
+#include "cpu_bits.h"
303
+#include "time_helper.h"
304
+#include "hw/intc/riscv_aclint.h"
305
+
306
+static void riscv_stimer_cb(void *opaque)
307
+{
308
+ RISCVCPU *cpu = opaque;
309
+ riscv_cpu_update_mip(cpu, MIP_STIP, BOOL_TO_MASK(1));
310
+}
311
+
312
+/*
313
+ * Called when timecmp is written to update the QEMU timer or immediately
314
+ * trigger timer interrupt if mtimecmp <= current timer value.
315
+ */
316
+void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer *timer,
317
+ uint64_t timecmp, uint64_t delta,
318
+ uint32_t timer_irq)
319
+{
320
+ uint64_t diff, ns_diff, next;
321
+ CPURISCVState *env = &cpu->env;
322
+ RISCVAclintMTimerState *mtimer = env->rdtime_fn_arg;
323
+ uint32_t timebase_freq = mtimer->timebase_freq;
324
+ uint64_t rtc_r = env->rdtime_fn(env->rdtime_fn_arg) + delta;
325
+
326
+ if (timecmp <= rtc_r) {
327
+ /*
328
+ * If we're setting an stimecmp value in the "past",
329
+ * immediately raise the timer interrupt
330
+ */
331
+ riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(1));
332
+ return;
333
+ }
334
+
335
+ /* Clear the [V]STIP bit in mip */
336
+ riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0));
337
+
338
+ /* otherwise, set up the future timer interrupt */
339
+ diff = timecmp - rtc_r;
340
+ /* back to ns (note args switched in muldiv64) */
341
+ ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq);
342
+
343
+ /*
344
+ * check if ns_diff overflowed and check if the addition would potentially
345
+ * overflow
346
+ */
347
+ if ((NANOSECONDS_PER_SECOND > timebase_freq && ns_diff < diff) ||
348
+ ns_diff > INT64_MAX) {
349
+ next = INT64_MAX;
350
+ } else {
351
+ /*
352
+ * as it is very unlikely qemu_clock_get_ns will return a value
353
+ * greater than INT64_MAX, no additional check is needed for an
354
+ * unsigned integer overflow.
355
+ */
356
+ next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns_diff;
357
+ /*
358
+ * if ns_diff is INT64_MAX next may still be outside the range
359
+ * of a signed integer.
360
+ */
361
+ next = MIN(next, INT64_MAX);
362
+ }
363
+
364
+ timer_mod(timer, next);
365
+}
366
+
367
+void riscv_timer_init(RISCVCPU *cpu)
368
+{
369
+ CPURISCVState *env;
370
+
371
+ if (!cpu) {
372
+ return;
373
+ }
374
+
375
+ env = &cpu->env;
376
+ env->stimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &riscv_stimer_cb, cpu);
377
+ env->stimecmp = 0;
378
+
379
+}
380
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
381
index XXXXXXX..XXXXXXX 100644
382
--- a/target/riscv/meson.build
383
+++ b/target/riscv/meson.build
384
@@ -XXX,XX +XXX,XX @@ riscv_softmmu_ss.add(files(
385
'debug.c',
386
'monitor.c',
387
'machine.c',
388
- 'pmu.c'
389
+ 'pmu.c',
390
+ 'time_helper.c'
391
))
392
393
target_arch += {'riscv': riscv_ss}
394
--
395
2.37.2
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Atish Patra <atishp@rivosinc.com>
2
2
3
Configuring a drive with "if=none" is meant for creation of a backend
3
vstimecmp CSR allows the guest OS or to program the next guest timer
4
only, it should not get automatically assigned to a device frontend.
4
interrupt directly. Thus, hypervisor no longer need to inject the
5
Use "if=pflash" for the One-Time-Programmable device instead (like
5
timer interrupt to the guest if vstimecmp is used. This was ratified
6
it is e.g. also done for the efuse device in hw/arm/xlnx-zcu102.c).
6
as a part of the Sstc extension.
7
7
8
Since the old way of configuring the device has already been published
9
with the previous QEMU versions, we cannot remove this immediately, but
10
have to deprecate it and support it for at least two more releases.
11
12
Signed-off-by: Thomas Huth <thuth@redhat.com>
13
Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
Reviewed-by: Markus Armbruster <armbru@redhat.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Message-id: 20211119102549.217755-1-thuth@redhat.com
9
Signed-off-by: Atish Patra <atishp@rivosinc.com>
10
Message-Id: <20220824221357.41070-4-atishp@rivosinc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
12
---
19
docs/about/deprecated.rst | 6 ++++++
13
target/riscv/cpu.h | 4 ++
20
hw/misc/sifive_u_otp.c | 9 ++++++++-
14
target/riscv/cpu_bits.h | 4 ++
21
2 files changed, 14 insertions(+), 1 deletion(-)
15
target/riscv/cpu_helper.c | 11 +++--
16
target/riscv/csr.c | 88 ++++++++++++++++++++++++++++++++++++--
17
target/riscv/machine.c | 1 +
18
target/riscv/time_helper.c | 16 +++++++
19
6 files changed, 118 insertions(+), 6 deletions(-)
22
20
23
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
21
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
24
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
25
--- a/docs/about/deprecated.rst
23
--- a/target/riscv/cpu.h
26
+++ b/docs/about/deprecated.rst
24
+++ b/target/riscv/cpu.h
27
@@ -XXX,XX +XXX,XX @@ as short-form boolean values, and passed to plugins as ``arg_name=on``.
25
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
28
However, short-form booleans are deprecated and full explicit ``arg_name=on``
26
/* Sstc CSRs */
29
form is preferred.
27
uint64_t stimecmp;
30
28
31
+``-drive if=none`` for the sifive_u OTP device (since 6.2)
29
+ uint64_t vstimecmp;
32
+''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
30
+
33
+
31
/* physical memory protection */
34
+Using ``-drive if=none`` to configure the OTP device of the sifive_u
32
pmp_table_t pmp_state;
35
+RISC-V machine is deprecated. Use ``-drive if=pflash`` instead.
33
target_ulong mseccfg;
36
+
34
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
37
35
38
QEMU Machine Protocol (QMP) commands
36
/* Fields from here on are preserved across CPU reset. */
39
------------------------------------
37
QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
40
diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c
38
+ QEMUTimer *vstimer; /* Internal timer for VS-mode interrupt */
41
index XXXXXXX..XXXXXXX 100644
39
+ bool vstime_irq;
42
--- a/hw/misc/sifive_u_otp.c
40
43
+++ b/hw/misc/sifive_u_otp.c
41
hwaddr kernel_addr;
44
@@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_realize(DeviceState *dev, Error **errp)
42
hwaddr fdt_addr;
45
TYPE_SIFIVE_U_OTP, SIFIVE_U_OTP_REG_SIZE);
43
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
46
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
44
index XXXXXXX..XXXXXXX 100644
47
45
--- a/target/riscv/cpu_bits.h
48
- dinfo = drive_get_next(IF_NONE);
46
+++ b/target/riscv/cpu_bits.h
49
+ dinfo = drive_get_next(IF_PFLASH);
47
@@ -XXX,XX +XXX,XX @@
50
+ if (!dinfo) {
48
#define CSR_VSIP 0x244
51
+ dinfo = drive_get_next(IF_NONE);
49
#define CSR_VSATP 0x280
52
+ if (dinfo) {
50
53
+ warn_report("using \"-drive if=none\" for the OTP is deprecated, "
51
+/* Sstc virtual CSRs */
54
+ "use \"-drive if=pflash\" instead.");
52
+#define CSR_VSTIMECMP 0x24D
53
+#define CSR_VSTIMECMPH 0x25D
54
+
55
#define CSR_MTINST 0x34a
56
#define CSR_MTVAL2 0x34b
57
58
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/riscv/cpu_helper.c
61
+++ b/target/riscv/cpu_helper.c
62
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_cpu_all_pending(CPURISCVState *env)
63
{
64
uint32_t gein = get_field(env->hstatus, HSTATUS_VGEIN);
65
uint64_t vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
66
+ uint64_t vstip = (env->vstime_irq) ? MIP_VSTIP : 0;
67
68
- return (env->mip | vsgein) & env->mie;
69
+ return (env->mip | vsgein | vstip) & env->mie;
70
}
71
72
int riscv_cpu_mirq_pending(CPURISCVState *env)
73
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value)
74
{
75
CPURISCVState *env = &cpu->env;
76
CPUState *cs = CPU(cpu);
77
- uint64_t gein, vsgein = 0, old = env->mip;
78
+ uint64_t gein, vsgein = 0, vstip = 0, old = env->mip;
79
bool locked = false;
80
81
if (riscv_cpu_virt_enabled(env)) {
82
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value)
83
vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
84
}
85
86
+ /* No need to update mip for VSTIP */
87
+ mask = ((mask == MIP_VSTIP) && env->vstime_irq) ? 0 : mask;
88
+ vstip = env->vstime_irq ? MIP_VSTIP : 0;
89
+
90
if (!qemu_mutex_iothread_locked()) {
91
locked = true;
92
qemu_mutex_lock_iothread();
93
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value)
94
95
env->mip = (env->mip & ~mask) | (value & mask);
96
97
- if (env->mip | vsgein) {
98
+ if (env->mip | vsgein | vstip) {
99
cpu_interrupt(cs, CPU_INTERRUPT_HARD);
100
} else {
101
cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
102
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/riscv/csr.c
105
+++ b/target/riscv/csr.c
106
@@ -XXX,XX +XXX,XX @@ static RISCVException sstc(CPURISCVState *env, int csrno)
107
{
108
CPUState *cs = env_cpu(env);
109
RISCVCPU *cpu = RISCV_CPU(cs);
110
+ bool hmode_check = false;
111
112
if (!cpu->cfg.ext_sstc || !env->rdtime_fn) {
113
return RISCV_EXCP_ILLEGAL_INST;
114
@@ -XXX,XX +XXX,XX @@ static RISCVException sstc(CPURISCVState *env, int csrno)
115
return RISCV_EXCP_ILLEGAL_INST;
116
}
117
118
- return smode(env, csrno);
119
+ if (riscv_cpu_virt_enabled(env)) {
120
+ if (!(get_field(env->hcounteren, COUNTEREN_TM) &
121
+ get_field(env->henvcfg, HENVCFG_STCE))) {
122
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
55
+ }
123
+ }
56
+ }
124
+ }
57
if (dinfo) {
125
+
58
int ret;
126
+ if ((csrno == CSR_VSTIMECMP) || (csrno == CSR_VSTIMECMPH)) {
59
uint64_t perm;
127
+ hmode_check = true;
128
+ }
129
+
130
+ return hmode_check ? hmode(env, csrno) : smode(env, csrno);
131
}
132
133
static RISCVException sstc_32(CPURISCVState *env, int csrno)
134
@@ -XXX,XX +XXX,XX @@ static RISCVException sstc_32(CPURISCVState *env, int csrno)
135
return sstc(env, csrno);
136
}
137
138
+static RISCVException read_vstimecmp(CPURISCVState *env, int csrno,
139
+ target_ulong *val)
140
+{
141
+ *val = env->vstimecmp;
142
+
143
+ return RISCV_EXCP_NONE;
144
+}
145
+
146
+static RISCVException read_vstimecmph(CPURISCVState *env, int csrno,
147
+ target_ulong *val)
148
+{
149
+ *val = env->vstimecmp >> 32;
150
+
151
+ return RISCV_EXCP_NONE;
152
+}
153
+
154
+static RISCVException write_vstimecmp(CPURISCVState *env, int csrno,
155
+ target_ulong val)
156
+{
157
+ RISCVCPU *cpu = env_archcpu(env);
158
+
159
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
160
+ env->vstimecmp = deposit64(env->vstimecmp, 0, 32, (uint64_t)val);
161
+ } else {
162
+ env->vstimecmp = val;
163
+ }
164
+
165
+ riscv_timer_write_timecmp(cpu, env->vstimer, env->vstimecmp,
166
+ env->htimedelta, MIP_VSTIP);
167
+
168
+ return RISCV_EXCP_NONE;
169
+}
170
+
171
+static RISCVException write_vstimecmph(CPURISCVState *env, int csrno,
172
+ target_ulong val)
173
+{
174
+ RISCVCPU *cpu = env_archcpu(env);
175
+
176
+ env->vstimecmp = deposit64(env->vstimecmp, 32, 32, (uint64_t)val);
177
+ riscv_timer_write_timecmp(cpu, env->vstimer, env->vstimecmp,
178
+ env->htimedelta, MIP_VSTIP);
179
+
180
+ return RISCV_EXCP_NONE;
181
+}
182
+
183
static RISCVException read_stimecmp(CPURISCVState *env, int csrno,
184
target_ulong *val)
185
{
186
- *val = env->stimecmp;
187
+ if (riscv_cpu_virt_enabled(env)) {
188
+ *val = env->vstimecmp;
189
+ } else {
190
+ *val = env->stimecmp;
191
+ }
192
+
193
return RISCV_EXCP_NONE;
194
}
195
196
static RISCVException read_stimecmph(CPURISCVState *env, int csrno,
197
target_ulong *val)
198
{
199
- *val = env->stimecmp >> 32;
200
+ if (riscv_cpu_virt_enabled(env)) {
201
+ *val = env->vstimecmp >> 32;
202
+ } else {
203
+ *val = env->stimecmp >> 32;
204
+ }
205
+
206
return RISCV_EXCP_NONE;
207
}
208
209
@@ -XXX,XX +XXX,XX @@ static RISCVException write_stimecmp(CPURISCVState *env, int csrno,
210
{
211
RISCVCPU *cpu = env_archcpu(env);
212
213
+ if (riscv_cpu_virt_enabled(env)) {
214
+ return write_vstimecmp(env, csrno, val);
215
+ }
216
+
217
if (riscv_cpu_mxl(env) == MXL_RV32) {
218
env->stimecmp = deposit64(env->stimecmp, 0, 32, (uint64_t)val);
219
} else {
220
@@ -XXX,XX +XXX,XX @@ static RISCVException write_stimecmph(CPURISCVState *env, int csrno,
221
{
222
RISCVCPU *cpu = env_archcpu(env);
223
224
+ if (riscv_cpu_virt_enabled(env)) {
225
+ return write_vstimecmph(env, csrno, val);
226
+ }
227
+
228
env->stimecmp = deposit64(env->stimecmp, 32, 32, (uint64_t)val);
229
riscv_timer_write_timecmp(cpu, env->stimer, env->stimecmp, 0, MIP_STIP);
230
231
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
232
if (csrno != CSR_HVIP) {
233
gin = get_field(env->hstatus, HSTATUS_VGEIN);
234
old_mip |= (env->hgeip & ((target_ulong)1 << gin)) ? MIP_VSEIP : 0;
235
+ old_mip |= env->vstime_irq ? MIP_VSTIP : 0;
236
}
237
238
if (ret_val) {
239
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
240
.min_priv_ver = PRIV_VERSION_1_12_0 },
241
[CSR_STIMECMPH] = { "stimecmph", sstc_32, read_stimecmph, write_stimecmph,
242
.min_priv_ver = PRIV_VERSION_1_12_0 },
243
+ [CSR_VSTIMECMP] = { "vstimecmp", sstc, read_vstimecmp,
244
+ write_vstimecmp,
245
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
246
+ [CSR_VSTIMECMPH] = { "vstimecmph", sstc_32, read_vstimecmph,
247
+ write_vstimecmph,
248
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
249
250
/* Supervisor Protection and Translation */
251
[CSR_SATP] = { "satp", smode, read_satp, write_satp },
252
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
253
index XXXXXXX..XXXXXXX 100644
254
--- a/target/riscv/machine.c
255
+++ b/target/riscv/machine.c
256
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_hyper = {
257
VMSTATE_UINTTL(env.hgeie, RISCVCPU),
258
VMSTATE_UINTTL(env.hgeip, RISCVCPU),
259
VMSTATE_UINT64(env.htimedelta, RISCVCPU),
260
+ VMSTATE_UINT64(env.vstimecmp, RISCVCPU),
261
262
VMSTATE_UINTTL(env.hvictl, RISCVCPU),
263
VMSTATE_UINT8_ARRAY(env.hviprio, RISCVCPU, 64),
264
diff --git a/target/riscv/time_helper.c b/target/riscv/time_helper.c
265
index XXXXXXX..XXXXXXX 100644
266
--- a/target/riscv/time_helper.c
267
+++ b/target/riscv/time_helper.c
268
@@ -XXX,XX +XXX,XX @@
269
#include "time_helper.h"
270
#include "hw/intc/riscv_aclint.h"
271
272
+static void riscv_vstimer_cb(void *opaque)
273
+{
274
+ RISCVCPU *cpu = opaque;
275
+ CPURISCVState *env = &cpu->env;
276
+ env->vstime_irq = 1;
277
+ riscv_cpu_update_mip(cpu, MIP_VSTIP, BOOL_TO_MASK(1));
278
+}
279
+
280
static void riscv_stimer_cb(void *opaque)
281
{
282
RISCVCPU *cpu = opaque;
283
@@ -XXX,XX +XXX,XX @@ void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer *timer,
284
* If we're setting an stimecmp value in the "past",
285
* immediately raise the timer interrupt
286
*/
287
+ if (timer_irq == MIP_VSTIP) {
288
+ env->vstime_irq = 1;
289
+ }
290
riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(1));
291
return;
292
}
293
294
+ if (timer_irq == MIP_VSTIP) {
295
+ env->vstime_irq = 0;
296
+ }
297
/* Clear the [V]STIP bit in mip */
298
riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0));
299
300
@@ -XXX,XX +XXX,XX @@ void riscv_timer_init(RISCVCPU *cpu)
301
env->stimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &riscv_stimer_cb, cpu);
302
env->stimecmp = 0;
303
304
+ env->vstimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &riscv_vstimer_cb, cpu);
305
+ env->vstimecmp = 0;
306
}
60
--
307
--
61
2.31.1
308
2.37.2
62
63
diff view generated by jsdifflib
New patch
1
From: Atish Patra <atishp@rivosinc.com>
1
2
3
The Sscofpmf ('Ss' for Privileged arch and Supervisor-level extensions,
4
and 'cofpmf' for Count OverFlow and Privilege Mode Filtering)
5
extension allows the perf to handle overflow interrupts and filtering
6
support. This patch provides a framework for programmable
7
counters to leverage the extension. As the extension doesn't have any
8
provision for the overflow bit for fixed counters, the fixed events
9
can also be monitoring using programmable counters. The underlying
10
counters for cycle and instruction counters are always running. Thus,
11
a separate timer device is programmed to handle the overflow.
12
13
Tested-by: Heiko Stuebner <heiko@sntech.de>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Atish Patra <atish.patra@wdc.com>
16
Signed-off-by: Atish Patra <atishp@rivosinc.com>
17
Message-Id: <20220824221701.41932-2-atishp@rivosinc.com>
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
---
20
target/riscv/cpu.h | 25 +++
21
target/riscv/cpu_bits.h | 55 ++++++
22
target/riscv/pmu.h | 7 +
23
target/riscv/cpu.c | 12 ++
24
target/riscv/csr.c | 166 +++++++++++++++++-
25
target/riscv/machine.c | 1 +
26
target/riscv/pmu.c | 368 +++++++++++++++++++++++++++++++++++++++-
27
7 files changed, 623 insertions(+), 11 deletions(-)
28
29
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/cpu.h
32
+++ b/target/riscv/cpu.h
33
@@ -XXX,XX +XXX,XX @@ typedef struct PMUCTRState {
34
/* Snapshort value of a counter in RV32 */
35
target_ulong mhpmcounterh_prev;
36
bool started;
37
+ /* Value beyond UINT32_MAX/UINT64_MAX before overflow interrupt trigger */
38
+ target_ulong irq_overflow_left;
39
} PMUCTRState;
40
41
struct CPUArchState {
42
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
43
/* PMU event selector configured values. First three are unused*/
44
target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS];
45
46
+ /* PMU event selector configured values for RV32*/
47
+ target_ulong mhpmeventh_val[RV_MAX_MHPMEVENTS];
48
+
49
target_ulong sscratch;
50
target_ulong mscratch;
51
52
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
53
bool ext_zmmul;
54
bool ext_smaia;
55
bool ext_ssaia;
56
+ bool ext_sscofpmf;
57
bool rvv_ta_all_1s;
58
bool rvv_ma_all_1s;
59
60
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
61
62
/* Configuration Settings */
63
RISCVCPUConfig cfg;
64
+
65
+ QEMUTimer *pmu_timer;
66
+ /* A bitmask of Available programmable counters */
67
+ uint32_t pmu_avail_ctrs;
68
+ /* Mapping of events to counters */
69
+ GHashTable *pmu_event_ctr_map;
70
};
71
72
static inline int riscv_has_ext(CPURISCVState *env, target_ulong ext)
73
@@ -XXX,XX +XXX,XX @@ enum {
74
CSR_TABLE_SIZE = 0x1000
75
};
76
77
+/**
78
+ * The event id are encoded based on the encoding specified in the
79
+ * SBI specification v0.3
80
+ */
81
+
82
+enum riscv_pmu_event_idx {
83
+ RISCV_PMU_EVENT_HW_CPU_CYCLES = 0x01,
84
+ RISCV_PMU_EVENT_HW_INSTRUCTIONS = 0x02,
85
+ RISCV_PMU_EVENT_CACHE_DTLB_READ_MISS = 0x10019,
86
+ RISCV_PMU_EVENT_CACHE_DTLB_WRITE_MISS = 0x1001B,
87
+ RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS = 0x10021,
88
+};
89
+
90
/* CSR function table */
91
extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
92
93
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
94
index XXXXXXX..XXXXXXX 100644
95
--- a/target/riscv/cpu_bits.h
96
+++ b/target/riscv/cpu_bits.h
97
@@ -XXX,XX +XXX,XX @@
98
#define CSR_MHPMEVENT29 0x33d
99
#define CSR_MHPMEVENT30 0x33e
100
#define CSR_MHPMEVENT31 0x33f
101
+
102
+#define CSR_MHPMEVENT3H 0x723
103
+#define CSR_MHPMEVENT4H 0x724
104
+#define CSR_MHPMEVENT5H 0x725
105
+#define CSR_MHPMEVENT6H 0x726
106
+#define CSR_MHPMEVENT7H 0x727
107
+#define CSR_MHPMEVENT8H 0x728
108
+#define CSR_MHPMEVENT9H 0x729
109
+#define CSR_MHPMEVENT10H 0x72a
110
+#define CSR_MHPMEVENT11H 0x72b
111
+#define CSR_MHPMEVENT12H 0x72c
112
+#define CSR_MHPMEVENT13H 0x72d
113
+#define CSR_MHPMEVENT14H 0x72e
114
+#define CSR_MHPMEVENT15H 0x72f
115
+#define CSR_MHPMEVENT16H 0x730
116
+#define CSR_MHPMEVENT17H 0x731
117
+#define CSR_MHPMEVENT18H 0x732
118
+#define CSR_MHPMEVENT19H 0x733
119
+#define CSR_MHPMEVENT20H 0x734
120
+#define CSR_MHPMEVENT21H 0x735
121
+#define CSR_MHPMEVENT22H 0x736
122
+#define CSR_MHPMEVENT23H 0x737
123
+#define CSR_MHPMEVENT24H 0x738
124
+#define CSR_MHPMEVENT25H 0x739
125
+#define CSR_MHPMEVENT26H 0x73a
126
+#define CSR_MHPMEVENT27H 0x73b
127
+#define CSR_MHPMEVENT28H 0x73c
128
+#define CSR_MHPMEVENT29H 0x73d
129
+#define CSR_MHPMEVENT30H 0x73e
130
+#define CSR_MHPMEVENT31H 0x73f
131
+
132
#define CSR_MHPMCOUNTER3H 0xb83
133
#define CSR_MHPMCOUNTER4H 0xb84
134
#define CSR_MHPMCOUNTER5H 0xb85
135
@@ -XXX,XX +XXX,XX @@
136
#define CSR_VSMTE 0x2c0
137
#define CSR_VSPMMASK 0x2c1
138
#define CSR_VSPMBASE 0x2c2
139
+#define CSR_SCOUNTOVF 0xda0
140
141
/* Crypto Extension */
142
#define CSR_SEED 0x015
143
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
144
#define IRQ_VS_EXT 10
145
#define IRQ_M_EXT 11
146
#define IRQ_S_GEXT 12
147
+#define IRQ_PMU_OVF 13
148
#define IRQ_LOCAL_MAX 16
149
#define IRQ_LOCAL_GUEST_MAX (TARGET_LONG_BITS - 1)
150
151
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
152
#define MIP_VSEIP (1 << IRQ_VS_EXT)
153
#define MIP_MEIP (1 << IRQ_M_EXT)
154
#define MIP_SGEIP (1 << IRQ_S_GEXT)
155
+#define MIP_LCOFIP (1 << IRQ_PMU_OVF)
156
157
/* sip masks */
158
#define SIP_SSIP MIP_SSIP
159
#define SIP_STIP MIP_STIP
160
#define SIP_SEIP MIP_SEIP
161
+#define SIP_LCOFIP MIP_LCOFIP
162
163
/* MIE masks */
164
#define MIE_SEIE (1 << IRQ_S_EXT)
165
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
166
#define SEED_OPST_WAIT (0b01 << 30)
167
#define SEED_OPST_ES16 (0b10 << 30)
168
#define SEED_OPST_DEAD (0b11 << 30)
169
+/* PMU related bits */
170
+#define MIE_LCOFIE (1 << IRQ_PMU_OVF)
171
+
172
+#define MHPMEVENT_BIT_OF BIT_ULL(63)
173
+#define MHPMEVENTH_BIT_OF BIT(31)
174
+#define MHPMEVENT_BIT_MINH BIT_ULL(62)
175
+#define MHPMEVENTH_BIT_MINH BIT(30)
176
+#define MHPMEVENT_BIT_SINH BIT_ULL(61)
177
+#define MHPMEVENTH_BIT_SINH BIT(29)
178
+#define MHPMEVENT_BIT_UINH BIT_ULL(60)
179
+#define MHPMEVENTH_BIT_UINH BIT(28)
180
+#define MHPMEVENT_BIT_VSINH BIT_ULL(59)
181
+#define MHPMEVENTH_BIT_VSINH BIT(27)
182
+#define MHPMEVENT_BIT_VUINH BIT_ULL(58)
183
+#define MHPMEVENTH_BIT_VUINH BIT(26)
184
+
185
+#define MHPMEVENT_SSCOF_MASK _ULL(0xFFFF000000000000)
186
+#define MHPMEVENT_IDX_MASK 0xFFFFF
187
+#define MHPMEVENT_SSCOF_RESVD 16
188
+
189
#endif
190
diff --git a/target/riscv/pmu.h b/target/riscv/pmu.h
191
index XXXXXXX..XXXXXXX 100644
192
--- a/target/riscv/pmu.h
193
+++ b/target/riscv/pmu.h
194
@@ -XXX,XX +XXX,XX @@ bool riscv_pmu_ctr_monitor_instructions(CPURISCVState *env,
195
uint32_t target_ctr);
196
bool riscv_pmu_ctr_monitor_cycles(CPURISCVState *env,
197
uint32_t target_ctr);
198
+void riscv_pmu_timer_cb(void *priv);
199
+int riscv_pmu_init(RISCVCPU *cpu, int num_counters);
200
+int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value,
201
+ uint32_t ctr_idx);
202
+int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum riscv_pmu_event_idx event_idx);
203
+int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t value,
204
+ uint32_t ctr_idx);
205
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
206
index XXXXXXX..XXXXXXX 100644
207
--- a/target/riscv/cpu.c
208
+++ b/target/riscv/cpu.c
209
@@ -XXX,XX +XXX,XX @@
210
#include "qemu/ctype.h"
211
#include "qemu/log.h"
212
#include "cpu.h"
213
+#include "pmu.h"
214
#include "internals.h"
215
#include "time_helper.h"
216
#include "exec/exec-all.h"
217
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
218
ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
219
ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia),
220
ISA_EXT_DATA_ENTRY(ssaia, true, PRIV_VERSION_1_12_0, ext_ssaia),
221
+ ISA_EXT_DATA_ENTRY(sscofpmf, true, PRIV_VERSION_1_12_0, ext_sscofpmf),
222
ISA_EXT_DATA_ENTRY(sstc, true, PRIV_VERSION_1_12_0, ext_sstc),
223
ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval),
224
ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
225
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
226
set_misa(env, env->misa_mxl, ext);
227
}
228
229
+#ifndef CONFIG_USER_ONLY
230
+ if (cpu->cfg.pmu_num) {
231
+ if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && cpu->cfg.ext_sscofpmf) {
232
+ cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
233
+ riscv_pmu_timer_cb, cpu);
234
+ }
235
+ }
236
+#endif
237
+
238
riscv_cpu_register_gdb_regs_for_features(cs);
239
240
qemu_init_vcpu(cs);
241
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
242
DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false),
243
DEFINE_PROP_BOOL("h", RISCVCPU, cfg.ext_h, true),
244
DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
245
+ DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false),
246
DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
247
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
248
DEFINE_PROP_BOOL("Zihintpause", RISCVCPU, cfg.ext_zihintpause, true),
249
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
250
index XXXXXXX..XXXXXXX 100644
251
--- a/target/riscv/csr.c
252
+++ b/target/riscv/csr.c
253
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
254
CPUState *cs = env_cpu(env);
255
RISCVCPU *cpu = RISCV_CPU(cs);
256
int ctr_index;
257
- int base_csrno = CSR_HPMCOUNTER3;
258
+ int base_csrno = CSR_CYCLE;
259
bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
260
261
if (rv32 && csrno >= CSR_CYCLEH) {
262
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
263
}
264
ctr_index = csrno - base_csrno;
265
266
- if (!cpu->cfg.pmu_num || ctr_index >= (cpu->cfg.pmu_num)) {
267
+ if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) ||
268
+ (csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) {
269
+ goto skip_ext_pmu_check;
270
+ }
271
+
272
+ if ((!cpu->cfg.pmu_num || !(cpu->pmu_avail_ctrs & BIT(ctr_index)))) {
273
/* No counter is enabled in PMU or the counter is out of range */
274
return RISCV_EXCP_ILLEGAL_INST;
275
}
276
277
+skip_ext_pmu_check:
278
+
279
if (env->priv == PRV_S) {
280
switch (csrno) {
281
case CSR_CYCLE:
282
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
283
}
284
break;
285
case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
286
- ctr_index = csrno - CSR_CYCLE;
287
if (!get_field(env->mcounteren, 1 << ctr_index)) {
288
return RISCV_EXCP_ILLEGAL_INST;
289
}
290
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
291
}
292
break;
293
case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
294
- ctr_index = csrno - CSR_CYCLEH;
295
if (!get_field(env->mcounteren, 1 << ctr_index)) {
296
return RISCV_EXCP_ILLEGAL_INST;
297
}
298
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
299
}
300
break;
301
case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
302
- ctr_index = csrno - CSR_CYCLE;
303
if (!get_field(env->hcounteren, 1 << ctr_index) &&
304
get_field(env->mcounteren, 1 << ctr_index)) {
305
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
306
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
307
}
308
break;
309
case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
310
- ctr_index = csrno - CSR_CYCLEH;
311
if (!get_field(env->hcounteren, 1 << ctr_index) &&
312
get_field(env->mcounteren, 1 << ctr_index)) {
313
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
314
@@ -XXX,XX +XXX,XX @@ static RISCVException mctr32(CPURISCVState *env, int csrno)
315
return mctr(env, csrno);
316
}
317
318
+static RISCVException sscofpmf(CPURISCVState *env, int csrno)
319
+{
320
+ CPUState *cs = env_cpu(env);
321
+ RISCVCPU *cpu = RISCV_CPU(cs);
322
+
323
+ if (!cpu->cfg.ext_sscofpmf) {
324
+ return RISCV_EXCP_ILLEGAL_INST;
325
+ }
326
+
327
+ return RISCV_EXCP_NONE;
328
+}
329
+
330
static RISCVException any(CPURISCVState *env, int csrno)
331
{
332
return RISCV_EXCP_NONE;
333
@@ -XXX,XX +XXX,XX @@ static int read_mhpmevent(CPURISCVState *env, int csrno, target_ulong *val)
334
static int write_mhpmevent(CPURISCVState *env, int csrno, target_ulong val)
335
{
336
int evt_index = csrno - CSR_MCOUNTINHIBIT;
337
+ uint64_t mhpmevt_val = val;
338
339
env->mhpmevent_val[evt_index] = val;
340
341
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
342
+ mhpmevt_val = mhpmevt_val |
343
+ ((uint64_t)env->mhpmeventh_val[evt_index] << 32);
344
+ }
345
+ riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
346
+
347
+ return RISCV_EXCP_NONE;
348
+}
349
+
350
+static int read_mhpmeventh(CPURISCVState *env, int csrno, target_ulong *val)
351
+{
352
+ int evt_index = csrno - CSR_MHPMEVENT3H + 3;
353
+
354
+ *val = env->mhpmeventh_val[evt_index];
355
+
356
+ return RISCV_EXCP_NONE;
357
+}
358
+
359
+static int write_mhpmeventh(CPURISCVState *env, int csrno, target_ulong val)
360
+{
361
+ int evt_index = csrno - CSR_MHPMEVENT3H + 3;
362
+ uint64_t mhpmevth_val = val;
363
+ uint64_t mhpmevt_val = env->mhpmevent_val[evt_index];
364
+
365
+ mhpmevt_val = mhpmevt_val | (mhpmevth_val << 32);
366
+ env->mhpmeventh_val[evt_index] = val;
367
+
368
+ riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
369
+
370
return RISCV_EXCP_NONE;
371
}
372
373
@@ -XXX,XX +XXX,XX @@ static int write_mhpmcounter(CPURISCVState *env, int csrno, target_ulong val)
374
{
375
int ctr_idx = csrno - CSR_MCYCLE;
376
PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
377
+ uint64_t mhpmctr_val = val;
378
379
counter->mhpmcounter_val = val;
380
if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
381
riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
382
counter->mhpmcounter_prev = get_ticks(false);
383
- } else {
384
+ if (ctr_idx > 2) {
385
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
386
+ mhpmctr_val = mhpmctr_val |
387
+ ((uint64_t)counter->mhpmcounterh_val << 32);
388
+ }
389
+ riscv_pmu_setup_timer(env, mhpmctr_val, ctr_idx);
390
+ }
391
+ } else {
392
/* Other counters can keep incrementing from the given value */
393
counter->mhpmcounter_prev = val;
394
}
395
@@ -XXX,XX +XXX,XX @@ static int write_mhpmcounterh(CPURISCVState *env, int csrno, target_ulong val)
396
{
397
int ctr_idx = csrno - CSR_MCYCLEH;
398
PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
399
+ uint64_t mhpmctr_val = counter->mhpmcounter_val;
400
+ uint64_t mhpmctrh_val = val;
401
402
counter->mhpmcounterh_val = val;
403
+ mhpmctr_val = mhpmctr_val | (mhpmctrh_val << 32);
404
if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
405
riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
406
counter->mhpmcounterh_prev = get_ticks(true);
407
+ if (ctr_idx > 2) {
408
+ riscv_pmu_setup_timer(env, mhpmctr_val, ctr_idx);
409
+ }
410
} else {
411
counter->mhpmcounterh_prev = val;
412
}
413
@@ -XXX,XX +XXX,XX @@ static int read_hpmcounterh(CPURISCVState *env, int csrno, target_ulong *val)
414
return riscv_pmu_read_ctr(env, val, true, ctr_index);
415
}
416
417
+static int read_scountovf(CPURISCVState *env, int csrno, target_ulong *val)
418
+{
419
+ int mhpmevt_start = CSR_MHPMEVENT3 - CSR_MCOUNTINHIBIT;
420
+ int i;
421
+ *val = 0;
422
+ target_ulong *mhpm_evt_val;
423
+ uint64_t of_bit_mask;
424
+
425
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
426
+ mhpm_evt_val = env->mhpmeventh_val;
427
+ of_bit_mask = MHPMEVENTH_BIT_OF;
428
+ } else {
429
+ mhpm_evt_val = env->mhpmevent_val;
430
+ of_bit_mask = MHPMEVENT_BIT_OF;
431
+ }
432
+
433
+ for (i = mhpmevt_start; i < RV_MAX_MHPMEVENTS; i++) {
434
+ if ((get_field(env->mcounteren, BIT(i))) &&
435
+ (mhpm_evt_val[i] & of_bit_mask)) {
436
+ *val |= BIT(i);
437
+ }
438
+ }
439
+
440
+ return RISCV_EXCP_NONE;
441
+}
442
+
443
static RISCVException read_time(CPURISCVState *env, int csrno,
444
target_ulong *val)
445
{
446
@@ -XXX,XX +XXX,XX @@ static RISCVException write_stimecmph(CPURISCVState *env, int csrno,
447
/* Machine constants */
448
449
#define M_MODE_INTERRUPTS ((uint64_t)(MIP_MSIP | MIP_MTIP | MIP_MEIP))
450
-#define S_MODE_INTERRUPTS ((uint64_t)(MIP_SSIP | MIP_STIP | MIP_SEIP))
451
+#define S_MODE_INTERRUPTS ((uint64_t)(MIP_SSIP | MIP_STIP | MIP_SEIP | \
452
+ MIP_LCOFIP))
453
#define VS_MODE_INTERRUPTS ((uint64_t)(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP))
454
#define HS_MODE_INTERRUPTS ((uint64_t)(MIP_SGEIP | VS_MODE_INTERRUPTS))
455
456
@@ -XXX,XX +XXX,XX @@ static const target_ulong vs_delegable_excps = DELEGABLE_EXCPS &
457
static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
458
SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
459
SSTATUS_SUM | SSTATUS_MXR | SSTATUS_VS;
460
-static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
461
+static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP |
462
+ SIP_LCOFIP;
463
static const target_ulong hip_writable_mask = MIP_VSSIP;
464
static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
465
static const target_ulong vsip_writable_mask = MIP_VSSIP;
466
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
467
[CSR_MHPMEVENT31] = { "mhpmevent31", any, read_mhpmevent,
468
write_mhpmevent },
469
470
+ [CSR_MHPMEVENT3H] = { "mhpmevent3h", sscofpmf, read_mhpmeventh,
471
+ write_mhpmeventh },
472
+ [CSR_MHPMEVENT4H] = { "mhpmevent4h", sscofpmf, read_mhpmeventh,
473
+ write_mhpmeventh },
474
+ [CSR_MHPMEVENT5H] = { "mhpmevent5h", sscofpmf, read_mhpmeventh,
475
+ write_mhpmeventh },
476
+ [CSR_MHPMEVENT6H] = { "mhpmevent6h", sscofpmf, read_mhpmeventh,
477
+ write_mhpmeventh },
478
+ [CSR_MHPMEVENT7H] = { "mhpmevent7h", sscofpmf, read_mhpmeventh,
479
+ write_mhpmeventh },
480
+ [CSR_MHPMEVENT8H] = { "mhpmevent8h", sscofpmf, read_mhpmeventh,
481
+ write_mhpmeventh },
482
+ [CSR_MHPMEVENT9H] = { "mhpmevent9h", sscofpmf, read_mhpmeventh,
483
+ write_mhpmeventh },
484
+ [CSR_MHPMEVENT10H] = { "mhpmevent10h", sscofpmf, read_mhpmeventh,
485
+ write_mhpmeventh },
486
+ [CSR_MHPMEVENT11H] = { "mhpmevent11h", sscofpmf, read_mhpmeventh,
487
+ write_mhpmeventh },
488
+ [CSR_MHPMEVENT12H] = { "mhpmevent12h", sscofpmf, read_mhpmeventh,
489
+ write_mhpmeventh },
490
+ [CSR_MHPMEVENT13H] = { "mhpmevent13h", sscofpmf, read_mhpmeventh,
491
+ write_mhpmeventh },
492
+ [CSR_MHPMEVENT14H] = { "mhpmevent14h", sscofpmf, read_mhpmeventh,
493
+ write_mhpmeventh },
494
+ [CSR_MHPMEVENT15H] = { "mhpmevent15h", sscofpmf, read_mhpmeventh,
495
+ write_mhpmeventh },
496
+ [CSR_MHPMEVENT16H] = { "mhpmevent16h", sscofpmf, read_mhpmeventh,
497
+ write_mhpmeventh },
498
+ [CSR_MHPMEVENT17H] = { "mhpmevent17h", sscofpmf, read_mhpmeventh,
499
+ write_mhpmeventh },
500
+ [CSR_MHPMEVENT18H] = { "mhpmevent18h", sscofpmf, read_mhpmeventh,
501
+ write_mhpmeventh },
502
+ [CSR_MHPMEVENT19H] = { "mhpmevent19h", sscofpmf, read_mhpmeventh,
503
+ write_mhpmeventh },
504
+ [CSR_MHPMEVENT20H] = { "mhpmevent20h", sscofpmf, read_mhpmeventh,
505
+ write_mhpmeventh },
506
+ [CSR_MHPMEVENT21H] = { "mhpmevent21h", sscofpmf, read_mhpmeventh,
507
+ write_mhpmeventh },
508
+ [CSR_MHPMEVENT22H] = { "mhpmevent22h", sscofpmf, read_mhpmeventh,
509
+ write_mhpmeventh },
510
+ [CSR_MHPMEVENT23H] = { "mhpmevent23h", sscofpmf, read_mhpmeventh,
511
+ write_mhpmeventh },
512
+ [CSR_MHPMEVENT24H] = { "mhpmevent24h", sscofpmf, read_mhpmeventh,
513
+ write_mhpmeventh },
514
+ [CSR_MHPMEVENT25H] = { "mhpmevent25h", sscofpmf, read_mhpmeventh,
515
+ write_mhpmeventh },
516
+ [CSR_MHPMEVENT26H] = { "mhpmevent26h", sscofpmf, read_mhpmeventh,
517
+ write_mhpmeventh },
518
+ [CSR_MHPMEVENT27H] = { "mhpmevent27h", sscofpmf, read_mhpmeventh,
519
+ write_mhpmeventh },
520
+ [CSR_MHPMEVENT28H] = { "mhpmevent28h", sscofpmf, read_mhpmeventh,
521
+ write_mhpmeventh },
522
+ [CSR_MHPMEVENT29H] = { "mhpmevent29h", sscofpmf, read_mhpmeventh,
523
+ write_mhpmeventh },
524
+ [CSR_MHPMEVENT30H] = { "mhpmevent30h", sscofpmf, read_mhpmeventh,
525
+ write_mhpmeventh },
526
+ [CSR_MHPMEVENT31H] = { "mhpmevent31h", sscofpmf, read_mhpmeventh,
527
+ write_mhpmeventh },
528
+
529
[CSR_HPMCOUNTER3H] = { "hpmcounter3h", ctr32, read_hpmcounterh },
530
[CSR_HPMCOUNTER4H] = { "hpmcounter4h", ctr32, read_hpmcounterh },
531
[CSR_HPMCOUNTER5H] = { "hpmcounter5h", ctr32, read_hpmcounterh },
532
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
533
write_mhpmcounterh },
534
[CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", mctr32, read_hpmcounterh,
535
write_mhpmcounterh },
536
+ [CSR_SCOUNTOVF] = { "scountovf", sscofpmf, read_scountovf },
537
+
538
#endif /* !CONFIG_USER_ONLY */
539
};
540
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
541
index XXXXXXX..XXXXXXX 100644
542
--- a/target/riscv/machine.c
543
+++ b/target/riscv/machine.c
544
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = {
545
VMSTATE_STRUCT_ARRAY(env.pmu_ctrs, RISCVCPU, RV_MAX_MHPMCOUNTERS, 0,
546
vmstate_pmu_ctr_state, PMUCTRState),
547
VMSTATE_UINTTL_ARRAY(env.mhpmevent_val, RISCVCPU, RV_MAX_MHPMEVENTS),
548
+ VMSTATE_UINTTL_ARRAY(env.mhpmeventh_val, RISCVCPU, RV_MAX_MHPMEVENTS),
549
VMSTATE_UINTTL(env.sscratch, RISCVCPU),
550
VMSTATE_UINTTL(env.mscratch, RISCVCPU),
551
VMSTATE_UINT64(env.mfromhost, RISCVCPU),
552
diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
553
index XXXXXXX..XXXXXXX 100644
554
--- a/target/riscv/pmu.c
555
+++ b/target/riscv/pmu.c
556
@@ -XXX,XX +XXX,XX @@
557
#include "qemu/osdep.h"
558
#include "cpu.h"
559
#include "pmu.h"
560
+#include "sysemu/cpu-timers.h"
561
+
562
+#define RISCV_TIMEBASE_FREQ 1000000000 /* 1Ghz */
563
+#define MAKE_32BIT_MASK(shift, length) \
564
+ (((uint32_t)(~0UL) >> (32 - (length))) << (shift))
565
+
566
+static bool riscv_pmu_counter_valid(RISCVCPU *cpu, uint32_t ctr_idx)
567
+{
568
+ if (ctr_idx < 3 || ctr_idx >= RV_MAX_MHPMCOUNTERS ||
569
+ !(cpu->pmu_avail_ctrs & BIT(ctr_idx))) {
570
+ return false;
571
+ } else {
572
+ return true;
573
+ }
574
+}
575
+
576
+static bool riscv_pmu_counter_enabled(RISCVCPU *cpu, uint32_t ctr_idx)
577
+{
578
+ CPURISCVState *env = &cpu->env;
579
+
580
+ if (riscv_pmu_counter_valid(cpu, ctr_idx) &&
581
+ !get_field(env->mcountinhibit, BIT(ctr_idx))) {
582
+ return true;
583
+ } else {
584
+ return false;
585
+ }
586
+}
587
+
588
+static int riscv_pmu_incr_ctr_rv32(RISCVCPU *cpu, uint32_t ctr_idx)
589
+{
590
+ CPURISCVState *env = &cpu->env;
591
+ target_ulong max_val = UINT32_MAX;
592
+ PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
593
+ bool virt_on = riscv_cpu_virt_enabled(env);
594
+
595
+ /* Privilege mode filtering */
596
+ if ((env->priv == PRV_M &&
597
+ (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_MINH)) ||
598
+ (env->priv == PRV_S && virt_on &&
599
+ (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_VSINH)) ||
600
+ (env->priv == PRV_U && virt_on &&
601
+ (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_VUINH)) ||
602
+ (env->priv == PRV_S && !virt_on &&
603
+ (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_SINH)) ||
604
+ (env->priv == PRV_U && !virt_on &&
605
+ (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_UINH))) {
606
+ return 0;
607
+ }
608
+
609
+ /* Handle the overflow scenario */
610
+ if (counter->mhpmcounter_val == max_val) {
611
+ if (counter->mhpmcounterh_val == max_val) {
612
+ counter->mhpmcounter_val = 0;
613
+ counter->mhpmcounterh_val = 0;
614
+ /* Generate interrupt only if OF bit is clear */
615
+ if (!(env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_OF)) {
616
+ env->mhpmeventh_val[ctr_idx] |= MHPMEVENTH_BIT_OF;
617
+ riscv_cpu_update_mip(cpu, MIP_LCOFIP, BOOL_TO_MASK(1));
618
+ }
619
+ } else {
620
+ counter->mhpmcounterh_val++;
621
+ }
622
+ } else {
623
+ counter->mhpmcounter_val++;
624
+ }
625
+
626
+ return 0;
627
+}
628
+
629
+static int riscv_pmu_incr_ctr_rv64(RISCVCPU *cpu, uint32_t ctr_idx)
630
+{
631
+ CPURISCVState *env = &cpu->env;
632
+ PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
633
+ uint64_t max_val = UINT64_MAX;
634
+ bool virt_on = riscv_cpu_virt_enabled(env);
635
+
636
+ /* Privilege mode filtering */
637
+ if ((env->priv == PRV_M &&
638
+ (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_MINH)) ||
639
+ (env->priv == PRV_S && virt_on &&
640
+ (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_VSINH)) ||
641
+ (env->priv == PRV_U && virt_on &&
642
+ (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_VUINH)) ||
643
+ (env->priv == PRV_S && !virt_on &&
644
+ (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_SINH)) ||
645
+ (env->priv == PRV_U && !virt_on &&
646
+ (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_UINH))) {
647
+ return 0;
648
+ }
649
+
650
+ /* Handle the overflow scenario */
651
+ if (counter->mhpmcounter_val == max_val) {
652
+ counter->mhpmcounter_val = 0;
653
+ /* Generate interrupt only if OF bit is clear */
654
+ if (!(env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_OF)) {
655
+ env->mhpmevent_val[ctr_idx] |= MHPMEVENT_BIT_OF;
656
+ riscv_cpu_update_mip(cpu, MIP_LCOFIP, BOOL_TO_MASK(1));
657
+ }
658
+ } else {
659
+ counter->mhpmcounter_val++;
660
+ }
661
+ return 0;
662
+}
663
+
664
+int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum riscv_pmu_event_idx event_idx)
665
+{
666
+ uint32_t ctr_idx;
667
+ int ret;
668
+ CPURISCVState *env = &cpu->env;
669
+ gpointer value;
670
+
671
+ if (!cpu->cfg.pmu_num) {
672
+ return 0;
673
+ }
674
+ value = g_hash_table_lookup(cpu->pmu_event_ctr_map,
675
+ GUINT_TO_POINTER(event_idx));
676
+ if (!value) {
677
+ return -1;
678
+ }
679
+
680
+ ctr_idx = GPOINTER_TO_UINT(value);
681
+ if (!riscv_pmu_counter_enabled(cpu, ctr_idx) ||
682
+ get_field(env->mcountinhibit, BIT(ctr_idx))) {
683
+ return -1;
684
+ }
685
+
686
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
687
+ ret = riscv_pmu_incr_ctr_rv32(cpu, ctr_idx);
688
+ } else {
689
+ ret = riscv_pmu_incr_ctr_rv64(cpu, ctr_idx);
690
+ }
691
+
692
+ return ret;
693
+}
694
695
bool riscv_pmu_ctr_monitor_instructions(CPURISCVState *env,
696
uint32_t target_ctr)
697
{
698
- return (target_ctr == 0) ? true : false;
699
+ RISCVCPU *cpu;
700
+ uint32_t event_idx;
701
+ uint32_t ctr_idx;
702
+
703
+ /* Fixed instret counter */
704
+ if (target_ctr == 2) {
705
+ return true;
706
+ }
707
+
708
+ cpu = RISCV_CPU(env_cpu(env));
709
+ if (!cpu->pmu_event_ctr_map) {
710
+ return false;
711
+ }
712
+
713
+ event_idx = RISCV_PMU_EVENT_HW_INSTRUCTIONS;
714
+ ctr_idx = GPOINTER_TO_UINT(g_hash_table_lookup(cpu->pmu_event_ctr_map,
715
+ GUINT_TO_POINTER(event_idx)));
716
+ if (!ctr_idx) {
717
+ return false;
718
+ }
719
+
720
+ return target_ctr == ctr_idx ? true : false;
721
}
722
723
bool riscv_pmu_ctr_monitor_cycles(CPURISCVState *env, uint32_t target_ctr)
724
{
725
- return (target_ctr == 2) ? true : false;
726
+ RISCVCPU *cpu;
727
+ uint32_t event_idx;
728
+ uint32_t ctr_idx;
729
+
730
+ /* Fixed mcycle counter */
731
+ if (target_ctr == 0) {
732
+ return true;
733
+ }
734
+
735
+ cpu = RISCV_CPU(env_cpu(env));
736
+ if (!cpu->pmu_event_ctr_map) {
737
+ return false;
738
+ }
739
+
740
+ event_idx = RISCV_PMU_EVENT_HW_CPU_CYCLES;
741
+ ctr_idx = GPOINTER_TO_UINT(g_hash_table_lookup(cpu->pmu_event_ctr_map,
742
+ GUINT_TO_POINTER(event_idx)));
743
+
744
+ /* Counter zero is not used for event_ctr_map */
745
+ if (!ctr_idx) {
746
+ return false;
747
+ }
748
+
749
+ return (target_ctr == ctr_idx) ? true : false;
750
+}
751
+
752
+static gboolean pmu_remove_event_map(gpointer key, gpointer value,
753
+ gpointer udata)
754
+{
755
+ return (GPOINTER_TO_UINT(value) == GPOINTER_TO_UINT(udata)) ? true : false;
756
+}
757
+
758
+static int64_t pmu_icount_ticks_to_ns(int64_t value)
759
+{
760
+ int64_t ret = 0;
761
+
762
+ if (icount_enabled()) {
763
+ ret = icount_to_ns(value);
764
+ } else {
765
+ ret = (NANOSECONDS_PER_SECOND / RISCV_TIMEBASE_FREQ) * value;
766
+ }
767
+
768
+ return ret;
769
+}
770
+
771
+int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value,
772
+ uint32_t ctr_idx)
773
+{
774
+ uint32_t event_idx;
775
+ RISCVCPU *cpu = RISCV_CPU(env_cpu(env));
776
+
777
+ if (!riscv_pmu_counter_valid(cpu, ctr_idx) || !cpu->pmu_event_ctr_map) {
778
+ return -1;
779
+ }
780
+
781
+ /*
782
+ * Expected mhpmevent value is zero for reset case. Remove the current
783
+ * mapping.
784
+ */
785
+ if (!value) {
786
+ g_hash_table_foreach_remove(cpu->pmu_event_ctr_map,
787
+ pmu_remove_event_map,
788
+ GUINT_TO_POINTER(ctr_idx));
789
+ return 0;
790
+ }
791
+
792
+ event_idx = value & MHPMEVENT_IDX_MASK;
793
+ if (g_hash_table_lookup(cpu->pmu_event_ctr_map,
794
+ GUINT_TO_POINTER(event_idx))) {
795
+ return 0;
796
+ }
797
+
798
+ switch (event_idx) {
799
+ case RISCV_PMU_EVENT_HW_CPU_CYCLES:
800
+ case RISCV_PMU_EVENT_HW_INSTRUCTIONS:
801
+ case RISCV_PMU_EVENT_CACHE_DTLB_READ_MISS:
802
+ case RISCV_PMU_EVENT_CACHE_DTLB_WRITE_MISS:
803
+ case RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS:
804
+ break;
805
+ default:
806
+ /* We don't support any raw events right now */
807
+ return -1;
808
+ }
809
+ g_hash_table_insert(cpu->pmu_event_ctr_map, GUINT_TO_POINTER(event_idx),
810
+ GUINT_TO_POINTER(ctr_idx));
811
+
812
+ return 0;
813
+}
814
+
815
+static void pmu_timer_trigger_irq(RISCVCPU *cpu,
816
+ enum riscv_pmu_event_idx evt_idx)
817
+{
818
+ uint32_t ctr_idx;
819
+ CPURISCVState *env = &cpu->env;
820
+ PMUCTRState *counter;
821
+ target_ulong *mhpmevent_val;
822
+ uint64_t of_bit_mask;
823
+ int64_t irq_trigger_at;
824
+
825
+ if (evt_idx != RISCV_PMU_EVENT_HW_CPU_CYCLES &&
826
+ evt_idx != RISCV_PMU_EVENT_HW_INSTRUCTIONS) {
827
+ return;
828
+ }
829
+
830
+ ctr_idx = GPOINTER_TO_UINT(g_hash_table_lookup(cpu->pmu_event_ctr_map,
831
+ GUINT_TO_POINTER(evt_idx)));
832
+ if (!riscv_pmu_counter_enabled(cpu, ctr_idx)) {
833
+ return;
834
+ }
835
+
836
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
837
+ mhpmevent_val = &env->mhpmeventh_val[ctr_idx];
838
+ of_bit_mask = MHPMEVENTH_BIT_OF;
839
+ } else {
840
+ mhpmevent_val = &env->mhpmevent_val[ctr_idx];
841
+ of_bit_mask = MHPMEVENT_BIT_OF;
842
+ }
843
+
844
+ counter = &env->pmu_ctrs[ctr_idx];
845
+ if (counter->irq_overflow_left > 0) {
846
+ irq_trigger_at = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
847
+ counter->irq_overflow_left;
848
+ timer_mod_anticipate_ns(cpu->pmu_timer, irq_trigger_at);
849
+ counter->irq_overflow_left = 0;
850
+ return;
851
+ }
852
+
853
+ if (cpu->pmu_avail_ctrs & BIT(ctr_idx)) {
854
+ /* Generate interrupt only if OF bit is clear */
855
+ if (!(*mhpmevent_val & of_bit_mask)) {
856
+ *mhpmevent_val |= of_bit_mask;
857
+ riscv_cpu_update_mip(cpu, MIP_LCOFIP, BOOL_TO_MASK(1));
858
+ }
859
+ }
860
+}
861
+
862
+/* Timer callback for instret and cycle counter overflow */
863
+void riscv_pmu_timer_cb(void *priv)
864
+{
865
+ RISCVCPU *cpu = priv;
866
+
867
+ /* Timer event was triggered only for these events */
868
+ pmu_timer_trigger_irq(cpu, RISCV_PMU_EVENT_HW_CPU_CYCLES);
869
+ pmu_timer_trigger_irq(cpu, RISCV_PMU_EVENT_HW_INSTRUCTIONS);
870
+}
871
+
872
+int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t value, uint32_t ctr_idx)
873
+{
874
+ uint64_t overflow_delta, overflow_at;
875
+ int64_t overflow_ns, overflow_left = 0;
876
+ RISCVCPU *cpu = RISCV_CPU(env_cpu(env));
877
+ PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
878
+
879
+ if (!riscv_pmu_counter_valid(cpu, ctr_idx) || !cpu->cfg.ext_sscofpmf) {
880
+ return -1;
881
+ }
882
+
883
+ if (value) {
884
+ overflow_delta = UINT64_MAX - value + 1;
885
+ } else {
886
+ overflow_delta = UINT64_MAX;
887
+ }
888
+
889
+ /*
890
+ * QEMU supports only int64_t timers while RISC-V counters are uint64_t.
891
+ * Compute the leftover and save it so that it can be reprogrammed again
892
+ * when timer expires.
893
+ */
894
+ if (overflow_delta > INT64_MAX) {
895
+ overflow_left = overflow_delta - INT64_MAX;
896
+ }
897
+
898
+ if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
899
+ riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
900
+ overflow_ns = pmu_icount_ticks_to_ns((int64_t)overflow_delta);
901
+ overflow_left = pmu_icount_ticks_to_ns(overflow_left) ;
902
+ } else {
903
+ return -1;
904
+ }
905
+ overflow_at = (uint64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + overflow_ns;
906
+
907
+ if (overflow_at > INT64_MAX) {
908
+ overflow_left += overflow_at - INT64_MAX;
909
+ counter->irq_overflow_left = overflow_left;
910
+ overflow_at = INT64_MAX;
911
+ }
912
+ timer_mod_anticipate_ns(cpu->pmu_timer, overflow_at);
913
+
914
+ return 0;
915
+}
916
+
917
+
918
+int riscv_pmu_init(RISCVCPU *cpu, int num_counters)
919
+{
920
+ if (num_counters > (RV_MAX_MHPMCOUNTERS - 3)) {
921
+ return -1;
922
+ }
923
+
924
+ cpu->pmu_event_ctr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
925
+ if (!cpu->pmu_event_ctr_map) {
926
+ /* PMU support can not be enabled */
927
+ qemu_log_mask(LOG_UNIMP, "PMU events can't be supported\n");
928
+ cpu->cfg.pmu_num = 0;
929
+ return -1;
930
+ }
931
+
932
+ /* Create a bitmask of available programmable counters */
933
+ cpu->pmu_avail_ctrs = MAKE_32BIT_MASK(3, num_counters);
934
+
935
+ return 0;
936
}
937
--
938
2.37.2
diff view generated by jsdifflib
New patch
1
From: Atish Patra <atishp@rivosinc.com>
1
2
3
All the hpmcounters and the fixed counters (CY, IR, TM) can be represented
4
as a unified counter. Thus, the predicate function doesn't need handle each
5
case separately.
6
7
Simplify the predicate function so that we just handle things differently
8
between RV32/RV64 and S/HS mode.
9
10
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
11
Acked-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Atish Patra <atishp@rivosinc.com>
13
Message-Id: <20220824221701.41932-3-atishp@rivosinc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
target/riscv/csr.c | 110 ++++-----------------------------------------
17
1 file changed, 9 insertions(+), 101 deletions(-)
18
19
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/csr.c
22
+++ b/target/riscv/csr.c
23
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
24
CPUState *cs = env_cpu(env);
25
RISCVCPU *cpu = RISCV_CPU(cs);
26
int ctr_index;
27
+ target_ulong ctr_mask;
28
int base_csrno = CSR_CYCLE;
29
bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
30
31
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
32
base_csrno += 0x80;
33
}
34
ctr_index = csrno - base_csrno;
35
+ ctr_mask = BIT(ctr_index);
36
37
if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) ||
38
(csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) {
39
goto skip_ext_pmu_check;
40
}
41
42
- if ((!cpu->cfg.pmu_num || !(cpu->pmu_avail_ctrs & BIT(ctr_index)))) {
43
+ if (!(cpu->pmu_avail_ctrs & ctr_mask)) {
44
/* No counter is enabled in PMU or the counter is out of range */
45
return RISCV_EXCP_ILLEGAL_INST;
46
}
47
48
skip_ext_pmu_check:
49
50
- if (env->priv == PRV_S) {
51
- switch (csrno) {
52
- case CSR_CYCLE:
53
- if (!get_field(env->mcounteren, COUNTEREN_CY)) {
54
- return RISCV_EXCP_ILLEGAL_INST;
55
- }
56
- break;
57
- case CSR_TIME:
58
- if (!get_field(env->mcounteren, COUNTEREN_TM)) {
59
- return RISCV_EXCP_ILLEGAL_INST;
60
- }
61
- break;
62
- case CSR_INSTRET:
63
- if (!get_field(env->mcounteren, COUNTEREN_IR)) {
64
- return RISCV_EXCP_ILLEGAL_INST;
65
- }
66
- break;
67
- case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
68
- if (!get_field(env->mcounteren, 1 << ctr_index)) {
69
- return RISCV_EXCP_ILLEGAL_INST;
70
- }
71
- break;
72
- }
73
- if (rv32) {
74
- switch (csrno) {
75
- case CSR_CYCLEH:
76
- if (!get_field(env->mcounteren, COUNTEREN_CY)) {
77
- return RISCV_EXCP_ILLEGAL_INST;
78
- }
79
- break;
80
- case CSR_TIMEH:
81
- if (!get_field(env->mcounteren, COUNTEREN_TM)) {
82
- return RISCV_EXCP_ILLEGAL_INST;
83
- }
84
- break;
85
- case CSR_INSTRETH:
86
- if (!get_field(env->mcounteren, COUNTEREN_IR)) {
87
- return RISCV_EXCP_ILLEGAL_INST;
88
- }
89
- break;
90
- case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
91
- if (!get_field(env->mcounteren, 1 << ctr_index)) {
92
- return RISCV_EXCP_ILLEGAL_INST;
93
- }
94
- break;
95
- }
96
- }
97
+ if (((env->priv == PRV_S) && (!get_field(env->mcounteren, ctr_mask))) ||
98
+ ((env->priv == PRV_U) && (!get_field(env->scounteren, ctr_mask)))) {
99
+ return RISCV_EXCP_ILLEGAL_INST;
100
}
101
102
if (riscv_cpu_virt_enabled(env)) {
103
- switch (csrno) {
104
- case CSR_CYCLE:
105
- if (!get_field(env->hcounteren, COUNTEREN_CY) &&
106
- get_field(env->mcounteren, COUNTEREN_CY)) {
107
- return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
108
- }
109
- break;
110
- case CSR_TIME:
111
- if (!get_field(env->hcounteren, COUNTEREN_TM) &&
112
- get_field(env->mcounteren, COUNTEREN_TM)) {
113
- return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
114
- }
115
- break;
116
- case CSR_INSTRET:
117
- if (!get_field(env->hcounteren, COUNTEREN_IR) &&
118
- get_field(env->mcounteren, COUNTEREN_IR)) {
119
- return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
120
- }
121
- break;
122
- case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
123
- if (!get_field(env->hcounteren, 1 << ctr_index) &&
124
- get_field(env->mcounteren, 1 << ctr_index)) {
125
- return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
126
- }
127
- break;
128
- }
129
- if (rv32) {
130
- switch (csrno) {
131
- case CSR_CYCLEH:
132
- if (!get_field(env->hcounteren, COUNTEREN_CY) &&
133
- get_field(env->mcounteren, COUNTEREN_CY)) {
134
- return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
135
- }
136
- break;
137
- case CSR_TIMEH:
138
- if (!get_field(env->hcounteren, COUNTEREN_TM) &&
139
- get_field(env->mcounteren, COUNTEREN_TM)) {
140
- return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
141
- }
142
- break;
143
- case CSR_INSTRETH:
144
- if (!get_field(env->hcounteren, COUNTEREN_IR) &&
145
- get_field(env->mcounteren, COUNTEREN_IR)) {
146
- return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
147
- }
148
- break;
149
- case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
150
- if (!get_field(env->hcounteren, 1 << ctr_index) &&
151
- get_field(env->mcounteren, 1 << ctr_index)) {
152
- return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
153
- }
154
- break;
155
- }
156
+ if (!get_field(env->hcounteren, ctr_mask) &&
157
+ get_field(env->mcounteren, ctr_mask)) {
158
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
159
}
160
}
161
#endif
162
--
163
2.37.2
diff view generated by jsdifflib
New patch
1
From: Atish Patra <atish.patra@wdc.com>
1
2
3
Qemu can monitor the following cache related PMU events through
4
tlb_fill functions.
5
6
1. DTLB load/store miss
7
3. ITLB prefetch miss
8
9
Increment the PMU counter in tlb_fill function.
10
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Tested-by: Heiko Stuebner <heiko@sntech.de>
13
Signed-off-by: Atish Patra <atish.patra@wdc.com>
14
Signed-off-by: Atish Patra <atishp@rivosinc.com>
15
Message-Id: <20220824221701.41932-4-atishp@rivosinc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
18
target/riscv/cpu_helper.c | 25 +++++++++++++++++++++++++
19
1 file changed, 25 insertions(+)
20
21
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/cpu_helper.c
24
+++ b/target/riscv/cpu_helper.c
25
@@ -XXX,XX +XXX,XX @@
26
#include "qemu/log.h"
27
#include "qemu/main-loop.h"
28
#include "cpu.h"
29
+#include "pmu.h"
30
#include "exec/exec-all.h"
31
#include "instmap.h"
32
#include "tcg/tcg-op.h"
33
#include "trace.h"
34
#include "semihosting/common-semi.h"
35
+#include "cpu_bits.h"
36
37
int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
38
{
39
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
40
cpu_loop_exit_restore(cs, retaddr);
41
}
42
43
+
44
+static void pmu_tlb_fill_incr_ctr(RISCVCPU *cpu, MMUAccessType access_type)
45
+{
46
+ enum riscv_pmu_event_idx pmu_event_type;
47
+
48
+ switch (access_type) {
49
+ case MMU_INST_FETCH:
50
+ pmu_event_type = RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS;
51
+ break;
52
+ case MMU_DATA_LOAD:
53
+ pmu_event_type = RISCV_PMU_EVENT_CACHE_DTLB_READ_MISS;
54
+ break;
55
+ case MMU_DATA_STORE:
56
+ pmu_event_type = RISCV_PMU_EVENT_CACHE_DTLB_WRITE_MISS;
57
+ break;
58
+ default:
59
+ return;
60
+ }
61
+
62
+ riscv_pmu_incr_ctr(cpu, pmu_event_type);
63
+}
64
+
65
bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
66
MMUAccessType access_type, int mmu_idx,
67
bool probe, uintptr_t retaddr)
68
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
69
}
70
}
71
} else {
72
+ pmu_tlb_fill_incr_ctr(cpu, access_type);
73
/* Single stage lookup */
74
ret = get_physical_address(env, &pa, &prot, address, NULL,
75
access_type, mmu_idx, true, false, false);
76
--
77
2.37.2
diff view generated by jsdifflib
New patch
1
From: Atish Patra <atishp@rivosinc.com>
1
2
3
Qemu virt machine can support few cache events and cycle/instret counters.
4
It also supports counter overflow for these events.
5
6
Add a DT node so that OpenSBI/Linux kernel is aware of the virt machine
7
capabilities. There are some dummy nodes added for testing as well.
8
9
Acked-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Atish Patra <atish.patra@wdc.com>
11
Signed-off-by: Atish Patra <atishp@rivosinc.com>
12
Message-Id: <20220824221701.41932-5-atishp@rivosinc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
target/riscv/pmu.h | 1 +
16
hw/riscv/virt.c | 16 +++++++++++++
17
target/riscv/pmu.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++
18
3 files changed, 74 insertions(+)
19
20
diff --git a/target/riscv/pmu.h b/target/riscv/pmu.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/pmu.h
23
+++ b/target/riscv/pmu.h
24
@@ -XXX,XX +XXX,XX @@ int riscv_pmu_init(RISCVCPU *cpu, int num_counters);
25
int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value,
26
uint32_t ctr_idx);
27
int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum riscv_pmu_event_idx event_idx);
28
+void riscv_pmu_generate_fdt_node(void *fdt, int num_counters, char *pmu_name);
29
int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t value,
30
uint32_t ctr_idx);
31
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/riscv/virt.c
34
+++ b/hw/riscv/virt.c
35
@@ -XXX,XX +XXX,XX @@
36
#include "hw/char/serial.h"
37
#include "target/riscv/cpu.h"
38
#include "hw/core/sysbus-fdt.h"
39
+#include "target/riscv/pmu.h"
40
#include "hw/riscv/riscv_hart.h"
41
#include "hw/riscv/virt.h"
42
#include "hw/riscv/boot.h"
43
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
44
aplic_phandles[socket] = aplic_s_phandle;
45
}
46
47
+static void create_fdt_pmu(RISCVVirtState *s)
48
+{
49
+ char *pmu_name;
50
+ MachineState *mc = MACHINE(s);
51
+ RISCVCPU hart = s->soc[0].harts[0];
52
+
53
+ pmu_name = g_strdup_printf("/soc/pmu");
54
+ qemu_fdt_add_subnode(mc->fdt, pmu_name);
55
+ qemu_fdt_setprop_string(mc->fdt, pmu_name, "compatible", "riscv,pmu");
56
+ riscv_pmu_generate_fdt_node(mc->fdt, hart.cfg.pmu_num, pmu_name);
57
+
58
+ g_free(pmu_name);
59
+}
60
+
61
static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
62
bool is_32_bit, uint32_t *phandle,
63
uint32_t *irq_mmio_phandle,
64
@@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap,
65
66
create_fdt_flash(s, memmap);
67
create_fdt_fw_cfg(s, memmap);
68
+ create_fdt_pmu(s);
69
70
update_bootargs:
71
if (cmdline && *cmdline) {
72
diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/riscv/pmu.c
75
+++ b/target/riscv/pmu.c
76
@@ -XXX,XX +XXX,XX @@
77
#include "cpu.h"
78
#include "pmu.h"
79
#include "sysemu/cpu-timers.h"
80
+#include "sysemu/device_tree.h"
81
82
#define RISCV_TIMEBASE_FREQ 1000000000 /* 1Ghz */
83
#define MAKE_32BIT_MASK(shift, length) \
84
(((uint32_t)(~0UL) >> (32 - (length))) << (shift))
85
86
+/*
87
+ * To keep it simple, any event can be mapped to any programmable counters in
88
+ * QEMU. The generic cycle & instruction count events can also be monitored
89
+ * using programmable counters. In that case, mcycle & minstret must continue
90
+ * to provide the correct value as well. Heterogeneous PMU per hart is not
91
+ * supported yet. Thus, number of counters are same across all harts.
92
+ */
93
+void riscv_pmu_generate_fdt_node(void *fdt, int num_ctrs, char *pmu_name)
94
+{
95
+ uint32_t fdt_event_ctr_map[20] = {};
96
+ uint32_t cmask;
97
+
98
+ /* All the programmable counters can map to any event */
99
+ cmask = MAKE_32BIT_MASK(3, num_ctrs);
100
+
101
+ /*
102
+ * The event encoding is specified in the SBI specification
103
+ * Event idx is a 20bits wide number encoded as follows:
104
+ * event_idx[19:16] = type
105
+ * event_idx[15:0] = code
106
+ * The code field in cache events are encoded as follows:
107
+ * event_idx.code[15:3] = cache_id
108
+ * event_idx.code[2:1] = op_id
109
+ * event_idx.code[0:0] = result_id
110
+ */
111
+
112
+ /* SBI_PMU_HW_CPU_CYCLES: 0x01 : type(0x00) */
113
+ fdt_event_ctr_map[0] = cpu_to_be32(0x00000001);
114
+ fdt_event_ctr_map[1] = cpu_to_be32(0x00000001);
115
+ fdt_event_ctr_map[2] = cpu_to_be32(cmask | 1 << 0);
116
+
117
+ /* SBI_PMU_HW_INSTRUCTIONS: 0x02 : type(0x00) */
118
+ fdt_event_ctr_map[3] = cpu_to_be32(0x00000002);
119
+ fdt_event_ctr_map[4] = cpu_to_be32(0x00000002);
120
+ fdt_event_ctr_map[5] = cpu_to_be32(cmask | 1 << 2);
121
+
122
+ /* SBI_PMU_HW_CACHE_DTLB : 0x03 READ : 0x00 MISS : 0x00 type(0x01) */
123
+ fdt_event_ctr_map[6] = cpu_to_be32(0x00010019);
124
+ fdt_event_ctr_map[7] = cpu_to_be32(0x00010019);
125
+ fdt_event_ctr_map[8] = cpu_to_be32(cmask);
126
+
127
+ /* SBI_PMU_HW_CACHE_DTLB : 0x03 WRITE : 0x01 MISS : 0x00 type(0x01) */
128
+ fdt_event_ctr_map[9] = cpu_to_be32(0x0001001B);
129
+ fdt_event_ctr_map[10] = cpu_to_be32(0x0001001B);
130
+ fdt_event_ctr_map[11] = cpu_to_be32(cmask);
131
+
132
+ /* SBI_PMU_HW_CACHE_ITLB : 0x04 READ : 0x00 MISS : 0x00 type(0x01) */
133
+ fdt_event_ctr_map[12] = cpu_to_be32(0x00010021);
134
+ fdt_event_ctr_map[13] = cpu_to_be32(0x00010021);
135
+ fdt_event_ctr_map[14] = cpu_to_be32(cmask);
136
+
137
+ /* This a OpenSBI specific DT property documented in OpenSBI docs */
138
+ qemu_fdt_setprop(fdt, pmu_name, "riscv,event-to-mhpmcounters",
139
+ fdt_event_ctr_map, sizeof(fdt_event_ctr_map));
140
+}
141
+
142
static bool riscv_pmu_counter_valid(RISCVCPU *cpu, uint32_t ctr_idx)
143
{
144
if (ctr_idx < 3 || ctr_idx >= RV_MAX_MHPMCOUNTERS ||
145
--
146
2.37.2
diff view generated by jsdifflib
New patch
1
From: Atish Patra <atishp@rivosinc.com>
1
2
3
The sscofpmf extension was ratified as a part of priv spec v1.12.
4
Mark the csr_ops accordingly.
5
6
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Atish Patra <atishp@rivosinc.com>
9
Message-Id: <20220824221701.41932-6-atishp@rivosinc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/csr.c | 90 ++++++++++++++++++++++++++++++----------------
13
1 file changed, 60 insertions(+), 30 deletions(-)
14
15
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/csr.c
18
+++ b/target/riscv/csr.c
19
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
20
write_mhpmevent },
21
22
[CSR_MHPMEVENT3H] = { "mhpmevent3h", sscofpmf, read_mhpmeventh,
23
- write_mhpmeventh },
24
+ write_mhpmeventh,
25
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
26
[CSR_MHPMEVENT4H] = { "mhpmevent4h", sscofpmf, read_mhpmeventh,
27
- write_mhpmeventh },
28
+ write_mhpmeventh,
29
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
30
[CSR_MHPMEVENT5H] = { "mhpmevent5h", sscofpmf, read_mhpmeventh,
31
- write_mhpmeventh },
32
+ write_mhpmeventh,
33
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
34
[CSR_MHPMEVENT6H] = { "mhpmevent6h", sscofpmf, read_mhpmeventh,
35
- write_mhpmeventh },
36
+ write_mhpmeventh,
37
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
38
[CSR_MHPMEVENT7H] = { "mhpmevent7h", sscofpmf, read_mhpmeventh,
39
- write_mhpmeventh },
40
+ write_mhpmeventh,
41
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
42
[CSR_MHPMEVENT8H] = { "mhpmevent8h", sscofpmf, read_mhpmeventh,
43
- write_mhpmeventh },
44
+ write_mhpmeventh,
45
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
46
[CSR_MHPMEVENT9H] = { "mhpmevent9h", sscofpmf, read_mhpmeventh,
47
- write_mhpmeventh },
48
+ write_mhpmeventh,
49
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
50
[CSR_MHPMEVENT10H] = { "mhpmevent10h", sscofpmf, read_mhpmeventh,
51
- write_mhpmeventh },
52
+ write_mhpmeventh,
53
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
54
[CSR_MHPMEVENT11H] = { "mhpmevent11h", sscofpmf, read_mhpmeventh,
55
- write_mhpmeventh },
56
+ write_mhpmeventh,
57
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
58
[CSR_MHPMEVENT12H] = { "mhpmevent12h", sscofpmf, read_mhpmeventh,
59
- write_mhpmeventh },
60
+ write_mhpmeventh,
61
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
62
[CSR_MHPMEVENT13H] = { "mhpmevent13h", sscofpmf, read_mhpmeventh,
63
- write_mhpmeventh },
64
+ write_mhpmeventh,
65
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
66
[CSR_MHPMEVENT14H] = { "mhpmevent14h", sscofpmf, read_mhpmeventh,
67
- write_mhpmeventh },
68
+ write_mhpmeventh,
69
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
70
[CSR_MHPMEVENT15H] = { "mhpmevent15h", sscofpmf, read_mhpmeventh,
71
- write_mhpmeventh },
72
+ write_mhpmeventh,
73
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
74
[CSR_MHPMEVENT16H] = { "mhpmevent16h", sscofpmf, read_mhpmeventh,
75
- write_mhpmeventh },
76
+ write_mhpmeventh,
77
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
78
[CSR_MHPMEVENT17H] = { "mhpmevent17h", sscofpmf, read_mhpmeventh,
79
- write_mhpmeventh },
80
+ write_mhpmeventh,
81
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
82
[CSR_MHPMEVENT18H] = { "mhpmevent18h", sscofpmf, read_mhpmeventh,
83
- write_mhpmeventh },
84
+ write_mhpmeventh,
85
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
86
[CSR_MHPMEVENT19H] = { "mhpmevent19h", sscofpmf, read_mhpmeventh,
87
- write_mhpmeventh },
88
+ write_mhpmeventh,
89
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
90
[CSR_MHPMEVENT20H] = { "mhpmevent20h", sscofpmf, read_mhpmeventh,
91
- write_mhpmeventh },
92
+ write_mhpmeventh,
93
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
94
[CSR_MHPMEVENT21H] = { "mhpmevent21h", sscofpmf, read_mhpmeventh,
95
- write_mhpmeventh },
96
+ write_mhpmeventh,
97
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
98
[CSR_MHPMEVENT22H] = { "mhpmevent22h", sscofpmf, read_mhpmeventh,
99
- write_mhpmeventh },
100
+ write_mhpmeventh,
101
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
102
[CSR_MHPMEVENT23H] = { "mhpmevent23h", sscofpmf, read_mhpmeventh,
103
- write_mhpmeventh },
104
+ write_mhpmeventh,
105
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
106
[CSR_MHPMEVENT24H] = { "mhpmevent24h", sscofpmf, read_mhpmeventh,
107
- write_mhpmeventh },
108
+ write_mhpmeventh,
109
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
110
[CSR_MHPMEVENT25H] = { "mhpmevent25h", sscofpmf, read_mhpmeventh,
111
- write_mhpmeventh },
112
+ write_mhpmeventh,
113
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
114
[CSR_MHPMEVENT26H] = { "mhpmevent26h", sscofpmf, read_mhpmeventh,
115
- write_mhpmeventh },
116
+ write_mhpmeventh,
117
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
118
[CSR_MHPMEVENT27H] = { "mhpmevent27h", sscofpmf, read_mhpmeventh,
119
- write_mhpmeventh },
120
+ write_mhpmeventh,
121
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
122
[CSR_MHPMEVENT28H] = { "mhpmevent28h", sscofpmf, read_mhpmeventh,
123
- write_mhpmeventh },
124
+ write_mhpmeventh,
125
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
126
[CSR_MHPMEVENT29H] = { "mhpmevent29h", sscofpmf, read_mhpmeventh,
127
- write_mhpmeventh },
128
+ write_mhpmeventh,
129
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
130
[CSR_MHPMEVENT30H] = { "mhpmevent30h", sscofpmf, read_mhpmeventh,
131
- write_mhpmeventh },
132
+ write_mhpmeventh,
133
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
134
[CSR_MHPMEVENT31H] = { "mhpmevent31h", sscofpmf, read_mhpmeventh,
135
- write_mhpmeventh },
136
+ write_mhpmeventh,
137
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
138
139
[CSR_HPMCOUNTER3H] = { "hpmcounter3h", ctr32, read_hpmcounterh },
140
[CSR_HPMCOUNTER4H] = { "hpmcounter4h", ctr32, read_hpmcounterh },
141
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
142
write_mhpmcounterh },
143
[CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", mctr32, read_hpmcounterh,
144
write_mhpmcounterh },
145
- [CSR_SCOUNTOVF] = { "scountovf", sscofpmf, read_scountovf },
146
+ [CSR_SCOUNTOVF] = { "scountovf", sscofpmf, read_scountovf,
147
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
148
149
#endif /* !CONFIG_USER_ONLY */
150
};
151
--
152
2.37.2
diff view generated by jsdifflib