xref: /qemu/target/riscv/cpu.c (revision 19e8ff48)
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/log.h"
22 #include "cpu.h"
23 #include "exec/exec-all.h"
24 #include "qapi/error.h"
25 #include "migration/vmstate.h"
26 
27 /* RISC-V CPU definitions */
28 
29 static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
30 
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  "
36 };
37 
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"
43 };
44 
45 const char * const riscv_excp_names[] = {
46     "misaligned_fetch",
47     "fault_fetch",
48     "illegal_instruction",
49     "breakpoint",
50     "misaligned_load",
51     "fault_load",
52     "misaligned_store",
53     "fault_store",
54     "user_ecall",
55     "supervisor_ecall",
56     "hypervisor_ecall",
57     "machine_ecall",
58     "exec_page_fault",
59     "load_page_fault",
60     "reserved",
61     "store_page_fault"
62 };
63 
64 const char * const riscv_intr_names[] = {
65     "u_software",
66     "s_software",
67     "h_software",
68     "m_software",
69     "u_timer",
70     "s_timer",
71     "h_timer",
72     "m_timer",
73     "u_external",
74     "s_external",
75     "h_external",
76     "m_external",
77     "reserved",
78     "reserved",
79     "reserved",
80     "reserved"
81 };
82 
83 static void set_misa(CPURISCVState *env, target_ulong misa)
84 {
85     env->misa_mask = env->misa = misa;
86 }
87 
88 static void set_versions(CPURISCVState *env, int user_ver, int priv_ver)
89 {
90     env->user_ver = user_ver;
91     env->priv_ver = priv_ver;
92 }
93 
94 static void set_feature(CPURISCVState *env, int feature)
95 {
96     env->features |= (1ULL << feature);
97 }
98 
99 static void set_resetvec(CPURISCVState *env, int resetvec)
100 {
101 #ifndef CONFIG_USER_ONLY
102     env->resetvec = resetvec;
103 #endif
104 }
105 
106 static void riscv_any_cpu_init(Object *obj)
107 {
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);
112 }
113 
114 #if defined(TARGET_RISCV32)
115 
116 static void rv32gcsu_priv1_09_1_cpu_init(Object *obj)
117 {
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);
124 }
125 
126 static void rv32gcsu_priv1_10_0_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);
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);
134 }
135 
136 static void rv32imacu_nommu_cpu_init(Object *obj)
137 {
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);
143 }
144 
145 #elif defined(TARGET_RISCV64)
146 
147 static void rv64gcsu_priv1_09_1_cpu_init(Object *obj)
148 {
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);
155 }
156 
157 static void rv64gcsu_priv1_10_0_cpu_init(Object *obj)
158 {
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);
165 }
166 
167 static void rv64imacu_nommu_cpu_init(Object *obj)
168 {
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);
174 }
175 
176 #endif
177 
178 static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
179 {
180     ObjectClass *oc;
181     char *typename;
182     char **cpuname;
183 
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);
187     g_strfreev(cpuname);
188     g_free(typename);
189     if (!oc || !object_class_dynamic_cast(oc, TYPE_RISCV_CPU) ||
190         object_class_is_abstract(oc)) {
191         return NULL;
192     }
193     return oc;
194 }
195 
196 static void riscv_cpu_dump_state(CPUState *cs, FILE *f,
197     fprintf_function cpu_fprintf, int flags)
198 {
199     RISCVCPU *cpu = RISCV_CPU(cs);
200     CPURISCVState *env = &cpu->env;
201     int i;
202 
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);
215 #endif
216 
217     for (i = 0; i < 32; i++) {
218         cpu_fprintf(f, " %s " TARGET_FMT_lx,
219             riscv_int_regnames[i], env->gpr[i]);
220         if ((i & 3) == 3) {
221             cpu_fprintf(f, "\n");
222         }
223     }
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]);
228             if ((i & 3) == 3) {
229                 cpu_fprintf(f, "\n");
230             }
231         }
232     }
233 }
234 
235 static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
236 {
237     RISCVCPU *cpu = RISCV_CPU(cs);
238     CPURISCVState *env = &cpu->env;
239     env->pc = value;
240 }
241 
242 static void riscv_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
243 {
244     RISCVCPU *cpu = RISCV_CPU(cs);
245     CPURISCVState *env = &cpu->env;
246     env->pc = tb->pc;
247 }
248 
249 static bool riscv_cpu_has_work(CPUState *cs)
250 {
251 #ifndef CONFIG_USER_ONLY
252     RISCVCPU *cpu = RISCV_CPU(cs);
253     CPURISCVState *env = &cpu->env;
254     /*
255      * Definition of the WFI instruction requires it to ignore the privilege
256      * mode and delegation registers, but respect individual enables
257      */
258     return (atomic_read(&env->mip) & env->mie) != 0;
259 #else
260     return true;
261 #endif
262 }
263 
264 void restore_state_to_opc(CPURISCVState *env, TranslationBlock *tb,
265                           target_ulong *data)
266 {
267     env->pc = data[0];
268 }
269 
270 static void riscv_cpu_reset(CPUState *cs)
271 {
272     RISCVCPU *cpu = RISCV_CPU(cs);
273     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
274     CPURISCVState *env = &cpu->env;
275 
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);
285 }
286 
287 static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
288 {
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
294 }
295 
296 static void riscv_cpu_realize(DeviceState *dev, Error **errp)
297 {
298     CPUState *cs = CPU(dev);
299     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
300     Error *local_err = NULL;
301 
302     cpu_exec_realizefn(cs, &local_err);
303     if (local_err != NULL) {
304         error_propagate(errp, local_err);
305         return;
306     }
307 
308     riscv_cpu_register_gdb_regs_for_features(cs);
309 
310     qemu_init_vcpu(cs);
311     cpu_reset(cs);
312 
313     mcc->parent_realize(dev, errp);
314 }
315 
316 static void riscv_cpu_init(Object *obj)
317 {
318     CPUState *cs = CPU(obj);
319     RISCVCPU *cpu = RISCV_CPU(obj);
320 
321     cs->env_ptr = &cpu->env;
322 }
323 
324 static const VMStateDescription vmstate_riscv_cpu = {
325     .name = "cpu",
326     .unmigratable = 1,
327 };
328 
329 static void riscv_cpu_class_init(ObjectClass *c, void *data)
330 {
331     RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
332     CPUClass *cc = CPU_CLASS(c);
333     DeviceClass *dc = DEVICE_CLASS(c);
334 
335     device_class_set_parent_realize(dc, riscv_cpu_realize,
336                                     &mcc->parent_realize);
337 
338     mcc->parent_reset = cc->reset;
339     cc->reset = riscv_cpu_reset;
340 
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;
369 }
370 
371 char *riscv_isa_string(RISCVCPU *cpu)
372 {
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]);
380         }
381     }
382     *p = '\0';
383     return isa_str;
384 }
385 
386 typedef struct RISCVCPUListState {
387     fprintf_function cpu_fprintf;
388     FILE *file;
389 } RISCVCPUListState;
390 
391 static gint riscv_cpu_list_compare(gconstpointer a, gconstpointer b)
392 {
393     ObjectClass *class_a = (ObjectClass *)a;
394     ObjectClass *class_b = (ObjectClass *)b;
395     const char *name_a, *name_b;
396 
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);
400 }
401 
402 static void riscv_cpu_list_entry(gpointer data, gpointer user_data)
403 {
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);
407 
408     (*s->cpu_fprintf)(s->file, "%.*s\n", len, typename);
409 }
410 
411 void riscv_cpu_list(FILE *f, fprintf_function cpu_fprintf)
412 {
413     RISCVCPUListState s = {
414         .cpu_fprintf = cpu_fprintf,
415         .file = f,
416     };
417     GSList *list;
418 
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);
422     g_slist_free(list);
423 }
424 
425 #define DEFINE_CPU(type_name, initfn)      \
426     {                                      \
427         .name = type_name,                 \
428         .parent = TYPE_RISCV_CPU,          \
429         .instance_init = initfn            \
430     }
431 
432 static const TypeInfo riscv_cpu_type_infos[] = {
433     {
434         .name = TYPE_RISCV_CPU,
435         .parent = TYPE_CPU,
436         .instance_size = sizeof(RISCVCPU),
437         .instance_init = riscv_cpu_init,
438         .abstract = true,
439         .class_size = sizeof(RISCVCPUClass),
440         .class_init = riscv_cpu_class_init,
441     },
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)
455 #endif
456 };
457 
458 DEFINE_TYPES(riscv_cpu_type_infos)
459