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 ---