mirror of
https://github.com/qemu/qemu.git
synced 2024-12-15 23:43:31 +08:00
Merge patch series "make write_misa a no-op and FEATURE_* cleanups"
Daniel Henrique Barboza <dbarboza@ventanamicro.com> says: The RISCV_FEATURES_* enum and the CPUArchState::features attribute were introduced 4+ years ago, as a way to retrieve the enabled hart features that aren't represented via MISA CSR bits. Time passed on, and RISCVCPUConfig was introduced. With it, we now have a centralized way of reading all hart features that are enabled/disabled by the user and the board. All recent features are reading their correspondent cpu->cfg.X flag. All but the 5 features in the RISCV_FEATURE_* enum. These features are still operating in the same way: set it during riscv_cpu_realize() using their cpu->cfg value, read it using riscv_feature() when needed. There is nothing special about them in comparison with all the other features and extensions to justify this special handling. This series then is doing two things: first we're actually allowing users to write the MISA CSR if they so choose. Then we're deprecate each RISC_FEATURE_* usage until, in patch 11, we remove everything related to it. All 5 existing RISCV_FEATURE_* features will be handled as everyone else. * b4-shazam-merge: target/riscv/cpu: remove CPUArchState::features and friends target/riscv: remove RISCV_FEATURE_MMU hw/riscv/virt.c: do not use RISCV_FEATURE_MMU in create_fdt_socket_cpus() target/riscv: remove RISCV_FEATURE_PMP target/riscv: remove RISCV_FEATURE_EPMP target/riscv/cpu.c: error out if EPMP is enabled without PMP target/riscv: remove RISCV_FEATURE_DEBUG target/riscv: allow MISA writes as experimental target/riscv: do not mask unsupported QEMU extensions in write_misa() target/riscv: introduce riscv_cpu_cfg() Message-ID: <20230222185205.355361-1-dbarboza@ventanamicro.com> [Palmer: use the text from the v1] Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
This commit is contained in:
commit
d3e6d5762b
@ -232,20 +232,21 @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket,
|
||||
bool is_32_bit = riscv_is_32bit(&s->soc[0]);
|
||||
|
||||
for (cpu = s->soc[socket].num_harts - 1; cpu >= 0; cpu--) {
|
||||
RISCVCPU *cpu_ptr = &s->soc[socket].harts[cpu];
|
||||
|
||||
cpu_phandle = (*phandle)++;
|
||||
|
||||
cpu_name = g_strdup_printf("/cpus/cpu@%d",
|
||||
s->soc[socket].hartid_base + cpu);
|
||||
qemu_fdt_add_subnode(ms->fdt, cpu_name);
|
||||
if (riscv_feature(&s->soc[socket].harts[cpu].env,
|
||||
RISCV_FEATURE_MMU)) {
|
||||
if (cpu_ptr->cfg.mmu) {
|
||||
qemu_fdt_setprop_string(ms->fdt, cpu_name, "mmu-type",
|
||||
(is_32_bit) ? "riscv,sv32" : "riscv,sv48");
|
||||
} else {
|
||||
qemu_fdt_setprop_string(ms->fdt, cpu_name, "mmu-type",
|
||||
"riscv,none");
|
||||
}
|
||||
name = riscv_isa_string(&s->soc[socket].harts[cpu]);
|
||||
name = riscv_isa_string(cpu_ptr);
|
||||
qemu_fdt_setprop_string(ms->fdt, cpu_name, "riscv,isa", name);
|
||||
g_free(name);
|
||||
qemu_fdt_setprop_string(ms->fdt, cpu_name, "compatible", "riscv");
|
||||
|
@ -637,7 +637,7 @@ static void riscv_cpu_reset_hold(Object *obj)
|
||||
set_default_nan_mode(1, &env->fp_status);
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
if (riscv_feature(env, RISCV_FEATURE_DEBUG)) {
|
||||
if (cpu->cfg.debug) {
|
||||
riscv_trigger_init(env);
|
||||
}
|
||||
|
||||
@ -919,24 +919,13 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
if (cpu->cfg.mmu) {
|
||||
riscv_set_feature(env, RISCV_FEATURE_MMU);
|
||||
}
|
||||
|
||||
if (cpu->cfg.pmp) {
|
||||
riscv_set_feature(env, RISCV_FEATURE_PMP);
|
||||
|
||||
if (cpu->cfg.epmp && !cpu->cfg.pmp) {
|
||||
/*
|
||||
* Enhanced PMP should only be available
|
||||
* on harts with PMP support
|
||||
*/
|
||||
if (cpu->cfg.epmp) {
|
||||
riscv_set_feature(env, RISCV_FEATURE_EPMP);
|
||||
}
|
||||
}
|
||||
|
||||
if (cpu->cfg.debug) {
|
||||
riscv_set_feature(env, RISCV_FEATURE_DEBUG);
|
||||
error_setg(errp, "Invalid configuration: EPMP requires PMP support");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -1210,6 +1199,12 @@ static Property riscv_cpu_properties[] = {
|
||||
|
||||
DEFINE_PROP_BOOL("rvv_ta_all_1s", RISCVCPU, cfg.rvv_ta_all_1s, false),
|
||||
DEFINE_PROP_BOOL("rvv_ma_all_1s", RISCVCPU, cfg.rvv_ma_all_1s, false),
|
||||
|
||||
/*
|
||||
* write_misa() is marked as experimental for now so mark
|
||||
* it with -x and default to 'false'.
|
||||
*/
|
||||
DEFINE_PROP_BOOL("x-misa-w", RISCVCPU, cfg.misa_w, false),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
|
@ -81,17 +81,6 @@
|
||||
#define RVH RV('H')
|
||||
#define RVJ RV('J')
|
||||
|
||||
/* S extension denotes that Supervisor mode exists, however it is possible
|
||||
to have a core that support S mode but does not have an MMU and there
|
||||
is currently no bit in misa to indicate whether an MMU exists or not
|
||||
so a cpu features bitfield is required, likewise for optional PMP support */
|
||||
enum {
|
||||
RISCV_FEATURE_MMU,
|
||||
RISCV_FEATURE_PMP,
|
||||
RISCV_FEATURE_EPMP,
|
||||
RISCV_FEATURE_MISA,
|
||||
RISCV_FEATURE_DEBUG
|
||||
};
|
||||
|
||||
/* Privileged specification version */
|
||||
enum {
|
||||
@ -186,8 +175,6 @@ struct CPUArchState {
|
||||
/* 128-bit helpers upper part return value */
|
||||
target_ulong retxh;
|
||||
|
||||
uint32_t features;
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
uint32_t elf_flags;
|
||||
#endif
|
||||
@ -498,6 +485,7 @@ struct RISCVCPUConfig {
|
||||
bool pmp;
|
||||
bool epmp;
|
||||
bool debug;
|
||||
bool misa_w;
|
||||
|
||||
bool short_isa_string;
|
||||
};
|
||||
@ -535,16 +523,6 @@ static inline int riscv_has_ext(CPURISCVState *env, target_ulong ext)
|
||||
return (env->misa_ext & ext) != 0;
|
||||
}
|
||||
|
||||
static inline bool riscv_feature(CPURISCVState *env, int feature)
|
||||
{
|
||||
return env->features & (1ULL << feature);
|
||||
}
|
||||
|
||||
static inline void riscv_set_feature(CPURISCVState *env, int feature)
|
||||
{
|
||||
env->features |= (1ULL << feature);
|
||||
}
|
||||
|
||||
#include "cpu_user.h"
|
||||
|
||||
extern const char * const riscv_int_regnames[];
|
||||
@ -654,6 +632,11 @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
|
||||
#endif
|
||||
#define riscv_cpu_mxl_bits(env) (1UL << (4 + riscv_cpu_mxl(env)))
|
||||
|
||||
static inline const RISCVCPUConfig *riscv_cpu_cfg(CPURISCVState *env)
|
||||
{
|
||||
return &env_archcpu(env)->cfg;
|
||||
}
|
||||
|
||||
#if defined(TARGET_RISCV32)
|
||||
#define cpu_recompute_xl(env) ((void)(env), MXL_RV32)
|
||||
#else
|
||||
|
@ -105,7 +105,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
|
||||
flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_VS,
|
||||
get_field(env->mstatus_hs, MSTATUS_VS));
|
||||
}
|
||||
if (riscv_feature(env, RISCV_FEATURE_DEBUG) && !icount_enabled()) {
|
||||
if (cpu->cfg.debug && !icount_enabled()) {
|
||||
flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER, env->itrigger_enabled);
|
||||
}
|
||||
#endif
|
||||
@ -706,7 +706,7 @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot,
|
||||
pmp_priv_t pmp_priv;
|
||||
int pmp_index = -1;
|
||||
|
||||
if (!riscv_feature(env, RISCV_FEATURE_PMP)) {
|
||||
if (!riscv_cpu_cfg(env)->pmp) {
|
||||
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
|
||||
return TRANSLATE_SUCCESS;
|
||||
}
|
||||
@ -796,7 +796,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
|
||||
mode = PRV_U;
|
||||
}
|
||||
|
||||
if (mode == PRV_M || !riscv_feature(env, RISCV_FEATURE_MMU)) {
|
||||
if (mode == PRV_M || !riscv_cpu_cfg(env)->mmu) {
|
||||
*physical = addr;
|
||||
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
|
||||
return TRANSLATE_SUCCESS;
|
||||
|
@ -419,7 +419,7 @@ static int aia_hmode32(CPURISCVState *env, int csrno)
|
||||
|
||||
static RISCVException pmp(CPURISCVState *env, int csrno)
|
||||
{
|
||||
if (riscv_feature(env, RISCV_FEATURE_PMP)) {
|
||||
if (riscv_cpu_cfg(env)->pmp) {
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
@ -428,7 +428,7 @@ static RISCVException pmp(CPURISCVState *env, int csrno)
|
||||
|
||||
static RISCVException epmp(CPURISCVState *env, int csrno)
|
||||
{
|
||||
if (env->priv == PRV_M && riscv_feature(env, RISCV_FEATURE_EPMP)) {
|
||||
if (env->priv == PRV_M && riscv_cpu_cfg(env)->epmp) {
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
@ -437,7 +437,7 @@ static RISCVException epmp(CPURISCVState *env, int csrno)
|
||||
|
||||
static RISCVException debug(CPURISCVState *env, int csrno)
|
||||
{
|
||||
if (riscv_feature(env, RISCV_FEATURE_DEBUG)) {
|
||||
if (riscv_cpu_cfg(env)->debug) {
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
@ -1329,7 +1329,7 @@ static RISCVException read_misa(CPURISCVState *env, int csrno,
|
||||
static RISCVException write_misa(CPURISCVState *env, int csrno,
|
||||
target_ulong val)
|
||||
{
|
||||
if (!riscv_feature(env, RISCV_FEATURE_MISA)) {
|
||||
if (!riscv_cpu_cfg(env)->misa_w) {
|
||||
/* drop write to misa */
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
@ -1356,9 +1356,6 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
|
||||
/* Mask extensions that are not supported by this hart */
|
||||
val &= env->misa_ext_mask;
|
||||
|
||||
/* Mask extensions that are not supported by QEMU */
|
||||
val &= (RVI | RVE | RVM | RVA | RVF | RVD | RVC | RVS | RVU | RVV);
|
||||
|
||||
/* 'D' depends on 'F', so clear 'D' if 'F' is not present */
|
||||
if ((val & RVD) && !(val & RVF)) {
|
||||
val &= ~RVD;
|
||||
@ -2624,7 +2621,7 @@ static RISCVException rmw_siph(CPURISCVState *env, int csrno,
|
||||
static RISCVException read_satp(CPURISCVState *env, int csrno,
|
||||
target_ulong *val)
|
||||
{
|
||||
if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
|
||||
if (!riscv_cpu_cfg(env)->mmu) {
|
||||
*val = 0;
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
@ -2643,7 +2640,7 @@ static RISCVException write_satp(CPURISCVState *env, int csrno,
|
||||
{
|
||||
target_ulong vm, mask;
|
||||
|
||||
if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
|
||||
if (!riscv_cpu_cfg(env)->mmu) {
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
|
@ -27,9 +27,8 @@
|
||||
static bool pmp_needed(void *opaque)
|
||||
{
|
||||
RISCVCPU *cpu = opaque;
|
||||
CPURISCVState *env = &cpu->env;
|
||||
|
||||
return riscv_feature(env, RISCV_FEATURE_PMP);
|
||||
return cpu->cfg.pmp;
|
||||
}
|
||||
|
||||
static int pmp_post_load(void *opaque, int version_id)
|
||||
@ -226,9 +225,8 @@ static const VMStateDescription vmstate_kvmtimer = {
|
||||
static bool debug_needed(void *opaque)
|
||||
{
|
||||
RISCVCPU *cpu = opaque;
|
||||
CPURISCVState *env = &cpu->env;
|
||||
|
||||
return riscv_feature(env, RISCV_FEATURE_DEBUG);
|
||||
return cpu->cfg.debug;
|
||||
}
|
||||
|
||||
static int debug_post_load(void *opaque, int version_id)
|
||||
@ -333,8 +331,8 @@ static const VMStateDescription vmstate_pmu_ctr_state = {
|
||||
|
||||
const VMStateDescription vmstate_riscv_cpu = {
|
||||
.name = "cpu",
|
||||
.version_id = 6,
|
||||
.minimum_version_id = 6,
|
||||
.version_id = 7,
|
||||
.minimum_version_id = 7,
|
||||
.post_load = riscv_cpu_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
|
||||
@ -353,7 +351,6 @@ const VMStateDescription vmstate_riscv_cpu = {
|
||||
VMSTATE_UINT32(env.misa_ext, RISCVCPU),
|
||||
VMSTATE_UINT32(env.misa_mxl_max, RISCVCPU),
|
||||
VMSTATE_UINT32(env.misa_ext_mask, RISCVCPU),
|
||||
VMSTATE_UINT32(env.features, RISCVCPU),
|
||||
VMSTATE_UINTTL(env.priv, RISCVCPU),
|
||||
VMSTATE_UINTTL(env.virt, RISCVCPU),
|
||||
VMSTATE_UINT64(env.resetvec, RISCVCPU),
|
||||
|
@ -218,7 +218,7 @@ void hmp_info_mem(Monitor *mon, const QDict *qdict)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
|
||||
if (!riscv_cpu_cfg(env)->mmu) {
|
||||
monitor_printf(mon, "S-mode MMU unavailable\n");
|
||||
return;
|
||||
}
|
||||
|
@ -195,7 +195,7 @@ target_ulong helper_mret(CPURISCVState *env)
|
||||
uint64_t mstatus = env->mstatus;
|
||||
target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
|
||||
|
||||
if (riscv_feature(env, RISCV_FEATURE_PMP) &&
|
||||
if (riscv_cpu_cfg(env)->pmp &&
|
||||
!pmp_get_num_rules(env) && (prev_priv != PRV_M)) {
|
||||
riscv_raise_exception(env, RISCV_EXCP_INST_ACCESS_FAULT, GETPC());
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ static void pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)
|
||||
if (pmp_index < MAX_RISCV_PMPS) {
|
||||
bool locked = true;
|
||||
|
||||
if (riscv_feature(env, RISCV_FEATURE_EPMP)) {
|
||||
if (riscv_cpu_cfg(env)->epmp) {
|
||||
/* mseccfg.RLB is set */
|
||||
if (MSECCFG_RLB_ISSET(env)) {
|
||||
locked = false;
|
||||
@ -239,7 +239,7 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
|
||||
{
|
||||
bool ret;
|
||||
|
||||
if (riscv_feature(env, RISCV_FEATURE_EPMP)) {
|
||||
if (riscv_cpu_cfg(env)->epmp) {
|
||||
if (MSECCFG_MMWP_ISSET(env)) {
|
||||
/*
|
||||
* The Machine Mode Whitelist Policy (mseccfg.MMWP) is set
|
||||
@ -265,7 +265,7 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
|
||||
}
|
||||
}
|
||||
|
||||
if ((!riscv_feature(env, RISCV_FEATURE_PMP)) || (mode == PRV_M)) {
|
||||
if (!riscv_cpu_cfg(env)->pmp || (mode == PRV_M)) {
|
||||
/*
|
||||
* Privileged spec v1.10 states if HW doesn't implement any PMP entry
|
||||
* or no PMP entry matches an M-Mode access, the access succeeds.
|
||||
@ -315,7 +315,7 @@ int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
if (riscv_feature(env, RISCV_FEATURE_MMU)) {
|
||||
if (riscv_cpu_cfg(env)->mmu) {
|
||||
/*
|
||||
* If size is unknown (0), assume that all bytes
|
||||
* from addr to the end of the page will be accessed.
|
||||
|
Loading…
Reference in New Issue
Block a user