Statistics
| Branch: | Revision:

root / kqemu.c @ 0443eaf6

History | View | Annotate | Download (11.5 kB)

1 9df217a3 bellard
/*
2 9df217a3 bellard
 *  KQEMU support
3 9df217a3 bellard
 * 
4 9df217a3 bellard
 *  Copyright (c) 2005 Fabrice Bellard
5 9df217a3 bellard
 *
6 9df217a3 bellard
 * This library is free software; you can redistribute it and/or
7 9df217a3 bellard
 * modify it under the terms of the GNU Lesser General Public
8 9df217a3 bellard
 * License as published by the Free Software Foundation; either
9 9df217a3 bellard
 * version 2 of the License, or (at your option) any later version.
10 9df217a3 bellard
 *
11 9df217a3 bellard
 * This library is distributed in the hope that it will be useful,
12 9df217a3 bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 9df217a3 bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 9df217a3 bellard
 * Lesser General Public License for more details.
15 9df217a3 bellard
 *
16 9df217a3 bellard
 * You should have received a copy of the GNU Lesser General Public
17 9df217a3 bellard
 * License along with this library; if not, write to the Free Software
18 9df217a3 bellard
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 9df217a3 bellard
 */
20 9df217a3 bellard
#include "config.h"
21 9df217a3 bellard
#ifdef _WIN32
22 9df217a3 bellard
#include <windows.h>
23 9df217a3 bellard
#else
24 9df217a3 bellard
#include <sys/types.h>
25 9df217a3 bellard
#include <sys/mman.h>
26 9df217a3 bellard
#endif
27 9df217a3 bellard
#include <stdlib.h>
28 9df217a3 bellard
#include <stdio.h>
29 9df217a3 bellard
#include <stdarg.h>
30 9df217a3 bellard
#include <string.h>
31 9df217a3 bellard
#include <errno.h>
32 9df217a3 bellard
#include <unistd.h>
33 9df217a3 bellard
#include <inttypes.h>
34 9df217a3 bellard
35 9df217a3 bellard
#include "cpu.h"
36 9df217a3 bellard
#include "exec-all.h"
37 9df217a3 bellard
38 9df217a3 bellard
#ifdef USE_KQEMU
39 9df217a3 bellard
40 9df217a3 bellard
#define DEBUG
41 9df217a3 bellard
42 9df217a3 bellard
#include <unistd.h>
43 9df217a3 bellard
#include <fcntl.h>
44 9df217a3 bellard
#include <sys/ioctl.h>
45 9df217a3 bellard
#include "kqemu/kqemu.h"
46 9df217a3 bellard
47 9df217a3 bellard
#define KQEMU_DEVICE "/dev/kqemu"
48 9df217a3 bellard
49 9df217a3 bellard
int kqemu_allowed = 1;
50 9df217a3 bellard
int kqemu_fd = -1;
51 9df217a3 bellard
unsigned long *pages_to_flush;
52 9df217a3 bellard
unsigned int nb_pages_to_flush;
53 9df217a3 bellard
extern uint32_t **l1_phys_map;
54 9df217a3 bellard
55 9df217a3 bellard
#define cpuid(index, eax, ebx, ecx, edx) \
56 9df217a3 bellard
  asm volatile ("cpuid" \
57 9df217a3 bellard
                : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) \
58 9df217a3 bellard
                : "0" (index))
59 9df217a3 bellard
60 9df217a3 bellard
static int is_cpuid_supported(void)
61 9df217a3 bellard
{
62 9df217a3 bellard
    int v0, v1;
63 9df217a3 bellard
    asm volatile ("pushf\n"
64 9df217a3 bellard
                  "popl %0\n"
65 9df217a3 bellard
                  "movl %0, %1\n"
66 9df217a3 bellard
                  "xorl $0x00200000, %0\n"
67 9df217a3 bellard
                  "pushl %0\n"
68 9df217a3 bellard
                  "popf\n"
69 9df217a3 bellard
                  "pushf\n"
70 9df217a3 bellard
                  "popl %0\n"
71 9df217a3 bellard
                  : "=a" (v0), "=d" (v1)
72 9df217a3 bellard
                  :
73 9df217a3 bellard
                  : "cc");
74 9df217a3 bellard
    return (v0 != v1);
75 9df217a3 bellard
}
76 9df217a3 bellard
77 9df217a3 bellard
static void kqemu_update_cpuid(CPUState *env)
78 9df217a3 bellard
{
79 9df217a3 bellard
    int critical_features_mask, features;
80 9df217a3 bellard
    uint32_t eax, ebx, ecx, edx;
81 9df217a3 bellard
82 9df217a3 bellard
    /* the following features are kept identical on the host and
83 9df217a3 bellard
       target cpus because they are important for user code. Strictly
84 9df217a3 bellard
       speaking, only SSE really matters because the OS must support
85 9df217a3 bellard
       it if the user code uses it. */
86 9df217a3 bellard
    critical_features_mask = 
87 9df217a3 bellard
        CPUID_CMOV | CPUID_CX8 | 
88 9df217a3 bellard
        CPUID_FXSR | CPUID_MMX | CPUID_SSE | 
89 9df217a3 bellard
        CPUID_SSE2;
90 9df217a3 bellard
    if (!is_cpuid_supported()) {
91 9df217a3 bellard
        features = 0;
92 9df217a3 bellard
    } else {
93 9df217a3 bellard
        cpuid(1, eax, ebx, ecx, edx);
94 9df217a3 bellard
        features = edx;
95 9df217a3 bellard
    }
96 9df217a3 bellard
    env->cpuid_features = (env->cpuid_features & ~critical_features_mask) |
97 9df217a3 bellard
        (features & critical_features_mask);
98 9df217a3 bellard
    /* XXX: we could update more of the target CPUID state so that the
99 9df217a3 bellard
       non accelerated code sees exactly the same CPU features as the
100 9df217a3 bellard
       accelerated code */
101 9df217a3 bellard
}
102 9df217a3 bellard
103 9df217a3 bellard
int kqemu_init(CPUState *env)
104 9df217a3 bellard
{
105 9df217a3 bellard
    struct kqemu_init init;
106 9df217a3 bellard
    int ret, version;
107 9df217a3 bellard
108 9df217a3 bellard
    if (!kqemu_allowed)
109 9df217a3 bellard
        return -1;
110 9df217a3 bellard
111 9df217a3 bellard
    kqemu_fd = open(KQEMU_DEVICE, O_RDWR);
112 9df217a3 bellard
    if (kqemu_fd < 0) {
113 9df217a3 bellard
        fprintf(stderr, "Could not open '%s' - QEMU acceleration layer not activated\n", KQEMU_DEVICE);
114 9df217a3 bellard
        return -1;
115 9df217a3 bellard
    }
116 9df217a3 bellard
    version = 0;
117 9df217a3 bellard
    ioctl(kqemu_fd, KQEMU_GET_VERSION, &version);
118 9df217a3 bellard
    if (version != KQEMU_VERSION) {
119 9df217a3 bellard
        fprintf(stderr, "Version mismatch between kqemu module and qemu (%08x %08x) - disabling kqemu use\n",
120 9df217a3 bellard
                version, KQEMU_VERSION);
121 9df217a3 bellard
        goto fail;
122 9df217a3 bellard
    }
123 9df217a3 bellard
124 9df217a3 bellard
    pages_to_flush = qemu_vmalloc(KQEMU_MAX_PAGES_TO_FLUSH * 
125 9df217a3 bellard
                                  sizeof(unsigned long));
126 9df217a3 bellard
    if (!pages_to_flush)
127 9df217a3 bellard
        goto fail;
128 9df217a3 bellard
129 9df217a3 bellard
    init.ram_base = phys_ram_base;
130 9df217a3 bellard
    init.ram_size = phys_ram_size;
131 9df217a3 bellard
    init.ram_dirty = phys_ram_dirty;
132 9df217a3 bellard
    init.phys_to_ram_map = l1_phys_map;
133 9df217a3 bellard
    init.pages_to_flush = pages_to_flush;
134 9df217a3 bellard
    ret = ioctl(kqemu_fd, KQEMU_INIT, &init);
135 9df217a3 bellard
    if (ret < 0) {
136 9df217a3 bellard
        fprintf(stderr, "Error %d while initializing QEMU acceleration layer - disabling it for now\n", ret);
137 9df217a3 bellard
    fail:
138 9df217a3 bellard
        close(kqemu_fd);
139 9df217a3 bellard
        kqemu_fd = -1;
140 9df217a3 bellard
        return -1;
141 9df217a3 bellard
    }
142 9df217a3 bellard
    kqemu_update_cpuid(env);
143 9df217a3 bellard
    env->kqemu_enabled = 1;
144 9df217a3 bellard
    nb_pages_to_flush = 0;
145 9df217a3 bellard
    return 0;
146 9df217a3 bellard
}
147 9df217a3 bellard
148 9df217a3 bellard
void kqemu_flush_page(CPUState *env, target_ulong addr)
149 9df217a3 bellard
{
150 9df217a3 bellard
#ifdef DEBUG
151 9df217a3 bellard
    if (loglevel & CPU_LOG_INT) {
152 9df217a3 bellard
        fprintf(logfile, "kqemu_flush_page: addr=" TARGET_FMT_lx "\n", addr);
153 9df217a3 bellard
    }
154 9df217a3 bellard
#endif
155 9df217a3 bellard
    if (nb_pages_to_flush >= KQEMU_MAX_PAGES_TO_FLUSH)
156 9df217a3 bellard
        nb_pages_to_flush = KQEMU_FLUSH_ALL;
157 9df217a3 bellard
    else
158 9df217a3 bellard
        pages_to_flush[nb_pages_to_flush++] = addr;
159 9df217a3 bellard
}
160 9df217a3 bellard
161 9df217a3 bellard
void kqemu_flush(CPUState *env, int global)
162 9df217a3 bellard
{
163 9df217a3 bellard
#ifdef DEBUG
164 9df217a3 bellard
    if (loglevel & CPU_LOG_INT) {
165 9df217a3 bellard
        fprintf(logfile, "kqemu_flush:\n");
166 9df217a3 bellard
    }
167 9df217a3 bellard
#endif
168 9df217a3 bellard
    nb_pages_to_flush = KQEMU_FLUSH_ALL;
169 9df217a3 bellard
}
170 9df217a3 bellard
171 9df217a3 bellard
struct fpstate {
172 9df217a3 bellard
    uint16_t fpuc;
173 9df217a3 bellard
    uint16_t dummy1;
174 9df217a3 bellard
    uint16_t fpus;
175 9df217a3 bellard
    uint16_t dummy2;
176 9df217a3 bellard
    uint16_t fptag;
177 9df217a3 bellard
    uint16_t dummy3;
178 9df217a3 bellard
179 9df217a3 bellard
    uint32_t fpip;
180 9df217a3 bellard
    uint32_t fpcs;
181 9df217a3 bellard
    uint32_t fpoo;
182 9df217a3 bellard
    uint32_t fpos;
183 9df217a3 bellard
    uint8_t fpregs1[8 * 10];
184 9df217a3 bellard
};
185 9df217a3 bellard
186 9df217a3 bellard
struct fpxstate {
187 9df217a3 bellard
    uint16_t fpuc;
188 9df217a3 bellard
    uint16_t fpus;
189 9df217a3 bellard
    uint16_t fptag;
190 9df217a3 bellard
    uint16_t fop;
191 9df217a3 bellard
    uint32_t fpuip;
192 9df217a3 bellard
    uint16_t cs_sel;
193 9df217a3 bellard
    uint16_t dummy0;
194 9df217a3 bellard
    uint32_t fpudp;
195 9df217a3 bellard
    uint16_t ds_sel;
196 9df217a3 bellard
    uint16_t dummy1;
197 9df217a3 bellard
    uint32_t mxcsr;
198 9df217a3 bellard
    uint32_t mxcsr_mask;
199 9df217a3 bellard
    uint8_t fpregs1[8 * 16];
200 9df217a3 bellard
    uint8_t xmm_regs[8 * 16];
201 9df217a3 bellard
    uint8_t dummy2[224];
202 9df217a3 bellard
};
203 9df217a3 bellard
204 9df217a3 bellard
static struct fpxstate fpx1 __attribute__((aligned(16)));
205 9df217a3 bellard
206 9df217a3 bellard
static void restore_native_fp_frstor(CPUState *env)
207 9df217a3 bellard
{
208 9df217a3 bellard
    int fptag, i, j;
209 9df217a3 bellard
    struct fpstate fp1, *fp = &fp1;
210 9df217a3 bellard
    
211 9df217a3 bellard
    fp->fpuc = env->fpuc;
212 9df217a3 bellard
    fp->fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
213 9df217a3 bellard
    fptag = 0;
214 9df217a3 bellard
    for (i=7; i>=0; i--) {
215 9df217a3 bellard
        fptag <<= 2;
216 9df217a3 bellard
        if (env->fptags[i]) {
217 9df217a3 bellard
            fptag |= 3;
218 9df217a3 bellard
        } else {
219 9df217a3 bellard
            /* the FPU automatically computes it */
220 9df217a3 bellard
        }
221 9df217a3 bellard
    }
222 9df217a3 bellard
    fp->fptag = fptag;
223 9df217a3 bellard
    j = env->fpstt;
224 9df217a3 bellard
    for(i = 0;i < 8; i++) {
225 9df217a3 bellard
        memcpy(&fp->fpregs1[i * 10], &env->fpregs[j].d, 10);
226 9df217a3 bellard
        j = (j + 1) & 7;
227 9df217a3 bellard
    }
228 9df217a3 bellard
    asm volatile ("frstor %0" : "=m" (*fp));
229 9df217a3 bellard
}
230 9df217a3 bellard
 
