40
40
//#define DEBUG_EXEC
41
41
//#define DEBUG_SIGNAL
43
#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_M68K)
44
/* XXX: unify with i386 target */
45
43
void cpu_loop_exit(void)
45
/* NOTE: the register at this point must be saved by hand because
46
longjmp restore them */
47
48
longjmp(env->jmp_env, 1);
50
51
#if !(defined(TARGET_SPARC) || defined(TARGET_SH4) || defined(TARGET_M68K))
197
198
#elif defined(TARGET_M68K)
198
flags = env->fpcr & M68K_FPCR_PREC;
199
flags = (env->fpcr & M68K_FPCR_PREC) /* Bit 6 */
200
| (env->sr & SR_S) /* Bit 13 */
201
| ((env->macsr >> 4) & 0xf); /* Bits 0-3 */
201
204
#elif defined(TARGET_SH4)
202
205
flags = env->sr & (SR_MD | SR_RB);
203
206
cs_base = 0; /* XXXXX */
208
#elif defined(TARGET_ALPHA)
206
213
#error unsupported CPU
242
249
TranslationBlock *tb;
245
#if defined(TARGET_I386)
246
/* handle exit of HALTED state */
247
if (env1->hflags & HF_HALTED_MASK) {
248
/* disable halt condition */
249
if ((env1->interrupt_request & CPU_INTERRUPT_HARD) &&
250
(env1->eflags & IF_MASK)) {
251
env1->hflags &= ~HF_HALTED_MASK;
256
#elif defined(TARGET_PPC)
258
if (env1->msr[MSR_EE] &&
259
(env1->interrupt_request &
260
(CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER))) {
266
#elif defined(TARGET_SPARC)
268
if ((env1->interrupt_request & CPU_INTERRUPT_HARD) &&
269
(env1->psret != 0)) {
275
#elif defined(TARGET_ARM)
277
/* An interrupt wakes the CPU even if the I and F CPSR bits are
279
if (env1->interrupt_request
280
& (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD)) {
286
#elif defined(TARGET_MIPS)
288
if (env1->interrupt_request &
289
(CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER)) {
252
if (cpu_halted(env1) == EXCP_HALTED)
297
255
cpu_single_env = env1;
305
263
asm volatile ("mov %%i7, %0" : "=r" (saved_i7));
308
#if defined(TARGET_I386)
267
#if defined(TARGET_I386)
310
268
/* put eflags in CPU temporary format */
311
269
CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
312
270
DF = 1 - (2 * ((env->eflags >> 10) & 1));
313
271
CC_OP = CC_OP_EFLAGS;
314
272
env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
315
#elif defined(TARGET_ARM)
316
273
#elif defined(TARGET_SPARC)
317
274
#if defined(reg_REGWPTR)
318
275
saved_regwptr = REGWPTR;
320
#elif defined(TARGET_PPC)
321
277
#elif defined(TARGET_M68K)
322
278
env->cc_op = CC_OP_FLAGS;
323
279
env->cc_dest = env->sr & 0xf;
324
280
env->cc_x = (env->sr >> 4) & 1;
281
#elif defined(TARGET_ALPHA)
282
#elif defined(TARGET_ARM)
283
#elif defined(TARGET_PPC)
325
284
#elif defined(TARGET_MIPS)
326
285
#elif defined(TARGET_SH4)
361
320
env->exception_is_int,
363
322
env->exception_next_eip, 0);
323
/* successfully delivered */
324
env->old_exception = -1;
364
325
#elif defined(TARGET_PPC)
365
326
do_interrupt(env);
366
327
#elif defined(TARGET_MIPS)
410
375
interrupt_request = env->interrupt_request;
411
376
if (__builtin_expect(interrupt_request, 0)) {
377
if (interrupt_request & CPU_INTERRUPT_DEBUG) {
378
env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
379
env->exception_index = EXCP_DEBUG;
382
#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
383
defined(TARGET_PPC) || defined(TARGET_ALPHA)
384
if (interrupt_request & CPU_INTERRUPT_HALT) {
385
env->interrupt_request &= ~CPU_INTERRUPT_HALT;
387
env->exception_index = EXCP_HLT;
412
391
#if defined(TARGET_I386)
413
392
if ((interrupt_request & CPU_INTERRUPT_SMI) &&
414
393
!(env->hflags & HF_SMM_MASK)) {
443
422
cpu_ppc_reset(env);
447
if ((interrupt_request & CPU_INTERRUPT_HARD)) {
449
env->exception_index = EXCP_EXTERNAL;
425
if (interrupt_request & CPU_INTERRUPT_HARD) {
426
ppc_hw_interrupt(env);
427
if (env->pending_interrupts == 0)
452
428
env->interrupt_request &= ~CPU_INTERRUPT_HARD;
453
429
#if defined(__sparc__) && !defined(HOST_SOLARIS)
458
} else if ((interrupt_request & CPU_INTERRUPT_TIMER)) {
460
env->exception_index = EXCP_DECR;
463
env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
464
#if defined(__sparc__) && !defined(HOST_SOLARIS)
471
435
#elif defined(TARGET_MIPS)
472
436
if ((interrupt_request & CPU_INTERRUPT_HARD) &&
437
(env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) &&
473
438
(env->CP0_Status & (1 << CP0St_IE)) &&
474
(env->CP0_Status & env->CP0_Cause & 0x0000FF00) &&
475
!(env->hflags & MIPS_HFLAG_EXL) &&
476
!(env->hflags & MIPS_HFLAG_ERL) &&
439
!(env->CP0_Status & (1 << CP0St_EXL)) &&
440
!(env->CP0_Status & (1 << CP0St_ERL)) &&
477
441
!(env->hflags & MIPS_HFLAG_DM)) {
479
443
env->exception_index = EXCP_EXT_INTERRUPT;
497
461
env->interrupt_request &= ~CPU_INTERRUPT_HARD;
498
462
do_interrupt(env->interrupt_index);
499
463
env->interrupt_index = 0;
464
#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
500
467
#if defined(__sparc__) && !defined(HOST_SOLARIS)
506
473
} else if (interrupt_request & CPU_INTERRUPT_TIMER) {
507
474
//do_interrupt(0, 0, 0, 0, 0);
508
475
env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
509
} else if (interrupt_request & CPU_INTERRUPT_HALT) {
510
env->interrupt_request &= ~CPU_INTERRUPT_HALT;
512
env->exception_index = EXCP_HLT;
515
477
#elif defined(TARGET_ARM)
516
478
if (interrupt_request & CPU_INTERRUPT_FIQ
517
479
&& !(env->uncached_cpsr & CPSR_F)) {
526
488
#elif defined(TARGET_SH4)
490
#elif defined(TARGET_ALPHA)
491
if (interrupt_request & CPU_INTERRUPT_HARD) {
494
#elif defined(TARGET_M68K)
495
if (interrupt_request & CPU_INTERRUPT_HARD
496
&& ((env->sr & SR_I) >> SR_I_SHIFT)
497
< env->pending_level) {
498
/* Real hardware gets the interrupt vector via an
499
IACK cycle at this point. Current emulated
500
hardware doesn't rely on this, so we
501
provide/save the vector when the interrupt is
503
env->exception_index = env->pending_vector;
529
507
/* Don't use the cached interupt_request value,
530
508
do_interrupt may have updated the EXITTB flag. */
547
525
#ifdef DEBUG_EXEC
548
526
if ((loglevel & CPU_LOG_TB_CPU)) {
549
#if defined(TARGET_I386)
550
527
/* restore flags in standard format */
552
env->regs[R_EAX] = EAX;
555
env->regs[R_EBX] = EBX;
558
env->regs[R_ECX] = ECX;
561
env->regs[R_EDX] = EDX;
564
env->regs[R_ESI] = ESI;
567
env->regs[R_EDI] = EDI;
570
env->regs[R_EBP] = EBP;
573
env->regs[R_ESP] = ESP;
529
#if defined(TARGET_I386)
575
530
env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
576
531
cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
577
532
env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
593
548
cpu_dump_state(env, logfile, fprintf, 0);
594
549
#elif defined(TARGET_SH4)
595
550
cpu_dump_state(env, logfile, fprintf, 0);
551
#elif defined(TARGET_ALPHA)
552
cpu_dump_state(env, logfile, fprintf, 0);
597
554
#error unsupported target CPU
643
600
: /* no outputs */
645
602
: "i0", "i1", "i2", "i3", "i4", "i5",
603
"o0", "o1", "o2", "o3", "o4", "o5",
646
604
"l0", "l1", "l2", "l3", "l4", "l5",
648
606
#elif defined(__arm__)
784
742
| env->cc_dest | (env->cc_x << 4);
785
743
#elif defined(TARGET_MIPS)
786
744
#elif defined(TARGET_SH4)
745
#elif defined(TARGET_ALPHA)
789
748
#error unsupported target CPU
1112
1071
if (ret == 1) {
1114
printf("PF exception: NIP=0x%08x error=0x%x %p\n",
1115
env->nip, env->error_code, tb);
1073
printf("PF exception: PC=0x" TARGET_FMT_lx " error=0x%x %p\n",
1074
env->PC, env->error_code, tb);
1117
1076
/* we restore the process signal mask as the sigreturn should
1118
1077
do it (XXX: use sigsetjmp) */
1170
1129
/* never comes here */
1133
#elif defined (TARGET_ALPHA)
1134
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1135
int is_write, sigset_t *old_set,
1138
TranslationBlock *tb;
1142
env = cpu_single_env; /* XXX: find a correct solution for multithread */
1143
#if defined(DEBUG_SIGNAL)
1144
printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
1145
pc, address, is_write, *(unsigned long *)old_set);
1147
/* XXX: locking issue */
1148
if (is_write && page_unprotect(h2g(address), pc, puc)) {
1152
/* see if it is an MMU fault */
1153
ret = cpu_alpha_handle_mmu_fault(env, address, is_write, 1, 0);
1155
return 0; /* not an MMU fault */
1157
return 1; /* the MMU fault was handled without causing real CPU fault */
1159
/* now we have a real cpu fault */
1160
tb = tb_find_pc(pc);
1162
/* the PC is inside the translated code. It means that we have
1163
a virtual CPU fault */
1164
cpu_restore_state(tb, env, pc, puc);
1167
printf("PF exception: NIP=0x%08x error=0x%x %p\n",
1168
env->nip, env->error_code, tb);
1170
/* we restore the process signal mask as the sigreturn should
1171
do it (XXX: use sigsetjmp) */
1172
sigprocmask(SIG_SETMASK, old_set, NULL);
1174
/* never comes here */
1174
1178
#error unsupported target CPU
1474
1478
/* XXX: compute is_write */
1476
1480
return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1478
&uc->uc_sigmask, puc);
1481
is_write, &uc->uc_sigmask, puc);
1484
#elif defined(__mips__)
1486
int cpu_signal_handler(int host_signum, void *pinfo,
1489
siginfo_t *info = pinfo;
1490
struct ucontext *uc = puc;
1491
greg_t pc = uc->uc_mcontext.pc;
1494
/* XXX: compute is_write */
1496
return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1497
is_write, &uc->uc_sigmask, puc);