block/ssh: Implement .bdrv_dirname()
[qemu/ar7.git] / target / riscv / cpu.c
blob1bcf4eaeb8d4a291154432704d4b010e35b60a03
1 /*
2 * QEMU RISC-V CPU
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
14 * more details.
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"
21 #include "qemu/qemu-print.h"
22 #include "qemu/log.h"
23 #include "cpu.h"
24 #include "exec/exec-all.h"
25 #include "qapi/error.h"
26 #include "migration/vmstate.h"
28 /* RISC-V CPU definitions */
30 static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
32 const char * const riscv_int_regnames[] = {
33 "zero", "ra ", "sp ", "gp ", "tp ", "t0 ", "t1 ", "t2 ",
34 "s0 ", "s1 ", "a0 ", "a1 ", "a2 ", "a3 ", "a4 ", "a5 ",
35 "a6 ", "a7 ", "s2 ", "s3 ", "s4 ", "s5 ", "s6 ", "s7 ",
36 "s8 ", "s9 ", "s10 ", "s11 ", "t3 ", "t4 ", "t5 ", "t6 "
39 const char * const riscv_fpr_regnames[] = {
40 "ft0 ", "ft1 ", "ft2 ", "ft3 ", "ft4 ", "ft5 ", "ft6 ", "ft7 ",
41 "fs0 ", "fs1 ", "fa0 ", "fa1 ", "fa2 ", "fa3 ", "fa4 ", "fa5 ",
42 "fa6 ", "fa7 ", "fs2 ", "fs3 ", "fs4 ", "fs5 ", "fs6 ", "fs7 ",
43 "fs8 ", "fs9 ", "fs10", "fs11", "ft8 ", "ft9 ", "ft10", "ft11"
46 const char * const riscv_excp_names[] = {
47 "misaligned_fetch",
48 "fault_fetch",
49 "illegal_instruction",
50 "breakpoint",
51 "misaligned_load",
52 "fault_load",
53 "misaligned_store",
54 "fault_store",
55 "user_ecall",
56 "supervisor_ecall",
57 "hypervisor_ecall",
58 "machine_ecall",
59 "exec_page_fault",
60 "load_page_fault",
61 "reserved",
62 "store_page_fault"
65 const char * const riscv_intr_names[] = {
66 "u_software",
67 "s_software",
68 "h_software",
69 "m_software",
70 "u_timer",
71 "s_timer",
72 "h_timer",
73 "m_timer",
74 "u_external",
75 "s_external",
76 "h_external",
77 "m_external",
78 "reserved",
79 "reserved",
80 "reserved",
81 "reserved"
84 static void set_misa(CPURISCVState *env, target_ulong misa)
86 env->misa_mask = env->misa = misa;
89 static void set_versions(CPURISCVState *env, int user_ver, int priv_ver)
91 env->user_ver = user_ver;
92 env->priv_ver = priv_ver;
95 static void set_feature(CPURISCVState *env, int feature)
97 env->features |= (1ULL << feature);
100 static void set_resetvec(CPURISCVState *env, int resetvec)
102 #ifndef CONFIG_USER_ONLY
103 env->resetvec = resetvec;
104 #endif
107 static void riscv_any_cpu_init(Object *obj)
109 CPURISCVState *env = &RISCV_CPU(obj)->env;
110 set_misa(env, RVXLEN | RVI | RVM | RVA | RVF | RVD | RVC | RVU);
111 set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_10_0);
112 set_resetvec(env, DEFAULT_RSTVEC);
115 #if defined(TARGET_RISCV32)
117 static void rv32gcsu_priv1_09_1_cpu_init(Object *obj)
119 CPURISCVState *env = &RISCV_CPU(obj)->env;
120 set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
121 set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_09_1);
122 set_resetvec(env, DEFAULT_RSTVEC);
123 set_feature(env, RISCV_FEATURE_MMU);
124 set_feature(env, RISCV_FEATURE_PMP);
127 static void rv32gcsu_priv1_10_0_cpu_init(Object *obj)
129 CPURISCVState *env = &RISCV_CPU(obj)->env;
130 set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
131 set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_10_0);
132 set_resetvec(env, DEFAULT_RSTVEC);
133 set_feature(env, RISCV_FEATURE_MMU);
134 set_feature(env, RISCV_FEATURE_PMP);
137 static void rv32imacu_nommu_cpu_init(Object *obj)
139 CPURISCVState *env = &RISCV_CPU(obj)->env;
140 set_misa(env, RV32 | RVI | RVM | RVA | RVC | RVU);
141 set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_10_0);
142 set_resetvec(env, DEFAULT_RSTVEC);
143 set_feature(env, RISCV_FEATURE_PMP);
146 #elif defined(TARGET_RISCV64)
148 static void rv64gcsu_priv1_09_1_cpu_init(Object *obj)
150 CPURISCVState *env = &RISCV_CPU(obj)->env;
151 set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
152 set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_09_1);
153 set_resetvec(env, DEFAULT_RSTVEC);
154 set_feature(env, RISCV_FEATURE_MMU);
155 set_feature(env, RISCV_FEATURE_PMP);
158 static void rv64gcsu_priv1_10_0_cpu_init(Object *obj)
160 CPURISCVState *env = &RISCV_CPU(obj)->env;
161 set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
162 set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_10_0);
163 set_resetvec(env, DEFAULT_RSTVEC);
164 set_feature(env, RISCV_FEATURE_MMU);
165 set_feature(env, RISCV_FEATURE_PMP);
168 static void rv64imacu_nommu_cpu_init(Object *obj)
170 CPURISCVState *env = &RISCV_CPU(obj)->env;
171 set_misa(env, RV64 | RVI | RVM | RVA | RVC | RVU);
172 set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_10_0);
173 set_resetvec(env, DEFAULT_RSTVEC);
174 set_feature(env, RISCV_FEATURE_PMP);
177 #endif
179 static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
181 ObjectClass *oc;
182 char *typename;
183 char **cpuname;
185 cpuname = g_strsplit(cpu_model, ",", 1);
186 typename = g_strdup_printf(RISCV_CPU_TYPE_NAME("%s"), cpuname[0]);
187 oc = object_class_by_name(typename);
188 g_strfreev(cpuname);
189 g_free(typename);
190 if (!oc || !object_class_dynamic_cast(oc, TYPE_RISCV_CPU) ||
191 object_class_is_abstract(oc)) {
192 return NULL;
194 return oc;
197 static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
199 RISCVCPU *cpu = RISCV_CPU(cs);
200 CPURISCVState *env = &cpu->env;
201 int i;
203 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "pc ", env->pc);
204 #ifndef CONFIG_USER_ONLY
205 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mhartid ", env->mhartid);
206 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", env->mstatus);
207 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mip ",
208 (target_ulong)atomic_read(&env->mip));
209 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mie ", env->mie);
210 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mideleg ", env->mideleg);
211 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "medeleg ", env->medeleg);
212 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mtvec ", env->mtvec);
213 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mepc ", env->mepc);
214 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mcause ", env->mcause);
215 #endif
217 for (i = 0; i < 32; i++) {
218 qemu_fprintf(f, " %s " TARGET_FMT_lx,
219 riscv_int_regnames[i], env->gpr[i]);
220 if ((i & 3) == 3) {
221 qemu_fprintf(f, "\n");
224 if (flags & CPU_DUMP_FPU) {
225 for (i = 0; i < 32; i++) {
226 qemu_fprintf(f, " %s %016" PRIx64,
227 riscv_fpr_regnames[i], env->fpr[i]);
228 if ((i & 3) == 3) {
229 qemu_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;
239 env->pc = value;
242 static void riscv_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
244 RISCVCPU *cpu = RISCV_CPU(cs);
245 CPURISCVState *env = &cpu->env;
246 env->pc = tb->pc;
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;
259 #else
260 return true;
261 #endif
264 void restore_state_to_opc(CPURISCVState *env, TranslationBlock *tb,
265 target_ulong *data)
267 env->pc = data[0];
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
278 env->priv = PRV_M;
279 env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV);
280 env->mcause = 0;
281 env->pc = env->resetvec;
282 #endif
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;
293 #endif
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);
305 return;
308 riscv_cpu_register_gdb_regs_for_features(cs);
310 qemu_init_vcpu(cs);
311 cpu_reset(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 = {
325 .name = "cpu",
326 .unmigratable = 1,
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";
355 #endif
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;
360 #else
361 cc->do_unaligned_access = riscv_cpu_do_unaligned_access;
362 cc->get_phys_page_debug = riscv_cpu_get_phys_page_debug;
363 #endif
364 #ifdef CONFIG_TCG
365 cc->tcg_initialize = riscv_translate_init;
366 #endif
367 /* For now, mark unmigratable: */
368 cc->vmsd = &vmstate_riscv_cpu;
371 char *riscv_isa_string(RISCVCPU *cpu)
373 int i;
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]);
382 *p = '\0';
383 return isa_str;
386 static gint riscv_cpu_list_compare(gconstpointer a, gconstpointer b)
388 ObjectClass *class_a = (ObjectClass *)a;
389 ObjectClass *class_b = (ObjectClass *)b;
390 const char *name_a, *name_b;
392 name_a = object_class_get_name(class_a);
393 name_b = object_class_get_name(class_b);
394 return strcmp(name_a, name_b);
397 static void riscv_cpu_list_entry(gpointer data, gpointer user_data)
399 const char *typename = object_class_get_name(OBJECT_CLASS(data));
400 int len = strlen(typename) - strlen(RISCV_CPU_TYPE_SUFFIX);
402 qemu_printf("%.*s\n", len, typename);
405 void riscv_cpu_list(void)
407 GSList *list;
409 list = object_class_get_list(TYPE_RISCV_CPU, false);
410 list = g_slist_sort(list, riscv_cpu_list_compare);
411 g_slist_foreach(list, riscv_cpu_list_entry, NULL);
412 g_slist_free(list);
415 #define DEFINE_CPU(type_name, initfn) \
417 .name = type_name, \
418 .parent = TYPE_RISCV_CPU, \
419 .instance_init = initfn \
422 static const TypeInfo riscv_cpu_type_infos[] = {
424 .name = TYPE_RISCV_CPU,
425 .parent = TYPE_CPU,
426 .instance_size = sizeof(RISCVCPU),
427 .instance_init = riscv_cpu_init,
428 .abstract = true,
429 .class_size = sizeof(RISCVCPUClass),
430 .class_init = riscv_cpu_class_init,
432 DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
433 #if defined(TARGET_RISCV32)
434 DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_09_1, rv32gcsu_priv1_09_1_cpu_init),
435 DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_10_0, rv32gcsu_priv1_10_0_cpu_init),
436 DEFINE_CPU(TYPE_RISCV_CPU_RV32IMACU_NOMMU, rv32imacu_nommu_cpu_init),
437 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32imacu_nommu_cpu_init),
438 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32gcsu_priv1_10_0_cpu_init)
439 #elif defined(TARGET_RISCV64)
440 DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_09_1, rv64gcsu_priv1_09_1_cpu_init),
441 DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_10_0, rv64gcsu_priv1_10_0_cpu_init),
442 DEFINE_CPU(TYPE_RISCV_CPU_RV64IMACU_NOMMU, rv64imacu_nommu_cpu_init),
443 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64imacu_nommu_cpu_init),
444 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64gcsu_priv1_10_0_cpu_init)
445 #endif
448 DEFINE_TYPES(riscv_cpu_type_infos)