SH usermode fault handling.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1988 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
9854bc4662
commit
355fb23d83
|
@ -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)
|
||||||
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)
|
||||||
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 @@
|
||||||
#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,
|
||||||
|
|
||||||
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)
|
||||||
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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
#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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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,
|
||||||
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)
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue