Statistics
| Branch: | Revision:

root / cpu-exec.c @ b09ea7d5

History | View | Annotate | Download (54.9 kB)

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
#include "exec.h"
22
#include "disas.h"
23
#include "tcg.h"
24
#include "kvm.h"
25

    
26
#if !defined(CONFIG_SOFTMMU)
27
#undef EAX
28
#undef ECX
29
#undef EDX
30
#undef EBX
31
#undef ESP
32
#undef EBP
33
#undef ESI
34
#undef EDI
35
#undef EIP
36
#include <signal.h>
37
#ifdef __linux__
38
#include <sys/ucontext.h>
39
#endif
40
#endif
41

    
42
#if defined(__sparc__) && !defined(HOST_SOLARIS)
43
// Work around ugly bugs in glibc that mangle global register contents
44
#undef env
45
#define env cpu_single_env
46
#endif
47

    
48
int tb_invalidated_flag;
49

    
50
//#define DEBUG_EXEC
51
//#define DEBUG_SIGNAL
52

    
53
int qemu_cpu_has_work(CPUState *env)
54
{
55
    return cpu_has_work(env);
56
}
57

    
58
void cpu_loop_exit(void)
59
{
60
    /* NOTE: the register at this point must be saved by hand because
61
       longjmp restore them */
62
    regs_to_env();
63
    longjmp(env->jmp_env, 1);
64
}
65

    
66
/* exit the current TB from a signal handler. The host registers are
67
   restored in a state compatible with the CPU emulator
68
 */
69
void cpu_resume_from_signal(CPUState *env1, void *puc)
70
{
71
#if !defined(CONFIG_SOFTMMU)
72
#ifdef __linux__
73
    struct ucontext *uc = puc;
74
#elif defined(__OpenBSD__)
75
    struct sigcontext *uc = puc;
76
#endif
77
#endif
78

    
79
    env = env1;
80

    
81
    /* XXX: restore cpu registers saved in host registers */
82

    
83
#if !defined(CONFIG_SOFTMMU)
84
    if (puc) {
85
        /* XXX: use siglongjmp ? */
86
#ifdef __linux__
87
        sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
88
#elif defined(__OpenBSD__)
89
        sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL);
90
#endif
91
    }
92
#endif
93
    env->exception_index = -1;
94
    longjmp(env->jmp_env, 1);
95
}
96

    
97
/* Execute the code without caching the generated code. An interpreter
98
   could be used if available. */
99
static void cpu_exec_nocache(int max_cycles, TranslationBlock *orig_tb)
100
{
101
    unsigned long next_tb;
102
    TranslationBlock *tb;
103

    
104
    /* Should never happen.
105
       We only end up here when an existing TB is too long.  */
106
    if (max_cycles > CF_COUNT_MASK)
107
        max_cycles = CF_COUNT_MASK;
108

    
109
    tb = tb_gen_code(env, orig_tb->pc, orig_tb->cs_base, orig_tb->flags,
110
                     max_cycles);
111
    env->current_tb = tb;
112
    /* execute the generated code */
113
    next_tb = tcg_qemu_tb_exec(tb->tc_ptr);
114

    
115
    if ((next_tb & 3) == 2) {
116
        /* Restore PC.  This may happen if async event occurs before
117
           the TB starts executing.  */
118
        cpu_pc_from_tb(env, tb);
119
    }
120
    tb_phys_invalidate(tb, -1);
121
    tb_free(tb);
122
}
123

    
124
static TranslationBlock *tb_find_slow(target_ulong pc,
125
                                      target_ulong cs_base,
126
                                      uint64_t flags)
127
{
128
    TranslationBlock *tb, **ptb1;
129
    unsigned int h;
130
    target_ulong phys_pc, phys_page1, phys_page2, virt_page2;
131

    
132
    tb_invalidated_flag = 0;
133

    
134
    regs_to_env(); /* XXX: do it just before cpu_gen_code() */
135

    
136
    /* find translated block using physical mappings */
137
    phys_pc = get_phys_addr_code(env, pc);
138
    phys_page1 = phys_pc & TARGET_PAGE_MASK;
139
    phys_page2 = -1;
140
    h = tb_phys_hash_func(phys_pc);
141
    ptb1 = &tb_phys_hash[h];
142
    for(;;) {
143
        tb = *ptb1;
144
        if (!tb)
145
            goto not_found;
146
        if (tb->pc == pc &&
147
            tb->page_addr[0] == phys_page1 &&
148
            tb->cs_base == cs_base &&
149
            tb->flags == flags) {
150
            /* check next page if needed */
151
            if (tb->page_addr[1] != -1) {
152
                virt_page2 = (pc & TARGET_PAGE_MASK) +
153
                    TARGET_PAGE_SIZE;
154
                phys_page2 = get_phys_addr_code(env, virt_page2);
155
                if (tb->page_addr[1] == phys_page2)
156
                    goto found;
157
            } else {
158
                goto found;
159
            }
160
        }
161
        ptb1 = &tb->phys_hash_next;
162
    }
163
 not_found:
164
   /* if no translated code available, then translate it now */
165
    tb = tb_gen_code(env, pc, cs_base, flags, 0);
166

    
167
 found:
168
    /* we add the TB in the virtual pc hash table */
169
    env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
170
    return tb;
171
}
172

    
173
static inline TranslationBlock *tb_find_fast(void)
174
{
175
    TranslationBlock *tb;
176
    target_ulong cs_base, pc;
177
    int flags;
178

    
179
    /* we record a subset of the CPU state. It will
180
       always be the same before a given translated block
181
       is executed. */
182
    cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
183
    tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
184
    if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
185
                 tb->flags != flags)) {
186
        tb = tb_find_slow(pc, cs_base, flags);
187
    }
188
    return tb;
