target/riscv: add priv ver restriction to profiles

Some profiles, like RVA22S64, has a priv_spec requirement.

Make this requirement explicit for all profiles. We'll validate this
requirement finalize() time and, in case the user chooses an
incompatible priv_spec while activating a profile, a warning will be
shown.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20231218125334.37184-21-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
Daniel Henrique Barboza 2023-12-18 09:53:28 -03:00 committed by Alistair Francis
parent 48531f5adb
commit 1a7d4fcb3f
3 changed files with 34 additions and 0 deletions

View file

@ -74,6 +74,20 @@ static void riscv_cpu_write_misa_bit(RISCVCPU *cpu, uint32_t bit,
}
}
static const char *cpu_priv_ver_to_str(int priv_ver)
{
switch (priv_ver) {
case PRIV_VERSION_1_10_0:
return "v1.10.0";
case PRIV_VERSION_1_11_0:
return "v1.11.0";
case PRIV_VERSION_1_12_0:
return "v1.12.0";
}
g_assert_not_reached();
}
static void riscv_cpu_synchronize_from_tb(CPUState *cs,
const TranslationBlock *tb)
{
@ -760,11 +774,24 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
static void riscv_cpu_validate_profile(RISCVCPU *cpu,
RISCVCPUProfile *profile)
{
CPURISCVState *env = &cpu->env;
const char *warn_msg = "Profile %s mandates disabled extension %s";
bool send_warn = profile->user_set && profile->enabled;
bool profile_impl = true;
int i;
if (profile->priv_spec != RISCV_PROFILE_ATTR_UNUSED &&
profile->priv_spec != env->priv_ver) {
profile_impl = false;
if (send_warn) {
warn_report("Profile %s requires priv spec %s, "
"but priv ver %s was set", profile->name,
cpu_priv_ver_to_str(profile->priv_spec),
cpu_priv_ver_to_str(env->priv_ver));
}
}
for (i = 0; misa_bits[i] != 0; i++) {
uint32_t bit = misa_bits[i];
@ -1053,6 +1080,10 @@ static void cpu_set_profile(Object *obj, Visitor *v, const char *name,
profile->user_set = true;
profile->enabled = value;
if (profile->enabled) {
cpu->env.priv_ver = profile->priv_spec;
}
for (i = 0; misa_bits[i] != 0; i++) {
uint32_t bit = misa_bits[i];