target/riscv/cpu: set cpu->cfg in register_cpu_props()

There is an informal contract between the cpu_init() functions and
riscv_cpu_realize(): if cpu->env.misa_ext is zero, assume that the
default settings were loaded via register_cpu_props() and do validations
to set env.misa_ext. If it's not zero, skip this whole process and
assume that the board somehow did everything.

At this moment, all SiFive CPUs are setting a non-zero misa_ext during
their cpu_init() and skipping a good chunk of riscv_cpu_realize().  This
causes problems when the code being skipped in riscv_cpu_realize()
contains fixes or assumptions that affects all CPUs, meaning that SiFive
CPUs are missing out.

To allow this code to not be skipped anymore, all the cpu->cfg.ext_*
attributes needs to be set during cpu_init() time. At this moment this
is being done in register_cpu_props(). The SiFive boards are setting
their own extensions during cpu_init() though, meaning that they don't
want all the defaults from register_cpu_props().

Let's move the contract between *_cpu_init() and riscv_cpu_realize() to
register_cpu_props(). Inside this function we'll check if
cpu->env.misa_ext was set and, if that's the case, set all relevant
cpu->cfg.ext_* attributes, and only that. Leave the 'misa_ext' = 0 case
as is today, i.e. loading all the defaults from riscv_cpu_extensions[].

register_cpu_props() can then be called by all the cpu_init() functions,
including the SiFive ones. This will make all CPUs behave more in line
with what riscv_cpu_realize() expects.

This will also make the cpu_init() functions even more alike, but at this
moment we would need some design changes in how we're initializing
extensions/attributes (e.g. some CPUs are setting cfg options after
register_cpu_props(), so we can't simply add the function to a common
post_init() hook)  to make a common cpu_init() code across all CPUs.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20230113175230.473975-2-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
Daniel Henrique Barboza 2023-01-13 14:52:29 -03:00 committed by Alistair Francis
parent 60c1f05e36
commit c66ffcd535
2 changed files with 44 additions and 0 deletions

View File

@ -256,6 +256,7 @@ static void rv64_sifive_u_cpu_init(Object *obj)
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
register_cpu_props(DEVICE(obj));
set_priv_version(env, PRIV_VERSION_1_10_0);
}
@ -265,6 +266,7 @@ static void rv64_sifive_e_cpu_init(Object *obj)
RISCVCPU *cpu = RISCV_CPU(obj);
set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
register_cpu_props(DEVICE(obj));
set_priv_version(env, PRIV_VERSION_1_10_0);
cpu->cfg.mmu = false;
}
@ -299,6 +301,7 @@ static void rv32_sifive_u_cpu_init(Object *obj)
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
register_cpu_props(DEVICE(obj));
set_priv_version(env, PRIV_VERSION_1_10_0);
}
@ -308,6 +311,7 @@ static void rv32_sifive_e_cpu_init(Object *obj)
RISCVCPU *cpu = RISCV_CPU(obj);
set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
register_cpu_props(DEVICE(obj));
set_priv_version(env, PRIV_VERSION_1_10_0);
cpu->cfg.mmu = false;
}
@ -318,6 +322,7 @@ static void rv32_ibex_cpu_init(Object *obj)
RISCVCPU *cpu = RISCV_CPU(obj);
set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
register_cpu_props(DEVICE(obj));
set_priv_version(env, PRIV_VERSION_1_11_0);
cpu->cfg.mmu = false;
cpu->cfg.epmp = true;
@ -329,6 +334,7 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
RISCVCPU *cpu = RISCV_CPU(obj);
set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
register_cpu_props(DEVICE(obj));
set_priv_version(env, PRIV_VERSION_1_10_0);
cpu->cfg.mmu = false;
}
@ -1083,10 +1089,44 @@ static Property riscv_cpu_extensions[] = {
DEFINE_PROP_END_OF_LIST(),
};
/*
* Register CPU props based on env.misa_ext. If a non-zero
* value was set, register only the required cpu->cfg.ext_*
* properties and leave. env.misa_ext = 0 means that we want
* all the default properties to be registered.
*/
static void register_cpu_props(DeviceState *dev)
{
RISCVCPU *cpu = RISCV_CPU(OBJECT(dev));
uint32_t misa_ext = cpu->env.misa_ext;
Property *prop;
/*
* If misa_ext is not zero, set cfg properties now to
* allow them to be read during riscv_cpu_realize()
* later on.
*/
if (cpu->env.misa_ext != 0) {
cpu->cfg.ext_i = misa_ext & RVI;
cpu->cfg.ext_e = misa_ext & RVE;
cpu->cfg.ext_m = misa_ext & RVM;
cpu->cfg.ext_a = misa_ext & RVA;
cpu->cfg.ext_f = misa_ext & RVF;
cpu->cfg.ext_d = misa_ext & RVD;
cpu->cfg.ext_v = misa_ext & RVV;
cpu->cfg.ext_c = misa_ext & RVC;
cpu->cfg.ext_s = misa_ext & RVS;
cpu->cfg.ext_u = misa_ext & RVU;
cpu->cfg.ext_h = misa_ext & RVH;
cpu->cfg.ext_j = misa_ext & RVJ;
/*
* We don't want to set the default riscv_cpu_extensions
* in this case.
*/
return;
}
for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
qdev_property_add_static(dev, prop);
}

View File

@ -63,6 +63,10 @@
#define RV(x) ((target_ulong)1 << (x - 'A'))
/*
* Consider updating register_cpu_props() when adding
* new MISA bits here.
*/
#define RVI RV('I')
#define RVE RV('E') /* E and I are mutually exclusive */
#define RVM RV('M')