diff options
author | pbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162> | 2006-06-17 19:58:25 +0000 |
---|---|---|
committer | pbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162> | 2006-06-17 19:58:25 +0000 |
commit | 355fb23d83aad9ffae376cac09c6b52656e7d083 (patch) | |
tree | 6d4279f10b498a5723c0d829887557e46517cf62 /target-sh4 | |
parent | 9854bc4662906a60c35c64c1e5b4d76eee4ac631 (diff) |
SH usermode fault handling.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1988 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-sh4')
-rw-r--r-- | target-sh4/helper.c | 43 | ||||
-rw-r--r-- | target-sh4/translate.c | 40 |
2 files changed, 64 insertions, 19 deletions
diff --git a/target-sh4/helper.c b/target-sh4/helper.c index 5ab505aedd..1839c96dde 100644 --- a/target-sh4/helper.c +++ b/target-sh4/helper.c @@ -28,6 +28,38 @@ #include "cpu.h" #include "exec-all.h" +#if defined(CONFIG_USER_ONLY) + +void do_interrupt (CPUState *env) +{ + env->exception_index = -1; +} + +int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw, + int is_user, int is_softmmu) +{ + env->tea = address; + switch (rw) { + case 0: + env->exception_index = 0x0a0; + break; + case 1: + env->exception_index = 0x0c0; + break; + case 2: + env->exception_index = 0x0a0; + break; + } + return 1; +} + +target_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr) +{ + return addr; +} + +#else /* !CONFIG_USER_ONLY */ + #define MMU_OK 0 #define MMU_ITLB_MISS (-1) #define MMU_ITLB_MULTIPLE (-2) @@ -396,3 +428,14 @@ int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw, return tlb_set_page(env, address, physical, prot, is_user, is_softmmu); } + +target_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr) +{ + target_ulong physical; + int prot; + + get_physical_address(env, &physical, &prot, addr, PAGE_READ, 0); + return physical; +} + +#endif diff --git a/target-sh4/translate.c b/target-sh4/translate.c index b08d25a15a..84deced19e 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -144,22 +144,6 @@ CPUSH4State *cpu_sh4_init(void) return env; } -#ifdef CONFIG_USER_ONLY -target_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr) -{ - return addr; -} -#else -target_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr) -{ - target_ulong physical; - int prot; - - get_physical_address(env, &physical, &prot, addr, PAGE_READ, 0); - return physical; -} -#endif - static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest) { TranslationBlock *tb; @@ -1108,7 +1092,7 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, target_ulong pc_start; static uint16_t *gen_opc_end; uint32_t old_flags; - int i; + int i, ii; pc_start = tb->pc; gen_opc_ptr = gen_opc_buf; @@ -1135,6 +1119,7 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, } #endif + ii = -1; while ((old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) == 0 && (ctx.flags & (BRANCH | BRANCH_CONDITIONAL | MODE_CHANGE | BRANCH_EXCEPTION)) == 0 && @@ -1151,6 +1136,16 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, } } } + if (search_pc) { + i = gen_opc_ptr - gen_opc_buf; + if (ii < i) { + ii++; + while (ii < i) + gen_opc_instr_start[ii++] = 0; + } + gen_opc_pc[ii] = ctx.pc; + gen_opc_instr_start[ii] = 1; + } #if 0 fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc); fflush(stderr); @@ -1192,7 +1187,15 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, gen_op_debug(); } *gen_opc_ptr = INDEX_op_end; - tb->size = ctx.pc - pc_start; + if (search_pc) { + i = gen_opc_ptr - gen_opc_buf; + ii++; + while (ii <= i) + gen_opc_instr_start[ii++] = 0; + tb->size = 0; + } else { + tb->size = ctx.pc - pc_start; + } #ifdef DEBUG_DISAS #ifdef SH4_DEBUG_DISAS @@ -1220,6 +1223,5 @@ int gen_intermediate_code(CPUState * env, struct TranslationBlock *tb) int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb) { - assert(0); return gen_intermediate_code_internal(env, tb, 1); } |