4 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5 * Copyright (c) 2017-2018 SiFive, Inc.
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.
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
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/>.
20 #include "qemu/osdep.h"
23 #include "exec/exec-all.h"
24 #include "qapi/error.h"
25 #include "migration/vmstate.h"
27 /* RISC-V CPU definitions */
29 static const char riscv_exts
[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
31 const char * const riscv_int_regnames
[] = {
32 "zero", "ra ", "sp ", "gp ", "tp ", "t0 ", "t1 ", "t2 ",
33 "s0 ", "s1 ", "a0 ", "a1 ", "a2 ", "a3 ", "a4 ", "a5 ",
34 "a6 ", "a7 ", "s2 ", "s3 ", "s4 ", "s5 ", "s6 ", "s7 ",
35 "s8 ", "s9 ", "s10 ", "s11 ", "t3 ", "t4 ", "t5 ", "t6 "
38 const char * const riscv_fpr_regnames
[] = {
39 "ft0 ", "ft1 ", "ft2 ", "ft3 ", "ft4 ", "ft5 ", "ft6 ", "ft7 ",
40 "fs0 ", "fs1 ", "fa0 ", "fa1 ", "fa2 ", "fa3 ", "fa4 ", "fa5 ",
41 "fa6 ", "fa7 ", "fs2 ", "fs3 ", "fs4 ", "fs5 ", "fs6 ", "fs7 ",
42 "fs8 ", "fs9 ", "fs10", "fs11", "ft8 ", "ft9 ", "ft10", "ft11"
45 const char * const riscv_excp_names
[] = {
48 "illegal_instruction",
64 const char * const riscv_intr_names
[] = {
83 static void set_misa(CPURISCVState
*env
, target_ulong misa
)
85 env
->misa_mask
= env
->misa
= misa
;
88 static void set_versions(CPURISCVState
*env
, int user_ver
, int priv_ver
)
90 env
->user_ver
= user_ver
;
91 env
->priv_ver
= priv_ver
;
94 static void set_feature(CPURISCVState
*env
, int feature
)
96 env
->features
|= (1ULL << feature
);
99 static void set_resetvec(CPURISCVState
*env
, int resetvec
)
101 #ifndef CONFIG_USER_ONLY
102 env
->resetvec
= resetvec
;
106 static void riscv_any_cpu_init(Object
*obj
)
108 CPURISCVState
*env
= &RISCV_CPU(obj
)->env
;
109 set_misa(env
, RVXLEN
| RVI
| RVM
| RVA
| RVF
| RVD
| RVC
| RVU
);
110 set_versions(env
, USER_VERSION_2_02_0
, PRIV_VERSION_1_10_0
);
111 set_resetvec(env
, DEFAULT_RSTVEC
);
114 #if defined(TARGET_RISCV32)
116 static void rv32gcsu_priv1_09_1_cpu_init(Object
*obj
)
118 CPURISCVState
*env
= &RISCV_CPU(obj
)->env
;
119 set_misa(env
, RV32
| RVI
| RVM
| RVA
| RVF
| RVD
| RVC
| RVS
| RVU
);
120 set_versions(env
, USER_VERSION_2_02_0
, PRIV_VERSION_1_09_1
);
121 set_resetvec(env
, DEFAULT_RSTVEC
);
122 set_feature(env
, RISCV_FEATURE_MMU
);
123 set_feature(env
, RISCV_FEATURE_PMP
);
126 static void rv32gcsu_priv1_10_0_cpu_init(Object
*obj
)
128 CPURISCVState
*env
= &RISCV_CPU(obj
)->env
;
129 set_misa(env
, RV32
| RVI
| RVM
| RVA
| RVF
| RVD
| RVC
| RVS
| RVU
);
130 set_versions(env
, USER_VERSION_2_02_0
, PRIV_VERSION_1_10_0
);
131 set_resetvec(env
, DEFAULT_RSTVEC
);
132 set_feature(env
, RISCV_FEATURE_MMU
);
133 set_feature(env
, RISCV_FEATURE_PMP
);
136 static void rv32imacu_nommu_cpu_init(Object
*obj
)
138 CPURISCVState
*env
= &RISCV_CPU(obj
)->env
;
139 set_misa(env
, RV32
| RVI
| RVM
| RVA
| RVC
| RVU
);
140 set_versions(env
, USER_VERSION_2_02_0
, PRIV_VERSION_1_10_0
);
141 set_resetvec(env
, DEFAULT_RSTVEC
);
142 set_feature(env
, RISCV_FEATURE_PMP
);
145 #elif defined(TARGET_RISCV64)
147 static void rv64gcsu_priv1_09_1_cpu_init(Object
*obj
)
149 CPURISCVState
*env
= &RISCV_CPU(obj
)->env
;
150 set_misa(env
, RV64
| RVI
| RVM
| RVA
| RVF
| RVD
| RVC
| RVS
| RVU
);
151 set_versions(env
, USER_VERSION_2_02_0
, PRIV_VERSION_1_09_1
);
152 set_resetvec(env
, DEFAULT_RSTVEC
);
153 set_feature(env
, RISCV_FEATURE_MMU
);
154 set_feature(env
, RISCV_FEATURE_PMP
);
157 static void rv64gcsu_priv1_10_0_cpu_init(Object
*obj
)
159 CPURISCVState
*env
= &RISCV_CPU(obj
)->env
;
160 set_misa(env
, RV64
| RVI
| RVM
| RVA
| RVF
| RVD
| RVC
| RVS
| RVU
);
161 set_versions(env
, USER_VERSION_2_02_0
, PRIV_VERSION_1_10_0
);
162 set_resetvec(env
, DEFAULT_RSTVEC
);
163 set_feature(env
, RISCV_FEATURE_MMU
);
164 set_feature(env
, RISCV_FEATURE_PMP
);
167 static void rv64imacu_nommu_cpu_init(Object
*obj
)
169 CPURISCVState
*env
= &RISCV_CPU(obj
)->env
;
170 set_misa(env
, RV64
| RVI
| RVM
| RVA
| RVC
| RVU
);
171 set_versions(env
, USER_VERSION_2_02_0
, PRIV_VERSION_1_10_0
);
172 set_resetvec(env
, DEFAULT_RSTVEC
);
173 set_feature(env
, RISCV_FEATURE_PMP
);
178 static ObjectClass
*riscv_cpu_class_by_name(const char *cpu_model
)
184 cpuname
= g_strsplit(cpu_model
, ",", 1);
185 typename
= g_strdup_printf(RISCV_CPU_TYPE_NAME("%s"), cpuname
[0]);
186 oc
= object_class_by_name(typename
);
189 if (!oc
|| !object_class_dynamic_cast(oc
, TYPE_RISCV_CPU
) ||
190 object_class_is_abstract(oc
)) {
196 static void riscv_cpu_dump_state(CPUState
*cs
, FILE *f
,
197 fprintf_function cpu_fprintf
, int flags
)
199 RISCVCPU
*cpu
= RISCV_CPU(cs
);
200 CPURISCVState
*env
= &cpu
->env
;
203 cpu_fprintf(f
, " %s " TARGET_FMT_lx
"\n", "pc ", env
->pc
);
204 #ifndef CONFIG_USER_ONLY
205 cpu_fprintf(f
, " %s " TARGET_FMT_lx
"\n", "mhartid ", env
->mhartid
);
206 cpu_fprintf(f
, " %s " TARGET_FMT_lx
"\n", "mstatus ", env
->mstatus
);
207 cpu_fprintf(f
, " %s " TARGET_FMT_lx
"\n", "mip ",
208 (target_ulong
)atomic_read(&env
->mip
));
209 cpu_fprintf(f
, " %s " TARGET_FMT_lx
"\n", "mie ", env
->mie
);
210 cpu_fprintf(f
, " %s " TARGET_FMT_lx
"\n", "mideleg ", env
->mideleg
);
211 cpu_fprintf(f
, " %s " TARGET_FMT_lx
"\n", "medeleg ", env
->medeleg
);
212 cpu_fprintf(f
, " %s " TARGET_FMT_lx
"\n", "mtvec ", env
->mtvec
);
213 cpu_fprintf(f
, " %s " TARGET_FMT_lx
"\n", "mepc ", env
->mepc
);
214 cpu_fprintf(f
, " %s " TARGET_FMT_lx
"\n", "mcause ", env
->mcause
);
217 for (i
= 0; i
< 32; i
++) {
218 cpu_fprintf(f
, " %s " TARGET_FMT_lx
,
219 riscv_int_regnames
[i
], env
->gpr
[i
]);
221 cpu_fprintf(f
, "\n");
224 if (flags
& CPU_DUMP_FPU
) {
225 for (i
= 0; i
< 32; i
++) {
226 cpu_fprintf(f
, " %s %016" PRIx64
,
227 riscv_fpr_regnames
[i
], env
->fpr
[i
]);
229 cpu_fprintf(f
, "\n");
235 static void riscv_cpu_set_pc(CPUState
*cs
, vaddr value
)
237 RISCVCPU
*cpu
= RISCV_CPU(cs
);
238 CPURISCVState
*env
= &cpu
->env
;
242 static void riscv_cpu_synchronize_from_tb(CPUState
*cs
, TranslationBlock
*tb
)
244 RISCVCPU
*cpu
= RISCV_CPU(cs
);
245 CPURISCVState
*env
= &cpu
->env
;
249 static bool riscv_cpu_has_work(CPUState
*cs
)
251 #ifndef CONFIG_USER_ONLY
252 RISCVCPU
*cpu
= RISCV_CPU(cs
);
253 CPURISCVState
*env
= &cpu
->env
;
255 * Definition of the WFI instruction requires it to ignore the privilege
256 * mode and delegation registers, but respect individual enables
258 return (atomic_read(&env
->mip
) & env
->mie
) != 0;
264 void restore_state_to_opc(CPURISCVState
*env
, TranslationBlock
*tb
,
270 static void riscv_cpu_reset(CPUState
*cs
)
272 RISCVCPU
*cpu
= RISCV_CPU(cs
);
273 RISCVCPUClass
*mcc
= RISCV_CPU_GET_CLASS(cpu
);
274 CPURISCVState
*env
= &cpu
->env
;
276 mcc
->parent_reset(cs
);
277 #ifndef CONFIG_USER_ONLY
279 env
->mstatus
&= ~(MSTATUS_MIE
| MSTATUS_MPRV
);
281 env
->pc
= env
->resetvec
;
283 cs
->exception_index
= EXCP_NONE
;
284 set_default_nan_mode(1, &env
->fp_status
);
287 static void riscv_cpu_disas_set_info(CPUState
*s
, disassemble_info
*info
)
289 #if defined(TARGET_RISCV32)
290 info
->print_insn
= print_insn_riscv32
;
291 #elif defined(TARGET_RISCV64)
292 info
->print_insn
= print_insn_riscv64
;
296 static void riscv_cpu_realize(DeviceState
*dev
, Error
**errp
)
298 CPUState
*cs
= CPU(dev
);
299 RISCVCPUClass
*mcc
= RISCV_CPU_GET_CLASS(dev
);
300 Error
*local_err
= NULL
;
302 cpu_exec_realizefn(cs
, &local_err
);
303 if (local_err
!= NULL
) {
304 error_propagate(errp
, local_err
);
308 riscv_cpu_register_gdb_regs_for_features(cs
);
313 mcc
->parent_realize(dev
, errp
);
316 static void riscv_cpu_init(Object
*obj
)
318 CPUState
*cs
= CPU(obj
);
319 RISCVCPU
*cpu
= RISCV_CPU(obj
);
321 cs
->env_ptr
= &cpu
->env
;
324 static const VMStateDescription vmstate_riscv_cpu
= {
329 static void riscv_cpu_class_init(ObjectClass
*c
, void *data
)
331 RISCVCPUClass
*mcc
= RISCV_CPU_CLASS(c
);
332 CPUClass
*cc
= CPU_CLASS(c
);
333 DeviceClass
*dc
= DEVICE_CLASS(c
);
335 device_class_set_parent_realize(dc
, riscv_cpu_realize
,
336 &mcc
->parent_realize
);
338 mcc
->parent_reset
= cc
->reset
;
339 cc
->reset
= riscv_cpu_reset
;
341 cc
->class_by_name
= riscv_cpu_class_by_name
;
342 cc
->has_work
= riscv_cpu_has_work
;
343 cc
->do_interrupt
= riscv_cpu_do_interrupt
;
344 cc
->cpu_exec_interrupt
= riscv_cpu_exec_interrupt
;
345 cc
->dump_state
= riscv_cpu_dump_state
;
346 cc
->set_pc
= riscv_cpu_set_pc
;
347 cc
->synchronize_from_tb
= riscv_cpu_synchronize_from_tb
;
348 cc
->gdb_read_register
= riscv_cpu_gdb_read_register
;
349 cc
->gdb_write_register
= riscv_cpu_gdb_write_register
;
350 cc
->gdb_num_core_regs
= 33;
351 #if defined(TARGET_RISCV32)
352 cc
->gdb_core_xml_file
= "riscv-32bit-cpu.xml";
353 #elif defined(TARGET_RISCV64)
354 cc
->gdb_core_xml_file
= "riscv-64bit-cpu.xml";
356 cc
->gdb_stop_before_watchpoint
= true;
357 cc
->disas_set_info
= riscv_cpu_disas_set_info
;
358 #ifdef CONFIG_USER_ONLY
359 cc
->handle_mmu_fault
= riscv_cpu_handle_mmu_fault
;
361 cc
->do_unaligned_access
= riscv_cpu_do_unaligned_access
;
362 cc
->get_phys_page_debug
= riscv_cpu_get_phys_page_debug
;
365 cc
->tcg_initialize
= riscv_translate_init
;
367 /* For now, mark unmigratable: */
368 cc
->vmsd
= &vmstate_riscv_cpu
;
371 char *riscv_isa_string(RISCVCPU
*cpu
)
374 const size_t maxlen
= sizeof("rv128") + sizeof(riscv_exts
) + 1;
375 char *isa_str
= g_new(char, maxlen
);
376 char *p
= isa_str
+ snprintf(isa_str
, maxlen
, "rv%d", TARGET_LONG_BITS
);
377 for (i
= 0; i
< sizeof(riscv_exts
); i
++) {
378 if (cpu
->env
.misa
& RV(riscv_exts
[i
])) {
379 *p
++ = qemu_tolower(riscv_exts
[i
]);
386 typedef struct RISCVCPUListState
{
387 fprintf_function cpu_fprintf
;
391 static gint
riscv_cpu_list_compare(gconstpointer a
, gconstpointer b
)
393 ObjectClass
*class_a
= (ObjectClass
*)a
;
394 ObjectClass
*class_b
= (ObjectClass
*)b
;
395 const char *name_a
, *name_b
;
397 name_a
= object_class_get_name(class_a
);
398 name_b
= object_class_get_name(class_b
);
399 return strcmp(name_a
, name_b
);
402 static void riscv_cpu_list_entry(gpointer data
, gpointer user_data
)
404 RISCVCPUListState
*s
= user_data
;
405 const char *typename
= object_class_get_name(OBJECT_CLASS(data
));
406 int len
= strlen(typename
) - strlen(RISCV_CPU_TYPE_SUFFIX
);
408 (*s
->cpu_fprintf
)(s
->file
, "%.*s\n", len
, typename
);
411 void riscv_cpu_list(FILE *f
, fprintf_function cpu_fprintf
)
413 RISCVCPUListState s
= {
414 .cpu_fprintf
= cpu_fprintf
,
419 list
= object_class_get_list(TYPE_RISCV_CPU
, false);
420 list
= g_slist_sort(list
, riscv_cpu_list_compare
);
421 g_slist_foreach(list
, riscv_cpu_list_entry
, &s
);
425 #define DEFINE_CPU(type_name, initfn) \
428 .parent = TYPE_RISCV_CPU, \
429 .instance_init = initfn \
432 static const TypeInfo riscv_cpu_type_infos
[] = {
434 .name
= TYPE_RISCV_CPU
,
436 .instance_size
= sizeof(RISCVCPU
),
437 .instance_init
= riscv_cpu_init
,
439 .class_size
= sizeof(RISCVCPUClass
),
440 .class_init
= riscv_cpu_class_init
,
442 DEFINE_CPU(TYPE_RISCV_CPU_ANY
, riscv_any_cpu_init
),
443 #if defined(TARGET_RISCV32)
444 DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_09_1
, rv32gcsu_priv1_09_1_cpu_init
),
445 DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_10_0
, rv32gcsu_priv1_10_0_cpu_init
),
446 DEFINE_CPU(TYPE_RISCV_CPU_RV32IMACU_NOMMU
, rv32imacu_nommu_cpu_init
),
447 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31
, rv32imacu_nommu_cpu_init
),
448 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34
, rv32gcsu_priv1_10_0_cpu_init
)
449 #elif defined(TARGET_RISCV64)
450 DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_09_1
, rv64gcsu_priv1_09_1_cpu_init
),
451 DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_10_0
, rv64gcsu_priv1_10_0_cpu_init
),
452 DEFINE_CPU(TYPE_RISCV_CPU_RV64IMACU_NOMMU
, rv64imacu_nommu_cpu_init
),
453 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51
, rv64imacu_nommu_cpu_init
),
454 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54
, rv64gcsu_priv1_10_0_cpu_init
)
458 DEFINE_TYPES(riscv_cpu_type_infos
)