diff options
author | Alistair Francis <Alistair.Francis@wdc.com> | 2019-04-20 02:24:01 +0000 |
---|---|---|
committer | Palmer Dabbelt <palmer@sifive.com> | 2019-05-24 12:09:23 -0700 |
commit | c4e95030ba3532d13aa4e6f0738326f6f2d0c2bf (patch) | |
tree | 0613255fefe99ec095d0a91adffc7bbe6a420a8f | |
parent | ceb2ffd56e3ec7caa8afc94b78257bac99cd738b (diff) |
target/riscv: Create settable CPU properties
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Palmer Dabbelt <palmer@sifive.com>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
-rw-r--r-- | target/riscv/cpu.c | 49 | ||||
-rw-r--r-- | target/riscv/cpu.h | 8 |
2 files changed, 57 insertions, 0 deletions
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 6a58bc9e9d..0399e03e89 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 */ @@ -296,7 +297,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 +310,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 +366,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 +413,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) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index c17184f4e4..3902138639 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -224,6 +224,14 @@ typedef struct RISCVCPU { CPUState parent_obj; /*< public >*/ CPURISCVState env; + + /* Configuration Settings */ + struct { + char *priv_spec; + char *user_spec; + bool mmu; + bool pmp; + } cfg; } RISCVCPU; static inline RISCVCPU *riscv_env_get_cpu(CPURISCVState *env) |