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