Commit b333af066655c15031820a109b651c45adb7eccf

Authored by bellard
1 parent 76c8b771

removed trace - merged 2.4.20 vm86 patches


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@167 c046a42c-6fe2-441c-8c8c-71466251a162
linux-user/qemu.h
@@ -54,6 +54,7 @@ typedef struct TaskState { @@ -54,6 +54,7 @@ typedef struct TaskState {
54 struct TaskState *next; 54 struct TaskState *next;
55 struct target_vm86plus_struct *target_v86; 55 struct target_vm86plus_struct *target_v86;
56 struct vm86_saved_state vm86_saved_regs; 56 struct vm86_saved_state vm86_saved_regs;
  57 + struct target_vm86plus_struct vm86plus;
57 uint32_t v86flags; 58 uint32_t v86flags;
58 uint32_t v86mask; 59 uint32_t v86mask;
59 int used; /* non zero if used */ 60 int used; /* non zero if used */
linux-user/vm86.c
@@ -36,7 +36,7 @@ @@ -36,7 +36,7 @@
36 36
37 static inline int is_revectored(int nr, struct target_revectored_struct *bitmap) 37 static inline int is_revectored(int nr, struct target_revectored_struct *bitmap)
38 { 38 {
39 - return (tswap32(bitmap->__map[nr >> 5]) >> (nr & 0x1f)) & 1; 39 + return (((uint8_t *)bitmap)[nr >> 3] >> (nr & 7)) & 1;
40 } 40 }
41 41
42 static inline void vm_putw(uint8_t *segptr, unsigned int reg16, unsigned int val) 42 static inline void vm_putw(uint8_t *segptr, unsigned int reg16, unsigned int val)
@@ -194,17 +194,12 @@ static void do_int(CPUX86State *env, int intno) @@ -194,17 +194,12 @@ static void do_int(CPUX86State *env, int intno)
194 uint8_t *ssp; 194 uint8_t *ssp;
195 unsigned int sp; 195 unsigned int sp;
196 196
197 -#if 1  
198 - if (intno == 0xe6 && (env->regs[R_EAX] & 0xffff) == 0x00c0)  
199 - loglevel = 1;  
200 -#endif  
201 -  
202 if (env->segs[R_CS] == TARGET_BIOSSEG) 197 if (env->segs[R_CS] == TARGET_BIOSSEG)
203 goto cannot_handle; 198 goto cannot_handle;
204 - if (is_revectored(intno, &ts->target_v86->int_revectored)) 199 + if (is_revectored(intno, &ts->vm86plus.int_revectored))
205 goto cannot_handle; 200 goto cannot_handle;
206 if (intno == 0x21 && is_revectored((env->regs[R_EAX] >> 8) & 0xff, 201 if (intno == 0x21 && is_revectored((env->regs[R_EAX] >> 8) & 0xff,
207 - &ts->target_v86->int21_revectored)) 202 + &ts->vm86plus.int21_revectored))
208 goto cannot_handle; 203 goto cannot_handle;
209 int_ptr = (uint32_t *)(intno << 2); 204 int_ptr = (uint32_t *)(intno << 2);
210 segoffs = tswap32(*int_ptr); 205 segoffs = tswap32(*int_ptr);
@@ -244,13 +239,13 @@ void handle_vm86_trap(CPUX86State *env, int trapno) @@ -244,13 +239,13 @@ void handle_vm86_trap(CPUX86State *env, int trapno)
244 } 239 }
245 } 240 }
246 241
247 -#define CHECK_IF_IN_TRAP(disp) \  
248 - if ((tswap32(ts->target_v86->vm86plus.flags) & TARGET_vm86dbg_active) && \  
249 - (tswap32(ts->target_v86->vm86plus.flags) & TARGET_vm86dbg_TFpendig)) \  
250 - vm_putw(ssp,sp + disp,vm_getw(ssp,sp + disp) | TF_MASK) 242 +#define CHECK_IF_IN_TRAP() \
  243 + if ((ts->vm86plus.vm86plus.flags & TARGET_vm86dbg_active) && \
  244 + (ts->vm86plus.vm86plus.flags & TARGET_vm86dbg_TFpendig)) \
  245 + newflags |= TF_MASK
