Commit 355fb23d authored by Paul Brook's avatar Paul Brook
Browse files

SH usermode fault handling.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1988 c046a42c-6fe2-441c-8c8c-71466251a162
parent 9854bc46
Loading
Loading
Loading
Loading
+2 −7
Original line number Diff line number Diff line
@@ -1172,7 +1172,6 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
           a virtual CPU fault */
        cpu_restore_state(tb, env, pc, puc);
    }
    if (ret == 1) {
#if 0
        printf("PF exception: NIP=0x%08x error=0x%x %p\n", 
               env->nip, env->error_code, tb);
@@ -1180,11 +1179,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
    /* we restore the process signal mask as the sigreturn should
       do it (XXX: use sigsetjmp) */
    sigprocmask(SIG_SETMASK, old_set, NULL);
        //        do_raise_exception_err(env->exception_index, env->error_code);
    } else {
        /* activate soft MMU for this block */
        cpu_resume_from_signal(env, puc);
    }
    cpu_loop_exit();
    /* never comes here */
    return 1;
}
+15 −1
Original line number Diff line number Diff line
@@ -1362,7 +1362,7 @@ void cpu_loop(CPUMIPSState *env)
void cpu_loop (CPUState *env)
{
    int trapnr, ret;
    //    target_siginfo_t info;
    target_siginfo_t info;
    
    while (1) {
        trapnr = cpu_sh4_exec (env);
@@ -1380,6 +1380,20 @@ void cpu_loop (CPUState *env)
            env->gregs[0x10] = ret;
            env->pc += 2;
            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:
            printf ("Unhandled trap: 0x%x\n", trapnr);
            cpu_dump_state(env, stderr, fprintf, 0);
+43 −0
Original line number Diff line number Diff line
@@ -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
+21 −19
Original line number Diff line number Diff line
@@ -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;
    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);
}