target/riscv: sync env->misa_ext* with cpu->cfg in realize()
When riscv_cpu_realize() starts we're guaranteed to have cpu->cfg.ext_N properties updated. The same can't be said about env->misa_ext*, since the user might enable/disable MISA extensions in the command line, and env->misa_ext* won't caught these changes. The current solution is to sync everything at the end of validate_set_extensions(), checking every cpu->cfg.ext_N value to do a set_misa() in the end. The last change we're making in the MISA cfg flags are in the G extension logic, enabling IMAFG if cpu->cfg_ext.g is enabled. Otherwise we're not making any changes in MISA bits ever since realize() starts. There's no reason to postpone misa_ext updates until the end of the validation. Let's do it earlier, during realize(), in a new helper called riscv_cpu_sync_misa_cfg(). If cpu->cfg.ext_g is enabled, do it again by updating env->misa_ext* directly. This is a pre-requisite to allow riscv_cpu_validate_set_extensions() to use riscv_has_ext() instead of cpu->cfg.ext_N to validate the MISA extensions, which is our end goal here. Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-Id: <20230406180351.570807-2-dbarboza@ventanamicro.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
66247edc8b
commit
1ffa805c9d
@ -811,12 +811,11 @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
|
||||
|
||||
/*
|
||||
* Check consistency between chosen extensions while setting
|
||||
* cpu->cfg accordingly, doing a set_misa() in the end.
|
||||
* cpu->cfg accordingly.
|
||||
*/
|
||||
static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
|
||||
{
|
||||
CPURISCVState *env = &cpu->env;
|
||||
uint32_t ext = 0;
|
||||
|
||||
/* Do some ISA extension error checking */
|
||||
if (cpu->cfg.ext_g && !(cpu->cfg.ext_i && cpu->cfg.ext_m &&
|
||||
@ -831,6 +830,9 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
|
||||
cpu->cfg.ext_d = true;
|
||||
cpu->cfg.ext_icsr = true;
|
||||
cpu->cfg.ext_ifencei = true;
|
||||
|
||||
env->misa_ext |= RVI | RVM | RVA | RVF | RVD;
|
||||
env->misa_ext_mask = env->misa_ext;
|
||||
}
|
||||
|
||||
if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
|
||||
@ -1022,39 +1024,8 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
|
||||
cpu->cfg.ext_zksh = true;
|
||||
}
|
||||
|
||||
if (cpu->cfg.ext_i) {
|
||||
ext |= RVI;
|
||||
}
|
||||
if (cpu->cfg.ext_e) {
|
||||
ext |= RVE;
|
||||
}
|
||||
if (cpu->cfg.ext_m) {
|
||||
ext |= RVM;
|
||||
}
|
||||
if (cpu->cfg.ext_a) {
|
||||
ext |= RVA;
|
||||
}
|
||||
if (cpu->cfg.ext_f) {
|
||||
ext |= RVF;
|
||||
}
|
||||
if (cpu->cfg.ext_d) {
|
||||
ext |= RVD;
|
||||
}
|
||||
if (cpu->cfg.ext_c) {
|
||||
ext |= RVC;
|
||||
}
|
||||
if (cpu->cfg.ext_s) {
|
||||
ext |= RVS;
|
||||
}
|
||||
if (cpu->cfg.ext_u) {
|
||||
ext |= RVU;
|
||||
}
|
||||
if (cpu->cfg.ext_h) {
|
||||
ext |= RVH;
|
||||
}
|
||||
if (cpu->cfg.ext_v) {
|
||||
int vext_version = VEXT_VERSION_1_00_0;
|
||||
ext |= RVV;
|
||||
if (!is_power_of_2(cpu->cfg.vlen)) {
|
||||
error_setg(errp,
|
||||
"Vector extension VLEN must be power of 2");
|
||||
@ -1092,11 +1063,6 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
|
||||
}
|
||||
set_vext_version(env, vext_version);
|
||||
}
|
||||
if (cpu->cfg.ext_j) {
|
||||
ext |= RVJ;
|
||||
}
|
||||
|
||||
set_misa(env, env->misa_mxl, ext);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
@ -1181,6 +1147,50 @@ static void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void riscv_cpu_sync_misa_cfg(CPURISCVState *env)
|
||||
{
|
||||
uint32_t ext = 0;
|
||||
|
||||
if (riscv_cpu_cfg(env)->ext_i) {
|
||||
ext |= RVI;
|
||||
}
|
||||
if (riscv_cpu_cfg(env)->ext_e) {
|
||||
ext |= RVE;
|
||||
}
|
||||
if (riscv_cpu_cfg(env)->ext_m) {
|
||||
ext |= RVM;
|
||||
}
|
||||
if (riscv_cpu_cfg(env)->ext_a) {
|
||||
ext |= RVA;
|
||||
}
|
||||
if (riscv_cpu_cfg(env)->ext_f) {
|
||||
ext |= RVF;
|
||||
}
|
||||
if (riscv_cpu_cfg(env)->ext_d) {
|
||||
ext |= RVD;
|
||||
}
|
||||
if (riscv_cpu_cfg(env)->ext_c) {
|
||||
ext |= RVC;
|
||||
}
|
||||
if (riscv_cpu_cfg(env)->ext_s) {
|
||||
ext |= RVS;
|
||||
}
|
||||
if (riscv_cpu_cfg(env)->ext_u) {
|
||||
ext |= RVU;
|
||||
}
|
||||
if (riscv_cpu_cfg(env)->ext_h) {
|
||||
ext |= RVH;
|
||||
}
|
||||
if (riscv_cpu_cfg(env)->ext_v) {
|
||||
ext |= RVV;
|
||||
}
|
||||
if (riscv_cpu_cfg(env)->ext_j) {
|
||||
ext |= RVJ;
|
||||
}
|
||||
|
||||
env->misa_ext = env->misa_ext_mask = ext;
|
||||
}
|
||||
|
||||
static void riscv_cpu_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
CPUState *cs = CPU(dev);
|
||||
@ -1216,6 +1226,14 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
|
||||
set_priv_version(env, priv_version);
|
||||
}
|
||||
|
||||
/*
|
||||
* We can't be sure of whether we set defaults during cpu_init()
|
||||
* or whether the user enabled/disabled some bits via cpu->cfg
|
||||
* flags. Sync env->misa_ext with cpu->cfg now to allow us to
|
||||
* use just env->misa_ext later.
|
||||
*/
|
||||
riscv_cpu_sync_misa_cfg(env);
|
||||
|
||||
/* Force disable extensions if priv spec version does not match */
|
||||
for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
|
||||
if (isa_ext_is_enabled(cpu, &isa_edata_arr[i]) &&
|
||||
|
Loading…
Reference in New Issue
Block a user