mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-03 16:35:46 +00:00
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. Backports 1c1c060aa866986ef8b7eb334abbb8c104a46e5c
This commit is contained in:
parent
e5a9b8fc17
commit
bd81c057ed
|
@ -7324,7 +7324,6 @@ riscv_symbols = (
|
||||||
'riscv_cpu_set_force_hs_excep',
|
'riscv_cpu_set_force_hs_excep',
|
||||||
'riscv_cpu_set_mode',
|
'riscv_cpu_set_mode',
|
||||||
'riscv_cpu_set_rdtime_fn',
|
'riscv_cpu_set_rdtime_fn',
|
||||||
'riscv_cpu_set_two_stage_lookup',
|
|
||||||
'riscv_cpu_set_virt_enabled',
|
'riscv_cpu_set_virt_enabled',
|
||||||
'riscv_cpu_swap_hypervisor_regs',
|
'riscv_cpu_swap_hypervisor_regs',
|
||||||
'riscv_cpu_tlb_fill',
|
'riscv_cpu_tlb_fill',
|
||||||
|
|
|
@ -4760,7 +4760,6 @@
|
||||||
#define riscv_cpu_set_force_hs_excep riscv_cpu_set_force_hs_excep_riscv32
|
#define riscv_cpu_set_force_hs_excep riscv_cpu_set_force_hs_excep_riscv32
|
||||||
#define riscv_cpu_set_mode riscv_cpu_set_mode_riscv32
|
#define riscv_cpu_set_mode riscv_cpu_set_mode_riscv32
|
||||||
#define riscv_cpu_set_rdtime_fn riscv_cpu_set_rdtime_fn_riscv32
|
#define riscv_cpu_set_rdtime_fn riscv_cpu_set_rdtime_fn_riscv32
|
||||||
#define riscv_cpu_set_two_stage_lookup riscv_cpu_set_two_stage_lookup_riscv32
|
|
||||||
#define riscv_cpu_set_virt_enabled riscv_cpu_set_virt_enabled_riscv32
|
#define riscv_cpu_set_virt_enabled riscv_cpu_set_virt_enabled_riscv32
|
||||||
#define riscv_cpu_swap_hypervisor_regs riscv_cpu_swap_hypervisor_regs_riscv32
|
#define riscv_cpu_swap_hypervisor_regs riscv_cpu_swap_hypervisor_regs_riscv32
|
||||||
#define riscv_cpu_tlb_fill riscv_cpu_tlb_fill_riscv32
|
#define riscv_cpu_tlb_fill riscv_cpu_tlb_fill_riscv32
|
||||||
|
|
|
@ -4760,7 +4760,6 @@
|
||||||
#define riscv_cpu_set_force_hs_excep riscv_cpu_set_force_hs_excep_riscv64
|
#define riscv_cpu_set_force_hs_excep riscv_cpu_set_force_hs_excep_riscv64
|
||||||
#define riscv_cpu_set_mode riscv_cpu_set_mode_riscv64
|
#define riscv_cpu_set_mode riscv_cpu_set_mode_riscv64
|
||||||
#define riscv_cpu_set_rdtime_fn riscv_cpu_set_rdtime_fn_riscv64
|
#define riscv_cpu_set_rdtime_fn riscv_cpu_set_rdtime_fn_riscv64
|
||||||
#define riscv_cpu_set_two_stage_lookup riscv_cpu_set_two_stage_lookup_riscv64
|
|
||||||
#define riscv_cpu_set_virt_enabled riscv_cpu_set_virt_enabled_riscv64
|
#define riscv_cpu_set_virt_enabled riscv_cpu_set_virt_enabled_riscv64
|
||||||
#define riscv_cpu_swap_hypervisor_regs riscv_cpu_swap_hypervisor_regs_riscv64
|
#define riscv_cpu_swap_hypervisor_regs riscv_cpu_swap_hypervisor_regs_riscv64
|
||||||
#define riscv_cpu_tlb_fill riscv_cpu_tlb_fill_riscv64
|
#define riscv_cpu_tlb_fill riscv_cpu_tlb_fill_riscv64
|
||||||
|
|
|
@ -328,8 +328,7 @@ bool riscv_cpu_virt_enabled(CPURISCVState *env);
|
||||||
void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
|
void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
|
||||||
bool riscv_cpu_force_hs_excep_enabled(CPURISCVState *env);
|
bool riscv_cpu_force_hs_excep_enabled(CPURISCVState *env);
|
||||||
void riscv_cpu_set_force_hs_excep(CPURISCVState *env, bool enable);
|
void riscv_cpu_set_force_hs_excep(CPURISCVState *env, bool enable);
|
||||||
bool riscv_cpu_two_stage_lookup(CPURISCVState *env);
|
bool riscv_cpu_two_stage_lookup(int mmu_idx);
|
||||||
void riscv_cpu_set_two_stage_lookup(CPURISCVState *env, bool enable);
|
|
||||||
int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
|
int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
|
||||||
hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||||
void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
|
void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
|
||||||
|
|
|
@ -469,7 +469,6 @@
|
||||||
* page table fault.
|
* page table fault.
|
||||||
*/
|
*/
|
||||||
#define FORCE_HS_EXCEP 2
|
#define FORCE_HS_EXCEP 2
|
||||||
#define HS_TWO_STAGE 4
|
|
||||||
|
|
||||||
/* RV32 satp CSR field masks */
|
/* RV32 satp CSR field masks */
|
||||||
#define SATP32_MODE 0x80000000
|
#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);
|
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 mmu_idx & TB_FLAGS_PRIV_HYP_ACCESS_MASK;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts)
|
int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts)
|
||||||
|
@ -327,7 +314,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
|
||||||
* was called. Background registers will be used if the guest has
|
* was called. Background registers will be used if the guest has
|
||||||
* forced a two stage translation to be on (in HS or M mode).
|
* 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;
|
use_background = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -566,7 +553,7 @@ restart:
|
||||||
|
|
||||||
static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
|
static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
|
||||||
MMUAccessType access_type, bool pmp_violation,
|
MMUAccessType access_type, bool pmp_violation,
|
||||||
bool first_stage)
|
bool first_stage, bool two_stage)
|
||||||
{
|
{
|
||||||
CPUState *cs = env_cpu(env);
|
CPUState *cs = env_cpu(env);
|
||||||
int page_fault_exceptions;
|
int page_fault_exceptions;
|
||||||
|
@ -589,8 +576,7 @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MMU_DATA_LOAD:
|
case MMU_DATA_LOAD:
|
||||||
if ((riscv_cpu_virt_enabled(env) || riscv_cpu_two_stage_lookup(env)) &&
|
if (two_stage && !first_stage) {
|
||||||
!first_stage) {
|
|
||||||
cs->exception_index = RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT;
|
cs->exception_index = RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT;
|
||||||
} else {
|
} else {
|
||||||
cs->exception_index = page_fault_exceptions ?
|
cs->exception_index = page_fault_exceptions ?
|
||||||
|
@ -598,8 +584,7 @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MMU_DATA_STORE:
|
case MMU_DATA_STORE:
|
||||||
if ((riscv_cpu_virt_enabled(env) || riscv_cpu_two_stage_lookup(env)) &&
|
if (two_stage && !first_stage) {
|
||||||
!first_stage) {
|
|
||||||
cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT;
|
cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT;
|
||||||
} else {
|
} else {
|
||||||
cs->exception_index = page_fault_exceptions ?
|
cs->exception_index = page_fault_exceptions ?
|
||||||
|
@ -687,6 +672,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
||||||
int prot, prot2;
|
int prot, prot2;
|
||||||
bool pmp_violation = false;
|
bool pmp_violation = false;
|
||||||
bool first_stage_error = true;
|
bool first_stage_error = true;
|
||||||
|
bool two_stage_lookup = false;
|
||||||
int ret = TRANSLATE_FAIL;
|
int ret = TRANSLATE_FAIL;
|
||||||
int mode = mmu_idx;
|
int mode = mmu_idx;
|
||||||
target_ulong tlb_size = 0;
|
target_ulong tlb_size = 0;
|
||||||
|
@ -706,11 +692,12 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
||||||
access_type != MMU_INST_FETCH &&
|
access_type != MMU_INST_FETCH &&
|
||||||
get_field(env->mstatus, MSTATUS_MPRV) &&
|
get_field(env->mstatus, MSTATUS_MPRV) &&
|
||||||
get_field(env->mstatus, MSTATUS_MPV)) {
|
get_field(env->mstatus, MSTATUS_MPV)) {
|
||||||
riscv_cpu_set_two_stage_lookup(env, true);
|
two_stage_lookup = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (riscv_cpu_virt_enabled(env) ||
|
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 */
|
/* Two stage lookup */
|
||||||
ret = get_physical_address(env, &pa, &prot, address,
|
ret = get_physical_address(env, &pa, &prot, address,
|
||||||
&env->guest_phys_fault_addr, access_type,
|
&env->guest_phys_fault_addr, access_type,
|
||||||
|
@ -773,14 +760,6 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
||||||
__func__, address, ret, pa, prot);
|
__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) &&
|
if (riscv_feature(env, RISCV_FEATURE_PMP) &&
|
||||||
(ret == TRANSLATE_SUCCESS) &&
|
(ret == TRANSLATE_SUCCESS) &&
|
||||||
!pmp_hart_has_privs(env, pa, size, 1 << access_type, mode)) {
|
!pmp_hart_has_privs(env, pa, size, 1 << access_type, mode)) {
|
||||||
|
@ -802,7 +781,10 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
||||||
} else if (probe) {
|
} else if (probe) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} 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);
|
riscv_raise_exception(env, cs->exception_index, retaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -902,9 +884,16 @@ void riscv_cpu_do_interrupt(CPUState *cs)
|
||||||
/* handle the trap in S-mode */
|
/* handle the trap in S-mode */
|
||||||
if (riscv_has_ext(env, RVH)) {
|
if (riscv_has_ext(env, RVH)) {
|
||||||
target_ulong hdeleg = async ? env->hideleg : env->hedeleg;
|
target_ulong hdeleg = async ? env->hideleg : env->hedeleg;
|
||||||
|
bool two_stage_lookup = false;
|
||||||
|
|
||||||
if ((riscv_cpu_virt_enabled(env) ||
|
if (env->priv == PRV_M ||
|
||||||
riscv_cpu_two_stage_lookup(env)) && write_tval) {
|
(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
|
* 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
|
* this to 1. If we are trapping to VS we will set this to 0
|
||||||
|
@ -942,11 +931,10 @@ void riscv_cpu_do_interrupt(CPUState *cs)
|
||||||
riscv_cpu_set_force_hs_excep(env, 0);
|
riscv_cpu_set_force_hs_excep(env, 0);
|
||||||
} else {
|
} else {
|
||||||
/* Trap into HS mode */
|
/* Trap into HS mode */
|
||||||
if (!riscv_cpu_two_stage_lookup(env)) {
|
if (!two_stage_lookup) {
|
||||||
env->hstatus = set_field(env->hstatus, HSTATUS_SPV,
|
env->hstatus = set_field(env->hstatus, HSTATUS_SPV,
|
||||||
riscv_cpu_virt_enabled(env));
|
riscv_cpu_virt_enabled(env));
|
||||||
}
|
}
|
||||||
riscv_cpu_set_two_stage_lookup(env, false);
|
|
||||||
htval = env->guest_phys_fault_addr;
|
htval = env->guest_phys_fault_addr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,8 +237,6 @@ target_ulong helper_hyp_load(CPURISCVState *env, target_ulong address,
|
||||||
target_ulong pte;
|
target_ulong pte;
|
||||||
int mmu_idx = cpu_mmu_index(env, false) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
|
int mmu_idx = cpu_mmu_index(env, false) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
|
||||||
|
|
||||||
riscv_cpu_set_two_stage_lookup(env, true);
|
|
||||||
|
|
||||||
switch (memop) {
|
switch (memop) {
|
||||||
case MO_SB:
|
case MO_SB:
|
||||||
pte = cpu_ldsb_mmuidx_ra(env, address, mmu_idx, GETPC());
|
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();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
riscv_cpu_set_two_stage_lookup(env, false);
|
|
||||||
|
|
||||||
return pte;
|
return pte;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,7 +282,6 @@ void helper_hyp_store(CPURISCVState *env, target_ulong address,
|
||||||
(env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
|
(env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
|
||||||
get_field(env->hstatus, HSTATUS_HU))) {
|
get_field(env->hstatus, HSTATUS_HU))) {
|
||||||
int mmu_idx = cpu_mmu_index(env, false) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
|
int mmu_idx = cpu_mmu_index(env, false) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
|
||||||
riscv_cpu_set_two_stage_lookup(env, true);
|
|
||||||
|
|
||||||
switch (memop) {
|
switch (memop) {
|
||||||
case MO_SB:
|
case MO_SB:
|
||||||
|
@ -308,8 +303,6 @@ void helper_hyp_store(CPURISCVState *env, target_ulong address,
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
riscv_cpu_set_two_stage_lookup(env, false);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,8 +323,6 @@ target_ulong helper_hyp_x_load(CPURISCVState *env, target_ulong address,
|
||||||
target_ulong pte;
|
target_ulong pte;
|
||||||
int mmu_idx = cpu_mmu_index(env, false) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
|
int mmu_idx = cpu_mmu_index(env, false) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
|
||||||
|
|
||||||
riscv_cpu_set_two_stage_lookup(env, true);
|
|
||||||
|
|
||||||
switch (memop) {
|
switch (memop) {
|
||||||
case MO_TEUW:
|
case MO_TEUW:
|
||||||
pte = cpu_lduw_mmuidx_ra(env, address, mmu_idx, GETPC());
|
pte = cpu_lduw_mmuidx_ra(env, address, mmu_idx, GETPC());
|
||||||
|
@ -343,8 +334,6 @@ target_ulong helper_hyp_x_load(CPURISCVState *env, target_ulong address,
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
riscv_cpu_set_two_stage_lookup(env, false);
|
|
||||||
|
|
||||||
return pte;
|
return pte;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue