helper_exec.c revision af31da9a
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 return xf86BlockSIGIO(); 79} 80 81void 82finish_int(xf86Int10InfoPtr pInt, int sig) 83{ 84 xf86UnblockSIGIO(sig); 85 pInt->ax = (CARD32) X86_EAX; 86 pInt->bx = (CARD32) X86_EBX; 87 pInt->cx = (CARD32) X86_ECX; 88 pInt->dx = (CARD32) X86_EDX; 89 pInt->si = (CARD32) X86_ESI; 90 pInt->di = (CARD32) X86_EDI; 91 pInt->es = (CARD16) X86_ES; 92 pInt->bp = (CARD32) X86_EBP; 93 pInt->flags = (CARD32) X86_FLAGS; 94#if defined (_PC) 95 if (pInt->Flags & RESTORE_BIOS_SCRATCH) 96 SetResetBIOSVars(pInt, FALSE); 97#endif 98} 99 100/* general software interrupt handler */ 101CARD32 102getIntVect(xf86Int10InfoPtr pInt,int num) 103{ 104 return MEM_RW(pInt, num << 2) + (MEM_RW(pInt, (num << 2) + 2) << 4); 105} 106 107void 108pushw(xf86Int10InfoPtr pInt, CARD16 val) 109{ 110 X86_ESP -= 2; 111 MEM_WW(pInt, ((CARD32) X86_SS << 4) + X86_SP, val); 112} 113 114int 115run_bios_int(int num, xf86Int10InfoPtr pInt) 116{ 117 CARD32 eflags; 118#ifndef _PC 119 /* check if bios vector is initialized */ 120 if (MEM_RW(pInt, (num << 2) + 2) == (SYS_BIOS >> 4)) { /* SYS_BIOS_SEG ?*/ 121 122 if (num == 21 && X86_AH == 0x4e) { 123 xf86DrvMsg(pInt->scrnIndex, X_NOTICE, 124 "Failing Find-Matching-File on non-PC" 125 " (int 21, func 4e)\n"); 126 X86_AX = 2; 127 SET_FLAG(F_CF); 128 return 1; 129 } else { 130 xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 2, 131 "Ignoring int 0x%02x call\n", num); 132 if (xf86GetVerbosity() > 3) { 133 dump_registers(pInt); 134 stack_trace(pInt); 135 } 136 return 1; 137 } 138 } 139#endif 140#ifdef PRINT_INT 141 ErrorF("calling card BIOS at: "); 142#endif 143 eflags = X86_EFLAGS; 144#if 0 145 eflags = eflags | IF_MASK; 146 X86_EFLAGS = X86_EFLAGS & ~(VIF_MASK | TF_MASK | IF_MASK | NT_MASK); 147#endif 148 pushw(pInt, eflags); 149 pushw(pInt, X86_CS); 150 pushw(pInt, X86_IP); 151 X86_CS = MEM_RW(pInt, (num << 2) + 2); 152 X86_IP = MEM_RW(pInt, num << 2); 153#ifdef PRINT_INT 154 ErrorF("0x%x:%lx\n", X86_CS, X86_EIP); 155#endif 156 return 1; 157} 158 159/* Debugging stuff */ 160void 161dump_code(xf86Int10InfoPtr pInt) 162{ 163 int i; 164 unsigned long lina = SEG_ADR((CARD32), X86_CS, IP); 165 166 xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3, "code at 0x%8.8lx:\n", lina); 167 for (i=0; i<0x10; i++) 168 xf86ErrorFVerb(3, " %2.2x", MEM_RB(pInt, lina + i)); 169 xf86ErrorFVerb(3, "\n"); 170 for (; i<0x20; i++) 171 xf86ErrorFVerb(3, " %2.2x", MEM_RB(pInt, lina + i)); 172 xf86ErrorFVerb(3, "\n"); 173} 174 175void 176dump_registers(xf86Int10InfoPtr pInt) 177{ 178 xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3, 179 "EAX=0x%8.8lx, EBX=0x%8.8lx, ECX=0x%8.8lx, EDX=0x%8.8lx\n", 180 (unsigned long)X86_EAX, (unsigned long)X86_EBX, 181 (unsigned long)X86_ECX, (unsigned long)X86_EDX); 182 xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3, 183 "ESP=0x%8.8lx, EBP=0x%8.8lx, ESI=0x%8.8lx, EDI=0x%8.8lx\n", 184 (unsigned long)X86_ESP, (unsigned long)X86_EBP, 185 (unsigned long)X86_ESI, (unsigned long)X86_EDI); 186 xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3, 187 "CS=0x%4.4x, SS=0x%4.4x," 188 " DS=0x%4.4x, ES=0x%4.4x, FS=0x%4.4x, GS=0x%4.4x\n", 189 X86_CS, X86_SS, X86_DS, X86_ES, X86_FS, X86_GS); 190 xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3, 191 "EIP=0x%8.8lx, EFLAGS=0x%8.8lx\n", 192 (unsigned long)X86_EIP, (unsigned long)X86_EFLAGS); 193} 194 195void 196stack_trace(xf86Int10InfoPtr pInt) 197{ 198 int i = 0; 199 unsigned long stack = SEG_ADR((CARD32), X86_SS, SP); 200 unsigned long tail = (CARD32)((X86_SS << 4) + 0x1000); 201 202 if (stack >= tail) return; 203 204 xf86MsgVerb(X_INFO, 3, "stack at 0x%8.8lx:\n", stack); 205 for (; stack < tail; stack++) { 206 xf86ErrorFVerb(3, " %2.2x", MEM_RB(pInt, stack)); 207 i = (i + 1) % 0x10; 208 if (!i) 209 xf86ErrorFVerb(3, "\n"); 210 } 211 if (i) 212 xf86ErrorFVerb(3, "\n"); 213} 214 215int 216port_rep_inb(xf86Int10InfoPtr pInt, 217 CARD16 port, CARD32 base, int d_f, CARD32 count) 218{ 219 register int inc = d_f ? -1 : 1; 220 CARD32 dst = base; 221 if (PRINT_PORT && DEBUG_IO_TRACE()) 222 ErrorF(" rep_insb(%#x) %ld bytes at %8.8lx %s\n", 223 port, count, base, d_f ? "up" : "down"); 224 while (count--) { 225 MEM_WB(pInt, dst, x_inb(port)); 226 dst += inc; 227 } 228 return dst - base; 229} 230 231int 232port_rep_inw(xf86Int10InfoPtr pInt, 233 CARD16 port, CARD32 base, int d_f, CARD32 count) 234{ 235 register int inc = d_f ? -2 : 2; 236 CARD32 dst = base; 237 if (PRINT_PORT && DEBUG_IO_TRACE()) 238 ErrorF(" rep_insw(%#x) %ld bytes at %8.8lx %s\n", 239 port, count, base, d_f ? "up" : "down"); 240 while (count--) { 241 MEM_WW(pInt, dst, x_inw(port)); 242 dst += inc; 243 } 244 return dst - base; 245} 246 247int 248port_rep_inl(xf86Int10InfoPtr pInt, 249 CARD16 port, CARD32 base, int d_f, CARD32 count) 250{ 251 register int inc = d_f ? -4 : 4; 252 CARD32 dst = base; 253 if (PRINT_PORT && DEBUG_IO_TRACE()) 254 ErrorF(" rep_insl(%#x) %ld bytes at %8.8lx %s\n", 255 port, count, base, d_f ? "up" : "down"); 256 while (count--) { 257 MEM_WL(pInt, dst, x_inl(port)); 258 dst += inc; 259 } 260 return dst - base; 261} 262 263int 264port_rep_outb(xf86Int10InfoPtr pInt, 265 CARD16 port, CARD32 base, int d_f, CARD32 count) 266{ 267 register int inc = d_f ? -1 : 1; 268 CARD32 dst = base; 269 if (PRINT_PORT && DEBUG_IO_TRACE()) 270 ErrorF(" rep_outb(%#x) %ld bytes at %8.8lx %s\n", 271 port, count, base, d_f ? "up" : "down"); 272 while (count--) { 273 x_outb(port, MEM_RB(pInt, dst)); 274 dst += inc; 275 } 276 return dst - base; 277} 278 279int 280port_rep_outw(xf86Int10InfoPtr pInt, 281 CARD16 port, CARD32 base, int d_f, CARD32 count) 282{ 283 register int inc = d_f ? -2 : 2; 284 CARD32 dst = base; 285 if (PRINT_PORT && DEBUG_IO_TRACE()) 286 ErrorF(" rep_outw(%#x) %ld bytes at %8.8lx %s\n", 287 port, count, base, d_f ? "up" : "down"); 288 while (count--) { 289 x_outw(port, MEM_RW(pInt, dst)); 290 dst += inc; 291 } 292 return dst - base; 293} 294 295int 296port_rep_outl(xf86Int10InfoPtr pInt, 297 CARD16 port, CARD32 base, int d_f, CARD32 count) 298{ 299 register int inc = d_f ? -4 : 4; 300 CARD32 dst = base; 301 if (PRINT_PORT && DEBUG_IO_TRACE()) 302 ErrorF(" rep_outl(%#x) %ld bytes at %8.8lx %s\n", 303 port, count, base, d_f ? "up" : "down"); 304 while (count--) { 305 x_outl(port, MEM_RL(pInt, dst)); 306 dst += inc; 307 } 308 return dst - base; 309} 310 311CARD8 312x_inb(CARD16 port) 313{ 314 CARD8 val; 315 316 if (port == 0x40) { 317 Int10Current->inb40time++; 318 val = (CARD8)(Int10Current->inb40time >> 319 ((Int10Current->inb40time & 1) << 3)); 320 if (PRINT_PORT && DEBUG_IO_TRACE()) 321 ErrorF(" inb(%#x) = %2.2x\n", port, val); 322#ifdef __NOT_YET__ 323 } else if (port < 0x0100) { /* Don't interfere with mainboard */ 324 val = 0; 325 xf86DrvMsgVerb(Int10Current->scrnIndex, X_NOT_IMPLEMENTED, 2, 326 "inb 0x%4.4x\n", port); 327 if (xf86GetVerbosity() > 3) { 328 dump_registers(Int10Current); 329 stack_trace(Int10Current); 330 } 331#endif /* __NOT_YET__ */ 332 } else if (!pciCfg1inb(port, &val)) { 333 val = inb(Int10Current->ioBase + port); 334 if (PRINT_PORT && DEBUG_IO_TRACE()) 335 ErrorF(" inb(%#x) = %2.2x\n", port, val); 336 } 337 return val; 338} 339 340CARD16 341x_inw(CARD16 port) 342{ 343 CARD16 val; 344 345 if (port == 0x5c) { 346 struct timeval tv; 347 348 /* 349 * Emulate a PC98's timer. Typical resolution is 3.26 usec. 350 * Approximate this by dividing by 3. 351 */ 352 X_GETTIMEOFDAY(&tv); 353 val = (CARD16)(tv.tv_usec / 3); 354 } else if (!pciCfg1inw(port, &val)) { 355 val = inw(Int10Current->ioBase + port); 356 if (PRINT_PORT && DEBUG_IO_TRACE()) 357 ErrorF(" inw(%#x) = %4.4x\n", port, val); 358 } 359 return val; 360} 361 362void 363x_outb(CARD16 port, CARD8 val) 364{ 365 if ((port == 0x43) && (val == 0)) { 366 struct timeval tv; 367 /* 368 * Emulate a PC's timer 0. Such timers typically have a resolution of 369 * some .838 usec per tick, but this can only provide 1 usec per tick. 370 * (Not that this matters much, given inherent emulation delays.) Use 371 * the bottom bit as a byte select. See inb(0x40) above. 372 */ 373 X_GETTIMEOFDAY(&tv); 374 Int10Current->inb40time = (CARD16)(tv.tv_usec | 1); 375 if (PRINT_PORT && DEBUG_IO_TRACE()) 376 ErrorF(" outb(%#x, %2.2x)\n", port, val); 377#ifdef __NOT_YET__ 378 } else if (port < 0x0100) { /* Don't interfere with mainboard */ 379 xf86DrvMsgVerb(Int10Current->scrnIndex, X_NOT_IMPLEMENTED, 2, 380 "outb 0x%4.4x,0x%2.2x\n", port, val); 381 if (xf86GetVerbosity() > 3) { 382 dump_registers(Int10Current); 383 stack_trace(Int10Current); 384 } 385#endif /* __NOT_YET__ */ 386 } else if (!pciCfg1outb(port, val)) { 387 if (PRINT_PORT && DEBUG_IO_TRACE()) 388 ErrorF(" outb(%#x, %2.2x)\n", port, val); 389 outb(Int10Current->ioBase + port, val); 390 } 391} 392 393void 394x_outw(CARD16 port, CARD16 val) 395{ 396 397 if (!pciCfg1outw(port, val)) { 398 if (PRINT_PORT && DEBUG_IO_TRACE()) 399 ErrorF(" outw(%#x, %4.4x)\n", port, val); 400 outw(Int10Current->ioBase + port, val); 401 } 402} 403 404CARD32 405x_inl(CARD16 port) 406{ 407 CARD32 val; 408 409 if (!pciCfg1in(port, &val)) { 410 val = inl(Int10Current->ioBase + port); 411 if (PRINT_PORT && DEBUG_IO_TRACE()) 412 ErrorF(" inl(%#x) = %8.8lx\n", port, val); 413 } 414 return val; 415} 416 417void 418x_outl(CARD16 port, CARD32 val) 419{ 420 if (!pciCfg1out(port, val)) { 421 if (PRINT_PORT && DEBUG_IO_TRACE()) 422 ErrorF(" outl(%#x, %8.8lx)\n", port, val); 423 outl(Int10Current->ioBase + port, val); 424 } 425} 426 427CARD8 428Mem_rb(CARD32 addr) 429{ 430 return (*Int10Current->mem->rb)(Int10Current, addr); 431} 432 433CARD16 434Mem_rw(CARD32 addr) 435{ 436 return (*Int10Current->mem->rw)(Int10Current, addr); 437} 438 439CARD32 440Mem_rl(CARD32 addr) 441{ 442 return (*Int10Current->mem->rl)(Int10Current, addr); 443} 444 445void 446Mem_wb(CARD32 addr, CARD8 val) 447{ 448 (*Int10Current->mem->wb)(Int10Current, addr, val); 449} 450 451void 452Mem_ww(CARD32 addr, CARD16 val) 453{ 454 (*Int10Current->mem->ww)(Int10Current, addr, val); 455} 456 457void 458Mem_wl(CARD32 addr, CARD32 val) 459{ 460 (*Int10Current->mem->wl)(Int10Current, addr, val); 461} 462 463static CARD32 PciCfg1Addr = 0; 464 465#define PCI_OFFSET(x) ((x) & 0x000000ff) 466#define PCI_TAG(x) ((x) & 0x7fffff00) 467 468static struct pci_device* 469pci_device_for_cfg_address (CARD32 addr) 470{ 471 struct pci_device *dev = NULL; 472 PCITAG tag = PCI_TAG(addr); 473 struct pci_slot_match slot_match = { 474 .domain = PCI_DOM_FROM_TAG(tag), 475 .bus = PCI_BUS_NO_DOMAIN(PCI_BUS_FROM_TAG(tag)), 476 .dev = PCI_DEV_FROM_TAG(tag), 477 .func = PCI_FUNC_FROM_TAG(tag), 478 .match_data = 0 479 }; 480 481 struct pci_device_iterator *iter = 482 pci_slot_match_iterator_create (&slot_match); 483 484 if (iter) 485 dev = pci_device_next(iter); 486 487 pci_iterator_destroy(iter); 488 489 return dev; 490} 491 492static int 493pciCfg1in(CARD16 addr, CARD32 *val) 494{ 495 if (addr == 0xCF8) { 496 *val = PciCfg1Addr; 497 return 1; 498 } 499 if (addr == 0xCFC) { 500 pci_device_cfg_read_u32(pci_device_for_cfg_address(PciCfg1Addr), 501 /* 502 * XXXMRG 503 * this one is OK - CARD32 is "long" for 32 bit 504 * and "int" for 64 bit 505 */ 506 (uint32_t *) 507 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; 513} 514 515static int 516pciCfg1out(CARD16 addr, CARD32 val) 517{ 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; 530} 531 532static int 533pciCfg1inw(CARD16 addr, CARD16 *val) 534{ 535 int shift; 536 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; 544 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; 552} 553 554static int 555pciCfg1outw(CARD16 addr, CARD16 val) 556{ 557 int shift; 558 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; 567 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; 575} 576 577static int 578pciCfg1inb(CARD16 addr, CARD8 *val) 579{ 580 int shift; 581 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; 589 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; 597} 598 599static int 600pciCfg1outb(CARD16 addr, CARD8 val) 601{ 602 int shift; 603 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; 612 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; 620} 621 622CARD8 623bios_checksum(const CARD8 *start, int size) 624{ 625 CARD8 sum = 0; 626 627 while (size-- > 0) 628 sum += *start++; 629 return sum; 630} 631 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 */ 650void 651LockLegacyVGA(xf86Int10InfoPtr pInt, legacyVGAPtr vga) 652{ 653#ifndef NO_LEGACY_VGA 654 vga->save_msr = inb(pInt->ioBase + 0x03CC); 655 vga->save_vse = inb(pInt->ioBase + 0x03C3); 656#ifndef __ia64__ 657 vga->save_46e8 = inb(pInt->ioBase + 0x46E8); 658#endif 659 vga->save_pos102 = inb(pInt->ioBase + 0x0102); 660 outb(pInt->ioBase + 0x03C2, ~(CARD8)0x03 & vga->save_msr); 661 outb(pInt->ioBase + 0x03C3, ~(CARD8)0x01 & vga->save_vse); 662#ifndef __ia64__ 663 outb(pInt->ioBase + 0x46E8, ~(CARD8)0x08 & vga->save_46e8); 664#endif 665 outb(pInt->ioBase + 0x0102, ~(CARD8)0x01 & vga->save_pos102); 666#endif 667} 668 669void 670UnlockLegacyVGA(xf86Int10InfoPtr pInt, legacyVGAPtr vga) 671{ 672#ifndef NO_LEGACY_VGA 673 outb(pInt->ioBase + 0x0102, vga->save_pos102); 674#ifndef __ia64__ 675 outb(pInt->ioBase + 0x46E8, vga->save_46e8); 676#endif 677 outb(pInt->ioBase + 0x03C3, vga->save_vse); 678 outb(pInt->ioBase + 0x03C2, vga->save_msr); 679#endif 680} 681 682#if defined (_PC) 683static void 684SetResetBIOSVars(xf86Int10InfoPtr pInt, Bool set) 685{ 686 int pagesize = getpagesize(); 687 unsigned char* base = xf86MapVidMem(pInt->scrnIndex, 688 VIDMEM_MMIO, 0, pagesize); 689 int i; 690 691 if (set) { 692 for (i = BIOS_SCRATCH_OFF; i < BIOS_SCRATCH_END; i++) 693 MEM_WW(pInt, i, *(base + i)); 694 } else { 695 for (i = BIOS_SCRATCH_OFF; i < BIOS_SCRATCH_END; i++) 696 *(base + i) = MEM_RW(pInt, i); 697 } 698 699 xf86UnMapVidMem(pInt->scrnIndex,base,pagesize); 700} 701 702void 703xf86Int10SaveRestoreBIOSVars(xf86Int10InfoPtr pInt, Bool save) 704{ 705 int pagesize = getpagesize(); 706 unsigned char* base; 707 int i; 708 709 if (!xf86IsEntityPrimary(pInt->entityIndex) 710 || (!save && !pInt->BIOSScratch)) 711 return; 712 713 base = xf86MapVidMem(pInt->scrnIndex, VIDMEM_MMIO, 0, pagesize); 714 base += BIOS_SCRATCH_OFF; 715 if (save) { 716 if ((pInt->BIOSScratch 717 = xnfalloc(BIOS_SCRATCH_LEN))) 718 for (i = 0; i < BIOS_SCRATCH_LEN; i++) 719 *(((char*)pInt->BIOSScratch + i)) = *(base + i); 720 } else { 721 if (pInt->BIOSScratch) { 722 for (i = 0; i < BIOS_SCRATCH_LEN; i++) 723 *(base + i) = *(pInt->BIOSScratch + i); 724 free(pInt->BIOSScratch); 725 pInt->BIOSScratch = NULL; 726 } 727 } 728 729 xf86UnMapVidMem(pInt->scrnIndex,base - BIOS_SCRATCH_OFF ,pagesize); 730} 731#endif 732 733xf86Int10InfoPtr 734xf86InitInt10(int entityIndex) 735{ 736 return xf86ExtendedInitInt10(entityIndex, 0); 737} 738