diff options
Diffstat (limited to 'target/riscv/tcg/tcg-cpu.c')
| -rw-r--r-- | target/riscv/tcg/tcg-cpu.c | 143 |
1 files changed, 42 insertions, 101 deletions
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c index b7da92783b..dd5228c288 100644 --- a/target/riscv/tcg/tcg-cpu.c +++ b/target/riscv/tcg/tcg-cpu.c @@ -268,97 +268,24 @@ static void riscv_cpu_validate_misa_priv(CPURISCVState *env, Error **errp) } } -static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp) -{ - RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu); - CPUClass *cc = CPU_CLASS(mcc); - CPURISCVState *env = &cpu->env; - - /* Validate that MISA_MXL is set properly. */ - switch (env->misa_mxl_max) { -#ifdef TARGET_RISCV64 - case MXL_RV64: - case MXL_RV128: - cc->gdb_core_xml_file = "riscv-64bit-cpu.xml"; - break; -#endif - case MXL_RV32: - cc->gdb_core_xml_file = "riscv-32bit-cpu.xml"; - break; - default: - g_assert_not_reached(); - } - - if (env->misa_mxl_max != env->misa_mxl) { - error_setg(errp, "misa_mxl_max must be equal to misa_mxl"); - return; - } -} - -static void riscv_cpu_validate_priv_spec(RISCVCPU *cpu, Error **errp) -{ - CPURISCVState *env = &cpu->env; - int priv_version = -1; - - if (cpu->cfg.priv_spec) { - if (!g_strcmp0(cpu->cfg.priv_spec, "v1.12.0")) { - priv_version = PRIV_VERSION_1_12_0; - } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) { - priv_version = PRIV_VERSION_1_11_0; - } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) { - priv_version = PRIV_VERSION_1_10_0; - } else { - error_setg(errp, - "Unsupported privilege spec version '%s'", - cpu->cfg.priv_spec); - return; - } - - env->priv_ver = priv_version; - } -} - static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg, Error **errp) { - if (!is_power_of_2(cfg->vlen)) { - error_setg(errp, "Vector extension VLEN must be power of 2"); - return; - } + uint32_t vlen = cfg->vlenb << 3; - if (cfg->vlen > RV_VLEN_MAX || cfg->vlen < 128) { + if (vlen > RV_VLEN_MAX || vlen < 128) { error_setg(errp, "Vector extension implementation only supports VLEN " "in the range [128, %d]", RV_VLEN_MAX); return; } - if (!is_power_of_2(cfg->elen)) { - error_setg(errp, "Vector extension ELEN must be power of 2"); - return; - } - if (cfg->elen > 64 || cfg->elen < 8) { error_setg(errp, "Vector extension implementation only supports ELEN " "in the range [8, 64]"); return; } - - if (cfg->vext_spec) { - if (!g_strcmp0(cfg->vext_spec, "v1.0")) { - env->vext_ver = VEXT_VERSION_1_00_0; - } else { - error_setg(errp, "Unsupported vector spec version '%s'", - cfg->vext_spec); - return; - } - } else if (env->vext_ver == 0) { - qemu_log("vector version is not specified, " - "use the default value v1.0\n"); - - env->vext_ver = VEXT_VERSION_1_00_0; - } } static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu) @@ -442,12 +369,42 @@ static void riscv_cpu_validate_g(RISCVCPU *cpu) } } +static void riscv_cpu_validate_b(RISCVCPU *cpu) +{ + const char *warn_msg = "RVB mandates disabled extension %s"; + + if (!cpu->cfg.ext_zba) { + if (!cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zba))) { + cpu->cfg.ext_zba = true; + } else { + warn_report(warn_msg, "zba"); + } + } + + if (!cpu->cfg.ext_zbb) { + if (!cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zbb))) { + cpu->cfg.ext_zbb = true; + } else { + warn_report(warn_msg, "zbb"); + } + } + + if (!cpu->cfg.ext_zbs) { + if (!cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zbs))) { + cpu->cfg.ext_zbs = true; + } else { + warn_report(warn_msg, "zbs"); + } + } +} + /* * Check consistency between chosen extensions while setting * cpu->cfg accordingly. */ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) { + RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu); CPURISCVState *env = &cpu->env; Error *local_err = NULL; @@ -455,6 +412,10 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) riscv_cpu_validate_g(cpu); } + if (riscv_has_ext(env, RVB)) { + riscv_cpu_validate_b(cpu); + } + if (riscv_has_ext(env, RVI) && riscv_has_ext(env, RVE)) { error_setg(errp, "I and E extensions are incompatible"); @@ -610,7 +571,7 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zcb), true); cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zcmp), true); cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zcmt), true); - if (riscv_has_ext(env, RVF) && env->misa_mxl_max == MXL_RV32) { + if (riscv_has_ext(env, RVF) && mcc->misa_mxl_max == MXL_RV32) { cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zcf), true); } } @@ -618,7 +579,7 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) /* zca, zcd and zcf has a PRIV 1.12.0 restriction */ if (riscv_has_ext(env, RVC) && env->priv_ver >= PRIV_VERSION_1_12_0) { cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zca), true); - if (riscv_has_ext(env, RVF) && env->misa_mxl_max == MXL_RV32) { + if (riscv_has_ext(env, RVF) && mcc->misa_mxl_max == MXL_RV32) { cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zcf), true); } if (riscv_has_ext(env, RVD)) { @@ -626,7 +587,7 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) } } - if (env->misa_mxl_max != MXL_RV32 && cpu->cfg.ext_zcf) { + if (mcc->misa_mxl_max != MXL_RV32 && cpu->cfg.ext_zcf) { error_setg(errp, "Zcf extension is only relevant to RV32"); return; } @@ -876,12 +837,6 @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp) CPURISCVState *env = &cpu->env; Error *local_err = NULL; - riscv_cpu_validate_priv_spec(cpu, &local_err); - if (local_err != NULL) { - error_propagate(errp, local_err); - return; - } - riscv_cpu_validate_misa_priv(env, &local_err); if (local_err != NULL) { error_propagate(errp, local_err); @@ -917,11 +872,6 @@ static bool riscv_cpu_is_generic(Object *cpu_obj) return object_dynamic_cast(cpu_obj, TYPE_RISCV_DYNAMIC_CPU) != NULL; } -static bool riscv_cpu_is_vendor(Object *cpu_obj) -{ - return object_dynamic_cast(cpu_obj, TYPE_RISCV_VENDOR_CPU) != NULL; -} - /* * We'll get here via the following path: * @@ -932,7 +882,6 @@ static bool riscv_cpu_is_vendor(Object *cpu_obj) static bool riscv_tcg_cpu_realize(CPUState *cs, Error **errp) { RISCVCPU *cpu = RISCV_CPU(cs); - Error *local_err = NULL; if (!riscv_cpu_tcg_compatible(cpu)) { g_autofree char *name = riscv_cpu_get_name(cpu); @@ -941,14 +890,9 @@ static bool riscv_tcg_cpu_realize(CPUState *cs, Error **errp) return false; } - riscv_cpu_validate_misa_mxl(cpu, &local_err); - if (local_err != NULL) { - error_propagate(errp, local_err); - return false; - } - #ifndef CONFIG_USER_ONLY CPURISCVState *env = &cpu->env; + Error *local_err = NULL; CPU(cs)->tcg_cflags |= CF_PCREL; @@ -1056,6 +1000,7 @@ static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = { MISA_CFG(RVJ, false), MISA_CFG(RVV, false), MISA_CFG(RVG, false), + MISA_CFG(RVB, false), }; /* @@ -1326,10 +1271,6 @@ static void riscv_cpu_add_user_properties(Object *obj) riscv_cpu_add_multiext_prop_array(obj, riscv_cpu_deprecated_exts); riscv_cpu_add_profiles(obj); - - for (Property *prop = riscv_cpu_options; prop && prop->name; prop++) { - qdev_property_add_static(DEVICE(obj), prop); - } } /* @@ -1343,7 +1284,7 @@ static void riscv_init_max_cpu_extensions(Object *obj) const RISCVCPUMultiExtConfig *prop; /* Enable RVG, RVJ and RVV that are disabled by default */ - riscv_cpu_set_misa(env, env->misa_mxl, env->misa_ext | RVG | RVJ | RVV); + riscv_cpu_set_misa_ext(env, env->misa_ext | RVG | RVJ | RVV); for (prop = riscv_cpu_extensions; prop && prop->name; prop++) { isa_ext_update_enabled(cpu, prop->offset, true); |