//#define DEBUG_EXEC
//#define DEBUG_SIGNAL
-/* enable it to have a fully working x86 emulator for ring 0 */
-//#define RING0_HACKS
#if defined(TARGET_ARM)
/* XXX: unify with i386 target */
#ifdef __sparc__
int saved_i7, tmp_T0;
#endif
- int code_gen_size, ret;
+ int code_gen_size, ret, interrupt_request;
void (*gen_func)(void);
TranslationBlock *tb, **ptb;
uint8_t *tc_ptr, *cs_base, *pc;
#else
#error unsupported target CPU
#endif
- env->interrupt_request = 0;
env->exception_index = -1;
/* prepare setjmp context for exception handling */
/* if user mode only, we simulate a fake exception
which will be hanlded outside the cpu execution
loop */
+#if defined(TARGET_I386)
do_interrupt_user(env->exception_index,
env->exception_is_int,
env->error_code,
env->exception_next_eip);
+#endif
ret = env->exception_index;
break;
} else {
+#if defined(TARGET_I386)
/* simulate a real cpu exception. On i386, it can
trigger new exceptions, but we do not handle
double or triple faults yet. */
env->exception_is_int,
env->error_code,
env->exception_next_eip);
+#endif
}
env->exception_index = -1;
}
-#if defined(TARGET_I386)
- /* if hardware interrupt pending, we execute it */
- if (env->hard_interrupt_request &&
- (env->eflags & IF_MASK)) {
- int intno;
- intno = cpu_x86_get_pic_interrupt(env);
- if (loglevel) {
- fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno);
- }
- do_interrupt(intno, 0, 0, 0);
- env->hard_interrupt_request = 0;
- }
-#endif
T0 = 0; /* force lookup of first TB */
for(;;) {
#ifdef __sparc__
/* g1 can be modified by some libc? functions */
tmp_T0 = T0;
#endif
- if (env->interrupt_request) {
- env->exception_index = EXCP_INTERRUPT;
- cpu_loop_exit();
+ interrupt_request = env->interrupt_request;
+ if (interrupt_request) {
+#if defined(TARGET_I386)
+ /* if hardware interrupt pending, we execute it */
+ if ((interrupt_request & CPU_INTERRUPT_HARD) &&
+ (env->eflags & IF_MASK)) {
+ int intno;
+ intno = cpu_x86_get_pic_interrupt(env);
+ if (loglevel) {
+ fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno);
+ }
+ do_interrupt(intno, 0, 0, 0);
+ env->interrupt_request &= ~CPU_INTERRUPT_HARD;
+ }
+#endif
+ if (interrupt_request & CPU_INTERRUPT_EXIT) {
+ env->interrupt_request &= ~CPU_INTERRUPT_EXIT;
+ env->exception_index = EXCP_INTERRUPT;
+ cpu_loop_exit();
+ }
}
#ifdef DEBUG_EXEC
if (loglevel) {
env->regs[R_EBP] = EBP;
env->regs[R_ESP] = ESP;
env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
- cpu_x86_dump_state(env, logfile, 0);
+ cpu_x86_dump_state(env, logfile, X86_DUMP_CCOP);
env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
#elif defined(TARGET_ARM)
cpu_arm_dump_state(env, logfile, 0);
T0 = tmp_T0;
#endif
/* see if we can patch the calling TB. XXX: remove TF test */
-#ifndef RING0_HACKS
-
if (T0 != 0
#if defined(TARGET_I386)
&& !(env->eflags & TF_MASK)
tb_add_jump((TranslationBlock *)(T0 & ~3), T0 & 3, tb);
spin_unlock(&tb_lock);
}
-#endif
tc_ptr = tb->tc_ptr;
-
+ env->current_tb = tb;
/* execute the generated code */
gen_func = (void *)tc_ptr;
#if defined(__sparc__)
#else
gen_func();
#endif
+ env->current_tb = NULL;
}
} else {
}
return ret;
}
-void cpu_interrupt(CPUState *s)
-{
- s->interrupt_request = 1;
-}
-
-
#if defined(TARGET_I386)
void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector)
{
TranslationBlock *tb;
int ret;
-
-#ifdef RING0_HACKS
- env = global_env; /* XXX: find a better solution */
-#endif
+
+ if (cpu_single_env)
+ env = cpu_single_env; /* XXX: find a correct solution for multithread */
#if defined(DEBUG_SIGNAL)
printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
pc, address, is_write, *(unsigned long *)old_set);