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 for (i = 0; i < 32; i++) { 223 cpu_fprintf(f, " %s %016" PRIx64, 224 riscv_fpr_regnames[i], env->fpr[i]); 225 if ((i & 3) == 3) { 226 cpu_fprintf(f, "\n"); 227 } 228 } 229 } 230 231 static void riscv_cpu_set_pc(CPUState *cs, vaddr value) 232 { 233 RISCVCPU *cpu = RISCV_CPU(cs); 234 CPURISCVState *env = &cpu->env; 235 env->pc = value; 236 } 237 238 static void riscv_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb) 239 { 240 RISCVCPU *cpu = RISCV_CPU(cs); 241 CPURISCVState *env = &cpu->env; 242 env->pc = tb->pc; 243 } 244 245 static bool riscv_cpu_has_work(CPUState *cs) 246 { 247 #ifndef CONFIG_USER_ONLY 248 RISCVCPU *cpu = RISCV_CPU(cs); 249 CPURISCVState *env = &cpu->env; 250 /* 251 * Definition of the WFI instruction requires it to ignore the privilege 252 * mode and delegation registers, but respect individual enables 253 */ 254 return (atomic_read(&env->mip) & env->mie) != 0; 255 #else 256 return true; 257 #endif 258 } 259 260 void restore_state_to_opc(CPURISCVState *env, TranslationBlock *tb, 261 target_ulong *data) 262 { 263 env->pc = data[0]; 264 } 265 266 static void riscv_cpu_reset(CPUState *cs) 267 { 268 RISCVCPU *cpu = RISCV_CPU(cs); 269 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu); 270 CPURISCVState *env = &cpu->env; 271 272 mcc->parent_reset(cs); 273 #ifndef CONFIG_USER_ONLY 274 env->priv = PRV_M; 275 env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV); 276 env->mcause = 0; 277 env->pc = env->resetvec; 278 #endif 279 cs->exception_index = EXCP_NONE; 280 set_default_nan_mode(1, &env->fp_status); 281 } 282 283 static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info) 284 { 285 #if defined(TARGET_RISCV32) 286 info->print_insn = print_insn_riscv32; 287 #elif defined(TARGET_RISCV64) 288 info->print_insn = print_insn_riscv64; 289 #endif 290 } 291 292 static void riscv_cpu_realize(DeviceState *dev, Error **errp) 293 { 294 CPUState *cs = CPU(dev); 295 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev); 296 Error *local_err = NULL; 297 298 cpu_exec_realizefn(cs, &local_err); 299 if (local_err != NULL) { 300 error_propagate(errp, local_err); 301 return; 302 } 303 304 qemu_init_vcpu(cs); 305 cpu_reset(cs); 306 307 mcc->parent_realize(dev, errp); 308 } 309 310 static void riscv_cpu_init(Object *obj) 311 { 312 CPUState *cs = CPU(obj); 313 RISCVCPU *cpu = RISCV_CPU(obj); 314 315 cs->env_ptr = &cpu->env; 316 } 317 318 static const VMStateDescription vmstate_riscv_cpu = { 319 .name = "cpu", 320 .unmigratable = 1, 321 }; 322 323 static void riscv_cpu_class_init(ObjectClass *c, void *data) 324 { 325 RISCVCPUClass *mcc = RISCV_CPU_CLASS(c); 326 CPUClass *cc = CPU_CLASS(c); 327 DeviceClass *dc = DEVICE_CLASS(c); 328 329 mcc->parent_realize = dc->realize; 330 dc->realize = riscv_cpu_realize; 331 332 mcc->parent_reset = cc->reset; 333 cc->reset = riscv_cpu_reset; 334 335 cc->class_by_name = riscv_cpu_class_by_name; 336 cc->has_work = riscv_cpu_has_work; 337 cc->do_interrupt = riscv_cpu_do_interrupt; 338 cc->cpu_exec_interrupt = riscv_cpu_exec_interrupt; 339 cc->dump_state = riscv_cpu_dump_state; 340 cc->set_pc = riscv_cpu_set_pc; 341 cc->synchronize_from_tb = riscv_cpu_synchronize_from_tb; 342 cc->gdb_read_register = riscv_cpu_gdb_read_register; 343 cc->gdb_write_register = riscv_cpu_gdb_write_register; 344 cc->gdb_num_core_regs = 65; 345 cc->gdb_stop_before_watchpoint = true; 346 cc->disas_set_info = riscv_cpu_disas_set_info; 347 #ifdef CONFIG_USER_ONLY 348 cc->handle_mmu_fault = riscv_cpu_handle_mmu_fault; 349 #else 350 cc->do_unaligned_access = riscv_cpu_do_unaligned_access; 351 cc->get_phys_page_debug = riscv_cpu_get_phys_page_debug; 352 #endif 353 #ifdef CONFIG_TCG 354 cc->tcg_initialize = riscv_translate_init; 355 #endif 356 /* For now, mark unmigratable: */ 357 cc->vmsd = &vmstate_riscv_cpu; 358 } 359 360 char *riscv_isa_string(RISCVCPU *cpu) 361 { 362 int i; 363 const size_t maxlen = sizeof("rv128") + sizeof(riscv_exts) + 1; 364 char *isa_str = g_new(char, maxlen); 365 char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", TARGET_LONG_BITS); 366 for (i = 0; i < sizeof(riscv_exts); i++) { 367 if (cpu->env.misa & RV(riscv_exts[i])) { 368 *p++ = qemu_tolower(riscv_exts[i]); 369 } 370 } 371 *p = '\0'; 372 return isa_str; 373 } 374 375 typedef struct RISCVCPUListState { 376 fprintf_function cpu_fprintf; 377 FILE *file; 378 } RISCVCPUListState; 379 380 static gint riscv_cpu_list_compare(gconstpointer a, gconstpointer b) 381 { 382 ObjectClass *class_a = (ObjectClass *)a; 383 ObjectClass *class_b = (ObjectClass *)b; 384 const char *name_a, *name_b; 385 386 name_a = object_class_get_name(class_a); 387 name_b = object_class_get_name(class_b); 388 return strcmp(name_a, name_b); 389 } 390 391 static void riscv_cpu_list_entry(gpointer data, gpointer user_data) 392 { 393 RISCVCPUListState *s = user_data; 394 const char *typename = object_class_get_name(OBJECT_CLASS(data)); 395 int len = strlen(typename) - strlen(RISCV_CPU_TYPE_SUFFIX); 396 397 (*s->cpu_fprintf)(s->file, "%.*s\n", len, typename); 398 } 399 400 void riscv_cpu_list(FILE *f, fprintf_function cpu_fprintf) 401 { 402 RISCVCPUListState s = { 403 .cpu_fprintf = cpu_fprintf, 404 .file = f, 405 }; 406 GSList *list; 407 408 list = object_class_get_list(TYPE_RISCV_CPU, false); 409 list = g_slist_sort(list, riscv_cpu_list_compare); 410 g_slist_foreach(list, riscv_cpu_list_entry, &s); 411 g_slist_free(list); 412 } 413 414 #define DEFINE_CPU(type_name, initfn) \ 415 { \ 416 .name = type_name, \ 417 .parent = TYPE_RISCV_CPU, \ 418 .instance_init = initfn \ 419 } 420 421 static const TypeInfo riscv_cpu_type_infos[] = { 422 { 423 .name = TYPE_RISCV_CPU, 424 .parent = TYPE_CPU, 425 .instance_size = sizeof(RISCVCPU), 426 .instance_init = riscv_cpu_init, 427 .abstract = true, 428 .class_size = sizeof(RISCVCPUClass), 429 .class_init = riscv_cpu_class_init, 430 }, 431 DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init), 432 #if defined(TARGET_RISCV32) 433 DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_09_1, rv32gcsu_priv1_09_1_cpu_init), 434 DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_10_0, rv32gcsu_priv1_10_0_cpu_init), 435 DEFINE_CPU(TYPE_RISCV_CPU_RV32IMACU_NOMMU, rv32imacu_nommu_cpu_init), 436 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32imacu_nommu_cpu_init), 437 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32gcsu_priv1_10_0_cpu_init) 438 #elif defined(TARGET_RISCV64) 439 DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_09_1, rv64gcsu_priv1_09_1_cpu_init), 440 DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_10_0, rv64gcsu_priv1_10_0_cpu_init), 441 DEFINE_CPU(TYPE_RISCV_CPU_RV64IMACU_NOMMU, rv64imacu_nommu_cpu_init), 442 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64imacu_nommu_cpu_init), 443 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64gcsu_priv1_10_0_cpu_init) 444 #endif 445 }; 446 447 DEFINE_TYPES(riscv_cpu_type_infos) 448