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 riscv_cpu_register_gdb_regs_for_features(cs); 315 316 qemu_init_vcpu(cs); 317 cpu_reset(cs); 318 319 mcc->parent_realize(dev, errp); 320 } 321 322 static void riscv_cpu_init(Object *obj) 323 { 324 CPUState *cs = CPU(obj); 325 RISCVCPU *cpu = RISCV_CPU(obj); 326 327 cs->env_ptr = &cpu->env; 328 } 329 330 static const VMStateDescription vmstate_riscv_cpu = { 331 .name = "cpu", 332 .unmigratable = 1, 333 }; 334 335 static void riscv_cpu_class_init(ObjectClass *c, void *data) 336 { 337 RISCVCPUClass *mcc = RISCV_CPU_CLASS(c); 338 CPUClass *cc = CPU_CLASS(c); 339 DeviceClass *dc = DEVICE_CLASS(c); 340 341 device_class_set_parent_realize(dc, riscv_cpu_realize, 342 &mcc->parent_realize); 343 344 mcc->parent_reset = cc->reset; 345 cc->reset = riscv_cpu_reset; 346 347 cc->class_by_name = riscv_cpu_class_by_name; 348 cc->has_work = riscv_cpu_has_work; 349 cc->do_interrupt = riscv_cpu_do_interrupt; 350 cc->cpu_exec_interrupt = riscv_cpu_exec_interrupt; 351 cc->dump_state = riscv_cpu_dump_state; 352 cc->set_pc = riscv_cpu_set_pc; 353 cc->synchronize_from_tb = riscv_cpu_synchronize_from_tb; 354 cc->gdb_read_register = riscv_cpu_gdb_read_register; 355 cc->gdb_write_register = riscv_cpu_gdb_write_register; 356 cc->gdb_num_core_regs = 33; 357 #if defined(TARGET_RISCV32) 358 cc->gdb_core_xml_file = "riscv-32bit-cpu.xml"; 359 #elif defined(TARGET_RISCV64) 360 cc->gdb_core_xml_file = "riscv-64bit-cpu.xml"; 361 #endif 362 cc->gdb_stop_before_watchpoint = true; 363 cc->disas_set_info = riscv_cpu_disas_set_info; 364 #ifdef CONFIG_USER_ONLY 365 cc->handle_mmu_fault = riscv_cpu_handle_mmu_fault; 366 #else 367 cc->do_unaligned_access = riscv_cpu_do_unaligned_access; 368 cc->get_phys_page_debug = riscv_cpu_get_phys_page_debug; 369 #endif 370 #ifdef CONFIG_TCG 371 cc->tcg_initialize = riscv_translate_init; 372 #endif 373 /* For now, mark unmigratable: */ 374 cc->vmsd = &vmstate_riscv_cpu; 375 } 376 377 char *riscv_isa_string(RISCVCPU *cpu) 378 { 379 int i; 380 const size_t maxlen = sizeof("rv128") + sizeof(riscv_exts) + 1; 381 char *isa_str = g_new(char, maxlen); 382 char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", TARGET_LONG_BITS); 383 for (i = 0; i < sizeof(riscv_exts); i++) { 384 if (cpu->env.misa & RV(riscv_exts[i])) { 385 *p++ = qemu_tolower(riscv_exts[i]); 386 } 387 } 388 *p = '\0'; 389 return isa_str; 390 } 391 392 typedef struct RISCVCPUListState { 393 fprintf_function cpu_fprintf; 394 FILE *file; 395 } RISCVCPUListState; 396 397 static gint riscv_cpu_list_compare(gconstpointer a, gconstpointer b) 398 { 399 ObjectClass *class_a = (ObjectClass *)a; 400 ObjectClass *class_b = (ObjectClass *)b; 401 const char *name_a, *name_b; 402 403 name_a = object_class_get_name(class_a); 404 name_b = object_class_get_name(class_b); 405 return strcmp(name_a, name_b); 406 } 407 408 static void riscv_cpu_list_entry(gpointer data, gpointer user_data) 409 { 410 RISCVCPUListState *s = user_data; 411 const char *typename = object_class_get_name(OBJECT_CLASS(data)); 412 int len = strlen(typename) - strlen(RISCV_CPU_TYPE_SUFFIX); 413 414 (*s->cpu_fprintf)(s->file, "%.*s\n", len, typename); 415 } 416 417 void riscv_cpu_list(FILE *f, fprintf_function cpu_fprintf) 418 { 419 RISCVCPUListState s = { 420 .cpu_fprintf = cpu_fprintf, 421 .file = f, 422 }; 423 GSList *list; 424 425 list = object_class_get_list(TYPE_RISCV_CPU, false); 426 list = g_slist_sort(list, riscv_cpu_list_compare); 427 g_slist_foreach(list, riscv_cpu_list_entry, &s); 428 g_slist_free(list); 429 } 430 431 #define DEFINE_CPU(type_name, initfn) \ 432 { \ 433 .name = type_name, \ 434 .parent = TYPE_RISCV_CPU, \ 435 .instance_init = initfn \ 436 } 437 438 static const TypeInfo riscv_cpu_type_infos[] = { 439 { 440 .name = TYPE_RISCV_CPU, 441 .parent = TYPE_CPU, 442 .instance_size = sizeof(RISCVCPU), 443 .instance_init = riscv_cpu_init, 444 .abstract = true, 445 .class_size = sizeof(RISCVCPUClass), 446 .class_init = riscv_cpu_class_init, 447 }, 448 DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init), 449 #if defined(TARGET_RISCV32) 450 DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_09_1, rv32gcsu_priv1_09_1_cpu_init), 451 DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_10_0, rv32gcsu_priv1_10_0_cpu_init), 452 DEFINE_CPU(TYPE_RISCV_CPU_RV32IMACU_NOMMU, rv32imacu_nommu_cpu_init), 453 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32imacu_nommu_cpu_init), 454 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32gcsu_priv1_10_0_cpu_init) 455 #elif defined(TARGET_RISCV64) 456 DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_09_1, rv64gcsu_priv1_09_1_cpu_init), 457 DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_10_0, rv64gcsu_priv1_10_0_cpu_init), 458 DEFINE_CPU(TYPE_RISCV_CPU_RV64IMACU_NOMMU, rv64imacu_nommu_cpu_init), 459 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64imacu_nommu_cpu_init), 460 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64gcsu_priv1_10_0_cpu_init) 461 #endif 462 }; 463 464 DEFINE_TYPES(riscv_cpu_type_infos) 465