target/riscv: Remove the HS_TWO_STAGE flag
The HS_TWO_STAGE flag is no longer required as the MMU index contains the information if we are performing a two stage access. Signed-off-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: f514b128b1ff0fb41c85f914cee18f905007a922.1604464950.git.alistair.francis@wdc.com
This commit is contained in:
parent
3e5979046f
commit
1c1c060aa8
@ -323,8 +323,7 @@ bool riscv_cpu_virt_enabled(CPURISCVState *env);
|
||||
void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
|
||||
bool riscv_cpu_force_hs_excep_enabled(CPURISCVState *env);
|
||||
void riscv_cpu_set_force_hs_excep(CPURISCVState *env, bool enable);
|
||||
bool riscv_cpu_two_stage_lookup(CPURISCVState *env);
|
||||
void riscv_cpu_set_two_stage_lookup(CPURISCVState *env, bool enable);
|
||||
bool riscv_cpu_two_stage_lookup(int mmu_idx);
|
||||
int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
|
||||
hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||
void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
|
||||
|
@ -469,7 +469,6 @@
|
||||
* page table fault.
|
||||
*/
|
||||
#define FORCE_HS_EXCEP 2
|
||||
#define HS_TWO_STAGE 4
|
||||
|
||||
/* RV32 satp CSR field masks */
|
||||
#define SATP32_MODE 0x80000000
|
||||
|
@ -207,22 +207,9 @@ void riscv_cpu_set_force_hs_excep(CPURISCVState *env, bool enable)
|
||||
env->virt = set_field(env->virt, FORCE_HS_EXCEP, enable);
|
||||
}
|
||||
|
||||
bool riscv_cpu_two_stage_lookup(CPURISCVState *env)
|
||||
bool riscv_cpu_two_stage_lookup(int mmu_idx)
|
||||
{
|
||||
if (!riscv_has_ext(env, RVH)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return get_field(env->virt, HS_TWO_STAGE);
|
||||
}
|
||||
|
||||
void riscv_cpu_set_two_stage_lookup(CPURISCVState *env, bool enable)
|
||||
{
|
||||
if (!riscv_has_ext(env, RVH)) {
|
||||
return;
|
||||
}
|
||||
|
||||
env->virt = set_field(env->virt, HS_TWO_STAGE, enable);
|
||||
return mmu_idx & TB_FLAGS_PRIV_HYP_ACCESS_MASK;
|
||||
}
|
||||
|
||||
int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts)
|
||||
@ -333,7 +320,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
|
||||
* was called. Background registers will be used if the guest has
|
||||
* forced a two stage translation to be on (in HS or M mode).
|
||||
*/
|
||||
if (riscv_cpu_two_stage_lookup(env) && access_type != MMU_INST_FETCH) {
|
||||
if (!riscv_cpu_virt_enabled(env) && riscv_cpu_two_stage_lookup(mmu_idx)) {
|
||||
use_background = true;
|
||||
}
|
||||
|
||||
@ -572,7 +559,7 @@ restart:
|
||||
|
||||
static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
|
||||
MMUAccessType access_type, bool pmp_violation,
|
||||
bool first_stage)
|
||||
bool first_stage, bool two_stage)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
int page_fault_exceptions;
|
||||
@ -595,8 +582,7 @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
|
||||
}
|
||||
break;
|
||||
case MMU_DATA_LOAD:
|
||||
if ((riscv_cpu_virt_enabled(env) || riscv_cpu_two_stage_lookup(env)) &&
|
||||
!first_stage) {
|
||||
if (two_stage && !first_stage) {
|
||||
cs->exception_index = RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT;
|
||||
} else {
|
||||
cs->exception_index = page_fault_exceptions ?
|
||||
@ -604,8 +590,7 @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
|
||||
}
|
||||
break;
|
||||
case MMU_DATA_STORE:
|
||||
if ((riscv_cpu_virt_enabled(env) || riscv_cpu_two_stage_lookup(env)) &&
|
||||
!first_stage) {
|
||||
if (two_stage && !first_stage) {
|
||||
cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT;
|
||||
} else {
|
||||
cs->exception_index = page_fault_exceptions ?
|
||||
@ -696,6 +681,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
||||
int prot, prot2;
|
||||
bool pmp_violation = false;
|
||||
bool first_stage_error = true;
|
||||
bool two_stage_lookup = false;
|
||||
int ret = TRANSLATE_FAIL;
|
||||
int mode = mmu_idx;
|
||||
target_ulong tlb_size = 0;
|
||||
@ -715,11 +701,12 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
||||
access_type != MMU_INST_FETCH &&
|
||||
get_field(env->mstatus, MSTATUS_MPRV) &&
|
||||
get_field(env->mstatus, MSTATUS_MPV)) {
|
||||
riscv_cpu_set_two_stage_lookup(env, true);
|
||||
two_stage_lookup = true;
|
||||
}
|
||||
|
||||
if (riscv_cpu_virt_enabled(env) ||
|
||||
(riscv_cpu_two_stage_lookup(env) && access_type != MMU_INST_FETCH)) {
|
||||
((riscv_cpu_two_stage_lookup(mmu_idx) || two_stage_lookup) &&
|
||||
access_type != MMU_INST_FETCH)) {
|
||||
/* Two stage lookup */
|
||||
ret = get_physical_address(env, &pa, &prot, address,
|
||||
&env->guest_phys_fault_addr, access_type,
|
||||
@ -782,14 +769,6 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
||||
__func__, address, ret, pa, prot);
|
||||
}
|
||||
|
||||
/* We did the two stage lookup based on MPRV, unset the lookup */
|
||||
if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
|
||||
access_type != MMU_INST_FETCH &&
|
||||
get_field(env->mstatus, MSTATUS_MPRV) &&
|
||||
get_field(env->mstatus, MSTATUS_MPV)) {
|
||||
riscv_cpu_set_two_stage_lookup(env, false);
|
||||
}
|
||||
|
||||
if (riscv_feature(env, RISCV_FEATURE_PMP) &&
|
||||
(ret == TRANSLATE_SUCCESS) &&
|
||||
!pmp_hart_has_privs(env, pa, size, 1 << access_type, mode)) {
|
||||
@ -811,7 +790,10 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
||||
} else if (probe) {
|
||||
return false;
|
||||
} else {
|
||||
raise_mmu_exception(env, address, access_type, pmp_violation, first_stage_error);
|
||||
raise_mmu_exception(env, address, access_type, pmp_violation,
|
||||
first_stage_error,
|
||||
riscv_cpu_virt_enabled(env) ||
|
||||
riscv_cpu_two_stage_lookup(mmu_idx));
|
||||
riscv_raise_exception(env, cs->exception_index, retaddr);
|
||||
}
|
||||
|
||||
@ -915,9 +897,16 @@ void riscv_cpu_do_interrupt(CPUState *cs)
|
||||
/* handle the trap in S-mode */
|
||||
if (riscv_has_ext(env, RVH)) {
|
||||
target_ulong hdeleg = async ? env->hideleg : env->hedeleg;
|
||||
bool two_stage_lookup = false;
|
||||
|
||||
if ((riscv_cpu_virt_enabled(env) ||
|
||||
riscv_cpu_two_stage_lookup(env)) && write_tval) {
|
||||
if (env->priv == PRV_M ||
|
||||
(env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
|
||||
(env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
|
||||
get_field(env->hstatus, HSTATUS_HU))) {
|
||||
two_stage_lookup = true;
|
||||
}
|
||||
|
||||
if ((riscv_cpu_virt_enabled(env) || two_stage_lookup) && write_tval) {
|
||||
/*
|
||||
* If we are writing a guest virtual address to stval, set
|
||||
* this to 1. If we are trapping to VS we will set this to 0
|
||||
@ -955,11 +944,10 @@ void riscv_cpu_do_interrupt(CPUState *cs)
|
||||
riscv_cpu_set_force_hs_excep(env, 0);
|
||||
} else {
|
||||
/* Trap into HS mode */
|
||||
if (!riscv_cpu_two_stage_lookup(env)) {
|
||||
if (!two_stage_lookup) {
|
||||
env->hstatus = set_field(env->hstatus, HSTATUS_SPV,
|
||||
riscv_cpu_virt_enabled(env));
|
||||
}
|
||||
riscv_cpu_set_two_stage_lookup(env, false);
|
||||
htval = env->guest_phys_fault_addr;
|
||||
}
|
||||
}
|
||||
|
@ -237,8 +237,6 @@ target_ulong helper_hyp_load(CPURISCVState *env, target_ulong address,
|
||||
target_ulong pte;
|
||||
int mmu_idx = cpu_mmu_index(env, false) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
|
||||
|
||||
riscv_cpu_set_two_stage_lookup(env, true);
|
||||
|
||||
switch (memop) {
|
||||
case MO_SB:
|
||||
pte = cpu_ldsb_mmuidx_ra(env, address, mmu_idx, GETPC());
|
||||
@ -265,8 +263,6 @@ target_ulong helper_hyp_load(CPURISCVState *env, target_ulong address,
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
riscv_cpu_set_two_stage_lookup(env, false);
|
||||
|
||||
return pte;
|
||||
}
|
||||
|
||||
@ -287,8 +283,6 @@ void helper_hyp_store(CPURISCVState *env, target_ulong address,
|
||||
get_field(env->hstatus, HSTATUS_HU))) {
|
||||
int mmu_idx = cpu_mmu_index(env, false) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
|
||||
|
||||
riscv_cpu_set_two_stage_lookup(env, true);
|
||||
|
||||
switch (memop) {
|
||||
case MO_SB:
|
||||
case MO_UB:
|
||||
@ -309,8 +303,6 @@ void helper_hyp_store(CPURISCVState *env, target_ulong address,
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
riscv_cpu_set_two_stage_lookup(env, false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -331,8 +323,6 @@ target_ulong helper_hyp_x_load(CPURISCVState *env, target_ulong address,
|
||||
target_ulong pte;
|
||||
int mmu_idx = cpu_mmu_index(env, false) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
|
||||
|
||||
riscv_cpu_set_two_stage_lookup(env, true);
|
||||
|
||||
switch (memop) {
|
||||
case MO_TEUW:
|
||||
pte = cpu_lduw_mmuidx_ra(env, address, mmu_idx, GETPC());
|
||||
@ -344,8 +334,6 @@ target_ulong helper_hyp_x_load(CPURISCVState *env, target_ulong address,
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
riscv_cpu_set_two_stage_lookup(env, false);
|
||||
|
||||
return pte;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user