]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/xserver.git/blob - hw/xfree86/int10/helper_exec.c
Imported Upstream version 1.11.4
[glsdk/xserver.git] / hw / xfree86 / int10 / helper_exec.c
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  */
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  */
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 #include "Pci.h"
33 #ifdef _X86EMU
34 #include "x86emu/x86emui.h"
35 #else
36 #define DEBUG_IO_TRACE() 0
37 #endif
38 #include <pciaccess.h>
40 static int pciCfg1in(CARD16 addr, CARD32 *val);
41 static int pciCfg1out(CARD16 addr, CARD32 val);
42 static int pciCfg1inw(CARD16 addr, CARD16 *val);
43 static int pciCfg1outw(CARD16 addr, CARD16 val);
44 static int pciCfg1inb(CARD16 addr, CARD8 *val);
45 static int pciCfg1outb(CARD16 addr, CARD8 val);
46 #if defined (_PC)
47 static void SetResetBIOSVars(xf86Int10InfoPtr pInt, Bool set);
48 #endif
50 #define REG pInt
52 int
53 setup_int(xf86Int10InfoPtr pInt)
54 {
55     if (pInt != Int10Current) {
56         if (!MapCurrentInt10(pInt))
57             return -1;
58         Int10Current = pInt;
59     }
60     X86_EAX = (CARD32) pInt->ax;
61     X86_EBX = (CARD32) pInt->bx;
62     X86_ECX = (CARD32) pInt->cx;
63     X86_EDX = (CARD32) pInt->dx;
64     X86_ESI = (CARD32) pInt->si;
65     X86_EDI = (CARD32) pInt->di;
66     X86_EBP = (CARD32) pInt->bp;
67     X86_ESP = 0x1000; X86_SS = pInt->stackseg >> 4;
68     X86_EIP = 0x0600; X86_CS = 0x0;     /* address of 'hlt' */
69     X86_DS = 0x40;                      /* standard pc ds */
70     X86_ES = pInt->es;
71     X86_FS = 0;
72     X86_GS = 0;
73     X86_EFLAGS = X86_IF_MASK | X86_IOPL_MASK;
74 #if defined (_PC)
75     if (pInt->Flags & SET_BIOS_SCRATCH)
76         SetResetBIOSVars(pInt, TRUE);
77 #endif
78     OsBlockSignals();
79     return 0;
80 }
82 void
83 finish_int(xf86Int10InfoPtr pInt, int sig)
84 {
85     OsReleaseSignals();
86     pInt->ax = (CARD32) X86_EAX;
87     pInt->bx = (CARD32) X86_EBX;
88     pInt->cx = (CARD32) X86_ECX;
89     pInt->dx = (CARD32) X86_EDX;
90     pInt->si = (CARD32) X86_ESI;
91     pInt->di = (CARD32) X86_EDI;
92     pInt->es = (CARD16) X86_ES;
93     pInt->bp = (CARD32) X86_EBP;
94     pInt->flags = (CARD32) X86_FLAGS;
95 #if defined (_PC)
96     if (pInt->Flags & RESTORE_BIOS_SCRATCH)
97         SetResetBIOSVars(pInt, FALSE);
98 #endif
99 }
101 /* general software interrupt handler */
102 CARD32
103 getIntVect(xf86Int10InfoPtr pInt,int num)
105     return MEM_RW(pInt, num << 2) + (MEM_RW(pInt, (num << 2) + 2) << 4);
108 void
109 pushw(xf86Int10InfoPtr pInt, CARD16 val)
111     X86_ESP -= 2;
112     MEM_WW(pInt, ((CARD32) X86_SS << 4) + X86_SP, val);
115 int
116 run_bios_int(int num, xf86Int10InfoPtr pInt)
118     CARD32 eflags;
119 #ifndef _PC
120     /* check if bios vector is initialized */
121     if (MEM_RW(pInt, (num << 2) + 2) == (SYS_BIOS >> 4)) { /* SYS_BIOS_SEG ?*/
123         if (num == 21 && X86_AH == 0x4e) {
124             xf86DrvMsg(pInt->scrnIndex, X_NOTICE,
125                        "Failing Find-Matching-File on non-PC"
126                         " (int 21, func 4e)\n");
127             X86_AX = 2;
128             SET_FLAG(F_CF);
129             return 1;
130         } else {
131             xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 2,
132                            "Ignoring int 0x%02x call\n", num);
133             if (xf86GetVerbosity() > 3) {
134                 dump_registers(pInt);
135                 stack_trace(pInt);
136             }
137             return 1;
138         }
139     }
140 #endif
141 #ifdef PRINT_INT
142     ErrorF("calling card BIOS at: ");
143 #endif
144     eflags = X86_EFLAGS;
145 #if 0
146     eflags = eflags | IF_MASK;
147     X86_EFLAGS = X86_EFLAGS  & ~(VIF_MASK | TF_MASK | IF_MASK | NT_MASK);
148 #endif
149     pushw(pInt, eflags);
150     pushw(pInt, X86_CS);
151     pushw(pInt, X86_IP);
152     X86_CS = MEM_RW(pInt, (num << 2) + 2);
153     X86_IP = MEM_RW(pInt,  num << 2);
154 #ifdef PRINT_INT
155     ErrorF("0x%x:%lx\n", X86_CS, X86_EIP);
156 #endif
157     return 1;
160 /* Debugging stuff */
161 void
162 dump_code(xf86Int10InfoPtr pInt)
164     int i;
165     unsigned long lina = SEG_ADR((CARD32), X86_CS, IP);
167     xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3, "code at 0x%8.8lx:\n", lina);
168     for (i=0; i<0x10; i++)
169         xf86ErrorFVerb(3, " %2.2x", MEM_RB(pInt, lina + i));
170     xf86ErrorFVerb(3, "\n");
171     for (; i<0x20; i++)
172         xf86ErrorFVerb(3, " %2.2x", MEM_RB(pInt, lina + i));
173     xf86ErrorFVerb(3, "\n");
176 void
177 dump_registers(xf86Int10InfoPtr pInt)
179     xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
180         "EAX=0x%8.8lx, EBX=0x%8.8lx, ECX=0x%8.8lx, EDX=0x%8.8lx\n",
181         (unsigned long)X86_EAX, (unsigned long)X86_EBX,
182         (unsigned long)X86_ECX, (unsigned long)X86_EDX);
183     xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
184         "ESP=0x%8.8lx, EBP=0x%8.8lx, ESI=0x%8.8lx, EDI=0x%8.8lx\n",
185         (unsigned long)X86_ESP, (unsigned long)X86_EBP,
186         (unsigned long)X86_ESI, (unsigned long)X86_EDI);
187     xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
188         "CS=0x%4.4x, SS=0x%4.4x,"
189         " DS=0x%4.4x, ES=0x%4.4x, FS=0x%4.4x, GS=0x%4.4x\n",
190         X86_CS, X86_SS, X86_DS, X86_ES, X86_FS, X86_GS);
191     xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
192         "EIP=0x%8.8lx, EFLAGS=0x%8.8lx\n",
193         (unsigned long)X86_EIP, (unsigned long)X86_EFLAGS);
196 void
197 stack_trace(xf86Int10InfoPtr pInt)
199     int i = 0;
200     unsigned long stack = SEG_ADR((CARD32), X86_SS, SP);
201     unsigned long tail  = (CARD32)((X86_SS << 4) + 0x1000);
203     if (stack >= tail) return;
205     xf86MsgVerb(X_INFO, 3, "stack at 0x%8.8lx:\n", stack);
206     for (; stack < tail; stack++) {
207         xf86ErrorFVerb(3, " %2.2x", MEM_RB(pInt, stack));
208         i = (i + 1) % 0x10;
209         if (!i)
210             xf86ErrorFVerb(3, "\n");
211     }
212     if (i)
213         xf86ErrorFVerb(3, "\n");
216 int
217 port_rep_inb(xf86Int10InfoPtr pInt,
218              CARD16 port, CARD32 base, int d_f, CARD32 count)
220     register int inc = d_f ? -1 : 1;
221     CARD32 dst = base;
222     if (PRINT_PORT && DEBUG_IO_TRACE())
223         ErrorF(" rep_insb(%#x) %ld bytes at %8.8lx %s\n",
224                 port, count, base, d_f ? "up" : "down");
225     while (count--) {
226         MEM_WB(pInt, dst, x_inb(port));
227         dst += inc;
228     }
229     return dst - base;
232 int
233 port_rep_inw(xf86Int10InfoPtr pInt,
234              CARD16 port, CARD32 base, int d_f, CARD32 count)
236     register int inc = d_f ? -2 : 2;
237     CARD32 dst = base;
238     if (PRINT_PORT && DEBUG_IO_TRACE())
239         ErrorF(" rep_insw(%#x) %ld bytes at %8.8lx %s\n",
240              port, count, base, d_f ? "up" : "down");
241     while (count--) {
242         MEM_WW(pInt, dst, x_inw(port));
243         dst += inc;
244     }
245     return dst - base;
248 int
249 port_rep_inl(xf86Int10InfoPtr pInt,
250              CARD16 port, CARD32 base, int d_f, CARD32 count)
252     register int inc = d_f ? -4 : 4;
253     CARD32 dst = base;
254     if (PRINT_PORT && DEBUG_IO_TRACE())
255         ErrorF(" rep_insl(%#x) %ld bytes at %8.8lx %s\n",
256              port, count, base, d_f ? "up" : "down");
257     while (count--) {
258         MEM_WL(pInt, dst, x_inl(port));
259         dst += inc;
260     }
261     return dst - base;
264 int
265 port_rep_outb(xf86Int10InfoPtr pInt,
266               CARD16 port, CARD32 base, int d_f, CARD32 count)
268     register int inc = d_f ? -1 : 1;
269     CARD32 dst = base;
270     if (PRINT_PORT && DEBUG_IO_TRACE())
271         ErrorF(" rep_outb(%#x) %ld bytes at %8.8lx %s\n",
272              port, count, base, d_f ? "up" : "down");
273     while (count--) {
274         x_outb(port, MEM_RB(pInt, dst));
275         dst += inc;
276     }
277     return dst - base;
280 int
281 port_rep_outw(xf86Int10InfoPtr pInt,
282               CARD16 port, CARD32 base, int d_f, CARD32 count)
284     register int inc = d_f ? -2 : 2;
285     CARD32 dst = base;
286     if (PRINT_PORT && DEBUG_IO_TRACE())
287         ErrorF(" rep_outw(%#x) %ld bytes at %8.8lx %s\n",
288              port, count, base, d_f ? "up" : "down");
289     while (count--) {
290         x_outw(port, MEM_RW(pInt, dst));
291         dst += inc;
292     }
293     return dst - base;
296 int
297 port_rep_outl(xf86Int10InfoPtr pInt,
298               CARD16 port, CARD32 base, int d_f, CARD32 count)
300     register int inc = d_f ? -4 : 4;
301     CARD32 dst = base;
302     if (PRINT_PORT && DEBUG_IO_TRACE())
303         ErrorF(" rep_outl(%#x) %ld bytes at %8.8lx %s\n",
304              port, count, base, d_f ? "up" : "down");
305     while (count--) {
306         x_outl(port, MEM_RL(pInt, dst));
307         dst += inc;
308     }
309     return dst - base;
312 CARD8
313 x_inb(CARD16 port)
315     CARD8 val;
317     if (port == 0x40) {
318         Int10Current->inb40time++;
319         val = (CARD8)(Int10Current->inb40time >>
320                       ((Int10Current->inb40time & 1) << 3));
321         if (PRINT_PORT && DEBUG_IO_TRACE())
322             ErrorF(" inb(%#x) = %2.2x\n", port, val);
323 #ifdef __NOT_YET__
324     } else if (port < 0x0100) {         /* Don't interfere with mainboard */
325         val = 0;
326         xf86DrvMsgVerb(Int10Current->scrnIndex, X_NOT_IMPLEMENTED, 2,
327             "inb 0x%4.4x\n", port);
328         if (xf86GetVerbosity() > 3) {
329             dump_registers(Int10Current);
330             stack_trace(Int10Current);
331         }
332 #endif /* __NOT_YET__ */
333     } else if (!pciCfg1inb(port, &val)) {
334         val = inb(Int10Current->ioBase + port);
335         if (PRINT_PORT && DEBUG_IO_TRACE())
336             ErrorF(" inb(%#x) = %2.2x\n", port, val);
337     }
338     return val;
341 CARD16
342 x_inw(CARD16 port)
344     CARD16 val;
346     if (port == 0x5c) {
347         struct timeval tv;
349         /*
350          * Emulate a PC98's timer.  Typical resolution is 3.26 usec.
351          * Approximate this by dividing by 3.
352          */
353         X_GETTIMEOFDAY(&tv);
354         val = (CARD16)(tv.tv_usec / 3);
355     } else if (!pciCfg1inw(port, &val)) {
356         val = inw(Int10Current->ioBase + port);
357         if (PRINT_PORT && DEBUG_IO_TRACE())
358             ErrorF(" inw(%#x) = %4.4x\n", port, val);
359     }
360     return val;
363 void
364 x_outb(CARD16 port, CARD8 val)
366     if ((port == 0x43) && (val == 0)) {
367         struct timeval tv;
368         /*
369          * Emulate a PC's timer 0.  Such timers typically have a resolution of
370          * some .838 usec per tick, but this can only provide 1 usec per tick.
371          * (Not that this matters much, given inherent emulation delays.)  Use
372          * the bottom bit as a byte select.  See inb(0x40) above.
373          */
374         X_GETTIMEOFDAY(&tv);
375         Int10Current->inb40time = (CARD16)(tv.tv_usec | 1);
376         if (PRINT_PORT && DEBUG_IO_TRACE())
377             ErrorF(" outb(%#x, %2.2x)\n", port, val);
378 #ifdef __NOT_YET__
379     } else if (port < 0x0100) {         /* Don't interfere with mainboard */
380         xf86DrvMsgVerb(Int10Current->scrnIndex, X_NOT_IMPLEMENTED, 2,
381             "outb 0x%4.4x,0x%2.2x\n", port, val);
382         if (xf86GetVerbosity() > 3) {
383             dump_registers(Int10Current);
384             stack_trace(Int10Current);
385         }
386 #endif /* __NOT_YET__ */
387     } else if (!pciCfg1outb(port, val)) {
388         if (PRINT_PORT && DEBUG_IO_TRACE())
389             ErrorF(" outb(%#x, %2.2x)\n", port, val);
390         outb(Int10Current->ioBase + port, val);
391     }
394 void
395 x_outw(CARD16 port, CARD16 val)
398     if (!pciCfg1outw(port, val)) {
399         if (PRINT_PORT && DEBUG_IO_TRACE())
400             ErrorF(" outw(%#x, %4.4x)\n", port, val);
401         outw(Int10Current->ioBase + port, val);
402     }
405 CARD32
406 x_inl(CARD16 port)
408     CARD32 val;
410     if (!pciCfg1in(port, &val)) {
411         val = inl(Int10Current->ioBase + port);
412         if (PRINT_PORT && DEBUG_IO_TRACE())
413             ErrorF(" inl(%#x) = %8.8lx\n", port, val);
414     }
415     return val;
418 void
419 x_outl(CARD16 port, CARD32 val)
421     if (!pciCfg1out(port, val)) {
422         if (PRINT_PORT && DEBUG_IO_TRACE())
423             ErrorF(" outl(%#x, %8.8lx)\n", port, val);
424         outl(Int10Current->ioBase + port, val);
425     }
428 CARD8
429 Mem_rb(CARD32 addr)
431     return (*Int10Current->mem->rb)(Int10Current, addr);
434 CARD16
435 Mem_rw(CARD32 addr)
437     return (*Int10Current->mem->rw)(Int10Current, addr);
440 CARD32
441 Mem_rl(CARD32 addr)
443     return (*Int10Current->mem->rl)(Int10Current, addr);
446 void
447 Mem_wb(CARD32 addr, CARD8 val)
449     (*Int10Current->mem->wb)(Int10Current, addr, val);
452 void
453 Mem_ww(CARD32 addr, CARD16 val)
455     (*Int10Current->mem->ww)(Int10Current, addr, val);
458 void
459 Mem_wl(CARD32 addr, CARD32 val)
461     (*Int10Current->mem->wl)(Int10Current, addr, val);
464 static CARD32 PciCfg1Addr = 0;
466 #define PCI_DOM_FROM_TAG(tag)  (((tag) >> 24) & (PCI_DOM_MASK))
467 #define PCI_BUS_FROM_TAG(tag)  (((tag) >> 16) & (PCI_DOMBUS_MASK))
468 #define PCI_DEV_FROM_TAG(tag)  (((tag) & 0x0000f800u) >> 11)
469 #define PCI_FUNC_FROM_TAG(tag) (((tag) & 0x00000700u) >> 8)
471 #define PCI_OFFSET(x) ((x) & 0x000000ff)
472 #define PCI_TAG(x)    ((x) & 0x7fffff00)
474 static struct pci_device*
475 pci_device_for_cfg_address (CARD32 addr)
477         struct pci_device *dev = NULL;
478         PCITAG tag = PCI_TAG(addr);
479         struct pci_slot_match slot_match = {
480                 .domain = PCI_DOM_FROM_TAG(tag),
481                 .bus = PCI_BUS_NO_DOMAIN(PCI_BUS_FROM_TAG(tag)),
482                 .dev = PCI_DEV_FROM_TAG(tag),
483                 .func = PCI_FUNC_FROM_TAG(tag),
484                 .match_data = 0
485         };
487         struct pci_device_iterator *iter =
488             pci_slot_match_iterator_create (&slot_match);
490         if (iter)
491                 dev = pci_device_next(iter);
493         pci_iterator_destroy(iter);
495         return dev;
498 static int
499 pciCfg1in(CARD16 addr, CARD32 *val)
501     if (addr == 0xCF8) {
502         *val = PciCfg1Addr;
503         return 1;
504     }
505     if (addr == 0xCFC) {
506         pci_device_cfg_read_u32(pci_device_for_cfg_address(PciCfg1Addr),
507                         (uint32_t *)val, PCI_OFFSET(PciCfg1Addr));
508         if (PRINT_PORT && DEBUG_IO_TRACE())
509             ErrorF(" cfg_inl(%#lx) = %8.8lx\n", PciCfg1Addr, *val);
510         return 1;
511     }
512     return 0;
515 static int
516 pciCfg1out(CARD16 addr, CARD32 val)
518     if (addr == 0xCF8) {
519         PciCfg1Addr = val;
520         return 1;
521     }
522     if (addr == 0xCFC) {
523         if (PRINT_PORT && DEBUG_IO_TRACE())
524             ErrorF(" cfg_outl(%#lx, %8.8lx)\n", PciCfg1Addr, val);
525         pci_device_cfg_write_u32(pci_device_for_cfg_address(PciCfg1Addr),
526                         val, PCI_OFFSET(PciCfg1Addr));
527         return 1;
528     }
529     return 0;
532 static int
533 pciCfg1inw(CARD16 addr, CARD16 *val)
535     int shift;
537     if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
538         shift = (addr - 0xCF8) * 8;
539         *val = (PciCfg1Addr >> shift) & 0xffff;
540         return 1;
541     }
542     if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
543         const unsigned offset = addr - 0xCFC;
545         pci_device_cfg_read_u16(pci_device_for_cfg_address(PciCfg1Addr),
546                         val, PCI_OFFSET(PciCfg1Addr) + offset);
547         if (PRINT_PORT && DEBUG_IO_TRACE())
548             ErrorF(" cfg_inw(%#lx) = %4.4x\n", PciCfg1Addr + offset, *val);
549         return 1;
550     }
551     return 0;
554 static int
555 pciCfg1outw(CARD16 addr, CARD16 val)
557     int shift;
559     if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
560         shift = (addr - 0xCF8) * 8;
561         PciCfg1Addr &= ~(0xffff << shift);
562         PciCfg1Addr |= ((CARD32) val) << shift;
563         return 1;
564     }
565     if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
566         const unsigned offset = addr - 0xCFC;
568         if (PRINT_PORT && DEBUG_IO_TRACE())
569             ErrorF(" cfg_outw(%#lx, %4.4x)\n", PciCfg1Addr + offset, val);
570         pci_device_cfg_write_u16(pci_device_for_cfg_address(PciCfg1Addr),
571                         val, PCI_OFFSET(PciCfg1Addr) + offset);
572         return 1;
573     }
574     return 0;
577 static int
578 pciCfg1inb(CARD16 addr, CARD8 *val)
580     int shift;
582     if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
583         shift = (addr - 0xCF8) * 8;
584         *val = (PciCfg1Addr >> shift) & 0xff;
585         return 1;
586     }
587     if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
588         const unsigned offset = addr - 0xCFC;
590         pci_device_cfg_read_u8(pci_device_for_cfg_address(PciCfg1Addr),
591                         val, PCI_OFFSET(PciCfg1Addr) + offset);
592         if (PRINT_PORT && DEBUG_IO_TRACE())
593             ErrorF(" cfg_inb(%#lx) = %2.2x\n", PciCfg1Addr + offset, *val);
594         return 1;
595     }
596     return 0;
599 static int
600 pciCfg1outb(CARD16 addr, CARD8 val)
602     int shift;
604     if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
605         shift = (addr - 0xCF8) * 8;
606         PciCfg1Addr &= ~(0xff << shift);
607         PciCfg1Addr |= ((CARD32) val) << shift;
608         return 1;
609     }
610     if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
611         const unsigned offset = addr - 0xCFC;
613         if (PRINT_PORT && DEBUG_IO_TRACE())
614             ErrorF(" cfg_outb(%#lx, %2.2x)\n", PciCfg1Addr + offset, val);
615         pci_device_cfg_write_u8(pci_device_for_cfg_address(PciCfg1Addr),
616                         val, PCI_OFFSET(PciCfg1Addr) + offset);
617         return 1;
618     }
619     return 0;
622 CARD8
623 bios_checksum(const CARD8 *start, int size)
625     CARD8 sum = 0;
627     while (size-- > 0)
628         sum += *start++;
629     return sum;
632 /*
633  * Lock/Unlock legacy VGA. Some Bioses try to be very clever and make
634  * an attempt to detect a legacy ISA card. If they find one they might
635  * act very strange: for example they might configure the card as a
636  * monochrome card. This might cause some drivers to choke.
637  * To avoid this we attempt legacy VGA by writing to all know VGA
638  * disable registers before we call the BIOS initialization and
639  * restore the original values afterwards. In beween we hold our
640  * breath. To get to a (possibly exising) ISA card need to disable
641  * our current PCI card.
642  */
643 /*
644  * This is just for booting: we just want to catch pure
645  * legacy vga therefore we don't worry about mmio etc.
646  * This stuff should really go into vgaHW.c. However then
647  * the driver would have to load the vga-module prior to
648  * doing int10.
649  */
650 void
651 LockLegacyVGA(xf86Int10InfoPtr pInt, legacyVGAPtr vga)
653     vga->save_msr    = inb(pInt->ioBase + 0x03CC);
654     vga->save_vse    = inb(pInt->ioBase + 0x03C3);
655 #ifndef __ia64__
656     vga->save_46e8   = inb(pInt->ioBase + 0x46E8);
657 #endif
658     vga->save_pos102 = inb(pInt->ioBase + 0x0102);
659     outb(pInt->ioBase + 0x03C2, ~(CARD8)0x03 & vga->save_msr);
660     outb(pInt->ioBase + 0x03C3, ~(CARD8)0x01 & vga->save_vse);
661 #ifndef __ia64__
662     outb(pInt->ioBase + 0x46E8, ~(CARD8)0x08 & vga->save_46e8);
663 #endif
664     outb(pInt->ioBase + 0x0102, ~(CARD8)0x01 & vga->save_pos102);
667 void
668 UnlockLegacyVGA(xf86Int10InfoPtr pInt, legacyVGAPtr vga)
670     outb(pInt->ioBase + 0x0102, vga->save_pos102);
671 #ifndef __ia64__
672     outb(pInt->ioBase + 0x46E8, vga->save_46e8);
673 #endif
674     outb(pInt->ioBase + 0x03C3, vga->save_vse);
675     outb(pInt->ioBase + 0x03C2, vga->save_msr);
678 #if defined (_PC)
679 static void
680 SetResetBIOSVars(xf86Int10InfoPtr pInt, Bool set)
682     int pagesize = getpagesize();
683     unsigned char* base = xf86MapVidMem(pInt->scrnIndex,
684                                         VIDMEM_MMIO, 0, pagesize);
685     int i;
687     if (set) {
688         for (i = BIOS_SCRATCH_OFF; i < BIOS_SCRATCH_END; i++)
689             MEM_WW(pInt, i, *(base + i));
690     } else {
691         for (i = BIOS_SCRATCH_OFF; i < BIOS_SCRATCH_END; i++)
692             *(base + i) = MEM_RW(pInt, i);
693     }
694     
695     xf86UnMapVidMem(pInt->scrnIndex,base,pagesize);
698 void
699 xf86Int10SaveRestoreBIOSVars(xf86Int10InfoPtr pInt, Bool save)
701     int pagesize = getpagesize();
702     unsigned char* base;
703     int i;
705     if (!xf86IsEntityPrimary(pInt->entityIndex)
706         || (!save && !pInt->BIOSScratch))
707         return;
708     
709     base = xf86MapVidMem(pInt->scrnIndex, VIDMEM_MMIO, 0, pagesize);
710     base += BIOS_SCRATCH_OFF;
711     if (save) {
712         if ((pInt->BIOSScratch
713              = xnfalloc(BIOS_SCRATCH_LEN)))
714             for (i = 0; i < BIOS_SCRATCH_LEN; i++)
715                 *(((char*)pInt->BIOSScratch + i)) = *(base + i);        
716     } else {
717         if (pInt->BIOSScratch) {
718             for (i = 0; i < BIOS_SCRATCH_LEN; i++)
719                 *(base + i) = *(pInt->BIOSScratch + i); 
720             free(pInt->BIOSScratch);
721             pInt->BIOSScratch = NULL;
722         }
723     }
724     
725     xf86UnMapVidMem(pInt->scrnIndex,base - BIOS_SCRATCH_OFF ,pagesize);
727 #endif
729 xf86Int10InfoPtr
730 xf86InitInt10(int entityIndex)
732     return xf86ExtendedInitInt10(entityIndex, 0);