removed trace - merged 2.4.20 vm86 patches

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@167 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
bellard 2003-05-14 21:48:51 +00:00
parent 76c8b7710b
commit b333af0666
3 changed files with 123 additions and 65 deletions

View File

@ -54,6 +54,7 @@ typedef struct TaskState {
struct TaskState *next; struct TaskState *next;
struct target_vm86plus_struct *target_v86; struct target_vm86plus_struct *target_v86;
struct vm86_saved_state vm86_saved_regs; struct vm86_saved_state vm86_saved_regs;
struct target_vm86plus_struct vm86plus;
uint32_t v86flags; uint32_t v86flags;
uint32_t v86mask; uint32_t v86mask;
int used; /* non zero if used */ int used; /* non zero if used */

View File

@ -36,7 +36,7 @@
static inline int is_revectored(int nr, struct target_revectored_struct *bitmap) static inline int is_revectored(int nr, struct target_revectored_struct *bitmap)
{ {
return (tswap32(bitmap->__map[nr >> 5]) >> (nr & 0x1f)) & 1; return (((uint8_t *)bitmap)[nr >> 3] >> (nr & 7)) & 1;
} }
static inline void vm_putw(uint8_t *segptr, unsigned int reg16, unsigned int val) 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)
uint8_t *ssp; uint8_t *ssp;
unsigned int sp; unsigned int sp;
#if 1
if (intno == 0xe6 && (env->regs[R_EAX] & 0xffff) == 0x00c0)
loglevel = 1;
#endif
if (env->segs[R_CS] == TARGET_BIOSSEG) if (env->segs[R_CS] == TARGET_BIOSSEG)
goto cannot_handle; goto cannot_handle;
if (is_revectored(intno, &ts->target_v86->int_revectored)) if (is_revectored(intno, &ts->vm86plus.int_revectored))
goto cannot_handle; goto cannot_handle;
if (intno == 0x21 && is_revectored((env->regs[R_EAX] >> 8) & 0xff, if (intno == 0x21 && is_revectored((env->regs[R_EAX] >> 8) & 0xff,
&ts->target_v86->int21_revectored)) &ts->vm86plus.int21_revectored))
goto cannot_handle; goto cannot_handle;
int_ptr = (uint32_t *)(intno << 2); int_ptr = (uint32_t *)(intno << 2);
segoffs = tswap32(*int_ptr); segoffs = tswap32(*int_ptr);
@ -244,13 +239,13 @@ void handle_vm86_trap(CPUX86State *env, int trapno)
} }
} }
#define CHECK_IF_IN_TRAP(disp) \ #define CHECK_IF_IN_TRAP() \
if ((tswap32(ts->target_v86->vm86plus.flags) & TARGET_vm86dbg_active) && \ if ((ts->vm86plus.vm86plus.flags & TARGET_vm86dbg_active) && \
(tswap32(ts->target_v86->vm86plus.flags) & TARGET_vm86dbg_TFpendig)) \ (ts->vm86plus.vm86plus.flags & TARGET_vm86dbg_TFpendig)) \
vm_putw(ssp,sp + disp,vm_getw(ssp,sp + disp) | TF_MASK) newflags |= TF_MASK
#define VM86_FAULT_RETURN \ #define VM86_FAULT_RETURN \
if ((tswap32(ts->target_v86->vm86plus.flags) & TARGET_force_return_for_pic) && \ if ((ts->vm86plus.vm86plus.flags & TARGET_force_return_for_pic) && \
(ts->v86flags & (IF_MASK | VIF_MASK))) \ (ts->v86flags & (IF_MASK | VIF_MASK))) \
return_to_32bit(env, TARGET_VM86_PICRETURN); \ return_to_32bit(env, TARGET_VM86_PICRETURN); \
return return
@ -259,7 +254,8 @@ void handle_vm86_fault(CPUX86State *env)
{ {
TaskState *ts = env->opaque; TaskState *ts = env->opaque;
uint8_t *csp, *pc, *ssp; uint8_t *csp, *pc, *ssp;
unsigned int ip, sp; unsigned int ip, sp, newflags, newip, newcs, opcode, intno;
int data32, pref_done;
csp = (uint8_t *)(env->segs[R_CS] << 4); csp = (uint8_t *)(env->segs[R_CS] << 4);
ip = env->eip & 0xffff; ip = env->eip & 0xffff;
@ -273,78 +269,109 @@ void handle_vm86_fault(CPUX86State *env)
env->segs[R_CS], env->eip, pc[0], pc[1]); env->segs[R_CS], env->eip, pc[0], pc[1]);
#endif #endif
/* VM86 mode */ data32 = 0;
switch(pc[0]) { pref_done = 0;
case 0x66: do {
switch(pc[1]) { opcode = csp[ip];
case 0x9c: /* pushfd */ ADD16(ip, 1);
ADD16(env->eip, 2); switch (opcode) {
ADD16(env->regs[R_ESP], -4); case 0x66: /* 32-bit data */ data32=1; break;
vm_putl(ssp, sp - 4, get_vflags(env)); case 0x67: /* 32-bit address */ break;
VM86_FAULT_RETURN; case 0x2e: /* CS */ break;
case 0x3e: /* DS */ break;
case 0x9d: /* popfd */ case 0x26: /* ES */ break;
ADD16(env->eip, 2); case 0x36: /* SS */ break;
ADD16(env->regs[R_ESP], 4); case 0x65: /* GS */ break;
CHECK_IF_IN_TRAP(0); case 0x64: /* FS */ break;
if (set_vflags_long(vm_getl(ssp, sp), env)) case 0xf2: /* repnz */ break;
return; case 0xf3: /* rep */ break;
VM86_FAULT_RETURN; default: pref_done = 1;
case 0xcf: /* iretd */
ADD16(env->regs[R_ESP], 12);
env->eip = vm_getl(ssp, sp) & 0xffff;
cpu_x86_load_seg(env, R_CS, vm_getl(ssp, sp + 4) & 0xffff);
CHECK_IF_IN_TRAP(8);
if (set_vflags_long(vm_getl(ssp, sp + 8), env))
return;
VM86_FAULT_RETURN;
default:
goto vm86_gpf;
} }
break; } while (!pref_done);
/* VM86 mode */
switch(opcode) {
case 0x9c: /* pushf */ case 0x9c: /* pushf */
ADD16(env->eip, 1); ADD16(env->eip, 2);
ADD16(env->regs[R_ESP], -2); if (data32) {
vm_putl(ssp, sp - 4, get_vflags(env));
ADD16(env->regs[R_ESP], -4);
} else {
vm_putw(ssp, sp - 2, get_vflags(env)); vm_putw(ssp, sp - 2, get_vflags(env));
ADD16(env->regs[R_ESP], -2);
}
env->eip = ip;
VM86_FAULT_RETURN; VM86_FAULT_RETURN;
case 0x9d: /* popf */ case 0x9d: /* popf */
ADD16(env->eip, 1); if (data32) {
newflags = vm_getl(ssp, sp);
ADD16(env->regs[R_ESP], 4);
} else {
newflags = vm_getw(ssp, sp);
ADD16(env->regs[R_ESP], 2); ADD16(env->regs[R_ESP], 2);
CHECK_IF_IN_TRAP(0); }
if (set_vflags_short(vm_getw(ssp, sp), env)) env->eip = ip;
CHECK_IF_IN_TRAP();
if (data32) {
if (set_vflags_long(newflags, env))
return; return;
} else {
if (set_vflags_short(newflags, env))
return;
}
VM86_FAULT_RETURN; VM86_FAULT_RETURN;
case 0xcd: /* int */ case 0xcd: /* int */
ADD16(env->eip, 2); intno = csp[ip];
do_int(env, pc[1]); ADD16(ip, 1);
env->eip = ip;
if (ts->vm86plus.vm86plus.flags & TARGET_vm86dbg_active) {
if ( (ts->vm86plus.vm86plus.vm86dbg_intxxtab[intno >> 3] >>
(intno &7)) & 1) {
return_to_32bit(env, TARGET_VM86_INTx + (intno << 8));
return;
}
}
do_int(env, intno);
break; break;
case 0xcf: /* iret */ case 0xcf: /* iret */
if (data32) {
newip = vm_getl(ssp, sp) & 0xffff;
newcs = vm_getl(ssp, sp + 4) & 0xffff;
newflags = vm_getl(ssp, sp + 8);
ADD16(env->regs[R_ESP], 12);
} else {
newip = vm_getw(ssp, sp);
newcs = vm_getw(ssp, sp + 2);
newflags = vm_getw(ssp, sp + 4);
ADD16(env->regs[R_ESP], 6); ADD16(env->regs[R_ESP], 6);
env->eip = vm_getw(ssp, sp); }
cpu_x86_load_seg(env, R_CS, vm_getw(ssp, sp + 2)); env->eip = newip;
CHECK_IF_IN_TRAP(4); cpu_x86_load_seg(env, R_CS, newcs);
if (set_vflags_short(vm_getw(ssp, sp + 4), env)) CHECK_IF_IN_TRAP();
if (data32) {
if (set_vflags_long(newflags, env))
return; return;
} else {
if (set_vflags_short(newflags, env))
return;
}
VM86_FAULT_RETURN; VM86_FAULT_RETURN;
case 0xfa: /* cli */ case 0xfa: /* cli */
ADD16(env->eip, 1); env->eip = ip;
clear_IF(env); clear_IF(env);
VM86_FAULT_RETURN; VM86_FAULT_RETURN;
case 0xfb: /* sti */ case 0xfb: /* sti */
ADD16(env->eip, 1); env->eip = ip;
if (set_IF(env)) if (set_IF(env))
return; return;
VM86_FAULT_RETURN; VM86_FAULT_RETURN;
default: default:
vm86_gpf:
/* real VM86 GPF exception */ /* real VM86 GPF exception */
return_to_32bit(env, TARGET_VM86_UNKNOWN); return_to_32bit(env, TARGET_VM86_UNKNOWN);
break; break;
@ -398,7 +425,22 @@ int do_vm86(CPUX86State *env, long subfunction,
ts->v86flags = tswap32(target_v86->regs.eflags); ts->v86flags = tswap32(target_v86->regs.eflags);
env->eflags = (env->eflags & ~SAFE_MASK) | env->eflags = (env->eflags & ~SAFE_MASK) |
(tswap32(target_v86->regs.eflags) & SAFE_MASK) | VM_MASK; (tswap32(target_v86->regs.eflags) & SAFE_MASK) | VM_MASK;
ts->vm86plus.cpu_type = tswapl(target_v86->cpu_type);
switch (ts->vm86plus.cpu_type) {
case TARGET_CPU_286:
ts->v86mask = 0;
break;
case TARGET_CPU_386:
ts->v86mask = NT_MASK | IOPL_MASK;
break;
case TARGET_CPU_486:
ts->v86mask = AC_MASK | NT_MASK | IOPL_MASK;
break;
default:
ts->v86mask = ID_MASK | AC_MASK | NT_MASK | IOPL_MASK; ts->v86mask = ID_MASK | AC_MASK | NT_MASK | IOPL_MASK;
break;
}
env->regs[R_EBX] = tswap32(target_v86->regs.ebx); env->regs[R_EBX] = tswap32(target_v86->regs.ebx);
env->regs[R_ECX] = tswap32(target_v86->regs.ecx); env->regs[R_ECX] = tswap32(target_v86->regs.ecx);
@ -416,6 +458,14 @@ int do_vm86(CPUX86State *env, long subfunction,
cpu_x86_load_seg(env, R_GS, tswap16(target_v86->regs.gs)); cpu_x86_load_seg(env, R_GS, tswap16(target_v86->regs.gs));
ret = tswap32(target_v86->regs.eax); /* eax will be restored at ret = tswap32(target_v86->regs.eax); /* eax will be restored at
the end of the syscall */ the end of the syscall */
memcpy(&ts->vm86plus.int_revectored,
&target_v86->int_revectored, 32);
memcpy(&ts->vm86plus.int21_revectored,
&target_v86->int21_revectored, 32);
ts->vm86plus.vm86plus.flags = tswapl(target_v86->vm86plus.flags);
memcpy(&ts->vm86plus.vm86plus.vm86dbg_intxxtab,
target_v86->vm86plus.vm86dbg_intxxtab, 32);
#ifdef DEBUG_VM86 #ifdef DEBUG_VM86
fprintf(logfile, "do_vm86: cs:ip=%04x:%04x\n", env->segs[R_CS], env->eip); fprintf(logfile, "do_vm86: cs:ip=%04x:%04x\n", env->segs[R_CS], env->eip);
#endif #endif

View File

@ -784,6 +784,13 @@ struct target_modify_ldt_ldt_s {
#define TARGET_BIOSSEG 0x0f000 #define TARGET_BIOSSEG 0x0f000
#define TARGET_CPU_086 0
#define TARGET_CPU_186 1
#define TARGET_CPU_286 2
#define TARGET_CPU_386 3
#define TARGET_CPU_486 4
#define TARGET_CPU_586 5
#define TARGET_VM86_SIGNAL 0 /* return due to signal */ #define TARGET_VM86_SIGNAL 0 /* return due to signal */
#define TARGET_VM86_UNKNOWN 1 /* unhandled GP fault - IO-instruction or similar */ #define TARGET_VM86_UNKNOWN 1 /* unhandled GP fault - IO-instruction or similar */
#define TARGET_VM86_INTx 2 /* int3/int x instruction (ARG = x) */ #define TARGET_VM86_INTx 2 /* int3/int x instruction (ARG = x) */