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