231 9df217a3 bellard
static void save_native_fp_fsave(CPUState *env)
232 9df217a3 bellard
{
233 9df217a3 bellard
    int fptag, i, j;
234 9df217a3 bellard
    uint16_t fpuc;
235 9df217a3 bellard
    struct fpstate fp1, *fp = &fp1;
236 9df217a3 bellard
237 9df217a3 bellard
    asm volatile ("fsave %0" : : "m" (*fp));
238 9df217a3 bellard
    env->fpuc = fp->fpuc;
239 9df217a3 bellard
    env->fpstt = (fp->fpus >> 11) & 7;
240 9df217a3 bellard
    env->fpus = fp->fpus & ~0x3800;
241 9df217a3 bellard
    fptag = fp->fptag;
242 9df217a3 bellard
    for(i = 0;i < 8; i++) {
243 9df217a3 bellard
        env->fptags[i] = ((fptag & 3) == 3);
244 9df217a3 bellard
        fptag >>= 2;
245 9df217a3 bellard
    }
246 9df217a3 bellard
    j = env->fpstt;
247 9df217a3 bellard
    for(i = 0;i < 8; i++) {
248 9df217a3 bellard
        memcpy(&env->fpregs[j].d, &fp->fpregs1[i * 10], 10);
249 9df217a3 bellard
        j = (j + 1) & 7;
250 9df217a3 bellard
    }
251 9df217a3 bellard
    /* we must restore the default rounding state */
252 9df217a3 bellard
    fpuc = 0x037f | (env->fpuc & (3 << 10));
253 9df217a3 bellard
    asm volatile("fldcw %0" : : "m" (fpuc));
254 9df217a3 bellard
}
255 9df217a3 bellard
256 9df217a3 bellard
static void restore_native_fp_fxrstor(CPUState *env)
257 9df217a3 bellard
{
258 9df217a3 bellard
    struct fpxstate *fp = &fpx1;
259 9df217a3 bellard
    int i, j, fptag;
260 9df217a3 bellard
261 9df217a3 bellard
    fp->fpuc = env->fpuc;
262 9df217a3 bellard
    fp->fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
263 9df217a3 bellard
    fptag = 0;
264 9df217a3 bellard
    for(i = 0; i < 8; i++)
265 9df217a3 bellard
        fptag |= (env->fptags[i] << i);
266 9df217a3 bellard
    fp->fptag = fptag ^ 0xff;
267 9df217a3 bellard
268 9df217a3 bellard
    j = env->fpstt;
269 9df217a3 bellard
    for(i = 0;i < 8; i++) {
270 9df217a3 bellard
        memcpy(&fp->fpregs1[i * 16], &env->fpregs[j].d, 10);
271 9df217a3 bellard
        j = (j + 1) & 7;
272 9df217a3 bellard
    }
273 9df217a3 bellard
    if (env->cpuid_features & CPUID_SSE) {
274 9df217a3 bellard
        fp->mxcsr = env->mxcsr;
275 9df217a3 bellard
        /* XXX: check if DAZ is not available */
276 9df217a3 bellard
        fp->mxcsr_mask = 0xffff;
277 9df217a3 bellard
        memcpy(fp->xmm_regs, env->xmm_regs, 8 * 16);
278 9df217a3 bellard
    }
279 9df217a3 bellard
    asm volatile ("fxrstor %0" : "=m" (*fp));
280 9df217a3 bellard
}
281 9df217a3 bellard
282 9df217a3 bellard
static void save_native_fp_fxsave(CPUState *env)
283 9df217a3 bellard
{
284 9df217a3 bellard
    struct fpxstate *fp = &fpx1;
285 9df217a3 bellard
    int fptag, i, j;
286 9df217a3 bellard
    uint16_t fpuc;
287 9df217a3 bellard
288 9df217a3 bellard
    asm volatile ("fxsave %0" : : "m" (*fp));
289 9df217a3 bellard
    env->fpuc = fp->fpuc;
290 9df217a3 bellard
    env->fpstt = (fp->fpus >> 11) & 7;
291 9df217a3 bellard
    env->fpus = fp->fpus & ~0x3800;
292 9df217a3 bellard
    fptag = fp->fptag ^ 0xff;
293 9df217a3 bellard
    for(i = 0;i < 8; i++) {
294 9df217a3 bellard
        env->fptags[i] = (fptag >> i) & 1;
295 9df217a3 bellard
    }
296 9df217a3 bellard
    j = env->fpstt;
297 9df217a3 bellard
    for(i = 0;i < 8; i++) {
298 9df217a3 bellard
        memcpy(&env->fpregs[j].d, &fp->fpregs1[i * 16], 10);
299 9df217a3 bellard
        j = (j + 1) & 7;
300 9df217a3 bellard
    }
301 9df217a3 bellard
    if (env->cpuid_features & CPUID_SSE) {
302 9df217a3 bellard
        env->mxcsr = fp->mxcsr;
303 9df217a3 bellard
        memcpy(env->xmm_regs, fp->xmm_regs, 8 * 16);
304 9df217a3 bellard
    }
305 9df217a3 bellard
306 9df217a3 bellard
    /* we must restore the default rounding state */
307 9df217a3 bellard
    asm volatile ("fninit");
308 9df217a3 bellard
    fpuc = 0x037f | (env->fpuc & (3 << 10));
309 9df217a3 bellard
    asm volatile("fldcw %0" : : "m" (fpuc));
310 9df217a3 bellard
}
311 9df217a3 bellard
312 9df217a3 bellard
int kqemu_cpu_exec(CPUState *env)
313 9df217a3 bellard
{
314 9df217a3 bellard
    struct kqemu_cpu_state kcpu_state, *kenv = &kcpu_state;
315 9df217a3 bellard
    int ret;
316 9df217a3 bellard
317 9df217a3 bellard
#ifdef DEBUG
318 9df217a3 bellard
    if (loglevel & CPU_LOG_INT) {
319 9df217a3 bellard
        fprintf(logfile, "kqemu: cpu_exec: enter\n");
320 9df217a3 bellard
        cpu_dump_state(env, logfile, fprintf, 0);
321 9df217a3 bellard
    }
322 9df217a3 bellard
#endif
323 9df217a3 bellard
    memcpy(kenv->regs, env->regs, sizeof(kenv->regs));
324 9df217a3 bellard
    kenv->eip = env->eip;
325 9df217a3 bellard
    kenv->eflags = env->eflags;
326 9df217a3 bellard
    memcpy(&kenv->segs, &env->segs, sizeof(env->segs));
327 9df217a3 bellard
    memcpy(&kenv->ldt, &env->ldt, sizeof(env->ldt));
328 9df217a3 bellard
    memcpy(&kenv->tr, &env->tr, sizeof(env->tr));
329 9df217a3 bellard
    memcpy(&kenv->gdt, &env->gdt, sizeof(env->gdt));
330 9df217a3 bellard
    memcpy(&kenv->idt, &env->idt, sizeof(env->idt));
331 9df217a3 bellard
    kenv->cr0 = env->cr[0];
332 9df217a3 bellard
    kenv->cr2 = env->cr[2];
333 9df217a3 bellard
    kenv->cr3 = env->cr[3];
334 9df217a3 bellard
    kenv->cr4 = env->cr[4];
335 9df217a3 bellard
    kenv->a20_mask = env->a20_mask;
336 9df217a3 bellard
    if (env->dr[7] & 0xff) {
337 9df217a3 bellard
        kenv->dr7 = env->dr[7];
338 9df217a3 bellard
        kenv->dr0 = env->dr[0];
339 9df217a3 bellard
        kenv->dr1 = env->dr[1];
340 9df217a3 bellard
        kenv->dr2 = env->dr[2];
341 9df217a3 bellard
        kenv->dr3 = env->dr[3];
342 9df217a3 bellard
    } else {
343 9df217a3 bellard
        kenv->dr7 = 0;
344 9df217a3 bellard
    }
345 9df217a3 bellard
    kenv->dr6 = env->dr[6];
346 9df217a3 bellard
    kenv->cpl = 3;
347 9df217a3 bellard
    kenv->nb_pages_to_flush = nb_pages_to_flush;
348 9df217a3 bellard
    nb_pages_to_flush = 0;
349 9df217a3 bellard
    
350 9df217a3 bellard
    if (!(kenv->cr0 & CR0_TS_MASK)) {
351 9df217a3 bellard
        if (env->cpuid_features & CPUID_FXSR)
352 9df217a3 bellard
            restore_native_fp_fxrstor(env);
353 9df217a3 bellard
        else
354 9df217a3 bellard
            restore_native_fp_frstor(env);
355 9df217a3 bellard
    }
356 9df217a3 bellard
357 9df217a3 bellard
    ret = ioctl(kqemu_fd, KQEMU_EXEC, kenv);
358 9df217a3 bellard
359 9df217a3 bellard
    if (!(kenv->cr0 & CR0_TS_MASK)) {
360 9df217a3 bellard
        if (env->cpuid_features & CPUID_FXSR)
361 9df217a3 bellard
            save_native_fp_fxsave(env);
362 9df217a3 bellard
        else
363 9df217a3 bellard
            save_native_fp_fsave(env);
364 9df217a3 bellard
    }
365 9df217a3 bellard
366 9df217a3 bellard
    memcpy(env->regs, kenv->regs, sizeof(env->regs));
367 9df217a3 bellard
    env->eip = kenv->eip;
368 9df217a3 bellard
    env->eflags = kenv->eflags;
369 9df217a3 bellard
    memcpy(env->segs, kenv->segs, sizeof(env->segs));
370 9df217a3 bellard
#if 0
371 9df217a3 bellard
    /* no need to restore that */
372 9df217a3 bellard
    memcpy(env->ldt, kenv->ldt, sizeof(env->ldt));
373 9df217a3 bellard
    memcpy(env->tr, kenv->tr, sizeof(env->tr));
374 9df217a3 bellard
    memcpy(env->gdt, kenv->gdt, sizeof(env->gdt));
375 9df217a3 bellard
    memcpy(env->idt, kenv->idt, sizeof(env->idt));
376 9df217a3 bellard
    env->cr[0] = kenv->cr0;
377 9df217a3 bellard
    env->cr[3] = kenv->cr3;
378 9df217a3 bellard
    env->cr[4] = kenv->cr4;
379 9df217a3 bellard
    env->a20_mask = kenv->a20_mask;
380 9df217a3 bellard
#endif
381 9df217a3 bellard
    env->cr[2] = kenv->cr2;
382 9df217a3 bellard
    env->dr[6] = kenv->dr6;
383 9df217a3 bellard
384 9df217a3 bellard
#ifdef DEBUG
385 9df217a3 bellard
    if (loglevel & CPU_LOG_INT) {
386 9df217a3 bellard
        fprintf(logfile, "kqemu: kqemu_cpu_exec: ret=0x%x\n", ret);
387 9df217a3 bellard
    }
388 9df217a3 bellard
#endif
389 9df217a3 bellard
    if ((ret & 0xff00) == KQEMU_RET_INT) {
390 9df217a3 bellard
        env->exception_index = ret & 0xff;
391 9df217a3 bellard
        env->error_code = 0;
392 9df217a3 bellard
        env->exception_is_int = 1;
393 9df217a3 bellard
        env->exception_next_eip = kenv->next_eip;
394 9df217a3 bellard
#ifdef DEBUG
395 9df217a3 bellard
    if (loglevel & CPU_LOG_INT) {
396 9df217a3 bellard
        fprintf(logfile, "kqemu: interrupt v=%02x:\n", 
397 9df217a3 bellard
                env->exception_index);
398 9df217a3 bellard
        cpu_dump_state(env, logfile, fprintf, 0);
399 9df217a3 bellard
    }
400 9df217a3 bellard
#endif
401 9df217a3 bellard
        return 1;
402 9df217a3 bellard
    } else if ((ret & 0xff00) == KQEMU_RET_EXCEPTION) {
403 9df217a3 bellard
        env->exception_index = ret & 0xff;
404 9df217a3 bellard
        env->error_code = kenv->error_code;
405 9df217a3 bellard
        env->exception_is_int = 0;
406 9df217a3 bellard
        env->exception_next_eip = 0;
407 9df217a3 bellard
#ifdef DEBUG
408 9df217a3 bellard
        if (loglevel & CPU_LOG_INT) {
409 9df217a3 bellard
            fprintf(logfile, "kqemu: exception v=%02x e=%04x:\n",
410 9df217a3 bellard
                    env->exception_index, env->error_code);
411 9df217a3 bellard
            cpu_dump_state(env, logfile, fprintf, 0);
412 9df217a3 bellard
        }
413 9df217a3 bellard
#endif
414 9df217a3 bellard
        return 1;
415 9df217a3 bellard
    } else if (ret == KQEMU_RET_INTR) {
416 9df217a3 bellard
        return 0;
417 9df217a3 bellard
    } else if (ret == KQEMU_RET_SOFTMMU) { 
418 9df217a3 bellard
        return 2;
419 9df217a3 bellard
    } else {
420 9df217a3 bellard
        cpu_dump_state(env, stderr, fprintf, 0);
421 9df217a3 bellard
        fprintf(stderr, "Unsupported return value: 0x%x\n", ret);
422 9df217a3 bellard
        exit(1);
423 9df217a3 bellard
    }
424 9df217a3 bellard
    return 0;
425 9df217a3 bellard
}
426 9df217a3 bellard
427 9df217a3 bellard
#endif