target/riscv: Allow setting ISA extensions via CPU props
This patch allows us to enable/disable the RISC-V ISA extensions from the QEMU command line. This works with the rv32 and rv64 machines. The idea is that in the future we can now add extensions and leave them disabled by default until enabled by the user. Signed-off-by: Alistair Francis <alistair.francis@wdc.com> Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
This commit is contained in:
parent
474f3938d7
commit
b55d7d34f6
@ -24,6 +24,7 @@
|
||||
#include "cpu.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "migration/vmstate.h"
|
||||
|
||||
@ -119,7 +120,8 @@ static void riscv_any_cpu_init(Object *obj)
|
||||
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);
|
||||
/* We set this in the realise function */
|
||||
set_misa(env, 0);
|
||||
}
|
||||
|
||||
static void rv32gcsu_priv1_09_1_cpu_init(Object *obj)
|
||||
@ -156,7 +158,8 @@ static void rv32imacu_nommu_cpu_init(Object *obj)
|
||||
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);
|
||||
/* We set this in the realise function */
|
||||
set_misa(env, 0);
|
||||
}
|
||||
|
||||
static void rv64gcsu_priv1_09_1_cpu_init(Object *obj)
|
||||
@ -315,6 +318,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
|
||||
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
|
||||
int priv_version = PRIV_VERSION_1_10_0;
|
||||
int user_version = USER_VERSION_2_02_0;
|
||||
target_ulong target_misa = 0;
|
||||
Error *local_err = NULL;
|
||||
|
||||
cpu_exec_realizefn(cs, &local_err);
|
||||
@ -358,6 +362,58 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
|
||||
set_feature(env, RISCV_FEATURE_PMP);
|
||||
}
|
||||
|
||||
/* If misa isn't set (rv32 and rv64 machines) set it here */
|
||||
if (!env->misa) {
|
||||
/* Do some ISA extension error checking */
|
||||
if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
|
||||
error_setg(errp,
|
||||
"I and E extensions are incompatible");
|
||||
return;
|
||||
}
|
||||
|
||||
if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m &
|
||||
cpu->cfg.ext_a & cpu->cfg.ext_f &
|
||||
cpu->cfg.ext_d)) {
|
||||
warn_report("Setting G will also set IMAFD");
|
||||
cpu->cfg.ext_i = true;
|
||||
cpu->cfg.ext_m = true;
|
||||
cpu->cfg.ext_a = true;
|
||||
cpu->cfg.ext_f = true;
|
||||
cpu->cfg.ext_d = true;
|
||||
}
|
||||
|
||||
/* Set the ISA extensions, checks should have happened above */
|
||||
if (cpu->cfg.ext_i) {
|
||||
target_misa |= RVI;
|
||||
}
|
||||
if (cpu->cfg.ext_e) {
|
||||
target_misa |= RVE;
|
||||
}
|
||||
if (cpu->cfg.ext_m) {
|
||||
target_misa |= RVM;
|
||||
}
|
||||
if (cpu->cfg.ext_a) {
|
||||
target_misa |= RVA;
|
||||
}
|
||||
if (cpu->cfg.ext_f) {
|
||||
target_misa |= RVF;
|
||||
}
|
||||
if (cpu->cfg.ext_d) {
|
||||
target_misa |= RVD;
|
||||
}
|
||||
if (cpu->cfg.ext_c) {
|
||||
target_misa |= RVC;
|
||||
}
|
||||
if (cpu->cfg.ext_s) {
|
||||
target_misa |= RVS;
|
||||
}
|
||||
if (cpu->cfg.ext_u) {
|
||||
target_misa |= RVU;
|
||||
}
|
||||
|
||||
set_misa(env, RVXLEN | target_misa);
|
||||
}
|
||||
|
||||
riscv_cpu_register_gdb_regs_for_features(cs);
|
||||
|
||||
qemu_init_vcpu(cs);
|
||||
@ -379,6 +435,16 @@ static const VMStateDescription vmstate_riscv_cpu = {
|
||||
};
|
||||
|
||||
static Property riscv_cpu_properties[] = {
|
||||
DEFINE_PROP_BOOL("i", RISCVCPU, cfg.ext_i, true),
|
||||
DEFINE_PROP_BOOL("e", RISCVCPU, cfg.ext_e, false),
|
||||
DEFINE_PROP_BOOL("g", RISCVCPU, cfg.ext_g, true),
|
||||
DEFINE_PROP_BOOL("m", RISCVCPU, cfg.ext_m, true),
|
||||
DEFINE_PROP_BOOL("a", RISCVCPU, cfg.ext_a, true),
|
||||
DEFINE_PROP_BOOL("f", RISCVCPU, cfg.ext_f, true),
|
||||
DEFINE_PROP_BOOL("d", RISCVCPU, cfg.ext_d, true),
|
||||
DEFINE_PROP_BOOL("c", RISCVCPU, cfg.ext_c, true),
|
||||
DEFINE_PROP_BOOL("s", RISCVCPU, cfg.ext_s, true),
|
||||
DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
|
||||
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),
|
||||
|
@ -211,6 +211,17 @@ typedef struct RISCVCPU {
|
||||
|
||||
/* Configuration Settings */
|
||||
struct {
|
||||
bool ext_i;
|
||||
bool ext_e;
|
||||
bool ext_g;
|
||||
bool ext_m;
|
||||
bool ext_a;
|
||||
bool ext_f;
|
||||
bool ext_d;
|
||||
bool ext_c;
|
||||
bool ext_s;
|
||||
bool ext_u;
|
||||
|
||||
char *priv_spec;
|
||||
char *user_spec;
|
||||
bool mmu;
|
||||
|
Loading…
Reference in New Issue
Block a user