1 #ifdef HAVE_XORG_CONFIG_H
2 #include <xorg-config.h>
9 #include "xf86_OSproc.h"
12 #define _INT10_PRIVATE
13 #include "xf86int10.h"
18 #include "int10Defines.h"
20 static int vm86_rep(struct vm86_struct
*ptr
);
21 static struct vm86_struct vm86_s
;
24 xf86Int10ExecSetup(xf86Int10InfoPtr pInt
)
26 #define VM86S ((struct vm86_struct *)pInt->cpuRegs)
28 pInt
->cpuRegs
= &vm86_s
;
30 VM86S
->screen_bitmap
= 0;
31 VM86S
->cpu_type
= CPU_586
;
32 memset(&VM86S
->int_revectored
, 0xff, sizeof(VM86S
->int_revectored
));
33 memset(&VM86S
->int21_revectored
, 0xff, sizeof(VM86S
->int21_revectored
));
37 /* get the linear address */
38 #define LIN_PREF_SI ((pref_seg << 4) + X86_SI)
39 #define LWECX ((prefix66 ^ prefix67) ? X86_ECX : X86_CX)
40 #define LWECX_ZERO {if (prefix66 ^ prefix67) X86_ECX = 0; else X86_CX = 0;}
43 /* vm86 fault handling */
45 vm86_GP_fault(xf86Int10InfoPtr pInt
)
47 unsigned char *csp
, *lina
;
50 int done
, is_rep
, prefix66
, prefix67
;
52 csp
= lina
= SEG_ADR((unsigned char *), X86_CS
, IP
);
55 prefix66
= prefix67
= 0;
61 switch (MEM_RB(pInt
, (int) csp
++)) {
62 case 0x66: /* operand prefix */
65 case 0x67: /* address prefix */
88 case 0xf2: /* repnz */
96 csp
--; /* oops one too many */
98 X86_IP
+= (csp
- lina
);
100 switch (MEM_RB(pInt
, (int) csp
)) {
101 case 0x6c: /* insb */
102 /* NOTE: ES can't be overwritten; prefixes 66,67 should use esi,edi,ecx
103 * but is anyone using extended regs in real mode? */
104 /* WARNING: no test for DI wrapping! */
105 X86_EDI
+= port_rep_inb(pInt
, X86_DX
, SEG_EADR((CARD32
), X86_ES
, DI
),
106 X86_FLAGS
& DF
, is_rep
? LWECX
: 1);
112 case 0x6d: /* (rep) insw / insd */
113 /* NOTE: ES can't be overwritten */
114 /* WARNING: no test for _DI wrapping! */
116 X86_DI
+= port_rep_inl(pInt
, X86_DX
, SEG_ADR((CARD32
), X86_ES
, DI
),
117 X86_EFLAGS
& DF
, is_rep
? LWECX
: 1);
120 X86_DI
+= port_rep_inw(pInt
, X86_DX
, SEG_ADR((CARD32
), X86_ES
, DI
),
121 X86_FLAGS
& DF
, is_rep
? LWECX
: 1);
128 case 0x6e: /* (rep) outsb */
131 /* WARNING: no test for _SI wrapping! */
132 X86_SI
+= port_rep_outb(pInt
, X86_DX
, (CARD32
) LIN_PREF_SI
,
133 X86_FLAGS
& DF
, is_rep
? LWECX
: 1);
139 case 0x6f: /* (rep) outsw / outsd */
142 /* WARNING: no test for _SI wrapping! */
144 X86_SI
+= port_rep_outl(pInt
, X86_DX
, (CARD32
) LIN_PREF_SI
,
145 X86_EFLAGS
& DF
, is_rep
? LWECX
: 1);
148 X86_SI
+= port_rep_outw(pInt
, X86_DX
, (CARD32
) LIN_PREF_SI
,
149 X86_FLAGS
& DF
, is_rep
? LWECX
: 1);
156 case 0xe5: /* inw xx, inl xx */
158 X86_EAX
= x_inl(csp
[1]);
160 X86_AX
= x_inw(csp
[1]);
164 case 0xe4: /* inb xx */
165 X86_AL
= x_inb(csp
[1]);
169 case 0xed: /* inw dx, inl dx */
171 X86_EAX
= x_inl(X86_DX
);
173 X86_AX
= x_inw(X86_DX
);
177 case 0xec: /* inb dx */
178 X86_AL
= x_inb(X86_DX
);
182 case 0xe7: /* outw xx */
184 x_outl(csp
[1], X86_EAX
);
186 x_outw(csp
[1], X86_AX
);
190 case 0xe6: /* outb xx */
191 x_outb(csp
[1], X86_AL
);
195 case 0xef: /* outw dx */
197 x_outl(X86_DX
, X86_EAX
);
199 x_outw(X86_DX
, X86_AX
);
203 case 0xee: /* outb dx */
204 x_outb(X86_DX
, X86_AL
);
209 DebugF("hlt at %p\n", lina
);
213 xf86DrvMsg(pInt
->pScrn
->scrnIndex
, X_ERROR
,
214 "CPU 0x0f Trap at CS:EIP=0x%4.4x:0x%8.8lx\n", X86_CS
,
219 xf86DrvMsg(pInt
->pScrn
->scrnIndex
, X_ERROR
, "unknown reason for exception\n");
222 dump_registers(pInt
);
225 xf86DrvMsg(pInt
->pScrn
->scrnIndex
, X_ERROR
, "cannot continue\n");
227 } /* end of switch() */
232 do_vm86(xf86Int10InfoPtr pInt
)
236 xf86InterceptSignals(&signo
);
237 retval
= vm86_rep(VM86S
);
238 xf86InterceptSignals(NULL
);
241 xf86DrvMsg(pInt
->pScrn
->scrnIndex
, X_ERROR
,
242 "vm86() syscall generated signal %d.\n", signo
);
243 dump_registers(pInt
);
249 switch (VM86_TYPE(retval
)) {
251 if (!vm86_GP_fault(pInt
))
255 xf86DrvMsg(pInt
->pScrn
->scrnIndex
, X_ERROR
, "vm86_sti :-((\n");
256 dump_registers(pInt
);
261 pInt
->num
= VM86_ARG(retval
);
262 if (!int_handler(pInt
)) {
263 xf86DrvMsg(pInt
->pScrn
->scrnIndex
, X_ERROR
,
264 "Unknown vm86_int: 0x%X\n\n", VM86_ARG(retval
));
265 dump_registers(pInt
);
270 /* I'm not sure yet what to do if we can handle ints */
275 * we used to warn here and bail out - but now the sigio stuff
276 * always fires signals at us. So we just ignore them for now.
278 xf86DrvMsg(pInt
->pScrn
->scrnIndex
, X_WARNING
, "received signal\n");
281 xf86DrvMsg(pInt
->pScrn
->scrnIndex
, X_ERROR
, "unknown type(0x%x)=0x%x\n",
282 VM86_ARG(retval
), VM86_TYPE(retval
));
283 dump_registers(pInt
);
293 xf86ExecX86int10(xf86Int10InfoPtr pInt
)
295 int sig
= setup_int(pInt
);
297 if (int_handler(pInt
))
298 while (do_vm86(pInt
)) {
301 finish_int(pInt
, sig
);
305 vm86_rep(struct vm86_struct
*ptr
)
310 /* When compiling with -fPIC, we can't use asm constraint "b" because
311 %ebx is already taken by gcc. */
312 __asm__
__volatile__("pushl %%ebx\n\t"
316 "int $0x80\n\t" "pop %%gs\n\t" "popl %%ebx":"=a"(__res
)
317 :"n"((int) 113), "r"((struct vm86_struct
*) ptr
));
319 __asm__
__volatile__("push %%gs\n\t"
321 "pop %%gs":"=a"(__res
):"a"((int) 113),
322 "b"((struct vm86_struct
*) ptr
));