longjmp(env->jmp_env, 1);
}
#endif
-#ifndef TARGET_SPARC
+#if !(defined(TARGET_SPARC) || defined(TARGET_SH4))
#define reg_T2
#endif
pc = env->regs[15];
#elif defined(TARGET_SPARC)
#ifdef TARGET_SPARC64
- flags = (env->pstate << 2) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);
+ // Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled
+ flags = (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2))
+ | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);
#else
- flags = env->psrs | ((env->mmuregs[0] & (MMU_E | MMU_NF)) << 1);
+ // FPU enable . MMU enabled . MMU no-fault . Supervisor
+ flags = (env->psref << 3) | ((env->mmuregs[0] & (MMU_E | MMU_NF)) << 1)
+ | env->psrs;
#endif
cs_base = env->npc;
pc = env->pc;
cs_base = 0;
pc = env->nip;
#elif defined(TARGET_MIPS)
- flags = env->hflags & (MIPS_HFLAGS_TMASK | MIPS_HFLAG_BMASK);
+ flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
cs_base = 0;
pc = env->PC;
+#elif defined(TARGET_SH4)
+ flags = env->sr & (SR_MD | SR_RB);
+ cs_base = 0; /* XXXXX */
+ pc = env->pc;
#else
#error unsupported CPU
#endif
uint32_t *saved_regwptr;
#endif
#endif
-#ifdef __sparc__
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
int saved_i7, tmp_T0;
#endif
int ret, interrupt_request;
#if defined(reg_T2)
saved_T2 = T2;
#endif
-#ifdef __sparc__
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
/* we also save i7 because longjmp may not restore it */
asm volatile ("mov %%i7, %0" : "=r" (saved_i7));
#endif
#endif
#elif defined(TARGET_PPC)
#elif defined(TARGET_MIPS)
+#elif defined(TARGET_SH4)
+ /* XXXXX */
#else
#error unsupported target CPU
#endif
do_interrupt(env->exception_index);
#elif defined(TARGET_ARM)
do_interrupt(env);
+#elif defined(TARGET_SH4)
+ do_interrupt(env);
#endif
}
env->exception_index = -1;
T0 = 0; /* force lookup of first TB */
for(;;) {
-#ifdef __sparc__
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
/* g1 can be modified by some libc? functions */
tmp_T0 = T0;
#endif
do_interrupt(intno, 0, 0, 0, 1);
/* ensure that no TB jump will be modified as
the program flow was changed */
-#ifdef __sparc__
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
tmp_T0 = 0;
#else
T0 = 0;
env->error_code = 0;
do_interrupt(env);
env->interrupt_request &= ~CPU_INTERRUPT_HARD;
-#ifdef __sparc__
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
tmp_T0 = 0;
#else
T0 = 0;
env->error_code = 0;
do_interrupt(env);
env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
-#ifdef __sparc__
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
tmp_T0 = 0;
#else
T0 = 0;
env->error_code = 0;
do_interrupt(env);
env->interrupt_request &= ~CPU_INTERRUPT_HARD;
-#ifdef __sparc__
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
tmp_T0 = 0;
#else
T0 = 0;
env->interrupt_request &= ~CPU_INTERRUPT_HARD;
do_interrupt(env->interrupt_index);
env->interrupt_index = 0;
-#ifdef __sparc__
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
tmp_T0 = 0;
#else
T0 = 0;
env->exception_index = EXCP_IRQ;
do_interrupt(env);
}
+#elif defined(TARGET_SH4)
+ /* XXXXX */
#endif
+ /* Don't use the cached interupt_request value,
+ do_interrupt may have updated the EXITTB flag. */
if (env->interrupt_request & CPU_INTERRUPT_EXITTB) {
env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
/* ensure that no TB jump will be modified as
the program flow was changed */
-#ifdef __sparc__
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
tmp_T0 = 0;
#else
T0 = 0;
cpu_dump_state(env, logfile, fprintf, 0);
#elif defined(TARGET_MIPS)
cpu_dump_state(env, logfile, fprintf, 0);
+#elif defined(TARGET_SH4)
+ cpu_dump_state(env, logfile, fprintf, 0);
#else
#error unsupported target CPU
#endif
lookup_symbol(tb->pc));
}
#endif
-#ifdef __sparc__
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
T0 = tmp_T0;
#endif
/* see if we can patch the calling TB. When the TB
"mov %%o7,%%i0"
: /* no outputs */
: "r" (gen_func)
- : "i0", "i1", "i2", "i3", "i4", "i5");
+ : "i0", "i1", "i2", "i3", "i4", "i5",
+ "l0", "l1", "l2", "l3", "l4", "l5",
+ "l6", "l7");
#elif defined(__arm__)
asm volatile ("mov pc, %0\n\t"
".global exec_loop\n\t"
#endif
#elif defined(TARGET_PPC)
#elif defined(TARGET_MIPS)
+#elif defined(TARGET_SH4)
+ /* XXXXX */
#else
#error unsupported target CPU
#endif
-#ifdef __sparc__
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
asm volatile ("mov %0, %%i7" : : "r" (saved_i7));
#endif
T0 = saved_T0;
pc, address, is_write, *(unsigned long *)old_set);
#endif
/* XXX: locking issue */
- if (is_write && page_unprotect(address, pc, puc)) {
+ if (is_write && page_unprotect(h2g(address), pc, puc)) {
return 1;
}
pc, address, is_write, *(unsigned long *)old_set);
#endif
/* XXX: locking issue */
- if (is_write && page_unprotect(address, pc, puc)) {
+ if (is_write && page_unprotect(h2g(address), pc, puc)) {
return 1;
}
/* see if it is an MMU fault */
pc, address, is_write, *(unsigned long *)old_set);
#endif
/* XXX: locking issue */
- if (is_write && page_unprotect(address, pc, puc)) {
+ if (is_write && page_unprotect(h2g(address), pc, puc)) {
return 1;
}
/* see if it is an MMU fault */
pc, address, is_write, *(unsigned long *)old_set);
#endif
/* XXX: locking issue */
- if (is_write && page_unprotect(address, pc, puc)) {
+ if (is_write && page_unprotect(h2g(address), pc, puc)) {
return 1;
}
pc, address, is_write, *(unsigned long *)old_set);
#endif
/* XXX: locking issue */
- if (is_write && page_unprotect(address, pc, puc)) {
+ if (is_write && page_unprotect(h2g(address), pc, puc)) {
return 1;
}
return 1;
}
+#elif defined (TARGET_SH4)
+static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
+ int is_write, sigset_t *old_set,
+ void *puc)
+{
+ TranslationBlock *tb;
+ int ret;
+
+ if (cpu_single_env)
+ env = cpu_single_env; /* XXX: find a correct solution for multithread */
+#if defined(DEBUG_SIGNAL)
+ printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
+ pc, address, is_write, *(unsigned long *)old_set);
+#endif
+ /* XXX: locking issue */
+ if (is_write && page_unprotect(h2g(address), pc, puc)) {
+ return 1;
+ }
+
+ /* see if it is an MMU fault */
+ ret = cpu_sh4_handle_mmu_fault(env, address, is_write, 1, 0);
+ if (ret < 0)
+ return 0; /* not an MMU fault */
+ if (ret == 0)
+ return 1; /* the MMU fault was handled without causing real CPU fault */
+
+ /* now we have a real cpu fault */
+ tb = tb_find_pc(pc);
+ if (tb) {
+ /* the PC is inside the translated code. It means that we have
+ a virtual CPU fault */
+ cpu_restore_state(tb, env, pc, puc);
+ }
+#if 0
+ printf("PF exception: NIP=0x%08x error=0x%x %p\n",
+ env->nip, env->error_code, tb);
+#endif
+ /* we restore the process signal mask as the sigreturn should
+ do it (XXX: use sigsetjmp) */
+ sigprocmask(SIG_SETMASK, old_set, NULL);
+ cpu_loop_exit();
+ /* never comes here */
+ return 1;
+}
#else
#error unsupported target CPU
#endif
is_write = 0;
return handle_cpu_signal(pc, (unsigned long)info->si_addr,
is_write,
- &uc->uc_sigmask);
+ &uc->uc_sigmask, puc);
}
#elif defined(__mc68000)
#ifndef __ISR_VALID
/* This ought to be in <bits/siginfo.h>... */
# define __ISR_VALID 1
-# define si_flags _sifields._sigfault._si_pad0
#endif
int cpu_signal_handler(int host_signum, struct siginfo *info, void *puc)
case SIGSEGV:
case SIGBUS:
case SIGTRAP:
- if (info->si_code && (info->si_flags & __ISR_VALID))
+ if (info->si_code && (info->si_segvflags & __ISR_VALID))
/* ISR.W (write-access) is bit 33: */
is_write = (info->si_isr >> 33) & 1;
break;