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