123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885 |
- /*
- * XFree86 int10 module
- * execute BIOS int 10h calls in x86 real mode environment
- * Copyright 1999 Egbert Eich
- */
- #ifdef HAVE_XORG_CONFIG_H
- #include <xorg-config.h>
- #endif
- #include "xf86.h"
- #include "compiler.h"
- #define _INT10_PRIVATE
- #include "xf86int10.h"
- #include "int10Defines.h"
- #include "Pci.h"
- #define REG pInt
- xf86Int10InfoPtr Int10Current = NULL;
- static int int1A_handler(xf86Int10InfoPtr pInt);
- #ifndef _PC
- static int int42_handler(xf86Int10InfoPtr pInt);
- #endif
- static int intE6_handler(xf86Int10InfoPtr pInt);
- static struct pci_device *findPci(xf86Int10InfoPtr pInt, unsigned short bx);
- static CARD32 pciSlotBX(const struct pci_device *pvp);
- int
- int_handler(xf86Int10InfoPtr pInt)
- {
- int num = pInt->num;
- int ret = 0;
- switch (num) {
- #ifndef _PC
- case 0x10:
- case 0x42:
- case 0x6D:
- if (getIntVect(pInt, num) == I_S_DEFAULT_INT_VECT)
- ret = int42_handler(pInt);
- break;
- #endif
- case 0x1A:
- ret = int1A_handler(pInt);
- break;
- case 0xe6:
- ret = intE6_handler(pInt);
- break;
- default:
- break;
- }
- if (!ret)
- ret = run_bios_int(num, pInt);
- if (!ret) {
- xf86DrvMsg(pInt->pScrn->scrnIndex, X_ERROR, "Halting on int 0x%2.2x!\n", num);
- dump_registers(pInt);
- stack_trace(pInt);
- }
- return ret;
- }
- #ifndef _PC
- /*
- * This is derived from a number of PC system BIOS'es. The intent here is to
- * provide very primitive video support, before an EGA/VGA BIOS installs its
- * own interrupt vector. Here, "Ignored" calls should remain so. "Not
- * Implemented" denotes functionality that can be implemented should the need
- * arise. What are "Not Implemented" throughout are video memory accesses.
- * Also, very little input validity checking is done here.
- */
- static int
- int42_handler(xf86Int10InfoPtr pInt)
- {
- switch (X86_AH) {
- case 0x00:
- /* Set Video Mode */
- /* Enter: AL = video mode number */
- /* Leave: Nothing */
- /* Implemented (except for clearing the screen) */
- { /* Localise */
- unsigned int ioport;
- int i;
- CARD16 int1d, regvals, tmp;
- CARD8 mode, cgamode, cgacolour;
- /*
- * Ignore all mode numbers but 0x00-0x13. Some systems also ignore
- * 0x0B and 0x0C, but don't do that here.
- */
- if (X86_AL > 0x13)
- break;
- /*
- * You didn't think that was really the mode set, did you? There
- * are only so many slots in the video parameter table...
- */
- mode = X86_AL;
- ioport = 0x03D4;
- switch (MEM_RB(pInt, 0x0410) & 0x30) {
- case 0x30: /* MDA */
- mode = 0x07; /* Force mode to 0x07 */
- ioport = 0x03B4;
- break;
- case 0x10: /* CGA 40x25 */
- if (mode >= 0x07)
- mode = 0x01;
- break;
- case 0x20: /* CGA 80x25 (MCGA?) */
- if (mode >= 0x07)
- mode = 0x03;
- break;
- case 0x00: /* EGA/VGA */
- if (mode >= 0x07) /* Don't try MDA timings */
- mode = 0x01; /* !?!?! */
- break;
- }
- /* Locate data in video parameter table */
- int1d = MEM_RW(pInt, 0x1d << 2);
- regvals = ((mode >> 1) << 4) + int1d;
- cgacolour = 0x30;
- if (mode == 0x06) {
- regvals -= 0x10;
- cgacolour = 0x3F;
- }
- /** Update BIOS Data Area **/
- /* Video mode */
- MEM_WB(pInt, 0x0449, mode);
- /* Columns */
- tmp = MEM_RB(pInt, mode + int1d + 0x48);
- MEM_WW(pInt, 0x044A, tmp);
- /* Page length */
- tmp = MEM_RW(pInt, (mode & 0x06) + int1d + 0x40);
- MEM_WW(pInt, 0x044C, tmp);
- /* Start Address */
- MEM_WW(pInt, 0x044E, 0);
- /* Cursor positions, one for each display page */
- for (i = 0x0450; i < 0x0460; i += 2)
- MEM_WW(pInt, i, 0);
- /* Cursor start & end scanlines */
- tmp = MEM_RB(pInt, regvals + 0x0B);
- MEM_WB(pInt, 0x0460, tmp);
- tmp = MEM_RB(pInt, regvals + 0x0A);
- MEM_WB(pInt, 0x0461, tmp);
- /* Current display page number */
- MEM_WB(pInt, 0x0462, 0);
- /* CRTC I/O address */
- MEM_WW(pInt, 0x0463, ioport);
- /* CGA Mode register value */
- cgamode = MEM_RB(pInt, mode + int1d + 0x50);
- MEM_WB(pInt, 0x0465, cgamode);
- /* CGA Colour register value */
- MEM_WB(pInt, 0x0466, cgacolour);
- /* Rows */
- MEM_WB(pInt, 0x0484, (25 - 1));
- /* Program the mode */
- pci_io_write8(pInt->io, ioport + 4, cgamode & 0x37); /* Turn off screen */
- for (i = 0; i < 0x10; i++) {
- tmp = MEM_RB(pInt, regvals + i);
- pci_io_write8(pInt->io, ioport, i);
- pci_io_write8(pInt->io, ioport + 1, tmp);
- }
- pci_io_write8(pInt->io, ioport + 5, cgacolour); /* Select colour mode */
- pci_io_write8(pInt->io, ioport + 4, cgamode); /* Turn on screen */
- }
- break;
- case 0x01:
- /* Set Cursor Type */
- /* Enter: CH = starting line for cursor */
- /* CL = ending line for cursor */
- /* Leave: Nothing */
- /* Implemented */
- { /* Localise */
- unsigned int ioport = MEM_RW(pInt, 0x0463);
- MEM_WB(pInt, 0x0460, X86_CL);
- MEM_WB(pInt, 0x0461, X86_CH);
- pci_io_write8(pInt->io, ioport, 0x0A);
- pci_io_write8(pInt->io, ioport + 1, X86_CH);
- pci_io_write8(pInt->io, ioport, 0x0B);
- pci_io_write8(pInt->io, ioport + 1, X86_CL);
- }
- break;
- case 0x02:
- /* Set Cursor Position */
- /* Enter: BH = display page number */
- /* DH = row */
- /* DL = column */
- /* Leave: Nothing */
- /* Implemented */
- { /* Localise */
- unsigned int ioport;
- CARD16 offset;
- MEM_WB(pInt, (X86_BH << 1) + 0x0450, X86_DL);
- MEM_WB(pInt, (X86_BH << 1) + 0x0451, X86_DH);
- if (X86_BH != MEM_RB(pInt, 0x0462))
- break;
- offset = (X86_DH * MEM_RW(pInt, 0x044A)) + X86_DL;
- offset += MEM_RW(pInt, 0x044E) << 1;
- ioport = MEM_RW(pInt, 0x0463);
- pci_io_write8(pInt->io, ioport, 0x0E);
- pci_io_write8(pInt->io, ioport + 1, offset >> 8);
- pci_io_write8(pInt->io, ioport, 0x0F);
- pci_io_write8(pInt->io, ioport + 1, offset & 0xFF);
- }
- break;
- case 0x03:
- /* Get Cursor Position */
- /* Enter: BH = display page number */
- /* Leave: CH = starting line for cursor */
- /* CL = ending line for cursor */
- /* DH = row */
- /* DL = column */
- /* Implemented */
- { /* Localise */
- X86_CL = MEM_RB(pInt, 0x0460);
- X86_CH = MEM_RB(pInt, 0x0461);
- X86_DL = MEM_RB(pInt, (X86_BH << 1) + 0x0450);
- X86_DH = MEM_RB(pInt, (X86_BH << 1) + 0x0451);
- }
- break;
- case 0x04:
- /* Get Light Pen Position */
- /* Enter: Nothing */
- /* Leave: AH = 0x01 (down/triggered) or 0x00 (not) */
- /* BX = pixel column */
- /* CX = pixel row */
- /* DH = character row */
- /* DL = character column */
- /* Not Implemented */
- { /* Localise */
- xf86DrvMsgVerb(pInt->pScrn->scrnIndex, X_NOT_IMPLEMENTED, 2,
- "int 0x%2.2x(AH=0x04) -- Get Light Pen Position\n",
- pInt->num);
- if (xf86GetVerbosity() > 3) {
- dump_registers(pInt);
- stack_trace(pInt);
- }
- X86_AH = X86_BX = X86_CX = X86_DX = 0;
- }
- break;
- case 0x05:
- /* Set Display Page */
- /* Enter: AL = display page number */
- /* Leave: Nothing */
- /* Implemented */
- { /* Localise */
- unsigned int ioport = MEM_RW(pInt, 0x0463);
- CARD16 start;
- CARD8 x, y;
- /* Calculate new start address */
- MEM_WB(pInt, 0x0462, X86_AL);
- start = X86_AL * MEM_RW(pInt, 0x044C);
- MEM_WW(pInt, 0x044E, start);
- start <<= 1;
- /* Update start address */
- pci_io_write8(pInt->io, ioport, 0x0C);
- pci_io_write8(pInt->io, ioport + 1, start >> 8);
- pci_io_write8(pInt->io, ioport, 0x0D);
- pci_io_write8(pInt->io, ioport + 1, start & 0xFF);
- /* Switch cursor position */
- y = MEM_RB(pInt, (X86_AL << 1) + 0x0450);
- x = MEM_RB(pInt, (X86_AL << 1) + 0x0451);
- start += (y * MEM_RW(pInt, 0x044A)) + x;
- /* Update cursor position */
- pci_io_write8(pInt->io, ioport, 0x0E);
- pci_io_write8(pInt->io, ioport + 1, start >> 8);
- pci_io_write8(pInt->io, ioport, 0x0F);
- pci_io_write8(pInt->io, ioport + 1, start & 0xFF);
- }
- break;
- case 0x06:
- /* Initialise or Scroll Window Up */
- /* Enter: AL = lines to scroll up */
- /* BH = attribute for blank */
- /* CH = upper y of window */
- /* CL = left x of window */
- /* DH = lower y of window */
- /* DL = right x of window */
- /* Leave: Nothing */
- /* Not Implemented */
- { /* Localise */
- xf86DrvMsgVerb(pInt->pScrn->scrnIndex, X_NOT_IMPLEMENTED, 2,
- "int 0x%2.2x(AH=0x06) -- Initialise or Scroll Window Up\n",
- pInt->num);
- xf86DrvMsgVerb(pInt->pScrn->scrnIndex, X_NOT_IMPLEMENTED, 3,
- " AL=0x%2.2x, BH=0x%2.2x,"
- " CH=0x%2.2x, CL=0x%2.2x, DH=0x%2.2x, DL=0x%2.2x\n",
- X86_AL, X86_BH, X86_CH, X86_CL, X86_DH, X86_DL);
- if (xf86GetVerbosity() > 3) {
- dump_registers(pInt);
- stack_trace(pInt);
- }
- }
- break;
- case 0x07:
- /* Initialise or Scroll Window Down */
- /* Enter: AL = lines to scroll down */
- /* BH = attribute for blank */
- /* CH = upper y of window */
- /* CL = left x of window */
- /* DH = lower y of window */
- /* DL = right x of window */
- /* Leave: Nothing */
- /* Not Implemented */
- { /* Localise */
- xf86DrvMsgVerb(pInt->pScrn->scrnIndex, X_NOT_IMPLEMENTED, 2,
- "int 0x%2.2x(AH=0x07) -- Initialise or Scroll Window Down\n",
- pInt->num);
- xf86DrvMsgVerb(pInt->pScrn->scrnIndex, X_NOT_IMPLEMENTED, 3,
- " AL=0x%2.2x, BH=0x%2.2x,"
- " CH=0x%2.2x, CL=0x%2.2x, DH=0x%2.2x, DL=0x%2.2x\n",
- X86_AL, X86_BH, X86_CH, X86_CL, X86_DH, X86_DL);
- if (xf86GetVerbosity() > 3) {
- dump_registers(pInt);
- stack_trace(pInt);
- }
- }
- break;
- case 0x08:
- /* Read Character and Attribute at Cursor */
- /* Enter: BH = display page number */
- /* Leave: AH = attribute */
- /* AL = character */
- /* Not Implemented */
- { /* Localise */
- xf86DrvMsgVerb(pInt->pScrn->scrnIndex, X_NOT_IMPLEMENTED, 2,
- "int 0x%2.2x(AH=0x08) -- Read Character and Attribute at"
- " Cursor\n", pInt->num);
- xf86DrvMsgVerb(pInt->pScrn->scrnIndex, X_NOT_IMPLEMENTED, 3,
- "BH=0x%2.2x\n", X86_BH);
- if (xf86GetVerbosity() > 3) {
- dump_registers(pInt);
- stack_trace(pInt);
- }
- X86_AX = 0;
- }
- break;
- case 0x09:
- /* Write Character and Attribute at Cursor */
- /* Enter: AL = character */
- /* BH = display page number */
- /* BL = attribute (text) or colour (graphics) */
- /* CX = replication count */
- /* Leave: Nothing */
- /* Not Implemented */
- { /* Localise */
- xf86DrvMsgVerb(pInt->pScrn->scrnIndex, X_NOT_IMPLEMENTED, 2,
- "int 0x%2.2x(AH=0x09) -- Write Character and Attribute at"
- " Cursor\n", pInt->num);
- xf86DrvMsgVerb(pInt->pScrn->scrnIndex, X_NOT_IMPLEMENTED, 3,
- "AL=0x%2.2x, BH=0x%2.2x, BL=0x%2.2x, CX=0x%4.4x\n",
- X86_AL, X86_BH, X86_BL, X86_CX);
- if (xf86GetVerbosity() > 3) {
- dump_registers(pInt);
- stack_trace(pInt);
- }
- }
- break;
- case 0x0a:
- /* Write Character at Cursor */
- /* Enter: AL = character */
- /* BH = display page number */
- /* BL = colour */
- /* CX = replication count */
- /* Leave: Nothing */
- /* Not Implemented */
- { /* Localise */
- xf86DrvMsgVerb(pInt->pScrn->scrnIndex, X_NOT_IMPLEMENTED, 2,
- "int 0x%2.2x(AH=0x0A) -- Write Character at Cursor\n",
- pInt->num);
- xf86DrvMsgVerb(pInt->pScrn->scrnIndex, X_NOT_IMPLEMENTED, 3,
- "AL=0x%2.2x, BH=0x%2.2x, BL=0x%2.2x, CX=0x%4.4x\n",
- X86_AL, X86_BH, X86_BL, X86_CX);
- if (xf86GetVerbosity() > 3) {
- dump_registers(pInt);
- stack_trace(pInt);
- }
- }
- break;
- case 0x0b:
- /* Set Palette, Background or Border */
- /* Enter: BH = 0x00 or 0x01 */
- /* BL = colour or palette (respectively) */
- /* Leave: Nothing */
- /* Implemented */
- { /* Localise */
- unsigned int ioport = MEM_RW(pInt, 0x0463) + 5;
- CARD8 cgacolour = MEM_RB(pInt, 0x0466);
- if (X86_BH) {
- cgacolour &= 0xDF;
- cgacolour |= (X86_BL & 0x01) << 5;
- }
- else {
- cgacolour &= 0xE0;
- cgacolour |= X86_BL & 0x1F;
- }
- MEM_WB(pInt, 0x0466, cgacolour);
- pci_io_write8(pInt->io, ioport, cgacolour);
- }
- break;
- case 0x0c:
- /* Write Graphics Pixel */
- /* Enter: AL = pixel value */
- /* BH = display page number */
- /* CX = column */
- /* DX = row */
- /* Leave: Nothing */
- /* Not Implemented */
- { /* Localise */
- xf86DrvMsgVerb(pInt->pScrn->scrnIndex, X_NOT_IMPLEMENTED, 2,
- "int 0x%2.2x(AH=0x0C) -- Write Graphics Pixel\n",
- pInt->num);
- xf86DrvMsgVerb(pInt->pScrn->scrnIndex, X_NOT_IMPLEMENTED, 3,
- "AL=0x%2.2x, BH=0x%2.2x, CX=0x%4.4x, DX=0x%4.4x\n",
- X86_AL, X86_BH, X86_CX, X86_DX);
- if (xf86GetVerbosity() > 3) {
- dump_registers(pInt);
- stack_trace(pInt);
- }
- }
- break;
- case 0x0d:
- /* Read Graphics Pixel */
- /* Enter: BH = display page number */
- /* CX = column */
- /* DX = row */
- /* Leave: AL = pixel value */
- /* Not Implemented */
- { /* Localise */
- xf86DrvMsgVerb(pInt->pScrn->scrnIndex, X_NOT_IMPLEMENTED, 2,
- "int 0x%2.2x(AH=0x0D) -- Read Graphics Pixel\n",
- pInt->num);
- xf86DrvMsgVerb(pInt->pScrn->scrnIndex, X_NOT_IMPLEMENTED, 3,
- "BH=0x%2.2x, CX=0x%4.4x, DX=0x%4.4x\n", X86_BH, X86_CX,
- X86_DX);
- if (xf86GetVerbosity() > 3) {
- dump_registers(pInt);
- stack_trace(pInt);
- }
- X86_AL = 0;
- }
- break;
- case 0x0e:
- /* Write Character in Teletype Mode */
- /* Enter: AL = character */
- /* BH = display page number */
- /* BL = foreground colour */
- /* Leave: Nothing */
- /* Not Implemented */
- /* WARNING: Emulation of BEL characters will require */
- /* emulation of RTC and PC speaker I/O. */
- /* Also, this recurses through int 0x10 */
- /* which might or might not have been */
- /* installed yet. */
- { /* Localise */
- xf86DrvMsgVerb(pInt->pScrn->scrnIndex, X_NOT_IMPLEMENTED, 2,
- "int 0x%2.2x(AH=0x0E) -- Write Character in Teletype Mode\n",
- pInt->num);
- xf86DrvMsgVerb(pInt->pScrn->scrnIndex, X_NOT_IMPLEMENTED, 3,
- "AL=0x%2.2x, BH=0x%2.2x, BL=0x%2.2x\n",
- X86_AL, X86_BH, X86_BL);
- if (xf86GetVerbosity() > 3) {
- dump_registers(pInt);
- stack_trace(pInt);
- }
- }
- break;
- case 0x0f:
- /* Get Video Mode */
- /* Enter: Nothing */
- /* Leave: AH = number of columns */
- /* AL = video mode number */
- /* BH = display page number */
- /* Implemented */
- { /* Localise */
- X86_AH = MEM_RW(pInt, 0x044A);
- X86_AL = MEM_RB(pInt, 0x0449);
- X86_BH = MEM_RB(pInt, 0x0462);
- }
- break;
- case 0x10:
- /* Colour Control (subfunction in AL) */
- /* Enter: Various */
- /* Leave: Various */
- /* Ignored */
- break;
- case 0x11:
- /* Font Control (subfunction in AL) */
- /* Enter: Various */
- /* Leave: Various */
- /* Ignored */
- break;
- case 0x12:
- /* Miscellaneous (subfunction in BL) */
- /* Enter: Various */
- /* Leave: Various */
- /* Ignored. Previous code here optionally allowed */
- /* the enabling and disabling of VGA, but no system */
- /* BIOS I've come across actually implements it. */
- break;
- case 0x13:
- /* Write String in Teletype Mode */
- /* Enter: AL = write mode */
- /* BL = attribute (if (AL & 0x02) == 0) */
- /* CX = string length */
- /* DH = row */
- /* DL = column */
- /* ES:BP = string segment:offset */
- /* Leave: Nothing */
- /* Not Implemented */
- /* WARNING: Emulation of BEL characters will require */
- /* emulation of RTC and PC speaker I/O. */
- /* Also, this recurses through int 0x10 */
- /* which might or might not have been */
- /* installed yet. */
- { /* Localise */
- xf86DrvMsgVerb(pInt->pScrn->scrnIndex, X_NOT_IMPLEMENTED, 2,
- "int 0x%2.2x(AH=0x13) -- Write String in Teletype Mode\n",
- pInt->num);
- xf86DrvMsgVerb(pInt->pScrn->scrnIndex, X_NOT_IMPLEMENTED, 3,
- "AL=0x%2.2x, BL=0x%2.2x, CX=0x%4.4x,"
- " DH=0x%2.2x, DL=0x%2.2x, ES:BP=0x%4.4x:0x%4.4x\n",
- X86_AL, X86_BL, X86_CX, X86_DH, X86_DL, X86_ES, X86_BP);
- if (xf86GetVerbosity() > 3) {
- dump_registers(pInt);
- stack_trace(pInt);
- }
- }
- break;
- default:
- /* Various extensions */
- /* Enter: Various */
- /* Leave: Various */
- /* Ignored */
- break;
- }
- return 1;
- }
- #endif
- #define SUCCESSFUL 0x00
- #define DEVICE_NOT_FOUND 0x86
- #define BAD_REGISTER_NUMBER 0x87
- #ifdef SHOW_ALL_DEVICES
- /**
- * These functions are meant to be used by the PCI BIOS emulation. Some
- * BIOSes need to see if there are \b other chips of the same type around so
- * by setting \c exclude one PCI device can be explicitely excluded, if
- * required.
- */
- static struct pci_device *
- do_find(const struct pci_id_match *m, char n, const struct pci_device *exclude)
- {
- struct pci_device *dev;
- struct pci_device_iterator *iter;
- n++;
- iter = pci_id_match_iterator_create(m);
- while ((dev = pci_device_next(iter)) != NULL) {
- if ((dev != exclude) && !(--n)) {
- break;
- }
- }
- pci_iterator_destroy(iter);
- return dev;
- }
- static struct pci_device *
- find_pci_device_vendor(CARD16 vendorID, CARD16 deviceID,
- char n, const struct pci_device *exclude)
- {
- struct pci_id_match m;
- m.vendor_id = vendorID;
- m.device_id = deviceID;
- m.subvendor_id = PCI_MATCH_ANY;
- m.subdevice_id = PCI_MATCH_ANY;
- m.device_class = 0;
- m.device_class_mask = 0;
- return do_find(&m, n, exclude);
- }
- static struct pci_device *
- find_pci_class(CARD8 intf, CARD8 subClass, CARD16 _class,
- char n, const struct pci_device *exclude)
- {
- struct pci_id_match m;
- m.vendor_id = PCI_MATCH_ANY;
- m.device_id = PCI_MATCH_ANY;
- m.subvendor_id = PCI_MATCH_ANY;
- m.subdevice_id = PCI_MATCH_ANY;
- m.device_class = (((uint32_t) _class) << 16)
- | (((uint32_t) subClass) << 8) | intf;
- m.device_class_mask = 0x00ffffff;
- return do_find(&m, n, exclude);
- }
- #endif
- /*
- * Return the last bus number in the same domain as dev. Only look at the
- * one domain since this is going into %cl, and VGA I/O is per-domain anyway.
- */
- static int
- int1A_last_bus_number(struct pci_device *dev)
- {
- struct pci_device *d;
- struct pci_slot_match m = { dev->domain,
- PCI_MATCH_ANY,
- PCI_MATCH_ANY,
- PCI_MATCH_ANY
- };
- struct pci_device_iterator *iter;
- int i = 0;
- iter = pci_slot_match_iterator_create(&m);
- while ((d = pci_device_next(iter)))
- if (d->bus > i)
- i = d->bus;
- pci_iterator_destroy(iter);
- return i;
- }
- static int
- int1A_handler(xf86Int10InfoPtr pInt)
- {
- struct pci_device *const pvp = xf86GetPciInfoForEntity(pInt->entityIndex);
- struct pci_device *dev;
- if (pvp == NULL)
- return 0; /* oops */
- #ifdef PRINT_INT
- ErrorF("int 0x1a: ax=0x%x bx=0x%x cx=0x%x dx=0x%x di=0x%x es=0x%x\n",
- X86_EAX, X86_EBX, X86_ECX, X86_EDX, X86_EDI, X86_ESI);
- #endif
- switch (X86_AX) {
- case 0xb101:
- X86_EAX &= 0xFF00; /* no config space/special cycle support */
- X86_EDX = 0x20494350; /* " ICP" */
- X86_EBX = 0x0210; /* Version 2.10 */
- X86_ECX &= 0xFF00;
- X86_ECX |= int1A_last_bus_number(pvp);
- X86_EFLAGS &= ~((unsigned long) 0x01); /* clear carry flag */
- #ifdef PRINT_INT
- ErrorF("ax=0x%x dx=0x%x bx=0x%x cx=0x%x flags=0x%x\n",
- X86_EAX, X86_EDX, X86_EBX, X86_ECX, X86_EFLAGS);
- #endif
- return 1;
- case 0xb102:
- if ((X86_DX == pvp->vendor_id)
- && (X86_CX == pvp->device_id)
- && (X86_ESI == 0)) {
- X86_EAX = X86_AL | (SUCCESSFUL << 8);
- X86_EFLAGS &= ~((unsigned long) 0x01); /* clear carry flag */
- X86_EBX = pciSlotBX(pvp);
- }
- #ifdef SHOW_ALL_DEVICES
- else if ((dev = find_pci_device_vendor(X86_EDX, X86_ECX, X86_ESI, pvp))) {
- X86_EAX = X86_AL | (SUCCESSFUL << 8);
- X86_EFLAGS &= ~((unsigned long) 0x01); /* clear carry flag */
- X86_EBX = pciSlotBX(dev);
- }
- #endif
- else {
- X86_EAX = X86_AL | (DEVICE_NOT_FOUND << 8);
- X86_EFLAGS |= ((unsigned long) 0x01); /* set carry flag */
- }
- #ifdef PRINT_INT
- ErrorF("ax=0x%x bx=0x%x flags=0x%x\n", X86_EAX, X86_EBX, X86_EFLAGS);
- #endif
- return 1;
- case 0xb103:
- if ((X86_ECX & 0x00FFFFFF) == pvp->device_class) {
- X86_EAX = X86_AL | (SUCCESSFUL << 8);
- X86_EBX = pciSlotBX(pvp);
- X86_EFLAGS &= ~((unsigned long) 0x01); /* clear carry flag */
- }
- #ifdef SHOW_ALL_DEVICES
- else if ((dev = find_pci_class(X86_CL, X86_CH,
- (X86_ECX & 0xffff0000) >> 16,
- X86_ESI, pvp))) {
- X86_EAX = X86_AL | (SUCCESSFUL << 8);
- X86_EFLAGS &= ~((unsigned long) 0x01); /* clear carry flag */
- X86_EBX = pciSlotBX(dev);
- }
- #endif
- else {
- X86_EAX = X86_AL | (DEVICE_NOT_FOUND << 8);
- X86_EFLAGS |= ((unsigned long) 0x01); /* set carry flag */
- }
- #ifdef PRINT_INT
- ErrorF("ax=0x%x flags=0x%x\n", X86_EAX, X86_EFLAGS);
- #endif
- return 1;
- case 0xb108:
- if ((dev = findPci(pInt, X86_EBX)) != NULL) {
- pci_device_cfg_read_u8(dev, &X86_CL, X86_DI);
- X86_EAX = X86_AL | (SUCCESSFUL << 8);
- X86_EFLAGS &= ~((unsigned long) 0x01); /* clear carry flag */
- }
- else {
- X86_EAX = X86_AL | (BAD_REGISTER_NUMBER << 8);
- X86_EFLAGS |= ((unsigned long) 0x01); /* set carry flag */
- }
- #ifdef PRINT_INT
- ErrorF("ax=0x%x cx=0x%x flags=0x%x\n", X86_EAX, X86_ECX, X86_EFLAGS);
- #endif
- return 1;
- case 0xb109:
- if ((dev = findPci(pInt, X86_EBX)) != NULL) {
- pci_device_cfg_read_u16(dev, &X86_CX, X86_DI);
- X86_EAX = X86_AL | (SUCCESSFUL << 8);
- X86_EFLAGS &= ~((unsigned long) 0x01); /* clear carry flag */
- }
- else {
- X86_EAX = X86_AL | (BAD_REGISTER_NUMBER << 8);
- X86_EFLAGS |= ((unsigned long) 0x01); /* set carry flag */
- }
- #ifdef PRINT_INT
- ErrorF("ax=0x%x cx=0x%x flags=0x%x\n", X86_EAX, X86_ECX, X86_EFLAGS);
- #endif
- return 1;
- case 0xb10a:
- if ((dev = findPci(pInt, X86_EBX)) != NULL) {
- pci_device_cfg_read_u32(dev, &X86_ECX, X86_DI);
- X86_EAX = X86_AL | (SUCCESSFUL << 8);
- X86_EFLAGS &= ~((unsigned long) 0x01); /* clear carry flag */
- }
- else {
- X86_EAX = X86_AL | (BAD_REGISTER_NUMBER << 8);
- X86_EFLAGS |= ((unsigned long) 0x01); /* set carry flag */
- }
- #ifdef PRINT_INT
- ErrorF("ax=0x%x cx=0x%x flags=0x%x\n", X86_EAX, X86_ECX, X86_EFLAGS);
- #endif
- return 1;
- case 0xb10b:
- if ((dev = findPci(pInt, X86_EBX)) != NULL) {
- pci_device_cfg_write_u8(dev, X86_CL, X86_DI);
- X86_EAX = X86_AL | (SUCCESSFUL << 8);
- X86_EFLAGS &= ~((unsigned long) 0x01); /* clear carry flag */
- }
- else {
- X86_EAX = X86_AL | (BAD_REGISTER_NUMBER << 8);
- X86_EFLAGS |= ((unsigned long) 0x01); /* set carry flag */
- }
- #ifdef PRINT_INT
- ErrorF("ax=0x%x flags=0x%x\n", X86_EAX, X86_EFLAGS);
- #endif
- return 1;
- case 0xb10c:
- if ((dev = findPci(pInt, X86_EBX)) != NULL) {
- pci_device_cfg_write_u16(dev, X86_CX, X86_DI);
- X86_EAX = X86_AL | (SUCCESSFUL << 8);
- X86_EFLAGS &= ~((unsigned long) 0x01); /* clear carry flag */
- }
- else {
- X86_EAX = X86_AL | (BAD_REGISTER_NUMBER << 8);
- X86_EFLAGS |= ((unsigned long) 0x01); /* set carry flag */
- }
- #ifdef PRINT_INT
- ErrorF("ax=0x%x flags=0x%x\n", X86_EAX, X86_EFLAGS);
- #endif
- return 1;
- case 0xb10d:
- if ((dev = findPci(pInt, X86_EBX)) != NULL) {
- pci_device_cfg_write_u32(dev, X86_ECX, X86_DI);
- X86_EAX = X86_AL | (SUCCESSFUL << 8);
- X86_EFLAGS &= ~((unsigned long) 0x01); /* clear carry flag */
- }
- else {
- X86_EAX = X86_AL | (BAD_REGISTER_NUMBER << 8);
- X86_EFLAGS |= ((unsigned long) 0x01); /* set carry flag */
- }
- #ifdef PRINT_INT
- ErrorF("ax=0x%x flags=0x%x\n", X86_EAX, X86_EFLAGS);
- #endif
- return 1;
- default:
- xf86DrvMsgVerb(pInt->pScrn->scrnIndex, X_NOT_IMPLEMENTED, 2,
- "int 0x1a subfunction\n");
- dump_registers(pInt);
- if (xf86GetVerbosity() > 3)
- stack_trace(pInt);
- return 0;
- }
- }
- static struct pci_device *
- findPci(xf86Int10InfoPtr pInt, unsigned short bx)
- {
- const unsigned bus = (bx >> 8) & 0x00FF;
- const unsigned dev = (bx >> 3) & 0x001F;
- const unsigned func = (bx) & 0x0007;
- return pci_device_find_by_slot(pInt->dev->domain, bus, dev, func);
- }
- static CARD32
- pciSlotBX(const struct pci_device *pvp)
- {
- return ((pvp->bus << 8) & 0x00FF00) | (pvp->dev << 3) | (pvp->func);
- }
- /*
- * handle initialization
- */
- static int
- intE6_handler(xf86Int10InfoPtr pInt)
- {
- struct pci_device *pvp;
- if ((pvp = xf86GetPciInfoForEntity(pInt->entityIndex)))
- X86_AX = (pvp->bus << 8) | (pvp->dev << 3) | (pvp->func & 0x7);
- pushw(pInt, X86_CS);
- pushw(pInt, X86_IP);
- X86_CS = pInt->BIOSseg;
- X86_EIP = 0x0003;
- X86_ES = 0; /* standard pc es */
- return 1;
- }
|