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