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

@ -1536,6 +1536,7 @@ Property riscv_cpu_options[] = {
static RISCVCPUProfile RVA22U64 = {
.name = "rva22u64",
.misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVU,
.priv_spec = RISCV_PROFILE_ATTR_UNUSED,
.ext_offsets = {
CPU_CFG_OFFSET(ext_zicsr), CPU_CFG_OFFSET(ext_zihintpause),
CPU_CFG_OFFSET(ext_zba), CPU_CFG_OFFSET(ext_zbb),

View File

@ -81,10 +81,12 @@ typedef struct riscv_cpu_profile {
uint32_t misa_ext;
bool enabled;
bool user_set;
int priv_spec;
const int32_t ext_offsets[];
} RISCVCPUProfile;
#define RISCV_PROFILE_EXT_LIST_END -1
#define RISCV_PROFILE_ATTR_UNUSED -1
extern RISCVCPUProfile *riscv_profiles[];

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];