189
}
190

    
191
static CPUDebugExcpHandler *debug_excp_handler;
192

    
193
CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler)
194
{
195
    CPUDebugExcpHandler *old_handler = debug_excp_handler;
196

    
197
    debug_excp_handler = handler;
198
    return old_handler;
199
}
200

    
201
static void cpu_handle_debug_exception(CPUState *env)
202
{
203
    CPUWatchpoint *wp;
204

    
205
    if (!env->watchpoint_hit)
206
        TAILQ_FOREACH(wp, &env->watchpoints, entry)
207
            wp->flags &= ~BP_WATCHPOINT_HIT;
208

    
209
    if (debug_excp_handler)
210
        debug_excp_handler(env);
211
}
212

    
213
/* main execution loop */
214

    
215
int cpu_exec(CPUState *env1)
216
{
217
#define DECLARE_HOST_REGS 1
218
#include "hostregs_helper.h"
219
    int ret, interrupt_request;
220
    TranslationBlock *tb;
221
    uint8_t *tc_ptr;
222
    unsigned long next_tb;
223

    
224
    if (cpu_halted(env1) == EXCP_HALTED)
225
        return EXCP_HALTED;
226

    
227
    cpu_single_env = env1;
228

    
229
    /* first we save global registers */
230
#define SAVE_HOST_REGS 1
231
#include "hostregs_helper.h"
232
    env = env1;
233

    
234
    env_to_regs();
235
#if defined(TARGET_I386)
236
    /* put eflags in CPU temporary format */
237
    CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
238
    DF = 1 - (2 * ((env->eflags >> 10) & 1));
239
    CC_OP = CC_OP_EFLAGS;
240
    env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
241
#elif defined(TARGET_SPARC)
242
#elif defined(TARGET_M68K)
243
    env->cc_op = CC_OP_FLAGS;
244
    env->cc_dest = env->sr & 0xf;
245
    env->cc_x = (env->sr >> 4) & 1;
246
#elif defined(TARGET_ALPHA)
247
#elif defined(TARGET_ARM)
248
#elif defined(TARGET_PPC)
249
#elif defined(TARGET_MICROBLAZE)
250
#elif defined(TARGET_MIPS)
251
#elif defined(TARGET_SH4)
252
#elif defined(TARGET_CRIS)
253
    /* XXXXX */
254
#else
255
#error unsupported target CPU
256
#endif
257
    env->exception_index = -1;
258

    
259
    /* prepare setjmp context for exception handling */
260
    for(;;) {
261
        if (setjmp(env->jmp_env) == 0) {
262
#if defined(__sparc__) && !defined(HOST_SOLARIS)
263
#undef env
264
                    env = cpu_single_env;
265
#define env cpu_single_env
266
#endif
267
            env->current_tb = NULL;
268
            /* if an exception is pending, we execute it here */
269
            if (env->exception_index >= 0) {
270
                if (env->exception_index >= EXCP_INTERRUPT) {
271
                    /* exit request from the cpu execution loop */
272
                    ret = env->exception_index;
273
                    if (ret == EXCP_DEBUG)
274
                        cpu_handle_debug_exception(env);
275
                    break;
276
                } else {
277
#if defined(CONFIG_USER_ONLY)
278
                    /* if user mode only, we simulate a fake exception
279
                       which will be handled outside the cpu execution
280
                       loop */
281
#if defined(TARGET_I386)
282
                    do_interrupt_user(env->exception_index,
283
                                      env->exception_is_int,
284
                                      env->error_code,
285
                                      env->exception_next_eip);
286
                    /* successfully delivered */
287
                    env->old_exception = -1;
288
#endif
289
                    ret = env->exception_index;
290
                    break;
291
#else
292
#if defined(TARGET_I386)
293
                    /* simulate a real cpu exception. On i386, it can
294
                       trigger new exceptions, but we do not handle
295
                       double or triple faults yet. */
296
                    do_interrupt(env->exception_index,
297
                                 env->exception_is_int,
298
                                 env->error_code,
299
                                 env->exception_next_eip, 0);
300
                    /* successfully delivered */
301
                    env->old_exception = -1;
302
#elif defined(TARGET_PPC)
303
                    do_interrupt(env);
304
#elif defined(TARGET_MICROBLAZE)
305
                    do_interrupt(env);
306
#elif defined(TARGET_MIPS)
307
                    do_interrupt(env);
308
#elif defined(TARGET_SPARC)
309
                    do_interrupt(env);
310
#elif defined(TARGET_ARM)
311
                    do_interrupt(env);
312
#elif defined(TARGET_SH4)
313
                    do_interrupt(env);
314
#elif defined(TARGET_ALPHA)
315
                    do_interrupt(env);
316
#elif defined(TARGET_CRIS)
317
                    do_interrupt(env);
318
#elif defined(TARGET_M68K)
319
                    do_interrupt(0);
320
#endif
321
#endif
322
                }
323
                env->exception_index = -1;
324
            }
325
#ifdef CONFIG_KQEMU
326
            if (kqemu_is_ok(env) && env->interrupt_request == 0 && env->exit_request == 0) {
327
                int ret;
328
                env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
329
                ret = kqemu_cpu_exec(env);
330
                /* put eflags in CPU temporary format */
331
                CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
332
                DF = 1 - (2 * ((env->eflags >> 10) & 1));
333
                CC_OP = CC_OP_EFLAGS;
334
                env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
335
                if (ret == 1) {
336
                    /* exception */
337
                    longjmp(env->jmp_env, 1);
338
                } else if (ret == 2) {
339
                    /* softmmu execution needed */
340
                } else {
341
                    if (env->interrupt_request != 0 || env->exit_request != 0) {
342
                        /* hardware interrupt will be executed just after */
343
                    } else {
344
                        /* otherwise, we restart */
345
                        longjmp(env->jmp_env, 1);
346
                    }
347
                }
348
            }
349
#endif
350

    
351
            if (kvm_enabled()) {
352
                kvm_cpu_exec(env);
353
                longjmp(env->jmp_env, 1);
354
            }
355

    
356
            next_tb = 0; /* force lookup of first TB */
357
            for(;;) {
358
                interrupt_request = env->interrupt_request;
359
                if (unlikely(interrupt_request)) {
360
                    if (unlikely(env->singlestep_enabled & SSTEP_NOIRQ)) {
361
                        /* Mask out external interrupts for this step. */
362
                        interrupt_request &= ~(CPU_INTERRUPT_HARD |
363
                                               CPU_INTERRUPT_FIQ |
364
                                               CPU_INTERRUPT_SMI |
365
                                               CPU_INTERRUPT_NMI);
366
                    }
367
                    if (interrupt_request & CPU_INTERRUPT_DEBUG) {
368
                        env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
369
                        env->exception_index = EXCP_DEBUG;
370
                        cpu_loop_exit();
371
                    }
372
#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
373
    defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
374
    defined(TARGET_MICROBLAZE)
375
                    if (interrupt_request & CPU_INTERRUPT_HALT) {
376
                        env->interrupt_request &= ~CPU_INTERRUPT_HALT;
377
                        env->halted = 1;
378
                        env->exception_index = EXCP_HLT;
379
                        cpu_loop_exit();
380
                    }
381
#endif
382
#if defined(TARGET_I386)
383
                    if (interrupt_request & CPU_INTERRUPT_INIT) {
384
                            svm_check_intercept(SVM_EXIT_INIT);
385
                            do_cpu_init(env);
386
                            env->exception_index = EXCP_HALTED;
387
                            cpu_loop_exit();
388
                    } else if (interrupt_request & CPU_INTERRUPT_SIPI) {
389
                            do_cpu_sipi(env);
390
                    } else if (env->hflags2 & HF2_GIF_MASK) {
391
                        if ((interrupt_request & CPU_INTERRUPT_SMI) &&
392
                            !(env->hflags & HF_SMM_MASK)) {
393
                            svm_check_intercept(SVM_EXIT_SMI);
394
                            env->interrupt_request &= ~CPU_INTERRUPT_SMI;
395
                            do_smm_enter();
396
                            next_tb = 0;
397
                        } else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
398
                                   !(env->hflags2 & HF2_NMI_MASK)) {
399
                            env->interrupt_request &= ~CPU_INTERRUPT_NMI;
400
                            env->hflags2 |= HF2_NMI_MASK;
401
                            do_interrupt(EXCP02_NMI, 0, 0, 0, 1);
402
                            next_tb = 0;
403
                        } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
404
                                   (((env->hflags2 & HF2_VINTR_MASK) && 
405
                                     (env->hflags2 & HF2_HIF_MASK)) ||
406
                                    (!(env->hflags2 & HF2_VINTR_MASK) && 
407
                                     (env->eflags & IF_MASK && 
408
                                      !(env->hflags & HF_INHIBIT_IRQ_MASK))))) {
409
                            int intno;
410
                            svm_check_intercept(SVM_EXIT_INTR);
411
                            env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
412
                            intno = cpu_get_pic_interrupt(env);
413
                            qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno);
414
#if defined(__sparc__) && !defined(HOST_SOLARIS)
415
#undef env
416
                    env = cpu_single_env;
417
#define env cpu_single_env
418
#endif
419
                            do_interrupt(intno, 0, 0, 0, 1);
420
                            /* ensure that no TB jump will be modified as
421
                               the program flow was changed */
422
                            next_tb = 0;
423
#if !defined(CONFIG_USER_ONLY)
424
                        } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
425
                                   (env->eflags & IF_MASK) && 
426
                                   !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
427
                            int intno;
428
                            /* FIXME: this should respect TPR */
429
                            svm_check_intercept(SVM_EXIT_VINTR);
430
                            intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
431
                            qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing virtual hardware INT=0x%02x\n", intno);
432
                            do_interrupt(intno, 0, 0, 0, 1);
433
                            env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
434
                            next_tb = 0;
435
#endif
436
                        }
437
                    }
438
#elif defined(TARGET_PPC)
439
#if 0
440
                    if ((interrupt_request & CPU_INTERRUPT_RESET)) {
441
                        cpu_ppc_reset(env);
442
                    }
443
#endif
444
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
445
                        ppc_hw_interrupt(env);
446
                        if (env->pending_interrupts == 0)
447
                            env->interrupt_request &= ~CPU_INTERRUPT_HARD;
448
                        next_tb = 0;
449
                    }
450
#elif defined(TARGET_MICROBLAZE)
451
                    if ((interrupt_request & CPU_INTERRUPT_HARD)
452
                        && (env->sregs[SR_MSR] & MSR_IE)
453
                        && !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
454
                        && !(env->iflags & (D_FLAG | IMM_FLAG))) {
455
                        env->exception_index = EXCP_IRQ;
456
                        do_interrupt(env);
457
                        next_tb = 0;
458
                    }
459
#elif defined(TARGET_MIPS)
460
                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
461
                        (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) &&
462
                        (env->CP0_Status & (1 << CP0St_IE)) &&
463
                        !(env->CP0_Status & (1 << CP0St_EXL)) &&
464
                        !(env->CP0_Status & (1 << CP0St_ERL)) &&
465
                        !(env->hflags & MIPS_HFLAG_DM)) {
466
                        /* Raise it */
467
                        env->exception_index = EXCP_EXT_INTERRUPT;
468
                        env->error_code = 0;
469
                        do_interrupt(env);
470
                        next_tb = 0;
471
                    }
472
#elif defined(TARGET_SPARC)
473
                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
474
                        (env->psret != 0)) {
475
                        int pil = env->interrupt_index & 15;
476
                        int type = env->interrupt_index & 0xf0;
477

    
478
                        if (((type == TT_EXTINT) &&
479
                             (pil == 15 || pil > env->psrpil)) ||
480
                            type != TT_EXTINT) {
481
                            env->interrupt_request &= ~CPU_INTERRUPT_HARD;
482
                            env->exception_index = env->interrupt_index;
483
                            do_interrupt(env);
484
                            env->interrupt_index = 0;
485
#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
486
                            cpu_check_irqs(env);
487
#endif
488
                        next_tb = 0;
489
                        }
490
                    } else if (interrupt_request & CPU_INTERRUPT_TIMER) {
491
                        //do_interrupt(0, 0, 0, 0, 0);
492
                        env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
493
                    }
494
#elif defined(TARGET_ARM)
495
                    if (interrupt_request & CPU_INTERRUPT_FIQ
496
                        && !(env->uncached_cpsr & CPSR_F)) {
497
                        env->exception_index = EXCP_FIQ;
498
                        do_interrupt(env);
499
                        next_tb = 0;
500
                    }
501
                    /* ARMv7-M interrupt return works by loading a magic value
502
                       into the PC.  On real hardware the load causes the
503
                       return to occur.  The qemu implementation performs the
504
                       jump normally, then does the exception return when the
505
                       CPU tries to execute code at the magic address.
506
                       This will cause the magic PC value to be pushed to
507
                       the stack if an interrupt occured at the wrong time.
508
                       We avoid this by disabling interrupts when
509
                       pc contains a magic address.  */
510
                    if (interrupt_request & CPU_INTERRUPT_HARD
511
                        && ((IS_M(env) && env->regs[15] < 0xfffffff0)
512
                            || !(env->uncached_cpsr & CPSR_I))) {
513
                        env->exception_index = EXCP_IRQ;
514
                        do_interrupt(env);
515
                        next_tb = 0;
516
                    }
517
#elif defined(TARGET_SH4)
518
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
519
                        do_interrupt(env);
520
                        next_tb = 0;
521
                    }
522
#elif defined(TARGET_ALPHA)
523
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
524
                        do_interrupt(env);
525
                        next_tb = 0;
526
                    }
527
#elif defined(TARGET_CRIS)
528
                    if (interrupt_request & CPU_INTERRUPT_HARD
529
                        && (env->pregs[PR_CCS] & I_FLAG)) {
530
                        env->exception_index = EXCP_IRQ;
531
                        do_interrupt(env);
532
                        next_tb = 0;
533
                    }
534
                    if (interrupt_request & CPU_INTERRUPT_NMI
535
                        && (env->pregs[PR_CCS] & M_FLAG)) {
536
                        env->exception_index = EXCP_NMI;
537
                        do_interrupt(env);
538
                        next_tb = 0;
539
                    }
540
#elif defined(TARGET_M68K)
541
                    if (interrupt_request & CPU_INTERRUPT_HARD
542
                        && ((env->sr & SR_I) >> SR_I_SHIFT)
543
                            < env->pending_level) {
544
                        /* Real hardware gets the interrupt vector via an
545
                           IACK cycle at this point.  Current emulated
546
                           hardware doesn't rely on this, so we
547
                           provide/save the vector when the interrupt is
548
                           first signalled.  */
549
                        env->exception_index = env->pending_vector;
550
                        do_interrupt(1);
551
                        next_tb = 0;
552
                    }
553
#endif
554
                   /* Don't use the cached interupt_request value,
555
                      do_interrupt may have updated the EXITTB flag. */
556
                    if (env->interrupt_request & CPU_INTERRUPT_EXITTB) {
557
                        env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
558
                        /* ensure that no TB jump will be modified as
559
                           the program flow was changed */
560
                        next_tb = 0;
561
                    }
562
                }
563
                if (unlikely(env->exit_request)) {
564
                    env->exit_request = 0;
565
                    env->exception_index = EXCP_INTERRUPT;
566
                    cpu_loop_exit();
567
                }
568
#ifdef DEBUG_EXEC
569
                if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) {
570
                    /* restore flags in standard format */
571
                    regs_to_env();
572
#if defined(TARGET_I386)
573
                    env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
574
                    log_cpu_state(env, X86_DUMP_CCOP);
575
                    env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
576
#elif defined(TARGET_ARM)
577
                    log_cpu_state(env, 0);
578
#elif defined(TARGET_SPARC)
579
                    log_cpu_state(env, 0);
580
#elif defined(TARGET_PPC)
581
                    log_cpu_state(env, 0);
582
#elif defined(TARGET_M68K)
583
                    cpu_m68k_flush_flags(env, env->cc_op);
584
                    env->cc_op = CC_OP_FLAGS;
585
                    env->sr = (env->sr & 0xffe0)
586
                              | env->cc_dest | (env->cc_x << 4);
587
                    log_cpu_state(env, 0);
588
#elif defined(TARGET_MICROBLAZE)
589
                    log_cpu_state(env, 0);
590
#elif defined(TARGET_MIPS)
591
                    log_cpu_state(env, 0);
592
#elif defined(TARGET_SH4)
593
                    log_cpu_state(env, 0);
594
#elif defined(TARGET_ALPHA)
595
                    log_cpu_state(env, 0);
596
#elif defined(TARGET_CRIS)
597
                    log_cpu_state(env, 0);
598
#else
599
#error unsupported target CPU
600
#endif
601
                }
602
#endif
603
                spin_lock(&tb_lock);
604
                tb = tb_find_fast();
605
                /* Note: we do it here to avoid a gcc bug on Mac OS X when
606
                   doing it in tb_find_slow */
607
                if (tb_invalidated_flag) {
608
                    /* as some TB could have been invalidated because
609
                       of memory exceptions while generating the code, we
610
                       must recompute the hash index here */
611
                    next_tb = 0;
612
                    tb_invalidated_flag = 0;
613
                }
614
#ifdef DEBUG_EXEC
615
                qemu_log_mask(CPU_LOG_EXEC, "Trace 0x%08lx [" TARGET_FMT_lx "] %s\n",
616
                             (long)tb->tc_ptr, tb->pc,
617
                             lookup_symbol(tb->pc));
618
#endif
619
                /* see if we can patch the calling TB. When the TB
620
                   spans two pages, we cannot safely do a direct
621
                   jump. */
622
                {
623
                    if (next_tb != 0 &&
624
#ifdef CONFIG_KQEMU
625
                        (env->kqemu_enabled != 2) &&
626
#endif
627
                        tb->page_addr[1] == -1) {
628
                    tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb);
629
                }
630
                }
631
                spin_unlock(&tb_lock);
632
                env->current_tb = tb;
633

    
634
                /* cpu_interrupt might be called while translating the
635
                   TB, but before it is linked into a potentially
636
                   infinite loop and becomes env->current_tb. Avoid
637
                   starting execution if there is a pending interrupt. */
638
                if (unlikely (env->exit_request))
639
                    env->current_tb = NULL;
640

    
641
                while (env->current_tb) {
642
                    tc_ptr = tb->tc_ptr;
643
                /* execute the generated code */
644
#if defined(__sparc__) && !defined(HOST_SOLARIS)
645
#undef env
646
                    env = cpu_single_env;
647
#define env cpu_single_env
648
#endif
649
                    next_tb = tcg_qemu_tb_exec(tc_ptr);
650
                    env->current_tb = NULL;
651
                    if ((next_tb & 3) == 2) {
652
                        /* Instruction counter expired.  */
653
                        int insns_left;
654
                        tb = (TranslationBlock *)(long)(next_tb & ~3);
655
                        /* Restore PC.  */
656
                        cpu_pc_from_tb(env, tb);
657
                        insns_left = env->icount_decr.u32;
658
                        if (env->icount_extra && insns_left >= 0) {
659
                            /* Refill decrementer and continue execution.  */
660
                            env->icount_extra += insns_left;
661
                            if (env->icount_extra > 0xffff) {
662
                                insns_left = 0xffff;
663
                            } else {
664
                                insns_left = env->icount_extra;
665
                            }
666
                            env->icount_extra -= insns_left;
667
                            env->icount_decr.u16.low = insns_left;
668
                        } else {
669
                            if (insns_left > 0) {
670
                                /* Execute remaining instructions.  */
671
                                cpu_exec_nocache(insns_left, tb);
672
                            }
673
                            env->exception_index = EXCP_INTERRUPT;
674
                            next_tb = 0;
675
                            cpu_loop_exit();
676
                        }
677
                    }
678
                }
679
                /* reset soft MMU for next block (it can currently
680
                   only be set by a memory fault) */
681
#if defined(CONFIG_KQEMU)
682
#define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
683
                if (kqemu_is_ok(env) &&
684
                    (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) {
685
                    cpu_loop_exit();
686
                }
687
#endif
688
            } /* for(;;) */
689
        } else {
690
            env_to_regs();
691
        }
692
    } /* for(;;) */
693

    
694

    
695
#if defined(TARGET_I386)
696
    /* restore flags in standard format */
697
    env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
698
#elif defined(TARGET_ARM)
699
    /* XXX: Save/restore host fpu exception state?.  */
700
#elif defined(TARGET_SPARC)
701
#elif defined(TARGET_PPC)
702
#elif defined(TARGET_M68K)
703
    cpu_m68k_flush_flags(env, env->cc_op);
704
    env->cc_op = CC_OP_FLAGS;
705
    env->sr = (env->sr & 0xffe0)
706
              | env->cc_dest | (env->cc_x << 4);
707
#elif defined(TARGET_MICROBLAZE)
708
#elif defined(TARGET_MIPS)
709
#elif defined(TARGET_SH4)
710
#elif defined(TARGET_ALPHA)
711
#elif defined(TARGET_CRIS)
712
    /* XXXXX */
713
#else
714
#error unsupported target CPU
715
#endif
716

    
717
    /* restore global registers */
718
#include "hostregs_helper.h"
719

    
720
    /* fail safe : never use cpu_single_env outside cpu_exec() */
721
    cpu_single_env = NULL;
722
    return ret;
723
}
724

    
725
/* must only be called from the generated code as an exception can be
726
   generated */
727
void tb_invalidate_page_range(target_ulong start, target_ulong end)
728
{
729
    /* XXX: cannot enable it yet because it yields to MMU exception
730
       where NIP != read address on PowerPC */
731
#if 0
732
    target_ulong phys_addr;
733
    phys_addr = get_phys_addr_code(env, start);
734
    tb_invalidate_phys_page_range(phys_addr, phys_addr + end - start, 0);
735
#endif
736
}
737

    
738
#if defined(TARGET_I386) && defined(CONFIG_USER_ONLY)
739

    
740
void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector)
741
{
742
    CPUX86State *saved_env;
743

    
744
    saved_env = env;
745
    env = s;
746
    if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
747
        selector &= 0xffff;
748
        cpu_x86_load_seg_cache(env, seg_reg, selector,
749
                               (selector << 4), 0xffff, 0);
750
    } else {
751
        helper_load_seg(seg_reg, selector);
752
    }
753
    env = saved_env;
754
}
755

    
756
void cpu_x86_fsave(CPUX86State *s, target_ulong ptr, int data32)
757
{
758
    CPUX86State *saved_env;
759

    
760
    saved_env = env;
761
    env = s;
762

    
763
    helper_fsave(ptr, data32);
764

    
765
    env = saved_env;
766
}
767

    
768
void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32)
769
{
770
    CPUX86State *saved_env;
771

    
772
    saved_env = env;
773
    env = s;
774

    
775
    helper_frstor(ptr, data32);
776

    
777
    env = saved_env;
778
}
779

    
780
#endif /* TARGET_I386 */
781

    
782
#if !defined(CONFIG_SOFTMMU)
783

    
784
#if defined(TARGET_I386)
785

    
786
/* 'pc' is the host PC at which the exception was raised. 'address' is
787
   the effective address of the memory exception. 'is_write' is 1 if a
788
   write caused the exception and otherwise 0'. 'old_set' is the
789
   signal set which should be restored */
790
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
791
                                    int is_write, sigset_t *old_set,
792
                                    void *puc)
793
{
794
    TranslationBlock *tb;
795
    int ret;
796

    
797
    if (cpu_single_env)
798
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
799
#if defined(DEBUG_SIGNAL)
800
    qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
801
                pc, address, is_write, *(unsigned long *)old_set);
802
#endif
803
    /* XXX: locking issue */
804
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
805
        return 1;
806
    }
807

    
808
    /* see if it is an MMU fault */
809
    ret = cpu_x86_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
810
    if (ret < 0)
811
        return 0; /* not an MMU fault */
812
    if (ret == 0)
813
        return 1; /* the MMU fault was handled without causing real CPU fault */
814
    /* now we have a real cpu fault */
815
    tb = tb_find_pc(pc);
816
    if (tb) {
817
        /* the PC is inside the translated code. It means that we have
818
           a virtual CPU fault */
819
        cpu_restore_state(tb, env, pc, puc);
820
    }
821
    if (ret == 1) {
822
#if 0
823
        printf("PF exception: EIP=0x%08x CR2=0x%08x error=0x%x\n",
824
               env->eip, env->cr[2], env->error_code);
825
#endif
826
        /* we restore the process signal mask as the sigreturn should
827
           do it (XXX: use sigsetjmp) */
828
        sigprocmask(SIG_SETMASK, old_set, NULL);
829
        raise_exception_err(env->exception_index, env->error_code);
830
    } else {
831
        /* activate soft MMU for this block */
832
        env->hflags |= HF_SOFTMMU_MASK;
833
        cpu_resume_from_signal(env, puc);
834
    }
835
    /* never comes here */
836
    return 1;
837
}
838

    
839
#elif defined(TARGET_ARM)
840
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
841
                                    int is_write, sigset_t *old_set,
842
                                    void *puc)
843
{
844
    TranslationBlock *tb;
845
    int ret;
846

    
847
    if (cpu_single_env)
848
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
849
#if defined(DEBUG_SIGNAL)
850
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
851
           pc, address, is_write, *(unsigned long *)old_set);
852
#endif
853
    /* XXX: locking issue */
854
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
855
        return 1;
856
    }
857
    /* see if it is an MMU fault */
858
    ret = cpu_arm_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
859
    if (ret < 0)
860
        return 0; /* not an MMU fault */
861
    if (ret == 0)
862
        return 1; /* the MMU fault was handled without causing real CPU fault */
863
    /* now we have a real cpu fault */
864
    tb = tb_find_pc(pc);
865
    if (tb) {
866
        /* the PC is inside the translated code. It means that we have
867
           a virtual CPU fault */
868
        cpu_restore_state(tb, env, pc, puc);
869
    }
870
    /* we restore the process signal mask as the sigreturn should
871
       do it (XXX: use sigsetjmp) */
872
    sigprocmask(SIG_SETMASK, old_set, NULL);
873
    cpu_loop_exit();
874
    /* never comes here */
875
    return 1;
876
}
877
#elif defined(TARGET_SPARC)
878
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
879
                                    int is_write, sigset_t *old_set,
880
                                    void *puc)
881
{
882
    TranslationBlock *tb;
883
    int ret;
884

    
885
    if (cpu_single_env)
886
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
887
#if defined(DEBUG_SIGNAL)
888
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
889
           pc, address, is_write, *(unsigned long *)old_set);
890
#endif
891
    /* XXX: locking issue */
892
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
893
        return 1;
894
    }
895
    /* see if it is an MMU fault */
896
    ret = cpu_sparc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
897
    if (ret < 0)
898
        return 0; /* not an MMU fault */
899
    if (ret == 0)
900
        return 1; /* the MMU fault was handled without causing real CPU fault */
901
    /* now we have a real cpu fault */
902
    tb = tb_find_pc(pc);
903
    if (tb) {
904
        /* the PC is inside the translated code. It means that we have
905
           a virtual CPU fault */
906
        cpu_restore_state(tb, env, pc, puc);
907
    }
908
    /* we restore the process signal mask as the sigreturn should
909
       do it (XXX: use sigsetjmp) */
910
    sigprocmask(SIG_SETMASK, old_set, NULL);
911
    cpu_loop_exit();
912
    /* never comes here */
913
    return 1;
914
}
915
#elif defined (TARGET_PPC)
916
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
917
                                    int is_write, sigset_t *old_set,
918
                                    void *puc)
919
{
920
    TranslationBlock *tb;
921
    int ret;
922

    
923
    if (cpu_single_env)
924
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
925
#if defined(DEBUG_SIGNAL)
926
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
927
           pc, address, is_write, *(unsigned long *)old_set);
928
#endif
929
    /* XXX: locking issue */
930
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
931
        return 1;
932
    }
933

    
934
    /* see if it is an MMU fault */
935
    ret = cpu_ppc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
936
    if (ret < 0)
937
        return 0; /* not an MMU fault */
938
    if (ret == 0)
939
        return 1; /* the MMU fault was handled without causing real CPU fault */
940

    
941
    /* now we have a real cpu fault */
942
    tb = tb_find_pc(pc);
943
    if (tb) {
944
        /* the PC is inside the translated code. It means that we have
945
           a virtual CPU fault */
946
        cpu_restore_state(tb, env, pc, puc);
947
    }
948
    if (ret == 1) {
949
#if 0
950
        printf("PF exception: NIP=0x%08x error=0x%x %p\n",
951
               env->nip, env->error_code, tb);
952
#endif
953
    /* we restore the process signal mask as the sigreturn should
954
       do it (XXX: use sigsetjmp) */
955
        sigprocmask(SIG_SETMASK, old_set, NULL);
956
        cpu_loop_exit();
957
    } else {
958
        /* activate soft MMU for this block */
959
        cpu_resume_from_signal(env, puc);
960
    }
961
    /* never comes here */
962
    return 1;
963
}
964

    
965
#elif defined(TARGET_M68K)
966
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
967
                                    int is_write, sigset_t *old_set,
968
                                    void *puc)
969
{
970
    TranslationBlock *tb;
971
    int ret;
972

    
973
    if (cpu_single_env)
974
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
975
#if defined(DEBUG_SIGNAL)
976
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
977
           pc, address, is_write, *(unsigned long *)old_set);
978
#endif
979
    /* XXX: locking issue */
980
    if (is_write && page_unprotect(address, pc, puc)) {
981
        return 1;
982
    }
983
    /* see if it is an MMU fault */
984
    ret = cpu_m68k_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
985
    if (ret < 0)
986
        return 0; /* not an MMU fault */
987
    if (ret == 0)
988
        return 1; /* the MMU fault was handled without causing real CPU fault */
989
    /* now we have a real cpu fault */
990
    tb = tb_find_pc(pc);
991
    if (tb) {
992
        /* the PC is inside the translated code. It means that we have
993
           a virtual CPU fault */
994
        cpu_restore_state(tb, env, pc, puc);
995
    }
996
    /* we restore the process signal mask as the sigreturn should
997
       do it (XXX: use sigsetjmp) */
998
    sigprocmask(SIG_SETMASK, old_set, NULL);
999
    cpu_loop_exit();
1000
    /* never comes here */
1001
    return 1;
1002
}
1003

    
1004
#elif defined (TARGET_MIPS)
1005
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1006
                                    int is_write, sigset_t *old_set,
1007
                                    void *puc)
1008
{
1009
    TranslationBlock *tb;
1010
    int ret;
1011

    
1012
    if (cpu_single_env)
1013
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
1014
#if defined(DEBUG_SIGNAL)
1015
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
1016
           pc, address, is_write, *(unsigned long *)old_set);
1017
#endif
1018
    /* XXX: locking issue */
1019
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
1020
        return 1;
1021
    }
1022

    
1023
    /* see if it is an MMU fault */
1024
    ret = cpu_mips_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
1025
    if (ret < 0)
1026
        return 0; /* not an MMU fault */
1027
    if (ret == 0)
1028
        return 1; /* the MMU fault was handled without causing real CPU fault */
1029

    
1030
    /* now we have a real cpu fault */
1031
    tb = tb_find_pc(pc);
1032
    if (tb) {
1033
        /* the PC is inside the translated code. It means that we have
1034
           a virtual CPU fault */
1035
        cpu_restore_state(tb, env, pc, puc);
1036
    }
1037
    if (ret == 1) {
1038
#if 0
1039
        printf("PF exception: PC=0x" TARGET_FMT_lx " error=0x%x %p\n",
1040
               env->PC, env->error_code, tb);
1041
#endif
1042
    /* we restore the process signal mask as the sigreturn should
1043
       do it (XXX: use sigsetjmp) */
1044
        sigprocmask(SIG_SETMASK, old_set, NULL);
1045
        cpu_loop_exit();
1046
    } else {
1047
        /* activate soft MMU for this block */
1048
        cpu_resume_from_signal(env, puc);
1049
    }
1050
    /* never comes here */
1051
    return 1;
1052
}
1053

    
1054
#elif defined (TARGET_MICROBLAZE)
1055
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1056
                                    int is_write, sigset_t *old_set,
1057
                                    void *puc)
1058
{
1059
    TranslationBlock *tb;
1060
    int ret;
1061

    
1062
    if (cpu_single_env)
1063
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
1064
#if defined(DEBUG_SIGNAL)
1065
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
1066
           pc, address, is_write, *(unsigned long *)old_set);
1067
#endif
1068
    /* XXX: locking issue */
1069
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
1070
        return 1;
1071
    }
1072

    
1073
    /* see if it is an MMU fault */
1074
    ret = cpu_mb_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
1075
    if (ret < 0)
1076
        return 0; /* not an MMU fault */
1077
    if (ret == 0)
1078
        return 1; /* the MMU fault was handled without causing real CPU fault */
1079

    
1080
    /* now we have a real cpu fault */
1081
    tb = tb_find_pc(pc);
1082
    if (tb) {
1083
        /* the PC is inside the translated code. It means that we have
1084
           a virtual CPU fault */
1085
        cpu_restore_state(tb, env, pc, puc);
1086
    }
1087
    if (ret == 1) {
1088
#if 0
1089
        printf("PF exception: PC=0x" TARGET_FMT_lx " error=0x%x %p\n",
1090
               env->PC, env->error_code, tb);
1091
#endif
1092
    /* we restore the process signal mask as the sigreturn should
1093
       do it (XXX: use sigsetjmp) */
1094
        sigprocmask(SIG_SETMASK, old_set, NULL);
1095
        cpu_loop_exit();
1096
    } else {
1097
        /* activate soft MMU for this block */
1098
        cpu_resume_from_signal(env, puc);
1099
    }
1100
    /* never comes here */
1101
    return 1;
1102
}
1103

    
1104
#elif defined (TARGET_SH4)
1105
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1106
                                    int is_write, sigset_t *old_set,
1107
                                    void *puc)
1108
{
1109
    TranslationBlock *tb;
1110
    int ret;
1111

    
1112
    if (cpu_single_env)
1113
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
1114
#if defined(DEBUG_SIGNAL)
1115
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
1116
           pc, address, is_write, *(unsigned long *)old_set);
1117
#endif
1118
    /* XXX: locking issue */
1119
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
1120
        return 1;
1121
    }
1122

    
1123
    /* see if it is an MMU fault */
1124
    ret = cpu_sh4_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
1125
    if (ret < 0)
1126
        return 0; /* not an MMU fault */
1127
    if (ret == 0)
1128
        return 1; /* the MMU fault was handled without causing real CPU fault */
1129

    
1130
    /* now we have a real cpu fault */
1131
    tb = tb_find_pc(pc);
1132
    if (tb) {
1133
        /* the PC is inside the translated code. It means that we have
1134
           a virtual CPU fault */
1135
        cpu_restore_state(tb, env, pc, puc);
1136
    }
1137
#if 0
1138
        printf("PF exception: NIP=0x%08x error=0x%x %p\n",
1139
               env->nip, env->error_code, tb);
1140
#endif
1141
    /* we restore the process signal mask as the sigreturn should
1142
       do it (XXX: use sigsetjmp) */
1143
    sigprocmask(SIG_SETMASK, old_set, NULL);
1144
    cpu_loop_exit();
1145
    /* never comes here */
1146
    return 1;
1147
}
1148

    
1149
#elif defined (TARGET_ALPHA)
1150
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1151
                                    int is_write, sigset_t *old_set,
1152
                                    void *puc)
1153
{
1154
    TranslationBlock *tb;
1155
    int ret;
1156

    
1157
    if (cpu_single_env)
1158
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
1159
#if defined(DEBUG_SIGNAL)
1160
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
1161
           pc, address, is_write, *(unsigned long *)old_set);
1162
#endif
1163
    /* XXX: locking issue */
1164
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
1165
        return 1;
1166
    }
1167

    
1168
    /* see if it is an MMU fault */
1169
    ret = cpu_alpha_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
1170
    if (ret < 0)
1171
        return 0; /* not an MMU fault */
1172
    if (ret == 0)
1173
        return 1; /* the MMU fault was handled without causing real CPU fault */
1174

    
1175
    /* now we have a real cpu fault */
1176
    tb = tb_find_pc(pc);
1177
    if (tb) {
1178
        /* the PC is inside the translated code. It means that we have
1179
           a virtual CPU fault */
1180
        cpu_restore_state(tb, env, pc, puc);
1181
    }
1182
#if 0
1183
        printf("PF exception: NIP=0x%08x error=0x%x %p\n",
1184
               env->nip, env->error_code, tb);
1185
#endif
1186
    /* we restore the process signal mask as the sigreturn should
1187
       do it (XXX: use sigsetjmp) */
1188
    sigprocmask(SIG_SETMASK, old_set, NULL);
1189
    cpu_loop_exit();
1190
    /* never comes here */
1191
    return 1;
1192
}
1193
#elif defined (TARGET_CRIS)
1194
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1195
                                    int is_write, sigset_t *old_set,
1196
                                    void *puc)
1197
{
1198
    TranslationBlock *tb;
1199
    int ret;
1200

    
1201
    if (cpu_single_env)
1202
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
1203
#if defined(DEBUG_SIGNAL)
1204
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
1205
           pc, address, is_write, *(unsigned long *)old_set);
1206
#endif
1207
    /* XXX: locking issue */
1208
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
1209
        return 1;
1210
    }
1211

    
1212
    /* see if it is an MMU fault */
1213
    ret = cpu_cris_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
1214
    if (ret < 0)
1215
        return 0; /* not an MMU fault */
1216
    if (ret == 0)
1217
        return 1; /* the MMU fault was handled without causing real CPU fault */
1218

    
1219
    /* now we have a real cpu fault */
1220
    tb = tb_find_pc(pc);
1221
    if (tb) {
1222
        /* the PC is inside the translated code. It means that we have
1223
           a virtual CPU fault */
1224
        cpu_restore_state(tb, env, pc, puc);
1225
    }
1226
    /* we restore the process signal mask as the sigreturn should
1227
       do it (XXX: use sigsetjmp) */
1228
    sigprocmask(SIG_SETMASK, old_set, NULL);
1229
    cpu_loop_exit();
1230
    /* never comes here */
1231
    return 1;
1232
}
1233

    
1234
#else
1235
#error unsupported target CPU
1236
#endif
1237

    
1238
#if defined(__i386__)
1239

    
1240
#if defined(__APPLE__)
1241
# include <sys/ucontext.h>
1242

    
1243
# define EIP_sig(context)  (*((unsigned long*)&(context)->uc_mcontext->ss.eip))
1244
# define TRAP_sig(context)    ((context)->uc_mcontext->es.trapno)
1245
# define ERROR_sig(context)   ((context)->uc_mcontext->es.err)
1246
# define MASK_sig(context)    ((context)->uc_sigmask)
1247
#elif defined(__OpenBSD__)
1248
# define EIP_sig(context)     ((context)->sc_eip)
1249
# define TRAP_sig(context)    ((context)->sc_trapno)
1250
# define ERROR_sig(context)   ((context)->sc_err)
1251
# define MASK_sig(context)    ((context)->sc_mask)
1252
#else
1253
# define EIP_sig(context)     ((context)->uc_mcontext.gregs[REG_EIP])
1254
# define TRAP_sig(context)    ((context)->uc_mcontext.gregs[REG_TRAPNO])
1255
# define ERROR_sig(context)   ((context)->uc_mcontext.gregs[REG_ERR])
1256
# define MASK_sig(context)    ((context)->uc_sigmask)
1257
#endif
1258

    
1259
int cpu_signal_handler(int host_signum, void *pinfo,
1260
                       void *puc)
1261
{
1262
    siginfo_t *info = pinfo;
1263
#if defined(__OpenBSD__)
1264
    struct sigcontext *uc = puc;
1265
#else
1266
    struct ucontext *uc = puc;
1267
#endif
1268
    unsigned long pc;
1269
    int trapno;
1270

    
1271
#ifndef REG_EIP
1272
/* for glibc 2.1 */
1273
#define REG_EIP    EIP
1274
#define REG_ERR    ERR
1275
#define REG_TRAPNO TRAPNO
1276
#endif
1277
    pc = EIP_sig(uc);
1278
    trapno = TRAP_sig(uc);
1279
    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1280
                             trapno == 0xe ?
1281
                             (ERROR_sig(uc) >> 1) & 1 : 0,
1282
                             &MASK_sig(uc), puc);
1283
}
1284

    
1285
#elif defined(__x86_64__)
1286

    
1287
#ifdef __NetBSD__
1288
#define PC_sig(context)       _UC_MACHINE_PC(context)
1289
#define TRAP_sig(context)     ((context)->uc_mcontext.__gregs[_REG_TRAPNO])
1290
#define ERROR_sig(context)    ((context)->uc_mcontext.__gregs[_REG_ERR])
1291
#define MASK_sig(context)     ((context)->uc_sigmask)
1292
#elif defined(__OpenBSD__)
1293
#define PC_sig(context)       ((context)->sc_rip)
1294
#define TRAP_sig(context)     ((context)->sc_trapno)
1295
#define ERROR_sig(context)    ((context)->sc_err)
1296
#define MASK_sig(context)     ((context)->sc_mask)
1297
#else
1298
#define PC_sig(context)       ((context)->uc_mcontext.gregs[REG_RIP])
1299
#define TRAP_sig(context)     ((context)->uc_mcontext.gregs[REG_TRAPNO])
1300
#define ERROR_sig(context)    ((context)->uc_mcontext.gregs[REG_ERR])
1301
#define MASK_sig(context)     ((context)->uc_sigmask)
1302
#endif
1303

    
1304
int cpu_signal_handler(int host_signum, void *pinfo,
1305
                       void *puc)
1306
{
1307
    siginfo_t *info = pinfo;
1308
    unsigned long pc;
1309
#ifdef __NetBSD__
1310
    ucontext_t *uc = puc;
1311
#elif defined(__OpenBSD__)
1312
    struct sigcontext *uc = puc;
1313
#else
1314
    struct ucontext *uc = puc;
1315
#endif
1316

    
1317
    pc = PC_sig(uc);
1318
    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1319
                             TRAP_sig(uc) == 0xe ?
1320
                             (ERROR_sig(uc) >> 1) & 1 : 0,
1321
                             &MASK_sig(uc), puc);
1322
}
1323

    
1324
#elif defined(_ARCH_PPC)
1325

    
1326
/***********************************************************************
1327
 * signal context platform-specific definitions
1328
 * From Wine
1329
 */
1330
#ifdef linux
1331
/* All Registers access - only for local access */
1332
# define REG_sig(reg_name, context)                ((context)->uc_mcontext.regs->reg_name)
1333
/* Gpr Registers access  */
1334
# define GPR_sig(reg_num, context)                REG_sig(gpr[reg_num], context)
1335
# define IAR_sig(context)                        REG_sig(nip, context)        /* Program counter */
1336
# define MSR_sig(context)                        REG_sig(msr, context)   /* Machine State Register (Supervisor) */
1337
# define CTR_sig(context)                        REG_sig(ctr, context)   /* Count register */
1338
# define XER_sig(context)                        REG_sig(xer, context) /* User's integer exception register */
1339
# define LR_sig(context)                        REG_sig(link, context) /* Link register */
1340
# define CR_sig(context)                        REG_sig(ccr, context) /* Condition register */
1341
/* Float Registers access  */
1342
# define FLOAT_sig(reg_num, context)                (((double*)((char*)((context)->uc_mcontext.regs+48*4)))[reg_num])
1343
# define FPSCR_sig(context)                        (*(int*)((char*)((context)->uc_mcontext.regs+(48+32*2)*4)))
1344
/* Exception Registers access */
1345
# define DAR_sig(context)                        REG_sig(dar, context)
1346
# define DSISR_sig(context)                        REG_sig(dsisr, context)
1347
# define TRAP_sig(context)                        REG_sig(trap, context)
1348
#endif /* linux */
1349

    
1350
#ifdef __APPLE__
1351
# include <sys/ucontext.h>
1352
typedef struct ucontext SIGCONTEXT;
1353
/* All Registers access - only for local access */
1354
# define REG_sig(reg_name, context)                ((context)->uc_mcontext->ss.reg_name)
1355
# define FLOATREG_sig(reg_name, context)        ((context)->uc_mcontext->fs.reg_name)
1356
# define EXCEPREG_sig(reg_name, context)        ((context)->uc_mcontext->es.reg_name)
1357
# define VECREG_sig(reg_name, context)                ((context)->uc_mcontext->vs.reg_name)
1358
/* Gpr Registers access */
1359
# define GPR_sig(reg_num, context)                REG_sig(r##reg_num, context)
1360
# define IAR_sig(context)                        REG_sig(srr0, context)        /* Program counter */
1361
# define MSR_sig(context)                        REG_sig(srr1, context)  /* Machine State Register (Supervisor) */
1362
# define CTR_sig(context)                        REG_sig(ctr, context)
1363
# define XER_sig(context)                        REG_sig(xer, context) /* Link register */
1364
# define LR_sig(context)                        REG_sig(lr, context)  /* User's integer exception register */
1365
# define CR_sig(context)                        REG_sig(cr, context)  /* Condition register */
1366
/* Float Registers access */
1367
# define FLOAT_sig(reg_num, context)                FLOATREG_sig(fpregs[reg_num], context)
1368
# define FPSCR_sig(context)                        ((double)FLOATREG_sig(fpscr, context))
1369
/* Exception Registers access */
1370
# define DAR_sig(context)                        EXCEPREG_sig(dar, context)     /* Fault registers for coredump */
1371
# define DSISR_sig(context)                        EXCEPREG_sig(dsisr, context)
1372
# define TRAP_sig(context)                        EXCEPREG_sig(exception, context) /* number of powerpc exception taken */
1373
#endif /* __APPLE__ */
1374

    
1375
int cpu_signal_handler(int host_signum, void *pinfo,
1376
                       void *puc)
1377
{
1378
    siginfo_t *info = pinfo;
1379
    struct ucontext *uc = puc;
1380
    unsigned long pc;
1381
    int is_write;
1382

    
1383
    pc = IAR_sig(uc);
1384
    is_write = 0;
1385
#if 0
1386
    /* ppc 4xx case */
1387
    if (DSISR_sig(uc) & 0x00800000)
1388
        is_write = 1;
1389
#else
1390
    if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000))
1391
        is_write = 1;
1392
#endif
1393
    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1394
                             is_write, &uc->uc_sigmask, puc);
1395
}
1396

    
1397
#elif defined(__alpha__)
1398

    
1399
int cpu_signal_handler(int host_signum, void *pinfo,
1400
                           void *puc)
1401
{
1402
    siginfo_t *info = pinfo;
1403
    struct ucontext *uc = puc;
1404
    uint32_t *pc = uc->uc_mcontext.sc_pc;
1405
    uint32_t insn = *pc;
1406
    int is_write = 0;
1407

    
1408
    /* XXX: need kernel patch to get write flag faster */
1409
    switch (insn >> 26) {
1410
    case 0x0d: // stw
1411
    case 0x0e: // stb
1412
    case 0x0f: // stq_u
1413
    case 0x24: // stf
1414
    case 0x25: // stg
1415
    case 0x26: // sts
1416
    case 0x27: // stt
1417
    case 0x2c: // stl
1418
    case 0x2d: // stq
1419
    case 0x2e: // stl_c
1420
    case 0x2f: // stq_c
1421
        is_write = 1;
1422
    }
1423

    
1424
    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1425
                             is_write, &uc->uc_sigmask, puc);
1426
}
1427
#elif defined(__sparc__)
1428

    
1429
int cpu_signal_handler(int host_signum, void *pinfo,
1430
                       void *puc)
1431
{
1432
    siginfo_t *info = pinfo;
1433
    int is_write;
1434
    uint32_t insn;
1435
#if !defined(__arch64__) || defined(HOST_SOLARIS)
1436
    uint32_t *regs = (uint32_t *)(info + 1);
1437
    void *sigmask = (regs + 20);
1438
    /* XXX: is there a standard glibc define ? */
1439
    unsigned long pc = regs[1];
1440
#else
1441
#ifdef __linux__
1442
    struct sigcontext *sc = puc;
1443
    unsigned long pc = sc->sigc_regs.tpc;
1444
    void *sigmask = (void *)sc->sigc_mask;
1445
#elif defined(__OpenBSD__)
1446
    struct sigcontext *uc = puc;
1447
    unsigned long pc = uc->sc_pc;
1448
    void *sigmask = (void *)(long)uc->sc_mask;
1449
#endif
1450
#endif
1451

    
1452
    /* XXX: need kernel patch to get write flag faster */
1453
    is_write = 0;
1454
    insn = *(uint32_t *)pc;
1455
    if ((insn >> 30) == 3) {
1456
      switch((insn >> 19) & 0x3f) {
1457
      case 0x05: // stb
1458
      case 0x15: // stba
1459
      case 0x06: // sth
1460
      case 0x16: // stha
1461
      case 0x04: // st
1462
      case 0x14: // sta
1463
      case 0x07: // std
1464
      case 0x17: // stda
1465
      case 0x0e: // stx
1466
      case 0x1e: // stxa
1467
      case 0x24: // stf
1468
      case 0x34: // stfa
1469
      case 0x27: // stdf
1470
      case 0x37: // stdfa
1471
      case 0x26: // stqf
1472
      case 0x36: // stqfa
1473
      case 0x25: // stfsr
1474
      case 0x3c: // casa
1475
      case 0x3e: // casxa
1476
        is_write = 1;
1477
        break;
1478
      }
1479
    }
1480
    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1481
                             is_write, sigmask, NULL);
1482
}
1483

    
1484
#elif defined(__arm__)
1485

    
1486
int cpu_signal_handler(int host_signum, void *pinfo,
1487
                       void *puc)
1488
{
1489
    siginfo_t *info = pinfo;
1490
    struct ucontext *uc = puc;
1491
    unsigned long pc;
1492
    int is_write;
1493

    
1494
#if (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
1495
    pc = uc->uc_mcontext.gregs[R15];
1496
#else
1497
    pc = uc->uc_mcontext.arm_pc;
1498
#endif
1499
    /* XXX: compute is_write */
1500
    is_write = 0;
1501
    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1502
                             is_write,
1503
                             &uc->uc_sigmask, puc);
1504
}
1505

    
1506
#elif defined(__mc68000)
1507

    
1508
int cpu_signal_handler(int host_signum, void *pinfo,
1509
                       void *puc)
1510
{
1511
    siginfo_t *info = pinfo;
1512
    struct ucontext *uc = puc;
1513
    unsigned long pc;
1514
    int is_write;
1515

    
1516
    pc = uc->uc_mcontext.gregs[16];
1517
    /* XXX: compute is_write */
1518
    is_write = 0;
1519
    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1520
                             is_write,
1521
                             &uc->uc_sigmask, puc);
1522
}
1523

    
1524
#elif defined(__ia64)
1525

    
1526
#ifndef __ISR_VALID
1527
  /* This ought to be in <bits/siginfo.h>... */
1528
# define __ISR_VALID        1
1529
#endif
1530

    
1531
int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
1532
{
1533
    siginfo_t *info = pinfo;
1534
    struct ucontext *uc = puc;
1535
    unsigned long ip;
1536
    int is_write = 0;
1537

    
1538
    ip = uc->uc_mcontext.sc_ip;
1539
    switch (host_signum) {
1540
      case SIGILL:
1541
      case SIGFPE:
1542
      case SIGSEGV:
1543
      case SIGBUS:
1544
      case SIGTRAP:
1545
          if (info->si_code && (info->si_segvflags & __ISR_VALID))
1546
              /* ISR.W (write-access) is bit 33:  */
1547
              is_write = (info->si_isr >> 33) & 1;
1548
          break;
1549

    
1550
      default:
1551
          break;
1552
    }
1553
    return handle_cpu_signal(ip, (unsigned long)info->si_addr,
1554
                             is_write,
1555
                             &uc->uc_sigmask, puc);
1556
}
1557

    
1558
#elif defined(__s390__)
1559

    
1560
int cpu_signal_handler(int host_signum, void *pinfo,
1561
                       void *puc)
1562
{
1563
    siginfo_t *info = pinfo;
1564
    struct ucontext *uc = puc;
1565
    unsigned long pc;
1566
    int is_write;
1567

    
1568
    pc = uc->uc_mcontext.psw.addr;
1569
    /* XXX: compute is_write */
1570
    is_write = 0;
1571
    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1572
                             is_write, &uc->uc_sigmask, puc);
1573
}
1574

    
1575
#elif defined(__mips__)
1576

    
1577
int cpu_signal_handler(int host_signum, void *pinfo,
1578
                       void *puc)
1579
{
1580
    siginfo_t *info = pinfo;
1581
    struct ucontext *uc = puc;
1582
    greg_t pc = uc->uc_mcontext.pc;
1583
    int is_write;
1584

    
1585
    /* XXX: compute is_write */
1586
    is_write = 0;
1587
    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1588
                             is_write, &uc->uc_sigmask, puc);
1589
}
1590

    
1591
#elif defined(__hppa__)
1592

    
1593
int cpu_signal_handler(int host_signum, void *pinfo,
1594
                       void *puc)
1595
{
1596
    struct siginfo *info = pinfo;
1597
    struct ucontext *uc = puc;
1598
    unsigned long pc;
1599
    int is_write;
1600

    
1601
    pc = uc->uc_mcontext.sc_iaoq[0];
1602
    /* FIXME: compute is_write */
1603
    is_write = 0;
1604
    return handle_cpu_signal(pc, (unsigned long)info->si_addr, 
1605
                             is_write,
1606
                             &uc->uc_sigmask, puc);
1607
}
1608

    
1609
#else
1610

    
1611
#error host CPU specific signal handler needed
1612

    
1613
#endif
1614

    
1615
#endif /* !defined(CONFIG_SOFTMMU) */