diff --git a/linux-user/qemu.h b/linux-user/qemu.h index 300a188563..5613c3ed92 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -54,6 +54,8 @@ typedef struct TaskState { struct TaskState *next; struct target_vm86plus_struct *target_v86; struct vm86_saved_state vm86_saved_regs; + uint32_t v86flags; + uint32_t v86mask; int used; /* non zero if used */ uint8_t stack[0]; } __attribute__((aligned(16))) TaskState; @@ -73,9 +75,17 @@ void cpu_loop(CPUX86State *env); void process_pending_signals(void *cpu_env); void signal_init(void); int queue_signal(int sig, target_siginfo_t *info); -void save_v86_state(CPUX86State *env); void init_paths(const char *prefix); const char *path(const char *pathname); extern int loglevel; +extern FILE *logfile; + +/* vm86.c */ +void save_v86_state(CPUX86State *env); +void do_int(CPUX86State *env, int intno); +void handle_vm86_fault(CPUX86State *env); +int do_vm86(CPUX86State *env, long subfunction, + struct target_vm86plus_struct * target_v86); + #endif diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 3f6084d055..38e242b487 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -1058,78 +1058,6 @@ int do_modify_ldt(CPUX86State *env, int func, void *ptr, unsigned long bytecount return ret; } -/* vm86 emulation */ - -#define SAFE_MASK (0xDD5) - -int do_vm86(CPUX86State *env, long subfunction, - struct target_vm86plus_struct * target_v86) -{ - TaskState *ts = env->opaque; - int ret; - - switch (subfunction) { - case TARGET_VM86_REQUEST_IRQ: - case TARGET_VM86_FREE_IRQ: - case TARGET_VM86_GET_IRQ_BITS: - case TARGET_VM86_GET_AND_RESET_IRQ: - gemu_log("qemu: unsupported vm86 subfunction (%ld)\n", subfunction); - ret = -EINVAL; - goto out; - case TARGET_VM86_PLUS_INSTALL_CHECK: - /* NOTE: on old vm86 stuff this will return the error - from verify_area(), because the subfunction is - interpreted as (invalid) address to vm86_struct. - So the installation check works. - */ - ret = 0; - goto out; - } - - ts->target_v86 = target_v86; - /* save current CPU regs */ - ts->vm86_saved_regs.eax = 0; /* default vm86 syscall return code */ - ts->vm86_saved_regs.ebx = env->regs[R_EBX]; - ts->vm86_saved_regs.ecx = env->regs[R_ECX]; - ts->vm86_saved_regs.edx = env->regs[R_EDX]; - ts->vm86_saved_regs.esi = env->regs[R_ESI]; - ts->vm86_saved_regs.edi = env->regs[R_EDI]; - ts->vm86_saved_regs.ebp = env->regs[R_EBP]; - ts->vm86_saved_regs.esp = env->regs[R_ESP]; - ts->vm86_saved_regs.eflags = env->eflags; - ts->vm86_saved_regs.eip = env->eip; - ts->vm86_saved_regs.cs = env->segs[R_CS]; - ts->vm86_saved_regs.ss = env->segs[R_SS]; - ts->vm86_saved_regs.ds = env->segs[R_DS]; - ts->vm86_saved_regs.es = env->segs[R_ES]; - ts->vm86_saved_regs.fs = env->segs[R_FS]; - ts->vm86_saved_regs.gs = env->segs[R_GS]; - - /* build vm86 CPU state */ - env->eflags = (env->eflags & ~SAFE_MASK) | - (tswap32(target_v86->regs.eflags) & SAFE_MASK) | VM_MASK; - - env->regs[R_EBX] = tswap32(target_v86->regs.ebx); - env->regs[R_ECX] = tswap32(target_v86->regs.ecx); - env->regs[R_EDX] = tswap32(target_v86->regs.edx); - env->regs[R_ESI] = tswap32(target_v86->regs.esi); - env->regs[R_EDI] = tswap32(target_v86->regs.edi); - env->regs[R_EBP] = tswap32(target_v86->regs.ebp); - env->regs[R_ESP] = tswap32(target_v86->regs.esp); - env->eip = tswap32(target_v86->regs.eip); - cpu_x86_load_seg(env, R_CS, tswap16(target_v86->regs.cs)); - cpu_x86_load_seg(env, R_SS, tswap16(target_v86->regs.ss)); - cpu_x86_load_seg(env, R_DS, tswap16(target_v86->regs.ds)); - cpu_x86_load_seg(env, R_ES, tswap16(target_v86->regs.es)); - cpu_x86_load_seg(env, R_FS, tswap16(target_v86->regs.fs)); - cpu_x86_load_seg(env, R_GS, tswap16(target_v86->regs.gs)); - ret = tswap32(target_v86->regs.eax); /* eax will be restored at - the end of the syscall */ - /* now the virtual CPU is ready for vm86 execution ! */ - out: - return ret; -} - /* this stack is the equivalent of the kernel stack associated with a thread/process */ #define NEW_STACK_SIZE 8192