提交 355fb23d 编写于 作者: P pbrook

SH usermode fault handling.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1988 c046a42c-6fe2-441c-8c8c-71466251a162
上级 9854bc46
...@@ -1172,19 +1172,14 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, ...@@ -1172,19 +1172,14 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
a virtual CPU fault */ a virtual CPU fault */
cpu_restore_state(tb, env, pc, puc); cpu_restore_state(tb, env, pc, puc);
} }
if (ret == 1) {
#if 0 #if 0
printf("PF exception: NIP=0x%08x error=0x%x %p\n", printf("PF exception: NIP=0x%08x error=0x%x %p\n",
env->nip, env->error_code, tb); env->nip, env->error_code, tb);
#endif #endif
/* we restore the process signal mask as the sigreturn should /* we restore the process signal mask as the sigreturn should
do it (XXX: use sigsetjmp) */ do it (XXX: use sigsetjmp) */
sigprocmask(SIG_SETMASK, old_set, NULL); sigprocmask(SIG_SETMASK, old_set, NULL);
// do_raise_exception_err(env->exception_index, env->error_code); cpu_loop_exit();
} else {
/* activate soft MMU for this block */
cpu_resume_from_signal(env, puc);
}
/* never comes here */ /* never comes here */
return 1; return 1;
} }
......
...@@ -1362,7 +1362,7 @@ void cpu_loop(CPUMIPSState *env) ...@@ -1362,7 +1362,7 @@ void cpu_loop(CPUMIPSState *env)
void cpu_loop (CPUState *env) void cpu_loop (CPUState *env)
{ {
int trapnr, ret; int trapnr, ret;
// target_siginfo_t info; target_siginfo_t info;
while (1) { while (1) {
trapnr = cpu_sh4_exec (env); trapnr = cpu_sh4_exec (env);
...@@ -1380,6 +1380,20 @@ void cpu_loop (CPUState *env) ...@@ -1380,6 +1380,20 @@ void cpu_loop (CPUState *env)
env->gregs[0x10] = ret; env->gregs[0x10] = ret;
env->pc += 2; env->pc += 2;
break; break;
case EXCP_DEBUG:
{
int sig;
sig = gdb_handlesig (env, TARGET_SIGTRAP);
if (sig)
{
info.si_signo = sig;
info.si_errno = 0;
info.si_code = TARGET_TRAP_BRKPT;
queue_signal(info.si_signo, &info);
}
}
break;
default: default:
printf ("Unhandled trap: 0x%x\n", trapnr); printf ("Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(env, stderr, fprintf, 0); cpu_dump_state(env, stderr, fprintf, 0);
......
...@@ -28,6 +28,38 @@ ...@@ -28,6 +28,38 @@
#include "cpu.h" #include "cpu.h"
#include "exec-all.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_OK 0
#define MMU_ITLB_MISS (-1) #define MMU_ITLB_MISS (-1)
#define MMU_ITLB_MULTIPLE (-2) #define MMU_ITLB_MULTIPLE (-2)
...@@ -396,3 +428,14 @@ int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw, ...@@ -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); 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
...@@ -144,22 +144,6 @@ CPUSH4State *cpu_sh4_init(void) ...@@ -144,22 +144,6 @@ CPUSH4State *cpu_sh4_init(void)
return env; 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) static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
{ {
TranslationBlock *tb; TranslationBlock *tb;
...@@ -1108,7 +1092,7 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, ...@@ -1108,7 +1092,7 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
target_ulong pc_start; target_ulong pc_start;
static uint16_t *gen_opc_end; static uint16_t *gen_opc_end;
uint32_t old_flags; uint32_t old_flags;
int i; int i, ii;
pc_start = tb->pc; pc_start = tb->pc;
gen_opc_ptr = gen_opc_buf; gen_opc_ptr = gen_opc_buf;
...@@ -1135,6 +1119,7 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, ...@@ -1135,6 +1119,7 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
} }
#endif #endif
ii = -1;
while ((old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) == 0 && while ((old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) == 0 &&
(ctx.flags & (BRANCH | BRANCH_CONDITIONAL | MODE_CHANGE | (ctx.flags & (BRANCH | BRANCH_CONDITIONAL | MODE_CHANGE |
BRANCH_EXCEPTION)) == 0 && BRANCH_EXCEPTION)) == 0 &&
...@@ -1151,6 +1136,16 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, ...@@ -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 #if 0
fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc); fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
fflush(stderr); fflush(stderr);
...@@ -1192,7 +1187,15 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, ...@@ -1192,7 +1187,15 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
gen_op_debug(); gen_op_debug();
} }
*gen_opc_ptr = INDEX_op_end; *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 DEBUG_DISAS
#ifdef SH4_DEBUG_DISAS #ifdef SH4_DEBUG_DISAS
...@@ -1220,6 +1223,5 @@ int gen_intermediate_code(CPUState * env, struct TranslationBlock *tb) ...@@ -1220,6 +1223,5 @@ int gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
int gen_intermediate_code_pc(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); return gen_intermediate_code_internal(env, tb, 1);
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册