Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
danielhb authored and alistair23 committed May 5, 2023
1 parent 66247ed commit 1ffa805
Showing 1 changed file with 56 additions and 38 deletions.
94 changes: 56 additions & 38 deletions target/riscv/cpu.c
Expand Up @@ -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 &&
Expand All @@ -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) {
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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]) &&
Expand Down

0 comments on commit 1ffa805

Please sign in to comment.