Get rid of user_mode_only
[qemu] / cpu-exec.c
1 /*
2  *  i386 emulator main execution loop
3  *
4  *  Copyright (c) 2003-2005 Fabrice Bellard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
19  */
20 #include "config.h"
21 #define CPU_NO_GLOBAL_REGS
22 #include "exec.h"
23 #include "disas.h"
24 #include "tcg.h"
25 #include "kvm.h"
26
27 #if !defined(CONFIG_SOFTMMU)
28 #undef EAX
29 #undef ECX
30 #undef EDX
31 #undef EBX
32 #undef ESP
33 #undef EBP
34 #undef ESI
35 #undef EDI
36 #undef EIP
37 #include <signal.h>
38 #ifdef __linux__
39 #include <sys/ucontext.h>
40 #endif
41 #endif
42
43 #if defined(__sparc__) && !defined(HOST_SOLARIS)
44 // Work around ugly bugs in glibc that mangle global register contents
45 #undef env
46 #define env cpu_single_env
47 #endif
48
49 int tb_invalidated_flag;
50
51 //#define DEBUG_EXEC
52 //#define DEBUG_SIGNAL
53
54 void cpu_loop_exit(void)
55 {
56     /* NOTE: the register at this point must be saved by hand because
57        longjmp restore them */
58     regs_to_env();
59     longjmp(env->jmp_env, 1);
60 }
61
62 /* exit the current TB from a signal handler. The host registers are
63    restored in a state compatible with the CPU emulator
64  */
65 void cpu_resume_from_signal(CPUState *env1, void *puc)
66 {
67 #if !defined(CONFIG_SOFTMMU)
68 #ifdef __linux__
69     struct ucontext *uc = puc;
70 #elif defined(__OpenBSD__)
71     struct sigcontext *uc = puc;
72 #endif
73 #endif
74
75     env = env1;
76
77     /* XXX: restore cpu registers saved in host registers */
78
79 #if !defined(CONFIG_SOFTMMU)
80     if (puc) {
81         /* XXX: use siglongjmp ? */
82 #ifdef __linux__
83         sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
84 #elif defined(__OpenBSD__)
85         sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL);
86 #endif
87     }
88 #endif
89     env->exception_index = -1;
90     longjmp(env->jmp_env, 1);
91 }
92
93 /* Execute the code without caching the generated code. An interpreter
94    could be used if available. */
95 static void cpu_exec_nocache(int max_cycles, TranslationBlock *orig_tb)
96 {
97     unsigned long next_tb;
98     TranslationBlock *tb;
99
100     /* Should never happen.
101        We only end up here when an existing TB is too long.  */
102     if (max_cycles > CF_COUNT_MASK)
103         max_cycles = CF_COUNT_MASK;
104
105     tb = tb_gen_code(env, orig_tb->pc, orig_tb->cs_base, orig_tb->flags,
106                      max_cycles);
107     env->current_tb = tb;
108     /* execute the generated code */
109     next_tb = tcg_qemu_tb_exec(tb->tc_ptr);
110
111     if ((next_tb & 3) == 2) {
112         /* Restore PC.  This may happen if async event occurs before
113            the TB starts executing.  */
114         cpu_pc_from_tb(env, tb);
115     }
116     tb_phys_invalidate(tb, -1);
117     tb_free(tb);
118 }
119
120 static TranslationBlock *tb_find_slow(target_ulong pc,
121                                       target_ulong cs_base,
122                                       uint64_t flags)
123 {
124     TranslationBlock *tb, **ptb1;
125     unsigned int h;
126     target_ulong phys_pc, phys_page1, phys_page2, virt_page2;
127
128     tb_invalidated_flag = 0;
129
130     regs_to_env(); /* XXX: do it just before cpu_gen_code() */
131
132     /* find translated block using physical mappings */
133     phys_pc = get_phys_addr_code(env, pc);
134     phys_page1 = phys_pc & TARGET_PAGE_MASK;
135     phys_page2 = -1;
136     h = tb_phys_hash_func(phys_pc);
137     ptb1 = &tb_phys_hash[h];
138     for(;;) {
139         tb = *ptb1;
140         if (!tb)
141             goto not_found;
142         if (tb->pc == pc &&
143             tb->page_addr[0] == phys_page1 &&
144             tb->cs_base == cs_base &&
145             tb->flags == flags) {
146             /* check next page if needed */
147             if (tb->page_addr[1] != -1) {
148                 virt_page2 = (pc & TARGET_PAGE_MASK) +
149                     TARGET_PAGE_SIZE;
150                 phys_page2 = get_phys_addr_code(env, virt_page2);
151                 if (tb->page_addr[1] == phys_page2)
152                     goto found;
153             } else {
154                 goto found;
155             }
156         }
157         ptb1 = &tb->phys_hash_next;
158     }
159  not_found:
160    /* if no translated code available, then translate it now */
161     tb = tb_gen_code(env, pc, cs_base, flags, 0);
162
163  found:
164     /* we add the TB in the virtual pc hash table */
165     env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
166     return tb;
167 }
168
169 static inline TranslationBlock *tb_find_fast(void)
170 {
171     TranslationBlock *tb;
172     target_ulong cs_base, pc;
173     int flags;
174
175     /* we record a subset of the CPU state. It will
176        always be the same before a given translated block
177        is executed. */
178     cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
179     tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
180     if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
181                  tb->flags != flags)) {
182         tb = tb_find_slow(pc, cs_base, flags);
183     }
184     return tb;
185 }
186
187 static CPUDebugExcpHandler *debug_excp_handler;
188
189 CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler)
190 {
191     CPUDebugExcpHandler *old_handler = debug_excp_handler;
192
193     debug_excp_handler = handler;
194     return old_handler;
195 }
196
197 static void cpu_handle_debug_exception(CPUState *env)
198 {
199     CPUWatchpoint *wp;
200
201     if (!env->watchpoint_hit)
202         TAILQ_FOREACH(wp, &env->watchpoints, entry)
203             wp->flags &= ~BP_WATCHPOINT_HIT;
204
205     if (debug_excp_handler)
206         debug_excp_handler(env);
207 }
208
209 /* main execution loop */
210
211 int cpu_exec(CPUState *env1)
212 {
213 #define DECLARE_HOST_REGS 1
214 #include "hostregs_helper.h"
215     int ret, interrupt_request;
216     TranslationBlock *tb;
217     uint8_t *tc_ptr;
218     unsigned long next_tb;
219
220     if (cpu_halted(env1) == EXCP_HALTED)
221         return EXCP_HALTED;
222
223     cpu_single_env = env1;
224
225     /* first we save global registers */
226 #define SAVE_HOST_REGS 1
227 #include "hostregs_helper.h"
228     env = env1;
229
230     env_to_regs();
231 #if defined(TARGET_I386)
232     /* put eflags in CPU temporary format */
233     CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
234     DF = 1 - (2 * ((env->eflags >> 10) & 1));
235     CC_OP = CC_OP_EFLAGS;
236     env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
237 #elif defined(TARGET_SPARC)
238 #elif defined(TARGET_M68K)
239     env->cc_op = CC_OP_FLAGS;
240     env->cc_dest = env->sr & 0xf;
241     env->cc_x = (env->sr >> 4) & 1;
242 #elif defined(TARGET_ALPHA)
243 #elif defined(TARGET_ARM)
244 #elif defined(TARGET_PPC)
245 #elif defined(TARGET_MIPS)
246 #elif defined(TARGET_SH4)
247 #elif defined(TARGET_CRIS)
248     /* XXXXX */
249 #else
250 #error unsupported target CPU
251 #endif
252     env->exception_index = -1;
253
254     /* prepare setjmp context for exception handling */
255     for(;;) {
256         if (setjmp(env->jmp_env) == 0) {
257             env->current_tb = NULL;
258             /* if an exception is pending, we execute it here */
259             if (env->exception_index >= 0) {
260                 if (env->exception_index >= EXCP_INTERRUPT) {
261                     /* exit request from the cpu execution loop */
262                     ret = env->exception_index;
263                     if (ret == EXCP_DEBUG)
264                         cpu_handle_debug_exception(env);
265                     break;
266                 } else {
267 #if defined(CONFIG_USER_ONLY)
268                     /* if user mode only, we simulate a fake exception
269                        which will be handled outside the cpu execution
270                        loop */
271 #if defined(TARGET_I386)
272                     do_interrupt_user(env->exception_index,
273                                       env->exception_is_int,
274                                       env->error_code,
275                                       env->exception_next_eip);
276                     /* successfully delivered */
277                     env->old_exception = -1;
278 #endif
279                     ret = env->exception_index;
280                     break;
281 #else
282 #if defined(TARGET_I386)
283                     /* simulate a real cpu exception. On i386, it can
284                        trigger new exceptions, but we do not handle
285                        double or triple faults yet. */
286                     do_interrupt(env->exception_index,
287                                  env->exception_is_int,
288                                  env->error_code,
289                                  env->exception_next_eip, 0);
290                     /* successfully delivered */
291                     env->old_exception = -1;
292 #elif defined(TARGET_PPC)
293                     do_interrupt(env);
294 #elif defined(TARGET_MIPS)
295                     do_interrupt(env);
296 #elif defined(TARGET_SPARC)
297                     do_interrupt(env);
298 #elif defined(TARGET_ARM)
299                     do_interrupt(env);
300 #elif defined(TARGET_SH4)
301                     do_interrupt(env);
302 #elif defined(TARGET_ALPHA)
303                     do_interrupt(env);
304 #elif defined(TARGET_CRIS)
305                     do_interrupt(env);
306 #elif defined(TARGET_M68K)
307                     do_interrupt(0);
308 #endif
309 #endif
310                 }
311                 env->exception_index = -1;
312             }
313 #ifdef USE_KQEMU
314             if (kqemu_is_ok(env) && env->interrupt_request == 0) {
315                 int ret;
316                 env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
317                 ret = kqemu_cpu_exec(env);
318                 /* put eflags in CPU temporary format */
319                 CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
320                 DF = 1 - (2 * ((env->eflags >> 10) & 1));
321                 CC_OP = CC_OP_EFLAGS;
322                 env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
323                 if (ret == 1) {
324                     /* exception */
325                     longjmp(env->jmp_env, 1);
326                 } else if (ret == 2) {
327                     /* softmmu execution needed */
328                 } else {
329                     if (env->interrupt_request != 0) {
330                         /* hardware interrupt will be executed just after */
331                     } else {
332                         /* otherwise, we restart */
333                         longjmp(env->jmp_env, 1);
334                     }
335                 }
336             }
337 #endif
338
339             if (kvm_enabled()) {
340                 kvm_cpu_exec(env);
341                 longjmp(env->jmp_env, 1);
342             }
343
344             next_tb = 0; /* force lookup of first TB */
345             for(;;) {
346                 interrupt_request = env->interrupt_request;
347                 if (unlikely(interrupt_request)) {
348                     if (unlikely(env->singlestep_enabled & SSTEP_NOIRQ)) {
349                         /* Mask out external interrupts for this step. */
350                         interrupt_request &= ~(CPU_INTERRUPT_HARD |
351                                                CPU_INTERRUPT_FIQ |
352                                                CPU_INTERRUPT_SMI |
353                                                CPU_INTERRUPT_NMI);
354                     }
355                     if (interrupt_request & CPU_INTERRUPT_DEBUG) {
356                         env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
357                         env->exception_index = EXCP_DEBUG;
358                         cpu_loop_exit();
359                     }
360 #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
361     defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS)
362                     if (interrupt_request & CPU_INTERRUPT_HALT) {
363                         env->interrupt_request &= ~CPU_INTERRUPT_HALT;
364                         env->halted = 1;
365                         env->exception_index = EXCP_HLT;
366                         cpu_loop_exit();
367                     }
368 #endif
369 #if defined(TARGET_I386)
370                     if (env->hflags2 & HF2_GIF_MASK) {
371                         if ((interrupt_request & CPU_INTERRUPT_SMI) &&
372                             !(env->hflags & HF_SMM_MASK)) {
373                             svm_check_intercept(SVM_EXIT_SMI);
374                             env->interrupt_request &= ~CPU_INTERRUPT_SMI;
375                             do_smm_enter();
376                             next_tb = 0;
377                         } else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
378                                    !(env->hflags2 & HF2_NMI_MASK)) {
379                             env->interrupt_request &= ~CPU_INTERRUPT_NMI;
380                             env->hflags2 |= HF2_NMI_MASK;
381                             do_interrupt(EXCP02_NMI, 0, 0, 0, 1);
382                             next_tb = 0;
383                         } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
384                                    (((env->hflags2 & HF2_VINTR_MASK) && 
385                                      (env->hflags2 & HF2_HIF_MASK)) ||
386                                     (!(env->hflags2 & HF2_VINTR_MASK) && 
387                                      (env->eflags & IF_MASK && 
388                                       !(env->hflags & HF_INHIBIT_IRQ_MASK))))) {
389                             int intno;
390                             svm_check_intercept(SVM_EXIT_INTR);
391                             env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
392                             intno = cpu_get_pic_interrupt(env);
393                             if (loglevel & CPU_LOG_TB_IN_ASM) {
394                                 fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno);
395                             }
396                             do_interrupt(intno, 0, 0, 0, 1);
397                             /* ensure that no TB jump will be modified as
398                                the program flow was changed */
399                             next_tb = 0;
400 #if !defined(CONFIG_USER_ONLY)
401                         } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
402                                    (env->eflags & IF_MASK) && 
403                                    !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
404                             int intno;
405                             /* FIXME: this should respect TPR */
406                             svm_check_intercept(SVM_EXIT_VINTR);
407                             intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
408                             if (loglevel & CPU_LOG_TB_IN_ASM)
409                                 fprintf(logfile, "Servicing virtual hardware INT=0x%02x\n", intno);
410                             do_interrupt(intno, 0, 0, 0, 1);
411                             env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
412                             next_tb = 0;
413 #endif
414                         }
415                     }
416 #elif defined(TARGET_PPC)
417 #if 0
418                     if ((interrupt_request & CPU_INTERRUPT_RESET)) {
419                         cpu_ppc_reset(env);
420                     }
421 #endif
422                     if (interrupt_request & CPU_INTERRUPT_HARD) {
423                         ppc_hw_interrupt(env);
424                         if (env->pending_interrupts == 0)
425                             env->interrupt_request &= ~CPU_INTERRUPT_HARD;
426                         next_tb = 0;
427                     }
428 #elif defined(TARGET_MIPS)
429                     if ((interrupt_request & CPU_INTERRUPT_HARD) &&
430                         (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) &&
431                         (env->CP0_Status & (1 << CP0St_IE)) &&
432                         !(env->CP0_Status & (1 << CP0St_EXL)) &&
433                         !(env->CP0_Status & (1 << CP0St_ERL)) &&
434                         !(env->hflags & MIPS_HFLAG_DM)) {
435                         /* Raise it */
436                         env->exception_index = EXCP_EXT_INTERRUPT;
437                         env->error_code = 0;
438                         do_interrupt(env);
439                         next_tb = 0;
440                     }
441 #elif defined(TARGET_SPARC)
442                     if ((interrupt_request & CPU_INTERRUPT_HARD) &&
443                         (env->psret != 0)) {
444                         int pil = env->interrupt_index & 15;
445                         int type = env->interrupt_index & 0xf0;
446
447                         if (((type == TT_EXTINT) &&
448                              (pil == 15 || pil > env->psrpil)) ||
449                             type != TT_EXTINT) {
450                             env->interrupt_request &= ~CPU_INTERRUPT_HARD;
451                             env->exception_index = env->interrupt_index;
452                             do_interrupt(env);
453                             env->interrupt_index = 0;
454 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
455                             cpu_check_irqs(env);
456 #endif
457                         next_tb = 0;
458                         }
459                     } else if (interrupt_request & CPU_INTERRUPT_TIMER) {
460                         //do_interrupt(0, 0, 0, 0, 0);
461                         env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
462                     }
463 #elif defined(TARGET_ARM)
464                     if (interrupt_request & CPU_INTERRUPT_FIQ
465                         && !(env->uncached_cpsr & CPSR_F)) {
466                         env->exception_index = EXCP_FIQ;
467                         do_interrupt(env);
468                         next_tb = 0;
469                     }
470                     /* ARMv7-M interrupt return works by loading a magic value
471                        into the PC.  On real hardware the load causes the
472                        return to occur.  The qemu implementation performs the
473                        jump normally, then does the exception return when the
474                        CPU tries to execute code at the magic address.
475                        This will cause the magic PC value to be pushed to
476                        the stack if an interrupt occured at the wrong time.
477                        We avoid this by disabling interrupts when
478                        pc contains a magic address.  */
479                     if (interrupt_request & CPU_INTERRUPT_HARD
480                         && ((IS_M(env) && env->regs[15] < 0xfffffff0)
481                             || !(env->uncached_cpsr & CPSR_I))) {
482                         env->exception_index = EXCP_IRQ;
483                         do_interrupt(env);
484                         next_tb = 0;
485                     }
486 #elif defined(TARGET_SH4)
487                     if (interrupt_request & CPU_INTERRUPT_HARD) {
488                         do_interrupt(env);
489                         next_tb = 0;
490                     }
491 #elif defined(TARGET_ALPHA)
492                     if (interrupt_request & CPU_INTERRUPT_HARD) {
493                         do_interrupt(env);
494                         next_tb = 0;
495                     }
496 #elif defined(TARGET_CRIS)
497                     if (interrupt_request & CPU_INTERRUPT_HARD
498                         && (env->pregs[PR_CCS] & I_FLAG)) {
499                         env->exception_index = EXCP_IRQ;
500                         do_interrupt(env);
501                         next_tb = 0;
502                     }
503                     if (interrupt_request & CPU_INTERRUPT_NMI
504                         && (env->pregs[PR_CCS] & M_FLAG)) {
505                         env->exception_index = EXCP_NMI;
506                         do_interrupt(env);
507                         next_tb = 0;
508                     }
509 #elif defined(TARGET_M68K)
510                     if (interrupt_request & CPU_INTERRUPT_HARD
511                         && ((env->sr & SR_I) >> SR_I_SHIFT)
512                             < env->pending_level) {
513                         /* Real hardware gets the interrupt vector via an
514                            IACK cycle at this point.  Current emulated
515                            hardware doesn't rely on this, so we
516                            provide/save the vector when the interrupt is
517                            first signalled.  */
518                         env->exception_index = env->pending_vector;
519                         do_interrupt(1);
520                         next_tb = 0;
521                     }
522 #endif
523                    /* Don't use the cached interupt_request value,
524                       do_interrupt may have updated the EXITTB flag. */
525                     if (env->interrupt_request & CPU_INTERRUPT_EXITTB) {
526                         env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
527                         /* ensure that no TB jump will be modified as
528                            the program flow was changed */
529                         next_tb = 0;
530                     }
531                     if (interrupt_request & CPU_INTERRUPT_EXIT) {
532                         env->interrupt_request &= ~CPU_INTERRUPT_EXIT;
533                         env->exception_index = EXCP_INTERRUPT;
534                         cpu_loop_exit();
535                     }
536                 }
537 #ifdef DEBUG_EXEC
538                 if ((loglevel & CPU_LOG_TB_CPU)) {
539                     /* restore flags in standard format */
540                     regs_to_env();
541 #if defined(TARGET_I386)
542                     env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
543                     cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
544                     env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
545 #elif defined(TARGET_ARM)
546                     cpu_dump_state(env, logfile, fprintf, 0);
547 #elif defined(TARGET_SPARC)
548                     cpu_dump_state(env, logfile, fprintf, 0);
549 #elif defined(TARGET_PPC)
550                     cpu_dump_state(env, logfile, fprintf, 0);
551 #elif defined(TARGET_M68K)
552                     cpu_m68k_flush_flags(env, env->cc_op);
553                     env->cc_op = CC_OP_FLAGS;
554                     env->sr = (env->sr & 0xffe0)
555                               | env->cc_dest | (env->cc_x << 4);
556                     cpu_dump_state(env, logfile, fprintf, 0);
557 #elif defined(TARGET_MIPS)
558                     cpu_dump_state(env, logfile, fprintf, 0);
559 #elif defined(TARGET_SH4)
560                     cpu_dump_state(env, logfile, fprintf, 0);
561 #elif defined(TARGET_ALPHA)
562                     cpu_dump_state(env, logfile, fprintf, 0);
563 #elif defined(TARGET_CRIS)
564                     cpu_dump_state(env, logfile, fprintf, 0);
565 #else
566 #error unsupported target CPU
567 #endif
568                 }
569 #endif
570                 spin_lock(&tb_lock);
571                 tb = tb_find_fast();
572                 /* Note: we do it here to avoid a gcc bug on Mac OS X when
573                    doing it in tb_find_slow */
574                 if (tb_invalidated_flag) {
575                     /* as some TB could have been invalidated because
576                        of memory exceptions while generating the code, we
577                        must recompute the hash index here */
578                     next_tb = 0;
579                     tb_invalidated_flag = 0;
580                 }
581 #ifdef DEBUG_EXEC
582                 if ((loglevel & CPU_LOG_EXEC)) {
583                     fprintf(logfile, "Trace 0x%08lx [" TARGET_FMT_lx "] %s\n",
584                             (long)tb->tc_ptr, tb->pc,
585                             lookup_symbol(tb->pc));
586                 }
587 #endif
588                 /* see if we can patch the calling TB. When the TB
589                    spans two pages, we cannot safely do a direct
590                    jump. */
591                 {
592                     if (next_tb != 0 &&
593 #ifdef USE_KQEMU
594                         (env->kqemu_enabled != 2) &&
595 #endif
596                         tb->page_addr[1] == -1) {
597                     tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb);
598                 }
599                 }
600                 spin_unlock(&tb_lock);
601                 env->current_tb = tb;
602
603                 /* cpu_interrupt might be called while translating the
604                    TB, but before it is linked into a potentially
605                    infinite loop and becomes env->current_tb. Avoid
606                    starting execution if there is a pending interrupt. */
607                 if (unlikely (env->interrupt_request & CPU_INTERRUPT_EXIT))
608                     env->current_tb = NULL;
609
610                 while (env->current_tb) {
611                     tc_ptr = tb->tc_ptr;
612                 /* execute the generated code */
613 #if defined(__sparc__) && !defined(HOST_SOLARIS)
614 #undef env
615                     env = cpu_single_env;
616 #define env cpu_single_env
617 #endif
618                     next_tb = tcg_qemu_tb_exec(tc_ptr);
619                     env->current_tb = NULL;
620                     if ((next_tb & 3) == 2) {
621                         /* Instruction counter expired.  */
622                         int insns_left;
623                         tb = (TranslationBlock *)(long)(next_tb & ~3);
624                         /* Restore PC.  */
625                         cpu_pc_from_tb(env, tb);
626                         insns_left = env->icount_decr.u32;
627                         if (env->icount_extra && insns_left >= 0) {
628                             /* Refill decrementer and continue execution.  */
629                             env->icount_extra += insns_left;
630                             if (env->icount_extra > 0xffff) {
631                                 insns_left = 0xffff;
632                             } else {
633                                 insns_left = env->icount_extra;
634                             }
635                             env->icount_extra -= insns_left;
636                             env->icount_decr.u16.low = insns_left;
637                         } else {
638                             if (insns_left > 0) {
639                                 /* Execute remaining instructions.  */
640                                 cpu_exec_nocache(insns_left, tb);
641                             }
642                             env->exception_index = EXCP_INTERRUPT;
643                             next_tb = 0;
644                             cpu_loop_exit();
645                         }
646                     }
647                 }
648                 /* reset soft MMU for next block (it can currently
649                    only be set by a memory fault) */
650 #if defined(USE_KQEMU)
651 #define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
652                 if (kqemu_is_ok(env) &&
653                     (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) {
654                     cpu_loop_exit();
655                 }
656 #endif
657             } /* for(;;) */
658         } else {
659             env_to_regs();
660         }
661     } /* for(;;) */
662
663
664 #if defined(TARGET_I386)
665     /* restore flags in standard format */
666     env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
667 #elif defined(TARGET_ARM)
668     /* XXX: Save/restore host fpu exception state?.  */
669 #elif defined(TARGET_SPARC)
670 #elif defined(TARGET_PPC)
671 #elif defined(TARGET_M68K)
672     cpu_m68k_flush_flags(env, env->cc_op);
673     env->cc_op = CC_OP_FLAGS;
674     env->sr = (env->sr & 0xffe0)
675               | env->cc_dest | (env->cc_x << 4);
676 #elif defined(TARGET_MIPS)
677 #elif defined(TARGET_SH4)
678 #elif defined(TARGET_ALPHA)
679 #elif defined(TARGET_CRIS)
680     /* XXXXX */
681 #else
682 #error unsupported target CPU
683 #endif
684
685     /* restore global registers */
686 #include "hostregs_helper.h"
687
688     /* fail safe : never use cpu_single_env outside cpu_exec() */
689     cpu_single_env = NULL;
690     return ret;
691 }
692
693 /* must only be called from the generated code as an exception can be
694    generated */
695 void tb_invalidate_page_range(target_ulong start, target_ulong end)
696 {
697     /* XXX: cannot enable it yet because it yields to MMU exception
698        where NIP != read address on PowerPC */
699 #if 0
700     target_ulong phys_addr;
701     phys_addr = get_phys_addr_code(env, start);
702     tb_invalidate_phys_page_range(phys_addr, phys_addr + end - start, 0);
703 #endif
704 }
705
706 #if defined(TARGET_I386) && defined(CONFIG_USER_ONLY)
707
708 void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector)
709 {
710     CPUX86State *saved_env;
711
712     saved_env = env;
713     env = s;
714     if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
715         selector &= 0xffff;
716         cpu_x86_load_seg_cache(env, seg_reg, selector,
717                                (selector << 4), 0xffff, 0);
718     } else {
719         helper_load_seg(seg_reg, selector);
720     }
721     env = saved_env;
722 }
723
724 void cpu_x86_fsave(CPUX86State *s, target_ulong ptr, int data32)
725 {
726     CPUX86State *saved_env;
727
728     saved_env = env;
729     env = s;
730
731     helper_fsave(ptr, data32);
732
733     env = saved_env;
734 }
735
736 void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32)
737 {
738     CPUX86State *saved_env;
739
740     saved_env = env;
741     env = s;
742
743     helper_frstor(ptr, data32);
744
745     env = saved_env;
746 }
747
748 #endif /* TARGET_I386 */
749
750 #if !defined(CONFIG_SOFTMMU)
751
752 #if defined(TARGET_I386)
753
754 /* 'pc' is the host PC at which the exception was raised. 'address' is
755    the effective address of the memory exception. 'is_write' is 1 if a
756    write caused the exception and otherwise 0'. 'old_set' is the
757    signal set which should be restored */
758 static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
759                                     int is_write, sigset_t *old_set,
760                                     void *puc)
761 {
762     TranslationBlock *tb;
763     int ret;
764
765     if (cpu_single_env)
766         env = cpu_single_env; /* XXX: find a correct solution for multithread */
767 #if defined(DEBUG_SIGNAL)
768     qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
769                 pc, address, is_write, *(unsigned long *)old_set);
770 #endif
771     /* XXX: locking issue */
772     if (is_write && page_unprotect(h2g(address), pc, puc)) {
773         return 1;
774     }
775
776     /* see if it is an MMU fault */
777     ret = cpu_x86_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
778     if (ret < 0)
779         return 0; /* not an MMU fault */
780     if (ret == 0)
781         return 1; /* the MMU fault was handled without causing real CPU fault */
782     /* now we have a real cpu fault */
783     tb = tb_find_pc(pc);
784     if (tb) {
785         /* the PC is inside the translated code. It means that we have
786            a virtual CPU fault */
787         cpu_restore_state(tb, env, pc, puc);
788     }
789     if (ret == 1) {
790 #if 0
791         printf("PF exception: EIP=0x%08x CR2=0x%08x error=0x%x\n",
792                env->eip, env->cr[2], env->error_code);
793 #endif
794         /* we restore the process signal mask as the sigreturn should
795            do it (XXX: use sigsetjmp) */
796         sigprocmask(SIG_SETMASK, old_set, NULL);
797         raise_exception_err(env->exception_index, env->error_code);
798     } else {
799         /* activate soft MMU for this block */
800         env->hflags |= HF_SOFTMMU_MASK;
801         cpu_resume_from_signal(env, puc);
802     }
803     /* never comes here */
804     return 1;
805 }
806
807 #elif defined(TARGET_ARM)
808 static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
809                                     int is_write, sigset_t *old_set,
810                                     void *puc)
811 {
812     TranslationBlock *tb;
813     int ret;
814
815     if (cpu_single_env)
816         env = cpu_single_env; /* XXX: find a correct solution for multithread */
817 #if defined(DEBUG_SIGNAL)
818     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
819            pc, address, is_write, *(unsigned long *)old_set);
820 #endif
821     /* XXX: locking issue */
822     if (is_write && page_unprotect(h2g(address), pc, puc)) {
823         return 1;
824     }
825     /* see if it is an MMU fault */
826     ret = cpu_arm_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
827     if (ret < 0)
828         return 0; /* not an MMU fault */
829     if (ret == 0)
830         return 1; /* the MMU fault was handled without causing real CPU fault */
831     /* now we have a real cpu fault */
832     tb = tb_find_pc(pc);
833     if (tb) {
834         /* the PC is inside the translated code. It means that we have
835            a virtual CPU fault */
836         cpu_restore_state(tb, env, pc, puc);
837     }
838     /* we restore the process signal mask as the sigreturn should
839        do it (XXX: use sigsetjmp) */
840     sigprocmask(SIG_SETMASK, old_set, NULL);
841     cpu_loop_exit();
842     /* never comes here */
843     return 1;
844 }
845 #elif defined(TARGET_SPARC)
846 static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
847                                     int is_write, sigset_t *old_set,
848                                     void *puc)
849 {
850     TranslationBlock *tb;
851     int ret;
852
853     if (cpu_single_env)
854         env = cpu_single_env; /* XXX: find a correct solution for multithread */
855 #if defined(DEBUG_SIGNAL)
856     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
857            pc, address, is_write, *(unsigned long *)old_set);
858 #endif
859     /* XXX: locking issue */
860     if (is_write && page_unprotect(h2g(address), pc, puc)) {
861         return 1;
862     }
863     /* see if it is an MMU fault */
864     ret = cpu_sparc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
865     if (ret < 0)
866         return 0; /* not an MMU fault */
867     if (ret == 0)
868         return 1; /* the MMU fault was handled without causing real CPU fault */
869     /* now we have a real cpu fault */
870     tb = tb_find_pc(pc);
871     if (tb) {
872         /* the PC is inside the translated code. It means that we have
873            a virtual CPU fault */
874         cpu_restore_state(tb, env, pc, puc);
875     }
876     /* we restore the process signal mask as the sigreturn should
877        do it (XXX: use sigsetjmp) */
878     sigprocmask(SIG_SETMASK, old_set, NULL);
879     cpu_loop_exit();
880     /* never comes here */
881     return 1;
882 }
883 #elif defined (TARGET_PPC)
884 static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
885                                     int is_write, sigset_t *old_set,
886                                     void *puc)
887 {
888     TranslationBlock *tb;
889     int ret;
890
891     if (cpu_single_env)
892         env = cpu_single_env; /* XXX: find a correct solution for multithread */
893 #if defined(DEBUG_SIGNAL)
894     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
895            pc, address, is_write, *(unsigned long *)old_set);
896 #endif
897     /* XXX: locking issue */
898     if (is_write && page_unprotect(h2g(address), pc, puc)) {
899         return 1;
900     }
901
902     /* see if it is an MMU fault */
903     ret = cpu_ppc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
904     if (ret < 0)
905         return 0; /* not an MMU fault */
906     if (ret == 0)
907         return 1; /* the MMU fault was handled without causing real CPU fault */
908
909     /* now we have a real cpu fault */
910     tb = tb_find_pc(pc);
911     if (tb) {
912         /* the PC is inside the translated code. It means that we have
913            a virtual CPU fault */
914         cpu_restore_state(tb, env, pc, puc);
915     }
916     if (ret == 1) {
917 #if 0
918         printf("PF exception: NIP=0x%08x error=0x%x %p\n",
919                env->nip, env->error_code, tb);
920 #endif
921     /* we restore the process signal mask as the sigreturn should
922        do it (XXX: use sigsetjmp) */
923         sigprocmask(SIG_SETMASK, old_set, NULL);
924         cpu_loop_exit();
925     } else {
926         /* activate soft MMU for this block */
927         cpu_resume_from_signal(env, puc);
928     }
929     /* never comes here */
930     return 1;
931 }
932
933 #elif defined(TARGET_M68K)
934 static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
935                                     int is_write, sigset_t *old_set,
936                                     void *puc)
937 {
938     TranslationBlock *tb;
939     int ret;
940
941     if (cpu_single_env)
942         env = cpu_single_env; /* XXX: find a correct solution for multithread */
943 #if defined(DEBUG_SIGNAL)
944     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
945            pc, address, is_write, *(unsigned long *)old_set);
946 #endif
947     /* XXX: locking issue */
948     if (is_write && page_unprotect(address, pc, puc)) {
949         return 1;
950     }
951     /* see if it is an MMU fault */
952     ret = cpu_m68k_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
953     if (ret < 0)
954         return 0; /* not an MMU fault */
955     if (ret == 0)
956         return 1; /* the MMU fault was handled without causing real CPU fault */
957     /* now we have a real cpu fault */
958     tb = tb_find_pc(pc);
959     if (tb) {
960         /* the PC is inside the translated code. It means that we have
961            a virtual CPU fault */
962         cpu_restore_state(tb, env, pc, puc);
963     }
964     /* we restore the process signal mask as the sigreturn should
965        do it (XXX: use sigsetjmp) */
966     sigprocmask(SIG_SETMASK, old_set, NULL);
967     cpu_loop_exit();
968     /* never comes here */
969     return 1;
970 }
971
972 #elif defined (TARGET_MIPS)
973 static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
974                                     int is_write, sigset_t *old_set,
975                                     void *puc)
976 {
977     TranslationBlock *tb;
978     int ret;
979
980     if (cpu_single_env)
981         env = cpu_single_env; /* XXX: find a correct solution for multithread */
982 #if defined(DEBUG_SIGNAL)
983     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
984            pc, address, is_write, *(unsigned long *)old_set);
985 #endif
986     /* XXX: locking issue */
987     if (is_write && page_unprotect(h2g(address), pc, puc)) {
988         return 1;
989     }
990
991     /* see if it is an MMU fault */
992     ret = cpu_mips_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
993     if (ret < 0)
994         return 0; /* not an MMU fault */
995     if (ret == 0)
996         return 1; /* the MMU fault was handled without causing real CPU fault */
997
998     /* now we have a real cpu fault */
999     tb = tb_find_pc(pc);
1000     if (tb) {
1001         /* the PC is inside the translated code. It means that we have
1002            a virtual CPU fault */
1003         cpu_restore_state(tb, env, pc, puc);
1004     }
1005     if (ret == 1) {
1006 #if 0
1007         printf("PF exception: PC=0x" TARGET_FMT_lx " error=0x%x %p\n",
1008                env->PC, env->error_code, tb);
1009 #endif
1010     /* we restore the process signal mask as the sigreturn should
1011        do it (XXX: use sigsetjmp) */
1012         sigprocmask(SIG_SETMASK, old_set, NULL);
1013         cpu_loop_exit();
1014     } else {
1015         /* activate soft MMU for this block */
1016         cpu_resume_from_signal(env, puc);
1017     }
1018     /* never comes here */
1019     return 1;
1020 }
1021
1022 #elif defined (TARGET_SH4)
1023 static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1024                                     int is_write, sigset_t *old_set,
1025                                     void *puc)
1026 {
1027     TranslationBlock *tb;
1028     int ret;
1029
1030     if (cpu_single_env)
1031         env = cpu_single_env; /* XXX: find a correct solution for multithread */
1032 #if defined(DEBUG_SIGNAL)
1033     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
1034            pc, address, is_write, *(unsigned long *)old_set);
1035 #endif
1036     /* XXX: locking issue */
1037     if (is_write && page_unprotect(h2g(address), pc, puc)) {
1038         return 1;
1039     }
1040
1041     /* see if it is an MMU fault */
1042     ret = cpu_sh4_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
1043     if (ret < 0)
1044         return 0; /* not an MMU fault */
1045     if (ret == 0)
1046         return 1; /* the MMU fault was handled without causing real CPU fault */
1047
1048     /* now we have a real cpu fault */
1049     tb = tb_find_pc(pc);
1050     if (tb) {
1051         /* the PC is inside the translated code. It means that we have
1052            a virtual CPU fault */
1053         cpu_restore_state(tb, env, pc, puc);
1054     }
1055 #if 0
1056         printf("PF exception: NIP=0x%08x error=0x%x %p\n",
1057                env->nip, env->error_code, tb);
1058 #endif
1059     /* we restore the process signal mask as the sigreturn should
1060        do it (XXX: use sigsetjmp) */
1061     sigprocmask(SIG_SETMASK, old_set, NULL);
1062     cpu_loop_exit();
1063     /* never comes here */
1064     return 1;
1065 }
1066
1067 #elif defined (TARGET_ALPHA)
1068 static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1069                                     int is_write, sigset_t *old_set,
1070                                     void *puc)
1071 {
1072     TranslationBlock *tb;
1073     int ret;
1074
1075     if (cpu_single_env)
1076         env = cpu_single_env; /* XXX: find a correct solution for multithread */
1077 #if defined(DEBUG_SIGNAL)
1078     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
1079            pc, address, is_write, *(unsigned long *)old_set);
1080 #endif
1081     /* XXX: locking issue */
1082     if (is_write && page_unprotect(h2g(address), pc, puc)) {
1083         return 1;
1084     }
1085
1086     /* see if it is an MMU fault */
1087     ret = cpu_alpha_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
1088     if (ret < 0)
1089         return 0; /* not an MMU fault */
1090     if (ret == 0)
1091         return 1; /* the MMU fault was handled without causing real CPU fault */
1092
1093     /* now we have a real cpu fault */
1094     tb = tb_find_pc(pc);
1095     if (tb) {
1096         /* the PC is inside the translated code. It means that we have
1097            a virtual CPU fault */
1098         cpu_restore_state(tb, env, pc, puc);
1099     }
1100 #if 0
1101         printf("PF exception: NIP=0x%08x error=0x%x %p\n",
1102                env->nip, env->error_code, tb);
1103 #endif
1104     /* we restore the process signal mask as the sigreturn should
1105        do it (XXX: use sigsetjmp) */
1106     sigprocmask(SIG_SETMASK, old_set, NULL);
1107     cpu_loop_exit();
1108     /* never comes here */
1109     return 1;
1110 }
1111 #elif defined (TARGET_CRIS)
1112 static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1113                                     int is_write, sigset_t *old_set,
1114                                     void *puc)
1115 {
1116     TranslationBlock *tb;
1117     int ret;
1118
1119     if (cpu_single_env)
1120         env = cpu_single_env; /* XXX: find a correct solution for multithread */
1121 #if defined(DEBUG_SIGNAL)
1122     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
1123            pc, address, is_write, *(unsigned long *)old_set);
1124 #endif
1125     /* XXX: locking issue */
1126     if (is_write && page_unprotect(h2g(address), pc, puc)) {
1127         return 1;
1128     }
1129
1130     /* see if it is an MMU fault */
1131     ret = cpu_cris_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
1132     if (ret < 0)
1133         return 0; /* not an MMU fault */
1134     if (ret == 0)
1135         return 1; /* the MMU fault was handled without causing real CPU fault */
1136
1137     /* now we have a real cpu fault */
1138     tb = tb_find_pc(pc);
1139     if (tb) {
1140         /* the PC is inside the translated code. It means that we have
1141            a virtual CPU fault */
1142         cpu_restore_state(tb, env, pc, puc);
1143     }
1144     /* we restore the process signal mask as the sigreturn should
1145        do it (XXX: use sigsetjmp) */
1146     sigprocmask(SIG_SETMASK, old_set, NULL);
1147     cpu_loop_exit();
1148     /* never comes here */
1149     return 1;
1150 }
1151
1152 #else
1153 #error unsupported target CPU
1154 #endif
1155
1156 #if defined(__i386__)
1157
1158 #if defined(__APPLE__)
1159 # include <sys/ucontext.h>
1160
1161 # define EIP_sig(context)  (*((unsigned long*)&(context)->uc_mcontext->ss.eip))
1162 # define TRAP_sig(context)    ((context)->uc_mcontext->es.trapno)
1163 # define ERROR_sig(context)   ((context)->uc_mcontext->es.err)
1164 #else
1165 # define EIP_sig(context)     ((context)->uc_mcontext.gregs[REG_EIP])
1166 # define TRAP_sig(context)    ((context)->uc_mcontext.gregs[REG_TRAPNO])
1167 # define ERROR_sig(context)   ((context)->uc_mcontext.gregs[REG_ERR])
1168 #endif
1169
1170 int cpu_signal_handler(int host_signum, void *pinfo,
1171                        void *puc)
1172 {
1173     siginfo_t *info = pinfo;
1174     struct ucontext *uc = puc;
1175     unsigned long pc;
1176     int trapno;
1177
1178 #ifndef REG_EIP
1179 /* for glibc 2.1 */
1180 #define REG_EIP    EIP
1181 #define REG_ERR    ERR
1182 #define REG_TRAPNO TRAPNO
1183 #endif
1184     pc = EIP_sig(uc);
1185     trapno = TRAP_sig(uc);
1186     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1187                              trapno == 0xe ?
1188                              (ERROR_sig(uc) >> 1) & 1 : 0,
1189                              &uc->uc_sigmask, puc);
1190 }
1191
1192 #elif defined(__x86_64__)
1193
1194 #ifdef __NetBSD__
1195 #define REG_ERR _REG_ERR
1196 #define REG_TRAPNO _REG_TRAPNO
1197
1198 #define QEMU_UC_MCONTEXT_GREGS(uc, reg) (uc)->uc_mcontext.__gregs[(reg)]
1199 #define QEMU_UC_MACHINE_PC(uc)          _UC_MACHINE_PC(uc)
1200 #else
1201 #define QEMU_UC_MCONTEXT_GREGS(uc, reg) (uc)->uc_mcontext.gregs[(reg)]
1202 #define QEMU_UC_MACHINE_PC(uc)          QEMU_UC_MCONTEXT_GREGS(uc, REG_RIP)
1203 #endif
1204
1205 int cpu_signal_handler(int host_signum, void *pinfo,
1206                        void *puc)
1207 {
1208     siginfo_t *info = pinfo;
1209     unsigned long pc;
1210 #ifdef __NetBSD__
1211     ucontext_t *uc = puc;
1212 #else
1213     struct ucontext *uc = puc;
1214 #endif
1215
1216     pc = QEMU_UC_MACHINE_PC(uc);
1217     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1218                              QEMU_UC_MCONTEXT_GREGS(uc, REG_TRAPNO) == 0xe ?
1219                              (QEMU_UC_MCONTEXT_GREGS(uc, REG_ERR) >> 1) & 1 : 0,
1220                              &uc->uc_sigmask, puc);
1221 }
1222
1223 #elif defined(_ARCH_PPC)
1224
1225 /***********************************************************************
1226  * signal context platform-specific definitions
1227  * From Wine
1228  */
1229 #ifdef linux
1230 /* All Registers access - only for local access */
1231 # define REG_sig(reg_name, context)             ((context)->uc_mcontext.regs->reg_name)
1232 /* Gpr Registers access  */
1233 # define GPR_sig(reg_num, context)              REG_sig(gpr[reg_num], context)
1234 # define IAR_sig(context)                       REG_sig(nip, context)   /* Program counter */
1235 # define MSR_sig(context)                       REG_sig(msr, context)   /* Machine State Register (Supervisor) */
1236 # define CTR_sig(context)                       REG_sig(ctr, context)   /* Count register */
1237 # define XER_sig(context)                       REG_sig(xer, context) /* User's integer exception register */
1238 # define LR_sig(context)                        REG_sig(link, context) /* Link register */
1239 # define CR_sig(context)                        REG_sig(ccr, context) /* Condition register */
1240 /* Float Registers access  */
1241 # define FLOAT_sig(reg_num, context)            (((double*)((char*)((context)->uc_mcontext.regs+48*4)))[reg_num])
1242 # define FPSCR_sig(context)                     (*(int*)((char*)((context)->uc_mcontext.regs+(48+32*2)*4)))
1243 /* Exception Registers access */
1244 # define DAR_sig(context)                       REG_sig(dar, context)
1245 # define DSISR_sig(context)                     REG_sig(dsisr, context)
1246 # define TRAP_sig(context)                      REG_sig(trap, context)
1247 #endif /* linux */
1248
1249 #ifdef __APPLE__
1250 # include <sys/ucontext.h>
1251 typedef struct ucontext SIGCONTEXT;
1252 /* All Registers access - only for local access */
1253 # define REG_sig(reg_name, context)             ((context)->uc_mcontext->ss.reg_name)
1254 # define FLOATREG_sig(reg_name, context)        ((context)->uc_mcontext->fs.reg_name)
1255 # define EXCEPREG_sig(reg_name, context)        ((context)->uc_mcontext->es.reg_name)
1256 # define VECREG_sig(reg_name, context)          ((context)->uc_mcontext->vs.reg_name)
1257 /* Gpr Registers access */
1258 # define GPR_sig(reg_num, context)              REG_sig(r##reg_num, context)
1259 # define IAR_sig(context)                       REG_sig(srr0, context)  /* Program counter */
1260 # define MSR_sig(context)                       REG_sig(srr1, context)  /* Machine State Register (Supervisor) */
1261 # define CTR_sig(context)                       REG_sig(ctr, context)
1262 # define XER_sig(context)                       REG_sig(xer, context) /* Link register */
1263 # define LR_sig(context)                        REG_sig(lr, context)  /* User's integer exception register */
1264 # define CR_sig(context)                        REG_sig(cr, context)  /* Condition register */
1265 /* Float Registers access */
1266 # define FLOAT_sig(reg_num, context)            FLOATREG_sig(fpregs[reg_num], context)
1267 # define FPSCR_sig(context)                     ((double)FLOATREG_sig(fpscr, context))
1268 /* Exception Registers access */
1269 # define DAR_sig(context)                       EXCEPREG_sig(dar, context)     /* Fault registers for coredump */
1270 # define DSISR_sig(context)                     EXCEPREG_sig(dsisr, context)
1271 # define TRAP_sig(context)                      EXCEPREG_sig(exception, context) /* number of powerpc exception taken */
1272 #endif /* __APPLE__ */
1273
1274 int cpu_signal_handler(int host_signum, void *pinfo,
1275                        void *puc)
1276 {
1277     siginfo_t *info = pinfo;
1278     struct ucontext *uc = puc;
1279     unsigned long pc;
1280     int is_write;
1281
1282     pc = IAR_sig(uc);
1283     is_write = 0;
1284 #if 0
1285     /* ppc 4xx case */
1286     if (DSISR_sig(uc) & 0x00800000)
1287         is_write = 1;
1288 #else
1289     if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000))
1290         is_write = 1;
1291 #endif
1292     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1293                              is_write, &uc->uc_sigmask, puc);
1294 }
1295
1296 #elif defined(__alpha__)
1297
1298 int cpu_signal_handler(int host_signum, void *pinfo,
1299                            void *puc)
1300 {
1301     siginfo_t *info = pinfo;
1302     struct ucontext *uc = puc;
1303     uint32_t *pc = uc->uc_mcontext.sc_pc;
1304     uint32_t insn = *pc;
1305     int is_write = 0;
1306
1307     /* XXX: need kernel patch to get write flag faster */
1308     switch (insn >> 26) {
1309     case 0x0d: // stw
1310     case 0x0e: // stb
1311     case 0x0f: // stq_u
1312     case 0x24: // stf
1313     case 0x25: // stg
1314     case 0x26: // sts
1315     case 0x27: // stt
1316     case 0x2c: // stl
1317     case 0x2d: // stq
1318     case 0x2e: // stl_c
1319     case 0x2f: // stq_c
1320         is_write = 1;
1321     }
1322
1323     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1324                              is_write, &uc->uc_sigmask, puc);
1325 }
1326 #elif defined(__sparc__)
1327
1328 int cpu_signal_handler(int host_signum, void *pinfo,
1329                        void *puc)
1330 {
1331     siginfo_t *info = pinfo;
1332     int is_write;
1333     uint32_t insn;
1334 #if !defined(__arch64__) || defined(HOST_SOLARIS)
1335     uint32_t *regs = (uint32_t *)(info + 1);
1336     void *sigmask = (regs + 20);
1337     /* XXX: is there a standard glibc define ? */
1338     unsigned long pc = regs[1];
1339 #else
1340 #ifdef __linux__
1341     struct sigcontext *sc = puc;
1342     unsigned long pc = sc->sigc_regs.tpc;
1343     void *sigmask = (void *)sc->sigc_mask;
1344 #elif defined(__OpenBSD__)
1345     struct sigcontext *uc = puc;
1346     unsigned long pc = uc->sc_pc;
1347     void *sigmask = (void *)(long)uc->sc_mask;
1348 #endif
1349 #endif
1350
1351     /* XXX: need kernel patch to get write flag faster */
1352     is_write = 0;
1353     insn = *(uint32_t *)pc;
1354     if ((insn >> 30) == 3) {
1355       switch((insn >> 19) & 0x3f) {
1356       case 0x05: // stb
1357       case 0x06: // sth
1358       case 0x04: // st
1359       case 0x07: // std
1360       case 0x24: // stf
1361       case 0x27: // stdf
1362       case 0x25: // stfsr
1363         is_write = 1;
1364         break;
1365       }
1366     }
1367     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1368                              is_write, sigmask, NULL);
1369 }
1370
1371 #elif defined(__arm__)
1372
1373 int cpu_signal_handler(int host_signum, void *pinfo,
1374                        void *puc)
1375 {
1376     siginfo_t *info = pinfo;
1377     struct ucontext *uc = puc;
1378     unsigned long pc;
1379     int is_write;
1380
1381 #if (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
1382     pc = uc->uc_mcontext.gregs[R15];
1383 #else
1384     pc = uc->uc_mcontext.arm_pc;
1385 #endif
1386     /* XXX: compute is_write */
1387     is_write = 0;
1388     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1389                              is_write,
1390                              &uc->uc_sigmask, puc);
1391 }
1392
1393 #elif defined(__mc68000)
1394
1395 int cpu_signal_handler(int host_signum, void *pinfo,
1396                        void *puc)
1397 {
1398     siginfo_t *info = pinfo;
1399     struct ucontext *uc = puc;
1400     unsigned long pc;
1401     int is_write;
1402
1403     pc = uc->uc_mcontext.gregs[16];
1404     /* XXX: compute is_write */
1405     is_write = 0;
1406     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1407                              is_write,
1408                              &uc->uc_sigmask, puc);
1409 }
1410
1411 #elif defined(__ia64)
1412
1413 #ifndef __ISR_VALID
1414   /* This ought to be in <bits/siginfo.h>... */
1415 # define __ISR_VALID    1
1416 #endif
1417
1418 int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
1419 {
1420     siginfo_t *info = pinfo;
1421     struct ucontext *uc = puc;
1422     unsigned long ip;
1423     int is_write = 0;
1424
1425     ip = uc->uc_mcontext.sc_ip;
1426     switch (host_signum) {
1427       case SIGILL:
1428       case SIGFPE:
1429       case SIGSEGV:
1430       case SIGBUS:
1431       case SIGTRAP:
1432           if (info->si_code && (info->si_segvflags & __ISR_VALID))
1433               /* ISR.W (write-access) is bit 33:  */
1434               is_write = (info->si_isr >> 33) & 1;
1435           break;
1436
1437       default:
1438           break;
1439     }
1440     return handle_cpu_signal(ip, (unsigned long)info->si_addr,
1441                              is_write,
1442                              &uc->uc_sigmask, puc);
1443 }
1444
1445 #elif defined(__s390__)
1446
1447 int cpu_signal_handler(int host_signum, void *pinfo,
1448                        void *puc)
1449 {
1450     siginfo_t *info = pinfo;
1451     struct ucontext *uc = puc;
1452     unsigned long pc;
1453     int is_write;
1454
1455     pc = uc->uc_mcontext.psw.addr;
1456     /* XXX: compute is_write */
1457     is_write = 0;
1458     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1459                              is_write, &uc->uc_sigmask, puc);
1460 }
1461
1462 #elif defined(__mips__)
1463
1464 int cpu_signal_handler(int host_signum, void *pinfo,
1465                        void *puc)
1466 {
1467     siginfo_t *info = pinfo;
1468     struct ucontext *uc = puc;
1469     greg_t pc = uc->uc_mcontext.pc;
1470     int is_write;
1471
1472     /* XXX: compute is_write */
1473     is_write = 0;
1474     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1475                              is_write, &uc->uc_sigmask, puc);
1476 }
1477
1478 #elif defined(__hppa__)
1479
1480 int cpu_signal_handler(int host_signum, void *pinfo,
1481                        void *puc)
1482 {
1483     struct siginfo *info = pinfo;
1484     struct ucontext *uc = puc;
1485     unsigned long pc;
1486     int is_write;
1487
1488     pc = uc->uc_mcontext.sc_iaoq[0];
1489     /* FIXME: compute is_write */
1490     is_write = 0;
1491     return handle_cpu_signal(pc, (unsigned long)info->si_addr, 
1492                              is_write,
1493                              &uc->uc_sigmask, puc);
1494 }
1495
1496 #else
1497
1498 #error host CPU specific signal handler needed
1499
1500 #endif
1501
1502 #endif /* !defined(CONFIG_SOFTMMU) */