cpu.c (9d3d60b704f48217cf9b38b883cc15c40f76f286) | cpu.c (e91a7227cb802ea62ffa14707ebc2f588b01213d) |
---|---|
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, --- 96 unchanged lines hidden (view full) --- 105 } else { 106 return (cause < ARRAY_SIZE(riscv_excp_names)) ? 107 riscv_excp_names[cause] : "(unknown)"; 108 } 109} 110 111bool riscv_cpu_is_32bit(CPURISCVState *env) 112{ | 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, --- 96 unchanged lines hidden (view full) --- 105 } else { 106 return (cause < ARRAY_SIZE(riscv_excp_names)) ? 107 riscv_excp_names[cause] : "(unknown)"; 108 } 109} 110 111bool riscv_cpu_is_32bit(CPURISCVState *env) 112{ |
113 if (env->misa & RV64) { 114 return false; 115 } 116 117 return true; | 113 return env->misa_mxl == MXL_RV32; |
118} 119 | 114} 115 |
120static void set_misa(CPURISCVState *env, target_ulong misa) | 116static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext) |
121{ | 117{ |
122 env->misa_mask = env->misa = misa; | 118 env->misa_mxl_max = env->misa_mxl = mxl; 119 env->misa_ext_mask = env->misa_ext = ext; |
123} 124 125static void set_priv_version(CPURISCVState *env, int priv_ver) 126{ 127 env->priv_ver = priv_ver; 128} 129 130static void set_vext_version(CPURISCVState *env, int vext_ver) --- 12 unchanged lines hidden (view full) --- 143 env->resetvec = resetvec; 144#endif 145} 146 147static void riscv_any_cpu_init(Object *obj) 148{ 149 CPURISCVState *env = &RISCV_CPU(obj)->env; 150#if defined(TARGET_RISCV32) | 120} 121 122static void set_priv_version(CPURISCVState *env, int priv_ver) 123{ 124 env->priv_ver = priv_ver; 125} 126 127static void set_vext_version(CPURISCVState *env, int vext_ver) --- 12 unchanged lines hidden (view full) --- 140 env->resetvec = resetvec; 141#endif 142} 143 144static void riscv_any_cpu_init(Object *obj) 145{ 146 CPURISCVState *env = &RISCV_CPU(obj)->env; 147#if defined(TARGET_RISCV32) |
151 set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVU); | 148 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVU); |
152#elif defined(TARGET_RISCV64) | 149#elif defined(TARGET_RISCV64) |
153 set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVU); | 150 set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVU); |
154#endif 155 set_priv_version(env, PRIV_VERSION_1_11_0); 156} 157 158#if defined(TARGET_RISCV64) 159static void rv64_base_cpu_init(Object *obj) 160{ 161 CPURISCVState *env = &RISCV_CPU(obj)->env; 162 /* We set this in the realise function */ | 151#endif 152 set_priv_version(env, PRIV_VERSION_1_11_0); 153} 154 155#if defined(TARGET_RISCV64) 156static void rv64_base_cpu_init(Object *obj) 157{ 158 CPURISCVState *env = &RISCV_CPU(obj)->env; 159 /* We set this in the realise function */ |
163 set_misa(env, RV64); | 160 set_misa(env, MXL_RV64, 0); |
164} 165 166static void rv64_sifive_u_cpu_init(Object *obj) 167{ 168 CPURISCVState *env = &RISCV_CPU(obj)->env; | 161} 162 163static void rv64_sifive_u_cpu_init(Object *obj) 164{ 165 CPURISCVState *env = &RISCV_CPU(obj)->env; |
169 set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU); | 166 set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU); |
170 set_priv_version(env, PRIV_VERSION_1_10_0); 171} 172 173static void rv64_sifive_e_cpu_init(Object *obj) 174{ 175 CPURISCVState *env = &RISCV_CPU(obj)->env; | 167 set_priv_version(env, PRIV_VERSION_1_10_0); 168} 169 170static void rv64_sifive_e_cpu_init(Object *obj) 171{ 172 CPURISCVState *env = &RISCV_CPU(obj)->env; |
176 set_misa(env, RV64 | RVI | RVM | RVA | RVC | RVU); | 173 set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU); |
177 set_priv_version(env, PRIV_VERSION_1_10_0); 178 qdev_prop_set_bit(DEVICE(obj), "mmu", false); 179} 180#else 181static void rv32_base_cpu_init(Object *obj) 182{ 183 CPURISCVState *env = &RISCV_CPU(obj)->env; 184 /* We set this in the realise function */ | 174 set_priv_version(env, PRIV_VERSION_1_10_0); 175 qdev_prop_set_bit(DEVICE(obj), "mmu", false); 176} 177#else 178static void rv32_base_cpu_init(Object *obj) 179{ 180 CPURISCVState *env = &RISCV_CPU(obj)->env; 181 /* We set this in the realise function */ |
185 set_misa(env, RV32); | 182 set_misa(env, MXL_RV32, 0); |
186} 187 188static void rv32_sifive_u_cpu_init(Object *obj) 189{ 190 CPURISCVState *env = &RISCV_CPU(obj)->env; | 183} 184 185static void rv32_sifive_u_cpu_init(Object *obj) 186{ 187 CPURISCVState *env = &RISCV_CPU(obj)->env; |
191 set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU); | 188 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU); |
192 set_priv_version(env, PRIV_VERSION_1_10_0); 193} 194 195static void rv32_sifive_e_cpu_init(Object *obj) 196{ 197 CPURISCVState *env = &RISCV_CPU(obj)->env; | 189 set_priv_version(env, PRIV_VERSION_1_10_0); 190} 191 192static void rv32_sifive_e_cpu_init(Object *obj) 193{ 194 CPURISCVState *env = &RISCV_CPU(obj)->env; |
198 set_misa(env, RV32 | RVI | RVM | RVA | RVC | RVU); | 195 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU); |
199 set_priv_version(env, PRIV_VERSION_1_10_0); 200 qdev_prop_set_bit(DEVICE(obj), "mmu", false); 201} 202 203static void rv32_ibex_cpu_init(Object *obj) 204{ 205 CPURISCVState *env = &RISCV_CPU(obj)->env; | 196 set_priv_version(env, PRIV_VERSION_1_10_0); 197 qdev_prop_set_bit(DEVICE(obj), "mmu", false); 198} 199 200static void rv32_ibex_cpu_init(Object *obj) 201{ 202 CPURISCVState *env = &RISCV_CPU(obj)->env; |
206 set_misa(env, RV32 | RVI | RVM | RVC | RVU); | 203 set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU); |
207 set_priv_version(env, PRIV_VERSION_1_10_0); 208 qdev_prop_set_bit(DEVICE(obj), "mmu", false); 209 qdev_prop_set_bit(DEVICE(obj), "x-epmp", true); 210} 211 212static void rv32_imafcu_nommu_cpu_init(Object *obj) 213{ 214 CPURISCVState *env = &RISCV_CPU(obj)->env; | 204 set_priv_version(env, PRIV_VERSION_1_10_0); 205 qdev_prop_set_bit(DEVICE(obj), "mmu", false); 206 qdev_prop_set_bit(DEVICE(obj), "x-epmp", true); 207} 208 209static void rv32_imafcu_nommu_cpu_init(Object *obj) 210{ 211 CPURISCVState *env = &RISCV_CPU(obj)->env; |
215 set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVC | RVU); | 212 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU); |
216 set_priv_version(env, PRIV_VERSION_1_10_0); 217 set_resetvec(env, DEFAULT_RSTVEC); 218 qdev_prop_set_bit(DEVICE(obj), "mmu", false); 219} 220#endif 221 222static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model) 223{ --- 131 unchanged lines hidden (view full) --- 355{ 356 CPUState *cs = CPU(dev); 357 RISCVCPU *cpu = RISCV_CPU(cs); 358 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu); 359 CPURISCVState *env = &cpu->env; 360 361 mcc->parent_reset(dev); 362#ifndef CONFIG_USER_ONLY | 213 set_priv_version(env, PRIV_VERSION_1_10_0); 214 set_resetvec(env, DEFAULT_RSTVEC); 215 qdev_prop_set_bit(DEVICE(obj), "mmu", false); 216} 217#endif 218 219static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model) 220{ --- 131 unchanged lines hidden (view full) --- 352{ 353 CPUState *cs = CPU(dev); 354 RISCVCPU *cpu = RISCV_CPU(cs); 355 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu); 356 CPURISCVState *env = &cpu->env; 357 358 mcc->parent_reset(dev); 359#ifndef CONFIG_USER_ONLY |
360 env->misa_mxl = env->misa_mxl_max; |
|
363 env->priv = PRV_M; 364 env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV); 365 env->mcause = 0; 366 env->pc = env->resetvec; 367 env->two_stage_lookup = false; 368#endif 369 cs->exception_index = RISCV_EXCP_NONE; 370 env->load_res = -1; --- 12 unchanged lines hidden (view full) --- 383 384static void riscv_cpu_realize(DeviceState *dev, Error **errp) 385{ 386 CPUState *cs = CPU(dev); 387 RISCVCPU *cpu = RISCV_CPU(dev); 388 CPURISCVState *env = &cpu->env; 389 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev); 390 int priv_version = 0; | 361 env->priv = PRV_M; 362 env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV); 363 env->mcause = 0; 364 env->pc = env->resetvec; 365 env->two_stage_lookup = false; 366#endif 367 cs->exception_index = RISCV_EXCP_NONE; 368 env->load_res = -1; --- 12 unchanged lines hidden (view full) --- 381 382static void riscv_cpu_realize(DeviceState *dev, Error **errp) 383{ 384 CPUState *cs = CPU(dev); 385 RISCVCPU *cpu = RISCV_CPU(dev); 386 CPURISCVState *env = &cpu->env; 387 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev); 388 int priv_version = 0; |
391 target_ulong target_misa = env->misa; | |
392 Error *local_err = NULL; 393 394 cpu_exec_realizefn(cs, &local_err); 395 if (local_err != NULL) { 396 error_propagate(errp, local_err); 397 return; 398 } 399 --- 29 unchanged lines hidden (view full) --- 429 */ 430 if (cpu->cfg.epmp) { 431 set_feature(env, RISCV_FEATURE_EPMP); 432 } 433 } 434 435 set_resetvec(env, cpu->cfg.resetvec); 436 | 389 Error *local_err = NULL; 390 391 cpu_exec_realizefn(cs, &local_err); 392 if (local_err != NULL) { 393 error_propagate(errp, local_err); 394 return; 395 } 396 --- 29 unchanged lines hidden (view full) --- 426 */ 427 if (cpu->cfg.epmp) { 428 set_feature(env, RISCV_FEATURE_EPMP); 429 } 430 } 431 432 set_resetvec(env, cpu->cfg.resetvec); 433 |
437 /* If only XLEN is set for misa, then set misa from properties */ 438 if (env->misa == RV32 || env->misa == RV64) { | 434 /* Validate that MISA_MXL is set properly. */ 435 switch (env->misa_mxl_max) { 436#ifdef TARGET_RISCV64 437 case MXL_RV64: 438 break; 439#endif 440 case MXL_RV32: 441 break; 442 default: 443 g_assert_not_reached(); 444 } 445 assert(env->misa_mxl_max == env->misa_mxl); 446 447 /* If only MISA_EXT is unset for misa, then set it from properties */ 448 if (env->misa_ext == 0) { 449 uint32_t ext = 0; 450 |
439 /* Do some ISA extension error checking */ 440 if (cpu->cfg.ext_i && cpu->cfg.ext_e) { 441 error_setg(errp, 442 "I and E extensions are incompatible"); 443 return; 444 } 445 446 if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) { --- 10 unchanged lines hidden (view full) --- 457 cpu->cfg.ext_m = true; 458 cpu->cfg.ext_a = true; 459 cpu->cfg.ext_f = true; 460 cpu->cfg.ext_d = true; 461 } 462 463 /* Set the ISA extensions, checks should have happened above */ 464 if (cpu->cfg.ext_i) { | 451 /* Do some ISA extension error checking */ 452 if (cpu->cfg.ext_i && cpu->cfg.ext_e) { 453 error_setg(errp, 454 "I and E extensions are incompatible"); 455 return; 456 } 457 458 if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) { --- 10 unchanged lines hidden (view full) --- 469 cpu->cfg.ext_m = true; 470 cpu->cfg.ext_a = true; 471 cpu->cfg.ext_f = true; 472 cpu->cfg.ext_d = true; 473 } 474 475 /* Set the ISA extensions, checks should have happened above */ 476 if (cpu->cfg.ext_i) { |
465 target_misa |= RVI; | 477 ext |= RVI; |
466 } 467 if (cpu->cfg.ext_e) { | 478 } 479 if (cpu->cfg.ext_e) { |
468 target_misa |= RVE; | 480 ext |= RVE; |
469 } 470 if (cpu->cfg.ext_m) { | 481 } 482 if (cpu->cfg.ext_m) { |
471 target_misa |= RVM; | 483 ext |= RVM; |
472 } 473 if (cpu->cfg.ext_a) { | 484 } 485 if (cpu->cfg.ext_a) { |
474 target_misa |= RVA; | 486 ext |= RVA; |
475 } 476 if (cpu->cfg.ext_f) { | 487 } 488 if (cpu->cfg.ext_f) { |
477 target_misa |= RVF; | 489 ext |= RVF; |
478 } 479 if (cpu->cfg.ext_d) { | 490 } 491 if (cpu->cfg.ext_d) { |
480 target_misa |= RVD; | 492 ext |= RVD; |
481 } 482 if (cpu->cfg.ext_c) { | 493 } 494 if (cpu->cfg.ext_c) { |
483 target_misa |= RVC; | 495 ext |= RVC; |
484 } 485 if (cpu->cfg.ext_s) { | 496 } 497 if (cpu->cfg.ext_s) { |
486 target_misa |= RVS; | 498 ext |= RVS; |
487 } 488 if (cpu->cfg.ext_u) { | 499 } 500 if (cpu->cfg.ext_u) { |
489 target_misa |= RVU; | 501 ext |= RVU; |
490 } 491 if (cpu->cfg.ext_h) { | 502 } 503 if (cpu->cfg.ext_h) { |
492 target_misa |= RVH; | 504 ext |= RVH; |
493 } 494 if (cpu->cfg.ext_v) { 495 int vext_version = VEXT_VERSION_0_07_1; | 505 } 506 if (cpu->cfg.ext_v) { 507 int vext_version = VEXT_VERSION_0_07_1; |
496 target_misa |= RVV; | 508 ext |= RVV; |
497 if (!is_power_of_2(cpu->cfg.vlen)) { 498 error_setg(errp, 499 "Vector extension VLEN must be power of 2"); 500 return; 501 } 502 if (cpu->cfg.vlen > RV_VLEN_MAX || cpu->cfg.vlen < 128) { 503 error_setg(errp, 504 "Vector extension implementation only supports VLEN " --- 22 unchanged lines hidden (view full) --- 527 } 528 } else { 529 qemu_log("vector version is not specified, " 530 "use the default value v0.7.1\n"); 531 } 532 set_vext_version(env, vext_version); 533 } 534 | 509 if (!is_power_of_2(cpu->cfg.vlen)) { 510 error_setg(errp, 511 "Vector extension VLEN must be power of 2"); 512 return; 513 } 514 if (cpu->cfg.vlen > RV_VLEN_MAX || cpu->cfg.vlen < 128) { 515 error_setg(errp, 516 "Vector extension implementation only supports VLEN " --- 22 unchanged lines hidden (view full) --- 539 } 540 } else { 541 qemu_log("vector version is not specified, " 542 "use the default value v0.7.1\n"); 543 } 544 set_vext_version(env, vext_version); 545 } 546 |
535 set_misa(env, target_misa); | 547 set_misa(env, env->misa_mxl, ext); |
536 } 537 538 riscv_cpu_register_gdb_regs_for_features(cs); 539 540 qemu_init_vcpu(cs); 541 cpu_reset(cs); 542 543 mcc->parent_realize(dev, errp); --- 159 unchanged lines hidden (view full) --- 703 704char *riscv_isa_string(RISCVCPU *cpu) 705{ 706 int i; 707 const size_t maxlen = sizeof("rv128") + sizeof(riscv_exts) + 1; 708 char *isa_str = g_new(char, maxlen); 709 char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", TARGET_LONG_BITS); 710 for (i = 0; i < sizeof(riscv_exts); i++) { | 548 } 549 550 riscv_cpu_register_gdb_regs_for_features(cs); 551 552 qemu_init_vcpu(cs); 553 cpu_reset(cs); 554 555 mcc->parent_realize(dev, errp); --- 159 unchanged lines hidden (view full) --- 715 716char *riscv_isa_string(RISCVCPU *cpu) 717{ 718 int i; 719 const size_t maxlen = sizeof("rv128") + sizeof(riscv_exts) + 1; 720 char *isa_str = g_new(char, maxlen); 721 char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", TARGET_LONG_BITS); 722 for (i = 0; i < sizeof(riscv_exts); i++) { |
711 if (cpu->env.misa & RV(riscv_exts[i])) { | 723 if (cpu->env.misa_ext & RV(riscv_exts[i])) { |
712 *p++ = qemu_tolower(riscv_exts[i]); 713 } 714 } 715 *p = '\0'; 716 return isa_str; 717} 718 719static gint riscv_cpu_list_compare(gconstpointer a, gconstpointer b) --- 62 unchanged lines hidden --- | 724 *p++ = qemu_tolower(riscv_exts[i]); 725 } 726 } 727 *p = '\0'; 728 return isa_str; 729} 730 731static gint riscv_cpu_list_compare(gconstpointer a, gconstpointer b) --- 62 unchanged lines hidden --- |