Commit 89e957e7a292aa698fac77b53b5d80c7760161a8

Authored by bellard
1 parent 982b4315

moved vm86 stuff to vm86.c


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@135 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 4 additions and 158 deletions
linux-user/main.c
@@ -119,129 +119,7 @@ void write_dt(void *ptr, unsigned long addr, unsigned long limit, @@ -119,129 +119,7 @@ void write_dt(void *ptr, unsigned long addr, unsigned long limit,
119 119
120 uint64_t gdt_table[6]; 120 uint64_t gdt_table[6];
121 121
122 -//#define DEBUG_VM86  
123 -  
124 -static inline int is_revectored(int nr, struct target_revectored_struct *bitmap)  
125 -{  
126 - return (tswap32(bitmap->__map[nr >> 5]) >> (nr & 0x1f)) & 1;  
127 -}  
128 -  
129 -static inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg)  
130 -{  
131 - return (uint8_t *)((seg << 4) + (reg & 0xffff));  
132 -}  
133 -  
134 -static inline void pushw(CPUX86State *env, int val)  
135 -{  
136 - env->regs[R_ESP] = (env->regs[R_ESP] & ~0xffff) |  
137 - ((env->regs[R_ESP] - 2) & 0xffff);  
138 - *(uint16_t *)seg_to_linear(env->segs[R_SS], env->regs[R_ESP]) = val;  
139 -}  
140 -  
141 -static inline unsigned int get_vflags(CPUX86State *env)  
142 -{  
143 - unsigned int eflags;  
144 - eflags = env->eflags & ~(VM_MASK | RF_MASK | IF_MASK);  
145 - if (eflags & VIF_MASK)  
146 - eflags |= IF_MASK;  
147 - return eflags;  
148 -}  
149 -  
150 -void save_v86_state(CPUX86State *env)  
151 -{  
152 - TaskState *ts = env->opaque;  
153 -#ifdef DEBUG_VM86  
154 - printf("save_v86_state\n");  
155 -#endif  
156 -  
157 - /* put the VM86 registers in the userspace register structure */  
158 - ts->target_v86->regs.eax = tswap32(env->regs[R_EAX]);  
159 - ts->target_v86->regs.ebx = tswap32(env->regs[R_EBX]);  
160 - ts->target_v86->regs.ecx = tswap32(env->regs[R_ECX]);  
161 - ts->target_v86->regs.edx = tswap32(env->regs[R_EDX]);  
162 - ts->target_v86->regs.esi = tswap32(env->regs[R_ESI]);  
163 - ts->target_v86->regs.edi = tswap32(env->regs[R_EDI]);  
164 - ts->target_v86->regs.ebp = tswap32(env->regs[R_EBP]);  
165 - ts->target_v86->regs.esp = tswap32(env->regs[R_ESP]);  
166 - ts->target_v86->regs.eip = tswap32(env->eip);  
167 - ts->target_v86->regs.cs = tswap16(env->segs[R_CS]);  
168 - ts->target_v86->regs.ss = tswap16(env->segs[R_SS]);  
169 - ts->target_v86->regs.ds = tswap16(env->segs[R_DS]);  
170 - ts->target_v86->regs.es = tswap16(env->segs[R_ES]);  
171 - ts->target_v86->regs.fs = tswap16(env->segs[R_FS]);  
172 - ts->target_v86->regs.gs = tswap16(env->segs[R_GS]);  
173 - ts->target_v86->regs.eflags = tswap32(env->eflags);  
174 -  
175 - /* restore 32 bit registers */  
176 - env->regs[R_EAX] = ts->vm86_saved_regs.eax;  
177 - env->regs[R_EBX] = ts->vm86_saved_regs.ebx;  
178 - env->regs[R_ECX] = ts->vm86_saved_regs.ecx;  
179 - env->regs[R_EDX] = ts->vm86_saved_regs.edx;  
180 - env->regs[R_ESI] = ts->vm86_saved_regs.esi;  
181 - env->regs[R_EDI] = ts->vm86_saved_regs.edi;  
182 - env->regs[R_EBP] = ts->vm86_saved_regs.ebp;  
183 - env->regs[R_ESP] = ts->vm86_saved_regs.esp;  
184 - env->eflags = ts->vm86_saved_regs.eflags;  
185 - env->eip = ts->vm86_saved_regs.eip;  
186 -  
187 - cpu_x86_load_seg(env, R_CS, ts->vm86_saved_regs.cs);  
188 - cpu_x86_load_seg(env, R_SS, ts->vm86_saved_regs.ss);  
189 - cpu_x86_load_seg(env, R_DS, ts->vm86_saved_regs.ds);  
190 - cpu_x86_load_seg(env, R_ES, ts->vm86_saved_regs.es);  
191 - cpu_x86_load_seg(env, R_FS, ts->vm86_saved_regs.fs);  
192 - cpu_x86_load_seg(env, R_GS, ts->vm86_saved_regs.gs);  
193 -}  
194 -  
195 -/* return from vm86 mode to 32 bit. The vm86() syscall will return  
196 - 'retval' */  
197 -static inline void return_to_32bit(CPUX86State *env, int retval)  
198 -{  
199 -#ifdef DEBUG_VM86  
200 - printf("return_to_32bit: ret=0x%x\n", retval);  
201 -#endif  
202 - save_v86_state(env);  
203 - env->regs[R_EAX] = retval;  
204 -}  
205 -  
206 -/* handle VM86 interrupt (NOTE: the CPU core currently does not  
207 - support TSS interrupt revectoring, so this code is always executed) */  
208 -static void do_int(CPUX86State *env, int intno)  
209 -{  
210 - TaskState *ts = env->opaque;  
211 - uint32_t *int_ptr, segoffs;  
212 -  
213 - if (env->segs[R_CS] == TARGET_BIOSSEG)  
214 - goto cannot_handle; /* XXX: I am not sure this is really useful */  
215 - if (is_revectored(intno, &ts->target_v86->int_revectored))  
216 - goto cannot_handle;  
217 - if (intno == 0x21 && is_revectored((env->regs[R_EAX] >> 8) & 0xff,  
218 - &ts->target_v86->int21_revectored))  
219 - goto cannot_handle;  
220 - int_ptr = (uint32_t *)(intno << 2);  
221 - segoffs = tswap32(*int_ptr);  
222 - if ((segoffs >> 16) == TARGET_BIOSSEG)  
223 - goto cannot_handle;  
224 -#ifdef DEBUG_VM86  
225 - printf("VM86: emulating int 0x%x. CS:IP=%04x:%04x\n",  
226 - intno, segoffs >> 16, segoffs & 0xffff);  
227 -#endif  
228 - /* save old state */  
229 - pushw(env, get_vflags(env));  
230 - pushw(env, env->segs[R_CS]);  
231 - pushw(env, env->eip);  
232 - /* goto interrupt handler */  
233 - env->eip = segoffs & 0xffff;  
234 - cpu_x86_load_seg(env, R_CS, segoffs >> 16);  
235 - env->eflags &= ~(VIF_MASK | TF_MASK);  
236 - return;  
237 - cannot_handle:  
238 -#ifdef DEBUG_VM86  
239 - printf("VM86: return to 32 bits int 0x%x\n", intno);  
240 -#endif  
241 - return_to_32bit(env, TARGET_VM86_INTx | (intno << 8));  
242 -}  
243 -  
244 -void cpu_loop(struct CPUX86State *env) 122 +void cpu_loop(CPUX86State *env)
245 { 123 {
246 int trapnr; 124 int trapnr;
247 uint8_t *pc; 125 uint8_t *pc;
@@ -249,45 +127,12 @@ void cpu_loop(struct CPUX86State *env) @@ -249,45 +127,12 @@ void cpu_loop(struct CPUX86State *env)
249 127
250 for(;;) { 128 for(;;) {
251 trapnr = cpu_x86_exec(env); 129 trapnr = cpu_x86_exec(env);
252 - pc = env->seg_cache[R_CS].base + env->eip;  
253 switch(trapnr) { 130 switch(trapnr) {
254 case EXCP0D_GPF: 131 case EXCP0D_GPF:
255 if (env->eflags & VM_MASK) { 132 if (env->eflags & VM_MASK) {
256 -#ifdef DEBUG_VM86  
257 - printf("VM86 exception %04x:%08x %02x %02x\n",  
258 - env->segs[R_CS], env->eip, pc[0], pc[1]);  
259 -#endif  
260 - /* VM86 mode */  
261 - switch(pc[0]) {  
262 - case 0xcd: /* int */  
263 - env->eip += 2;  
264 - do_int(env, pc[1]);  
265 - break;  
266 - case 0x66:  
267 - switch(pc[1]) {  
268 - case 0xfb: /* sti */  
269 - case 0x9d: /* popf */  
270 - case 0xcf: /* iret */  
271 - env->eip += 2;  
272 - return_to_32bit(env, TARGET_VM86_STI);  
273 - break;  
274 - default:  
275 - goto vm86_gpf;  
276 - }  
277 - break;  
278 - case 0xfb: /* sti */  
279 - case 0x9d: /* popf */  
280 - case 0xcf: /* iret */  
281 - env->eip++;  
282 - return_to_32bit(env, TARGET_VM86_STI);  
283 - break;  
284 - default:  
285 - vm86_gpf:  
286 - /* real VM86 GPF exception */  
287 - return_to_32bit(env, TARGET_VM86_UNKNOWN);  
288 - break;  
289 - } 133 + handle_vm86_fault(env);
290 } else { 134 } else {
  135 + pc = env->seg_cache[R_CS].base + env->eip;
291 if (pc[0] == 0xcd && pc[1] == 0x80) { 136 if (pc[0] == 0xcd && pc[1] == 0x80) {
292 /* syscall */ 137 /* syscall */
293 env->eip += 2; 138 env->eip += 2;
@@ -354,6 +199,7 @@ void cpu_loop(struct CPUX86State *env) @@ -354,6 +199,7 @@ void cpu_loop(struct CPUX86State *env)
354 /* just indicate that signals should be handled asap */ 199 /* just indicate that signals should be handled asap */
355 break; 200 break;
356 default: 201 default:
  202 + pc = env->seg_cache[R_CS].base + env->eip;
357 fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n", 203 fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
358 (long)pc, trapnr); 204 (long)pc, trapnr);
359 abort(); 205 abort();