mirror of https://gitlab.com/qemu-project/qemu
target-mips: split code raising MMU exception in a separate function
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
0ae430454c
commit
1147e18994
|
@ -201,58 +201,12 @@ static int get_physical_address (CPUState *env, target_phys_addr_t *physical,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
|
static void raise_mmu_exception(CPUState *env, target_ulong address,
|
||||||
|
int rw, int tlb_error)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
return addr;
|
|
||||||
#else
|
|
||||||
target_phys_addr_t phys_addr;
|
|
||||||
int prot;
|
|
||||||
|
|
||||||
if (get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT) != 0)
|
|
||||||
return -1;
|
|
||||||
return phys_addr;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
|
|
||||||
int mmu_idx, int is_softmmu)
|
|
||||||
{
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
|
||||||
target_phys_addr_t physical;
|
|
||||||
int prot;
|
|
||||||
#endif
|
|
||||||
int exception = 0, error_code = 0;
|
int exception = 0, error_code = 0;
|
||||||
int access_type;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
#if 0
|
switch (tlb_error) {
|
||||||
log_cpu_state(env, 0);
|
|
||||||
#endif
|
|
||||||
qemu_log("%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d mmu_idx %d smmu %d\n",
|
|
||||||
__func__, env->active_tc.PC, address, rw, mmu_idx, is_softmmu);
|
|
||||||
|
|
||||||
rw &= 1;
|
|
||||||
|
|
||||||
/* data access */
|
|
||||||
/* XXX: put correct access by using cpu_restore_state()
|
|
||||||
correctly */
|
|
||||||
access_type = ACCESS_INT;
|
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
ret = TLBRET_NOMATCH;
|
|
||||||
#else
|
|
||||||
ret = get_physical_address(env, &physical, &prot,
|
|
||||||
address, rw, access_type);
|
|
||||||
qemu_log("%s address=" TARGET_FMT_lx " ret %d physical " TARGET_FMT_plx " prot %d\n",
|
|
||||||
__func__, address, ret, physical, prot);
|
|
||||||
if (ret == TLBRET_MATCH) {
|
|
||||||
ret = tlb_set_page(env, address & TARGET_PAGE_MASK,
|
|
||||||
physical & TARGET_PAGE_MASK, prot,
|
|
||||||
mmu_idx, is_softmmu);
|
|
||||||
} else if (ret < 0)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
switch (ret) {
|
|
||||||
default:
|
default:
|
||||||
case TLBRET_BADADDR:
|
case TLBRET_BADADDR:
|
||||||
/* Reference to kernel address from user mode or supervisor mode */
|
/* Reference to kernel address from user mode or supervisor mode */
|
||||||
|
@ -297,6 +251,59 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
|
||||||
#endif
|
#endif
|
||||||
env->exception_index = exception;
|
env->exception_index = exception;
|
||||||
env->error_code = error_code;
|
env->error_code = error_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
|
||||||
|
{
|
||||||
|
#if defined(CONFIG_USER_ONLY)
|
||||||
|
return addr;
|
||||||
|
#else
|
||||||
|
target_phys_addr_t phys_addr;
|
||||||
|
int prot;
|
||||||
|
|
||||||
|
if (get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT) != 0)
|
||||||
|
return -1;
|
||||||
|
return phys_addr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
|
||||||
|
int mmu_idx, int is_softmmu)
|
||||||
|
{
|
||||||
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
|
target_phys_addr_t physical;
|
||||||
|
int prot;
|
||||||
|
#endif
|
||||||
|
int access_type;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
log_cpu_state(env, 0);
|
||||||
|
#endif
|
||||||
|
qemu_log("%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d mmu_idx %d smmu %d\n",
|
||||||
|
__func__, env->active_tc.PC, address, rw, mmu_idx, is_softmmu);
|
||||||
|
|
||||||
|
rw &= 1;
|
||||||
|
|
||||||
|
/* data access */
|
||||||
|
/* XXX: put correct access by using cpu_restore_state()
|
||||||
|
correctly */
|
||||||
|
access_type = ACCESS_INT;
|
||||||
|
#if defined(CONFIG_USER_ONLY)
|
||||||
|
ret = TLBRET_NOMATCH;
|
||||||
|
#else
|
||||||
|
ret = get_physical_address(env, &physical, &prot,
|
||||||
|
address, rw, access_type);
|
||||||
|
qemu_log("%s address=" TARGET_FMT_lx " ret %d physical " TARGET_FMT_plx " prot %d\n",
|
||||||
|
__func__, address, ret, physical, prot);
|
||||||
|
if (ret == TLBRET_MATCH) {
|
||||||
|
ret = tlb_set_page(env, address & TARGET_PAGE_MASK,
|
||||||
|
physical & TARGET_PAGE_MASK, prot,
|
||||||
|
mmu_idx, is_softmmu);
|
||||||
|
} else if (ret < 0)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
raise_mmu_exception(env, address, rw, ret);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue