Statistics
| Branch: | Revision:

root / cpu-exec.c @ 2cade6a3

History | View | Annotate | Download (50.7 kB)

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