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 54 struct TaskState *next;
55 55 struct target_vm86plus_struct *target_v86;
56 56 struct vm86_saved_state vm86_saved_regs;
  57 + struct target_vm86plus_struct vm86plus;
57 58 uint32_t v86flags;
58 59 uint32_t v86mask;
59 60 int used; /* non zero if used */
... ...
linux-user/vm86.c
... ... @@ -36,7 +36,7 @@
36 36  
37 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 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 194 uint8_t *ssp;
195 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 197 if (env->segs[R_CS] == TARGET_BIOSSEG)
203 198 goto cannot_handle;
204   - if (is_revectored(intno, &ts->target_v86->int_revectored))
  199 + if (is_revectored(intno, &ts->vm86plus.int_revectored))
205 200 goto cannot_handle;
206 201 if (intno == 0x21 && is_revectored((env->regs[R_EAX] >> 8) & 0xff,
207   - &ts->target_v86->int21_revectored))
  202 + &ts->vm86plus.int21_revectored))
208 203 goto cannot_handle;
209 204 int_ptr = (uint32_t *)(intno << 2);
210 205 segoffs = tswap32(*int_ptr);
... ... @@ -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 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 249 (ts->v86flags & (IF_MASK | VIF_MASK))) \
255 250 return_to_32bit(env, TARGET_VM86_PICRETURN); \
256 251 return
... ... @@ -259,7 +254,8 @@ void handle_vm86_fault(CPUX86State *env)
259 254 {
260 255 TaskState *ts = env->opaque;
261 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 260 csp = (uint8_t *)(env->segs[R_CS] << 4);
265 261 ip = env->eip & 0xffff;
... ... @@ -273,78 +269,109 @@ void handle_vm86_fault(CPUX86State *env)
273 269 env->segs[R_CS], env->eip, pc[0], pc[1]);
274 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 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 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 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 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 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 323 VM86_FAULT_RETURN;
320 324  
321 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 337 break;
325 338  
326 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 361 VM86_FAULT_RETURN;
334   -
  362 +
335 363 case 0xfa: /* cli */
336   - ADD16(env->eip, 1);
  364 + env->eip = ip;
337 365 clear_IF(env);
338 366 VM86_FAULT_RETURN;
339 367  
340 368 case 0xfb: /* sti */
341   - ADD16(env->eip, 1);
  369 + env->eip = ip;
342 370 if (set_IF(env))
343 371 return;
344 372 VM86_FAULT_RETURN;
345 373  
346 374 default:
347   - vm86_gpf:
348 375 /* real VM86 GPF exception */
349 376 return_to_32bit(env, TARGET_VM86_UNKNOWN);
350 377 break;
... ... @@ -398,7 +425,22 @@ int do_vm86(CPUX86State *env, long subfunction,
398 425 ts->v86flags = tswap32(target_v86->regs.eflags);
399 426 env->eflags = (env->eflags & ~SAFE_MASK) |
400 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 445 env->regs[R_EBX] = tswap32(target_v86->regs.ebx);
404 446 env->regs[R_ECX] = tswap32(target_v86->regs.ecx);
... ... @@ -416,6 +458,14 @@ int do_vm86(CPUX86State *env, long subfunction,
416 458 cpu_x86_load_seg(env, R_GS, tswap16(target_v86->regs.gs));
417 459 ret = tswap32(target_v86->regs.eax); /* eax will be restored at
418 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 469 #ifdef DEBUG_VM86
420 470 fprintf(logfile, "do_vm86: cs:ip=%04x:%04x\n", env->segs[R_CS], env->eip);
421 471 #endif
... ...
syscall-i386.h
... ... @@ -784,6 +784,13 @@ struct target_modify_ldt_ldt_s {
784 784  
785 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 794 #define TARGET_VM86_SIGNAL 0 /* return due to signal */
788 795 #define TARGET_VM86_UNKNOWN 1 /* unhandled GP fault - IO-instruction or similar */
789 796 #define TARGET_VM86_INTx 2 /* int3/int x instruction (ARG = x) */
... ...