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 40static int pciCfg1in(CARD16 addr, CARD32 *val); 41static int pciCfg1out(CARD16 addr, CARD32 val); 42static int pciCfg1inw(CARD16 addr, CARD16 *val); 43static int pciCfg1outw(CARD16 addr, CARD16 val); 44static int pciCfg1inb(CARD16 addr, CARD8 *val); 45static int pciCfg1outb(CARD16 addr, CARD8 val); 46#if defined (_PC) 47static void SetResetBIOSVars(xf86Int10InfoPtr pInt, Bool set); 48#endif 49 50#define REG pInt 51 52int 53setup_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} 81 82void 83finish_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} 100 101/* general software interrupt handler */ 102CARD32 103getIntVect(xf86Int10InfoPtr pInt,int num) 104{ 105 return MEM_RW(pInt, num << 2) + (MEM_RW(pInt, (num << 2) + 2) << 4); 106} 107 108void 109pushw(xf86Int10InfoPtr pInt, CARD16 val) 110{ 111 X86_ESP -= 2; 112 MEM_WW(pInt, ((CARD32) X86_SS << 4) + X86_SP, val); 113} 114 115int 116run_bios_int(int num, xf86Int10InfoPtr pInt) 117{ 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 ?*/ 122 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; 158} 159 160/* Debugging stuff */ 161void 162dump_code(xf86Int10InfoPtr pInt) 163{ 164 int i; 165 unsigned long lina = SEG_ADR((CARD32), X86_CS, IP); 166 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"); 174} 175 176void 177dump_registers(xf86Int10InfoPtr pInt) 178{ 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); 194} 195 196void 197stack_trace(xf86Int10InfoPtr pInt) 198{ 199 int i = 0; 200 unsigned long stack = SEG_ADR((CARD32), X86_SS, SP); 201 unsigned long tail = (CARD32)((X86_SS << 4) + 0x1000); 202 203 if (stack >= tail) return; 204 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"); 214} 215 216int 217port_rep_inb(xf86Int10InfoPtr pInt, 218 CARD16 port, CARD32 base, int d_f, CARD32 count) 219{ 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; 230} 231 232int 233port_rep_inw(xf86Int10InfoPtr pInt, 234 CARD16 port, CARD32 base, int d_f, CARD32 count) 235{ 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; 246} 247 248int 249port_rep_inl(xf86Int10InfoPtr pInt, 250 CARD16 port, CARD32 base, int d_f, CARD32 count) 251{ 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; 262} 263 264int 265port_rep_outb(xf86Int10InfoPtr pInt, 266 CARD16 port, CARD32 base, int d_f, CARD32 count) 267{ 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; 278} 279 280int 281port_rep_outw(xf86Int10InfoPtr pInt, 282 CARD16 port, CARD32 base, int d_f, CARD32 count) 283{ 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; 294} 295 296int 297port_rep_outl(xf86Int10InfoPtr pInt, 298 CARD16 port, CARD32 base, int d_f, CARD32 count) 299{ 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; 310} 311 312CARD8 313x_inb(CARD16 port) 314{ 315 CARD8 val; 316 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; 339} 340 341CARD16 342x_inw(CARD16 port) 343{ 344 CARD16 val; 345 346 if (port == 0x5c) { 347 struct timeval tv; 348 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; 361} 362 363void 364x_outb(CARD16 port, CARD8 val) 365{ 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 } 392} 393 394void 395x_outw(CARD16 port, CARD16 val) 396{ 397 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 } 403} 404 405CARD32 406x_inl(CARD16 port) 407{ 408 CARD32 val; 409 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; 416} 417 418void 419x_outl(CARD16 port, CARD32 val) 420{ 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 } 426} 427 428CARD8 429Mem_rb(CARD32 addr) 430{ 431 return (*Int10Current->mem->rb)(Int10Current, addr); 432} 433 434CARD16 435Mem_rw(CARD32 addr) 436{ 437 return (*Int10Current->mem->rw)(Int10Current, addr); 438} 439 440CARD32 441Mem_rl(CARD32 addr) 442{ 443 return (*Int10Current->mem->rl)(Int10Current, addr); 444} 445 446void 447Mem_wb(CARD32 addr, CARD8 val) 448{ 449 (*Int10Current->mem->wb)(Int10Current, addr, val); 450} 451 452void 453Mem_ww(CARD32 addr, CARD16 val) 454{ 455 (*Int10Current->mem->ww)(Int10Current, addr, val); 456} 457 458void 459Mem_wl(CARD32 addr, CARD32 val) 460{ 461 (*Int10Current->mem->wl)(Int10Current, addr, val); 462} 463 464static CARD32 PciCfg1Addr = 0; 465 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) 470 471#define PCI_OFFSET(x) ((x) & 0x000000ff) 472#define PCI_TAG(x) ((x) & 0x7fffff00) 473 474static struct pci_device* 475pci_device_for_cfg_address (CARD32 addr) 476{ 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 }; 486 487 struct pci_device_iterator *iter = 488 pci_slot_match_iterator_create (&slot_match); 489 490 if (iter) 491 dev = pci_device_next(iter); 492 493 pci_iterator_destroy(iter); 494 495 return dev; 496} 497 498static int 499pciCfg1in(CARD16 addr, CARD32 *val) 500{ 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 /* 508 * XXXMRG 509 * this one is OK - CARD32 is "long" for 32 bit 510 * and "int" for 64 bit 511 */ 512 (uint32_t *)val, PCI_OFFSET(PciCfg1Addr)); 513 if (PRINT_PORT && DEBUG_IO_TRACE()) 514 ErrorF(" cfg_inl(%#lx) = %8.8lx\n", PciCfg1Addr, *val); 515 return 1; 516 } 517 return 0; 518} 519 520static int 521pciCfg1out(CARD16 addr, CARD32 val) 522{ 523 if (addr == 0xCF8) { 524 PciCfg1Addr = val; 525 return 1; 526 } 527 if (addr == 0xCFC) { 528 if (PRINT_PORT && DEBUG_IO_TRACE()) 529 ErrorF(" cfg_outl(%#lx, %8.8lx)\n", PciCfg1Addr, val); 530 pci_device_cfg_write_u32(pci_device_for_cfg_address(PciCfg1Addr), 531 val, PCI_OFFSET(PciCfg1Addr)); 532 return 1; 533 } 534 return 0; 535} 536 537static int 538pciCfg1inw(CARD16 addr, CARD16 *val) 539{ 540 int shift; 541 542 if ((addr >= 0xCF8) && (addr <= 0xCFB)) { 543 shift = (addr - 0xCF8) * 8; 544 *val = (PciCfg1Addr >> shift) & 0xffff; 545 return 1; 546 } 547 if ((addr >= 0xCFC) && (addr <= 0xCFF)) { 548 const unsigned offset = addr - 0xCFC; 549 550 pci_device_cfg_read_u16(pci_device_for_cfg_address(PciCfg1Addr), 551 val, PCI_OFFSET(PciCfg1Addr) + offset); 552 if (PRINT_PORT && DEBUG_IO_TRACE()) 553 ErrorF(" cfg_inw(%#lx) = %4.4x\n", PciCfg1Addr + offset, *val); 554 return 1; 555 } 556 return 0; 557} 558 559static int 560pciCfg1outw(CARD16 addr, CARD16 val) 561{ 562 int shift; 563 564 if ((addr >= 0xCF8) && (addr <= 0xCFB)) { 565 shift = (addr - 0xCF8) * 8; 566 PciCfg1Addr &= ~(0xffff << shift); 567 PciCfg1Addr |= ((CARD32) val) << shift; 568 return 1; 569 } 570 if ((addr >= 0xCFC) && (addr <= 0xCFF)) { 571 const unsigned offset = addr - 0xCFC; 572 573 if (PRINT_PORT && DEBUG_IO_TRACE()) 574 ErrorF(" cfg_outw(%#lx, %4.4x)\n", PciCfg1Addr + offset, val); 575 pci_device_cfg_write_u16(pci_device_for_cfg_address(PciCfg1Addr), 576 val, PCI_OFFSET(PciCfg1Addr) + offset); 577 return 1; 578 } 579 return 0; 580} 581 582static int 583pciCfg1inb(CARD16 addr, CARD8 *val) 584{ 585 int shift; 586 587 if ((addr >= 0xCF8) && (addr <= 0xCFB)) { 588 shift = (addr - 0xCF8) * 8; 589 *val = (PciCfg1Addr >> shift) & 0xff; 590 return 1; 591 } 592 if ((addr >= 0xCFC) && (addr <= 0xCFF)) { 593 const unsigned offset = addr - 0xCFC; 594 595 pci_device_cfg_read_u8(pci_device_for_cfg_address(PciCfg1Addr), 596 val, PCI_OFFSET(PciCfg1Addr) + offset); 597 if (PRINT_PORT && DEBUG_IO_TRACE()) 598 ErrorF(" cfg_inb(%#lx) = %2.2x\n", PciCfg1Addr + offset, *val); 599 return 1; 600 } 601 return 0; 602} 603 604static int 605pciCfg1outb(CARD16 addr, CARD8 val) 606{ 607 int shift; 608 609 if ((addr >= 0xCF8) && (addr <= 0xCFB)) { 610 shift = (addr - 0xCF8) * 8; 611 PciCfg1Addr &= ~(0xff << shift); 612 PciCfg1Addr |= ((CARD32) val) << shift; 613 return 1; 614 } 615 if ((addr >= 0xCFC) && (addr <= 0xCFF)) { 616 const unsigned offset = addr - 0xCFC; 617 618 if (PRINT_PORT && DEBUG_IO_TRACE()) 619 ErrorF(" cfg_outb(%#lx, %2.2x)\n", PciCfg1Addr + offset, val); 620 pci_device_cfg_write_u8(pci_device_for_cfg_address(PciCfg1Addr), 621 val, PCI_OFFSET(PciCfg1Addr) + offset); 622 return 1; 623 } 624 return 0; 625} 626 627CARD8 628bios_checksum(const CARD8 *start, int size) 629{ 630 CARD8 sum = 0; 631 632 while (size-- > 0) 633 sum += *start++; 634 return sum; 635} 636 637/* 638 * Lock/Unlock legacy VGA. Some Bioses try to be very clever and make 639 * an attempt to detect a legacy ISA card. If they find one they might 640 * act very strange: for example they might configure the card as a 641 * monochrome card. This might cause some drivers to choke. 642 * To avoid this we attempt legacy VGA by writing to all know VGA 643 * disable registers before we call the BIOS initialization and 644 * restore the original values afterwards. In beween we hold our 645 * breath. To get to a (possibly exising) ISA card need to disable 646 * our current PCI card. 647 */ 648/* 649 * This is just for booting: we just want to catch pure 650 * legacy vga therefore we don't worry about mmio etc. 651 * This stuff should really go into vgaHW.c. However then 652 * the driver would have to load the vga-module prior to 653 * doing int10. 654 */ 655void 656LockLegacyVGA(xf86Int10InfoPtr pInt, legacyVGAPtr vga) 657{ 658#ifndef NO_LEGACY_VGA 659 vga->save_msr = inb(pInt->ioBase + 0x03CC); 660 vga->save_vse = inb(pInt->ioBase + 0x03C3); 661#ifndef __ia64__ 662 vga->save_46e8 = inb(pInt->ioBase + 0x46E8); 663#endif 664 vga->save_pos102 = inb(pInt->ioBase + 0x0102); 665 outb(pInt->ioBase + 0x03C2, ~(CARD8)0x03 & vga->save_msr); 666 outb(pInt->ioBase + 0x03C3, ~(CARD8)0x01 & vga->save_vse); 667#ifndef __ia64__ 668 outb(pInt->ioBase + 0x46E8, ~(CARD8)0x08 & vga->save_46e8); 669#endif 670 outb(pInt->ioBase + 0x0102, ~(CARD8)0x01 & vga->save_pos102); 671#endif 672} 673 674void 675UnlockLegacyVGA(xf86Int10InfoPtr pInt, legacyVGAPtr vga) 676{ 677#ifndef NO_LEGACY_VGA 678 outb(pInt->ioBase + 0x0102, vga->save_pos102); 679#ifndef __ia64__ 680 outb(pInt->ioBase + 0x46E8, vga->save_46e8); 681#endif 682 outb(pInt->ioBase + 0x03C3, vga->save_vse); 683 outb(pInt->ioBase + 0x03C2, vga->save_msr); 684#endif 685} 686 687#if defined (_PC) 688static void 689SetResetBIOSVars(xf86Int10InfoPtr pInt, Bool set) 690{ 691 int pagesize = getpagesize(); 692 unsigned char* base = xf86MapVidMem(pInt->scrnIndex, 693 VIDMEM_MMIO, 0, pagesize); 694 int i; 695 696 if (set) { 697 for (i = BIOS_SCRATCH_OFF; i < BIOS_SCRATCH_END; i++) 698 MEM_WW(pInt, i, *(base + i)); 699 } else { 700 for (i = BIOS_SCRATCH_OFF; i < BIOS_SCRATCH_END; i++) 701 *(base + i) = MEM_RW(pInt, i); 702 } 703 704 xf86UnMapVidMem(pInt->scrnIndex,base,pagesize); 705} 706 707void 708xf86Int10SaveRestoreBIOSVars(xf86Int10InfoPtr pInt, Bool save) 709{ 710 int pagesize = getpagesize(); 711 unsigned char* base; 712 int i; 713 714 if (!xf86IsEntityPrimary(pInt->entityIndex) 715 || (!save && !pInt->BIOSScratch)) 716 return; 717 718 base = xf86MapVidMem(pInt->scrnIndex, VIDMEM_MMIO, 0, pagesize); 719 base += BIOS_SCRATCH_OFF; 720 if (save) { 721 if ((pInt->BIOSScratch 722 = xnfalloc(BIOS_SCRATCH_LEN))) 723 for (i = 0; i < BIOS_SCRATCH_LEN; i++) 724 *(((char*)pInt->BIOSScratch + i)) = *(base + i); 725 } else { 726 if (pInt->BIOSScratch) { 727 for (i = 0; i < BIOS_SCRATCH_LEN; i++) 728 *(base + i) = *(pInt->BIOSScratch + i); 729 free(pInt->BIOSScratch); 730 pInt->BIOSScratch = NULL; 731 } 732 } 733 734 xf86UnMapVidMem(pInt->scrnIndex,base - BIOS_SCRATCH_OFF ,pagesize); 735} 736#endif 737 738xf86Int10InfoPtr 739xf86InitInt10(int entityIndex) 740{ 741 return xf86ExtendedInitInt10(entityIndex, 0); 742} 743