target/riscv: Allow specifying MMU stage
Signed-off-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com> Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
This commit is contained in:
parent
ae84dd0ab7
commit
1448689c7b
@ -277,10 +277,19 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
|
||||
*
|
||||
* Adapted from Spike's mmu_t::translate and mmu_t::walk
|
||||
*
|
||||
* @env: CPURISCVState
|
||||
* @physical: This will be set to the calculated physical address
|
||||
* @prot: The returned protection attributes
|
||||
* @addr: The virtual address to be translated
|
||||
* @access_type: The type of MMU access
|
||||
* @mmu_idx: Indicates current privilege level
|
||||
* @first_stage: Are we in first stage translation?
|
||||
* Second stage is used for hypervisor guest translation
|
||||
*/
|
||||
static int get_physical_address(CPURISCVState *env, hwaddr *physical,
|
||||
int *prot, target_ulong addr,
|
||||
int access_type, int mmu_idx)
|
||||
int access_type, int mmu_idx,
|
||||
bool first_stage)
|
||||
{
|
||||
/* NOTE: the env->pc value visible here will not be
|
||||
* correct, but the value visible to the exception handler
|
||||
@ -485,13 +494,21 @@ restart:
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
int page_fault_exceptions =
|
||||
(env->priv_ver >= PRIV_VERSION_1_10_0) &&
|
||||
get_field(env->satp, SATP_MODE) != VM_1_10_MBARE &&
|
||||
!pmp_violation;
|
||||
int page_fault_exceptions;
|
||||
if (first_stage) {
|
||||
page_fault_exceptions =
|
||||
(env->priv_ver >= PRIV_VERSION_1_10_0) &&
|
||||
get_field(env->satp, SATP_MODE) != VM_1_10_MBARE &&
|
||||
!pmp_violation;
|
||||
} else {
|
||||
page_fault_exceptions =
|
||||
get_field(env->hgatp, HGATP_MODE) != VM_1_10_MBARE &&
|
||||
!pmp_violation;
|
||||
}
|
||||
switch (access_type) {
|
||||
case MMU_INST_FETCH:
|
||||
cs->exception_index = page_fault_exceptions ?
|
||||
@ -518,7 +535,8 @@ hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||
int prot;
|
||||
int mmu_idx = cpu_mmu_index(&cpu->env, false);
|
||||
|
||||
if (get_physical_address(&cpu->env, &phys_addr, &prot, addr, 0, mmu_idx)) {
|
||||
if (get_physical_address(&cpu->env, &phys_addr, &prot, addr, 0, mmu_idx,
|
||||
true)) {
|
||||
return -1;
|
||||
}
|
||||
return phys_addr;
|
||||
@ -583,7 +601,8 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
||||
qemu_log_mask(CPU_LOG_MMU, "%s ad %" VADDR_PRIx " rw %d mmu_idx %d\n",
|
||||
__func__, address, access_type, mmu_idx);
|
||||
|
||||
ret = get_physical_address(env, &pa, &prot, address, access_type, mmu_idx);
|
||||
ret = get_physical_address(env, &pa, &prot, address, access_type, mmu_idx,
|
||||
true);
|
||||
|
||||
if (mode == PRV_M && access_type != MMU_INST_FETCH) {
|
||||
if (get_field(env->mstatus, MSTATUS_MPRV)) {
|
||||
@ -610,7 +629,7 @@ 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);
|
||||
raise_mmu_exception(env, address, access_type, pmp_violation, true);
|
||||
riscv_raise_exception(env, cs->exception_index, retaddr);
|
||||
}
|
||||
#else
|
||||
|
Loading…
Reference in New Issue
Block a user