xref: /qemu/target/riscv/cpu.c (revision 73969720)
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 typedef struct RISCVCPUInfo {
84     const int bit_widths;
85     const char *name;
86     void (*initfn)(Object *obj);
87 } RISCVCPUInfo;
88 
89 static void set_misa(CPURISCVState *env, target_ulong misa)
90 {
91     env->misa = misa;
92 }
93 
94 static void set_versions(CPURISCVState *env, int user_ver, int priv_ver)
95 {
96     env->user_ver = user_ver;
97     env->priv_ver = priv_ver;
98 }
99 
100 static void set_feature(CPURISCVState *env, int feature)
101 {
102     env->features |= (1ULL << feature);
103 }
104 
105 static void set_resetvec(CPURISCVState *env, int resetvec)
106 {
107 #ifndef CONFIG_USER_ONLY
108     env->resetvec = resetvec;
109 #endif
110 }
111 
112 static void riscv_any_cpu_init(Object *obj)
113 {
114     CPURISCVState *env = &RISCV_CPU(obj)->env;
115     set_misa(env, RVXLEN | RVI | RVM | RVA | RVF | RVD | RVC | RVU);
116     set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_10_0);
117     set_resetvec(env, DEFAULT_RSTVEC);
118 }
119 
120 #if defined(TARGET_RISCV32)
121 
122 static void rv32gcsu_priv1_09_1_cpu_init(Object *obj)
123 {
124     CPURISCVState *env = &RISCV_CPU(obj)->env;
125     set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
126     set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_09_1);
127     set_resetvec(env, DEFAULT_RSTVEC);
128     set_feature(env, RISCV_FEATURE_MMU);
129 }
130 
131 static void rv32gcsu_priv1_10_0_cpu_init(Object *obj)
132 {
133     CPURISCVState *env = &RISCV_CPU(obj)->env;
134     set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
135     set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_10_0);
136     set_resetvec(env, DEFAULT_RSTVEC);
137     set_feature(env, RISCV_FEATURE_MMU);
138 }
139 
140 static void rv32imacu_nommu_cpu_init(Object *obj)
141 {
142     CPURISCVState *env = &RISCV_CPU(obj)->env;
143     set_misa(env, RV32 | RVI | RVM | RVA | RVC | RVU);
144     set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_10_0);
145     set_resetvec(env, DEFAULT_RSTVEC);
146 }
147 
148 #elif defined(TARGET_RISCV64)
149 
150 static void rv64gcsu_priv1_09_1_cpu_init(Object *obj)
151 {
152     CPURISCVState *env = &RISCV_CPU(obj)->env;
153     set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
154     set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_09_1);
155     set_resetvec(env, DEFAULT_RSTVEC);
156     set_feature(env, RISCV_FEATURE_MMU);
157 }
158 
159 static void rv64gcsu_priv1_10_0_cpu_init(Object *obj)
160 {
161     CPURISCVState *env = &RISCV_CPU(obj)->env;
162     set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
163     set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_10_0);
164     set_resetvec(env, DEFAULT_RSTVEC);
165     set_feature(env, RISCV_FEATURE_MMU);
166 }
167 
168 static void rv64imacu_nommu_cpu_init(Object *obj)
169 {
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 }
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     qemu_init_vcpu(cs);
309     cpu_reset(cs);
310 
311     mcc->parent_realize(dev, errp);
312 }
313 
314 static void riscv_cpu_init(Object *obj)
315 {
316     CPUState *cs = CPU(obj);
317     RISCVCPU *cpu = RISCV_CPU(obj);
318 
319     cs->env_ptr = &cpu->env;
320 }
321 
322 static const VMStateDescription vmstate_riscv_cpu = {
323     .name = "cpu",
324     .unmigratable = 1,
325 };
326 
327 static void riscv_cpu_class_init(ObjectClass *c, void *data)
328 {
329     RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
330     CPUClass *cc = CPU_CLASS(c);
331     DeviceClass *dc = DEVICE_CLASS(c);
332 
333     mcc->parent_realize = dc->realize;
334     dc->realize = riscv_cpu_realize;
335 
336     mcc->parent_reset = cc->reset;
337     cc->reset = riscv_cpu_reset;
338 
339     cc->class_by_name = riscv_cpu_class_by_name;
340     cc->has_work = riscv_cpu_has_work;
341     cc->do_interrupt = riscv_cpu_do_interrupt;
342     cc->cpu_exec_interrupt = riscv_cpu_exec_interrupt;
343     cc->dump_state = riscv_cpu_dump_state;
344     cc->set_pc = riscv_cpu_set_pc;
345     cc->synchronize_from_tb = riscv_cpu_synchronize_from_tb;
346     cc->gdb_read_register = riscv_cpu_gdb_read_register;
347     cc->gdb_write_register = riscv_cpu_gdb_write_register;
348     cc->gdb_num_core_regs = 65;
349     cc->gdb_stop_before_watchpoint = true;
350     cc->disas_set_info = riscv_cpu_disas_set_info;
351 #ifdef CONFIG_USER_ONLY
352     cc->handle_mmu_fault = riscv_cpu_handle_mmu_fault;
353 #else
354     cc->do_unaligned_access = riscv_cpu_do_unaligned_access;
355     cc->get_phys_page_debug = riscv_cpu_get_phys_page_debug;
356 #endif
357 #ifdef CONFIG_TCG
358     cc->tcg_initialize = riscv_translate_init;
359 #endif
360     /* For now, mark unmigratable: */
361     cc->vmsd = &vmstate_riscv_cpu;
362 }
363 
364 char *riscv_isa_string(RISCVCPU *cpu)
365 {
366     int i;
367     const size_t maxlen = sizeof("rv128") + sizeof(riscv_exts) + 1;
368     char *isa_str = g_new(char, maxlen);
369     char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", TARGET_LONG_BITS);
370     for (i = 0; i < sizeof(riscv_exts); i++) {
371         if (cpu->env.misa & RV(riscv_exts[i])) {
372             *p++ = qemu_tolower(riscv_exts[i]);
373         }
374     }
375     *p = '\0';
376     return isa_str;
377 }
378 
379 typedef struct RISCVCPUListState {
380     fprintf_function cpu_fprintf;
381     FILE *file;
382 } RISCVCPUListState;
383 
384 static gint riscv_cpu_list_compare(gconstpointer a, gconstpointer b)
385 {
386     ObjectClass *class_a = (ObjectClass *)a;
387     ObjectClass *class_b = (ObjectClass *)b;
388     const char *name_a, *name_b;
389 
390     name_a = object_class_get_name(class_a);
391     name_b = object_class_get_name(class_b);
392     return strcmp(name_a, name_b);
393 }
394 
395 static void riscv_cpu_list_entry(gpointer data, gpointer user_data)
396 {
397     RISCVCPUListState *s = user_data;
398     const char *typename = object_class_get_name(OBJECT_CLASS(data));
399     int len = strlen(typename) - strlen(RISCV_CPU_TYPE_SUFFIX);
400 
401     (*s->cpu_fprintf)(s->file, "%.*s\n", len, typename);
402 }
403 
404 void riscv_cpu_list(FILE *f, fprintf_function cpu_fprintf)
405 {
406     RISCVCPUListState s = {
407         .cpu_fprintf = cpu_fprintf,
408         .file = f,
409     };
410     GSList *list;
411 
412     list = object_class_get_list(TYPE_RISCV_CPU, false);
413     list = g_slist_sort(list, riscv_cpu_list_compare);
414     g_slist_foreach(list, riscv_cpu_list_entry, &s);
415     g_slist_free(list);
416 }
417 
418 #define DEFINE_CPU(type_name, initfn)      \
419     {                                      \
420         .name = type_name,                 \
421         .parent = TYPE_RISCV_CPU,          \
422         .instance_init = initfn            \
423     }
424 
425 static const TypeInfo riscv_cpu_type_infos[] = {
426     {
427         .name = TYPE_RISCV_CPU,
428         .parent = TYPE_CPU,
429         .instance_size = sizeof(RISCVCPU),
430         .instance_init = riscv_cpu_init,
431         .abstract = true,
432         .class_size = sizeof(RISCVCPUClass),
433         .class_init = riscv_cpu_class_init,
434     },
435     DEFINE_CPU(TYPE_RISCV_CPU_ANY,              riscv_any_cpu_init),
436 #if defined(TARGET_RISCV32)
437     DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_09_1, rv32gcsu_priv1_09_1_cpu_init),
438     DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_10_0, rv32gcsu_priv1_10_0_cpu_init),
439     DEFINE_CPU(TYPE_RISCV_CPU_RV32IMACU_NOMMU,  rv32imacu_nommu_cpu_init),
440     DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31,       rv32imacu_nommu_cpu_init),
441     DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34,       rv32gcsu_priv1_10_0_cpu_init)
442 #elif defined(TARGET_RISCV64)
443     DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_09_1, rv64gcsu_priv1_09_1_cpu_init),
444     DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_10_0, rv64gcsu_priv1_10_0_cpu_init),
445     DEFINE_CPU(TYPE_RISCV_CPU_RV64IMACU_NOMMU,  rv64imacu_nommu_cpu_init),
446     DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51,       rv64imacu_nommu_cpu_init),
447     DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54,       rv64gcsu_priv1_10_0_cpu_init)
448 #endif
449 };
450 
451 DEFINE_TYPES(riscv_cpu_type_infos)
452