29 |
|
|
30 |
//#define DEBUG_EXEC |
//#define DEBUG_EXEC |
31 |
//#define DEBUG_SIGNAL |
//#define DEBUG_SIGNAL |
|
/* enable it to have a fully working x86 emulator for ring 0 */ |
|
|
//#define RING0_HACKS |
|
32 |
|
|
33 |
#if defined(TARGET_ARM) |
#if defined(TARGET_ARM) |
34 |
/* XXX: unify with i386 target */ |
/* XXX: unify with i386 target */ |
155 |
/* if user mode only, we simulate a fake exception |
/* if user mode only, we simulate a fake exception |
156 |
which will be hanlded outside the cpu execution |
which will be hanlded outside the cpu execution |
157 |
loop */ |
loop */ |
158 |
|
#if defined(TARGET_I386) |
159 |
do_interrupt_user(env->exception_index, |
do_interrupt_user(env->exception_index, |
160 |
env->exception_is_int, |
env->exception_is_int, |
161 |
env->error_code, |
env->error_code, |
162 |
env->exception_next_eip); |
env->exception_next_eip); |
163 |
|
#endif |
164 |
ret = env->exception_index; |
ret = env->exception_index; |
165 |
break; |
break; |
166 |
} else { |
} else { |
167 |
|
#if defined(TARGET_I386) |
168 |
/* simulate a real cpu exception. On i386, it can |
/* simulate a real cpu exception. On i386, it can |
169 |
trigger new exceptions, but we do not handle |
trigger new exceptions, but we do not handle |
170 |
double or triple faults yet. */ |
double or triple faults yet. */ |
172 |
env->exception_is_int, |
env->exception_is_int, |
173 |
env->error_code, |
env->error_code, |
174 |
env->exception_next_eip); |
env->exception_next_eip); |
175 |
|
#endif |
176 |
} |
} |
177 |
env->exception_index = -1; |
env->exception_index = -1; |
178 |
} |
} |
296 |
T0 = tmp_T0; |
T0 = tmp_T0; |
297 |
#endif |
#endif |
298 |
/* see if we can patch the calling TB. XXX: remove TF test */ |
/* see if we can patch the calling TB. XXX: remove TF test */ |
|
#ifndef RING0_HACKS |
|
|
|
|
299 |
if (T0 != 0 |
if (T0 != 0 |
300 |
#if defined(TARGET_I386) |
#if defined(TARGET_I386) |
301 |
&& !(env->eflags & TF_MASK) |
&& !(env->eflags & TF_MASK) |
305 |
tb_add_jump((TranslationBlock *)(T0 & ~3), T0 & 3, tb); |
tb_add_jump((TranslationBlock *)(T0 & ~3), T0 & 3, tb); |
306 |
spin_unlock(&tb_lock); |
spin_unlock(&tb_lock); |
307 |
} |
} |
|
#endif |
|
308 |
tc_ptr = tb->tc_ptr; |
tc_ptr = tb->tc_ptr; |
309 |
|
env->current_tb = tb; |
310 |
/* execute the generated code */ |
/* execute the generated code */ |
311 |
gen_func = (void *)tc_ptr; |
gen_func = (void *)tc_ptr; |
312 |
#if defined(__sparc__) |
#if defined(__sparc__) |
325 |
#else |
#else |
326 |
gen_func(); |
gen_func(); |
327 |
#endif |
#endif |
328 |
|
env->current_tb = NULL; |
329 |
} |
} |
330 |
} else { |
} else { |
331 |
} |
} |
381 |
return ret; |
return ret; |
382 |
} |
} |
383 |
|
|
|
void cpu_interrupt(CPUState *s) |
|
|
{ |
|
|
s->interrupt_request = 1; |
|
|
} |
|
|
|
|
|
|
|
384 |
#if defined(TARGET_I386) |
#if defined(TARGET_I386) |
385 |
|
|
386 |
void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector) |
void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector) |
455 |
TranslationBlock *tb; |
TranslationBlock *tb; |
456 |
int ret; |
int ret; |
457 |
|
|
458 |
#ifdef RING0_HACKS |
if (cpu_single_env) |
459 |
env = global_env; /* XXX: find a better solution */ |
env = cpu_single_env; /* XXX: find a correct solution for multithread */ |
|
#endif |
|
460 |
#if defined(DEBUG_SIGNAL) |
#if defined(DEBUG_SIGNAL) |
461 |
printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", |
printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", |
462 |
pc, address, is_write, *(unsigned long *)old_set); |
pc, address, is_write, *(unsigned long *)old_set); |