251 246
252 #define VM86_FAULT_RETURN \ 247 #define VM86_FAULT_RETURN \
253 - if ((tswap32(ts->target_v86->vm86plus.flags) & TARGET_force_return_for_pic) && \ 248 + if ((ts->vm86plus.vm86plus.flags & TARGET_force_return_for_pic) && \
254 (ts->v86flags & (IF_MASK | VIF_MASK))) \ 249 (ts->v86flags & (IF_MASK | VIF_MASK))) \
255 return_to_32bit(env, TARGET_VM86_PICRETURN); \ 250 return_to_32bit(env, TARGET_VM86_PICRETURN); \
256 return 251 return
@@ -259,7 +254,8 @@ void handle_vm86_fault(CPUX86State *env) @@ -259,7 +254,8 @@ void handle_vm86_fault(CPUX86State *env)
259 { 254 {
260 TaskState *ts = env->opaque; 255 TaskState *ts = env->opaque;
261 uint8_t *csp, *pc, *ssp; 256 uint8_t *csp, *pc, *ssp;
262 - unsigned int ip, sp; 257 + unsigned int ip, sp, newflags, newip, newcs, opcode, intno;
  258 + int data32, pref_done;
263 259
264 csp = (uint8_t *)(env->segs[R_CS] << 4); 260 csp = (uint8_t *)(env->segs[R_CS] << 4);
265 ip = env->eip & 0xffff; 261 ip = env->eip & 0xffff;
@@ -273,78 +269,109 @@ void handle_vm86_fault(CPUX86State *env) @@ -273,78 +269,109 @@ void handle_vm86_fault(CPUX86State *env)
273 env->segs[R_CS], env->eip, pc[0], pc[1]); 269 env->segs[R_CS], env->eip, pc[0], pc[1]);
274 #endif 270 #endif
275 271
  272 + data32 = 0;
  273 + pref_done = 0;
  274 + do {
  275 + opcode = csp[ip];
  276 + ADD16(ip, 1);
  277 + switch (opcode) {
  278 + case 0x66: /* 32-bit data */ data32=1; break;
  279 + case 0x67: /* 32-bit address */ break;
  280 + case 0x2e: /* CS */ break;
  281 + case 0x3e: /* DS */ break;
  282 + case 0x26: /* ES */ break;
  283 + case 0x36: /* SS */ break;
  284 + case 0x65: /* GS */ break;
  285 + case 0x64: /* FS */ break;
  286 + case 0xf2: /* repnz */ break;
  287 + case 0xf3: /* rep */ break;
  288 + default: pref_done = 1;
  289 + }
  290 + } while (!pref_done);
  291 +
276 /* VM86 mode */ 292 /* VM86 mode */
277 - switch(pc[0]) {  
278 - case 0x66:  
279 - switch(pc[1]) {  
280 - case 0x9c: /* pushfd */  
281 - ADD16(env->eip, 2);  
282 - ADD16(env->regs[R_ESP], -4); 293 + switch(opcode) {
  294 + case 0x9c: /* pushf */
  295 + ADD16(env->eip, 2);
  296 + if (data32) {
283 vm_putl(ssp, sp - 4, get_vflags(env)); 297 vm_putl(ssp, sp - 4, get_vflags(env));
284 - VM86_FAULT_RETURN; 298 + ADD16(env->regs[R_ESP], -4);
  299 + } else {
  300 + vm_putw(ssp, sp - 2, get_vflags(env));
  301 + ADD16(env->regs[R_ESP], -2);
  302 + }
  303 + env->eip = ip;
  304 + VM86_FAULT_RETURN;
285 305
286 - case 0x9d: /* popfd */  
287 - ADD16(env->eip, 2); 306 + case 0x9d: /* popf */
  307 + if (data32) {
  308 + newflags = vm_getl(ssp, sp);
288 ADD16(env->regs[R_ESP], 4); 309 ADD16(env->regs[R_ESP], 4);
289 - CHECK_IF_IN_TRAP(0);  
290 - if (set_vflags_long(vm_getl(ssp, sp), env)) 310 + } else {
  311 + newflags = vm_getw(ssp, sp);
  312 + ADD16(env->regs[R_ESP], 2);
  313 + }
  314 + env->eip = ip;
  315 + CHECK_IF_IN_TRAP();
  316 + if (data32) {
  317 + if (set_vflags_long(newflags, env))
291 return; 318 return;
292 - VM86_FAULT_RETURN;  
293 -  
294 - case 0xcf: /* iretd */  
295 - ADD16(env->regs[R_ESP], 12);  
296 - env->eip = vm_getl(ssp, sp) & 0xffff;  
297 - cpu_x86_load_seg(env, R_CS, vm_getl(ssp, sp + 4) & 0xffff);  
298 - CHECK_IF_IN_TRAP(8);  
299 - if (set_vflags_long(vm_getl(ssp, sp + 8), env)) 319 + } else {
  320 + if (set_vflags_short(newflags, env))
300 return; 321 return;
301 - VM86_FAULT_RETURN;  
302 -  
303 - default:  
304 - goto vm86_gpf;  
305 } 322 }
306 - break;  
307 - case 0x9c: /* pushf */  
308 - ADD16(env->eip, 1);  
309 - ADD16(env->regs[R_ESP], -2);  
310 - vm_putw(ssp, sp - 2, get_vflags(env));  
311 - VM86_FAULT_RETURN;  
312 -  
313 - case 0x9d: /* popf */  
314 - ADD16(env->eip, 1);  
315 - ADD16(env->regs[R_ESP], 2);  
316 - CHECK_IF_IN_TRAP(0);  
317 - if (set_vflags_short(vm_getw(ssp, sp), env))  
318 - return;  
319 VM86_FAULT_RETURN; 323 VM86_FAULT_RETURN;
320 324
321 case 0xcd: /* int */ 325 case 0xcd: /* int */
322 - ADD16(env->eip, 2);  
323 - do_int(env, pc[1]); 326 + intno = csp[ip];
  327 + ADD16(ip, 1);
  328 + env->eip = ip;
  329 + if (ts->vm86plus.vm86plus.flags & TARGET_vm86dbg_active) {
  330 + if ( (ts->vm86plus.vm86plus.vm86dbg_intxxtab[intno >> 3] >>
  331 + (intno &7)) & 1) {
  332 + return_to_32bit(env, TARGET_VM86_INTx + (intno << 8));
  333 + return;
  334 + }
  335 + }
  336 + do_int(env, intno);
324 break; 337 break;
325 338
326 case 0xcf: /* iret */ 339 case 0xcf: /* iret */
327 - ADD16(env->regs[R_ESP], 6);  
328 - env->eip = vm_getw(ssp, sp);  
329 - cpu_x86_load_seg(env, R_CS, vm_getw(ssp, sp + 2));  
330 - CHECK_IF_IN_TRAP(4);  
331 - if (set_vflags_short(vm_getw(ssp, sp + 4), env))  
332 - return; 340 + if (data32) {
  341 + newip = vm_getl(ssp, sp) & 0xffff;
  342 + newcs = vm_getl(ssp, sp + 4) & 0xffff;
  343 + newflags = vm_getl(ssp, sp + 8);
  344 + ADD16(env->regs[R_ESP], 12);
  345 + } else {
  346 + newip = vm_getw(ssp, sp);
  347 + newcs = vm_getw(ssp, sp + 2);
  348 + newflags = vm_getw(ssp, sp + 4);
  349 + ADD16(env->regs[R_ESP], 6);
  350 + }
  351 + env->eip = newip;
  352 + cpu_x86_load_seg(env, R_CS, newcs);
  353 + CHECK_IF_IN_TRAP();
  354 + if (data32) {
  355 + if (set_vflags_long(newflags, env))
  356 + return;
  357 + } else {
  358 + if (set_vflags_short(newflags, env))
  359 + return;
  360 + }
333 VM86_FAULT_RETURN; 361 VM86_FAULT_RETURN;
334 - 362 +
335 case 0xfa: /* cli */ 363 case 0xfa: /* cli */
336 - ADD16(env->eip, 1); 364 + env->eip = ip;
337 clear_IF(env); 365 clear_IF(env);
338 VM86_FAULT_RETURN; 366 VM86_FAULT_RETURN;
339 367
340 case 0xfb: /* sti */ 368 case 0xfb: /* sti */
341 - ADD16(env->eip, 1); 369 + env->eip = ip;
342 if (set_IF(env)) 370 if (set_IF(env))
343 return; 371 return;
344 VM86_FAULT_RETURN; 372 VM86_FAULT_RETURN;
345 373
346 default: 374 default:
347 - vm86_gpf:  
348 /* real VM86 GPF exception */ 375 /* real VM86 GPF exception */
349 return_to_32bit(env, TARGET_VM86_UNKNOWN); 376 return_to_32bit(env, TARGET_VM86_UNKNOWN);
350 break; 377 break;
@@ -398,7 +425,22 @@ int do_vm86(CPUX86State *env, long subfunction, @@ -398,7 +425,22 @@ int do_vm86(CPUX86State *env, long subfunction,
398 ts->v86flags = tswap32(target_v86->regs.eflags); 425 ts->v86flags = tswap32(target_v86->regs.eflags);
399 env->eflags = (env->eflags & ~SAFE_MASK) | 426 env->eflags = (env->eflags & ~SAFE_MASK) |
400 (tswap32(target_v86->regs.eflags) & SAFE_MASK) | VM_MASK; 427 (tswap32(target_v86->regs.eflags) & SAFE_MASK) | VM_MASK;
401 - ts->v86mask = ID_MASK | AC_MASK | NT_MASK | IOPL_MASK; 428 +
  429 + ts->vm86plus.cpu_type = tswapl(target_v86->cpu_type);
  430 + switch (ts->vm86plus.cpu_type) {
  431 + case TARGET_CPU_286:
  432 + ts->v86mask = 0;
  433 + break;
  434 + case TARGET_CPU_386:
  435 + ts->v86mask = NT_MASK | IOPL_MASK;
  436 + break;
  437 + case TARGET_CPU_486:
  438 + ts->v86mask = AC_MASK | NT_MASK | IOPL_MASK;
  439 + break;
  440 + default:
  441 + ts->v86mask = ID_MASK | AC_MASK | NT_MASK | IOPL_MASK;
  442 + break;
  443 + }
402 444
403 env->regs[R_EBX] = tswap32(target_v86->regs.ebx); 445 env->regs[R_EBX] = tswap32(target_v86->regs.ebx);
404 env->regs[R_ECX] = tswap32(target_v86->regs.ecx); 446 env->regs[R_ECX] = tswap32(target_v86->regs.ecx);
@@ -416,6 +458,14 @@ int do_vm86(CPUX86State *env, long subfunction, @@ -416,6 +458,14 @@ int do_vm86(CPUX86State *env, long subfunction,
416 cpu_x86_load_seg(env, R_GS, tswap16(target_v86->regs.gs)); 458 cpu_x86_load_seg(env, R_GS, tswap16(target_v86->regs.gs));
417 ret = tswap32(target_v86->regs.eax); /* eax will be restored at 459 ret = tswap32(target_v86->regs.eax); /* eax will be restored at
418 the end of the syscall */ 460 the end of the syscall */
  461 + memcpy(&ts->vm86plus.int_revectored,
  462 + &target_v86->int_revectored, 32);
  463 + memcpy(&ts->vm86plus.int21_revectored,
  464 + &target_v86->int21_revectored, 32);
  465 + ts->vm86plus.vm86plus.flags = tswapl(target_v86->vm86plus.flags);
  466 + memcpy(&ts->vm86plus.vm86plus.vm86dbg_intxxtab,
  467 + target_v86->vm86plus.vm86dbg_intxxtab, 32);
  468 +
419 #ifdef DEBUG_VM86 469 #ifdef DEBUG_VM86
420 fprintf(logfile, "do_vm86: cs:ip=%04x:%04x\n", env->segs[R_CS], env->eip); 470 fprintf(logfile, "do_vm86: cs:ip=%04x:%04x\n", env->segs[R_CS], env->eip);
421 #endif 471 #endif
syscall-i386.h
@@ -784,6 +784,13 @@ struct target_modify_ldt_ldt_s { @@ -784,6 +784,13 @@ struct target_modify_ldt_ldt_s {
784 784
785 #define TARGET_BIOSSEG 0x0f000 785 #define TARGET_BIOSSEG 0x0f000
786 786
  787 +#define TARGET_CPU_086 0
  788 +#define TARGET_CPU_186 1
  789 +#define TARGET_CPU_286 2
  790 +#define TARGET_CPU_386 3
  791 +#define TARGET_CPU_486 4
  792 +#define TARGET_CPU_586 5
  793 +
787 #define TARGET_VM86_SIGNAL 0 /* return due to signal */ 794 #define TARGET_VM86_SIGNAL 0 /* return due to signal */
788 #define TARGET_VM86_UNKNOWN 1 /* unhandled GP fault - IO-instruction or similar */ 795 #define TARGET_VM86_UNKNOWN 1 /* unhandled GP fault - IO-instruction or similar */
789 #define TARGET_VM86_INTx 2 /* int3/int x instruction (ARG = x) */ 796 #define TARGET_VM86_INTx 2 /* int3/int x instruction (ARG = x) */