aboutsummaryrefslogtreecommitdiff
path: root/target/riscv/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/riscv/cpu.c')
-rw-r--r--target/riscv/cpu.c79
1 files changed, 71 insertions, 8 deletions
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index b7675707e0..e29879915f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -23,6 +23,7 @@
#include "cpu.h"
#include "exec/exec-all.h"
#include "qapi/error.h"
+#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
/* RISC-V CPU definitions */
@@ -30,17 +31,17 @@
static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
const char * const riscv_int_regnames[] = {
- "zero", "ra ", "sp ", "gp ", "tp ", "t0 ", "t1 ", "t2 ",
- "s0 ", "s1 ", "a0 ", "a1 ", "a2 ", "a3 ", "a4 ", "a5 ",
- "a6 ", "a7 ", "s2 ", "s3 ", "s4 ", "s5 ", "s6 ", "s7 ",
- "s8 ", "s9 ", "s10 ", "s11 ", "t3 ", "t4 ", "t5 ", "t6 "
+ "zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2",
+ "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5",
+ "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7",
+ "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6"
};
const char * const riscv_fpr_regnames[] = {
- "ft0 ", "ft1 ", "ft2 ", "ft3 ", "ft4 ", "ft5 ", "ft6 ", "ft7 ",
- "fs0 ", "fs1 ", "fa0 ", "fa1 ", "fa2 ", "fa3 ", "fa4 ", "fa5 ",
- "fa6 ", "fa7 ", "fs2 ", "fs3 ", "fs4 ", "fs5 ", "fs6 ", "fs7 ",
- "fs8 ", "fs9 ", "fs10", "fs11", "ft8 ", "ft9 ", "ft10", "ft11"
+ "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7",
+ "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5",
+ "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7",
+ "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11"
};
const char * const riscv_excp_names[] = {
@@ -114,6 +115,12 @@ static void riscv_any_cpu_init(Object *obj)
#if defined(TARGET_RISCV32)
+static void riscv_base32_cpu_init(Object *obj)
+{
+ CPURISCVState *env = &RISCV_CPU(obj)->env;
+ set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+}
+
static void rv32gcsu_priv1_09_1_cpu_init(Object *obj)
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
@@ -145,6 +152,12 @@ static void rv32imacu_nommu_cpu_init(Object *obj)
#elif defined(TARGET_RISCV64)
+static void riscv_base64_cpu_init(Object *obj)
+{
+ CPURISCVState *env = &RISCV_CPU(obj)->env;
+ set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+}
+
static void rv64gcsu_priv1_09_1_cpu_init(Object *obj)
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
@@ -296,7 +309,11 @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
static void riscv_cpu_realize(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
+ RISCVCPU *cpu = RISCV_CPU(dev);
+ CPURISCVState *env = &cpu->env;
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
+ int priv_version = PRIV_VERSION_1_10_0;
+ int user_version = USER_VERSION_2_02_0;
Error *local_err = NULL;
cpu_exec_realizefn(cs, &local_err);
@@ -305,6 +322,41 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
return;
}
+ if (cpu->cfg.priv_spec) {
+ if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) {
+ priv_version = PRIV_VERSION_1_10_0;
+ } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.9.1")) {
+ priv_version = PRIV_VERSION_1_09_1;
+ } else {
+ error_setg(errp,
+ "Unsupported privilege spec version '%s'",
+ cpu->cfg.priv_spec);
+ return;
+ }
+ }
+
+ if (cpu->cfg.user_spec) {
+ if (!g_strcmp0(cpu->cfg.user_spec, "v2.02.0")) {
+ user_version = USER_VERSION_2_02_0;
+ } else {
+ error_setg(errp,
+ "Unsupported user spec version '%s'",
+ cpu->cfg.user_spec);
+ return;
+ }
+ }
+
+ set_versions(env, user_version, priv_version);
+ set_resetvec(env, DEFAULT_RSTVEC);
+
+ if (cpu->cfg.mmu) {
+ set_feature(env, RISCV_FEATURE_MMU);
+ }
+
+ if (cpu->cfg.pmp) {
+ set_feature(env, RISCV_FEATURE_PMP);
+ }
+
riscv_cpu_register_gdb_regs_for_features(cs);
qemu_init_vcpu(cs);
@@ -326,6 +378,14 @@ static const VMStateDescription vmstate_riscv_cpu = {
.unmigratable = 1,
};
+static Property riscv_cpu_properties[] = {
+ DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
+ DEFINE_PROP_STRING("user_spec", RISCVCPU, cfg.user_spec),
+ DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
+ DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
static void riscv_cpu_class_init(ObjectClass *c, void *data)
{
RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
@@ -365,6 +425,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
#endif
/* For now, mark unmigratable: */
cc->vmsd = &vmstate_riscv_cpu;
+ dc->props = riscv_cpu_properties;
}
char *riscv_isa_string(RISCVCPU *cpu)
@@ -430,12 +491,14 @@ static const TypeInfo riscv_cpu_type_infos[] = {
},
DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
#if defined(TARGET_RISCV32)
+ DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base32_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_09_1, rv32gcsu_priv1_09_1_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_10_0, rv32gcsu_priv1_10_0_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_RV32IMACU_NOMMU, rv32imacu_nommu_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32imacu_nommu_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32gcsu_priv1_10_0_cpu_init)
#elif defined(TARGET_RISCV64)
+ DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base64_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_09_1, rv64gcsu_priv1_09_1_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_10_0, rv64gcsu_priv1_10_0_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_RV64IMACU_NOMMU, rv64imacu_nommu_cpu_init),