helper_exec.c revision 05b261ec
1/*
2 *                   XFree86 int10 module
3 *   execute BIOS int 10h calls in x86 real mode environment
4 *                 Copyright 1999 Egbert Eich
5 *
6 *   Part of this code was inspired  by the VBIOS POSTing code in DOSEMU
7 *   developed by the "DOSEMU-Development-Team"
8 */
9
10/*
11 * To debug port accesses define PRINT_PORT to 1.
12 * Note! You also have to comment out ioperm()
13 * in xf86EnableIO(). Otherwise we won't trap
14 * on PIO.
15 */
16
17#ifdef HAVE_XORG_CONFIG_H
18#include <xorg-config.h>
19#endif
20
21#define PRINT_PORT 0
22
23#include <unistd.h>
24
25#include <X11/Xos.h>
26#include "xf86.h"
27#include "xf86_OSproc.h"
28#include "compiler.h"
29#define _INT10_PRIVATE
30#include "int10Defines.h"
31#include "xf86int10.h"
32#ifdef _X86EMU
33#include "x86emu/x86emui.h"
34#endif
35
36static int pciCfg1in(CARD16 addr, CARD32 *val);
37static int pciCfg1out(CARD16 addr, CARD32 val);
38static int pciCfg1inw(CARD16 addr, CARD16 *val);
39static int pciCfg1outw(CARD16 addr, CARD16 val);
40static int pciCfg1inb(CARD16 addr, CARD8 *val);
41static int pciCfg1outb(CARD16 addr, CARD8 val);
42#if defined (_PC)
43static void SetResetBIOSVars(xf86Int10InfoPtr pInt, Bool set);
44#endif
45
46#define REG pInt
47
48static int pci_config_cycle = 0;
49
50int
51setup_int(xf86Int10InfoPtr pInt)
52{
53    if (pInt != Int10Current) {
54	if (!MapCurrentInt10(pInt))
55	    return -1;
56	Int10Current = pInt;
57    }
58    X86_EAX = (CARD32) pInt->ax;
59    X86_EBX = (CARD32) pInt->bx;
60    X86_ECX = (CARD32) pInt->cx;
61    X86_EDX = (CARD32) pInt->dx;
62    X86_ESI = (CARD32) pInt->si;
63    X86_EDI = (CARD32) pInt->di;
64    X86_EBP = (CARD32) pInt->bp;
65    X86_ESP = 0x1000; X86_SS = pInt->stackseg >> 4;
66    X86_EIP = 0x0600; X86_CS = 0x0;	/* address of 'hlt' */
67    X86_DS = 0x40;			/* standard pc ds */
68    X86_ES = pInt->es;
69    X86_FS = 0;
70    X86_GS = 0;
71    X86_EFLAGS = X86_IF_MASK | X86_IOPL_MASK;
72#if defined (_PC)
73    if (pInt->Flags & SET_BIOS_SCRATCH)
74	SetResetBIOSVars(pInt, TRUE);
75#endif
76    return xf86BlockSIGIO();
77}
78
79void
80finish_int(xf86Int10InfoPtr pInt, int sig)
81{
82    xf86UnblockSIGIO(sig);
83    pInt->ax = (CARD32) X86_EAX;
84    pInt->bx = (CARD32) X86_EBX;
85    pInt->cx = (CARD32) X86_ECX;
86    pInt->dx = (CARD32) X86_EDX;
87    pInt->si = (CARD32) X86_ESI;
88    pInt->di = (CARD32) X86_EDI;
89    pInt->es = (CARD16) X86_ES;
90    pInt->bp = (CARD32) X86_EBP;
91    pInt->flags = (CARD32) X86_FLAGS;
92#if defined (_PC)
93    if (pInt->Flags & RESTORE_BIOS_SCRATCH)
94	SetResetBIOSVars(pInt, FALSE);
95#endif
96}
97
98/* general software interrupt handler */
99CARD32
100getIntVect(xf86Int10InfoPtr pInt,int num)
101{
102    return MEM_RW(pInt, num << 2) + (MEM_RW(pInt, (num << 2) + 2) << 4);
103}
104
105void
106pushw(xf86Int10InfoPtr pInt, CARD16 val)
107{
108    X86_ESP -= 2;
109    MEM_WW(pInt, ((CARD32) X86_SS << 4) + X86_SP, val);
110}
111
112int
113run_bios_int(int num, xf86Int10InfoPtr pInt)
114{
115    CARD32 eflags;
116#ifndef _PC
117    /* check if bios vector is initialized */
118    if (MEM_RW(pInt, (num << 2) + 2) == (SYS_BIOS >> 4)) { /* SYS_BIOS_SEG ?*/
119
120	if (num == 21 && X86_AH == 0x4e) {
121 	    xf86DrvMsg(pInt->scrnIndex, X_NOTICE,
122		       "Failing Find-Matching-File on non-PC"
123			" (int 21, func 4e)\n");
124 	    X86_AX = 2;
125 	    SET_FLAG(F_CF);
126 	    return 1;
127 	} else {
128	    xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 2,
129			   "Ignoring int 0x%02x call\n", num);
130	    if (xf86GetVerbosity() > 3) {
131		dump_registers(pInt);
132		stack_trace(pInt);
133	    }
134	    return 1;
135	}
136    }
137#endif
138#ifdef PRINT_INT
139    ErrorF("calling card BIOS at: ");
140#endif
141    eflags = X86_EFLAGS;
142#if 0
143    eflags = eflags | IF_MASK;
144    X86_EFLAGS = X86_EFLAGS  & ~(VIF_MASK | TF_MASK | IF_MASK | NT_MASK);
145#endif
146    pushw(pInt, eflags);
147    pushw(pInt, X86_CS);
148    pushw(pInt, X86_IP);
149    X86_CS = MEM_RW(pInt, (num << 2) + 2);
150    X86_IP = MEM_RW(pInt,  num << 2);
151#ifdef PRINT_INT
152    ErrorF("0x%x:%lx\n", X86_CS, X86_EIP);
153#endif
154    return 1;
155}
156
157/* Debugging stuff */
158void
159dump_code(xf86Int10InfoPtr pInt)
160{
161    int i;
162    unsigned long lina = SEG_ADR((CARD32), X86_CS, IP);
163
164    xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3, "code at 0x%8.8lx:\n", lina);
165    for (i=0; i<0x10; i++)
166	xf86ErrorFVerb(3, " %2.2x", MEM_RB(pInt, lina + i));
167    xf86ErrorFVerb(3, "\n");
168    for (; i<0x20; i++)
169	xf86ErrorFVerb(3, " %2.2x", MEM_RB(pInt, lina + i));
170    xf86ErrorFVerb(3, "\n");
171}
172
173void
174dump_registers(xf86Int10InfoPtr pInt)
175{
176    xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
177	"EAX=0x%8.8lx, EBX=0x%8.8lx, ECX=0x%8.8lx, EDX=0x%8.8lx\n",
178	(unsigned long)X86_EAX, (unsigned long)X86_EBX,
179	(unsigned long)X86_ECX, (unsigned long)X86_EDX);
180    xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
181	"ESP=0x%8.8lx, EBP=0x%8.8lx, ESI=0x%8.8lx, EDI=0x%8.8lx\n",
182	(unsigned long)X86_ESP, (unsigned long)X86_EBP,
183	(unsigned long)X86_ESI, (unsigned long)X86_EDI);
184    xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
185	"CS=0x%4.4x, SS=0x%4.4x,"
186	" DS=0x%4.4x, ES=0x%4.4x, FS=0x%4.4x, GS=0x%4.4x\n",
187	X86_CS, X86_SS, X86_DS, X86_ES, X86_FS, X86_GS);
188    xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
189	"EIP=0x%8.8lx, EFLAGS=0x%8.8lx\n",
190	(unsigned long)X86_EIP, (unsigned long)X86_EFLAGS);
191}
192
193void
194stack_trace(xf86Int10InfoPtr pInt)
195{
196    int i = 0;
197    unsigned long stack = SEG_ADR((CARD32), X86_SS, SP);
198    unsigned long tail  = (CARD32)((X86_SS << 4) + 0x1000);
199
200    if (stack >= tail) return;
201
202    xf86MsgVerb(X_INFO, 3, "stack at 0x%8.8lx:\n", stack);
203    for (; stack < tail; stack++) {
204	xf86ErrorFVerb(3, " %2.2x", MEM_RB(pInt, stack));
205	i = (i + 1) % 0x10;
206	if (!i)
207	    xf86ErrorFVerb(3, "\n");
208    }
209    if (i)
210	xf86ErrorFVerb(3, "\n");
211}
212
213int
214port_rep_inb(xf86Int10InfoPtr pInt,
215	     CARD16 port, CARD32 base, int d_f, CARD32 count)
216{
217    register int inc = d_f ? -1 : 1;
218    CARD32 dst = base;
219    if (PRINT_PORT && DEBUG_IO_TRACE())
220	ErrorF(" rep_insb(%#x) %d bytes at %8.8x %s\n",
221		port, count, base, d_f ? "up" : "down");
222    while (count--) {
223	MEM_WB(pInt, dst, x_inb(port));
224	dst += inc;
225    }
226    return dst - base;
227}
228
229int
230port_rep_inw(xf86Int10InfoPtr pInt,
231	     CARD16 port, CARD32 base, int d_f, CARD32 count)
232{
233    register int inc = d_f ? -2 : 2;
234    CARD32 dst = base;
235    if (PRINT_PORT && DEBUG_IO_TRACE())
236	ErrorF(" rep_insw(%#x) %d bytes at %8.8x %s\n",
237	     port, count, base, d_f ? "up" : "down");
238    while (count--) {
239	MEM_WW(pInt, dst, x_inw(port));
240	dst += inc;
241    }
242    return dst - base;
243}
244
245int
246port_rep_inl(xf86Int10InfoPtr pInt,
247	     CARD16 port, CARD32 base, int d_f, CARD32 count)
248{
249    register int inc = d_f ? -4 : 4;
250    CARD32 dst = base;
251    if (PRINT_PORT && DEBUG_IO_TRACE())
252	ErrorF(" rep_insl(%#x) %d bytes at %8.8x %s\n",
253	     port, count, base, d_f ? "up" : "down");
254    while (count--) {
255	MEM_WL(pInt, dst, x_inl(port));
256	dst += inc;
257    }
258    return dst - base;
259}
260
261int
262port_rep_outb(xf86Int10InfoPtr pInt,
263	      CARD16 port, CARD32 base, int d_f, CARD32 count)
264{
265    register int inc = d_f ? -1 : 1;
266    CARD32 dst = base;
267    if (PRINT_PORT && DEBUG_IO_TRACE())
268	ErrorF(" rep_outb(%#x) %d bytes at %8.8x %s\n",
269	     port, count, base, d_f ? "up" : "down");
270    while (count--) {
271	x_outb(port, MEM_RB(pInt, dst));
272	dst += inc;
273    }
274    return dst - base;
275}
276
277int
278port_rep_outw(xf86Int10InfoPtr pInt,
279	      CARD16 port, CARD32 base, int d_f, CARD32 count)
280{
281    register int inc = d_f ? -2 : 2;
282    CARD32 dst = base;
283    if (PRINT_PORT && DEBUG_IO_TRACE())
284	ErrorF(" rep_outw(%#x) %d bytes at %8.8x %s\n",
285	     port, count, base, d_f ? "up" : "down");
286    while (count--) {
287	x_outw(port, MEM_RW(pInt, dst));
288	dst += inc;
289    }
290    return dst - base;
291}
292
293int
294port_rep_outl(xf86Int10InfoPtr pInt,
295	      CARD16 port, CARD32 base, int d_f, CARD32 count)
296{
297    register int inc = d_f ? -4 : 4;
298    CARD32 dst = base;
299    if (PRINT_PORT && DEBUG_IO_TRACE())
300	ErrorF(" rep_outl(%#x) %d bytes at %8.8x %s\n",
301	     port, count, base, d_f ? "up" : "down");
302    while (count--) {
303	x_outl(port, MEM_RL(pInt, dst));
304	dst += inc;
305    }
306    return dst - base;
307}
308
309CARD8
310x_inb(CARD16 port)
311{
312    CARD8 val;
313
314    if (port == 0x40) {
315	Int10Current->inb40time++;
316	val = (CARD8)(Int10Current->inb40time >>
317		      ((Int10Current->inb40time & 1) << 3));
318	if (PRINT_PORT && DEBUG_IO_TRACE())
319	    ErrorF(" inb(%#x) = %2.2x\n", port, val);
320#ifdef __NOT_YET__
321    } else if (port < 0x0100) {		/* Don't interfere with mainboard */
322	val = 0;
323	xf86DrvMsgVerb(Int10Current->scrnIndex, X_NOT_IMPLEMENTED, 2,
324	    "inb 0x%4.4x\n", port);
325	if (xf86GetVerbosity() > 3) {
326	    dump_registers(Int10Current);
327	    stack_trace(Int10Current);
328	}
329#endif /* __NOT_YET__ */
330    } else if (!pciCfg1inb(port, &val)) {
331	val = inb(Int10Current->ioBase + port);
332	if (PRINT_PORT && DEBUG_IO_TRACE())
333	    ErrorF(" inb(%#x) = %2.2x\n", port, val);
334    }
335    return val;
336}
337
338CARD16
339x_inw(CARD16 port)
340{
341    CARD16 val;
342
343    if (port == 0x5c) {
344	struct timeval tv;
345
346	/*
347	 * Emulate a PC98's timer.  Typical resolution is 3.26 usec.
348	 * Approximate this by dividing by 3.
349	 */
350	X_GETTIMEOFDAY(&tv);
351	val = (CARD16)(tv.tv_usec / 3);
352    } else if (!pciCfg1inw(port, &val)) {
353	val = inw(Int10Current->ioBase + port);
354	if (PRINT_PORT && DEBUG_IO_TRACE())
355	    ErrorF(" inw(%#x) = %4.4x\n", port, val);
356    }
357    return val;
358}
359
360void
361x_outb(CARD16 port, CARD8 val)
362{
363    if ((port == 0x43) && (val == 0)) {
364	struct timeval tv;
365	/*
366	 * Emulate a PC's timer 0.  Such timers typically have a resolution of
367	 * some .838 usec per tick, but this can only provide 1 usec per tick.
368	 * (Not that this matters much, given inherent emulation delays.)  Use
369	 * the bottom bit as a byte select.  See inb(0x40) above.
370	 */
371	X_GETTIMEOFDAY(&tv);
372	Int10Current->inb40time = (CARD16)(tv.tv_usec | 1);
373	if (PRINT_PORT && DEBUG_IO_TRACE())
374	    ErrorF(" outb(%#x, %2.2x)\n", port, val);
375#ifdef __NOT_YET__
376    } else if (port < 0x0100) {		/* Don't interfere with mainboard */
377	xf86DrvMsgVerb(Int10Current->scrnIndex, X_NOT_IMPLEMENTED, 2,
378	    "outb 0x%4.4x,0x%2.2x\n", port, val);
379	if (xf86GetVerbosity() > 3) {
380	    dump_registers(Int10Current);
381	    stack_trace(Int10Current);
382	}
383#endif /* __NOT_YET__ */
384    } else if (!pciCfg1outb(port, val)) {
385	if (PRINT_PORT && DEBUG_IO_TRACE())
386	    ErrorF(" outb(%#x, %2.2x)\n", port, val);
387	outb(Int10Current->ioBase + port, val);
388    }
389}
390
391void
392x_outw(CARD16 port, CARD16 val)
393{
394
395    if (!pciCfg1outw(port, val)) {
396	if (PRINT_PORT && DEBUG_IO_TRACE())
397	    ErrorF(" outw(%#x, %4.4x)\n", port, val);
398	outw(Int10Current->ioBase + port, val);
399    }
400}
401
402CARD32
403x_inl(CARD16 port)
404{
405    CARD32 val;
406
407    if (!pciCfg1in(port, &val)) {
408	val = inl(Int10Current->ioBase + port);
409	if (PRINT_PORT && DEBUG_IO_TRACE())
410	    ErrorF(" inl(%#x) = %8.8x\n", port, val);
411    }
412    return val;
413}
414
415void
416x_outl(CARD16 port, CARD32 val)
417{
418    if (!pciCfg1out(port, val)) {
419	if (PRINT_PORT && DEBUG_IO_TRACE())
420	    ErrorF(" outl(%#x, %8.8x)\n", port, val);
421	outl(Int10Current->ioBase + port, val);
422    }
423}
424
425CARD8
426Mem_rb(CARD32 addr)
427{
428    return (*Int10Current->mem->rb)(Int10Current, addr);
429}
430
431CARD16
432Mem_rw(CARD32 addr)
433{
434    return (*Int10Current->mem->rw)(Int10Current, addr);
435}
436
437CARD32
438Mem_rl(CARD32 addr)
439{
440    return (*Int10Current->mem->rl)(Int10Current, addr);
441}
442
443void
444Mem_wb(CARD32 addr, CARD8 val)
445{
446    (*Int10Current->mem->wb)(Int10Current, addr, val);
447}
448
449void
450Mem_ww(CARD32 addr, CARD16 val)
451{
452    (*Int10Current->mem->ww)(Int10Current, addr, val);
453}
454
455void
456Mem_wl(CARD32 addr, CARD32 val)
457{
458    (*Int10Current->mem->wl)(Int10Current, addr, val);
459}
460
461static CARD32 PciCfg1Addr = 0;
462
463#define OFFSET(Cfg1Addr) (Cfg1Addr & 0xff)
464
465static int
466pciCfg1in(CARD16 addr, CARD32 *val)
467{
468    if (addr == 0xCF8) {
469	*val = PciCfg1Addr;
470	return 1;
471    }
472    if (addr == 0xCFC) {
473	*val = pciReadLong(Int10Current->Tag, OFFSET(PciCfg1Addr));
474	if (PRINT_PORT && DEBUG_IO_TRACE())
475	    ErrorF(" cfg_inl(%#x) = %8.8x\n", PciCfg1Addr, *val);
476	return 1;
477    }
478    return 0;
479}
480
481static int
482pciCfg1out(CARD16 addr, CARD32 val)
483{
484    if (addr == 0xCF8) {
485	PciCfg1Addr = val;
486	return 1;
487    }
488    if (addr == 0xCFC) {
489	if (PRINT_PORT && DEBUG_IO_TRACE())
490	    ErrorF(" cfg_outl(%#x, %8.8x)\n", PciCfg1Addr, val);
491	pciWriteLong(Int10Current->Tag, OFFSET(PciCfg1Addr), val);
492	return 1;
493    }
494    return 0;
495}
496
497static int
498pciCfg1inw(CARD16 addr, CARD16 *val)
499{
500    int offset, shift;
501
502    if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
503	shift = (addr - 0xCF8) * 8;
504	*val = (PciCfg1Addr >> shift) & 0xffff;
505	return 1;
506    }
507    if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
508	offset = addr - 0xCFC;
509	*val = pciReadWord(Int10Current->Tag, OFFSET(PciCfg1Addr) + offset);
510	if (PRINT_PORT && DEBUG_IO_TRACE())
511	    ErrorF(" cfg_inw(%#x) = %4.4x\n", PciCfg1Addr + offset, *val);
512	return 1;
513    }
514    return 0;
515}
516
517static int
518pciCfg1outw(CARD16 addr, CARD16 val)
519{
520    int offset, shift;
521
522    if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
523	shift = (addr - 0xCF8) * 8;
524	PciCfg1Addr &= ~(0xffff << shift);
525	PciCfg1Addr |= ((CARD32) val) << shift;
526	return 1;
527    }
528    if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
529	offset = addr - 0xCFC;
530	if (PRINT_PORT && DEBUG_IO_TRACE())
531	    ErrorF(" cfg_outw(%#x, %4.4x)\n", PciCfg1Addr + offset, val);
532	pciWriteWord(Int10Current->Tag, OFFSET(PciCfg1Addr) + offset, val);
533	return 1;
534    }
535    return 0;
536}
537
538static int
539pciCfg1inb(CARD16 addr, CARD8 *val)
540{
541    int offset, shift;
542
543    if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
544	shift = (addr - 0xCF8) * 8;
545	*val = (PciCfg1Addr >> shift) & 0xff;
546	return 1;
547    }
548    if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
549	offset = addr - 0xCFC;
550	*val = pciReadByte(Int10Current->Tag, OFFSET(PciCfg1Addr) + offset);
551	if (PRINT_PORT && DEBUG_IO_TRACE())
552	    ErrorF(" cfg_inb(%#x) = %2.2x\n", PciCfg1Addr + offset, *val);
553	return 1;
554    }
555    return 0;
556}
557
558static int
559pciCfg1outb(CARD16 addr, CARD8 val)
560{
561    int offset, shift;
562
563    if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
564	shift = (addr - 0xCF8) * 8;
565	PciCfg1Addr &= ~(0xff << shift);
566	PciCfg1Addr |= ((CARD32) val) << shift;
567	return 1;
568    }
569    if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
570	offset = addr - 0xCFC;
571	if (PRINT_PORT && DEBUG_IO_TRACE())
572	    ErrorF(" cfg_outb(%#x, %2.2x)\n", PciCfg1Addr + offset, val);
573	pciWriteByte(Int10Current->Tag, OFFSET(PciCfg1Addr) + offset, val);
574	return 1;
575    }
576    return 0;
577}
578
579CARD8
580bios_checksum(const CARD8 *start, int size)
581{
582    CARD8 sum = 0;
583
584    while (size-- > 0)
585	sum += *start++;
586    return sum;
587}
588
589/*
590 * Lock/Unlock legacy VGA. Some Bioses try to be very clever and make
591 * an attempt to detect a legacy ISA card. If they find one they might
592 * act very strange: for example they might configure the card as a
593 * monochrome card. This might cause some drivers to choke.
594 * To avoid this we attempt legacy VGA by writing to all know VGA
595 * disable registers before we call the BIOS initialization and
596 * restore the original values afterwards. In beween we hold our
597 * breath. To get to a (possibly exising) ISA card need to disable
598 * our current PCI card.
599 */
600/*
601 * This is just for booting: we just want to catch pure
602 * legacy vga therefore we don't worry about mmio etc.
603 * This stuff should really go into vgaHW.c. However then
604 * the driver would have to load the vga-module prior to
605 * doing int10.
606 */
607void
608LockLegacyVGA(xf86Int10InfoPtr pInt, legacyVGAPtr vga)
609{
610    xf86SetCurrentAccess(FALSE, xf86Screens[pInt->scrnIndex]);
611    vga->save_msr    = inb(pInt->ioBase + 0x03CC);
612    vga->save_vse    = inb(pInt->ioBase + 0x03C3);
613#ifndef __ia64__
614    vga->save_46e8   = inb(pInt->ioBase + 0x46E8);
615#endif
616    vga->save_pos102 = inb(pInt->ioBase + 0x0102);
617    outb(pInt->ioBase + 0x03C2, ~(CARD8)0x03 & vga->save_msr);
618    outb(pInt->ioBase + 0x03C3, ~(CARD8)0x01 & vga->save_vse);
619#ifndef __ia64__
620    outb(pInt->ioBase + 0x46E8, ~(CARD8)0x08 & vga->save_46e8);
621#endif
622    outb(pInt->ioBase + 0x0102, ~(CARD8)0x01 & vga->save_pos102);
623    xf86SetCurrentAccess(TRUE, xf86Screens[pInt->scrnIndex]);
624}
625
626void
627UnlockLegacyVGA(xf86Int10InfoPtr pInt, legacyVGAPtr vga)
628{
629    xf86SetCurrentAccess(FALSE, xf86Screens[pInt->scrnIndex]);
630    outb(pInt->ioBase + 0x0102, vga->save_pos102);
631#ifndef __ia64__
632    outb(pInt->ioBase + 0x46E8, vga->save_46e8);
633#endif
634    outb(pInt->ioBase + 0x03C3, vga->save_vse);
635    outb(pInt->ioBase + 0x03C2, vga->save_msr);
636    xf86SetCurrentAccess(TRUE, xf86Screens[pInt->scrnIndex]);
637}
638
639#if defined (_PC)
640static void
641SetResetBIOSVars(xf86Int10InfoPtr pInt, Bool set)
642{
643    int pagesize = getpagesize();
644    unsigned char* base = xf86MapVidMem(pInt->scrnIndex,
645					VIDMEM_MMIO, 0, pagesize);
646    int i;
647
648    if (set) {
649	for (i = BIOS_SCRATCH_OFF; i < BIOS_SCRATCH_END; i++)
650	    MEM_WW(pInt, i, *(base + i));
651    } else {
652	for (i = BIOS_SCRATCH_OFF; i < BIOS_SCRATCH_END; i++)
653	    *(base + i) = MEM_RW(pInt, i);
654    }
655
656    xf86UnMapVidMem(pInt->scrnIndex,base,pagesize);
657}
658
659void
660xf86Int10SaveRestoreBIOSVars(xf86Int10InfoPtr pInt, Bool save)
661{
662    int pagesize = getpagesize();
663    unsigned char* base;
664    int i;
665
666    if (!xf86IsEntityPrimary(pInt->entityIndex)
667	|| (!save && !pInt->BIOSScratch))
668	return;
669
670    base = xf86MapVidMem(pInt->scrnIndex, VIDMEM_MMIO, 0, pagesize);
671    base += BIOS_SCRATCH_OFF;
672    if (save) {
673	if ((pInt->BIOSScratch
674	     = xnfalloc(BIOS_SCRATCH_LEN)))
675	    for (i = 0; i < BIOS_SCRATCH_LEN; i++)
676		*(((char*)pInt->BIOSScratch + i)) = *(base + i);
677    } else {
678	if (pInt->BIOSScratch) {
679	    for (i = 0; i < BIOS_SCRATCH_LEN; i++)
680		*(base + i) = *(pInt->BIOSScratch + i);
681	    xfree(pInt->BIOSScratch);
682	    pInt->BIOSScratch = NULL;
683	}
684    }
685
686    xf86UnMapVidMem(pInt->scrnIndex,base - BIOS_SCRATCH_OFF ,pagesize);
687}
688#endif
689
690xf86Int10InfoPtr
691xf86InitInt10(int entityIndex)
692{
693    return xf86ExtendedInitInt10(entityIndex, 0);
694}
695