Initial commit
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / int10 / helper_exec.c
bloba12a9a0ca5499f0bb332b3153d16f77005695690
1 /*
2 * XFree86 int10 module
3 * execute BIOS int 10h calls in x86 real mode environment
4 * Copyright 1999 Egbert Eich
6 * Part of this code was inspired by the VBIOS POSTing code in DOSEMU
7 * developed by the "DOSEMU-Development-Team"
8 */
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.
17 #ifdef HAVE_XORG_CONFIG_H
18 #include <xorg-config.h>
19 #endif
21 #define PRINT_PORT 0
23 #include <unistd.h>
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
36 static int pciCfg1in(CARD16 addr, CARD32 *val);
37 static int pciCfg1out(CARD16 addr, CARD32 val);
38 static int pciCfg1inw(CARD16 addr, CARD16 *val);
39 static int pciCfg1outw(CARD16 addr, CARD16 val);
40 static int pciCfg1inb(CARD16 addr, CARD8 *val);
41 static int pciCfg1outb(CARD16 addr, CARD8 val);
42 #if defined (_PC)
43 static void SetResetBIOSVars(xf86Int10InfoPtr pInt, Bool set);
44 #endif
46 #define REG pInt
48 static int pci_config_cycle = 0;
50 int
51 setup_int(xf86Int10InfoPtr pInt)
53 if (pInt != Int10Current) {
54 if (!MapCurrentInt10(pInt))
55 return -1;
56 Int10Current = pInt;
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();
79 void
80 finish_int(xf86Int10InfoPtr pInt, int sig)
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
98 /* general software interrupt handler */
99 CARD32
100 getIntVect(xf86Int10InfoPtr pInt,int num)
102 return MEM_RW(pInt, num << 2) + (MEM_RW(pInt, (num << 2) + 2) << 4);
105 void
106 pushw(xf86Int10InfoPtr pInt, CARD16 val)
108 X86_ESP -= 2;
109 MEM_WW(pInt, ((CARD32) X86_SS << 4) + X86_SP, val);
113 run_bios_int(int num, xf86Int10InfoPtr pInt)
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 ?*/
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);
134 return 1;
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;
157 /* Debugging stuff */
158 void
159 dump_code(xf86Int10InfoPtr pInt)
161 int i;
162 unsigned long lina = SEG_ADR((CARD32), X86_CS, IP);
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");
173 void
174 dump_registers(xf86Int10InfoPtr pInt)
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);
193 void
194 stack_trace(xf86Int10InfoPtr pInt)
196 int i = 0;
197 unsigned long stack = SEG_ADR((CARD32), X86_SS, SP);
198 unsigned long tail = (CARD32)((X86_SS << 4) + 0x1000);
200 if (stack >= tail) return;
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");
209 if (i)
210 xf86ErrorFVerb(3, "\n");
214 port_rep_inb(xf86Int10InfoPtr pInt,
215 CARD16 port, CARD32 base, int d_f, CARD32 count)
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;
226 return dst - base;
230 port_rep_inw(xf86Int10InfoPtr pInt,
231 CARD16 port, CARD32 base, int d_f, CARD32 count)
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;
242 return dst - base;
246 port_rep_inl(xf86Int10InfoPtr pInt,
247 CARD16 port, CARD32 base, int d_f, CARD32 count)
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;
258 return dst - base;
262 port_rep_outb(xf86Int10InfoPtr pInt,
263 CARD16 port, CARD32 base, int d_f, CARD32 count)
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;
274 return dst - base;
278 port_rep_outw(xf86Int10InfoPtr pInt,
279 CARD16 port, CARD32 base, int d_f, CARD32 count)
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;
290 return dst - base;
294 port_rep_outl(xf86Int10InfoPtr pInt,
295 CARD16 port, CARD32 base, int d_f, CARD32 count)
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;
306 return dst - base;
309 CARD8
310 x_inb(CARD16 port)
312 CARD8 val;
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);
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);
335 return val;
338 CARD16
339 x_inw(CARD16 port)
341 CARD16 val;
343 if (port == 0x5c) {
344 struct timeval tv;
347 * Emulate a PC98's timer. Typical resolution is 3.26 usec.
348 * Approximate this by dividing by 3.
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);
357 return val;
360 void
361 x_outb(CARD16 port, CARD8 val)
363 if ((port == 0x43) && (val == 0)) {
364 struct timeval tv;
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.
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);
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);
391 void
392 x_outw(CARD16 port, CARD16 val)
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);
402 CARD32
403 x_inl(CARD16 port)
405 CARD32 val;
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);
412 return val;
415 void
416 x_outl(CARD16 port, CARD32 val)
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);
425 CARD8
426 Mem_rb(CARD32 addr)
428 return (*Int10Current->mem->rb)(Int10Current, addr);
431 CARD16
432 Mem_rw(CARD32 addr)
434 return (*Int10Current->mem->rw)(Int10Current, addr);
437 CARD32
438 Mem_rl(CARD32 addr)
440 return (*Int10Current->mem->rl)(Int10Current, addr);
443 void
444 Mem_wb(CARD32 addr, CARD8 val)
446 (*Int10Current->mem->wb)(Int10Current, addr, val);
449 void
450 Mem_ww(CARD32 addr, CARD16 val)
452 (*Int10Current->mem->ww)(Int10Current, addr, val);
455 void
456 Mem_wl(CARD32 addr, CARD32 val)
458 (*Int10Current->mem->wl)(Int10Current, addr, val);
461 static CARD32 PciCfg1Addr = 0;
463 #define OFFSET(Cfg1Addr) (Cfg1Addr & 0xff)
465 static int
466 pciCfg1in(CARD16 addr, CARD32 *val)
468 if (addr == 0xCF8) {
469 *val = PciCfg1Addr;
470 return 1;
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;
478 return 0;
481 static int
482 pciCfg1out(CARD16 addr, CARD32 val)
484 if (addr == 0xCF8) {
485 PciCfg1Addr = val;
486 return 1;
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;
494 return 0;
497 static int
498 pciCfg1inw(CARD16 addr, CARD16 *val)
500 int offset, shift;
502 if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
503 shift = (addr - 0xCF8) * 8;
504 *val = (PciCfg1Addr >> shift) & 0xffff;
505 return 1;
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;
514 return 0;
517 static int
518 pciCfg1outw(CARD16 addr, CARD16 val)
520 int offset, shift;
522 if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
523 shift = (addr - 0xCF8) * 8;
524 PciCfg1Addr &= ~(0xffff << shift);
525 PciCfg1Addr |= ((CARD32) val) << shift;
526 return 1;
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;
535 return 0;
538 static int
539 pciCfg1inb(CARD16 addr, CARD8 *val)
541 int offset, shift;
543 if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
544 shift = (addr - 0xCF8) * 8;
545 *val = (PciCfg1Addr >> shift) & 0xff;
546 return 1;
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;
555 return 0;
558 static int
559 pciCfg1outb(CARD16 addr, CARD8 val)
561 int offset, shift;
563 if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
564 shift = (addr - 0xCF8) * 8;
565 PciCfg1Addr &= ~(0xff << shift);
566 PciCfg1Addr |= ((CARD32) val) << shift;
567 return 1;
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;
576 return 0;
579 CARD8
580 bios_checksum(const CARD8 *start, int size)
582 CARD8 sum = 0;
584 while (size-- > 0)
585 sum += *start++;
586 return sum;
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.
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.
607 void
608 LockLegacyVGA(xf86Int10InfoPtr pInt, legacyVGAPtr vga)
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]);
626 void
627 UnlockLegacyVGA(xf86Int10InfoPtr pInt, legacyVGAPtr vga)
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]);
639 #if defined (_PC)
640 static void
641 SetResetBIOSVars(xf86Int10InfoPtr pInt, Bool set)
643 int pagesize = getpagesize();
644 unsigned char* base = xf86MapVidMem(pInt->scrnIndex,
645 VIDMEM_MMIO, 0, pagesize);
646 int i;
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);
656 xf86UnMapVidMem(pInt->scrnIndex,base,pagesize);
659 void
660 xf86Int10SaveRestoreBIOSVars(xf86Int10InfoPtr pInt, Bool save)
662 int pagesize = getpagesize();
663 unsigned char* base;
664 int i;
666 if (!xf86IsEntityPrimary(pInt->entityIndex)
667 || (!save && !pInt->BIOSScratch))
668 return;
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;
686 xf86UnMapVidMem(pInt->scrnIndex,base - BIOS_SCRATCH_OFF ,pagesize);
688 #endif
690 xf86Int10InfoPtr
691 xf86InitInt10(int entityIndex)
693 return xf86ExtendedInitInt10(entityIndex, 0);