|
@@ -110,16 +110,13 @@ const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
|
|
|
|
|
|
bool riscv_cpu_is_32bit(CPURISCVState *env)
|
|
bool riscv_cpu_is_32bit(CPURISCVState *env)
|
|
{
|
|
{
|
|
- if (env->misa & RV64) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return true;
|
|
|
|
|
|
+ return env->misa_mxl == MXL_RV32;
|
|
}
|
|
}
|
|
|
|
|
|
-static void set_misa(CPURISCVState *env, target_ulong misa)
|
|
|
|
|
|
+static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
|
|
{
|
|
{
|
|
- env->misa_mask = env->misa = misa;
|
|
|
|
|
|
+ env->misa_mxl_max = env->misa_mxl = mxl;
|
|
|
|
+ env->misa_ext_mask = env->misa_ext = ext;
|
|
}
|
|
}
|
|
|
|
|
|
static void set_priv_version(CPURISCVState *env, int priv_ver)
|
|
static void set_priv_version(CPURISCVState *env, int priv_ver)
|
|
@@ -148,9 +145,9 @@ static void riscv_any_cpu_init(Object *obj)
|
|
{
|
|
{
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
|
#if defined(TARGET_RISCV32)
|
|
#if defined(TARGET_RISCV32)
|
|
- set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVU);
|
|
|
|
|
|
+ set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
|
|
#elif defined(TARGET_RISCV64)
|
|
#elif defined(TARGET_RISCV64)
|
|
- set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVU);
|
|
|
|
|
|
+ set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
|
|
#endif
|
|
#endif
|
|
set_priv_version(env, PRIV_VERSION_1_11_0);
|
|
set_priv_version(env, PRIV_VERSION_1_11_0);
|
|
}
|
|
}
|
|
@@ -160,20 +157,20 @@ static void rv64_base_cpu_init(Object *obj)
|
|
{
|
|
{
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
|
/* We set this in the realise function */
|
|
/* We set this in the realise function */
|
|
- set_misa(env, RV64);
|
|
|
|
|
|
+ set_misa(env, MXL_RV64, 0);
|
|
}
|
|
}
|
|
|
|
|
|
static void rv64_sifive_u_cpu_init(Object *obj)
|
|
static void rv64_sifive_u_cpu_init(Object *obj)
|
|
{
|
|
{
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
|
- set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
|
|
|
|
|
|
+ set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
|
|
set_priv_version(env, PRIV_VERSION_1_10_0);
|
|
set_priv_version(env, PRIV_VERSION_1_10_0);
|
|
}
|
|
}
|
|
|
|
|
|
static void rv64_sifive_e_cpu_init(Object *obj)
|
|
static void rv64_sifive_e_cpu_init(Object *obj)
|
|
{
|
|
{
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
|
- set_misa(env, RV64 | RVI | RVM | RVA | RVC | RVU);
|
|
|
|
|
|
+ set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
|
|
set_priv_version(env, PRIV_VERSION_1_10_0);
|
|
set_priv_version(env, PRIV_VERSION_1_10_0);
|
|
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
|
|
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
|
|
}
|
|
}
|
|
@@ -182,20 +179,20 @@ static void rv32_base_cpu_init(Object *obj)
|
|
{
|
|
{
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
|
/* We set this in the realise function */
|
|
/* We set this in the realise function */
|
|
- set_misa(env, RV32);
|
|
|
|
|
|
+ set_misa(env, MXL_RV32, 0);
|
|
}
|
|
}
|
|
|
|
|
|
static void rv32_sifive_u_cpu_init(Object *obj)
|
|
static void rv32_sifive_u_cpu_init(Object *obj)
|
|
{
|
|
{
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
|
- set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
|
|
|
|
|
|
+ set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
|
|
set_priv_version(env, PRIV_VERSION_1_10_0);
|
|
set_priv_version(env, PRIV_VERSION_1_10_0);
|
|
}
|
|
}
|
|
|
|
|
|
static void rv32_sifive_e_cpu_init(Object *obj)
|
|
static void rv32_sifive_e_cpu_init(Object *obj)
|
|
{
|
|
{
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
|
- set_misa(env, RV32 | RVI | RVM | RVA | RVC | RVU);
|
|
|
|
|
|
+ set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
|
|
set_priv_version(env, PRIV_VERSION_1_10_0);
|
|
set_priv_version(env, PRIV_VERSION_1_10_0);
|
|
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
|
|
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
|
|
}
|
|
}
|
|
@@ -203,7 +200,7 @@ static void rv32_sifive_e_cpu_init(Object *obj)
|
|
static void rv32_ibex_cpu_init(Object *obj)
|
|
static void rv32_ibex_cpu_init(Object *obj)
|
|
{
|
|
{
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
|
- set_misa(env, RV32 | RVI | RVM | RVC | RVU);
|
|
|
|
|
|
+ set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
|
|
set_priv_version(env, PRIV_VERSION_1_10_0);
|
|
set_priv_version(env, PRIV_VERSION_1_10_0);
|
|
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
|
|
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
|
|
qdev_prop_set_bit(DEVICE(obj), "x-epmp", true);
|
|
qdev_prop_set_bit(DEVICE(obj), "x-epmp", true);
|
|
@@ -212,7 +209,7 @@ static void rv32_ibex_cpu_init(Object *obj)
|
|
static void rv32_imafcu_nommu_cpu_init(Object *obj)
|
|
static void rv32_imafcu_nommu_cpu_init(Object *obj)
|
|
{
|
|
{
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
|
- set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVC | RVU);
|
|
|
|
|
|
+ set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
|
|
set_priv_version(env, PRIV_VERSION_1_10_0);
|
|
set_priv_version(env, PRIV_VERSION_1_10_0);
|
|
set_resetvec(env, DEFAULT_RSTVEC);
|
|
set_resetvec(env, DEFAULT_RSTVEC);
|
|
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
|
|
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
|
|
@@ -360,6 +357,7 @@ static void riscv_cpu_reset(DeviceState *dev)
|
|
|
|
|
|
mcc->parent_reset(dev);
|
|
mcc->parent_reset(dev);
|
|
#ifndef CONFIG_USER_ONLY
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
+ env->misa_mxl = env->misa_mxl_max;
|
|
env->priv = PRV_M;
|
|
env->priv = PRV_M;
|
|
env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV);
|
|
env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV);
|
|
env->mcause = 0;
|
|
env->mcause = 0;
|
|
@@ -388,7 +386,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
|
|
CPURISCVState *env = &cpu->env;
|
|
CPURISCVState *env = &cpu->env;
|
|
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
|
|
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
|
|
int priv_version = 0;
|
|
int priv_version = 0;
|
|
- target_ulong target_misa = env->misa;
|
|
|
|
Error *local_err = NULL;
|
|
Error *local_err = NULL;
|
|
|
|
|
|
cpu_exec_realizefn(cs, &local_err);
|
|
cpu_exec_realizefn(cs, &local_err);
|
|
@@ -434,8 +431,23 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
|
|
|
|
|
|
set_resetvec(env, cpu->cfg.resetvec);
|
|
set_resetvec(env, cpu->cfg.resetvec);
|
|
|
|
|
|
- /* If only XLEN is set for misa, then set misa from properties */
|
|
|
|
- if (env->misa == RV32 || env->misa == RV64) {
|
|
|
|
|
|
+ /* Validate that MISA_MXL is set properly. */
|
|
|
|
+ switch (env->misa_mxl_max) {
|
|
|
|
+#ifdef TARGET_RISCV64
|
|
|
|
+ case MXL_RV64:
|
|
|
|
+ break;
|
|
|
|
+#endif
|
|
|
|
+ case MXL_RV32:
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ g_assert_not_reached();
|
|
|
|
+ }
|
|
|
|
+ assert(env->misa_mxl_max == env->misa_mxl);
|
|
|
|
+
|
|
|
|
+ /* If only MISA_EXT is unset for misa, then set it from properties */
|
|
|
|
+ if (env->misa_ext == 0) {
|
|
|
|
+ uint32_t ext = 0;
|
|
|
|
+
|
|
/* Do some ISA extension error checking */
|
|
/* Do some ISA extension error checking */
|
|
if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
|
|
if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
|
|
error_setg(errp,
|
|
error_setg(errp,
|
|
@@ -462,38 +474,38 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
|
|
|
|
|
|
/* Set the ISA extensions, checks should have happened above */
|
|
/* Set the ISA extensions, checks should have happened above */
|
|
if (cpu->cfg.ext_i) {
|
|
if (cpu->cfg.ext_i) {
|
|
- target_misa |= RVI;
|
|
|
|
|
|
+ ext |= RVI;
|
|
}
|
|
}
|
|
if (cpu->cfg.ext_e) {
|
|
if (cpu->cfg.ext_e) {
|
|
- target_misa |= RVE;
|
|
|
|
|
|
+ ext |= RVE;
|
|
}
|
|
}
|
|
if (cpu->cfg.ext_m) {
|
|
if (cpu->cfg.ext_m) {
|
|
- target_misa |= RVM;
|
|
|
|
|
|
+ ext |= RVM;
|
|
}
|
|
}
|
|
if (cpu->cfg.ext_a) {
|
|
if (cpu->cfg.ext_a) {
|
|
- target_misa |= RVA;
|
|
|
|
|
|
+ ext |= RVA;
|
|
}
|
|
}
|
|
if (cpu->cfg.ext_f) {
|
|
if (cpu->cfg.ext_f) {
|
|
- target_misa |= RVF;
|
|
|
|
|
|
+ ext |= RVF;
|
|
}
|
|
}
|
|
if (cpu->cfg.ext_d) {
|
|
if (cpu->cfg.ext_d) {
|
|
- target_misa |= RVD;
|
|
|
|
|
|
+ ext |= RVD;
|
|
}
|
|
}
|
|
if (cpu->cfg.ext_c) {
|
|
if (cpu->cfg.ext_c) {
|
|
- target_misa |= RVC;
|
|
|
|
|
|
+ ext |= RVC;
|
|
}
|
|
}
|
|
if (cpu->cfg.ext_s) {
|
|
if (cpu->cfg.ext_s) {
|
|
- target_misa |= RVS;
|
|
|
|
|
|
+ ext |= RVS;
|
|
}
|
|
}
|
|
if (cpu->cfg.ext_u) {
|
|
if (cpu->cfg.ext_u) {
|
|
- target_misa |= RVU;
|
|
|
|
|
|
+ ext |= RVU;
|
|
}
|
|
}
|
|
if (cpu->cfg.ext_h) {
|
|
if (cpu->cfg.ext_h) {
|
|
- target_misa |= RVH;
|
|
|
|
|
|
+ ext |= RVH;
|
|
}
|
|
}
|
|
if (cpu->cfg.ext_v) {
|
|
if (cpu->cfg.ext_v) {
|
|
int vext_version = VEXT_VERSION_0_07_1;
|
|
int vext_version = VEXT_VERSION_0_07_1;
|
|
- target_misa |= RVV;
|
|
|
|
|
|
+ ext |= RVV;
|
|
if (!is_power_of_2(cpu->cfg.vlen)) {
|
|
if (!is_power_of_2(cpu->cfg.vlen)) {
|
|
error_setg(errp,
|
|
error_setg(errp,
|
|
"Vector extension VLEN must be power of 2");
|
|
"Vector extension VLEN must be power of 2");
|
|
@@ -532,7 +544,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
|
|
set_vext_version(env, vext_version);
|
|
set_vext_version(env, vext_version);
|
|
}
|
|
}
|
|
|
|
|
|
- set_misa(env, target_misa);
|
|
|
|
|
|
+ set_misa(env, env->misa_mxl, ext);
|
|
}
|
|
}
|
|
|
|
|
|
riscv_cpu_register_gdb_regs_for_features(cs);
|
|
riscv_cpu_register_gdb_regs_for_features(cs);
|
|
@@ -708,7 +720,7 @@ char *riscv_isa_string(RISCVCPU *cpu)
|
|
char *isa_str = g_new(char, maxlen);
|
|
char *isa_str = g_new(char, maxlen);
|
|
char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", TARGET_LONG_BITS);
|
|
char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", TARGET_LONG_BITS);
|
|
for (i = 0; i < sizeof(riscv_exts); i++) {
|
|
for (i = 0; i < sizeof(riscv_exts); i++) {
|
|
- if (cpu->env.misa & RV(riscv_exts[i])) {
|
|
|
|
|
|
+ if (cpu->env.misa_ext & RV(riscv_exts[i])) {
|
|
*p++ = qemu_tolower(riscv_exts[i]);
|
|
*p++ = qemu_tolower(riscv_exts[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|