Commit 631271d7164f8209c044988b6a02e1153391c4f9
1 parent
9d27abd9
added vm86.c
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@143 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
11 additions
and
73 deletions
linux-user/qemu.h
| ... | ... | @@ -54,6 +54,8 @@ typedef struct TaskState { |
| 54 | 54 | struct TaskState *next; |
| 55 | 55 | struct target_vm86plus_struct *target_v86; |
| 56 | 56 | struct vm86_saved_state vm86_saved_regs; |
| 57 | + uint32_t v86flags; | |
| 58 | + uint32_t v86mask; | |
| 57 | 59 | int used; /* non zero if used */ |
| 58 | 60 | uint8_t stack[0]; |
| 59 | 61 | } __attribute__((aligned(16))) TaskState; |
| ... | ... | @@ -73,9 +75,17 @@ void cpu_loop(CPUX86State *env); |
| 73 | 75 | void process_pending_signals(void *cpu_env); |
| 74 | 76 | void signal_init(void); |
| 75 | 77 | int queue_signal(int sig, target_siginfo_t *info); |
| 76 | -void save_v86_state(CPUX86State *env); | |
| 77 | 78 | void init_paths(const char *prefix); |
| 78 | 79 | const char *path(const char *pathname); |
| 79 | 80 | |
| 80 | 81 | extern int loglevel; |
| 82 | +extern FILE *logfile; | |
| 83 | + | |
| 84 | +/* vm86.c */ | |
| 85 | +void save_v86_state(CPUX86State *env); | |
| 86 | +void do_int(CPUX86State *env, int intno); | |
| 87 | +void handle_vm86_fault(CPUX86State *env); | |
| 88 | +int do_vm86(CPUX86State *env, long subfunction, | |
| 89 | + struct target_vm86plus_struct * target_v86); | |
| 90 | + | |
| 81 | 91 | #endif | ... | ... |
linux-user/syscall.c
| ... | ... | @@ -1058,78 +1058,6 @@ int do_modify_ldt(CPUX86State *env, int func, void *ptr, unsigned long bytecount |
| 1058 | 1058 | return ret; |
| 1059 | 1059 | } |
| 1060 | 1060 | |
| 1061 | -/* vm86 emulation */ | |
| 1062 | - | |
| 1063 | -#define SAFE_MASK (0xDD5) | |
| 1064 | - | |
| 1065 | -int do_vm86(CPUX86State *env, long subfunction, | |
| 1066 | - struct target_vm86plus_struct * target_v86) | |
| 1067 | -{ | |
| 1068 | - TaskState *ts = env->opaque; | |
| 1069 | - int ret; | |
| 1070 | - | |
| 1071 | - switch (subfunction) { | |
| 1072 | - case TARGET_VM86_REQUEST_IRQ: | |
| 1073 | - case TARGET_VM86_FREE_IRQ: | |
| 1074 | - case TARGET_VM86_GET_IRQ_BITS: | |
| 1075 | - case TARGET_VM86_GET_AND_RESET_IRQ: | |
| 1076 | - gemu_log("qemu: unsupported vm86 subfunction (%ld)\n", subfunction); | |
| 1077 | - ret = -EINVAL; | |
| 1078 | - goto out; | |
| 1079 | - case TARGET_VM86_PLUS_INSTALL_CHECK: | |
| 1080 | - /* NOTE: on old vm86 stuff this will return the error | |
| 1081 | - from verify_area(), because the subfunction is | |
| 1082 | - interpreted as (invalid) address to vm86_struct. | |
| 1083 | - So the installation check works. | |
| 1084 | - */ | |
| 1085 | - ret = 0; | |
| 1086 | - goto out; | |
| 1087 | - } | |
| 1088 | - | |
| 1089 | - ts->target_v86 = target_v86; | |
| 1090 | - /* save current CPU regs */ | |
| 1091 | - ts->vm86_saved_regs.eax = 0; /* default vm86 syscall return code */ | |
| 1092 | - ts->vm86_saved_regs.ebx = env->regs[R_EBX]; | |
| 1093 | - ts->vm86_saved_regs.ecx = env->regs[R_ECX]; | |
| 1094 | - ts->vm86_saved_regs.edx = env->regs[R_EDX]; | |
| 1095 | - ts->vm86_saved_regs.esi = env->regs[R_ESI]; | |
| 1096 | - ts->vm86_saved_regs.edi = env->regs[R_EDI]; | |
| 1097 | - ts->vm86_saved_regs.ebp = env->regs[R_EBP]; | |
| 1098 | - ts->vm86_saved_regs.esp = env->regs[R_ESP]; | |
| 1099 | - ts->vm86_saved_regs.eflags = env->eflags; | |
| 1100 | - ts->vm86_saved_regs.eip = env->eip; | |
| 1101 | - ts->vm86_saved_regs.cs = env->segs[R_CS]; | |
| 1102 | - ts->vm86_saved_regs.ss = env->segs[R_SS]; | |
| 1103 | - ts->vm86_saved_regs.ds = env->segs[R_DS]; | |
| 1104 | - ts->vm86_saved_regs.es = env->segs[R_ES]; | |
| 1105 | - ts->vm86_saved_regs.fs = env->segs[R_FS]; | |
| 1106 | - ts->vm86_saved_regs.gs = env->segs[R_GS]; | |
| 1107 | - | |
| 1108 | - /* build vm86 CPU state */ | |
| 1109 | - env->eflags = (env->eflags & ~SAFE_MASK) | | |
| 1110 | - (tswap32(target_v86->regs.eflags) & SAFE_MASK) | VM_MASK; | |
| 1111 | - | |
| 1112 | - env->regs[R_EBX] = tswap32(target_v86->regs.ebx); | |
| 1113 | - env->regs[R_ECX] = tswap32(target_v86->regs.ecx); | |
| 1114 | - env->regs[R_EDX] = tswap32(target_v86->regs.edx); | |
| 1115 | - env->regs[R_ESI] = tswap32(target_v86->regs.esi); | |
| 1116 | - env->regs[R_EDI] = tswap32(target_v86->regs.edi); | |
| 1117 | - env->regs[R_EBP] = tswap32(target_v86->regs.ebp); | |
| 1118 | - env->regs[R_ESP] = tswap32(target_v86->regs.esp); | |
| 1119 | - env->eip = tswap32(target_v86->regs.eip); | |
| 1120 | - cpu_x86_load_seg(env, R_CS, tswap16(target_v86->regs.cs)); | |
| 1121 | - cpu_x86_load_seg(env, R_SS, tswap16(target_v86->regs.ss)); | |
| 1122 | - cpu_x86_load_seg(env, R_DS, tswap16(target_v86->regs.ds)); | |
| 1123 | - cpu_x86_load_seg(env, R_ES, tswap16(target_v86->regs.es)); | |
| 1124 | - cpu_x86_load_seg(env, R_FS, tswap16(target_v86->regs.fs)); | |
| 1125 | - cpu_x86_load_seg(env, R_GS, tswap16(target_v86->regs.gs)); | |
| 1126 | - ret = tswap32(target_v86->regs.eax); /* eax will be restored at | |
| 1127 | - the end of the syscall */ | |
| 1128 | - /* now the virtual CPU is ready for vm86 execution ! */ | |
| 1129 | - out: | |
| 1130 | - return ret; | |
| 1131 | -} | |
| 1132 | - | |
| 1133 | 1061 | /* this stack is the equivalent of the kernel stack associated with a |
| 1134 | 1062 | thread/process */ |
| 1135 | 1063 | #define NEW_STACK_SIZE 8192 | ... | ... |