]> git.proxmox.com Git - mirror_qemu.git/blame - target/riscv/cpu.c
target/riscv: move riscv_tcg_ops to tcg-cpu.c
[mirror_qemu.git] / target / riscv / cpu.c
CommitLineData
dc5bd18f
MC
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"
0442428a 21#include "qemu/qemu-print.h"
856dfd8a 22#include "qemu/ctype.h"
dc5bd18f
MC
23#include "qemu/log.h"
24#include "cpu.h"
95bd8daa 25#include "cpu_vendorid.h"
f7697f0e 26#include "internals.h"
dc5bd18f
MC
27#include "exec/exec-all.h"
28#include "qapi/error.h"
6f23aaeb 29#include "qapi/visitor.h"
b55d7d34 30#include "qemu/error-report.h"
c4e95030 31#include "hw/qdev-properties.h"
dc5bd18f 32#include "migration/vmstate.h"
135b03cb 33#include "fpu/softfloat-helpers.h"
ad40be27 34#include "sysemu/kvm.h"
eddabb6b 35#include "sysemu/tcg.h"
ad40be27 36#include "kvm_riscv.h"
0489d5bd 37#include "tcg/tcg.h"
dc5bd18f
MC
38
39/* RISC-V CPU definitions */
0e2c3770 40static const char riscv_single_letter_exts[] = "IEMAFDQCPVH";
dc5bd18f 41
a775398b
AP
42struct isa_ext_data {
43 const char *name;
9a1f054d
AP
44 int min_version;
45 int ext_enable_offset;
a775398b
AP
46};
47
ccc84a75 48#define ISA_EXT_DATA_ENTRY(_name, _min_ver, _prop) \
238fd586 49 {#_name, _min_ver, CPU_CFG_OFFSET(_prop)}
9a1f054d 50
b227f6a8
IK
51/*
52 * From vector_helper.c
53 * Note that vector data is stored in host-endian 64-bit chunks,
54 * so addressing bytes needs a host-endian fixup.
55 */
56#if HOST_BIG_ENDIAN
57#define BYTE(x) ((x) ^ 7)
58#else
59#define BYTE(x) (x)
60#endif
61
3b57254d 62/*
9a1f054d
AP
63 * Here are the ordering rules of extension naming defined by RISC-V
64 * specification :
65 * 1. All extensions should be separated from other multi-letter extensions
66 * by an underscore.
67 * 2. The first letter following the 'Z' conventionally indicates the most
68 * closely related alphabetical extension category, IMAFDQLCBKJTPVH.
69 * If multiple 'Z' extensions are named, they should be ordered first
70 * by category, then alphabetically within a category.
71 * 3. Standard supervisor-level extensions (starts with 'S') should be
72 * listed after standard unprivileged extensions. If multiple
73 * supervisor-level extensions are listed, they should be ordered
74 * alphabetically.
75 * 4. Non-standard extensions (starts with 'X') must be listed after all
76 * standard extensions. They must be separated from other multi-letter
77 * extensions by an underscore.
6508272a
DHB
78 *
79 * Single letter extensions are checked in riscv_cpu_validate_misa_priv()
80 * instead.
9a1f054d
AP
81 */
82static const struct isa_ext_data isa_edata_arr[] = {
ccc84a75
DHB
83 ISA_EXT_DATA_ENTRY(zicbom, PRIV_VERSION_1_12_0, ext_icbom),
84 ISA_EXT_DATA_ENTRY(zicboz, PRIV_VERSION_1_12_0, ext_icboz),
85 ISA_EXT_DATA_ENTRY(zicond, PRIV_VERSION_1_12_0, ext_zicond),
86 ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_icsr),
87 ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei),
0228aca2 88 ISA_EXT_DATA_ENTRY(zihintntl, PRIV_VERSION_1_10_0, ext_zihintntl),
ccc84a75 89 ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
50f94649 90 ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
ccc84a75 91 ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
a47842d1 92 ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
889caa44 93 ISA_EXT_DATA_ENTRY(zfbfmin, PRIV_VERSION_1_12_0, ext_zfbfmin),
ccc84a75
DHB
94 ISA_EXT_DATA_ENTRY(zfh, PRIV_VERSION_1_11_0, ext_zfh),
95 ISA_EXT_DATA_ENTRY(zfhmin, PRIV_VERSION_1_11_0, ext_zfhmin),
96 ISA_EXT_DATA_ENTRY(zfinx, PRIV_VERSION_1_12_0, ext_zfinx),
97 ISA_EXT_DATA_ENTRY(zdinx, PRIV_VERSION_1_12_0, ext_zdinx),
98 ISA_EXT_DATA_ENTRY(zca, PRIV_VERSION_1_12_0, ext_zca),
99 ISA_EXT_DATA_ENTRY(zcb, PRIV_VERSION_1_12_0, ext_zcb),
100 ISA_EXT_DATA_ENTRY(zcf, PRIV_VERSION_1_12_0, ext_zcf),
101 ISA_EXT_DATA_ENTRY(zcd, PRIV_VERSION_1_12_0, ext_zcd),
102 ISA_EXT_DATA_ENTRY(zce, PRIV_VERSION_1_12_0, ext_zce),
103 ISA_EXT_DATA_ENTRY(zcmp, PRIV_VERSION_1_12_0, ext_zcmp),
104 ISA_EXT_DATA_ENTRY(zcmt, PRIV_VERSION_1_12_0, ext_zcmt),
105 ISA_EXT_DATA_ENTRY(zba, PRIV_VERSION_1_12_0, ext_zba),
106 ISA_EXT_DATA_ENTRY(zbb, PRIV_VERSION_1_12_0, ext_zbb),
107 ISA_EXT_DATA_ENTRY(zbc, PRIV_VERSION_1_12_0, ext_zbc),
108 ISA_EXT_DATA_ENTRY(zbkb, PRIV_VERSION_1_12_0, ext_zbkb),
109 ISA_EXT_DATA_ENTRY(zbkc, PRIV_VERSION_1_12_0, ext_zbkc),
110 ISA_EXT_DATA_ENTRY(zbkx, PRIV_VERSION_1_12_0, ext_zbkx),
111 ISA_EXT_DATA_ENTRY(zbs, PRIV_VERSION_1_12_0, ext_zbs),
112 ISA_EXT_DATA_ENTRY(zk, PRIV_VERSION_1_12_0, ext_zk),
113 ISA_EXT_DATA_ENTRY(zkn, PRIV_VERSION_1_12_0, ext_zkn),
114 ISA_EXT_DATA_ENTRY(zknd, PRIV_VERSION_1_12_0, ext_zknd),
115 ISA_EXT_DATA_ENTRY(zkne, PRIV_VERSION_1_12_0, ext_zkne),
116 ISA_EXT_DATA_ENTRY(zknh, PRIV_VERSION_1_12_0, ext_zknh),
117 ISA_EXT_DATA_ENTRY(zkr, PRIV_VERSION_1_12_0, ext_zkr),
118 ISA_EXT_DATA_ENTRY(zks, PRIV_VERSION_1_12_0, ext_zks),
119 ISA_EXT_DATA_ENTRY(zksed, PRIV_VERSION_1_12_0, ext_zksed),
120 ISA_EXT_DATA_ENTRY(zksh, PRIV_VERSION_1_12_0, ext_zksh),
121 ISA_EXT_DATA_ENTRY(zkt, PRIV_VERSION_1_12_0, ext_zkt),
06028472 122 ISA_EXT_DATA_ENTRY(zvbb, PRIV_VERSION_1_12_0, ext_zvbb),
e13c7d3b 123 ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
ccc84a75
DHB
124 ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
125 ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
126 ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
889caa44
WL
127 ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
128 ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
ccc84a75
DHB
129 ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
130 ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
767eb035 131 ISA_EXT_DATA_ENTRY(zvkg, PRIV_VERSION_1_12_0, ext_zvkg),
e972bf22 132 ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
fcf19433
KO
133 ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
134 ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
8b045ff4 135 ISA_EXT_DATA_ENTRY(zvksed, PRIV_VERSION_1_12_0, ext_zvksed),
2350881c 136 ISA_EXT_DATA_ENTRY(zvksh, PRIV_VERSION_1_12_0, ext_zvksh),
ccc84a75
DHB
137 ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
138 ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
139 ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
03d7bbfd 140 ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, epmp),
3594e3e5 141 ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
ccc84a75
DHB
142 ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
143 ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
144 ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc),
145 ISA_EXT_DATA_ENTRY(svadu, PRIV_VERSION_1_12_0, ext_svadu),
146 ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval),
147 ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot),
148 ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt),
149 ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba),
150 ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb),
151 ISA_EXT_DATA_ENTRY(xtheadbs, PRIV_VERSION_1_11_0, ext_xtheadbs),
152 ISA_EXT_DATA_ENTRY(xtheadcmo, PRIV_VERSION_1_11_0, ext_xtheadcmo),
153 ISA_EXT_DATA_ENTRY(xtheadcondmov, PRIV_VERSION_1_11_0, ext_xtheadcondmov),
154 ISA_EXT_DATA_ENTRY(xtheadfmemidx, PRIV_VERSION_1_11_0, ext_xtheadfmemidx),
155 ISA_EXT_DATA_ENTRY(xtheadfmv, PRIV_VERSION_1_11_0, ext_xtheadfmv),
156 ISA_EXT_DATA_ENTRY(xtheadmac, PRIV_VERSION_1_11_0, ext_xtheadmac),
157 ISA_EXT_DATA_ENTRY(xtheadmemidx, PRIV_VERSION_1_11_0, ext_xtheadmemidx),
158 ISA_EXT_DATA_ENTRY(xtheadmempair, PRIV_VERSION_1_11_0, ext_xtheadmempair),
159 ISA_EXT_DATA_ENTRY(xtheadsync, PRIV_VERSION_1_11_0, ext_xtheadsync),
160 ISA_EXT_DATA_ENTRY(xventanacondops, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
9a1f054d
AP
161};
162
549cbf78
DHB
163/* Hash that stores user set extensions */
164static GHashTable *multi_ext_user_opts;
165
36c1118d 166bool isa_ext_is_enabled(RISCVCPU *cpu, uint32_t ext_offset)
9a1f054d 167{
5f2c80f1 168 bool *ext_enabled = (void *)&cpu->cfg + ext_offset;
9a1f054d
AP
169
170 return *ext_enabled;
171}
172
36c1118d 173void isa_ext_update_enabled(RISCVCPU *cpu, uint32_t ext_offset, bool en)
9a1f054d 174{
5f2c80f1 175 bool *ext_enabled = (void *)&cpu->cfg + ext_offset;
9a1f054d
AP
176
177 *ext_enabled = en;
178}
179
36c1118d 180int cpu_cfg_ext_get_min_version(uint32_t ext_offset)
997e7195
DHB
181{
182 int i;
183
184 for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
185 if (isa_edata_arr[i].ext_enable_offset != ext_offset) {
186 continue;
187 }
188
189 return isa_edata_arr[i].min_version;
190 }
191
192 g_assert_not_reached();
193}
194
36c1118d 195bool cpu_cfg_ext_is_user_set(uint32_t ext_offset)
0a9eb9b4
DHB
196{
197 return g_hash_table_contains(multi_ext_user_opts,
198 GUINT_TO_POINTER(ext_offset));
199}
200
dc5bd18f 201const char * const riscv_int_regnames[] = {
c45eff30
WL
202 "x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1",
203 "x7/t2", "x8/s0", "x9/s1", "x10/a0", "x11/a1", "x12/a2", "x13/a3",
204 "x14/a4", "x15/a5", "x16/a6", "x17/a7", "x18/s2", "x19/s3", "x20/s4",
205 "x21/s5", "x22/s6", "x23/s7", "x24/s8", "x25/s9", "x26/s10", "x27/s11",
206 "x28/t3", "x29/t4", "x30/t5", "x31/t6"
dc5bd18f
MC
207};
208
2b547084 209const char * const riscv_int_regnamesh[] = {
c45eff30
WL
210 "x0h/zeroh", "x1h/rah", "x2h/sph", "x3h/gph", "x4h/tph", "x5h/t0h",
211 "x6h/t1h", "x7h/t2h", "x8h/s0h", "x9h/s1h", "x10h/a0h", "x11h/a1h",
212 "x12h/a2h", "x13h/a3h", "x14h/a4h", "x15h/a5h", "x16h/a6h", "x17h/a7h",
213 "x18h/s2h", "x19h/s3h", "x20h/s4h", "x21h/s5h", "x22h/s6h", "x23h/s7h",
214 "x24h/s8h", "x25h/s9h", "x26h/s10h", "x27h/s11h", "x28h/t3h", "x29h/t4h",
215 "x30h/t5h", "x31h/t6h"
2b547084
FP
216};
217
dc5bd18f 218const char * const riscv_fpr_regnames[] = {
c45eff30
WL
219 "f0/ft0", "f1/ft1", "f2/ft2", "f3/ft3", "f4/ft4", "f5/ft5",
220 "f6/ft6", "f7/ft7", "f8/fs0", "f9/fs1", "f10/fa0", "f11/fa1",
221 "f12/fa2", "f13/fa3", "f14/fa4", "f15/fa5", "f16/fa6", "f17/fa7",
222 "f18/fs2", "f19/fs3", "f20/fs4", "f21/fs5", "f22/fs6", "f23/fs7",
223 "f24/fs8", "f25/fs9", "f26/fs10", "f27/fs11", "f28/ft8", "f29/ft9",
224 "f30/ft10", "f31/ft11"
dc5bd18f
MC
225};
226
b227f6a8
IK
227const char * const riscv_rvv_regnames[] = {
228 "v0", "v1", "v2", "v3", "v4", "v5", "v6",
229 "v7", "v8", "v9", "v10", "v11", "v12", "v13",
230 "v14", "v15", "v16", "v17", "v18", "v19", "v20",
231 "v21", "v22", "v23", "v24", "v25", "v26", "v27",
232 "v28", "v29", "v30", "v31"
233};
234
9a575d33 235static const char * const riscv_excp_names[] = {
dc5bd18f
MC
236 "misaligned_fetch",
237 "fault_fetch",
238 "illegal_instruction",
239 "breakpoint",
240 "misaligned_load",
241 "fault_load",
242 "misaligned_store",
243 "fault_store",
244 "user_ecall",
245 "supervisor_ecall",
246 "hypervisor_ecall",
247 "machine_ecall",
248 "exec_page_fault",
249 "load_page_fault",
250 "reserved",
fd990e86 251 "store_page_fault",
ab67a1d0
AF
252 "reserved",
253 "reserved",
254 "reserved",
255 "reserved",
256 "guest_exec_page_fault",
257 "guest_load_page_fault",
258 "reserved",
fd990e86 259 "guest_store_page_fault",
dc5bd18f
MC
260};
261
9a575d33 262static const char * const riscv_intr_names[] = {
dc5bd18f
MC
263 "u_software",
264 "s_software",
205377f8 265 "vs_software",
dc5bd18f
MC
266 "m_software",
267 "u_timer",
268 "s_timer",
205377f8 269 "vs_timer",
dc5bd18f
MC
270 "m_timer",
271 "u_external",
6cfcf775 272 "s_external",
205377f8 273 "vs_external",
dc5bd18f 274 "m_external",
426f0348
MC
275 "reserved",
276 "reserved",
277 "reserved",
278 "reserved"
dc5bd18f
MC
279};
280
dd8f244f 281static void riscv_cpu_add_user_properties(Object *obj);
b97e5a6b 282static void riscv_init_max_cpu_extensions(Object *obj);
26b2bc58 283
c51a3f5d
YJ
284const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
285{
286 if (async) {
287 return (cause < ARRAY_SIZE(riscv_intr_names)) ?
288 riscv_intr_names[cause] : "(unknown)";
289 } else {
290 return (cause < ARRAY_SIZE(riscv_excp_names)) ?
291 riscv_excp_names[cause] : "(unknown)";
292 }
293}
294
e91a7227 295static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
dc5bd18f 296{
e91a7227
RH
297 env->misa_mxl_max = env->misa_mxl = mxl;
298 env->misa_ext_mask = env->misa_ext = ext;
dc5bd18f
MC
299}
300
6f23aaeb
AG
301#ifndef CONFIG_USER_ONLY
302static uint8_t satp_mode_from_str(const char *satp_mode_str)
303{
304 if (!strncmp(satp_mode_str, "mbare", 5)) {
305 return VM_1_10_MBARE;
306 }
307
308 if (!strncmp(satp_mode_str, "sv32", 4)) {
309 return VM_1_10_SV32;
310 }
311
312 if (!strncmp(satp_mode_str, "sv39", 4)) {
313 return VM_1_10_SV39;
314 }
315
316 if (!strncmp(satp_mode_str, "sv48", 4)) {
317 return VM_1_10_SV48;
318 }
319
320 if (!strncmp(satp_mode_str, "sv57", 4)) {
321 return VM_1_10_SV57;
322 }
323
324 if (!strncmp(satp_mode_str, "sv64", 4)) {
325 return VM_1_10_SV64;
326 }
327
328 g_assert_not_reached();
329}
330
331uint8_t satp_mode_max_from_map(uint32_t map)
332{
3a2fc235
DHB
333 /*
334 * 'map = 0' will make us return (31 - 32), which C will
335 * happily overflow to UINT_MAX. There's no good result to
336 * return if 'map = 0' (e.g. returning 0 will be ambiguous
337 * with the result for 'map = 1').
338 *
339 * Assert out if map = 0. Callers will have to deal with
340 * it outside of this function.
341 */
342 g_assert(map > 0);
343
6f23aaeb
AG
344 /* map here has at least one bit set, so no problem with clz */
345 return 31 - __builtin_clz(map);
346}
347
348const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit)
349{
350 if (is_32_bit) {
351 switch (satp_mode) {
352 case VM_1_10_SV32:
353 return "sv32";
354 case VM_1_10_MBARE:
355 return "none";
356 }
357 } else {
358 switch (satp_mode) {
359 case VM_1_10_SV64:
360 return "sv64";
361 case VM_1_10_SV57:
362 return "sv57";
363 case VM_1_10_SV48:
364 return "sv48";
365 case VM_1_10_SV39:
366 return "sv39";
367 case VM_1_10_MBARE:
368 return "none";
369 }
370 }
371
372 g_assert_not_reached();
373}
374
6df3747a
AG
375static void set_satp_mode_max_supported(RISCVCPU *cpu,
376 uint8_t satp_mode)
6f23aaeb
AG
377{
378 bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32;
6df3747a 379 const bool *valid_vm = rv32 ? valid_vm_1_10_32 : valid_vm_1_10_64;
6f23aaeb 380
6df3747a
AG
381 for (int i = 0; i <= satp_mode; ++i) {
382 if (valid_vm[i]) {
383 cpu->cfg.satp_mode.supported |= (1 << i);
384 }
6f23aaeb
AG
385 }
386}
6df3747a
AG
387
388/* Set the satp mode to the max supported */
389static void set_satp_mode_default_map(RISCVCPU *cpu)
390{
391 cpu->cfg.satp_mode.map = cpu->cfg.satp_mode.supported;
392}
6f23aaeb
AG
393#endif
394
dc5bd18f
MC
395static void riscv_any_cpu_init(Object *obj)
396{
7f0bdfb5
DHB
397 RISCVCPU *cpu = RISCV_CPU(obj);
398 CPURISCVState *env = &cpu->env;
3820602f 399#if defined(TARGET_RISCV32)
e91a7227 400 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
3820602f 401#elif defined(TARGET_RISCV64)
e91a7227 402 set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
3820602f 403#endif
6df3747a
AG
404
405#ifndef CONFIG_USER_ONLY
406 set_satp_mode_max_supported(RISCV_CPU(obj),
c45eff30
WL
407 riscv_cpu_mxl(&RISCV_CPU(obj)->env) == MXL_RV32 ?
408 VM_1_10_SV32 : VM_1_10_SV57);
6df3747a
AG
409#endif
410
b9a2b98e 411 env->priv_ver = PRIV_VERSION_LATEST;
7f0bdfb5
DHB
412
413 /* inherited from parent obj via riscv_cpu_init() */
414 cpu->cfg.ext_ifencei = true;
415 cpu->cfg.ext_icsr = true;
416 cpu->cfg.mmu = true;
417 cpu->cfg.pmp = true;
dc5bd18f
MC
418}
419
b97e5a6b
DHB
420static void riscv_max_cpu_init(Object *obj)
421{
422 RISCVCPU *cpu = RISCV_CPU(obj);
423 CPURISCVState *env = &cpu->env;
424 RISCVMXL mlx = MXL_RV64;
425
426#ifdef TARGET_RISCV32
427 mlx = MXL_RV32;
428#endif
429 set_misa(env, mlx, 0);
430 riscv_cpu_add_user_properties(obj);
431 riscv_init_max_cpu_extensions(obj);
432 env->priv_ver = PRIV_VERSION_LATEST;
433#ifndef CONFIG_USER_ONLY
434 set_satp_mode_max_supported(RISCV_CPU(obj), mlx == MXL_RV32 ?
435 VM_1_10_SV32 : VM_1_10_SV57);
436#endif
437}
438
094b072c
AF
439#if defined(TARGET_RISCV64)
440static void rv64_base_cpu_init(Object *obj)
8903bf6e
AF
441{
442 CPURISCVState *env = &RISCV_CPU(obj)->env;
b55d7d34 443 /* We set this in the realise function */
e91a7227 444 set_misa(env, MXL_RV64, 0);
dd8f244f 445 riscv_cpu_add_user_properties(obj);
18800095 446 /* Set latest version of privileged specification */
b9a2b98e 447 env->priv_ver = PRIV_VERSION_LATEST;
6df3747a
AG
448#ifndef CONFIG_USER_ONLY
449 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
450#endif
8903bf6e
AF
451}
452
114baaca 453static void rv64_sifive_u_cpu_init(Object *obj)
dc5bd18f 454{
7f0bdfb5
DHB
455 RISCVCPU *cpu = RISCV_CPU(obj);
456 CPURISCVState *env = &cpu->env;
e91a7227 457 set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
8c6eeb50 458 env->priv_ver = PRIV_VERSION_1_10_0;
6df3747a
AG
459#ifndef CONFIG_USER_ONLY
460 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
461#endif
7f0bdfb5
DHB
462
463 /* inherited from parent obj via riscv_cpu_init() */
464 cpu->cfg.ext_ifencei = true;
465 cpu->cfg.ext_icsr = true;
466 cpu->cfg.mmu = true;
467 cpu->cfg.pmp = true;
dc5bd18f
MC
468}
469
114baaca 470static void rv64_sifive_e_cpu_init(Object *obj)
36b80ad9
AF
471{
472 CPURISCVState *env = &RISCV_CPU(obj)->env;
26b2bc58
AF
473 RISCVCPU *cpu = RISCV_CPU(obj);
474
e91a7227 475 set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
8c6eeb50 476 env->priv_ver = PRIV_VERSION_1_10_0;
6df3747a
AG
477#ifndef CONFIG_USER_ONLY
478 set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
479#endif
7f0bdfb5
DHB
480
481 /* inherited from parent obj via riscv_cpu_init() */
482 cpu->cfg.ext_ifencei = true;
483 cpu->cfg.ext_icsr = true;
484 cpu->cfg.pmp = true;
36b80ad9 485}
332dab68 486
95bd8daa
CM
487static void rv64_thead_c906_cpu_init(Object *obj)
488{
489 CPURISCVState *env = &RISCV_CPU(obj)->env;
490 RISCVCPU *cpu = RISCV_CPU(obj);
491
4f13abcb 492 set_misa(env, MXL_RV64, RVG | RVC | RVS | RVU);
8c6eeb50 493 env->priv_ver = PRIV_VERSION_1_11_0;
95bd8daa 494
a47842d1 495 cpu->cfg.ext_zfa = true;
95bd8daa
CM
496 cpu->cfg.ext_zfh = true;
497 cpu->cfg.mmu = true;
498 cpu->cfg.ext_xtheadba = true;
499 cpu->cfg.ext_xtheadbb = true;
500 cpu->cfg.ext_xtheadbs = true;
501 cpu->cfg.ext_xtheadcmo = true;
502 cpu->cfg.ext_xtheadcondmov = true;
503 cpu->cfg.ext_xtheadfmemidx = true;
504 cpu->cfg.ext_xtheadmac = true;
505 cpu->cfg.ext_xtheadmemidx = true;
506 cpu->cfg.ext_xtheadmempair = true;
507 cpu->cfg.ext_xtheadsync = true;
508
509 cpu->cfg.mvendorid = THEAD_VENDOR_ID;
6df3747a
AG
510#ifndef CONFIG_USER_ONLY
511 set_satp_mode_max_supported(cpu, VM_1_10_SV39);
512#endif
7f0bdfb5
DHB
513
514 /* inherited from parent obj via riscv_cpu_init() */
515 cpu->cfg.pmp = true;
95bd8daa
CM
516}
517
e1d084a8
RP
518static void rv64_veyron_v1_cpu_init(Object *obj)
519{
520 CPURISCVState *env = &RISCV_CPU(obj)->env;
521 RISCVCPU *cpu = RISCV_CPU(obj);
522
523 set_misa(env, MXL_RV64, RVG | RVC | RVS | RVU | RVH);
524 env->priv_ver = PRIV_VERSION_1_12_0;
525
526 /* Enable ISA extensions */
527 cpu->cfg.mmu = true;
029f5fee
DHB
528 cpu->cfg.ext_ifencei = true;
529 cpu->cfg.ext_icsr = true;
530 cpu->cfg.pmp = true;
e1d084a8
RP
531 cpu->cfg.ext_icbom = true;
532 cpu->cfg.cbom_blocksize = 64;
533 cpu->cfg.cboz_blocksize = 64;
534 cpu->cfg.ext_icboz = true;
535 cpu->cfg.ext_smaia = true;
536 cpu->cfg.ext_ssaia = true;
537 cpu->cfg.ext_sscofpmf = true;
538 cpu->cfg.ext_sstc = true;
539 cpu->cfg.ext_svinval = true;
540 cpu->cfg.ext_svnapot = true;
541 cpu->cfg.ext_svpbmt = true;
542 cpu->cfg.ext_smstateen = true;
543 cpu->cfg.ext_zba = true;
544 cpu->cfg.ext_zbb = true;
545 cpu->cfg.ext_zbc = true;
546 cpu->cfg.ext_zbs = true;
547 cpu->cfg.ext_XVentanaCondOps = true;
548
549 cpu->cfg.mvendorid = VEYRON_V1_MVENDORID;
550 cpu->cfg.marchid = VEYRON_V1_MARCHID;
551 cpu->cfg.mimpid = VEYRON_V1_MIMPID;
552
553#ifndef CONFIG_USER_ONLY
554 set_satp_mode_max_supported(cpu, VM_1_10_SV48);
555#endif
556}
557
332dab68
FP
558static void rv128_base_cpu_init(Object *obj)
559{
560 if (qemu_tcg_mttcg_enabled()) {
561 /* Missing 128-bit aligned atomics */
562 error_report("128-bit RISC-V currently does not work with Multi "
563 "Threaded TCG. Please use: -accel tcg,thread=single");
564 exit(EXIT_FAILURE);
565 }
566 CPURISCVState *env = &RISCV_CPU(obj)->env;
567 /* We set this in the realise function */
568 set_misa(env, MXL_RV128, 0);
dd8f244f 569 riscv_cpu_add_user_properties(obj);
18800095 570 /* Set latest version of privileged specification */
b9a2b98e 571 env->priv_ver = PRIV_VERSION_LATEST;
6df3747a
AG
572#ifndef CONFIG_USER_ONLY
573 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
574#endif
332dab68 575}
114baaca 576#else
094b072c
AF
577static void rv32_base_cpu_init(Object *obj)
578{
579 CPURISCVState *env = &RISCV_CPU(obj)->env;
580 /* We set this in the realise function */
e91a7227 581 set_misa(env, MXL_RV32, 0);
dd8f244f 582 riscv_cpu_add_user_properties(obj);
18800095 583 /* Set latest version of privileged specification */
b9a2b98e 584 env->priv_ver = PRIV_VERSION_LATEST;
6df3747a
AG
585#ifndef CONFIG_USER_ONLY
586 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
587#endif
094b072c
AF
588}
589
114baaca
AF
590static void rv32_sifive_u_cpu_init(Object *obj)
591{
7f0bdfb5
DHB
592 RISCVCPU *cpu = RISCV_CPU(obj);
593 CPURISCVState *env = &cpu->env;
e91a7227 594 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
8c6eeb50 595 env->priv_ver = PRIV_VERSION_1_10_0;
6df3747a
AG
596#ifndef CONFIG_USER_ONLY
597 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
598#endif
7f0bdfb5
DHB
599
600 /* inherited from parent obj via riscv_cpu_init() */
601 cpu->cfg.ext_ifencei = true;
602 cpu->cfg.ext_icsr = true;
603 cpu->cfg.mmu = true;
604 cpu->cfg.pmp = true;
114baaca 605}
36b80ad9 606
114baaca
AF
607static void rv32_sifive_e_cpu_init(Object *obj)
608{
609 CPURISCVState *env = &RISCV_CPU(obj)->env;
26b2bc58
AF
610 RISCVCPU *cpu = RISCV_CPU(obj);
611
e91a7227 612 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
8c6eeb50 613 env->priv_ver = PRIV_VERSION_1_10_0;
6df3747a
AG
614#ifndef CONFIG_USER_ONLY
615 set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
616#endif
7f0bdfb5
DHB
617
618 /* inherited from parent obj via riscv_cpu_init() */
619 cpu->cfg.ext_ifencei = true;
620 cpu->cfg.ext_icsr = true;
621 cpu->cfg.pmp = true;
114baaca 622}
d8e72bd1 623
e8905c6c 624static void rv32_ibex_cpu_init(Object *obj)
dc5bd18f
MC
625{
626 CPURISCVState *env = &RISCV_CPU(obj)->env;
26b2bc58
AF
627 RISCVCPU *cpu = RISCV_CPU(obj);
628
e91a7227 629 set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
8c6eeb50 630 env->priv_ver = PRIV_VERSION_1_11_0;
6df3747a
AG
631#ifndef CONFIG_USER_ONLY
632 set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
633#endif
26b2bc58 634 cpu->cfg.epmp = true;
7f0bdfb5
DHB
635
636 /* inherited from parent obj via riscv_cpu_init() */
637 cpu->cfg.ext_ifencei = true;
638 cpu->cfg.ext_icsr = true;
639 cpu->cfg.pmp = true;
dc5bd18f
MC
640}
641
2fdd2c09 642static void rv32_imafcu_nommu_cpu_init(Object *obj)
d784733b
CW
643{
644 CPURISCVState *env = &RISCV_CPU(obj)->env;
26b2bc58
AF
645 RISCVCPU *cpu = RISCV_CPU(obj);
646
e91a7227 647 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
8c6eeb50 648 env->priv_ver = PRIV_VERSION_1_10_0;
6df3747a
AG
649#ifndef CONFIG_USER_ONLY
650 set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
651#endif
7f0bdfb5
DHB
652
653 /* inherited from parent obj via riscv_cpu_init() */
654 cpu->cfg.ext_ifencei = true;
655 cpu->cfg.ext_icsr = true;
656 cpu->cfg.pmp = true;
d784733b 657}
eab15862 658#endif
dc5bd18f 659
10f1ca27
YJ
660#if defined(CONFIG_KVM)
661static void riscv_host_cpu_init(Object *obj)
662{
663 CPURISCVState *env = &RISCV_CPU(obj)->env;
664#if defined(TARGET_RISCV32)
665 set_misa(env, MXL_RV32, 0);
666#elif defined(TARGET_RISCV64)
667 set_misa(env, MXL_RV64, 0);
668#endif
dd8f244f 669 riscv_cpu_add_user_properties(obj);
10f1ca27 670}
9638cbde 671#endif /* CONFIG_KVM */
10f1ca27 672
dc5bd18f
MC
673static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
674{
675 ObjectClass *oc;
676 char *typename;
677 char **cpuname;
678
679 cpuname = g_strsplit(cpu_model, ",", 1);
680 typename = g_strdup_printf(RISCV_CPU_TYPE_NAME("%s"), cpuname[0]);
681 oc = object_class_by_name(typename);
682 g_strfreev(cpuname);
683 g_free(typename);
684 if (!oc || !object_class_dynamic_cast(oc, TYPE_RISCV_CPU) ||
685 object_class_is_abstract(oc)) {
686 return NULL;
687 }
688 return oc;
689}
690
90c84c56 691static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
dc5bd18f
MC
692{
693 RISCVCPU *cpu = RISCV_CPU(cs);
694 CPURISCVState *env = &cpu->env;
b227f6a8
IK
695 int i, j;
696 uint8_t *p;
dc5bd18f 697
df30e652
AF
698#if !defined(CONFIG_USER_ONLY)
699 if (riscv_has_ext(env, RVH)) {
38256529 700 qemu_fprintf(f, " %s %d\n", "V = ", env->virt_enabled);
df30e652
AF
701 }
702#endif
90c84c56 703 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "pc ", env->pc);
dc5bd18f 704#ifndef CONFIG_USER_ONLY
665b90d8
RH
705 {
706 static const int dump_csrs[] = {
707 CSR_MHARTID,
708 CSR_MSTATUS,
709 CSR_MSTATUSH,
bc7dca13
BM
710 /*
711 * CSR_SSTATUS is intentionally omitted here as its value
712 * can be figured out by looking at CSR_MSTATUS
713 */
665b90d8
RH
714 CSR_HSTATUS,
715 CSR_VSSTATUS,
716 CSR_MIP,
717 CSR_MIE,
718 CSR_MIDELEG,
719 CSR_HIDELEG,
720 CSR_MEDELEG,
721 CSR_HEDELEG,
722 CSR_MTVEC,
723 CSR_STVEC,
724 CSR_VSTVEC,
725 CSR_MEPC,
726 CSR_SEPC,
727 CSR_VSEPC,
728 CSR_MCAUSE,
729 CSR_SCAUSE,
730 CSR_VSCAUSE,
731 CSR_MTVAL,
732 CSR_STVAL,
733 CSR_HTVAL,
734 CSR_MTVAL2,
735 CSR_MSCRATCH,
736 CSR_SSCRATCH,
737 CSR_SATP,
bd5594ca
AB
738 CSR_MMTE,
739 CSR_UPMBASE,
740 CSR_UPMMASK,
741 CSR_SPMBASE,
742 CSR_SPMMASK,
743 CSR_MPMBASE,
744 CSR_MPMMASK,
665b90d8
RH
745 };
746
29332994 747 for (i = 0; i < ARRAY_SIZE(dump_csrs); ++i) {
665b90d8
RH
748 int csrno = dump_csrs[i];
749 target_ulong val = 0;
750 RISCVException res = riscv_csrrw_debug(env, csrno, &val, 0, 0);
751
752 /*
753 * Rely on the smode, hmode, etc, predicates within csr.c
754 * to do the filtering of the registers that are present.
755 */
756 if (res == RISCV_EXCP_NONE) {
757 qemu_fprintf(f, " %-8s " TARGET_FMT_lx "\n",
758 csr_ops[csrno].name, val);
759 }
760 }
df30e652 761 }
dc5bd18f
MC
762#endif
763
764 for (i = 0; i < 32; i++) {
e573a7f3 765 qemu_fprintf(f, " %-8s " TARGET_FMT_lx,
90c84c56 766 riscv_int_regnames[i], env->gpr[i]);
dc5bd18f 767 if ((i & 3) == 3) {
90c84c56 768 qemu_fprintf(f, "\n");
dc5bd18f
MC
769 }
770 }
86ea1880
RH
771 if (flags & CPU_DUMP_FPU) {
772 for (i = 0; i < 32; i++) {
e573a7f3 773 qemu_fprintf(f, " %-8s %016" PRIx64,
90c84c56 774 riscv_fpr_regnames[i], env->fpr[i]);
86ea1880 775 if ((i & 3) == 3) {
90c84c56 776 qemu_fprintf(f, "\n");
86ea1880 777 }
dc5bd18f
MC
778 }
779 }
b227f6a8
IK
780 if (riscv_has_ext(env, RVV) && (flags & CPU_DUMP_VPU)) {
781 static const int dump_rvv_csrs[] = {
782 CSR_VSTART,
783 CSR_VXSAT,
784 CSR_VXRM,
785 CSR_VCSR,
786 CSR_VL,
787 CSR_VTYPE,
788 CSR_VLENB,
789 };
29332994 790 for (i = 0; i < ARRAY_SIZE(dump_rvv_csrs); ++i) {
b227f6a8
IK
791 int csrno = dump_rvv_csrs[i];
792 target_ulong val = 0;
793 RISCVException res = riscv_csrrw_debug(env, csrno, &val, 0, 0);
794
795 /*
796 * Rely on the smode, hmode, etc, predicates within csr.c
797 * to do the filtering of the registers that are present.
798 */
799 if (res == RISCV_EXCP_NONE) {
800 qemu_fprintf(f, " %-8s " TARGET_FMT_lx "\n",
801 csr_ops[csrno].name, val);
802 }
803 }
804 uint16_t vlenb = cpu->cfg.vlen >> 3;
805
806 for (i = 0; i < 32; i++) {
807 qemu_fprintf(f, " %-8s ", riscv_rvv_regnames[i]);
808 p = (uint8_t *)env->vreg;
809 for (j = vlenb - 1 ; j >= 0; j--) {
810 qemu_fprintf(f, "%02x", *(p + i * vlenb + BYTE(j)));
811 }
812 qemu_fprintf(f, "\n");
813 }
814 }
dc5bd18f
MC
815}
816
817static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
818{
819 RISCVCPU *cpu = RISCV_CPU(cs);
820 CPURISCVState *env = &cpu->env;
bf9e776e
LZ
821
822 if (env->xl == MXL_RV32) {
823 env->pc = (int32_t)value;
824 } else {
825 env->pc = value;
826 }
dc5bd18f
MC
827}
828
e4fdf9df
RH
829static vaddr riscv_cpu_get_pc(CPUState *cs)
830{
831 RISCVCPU *cpu = RISCV_CPU(cs);
832 CPURISCVState *env = &cpu->env;
833
834 /* Match cpu_get_tb_cpu_state. */
835 if (env->xl == MXL_RV32) {
836 return env->pc & UINT32_MAX;
837 }
838 return env->pc;
839}
840
dc5bd18f
MC
841static bool riscv_cpu_has_work(CPUState *cs)
842{
843#ifndef CONFIG_USER_ONLY
844 RISCVCPU *cpu = RISCV_CPU(cs);
845 CPURISCVState *env = &cpu->env;
846 /*
847 * Definition of the WFI instruction requires it to ignore the privilege
848 * mode and delegation registers, but respect individual enables
849 */
8f42415f 850 return riscv_cpu_all_pending(env) != 0;
dc5bd18f
MC
851#else
852 return true;
853#endif
854}
855
4fa485a7 856static void riscv_cpu_reset_hold(Object *obj)
dc5bd18f 857{
43dc93af
AP
858#ifndef CONFIG_USER_ONLY
859 uint8_t iprio;
860 int i, irq, rdzero;
861#endif
4fa485a7 862 CPUState *cs = CPU(obj);
dc5bd18f
MC
863 RISCVCPU *cpu = RISCV_CPU(cs);
864 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
865 CPURISCVState *env = &cpu->env;
866
4fa485a7
PM
867 if (mcc->parent_phases.hold) {
868 mcc->parent_phases.hold(obj);
869 }
dc5bd18f 870#ifndef CONFIG_USER_ONLY
e91a7227 871 env->misa_mxl = env->misa_mxl_max;
dc5bd18f
MC
872 env->priv = PRV_M;
873 env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV);
92371bd9
RH
874 if (env->misa_mxl > MXL_RV32) {
875 /*
876 * The reset status of SXL/UXL is undefined, but mstatus is WARL
877 * and we must ensure that the value after init is valid for read.
878 */
879 env->mstatus = set_field(env->mstatus, MSTATUS64_SXL, env->misa_mxl);
880 env->mstatus = set_field(env->mstatus, MSTATUS64_UXL, env->misa_mxl);
5a2ae235
LZ
881 if (riscv_has_ext(env, RVH)) {
882 env->vsstatus = set_field(env->vsstatus,
883 MSTATUS64_SXL, env->misa_mxl);
884 env->vsstatus = set_field(env->vsstatus,
885 MSTATUS64_UXL, env->misa_mxl);
886 env->mstatus_hs = set_field(env->mstatus_hs,
887 MSTATUS64_SXL, env->misa_mxl);
888 env->mstatus_hs = set_field(env->mstatus_hs,
889 MSTATUS64_UXL, env->misa_mxl);
890 }
92371bd9 891 }
dc5bd18f 892 env->mcause = 0;
881df35d 893 env->miclaim = MIP_SGEIP;
dc5bd18f 894 env->pc = env->resetvec;
62cf0245 895 env->bins = 0;
ec352d0c 896 env->two_stage_lookup = false;
43dc93af 897
0af3f115 898 env->menvcfg = (cpu->cfg.ext_svpbmt ? MENVCFG_PBMTE : 0) |
ed67d637 899 (cpu->cfg.ext_svadu ? MENVCFG_ADUE : 0);
0af3f115 900 env->henvcfg = (cpu->cfg.ext_svpbmt ? HENVCFG_PBMTE : 0) |
ed67d637 901 (cpu->cfg.ext_svadu ? HENVCFG_ADUE : 0);
7a6613da 902
43dc93af
AP
903 /* Initialized default priorities of local interrupts. */
904 for (i = 0; i < ARRAY_SIZE(env->miprio); i++) {
905 iprio = riscv_cpu_default_priority(i);
906 env->miprio[i] = (i == IRQ_M_EXT) ? 0 : iprio;
907 env->siprio[i] = (i == IRQ_S_EXT) ? 0 : iprio;
908 env->hviprio[i] = 0;
909 }
910 i = 0;
911 while (!riscv_cpu_hviprio_index2irq(i, &irq, &rdzero)) {
912 if (!rdzero) {
913 env->hviprio[irq] = env->miprio[irq];
914 }
915 i++;
916 }
4bbe8033 917 /* mmte is supposed to have pm.current hardwired to 1 */
42967f40 918 env->mmte |= (EXT_STATUS_INITIAL | MMTE_M_PM_CURRENT);
dc5bd18f 919#endif
440544e1 920 env->xl = riscv_cpu_mxl(env);
40bfa5f6 921 riscv_cpu_update_mask(env);
330d2ae3 922 cs->exception_index = RISCV_EXCP_NONE;
c13b169f 923 env->load_res = -1;
dc5bd18f 924 set_default_nan_mode(1, &env->fp_status);
ad40be27
YJ
925
926#ifndef CONFIG_USER_ONLY
cdfb2905 927 if (cpu->cfg.debug) {
a7c272df 928 riscv_trigger_reset_hold(env);
b6092544
BM
929 }
930
ad40be27
YJ
931 if (kvm_enabled()) {
932 kvm_riscv_reset_vcpu(cpu);
933 }
934#endif
dc5bd18f
MC
935}
936
937static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
938{
5c5a47f1 939 RISCVCPU *cpu = RISCV_CPU(s);
94692c3a 940 CPURISCVState *env = &cpu->env;
454c2201 941 info->target_info = &cpu->cfg;
db23e5d9 942
94692c3a 943 switch (env->xl) {
db23e5d9 944 case MXL_RV32:
5c5a47f1 945 info->print_insn = print_insn_riscv32;
db23e5d9
RH
946 break;
947 case MXL_RV64:
5c5a47f1 948 info->print_insn = print_insn_riscv64;
db23e5d9 949 break;
332dab68
FP
950 case MXL_RV128:
951 info->print_insn = print_insn_riscv128;
952 break;
db23e5d9
RH
953 default:
954 g_assert_not_reached();
5c5a47f1 955 }
dc5bd18f
MC
956}
957
36c1118d 958void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
bd305595
DHB
959{
960 CPURISCVState *env = &cpu->env;
961 int i;
962
963 /* Force disable extensions if priv spec version does not match */
964 for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
5f2c80f1 965 if (isa_ext_is_enabled(cpu, isa_edata_arr[i].ext_enable_offset) &&
bd305595 966 (env->priv_ver < isa_edata_arr[i].min_version)) {
5f2c80f1
DHB
967 isa_ext_update_enabled(cpu, isa_edata_arr[i].ext_enable_offset,
968 false);
bd305595
DHB
969#ifndef CONFIG_USER_ONLY
970 warn_report("disabling %s extension for hart 0x" TARGET_FMT_lx
971 " because privilege spec version does not match",
972 isa_edata_arr[i].name, env->mhartid);
973#else
974 warn_report("disabling %s extension because "
975 "privilege spec version does not match",
976 isa_edata_arr[i].name);
977#endif
978 }
979 }
980}
981
6f23aaeb
AG
982#ifndef CONFIG_USER_ONLY
983static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
984{
985 bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32;
3a2fc235
DHB
986 uint8_t satp_mode_map_max, satp_mode_supported_max;
987
988 /* The CPU wants the OS to decide which satp mode to use */
989 if (cpu->cfg.satp_mode.supported == 0) {
990 return;
991 }
992
993 satp_mode_supported_max =
994 satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
6f23aaeb
AG
995
996 if (cpu->cfg.satp_mode.map == 0) {
997 if (cpu->cfg.satp_mode.init == 0) {
998 /* If unset by the user, we fallback to the default satp mode. */
999 set_satp_mode_default_map(cpu);
1000 } else {
1001 /*
1002 * Find the lowest level that was disabled and then enable the
1003 * first valid level below which can be found in
1004 * valid_vm_1_10_32/64.
1005 */
1006 for (int i = 1; i < 16; ++i) {
6df3747a
AG
1007 if ((cpu->cfg.satp_mode.init & (1 << i)) &&
1008 (cpu->cfg.satp_mode.supported & (1 << i))) {
6f23aaeb 1009 for (int j = i - 1; j >= 0; --j) {
6df3747a 1010 if (cpu->cfg.satp_mode.supported & (1 << j)) {
6f23aaeb
AG
1011 cpu->cfg.satp_mode.map |= (1 << j);
1012 break;
1013 }
1014 }
1015 break;
1016 }
1017 }
1018 }
1019 }
1020
6df3747a
AG
1021 satp_mode_map_max = satp_mode_max_from_map(cpu->cfg.satp_mode.map);
1022
1023 /* Make sure the user asked for a supported configuration (HW and qemu) */
1024 if (satp_mode_map_max > satp_mode_supported_max) {
1025 error_setg(errp, "satp_mode %s is higher than hw max capability %s",
1026 satp_mode_str(satp_mode_map_max, rv32),
1027 satp_mode_str(satp_mode_supported_max, rv32));
1028 return;
6f23aaeb
AG
1029 }
1030
1031 /*
1032 * Make sure the user did not ask for an invalid configuration as per
1033 * the specification.
1034 */
6f23aaeb 1035 if (!rv32) {
6df3747a 1036 for (int i = satp_mode_map_max - 1; i >= 0; --i) {
6f23aaeb
AG
1037 if (!(cpu->cfg.satp_mode.map & (1 << i)) &&
1038 (cpu->cfg.satp_mode.init & (1 << i)) &&
6df3747a 1039 (cpu->cfg.satp_mode.supported & (1 << i))) {
6f23aaeb
AG
1040 error_setg(errp, "cannot disable %s satp mode if %s "
1041 "is enabled", satp_mode_str(i, false),
6df3747a 1042 satp_mode_str(satp_mode_map_max, false));
6f23aaeb
AG
1043 return;
1044 }
1045 }
1046 }
1047
1048 /* Finally expand the map so that all valid modes are set */
6df3747a
AG
1049 for (int i = satp_mode_map_max - 1; i >= 0; --i) {
1050 if (cpu->cfg.satp_mode.supported & (1 << i)) {
6f23aaeb
AG
1051 cpu->cfg.satp_mode.map |= (1 << i);
1052 }
1053 }
1054}
1055#endif
1056
1057static void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
1058{
1059#ifndef CONFIG_USER_ONLY
1060 Error *local_err = NULL;
1061
1062 riscv_cpu_satp_mode_finalize(cpu, &local_err);
1063 if (local_err != NULL) {
1064 error_propagate(errp, local_err);
1065 return;
1066 }
1067#endif
1068}
1069
eddabb6b
DHB
1070static void riscv_cpu_realize(DeviceState *dev, Error **errp)
1071{
1072 CPUState *cs = CPU(dev);
1073 RISCVCPU *cpu = RISCV_CPU(dev);
1074 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
1075 Error *local_err = NULL;
1076
f57d5f80
DHB
1077 if (object_dynamic_cast(OBJECT(dev), TYPE_RISCV_CPU_ANY) != NULL) {
1078 warn_report("The 'any' CPU is deprecated and will be "
1079 "removed in the future.");
1080 }
1081
eddabb6b
DHB
1082 cpu_exec_realizefn(cs, &local_err);
1083 if (local_err != NULL) {
1084 error_propagate(errp, local_err);
1085 return;
1086 }
1087
6f23aaeb
AG
1088 riscv_cpu_finalize_features(cpu, &local_err);
1089 if (local_err != NULL) {
1090 error_propagate(errp, local_err);
1091 return;
1092 }
1093
5371f5cd
JW
1094 riscv_cpu_register_gdb_regs_for_features(cs);
1095
a7c272df
AO
1096#ifndef CONFIG_USER_ONLY
1097 if (cpu->cfg.debug) {
1098 riscv_trigger_realize(&cpu->env);
1099 }
1100#endif
1101
dc5bd18f
MC
1102 qemu_init_vcpu(cs);
1103 cpu_reset(cs);
1104
1105 mcc->parent_realize(dev, errp);
1106}
1107
0f0b70ee 1108#ifndef CONFIG_USER_ONLY
6f23aaeb
AG
1109static void cpu_riscv_get_satp(Object *obj, Visitor *v, const char *name,
1110 void *opaque, Error **errp)
1111{
1112 RISCVSATPMap *satp_map = opaque;
1113 uint8_t satp = satp_mode_from_str(name);
1114 bool value;
1115
1116 value = satp_map->map & (1 << satp);
1117
1118 visit_type_bool(v, name, &value, errp);
1119}
1120
1121static void cpu_riscv_set_satp(Object *obj, Visitor *v, const char *name,
1122 void *opaque, Error **errp)
1123{
1124 RISCVSATPMap *satp_map = opaque;
1125 uint8_t satp = satp_mode_from_str(name);
1126 bool value;
1127
1128 if (!visit_type_bool(v, name, &value, errp)) {
1129 return;
1130 }
1131
1132 satp_map->map = deposit32(satp_map->map, satp, 1, value);
1133 satp_map->init |= 1 << satp;
1134}
1135
1136static void riscv_add_satp_mode_properties(Object *obj)
1137{
1138 RISCVCPU *cpu = RISCV_CPU(obj);
1139
1140 if (cpu->env.misa_mxl == MXL_RV32) {
1141 object_property_add(obj, "sv32", "bool", cpu_riscv_get_satp,
1142 cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode);
1143 } else {
1144 object_property_add(obj, "sv39", "bool", cpu_riscv_get_satp,
1145 cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode);
1146 object_property_add(obj, "sv48", "bool", cpu_riscv_get_satp,
1147 cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode);
1148 object_property_add(obj, "sv57", "bool", cpu_riscv_get_satp,
1149 cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode);
1150 object_property_add(obj, "sv64", "bool", cpu_riscv_get_satp,
1151 cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode);
1152 }
1153}
1154
0f0b70ee
AF
1155static void riscv_cpu_set_irq(void *opaque, int irq, int level)
1156{
1157 RISCVCPU *cpu = RISCV_CPU(opaque);
cd032fe7 1158 CPURISCVState *env = &cpu->env;
0f0b70ee 1159
cd032fe7
AP
1160 if (irq < IRQ_LOCAL_MAX) {
1161 switch (irq) {
1162 case IRQ_U_SOFT:
1163 case IRQ_S_SOFT:
1164 case IRQ_VS_SOFT:
1165 case IRQ_M_SOFT:
1166 case IRQ_U_TIMER:
1167 case IRQ_S_TIMER:
1168 case IRQ_VS_TIMER:
1169 case IRQ_M_TIMER:
1170 case IRQ_U_EXT:
cd032fe7
AP
1171 case IRQ_VS_EXT:
1172 case IRQ_M_EXT:
8b5c807b 1173 if (kvm_enabled()) {
cd032fe7 1174 kvm_riscv_set_irq(cpu, irq, level);
8b5c807b 1175 } else {
bbb9fc25 1176 riscv_cpu_update_mip(env, 1 << irq, BOOL_TO_MASK(level));
8b5c807b 1177 }
cd032fe7 1178 break;
33fe584f
AF
1179 case IRQ_S_EXT:
1180 if (kvm_enabled()) {
1181 kvm_riscv_set_irq(cpu, irq, level);
1182 } else {
1183 env->external_seip = level;
bbb9fc25 1184 riscv_cpu_update_mip(env, 1 << irq,
33fe584f
AF
1185 BOOL_TO_MASK(level | env->software_seip));
1186 }
1187 break;
cd032fe7
AP
1188 default:
1189 g_assert_not_reached();
2b650fbb 1190 }
cd032fe7
AP
1191 } else if (irq < (IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX)) {
1192 /* Require H-extension for handling guest local interrupts */
1193 if (!riscv_has_ext(env, RVH)) {
1194 g_assert_not_reached();
1195 }
1196
1197 /* Compute bit position in HGEIP CSR */
1198 irq = irq - IRQ_LOCAL_MAX + 1;
1199 if (env->geilen < irq) {
1200 g_assert_not_reached();
1201 }
1202
1203 /* Update HGEIP CSR */
1204 env->hgeip &= ~((target_ulong)1 << irq);
1205 if (level) {
1206 env->hgeip |= (target_ulong)1 << irq;
1207 }
1208
1209 /* Update mip.SGEIP bit */
bbb9fc25 1210 riscv_cpu_update_mip(env, MIP_SGEIP,
cd032fe7
AP
1211 BOOL_TO_MASK(!!(env->hgeie & env->hgeip)));
1212 } else {
0f0b70ee
AF
1213 g_assert_not_reached();
1214 }
1215}
1216#endif /* CONFIG_USER_ONLY */
1217
dc5bd18f
MC
1218static void riscv_cpu_init(Object *obj)
1219{
0f0b70ee 1220#ifndef CONFIG_USER_ONLY
8fa08d7e 1221 qdev_init_gpio_in(DEVICE(obj), riscv_cpu_set_irq,
cd032fe7 1222 IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX);
0f0b70ee 1223#endif /* CONFIG_USER_ONLY */
549cbf78
DHB
1224
1225 multi_ext_user_opts = g_hash_table_new(NULL, g_direct_equal);
dc5bd18f
MC
1226}
1227
b3df64c8
DHB
1228typedef struct RISCVCPUMisaExtConfig {
1229 const char *name;
1230 const char *description;
1231 target_ulong misa_bit;
1232 bool enabled;
1233} RISCVCPUMisaExtConfig;
1234
1235static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, const char *name,
1236 void *opaque, Error **errp)
1237{
1238 const RISCVCPUMisaExtConfig *misa_ext_cfg = opaque;
1239 target_ulong misa_bit = misa_ext_cfg->misa_bit;
1240 RISCVCPU *cpu = RISCV_CPU(obj);
1241 CPURISCVState *env = &cpu->env;
1242 bool value;
1243
1244 if (!visit_type_bool(v, name, &value, errp)) {
1245 return;
1246 }
1247
1248 if (value) {
1249 env->misa_ext |= misa_bit;
1250 env->misa_ext_mask |= misa_bit;
1251 } else {
1252 env->misa_ext &= ~misa_bit;
1253 env->misa_ext_mask &= ~misa_bit;
1254 }
1255}
1256
1257static void cpu_get_misa_ext_cfg(Object *obj, Visitor *v, const char *name,
1258 void *opaque, Error **errp)
1259{
1260 const RISCVCPUMisaExtConfig *misa_ext_cfg = opaque;
1261 target_ulong misa_bit = misa_ext_cfg->misa_bit;
1262 RISCVCPU *cpu = RISCV_CPU(obj);
1263 CPURISCVState *env = &cpu->env;
1264 bool value;
1265
1266 value = env->misa_ext & misa_bit;
1267
1268 visit_type_bool(v, name, &value, errp);
1269}
1270
ed7e6182
DHB
1271typedef struct misa_ext_info {
1272 const char *name;
1273 const char *description;
1274} MISAExtInfo;
1275
1276#define MISA_INFO_IDX(_bit) \
1277 __builtin_ctz(_bit)
1278
1279#define MISA_EXT_INFO(_bit, _propname, _descr) \
1280 [MISA_INFO_IDX(_bit)] = {.name = _propname, .description = _descr}
1281
1282static const MISAExtInfo misa_ext_info_arr[] = {
1283 MISA_EXT_INFO(RVA, "a", "Atomic instructions"),
1284 MISA_EXT_INFO(RVC, "c", "Compressed instructions"),
1285 MISA_EXT_INFO(RVD, "d", "Double-precision float point"),
1286 MISA_EXT_INFO(RVF, "f", "Single-precision float point"),
1287 MISA_EXT_INFO(RVI, "i", "Base integer instruction set"),
1288 MISA_EXT_INFO(RVE, "e", "Base integer instruction set (embedded)"),
1289 MISA_EXT_INFO(RVM, "m", "Integer multiplication and division"),
1290 MISA_EXT_INFO(RVS, "s", "Supervisor-level instructions"),
1291 MISA_EXT_INFO(RVU, "u", "User-level instructions"),
1292 MISA_EXT_INFO(RVH, "h", "Hypervisor"),
1293 MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"),
1294 MISA_EXT_INFO(RVV, "v", "Vector operations"),
1295 MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"),
1296};
1297
1298static int riscv_validate_misa_info_idx(uint32_t bit)
1299{
1300 int idx;
1301
1302 /*
1303 * Our lowest valid input (RVA) is 1 and
1304 * __builtin_ctz() is UB with zero.
1305 */
1306 g_assert(bit != 0);
1307 idx = MISA_INFO_IDX(bit);
1308
1309 g_assert(idx < ARRAY_SIZE(misa_ext_info_arr));
1310 return idx;
1311}
1312
1313const char *riscv_get_misa_ext_name(uint32_t bit)
1314{
1315 int idx = riscv_validate_misa_info_idx(bit);
1316 const char *val = misa_ext_info_arr[idx].name;
1317
1318 g_assert(val != NULL);
1319 return val;
1320}
1321
1322const char *riscv_get_misa_ext_description(uint32_t bit)
1323{
1324 int idx = riscv_validate_misa_info_idx(bit);
1325 const char *val = misa_ext_info_arr[idx].description;
1326
1327 g_assert(val != NULL);
1328 return val;
1329}
1330
1331#define MISA_CFG(_bit, _enabled) \
1332 {.misa_bit = _bit, .enabled = _enabled}
1333
1334static RISCVCPUMisaExtConfig misa_ext_cfgs[] = {
1335 MISA_CFG(RVA, true),
1336 MISA_CFG(RVC, true),
1337 MISA_CFG(RVD, true),
1338 MISA_CFG(RVF, true),
1339 MISA_CFG(RVI, true),
1340 MISA_CFG(RVE, false),
1341 MISA_CFG(RVM, true),
1342 MISA_CFG(RVS, true),
1343 MISA_CFG(RVU, true),
1344 MISA_CFG(RVH, true),
1345 MISA_CFG(RVJ, false),
1346 MISA_CFG(RVV, false),
1347 MISA_CFG(RVG, false),
4c759943 1348};
b3df64c8 1349
0a9eb9b4
DHB
1350/*
1351 * We do not support user choice tracking for MISA
1352 * extensions yet because, so far, we do not silently
1353 * change MISA bits during realize() (RVG enables MISA
1354 * bits but the user is warned about it).
1355 */
b3df64c8
DHB
1356static void riscv_cpu_add_misa_properties(Object *cpu_obj)
1357{
1358 int i;
1359
1360 for (i = 0; i < ARRAY_SIZE(misa_ext_cfgs); i++) {
ed7e6182
DHB
1361 RISCVCPUMisaExtConfig *misa_cfg = &misa_ext_cfgs[i];
1362 int bit = misa_cfg->misa_bit;
1363
1364 misa_cfg->name = riscv_get_misa_ext_name(bit);
1365 misa_cfg->description = riscv_get_misa_ext_description(bit);
b3df64c8 1366
92becce5
DHB
1367 /* Check if KVM already created the property */
1368 if (object_property_find(cpu_obj, misa_cfg->name)) {
1369 continue;
1370 }
1371
b3df64c8
DHB
1372 object_property_add(cpu_obj, misa_cfg->name, "bool",
1373 cpu_get_misa_ext_cfg,
1374 cpu_set_misa_ext_cfg,
1375 NULL, (void *)misa_cfg);
1376 object_property_set_description(cpu_obj, misa_cfg->name,
1377 misa_cfg->description);
1378 object_property_set_bool(cpu_obj, misa_cfg->name,
1379 misa_cfg->enabled, NULL);
1380 }
1381}
1382
549cbf78
DHB
1383typedef struct RISCVCPUMultiExtConfig {
1384 const char *name;
1385 uint32_t offset;
1386 bool enabled;
1387} RISCVCPUMultiExtConfig;
1388
1389#define MULTI_EXT_CFG_BOOL(_name, _prop, _defval) \
1390 {.name = _name, .offset = CPU_CFG_OFFSET(_prop), \
1391 .enabled = _defval}
1392
1393static RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
9d3d60b7 1394 /* Defaults for standard extensions */
549cbf78
DHB
1395 MULTI_EXT_CFG_BOOL("sscofpmf", ext_sscofpmf, false),
1396 MULTI_EXT_CFG_BOOL("Zifencei", ext_ifencei, true),
1397 MULTI_EXT_CFG_BOOL("Zicsr", ext_icsr, true),
1398 MULTI_EXT_CFG_BOOL("Zihintntl", ext_zihintntl, true),
1399 MULTI_EXT_CFG_BOOL("Zihintpause", ext_zihintpause, true),
1400 MULTI_EXT_CFG_BOOL("Zawrs", ext_zawrs, true),
1401 MULTI_EXT_CFG_BOOL("Zfa", ext_zfa, true),
1402 MULTI_EXT_CFG_BOOL("Zfh", ext_zfh, false),
1403 MULTI_EXT_CFG_BOOL("Zfhmin", ext_zfhmin, false),
1404 MULTI_EXT_CFG_BOOL("Zve32f", ext_zve32f, false),
1405 MULTI_EXT_CFG_BOOL("Zve64f", ext_zve64f, false),
1406 MULTI_EXT_CFG_BOOL("Zve64d", ext_zve64d, false),
1407 MULTI_EXT_CFG_BOOL("sstc", ext_sstc, true),
1408
1409 MULTI_EXT_CFG_BOOL("smstateen", ext_smstateen, false),
1410 MULTI_EXT_CFG_BOOL("svadu", ext_svadu, true),
1411 MULTI_EXT_CFG_BOOL("svinval", ext_svinval, false),
1412 MULTI_EXT_CFG_BOOL("svnapot", ext_svnapot, false),
1413 MULTI_EXT_CFG_BOOL("svpbmt", ext_svpbmt, false),
1414
1415 MULTI_EXT_CFG_BOOL("zba", ext_zba, true),
1416 MULTI_EXT_CFG_BOOL("zbb", ext_zbb, true),
1417 MULTI_EXT_CFG_BOOL("zbc", ext_zbc, true),
1418 MULTI_EXT_CFG_BOOL("zbkb", ext_zbkb, false),
1419 MULTI_EXT_CFG_BOOL("zbkc", ext_zbkc, false),
1420 MULTI_EXT_CFG_BOOL("zbkx", ext_zbkx, false),
1421 MULTI_EXT_CFG_BOOL("zbs", ext_zbs, true),
1422 MULTI_EXT_CFG_BOOL("zk", ext_zk, false),
1423 MULTI_EXT_CFG_BOOL("zkn", ext_zkn, false),
1424 MULTI_EXT_CFG_BOOL("zknd", ext_zknd, false),
1425 MULTI_EXT_CFG_BOOL("zkne", ext_zkne, false),
1426 MULTI_EXT_CFG_BOOL("zknh", ext_zknh, false),
1427 MULTI_EXT_CFG_BOOL("zkr", ext_zkr, false),
1428 MULTI_EXT_CFG_BOOL("zks", ext_zks, false),
1429 MULTI_EXT_CFG_BOOL("zksed", ext_zksed, false),
1430 MULTI_EXT_CFG_BOOL("zksh", ext_zksh, false),
1431 MULTI_EXT_CFG_BOOL("zkt", ext_zkt, false),
1432
1433 MULTI_EXT_CFG_BOOL("zdinx", ext_zdinx, false),
1434 MULTI_EXT_CFG_BOOL("zfinx", ext_zfinx, false),
1435 MULTI_EXT_CFG_BOOL("zhinx", ext_zhinx, false),
1436 MULTI_EXT_CFG_BOOL("zhinxmin", ext_zhinxmin, false),
1437
1438 MULTI_EXT_CFG_BOOL("zicbom", ext_icbom, true),
1439 MULTI_EXT_CFG_BOOL("zicboz", ext_icboz, true),
1440
1441 MULTI_EXT_CFG_BOOL("zmmul", ext_zmmul, false),
1442
1443 MULTI_EXT_CFG_BOOL("zca", ext_zca, false),
1444 MULTI_EXT_CFG_BOOL("zcb", ext_zcb, false),
1445 MULTI_EXT_CFG_BOOL("zcd", ext_zcd, false),
1446 MULTI_EXT_CFG_BOOL("zce", ext_zce, false),
1447 MULTI_EXT_CFG_BOOL("zcf", ext_zcf, false),
1448 MULTI_EXT_CFG_BOOL("zcmp", ext_zcmp, false),
1449 MULTI_EXT_CFG_BOOL("zcmt", ext_zcmt, false),
1450 MULTI_EXT_CFG_BOOL("zicond", ext_zicond, false),
6672e29d 1451
82822b5d
DHB
1452 DEFINE_PROP_END_OF_LIST(),
1453};
1454
549cbf78
DHB
1455static RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
1456 MULTI_EXT_CFG_BOOL("xtheadba", ext_xtheadba, false),
1457 MULTI_EXT_CFG_BOOL("xtheadbb", ext_xtheadbb, false),
1458 MULTI_EXT_CFG_BOOL("xtheadbs", ext_xtheadbs, false),
1459 MULTI_EXT_CFG_BOOL("xtheadcmo", ext_xtheadcmo, false),
1460 MULTI_EXT_CFG_BOOL("xtheadcondmov", ext_xtheadcondmov, false),
1461 MULTI_EXT_CFG_BOOL("xtheadfmemidx", ext_xtheadfmemidx, false),
1462 MULTI_EXT_CFG_BOOL("xtheadfmv", ext_xtheadfmv, false),
1463 MULTI_EXT_CFG_BOOL("xtheadmac", ext_xtheadmac, false),
1464 MULTI_EXT_CFG_BOOL("xtheadmemidx", ext_xtheadmemidx, false),
1465 MULTI_EXT_CFG_BOOL("xtheadmempair", ext_xtheadmempair, false),
1466 MULTI_EXT_CFG_BOOL("xtheadsync", ext_xtheadsync, false),
1467 MULTI_EXT_CFG_BOOL("xventanacondops", ext_XVentanaCondOps, false),
0d429bd2 1468
b955fd1a
DHB
1469 DEFINE_PROP_END_OF_LIST(),
1470};
d364c0ab 1471
b955fd1a 1472/* These are experimental so mark with 'x-' */
549cbf78 1473static RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = {
a44da25a 1474 /* ePMP 0.9.3 */
549cbf78
DHB
1475 MULTI_EXT_CFG_BOOL("x-epmp", epmp, false),
1476 MULTI_EXT_CFG_BOOL("x-smaia", ext_smaia, false),
1477 MULTI_EXT_CFG_BOOL("x-ssaia", ext_ssaia, false),
5da9514e 1478
549cbf78
DHB
1479 MULTI_EXT_CFG_BOOL("x-zvfh", ext_zvfh, false),
1480 MULTI_EXT_CFG_BOOL("x-zvfhmin", ext_zvfhmin, false),
058d9d30 1481
549cbf78
DHB
1482 MULTI_EXT_CFG_BOOL("x-zfbfmin", ext_zfbfmin, false),
1483 MULTI_EXT_CFG_BOOL("x-zvfbfmin", ext_zvfbfmin, false),
1484 MULTI_EXT_CFG_BOOL("x-zvfbfwma", ext_zvfbfwma, false),
889caa44 1485
e13c7d3b 1486 /* Vector cryptography extensions */
549cbf78
DHB
1487 MULTI_EXT_CFG_BOOL("x-zvbb", ext_zvbb, false),
1488 MULTI_EXT_CFG_BOOL("x-zvbc", ext_zvbc, false),
1489 MULTI_EXT_CFG_BOOL("x-zvkg", ext_zvkg, false),
1490 MULTI_EXT_CFG_BOOL("x-zvkned", ext_zvkned, false),
1491 MULTI_EXT_CFG_BOOL("x-zvknha", ext_zvknha, false),
1492 MULTI_EXT_CFG_BOOL("x-zvknhb", ext_zvknhb, false),
1493 MULTI_EXT_CFG_BOOL("x-zvksed", ext_zvksed, false),
1494 MULTI_EXT_CFG_BOOL("x-zvksh", ext_zvksh, false),
e13c7d3b 1495
26b2bc58
AF
1496 DEFINE_PROP_END_OF_LIST(),
1497};
1498
8ea3fcef
DHB
1499static Property riscv_cpu_options[] = {
1500 DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
1501
1502 DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
1503 DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
1504
1505 DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
1506 DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
1507
1508 DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
1509 DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
1510
1511 DEFINE_PROP_UINT16("cbom_blocksize", RISCVCPU, cfg.cbom_blocksize, 64),
1512 DEFINE_PROP_UINT16("cboz_blocksize", RISCVCPU, cfg.cboz_blocksize, 64),
d09d085a
DHB
1513
1514 DEFINE_PROP_END_OF_LIST(),
8ea3fcef 1515};
56f0e992 1516
549cbf78
DHB
1517static void cpu_set_multi_ext_cfg(Object *obj, Visitor *v, const char *name,
1518 void *opaque, Error **errp)
1519{
1520 const RISCVCPUMultiExtConfig *multi_ext_cfg = opaque;
1521 bool value;
1522
1523 if (!visit_type_bool(v, name, &value, errp)) {
1524 return;
1525 }
1526
1527 isa_ext_update_enabled(RISCV_CPU(obj), multi_ext_cfg->offset, value);
1528
1529 g_hash_table_insert(multi_ext_user_opts,
1530 GUINT_TO_POINTER(multi_ext_cfg->offset),
1531 (gpointer)value);
1532}
1533
1534static void cpu_get_multi_ext_cfg(Object *obj, Visitor *v, const char *name,
1535 void *opaque, Error **errp)
1536{
1537 const RISCVCPUMultiExtConfig *multi_ext_cfg = opaque;
1538 bool value = isa_ext_is_enabled(RISCV_CPU(obj), multi_ext_cfg->offset);
1539
1540 visit_type_bool(v, name, &value, errp);
1541}
1542
1543static void cpu_add_multi_ext_prop(Object *cpu_obj,
1544 RISCVCPUMultiExtConfig *multi_cfg)
1545{
1546 object_property_add(cpu_obj, multi_cfg->name, "bool",
1547 cpu_get_multi_ext_cfg,
1548 cpu_set_multi_ext_cfg,
1549 NULL, (void *)multi_cfg);
1550
1551 /*
1552 * Set def val directly instead of using
1553 * object_property_set_bool() to save the set()
1554 * callback hash for user inputs.
1555 */
1556 isa_ext_update_enabled(RISCV_CPU(cpu_obj), multi_cfg->offset,
1557 multi_cfg->enabled);
1558}
1559
1560static void riscv_cpu_add_multiext_prop_array(Object *obj,
1561 RISCVCPUMultiExtConfig *array)
370d7c8e
DHB
1562{
1563 g_assert(array);
1564
549cbf78
DHB
1565 for (RISCVCPUMultiExtConfig *prop = array; prop && prop->name; prop++) {
1566 cpu_add_multi_ext_prop(obj, prop);
370d7c8e
DHB
1567 }
1568}
1569
68aba1f2 1570#ifdef CONFIG_KVM
56f0e992
DHB
1571static void cpu_set_cfg_unavailable(Object *obj, Visitor *v,
1572 const char *name,
1573 void *opaque, Error **errp)
1574{
1575 const char *propname = opaque;
1576 bool value;
1577
1578 if (!visit_type_bool(v, name, &value, errp)) {
1579 return;
1580 }
1581
1582 if (value) {
1583 error_setg(errp, "extension %s is not available with KVM",
1584 propname);
1585 }
1586}
68aba1f2
DHB
1587
1588static void riscv_cpu_add_kvm_unavail_prop(Object *obj, const char *prop_name)
1589{
1590 /* Check if KVM created the property already */
1591 if (object_property_find(obj, prop_name)) {
1592 return;
1593 }
1594
1595 /*
1596 * Set the default to disabled for every extension
1597 * unknown to KVM and error out if the user attempts
1598 * to enable any of them.
1599 */
1600 object_property_add(obj, prop_name, "bool",
1601 NULL, cpu_set_cfg_unavailable,
1602 NULL, (void *)prop_name);
1603}
1604
b55c39b3 1605static void riscv_cpu_add_kvm_unavail_prop_array(Object *obj,
549cbf78 1606 RISCVCPUMultiExtConfig *array)
b55c39b3
DHB
1607{
1608 g_assert(array);
1609
549cbf78 1610 for (RISCVCPUMultiExtConfig *prop = array; prop && prop->name; prop++) {
b55c39b3
DHB
1611 riscv_cpu_add_kvm_unavail_prop(obj, prop->name);
1612 }
1613}
1614
68aba1f2
DHB
1615void kvm_riscv_cpu_add_kvm_properties(Object *obj)
1616{
1617 Property *prop;
1618 DeviceState *dev = DEVICE(obj);
1619
1620 kvm_riscv_init_user_properties(obj);
1621 riscv_cpu_add_misa_properties(obj);
1622
b55c39b3
DHB
1623 riscv_cpu_add_kvm_unavail_prop_array(obj, riscv_cpu_extensions);
1624 riscv_cpu_add_kvm_unavail_prop_array(obj, riscv_cpu_vendor_exts);
1625 riscv_cpu_add_kvm_unavail_prop_array(obj, riscv_cpu_experimental_exts);
b955fd1a 1626
d09d085a 1627 for (prop = riscv_cpu_options; prop && prop->name; prop++) {
68aba1f2 1628 /* Check if KVM created the property already */
d09d085a 1629 if (object_property_find(obj, prop->name)) {
68aba1f2
DHB
1630 continue;
1631 }
d09d085a 1632 qdev_property_add_static(dev, prop);
68aba1f2
DHB
1633 }
1634}
56f0e992
DHB
1635#endif
1636
c66ffcd5 1637/*
dd8f244f
DHB
1638 * Add CPU properties with user-facing flags.
1639 *
1640 * This will overwrite existing env->misa_ext values with the
1641 * defaults set via riscv_cpu_add_misa_properties().
c66ffcd5 1642 */
dd8f244f 1643static void riscv_cpu_add_user_properties(Object *obj)
26b2bc58 1644{
492265ae 1645#ifndef CONFIG_USER_ONLY
b71f9dca
DHB
1646 riscv_add_satp_mode_properties(obj);
1647
492265ae 1648 if (kvm_enabled()) {
68aba1f2
DHB
1649 kvm_riscv_cpu_add_kvm_properties(obj);
1650 return;
492265ae
DHB
1651 }
1652#endif
1653
b3df64c8
DHB
1654 riscv_cpu_add_misa_properties(obj);
1655
549cbf78
DHB
1656 riscv_cpu_add_multiext_prop_array(obj, riscv_cpu_extensions);
1657 riscv_cpu_add_multiext_prop_array(obj, riscv_cpu_vendor_exts);
1658 riscv_cpu_add_multiext_prop_array(obj, riscv_cpu_experimental_exts);
1659
1660 for (Property *prop = riscv_cpu_options; prop && prop->name; prop++) {
1661 qdev_property_add_static(DEVICE(obj), prop);
1662 }
26b2bc58
AF
1663}
1664
b97e5a6b
DHB
1665/*
1666 * The 'max' type CPU will have all possible ratified
1667 * non-vendor extensions enabled.
1668 */
1669static void riscv_init_max_cpu_extensions(Object *obj)
1670{
1671 RISCVCPU *cpu = RISCV_CPU(obj);
1672 CPURISCVState *env = &cpu->env;
549cbf78 1673 RISCVCPUMultiExtConfig *prop;
b97e5a6b
DHB
1674
1675 /* Enable RVG, RVJ and RVV that are disabled by default */
1676 set_misa(env, env->misa_mxl, env->misa_ext | RVG | RVJ | RVV);
1677
1678 for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
25aa6f72 1679 isa_ext_update_enabled(cpu, prop->offset, true);
b97e5a6b
DHB
1680 }
1681
1682 /* set vector version */
1683 env->vext_ver = VEXT_VERSION_1_00_0;
1684
1685 /* Zfinx is not compatible with F. Disable it */
25aa6f72
DHB
1686 isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zfinx), false);
1687 isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zdinx), false);
1688 isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zhinx), false);
1689 isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zhinxmin), false);
b97e5a6b 1690
25aa6f72
DHB
1691 isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zce), false);
1692 isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zcmp), false);
1693 isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zcmt), false);
b97e5a6b
DHB
1694
1695 if (env->misa_mxl != MXL_RV32) {
25aa6f72 1696 isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zcf), false);
b97e5a6b
DHB
1697 }
1698}
1699
26b2bc58
AF
1700static Property riscv_cpu_properties[] = {
1701 DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
1702
277b210d
AF
1703#ifndef CONFIG_USER_ONLY
1704 DEFINE_PROP_UINT64("resetvec", RISCVCPU, env.resetvec, DEFAULT_RSTVEC),
1705#endif
a4a9a443
TO
1706
1707 DEFINE_PROP_BOOL("short-isa-string", RISCVCPU, cfg.short_isa_string, false),
b8312675 1708
1709 DEFINE_PROP_BOOL("rvv_ta_all_1s", RISCVCPU, cfg.rvv_ta_all_1s, false),
1ad3f9bd 1710 DEFINE_PROP_BOOL("rvv_ma_all_1s", RISCVCPU, cfg.rvv_ma_all_1s, false),
54bd9b6e
DHB
1711
1712 /*
1713 * write_misa() is marked as experimental for now so mark
1714 * it with -x and default to 'false'.
1715 */
1716 DEFINE_PROP_BOOL("x-misa-w", RISCVCPU, cfg.misa_w, false),
c4e95030
AF
1717 DEFINE_PROP_END_OF_LIST(),
1718};
1719
a6506838 1720static const gchar *riscv_gdb_arch_name(CPUState *cs)
edf64786
SP
1721{
1722 RISCVCPU *cpu = RISCV_CPU(cs);
1723 CPURISCVState *env = &cpu->env;
1724
db23e5d9
RH
1725 switch (riscv_cpu_mxl(env)) {
1726 case MXL_RV32:
a6506838 1727 return "riscv:rv32";
db23e5d9 1728 case MXL_RV64:
332dab68 1729 case MXL_RV128:
a6506838 1730 return "riscv:rv64";
db23e5d9
RH
1731 default:
1732 g_assert_not_reached();
edf64786
SP
1733 }
1734}
1735
b93777e1
BM
1736static const char *riscv_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname)
1737{
1738 RISCVCPU *cpu = RISCV_CPU(cs);
1739
1740 if (strcmp(xmlname, "riscv-csr.xml") == 0) {
1741 return cpu->dyn_csr_xml;
719d3561
HW
1742 } else if (strcmp(xmlname, "riscv-vector.xml") == 0) {
1743 return cpu->dyn_vreg_xml;
b93777e1
BM
1744 }
1745
1746 return NULL;
1747}
1748
8b80bd28 1749#ifndef CONFIG_USER_ONLY
f1bd6f8e
MC
1750static int64_t riscv_get_arch_id(CPUState *cs)
1751{
1752 RISCVCPU *cpu = RISCV_CPU(cs);
1753
1754 return cpu->env.mhartid;
1755}
1756
8b80bd28
PMD
1757#include "hw/core/sysemu-cpu-ops.h"
1758
1759static const struct SysemuCPUOps riscv_sysemu_ops = {
08928c6d 1760 .get_phys_page_debug = riscv_cpu_get_phys_page_debug,
715e3c1a
PMD
1761 .write_elf64_note = riscv_cpu_write_elf64_note,
1762 .write_elf32_note = riscv_cpu_write_elf32_note,
feece4d0 1763 .legacy_vmsd = &vmstate_riscv_cpu,
8b80bd28
PMD
1764};
1765#endif
1766
1e341500
DHB
1767static bool riscv_cpu_is_dynamic(Object *cpu_obj)
1768{
1769 return object_dynamic_cast(cpu_obj, TYPE_RISCV_DYNAMIC_CPU) != NULL;
1770}
1771
1772static void cpu_set_mvendorid(Object *obj, Visitor *v, const char *name,
1773 void *opaque, Error **errp)
1774{
1775 bool dynamic_cpu = riscv_cpu_is_dynamic(obj);
1776 RISCVCPU *cpu = RISCV_CPU(obj);
1777 uint32_t prev_val = cpu->cfg.mvendorid;
1778 uint32_t value;
1779
1780 if (!visit_type_uint32(v, name, &value, errp)) {
1781 return;
1782 }
1783
1784 if (!dynamic_cpu && prev_val != value) {
1785 error_setg(errp, "Unable to change %s mvendorid (0x%x)",
1786 object_get_typename(obj), prev_val);
1787 return;
1788 }
1789
1790 cpu->cfg.mvendorid = value;
1791}
1792
1793static void cpu_get_mvendorid(Object *obj, Visitor *v, const char *name,
1794 void *opaque, Error **errp)
1795{
1796 bool value = RISCV_CPU(obj)->cfg.mvendorid;
1797
1798 visit_type_bool(v, name, &value, errp);
1799}
1800
a1863ad3
DHB
1801static void cpu_set_mimpid(Object *obj, Visitor *v, const char *name,
1802 void *opaque, Error **errp)
1803{
1804 bool dynamic_cpu = riscv_cpu_is_dynamic(obj);
1805 RISCVCPU *cpu = RISCV_CPU(obj);
1806 uint64_t prev_val = cpu->cfg.mimpid;
1807 uint64_t value;
1808
1809 if (!visit_type_uint64(v, name, &value, errp)) {
1810 return;
1811 }
1812
1813 if (!dynamic_cpu && prev_val != value) {
1814 error_setg(errp, "Unable to change %s mimpid (0x%" PRIu64 ")",
1815 object_get_typename(obj), prev_val);
1816 return;
1817 }
1818
1819 cpu->cfg.mimpid = value;
1820}
1821
1822static void cpu_get_mimpid(Object *obj, Visitor *v, const char *name,
1823 void *opaque, Error **errp)
1824{
1825 bool value = RISCV_CPU(obj)->cfg.mimpid;
1826
1827 visit_type_bool(v, name, &value, errp);
1828}
1829
d6a427e2
DHB
1830static void cpu_set_marchid(Object *obj, Visitor *v, const char *name,
1831 void *opaque, Error **errp)
1832{
1833 bool dynamic_cpu = riscv_cpu_is_dynamic(obj);
1834 RISCVCPU *cpu = RISCV_CPU(obj);
1835 uint64_t prev_val = cpu->cfg.marchid;
1836 uint64_t value, invalid_val;
1837 uint32_t mxlen = 0;
1838
1839 if (!visit_type_uint64(v, name, &value, errp)) {
1840 return;
1841 }
1842
1843 if (!dynamic_cpu && prev_val != value) {
1844 error_setg(errp, "Unable to change %s marchid (0x%" PRIu64 ")",
1845 object_get_typename(obj), prev_val);
1846 return;
1847 }
1848
1849 switch (riscv_cpu_mxl(&cpu->env)) {
1850 case MXL_RV32:
1851 mxlen = 32;
1852 break;
1853 case MXL_RV64:
1854 case MXL_RV128:
1855 mxlen = 64;
1856 break;
1857 default:
1858 g_assert_not_reached();
1859 }
1860
1861 invalid_val = 1LL << (mxlen - 1);
1862
1863 if (value == invalid_val) {
1864 error_setg(errp, "Unable to set marchid with MSB (%u) bit set "
1865 "and the remaining bits zero", mxlen);
1866 return;
1867 }
1868
1869 cpu->cfg.marchid = value;
1870}
1871
1872static void cpu_get_marchid(Object *obj, Visitor *v, const char *name,
1873 void *opaque, Error **errp)
1874{
1875 bool value = RISCV_CPU(obj)->cfg.marchid;
1876
1877 visit_type_bool(v, name, &value, errp);
1878}
1879
dc5bd18f
MC
1880static void riscv_cpu_class_init(ObjectClass *c, void *data)
1881{
1882 RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
1883 CPUClass *cc = CPU_CLASS(c);
1884 DeviceClass *dc = DEVICE_CLASS(c);
4fa485a7 1885 ResettableClass *rc = RESETTABLE_CLASS(c);
dc5bd18f 1886
41fbbba7
MZ
1887 device_class_set_parent_realize(dc, riscv_cpu_realize,
1888 &mcc->parent_realize);
dc5bd18f 1889
4fa485a7
PM
1890 resettable_class_set_parent_phases(rc, NULL, riscv_cpu_reset_hold, NULL,
1891 &mcc->parent_phases);
dc5bd18f
MC
1892
1893 cc->class_by_name = riscv_cpu_class_by_name;
1894 cc->has_work = riscv_cpu_has_work;
dc5bd18f
MC
1895 cc->dump_state = riscv_cpu_dump_state;
1896 cc->set_pc = riscv_cpu_set_pc;
e4fdf9df 1897 cc->get_pc = riscv_cpu_get_pc;
dc5bd18f
MC
1898 cc->gdb_read_register = riscv_cpu_gdb_read_register;
1899 cc->gdb_write_register = riscv_cpu_gdb_write_register;
5371f5cd 1900 cc->gdb_num_core_regs = 33;
dc5bd18f
MC
1901 cc->gdb_stop_before_watchpoint = true;
1902 cc->disas_set_info = riscv_cpu_disas_set_info;
8a4ca3c1 1903#ifndef CONFIG_USER_ONLY
8b80bd28 1904 cc->sysemu_ops = &riscv_sysemu_ops;
f1bd6f8e 1905 cc->get_arch_id = riscv_get_arch_id;
dc5bd18f 1906#endif
edf64786 1907 cc->gdb_arch_name = riscv_gdb_arch_name;
b93777e1 1908 cc->gdb_get_dynamic_xml = riscv_gdb_get_dynamic_xml;
6a3d2e7c 1909
1e341500
DHB
1910 object_class_property_add(c, "mvendorid", "uint32", cpu_get_mvendorid,
1911 cpu_set_mvendorid, NULL, NULL);
a1863ad3
DHB
1912
1913 object_class_property_add(c, "mimpid", "uint64", cpu_get_mimpid,
1914 cpu_set_mimpid, NULL, NULL);
d6a427e2
DHB
1915
1916 object_class_property_add(c, "marchid", "uint64", cpu_get_marchid,
1917 cpu_set_marchid, NULL, NULL);
1e341500 1918
4f67d30b 1919 device_class_set_props(dc, riscv_cpu_properties);
dc5bd18f
MC
1920}
1921
246f8796
WL
1922static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str,
1923 int max_str_len)
a775398b
AP
1924{
1925 char *old = *isa_str;
1926 char *new = *isa_str;
1927 int i;
1928
a775398b 1929 for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
5f2c80f1 1930 if (isa_ext_is_enabled(cpu, isa_edata_arr[i].ext_enable_offset)) {
a775398b
AP
1931 new = g_strconcat(old, "_", isa_edata_arr[i].name, NULL);
1932 g_free(old);
1933 old = new;
1934 }
1935 }
1936
1937 *isa_str = new;
1938}
1939
dc5bd18f
MC
1940char *riscv_isa_string(RISCVCPU *cpu)
1941{
1942 int i;
0e2c3770 1943 const size_t maxlen = sizeof("rv128") + sizeof(riscv_single_letter_exts);
d1fd31f8
MC
1944 char *isa_str = g_new(char, maxlen);
1945 char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", TARGET_LONG_BITS);
0e2c3770
TO
1946 for (i = 0; i < sizeof(riscv_single_letter_exts) - 1; i++) {
1947 if (cpu->env.misa_ext & RV(riscv_single_letter_exts[i])) {
1948 *p++ = qemu_tolower(riscv_single_letter_exts[i]);
dc5bd18f
MC
1949 }
1950 }
d1fd31f8 1951 *p = '\0';
a4a9a443
TO
1952 if (!cpu->cfg.short_isa_string) {
1953 riscv_isa_string_ext(cpu, &isa_str, maxlen);
1954 }
d1fd31f8 1955 return isa_str;
dc5bd18f
MC
1956}
1957
eab15862 1958static gint riscv_cpu_list_compare(gconstpointer a, gconstpointer b)
dc5bd18f 1959{
eab15862
MC
1960 ObjectClass *class_a = (ObjectClass *)a;
1961 ObjectClass *class_b = (ObjectClass *)b;
1962 const char *name_a, *name_b;
dc5bd18f 1963
eab15862
MC
1964 name_a = object_class_get_name(class_a);
1965 name_b = object_class_get_name(class_b);
1966 return strcmp(name_a, name_b);
dc5bd18f
MC
1967}
1968
eab15862 1969static void riscv_cpu_list_entry(gpointer data, gpointer user_data)
dc5bd18f 1970{
eab15862
MC
1971 const char *typename = object_class_get_name(OBJECT_CLASS(data));
1972 int len = strlen(typename) - strlen(RISCV_CPU_TYPE_SUFFIX);
dc5bd18f 1973
0442428a 1974 qemu_printf("%.*s\n", len, typename);
eab15862 1975}
dc5bd18f 1976
0442428a 1977void riscv_cpu_list(void)
eab15862 1978{
eab15862
MC
1979 GSList *list;
1980
1981 list = object_class_get_list(TYPE_RISCV_CPU, false);
1982 list = g_slist_sort(list, riscv_cpu_list_compare);
0442428a 1983 g_slist_foreach(list, riscv_cpu_list_entry, NULL);
eab15862 1984 g_slist_free(list);
dc5bd18f
MC
1985}
1986
eab15862
MC
1987#define DEFINE_CPU(type_name, initfn) \
1988 { \
1989 .name = type_name, \
1990 .parent = TYPE_RISCV_CPU, \
1991 .instance_init = initfn \
1992 }
1993
9e1a30d3
DHB
1994#define DEFINE_DYNAMIC_CPU(type_name, initfn) \
1995 { \
1996 .name = type_name, \
1997 .parent = TYPE_RISCV_DYNAMIC_CPU, \
1998 .instance_init = initfn \
1999 }
2000
eab15862
MC
2001static const TypeInfo riscv_cpu_type_infos[] = {
2002 {
2003 .name = TYPE_RISCV_CPU,
2004 .parent = TYPE_CPU,
2005 .instance_size = sizeof(RISCVCPU),
f669c992 2006 .instance_align = __alignof(RISCVCPU),
eab15862
MC
2007 .instance_init = riscv_cpu_init,
2008 .abstract = true,
2009 .class_size = sizeof(RISCVCPUClass),
2010 .class_init = riscv_cpu_class_init,
2011 },
9e1a30d3
DHB
2012 {
2013 .name = TYPE_RISCV_DYNAMIC_CPU,
2014 .parent = TYPE_RISCV_CPU,
2015 .abstract = true,
2016 },
2017 DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
b97e5a6b 2018 DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_MAX, riscv_max_cpu_init),
10f1ca27
YJ
2019#if defined(CONFIG_KVM)
2020 DEFINE_CPU(TYPE_RISCV_CPU_HOST, riscv_host_cpu_init),
2021#endif
eab15862 2022#if defined(TARGET_RISCV32)
9e1a30d3 2023 DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE32, rv32_base_cpu_init),
e8905c6c 2024 DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init),
114baaca 2025 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32_sifive_e_cpu_init),
2fdd2c09 2026 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init),
114baaca 2027 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32_sifive_u_cpu_init),
eab15862 2028#elif defined(TARGET_RISCV64)
9e1a30d3 2029 DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE64, rv64_base_cpu_init),
114baaca
AF
2030 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64_sifive_e_cpu_init),
2031 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64_sifive_u_cpu_init),
6ddc7069 2032 DEFINE_CPU(TYPE_RISCV_CPU_SHAKTI_C, rv64_sifive_u_cpu_init),
95bd8daa 2033 DEFINE_CPU(TYPE_RISCV_CPU_THEAD_C906, rv64_thead_c906_cpu_init),
e1d084a8 2034 DEFINE_CPU(TYPE_RISCV_CPU_VEYRON_V1, rv64_veyron_v1_cpu_init),
9e1a30d3 2035 DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128, rv128_base_cpu_init),
eab15862
MC
2036#endif
2037};
2038
2039DEFINE_TYPES(riscv_cpu_type_infos)