extern RISCVCPUProfile *riscv_profiles[];
+/*
+ * Type large enough to hold all PRV_* fields, update CPUArchState::priv
+ * migration field if changing this type.
+ */
+typedef uint8_t privilege_mode_t;
+
/* Privileged specification version */
#define PRIV_VER_1_10_0_STR "v1.10.0"
#define PRIV_VER_1_11_0_STR "v1.11.0"
uint32_t elf_flags;
#endif
- target_ulong priv;
+ privilege_mode_t priv;
/* CSRs for execution environment configuration */
uint64_t menvcfg;
uint64_t senvcfg;
#define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */
void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(void *),
void *arg);
-void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, uint32_t priv,
+void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, privilege_mode_t priv,
int (*rmw_fn)(void *arg,
target_ulong reg,
target_ulong *val,
RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit);
#endif /* !CONFIG_USER_ONLY */
-void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv, bool virt_en);
+void riscv_cpu_set_mode(CPURISCVState *env, privilege_mode_t newpriv,
+ bool virt_en);
void riscv_ctr_add_entry(CPURISCVState *env, target_long src, target_long dst,
- enum CTRType type, target_ulong prev_priv, bool prev_virt);
+ enum CTRType type, privilege_mode_t prev_priv, bool prev_virt);
void riscv_ctr_clear(CPURISCVState *env);
void riscv_translate_init(void);
}
#if !defined(CONFIG_USER_ONLY)
-static inline int cpu_address_mode(CPURISCVState *env)
+static inline privilege_mode_t cpu_address_mode(CPURISCVState *env)
{
- int mode = env->priv;
+ privilege_mode_t mode = env->priv;
if (mode == PRV_M && get_field(env->mstatus, MSTATUS_MPRV)) {
mode = get_field(env->mstatus, MSTATUS_MPP);
return mode;
}
-static inline RISCVMXL cpu_get_xl(CPURISCVState *env, target_ulong mode)
+static inline RISCVMXL cpu_get_xl(CPURISCVState *env, privilege_mode_t mode)
{
RISCVMXL xl = env->misa_mxl;
/*
#ifdef CONFIG_USER_ONLY
return env->xl;
#else
- int mode = cpu_address_mode(env);
+ privilege_mode_t mode = cpu_address_mode(env);
return cpu_get_xl(env, mode);
#endif
* Returns true if the effective privilege mode is modified.
*/
static inline QEMU_ALWAYS_INLINE
-bool riscv_cpu_eff_priv(CPURISCVState *env, int *priv, bool *virt)
+bool riscv_cpu_eff_priv(CPURISCVState *env, privilege_mode_t *priv, bool *virt)
{
- int mode = env->priv;
+ privilege_mode_t mode = env->priv;
bool virt_enabled = false;
bool mode_modified = false;
return 0;
#else
bool virt = env->virt_enabled;
- int mode = env->priv;
+ privilege_mode_t mode = env->priv;
bool mode_modified = false;
/* All priv -> mmu_idx mapping are here */
RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env)
{
#ifndef CONFIG_USER_ONLY
- int priv_mode;
+ privilege_mode_t priv_mode;
bool virt;
riscv_cpu_eff_priv(env, &priv_mode, &virt);
RISCVPmPmm riscv_pm_get_vm_ldst_pmm(CPURISCVState *env)
{
#ifndef CONFIG_USER_ONLY
- int priv_mode;
+ privilege_mode_t priv_mode;
if (!riscv_cpu_cfg(env)->ext_ssnpm ||
get_field(env->mstatus, MSTATUS_MXR) ||
#ifndef CONFIG_USER_ONLY
int satp_mode = 0;
uint64_t satp;
- int priv_mode;
+ privilege_mode_t priv_mode;
bool virt = false;
if (!is_vm_ldst) {
env->rdtime_fn_arg = arg;
}
-void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, uint32_t priv,
+void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, privilege_mode_t priv,
int (*rmw_fn)(void *arg,
target_ulong reg,
target_ulong *val,
memset(env->ctr_data, 0x0, sizeof(env->ctr_data));
}
-static uint64_t riscv_ctr_priv_to_mask(target_ulong priv, bool virt)
+static uint64_t riscv_ctr_priv_to_mask(privilege_mode_t priv, bool virt)
{
switch (priv) {
case PRV_M:
g_assert_not_reached();
}
-static uint64_t riscv_ctr_get_control(CPURISCVState *env, target_long priv,
+static uint64_t riscv_ctr_get_control(CPURISCVState *env,
+ privilege_mode_t priv,
bool virt)
{
switch (priv) {
* and src privilege is less than target privilege. This includes the virtual
* state as well.
*/
-static bool riscv_ctr_check_xte(CPURISCVState *env, target_long src_prv,
+static bool riscv_ctr_check_xte(CPURISCVState *env,
+ privilege_mode_t src_prv,
bool src_virt)
{
- target_long tgt_prv = env->priv;
+ privilege_mode_t tgt_prv = env->priv;
bool res = true;
/*
* idx = (sctrstatus.WRPTR - entry - 1) & (depth - 1);
*/
void riscv_ctr_add_entry(CPURISCVState *env, target_long src, target_long dst,
- enum CTRType type, target_ulong src_priv, bool src_virt)
+ enum CTRType type, privilege_mode_t src_priv, bool src_virt)
{
bool tgt_virt = env->virt_enabled;
uint64_t src_mask = riscv_ctr_priv_to_mask(src_priv, src_virt);
env->sctrstatus = set_field(env->sctrstatus, SCTRSTATUS_WRPTR_MASK, head);
}
-void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv, bool virt_en)
+void riscv_cpu_set_mode(CPURISCVState *env, privilege_mode_t newpriv,
+ bool virt_en)
{
g_assert(newpriv <= PRV_M && newpriv != PRV_RESERVED);
*/
static int get_physical_address_pmp(CPURISCVState *env, int *prot, hwaddr addr,
int size, MMUAccessType access_type,
- int mode)
+ privilege_mode_t mode)
{
pmp_priv_t pmp_priv;
bool pmp_has_privs;
/* Returns 'true' if a svukte address check is needed */
static bool do_svukte_check(CPURISCVState *env, bool first_stage,
- int mode, bool virt)
+ privilege_mode_t mode, bool virt)
{
/* Svukte extension depends on Sv39. */
if (!(env_archcpu(env)->cfg.ext_svukte ||
*/
MemTxResult res;
MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
- int mode = mmuidx_priv(mmu_idx);
+ privilege_mode_t mode = mmuidx_priv(mmu_idx);
bool virt = mmuidx_2stage(mmu_idx);
bool use_background = false;
hwaddr ppn;
bool two_stage_lookup = mmuidx_2stage(mmu_idx);
bool two_stage_indirect_error = false;
int ret = TRANSLATE_FAIL;
- int mode = mmuidx_priv(mmu_idx);
+ privilege_mode_t mode = mmuidx_priv(mmu_idx);
/* default TLB page size */
hwaddr tlb_size = TARGET_PAGE_SIZE;
bool always_storeamo = (env->excp_uw2 & RISCV_UW2_ALWAYS_STORE_AMO);
bool vsmode_exc;
uint64_t s;
- int mode;
+ privilege_mode_t mode;
/*
* cs->exception is 32-bits wide unlike mcause which is XLEN-bits wide
bool smode_double_trap = false;
uint64_t hdeleg = async ? env->hideleg : env->hedeleg;
const bool prev_virt = env->virt_enabled;
- const target_ulong prev_priv = env->priv;
+ const privilege_mode_t prev_priv = env->priv;
uint64_t last_pc = env->pc;
target_ulong tval = 0;
target_ulong tinst = 0;
static RISCVException aia_smode32(CPURISCVState *env, int csrno)
{
int ret;
- int csr_priv = get_field(csrno, 0x300);
+ privilege_mode_t csr_priv = get_field(csrno, 0x300);
if (csr_priv == PRV_M && !riscv_cpu_cfg(env)->ext_smaia) {
return RISCV_EXCP_ILLEGAL_INST;
bool virt = false, isel_reserved = false;
int ret = -EINVAL;
uint8_t *iprio;
- target_ulong priv, vgein;
+ privilege_mode_t priv;
+ uint32_t vgein;
/* VS-mode CSR number passed in has already been translated */
switch (csrno) {
{
bool virt;
int ret = -EINVAL;
- target_ulong priv, vgein;
+ privilege_mode_t priv;
+ uint32_t vgein;
/* Translate CSR number for VS-mode */
csrno = aia_xlate_vs_csrno(env, csrno);
}
#if !defined(CONFIG_USER_ONLY)
- int csr_priv, effective_priv = env->priv;
+ privilege_mode_t csr_priv, effective_priv = env->priv;
if (riscv_has_ext(env, RVH) && env->priv == PRV_S &&
!env->virt_enabled) {
const unsigned regsz = riscv_cpu_is_32bit(cpu) ? 4 : 8;
#ifndef CONFIG_USER_ONLY
CPURISCVState *env = &cpu->env;
- uint64_t new_priv = ldn(env, mem_buf, regsz) & 0x3;
+ privilege_mode_t new_priv = ldn(env, mem_buf, regsz) & 0x3;
bool new_virt = 0;
if (new_priv == PRV_RESERVED) {
#define MMU_2STAGE_BIT (1 << 2)
#define MMU_IDX_SS_WRITE (1 << 3)
-static inline int mmuidx_priv(int mmu_idx)
+static inline privilege_mode_t mmuidx_priv(int mmu_idx)
{
- int ret = mmu_idx & 3;
+ privilege_mode_t ret = mmu_idx & 3;
if (ret == MMUIdx_S_SUM) {
ret = PRV_S;
}
VMSTATE_UINT32(env.misa_ext, RISCVCPU),
VMSTATE_UNUSED(4),
VMSTATE_UINT32(env.misa_ext_mask, RISCVCPU),
- VMSTATE_UINTTL(env.priv, RISCVCPU),
+ VMSTATE_UINT8(env.priv, RISCVCPU),
VMSTATE_BOOL(env.virt_enabled, RISCVCPU),
VMSTATE_UINT64(env.resetvec, RISCVCPU),
VMSTATE_UINT64(env.mhartid, RISCVCPU),
target_ulong helper_sret(CPURISCVState *env)
{
uint64_t mstatus;
- target_ulong prev_priv, prev_virt = env->virt_enabled;
- const target_ulong src_priv = env->priv;
+ privilege_mode_t prev_priv;
+ bool prev_virt = env->virt_enabled;
+ const privilege_mode_t src_priv = env->priv;
const bool src_virt = env->virt_enabled;
if (!(env->priv >= PRV_S)) {
/* We support Hypervisor extensions and virtulisation is disabled */
target_ulong hstatus = env->hstatus;
- prev_virt = get_field(hstatus, HSTATUS_SPV);
+ prev_virt = !!(get_field(hstatus, HSTATUS_SPV));
hstatus = set_field(hstatus, HSTATUS_SPV, 0);
env->hstatus = hstatus;
}
static void check_ret_from_m_mode(CPURISCVState *env, target_ulong retpc,
- target_ulong prev_priv,
+ privilege_mode_t prev_priv,
uintptr_t ra)
{
if (!(env->priv >= PRV_M)) {
}
}
static target_ulong ssdbltrp_mxret(CPURISCVState *env, target_ulong mstatus,
- target_ulong prev_priv,
- target_ulong prev_virt)
+ privilege_mode_t prev_priv,
+ bool prev_virt)
{
/* If returning to U, VS or VU, sstatus.sdt = 0 */
if (prev_priv == PRV_U || (prev_virt &&
{
target_ulong retpc = env->mepc & get_xepc_mask(env);
uint64_t mstatus = env->mstatus;
- target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
+ privilege_mode_t prev_priv = get_field(mstatus, MSTATUS_MPP);
uintptr_t ra = GETPC();
check_ret_from_m_mode(env, retpc, prev_priv, ra);
- target_ulong prev_virt = get_field(env->mstatus, MSTATUS_MPV) &&
- (prev_priv != PRV_M);
+ bool prev_virt = !!(get_field(env->mstatus, MSTATUS_MPV) &&
+ (prev_priv != PRV_M));
mstatus = set_field(mstatus, MSTATUS_MIE,
get_field(mstatus, MSTATUS_MPIE));
mstatus = set_field(mstatus, MSTATUS_MPIE, 1);
target_ulong helper_mnret(CPURISCVState *env)
{
target_ulong retpc = env->mnepc;
- target_ulong prev_priv = get_field(env->mnstatus, MNSTATUS_MNPP);
- target_ulong prev_virt;
+ privilege_mode_t prev_priv = get_field(env->mnstatus, MNSTATUS_MNPP);
+ bool prev_virt;
uintptr_t ra = GETPC();
check_ret_from_m_mode(env, retpc, prev_priv, ra);
- prev_virt = get_field(env->mnstatus, MNSTATUS_MNPV) &&
- (prev_priv != PRV_M);
+ prev_virt = !!(get_field(env->mnstatus, MNSTATUS_MNPV) &&
+ (prev_priv != PRV_M));
env->mnstatus = set_field(env->mnstatus, MNSTATUS_NMIE, true);
/*
* new priv and new virt values are passed in as arguments.
*/
static void riscv_pmu_icount_update_priv(CPURISCVState *env,
- target_ulong newpriv, bool new_virt)
+ privilege_mode_t newpriv,
+ bool new_virt)
{
uint64_t *snapshot_prev, *snapshot_new;
uint64_t current_icount;
}
static void riscv_pmu_cycle_update_priv(CPURISCVState *env,
- target_ulong newpriv, bool new_virt)
+ privilege_mode_t newpriv,
+ bool new_virt)
{
uint64_t *snapshot_prev, *snapshot_new;
uint64_t current_ticks;
counter_arr[env->priv] += delta;
}
-void riscv_pmu_update_fixed_ctrs(CPURISCVState *env, target_ulong newpriv,
+void riscv_pmu_update_fixed_ctrs(CPURISCVState *env,
+ privilege_mode_t newpriv,
bool new_virt)
{
riscv_pmu_cycle_update_priv(env, newpriv, new_virt);
void riscv_pmu_generate_fdt_node(void *fdt, uint32_t cmask, char *pmu_name);
int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t value,
uint32_t ctr_idx);
-void riscv_pmu_update_fixed_ctrs(CPURISCVState *env, target_ulong newpriv,
+void riscv_pmu_update_fixed_ctrs(CPURISCVState *env, privilege_mode_t newpriv,
bool new_virt);
RISCVException riscv_pmu_read_ctr(CPURISCVState *env, target_ulong *val,
bool upper_half, uint32_t ctr_idx);
RISCVExtStatus mstatus_fs;
RISCVExtStatus mstatus_vs;
uint32_t mem_idx;
- uint32_t priv;
+ privilege_mode_t priv;
/*
* Remember the rounding mode encoded in the previous fp instruction,
* which we have already installed into env->fp_status. Or -1 for