diff options
61 files changed, 238 insertions, 151 deletions
diff --git a/include/qom/cpu.h b/include/qom/cpu.h index f5b0d7a8e1..5af434dde6 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -83,6 +83,7 @@ struct TranslationBlock; * @set_pc: Callback for setting the Program Counter register. * @synchronize_from_tb: Callback for synchronizing state from a TCG * #TranslationBlock. + * @handle_mmu_fault: Callback for handling an MMU fault. * @get_phys_page_debug: Callback for obtaining a physical address. * @gdb_read_register: Callback for letting GDB read a register. * @gdb_write_register: Callback for letting GDB write a register. @@ -117,6 +118,8 @@ typedef struct CPUClass { Error **errp); void (*set_pc)(CPUState *cpu, vaddr value); void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb); + int (*handle_mmu_fault)(CPUState *cpu, vaddr address, int rw, + int mmu_index); hwaddr (*get_phys_page_debug)(CPUState *cpu, vaddr addr); int (*gdb_read_register)(CPUState *cpu, uint8_t *buf, int reg); int (*gdb_write_register)(CPUState *cpu, uint8_t *buf, int reg); diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c index cf2a3156d1..4d8263f37d 100644 --- a/target-alpha/cpu.c +++ b/target-alpha/cpu.c @@ -288,7 +288,9 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data) cc->set_pc = alpha_cpu_set_pc; cc->gdb_read_register = alpha_cpu_gdb_read_register; cc->gdb_write_register = alpha_cpu_gdb_write_register; -#ifndef CONFIG_USER_ONLY +#ifdef CONFIG_USER_ONLY + cc->handle_mmu_fault = alpha_cpu_handle_mmu_fault; +#else cc->do_unassigned_access = alpha_cpu_unassigned_access; cc->get_phys_page_debug = alpha_cpu_get_phys_page_debug; dc->vmsd = &vmstate_alpha_cpu; diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h index a172124170..07d9f63d1f 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -446,9 +446,8 @@ int cpu_alpha_exec(CPUAlphaState *s); is returned if the signal was handled by the virtual CPU. */ int cpu_alpha_signal_handler(int host_signum, void *pinfo, void *puc); -int cpu_alpha_handle_mmu_fault (CPUAlphaState *env, uint64_t address, int rw, - int mmu_idx); -#define cpu_handle_mmu_fault cpu_alpha_handle_mmu_fault +int alpha_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, + int mmu_idx); void do_restore_state(CPUAlphaState *, uintptr_t retaddr); void QEMU_NORETURN dynamic_excp(CPUAlphaState *, uintptr_t, int, int); void QEMU_NORETURN arith_excp(CPUAlphaState *, uintptr_t, int, uint64_t); diff --git a/target-alpha/helper.c b/target-alpha/helper.c index 98ddcdf4e3..9c94b4382c 100644 --- a/target-alpha/helper.c +++ b/target-alpha/helper.c @@ -168,11 +168,13 @@ void helper_store_fpcr(CPUAlphaState *env, uint64_t val) } #if defined(CONFIG_USER_ONLY) -int cpu_alpha_handle_mmu_fault(CPUAlphaState *env, target_ulong address, +int alpha_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, int mmu_idx) { - env->exception_index = EXCP_MMFAULT; - env->trap_arg0 = address; + AlphaCPU *cpu = ALPHA_CPU(cs); + + cpu->env.exception_index = EXCP_MMFAULT; + cpu->env.trap_arg0 = address; return 1; } #else @@ -326,9 +328,11 @@ hwaddr alpha_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) return (fail >= 0 ? -1 : phys); } -int cpu_alpha_handle_mmu_fault(CPUAlphaState *env, target_ulong addr, int rw, +int alpha_cpu_handle_mmu_fault(CPUState *cs, vaddr addr, int rw, int mmu_idx) { + AlphaCPU *cpu = ALPHA_CPU(cs); + CPUAlphaState *env = &cpu->env; target_ulong phys; int prot, fail; diff --git a/target-alpha/mem_helper.c b/target-alpha/mem_helper.c index e1aba64416..d195935a96 100644 --- a/target-alpha/mem_helper.c +++ b/target-alpha/mem_helper.c @@ -153,9 +153,10 @@ void alpha_cpu_unassigned_access(CPUState *cs, hwaddr addr, void tlb_fill(CPUAlphaState *env, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr) { + AlphaCPU *cpu = alpha_env_get_cpu(env); int ret; - ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, mmu_idx); + ret = alpha_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx); if (unlikely(ret != 0)) { if (retaddr) { cpu_restore_state(env, retaddr); diff --git a/target-arm/cpu.c b/target-arm/cpu.c index d792a912e7..be17d72537 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -1013,7 +1013,9 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data) cc->set_pc = arm_cpu_set_pc; cc->gdb_read_register = arm_cpu_gdb_read_register; cc->gdb_write_register = arm_cpu_gdb_write_register; -#ifndef CONFIG_USER_ONLY +#ifdef CONFIG_USER_ONLY + cc->handle_mmu_fault = arm_cpu_handle_mmu_fault; +#else cc->get_phys_page_debug = arm_cpu_get_phys_page_debug; cc->vmsd = &vmstate_arm_cpu; #endif diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 00d91d1231..bf37cd60d0 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -339,9 +339,8 @@ static inline bool is_a64(CPUARMState *env) is returned if the signal was handled by the virtual CPU. */ int cpu_arm_signal_handler(int host_signum, void *pinfo, void *puc); -int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw, - int mmu_idx); -#define cpu_handle_mmu_fault cpu_arm_handle_mmu_fault +int arm_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, + int mmu_idx); /* SCTLR bit meanings. Several bits have been reused in newer * versions of the architecture; in that case we define constants diff --git a/target-arm/helper.c b/target-arm/helper.c index f64be6f36d..d3e68a6e24 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -2655,9 +2655,12 @@ void arm_cpu_do_interrupt(CPUState *cs) env->exception_index = -1; } -int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw, - int mmu_idx) +int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, + int mmu_idx) { + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + if (rw == 2) { env->exception_index = EXCP_PREFETCH_ABORT; env->cp15.c6_insn = address; @@ -3623,9 +3626,11 @@ static inline int get_phys_addr(CPUARMState *env, uint32_t address, } } -int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, - int access_type, int mmu_idx) +int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, + int access_type, int mmu_idx) { + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; hwaddr phys_addr; target_ulong page_size; int prot; diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c index 5851e041a0..ced6a7b83c 100644 --- a/target-arm/op_helper.c +++ b/target-arm/op_helper.c @@ -74,9 +74,10 @@ uint32_t HELPER(neon_tbl)(CPUARMState *env, uint32_t ireg, uint32_t def, void tlb_fill(CPUARMState *env, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr) { + ARMCPU *cpu = arm_env_get_cpu(env); int ret; - ret = cpu_arm_handle_mmu_fault(env, addr, is_write, mmu_idx); + ret = arm_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx); if (unlikely(ret)) { if (retaddr) { /* now we have a real cpu fault */ diff --git a/target-cris/cpu.c b/target-cris/cpu.c index 12c90eef34..ff27e7f773 100644 --- a/target-cris/cpu.c +++ b/target-cris/cpu.c @@ -283,7 +283,9 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data) cc->set_pc = cris_cpu_set_pc; cc->gdb_read_register = cris_cpu_gdb_read_register; cc->gdb_write_register = cris_cpu_gdb_write_register; -#ifndef CONFIG_USER_ONLY +#ifdef CONFIG_USER_ONLY + cc->handle_mmu_fault = cris_cpu_handle_mmu_fault; +#else cc->get_phys_page_debug = cris_cpu_get_phys_page_debug; #endif diff --git a/target-cris/cpu.h b/target-cris/cpu.h index 1287cad4ac..6cc0616523 100644 --- a/target-cris/cpu.h +++ b/target-cris/cpu.h @@ -247,9 +247,8 @@ static inline int cpu_mmu_index (CPUCRISState *env) return !!(env->pregs[PR_CCS] & U_FLAG); } -int cpu_cris_handle_mmu_fault(CPUCRISState *env, target_ulong address, int rw, +int cris_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, int mmu_idx); -#define cpu_handle_mmu_fault cpu_cris_handle_mmu_fault /* Support function regs. */ #define SFR_RW_GC_CFG 0][0 diff --git a/target-cris/helper.c b/target-cris/helper.c index c940582132..857cc99b29 100644 --- a/target-cris/helper.c +++ b/target-cris/helper.c @@ -50,14 +50,14 @@ void crisv10_cpu_do_interrupt(CPUState *cs) cris_cpu_do_interrupt(cs); } -int cpu_cris_handle_mmu_fault(CPUCRISState * env, target_ulong address, int rw, +int cris_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, int mmu_idx) { - CRISCPU *cpu = cris_env_get_cpu(env); + CRISCPU *cpu = CRIS_CPU(cs); - env->exception_index = 0xaa; - env->pregs[PR_EDA] = address; - cpu_dump_state(CPU(cpu), stderr, fprintf, 0); + cpu->env.exception_index = 0xaa; + cpu->env.pregs[PR_EDA] = address; + cpu_dump_state(cs, stderr, fprintf, 0); return 1; } @@ -73,23 +73,25 @@ static void cris_shift_ccs(CPUCRISState *env) env->pregs[PR_CCS] = ccs; } -int cpu_cris_handle_mmu_fault(CPUCRISState *env, target_ulong address, int rw, +int cris_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, int mmu_idx) { - D(CPUState *cpu = CPU(cris_env_get_cpu(env))); + CRISCPU *cpu = CRIS_CPU(cs); + CPUCRISState *env = &cpu->env; struct cris_mmu_result res; int prot, miss; int r = -1; target_ulong phy; - D(printf("%s addr=%x pc=%x rw=%x\n", __func__, address, env->pc, rw)); + D(printf("%s addr=%" VADDR_PRIx " pc=%x rw=%x\n", + __func__, address, env->pc, rw)); miss = cris_mmu_translate(&res, env, address & TARGET_PAGE_MASK, rw, mmu_idx, 0); if (miss) { if (env->exception_index == EXCP_BUSFAULT) { cpu_abort(env, "CRIS: Illegal recursive bus fault." - "addr=%x rw=%d\n", + "addr=%" VADDR_PRIx " rw=%d\n", address, rw); } @@ -109,8 +111,8 @@ int cpu_cris_handle_mmu_fault(CPUCRISState *env, target_ulong address, int rw, r = 0; } if (r > 0) { - D_LOG("%s returns %d irqreq=%x addr=%x phy=%x vec=%x pc=%x\n", - __func__, r, cpu->interrupt_request, address, res.phy, + D_LOG("%s returns %d irqreq=%x addr=%" VADDR_PRIx " phy=%x vec=%x" + " pc=%x\n", __func__, r, cs->interrupt_request, address, res.phy, res.bf_vec, env->pc); } return r; diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c index b580513848..4a6215d5d6 100644 --- a/target-cris/op_helper.c +++ b/target-cris/op_helper.c @@ -57,11 +57,12 @@ void tlb_fill(CPUCRISState *env, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr) { + CRISCPU *cpu = cris_env_get_cpu(env); int ret; D_LOG("%s pc=%x tpc=%x ra=%p\n", __func__, env->pc, env->pregs[PR_EDA], (void *)retaddr); - ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx); + ret = cris_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx); if (unlikely(ret)) { if (retaddr) { /* now we have a real cpu fault */ diff --git a/target-i386/cpu.c b/target-i386/cpu.c index e417e673c0..63ba2194cb 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2810,7 +2810,9 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data) cc->gdb_write_register = x86_cpu_gdb_write_register; cc->get_arch_id = x86_cpu_get_arch_id; cc->get_paging_enabled = x86_cpu_get_paging_enabled; -#ifndef CONFIG_USER_ONLY +#ifdef CONFIG_USER_ONLY + cc->handle_mmu_fault = x86_cpu_handle_mmu_fault; +#else cc->get_memory_mapping = x86_cpu_get_memory_mapping; cc->get_phys_page_debug = x86_cpu_get_phys_page_debug; cc->write_elf64_note = x86_cpu_write_elf64_note; diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 2403321fa1..62641af77e 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -1067,9 +1067,8 @@ void host_cpuid(uint32_t function, uint32_t count, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx); /* helper.c */ -int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, +int x86_cpu_handle_mmu_fault(CPUState *cpu, vaddr addr, int is_write, int mmu_idx); -#define cpu_handle_mmu_fault cpu_x86_handle_mmu_fault void x86_cpu_set_a20(X86CPU *cpu, int a20_state); static inline bool hw_local_breakpoint_enabled(unsigned long dr7, int index) diff --git a/target-i386/helper.c b/target-i386/helper.c index 11c7219b10..696bbf55c4 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -485,9 +485,12 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4) #if defined(CONFIG_USER_ONLY) -int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, +int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr, int is_write, int mmu_idx) { + X86CPU *cpu = X86_CPU(cs); + CPUX86State *env = &cpu->env; + /* user mode only emulation */ is_write &= 1; env->cr[2] = addr; @@ -508,14 +511,15 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, # endif /* return value: - -1 = cannot handle fault - 0 = nothing more to do - 1 = generate PF fault -*/ -int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, + * -1 = cannot handle fault + * 0 = nothing more to do + * 1 = generate PF fault + */ +int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr, int is_write1, int mmu_idx) { - CPUState *cs = CPU(x86_env_get_cpu(env)); + X86CPU *cpu = X86_CPU(cs); + CPUX86State *env = &cpu->env; uint64_t ptep, pte; target_ulong pde_addr, pte_addr; int error_code, is_dirty, prot, page_size, is_write, is_user; @@ -525,7 +529,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, is_user = mmu_idx == MMU_USER_IDX; #if defined(DEBUG_MMU) - printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n", + printf("MMU fault: addr=%" VADDR_PRIx " w=%d u=%d eip=" TARGET_FMT_lx "\n", addr, is_write1, is_user, env->eip); #endif is_write = is_write1 & 1; diff --git a/target-i386/mem_helper.c b/target-i386/mem_helper.c index 319a219f8a..5b25ccd605 100644 --- a/target-i386/mem_helper.c +++ b/target-i386/mem_helper.c @@ -135,9 +135,10 @@ void helper_boundl(CPUX86State *env, target_ulong a0, int v) void tlb_fill(CPUX86State *env, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr) { + X86CPU *cpu = x86_env_get_cpu(env); int ret; - ret = cpu_x86_handle_mmu_fault(env, addr, is_write, mmu_idx); + ret = x86_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx); if (ret) { if (retaddr) { /* now we have a real cpu fault */ diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c index c157f52985..daec499502 100644 --- a/target-lm32/cpu.c +++ b/target-lm32/cpu.c @@ -266,7 +266,9 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data) cc->set_pc = lm32_cpu_set_pc; cc->gdb_read_register = lm32_cpu_gdb_read_register; cc->gdb_write_register = lm32_cpu_gdb_write_register; -#ifndef CONFIG_USER_ONLY +#ifdef CONFIG_USER_ONLY + cc->handle_mmu_fault = lm32_cpu_handle_mmu_fault; +#else cc->get_phys_page_debug = lm32_cpu_get_phys_page_debug; cc->vmsd = &vmstate_lm32_cpu; #endif diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h index e6314c0064..b94d9b007e 100644 --- a/target-lm32/cpu.h +++ b/target-lm32/cpu.h @@ -231,9 +231,8 @@ static inline CPULM32State *cpu_init(const char *cpu_model) #define cpu_gen_code cpu_lm32_gen_code #define cpu_signal_handler cpu_lm32_signal_handler -int cpu_lm32_handle_mmu_fault(CPULM32State *env, target_ulong address, int rw, +int lm32_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, int mmu_idx); -#define cpu_handle_mmu_fault cpu_lm32_handle_mmu_fault #include "exec/cpu-all.h" diff --git a/target-lm32/helper.c b/target-lm32/helper.c index e813e7dce2..ce6dd45552 100644 --- a/target-lm32/helper.c +++ b/target-lm32/helper.c @@ -20,9 +20,11 @@ #include "cpu.h" #include "qemu/host-utils.h" -int cpu_lm32_handle_mmu_fault(CPULM32State *env, target_ulong address, int rw, +int lm32_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, int mmu_idx) { + LM32CPU *cpu = LM32_CPU(cs); + CPULM32State *env = &cpu->env; int prot; address &= TARGET_PAGE_MASK; diff --git a/target-lm32/op_helper.c b/target-lm32/op_helper.c index 7189cb5cc4..774dc65cf2 100644 --- a/target-lm32/op_helper.c +++ b/target-lm32/op_helper.c @@ -153,9 +153,10 @@ uint32_t HELPER(rcsr_jrx)(CPULM32State *env) void tlb_fill(CPULM32State *env, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr) { + LM32CPU *cpu = lm32_env_get_cpu(env); int ret; - ret = cpu_lm32_handle_mmu_fault(env, addr, is_write, mmu_idx); + ret = lm32_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx); if (unlikely(ret)) { if (retaddr) { /* now we have a real cpu fault */ diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c index 7d66ed0416..46601dcd5d 100644 --- a/target-m68k/cpu.c +++ b/target-m68k/cpu.c @@ -200,7 +200,9 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data) cc->set_pc = m68k_cpu_set_pc; cc->gdb_read_register = m68k_cpu_gdb_read_register; cc->gdb_write_register = m68k_cpu_gdb_write_register; -#ifndef CONFIG_USER_ONLY +#ifdef CONFIG_USER_ONLY + cc->handle_mmu_fault = m68k_cpu_handle_mmu_fault; +#else cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug; #endif dc->vmsd = &vmstate_m68k_cpu; diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h index 5f79d2a7ef..dd1794feac 100644 --- a/target-m68k/cpu.h +++ b/target-m68k/cpu.h @@ -237,9 +237,8 @@ static inline int cpu_mmu_index (CPUM68KState *env) return (env->sr & SR_S) == 0 ? 1 : 0; } -int cpu_m68k_handle_mmu_fault(CPUM68KState *env, target_ulong address, int rw, +int m68k_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, int mmu_idx); -#define cpu_handle_mmu_fault cpu_m68k_handle_mmu_fault #include "exec/cpu-all.h" diff --git a/target-m68k/helper.c b/target-m68k/helper.c index a364eb1e5c..0ffb861d08 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -277,11 +277,13 @@ void m68k_switch_sp(CPUM68KState *env) #if defined(CONFIG_USER_ONLY) -int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw, - int mmu_idx) +int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, + int mmu_idx) { - env->exception_index = EXCP_ACCESS; - env->mmu.ar = address; + M68kCPU *cpu = M68K_CPU(cs); + + cpu->env.exception_index = EXCP_ACCESS; + cpu->env.mmu.ar = address; return 1; } @@ -295,14 +297,15 @@ hwaddr m68k_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) return addr; } -int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw, - int mmu_idx) +int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, + int mmu_idx) { + M68kCPU *cpu = M68K_CPU(cs); int prot; address &= TARGET_PAGE_MASK; prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; - tlb_set_page(env, address, address, prot, mmu_idx, TARGET_PAGE_SIZE); + tlb_set_page(&cpu->env, address, address, prot, mmu_idx, TARGET_PAGE_SIZE); return 0; } diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c index bbbfd7f130..539d1d6724 100644 --- a/target-m68k/op_helper.c +++ b/target-m68k/op_helper.c @@ -59,9 +59,10 @@ extern int semihosting_enabled; void tlb_fill(CPUM68KState *env, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr) { + M68kCPU *cpu = m68k_env_get_cpu(env); int ret; - ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, mmu_idx); + ret = m68k_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx); if (unlikely(ret)) { if (retaddr) { /* now we have a real cpu fault */ diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c index bbda0fd820..86ec25811e 100644 --- a/target-microblaze/cpu.c +++ b/target-microblaze/cpu.c @@ -171,7 +171,9 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data) cc->set_pc = mb_cpu_set_pc; cc->gdb_read_register = mb_cpu_gdb_read_register; cc->gdb_write_register = mb_cpu_gdb_write_register; -#ifndef CONFIG_USER_ONLY +#ifdef CONFIG_USER_ONLY + cc->handle_mmu_fault = mb_cpu_handle_mmu_fault; +#else cc->do_unassigned_access = mb_cpu_unassigned_access; cc->get_phys_page_debug = mb_cpu_get_phys_page_debug; #endif diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h index 78a7661778..6ccd06068c 100644 --- a/target-microblaze/cpu.h +++ b/target-microblaze/cpu.h @@ -332,9 +332,8 @@ static inline int cpu_mmu_index (CPUMBState *env) return MMU_KERNEL_IDX; } -int cpu_mb_handle_mmu_fault(CPUMBState *env, target_ulong address, int rw, +int mb_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, int mmu_idx); -#define cpu_handle_mmu_fault cpu_mb_handle_mmu_fault static inline int cpu_interrupts_enabled(CPUMBState *env) { diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c index 4fa9ce9cb5..d03f3690bb 100644 --- a/target-microblaze/helper.c +++ b/target-microblaze/helper.c @@ -36,21 +36,23 @@ void mb_cpu_do_interrupt(CPUState *cs) env->regs[14] = env->sregs[SR_PC]; } -int cpu_mb_handle_mmu_fault(CPUMBState * env, target_ulong address, int rw, +int mb_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, int mmu_idx) { - MicroBlazeCPU *cpu = mb_env_get_cpu(env); + MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs); - env->exception_index = 0xaa; - cpu_dump_state(CPU(cpu), stderr, fprintf, 0); + cpu->env.exception_index = 0xaa; + cpu_dump_state(cs, stderr, fprintf, 0); return 1; } #else /* !CONFIG_USER_ONLY */ -int cpu_mb_handle_mmu_fault (CPUMBState *env, target_ulong address, int rw, - int mmu_idx) +int mb_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, + int mmu_idx) { + MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs); + CPUMBState *env = &cpu->env; unsigned int hit; unsigned int mmu_available; int r = 1; diff --git a/target-microblaze/op_helper.c b/target-microblaze/op_helper.c index 14baa84c74..b70b2ea99c 100644 --- a/target-microblaze/op_helper.c +++ b/target-microblaze/op_helper.c @@ -44,9 +44,10 @@ void tlb_fill(CPUMBState *env, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr) { + MicroBlazeCPU *cpu = mb_env_get_cpu(env); int ret; - ret = cpu_mb_handle_mmu_fault(env, addr, is_write, mmu_idx); + ret = mb_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx); if (unlikely(ret)) { if (retaddr) { /* now we have a real cpu fault */ diff --git a/target-mips/cpu.c b/target-mips/cpu.c index 0a2dc46144..8c304ac832 100644 --- a/target-mips/cpu.c +++ b/target-mips/cpu.c @@ -133,7 +133,9 @@ static void mips_cpu_class_init(ObjectClass *c, void *data) cc->synchronize_from_tb = mips_cpu_synchronize_from_tb; cc->gdb_read_register = mips_cpu_gdb_read_register; cc->gdb_write_register = mips_cpu_gdb_write_register; -#ifndef CONFIG_USER_ONLY +#ifdef CONFIG_USER_ONLY + cc->handle_mmu_fault = mips_cpu_handle_mmu_fault; +#else cc->do_unassigned_access = mips_cpu_unassigned_access; cc->get_phys_page_debug = mips_cpu_get_phys_page_debug; #endif diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 6981e7a109..a1d85efea1 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -666,9 +666,8 @@ void cpu_mips_stop_count(CPUMIPSState *env); void cpu_mips_soft_irq(CPUMIPSState *env, int irq, int level); /* helper.c */ -int cpu_mips_handle_mmu_fault (CPUMIPSState *env, target_ulong address, int rw, - int mmu_idx); -#define cpu_handle_mmu_fault cpu_mips_handle_mmu_fault +int mips_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, + int mmu_idx); #if !defined(CONFIG_USER_ONLY) void r4k_invalidate_tlb (CPUMIPSState *env, int idx, int use_extra); hwaddr cpu_mips_translate_address (CPUMIPSState *env, target_ulong address, diff --git a/target-mips/helper.c b/target-mips/helper.c index 33e0e88637..d8e9166c2c 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -268,9 +268,11 @@ hwaddr mips_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) } #endif -int cpu_mips_handle_mmu_fault (CPUMIPSState *env, target_ulong address, int rw, - int mmu_idx) +int mips_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, + int mmu_idx) { + MIPSCPU *cpu = MIPS_CPU(cs); + CPUMIPSState *env = &cpu->env; #if !defined(CONFIG_USER_ONLY) hwaddr physical; int prot; @@ -279,9 +281,9 @@ int cpu_mips_handle_mmu_fault (CPUMIPSState *env, target_ulong address, int rw, int ret = 0; #if 0 - log_cpu_state(CPU(mips_env_get_cpu(env)), 0); + log_cpu_state(cs, 0); #endif - qemu_log("%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d mmu_idx %d\n", + qemu_log("%s pc " TARGET_FMT_lx " ad %" VADDR_PRIx " rw %d mmu_idx %d\n", __func__, env->active_tc.PC, address, rw, mmu_idx); rw &= 1; @@ -293,8 +295,9 @@ int cpu_mips_handle_mmu_fault (CPUMIPSState *env, target_ulong address, int rw, access_type = ACCESS_INT; 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); + qemu_log("%s address=%" VADDR_PRIx " ret %d physical " TARGET_FMT_plx + " prot %d\n", + __func__, address, ret, physical, prot); if (ret == TLBRET_MATCH) { tlb_set_page(env, address & TARGET_PAGE_MASK, physical & TARGET_PAGE_MASK, prot | PAGE_EXEC, diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 2ef6633f47..a62496cc3b 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -2146,9 +2146,10 @@ static void do_unaligned_access(CPUMIPSState *env, target_ulong addr, void tlb_fill(CPUMIPSState *env, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr) { + MIPSCPU *cpu = mips_env_get_cpu(env); int ret; - ret = cpu_mips_handle_mmu_fault(env, addr, is_write, mmu_idx); + ret = mips_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx); if (ret) { do_raise_exception_err(env, env->exception_index, env->error_code, retaddr); diff --git a/target-moxie/cpu.c b/target-moxie/cpu.c index 32c6104950..03d8eb13d7 100644 --- a/target-moxie/cpu.c +++ b/target-moxie/cpu.c @@ -108,7 +108,9 @@ static void moxie_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = moxie_cpu_do_interrupt; cc->dump_state = moxie_cpu_dump_state; cc->set_pc = moxie_cpu_set_pc; -#ifndef CONFIG_USER_ONLY +#ifdef CONFIG_USER_ONLY + cc->handle_mmu_fault = moxie_cpu_handle_mmu_fault; +#else cc->get_phys_page_debug = moxie_cpu_get_phys_page_debug; cc->vmsd = &vmstate_moxie_cpu; #endif diff --git a/target-moxie/cpu.h b/target-moxie/cpu.h index 778cfc00c9..c5b12a5244 100644 --- a/target-moxie/cpu.h +++ b/target-moxie/cpu.h @@ -152,7 +152,7 @@ static inline void cpu_get_tb_cpu_state(CPUMoxieState *env, target_ulong *pc, *flags = 0; } -int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address, +int moxie_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, int mmu_idx); #endif /* _CPU_MOXIE_H */ diff --git a/target-moxie/helper.c b/target-moxie/helper.c index 7859102ab7..8160475414 100644 --- a/target-moxie/helper.c +++ b/target-moxie/helper.c @@ -49,9 +49,10 @@ void tlb_fill(CPUMoxieState *env, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr) { + MoxieCPU *cpu = moxie_env_get_cpu(env); int ret; - ret = cpu_moxie_handle_mmu_fault(env, addr, is_write, mmu_idx); + ret = moxie_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx); if (unlikely(ret)) { if (retaddr) { cpu_restore_state(env, retaddr); @@ -103,27 +104,29 @@ void helper_debug(CPUMoxieState *env) #if defined(CONFIG_USER_ONLY) -void moxie_cpu_do_interrupt(CPUState *env) +void moxie_cpu_do_interrupt(CPUState *cs) { env->exception_index = -1; } -int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address, +int moxie_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, int mmu_idx) { - MoxieCPU *cpu = moxie_env_get_cpu(env); + MoxieCPU *cpu = MOXIE_CPU(cs); - env->exception_index = 0xaa; - env->debug1 = address; - cpu_dump_state(CPU(cpu), stderr, fprintf, 0); + cpu->env.exception_index = 0xaa; + cpu->env.debug1 = address; + cpu_dump_state(cs, stderr, fprintf, 0); return 1; } #else /* !CONFIG_USER_ONLY */ -int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address, +int moxie_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, int mmu_idx) { + MoxieCPU *cpu = MOXIE_CPU(cs); + CPUMoxieState *env = &cpu->env; MoxieMMUResult res; int prot, miss; target_ulong phy; diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c index 0b2ffb23f0..99e4aa7c67 100644 --- a/target-openrisc/cpu.c +++ b/target-openrisc/cpu.c @@ -165,7 +165,9 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data) cc->set_pc = openrisc_cpu_set_pc; cc->gdb_read_register = openrisc_cpu_gdb_read_register; cc->gdb_write_register = openrisc_cpu_gdb_write_register; -#ifndef CONFIG_USER_ONLY +#ifdef CONFIG_USER_ONLY + cc->handle_mmu_fault = openrisc_cpu_handle_mmu_fault; +#else cc->get_phys_page_debug = openrisc_cpu_get_phys_page_debug; dc->vmsd = &vmstate_openrisc_cpu; #endif diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h index ae9d17f102..660bb4f1e7 100644 --- a/target-openrisc/cpu.h +++ b/target-openrisc/cpu.h @@ -353,15 +353,13 @@ hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); int openrisc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); int openrisc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void openrisc_translate_init(void); -int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env, - target_ulong address, +int openrisc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, int mmu_idx); int cpu_openrisc_signal_handler(int host_signum, void *pinfo, void *puc); #define cpu_list cpu_openrisc_list #define cpu_exec cpu_openrisc_exec #define cpu_gen_code cpu_openrisc_gen_code -#define cpu_handle_mmu_fault cpu_openrisc_handle_mmu_fault #define cpu_signal_handler cpu_openrisc_signal_handler #ifndef CONFIG_USER_ONLY diff --git a/target-openrisc/mmu.c b/target-openrisc/mmu.c index dd487bd0d1..1fd0a0a3fa 100644 --- a/target-openrisc/mmu.c +++ b/target-openrisc/mmu.c @@ -174,19 +174,19 @@ static void cpu_openrisc_raise_mmu_exception(OpenRISCCPU *cpu, } #ifndef CONFIG_USER_ONLY -int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env, - target_ulong address, int rw, int mmu_idx) +int openrisc_cpu_handle_mmu_fault(CPUState *cs, + vaddr address, int rw, int mmu_idx) { + OpenRISCCPU *cpu = OPENRISC_CPU(cs); int ret = 0; hwaddr physical = 0; int prot = 0; - OpenRISCCPU *cpu = openrisc_env_get_cpu(env); ret = cpu_openrisc_get_phys_addr(cpu, &physical, &prot, address, rw); if (ret == TLBRET_MATCH) { - tlb_set_page(env, address & TARGET_PAGE_MASK, + tlb_set_page(&cpu->env, address & TARGET_PAGE_MASK, physical & TARGET_PAGE_MASK, prot, mmu_idx, TARGET_PAGE_SIZE); ret = 0; @@ -198,11 +198,11 @@ int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env, return ret; } #else -int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env, - target_ulong address, int rw, int mmu_idx) +int openrisc_cpu_handle_mmu_fault(CPUState *cs, + vaddr address, int rw, int mmu_idx) { + OpenRISCCPU *cpu = OPENRISC_CPU(cs); int ret = 0; - OpenRISCCPU *cpu = openrisc_env_get_cpu(env); cpu_openrisc_raise_mmu_exception(cpu, address, rw, ret); ret = 1; diff --git a/target-openrisc/mmu_helper.c b/target-openrisc/mmu_helper.c index e46b092984..b023a5fb98 100644 --- a/target-openrisc/mmu_helper.c +++ b/target-openrisc/mmu_helper.c @@ -39,9 +39,10 @@ void tlb_fill(CPUOpenRISCState *env, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr) { + OpenRISCCPU *cpu = openrisc_env_get_cpu(env); int ret; - ret = cpu_openrisc_handle_mmu_fault(env, addr, is_write, mmu_idx); + ret = openrisc_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx); if (ret) { if (retaddr) { diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 501dd036c4..acf6909de7 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1111,8 +1111,8 @@ int cpu_ppc_signal_handler (int host_signum, void *pinfo, void *puc); void ppc_hw_interrupt (CPUPPCState *env); #if defined(CONFIG_USER_ONLY) -int cpu_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw, - int mmu_idx); +int ppc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, + int mmu_idx); #endif #if !defined(CONFIG_USER_ONLY) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 0418f068a2..703b3d8797 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -8507,7 +8507,9 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data) cc->set_pc = ppc_cpu_set_pc; cc->gdb_read_register = ppc_cpu_gdb_read_register; cc->gdb_write_register = ppc_cpu_gdb_write_register; -#ifndef CONFIG_USER_ONLY +#ifdef CONFIG_USER_ONLY + cc->handle_mmu_fault = ppc_cpu_handle_mmu_fault; +#else cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug; cc->vmsd = &vmstate_ppc_cpu; #if defined(TARGET_PPC64) diff --git a/target-ppc/user_only_helper.c b/target-ppc/user_only_helper.c index 56e686efd1..a7c99e032b 100644 --- a/target-ppc/user_only_helper.c +++ b/target-ppc/user_only_helper.c @@ -20,9 +20,11 @@ #include "cpu.h" -int cpu_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw, - int mmu_idx) +int ppc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, + int mmu_idx) { + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; int exception, error_code; if (rw == 2) { diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c index 5dac322f27..993d924e52 100644 --- a/target-s390x/cpu.c +++ b/target-s390x/cpu.c @@ -247,7 +247,9 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data) cc->set_pc = s390_cpu_set_pc; cc->gdb_read_register = s390_cpu_gdb_read_register; cc->gdb_write_register = s390_cpu_gdb_write_register; -#ifndef CONFIG_USER_ONLY +#ifdef CONFIG_USER_ONLY + cc->handle_mmu_fault = s390_cpu_handle_mmu_fault; +#else cc->get_phys_page_debug = s390_cpu_get_phys_page_debug; cc->write_elf64_note = s390_cpu_write_elf64_note; cc->write_elf64_qemunote = s390_cpu_write_elf64_qemunote; diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index 8b4a5c0155..f332d41b94 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -320,9 +320,8 @@ int cpu_s390x_exec(CPUS390XState *s); is returned if the signal was handled by the virtual CPU. */ int cpu_s390x_signal_handler(int host_signum, void *pinfo, void *puc); -int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw, - int mmu_idx); -#define cpu_handle_mmu_fault cpu_s390x_handle_mmu_fault +int s390_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, + int mmu_idx); #include "ioinst.h" diff --git a/target-s390x/helper.c b/target-s390x/helper.c index 0bae0a32fd..e71e5fd563 100644 --- a/target-s390x/helper.c +++ b/target-s390x/helper.c @@ -91,14 +91,16 @@ void s390_cpu_do_interrupt(CPUState *cs) env->exception_index = -1; } -int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong address, - int rw, int mmu_idx) +int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr address, + int rw, int mmu_idx) { - env->exception_index = EXCP_PGM; - env->int_pgm_code = PGM_ADDRESSING; + S390CPU *cpu = S390_CPU(cs); + + cpu->env.exception_index = EXCP_PGM; + cpu->env.int_pgm_code = PGM_ADDRESSING; /* On real machines this value is dropped into LowMem. Since this is userland, simply put this someplace that cpu_loop can find it. */ - env->__excp_addr = address; + cpu->env.__excp_addr = address; return 1; } @@ -379,14 +381,16 @@ int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc, return r; } -int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong orig_vaddr, - int rw, int mmu_idx) +int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr orig_vaddr, + int rw, int mmu_idx) { + S390CPU *cpu = S390_CPU(cs); + CPUS390XState *env = &cpu->env; uint64_t asc = env->psw.mask & PSW_MASK_ASC; target_ulong vaddr, raddr; int prot; - DPRINTF("%s: address 0x%" PRIx64 " rw %d mmu_idx %d\n", + DPRINTF("%s: address 0x%" VADDR_PRIx " rw %d mmu_idx %d\n", __func__, orig_vaddr, rw, mmu_idx); orig_vaddr &= TARGET_PAGE_MASK; diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c index db673cfbe8..d9dc8ae3df 100644 --- a/target-s390x/mem_helper.c +++ b/target-s390x/mem_helper.c @@ -47,9 +47,10 @@ void tlb_fill(CPUS390XState *env, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr) { + S390CPU *cpu = s390_env_get_cpu(env); int ret; - ret = cpu_s390x_handle_mmu_fault(env, addr, is_write, mmu_idx); + ret = s390_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx); if (unlikely(ret != 0)) { if (likely(retaddr)) { /* now we have a real cpu fault */ diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c index 8e7bcd248d..88960c8512 100644 --- a/target-sh4/cpu.c +++ b/target-sh4/cpu.c @@ -281,7 +281,9 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data) cc->synchronize_from_tb = superh_cpu_synchronize_from_tb; cc->gdb_read_register = superh_cpu_gdb_read_register; cc->gdb_write_register = superh_cpu_gdb_write_register; -#ifndef CONFIG_USER_ONLY +#ifdef CONFIG_USER_ONLY + cc->handle_mmu_fault = superh_cpu_handle_mmu_fault; +#else cc->get_phys_page_debug = superh_cpu_get_phys_page_debug; #endif dc->vmsd = &vmstate_sh_cpu; diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index 808f90f1cf..a85571087d 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h @@ -193,9 +193,8 @@ SuperHCPU *cpu_sh4_init(const char *cpu_model); int cpu_sh4_exec(CPUSH4State * s); int cpu_sh4_signal_handler(int host_signum, void *pinfo, void *puc); -int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw, - int mmu_idx); -#define cpu_handle_mmu_fault cpu_sh4_handle_mmu_fault +int superh_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, + int mmu_idx); void sh4_cpu_list(FILE *f, fprintf_function cpu_fprintf); #if !defined(CONFIG_USER_ONLY) diff --git a/target-sh4/helper.c b/target-sh4/helper.c index 9ac28250e0..3f8f1fa296 100644 --- a/target-sh4/helper.c +++ b/target-sh4/helper.c @@ -39,9 +39,12 @@ void superh_cpu_do_interrupt(CPUState *cs) env->exception_index = -1; } -int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw, - int mmu_idx) +int superh_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, + int mmu_idx) { + SuperHCPU *cpu = SUPERH_CPU(cs); + CPUSH4State *env = &cpu->env; + env->tea = address; env->exception_index = -1; switch (rw) { @@ -447,9 +450,11 @@ static int get_physical_address(CPUSH4State * env, target_ulong * physical, return get_mmu_address(env, physical, prot, address, rw, access_type); } -int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw, - int mmu_idx) +int superh_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, + int mmu_idx) { + SuperHCPU *cpu = SUPERH_CPU(cs); + CPUSH4State *env = &cpu->env; target_ulong physical; int prot, ret, access_type; diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c index e955e810b5..35f906788a 100644 --- a/target-sh4/op_helper.c +++ b/target-sh4/op_helper.c @@ -41,9 +41,10 @@ void tlb_fill(CPUSH4State *env, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr) { + SuperHCPU *cpu = sh_env_get_cpu(env); int ret; - ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, mmu_idx); + ret = superh_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx); if (ret) { /* now we have a real cpu fault */ if (retaddr) { diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c index 9a315c8d4c..3e6e7a754e 100644 --- a/target-sparc/cpu.c +++ b/target-sparc/cpu.c @@ -821,7 +821,9 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data) cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb; cc->gdb_read_register = sparc_cpu_gdb_read_register; cc->gdb_write_register = sparc_cpu_gdb_write_register; -#ifndef CONFIG_USER_ONLY +#ifdef CONFIG_USER_ONLY + cc->handle_mmu_fault = sparc_cpu_handle_mmu_fault; +#else cc->do_unassigned_access = sparc_cpu_unassigned_access; cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug; #endif diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index e14b5a12aa..893caa0576 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -521,9 +521,8 @@ SPARCCPU *cpu_sparc_init(const char *cpu_model); void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu); void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf); /* mmu_helper.c */ -int cpu_sparc_handle_mmu_fault(CPUSPARCState *env1, target_ulong address, int rw, +int sparc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, int mmu_idx); -#define cpu_handle_mmu_fault cpu_sparc_handle_mmu_fault target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev); void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env); diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c index 45ed154346..c2482454ac 100644 --- a/target-sparc/ldst_helper.c +++ b/target-sparc/ldst_helper.c @@ -2441,9 +2441,10 @@ static void QEMU_NORETURN do_unaligned_access(CPUSPARCState *env, void tlb_fill(CPUSPARCState *env, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr) { + SPARCCPU *cpu = sparc_env_get_cpu(env); int ret; - ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx); + ret = sparc_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx); if (ret) { if (retaddr) { cpu_restore_state(env, retaddr); diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c index 511eb7e65c..5a9748e347 100644 --- a/target-sparc/mmu_helper.c +++ b/target-sparc/mmu_helper.c @@ -25,13 +25,15 @@ #if defined(CONFIG_USER_ONLY) -int cpu_sparc_handle_mmu_fault(CPUSPARCState *env1, target_ulong address, int rw, +int sparc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, int mmu_idx) { + SPARCCPU *cpu = SPARC_CPU(cs); + if (rw & 2) { - env1->exception_index = TT_TFAULT; + cpu->env.exception_index = TT_TFAULT; } else { - env1->exception_index = TT_DFAULT; + cpu->env.exception_index = TT_DFAULT; } return 1; } @@ -198,9 +200,11 @@ static int get_physical_address(CPUSPARCState *env, hwaddr *physical, } /* Perform address translation */ -int cpu_sparc_handle_mmu_fault(CPUSPARCState *env, target_ulong address, int rw, +int sparc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, int mmu_idx) { + SPARCCPU *cpu = SPARC_CPU(cs); + CPUSPARCState *env = &cpu->env; hwaddr paddr; target_ulong vaddr; target_ulong page_size; @@ -212,7 +216,7 @@ int cpu_sparc_handle_mmu_fault(CPUSPARCState *env, target_ulong address, int rw, vaddr = address; if (error_code == 0) { #ifdef DEBUG_MMU - printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", vaddr " + printf("Translate at %" VADDR_PRIx " -> " TARGET_FMT_plx ", vaddr " TARGET_FMT_lx "\n", address, paddr, vaddr); #endif tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size); @@ -705,9 +709,11 @@ static int get_physical_address(CPUSPARCState *env, hwaddr *physical, } /* Perform address translation */ -int cpu_sparc_handle_mmu_fault(CPUSPARCState *env, target_ulong address, int rw, +int sparc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, int mmu_idx) { + SPARCCPU *cpu = SPARC_CPU(cs); + CPUSPARCState *env = &cpu->env; target_ulong vaddr; hwaddr paddr; target_ulong page_size; diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c index 1cfe50a432..24dec13985 100644 --- a/target-unicore32/cpu.c +++ b/target-unicore32/cpu.c @@ -148,7 +148,9 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = uc32_cpu_do_interrupt; cc->dump_state = uc32_cpu_dump_state; cc->set_pc = uc32_cpu_set_pc; -#ifndef CONFIG_USER_ONLY +#ifdef CONFIG_USER_ONLY + cc->handle_mmu_fault = uc32_cpu_handle_mmu_fault; +#else cc->get_phys_page_debug = uc32_cpu_get_phys_page_debug; #endif dc->vmsd = &vmstate_uc32_cpu; diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h index 1db7419733..50972f9494 100644 --- a/target-unicore32/cpu.h +++ b/target-unicore32/cpu.h @@ -125,13 +125,10 @@ void cpu_asr_write(CPUUniCore32State *env1, target_ulong val, target_ulong mask) #define cpu_init uc32_cpu_init #define cpu_exec uc32_cpu_exec #define cpu_signal_handler uc32_cpu_signal_handler -#define cpu_handle_mmu_fault uc32_cpu_handle_mmu_fault CPUUniCore32State *uc32_cpu_init(const char *cpu_model); int uc32_cpu_exec(CPUUniCore32State *s); int uc32_cpu_signal_handler(int host_signum, void *pinfo, void *puc); -int uc32_cpu_handle_mmu_fault(CPUUniCore32State *env, target_ulong address, int rw, - int mmu_idx); /* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernel @@ -157,6 +154,8 @@ static inline void cpu_get_tb_cpu_state(CPUUniCore32State *env, target_ulong *pc } } +int uc32_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, + int mmu_idx); void uc32_translate_init(void); void switch_mode(CPUUniCore32State *, int); diff --git a/target-unicore32/helper.c b/target-unicore32/helper.c index a1f86b0d13..29cf5755bc 100644 --- a/target-unicore32/helper.c +++ b/target-unicore32/helper.c @@ -242,9 +242,12 @@ void uc32_cpu_do_interrupt(CPUState *cs) cpu_abort(env, "NO interrupt in user mode\n"); } -int uc32_cpu_handle_mmu_fault(CPUUniCore32State *env, target_ulong address, +int uc32_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int access_type, int mmu_idx) { + UniCore32CPU *cpu = UNICORE32_CPU(cs); + CPUUniCore32State *env = &cpu->env; + cpu_abort(env, "NO mmu fault in user mode\n"); return 1; } diff --git a/target-unicore32/op_helper.c b/target-unicore32/op_helper.c index 4f9f41eb36..5cd2378c6d 100644 --- a/target-unicore32/op_helper.c +++ b/target-unicore32/op_helper.c @@ -258,9 +258,10 @@ uint32_t HELPER(ror_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i) void tlb_fill(CPUUniCore32State *env, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr) { + UniCore32CPU *cpu = uc32_env_get_cpu(env); int ret; - ret = uc32_cpu_handle_mmu_fault(env, addr, is_write, mmu_idx); + ret = uc32_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx); if (unlikely(ret)) { if (retaddr) { /* now we have a real cpu fault */ diff --git a/target-unicore32/softmmu.c b/target-unicore32/softmmu.c index 9552f69228..75f73865f1 100644 --- a/target-unicore32/softmmu.c +++ b/target-unicore32/softmmu.c @@ -209,9 +209,11 @@ do_fault: return code; } -int uc32_cpu_handle_mmu_fault(CPUUniCore32State *env, target_ulong address, +int uc32_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int access_type, int mmu_idx) { + UniCore32CPU *cpu = UNICORE32_CPU(cs); + CPUUniCore32State *env = &cpu->env; uint32_t phys_addr; target_ulong page_size; int prot; @@ -231,7 +233,7 @@ int uc32_cpu_handle_mmu_fault(CPUUniCore32State *env, target_ulong address, ret = get_phys_addr_ucv2(env, address, access_type, is_user, &phys_addr, &prot, &page_size); if (is_user) { - DPRINTF("user space access: ret %x, address %x, " + DPRINTF("user space access: ret %x, address %" VADDR_PRIx ", " "access_type %x, phys_addr %x, prot %x\n", ret, address, access_type, phys_addr, prot); } diff --git a/user-exec.c b/user-exec.c index 82bfa66ce3..d850d41d45 100644 --- a/user-exec.c +++ b/user-exec.c @@ -82,6 +82,8 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address, int is_write, sigset_t *old_set, void *puc) { + CPUState *cpu; + CPUClass *cc; CPUArchState *env; int ret; @@ -99,9 +101,12 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address, are still valid segv ones */ address = h2g_nocheck(address); - env = current_cpu->env_ptr; + cpu = current_cpu; + cc = CPU_GET_CLASS(cpu); + env = cpu->env_ptr; /* see if it is an MMU fault */ - ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX); + g_assert(cc->handle_mmu_fault); + ret = cc->handle_mmu_fault(cpu, address, is_write, MMU_USER_IDX); if (ret < 0) { return 0; /* not an MMU fault */ } |