]> git.proxmox.com Git - mirror_qemu.git/blame - target/riscv/cpu.c
RISC-V: Clear load reservations on context switch and SC
[mirror_qemu.git] / target / riscv / cpu.c
CommitLineData
dc5bd18f
MC
1/*
2 * QEMU RISC-V CPU
3 *
4 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5 * Copyright (c) 2017-2018 SiFive, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2 or later, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "qemu/osdep.h"
0442428a 21#include "qemu/qemu-print.h"
856dfd8a 22#include "qemu/ctype.h"
dc5bd18f
MC
23#include "qemu/log.h"
24#include "cpu.h"
25#include "exec/exec-all.h"
26#include "qapi/error.h"
b55d7d34 27#include "qemu/error-report.h"
c4e95030 28#include "hw/qdev-properties.h"
dc5bd18f
MC
29#include "migration/vmstate.h"
30
31/* RISC-V CPU definitions */
32
79f86934 33static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
dc5bd18f
MC
34
35const char * const riscv_int_regnames[] = {
7f9188e2
RH
36 "zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2",
37 "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5",
38 "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7",
39 "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6"
dc5bd18f
MC
40};
41
42const char * const riscv_fpr_regnames[] = {
7f9188e2
RH
43 "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7",
44 "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5",
45 "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7",
46 "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11"
dc5bd18f
MC
47};
48
49const char * const riscv_excp_names[] = {
50 "misaligned_fetch",
51 "fault_fetch",
52 "illegal_instruction",
53 "breakpoint",
54 "misaligned_load",
55 "fault_load",
56 "misaligned_store",
57 "fault_store",
58 "user_ecall",
59 "supervisor_ecall",
60 "hypervisor_ecall",
61 "machine_ecall",
62 "exec_page_fault",
63 "load_page_fault",
64 "reserved",
65 "store_page_fault"
66};
67
68const char * const riscv_intr_names[] = {
69 "u_software",
70 "s_software",
71 "h_software",
72 "m_software",
73 "u_timer",
74 "s_timer",
75 "h_timer",
76 "m_timer",
77 "u_external",
78 "s_external",
79 "h_external",
80 "m_external",
426f0348
MC
81 "reserved",
82 "reserved",
83 "reserved",
84 "reserved"
dc5bd18f
MC
85};
86
dc5bd18f
MC
87static void set_misa(CPURISCVState *env, target_ulong misa)
88{
f18637cd 89 env->misa_mask = env->misa = misa;
dc5bd18f
MC
90}
91
c9a73910 92static void set_priv_version(CPURISCVState *env, int priv_ver)
dc5bd18f 93{
dc5bd18f
MC
94 env->priv_ver = priv_ver;
95}
96
97static void set_feature(CPURISCVState *env, int feature)
98{
99 env->features |= (1ULL << feature);
100}
101
102static void set_resetvec(CPURISCVState *env, int resetvec)
103{
104#ifndef CONFIG_USER_ONLY
105 env->resetvec = resetvec;
106#endif
107}
108
109static void riscv_any_cpu_init(Object *obj)
110{
111 CPURISCVState *env = &RISCV_CPU(obj)->env;
112 set_misa(env, RVXLEN | RVI | RVM | RVA | RVF | RVD | RVC | RVU);
c9a73910 113 set_priv_version(env, PRIV_VERSION_1_11_0);
dc5bd18f
MC
114 set_resetvec(env, DEFAULT_RSTVEC);
115}
116
eab15862
MC
117#if defined(TARGET_RISCV32)
118
8903bf6e
AF
119static void riscv_base32_cpu_init(Object *obj)
120{
121 CPURISCVState *env = &RISCV_CPU(obj)->env;
b55d7d34
AF
122 /* We set this in the realise function */
123 set_misa(env, 0);
8903bf6e
AF
124}
125
dc5bd18f
MC
126static void rv32gcsu_priv1_09_1_cpu_init(Object *obj)
127{
128 CPURISCVState *env = &RISCV_CPU(obj)->env;
129 set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
c9a73910 130 set_priv_version(env, PRIV_VERSION_1_09_1);
dc5bd18f
MC
131 set_resetvec(env, DEFAULT_RSTVEC);
132 set_feature(env, RISCV_FEATURE_MMU);
a88365c1 133 set_feature(env, RISCV_FEATURE_PMP);
dc5bd18f
MC
134}
135
136static void rv32gcsu_priv1_10_0_cpu_init(Object *obj)
137{
138 CPURISCVState *env = &RISCV_CPU(obj)->env;
139 set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
c9a73910 140 set_priv_version(env, PRIV_VERSION_1_10_0);
dc5bd18f
MC
141 set_resetvec(env, DEFAULT_RSTVEC);
142 set_feature(env, RISCV_FEATURE_MMU);
a88365c1 143 set_feature(env, RISCV_FEATURE_PMP);
dc5bd18f
MC
144}
145
146static void rv32imacu_nommu_cpu_init(Object *obj)
147{
148 CPURISCVState *env = &RISCV_CPU(obj)->env;
149 set_misa(env, RV32 | RVI | RVM | RVA | RVC | RVU);
c9a73910 150 set_priv_version(env, PRIV_VERSION_1_10_0);
dc5bd18f 151 set_resetvec(env, DEFAULT_RSTVEC);
a88365c1 152 set_feature(env, RISCV_FEATURE_PMP);
dc5bd18f
MC
153}
154
eab15862
MC
155#elif defined(TARGET_RISCV64)
156
8903bf6e
AF
157static void riscv_base64_cpu_init(Object *obj)
158{
159 CPURISCVState *env = &RISCV_CPU(obj)->env;
b55d7d34
AF
160 /* We set this in the realise function */
161 set_misa(env, 0);
8903bf6e
AF
162}
163
dc5bd18f
MC
164static void rv64gcsu_priv1_09_1_cpu_init(Object *obj)
165{
166 CPURISCVState *env = &RISCV_CPU(obj)->env;
167 set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
c9a73910 168 set_priv_version(env, PRIV_VERSION_1_09_1);
dc5bd18f
MC
169 set_resetvec(env, DEFAULT_RSTVEC);
170 set_feature(env, RISCV_FEATURE_MMU);
a88365c1 171 set_feature(env, RISCV_FEATURE_PMP);
dc5bd18f
MC
172}
173
174static void rv64gcsu_priv1_10_0_cpu_init(Object *obj)
175{
176 CPURISCVState *env = &RISCV_CPU(obj)->env;
177 set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
c9a73910 178 set_priv_version(env, PRIV_VERSION_1_10_0);
dc5bd18f
MC
179 set_resetvec(env, DEFAULT_RSTVEC);
180 set_feature(env, RISCV_FEATURE_MMU);
a88365c1 181 set_feature(env, RISCV_FEATURE_PMP);
dc5bd18f
MC
182}
183
184static void rv64imacu_nommu_cpu_init(Object *obj)
185{
186 CPURISCVState *env = &RISCV_CPU(obj)->env;
187 set_misa(env, RV64 | RVI | RVM | RVA | RVC | RVU);
c9a73910 188 set_priv_version(env, PRIV_VERSION_1_10_0);
dc5bd18f 189 set_resetvec(env, DEFAULT_RSTVEC);
a88365c1 190 set_feature(env, RISCV_FEATURE_PMP);
dc5bd18f
MC
191}
192
eab15862 193#endif
dc5bd18f
MC
194
195static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
196{
197 ObjectClass *oc;
198 char *typename;
199 char **cpuname;
200
201 cpuname = g_strsplit(cpu_model, ",", 1);
202 typename = g_strdup_printf(RISCV_CPU_TYPE_NAME("%s"), cpuname[0]);
203 oc = object_class_by_name(typename);
204 g_strfreev(cpuname);
205 g_free(typename);
206 if (!oc || !object_class_dynamic_cast(oc, TYPE_RISCV_CPU) ||
207 object_class_is_abstract(oc)) {
208 return NULL;
209 }
210 return oc;
211}
212
90c84c56 213static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
dc5bd18f
MC
214{
215 RISCVCPU *cpu = RISCV_CPU(cs);
216 CPURISCVState *env = &cpu->env;
217 int i;
218
90c84c56 219 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "pc ", env->pc);
dc5bd18f 220#ifndef CONFIG_USER_ONLY
90c84c56
MA
221 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mhartid ", env->mhartid);
222 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", env->mstatus);
223 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mip ",
224 (target_ulong)atomic_read(&env->mip));
225 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mie ", env->mie);
226 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mideleg ", env->mideleg);
227 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "medeleg ", env->medeleg);
228 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mtvec ", env->mtvec);
229 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mepc ", env->mepc);
230 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mcause ", env->mcause);
dc5bd18f
MC
231#endif
232
233 for (i = 0; i < 32; i++) {
90c84c56
MA
234 qemu_fprintf(f, " %s " TARGET_FMT_lx,
235 riscv_int_regnames[i], env->gpr[i]);
dc5bd18f 236 if ((i & 3) == 3) {
90c84c56 237 qemu_fprintf(f, "\n");
dc5bd18f
MC
238 }
239 }
86ea1880
RH
240 if (flags & CPU_DUMP_FPU) {
241 for (i = 0; i < 32; i++) {
90c84c56
MA
242 qemu_fprintf(f, " %s %016" PRIx64,
243 riscv_fpr_regnames[i], env->fpr[i]);
86ea1880 244 if ((i & 3) == 3) {
90c84c56 245 qemu_fprintf(f, "\n");
86ea1880 246 }
dc5bd18f
MC
247 }
248 }
249}
250
251static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
252{
253 RISCVCPU *cpu = RISCV_CPU(cs);
254 CPURISCVState *env = &cpu->env;
255 env->pc = value;
256}
257
258static void riscv_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
259{
260 RISCVCPU *cpu = RISCV_CPU(cs);
261 CPURISCVState *env = &cpu->env;
262 env->pc = tb->pc;
263}
264
265static bool riscv_cpu_has_work(CPUState *cs)
266{
267#ifndef CONFIG_USER_ONLY
268 RISCVCPU *cpu = RISCV_CPU(cs);
269 CPURISCVState *env = &cpu->env;
270 /*
271 * Definition of the WFI instruction requires it to ignore the privilege
272 * mode and delegation registers, but respect individual enables
273 */
274 return (atomic_read(&env->mip) & env->mie) != 0;
275#else
276 return true;
277#endif
278}
279
280void restore_state_to_opc(CPURISCVState *env, TranslationBlock *tb,
281 target_ulong *data)
282{
283 env->pc = data[0];
284}
285
286static void riscv_cpu_reset(CPUState *cs)
287{
288 RISCVCPU *cpu = RISCV_CPU(cs);
289 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
290 CPURISCVState *env = &cpu->env;
291
292 mcc->parent_reset(cs);
293#ifndef CONFIG_USER_ONLY
294 env->priv = PRV_M;
295 env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV);
296 env->mcause = 0;
297 env->pc = env->resetvec;
298#endif
299 cs->exception_index = EXCP_NONE;
c13b169f 300 env->load_res = -1;
dc5bd18f
MC
301 set_default_nan_mode(1, &env->fp_status);
302}
303
304static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
305{
306#if defined(TARGET_RISCV32)
307 info->print_insn = print_insn_riscv32;
308#elif defined(TARGET_RISCV64)
309 info->print_insn = print_insn_riscv64;
310#endif
311}
312
313static void riscv_cpu_realize(DeviceState *dev, Error **errp)
314{
315 CPUState *cs = CPU(dev);
c4e95030
AF
316 RISCVCPU *cpu = RISCV_CPU(dev);
317 CPURISCVState *env = &cpu->env;
dc5bd18f 318 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
e3147506 319 int priv_version = PRIV_VERSION_1_11_0;
b55d7d34 320 target_ulong target_misa = 0;
dc5bd18f
MC
321 Error *local_err = NULL;
322
323 cpu_exec_realizefn(cs, &local_err);
324 if (local_err != NULL) {
325 error_propagate(errp, local_err);
326 return;
327 }
328
c4e95030 329 if (cpu->cfg.priv_spec) {
e3147506
AF
330 if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) {
331 priv_version = PRIV_VERSION_1_11_0;
332 } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) {
c4e95030
AF
333 priv_version = PRIV_VERSION_1_10_0;
334 } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.9.1")) {
335 priv_version = PRIV_VERSION_1_09_1;
336 } else {
337 error_setg(errp,
338 "Unsupported privilege spec version '%s'",
339 cpu->cfg.priv_spec);
340 return;
341 }
342 }
343
c9a73910 344 set_priv_version(env, priv_version);
c4e95030
AF
345 set_resetvec(env, DEFAULT_RSTVEC);
346
347 if (cpu->cfg.mmu) {
348 set_feature(env, RISCV_FEATURE_MMU);
349 }
350
351 if (cpu->cfg.pmp) {
352 set_feature(env, RISCV_FEATURE_PMP);
353 }
354
b55d7d34
AF
355 /* If misa isn't set (rv32 and rv64 machines) set it here */
356 if (!env->misa) {
357 /* Do some ISA extension error checking */
358 if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
359 error_setg(errp,
360 "I and E extensions are incompatible");
361 return;
362 }
363
bdddd446
AF
364 if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) {
365 error_setg(errp,
366 "Either I or E extension must be set");
367 return;
368 }
369
b55d7d34
AF
370 if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m &
371 cpu->cfg.ext_a & cpu->cfg.ext_f &
372 cpu->cfg.ext_d)) {
373 warn_report("Setting G will also set IMAFD");
374 cpu->cfg.ext_i = true;
375 cpu->cfg.ext_m = true;
376 cpu->cfg.ext_a = true;
377 cpu->cfg.ext_f = true;
378 cpu->cfg.ext_d = true;
379 }
380
381 /* Set the ISA extensions, checks should have happened above */
382 if (cpu->cfg.ext_i) {
383 target_misa |= RVI;
384 }
385 if (cpu->cfg.ext_e) {
386 target_misa |= RVE;
387 }
388 if (cpu->cfg.ext_m) {
389 target_misa |= RVM;
390 }
391 if (cpu->cfg.ext_a) {
392 target_misa |= RVA;
393 }
394 if (cpu->cfg.ext_f) {
395 target_misa |= RVF;
396 }
397 if (cpu->cfg.ext_d) {
398 target_misa |= RVD;
399 }
400 if (cpu->cfg.ext_c) {
401 target_misa |= RVC;
402 }
403 if (cpu->cfg.ext_s) {
404 target_misa |= RVS;
405 }
406 if (cpu->cfg.ext_u) {
407 target_misa |= RVU;
408 }
409
410 set_misa(env, RVXLEN | target_misa);
411 }
412
5371f5cd
JW
413 riscv_cpu_register_gdb_regs_for_features(cs);
414
dc5bd18f
MC
415 qemu_init_vcpu(cs);
416 cpu_reset(cs);
417
418 mcc->parent_realize(dev, errp);
419}
420
421static void riscv_cpu_init(Object *obj)
422{
dc5bd18f
MC
423 RISCVCPU *cpu = RISCV_CPU(obj);
424
7506ed90 425 cpu_set_cpustate_pointers(cpu);
dc5bd18f
MC
426}
427
428static const VMStateDescription vmstate_riscv_cpu = {
429 .name = "cpu",
430 .unmigratable = 1,
431};
432
c4e95030 433static Property riscv_cpu_properties[] = {
b55d7d34
AF
434 DEFINE_PROP_BOOL("i", RISCVCPU, cfg.ext_i, true),
435 DEFINE_PROP_BOOL("e", RISCVCPU, cfg.ext_e, false),
436 DEFINE_PROP_BOOL("g", RISCVCPU, cfg.ext_g, true),
437 DEFINE_PROP_BOOL("m", RISCVCPU, cfg.ext_m, true),
438 DEFINE_PROP_BOOL("a", RISCVCPU, cfg.ext_a, true),
439 DEFINE_PROP_BOOL("f", RISCVCPU, cfg.ext_f, true),
440 DEFINE_PROP_BOOL("d", RISCVCPU, cfg.ext_d, true),
441 DEFINE_PROP_BOOL("c", RISCVCPU, cfg.ext_c, true),
442 DEFINE_PROP_BOOL("s", RISCVCPU, cfg.ext_s, true),
443 DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
0a13a5b8 444 DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true),
50fba816 445 DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
591bddea 446 DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
c4e95030 447 DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
c4e95030
AF
448 DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
449 DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
450 DEFINE_PROP_END_OF_LIST(),
451};
452
dc5bd18f
MC
453static void riscv_cpu_class_init(ObjectClass *c, void *data)
454{
455 RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
456 CPUClass *cc = CPU_CLASS(c);
457 DeviceClass *dc = DEVICE_CLASS(c);
458
41fbbba7
MZ
459 device_class_set_parent_realize(dc, riscv_cpu_realize,
460 &mcc->parent_realize);
dc5bd18f
MC
461
462 mcc->parent_reset = cc->reset;
463 cc->reset = riscv_cpu_reset;
464
465 cc->class_by_name = riscv_cpu_class_by_name;
466 cc->has_work = riscv_cpu_has_work;
467 cc->do_interrupt = riscv_cpu_do_interrupt;
468 cc->cpu_exec_interrupt = riscv_cpu_exec_interrupt;
469 cc->dump_state = riscv_cpu_dump_state;
470 cc->set_pc = riscv_cpu_set_pc;
471 cc->synchronize_from_tb = riscv_cpu_synchronize_from_tb;
472 cc->gdb_read_register = riscv_cpu_gdb_read_register;
473 cc->gdb_write_register = riscv_cpu_gdb_write_register;
5371f5cd
JW
474 cc->gdb_num_core_regs = 33;
475#if defined(TARGET_RISCV32)
476 cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
477#elif defined(TARGET_RISCV64)
478 cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
479#endif
dc5bd18f
MC
480 cc->gdb_stop_before_watchpoint = true;
481 cc->disas_set_info = riscv_cpu_disas_set_info;
8a4ca3c1 482#ifndef CONFIG_USER_ONLY
cbf58276 483 cc->do_unassigned_access = riscv_cpu_unassigned_access;
dc5bd18f
MC
484 cc->do_unaligned_access = riscv_cpu_do_unaligned_access;
485 cc->get_phys_page_debug = riscv_cpu_get_phys_page_debug;
486#endif
487#ifdef CONFIG_TCG
488 cc->tcg_initialize = riscv_translate_init;
8a4ca3c1 489 cc->tlb_fill = riscv_cpu_tlb_fill;
dc5bd18f
MC
490#endif
491 /* For now, mark unmigratable: */
492 cc->vmsd = &vmstate_riscv_cpu;
c4e95030 493 dc->props = riscv_cpu_properties;
dc5bd18f
MC
494}
495
dc5bd18f
MC
496char *riscv_isa_string(RISCVCPU *cpu)
497{
498 int i;
d1fd31f8
MC
499 const size_t maxlen = sizeof("rv128") + sizeof(riscv_exts) + 1;
500 char *isa_str = g_new(char, maxlen);
501 char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", TARGET_LONG_BITS);
dc5bd18f
MC
502 for (i = 0; i < sizeof(riscv_exts); i++) {
503 if (cpu->env.misa & RV(riscv_exts[i])) {
d1fd31f8 504 *p++ = qemu_tolower(riscv_exts[i]);
dc5bd18f
MC
505 }
506 }
d1fd31f8
MC
507 *p = '\0';
508 return isa_str;
dc5bd18f
MC
509}
510
eab15862 511static gint riscv_cpu_list_compare(gconstpointer a, gconstpointer b)
dc5bd18f 512{
eab15862
MC
513 ObjectClass *class_a = (ObjectClass *)a;
514 ObjectClass *class_b = (ObjectClass *)b;
515 const char *name_a, *name_b;
dc5bd18f 516
eab15862
MC
517 name_a = object_class_get_name(class_a);
518 name_b = object_class_get_name(class_b);
519 return strcmp(name_a, name_b);
dc5bd18f
MC
520}
521
eab15862 522static void riscv_cpu_list_entry(gpointer data, gpointer user_data)
dc5bd18f 523{
eab15862
MC
524 const char *typename = object_class_get_name(OBJECT_CLASS(data));
525 int len = strlen(typename) - strlen(RISCV_CPU_TYPE_SUFFIX);
dc5bd18f 526
0442428a 527 qemu_printf("%.*s\n", len, typename);
eab15862 528}
dc5bd18f 529
0442428a 530void riscv_cpu_list(void)
eab15862 531{
eab15862
MC
532 GSList *list;
533
534 list = object_class_get_list(TYPE_RISCV_CPU, false);
535 list = g_slist_sort(list, riscv_cpu_list_compare);
0442428a 536 g_slist_foreach(list, riscv_cpu_list_entry, NULL);
eab15862 537 g_slist_free(list);
dc5bd18f
MC
538}
539
eab15862
MC
540#define DEFINE_CPU(type_name, initfn) \
541 { \
542 .name = type_name, \
543 .parent = TYPE_RISCV_CPU, \
544 .instance_init = initfn \
545 }
546
547static const TypeInfo riscv_cpu_type_infos[] = {
548 {
549 .name = TYPE_RISCV_CPU,
550 .parent = TYPE_CPU,
551 .instance_size = sizeof(RISCVCPU),
552 .instance_init = riscv_cpu_init,
553 .abstract = true,
554 .class_size = sizeof(RISCVCPUClass),
555 .class_init = riscv_cpu_class_init,
556 },
557 DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
558#if defined(TARGET_RISCV32)
8903bf6e 559 DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base32_cpu_init),
eab15862 560 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32imacu_nommu_cpu_init),
c1fb65e6
AF
561 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32gcsu_priv1_10_0_cpu_init),
562 /* Depreacted */
563 DEFINE_CPU(TYPE_RISCV_CPU_RV32IMACU_NOMMU, rv32imacu_nommu_cpu_init),
564 DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_09_1, rv32gcsu_priv1_09_1_cpu_init),
565 DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_10_0, rv32gcsu_priv1_10_0_cpu_init)
eab15862 566#elif defined(TARGET_RISCV64)
8903bf6e 567 DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base64_cpu_init),
eab15862 568 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64imacu_nommu_cpu_init),
c1fb65e6
AF
569 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64gcsu_priv1_10_0_cpu_init),
570 /* Deprecated */
571 DEFINE_CPU(TYPE_RISCV_CPU_RV64IMACU_NOMMU, rv64imacu_nommu_cpu_init),
572 DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_09_1, rv64gcsu_priv1_09_1_cpu_init),
573 DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_10_0, rv64gcsu_priv1_10_0_cpu_init)
eab15862
MC
574#endif
575};
576
577DEFINE_TYPES(riscv_cpu_type_infos)