master
c 3,772 lines 113 KB
Raw
1 /*
2 * QEMU RISC-V CPU
3 *
4 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5 * Copyright (c) 2017-2018 SiFive, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2 or later, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "qemu/osdep.h"
21 #include "qemu/qemu-print.h"
22 #include "qemu/ctype.h"
23 #include "qemu/log.h"
24 #include "qemu/guest-random.h"
25 #include "cpu.h"
26 #include "cpu_vendorid.h"
27 #include "target/riscv/tcg/csr.h"
28 #include "internals.h"
29 #include "qapi/error.h"
30 #include "qapi/visitor.h"
31 #include "qemu/error-report.h"
32 #include "qemu/timer.h"
33 #include "hw/core/qdev-properties.h"
34 #include "hw/core/qdev-prop-internal.h"
35 #include "migration/vmstate.h"
36 #include "fpu/softfloat-helpers.h"
37 #include "system/device_tree.h"
38 #include "system/kvm.h"
39 #include "system/tcg.h"
40 #include "kvm/kvm_riscv.h"
41 #include "tcg/tcg-cpu.h"
42 #include "disas/capstone.h"
43 #if !defined(CONFIG_USER_ONLY)
44 #include "target/riscv/tcg/debug.h"
45 #endif
46
47 /* RISC-V CPU definitions */
48 static const char riscv_single_letter_exts[] = "IEMAFDQCBPVH";
49 const uint32_t misa_bits[] = {RVI, RVE, RVM, RVA, RVF, RVD, RVV,
50 RVC, RVS, RVU, RVH, RVG, RVB, 0};
51 #define RISCV_CPU_MVENDORID 0
52 #define RISCV_CPU_MIMPID 0
53 /*
54 * marchid allocated for qemu:
55 * https://github.com/riscv/riscv-isa-manual/blob/main/marchid.md
56 */
57 #define RISCV_CPU_MARCHID 42
58
59 /*
60 * From vector_helper.c
61 * Note that vector data is stored in host-endian 64-bit chunks,
62 * so addressing bytes needs a host-endian fixup.
63 */
64 #if HOST_BIG_ENDIAN
65 #define BYTE(x) ((x) ^ 7)
66 #else
67 #define BYTE(x) (x)
68 #endif
69
70 /* SATP bits that are shared between TCG and KVM */
71 const bool valid_vm_1_10_32[16] = {
72 [VM_1_10_MBARE] = true,
73 [VM_1_10_SV32] = true
74 };
75
76 const bool valid_vm_1_10_64[16] = {
77 [VM_1_10_MBARE] = true,
78 [VM_1_10_SV39] = true,
79 [VM_1_10_SV48] = true,
80 [VM_1_10_SV57] = true
81 };
82
83 bool riscv_cpu_is_32bit(RISCVCPU *cpu)
84 {
85 return riscv_cpu_mxl(&cpu->env) == MXL_RV32;
86 }
87
88 static void cpu_option_add_user_setting(RISCVCPU *cpu, const char *optname)
89 {
90 g_hash_table_add(cpu->user_options, (gpointer)optname);
91 }
92
93 bool riscv_cpu_option_set(RISCVCPU *cpu, const char *optname)
94 {
95 return g_hash_table_contains(cpu->user_options, optname);
96 }
97
98 #ifndef CONFIG_USER_ONLY
99 /* This is used in runtime only. */
100 void cpu_set_exception_base(int vp_index, uint64_t address)
101 {
102 RISCVCPU *cpu;
103 CPUState *cs = qemu_get_cpu(vp_index);
104 if (cs == NULL) {
105 qemu_log_mask(LOG_GUEST_ERROR,
106 "cpu_set_exception_base: invalid vp_index: %u",
107 vp_index);
108 return;
109 }
110 cpu = RISCV_CPU(cs);
111 cpu->env.resetvec = address;
112 }
113 #endif
114
115 static void riscv_cpu_cfg_merge(RISCVCPUConfig *dest, const RISCVCPUConfig *src)
116 {
117 #define BOOL_FIELD(x) dest->x |= src->x;
118 #define TYPED_FIELD(type, x, default_) if (src->x != default_) dest->x = src->x;
119 #include "cpu_cfg_fields.h.inc"
120 }
121
122 /* Use this for regular user facing extensions */
123 #define ISA_EXT_DATA_ENTRY(_name, _min_ver, _prop) \
124 {#_name, #_name, _min_ver, CPU_CFG_OFFSET(_prop)}
125
126 /*
127 * Same as above but for experimental extensions. We'll add a
128 * "x-" right after "_name" when creating the user property.
129 */
130 #define ISA_EXPERIMENTAL_EXT_DATA_ENTRY(_name, _min_ver, _prop) \
131 {#_name, "x-" #_name, _min_ver, CPU_CFG_OFFSET(_prop)}
132
133 /*
134 * Internal extensions are extensions we will declare in the
135 * riscv,isa DT but they don't have an user property, i.e.
136 * users/management can't enable/disable them.
137 */
138 #define ISA_INTERNAL_EXT_DATA_ENTRY(_name, _min_ver, _prop) \
139 {#_name, NULL, _min_ver, CPU_CFG_OFFSET(_prop)}
140
141 /*
142 * Here are the ordering rules of extension naming defined by RISC-V
143 * specification :
144 * 1. All extensions should be separated from other multi-letter extensions
145 * by an underscore.
146 * 2. The first letter following the 'Z' conventionally indicates the most
147 * closely related alphabetical extension category, IMAFDQLCBKJTPVH.
148 * If multiple 'Z' extensions are named, they should be ordered first
149 * by category, then alphabetically within a category.
150 * 3. Standard supervisor-level extensions (starts with 'S') should be
151 * listed after standard unprivileged extensions. If multiple
152 * supervisor-level extensions are listed, they should be ordered
153 * alphabetically.
154 * 4. Non-standard extensions (starts with 'X') must be listed after all
155 * standard extensions. They must be separated from other multi-letter
156 * extensions by an underscore.
157 *
158 * Single letter extensions are checked in riscv_cpu_validate_misa_priv()
159 * instead.
160 */
161 const RISCVIsaExtData isa_edata_arr[] = {
162 ISA_INTERNAL_EXT_DATA_ENTRY(zic64b, PRIV_VERSION_1_12_0, ext_zic64b),
163 ISA_EXT_DATA_ENTRY(zicbom, PRIV_VERSION_1_12_0, ext_zicbom),
164 ISA_EXT_DATA_ENTRY(zicbop, PRIV_VERSION_1_12_0, ext_zicbop),
165 ISA_EXT_DATA_ENTRY(zicboz, PRIV_VERSION_1_12_0, ext_zicboz),
166 ISA_INTERNAL_EXT_DATA_ENTRY(ziccamoa, PRIV_VERSION_1_11_0, has_priv_1_11),
167 ISA_INTERNAL_EXT_DATA_ENTRY(ziccif, PRIV_VERSION_1_11_0, has_priv_1_11),
168 ISA_EXT_DATA_ENTRY(zicclsm, PRIV_VERSION_1_11_0, ext_zicclsm),
169 ISA_EXT_DATA_ENTRY(ziccrse, PRIV_VERSION_1_11_0, ext_ziccrse),
170 ISA_EXT_DATA_ENTRY(zicfilp, PRIV_VERSION_1_12_0, ext_zicfilp),
171 ISA_EXT_DATA_ENTRY(zicfiss, PRIV_VERSION_1_13_0, ext_zicfiss),
172 ISA_EXT_DATA_ENTRY(zicond, PRIV_VERSION_1_12_0, ext_zicond),
173 ISA_EXT_DATA_ENTRY(zicntr, PRIV_VERSION_1_12_0, ext_zicntr),
174 ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_zicsr),
175 ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_zifencei),
176 ISA_EXT_DATA_ENTRY(zihintntl, PRIV_VERSION_1_10_0, ext_zihintntl),
177 ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
178 ISA_EXT_DATA_ENTRY(zihpm, PRIV_VERSION_1_12_0, ext_zihpm),
179 ISA_EXT_DATA_ENTRY(zilsd, PRIV_VERSION_1_12_0, ext_zilsd),
180 ISA_EXT_DATA_ENTRY(zimop, PRIV_VERSION_1_13_0, ext_zimop),
181 ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
182 ISA_INTERNAL_EXT_DATA_ENTRY(za64rs, PRIV_VERSION_1_12_0, has_priv_1_12),
183 ISA_EXT_DATA_ENTRY(zaamo, PRIV_VERSION_1_12_0, ext_zaamo),
184 ISA_EXT_DATA_ENTRY(zabha, PRIV_VERSION_1_13_0, ext_zabha),
185 ISA_EXT_DATA_ENTRY(zacas, PRIV_VERSION_1_12_0, ext_zacas),
186 ISA_EXT_DATA_ENTRY(zalasr, PRIV_VERSION_1_12_0, ext_zalasr),
187 ISA_EXT_DATA_ENTRY(zalrsc, PRIV_VERSION_1_12_0, ext_zalrsc),
188 ISA_EXT_DATA_ENTRY(zama16b, PRIV_VERSION_1_13_0, ext_zama16b),
189 ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
190 ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
191 ISA_EXT_DATA_ENTRY(zfbfmin, PRIV_VERSION_1_12_0, ext_zfbfmin),
192 ISA_EXT_DATA_ENTRY(zfh, PRIV_VERSION_1_11_0, ext_zfh),
193 ISA_EXT_DATA_ENTRY(zfhmin, PRIV_VERSION_1_11_0, ext_zfhmin),
194 ISA_EXT_DATA_ENTRY(zfinx, PRIV_VERSION_1_12_0, ext_zfinx),
195 ISA_EXT_DATA_ENTRY(zdinx, PRIV_VERSION_1_12_0, ext_zdinx),
196 ISA_EXT_DATA_ENTRY(zca, PRIV_VERSION_1_12_0, ext_zca),
197 ISA_EXT_DATA_ENTRY(zcb, PRIV_VERSION_1_12_0, ext_zcb),
198 ISA_EXT_DATA_ENTRY(zcf, PRIV_VERSION_1_12_0, ext_zcf),
199 ISA_EXT_DATA_ENTRY(zcd, PRIV_VERSION_1_12_0, ext_zcd),
200 ISA_EXT_DATA_ENTRY(zce, PRIV_VERSION_1_12_0, ext_zce),
201 ISA_EXT_DATA_ENTRY(zcmop, PRIV_VERSION_1_13_0, ext_zcmop),
202 ISA_EXT_DATA_ENTRY(zcmp, PRIV_VERSION_1_12_0, ext_zcmp),
203 ISA_EXT_DATA_ENTRY(zcmt, PRIV_VERSION_1_12_0, ext_zcmt),
204 ISA_EXT_DATA_ENTRY(zclsd, PRIV_VERSION_1_12_0, ext_zclsd),
205 ISA_EXT_DATA_ENTRY(zba, PRIV_VERSION_1_12_0, ext_zba),
206 ISA_EXT_DATA_ENTRY(zbb, PRIV_VERSION_1_12_0, ext_zbb),
207 ISA_EXT_DATA_ENTRY(zbc, PRIV_VERSION_1_12_0, ext_zbc),
208 ISA_EXT_DATA_ENTRY(zbkb, PRIV_VERSION_1_12_0, ext_zbkb),
209 ISA_EXT_DATA_ENTRY(zbkc, PRIV_VERSION_1_12_0, ext_zbkc),
210 ISA_EXT_DATA_ENTRY(zbkx, PRIV_VERSION_1_12_0, ext_zbkx),
211 ISA_EXT_DATA_ENTRY(zbs, PRIV_VERSION_1_12_0, ext_zbs),
212 ISA_EXT_DATA_ENTRY(zk, PRIV_VERSION_1_12_0, ext_zk),
213 ISA_EXT_DATA_ENTRY(zkn, PRIV_VERSION_1_12_0, ext_zkn),
214 ISA_EXT_DATA_ENTRY(zknd, PRIV_VERSION_1_12_0, ext_zknd),
215 ISA_EXT_DATA_ENTRY(zkne, PRIV_VERSION_1_12_0, ext_zkne),
216 ISA_EXT_DATA_ENTRY(zknh, PRIV_VERSION_1_12_0, ext_zknh),
217 ISA_EXT_DATA_ENTRY(zkr, PRIV_VERSION_1_12_0, ext_zkr),
218 ISA_EXT_DATA_ENTRY(zks, PRIV_VERSION_1_12_0, ext_zks),
219 ISA_EXT_DATA_ENTRY(zksed, PRIV_VERSION_1_12_0, ext_zksed),
220 ISA_EXT_DATA_ENTRY(zksh, PRIV_VERSION_1_12_0, ext_zksh),
221 ISA_EXT_DATA_ENTRY(zkt, PRIV_VERSION_1_12_0, ext_zkt),
222 ISA_EXT_DATA_ENTRY(ztso, PRIV_VERSION_1_12_0, ext_ztso),
223 ISA_EXT_DATA_ENTRY(zvbb, PRIV_VERSION_1_12_0, ext_zvbb),
224 ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
225 ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
226 ISA_EXT_DATA_ENTRY(zve32x, PRIV_VERSION_1_10_0, ext_zve32x),
227 ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
228 ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
229 ISA_EXT_DATA_ENTRY(zve64x, PRIV_VERSION_1_10_0, ext_zve64x),
230 ISA_EXT_DATA_ENTRY(zvfbfa, PRIV_VERSION_1_13_0, ext_zvfbfa),
231 ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
232 ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
233 ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
234 ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
235 ISA_EXT_DATA_ENTRY(zvkb, PRIV_VERSION_1_12_0, ext_zvkb),
236 ISA_EXT_DATA_ENTRY(zvkg, PRIV_VERSION_1_12_0, ext_zvkg),
237 ISA_EXT_DATA_ENTRY(zvkn, PRIV_VERSION_1_12_0, ext_zvkn),
238 ISA_EXT_DATA_ENTRY(zvknc, PRIV_VERSION_1_12_0, ext_zvknc),
239 ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
240 ISA_EXT_DATA_ENTRY(zvkng, PRIV_VERSION_1_12_0, ext_zvkng),
241 ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
242 ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
243 ISA_EXT_DATA_ENTRY(zvks, PRIV_VERSION_1_12_0, ext_zvks),
244 ISA_EXT_DATA_ENTRY(zvksc, PRIV_VERSION_1_12_0, ext_zvksc),
245 ISA_EXT_DATA_ENTRY(zvksed, PRIV_VERSION_1_12_0, ext_zvksed),
246 ISA_EXT_DATA_ENTRY(zvksg, PRIV_VERSION_1_12_0, ext_zvksg),
247 ISA_EXT_DATA_ENTRY(zvksh, PRIV_VERSION_1_12_0, ext_zvksh),
248 ISA_EXT_DATA_ENTRY(zvkt, PRIV_VERSION_1_12_0, ext_zvkt),
249 ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
250 ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
251 ISA_EXT_DATA_ENTRY(sdtrig, PRIV_VERSION_1_12_0, debug),
252 ISA_INTERNAL_EXT_DATA_ENTRY(shcounterenw, PRIV_VERSION_1_12_0,
253 has_priv_1_12),
254 ISA_INTERNAL_EXT_DATA_ENTRY(sha, PRIV_VERSION_1_12_0, ext_sha),
255 ISA_INTERNAL_EXT_DATA_ENTRY(shgatpa, PRIV_VERSION_1_12_0, has_priv_1_12),
256 ISA_INTERNAL_EXT_DATA_ENTRY(shtvala, PRIV_VERSION_1_12_0, has_priv_1_12),
257 ISA_INTERNAL_EXT_DATA_ENTRY(shvsatpa, PRIV_VERSION_1_12_0, has_priv_1_12),
258 ISA_INTERNAL_EXT_DATA_ENTRY(shvstvala, PRIV_VERSION_1_12_0, has_priv_1_12),
259 ISA_INTERNAL_EXT_DATA_ENTRY(shvstvecd, PRIV_VERSION_1_12_0, has_priv_1_12),
260 ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
261 ISA_EXT_DATA_ENTRY(smcdeleg, PRIV_VERSION_1_13_0, ext_smcdeleg),
262 ISA_EXT_DATA_ENTRY(smcntrpmf, PRIV_VERSION_1_12_0, ext_smcntrpmf),
263 ISA_EXT_DATA_ENTRY(smcsrind, PRIV_VERSION_1_13_0, ext_smcsrind),
264 ISA_EXT_DATA_ENTRY(smctr, PRIV_VERSION_1_12_0, ext_smctr),
265 ISA_EXT_DATA_ENTRY(smdbltrp, PRIV_VERSION_1_13_0, ext_smdbltrp),
266 ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
267 ISA_EXT_DATA_ENTRY(smpmpmt, PRIV_VERSION_1_12_0, ext_smpmpmt),
268 ISA_EXT_DATA_ENTRY(smrnmi, PRIV_VERSION_1_12_0, ext_smrnmi),
269 ISA_EXT_DATA_ENTRY(smmpm, PRIV_VERSION_1_13_0, ext_smmpm),
270 ISA_EXT_DATA_ENTRY(smnpm, PRIV_VERSION_1_13_0, ext_smnpm),
271 ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
272 ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
273 ISA_EXT_DATA_ENTRY(ssccfg, PRIV_VERSION_1_13_0, ext_ssccfg),
274 ISA_INTERNAL_EXT_DATA_ENTRY(ssccptr, PRIV_VERSION_1_11_0, has_priv_1_11),
275 ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
276 ISA_INTERNAL_EXT_DATA_ENTRY(sscounterenw, PRIV_VERSION_1_12_0,
277 has_priv_1_12),
278 ISA_EXT_DATA_ENTRY(sscsrind, PRIV_VERSION_1_12_0, ext_sscsrind),
279 ISA_EXT_DATA_ENTRY(ssctr, PRIV_VERSION_1_12_0, ext_ssctr),
280 ISA_EXT_DATA_ENTRY(ssdbltrp, PRIV_VERSION_1_13_0, ext_ssdbltrp),
281 ISA_EXT_DATA_ENTRY(ssnpm, PRIV_VERSION_1_13_0, ext_ssnpm),
282 ISA_EXT_DATA_ENTRY(sspm, PRIV_VERSION_1_13_0, ext_sspm),
283 ISA_INTERNAL_EXT_DATA_ENTRY(ssstateen, PRIV_VERSION_1_12_0, ext_ssstateen),
284 ISA_INTERNAL_EXT_DATA_ENTRY(ssstrict, PRIV_VERSION_1_12_0, has_priv_1_12),
285 ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc),
286 ISA_INTERNAL_EXT_DATA_ENTRY(sstvala, PRIV_VERSION_1_12_0, has_priv_1_12),
287 ISA_INTERNAL_EXT_DATA_ENTRY(sstvecd, PRIV_VERSION_1_12_0, has_priv_1_12),
288 ISA_INTERNAL_EXT_DATA_ENTRY(ssu64xl, PRIV_VERSION_1_12_0, has_priv_1_12),
289 ISA_EXT_DATA_ENTRY(supm, PRIV_VERSION_1_13_0, ext_supm),
290 ISA_EXT_DATA_ENTRY(svade, PRIV_VERSION_1_11_0, ext_svade),
291 ISA_EXT_DATA_ENTRY(svadu, PRIV_VERSION_1_12_0, ext_svadu),
292 ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval),
293 ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot),
294 ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt),
295 ISA_EXT_DATA_ENTRY(svrsw60t59b, PRIV_VERSION_1_13_0, ext_svrsw60t59b),
296 ISA_EXPERIMENTAL_EXT_DATA_ENTRY(svukte, PRIV_VERSION_1_13_0, ext_svukte),
297 ISA_EXT_DATA_ENTRY(svvptc, PRIV_VERSION_1_13_0, ext_svvptc),
298 ISA_EXT_DATA_ENTRY(xlrbr, PRIV_VERSION_1_13_0, ext_xlrbr),
299 ISA_EXT_DATA_ENTRY(xmipscbop, PRIV_VERSION_1_12_0, ext_xmipscbop),
300 ISA_EXT_DATA_ENTRY(xmipscmov, PRIV_VERSION_1_12_0, ext_xmipscmov),
301 ISA_EXT_DATA_ENTRY(xmipslsp, PRIV_VERSION_1_12_0, ext_xmipslsp),
302 ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba),
303 ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb),
304 ISA_EXT_DATA_ENTRY(xtheadbs, PRIV_VERSION_1_11_0, ext_xtheadbs),
305 ISA_EXT_DATA_ENTRY(xtheadcmo, PRIV_VERSION_1_11_0, ext_xtheadcmo),
306 ISA_EXT_DATA_ENTRY(xtheadcondmov, PRIV_VERSION_1_11_0, ext_xtheadcondmov),
307 ISA_EXT_DATA_ENTRY(xtheadfmemidx, PRIV_VERSION_1_11_0, ext_xtheadfmemidx),
308 ISA_EXT_DATA_ENTRY(xtheadfmv, PRIV_VERSION_1_11_0, ext_xtheadfmv),
309 ISA_EXT_DATA_ENTRY(xtheadmac, PRIV_VERSION_1_11_0, ext_xtheadmac),
310 ISA_EXT_DATA_ENTRY(xtheadmemidx, PRIV_VERSION_1_11_0, ext_xtheadmemidx),
311 ISA_EXT_DATA_ENTRY(xtheadmempair, PRIV_VERSION_1_11_0, ext_xtheadmempair),
312 ISA_EXT_DATA_ENTRY(xtheadsync, PRIV_VERSION_1_11_0, ext_xtheadsync),
313 ISA_EXT_DATA_ENTRY(xventanacondops, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
314
315 { },
316 };
317
318 bool isa_ext_is_enabled(RISCVCPU *cpu, uint32_t ext_offset)
319 {
320 bool *ext_enabled = (void *)&cpu->cfg + ext_offset;
321
322 return *ext_enabled;
323 }
324
325 void isa_ext_update_enabled(RISCVCPU *cpu, uint32_t ext_offset, bool en)
326 {
327 bool *ext_enabled = (void *)&cpu->cfg + ext_offset;
328
329 *ext_enabled = en;
330 }
331
332 bool riscv_cpu_is_vendor(Object *cpu_obj)
333 {
334 return object_dynamic_cast(cpu_obj, TYPE_RISCV_VENDOR_CPU) != NULL;
335 }
336
337 const char * const riscv_int_regnames[] = {
338 "x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1",
339 "x7/t2", "x8/s0", "x9/s1", "x10/a0", "x11/a1", "x12/a2", "x13/a3",
340 "x14/a4", "x15/a5", "x16/a6", "x17/a7", "x18/s2", "x19/s3", "x20/s4",
341 "x21/s5", "x22/s6", "x23/s7", "x24/s8", "x25/s9", "x26/s10", "x27/s11",
342 "x28/t3", "x29/t4", "x30/t5", "x31/t6"
343 };
344
345 const char * const riscv_int_regnamesh[] = {
346 "x0h/zeroh", "x1h/rah", "x2h/sph", "x3h/gph", "x4h/tph", "x5h/t0h",
347 "x6h/t1h", "x7h/t2h", "x8h/s0h", "x9h/s1h", "x10h/a0h", "x11h/a1h",
348 "x12h/a2h", "x13h/a3h", "x14h/a4h", "x15h/a5h", "x16h/a6h", "x17h/a7h",
349 "x18h/s2h", "x19h/s3h", "x20h/s4h", "x21h/s5h", "x22h/s6h", "x23h/s7h",
350 "x24h/s8h", "x25h/s9h", "x26h/s10h", "x27h/s11h", "x28h/t3h", "x29h/t4h",
351 "x30h/t5h", "x31h/t6h"
352 };
353
354 const char * const riscv_fpr_regnames[] = {
355 "f0/ft0", "f1/ft1", "f2/ft2", "f3/ft3", "f4/ft4", "f5/ft5",
356 "f6/ft6", "f7/ft7", "f8/fs0", "f9/fs1", "f10/fa0", "f11/fa1",
357 "f12/fa2", "f13/fa3", "f14/fa4", "f15/fa5", "f16/fa6", "f17/fa7",
358 "f18/fs2", "f19/fs3", "f20/fs4", "f21/fs5", "f22/fs6", "f23/fs7",
359 "f24/fs8", "f25/fs9", "f26/fs10", "f27/fs11", "f28/ft8", "f29/ft9",
360 "f30/ft10", "f31/ft11"
361 };
362
363 const char * const riscv_rvv_regnames[] = {
364 "v0", "v1", "v2", "v3", "v4", "v5", "v6",
365 "v7", "v8", "v9", "v10", "v11", "v12", "v13",
366 "v14", "v15", "v16", "v17", "v18", "v19", "v20",
367 "v21", "v22", "v23", "v24", "v25", "v26", "v27",
368 "v28", "v29", "v30", "v31"
369 };
370
371 static const char * const riscv_excp_names[] = {
372 [RISCV_EXCP_INST_ADDR_MIS] = "misaligned_fetch",
373 [RISCV_EXCP_INST_ACCESS_FAULT] = "fault_fetch",
374 [RISCV_EXCP_ILLEGAL_INST] = "illegal_instruction",
375 [RISCV_EXCP_BREAKPOINT] = "breakpoint",
376 [RISCV_EXCP_LOAD_ADDR_MIS] = "misaligned_load",
377 [RISCV_EXCP_LOAD_ACCESS_FAULT] = "fault_load",
378 [RISCV_EXCP_STORE_AMO_ADDR_MIS] = "misaligned_store",
379 [RISCV_EXCP_STORE_AMO_ACCESS_FAULT] = "fault_store",
380 [RISCV_EXCP_U_ECALL] = "user_ecall",
381 [RISCV_EXCP_S_ECALL] = "supervisor_ecall",
382 [RISCV_EXCP_VS_ECALL] = "hypervisor_ecall",
383 [RISCV_EXCP_M_ECALL] = "machine_ecall",
384 [RISCV_EXCP_INST_PAGE_FAULT] = "exec_page_fault",
385 [RISCV_EXCP_LOAD_PAGE_FAULT] = "load_page_fault",
386 [RISCV_EXCP_STORE_PAGE_FAULT] = "store_page_fault",
387 [RISCV_EXCP_DOUBLE_TRAP] = "double_trap",
388 [RISCV_EXCP_SW_CHECK] = "sw_check",
389 [RISCV_EXCP_HW_ERR] = "hw_error",
390 [RISCV_EXCP_INST_GUEST_PAGE_FAULT] = "guest_exec_page_fault",
391 [RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT] = "guest_load_page_fault",
392 [RISCV_EXCP_VIRT_INSTRUCTION_FAULT] = "virt_illegal_instruction",
393 [RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT] = "guest_store_page_fault",
394 [RISCV_EXCP_SEMIHOST] = "semihost",
395 };
396
397 static const char * const riscv_intr_names[] = {
398 [IRQ_U_SOFT] = "u_software",
399 [IRQ_S_SOFT] = "s_software",
400 [IRQ_VS_SOFT] = "vs_software",
401 [IRQ_M_SOFT] = "m_software",
402 [IRQ_U_TIMER] = "u_timer",
403 [IRQ_S_TIMER] = "s_timer",
404 [IRQ_VS_TIMER] = "vs_timer",
405 [IRQ_M_TIMER] = "m_timer",
406 [IRQ_U_EXT] = "u_external",
407 [IRQ_S_EXT] = "s_external",
408 [IRQ_VS_EXT] = "vs_external",
409 [IRQ_M_EXT] = "m_external",
410 [IRQ_S_GEXT] = "s_guest_external",
411 [IRQ_PMU_OVF] = "counter_overflow",
412 };
413
414 const char *riscv_cpu_get_trap_name(uint64_t cause, bool async)
415 {
416 if (async) {
417 if ((cause < ARRAY_SIZE(riscv_intr_names)) && riscv_intr_names[cause]) {
418 return riscv_intr_names[cause];
419 }
420 } else {
421 if ((cause < ARRAY_SIZE(riscv_excp_names)) && riscv_excp_names[cause]) {
422 return riscv_excp_names[cause];
423 }
424 }
425
426 return "(unknown)";
427 }
428
429 void riscv_cpu_set_misa_ext(CPURISCVState *env, uint32_t ext)
430 {
431 env->misa_ext_mask = env->misa_ext = ext;
432 }
433
434 int riscv_cpu_max_xlen(RISCVCPUClass *mcc)
435 {
436 return 16 << mcc->def->misa_mxl_max;
437 }
438
439 #ifndef CONFIG_USER_ONLY
440 static uint8_t satp_mode_from_str(const char *satp_mode_str)
441 {
442 if (!strncmp(satp_mode_str, "svbare", 6)) {
443 return VM_1_10_MBARE;
444 }
445
446 if (!strncmp(satp_mode_str, "sv32", 4)) {
447 return VM_1_10_SV32;
448 }
449
450 if (!strncmp(satp_mode_str, "sv39", 4)) {
451 return VM_1_10_SV39;
452 }
453
454 if (!strncmp(satp_mode_str, "sv48", 4)) {
455 return VM_1_10_SV48;
456 }
457
458 if (!strncmp(satp_mode_str, "sv57", 4)) {
459 return VM_1_10_SV57;
460 }
461
462 if (!strncmp(satp_mode_str, "sv64", 4)) {
463 return VM_1_10_SV64;
464 }
465
466 g_assert_not_reached();
467 }
468
469 static uint8_t satp_mode_max_from_map(uint32_t map)
470 {
471 /*
472 * 'map = 0' will make us return (31 - 32), which C will
473 * happily overflow to UINT_MAX. There's no good result to
474 * return if 'map = 0' (e.g. returning 0 will be ambiguous
475 * with the result for 'map = 1').
476 *
477 * Assert out if map = 0. Callers will have to deal with
478 * it outside of this function.
479 */
480 g_assert(map > 0);
481
482 /* map here has at least one bit set, so no problem with clz */
483 return 31 - __builtin_clz(map);
484 }
485
486 const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit)
487 {
488 if (is_32_bit) {
489 switch (satp_mode) {
490 case VM_1_10_SV32:
491 return "sv32";
492 case VM_1_10_MBARE:
493 return "none";
494 }
495 } else {
496 switch (satp_mode) {
497 case VM_1_10_SV64:
498 return "sv64";
499 case VM_1_10_SV57:
500 return "sv57";
501 case VM_1_10_SV48:
502 return "sv48";
503 case VM_1_10_SV39:
504 return "sv39";
505 case VM_1_10_MBARE:
506 return "none";
507 }
508 }
509
510 g_assert_not_reached();
511 }
512
513 static bool get_satp_mode_supported(RISCVCPU *cpu, uint16_t *supported)
514 {
515 bool rv32 = riscv_cpu_is_32bit(cpu);
516 const bool *valid_vm = rv32 ? valid_vm_1_10_32 : valid_vm_1_10_64;
517 int satp_mode = cpu->cfg.max_satp_mode;
518
519 if (satp_mode == -1) {
520 return false;
521 }
522
523 *supported = 0;
524 for (int i = 0; i <= satp_mode; ++i) {
525 if (valid_vm[i]) {
526 *supported |= (1 << i);
527 }
528 }
529 return true;
530 }
531
532 /* Set the satp mode to the max supported */
533 static void set_satp_mode_default_map(RISCVCPU *cpu)
534 {
535 /*
536 * Bare CPUs do not default to the max available.
537 * Users must set a valid satp_mode in the command
538 * line. Otherwise, leave the existing max_satp_mode
539 * in place.
540 */
541 if (object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_BARE_CPU) != NULL) {
542 warn_report("No satp mode set. Defaulting to 'bare'");
543 cpu->cfg.max_satp_mode = VM_1_10_MBARE;
544 }
545 }
546 #endif
547
548 /* Used by csr.c and the KVM driver */
549 target_ulong riscv_new_csr_seed(target_ulong new_value,
550 target_ulong write_mask)
551 {
552 uint16_t random_v;
553 Error *random_e = NULL;
554 int random_r;
555 target_ulong rval;
556
557 random_r = qemu_guest_getrandom(&random_v, 2, &random_e);
558 if (unlikely(random_r < 0)) {
559 /*
560 * Failed, for unknown reasons in the crypto subsystem.
561 * The best we can do is log the reason and return a
562 * failure indication to the guest. There is no reason
563 * we know to expect the failure to be transitory, so
564 * indicate DEAD to avoid having the guest spin on WAIT.
565 */
566 qemu_log_mask(LOG_UNIMP, "%s: Crypto failure: %s",
567 __func__, error_get_pretty(random_e));
568 error_free(random_e);
569 rval = SEED_OPST_DEAD;
570 } else {
571 rval = random_v | SEED_OPST_ES16;
572 }
573
574 return rval;
575 }
576
577 #ifndef CONFIG_USER_ONLY
578 /* Used by lots of folks in hw/intc */
579 int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts)
580 {
581 CPURISCVState *env = &cpu->env;
582 if (env->miclaim & interrupts) {
583 return -1;
584 } else {
585 env->miclaim |= interrupts;
586 return 0;
587 }
588 }
589 #endif
590
591 static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
592 {
593 ObjectClass *oc;
594 char *typename;
595 char **cpuname;
596
597 cpuname = g_strsplit(cpu_model, ",", 1);
598 typename = g_strdup_printf(RISCV_CPU_TYPE_NAME("%s"), cpuname[0]);
599 oc = object_class_by_name(typename);
600 g_strfreev(cpuname);
601 g_free(typename);
602
603 return oc;
604 }
605
606 char *riscv_cpu_get_name(RISCVCPU *cpu)
607 {
608 RISCVCPUClass *rcc = RISCV_CPU_GET_CLASS(cpu);
609 const char *typename = object_class_get_name(OBJECT_CLASS(rcc));
610
611 g_assert(g_str_has_suffix(typename, RISCV_CPU_TYPE_SUFFIX));
612
613 return cpu_model_from_type(typename);
614 }
615
616 /* Note: this function needs a KVM implementation. */
617 static void riscv_dump_csr(CPURISCVState *env, int csrno, FILE *f)
618 {
619 #ifdef CONFIG_TCG
620 target_ulong val = 0;
621 RISCVException res = riscv_csrrw_debug(env, csrno, &val, 0, 0);
622
623 /*
624 * Rely on the smode, hmode, etc, predicates within csr.c
625 * to do the filtering of the registers that are present.
626 */
627 if (res == RISCV_EXCP_NONE) {
628 qemu_fprintf(f, " %-13s " TARGET_FMT_lx "\n",
629 csr_ops[csrno].name, val);
630 }
631 #endif
632 }
633
634 #if !defined(CONFIG_USER_ONLY)
635 static const char *riscv_priv_str(uint32_t priv)
636 {
637 switch (priv) {
638 case PRV_M:
639 return "M";
640 case PRV_S:
641 return "S";
642 case PRV_U:
643 return "U";
644 }
645
646 return "?";
647 }
648 #endif
649
650 static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
651 {
652 RISCVCPU *cpu = RISCV_CPU(cs);
653 CPURISCVState *env = &cpu->env;
654 bool rv32 = riscv_cpu_is_32bit(cpu);
655 int width = rv32 ? 8 : 16;
656 uint64_t mask = rv32 ? UINT32_MAX : UINT64_MAX;
657 int i, j;
658 uint8_t *p;
659
660 #if !defined(CONFIG_USER_ONLY)
661 qemu_fprintf(f, " %-13s %s\n", "priv", riscv_priv_str(env->priv));
662
663 if (riscv_has_ext(env, RVH)) {
664 qemu_fprintf(f, " %-13s %d\n", "V", env->virt_enabled);
665 }
666
667 if (cpu->cfg.ext_zicfilp) {
668 qemu_fprintf(f, " %-13s %d\n", "elp", env->elp);
669 }
670 #endif
671 qemu_fprintf(f, " %-13s %0*" PRIx64 "\n", "pc", width, env->pc & mask);
672 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
673 for (i = 0; i < ARRAY_SIZE(csr_ops); i++) {
674 int csrno = i;
675
676 /*
677 * Early skip when possible since we're going
678 * through a lot of NULL entries.
679 */
680 if (csr_ops[csrno].predicate == NULL) {
681 continue;
682 }
683
684 /*
685 * FPU and VPU CSRs will be printed in the
686 * CPU_DUMP_FPU/CPU_DUMP_VPU blocks later.
687 */
688 if (riscv_csr_is_fpu(csrno) ||
689 riscv_csr_is_vpu(csrno)) {
690 continue;
691 }
692
693 riscv_dump_csr(env, csrno, f);
694 }
695 #endif
696
697 for (i = 0; i < 32; i++) {
698 qemu_fprintf(f, " %-8s %0*" PRIx64,
699 riscv_int_regnames[i], width, env->gpr[i] & mask);
700 if ((i & 3) == 3) {
701 qemu_fprintf(f, "\n");
702 }
703 }
704 if (flags & CPU_DUMP_FPU) {
705 riscv_dump_csr(env, CSR_FFLAGS, f);
706 riscv_dump_csr(env, CSR_FRM, f);
707 riscv_dump_csr(env, CSR_FCSR, f);
708
709 for (i = 0; i < 32; i++) {
710 qemu_fprintf(f, " %-8s %016" PRIx64,
711 riscv_fpr_regnames[i], env->fpr[i]);
712 if ((i & 3) == 3) {
713 qemu_fprintf(f, "\n");
714 }
715 }
716 }
717 if (riscv_cpu_cfg(env)->ext_zve32x && (flags & CPU_DUMP_VPU)) {
718 static const int dump_rvv_csrs[] = {
719 CSR_VSTART,
720 CSR_VXSAT,
721 CSR_VXRM,
722 CSR_VCSR,
723 CSR_VL,
724 CSR_VTYPE,
725 CSR_VLENB,
726 };
727 uint16_t vlenb = cpu->cfg.vlenb;
728
729 for (i = 0; i < ARRAY_SIZE(dump_rvv_csrs); ++i) {
730 riscv_dump_csr(env, dump_rvv_csrs[i], f);
731 }
732
733 for (i = 0; i < 32; i++) {
734 qemu_fprintf(f, " %-8s ", riscv_rvv_regnames[i]);
735 p = (uint8_t *)env->vreg;
736 for (j = vlenb - 1 ; j >= 0; j--) {
737 qemu_fprintf(f, "%02x", *(p + i * vlenb + BYTE(j)));
738 }
739 qemu_fprintf(f, "\n");
740 }
741 }
742 }
743
744 static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
745 {
746 RISCVCPU *cpu = RISCV_CPU(cs);
747 CPURISCVState *env = &cpu->env;
748
749 if (env->xl == MXL_RV32) {
750 env->pc = (int32_t)value;
751 } else {
752 env->pc = value;
753 }
754 }
755
756 static vaddr riscv_cpu_get_pc(CPUState *cs)
757 {
758 RISCVCPU *cpu = RISCV_CPU(cs);
759 CPURISCVState *env = &cpu->env;
760
761 /* Match cpu_get_tb_cpu_state. */
762 if (env->xl == MXL_RV32) {
763 return env->pc & UINT32_MAX;
764 }
765 return env->pc;
766 }
767
768 #ifndef CONFIG_USER_ONLY
769 /*
770 * Default priorities of local interrupts are defined in the
771 * RISC-V Advanced Interrupt Architecture specification.
772 *
773 * ----------------------------------------------------------------
774 * Default |
775 * Priority | Major Interrupt Numbers
776 * ----------------------------------------------------------------
777 * Highest | 47, 23, 46, 45, 22, 44,
778 * | 43, 21, 42, 41, 20, 40
779 * |
780 * | 11 (0b), 3 (03), 7 (07)
781 * | 9 (09), 1 (01), 5 (05)
782 * | 12 (0c)
783 * | 10 (0a), 2 (02), 6 (06)
784 * |
785 * | 39, 19, 38, 37, 18, 36,
786 * Lowest | 35, 17, 34, 33, 16, 32
787 * ----------------------------------------------------------------
788 */
789 static const uint8_t default_iprio[64] = {
790 /* Custom interrupts 48 to 63 */
791 [63] = IPRIO_MMAXIPRIO,
792 [62] = IPRIO_MMAXIPRIO,
793 [61] = IPRIO_MMAXIPRIO,
794 [60] = IPRIO_MMAXIPRIO,
795 [59] = IPRIO_MMAXIPRIO,
796 [58] = IPRIO_MMAXIPRIO,
797 [57] = IPRIO_MMAXIPRIO,
798 [56] = IPRIO_MMAXIPRIO,
799 [55] = IPRIO_MMAXIPRIO,
800 [54] = IPRIO_MMAXIPRIO,
801 [53] = IPRIO_MMAXIPRIO,
802 [52] = IPRIO_MMAXIPRIO,
803 [51] = IPRIO_MMAXIPRIO,
804 [50] = IPRIO_MMAXIPRIO,
805 [49] = IPRIO_MMAXIPRIO,
806 [48] = IPRIO_MMAXIPRIO,
807
808 /* Custom interrupts 24 to 31 */
809 [31] = IPRIO_MMAXIPRIO,
810 [30] = IPRIO_MMAXIPRIO,
811 [29] = IPRIO_MMAXIPRIO,
812 [28] = IPRIO_MMAXIPRIO,
813 [27] = IPRIO_MMAXIPRIO,
814 [26] = IPRIO_MMAXIPRIO,
815 [25] = IPRIO_MMAXIPRIO,
816 [24] = IPRIO_MMAXIPRIO,
817
818 [47] = IPRIO_DEFAULT_UPPER,
819 [23] = IPRIO_DEFAULT_UPPER + 1,
820 [46] = IPRIO_DEFAULT_UPPER + 2,
821 [45] = IPRIO_DEFAULT_UPPER + 3,
822 [22] = IPRIO_DEFAULT_UPPER + 4,
823 [44] = IPRIO_DEFAULT_UPPER + 5,
824
825 [43] = IPRIO_DEFAULT_UPPER + 6,
826 [21] = IPRIO_DEFAULT_UPPER + 7,
827 [42] = IPRIO_DEFAULT_UPPER + 8,
828 [41] = IPRIO_DEFAULT_UPPER + 9,
829 [20] = IPRIO_DEFAULT_UPPER + 10,
830 [40] = IPRIO_DEFAULT_UPPER + 11,
831
832 [11] = IPRIO_DEFAULT_M,
833 [3] = IPRIO_DEFAULT_M + 1,
834 [7] = IPRIO_DEFAULT_M + 2,
835
836 [9] = IPRIO_DEFAULT_S,
837 [1] = IPRIO_DEFAULT_S + 1,
838 [5] = IPRIO_DEFAULT_S + 2,
839
840 [12] = IPRIO_DEFAULT_SGEXT,
841
842 [10] = IPRIO_DEFAULT_VS,
843 [2] = IPRIO_DEFAULT_VS + 1,
844 [6] = IPRIO_DEFAULT_VS + 2,
845
846 [39] = IPRIO_DEFAULT_LOWER,
847 [19] = IPRIO_DEFAULT_LOWER + 1,
848 [38] = IPRIO_DEFAULT_LOWER + 2,
849 [37] = IPRIO_DEFAULT_LOWER + 3,
850 [18] = IPRIO_DEFAULT_LOWER + 4,
851 [36] = IPRIO_DEFAULT_LOWER + 5,
852
853 [35] = IPRIO_DEFAULT_LOWER + 6,
854 [17] = IPRIO_DEFAULT_LOWER + 7,
855 [34] = IPRIO_DEFAULT_LOWER + 8,
856 [33] = IPRIO_DEFAULT_LOWER + 9,
857 [16] = IPRIO_DEFAULT_LOWER + 10,
858 [32] = IPRIO_DEFAULT_LOWER + 11,
859 };
860
861 uint8_t riscv_cpu_default_priority(int irq)
862 {
863 if (irq < 0 || irq > 63) {
864 return IPRIO_MMAXIPRIO;
865 }
866
867 return default_iprio[irq] ? default_iprio[irq] : IPRIO_MMAXIPRIO;
868 };
869
870 int riscv_cpu_pending_to_irq(CPURISCVState *env,
871 int extirq, unsigned int extirq_def_prio,
872 uint64_t pending, uint8_t *iprio)
873 {
874 int irq, best_irq = RISCV_EXCP_NONE;
875 unsigned int prio, best_prio = UINT_MAX;
876
877 if (!pending) {
878 return RISCV_EXCP_NONE;
879 }
880
881 irq = ctz64(pending);
882 if (!((extirq == IRQ_M_EXT) ? riscv_cpu_cfg(env)->ext_smaia :
883 riscv_cpu_cfg(env)->ext_ssaia)) {
884 return irq;
885 }
886
887 pending = pending >> irq;
888 while (pending) {
889 prio = iprio[irq];
890 if (!prio) {
891 if (irq == extirq) {
892 prio = extirq_def_prio;
893 } else {
894 prio = (riscv_cpu_default_priority(irq) < extirq_def_prio) ?
895 1 : IPRIO_MMAXIPRIO;
896 }
897 }
898 if ((pending & 0x1) && (prio <= best_prio)) {
899 best_irq = irq;
900 best_prio = prio;
901 }
902 irq++;
903 pending = pending >> 1;
904 }
905
906 return best_irq;
907 }
908
909 /*
910 * Doesn't report interrupts inserted using mvip from M-mode firmware or
911 * using hvip bits 13:63 from HS-mode. Those are returned in
912 * riscv_cpu_sirq_pending() and riscv_cpu_vsirq_pending().
913 */
914 uint64_t riscv_cpu_all_pending(CPURISCVState *env)
915 {
916 uint32_t gein = get_field(env->hstatus, HSTATUS_VGEIN);
917 uint64_t vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
918 uint64_t vstip = (env->vstime_irq) ? MIP_VSTIP : 0;
919
920 return (env->mip | vsgein | vstip) & env->mie;
921 }
922
923 int riscv_cpu_mirq_pending(CPURISCVState *env)
924 {
925 uint64_t irqs = riscv_cpu_all_pending(env) & ~env->mideleg &
926 ~(MIP_SGEIP | MIP_VSSIP | MIP_VSTIP | MIP_VSEIP);
927
928 return riscv_cpu_pending_to_irq(env, IRQ_M_EXT, IPRIO_DEFAULT_M,
929 irqs, env->miprio);
930 }
931
932 int riscv_cpu_sirq_pending(CPURISCVState *env)
933 {
934 uint64_t irqs = riscv_cpu_all_pending(env) & env->mideleg & ~env->hideleg;
935 uint64_t irqs_f = env->mvip & env->mvien & ~env->mideleg & env->sie;
936
937 return riscv_cpu_pending_to_irq(env, IRQ_S_EXT, IPRIO_DEFAULT_S,
938 irqs | irqs_f, env->siprio);
939 }
940
941 int riscv_cpu_vsirq_pending(CPURISCVState *env)
942 {
943 uint64_t irqs = riscv_cpu_all_pending(env) & env->mideleg & env->hideleg;
944 uint64_t irqs_f_vs = env->hvip & env->hvien & ~env->hideleg & env->vsie;
945 uint64_t vsbits;
946
947 /* Bring VS-level bits to correct position */
948 vsbits = irqs & VS_MODE_INTERRUPTS;
949 irqs &= ~VS_MODE_INTERRUPTS;
950 irqs |= vsbits >> 1;
951
952 return riscv_cpu_pending_to_irq(env, IRQ_S_EXT, IPRIO_DEFAULT_S,
953 (irqs | irqs_f_vs), env->hviprio);
954 }
955
956 bool riscv_cpu_has_work(CPUState *cs)
957 {
958 RISCVCPU *cpu = RISCV_CPU(cs);
959 CPURISCVState *env = &cpu->env;
960 /*
961 * Definition of the WFI instruction requires it to ignore the privilege
962 * mode and delegation registers, but respect individual enables
963 */
964 return riscv_cpu_all_pending(env) != 0 ||
965 riscv_cpu_sirq_pending(env) != RISCV_EXCP_NONE ||
966 riscv_cpu_vsirq_pending(env) != RISCV_EXCP_NONE;
967 }
968 #endif /* !CONFIG_USER_ONLY */
969
970 static void riscv_cpu_reset_hold(Object *obj, ResetType type)
971 {
972 CPUState *cs = CPU(obj);
973 RISCVCPU *cpu = RISCV_CPU(cs);
974 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(obj);
975 CPURISCVState *env = &cpu->env;
976
977 if (mcc->parent_phases.hold) {
978 mcc->parent_phases.hold(obj, type);
979 }
980 #ifndef CONFIG_USER_ONLY
981 env->misa_mxl = mcc->def->misa_mxl_max;
982 env->priv = PRV_M;
983 env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV);
984 if (env->misa_mxl > MXL_RV32) {
985 /*
986 * The reset status of SXL/UXL is undefined, but mstatus is WARL
987 * and we must ensure that the value after init is valid for read.
988 */
989 env->mstatus = set_field(env->mstatus, MSTATUS64_SXL, env->misa_mxl);
990 env->mstatus = set_field(env->mstatus, MSTATUS64_UXL, env->misa_mxl);
991 if (riscv_has_ext(env, RVH)) {
992 env->vsstatus = set_field(env->vsstatus,
993 MSTATUS64_SXL, env->misa_mxl);
994 env->vsstatus = set_field(env->vsstatus,
995 MSTATUS64_UXL, env->misa_mxl);
996 env->mstatus_hs = set_field(env->mstatus_hs,
997 MSTATUS64_SXL, env->misa_mxl);
998 env->mstatus_hs = set_field(env->mstatus_hs,
999 MSTATUS64_UXL, env->misa_mxl);
1000 }
1001 if (riscv_cpu_cfg(env)->ext_smdbltrp) {
1002 env->mstatus = set_field(env->mstatus, MSTATUS_MDT, 1);
1003 }
1004 }
1005 /*
1006 * Model fixed-endian harts: MBE/SBE/UBE are initialized from the
1007 * CPU configuration and are intentionally not writable via status CSRs.
1008 */
1009 env->mstatus = set_field(env->mstatus, MSTATUS_MBE, cpu->cfg.big_endian);
1010 env->mstatus = set_field(env->mstatus, MSTATUS_SBE, cpu->cfg.big_endian);
1011 env->mstatus = set_field(env->mstatus, MSTATUS_UBE, cpu->cfg.big_endian);
1012 env->mcause = 0;
1013 env->miclaim = MIP_SGEIP;
1014 env->pc = env->resetvec;
1015 env->bins = 0;
1016 env->two_stage_lookup = false;
1017
1018 env->menvcfg = (cpu->cfg.ext_svpbmt ? MENVCFG_PBMTE : 0) |
1019 (!cpu->cfg.ext_svade && cpu->cfg.ext_svadu ?
1020 MENVCFG_ADUE : 0);
1021 env->henvcfg = 0;
1022
1023 #ifdef CONFIG_TCG
1024 uint8_t iprio;
1025 int i, irq, rdzero;
1026
1027 /* Initialized default priorities of local interrupts. */
1028 for (i = 0; i < ARRAY_SIZE(env->miprio); i++) {
1029 iprio = riscv_cpu_default_priority(i);
1030 env->miprio[i] = (i == IRQ_M_EXT) ? 0 : iprio;
1031 env->siprio[i] = (i == IRQ_S_EXT) ? 0 : iprio;
1032 env->hviprio[i] = 0;
1033 }
1034 i = 0;
1035 while (!riscv_cpu_hviprio_index2irq(i, &irq, &rdzero)) {
1036 if (!rdzero) {
1037 env->hviprio[irq] = env->miprio[irq];
1038 }
1039 i++;
1040 }
1041
1042 /*
1043 * Bits 10, 6, 2 and 12 of mideleg are read only 1 when the Hypervisor
1044 * extension is enabled.
1045 */
1046 if (riscv_has_ext(env, RVH)) {
1047 env->mideleg |= HS_MODE_INTERRUPTS;
1048 }
1049
1050 /*
1051 * Clear mseccfg and unlock all the PMP entries upon reset.
1052 * This is required as per the priv, smepmp, and other security
1053 * extension specifications that share this CSR, and is needed
1054 * to clear stale entries across reboots.
1055 */
1056 if (riscv_cpu_cfg(env)->ext_smepmp ||
1057 riscv_cpu_cfg(env)->ext_zkr ||
1058 riscv_cpu_cfg(env)->ext_smmpm ||
1059 riscv_cpu_cfg(env)->ext_zicfilp) {
1060 env->mseccfg = 0;
1061 }
1062
1063 pmp_unlock_entries(env);
1064 #endif /* ifdef CONFIG_TCG */
1065 #else
1066 env->priv = PRV_U;
1067 env->senvcfg = 0;
1068 /*
1069 * Match the user-mode view of a typical firmware/kernel setup where
1070 * cbo.zero is enabled for user mode; the CBCFE/CBIE bits stay zero,
1071 * so the cache-management operations remain illegal in user mode.
1072 */
1073 if (riscv_cpu_cfg(env)->ext_zicboz) {
1074 env->senvcfg |= SENVCFG_CBZE;
1075 }
1076 env->menvcfg = 0;
1077 #endif /* !CONFIG_USER_ONLY */
1078
1079 /* on reset elp is clear */
1080 env->elp = false;
1081 /* on reset ssp is set to 0 */
1082 env->ssp = 0;
1083
1084 env->xl = riscv_cpu_mxl(env);
1085 cs->exception_index = RISCV_EXCP_NONE;
1086 env->load_res = -1;
1087 set_default_nan_mode(1, &env->fp_status);
1088 /* Default NaN value: sign bit clear, frac msb set */
1089 set_float_default_nan_pattern(0b01000000, &env->fp_status);
1090 env->vill = true;
1091
1092 #ifndef CONFIG_USER_ONLY
1093 #ifdef CONFIG_TCG
1094 if (cpu->cfg.debug) {
1095 riscv_trigger_reset_hold(env);
1096 }
1097 #endif
1098
1099 if (cpu->cfg.ext_smrnmi) {
1100 env->rnmip = 0;
1101 env->mnstatus = set_field(env->mnstatus, MNSTATUS_NMIE, false);
1102 }
1103
1104 if (kvm_enabled()) {
1105 kvm_riscv_reset_vcpu(cpu);
1106 }
1107 #endif
1108 }
1109
1110 static void riscv_cpu_disas_set_info(const CPUState *s, disassemble_info *info)
1111 {
1112 const RISCVCPU *cpu = RISCV_CPU(s);
1113 const CPURISCVState *env = &cpu->env;
1114 int cap_mode;
1115
1116 info->target_info = &cpu->cfg;
1117
1118 /*
1119 * RISC-V instructions are always little-endian, regardless of the
1120 * data endianness configured via MSTATUS UBE/SBE/MBE bits.
1121 */
1122 info->endian = BFD_ENDIAN_LITTLE;
1123
1124 switch (env->xl) {
1125 case MXL_RV32:
1126 info->print_insn = print_insn_riscv32;
1127 cap_mode = CS_MODE_RISCV32;
1128 break;
1129 case MXL_RV64:
1130 info->print_insn = print_insn_riscv64;
1131 cap_mode = CS_MODE_RISCV64;
1132 break;
1133 case MXL_RV128:
1134 info->print_insn = print_insn_riscv128;
1135 /* capstone v6 doesn't support RV128 */
1136 return;
1137 default:
1138 g_assert_not_reached();
1139 }
1140
1141 info->cap_arch = CS_ARCH_RISCV;
1142 info->cap_insn_unit = 4;
1143 info->cap_insn_split = 4;
1144
1145 /*
1146 * Capstone compresses some features together. See RISCV_getFeatureBits,
1147 * which maps LLVM feature bits to capstone bits.
1148 */
1149 if (riscv_has_ext(env, RVC) || cpu->cfg.ext_zca) {
1150 cap_mode |= CS_MODE_RISCV_C;
1151 }
1152 if (riscv_has_ext(env, RVF)) {
1153 cap_mode |= CS_MODE_RISCV_FD;
1154 }
1155 if (riscv_has_ext(env, RVV)) {
1156 cap_mode |= CS_MODE_RISCV_V;
1157 }
1158 if (cpu->cfg.ext_zfinx || cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinx) {
1159 cap_mode |= CS_MODE_RISCV_ZFINX;
1160 }
1161 if (cpu->cfg.ext_zcmp || cpu->cfg.ext_zcmt || cpu->cfg.ext_zce) {
1162 cap_mode |= CS_MODE_RISCV_ZCMP_ZCMT_ZCE;
1163 }
1164 if (cpu->cfg.ext_zicfiss) {
1165 cap_mode |= CS_MODE_RISCV_ZICFISS;
1166 }
1167 if (riscv_has_ext(env, RVE)) {
1168 cap_mode |= CS_MODE_RISCV_E;
1169 }
1170 if (riscv_has_ext(env, RVA)) {
1171 cap_mode |= CS_MODE_RISCV_A;
1172 }
1173 if (cpu->cfg.ext_xlrbr) {
1174 cap_mode |= CS_MODE_RISCV_BITMANIP;
1175 }
1176 if (cpu->cfg.ext_zba) {
1177 cap_mode |= CS_MODE_RISCV_ZBA;
1178 }
1179 if (cpu->cfg.ext_zbb) {
1180 cap_mode |= CS_MODE_RISCV_ZBB;
1181 }
1182 if (cpu->cfg.ext_zbc) {
1183 cap_mode |= CS_MODE_RISCV_ZBC;
1184 }
1185 if (cpu->cfg.ext_zbkb) {
1186 cap_mode |= CS_MODE_RISCV_ZBKB;
1187 }
1188 if (cpu->cfg.ext_zbkc) {
1189 cap_mode |= CS_MODE_RISCV_ZBKC;
1190 }
1191 if (cpu->cfg.ext_zbkx) {
1192 cap_mode |= CS_MODE_RISCV_ZBKX;
1193 }
1194 if (cpu->cfg.ext_zbs) {
1195 cap_mode |= CS_MODE_RISCV_ZBS;
1196 }
1197 if (cpu->cfg.ext_xtheadba ||
1198 cpu->cfg.ext_xtheadbb ||
1199 cpu->cfg.ext_xtheadbs ||
1200 cpu->cfg.ext_xtheadcmo ||
1201 cpu->cfg.ext_xtheadcondmov ||
1202 cpu->cfg.ext_xtheadfmemidx ||
1203 cpu->cfg.ext_xtheadfmv ||
1204 cpu->cfg.ext_xtheadmac ||
1205 cpu->cfg.ext_xtheadmemidx ||
1206 cpu->cfg.ext_xtheadmempair ||
1207 cpu->cfg.ext_xtheadsync) {
1208 cap_mode |= CS_MODE_RISCV_THEAD;
1209 }
1210 if (cpu->cfg.ext_XVentanaCondOps) {
1211 cap_mode |= CS_MODE_RISCV_VENTANA;
1212 }
1213 info->cap_mode = cap_mode;
1214 }
1215
1216 #ifndef CONFIG_USER_ONLY
1217 static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
1218 {
1219 bool rv32 = riscv_cpu_is_32bit(cpu);
1220 uint16_t supported;
1221 uint8_t satp_mode_map_max;
1222
1223 if (!get_satp_mode_supported(cpu, &supported)) {
1224 /* The CPU wants the hypervisor to decide which satp mode to allow */
1225 return;
1226 }
1227
1228 if (cpu->satp_modes.map == 0) {
1229 if (cpu->satp_modes.init == 0) {
1230 /* If unset by the user, we fallback to the default satp mode. */
1231 set_satp_mode_default_map(cpu);
1232 } else {
1233 /*
1234 * Find the lowest level that was disabled and then enable the
1235 * first valid level below which can be found in
1236 * valid_vm_1_10_32/64.
1237 */
1238 for (int i = 1; i < 16; ++i) {
1239 if ((cpu->satp_modes.init & (1 << i)) &&
1240 supported & (1 << i)) {
1241 for (int j = i - 1; j >= 0; --j) {
1242 if (supported & (1 << j)) {
1243 cpu->cfg.max_satp_mode = j;
1244 return;
1245 }
1246 }
1247 }
1248 }
1249 }
1250 return;
1251 }
1252
1253 satp_mode_map_max = satp_mode_max_from_map(cpu->satp_modes.map);
1254
1255 /* Make sure the user asked for a supported configuration (HW and qemu) */
1256 if (satp_mode_map_max > cpu->cfg.max_satp_mode) {
1257 error_setg(errp, "satp_mode %s is higher than hw max capability %s",
1258 satp_mode_str(satp_mode_map_max, rv32),
1259 satp_mode_str(cpu->cfg.max_satp_mode, rv32));
1260 return;
1261 }
1262
1263 /*
1264 * Make sure the user did not ask for an invalid configuration as per
1265 * the specification.
1266 */
1267 if (!rv32) {
1268 for (int i = satp_mode_map_max - 1; i >= 0; --i) {
1269 if (!(cpu->satp_modes.map & (1 << i)) &&
1270 (cpu->satp_modes.init & (1 << i)) &&
1271 (supported & (1 << i))) {
1272 error_setg(errp, "cannot disable %s satp mode if %s "
1273 "is enabled", satp_mode_str(i, false),
1274 satp_mode_str(satp_mode_map_max, false));
1275 return;
1276 }
1277 }
1278 }
1279
1280 cpu->cfg.max_satp_mode = satp_mode_map_max;
1281 }
1282 #endif
1283
1284 void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
1285 {
1286 Error *local_err = NULL;
1287
1288 #ifndef CONFIG_USER_ONLY
1289 riscv_cpu_satp_mode_finalize(cpu, &local_err);
1290 if (local_err != NULL) {
1291 error_propagate(errp, local_err);
1292 return;
1293 }
1294 #endif
1295
1296 if (tcg_enabled()) {
1297 riscv_tcg_cpu_finalize_features(cpu, &local_err);
1298 if (local_err != NULL) {
1299 error_propagate(errp, local_err);
1300 return;
1301 }
1302 riscv_tcg_cpu_finalize_dynamic_decoder(cpu);
1303 } else if (kvm_enabled()) {
1304 riscv_kvm_cpu_finalize_features(cpu, &local_err);
1305 if (local_err != NULL) {
1306 error_propagate(errp, local_err);
1307 return;
1308 }
1309 }
1310 }
1311
1312 static void riscv_cpu_realize(DeviceState *dev, Error **errp)
1313 {
1314 CPUState *cs = CPU(dev);
1315 RISCVCPU *cpu = RISCV_CPU(dev);
1316 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
1317 Error *local_err = NULL;
1318
1319 cpu_common_realize(cs, &local_err);
1320 if (local_err != NULL) {
1321 error_propagate(errp, local_err);
1322 return;
1323 }
1324
1325 riscv_cpu_finalize_features(cpu, &local_err);
1326 if (local_err != NULL) {
1327 error_propagate(errp, local_err);
1328 return;
1329 }
1330
1331 riscv_cpu_register_gdb_regs_for_features(cs);
1332
1333 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
1334 if (cpu->cfg.debug) {
1335 riscv_trigger_realize(&cpu->env);
1336 }
1337 #endif
1338
1339 qemu_init_vcpu(cs);
1340 cpu_reset(cs);
1341
1342 mcc->parent_realize(dev, errp);
1343 }
1344
1345 static void riscv_cpu_unrealize(DeviceState *dev)
1346 {
1347 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
1348 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
1349 RISCVCPU *cpu = RISCV_CPU(dev);
1350
1351 if (cpu->cfg.debug) {
1352 riscv_trigger_unrealize(&cpu->env);
1353 }
1354 #endif
1355 mcc->parent_unrealize(dev);
1356 }
1357
1358 bool riscv_cpu_accelerator_compatible(RISCVCPU *cpu)
1359 {
1360 if (tcg_enabled()) {
1361 return riscv_cpu_tcg_compatible(cpu);
1362 }
1363
1364 return true;
1365 }
1366
1367 #ifndef CONFIG_USER_ONLY
1368 static void cpu_riscv_get_satp(Object *obj, Visitor *v, const char *name,
1369 void *opaque, Error **errp)
1370 {
1371 RISCVSATPModes *satp_modes = opaque;
1372 uint8_t satp = satp_mode_from_str(name);
1373 bool value;
1374
1375 value = satp_modes->map & (1 << satp);
1376
1377 visit_type_bool(v, name, &value, errp);
1378 }
1379
1380 static void cpu_riscv_set_satp(Object *obj, Visitor *v, const char *name,
1381 void *opaque, Error **errp)
1382 {
1383 RISCVSATPModes *satp_modes = opaque;
1384 uint8_t satp = satp_mode_from_str(name);
1385 bool value;
1386
1387 if (!visit_type_bool(v, name, &value, errp)) {
1388 return;
1389 }
1390
1391 satp_modes->map = deposit32(satp_modes->map, satp, 1, value);
1392 satp_modes->init |= 1 << satp;
1393 }
1394
1395 void riscv_add_satp_mode_properties(Object *obj)
1396 {
1397 RISCVCPU *cpu = RISCV_CPU(obj);
1398
1399 object_property_add(obj, "svbare", "bool", cpu_riscv_get_satp,
1400 cpu_riscv_set_satp, NULL, &cpu->satp_modes);
1401
1402 if (cpu->env.misa_mxl == MXL_RV32) {
1403 object_property_add(obj, "sv32", "bool", cpu_riscv_get_satp,
1404 cpu_riscv_set_satp, NULL, &cpu->satp_modes);
1405 } else {
1406 object_property_add(obj, "sv39", "bool", cpu_riscv_get_satp,
1407 cpu_riscv_set_satp, NULL, &cpu->satp_modes);
1408 object_property_add(obj, "sv48", "bool", cpu_riscv_get_satp,
1409 cpu_riscv_set_satp, NULL, &cpu->satp_modes);
1410 object_property_add(obj, "sv57", "bool", cpu_riscv_get_satp,
1411 cpu_riscv_set_satp, NULL, &cpu->satp_modes);
1412 object_property_add(obj, "sv64", "bool", cpu_riscv_get_satp,
1413 cpu_riscv_set_satp, NULL, &cpu->satp_modes);
1414 }
1415 }
1416
1417 static void riscv_cpu_set_irq(void *opaque, int irq, int level)
1418 {
1419 RISCVCPU *cpu = RISCV_CPU(opaque);
1420 CPURISCVState *env = &cpu->env;
1421
1422 if (irq < IRQ_LOCAL_MAX) {
1423 switch (irq) {
1424 case IRQ_U_SOFT:
1425 case IRQ_S_SOFT:
1426 case IRQ_VS_SOFT:
1427 case IRQ_M_SOFT:
1428 case IRQ_U_TIMER:
1429 case IRQ_S_TIMER:
1430 case IRQ_VS_TIMER:
1431 case IRQ_M_TIMER:
1432 case IRQ_U_EXT:
1433 case IRQ_VS_EXT:
1434 case IRQ_M_EXT:
1435 if (kvm_enabled()) {
1436 kvm_riscv_set_irq(cpu, irq, level);
1437 }
1438
1439 if (tcg_enabled()) {
1440 riscv_cpu_update_mip(env, 1 << irq, BOOL_TO_MASK(level));
1441 }
1442 break;
1443 case IRQ_S_EXT:
1444 if (kvm_enabled()) {
1445 kvm_riscv_set_irq(cpu, irq, level);
1446 }
1447
1448 if (tcg_enabled()) {
1449 env->external_seip = level;
1450 riscv_cpu_update_mip(env, 1 << irq,
1451 BOOL_TO_MASK(level | env->software_seip));
1452 }
1453 break;
1454 default:
1455 g_assert_not_reached();
1456 }
1457 } else if (irq < (IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX)) {
1458 /* Require H-extension for handling guest local interrupts */
1459 if (!riscv_has_ext(env, RVH)) {
1460 g_assert_not_reached();
1461 }
1462
1463 /* Compute bit position in HGEIP CSR */
1464 irq = irq - IRQ_LOCAL_MAX + 1;
1465 if (env->geilen < irq) {
1466 g_assert_not_reached();
1467 }
1468
1469 /* Update HGEIP CSR */
1470 env->hgeip &= ~(1ULL << irq);
1471 if (level) {
1472 env->hgeip |= 1ULL << irq;
1473 }
1474
1475 if (kvm_enabled()) {
1476 kvm_riscv_set_irq(cpu, irq, level);
1477 }
1478 if (tcg_enabled()) {
1479 /* Update mip.SGEIP bit */
1480 riscv_cpu_update_mip(env, MIP_SGEIP,
1481 BOOL_TO_MASK(!!(env->hgeie & env->hgeip)));
1482 }
1483 } else {
1484 g_assert_not_reached();
1485 }
1486 }
1487 #endif /* CONFIG_USER_ONLY */
1488
1489 static bool riscv_cpu_is_dynamic(Object *cpu_obj)
1490 {
1491 return object_dynamic_cast(cpu_obj, TYPE_RISCV_DYNAMIC_CPU) != NULL;
1492 }
1493
1494 static void riscv_cpu_init(Object *obj)
1495 {
1496 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(obj);
1497 RISCVCPU *cpu = RISCV_CPU(obj);
1498 CPURISCVState *env = &cpu->env;
1499
1500 env->misa_mxl = mcc->def->misa_mxl_max;
1501
1502 #ifndef CONFIG_USER_ONLY
1503 qdev_init_gpio_in(DEVICE(obj), riscv_cpu_set_irq,
1504 IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX);
1505 if (mcc->def->num_triggers) {
1506 env->num_triggers = mcc->def->num_triggers;
1507 }
1508
1509 #endif /* CONFIG_USER_ONLY */
1510
1511 cpu->user_options = g_hash_table_new(g_str_hash, g_str_equal);
1512
1513 /*
1514 * The timer and performance counters extensions were supported
1515 * in QEMU before they were added as discrete extensions in the
1516 * ISA. To keep compatibility we'll always default them to 'true'
1517 * for all CPUs. Each accelerator will decide what to do when
1518 * users disable them.
1519 */
1520 RISCV_CPU(obj)->cfg.ext_zicntr = !mcc->def->bare;
1521 RISCV_CPU(obj)->cfg.ext_zihpm = !mcc->def->bare;
1522
1523 /* Default values for non-bool cpu properties */
1524 cpu->cfg.pmu_mask = MAKE_64BIT_MASK(3, 16);
1525 cpu->cfg.vlenb = 128 >> 3;
1526 cpu->cfg.elen = 64;
1527 cpu->cfg.cbom_blocksize = 64;
1528 cpu->cfg.cbop_blocksize = 64;
1529 cpu->cfg.cboz_blocksize = 64;
1530 cpu->cfg.pmp_regions = 16;
1531 #ifndef CONFIG_USER_ONLY
1532 cpu->cfg.pmp_granularity = MIN_RISCV_PMP_GRANULARITY;
1533 #endif
1534 cpu->env.vext_ver = VEXT_VERSION_1_00_0;
1535 cpu->cfg.max_satp_mode = -1;
1536
1537 if (mcc->def->profile) {
1538 mcc->def->profile->enabled = true;
1539 }
1540
1541 cpu->cfg.mvendorid = RISCV_CPU_MVENDORID;
1542 cpu->cfg.marchid = RISCV_CPU_MARCHID;
1543 cpu->cfg.mimpid = RISCV_CPU_MIMPID;
1544
1545 env->misa_ext_mask = env->misa_ext = mcc->def->misa_ext;
1546 riscv_cpu_cfg_merge(&cpu->cfg, &mcc->def->cfg);
1547
1548 if (mcc->def->priv_spec != RISCV_PROFILE_ATTR_UNUSED) {
1549 cpu->env.priv_ver = mcc->def->priv_spec;
1550 }
1551 if (mcc->def->vext_spec != RISCV_PROFILE_ATTR_UNUSED) {
1552 cpu->env.vext_ver = mcc->def->vext_spec;
1553 }
1554
1555 accel_cpu_instance_init(CPU(obj));
1556 }
1557
1558 typedef struct misa_ext_info {
1559 const char *name;
1560 const char *description;
1561 } MISAExtInfo;
1562
1563 #define MISA_INFO_IDX(_bit) \
1564 __builtin_ctz(_bit)
1565
1566 #define MISA_EXT_INFO(_bit, _propname, _descr) \
1567 [MISA_INFO_IDX(_bit)] = {.name = _propname, .description = _descr}
1568
1569 static const MISAExtInfo misa_ext_info_arr[] = {
1570 MISA_EXT_INFO(RVA, "a", "Atomic instructions"),
1571 MISA_EXT_INFO(RVC, "c", "Compressed instructions"),
1572 MISA_EXT_INFO(RVD, "d", "Double-precision float point"),
1573 MISA_EXT_INFO(RVF, "f", "Single-precision float point"),
1574 MISA_EXT_INFO(RVI, "i", "Base integer instruction set"),
1575 MISA_EXT_INFO(RVE, "e", "Base integer instruction set (embedded)"),
1576 MISA_EXT_INFO(RVM, "m", "Integer multiplication and division"),
1577 MISA_EXT_INFO(RVS, "s", "Supervisor-level instructions"),
1578 MISA_EXT_INFO(RVU, "u", "User-level instructions"),
1579 MISA_EXT_INFO(RVH, "h", "Hypervisor"),
1580 MISA_EXT_INFO(RVV, "v", "Vector operations"),
1581 MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"),
1582 MISA_EXT_INFO(RVB, "b", "Bit manipulation (Zba_Zbb_Zbs)")
1583 };
1584
1585 static void riscv_cpu_validate_misa_mxl(RISCVCPUClass *mcc)
1586 {
1587 CPUClass *cc = CPU_CLASS(mcc);
1588
1589 /* Validate that MISA_MXL is set properly. */
1590 switch (mcc->def->misa_mxl_max) {
1591 #ifdef TARGET_RISCV64
1592 case MXL_RV64:
1593 case MXL_RV128:
1594 cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
1595 break;
1596 #endif
1597 case MXL_RV32:
1598 cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
1599 break;
1600 default:
1601 g_assert_not_reached();
1602 }
1603 }
1604
1605 static int riscv_validate_misa_info_idx(uint32_t bit)
1606 {
1607 int idx;
1608
1609 /*
1610 * Our lowest valid input (RVA) is 1 and
1611 * __builtin_ctz() is UB with zero.
1612 */
1613 g_assert(bit != 0);
1614 idx = MISA_INFO_IDX(bit);
1615
1616 g_assert(idx < ARRAY_SIZE(misa_ext_info_arr));
1617 return idx;
1618 }
1619
1620 const char *riscv_get_misa_ext_name(uint32_t bit)
1621 {
1622 int idx = riscv_validate_misa_info_idx(bit);
1623 const char *val = misa_ext_info_arr[idx].name;
1624
1625 g_assert(val != NULL);
1626 return val;
1627 }
1628
1629 const char *riscv_get_misa_ext_description(uint32_t bit)
1630 {
1631 int idx = riscv_validate_misa_info_idx(bit);
1632 const char *val = misa_ext_info_arr[idx].description;
1633
1634 g_assert(val != NULL);
1635 return val;
1636 }
1637
1638 static void cpu_set_prop_err(RISCVCPU *cpu, const char *propname,
1639 Error **errp)
1640 {
1641 g_autofree char *cpuname = riscv_cpu_get_name(cpu);
1642 error_setg(errp, "CPU '%s' does not allow changing the value of '%s'",
1643 cpuname, propname);
1644 }
1645
1646 static void prop_pmu_num_set(Object *obj, Visitor *v, const char *name,
1647 void *opaque, Error **errp)
1648 {
1649 RISCVCPU *cpu = RISCV_CPU(obj);
1650 uint8_t pmu_num, curr_pmu_num;
1651 uint32_t pmu_mask;
1652
1653 visit_type_uint8(v, name, &pmu_num, errp);
1654
1655 curr_pmu_num = ctpop32(cpu->cfg.pmu_mask);
1656
1657 if (pmu_num != curr_pmu_num && riscv_cpu_is_vendor(obj)) {
1658 cpu_set_prop_err(cpu, name, errp);
1659 error_append_hint(errp, "Current '%s' val: %u\n",
1660 name, curr_pmu_num);
1661 return;
1662 }
1663
1664 if (pmu_num > (RV_MAX_MHPMCOUNTERS - 3)) {
1665 error_setg(errp, "Number of counters exceeds maximum available");
1666 return;
1667 }
1668
1669 if (pmu_num == 0) {
1670 pmu_mask = 0;
1671 } else {
1672 pmu_mask = MAKE_64BIT_MASK(3, pmu_num);
1673 }
1674
1675 warn_report("\"pmu-num\" property is deprecated; use \"pmu-mask\"");
1676 cpu->cfg.pmu_mask = pmu_mask;
1677 cpu_option_add_user_setting(cpu, "pmu-mask");
1678 }
1679
1680 static void prop_pmu_num_get(Object *obj, Visitor *v, const char *name,
1681 void *opaque, Error **errp)
1682 {
1683 RISCVCPU *cpu = RISCV_CPU(obj);
1684 uint8_t pmu_num = ctpop32(cpu->cfg.pmu_mask);
1685
1686 visit_type_uint8(v, name, &pmu_num, errp);
1687 }
1688
1689 static const PropertyInfo prop_pmu_num = {
1690 .type = "int8",
1691 .description = "pmu-num",
1692 .get = prop_pmu_num_get,
1693 .set = prop_pmu_num_set,
1694 };
1695
1696 static void prop_pmu_mask_set(Object *obj, Visitor *v, const char *name,
1697 void *opaque, Error **errp)
1698 {
1699 RISCVCPU *cpu = RISCV_CPU(obj);
1700 uint32_t value;
1701 uint8_t pmu_num;
1702
1703 visit_type_uint32(v, name, &value, errp);
1704
1705 if (value != cpu->cfg.pmu_mask && riscv_cpu_is_vendor(obj)) {
1706 cpu_set_prop_err(cpu, name, errp);
1707 error_append_hint(errp, "Current '%s' val: %x\n",
1708 name, cpu->cfg.pmu_mask);
1709 return;
1710 }
1711
1712 pmu_num = ctpop32(value);
1713
1714 if (pmu_num > (RV_MAX_MHPMCOUNTERS - 3)) {
1715 error_setg(errp, "Number of counters exceeds maximum available");
1716 return;
1717 }
1718
1719 cpu_option_add_user_setting(cpu, name);
1720 cpu->cfg.pmu_mask = value;
1721 }
1722
1723 static void prop_pmu_mask_get(Object *obj, Visitor *v, const char *name,
1724 void *opaque, Error **errp)
1725 {
1726 uint8_t pmu_mask = RISCV_CPU(obj)->cfg.pmu_mask;
1727
1728 visit_type_uint8(v, name, &pmu_mask, errp);
1729 }
1730
1731 static const PropertyInfo prop_pmu_mask = {
1732 .type = "int8",
1733 .description = "pmu-mask",
1734 .get = prop_pmu_mask_get,
1735 .set = prop_pmu_mask_set,
1736 };
1737
1738 static void prop_mmu_set(Object *obj, Visitor *v, const char *name,
1739 void *opaque, Error **errp)
1740 {
1741 RISCVCPU *cpu = RISCV_CPU(obj);
1742 bool value;
1743
1744 visit_type_bool(v, name, &value, errp);
1745
1746 if (cpu->cfg.mmu != value && riscv_cpu_is_vendor(obj)) {
1747 cpu_set_prop_err(cpu, "mmu", errp);
1748 return;
1749 }
1750
1751 cpu_option_add_user_setting(cpu, name);
1752 cpu->cfg.mmu = value;
1753 }
1754
1755 static void prop_mmu_get(Object *obj, Visitor *v, const char *name,
1756 void *opaque, Error **errp)
1757 {
1758 bool value = RISCV_CPU(obj)->cfg.mmu;
1759
1760 visit_type_bool(v, name, &value, errp);
1761 }
1762
1763 static const PropertyInfo prop_mmu = {
1764 .type = "bool",
1765 .description = "mmu",
1766 .get = prop_mmu_get,
1767 .set = prop_mmu_set,
1768 };
1769
1770 #ifndef CONFIG_USER_ONLY
1771 static void prop_pmp_set(Object *obj, Visitor *v, const char *name,
1772 void *opaque, Error **errp)
1773 {
1774 RISCVCPU *cpu = RISCV_CPU(obj);
1775 bool value;
1776
1777 visit_type_bool(v, name, &value, errp);
1778
1779 if (cpu->cfg.pmp != value && riscv_cpu_is_vendor(obj)) {
1780 cpu_set_prop_err(cpu, name, errp);
1781 return;
1782 }
1783
1784 cpu_option_add_user_setting(cpu, name);
1785 cpu->cfg.pmp = value;
1786 }
1787
1788 static void prop_pmp_get(Object *obj, Visitor *v, const char *name,
1789 void *opaque, Error **errp)
1790 {
1791 bool value = RISCV_CPU(obj)->cfg.pmp;
1792
1793 visit_type_bool(v, name, &value, errp);
1794 }
1795
1796 static const PropertyInfo prop_pmp = {
1797 .type = "bool",
1798 .description = "pmp",
1799 .get = prop_pmp_get,
1800 .set = prop_pmp_set,
1801 };
1802
1803 static void prop_num_pmp_regions_set(Object *obj, Visitor *v, const char *name,
1804 void *opaque, Error **errp)
1805 {
1806 RISCVCPU *cpu = RISCV_CPU(obj);
1807 uint8_t value;
1808
1809 visit_type_uint8(v, name, &value, errp);
1810
1811 if (cpu->cfg.pmp_regions != value && riscv_cpu_is_vendor(obj)) {
1812 cpu_set_prop_err(cpu, name, errp);
1813 return;
1814 }
1815
1816 if (cpu->env.priv_ver < PRIV_VERSION_1_12_0 && value > OLD_MAX_RISCV_PMPS) {
1817 error_setg(errp, "Number of PMP regions exceeds maximum available");
1818 return;
1819 } else if (value > MAX_RISCV_PMPS) {
1820 error_setg(errp, "Number of PMP regions exceeds maximum available");
1821 return;
1822 }
1823
1824 cpu_option_add_user_setting(cpu, name);
1825 cpu->cfg.pmp_regions = value;
1826 }
1827
1828 static void prop_num_pmp_regions_get(Object *obj, Visitor *v, const char *name,
1829 void *opaque, Error **errp)
1830 {
1831 uint8_t value = RISCV_CPU(obj)->cfg.pmp_regions;
1832
1833 visit_type_uint8(v, name, &value, errp);
1834 }
1835
1836 static const PropertyInfo prop_num_pmp_regions = {
1837 .type = "uint8",
1838 .description = "num-pmp-regions",
1839 .get = prop_num_pmp_regions_get,
1840 .set = prop_num_pmp_regions_set,
1841 };
1842
1843 static void prop_pmp_granularity_set(Object *obj, Visitor *v, const char *name,
1844 void *opaque, Error **errp)
1845 {
1846 RISCVCPU *cpu = RISCV_CPU(obj);
1847 uint32_t value;
1848
1849 visit_type_uint32(v, name, &value, errp);
1850
1851 if ((value < MIN_RISCV_PMP_GRANULARITY) && (value & (value - 1))) {
1852 error_setg(errp, "PMP granularity must be a power of 2 and at least %d",
1853 MIN_RISCV_PMP_GRANULARITY);
1854 return;
1855 }
1856
1857 if (cpu->cfg.pmp_granularity != value && riscv_cpu_is_vendor(obj)) {
1858 cpu_set_prop_err(cpu, name, errp);
1859 return;
1860 }
1861
1862 cpu_option_add_user_setting(cpu, name);
1863 cpu->cfg.pmp_granularity = value;
1864 }
1865
1866 static void prop_pmp_granularity_get(Object *obj, Visitor *v, const char *name,
1867 void *opaque, Error **errp)
1868 {
1869 uint32_t value = RISCV_CPU(obj)->cfg.pmp_granularity;
1870
1871 visit_type_uint32(v, name, &value, errp);
1872 }
1873
1874 static const PropertyInfo prop_pmp_granularity = {
1875 .description = "pmp-granularity",
1876 .get = prop_pmp_granularity_get,
1877 .set = prop_pmp_granularity_set,
1878 };
1879 #endif /* !CONFIG_USER_ONLY */
1880
1881 static int priv_spec_from_str(const char *priv_spec_str)
1882 {
1883 int priv_version = -1;
1884
1885 if (!g_strcmp0(priv_spec_str, PRIV_VER_1_13_0_STR)) {
1886 priv_version = PRIV_VERSION_1_13_0;
1887 } else if (!g_strcmp0(priv_spec_str, PRIV_VER_1_12_0_STR)) {
1888 priv_version = PRIV_VERSION_1_12_0;
1889 } else if (!g_strcmp0(priv_spec_str, PRIV_VER_1_11_0_STR)) {
1890 priv_version = PRIV_VERSION_1_11_0;
1891 } else if (!g_strcmp0(priv_spec_str, PRIV_VER_1_10_0_STR)) {
1892 priv_version = PRIV_VERSION_1_10_0;
1893 }
1894
1895 return priv_version;
1896 }
1897
1898 const char *priv_spec_to_str(int priv_version)
1899 {
1900 switch (priv_version) {
1901 case PRIV_VERSION_1_10_0:
1902 return PRIV_VER_1_10_0_STR;
1903 case PRIV_VERSION_1_11_0:
1904 return PRIV_VER_1_11_0_STR;
1905 case PRIV_VERSION_1_12_0:
1906 return PRIV_VER_1_12_0_STR;
1907 case PRIV_VERSION_1_13_0:
1908 return PRIV_VER_1_13_0_STR;
1909 default:
1910 return NULL;
1911 }
1912 }
1913
1914 static void prop_priv_spec_set(Object *obj, Visitor *v, const char *name,
1915 void *opaque, Error **errp)
1916 {
1917 RISCVCPU *cpu = RISCV_CPU(obj);
1918 g_autofree char *value = NULL;
1919 int priv_version = -1;
1920
1921 visit_type_str(v, name, &value, errp);
1922
1923 priv_version = priv_spec_from_str(value);
1924 if (priv_version < 0) {
1925 error_setg(errp, "Unsupported privilege spec version '%s'", value);
1926 return;
1927 }
1928
1929 if (priv_version != cpu->env.priv_ver && riscv_cpu_is_vendor(obj)) {
1930 cpu_set_prop_err(cpu, name, errp);
1931 error_append_hint(errp, "Current '%s' val: %s\n", name,
1932 object_property_get_str(obj, name, NULL));
1933 return;
1934 }
1935
1936 cpu_option_add_user_setting(cpu, name);
1937 cpu->env.priv_ver = priv_version;
1938 }
1939
1940 static void prop_priv_spec_get(Object *obj, Visitor *v, const char *name,
1941 void *opaque, Error **errp)
1942 {
1943 RISCVCPU *cpu = RISCV_CPU(obj);
1944 const char *value = priv_spec_to_str(cpu->env.priv_ver);
1945
1946 visit_type_str(v, name, (char **)&value, errp);
1947 }
1948
1949 static const PropertyInfo prop_priv_spec = {
1950 .type = "str",
1951 .description = "priv_spec",
1952 /* FIXME enum? */
1953 .get = prop_priv_spec_get,
1954 .set = prop_priv_spec_set,
1955 };
1956
1957 static void prop_vext_spec_set(Object *obj, Visitor *v, const char *name,
1958 void *opaque, Error **errp)
1959 {
1960 RISCVCPU *cpu = RISCV_CPU(obj);
1961 g_autofree char *value = NULL;
1962
1963 visit_type_str(v, name, &value, errp);
1964
1965 if (g_strcmp0(value, VEXT_VER_1_00_0_STR) != 0) {
1966 error_setg(errp, "Unsupported vector spec version '%s'", value);
1967 return;
1968 }
1969
1970 cpu_option_add_user_setting(cpu, name);
1971 cpu->env.vext_ver = VEXT_VERSION_1_00_0;
1972 }
1973
1974 static void prop_vext_spec_get(Object *obj, Visitor *v, const char *name,
1975 void *opaque, Error **errp)
1976 {
1977 const char *value = VEXT_VER_1_00_0_STR;
1978
1979 visit_type_str(v, name, (char **)&value, errp);
1980 }
1981
1982 static const PropertyInfo prop_vext_spec = {
1983 .type = "str",
1984 .description = "vext_spec",
1985 /* FIXME enum? */
1986 .get = prop_vext_spec_get,
1987 .set = prop_vext_spec_set,
1988 };
1989
1990 static void prop_vlen_set(Object *obj, Visitor *v, const char *name,
1991 void *opaque, Error **errp)
1992 {
1993 RISCVCPU *cpu = RISCV_CPU(obj);
1994 uint16_t cpu_vlen = cpu->cfg.vlenb << 3;
1995 uint16_t value;
1996
1997 if (!visit_type_uint16(v, name, &value, errp)) {
1998 return;
1999 }
2000
2001 if (!is_power_of_2(value)) {
2002 error_setg(errp, "Vector extension VLEN must be power of 2");
2003 return;
2004 }
2005
2006 if (value != cpu_vlen && riscv_cpu_is_vendor(obj)) {
2007 cpu_set_prop_err(cpu, name, errp);
2008 error_append_hint(errp, "Current '%s' val: %u\n",
2009 name, cpu_vlen);
2010 return;
2011 }
2012
2013 cpu_option_add_user_setting(cpu, name);
2014 cpu->cfg.vlenb = value >> 3;
2015 }
2016
2017 static void prop_vlen_get(Object *obj, Visitor *v, const char *name,
2018 void *opaque, Error **errp)
2019 {
2020 uint16_t value = RISCV_CPU(obj)->cfg.vlenb << 3;
2021
2022 visit_type_uint16(v, name, &value, errp);
2023 }
2024
2025 static const PropertyInfo prop_vlen = {
2026 .type = "uint16",
2027 .description = "vlen",
2028 .get = prop_vlen_get,
2029 .set = prop_vlen_set,
2030 };
2031
2032 static void prop_elen_set(Object *obj, Visitor *v, const char *name,
2033 void *opaque, Error **errp)
2034 {
2035 RISCVCPU *cpu = RISCV_CPU(obj);
2036 uint16_t value;
2037
2038 if (!visit_type_uint16(v, name, &value, errp)) {
2039 return;
2040 }
2041
2042 if (!is_power_of_2(value)) {
2043 error_setg(errp, "Vector extension ELEN must be power of 2");
2044 return;
2045 }
2046
2047 if (value != cpu->cfg.elen && riscv_cpu_is_vendor(obj)) {
2048 cpu_set_prop_err(cpu, name, errp);
2049 error_append_hint(errp, "Current '%s' val: %u\n",
2050 name, cpu->cfg.elen);
2051 return;
2052 }
2053
2054 cpu_option_add_user_setting(cpu, name);
2055 cpu->cfg.elen = value;
2056 }
2057
2058 static void prop_elen_get(Object *obj, Visitor *v, const char *name,
2059 void *opaque, Error **errp)
2060 {
2061 uint16_t value = RISCV_CPU(obj)->cfg.elen;
2062
2063 visit_type_uint16(v, name, &value, errp);
2064 }
2065
2066 static const PropertyInfo prop_elen = {
2067 .type = "uint16",
2068 .description = "elen",
2069 .get = prop_elen_get,
2070 .set = prop_elen_set,
2071 };
2072
2073 static void prop_cbom_blksize_set(Object *obj, Visitor *v, const char *name,
2074 void *opaque, Error **errp)
2075 {
2076 RISCVCPU *cpu = RISCV_CPU(obj);
2077 uint16_t value;
2078
2079 if (!visit_type_uint16(v, name, &value, errp)) {
2080 return;
2081 }
2082
2083 if (value != cpu->cfg.cbom_blocksize && riscv_cpu_is_vendor(obj)) {
2084 cpu_set_prop_err(cpu, name, errp);
2085 error_append_hint(errp, "Current '%s' val: %u\n",
2086 name, cpu->cfg.cbom_blocksize);
2087 return;
2088 }
2089
2090 cpu_option_add_user_setting(cpu, name);
2091 cpu->cfg.cbom_blocksize = value;
2092 }
2093
2094 static void prop_cbom_blksize_get(Object *obj, Visitor *v, const char *name,
2095 void *opaque, Error **errp)
2096 {
2097 uint16_t value = RISCV_CPU(obj)->cfg.cbom_blocksize;
2098
2099 visit_type_uint16(v, name, &value, errp);
2100 }
2101
2102 static const PropertyInfo prop_cbom_blksize = {
2103 .type = "uint16",
2104 .description = "cbom_blocksize",
2105 .get = prop_cbom_blksize_get,
2106 .set = prop_cbom_blksize_set,
2107 };
2108
2109 static void prop_cbop_blksize_set(Object *obj, Visitor *v, const char *name,
2110 void *opaque, Error **errp)
2111 {
2112 RISCVCPU *cpu = RISCV_CPU(obj);
2113 uint16_t value;
2114
2115 if (!visit_type_uint16(v, name, &value, errp)) {
2116 return;
2117 }
2118
2119 if (value != cpu->cfg.cbop_blocksize && riscv_cpu_is_vendor(obj)) {
2120 cpu_set_prop_err(cpu, name, errp);
2121 error_append_hint(errp, "Current '%s' val: %u\n",
2122 name, cpu->cfg.cbop_blocksize);
2123 return;
2124 }
2125
2126 cpu_option_add_user_setting(cpu, name);
2127 cpu->cfg.cbop_blocksize = value;
2128 }
2129
2130 static void prop_cbop_blksize_get(Object *obj, Visitor *v, const char *name,
2131 void *opaque, Error **errp)
2132 {
2133 uint16_t value = RISCV_CPU(obj)->cfg.cbop_blocksize;
2134
2135 visit_type_uint16(v, name, &value, errp);
2136 }
2137
2138 static const PropertyInfo prop_cbop_blksize = {
2139 .type = "uint16",
2140 .description = "cbop_blocksize",
2141 .get = prop_cbop_blksize_get,
2142 .set = prop_cbop_blksize_set,
2143 };
2144
2145 static void prop_cboz_blksize_set(Object *obj, Visitor *v, const char *name,
2146 void *opaque, Error **errp)
2147 {
2148 RISCVCPU *cpu = RISCV_CPU(obj);
2149 uint16_t value;
2150
2151 if (!visit_type_uint16(v, name, &value, errp)) {
2152 return;
2153 }
2154
2155 if (value != cpu->cfg.cboz_blocksize && riscv_cpu_is_vendor(obj)) {
2156 cpu_set_prop_err(cpu, name, errp);
2157 error_append_hint(errp, "Current '%s' val: %u\n",
2158 name, cpu->cfg.cboz_blocksize);
2159 return;
2160 }
2161
2162 cpu_option_add_user_setting(cpu, name);
2163 cpu->cfg.cboz_blocksize = value;
2164 }
2165
2166 static void prop_cboz_blksize_get(Object *obj, Visitor *v, const char *name,
2167 void *opaque, Error **errp)
2168 {
2169 uint16_t value = RISCV_CPU(obj)->cfg.cboz_blocksize;
2170
2171 visit_type_uint16(v, name, &value, errp);
2172 }
2173
2174 static const PropertyInfo prop_cboz_blksize = {
2175 .type = "uint16",
2176 .description = "cboz_blocksize",
2177 .get = prop_cboz_blksize_get,
2178 .set = prop_cboz_blksize_set,
2179 };
2180
2181 static void prop_mvendorid_set(Object *obj, Visitor *v, const char *name,
2182 void *opaque, Error **errp)
2183 {
2184 bool dynamic_cpu = riscv_cpu_is_dynamic(obj);
2185 RISCVCPU *cpu = RISCV_CPU(obj);
2186 uint32_t prev_val = cpu->cfg.mvendorid;
2187 uint32_t value;
2188
2189 if (!visit_type_uint32(v, name, &value, errp)) {
2190 return;
2191 }
2192
2193 if (!dynamic_cpu && prev_val != value) {
2194 error_setg(errp, "Unable to change %s mvendorid (0x%x)",
2195 object_get_typename(obj), prev_val);
2196 return;
2197 }
2198
2199 cpu->cfg.mvendorid = value;
2200 }
2201
2202 static void prop_mvendorid_get(Object *obj, Visitor *v, const char *name,
2203 void *opaque, Error **errp)
2204 {
2205 uint32_t value = RISCV_CPU(obj)->cfg.mvendorid;
2206
2207 visit_type_uint32(v, name, &value, errp);
2208 }
2209
2210 static const PropertyInfo prop_mvendorid = {
2211 .type = "uint32",
2212 .description = "mvendorid",
2213 .get = prop_mvendorid_get,
2214 .set = prop_mvendorid_set,
2215 };
2216
2217 static void prop_mimpid_set(Object *obj, Visitor *v, const char *name,
2218 void *opaque, Error **errp)
2219 {
2220 bool dynamic_cpu = riscv_cpu_is_dynamic(obj);
2221 RISCVCPU *cpu = RISCV_CPU(obj);
2222 uint64_t prev_val = cpu->cfg.mimpid;
2223 uint64_t value;
2224
2225 if (!visit_type_uint64(v, name, &value, errp)) {
2226 return;
2227 }
2228
2229 if (!dynamic_cpu && prev_val != value) {
2230 error_setg(errp, "Unable to change %s mimpid (0x%" PRIu64 ")",
2231 object_get_typename(obj), prev_val);
2232 return;
2233 }
2234
2235 cpu->cfg.mimpid = value;
2236 }
2237
2238 static void prop_mimpid_get(Object *obj, Visitor *v, const char *name,
2239 void *opaque, Error **errp)
2240 {
2241 uint64_t value = RISCV_CPU(obj)->cfg.mimpid;
2242
2243 visit_type_uint64(v, name, &value, errp);
2244 }
2245
2246 static const PropertyInfo prop_mimpid = {
2247 .type = "uint64",
2248 .description = "mimpid",
2249 .get = prop_mimpid_get,
2250 .set = prop_mimpid_set,
2251 };
2252
2253 static void prop_marchid_set(Object *obj, Visitor *v, const char *name,
2254 void *opaque, Error **errp)
2255 {
2256 bool dynamic_cpu = riscv_cpu_is_dynamic(obj);
2257 RISCVCPU *cpu = RISCV_CPU(obj);
2258 uint64_t prev_val = cpu->cfg.marchid;
2259 uint64_t value, invalid_val;
2260 uint32_t mxlen = 0;
2261
2262 if (!visit_type_uint64(v, name, &value, errp)) {
2263 return;
2264 }
2265
2266 if (!dynamic_cpu && prev_val != value) {
2267 error_setg(errp, "Unable to change %s marchid (0x%" PRIu64 ")",
2268 object_get_typename(obj), prev_val);
2269 return;
2270 }
2271
2272 switch (riscv_cpu_mxl(&cpu->env)) {
2273 case MXL_RV32:
2274 mxlen = 32;
2275 break;
2276 case MXL_RV64:
2277 case MXL_RV128:
2278 mxlen = 64;
2279 break;
2280 default:
2281 g_assert_not_reached();
2282 }
2283
2284 invalid_val = 1LL << (mxlen - 1);
2285
2286 if (value == invalid_val) {
2287 error_setg(errp, "Unable to set marchid with MSB (%u) bit set "
2288 "and the remaining bits zero", mxlen);
2289 return;
2290 }
2291
2292 cpu->cfg.marchid = value;
2293 }
2294
2295 static void prop_marchid_get(Object *obj, Visitor *v, const char *name,
2296 void *opaque, Error **errp)
2297 {
2298 uint64_t value = RISCV_CPU(obj)->cfg.marchid;
2299
2300 visit_type_uint64(v, name, &value, errp);
2301 }
2302
2303 static const PropertyInfo prop_marchid = {
2304 .type = "uint64",
2305 .description = "marchid",
2306 .get = prop_marchid_get,
2307 .set = prop_marchid_set,
2308 };
2309
2310 /*
2311 * RVA22U64 defines some 'named features' that are cache
2312 * related: Za64rs, Zic64b, Ziccif, Ziccrse, Ziccamoa
2313 * and Zicclsm. They are always implemented in TCG and
2314 * doesn't need to be manually enabled by the profile.
2315 */
2316 static RISCVCPUProfile RVA22U64 = {
2317 .u_parent = NULL,
2318 .s_parent = NULL,
2319 .name = "rva22u64",
2320 .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVB | RVU,
2321 .priv_spec = RISCV_PROFILE_ATTR_UNUSED,
2322 .satp_mode = RISCV_PROFILE_ATTR_UNUSED,
2323 .ext_offsets = {
2324 CPU_CFG_OFFSET(ext_zicsr), CPU_CFG_OFFSET(ext_zihintpause),
2325 CPU_CFG_OFFSET(ext_zba), CPU_CFG_OFFSET(ext_zbb),
2326 CPU_CFG_OFFSET(ext_zbs), CPU_CFG_OFFSET(ext_zfhmin),
2327 CPU_CFG_OFFSET(ext_zkt), CPU_CFG_OFFSET(ext_zicntr),
2328 CPU_CFG_OFFSET(ext_zihpm), CPU_CFG_OFFSET(ext_zicbom),
2329 CPU_CFG_OFFSET(ext_zicbop), CPU_CFG_OFFSET(ext_zicboz),
2330 CPU_CFG_OFFSET(ext_zicclsm),
2331
2332 /* mandatory named features for this profile */
2333 CPU_CFG_OFFSET(ext_zic64b),
2334
2335 RISCV_PROFILE_EXT_LIST_END
2336 }
2337 };
2338
2339 /*
2340 * As with RVA22U64, RVA22S64 also defines 'named features'.
2341 *
2342 * Cache related features that we consider enabled since we don't
2343 * implement cache: Ssccptr
2344 *
2345 * Other named features that we already implement: Sstvecd, Sstvala,
2346 * Sscounterenw
2347 *
2348 * The remaining features/extensions comes from RVA22U64.
2349 */
2350 static RISCVCPUProfile RVA22S64 = {
2351 .u_parent = &RVA22U64,
2352 .s_parent = NULL,
2353 .name = "rva22s64",
2354 .misa_ext = RVS,
2355 .priv_spec = PRIV_VERSION_1_12_0,
2356 .satp_mode = VM_1_10_SV39,
2357 .ext_offsets = {
2358 /* rva22s64 exts */
2359 CPU_CFG_OFFSET(ext_zifencei), CPU_CFG_OFFSET(ext_svpbmt),
2360 CPU_CFG_OFFSET(ext_svinval), CPU_CFG_OFFSET(ext_svade),
2361
2362 RISCV_PROFILE_EXT_LIST_END
2363 }
2364 };
2365
2366 /*
2367 * All mandatory extensions from RVA22U64 are present
2368 * in RVA23U64 so set RVA22 as a parent. We need to
2369 * declare just the newly added mandatory extensions.
2370 */
2371 static RISCVCPUProfile RVA23U64 = {
2372 .u_parent = &RVA22U64,
2373 .s_parent = NULL,
2374 .name = "rva23u64",
2375 .misa_ext = RVV,
2376 .priv_spec = RISCV_PROFILE_ATTR_UNUSED,
2377 .satp_mode = RISCV_PROFILE_ATTR_UNUSED,
2378 .ext_offsets = {
2379 CPU_CFG_OFFSET(ext_zvfhmin), CPU_CFG_OFFSET(ext_zvbb),
2380 CPU_CFG_OFFSET(ext_zvkt), CPU_CFG_OFFSET(ext_zihintntl),
2381 CPU_CFG_OFFSET(ext_zicond), CPU_CFG_OFFSET(ext_zimop),
2382 CPU_CFG_OFFSET(ext_zcmop), CPU_CFG_OFFSET(ext_zcb),
2383 CPU_CFG_OFFSET(ext_zfa), CPU_CFG_OFFSET(ext_zawrs),
2384 CPU_CFG_OFFSET(ext_supm),
2385
2386 RISCV_PROFILE_EXT_LIST_END
2387 }
2388 };
2389
2390 /*
2391 * As with RVA23U64, RVA23S64 also defines 'named features'.
2392 *
2393 * Cache related features that we consider enabled since we don't
2394 * implement cache: Ssccptr
2395 *
2396 * Other named features that we already implement: Sstvecd, Sstvala,
2397 * Sscounterenw, Ssu64xl
2398 *
2399 * The remaining features/extensions comes from RVA23S64.
2400 */
2401 static RISCVCPUProfile RVA23S64 = {
2402 .u_parent = &RVA23U64,
2403 .s_parent = &RVA22S64,
2404 .name = "rva23s64",
2405 .misa_ext = RVS,
2406 .priv_spec = PRIV_VERSION_1_13_0,
2407 .satp_mode = VM_1_10_SV39,
2408 .ext_offsets = {
2409 /* New in RVA23S64 */
2410 CPU_CFG_OFFSET(ext_svnapot), CPU_CFG_OFFSET(ext_sstc),
2411 CPU_CFG_OFFSET(ext_sscofpmf), CPU_CFG_OFFSET(ext_ssnpm),
2412
2413 /* Named features: Sha */
2414 CPU_CFG_OFFSET(ext_sha),
2415
2416 RISCV_PROFILE_EXT_LIST_END
2417 }
2418 };
2419
2420 RISCVCPUProfile *riscv_profiles[] = {
2421 &RVA22U64,
2422 &RVA22S64,
2423 &RVA23U64,
2424 &RVA23S64,
2425 NULL,
2426 };
2427
2428 static RISCVCPUImpliedExtsRule RVA_IMPLIED = {
2429 .is_misa = true,
2430 .ext = RVA,
2431 .implied_multi_exts = {
2432 CPU_CFG_OFFSET(ext_zalrsc), CPU_CFG_OFFSET(ext_zaamo),
2433
2434 RISCV_IMPLIED_EXTS_RULE_END
2435 },
2436 };
2437
2438 static RISCVCPUImpliedExtsRule RVD_IMPLIED = {
2439 .is_misa = true,
2440 .ext = RVD,
2441 .implied_misa_exts = RVF,
2442 .implied_multi_exts = { RISCV_IMPLIED_EXTS_RULE_END },
2443 };
2444
2445 static RISCVCPUImpliedExtsRule RVF_IMPLIED = {
2446 .is_misa = true,
2447 .ext = RVF,
2448 .implied_multi_exts = {
2449 CPU_CFG_OFFSET(ext_zicsr),
2450
2451 RISCV_IMPLIED_EXTS_RULE_END
2452 },
2453 };
2454
2455 static RISCVCPUImpliedExtsRule RVM_IMPLIED = {
2456 .is_misa = true,
2457 .ext = RVM,
2458 .implied_multi_exts = {
2459 CPU_CFG_OFFSET(ext_zmmul),
2460
2461 RISCV_IMPLIED_EXTS_RULE_END
2462 },
2463 };
2464
2465 static RISCVCPUImpliedExtsRule RVV_IMPLIED = {
2466 .is_misa = true,
2467 .ext = RVV,
2468 .implied_multi_exts = {
2469 CPU_CFG_OFFSET(ext_zve64d),
2470
2471 RISCV_IMPLIED_EXTS_RULE_END
2472 },
2473 };
2474
2475 static RISCVCPUImpliedExtsRule RVG_IMPLIED = {
2476 .is_misa = true,
2477 .ext = RVG,
2478 .implied_misa_exts = RVI | RVM | RVA | RVF | RVD,
2479 .implied_multi_exts = {
2480 CPU_CFG_OFFSET(ext_zicsr),
2481 CPU_CFG_OFFSET(ext_zifencei),
2482
2483 RISCV_IMPLIED_EXTS_RULE_END
2484 },
2485 };
2486
2487 static RISCVCPUImpliedExtsRule RVB_IMPLIED = {
2488 .is_misa = true,
2489 .ext = RVB,
2490 .implied_multi_exts = {
2491 CPU_CFG_OFFSET(ext_zba), CPU_CFG_OFFSET(ext_zbb),
2492 CPU_CFG_OFFSET(ext_zbs),
2493
2494 RISCV_IMPLIED_EXTS_RULE_END
2495 },
2496 };
2497
2498 static RISCVCPUImpliedExtsRule ZCB_IMPLIED = {
2499 .ext = CPU_CFG_OFFSET(ext_zcb),
2500 .implied_multi_exts = {
2501 CPU_CFG_OFFSET(ext_zca),
2502
2503 RISCV_IMPLIED_EXTS_RULE_END
2504 },
2505 };
2506
2507 static RISCVCPUImpliedExtsRule ZCD_IMPLIED = {
2508 .ext = CPU_CFG_OFFSET(ext_zcd),
2509 .implied_misa_exts = RVD,
2510 .implied_multi_exts = {
2511 CPU_CFG_OFFSET(ext_zca),
2512
2513 RISCV_IMPLIED_EXTS_RULE_END
2514 },
2515 };
2516
2517 static RISCVCPUImpliedExtsRule ZCE_IMPLIED = {
2518 .ext = CPU_CFG_OFFSET(ext_zce),
2519 .implied_multi_exts = {
2520 CPU_CFG_OFFSET(ext_zcb), CPU_CFG_OFFSET(ext_zcmp),
2521 CPU_CFG_OFFSET(ext_zcmt),
2522
2523 RISCV_IMPLIED_EXTS_RULE_END
2524 },
2525 };
2526
2527 static RISCVCPUImpliedExtsRule ZCF_IMPLIED = {
2528 .ext = CPU_CFG_OFFSET(ext_zcf),
2529 .implied_misa_exts = RVF,
2530 .implied_multi_exts = {
2531 CPU_CFG_OFFSET(ext_zca),
2532
2533 RISCV_IMPLIED_EXTS_RULE_END
2534 },
2535 };
2536
2537 static RISCVCPUImpliedExtsRule ZCMP_IMPLIED = {
2538 .ext = CPU_CFG_OFFSET(ext_zcmp),
2539 .implied_multi_exts = {
2540 CPU_CFG_OFFSET(ext_zca),
2541
2542 RISCV_IMPLIED_EXTS_RULE_END
2543 },
2544 };
2545
2546 static RISCVCPUImpliedExtsRule ZCMT_IMPLIED = {
2547 .ext = CPU_CFG_OFFSET(ext_zcmt),
2548 .implied_multi_exts = {
2549 CPU_CFG_OFFSET(ext_zca), CPU_CFG_OFFSET(ext_zicsr),
2550
2551 RISCV_IMPLIED_EXTS_RULE_END
2552 },
2553 };
2554
2555 static RISCVCPUImpliedExtsRule ZDINX_IMPLIED = {
2556 .ext = CPU_CFG_OFFSET(ext_zdinx),
2557 .implied_multi_exts = {
2558 CPU_CFG_OFFSET(ext_zfinx),
2559
2560 RISCV_IMPLIED_EXTS_RULE_END
2561 },
2562 };
2563
2564 static RISCVCPUImpliedExtsRule ZFA_IMPLIED = {
2565 .ext = CPU_CFG_OFFSET(ext_zfa),
2566 .implied_misa_exts = RVF,
2567 .implied_multi_exts = { RISCV_IMPLIED_EXTS_RULE_END },
2568 };
2569
2570 static RISCVCPUImpliedExtsRule ZFBFMIN_IMPLIED = {
2571 .ext = CPU_CFG_OFFSET(ext_zfbfmin),
2572 .implied_misa_exts = RVF,
2573 .implied_multi_exts = { RISCV_IMPLIED_EXTS_RULE_END },
2574 };
2575
2576 static RISCVCPUImpliedExtsRule ZFH_IMPLIED = {
2577 .ext = CPU_CFG_OFFSET(ext_zfh),
2578 .implied_multi_exts = {
2579 CPU_CFG_OFFSET(ext_zfhmin),
2580
2581 RISCV_IMPLIED_EXTS_RULE_END
2582 },
2583 };
2584
2585 static RISCVCPUImpliedExtsRule ZFHMIN_IMPLIED = {
2586 .ext = CPU_CFG_OFFSET(ext_zfhmin),
2587 .implied_misa_exts = RVF,
2588 .implied_multi_exts = { RISCV_IMPLIED_EXTS_RULE_END },
2589 };
2590
2591 static RISCVCPUImpliedExtsRule ZFINX_IMPLIED = {
2592 .ext = CPU_CFG_OFFSET(ext_zfinx),
2593 .implied_multi_exts = {
2594 CPU_CFG_OFFSET(ext_zicsr),
2595
2596 RISCV_IMPLIED_EXTS_RULE_END
2597 },
2598 };
2599
2600 static RISCVCPUImpliedExtsRule ZHINX_IMPLIED = {
2601 .ext = CPU_CFG_OFFSET(ext_zhinx),
2602 .implied_multi_exts = {
2603 CPU_CFG_OFFSET(ext_zhinxmin),
2604
2605 RISCV_IMPLIED_EXTS_RULE_END
2606 },
2607 };
2608
2609 static RISCVCPUImpliedExtsRule ZHINXMIN_IMPLIED = {
2610 .ext = CPU_CFG_OFFSET(ext_zhinxmin),
2611 .implied_multi_exts = {
2612 CPU_CFG_OFFSET(ext_zfinx),
2613
2614 RISCV_IMPLIED_EXTS_RULE_END
2615 },
2616 };
2617
2618 static RISCVCPUImpliedExtsRule ZICNTR_IMPLIED = {
2619 .ext = CPU_CFG_OFFSET(ext_zicntr),
2620 .implied_multi_exts = {
2621 CPU_CFG_OFFSET(ext_zicsr),
2622
2623 RISCV_IMPLIED_EXTS_RULE_END
2624 },
2625 };
2626
2627 static RISCVCPUImpliedExtsRule ZIHPM_IMPLIED = {
2628 .ext = CPU_CFG_OFFSET(ext_zihpm),
2629 .implied_multi_exts = {
2630 CPU_CFG_OFFSET(ext_zicsr),
2631
2632 RISCV_IMPLIED_EXTS_RULE_END
2633 },
2634 };
2635
2636 static RISCVCPUImpliedExtsRule ZK_IMPLIED = {
2637 .ext = CPU_CFG_OFFSET(ext_zk),
2638 .implied_multi_exts = {
2639 CPU_CFG_OFFSET(ext_zkn), CPU_CFG_OFFSET(ext_zkr),
2640 CPU_CFG_OFFSET(ext_zkt),
2641
2642 RISCV_IMPLIED_EXTS_RULE_END
2643 },
2644 };
2645
2646 static RISCVCPUImpliedExtsRule ZKN_IMPLIED = {
2647 .ext = CPU_CFG_OFFSET(ext_zkn),
2648 .implied_multi_exts = {
2649 CPU_CFG_OFFSET(ext_zbkb), CPU_CFG_OFFSET(ext_zbkc),
2650 CPU_CFG_OFFSET(ext_zbkx), CPU_CFG_OFFSET(ext_zkne),
2651 CPU_CFG_OFFSET(ext_zknd), CPU_CFG_OFFSET(ext_zknh),
2652
2653 RISCV_IMPLIED_EXTS_RULE_END
2654 },
2655 };
2656
2657 static RISCVCPUImpliedExtsRule ZKS_IMPLIED = {
2658 .ext = CPU_CFG_OFFSET(ext_zks),
2659 .implied_multi_exts = {
2660 CPU_CFG_OFFSET(ext_zbkb), CPU_CFG_OFFSET(ext_zbkc),
2661 CPU_CFG_OFFSET(ext_zbkx), CPU_CFG_OFFSET(ext_zksed),
2662 CPU_CFG_OFFSET(ext_zksh),
2663
2664 RISCV_IMPLIED_EXTS_RULE_END
2665 },
2666 };
2667
2668 static RISCVCPUImpliedExtsRule ZVBB_IMPLIED = {
2669 .ext = CPU_CFG_OFFSET(ext_zvbb),
2670 .implied_multi_exts = {
2671 CPU_CFG_OFFSET(ext_zvkb),
2672
2673 RISCV_IMPLIED_EXTS_RULE_END
2674 },
2675 };
2676
2677 static RISCVCPUImpliedExtsRule ZVE32F_IMPLIED = {
2678 .ext = CPU_CFG_OFFSET(ext_zve32f),
2679 .implied_misa_exts = RVF,
2680 .implied_multi_exts = {
2681 CPU_CFG_OFFSET(ext_zve32x),
2682
2683 RISCV_IMPLIED_EXTS_RULE_END
2684 },
2685 };
2686
2687 static RISCVCPUImpliedExtsRule ZVE32X_IMPLIED = {
2688 .ext = CPU_CFG_OFFSET(ext_zve32x),
2689 .implied_multi_exts = {
2690 CPU_CFG_OFFSET(ext_zicsr),
2691
2692 RISCV_IMPLIED_EXTS_RULE_END
2693 },
2694 };
2695
2696 static RISCVCPUImpliedExtsRule ZVE64D_IMPLIED = {
2697 .ext = CPU_CFG_OFFSET(ext_zve64d),
2698 .implied_misa_exts = RVD,
2699 .implied_multi_exts = {
2700 CPU_CFG_OFFSET(ext_zve64f),
2701
2702 RISCV_IMPLIED_EXTS_RULE_END
2703 },
2704 };
2705
2706 static RISCVCPUImpliedExtsRule ZVE64F_IMPLIED = {
2707 .ext = CPU_CFG_OFFSET(ext_zve64f),
2708 .implied_misa_exts = RVF,
2709 .implied_multi_exts = {
2710 CPU_CFG_OFFSET(ext_zve32f), CPU_CFG_OFFSET(ext_zve64x),
2711
2712 RISCV_IMPLIED_EXTS_RULE_END
2713 },
2714 };
2715
2716 static RISCVCPUImpliedExtsRule ZVE64X_IMPLIED = {
2717 .ext = CPU_CFG_OFFSET(ext_zve64x),
2718 .implied_multi_exts = {
2719 CPU_CFG_OFFSET(ext_zve32x),
2720
2721 RISCV_IMPLIED_EXTS_RULE_END
2722 },
2723 };
2724
2725 static RISCVCPUImpliedExtsRule ZVFBFMIN_IMPLIED = {
2726 .ext = CPU_CFG_OFFSET(ext_zvfbfmin),
2727 .implied_multi_exts = {
2728 CPU_CFG_OFFSET(ext_zve32f),
2729
2730 RISCV_IMPLIED_EXTS_RULE_END
2731 },
2732 };
2733
2734 static RISCVCPUImpliedExtsRule ZVFBFWMA_IMPLIED = {
2735 .ext = CPU_CFG_OFFSET(ext_zvfbfwma),
2736 .implied_multi_exts = {
2737 CPU_CFG_OFFSET(ext_zvfbfmin), CPU_CFG_OFFSET(ext_zfbfmin),
2738
2739 RISCV_IMPLIED_EXTS_RULE_END
2740 },
2741 };
2742
2743 static RISCVCPUImpliedExtsRule ZVFH_IMPLIED = {
2744 .ext = CPU_CFG_OFFSET(ext_zvfh),
2745 .implied_multi_exts = {
2746 CPU_CFG_OFFSET(ext_zvfhmin), CPU_CFG_OFFSET(ext_zfhmin),
2747
2748 RISCV_IMPLIED_EXTS_RULE_END
2749 },
2750 };
2751
2752 static RISCVCPUImpliedExtsRule ZVFHMIN_IMPLIED = {
2753 .ext = CPU_CFG_OFFSET(ext_zvfhmin),
2754 .implied_multi_exts = {
2755 CPU_CFG_OFFSET(ext_zve32f),
2756
2757 RISCV_IMPLIED_EXTS_RULE_END
2758 },
2759 };
2760
2761 static RISCVCPUImpliedExtsRule ZVKN_IMPLIED = {
2762 .ext = CPU_CFG_OFFSET(ext_zvkn),
2763 .implied_multi_exts = {
2764 CPU_CFG_OFFSET(ext_zvkned), CPU_CFG_OFFSET(ext_zvknhb),
2765 CPU_CFG_OFFSET(ext_zvkb), CPU_CFG_OFFSET(ext_zvkt),
2766
2767 RISCV_IMPLIED_EXTS_RULE_END
2768 },
2769 };
2770
2771 static RISCVCPUImpliedExtsRule ZVKNC_IMPLIED = {
2772 .ext = CPU_CFG_OFFSET(ext_zvknc),
2773 .implied_multi_exts = {
2774 CPU_CFG_OFFSET(ext_zvkn), CPU_CFG_OFFSET(ext_zvbc),
2775
2776 RISCV_IMPLIED_EXTS_RULE_END
2777 },
2778 };
2779
2780 static RISCVCPUImpliedExtsRule ZVKNG_IMPLIED = {
2781 .ext = CPU_CFG_OFFSET(ext_zvkng),
2782 .implied_multi_exts = {
2783 CPU_CFG_OFFSET(ext_zvkn), CPU_CFG_OFFSET(ext_zvkg),
2784
2785 RISCV_IMPLIED_EXTS_RULE_END
2786 },
2787 };
2788
2789 static RISCVCPUImpliedExtsRule ZVKNHB_IMPLIED = {
2790 .ext = CPU_CFG_OFFSET(ext_zvknhb),
2791 .implied_multi_exts = {
2792 CPU_CFG_OFFSET(ext_zve64x), CPU_CFG_OFFSET(ext_zvknha),
2793
2794 RISCV_IMPLIED_EXTS_RULE_END
2795 },
2796 };
2797
2798 static RISCVCPUImpliedExtsRule ZVKS_IMPLIED = {
2799 .ext = CPU_CFG_OFFSET(ext_zvks),
2800 .implied_multi_exts = {
2801 CPU_CFG_OFFSET(ext_zvksed), CPU_CFG_OFFSET(ext_zvksh),
2802 CPU_CFG_OFFSET(ext_zvkb), CPU_CFG_OFFSET(ext_zvkt),
2803
2804 RISCV_IMPLIED_EXTS_RULE_END
2805 },
2806 };
2807
2808 static RISCVCPUImpliedExtsRule ZVKSC_IMPLIED = {
2809 .ext = CPU_CFG_OFFSET(ext_zvksc),
2810 .implied_multi_exts = {
2811 CPU_CFG_OFFSET(ext_zvks), CPU_CFG_OFFSET(ext_zvbc),
2812
2813 RISCV_IMPLIED_EXTS_RULE_END
2814 },
2815 };
2816
2817 static RISCVCPUImpliedExtsRule ZVKSG_IMPLIED = {
2818 .ext = CPU_CFG_OFFSET(ext_zvksg),
2819 .implied_multi_exts = {
2820 CPU_CFG_OFFSET(ext_zvks), CPU_CFG_OFFSET(ext_zvkg),
2821
2822 RISCV_IMPLIED_EXTS_RULE_END
2823 },
2824 };
2825
2826 static RISCVCPUImpliedExtsRule SHA_IMPLIED = {
2827 .ext = CPU_CFG_OFFSET(ext_sha),
2828 .implied_misa_exts = RVH,
2829 .implied_multi_exts = {
2830 CPU_CFG_OFFSET(ext_smstateen),
2831 CPU_CFG_OFFSET(ext_ssstateen),
2832
2833 RISCV_IMPLIED_EXTS_RULE_END
2834 },
2835 };
2836
2837 static RISCVCPUImpliedExtsRule SSCFG_IMPLIED = {
2838 .ext = CPU_CFG_OFFSET(ext_ssccfg),
2839 .implied_multi_exts = {
2840 CPU_CFG_OFFSET(ext_smcsrind), CPU_CFG_OFFSET(ext_sscsrind),
2841 CPU_CFG_OFFSET(ext_smcdeleg),
2842
2843 RISCV_IMPLIED_EXTS_RULE_END
2844 },
2845 };
2846
2847 static RISCVCPUImpliedExtsRule SUPM_IMPLIED = {
2848 .ext = CPU_CFG_OFFSET(ext_supm),
2849 .implied_multi_exts = {
2850 CPU_CFG_OFFSET(ext_ssnpm), CPU_CFG_OFFSET(ext_smnpm),
2851
2852 RISCV_IMPLIED_EXTS_RULE_END
2853 },
2854 };
2855
2856 static RISCVCPUImpliedExtsRule SSPM_IMPLIED = {
2857 .ext = CPU_CFG_OFFSET(ext_sspm),
2858 .implied_multi_exts = {
2859 CPU_CFG_OFFSET(ext_smnpm),
2860
2861 RISCV_IMPLIED_EXTS_RULE_END
2862 },
2863 };
2864
2865 static RISCVCPUImpliedExtsRule SMCTR_IMPLIED = {
2866 .ext = CPU_CFG_OFFSET(ext_smctr),
2867 .implied_misa_exts = RVS,
2868 .implied_multi_exts = {
2869 CPU_CFG_OFFSET(ext_sscsrind),
2870
2871 RISCV_IMPLIED_EXTS_RULE_END
2872 },
2873 };
2874
2875 static RISCVCPUImpliedExtsRule SSCTR_IMPLIED = {
2876 .ext = CPU_CFG_OFFSET(ext_ssctr),
2877 .implied_misa_exts = RVS,
2878 .implied_multi_exts = {
2879 CPU_CFG_OFFSET(ext_sscsrind),
2880
2881 RISCV_IMPLIED_EXTS_RULE_END
2882 },
2883 };
2884
2885 static RISCVCPUImpliedExtsRule SSSTATEEN_IMPLIED = {
2886 .ext = CPU_CFG_OFFSET(ext_ssstateen),
2887 .implied_multi_exts = {
2888 CPU_CFG_OFFSET(ext_smstateen),
2889
2890 RISCV_IMPLIED_EXTS_RULE_END
2891 },
2892 };
2893
2894 static RISCVCPUImpliedExtsRule ZVFBFA_IMPLIED = {
2895 .ext = CPU_CFG_OFFSET(ext_zvfbfa),
2896 .implied_multi_exts = {
2897 CPU_CFG_OFFSET(ext_zve32f), CPU_CFG_OFFSET(ext_zfbfmin),
2898
2899 RISCV_IMPLIED_EXTS_RULE_END
2900 },
2901 };
2902
2903 RISCVCPUImpliedExtsRule *riscv_misa_ext_implied_rules[] = {
2904 &RVA_IMPLIED, &RVD_IMPLIED, &RVF_IMPLIED,
2905 &RVM_IMPLIED, &RVV_IMPLIED, &RVG_IMPLIED,
2906 &RVB_IMPLIED, NULL
2907 };
2908
2909 RISCVCPUImpliedExtsRule *riscv_multi_ext_implied_rules[] = {
2910 &ZCB_IMPLIED, &ZCD_IMPLIED, &ZCE_IMPLIED,
2911 &ZCF_IMPLIED, &ZCMP_IMPLIED, &ZCMT_IMPLIED,
2912 &ZDINX_IMPLIED, &ZFA_IMPLIED, &ZFBFMIN_IMPLIED,
2913 &ZFH_IMPLIED, &ZFHMIN_IMPLIED, &ZFINX_IMPLIED,
2914 &ZHINX_IMPLIED, &ZHINXMIN_IMPLIED, &ZICNTR_IMPLIED,
2915 &ZIHPM_IMPLIED, &ZK_IMPLIED, &ZKN_IMPLIED,
2916 &ZKS_IMPLIED, &ZVBB_IMPLIED, &ZVE32F_IMPLIED,
2917 &ZVE32X_IMPLIED, &ZVE64D_IMPLIED, &ZVE64F_IMPLIED, &ZVE64X_IMPLIED,
2918 &ZVFBFA_IMPLIED, &ZVFBFMIN_IMPLIED, &ZVFBFWMA_IMPLIED,
2919 &ZVFH_IMPLIED, &ZVFHMIN_IMPLIED, &ZVKN_IMPLIED,
2920 &ZVKNC_IMPLIED, &ZVKNG_IMPLIED, &ZVKNHB_IMPLIED,
2921 &ZVKS_IMPLIED, &ZVKSC_IMPLIED, &ZVKSG_IMPLIED, &SHA_IMPLIED,
2922 &SSCFG_IMPLIED, &SUPM_IMPLIED, &SSPM_IMPLIED, &SMCTR_IMPLIED,
2923 &SSCTR_IMPLIED, &SSSTATEEN_IMPLIED,
2924 NULL
2925 };
2926
2927 static const Property riscv_cpu_properties[] = {
2928 DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
2929 DEFINE_PROP_BOOL("big-endian", RISCVCPU, cfg.big_endian, false),
2930
2931 {.name = "pmu-mask", .info = &prop_pmu_mask},
2932 {.name = "pmu-num", .info = &prop_pmu_num}, /* Deprecated */
2933
2934 {.name = "mmu", .info = &prop_mmu},
2935 #ifndef CONFIG_USER_ONLY
2936 {.name = "pmp", .info = &prop_pmp},
2937 {.name = "num-pmp-regions", .info = &prop_num_pmp_regions},
2938 {.name = "pmp-granularity", .info = &prop_pmp_granularity},
2939 #endif
2940
2941 {.name = "priv_spec", .info = &prop_priv_spec},
2942 {.name = "vext_spec", .info = &prop_vext_spec},
2943
2944 {.name = "vlen", .info = &prop_vlen},
2945 {.name = "elen", .info = &prop_elen},
2946
2947 {.name = "cbom_blocksize", .info = &prop_cbom_blksize},
2948 {.name = "cbop_blocksize", .info = &prop_cbop_blksize},
2949 {.name = "cboz_blocksize", .info = &prop_cboz_blksize},
2950
2951 {.name = "mvendorid", .info = &prop_mvendorid},
2952 {.name = "mimpid", .info = &prop_mimpid},
2953 {.name = "marchid", .info = &prop_marchid},
2954
2955 #ifndef CONFIG_USER_ONLY
2956 DEFINE_PROP_UINT64("resetvec", RISCVCPU, env.resetvec, DEFAULT_RSTVEC),
2957 DEFINE_PROP_UINT64("rnmi-interrupt-vector", RISCVCPU, env.rnmi_irqvec,
2958 DEFAULT_RNMI_IRQVEC),
2959 DEFINE_PROP_UINT64("rnmi-exception-vector", RISCVCPU, env.rnmi_excpvec,
2960 DEFAULT_RNMI_EXCPVEC),
2961 DEFINE_PROP_UINT32("num-triggers", RISCVCPU, env.num_triggers,
2962 RV_DEFAULT_NUM_TRIGGERS),
2963 #endif
2964
2965 DEFINE_PROP_BOOL("short-isa-string", RISCVCPU, cfg.short_isa_string, false),
2966
2967 DEFINE_PROP_BOOL("rvv_ta_all_1s", RISCVCPU, cfg.rvv_ta_all_1s, false),
2968 DEFINE_PROP_BOOL("rvv_ma_all_1s", RISCVCPU, cfg.rvv_ma_all_1s, false),
2969 DEFINE_PROP_BOOL("rvv_vl_half_avl", RISCVCPU, cfg.rvv_vl_half_avl, false),
2970 DEFINE_PROP_BOOL("rvv_vsetvl_x0_vill", RISCVCPU, cfg.rvv_vsetvl_x0_vill, false),
2971
2972 /*
2973 * write_misa() is marked as experimental for now so mark
2974 * it with -x and default to 'false'.
2975 */
2976 DEFINE_PROP_BOOL("x-misa-w", RISCVCPU, cfg.misa_w, false),
2977 };
2978
2979 static const gchar *riscv_gdb_arch_name(CPUState *cs)
2980 {
2981 RISCVCPU *cpu = RISCV_CPU(cs);
2982 CPURISCVState *env = &cpu->env;
2983
2984 switch (riscv_cpu_mxl(env)) {
2985 case MXL_RV32:
2986 return "riscv:rv32";
2987 case MXL_RV64:
2988 case MXL_RV128:
2989 return "riscv:rv64";
2990 default:
2991 g_assert_not_reached();
2992 }
2993 }
2994
2995 #ifndef CONFIG_USER_ONLY
2996 static int64_t riscv_get_arch_id(CPUState *cs)
2997 {
2998 RISCVCPU *cpu = RISCV_CPU(cs);
2999
3000 return cpu->env.mhartid;
3001 }
3002
3003 #include "hw/core/sysemu-cpu-ops.h"
3004
3005 static const struct SysemuCPUOps riscv_sysemu_ops = {
3006 .has_work = riscv_cpu_has_work,
3007 .write_elf64_note = riscv_cpu_write_elf64_note,
3008 .write_elf32_note = riscv_cpu_write_elf32_note,
3009 .legacy_vmsd = &vmstate_riscv_cpu,
3010 #ifdef CONFIG_TCG
3011 .translate_for_debug = riscv_cpu_translate_for_debug,
3012 .monitor_get_register = riscv_monitor_get_register_legacy,
3013 #endif
3014 };
3015 #endif
3016
3017 static void riscv_cpu_common_class_init(ObjectClass *c, const void *data)
3018 {
3019 RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
3020 CPUClass *cc = CPU_CLASS(c);
3021 DeviceClass *dc = DEVICE_CLASS(c);
3022 ResettableClass *rc = RESETTABLE_CLASS(c);
3023
3024 device_class_set_parent_realize(dc, riscv_cpu_realize,
3025 &mcc->parent_realize);
3026 device_class_set_parent_unrealize(dc, riscv_cpu_unrealize,
3027 &mcc->parent_unrealize);
3028
3029 resettable_class_set_parent_phases(rc, NULL, riscv_cpu_reset_hold, NULL,
3030 &mcc->parent_phases);
3031
3032 cc->class_by_name = riscv_cpu_class_by_name;
3033 cc->dump_state = riscv_cpu_dump_state;
3034 cc->set_pc = riscv_cpu_set_pc;
3035 cc->get_pc = riscv_cpu_get_pc;
3036 cc->gdb_read_register = riscv_cpu_gdb_read_register;
3037 cc->gdb_write_register = riscv_cpu_gdb_write_register;
3038 cc->gdb_stop_before_watchpoint = true;
3039 cc->disas_set_info = riscv_cpu_disas_set_info;
3040 #ifndef CONFIG_USER_ONLY
3041 cc->sysemu_ops = &riscv_sysemu_ops;
3042 cc->get_arch_id = riscv_get_arch_id;
3043 #endif
3044 cc->gdb_arch_name = riscv_gdb_arch_name;
3045 #ifdef CONFIG_TCG
3046 cc->tcg_ops = &riscv_tcg_ops;
3047 #endif /* CONFIG_TCG */
3048
3049 device_class_set_props(dc, riscv_cpu_properties);
3050 }
3051
3052 static bool profile_extends(RISCVCPUProfile *trial, RISCVCPUProfile *parent)
3053 {
3054 RISCVCPUProfile *curr;
3055 if (!parent) {
3056 return true;
3057 }
3058
3059 curr = trial;
3060 while (curr) {
3061 if (curr == parent) {
3062 return true;
3063 }
3064 curr = curr->u_parent;
3065 }
3066
3067 curr = trial;
3068 while (curr) {
3069 if (curr == parent) {
3070 return true;
3071 }
3072 curr = curr->s_parent;
3073 }
3074
3075 return false;
3076 }
3077
3078 static void riscv_cpu_class_base_init(ObjectClass *c, const void *data)
3079 {
3080 RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
3081 RISCVCPUClass *pcc = RISCV_CPU_CLASS(object_class_get_parent(c));
3082
3083 if (pcc->def) {
3084 mcc->def = g_memdup2(pcc->def, sizeof(*pcc->def));
3085 } else {
3086 mcc->def = g_new0(RISCVCPUDef, 1);
3087 }
3088
3089 if (data) {
3090 const RISCVCPUDef *def = data;
3091 mcc->def->bare |= def->bare;
3092 if (def->profile) {
3093 assert(profile_extends(def->profile, mcc->def->profile));
3094 assert(mcc->def->bare);
3095 mcc->def->profile = def->profile;
3096 }
3097 if (def->misa_mxl_max) {
3098 assert(def->misa_mxl_max <= MXL_RV128);
3099 mcc->def->misa_mxl_max = def->misa_mxl_max;
3100
3101 #ifndef CONFIG_USER_ONLY
3102 /*
3103 * Hack to simplify CPU class hierarchies that include both 32- and
3104 * 64-bit models: reduce SV39/48/57/64 to SV32 for 32-bit models.
3105 */
3106 if (mcc->def->misa_mxl_max == MXL_RV32 &&
3107 !valid_vm_1_10_32[mcc->def->cfg.max_satp_mode]) {
3108 mcc->def->cfg.max_satp_mode = VM_1_10_SV32;
3109 }
3110
3111 if (def->num_triggers) {
3112 mcc->def->num_triggers = def->num_triggers;
3113 }
3114 #endif
3115 }
3116 if (def->priv_spec != RISCV_PROFILE_ATTR_UNUSED) {
3117 assert(def->priv_spec <= PRIV_VERSION_LATEST);
3118 mcc->def->priv_spec = def->priv_spec;
3119 }
3120 if (def->vext_spec != RISCV_PROFILE_ATTR_UNUSED) {
3121 assert(def->vext_spec != 0);
3122 mcc->def->vext_spec = def->vext_spec;
3123 }
3124 mcc->def->misa_ext |= def->misa_ext;
3125
3126 riscv_cpu_cfg_merge(&mcc->def->cfg, &def->cfg);
3127
3128 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
3129 if (def->custom_csrs) {
3130 assert(!mcc->def->custom_csrs);
3131 mcc->def->custom_csrs = def->custom_csrs;
3132 }
3133 #endif
3134 }
3135
3136 if (!object_class_is_abstract(c)) {
3137 riscv_cpu_validate_misa_mxl(mcc);
3138 }
3139 }
3140
3141 static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str,
3142 int max_str_len)
3143 {
3144 const RISCVIsaExtData *edata;
3145 char *old = *isa_str;
3146 char *new = *isa_str;
3147
3148 for (edata = isa_edata_arr; edata && edata->name; edata++) {
3149 if (isa_ext_is_enabled(cpu, edata->ext_enable_offset)) {
3150 new = g_strconcat(old, "_", edata->name, NULL);
3151 g_free(old);
3152 old = new;
3153 }
3154 }
3155
3156 *isa_str = new;
3157 }
3158
3159 char *riscv_isa_string(RISCVCPU *cpu)
3160 {
3161 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
3162 int i;
3163 const size_t maxlen = sizeof("rv128") + sizeof(riscv_single_letter_exts);
3164 char *isa_str = g_new(char, maxlen);
3165 int xlen = riscv_cpu_max_xlen(mcc);
3166 char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", xlen);
3167
3168 for (i = 0; i < sizeof(riscv_single_letter_exts) - 1; i++) {
3169 if (cpu->env.misa_ext & RV(riscv_single_letter_exts[i])) {
3170 *p++ = qemu_tolower(riscv_single_letter_exts[i]);
3171 }
3172 }
3173 *p = '\0';
3174 if (!cpu->cfg.short_isa_string) {
3175 riscv_isa_string_ext(cpu, &isa_str, maxlen);
3176 }
3177 return isa_str;
3178 }
3179
3180 #ifndef CONFIG_USER_ONLY
3181 static char **riscv_isa_extensions_list(RISCVCPU *cpu, int *count)
3182 {
3183 int maxlen = ARRAY_SIZE(riscv_single_letter_exts) + ARRAY_SIZE(isa_edata_arr);
3184 char **extensions = g_new(char *, maxlen);
3185
3186 for (int i = 0; i < sizeof(riscv_single_letter_exts) - 1; i++) {
3187 if (cpu->env.misa_ext & RV(riscv_single_letter_exts[i])) {
3188 extensions[*count] = g_new(char, 2);
3189 snprintf(extensions[*count], 2, "%c",
3190 qemu_tolower(riscv_single_letter_exts[i]));
3191 (*count)++;
3192 }
3193 }
3194
3195 for (const RISCVIsaExtData *edata = isa_edata_arr; edata->name; edata++) {
3196 if (isa_ext_is_enabled(cpu, edata->ext_enable_offset)) {
3197 extensions[*count] = g_strdup(edata->name);
3198 (*count)++;
3199 }
3200 }
3201
3202 return extensions;
3203 }
3204
3205 void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char *nodename)
3206 {
3207 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
3208 const size_t maxlen = sizeof("rv128i");
3209 g_autofree char *isa_base = g_new(char, maxlen);
3210 g_autofree char *riscv_isa;
3211 char **isa_extensions;
3212 int count = 0;
3213 int xlen = riscv_cpu_max_xlen(mcc);
3214
3215 riscv_isa = riscv_isa_string(cpu);
3216 qemu_fdt_setprop_string(fdt, nodename, "riscv,isa", riscv_isa);
3217
3218 snprintf(isa_base, maxlen, "rv%di", xlen & 0xFF);
3219 qemu_fdt_setprop_string(fdt, nodename, "riscv,isa-base", isa_base);
3220
3221 isa_extensions = riscv_isa_extensions_list(cpu, &count);
3222 qemu_fdt_setprop_string_array(fdt, nodename, "riscv,isa-extensions",
3223 isa_extensions, count);
3224
3225 for (int i = 0; i < count; i++) {
3226 g_free(isa_extensions[i]);
3227 }
3228
3229 g_free(isa_extensions);
3230 }
3231 #endif
3232
3233 #define DEFINE_ABSTRACT_RISCV_CPU(type_name, parent_type_name, ...) \
3234 { \
3235 .name = (type_name), \
3236 .parent = (parent_type_name), \
3237 .abstract = true, \
3238 .class_data = &(const RISCVCPUDef) { \
3239 .priv_spec = RISCV_PROFILE_ATTR_UNUSED, \
3240 .vext_spec = RISCV_PROFILE_ATTR_UNUSED, \
3241 .cfg.max_satp_mode = -1, \
3242 __VA_ARGS__ \
3243 }, \
3244 }
3245
3246 #define DEFINE_RISCV_CPU(type_name, parent_type_name, ...) \
3247 { \
3248 .name = (type_name), \
3249 .parent = (parent_type_name), \
3250 .class_data = &(const RISCVCPUDef) { \
3251 .priv_spec = RISCV_PROFILE_ATTR_UNUSED, \
3252 .vext_spec = RISCV_PROFILE_ATTR_UNUSED, \
3253 .cfg.max_satp_mode = -1, \
3254 __VA_ARGS__ \
3255 }, \
3256 }
3257
3258 #define DEFINE_PROFILE_CPU(type_name, parent_type_name, profile_) \
3259 DEFINE_RISCV_CPU(type_name, parent_type_name, \
3260 .profile = &(profile_))
3261
3262 static void riscv_cpu_instance_finalize(Object *obj)
3263 {
3264 RISCVCPU *cpu = RISCV_CPU(obj);
3265
3266 #ifndef CONFIG_USER_ONLY
3267 g_clear_pointer(&cpu->pmu_timer, timer_free);
3268 g_clear_pointer(&cpu->pmu_event_ctr_map, g_hash_table_destroy);
3269 #endif
3270 g_clear_pointer(&cpu->user_options, g_hash_table_destroy);
3271 }
3272
3273 static const TypeInfo riscv_cpu_type_infos[] = {
3274 {
3275 .name = TYPE_RISCV_CPU,
3276 .parent = TYPE_CPU,
3277 .instance_size = sizeof(RISCVCPU),
3278 .instance_align = __alignof(RISCVCPU),
3279 .instance_init = riscv_cpu_init,
3280 .instance_finalize = riscv_cpu_instance_finalize,
3281 .abstract = true,
3282 .class_size = sizeof(RISCVCPUClass),
3283 .class_init = riscv_cpu_common_class_init,
3284 .class_base_init = riscv_cpu_class_base_init,
3285 },
3286
3287 DEFINE_ABSTRACT_RISCV_CPU(TYPE_RISCV_DYNAMIC_CPU, TYPE_RISCV_CPU,
3288 .cfg.mmu = true,
3289 .cfg.pmp = true,
3290 .priv_spec = PRIV_VERSION_LATEST,
3291 ),
3292
3293 DEFINE_ABSTRACT_RISCV_CPU(TYPE_RISCV_VENDOR_CPU, TYPE_RISCV_CPU),
3294 DEFINE_ABSTRACT_RISCV_CPU(TYPE_RISCV_BARE_CPU, TYPE_RISCV_CPU,
3295 /*
3296 * Bare CPUs do not inherit the timer and performance
3297 * counters from the parent class (see riscv_cpu_init()
3298 * for info on why the parent enables them).
3299 *
3300 * Users have to explicitly enable these counters for
3301 * bare CPUs.
3302 */
3303 .bare = true,
3304
3305 /* Set to QEMU's first supported priv version */
3306 .priv_spec = PRIV_VERSION_1_10_0,
3307
3308 /*
3309 * Support all available satp_mode settings. By default
3310 * only MBARE will be available if the user doesn't enable
3311 * a mode manually (see riscv_cpu_satp_mode_finalize()).
3312 */
3313 #ifdef TARGET_RISCV32
3314 .cfg.max_satp_mode = VM_1_10_SV32,
3315 #else
3316 .cfg.max_satp_mode = VM_1_10_SV57,
3317 #endif
3318 ),
3319
3320 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_MAX, TYPE_RISCV_DYNAMIC_CPU,
3321 #if defined(TARGET_RISCV32)
3322 .misa_mxl_max = MXL_RV32,
3323 .cfg.max_satp_mode = VM_1_10_SV32,
3324 #elif defined(TARGET_RISCV64)
3325 .misa_mxl_max = MXL_RV64,
3326 .cfg.max_satp_mode = VM_1_10_SV57,
3327 #endif
3328 ),
3329
3330 DEFINE_ABSTRACT_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_E, TYPE_RISCV_VENDOR_CPU,
3331 .misa_ext = RVI | RVM | RVA | RVC | RVU,
3332 .priv_spec = PRIV_VERSION_1_10_0,
3333 .cfg.max_satp_mode = VM_1_10_MBARE,
3334 .cfg.ext_zifencei = true,
3335 .cfg.ext_zicsr = true,
3336 .cfg.pmp = true,
3337 .cfg.pmp_regions = 8
3338 ),
3339
3340 DEFINE_ABSTRACT_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_U, TYPE_RISCV_VENDOR_CPU,
3341 .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU,
3342 .priv_spec = PRIV_VERSION_1_10_0,
3343
3344 .cfg.max_satp_mode = VM_1_10_SV39,
3345 .cfg.ext_zifencei = true,
3346 .cfg.ext_zicsr = true,
3347 .cfg.mmu = true,
3348 .cfg.pmp = true,
3349 .cfg.pmp_regions = 8
3350 ),
3351
3352 #if defined(TARGET_RISCV32) || \
3353 (defined(TARGET_RISCV64) && !defined(CONFIG_USER_ONLY))
3354 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_BASE32, TYPE_RISCV_DYNAMIC_CPU,
3355 .cfg.max_satp_mode = VM_1_10_SV32,
3356 .misa_mxl_max = MXL_RV32,
3357
3358 /* Default extensions as of QEMU 11.1. */
3359 .cfg.ext_zicbom = true,
3360 .cfg.ext_zicbop = true,
3361 .cfg.ext_zicboz = true,
3362 .cfg.ext_zicclsm = true,
3363 .cfg.ext_zicntr = true,
3364 .cfg.ext_zicsr = true,
3365 .cfg.ext_zifencei = true,
3366 .cfg.ext_zihintntl = true,
3367 .cfg.ext_zihintpause = true,
3368 .cfg.ext_zihpm = true,
3369 .cfg.ext_zawrs = true,
3370 .cfg.ext_zfa = true,
3371 .cfg.ext_zba = true,
3372 .cfg.ext_zbb = true,
3373 .cfg.ext_zbc = true,
3374 .cfg.ext_zbs = true,
3375 .cfg.ext_sstc = true,
3376 .cfg.ext_svadu = true,
3377 .cfg.ext_svvptc = true,
3378 ),
3379
3380 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_IBEX, TYPE_RISCV_VENDOR_CPU,
3381 .misa_mxl_max = MXL_RV32,
3382 .misa_ext = RVI | RVM | RVC | RVU,
3383 .priv_spec = PRIV_VERSION_1_12_0,
3384 .cfg.max_satp_mode = VM_1_10_MBARE,
3385 .cfg.ext_zifencei = true,
3386 .cfg.ext_zicsr = true,
3387 .cfg.pmp = true,
3388 .cfg.ext_smepmp = true,
3389
3390 .cfg.ext_zba = true,
3391 .cfg.ext_zbb = true,
3392 .cfg.ext_zbc = true,
3393 .cfg.ext_zbs = true,
3394 .cfg.ext_xlrbr = true
3395 ),
3396
3397 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_E31, TYPE_RISCV_CPU_SIFIVE_E,
3398 .misa_mxl_max = MXL_RV32
3399 ),
3400 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_E34, TYPE_RISCV_CPU_SIFIVE_E,
3401 .misa_mxl_max = MXL_RV32,
3402 .misa_ext = RVF, /* IMAFCU */
3403 ),
3404
3405 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_U34, TYPE_RISCV_CPU_SIFIVE_U,
3406 .misa_mxl_max = MXL_RV32,
3407 ),
3408
3409 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_RV32I, TYPE_RISCV_BARE_CPU,
3410 .misa_mxl_max = MXL_RV32,
3411 .misa_ext = RVI
3412 ),
3413 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_RV32E, TYPE_RISCV_BARE_CPU,
3414 .misa_mxl_max = MXL_RV32,
3415 .misa_ext = RVE
3416 ),
3417 #endif
3418
3419 #if (defined(TARGET_RISCV64) && !defined(CONFIG_USER_ONLY))
3420 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_MAX32, TYPE_RISCV_DYNAMIC_CPU,
3421 .cfg.max_satp_mode = VM_1_10_SV32,
3422 .misa_mxl_max = MXL_RV32,
3423 ),
3424 #endif
3425
3426 #if defined(TARGET_RISCV64)
3427 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_BASE64, TYPE_RISCV_DYNAMIC_CPU,
3428 .cfg.max_satp_mode = VM_1_10_SV57,
3429 .misa_mxl_max = MXL_RV64,
3430
3431 /* Default extensions as of QEMU 11.1. */
3432 .cfg.ext_zicbom = true,
3433 .cfg.ext_zicbop = true,
3434 .cfg.ext_zicboz = true,
3435 .cfg.ext_zicclsm = true,
3436 .cfg.ext_zicntr = true,
3437 .cfg.ext_zicsr = true,
3438 .cfg.ext_zifencei = true,
3439 .cfg.ext_zihintntl = true,
3440 .cfg.ext_zihintpause = true,
3441 .cfg.ext_zihpm = true,
3442 .cfg.ext_zawrs = true,
3443 .cfg.ext_zfa = true,
3444 .cfg.ext_zba = true,
3445 .cfg.ext_zbb = true,
3446 .cfg.ext_zbc = true,
3447 .cfg.ext_zbs = true,
3448 .cfg.ext_sstc = true,
3449 .cfg.ext_svadu = true,
3450 .cfg.ext_svvptc = true,
3451 ),
3452
3453 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_E51, TYPE_RISCV_CPU_SIFIVE_E,
3454 .misa_mxl_max = MXL_RV64
3455 ),
3456
3457 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_U54, TYPE_RISCV_CPU_SIFIVE_U,
3458 .misa_mxl_max = MXL_RV64,
3459 ),
3460
3461 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_SHAKTI_C, TYPE_RISCV_CPU_SIFIVE_U,
3462 .misa_mxl_max = MXL_RV64,
3463 ),
3464
3465 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_THEAD_C906, TYPE_RISCV_VENDOR_CPU,
3466 .misa_mxl_max = MXL_RV64,
3467 .misa_ext = RVG | RVC | RVS | RVU,
3468 .priv_spec = PRIV_VERSION_1_11_0,
3469
3470 .cfg.ext_zfa = true,
3471 .cfg.ext_zfh = true,
3472 .cfg.mmu = true,
3473 .cfg.ext_xtheadba = true,
3474 .cfg.ext_xtheadbb = true,
3475 .cfg.ext_xtheadbs = true,
3476 .cfg.ext_xtheadcmo = true,
3477 .cfg.ext_xtheadcondmov = true,
3478 .cfg.ext_xtheadfmemidx = true,
3479 .cfg.ext_xtheadmac = true,
3480 .cfg.ext_xtheadmemidx = true,
3481 .cfg.ext_xtheadmempair = true,
3482 .cfg.ext_xtheadsync = true,
3483 .cfg.pmp = true,
3484
3485 .cfg.mvendorid = THEAD_VENDOR_ID,
3486
3487 .cfg.max_satp_mode = VM_1_10_SV39,
3488 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
3489 .custom_csrs = th_csr_list,
3490 #endif
3491 ),
3492
3493 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_THEAD_C908, TYPE_RISCV_VENDOR_CPU,
3494 .misa_mxl_max = MXL_RV64,
3495 .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU,
3496 .priv_spec = PRIV_VERSION_1_12_0,
3497
3498 /* ISA extensions */
3499 .cfg.ext_xtheadba = true,
3500 .cfg.ext_xtheadbb = true,
3501 .cfg.ext_xtheadbs = true,
3502 .cfg.ext_xtheadcmo = true,
3503 .cfg.ext_xtheadcondmov = true,
3504 .cfg.ext_xtheadfmv = true,
3505 .cfg.ext_xtheadfmemidx = true,
3506 .cfg.ext_xtheadmac = true,
3507 .cfg.ext_xtheadmemidx = true,
3508 .cfg.ext_xtheadmempair = true,
3509 .cfg.ext_xtheadsync = true,
3510 .cfg.ext_smepmp = true,
3511 .cfg.ext_sscofpmf = true,
3512 .cfg.ext_sstc = true,
3513 .cfg.ext_svpbmt = true,
3514 .cfg.ext_svinval = true,
3515 .cfg.ext_svnapot = true,
3516 .cfg.ext_zba = true,
3517 .cfg.ext_zbb = true,
3518 .cfg.ext_zbc = true,
3519 .cfg.ext_zbs = true,
3520 .cfg.ext_zkt = true,
3521 .cfg.ext_zbkc = true,
3522 .cfg.ext_zicclsm = true,
3523 .cfg.ext_zicsr = true,
3524 .cfg.ext_zifencei = true,
3525 .cfg.ext_zihintpause = true,
3526 .cfg.ext_zicbom = true,
3527 .cfg.ext_zicboz = true,
3528
3529 .cfg.pmp = true,
3530 .cfg.mmu = true,
3531 .cfg.max_satp_mode = VM_1_10_SV48,
3532
3533 .cfg.marchid = 0x8d143000,
3534 .cfg.mvendorid = THEAD_VENDOR_ID,
3535 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
3536 .custom_csrs = th_csr_list,
3537 #endif
3538 ),
3539
3540 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_THEAD_C908V, TYPE_RISCV_CPU_THEAD_C908,
3541 .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU | RVV,
3542 .vext_spec = VEXT_VERSION_1_00_0,
3543 ),
3544
3545 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_TT_ASCALON, TYPE_RISCV_VENDOR_CPU,
3546 .misa_mxl_max = MXL_RV64,
3547 .misa_ext = RVG | RVC | RVS | RVU | RVH | RVV,
3548 .priv_spec = PRIV_VERSION_1_13_0,
3549 .vext_spec = VEXT_VERSION_1_00_0,
3550
3551 /* ISA extensions */
3552 .cfg.mmu = true,
3553 .cfg.vlenb = 256 >> 3,
3554 .cfg.elen = 64,
3555 .cfg.rvv_ma_all_1s = true,
3556 .cfg.rvv_ta_all_1s = true,
3557 .cfg.misa_w = true,
3558 .cfg.pmp = true,
3559 .cfg.cbom_blocksize = 64,
3560 .cfg.cbop_blocksize = 64,
3561 .cfg.cboz_blocksize = 64,
3562 .cfg.ext_zic64b = true,
3563 .cfg.ext_zicbom = true,
3564 .cfg.ext_zicbop = true,
3565 .cfg.ext_zicboz = true,
3566 .cfg.ext_zicclsm = true,
3567 .cfg.ext_zicntr = true,
3568 .cfg.ext_zicond = true,
3569 .cfg.ext_zicsr = true,
3570 .cfg.ext_zifencei = true,
3571 .cfg.ext_zihintntl = true,
3572 .cfg.ext_zihintpause = true,
3573 .cfg.ext_zihpm = true,
3574 .cfg.ext_zimop = true,
3575 .cfg.ext_zawrs = true,
3576 .cfg.ext_zfa = true,
3577 .cfg.ext_zfbfmin = true,
3578 .cfg.ext_zfh = true,
3579 .cfg.ext_zfhmin = true,
3580 .cfg.ext_zcb = true,
3581 .cfg.ext_zcmop = true,
3582 .cfg.ext_zba = true,
3583 .cfg.ext_zbb = true,
3584 .cfg.ext_zbs = true,
3585 .cfg.ext_zkr = true,
3586 .cfg.ext_zkt = true,
3587 .cfg.ext_zvbb = true,
3588 .cfg.ext_zvbc = true,
3589 .cfg.ext_zvfbfmin = true,
3590 .cfg.ext_zvfbfwma = true,
3591 .cfg.ext_zvfh = true,
3592 .cfg.ext_zvfhmin = true,
3593 .cfg.ext_zvkng = true,
3594 .cfg.ext_smaia = true,
3595 .cfg.ext_smstateen = true,
3596 .cfg.ext_ssaia = true,
3597 .cfg.ext_sscofpmf = true,
3598 .cfg.ext_sstc = true,
3599 .cfg.ext_svade = true,
3600 .cfg.ext_svinval = true,
3601 .cfg.ext_svnapot = true,
3602 .cfg.ext_svpbmt = true,
3603
3604 .cfg.mvendorid = TENSTORRENT_VENDOR_ID,
3605
3606 .cfg.max_satp_mode = VM_1_10_SV57,
3607 ),
3608
3609 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_VEYRON_V1, TYPE_RISCV_VENDOR_CPU,
3610 .misa_mxl_max = MXL_RV64,
3611 .misa_ext = RVG | RVC | RVS | RVU | RVH,
3612 .priv_spec = PRIV_VERSION_1_12_0,
3613
3614 /* ISA extensions */
3615 .cfg.mmu = true,
3616 .cfg.ext_zicclsm = true,
3617 .cfg.ext_zifencei = true,
3618 .cfg.ext_zicsr = true,
3619 .cfg.pmp = true,
3620 .cfg.ext_zicbom = true,
3621 .cfg.cbom_blocksize = 64,
3622 .cfg.cboz_blocksize = 64,
3623 .cfg.ext_zicboz = true,
3624 .cfg.ext_smaia = true,
3625 .cfg.ext_ssaia = true,
3626 .cfg.ext_sscofpmf = true,
3627 .cfg.ext_sstc = true,
3628 .cfg.ext_svinval = true,
3629 .cfg.ext_svnapot = true,
3630 .cfg.ext_svpbmt = true,
3631 .cfg.ext_smstateen = true,
3632 .cfg.ext_zba = true,
3633 .cfg.ext_zbb = true,
3634 .cfg.ext_zbc = true,
3635 .cfg.ext_zbs = true,
3636 .cfg.ext_XVentanaCondOps = true,
3637
3638 .cfg.mvendorid = VEYRON_V1_MVENDORID,
3639 .cfg.marchid = VEYRON_V1_MARCHID,
3640 .cfg.mimpid = VEYRON_V1_MIMPID,
3641
3642 .cfg.max_satp_mode = VM_1_10_SV48,
3643 ),
3644
3645 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_XIANGSHAN_NANHU, TYPE_RISCV_VENDOR_CPU,
3646 .misa_mxl_max = MXL_RV64,
3647 .misa_ext = RVG | RVC | RVB | RVS | RVU,
3648 .priv_spec = PRIV_VERSION_1_12_0,
3649
3650 /* ISA extensions */
3651 .cfg.ext_zbc = true,
3652 .cfg.ext_zbkb = true,
3653 .cfg.ext_zbkc = true,
3654 .cfg.ext_zbkx = true,
3655 .cfg.ext_zknd = true,
3656 .cfg.ext_zkne = true,
3657 .cfg.ext_zknh = true,
3658 .cfg.ext_zksed = true,
3659 .cfg.ext_zksh = true,
3660 .cfg.ext_svinval = true,
3661
3662 .cfg.mmu = true,
3663 .cfg.pmp = true,
3664
3665 .cfg.max_satp_mode = VM_1_10_SV39,
3666 ),
3667
3668 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_XIANGSHAN_KMH, TYPE_RISCV_VENDOR_CPU,
3669 .misa_mxl_max = MXL_RV64,
3670 .misa_ext = RVG | RVC | RVB | RVS | RVU | RVH | RVV,
3671 .priv_spec = PRIV_VERSION_1_13_0,
3672 /*
3673 * The RISC-V Instruction Set Manual: Volume I
3674 * Unprivileged Architecture
3675 */
3676 .cfg.ext_zicclsm = true,
3677 .cfg.ext_zicntr = true,
3678 .cfg.ext_zihpm = true,
3679 .cfg.ext_zihintntl = true,
3680 .cfg.ext_zihintpause = true,
3681 .cfg.ext_zimop = true,
3682 .cfg.ext_zcmop = true,
3683 .cfg.ext_zicond = true,
3684 .cfg.ext_zawrs = true,
3685 .cfg.ext_zacas = true,
3686 .cfg.ext_zfh = true,
3687 .cfg.ext_zfa = true,
3688 .cfg.ext_zcb = true,
3689 .cfg.ext_zbc = true,
3690 .cfg.ext_zvfh = true,
3691 .cfg.ext_zkn = true,
3692 .cfg.ext_zks = true,
3693 .cfg.ext_zkt = true,
3694 .cfg.ext_zvbb = true,
3695 .cfg.ext_zvkt = true,
3696 /*
3697 * The RISC-V Instruction Set Manual: Volume II
3698 * Privileged Architecture
3699 */
3700 .cfg.ext_smstateen = true,
3701 .cfg.ext_smcsrind = true,
3702 .cfg.ext_sscsrind = true,
3703 .cfg.ext_svnapot = true,
3704 .cfg.ext_svpbmt = true,
3705 .cfg.ext_svinval = true,
3706 .cfg.ext_sstc = true,
3707 .cfg.ext_sscofpmf = true,
3708 .cfg.ext_ssdbltrp = true,
3709 .cfg.ext_ssnpm = true,
3710 .cfg.ext_smnpm = true,
3711 .cfg.ext_smmpm = true,
3712 .cfg.ext_sspm = true,
3713 .cfg.ext_supm = true,
3714 /* The RISC-V Advanced Interrupt Architecture */
3715 .cfg.ext_smaia = true,
3716 .cfg.ext_ssaia = true,
3717 /* RVA23 Profiles */
3718 .cfg.ext_zicbom = true,
3719 .cfg.ext_zicbop = true,
3720 .cfg.ext_zicboz = true,
3721 .cfg.ext_svade = true,
3722 .cfg.mmu = true,
3723 .cfg.pmp = true,
3724 .cfg.max_satp_mode = VM_1_10_SV48,
3725 ),
3726
3727 /* https://mips.com/products/hardware/p8700/ */
3728 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_MIPS_P8700, TYPE_RISCV_VENDOR_CPU,
3729 .misa_mxl_max = MXL_RV64,
3730 .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU,
3731 .priv_spec = PRIV_VERSION_1_12_0,
3732 .cfg.max_satp_mode = VM_1_10_SV48,
3733 .cfg.ext_zicclsm = true,
3734 .cfg.ext_zifencei = true,
3735 .cfg.ext_zicsr = true,
3736 .cfg.mmu = true,
3737 .cfg.pmp = true,
3738 .cfg.ext_zba = true,
3739 .cfg.ext_zbb = true,
3740 .cfg.ext_xmipslsp = true,
3741 .cfg.ext_xmipscbop = true,
3742 .cfg.ext_xmipscmov = true,
3743 .cfg.marchid = 0x8000000000000201,
3744 .cfg.mvendorid = MIPS_VENDOR_ID,
3745 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
3746 .custom_csrs = mips_csr_list,
3747 #endif
3748 ),
3749
3750 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
3751 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_BASE128, TYPE_RISCV_DYNAMIC_CPU,
3752 .cfg.max_satp_mode = VM_1_10_SV57,
3753 .misa_mxl_max = MXL_RV128,
3754 ),
3755 #endif /* CONFIG_TCG */
3756 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_RV64I, TYPE_RISCV_BARE_CPU,
3757 .misa_mxl_max = MXL_RV64,
3758 .misa_ext = RVI
3759 ),
3760 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_RV64E, TYPE_RISCV_BARE_CPU,
3761 .misa_mxl_max = MXL_RV64,
3762 .misa_ext = RVE
3763 ),
3764
3765 DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22U64, TYPE_RISCV_CPU_RV64I, RVA22U64),
3766 DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22S64, TYPE_RISCV_CPU_RV64I, RVA22S64),
3767 DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA23U64, TYPE_RISCV_CPU_RV64I, RVA23U64),
3768 DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA23S64, TYPE_RISCV_CPU_RV64I, RVA23S64),
3769 #endif /* TARGET_RISCV64 */
3770 };
3771
3772 DEFINE_TYPES(riscv_cpu_type_infos)