xref: /openbmc/qemu/target/riscv/cpu.c (revision 1be82d89)
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_mask = 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     set_feature(env, RISCV_FEATURE_PMP);
130 }
131 
132 static void rv32gcsu_priv1_10_0_cpu_init(Object *obj)
133 {
134     CPURISCVState *env = &RISCV_CPU(obj)->env;
135     set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
136     set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_10_0);
137     set_resetvec(env, DEFAULT_RSTVEC);
138     set_feature(env, RISCV_FEATURE_MMU);
139     set_feature(env, RISCV_FEATURE_PMP);
140 }
141 
142 static void rv32imacu_nommu_cpu_init(Object *obj)
143 {
144     CPURISCVState *env = &RISCV_CPU(obj)->env;
145     set_misa(env, RV32 | RVI | RVM | RVA | RVC | RVU);
146     set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_10_0);
147     set_resetvec(env, DEFAULT_RSTVEC);
148     set_feature(env, RISCV_FEATURE_PMP);
149 }
150 
151 #elif defined(TARGET_RISCV64)
152 
153 static void rv64gcsu_priv1_09_1_cpu_init(Object *obj)
154 {
155     CPURISCVState *env = &RISCV_CPU(obj)->env;
156     set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
157     set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_09_1);
158     set_resetvec(env, DEFAULT_RSTVEC);
159     set_feature(env, RISCV_FEATURE_MMU);
160     set_feature(env, RISCV_FEATURE_PMP);
161 }
162 
163 static void rv64gcsu_priv1_10_0_cpu_init(Object *obj)
164 {
165     CPURISCVState *env = &RISCV_CPU(obj)->env;
166     set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
167     set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_10_0);
168     set_resetvec(env, DEFAULT_RSTVEC);
169     set_feature(env, RISCV_FEATURE_MMU);
170     set_feature(env, RISCV_FEATURE_PMP);
171 }
172 
173 static void rv64imacu_nommu_cpu_init(Object *obj)
174 {
175     CPURISCVState *env = &RISCV_CPU(obj)->env;
176     set_misa(env, RV64 | RVI | RVM | RVA | RVC | RVU);
177     set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_10_0);
178     set_resetvec(env, DEFAULT_RSTVEC);
179     set_feature(env, RISCV_FEATURE_PMP);
180 }
181 
182 #endif
183 
184 static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
185 {
186     ObjectClass *oc;
187     char *typename;
188     char **cpuname;
189 
190     cpuname = g_strsplit(cpu_model, ",", 1);
191     typename = g_strdup_printf(RISCV_CPU_TYPE_NAME("%s"), cpuname[0]);
192     oc = object_class_by_name(typename);
193     g_strfreev(cpuname);
194     g_free(typename);
195     if (!oc || !object_class_dynamic_cast(oc, TYPE_RISCV_CPU) ||
196         object_class_is_abstract(oc)) {
197         return NULL;
198     }
199     return oc;
200 }
201 
202 static void riscv_cpu_dump_state(CPUState *cs, FILE *f,
203     fprintf_function cpu_fprintf, int flags)
204 {
205     RISCVCPU *cpu = RISCV_CPU(cs);
206     CPURISCVState *env = &cpu->env;
207     int i;
208 
209     cpu_fprintf(f, " %s " TARGET_FMT_lx "\n", "pc      ", env->pc);
210 #ifndef CONFIG_USER_ONLY
211     cpu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mhartid ", env->mhartid);
212     cpu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", env->mstatus);
213     cpu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mip     ",
214         (target_ulong)atomic_read(&env->mip));
215     cpu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mie     ", env->mie);
216     cpu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mideleg ", env->mideleg);
217     cpu_fprintf(f, " %s " TARGET_FMT_lx "\n", "medeleg ", env->medeleg);
218     cpu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mtvec   ", env->mtvec);
219     cpu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mepc    ", env->mepc);
220     cpu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mcause  ", env->mcause);
221 #endif
222 
223     for (i = 0; i < 32; i++) {
224         cpu_fprintf(f, " %s " TARGET_FMT_lx,
225             riscv_int_regnames[i], env->gpr[i]);
226         if ((i & 3) == 3) {
227             cpu_fprintf(f, "\n");
228         }
229     }
230     if (flags & CPU_DUMP_FPU) {
231         for (i = 0; i < 32; i++) {
232             cpu_fprintf(f, " %s %016" PRIx64,
233                 riscv_fpr_regnames[i], env->fpr[i]);
234             if ((i & 3) == 3) {
235                 cpu_fprintf(f, "\n");
236             }
237         }
238     }
239 }
240 
241 static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
242 {
243     RISCVCPU *cpu = RISCV_CPU(cs);
244     CPURISCVState *env = &cpu->env;
245     env->pc = value;
246 }
247 
248 static void riscv_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
249 {
250     RISCVCPU *cpu = RISCV_CPU(cs);
251     CPURISCVState *env = &cpu->env;
252     env->pc = tb->pc;
253 }
254 
255 static bool riscv_cpu_has_work(CPUState *cs)
256 {
257 #ifndef CONFIG_USER_ONLY
258     RISCVCPU *cpu = RISCV_CPU(cs);
259     CPURISCVState *env = &cpu->env;
260     /*
261      * Definition of the WFI instruction requires it to ignore the privilege
262      * mode and delegation registers, but respect individual enables
263      */
264     return (atomic_read(&env->mip) & env->mie) != 0;
265 #else
266     return true;
267 #endif
268 }
269 
270 void restore_state_to_opc(CPURISCVState *env, TranslationBlock *tb,
271                           target_ulong *data)
272 {
273     env->pc = data[0];
274 }
275 
276 static void riscv_cpu_reset(CPUState *cs)
277 {
278     RISCVCPU *cpu = RISCV_CPU(cs);
279     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
280     CPURISCVState *env = &cpu->env;
281 
282     mcc->parent_reset(cs);
283 #ifndef CONFIG_USER_ONLY
284     env->priv = PRV_M;
285     env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV);
286     env->mcause = 0;
287     env->pc = env->resetvec;
288 #endif
289     cs->exception_index = EXCP_NONE;
290     set_default_nan_mode(1, &env->fp_status);
291 }
292 
293 static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
294 {
295 #if defined(TARGET_RISCV32)
296     info->print_insn = print_insn_riscv32;
297 #elif defined(TARGET_RISCV64)
298     info->print_insn = print_insn_riscv64;
299 #endif
300 }
301 
302 static void riscv_cpu_realize(DeviceState *dev, Error **errp)
303 {
304     CPUState *cs = CPU(dev);
305     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
306     Error *local_err = NULL;
307 
308     cpu_exec_realizefn(cs, &local_err);
309     if (local_err != NULL) {
310         error_propagate(errp, local_err);
311         return;
312     }
313 
314     qemu_init_vcpu(cs);
315     cpu_reset(cs);
316 
317     mcc->parent_realize(dev, errp);
318 }
319 
320 static void riscv_cpu_init(Object *obj)
321 {
322     CPUState *cs = CPU(obj);
323     RISCVCPU *cpu = RISCV_CPU(obj);
324 
325     cs->env_ptr = &cpu->env;
326 }
327 
328 static const VMStateDescription vmstate_riscv_cpu = {
329     .name = "cpu",
330     .unmigratable = 1,
331 };
332 
333 static void riscv_cpu_class_init(ObjectClass *c, void *data)
334 {
335     RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
336     CPUClass *cc = CPU_CLASS(c);
337     DeviceClass *dc = DEVICE_CLASS(c);
338 
339     device_class_set_parent_realize(dc, riscv_cpu_realize,
340                                     &mcc->parent_realize);
341 
342     mcc->parent_reset = cc->reset;
343     cc->reset = riscv_cpu_reset;
344 
345     cc->class_by_name = riscv_cpu_class_by_name;
346     cc->has_work = riscv_cpu_has_work;
347     cc->do_interrupt = riscv_cpu_do_interrupt;
348     cc->cpu_exec_interrupt = riscv_cpu_exec_interrupt;
349     cc->dump_state = riscv_cpu_dump_state;
350     cc->set_pc = riscv_cpu_set_pc;
351     cc->synchronize_from_tb = riscv_cpu_synchronize_from_tb;
352     cc->gdb_read_register = riscv_cpu_gdb_read_register;
353     cc->gdb_write_register = riscv_cpu_gdb_write_register;
354     cc->gdb_num_core_regs = 65;
355     cc->gdb_stop_before_watchpoint = true;
356     cc->disas_set_info = riscv_cpu_disas_set_info;
357 #ifdef CONFIG_USER_ONLY
358     cc->handle_mmu_fault = riscv_cpu_handle_mmu_fault;
359 #else
360     cc->do_unaligned_access = riscv_cpu_do_unaligned_access;
361     cc->get_phys_page_debug = riscv_cpu_get_phys_page_debug;
362 #endif
363 #ifdef CONFIG_TCG
364     cc->tcg_initialize = riscv_translate_init;
365 #endif
366     /* For now, mark unmigratable: */
367     cc->vmsd = &vmstate_riscv_cpu;
368 }
369 
370 char *riscv_isa_string(RISCVCPU *cpu)
371 {
372     int i;
373     const size_t maxlen = sizeof("rv128") + sizeof(riscv_exts) + 1;
374     char *isa_str = g_new(char, maxlen);
375     char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", TARGET_LONG_BITS);
376     for (i = 0; i < sizeof(riscv_exts); i++) {
377         if (cpu->env.misa & RV(riscv_exts[i])) {
378             *p++ = qemu_tolower(riscv_exts[i]);
379         }
380     }
381     *p = '\0';
382     return isa_str;
383 }
384 
385 typedef struct RISCVCPUListState {
386     fprintf_function cpu_fprintf;
387     FILE *file;
388 } RISCVCPUListState;
389 
390 static gint riscv_cpu_list_compare(gconstpointer a, gconstpointer b)
391 {
392     ObjectClass *class_a = (ObjectClass *)a;
393     ObjectClass *class_b = (ObjectClass *)b;
394     const char *name_a, *name_b;
395 
396     name_a = object_class_get_name(class_a);
397     name_b = object_class_get_name(class_b);
398     return strcmp(name_a, name_b);
399 }
400 
401 static void riscv_cpu_list_entry(gpointer data, gpointer user_data)
402 {
403     RISCVCPUListState *s = user_data;
404     const char *typename = object_class_get_name(OBJECT_CLASS(data));
405     int len = strlen(typename) - strlen(RISCV_CPU_TYPE_SUFFIX);
406 
407     (*s->cpu_fprintf)(s->file, "%.*s\n", len, typename);
408 }
409 
410 void riscv_cpu_list(FILE *f, fprintf_function cpu_fprintf)
411 {
412     RISCVCPUListState s = {
413         .cpu_fprintf = cpu_fprintf,
414         .file = f,
415     };
416     GSList *list;
417 
418     list = object_class_get_list(TYPE_RISCV_CPU, false);
419     list = g_slist_sort(list, riscv_cpu_list_compare);
420     g_slist_foreach(list, riscv_cpu_list_entry, &s);
421     g_slist_free(list);
422 }
423 
424 #define DEFINE_CPU(type_name, initfn)      \
425     {                                      \
426         .name = type_name,                 \
427         .parent = TYPE_RISCV_CPU,          \
428         .instance_init = initfn            \
429     }
430 
431 static const TypeInfo riscv_cpu_type_infos[] = {
432     {
433         .name = TYPE_RISCV_CPU,
434         .parent = TYPE_CPU,
435         .instance_size = sizeof(RISCVCPU),
436         .instance_init = riscv_cpu_init,
437         .abstract = true,
438         .class_size = sizeof(RISCVCPUClass),
439         .class_init = riscv_cpu_class_init,
440     },
441     DEFINE_CPU(TYPE_RISCV_CPU_ANY,              riscv_any_cpu_init),
442 #if defined(TARGET_RISCV32)
443     DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_09_1, rv32gcsu_priv1_09_1_cpu_init),
444     DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_10_0, rv32gcsu_priv1_10_0_cpu_init),
445     DEFINE_CPU(TYPE_RISCV_CPU_RV32IMACU_NOMMU,  rv32imacu_nommu_cpu_init),
446     DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31,       rv32imacu_nommu_cpu_init),
447     DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34,       rv32gcsu_priv1_10_0_cpu_init)
448 #elif defined(TARGET_RISCV64)
449     DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_09_1, rv64gcsu_priv1_09_1_cpu_init),
450     DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_10_0, rv64gcsu_priv1_10_0_cpu_init),
451     DEFINE_CPU(TYPE_RISCV_CPU_RV64IMACU_NOMMU,  rv64imacu_nommu_cpu_init),
452     DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51,       rv64imacu_nommu_cpu_init),
453     DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54,       rv64gcsu_priv1_10_0_cpu_init)
454 #endif
455 };
456 
457 DEFINE_TYPES(riscv_cpu_type_infos)
458