diff --git a/target-arm/cpu.h b/target-arm/cpu.h index d754512811..c0994c0c64 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -24,8 +24,10 @@ #include "cpu-defs.h" -#define EXCP_UDEF 1 /* undefined instruction */ -#define EXCP_SWI 2 /* software interrupt */ +#define EXCP_UDEF 1 /* undefined instruction */ +#define EXCP_SWI 2 /* software interrupt */ +#define EXCP_PREFETCH_ABORT 3 +#define EXCP_DATA_ABORT 4 typedef struct CPUARMState { uint32_t regs[16]; @@ -39,6 +41,9 @@ typedef struct CPUARMState { int thumb; /* 0 = arm mode, 1 = thumb mode */ + /* coprocessor 15 (MMU) status */ + uint32_t cp15_6; + /* exception/interrupt handling */ jmp_buf jmp_env; int exception_index; diff --git a/target-arm/exec.h b/target-arm/exec.h index 373b63dbea..e17302e0b5 100644 --- a/target-arm/exec.h +++ b/target-arm/exec.h @@ -48,3 +48,6 @@ static inline void env_to_regs(void) static inline void regs_to_env(void) { } + +int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw, + int is_user, int is_softmmu); diff --git a/target-arm/translate.c b/target-arm/translate.c index 7223242136..2eb325e8e6 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -424,6 +424,7 @@ static void disas_arm_insn(DisasContext *s) gen_op_movl_T0_psr(); gen_movl_reg_T0(s, rd); } + break; case 0x1: if (op1 == 1) { /* branch/exchange thumb (bx). */ @@ -1576,3 +1577,23 @@ target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr) { return addr; } + +#if defined(CONFIG_USER_ONLY) + +int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw, + int is_user, int is_softmmu) +{ + env->cp15_6 = address; + if (rw == 2) { + env->exception_index = EXCP_PREFETCH_ABORT; + } else { + env->exception_index = EXCP_DATA_ABORT; + } + return 1; +} + +#else + +#error not implemented + +#endif