diff options
Diffstat (limited to 'xorg-server/hw/xfree86/os-support/linux/int10/vm86')
-rw-r--r-- | xorg-server/hw/xfree86/os-support/linux/int10/vm86/linux_vm86.c | 390 |
1 files changed, 212 insertions, 178 deletions
diff --git a/xorg-server/hw/xfree86/os-support/linux/int10/vm86/linux_vm86.c b/xorg-server/hw/xfree86/os-support/linux/int10/vm86/linux_vm86.c index 34afd9502..8502b21b7 100644 --- a/xorg-server/hw/xfree86/os-support/linux/int10/vm86/linux_vm86.c +++ b/xorg-server/hw/xfree86/os-support/linux/int10/vm86/linux_vm86.c @@ -25,7 +25,7 @@ xf86Int10ExecSetup(xf86Int10InfoPtr pInt) { #define VM86S ((struct vm86_struct *)pInt->cpuRegs) - pInt->cpuRegs = &vm86_s; + pInt->cpuRegs = &vm86_s; VM86S->flags = 0; VM86S->screen_bitmap = 0; VM86S->cpu_type = CPU_586; @@ -58,137 +58,172 @@ vm86_GP_fault(xf86Int10InfoPtr pInt) /* eat up prefixes */ done = 0; do { - switch (MEM_RB(pInt, (int)csp++)) { - case 0x66: /* operand prefix */ prefix66=1; break; - case 0x67: /* address prefix */ prefix67=1; break; - case 0x2e: /* CS */ pref_seg=X86_CS; break; - case 0x3e: /* DS */ pref_seg=X86_DS; break; - case 0x26: /* ES */ pref_seg=X86_ES; break; - case 0x36: /* SS */ pref_seg=X86_SS; break; - case 0x65: /* GS */ pref_seg=X86_GS; break; - case 0x64: /* FS */ pref_seg=X86_FS; break; - case 0xf0: /* lock */ break; - case 0xf2: /* repnz */ - case 0xf3: /* rep */ is_rep=1; break; - default: done=1; - } + switch (MEM_RB(pInt, (int) csp++)) { + case 0x66: /* operand prefix */ + prefix66 = 1; + break; + case 0x67: /* address prefix */ + prefix67 = 1; + break; + case 0x2e: /* CS */ + pref_seg = X86_CS; + break; + case 0x3e: /* DS */ + pref_seg = X86_DS; + break; + case 0x26: /* ES */ + pref_seg = X86_ES; + break; + case 0x36: /* SS */ + pref_seg = X86_SS; + break; + case 0x65: /* GS */ + pref_seg = X86_GS; + break; + case 0x64: /* FS */ + pref_seg = X86_FS; + break; + case 0xf0: /* lock */ + break; + case 0xf2: /* repnz */ + case 0xf3: /* rep */ + is_rep = 1; + break; + default: + done = 1; + } } while (!done); - csp--; /* oops one too many */ + csp--; /* oops one too many */ org_eip = X86_EIP; X86_IP += (csp - lina); - switch (MEM_RB(pInt, (int)csp)) { - case 0x6c: /* insb */ - /* NOTE: ES can't be overwritten; prefixes 66,67 should use esi,edi,ecx - * but is anyone using extended regs in real mode? */ - /* WARNING: no test for DI wrapping! */ - X86_EDI += port_rep_inb(pInt, X86_DX, SEG_EADR((CARD32), X86_ES, DI), - X86_FLAGS & DF, is_rep ? LWECX : 1); - if (is_rep) LWECX_ZERO; - X86_IP++; - break; - - case 0x6d: /* (rep) insw / insd */ - /* NOTE: ES can't be overwritten */ - /* WARNING: no test for _DI wrapping! */ - if (prefix66) { - X86_DI += port_rep_inl(pInt, X86_DX, SEG_ADR((CARD32), X86_ES, DI), - X86_EFLAGS & DF, is_rep ? LWECX : 1); - } - else { - X86_DI += port_rep_inw(pInt, X86_DX, SEG_ADR((CARD32), X86_ES, DI), - X86_FLAGS & DF, is_rep ? LWECX : 1); - } - if (is_rep) LWECX_ZERO; - X86_IP++; - break; - - case 0x6e: /* (rep) outsb */ - if (pref_seg < 0) pref_seg = X86_DS; - /* WARNING: no test for _SI wrapping! */ - X86_SI += port_rep_outb(pInt, X86_DX, (CARD32)LIN_PREF_SI, - X86_FLAGS & DF, is_rep ? LWECX : 1); - if (is_rep) LWECX_ZERO; - X86_IP++; - break; - - case 0x6f: /* (rep) outsw / outsd */ - if (pref_seg < 0) pref_seg = X86_DS; - /* WARNING: no test for _SI wrapping! */ - if (prefix66) { - X86_SI += port_rep_outl(pInt, X86_DX, (CARD32)LIN_PREF_SI, - X86_EFLAGS & DF, is_rep ? LWECX : 1); - } - else { - X86_SI += port_rep_outw(pInt, X86_DX, (CARD32)LIN_PREF_SI, - X86_FLAGS & DF, is_rep ? LWECX : 1); - } - if (is_rep) LWECX_ZERO; - X86_IP++; - break; - - case 0xe5: /* inw xx, inl xx */ - if (prefix66) X86_EAX = x_inl(csp[1]); - else X86_AX = x_inw(csp[1]); - X86_IP += 2; - break; - - case 0xe4: /* inb xx */ - X86_AL = x_inb(csp[1]); - X86_IP += 2; - break; - - case 0xed: /* inw dx, inl dx */ - if (prefix66) X86_EAX = x_inl(X86_DX); - else X86_AX = x_inw(X86_DX); - X86_IP += 1; - break; - - case 0xec: /* inb dx */ - X86_AL = x_inb(X86_DX); - X86_IP += 1; - break; - - case 0xe7: /* outw xx */ - if (prefix66) x_outl(csp[1], X86_EAX); - else x_outw(csp[1], X86_AX); - X86_IP += 2; - break; - - case 0xe6: /* outb xx */ - x_outb(csp[1], X86_AL); - X86_IP += 2; - break; - - case 0xef: /* outw dx */ - if (prefix66) x_outl(X86_DX, X86_EAX); - else x_outw(X86_DX, X86_AX); - X86_IP += 1; - break; - - case 0xee: /* outb dx */ - x_outb(X86_DX, X86_AL); - X86_IP += 1; - break; + switch (MEM_RB(pInt, (int) csp)) { + case 0x6c: /* insb */ + /* NOTE: ES can't be overwritten; prefixes 66,67 should use esi,edi,ecx + * but is anyone using extended regs in real mode? */ + /* WARNING: no test for DI wrapping! */ + X86_EDI += port_rep_inb(pInt, X86_DX, SEG_EADR((CARD32), X86_ES, DI), + X86_FLAGS & DF, is_rep ? LWECX : 1); + if (is_rep) + LWECX_ZERO; + X86_IP++; + break; + + case 0x6d: /* (rep) insw / insd */ + /* NOTE: ES can't be overwritten */ + /* WARNING: no test for _DI wrapping! */ + if (prefix66) { + X86_DI += port_rep_inl(pInt, X86_DX, SEG_ADR((CARD32), X86_ES, DI), + X86_EFLAGS & DF, is_rep ? LWECX : 1); + } + else { + X86_DI += port_rep_inw(pInt, X86_DX, SEG_ADR((CARD32), X86_ES, DI), + X86_FLAGS & DF, is_rep ? LWECX : 1); + } + if (is_rep) + LWECX_ZERO; + X86_IP++; + break; + + case 0x6e: /* (rep) outsb */ + if (pref_seg < 0) + pref_seg = X86_DS; + /* WARNING: no test for _SI wrapping! */ + X86_SI += port_rep_outb(pInt, X86_DX, (CARD32) LIN_PREF_SI, + X86_FLAGS & DF, is_rep ? LWECX : 1); + if (is_rep) + LWECX_ZERO; + X86_IP++; + break; + + case 0x6f: /* (rep) outsw / outsd */ + if (pref_seg < 0) + pref_seg = X86_DS; + /* WARNING: no test for _SI wrapping! */ + if (prefix66) { + X86_SI += port_rep_outl(pInt, X86_DX, (CARD32) LIN_PREF_SI, + X86_EFLAGS & DF, is_rep ? LWECX : 1); + } + else { + X86_SI += port_rep_outw(pInt, X86_DX, (CARD32) LIN_PREF_SI, + X86_FLAGS & DF, is_rep ? LWECX : 1); + } + if (is_rep) + LWECX_ZERO; + X86_IP++; + break; + + case 0xe5: /* inw xx, inl xx */ + if (prefix66) + X86_EAX = x_inl(csp[1]); + else + X86_AX = x_inw(csp[1]); + X86_IP += 2; + break; + + case 0xe4: /* inb xx */ + X86_AL = x_inb(csp[1]); + X86_IP += 2; + break; + + case 0xed: /* inw dx, inl dx */ + if (prefix66) + X86_EAX = x_inl(X86_DX); + else + X86_AX = x_inw(X86_DX); + X86_IP += 1; + break; + + case 0xec: /* inb dx */ + X86_AL = x_inb(X86_DX); + X86_IP += 1; + break; + + case 0xe7: /* outw xx */ + if (prefix66) + x_outl(csp[1], X86_EAX); + else + x_outw(csp[1], X86_AX); + X86_IP += 2; + break; + + case 0xe6: /* outb xx */ + x_outb(csp[1], X86_AL); + X86_IP += 2; + break; + + case 0xef: /* outw dx */ + if (prefix66) + x_outl(X86_DX, X86_EAX); + else + x_outw(X86_DX, X86_AX); + X86_IP += 1; + break; + + case 0xee: /* outb dx */ + x_outb(X86_DX, X86_AL); + X86_IP += 1; + break; case 0xf4: - DebugF("hlt at %p\n", lina); - return FALSE; + DebugF("hlt at %p\n", lina); + return FALSE; case 0x0f: - xf86DrvMsg(pInt->scrnIndex, X_ERROR, - "CPU 0x0f Trap at CS:EIP=0x%4.4x:0x%8.8lx\n", X86_CS, X86_EIP); - goto op0ferr; + xf86DrvMsg(pInt->scrnIndex, X_ERROR, + "CPU 0x0f Trap at CS:EIP=0x%4.4x:0x%8.8lx\n", X86_CS, + X86_EIP); + goto op0ferr; default: - xf86DrvMsg(pInt->scrnIndex, X_ERROR, "unknown reason for exception\n"); - - op0ferr: - dump_registers(pInt); - stack_trace(pInt); - dump_code(pInt); - xf86DrvMsg(pInt->scrnIndex, X_ERROR, "cannot continue\n"); - return FALSE; + xf86DrvMsg(pInt->scrnIndex, X_ERROR, "unknown reason for exception\n"); + + op0ferr: + dump_registers(pInt); + stack_trace(pInt); + dump_code(pInt); + xf86DrvMsg(pInt->scrnIndex, X_ERROR, "cannot continue\n"); + return FALSE; } /* end of switch() */ return TRUE; } @@ -203,51 +238,52 @@ do_vm86(xf86Int10InfoPtr pInt) xf86InterceptSignals(NULL); if (signo >= 0) { - xf86DrvMsg(pInt->scrnIndex, X_ERROR, - "vm86() syscall generated signal %d.\n", signo); - dump_registers(pInt); - dump_code(pInt); - stack_trace(pInt); - return 0; + xf86DrvMsg(pInt->scrnIndex, X_ERROR, + "vm86() syscall generated signal %d.\n", signo); + dump_registers(pInt); + dump_code(pInt); + stack_trace(pInt); + return 0; } switch (VM86_TYPE(retval)) { case VM86_UNKNOWN: - if (!vm86_GP_fault(pInt)) return 0; - break; + if (!vm86_GP_fault(pInt)) + return 0; + break; case VM86_STI: - xf86DrvMsg(pInt->scrnIndex, X_ERROR, "vm86_sti :-((\n"); - dump_registers(pInt); - dump_code(pInt); - stack_trace(pInt); - return 0; + xf86DrvMsg(pInt->scrnIndex, X_ERROR, "vm86_sti :-((\n"); + dump_registers(pInt); + dump_code(pInt); + stack_trace(pInt); + return 0; case VM86_INTx: - pInt->num = VM86_ARG(retval); - if (!int_handler(pInt)) { - xf86DrvMsg(pInt->scrnIndex, X_ERROR, - "Unknown vm86_int: 0x%X\n\n", VM86_ARG(retval)); - dump_registers(pInt); - dump_code(pInt); - stack_trace(pInt); - return 0; - } - /* I'm not sure yet what to do if we can handle ints */ - break; + pInt->num = VM86_ARG(retval); + if (!int_handler(pInt)) { + xf86DrvMsg(pInt->scrnIndex, X_ERROR, + "Unknown vm86_int: 0x%X\n\n", VM86_ARG(retval)); + dump_registers(pInt); + dump_code(pInt); + stack_trace(pInt); + return 0; + } + /* I'm not sure yet what to do if we can handle ints */ + break; case VM86_SIGNAL: - return 1; - /* - * we used to warn here and bail out - but now the sigio stuff - * always fires signals at us. So we just ignore them for now. - */ - xf86DrvMsg(pInt->scrnIndex, X_WARNING, "received signal\n"); - return 0; + return 1; + /* + * we used to warn here and bail out - but now the sigio stuff + * always fires signals at us. So we just ignore them for now. + */ + xf86DrvMsg(pInt->scrnIndex, X_WARNING, "received signal\n"); + return 0; default: - xf86DrvMsg(pInt->scrnIndex, X_ERROR, "unknown type(0x%x)=0x%x\n", - VM86_ARG(retval), VM86_TYPE(retval)); - dump_registers(pInt); - dump_code(pInt); - stack_trace(pInt); - return 0; + xf86DrvMsg(pInt->scrnIndex, X_ERROR, "unknown type(0x%x)=0x%x\n", + VM86_ARG(retval), VM86_TYPE(retval)); + dump_registers(pInt); + dump_code(pInt); + stack_trace(pInt); + return 0; } return 1; @@ -259,7 +295,8 @@ xf86ExecX86int10(xf86Int10InfoPtr pInt) int sig = setup_int(pInt); if (int_handler(pInt)) - while(do_vm86(pInt)) {}; + while (do_vm86(pInt)) { + }; finish_int(pInt, sig); } @@ -273,28 +310,25 @@ vm86_rep(struct vm86_struct *ptr) /* When compiling with -fPIC, we can't use asm constraint "b" because %ebx is already taken by gcc. */ __asm__ __volatile__("pushl %%ebx\n\t" - "push %%gs\n\t" - "movl %2,%%ebx\n\t" - "movl %1,%%eax\n\t" - "int $0x80\n\t" - "pop %%gs\n\t" - "popl %%ebx" - :"=a" (__res) - :"n" ((int)113), "r" ((struct vm86_struct *)ptr)); + "push %%gs\n\t" + "movl %2,%%ebx\n\t" + "movl %1,%%eax\n\t" + "int $0x80\n\t" "pop %%gs\n\t" "popl %%ebx":"=a"(__res) + :"n"((int) 113), "r"((struct vm86_struct *) ptr)); #else __asm__ __volatile__("push %%gs\n\t" - "int $0x80\n\t" - "pop %%gs" - :"=a" (__res):"a" ((int)113), - "b" ((struct vm86_struct *)ptr)); + "int $0x80\n\t" + "pop %%gs":"=a"(__res):"a"((int) 113), + "b"((struct vm86_struct *) ptr)); #endif - if (__res < 0) { - errno = -__res; - __res = -1; - } - else errno = 0; - return __res; + if (__res < 0) { + errno = -__res; + __res = -1; + } + else + errno = 0; + return __res; } #endif |