xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

helper_exec.c (21448B)


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