3 * execute BIOS int 10h calls in x86 real mode environment
4 * Copyright 1999 Egbert Eich
7 #ifdef HAVE_XORG_CONFIG_H
8 #include <xorg-config.h>
13 #define _INT10_PRIVATE
14 #include "xf86int10.h"
15 #include "int10Defines.h"
20 xf86Int10InfoPtr Int10Current
= NULL
;
22 static int int1A_handler(xf86Int10InfoPtr pInt
);
25 static int int42_handler(xf86Int10InfoPtr pInt
);
27 static int intE6_handler(xf86Int10InfoPtr pInt
);
28 static struct pci_device
*findPci(xf86Int10InfoPtr pInt
, unsigned short bx
);
29 static CARD32
pciSlotBX(const struct pci_device
*pvp
);
32 int_handler(xf86Int10InfoPtr pInt
)
42 if (getIntVect(pInt
, num
) == I_S_DEFAULT_INT_VECT
)
43 ret
= int42_handler(pInt
);
47 ret
= int1A_handler(pInt
);
50 ret
= intE6_handler(pInt
);
57 ret
= run_bios_int(num
, pInt
);
60 xf86DrvMsg(pInt
->pScrn
->scrnIndex
, X_ERROR
, "Halting on int 0x%2.2x!\n", num
);
70 * This is derived from a number of PC system BIOS'es. The intent here is to
71 * provide very primitive video support, before an EGA/VGA BIOS installs its
72 * own interrupt vector. Here, "Ignored" calls should remain so. "Not
73 * Implemented" denotes functionality that can be implemented should the need
74 * arise. What are "Not Implemented" throughout are video memory accesses.
75 * Also, very little input validity checking is done here.
78 int42_handler(xf86Int10InfoPtr pInt
)
83 /* Enter: AL = video mode number */
85 /* Implemented (except for clearing the screen) */
89 CARD16 int1d
, regvals
, tmp
;
90 CARD8 mode
, cgamode
, cgacolour
;
93 * Ignore all mode numbers but 0x00-0x13. Some systems also ignore
94 * 0x0B and 0x0C, but don't do that here.
100 * You didn't think that was really the mode set, did you? There
101 * are only so many slots in the video parameter table...
105 switch (MEM_RB(pInt
, 0x0410) & 0x30) {
107 mode
= 0x07; /* Force mode to 0x07 */
110 case 0x10: /* CGA 40x25 */
114 case 0x20: /* CGA 80x25 (MCGA?) */
118 case 0x00: /* EGA/VGA */
119 if (mode
>= 0x07) /* Don't try MDA timings */
120 mode
= 0x01; /* !?!?! */
124 /* Locate data in video parameter table */
125 int1d
= MEM_RW(pInt
, 0x1d << 2);
126 regvals
= ((mode
>> 1) << 4) + int1d
;
133 /** Update BIOS Data Area **/
136 MEM_WB(pInt
, 0x0449, mode
);
139 tmp
= MEM_RB(pInt
, mode
+ int1d
+ 0x48);
140 MEM_WW(pInt
, 0x044A, tmp
);
143 tmp
= MEM_RW(pInt
, (mode
& 0x06) + int1d
+ 0x40);
144 MEM_WW(pInt
, 0x044C, tmp
);
147 MEM_WW(pInt
, 0x044E, 0);
149 /* Cursor positions, one for each display page */
150 for (i
= 0x0450; i
< 0x0460; i
+= 2)
153 /* Cursor start & end scanlines */
154 tmp
= MEM_RB(pInt
, regvals
+ 0x0B);
155 MEM_WB(pInt
, 0x0460, tmp
);
156 tmp
= MEM_RB(pInt
, regvals
+ 0x0A);
157 MEM_WB(pInt
, 0x0461, tmp
);
159 /* Current display page number */
160 MEM_WB(pInt
, 0x0462, 0);
162 /* CRTC I/O address */
163 MEM_WW(pInt
, 0x0463, ioport
);
165 /* CGA Mode register value */
166 cgamode
= MEM_RB(pInt
, mode
+ int1d
+ 0x50);
167 MEM_WB(pInt
, 0x0465, cgamode
);
169 /* CGA Colour register value */
170 MEM_WB(pInt
, 0x0466, cgacolour
);
173 MEM_WB(pInt
, 0x0484, (25 - 1));
175 /* Program the mode */
176 pci_io_write8(pInt
->io
, ioport
+ 4, cgamode
& 0x37); /* Turn off screen */
177 for (i
= 0; i
< 0x10; i
++) {
178 tmp
= MEM_RB(pInt
, regvals
+ i
);
179 pci_io_write8(pInt
->io
, ioport
, i
);
180 pci_io_write8(pInt
->io
, ioport
+ 1, tmp
);
182 pci_io_write8(pInt
->io
, ioport
+ 5, cgacolour
); /* Select colour mode */
183 pci_io_write8(pInt
->io
, ioport
+ 4, cgamode
); /* Turn on screen */
188 /* Set Cursor Type */
189 /* Enter: CH = starting line for cursor */
190 /* CL = ending line for cursor */
194 unsigned int ioport
= MEM_RW(pInt
, 0x0463);
196 MEM_WB(pInt
, 0x0460, X86_CL
);
197 MEM_WB(pInt
, 0x0461, X86_CH
);
199 pci_io_write8(pInt
->io
, ioport
, 0x0A);
200 pci_io_write8(pInt
->io
, ioport
+ 1, X86_CH
);
201 pci_io_write8(pInt
->io
, ioport
, 0x0B);
202 pci_io_write8(pInt
->io
, ioport
+ 1, X86_CL
);
207 /* Set Cursor Position */
208 /* Enter: BH = display page number */
217 MEM_WB(pInt
, (X86_BH
<< 1) + 0x0450, X86_DL
);
218 MEM_WB(pInt
, (X86_BH
<< 1) + 0x0451, X86_DH
);
220 if (X86_BH
!= MEM_RB(pInt
, 0x0462))
223 offset
= (X86_DH
* MEM_RW(pInt
, 0x044A)) + X86_DL
;
224 offset
+= MEM_RW(pInt
, 0x044E) << 1;
226 ioport
= MEM_RW(pInt
, 0x0463);
227 pci_io_write8(pInt
->io
, ioport
, 0x0E);
228 pci_io_write8(pInt
->io
, ioport
+ 1, offset
>> 8);
229 pci_io_write8(pInt
->io
, ioport
, 0x0F);
230 pci_io_write8(pInt
->io
, ioport
+ 1, offset
& 0xFF);
235 /* Get Cursor Position */
236 /* Enter: BH = display page number */
237 /* Leave: CH = starting line for cursor */
238 /* CL = ending line for cursor */
243 X86_CL
= MEM_RB(pInt
, 0x0460);
244 X86_CH
= MEM_RB(pInt
, 0x0461);
245 X86_DL
= MEM_RB(pInt
, (X86_BH
<< 1) + 0x0450);
246 X86_DH
= MEM_RB(pInt
, (X86_BH
<< 1) + 0x0451);
251 /* Get Light Pen Position */
253 /* Leave: AH = 0x01 (down/triggered) or 0x00 (not) */
254 /* BX = pixel column */
256 /* DH = character row */
257 /* DL = character column */
258 /* Not Implemented */
260 xf86DrvMsgVerb(pInt
->pScrn
->scrnIndex
, X_NOT_IMPLEMENTED
, 2,
261 "int 0x%2.2x(AH=0x04) -- Get Light Pen Position\n",
263 if (xf86GetVerbosity() > 3) {
264 dump_registers(pInt
);
267 X86_AH
= X86_BX
= X86_CX
= X86_DX
= 0;
272 /* Set Display Page */
273 /* Enter: AL = display page number */
277 unsigned int ioport
= MEM_RW(pInt
, 0x0463);
281 /* Calculate new start address */
282 MEM_WB(pInt
, 0x0462, X86_AL
);
283 start
= X86_AL
* MEM_RW(pInt
, 0x044C);
284 MEM_WW(pInt
, 0x044E, start
);
287 /* Update start address */
288 pci_io_write8(pInt
->io
, ioport
, 0x0C);
289 pci_io_write8(pInt
->io
, ioport
+ 1, start
>> 8);
290 pci_io_write8(pInt
->io
, ioport
, 0x0D);
291 pci_io_write8(pInt
->io
, ioport
+ 1, start
& 0xFF);
293 /* Switch cursor position */
294 y
= MEM_RB(pInt
, (X86_AL
<< 1) + 0x0450);
295 x
= MEM_RB(pInt
, (X86_AL
<< 1) + 0x0451);
296 start
+= (y
* MEM_RW(pInt
, 0x044A)) + x
;
298 /* Update cursor position */
299 pci_io_write8(pInt
->io
, ioport
, 0x0E);
300 pci_io_write8(pInt
->io
, ioport
+ 1, start
>> 8);
301 pci_io_write8(pInt
->io
, ioport
, 0x0F);
302 pci_io_write8(pInt
->io
, ioport
+ 1, start
& 0xFF);
307 /* Initialise or Scroll Window Up */
308 /* Enter: AL = lines to scroll up */
309 /* BH = attribute for blank */
310 /* CH = upper y of window */
311 /* CL = left x of window */
312 /* DH = lower y of window */
313 /* DL = right x of window */
315 /* Not Implemented */
317 xf86DrvMsgVerb(pInt
->pScrn
->scrnIndex
, X_NOT_IMPLEMENTED
, 2,
318 "int 0x%2.2x(AH=0x06) -- Initialise or Scroll Window Up\n",
320 xf86DrvMsgVerb(pInt
->pScrn
->scrnIndex
, X_NOT_IMPLEMENTED
, 3,
321 " AL=0x%2.2x, BH=0x%2.2x,"
322 " CH=0x%2.2x, CL=0x%2.2x, DH=0x%2.2x, DL=0x%2.2x\n",
323 X86_AL
, X86_BH
, X86_CH
, X86_CL
, X86_DH
, X86_DL
);
324 if (xf86GetVerbosity() > 3) {
325 dump_registers(pInt
);
332 /* Initialise or Scroll Window Down */
333 /* Enter: AL = lines to scroll down */
334 /* BH = attribute for blank */
335 /* CH = upper y of window */
336 /* CL = left x of window */
337 /* DH = lower y of window */
338 /* DL = right x of window */
340 /* Not Implemented */
342 xf86DrvMsgVerb(pInt
->pScrn
->scrnIndex
, X_NOT_IMPLEMENTED
, 2,
343 "int 0x%2.2x(AH=0x07) -- Initialise or Scroll Window Down\n",
345 xf86DrvMsgVerb(pInt
->pScrn
->scrnIndex
, X_NOT_IMPLEMENTED
, 3,
346 " AL=0x%2.2x, BH=0x%2.2x,"
347 " CH=0x%2.2x, CL=0x%2.2x, DH=0x%2.2x, DL=0x%2.2x\n",
348 X86_AL
, X86_BH
, X86_CH
, X86_CL
, X86_DH
, X86_DL
);
349 if (xf86GetVerbosity() > 3) {
350 dump_registers(pInt
);
357 /* Read Character and Attribute at Cursor */
358 /* Enter: BH = display page number */
359 /* Leave: AH = attribute */
361 /* Not Implemented */
363 xf86DrvMsgVerb(pInt
->pScrn
->scrnIndex
, X_NOT_IMPLEMENTED
, 2,
364 "int 0x%2.2x(AH=0x08) -- Read Character and Attribute at"
365 " Cursor\n", pInt
->num
);
366 xf86DrvMsgVerb(pInt
->pScrn
->scrnIndex
, X_NOT_IMPLEMENTED
, 3,
367 "BH=0x%2.2x\n", X86_BH
);
368 if (xf86GetVerbosity() > 3) {
369 dump_registers(pInt
);
377 /* Write Character and Attribute at Cursor */
378 /* Enter: AL = character */
379 /* BH = display page number */
380 /* BL = attribute (text) or colour (graphics) */
381 /* CX = replication count */
383 /* Not Implemented */
385 xf86DrvMsgVerb(pInt
->pScrn
->scrnIndex
, X_NOT_IMPLEMENTED
, 2,
386 "int 0x%2.2x(AH=0x09) -- Write Character and Attribute at"
387 " Cursor\n", pInt
->num
);
388 xf86DrvMsgVerb(pInt
->pScrn
->scrnIndex
, X_NOT_IMPLEMENTED
, 3,
389 "AL=0x%2.2x, BH=0x%2.2x, BL=0x%2.2x, CX=0x%4.4x\n",
390 X86_AL
, X86_BH
, X86_BL
, X86_CX
);
391 if (xf86GetVerbosity() > 3) {
392 dump_registers(pInt
);
399 /* Write Character at Cursor */
400 /* Enter: AL = character */
401 /* BH = display page number */
403 /* CX = replication count */
405 /* Not Implemented */
407 xf86DrvMsgVerb(pInt
->pScrn
->scrnIndex
, X_NOT_IMPLEMENTED
, 2,
408 "int 0x%2.2x(AH=0x0A) -- Write Character at Cursor\n",
410 xf86DrvMsgVerb(pInt
->pScrn
->scrnIndex
, X_NOT_IMPLEMENTED
, 3,
411 "AL=0x%2.2x, BH=0x%2.2x, BL=0x%2.2x, CX=0x%4.4x\n",
412 X86_AL
, X86_BH
, X86_BL
, X86_CX
);
413 if (xf86GetVerbosity() > 3) {
414 dump_registers(pInt
);
421 /* Set Palette, Background or Border */
422 /* Enter: BH = 0x00 or 0x01 */
423 /* BL = colour or palette (respectively) */
427 unsigned int ioport
= MEM_RW(pInt
, 0x0463) + 5;
428 CARD8 cgacolour
= MEM_RB(pInt
, 0x0466);
432 cgacolour
|= (X86_BL
& 0x01) << 5;
436 cgacolour
|= X86_BL
& 0x1F;
439 MEM_WB(pInt
, 0x0466, cgacolour
);
440 pci_io_write8(pInt
->io
, ioport
, cgacolour
);
445 /* Write Graphics Pixel */
446 /* Enter: AL = pixel value */
447 /* BH = display page number */
451 /* Not Implemented */
453 xf86DrvMsgVerb(pInt
->pScrn
->scrnIndex
, X_NOT_IMPLEMENTED
, 2,
454 "int 0x%2.2x(AH=0x0C) -- Write Graphics Pixel\n",
456 xf86DrvMsgVerb(pInt
->pScrn
->scrnIndex
, X_NOT_IMPLEMENTED
, 3,
457 "AL=0x%2.2x, BH=0x%2.2x, CX=0x%4.4x, DX=0x%4.4x\n",
458 X86_AL
, X86_BH
, X86_CX
, X86_DX
);
459 if (xf86GetVerbosity() > 3) {
460 dump_registers(pInt
);
467 /* Read Graphics Pixel */
468 /* Enter: BH = display page number */
471 /* Leave: AL = pixel value */
472 /* Not Implemented */
474 xf86DrvMsgVerb(pInt
->pScrn
->scrnIndex
, X_NOT_IMPLEMENTED
, 2,
475 "int 0x%2.2x(AH=0x0D) -- Read Graphics Pixel\n",
477 xf86DrvMsgVerb(pInt
->pScrn
->scrnIndex
, X_NOT_IMPLEMENTED
, 3,
478 "BH=0x%2.2x, CX=0x%4.4x, DX=0x%4.4x\n", X86_BH
, X86_CX
,
480 if (xf86GetVerbosity() > 3) {
481 dump_registers(pInt
);
489 /* Write Character in Teletype Mode */
490 /* Enter: AL = character */
491 /* BH = display page number */
492 /* BL = foreground colour */
494 /* Not Implemented */
495 /* WARNING: Emulation of BEL characters will require */
496 /* emulation of RTC and PC speaker I/O. */
497 /* Also, this recurses through int 0x10 */
498 /* which might or might not have been */
501 xf86DrvMsgVerb(pInt
->pScrn
->scrnIndex
, X_NOT_IMPLEMENTED
, 2,
502 "int 0x%2.2x(AH=0x0E) -- Write Character in Teletype Mode\n",
504 xf86DrvMsgVerb(pInt
->pScrn
->scrnIndex
, X_NOT_IMPLEMENTED
, 3,
505 "AL=0x%2.2x, BH=0x%2.2x, BL=0x%2.2x\n",
506 X86_AL
, X86_BH
, X86_BL
);
507 if (xf86GetVerbosity() > 3) {
508 dump_registers(pInt
);
517 /* Leave: AH = number of columns */
518 /* AL = video mode number */
519 /* BH = display page number */
522 X86_AH
= MEM_RW(pInt
, 0x044A);
523 X86_AL
= MEM_RB(pInt
, 0x0449);
524 X86_BH
= MEM_RB(pInt
, 0x0462);
529 /* Colour Control (subfunction in AL) */
536 /* Font Control (subfunction in AL) */
543 /* Miscellaneous (subfunction in BL) */
546 /* Ignored. Previous code here optionally allowed */
547 /* the enabling and disabling of VGA, but no system */
548 /* BIOS I've come across actually implements it. */
552 /* Write String in Teletype Mode */
553 /* Enter: AL = write mode */
554 /* BL = attribute (if (AL & 0x02) == 0) */
555 /* CX = string length */
558 /* ES:BP = string segment:offset */
560 /* Not Implemented */
561 /* WARNING: Emulation of BEL characters will require */
562 /* emulation of RTC and PC speaker I/O. */
563 /* Also, this recurses through int 0x10 */
564 /* which might or might not have been */
567 xf86DrvMsgVerb(pInt
->pScrn
->scrnIndex
, X_NOT_IMPLEMENTED
, 2,
568 "int 0x%2.2x(AH=0x13) -- Write String in Teletype Mode\n",
570 xf86DrvMsgVerb(pInt
->pScrn
->scrnIndex
, X_NOT_IMPLEMENTED
, 3,
571 "AL=0x%2.2x, BL=0x%2.2x, CX=0x%4.4x,"
572 " DH=0x%2.2x, DL=0x%2.2x, ES:BP=0x%4.4x:0x%4.4x\n",
573 X86_AL
, X86_BL
, X86_CX
, X86_DH
, X86_DL
, X86_ES
, X86_BP
);
574 if (xf86GetVerbosity() > 3) {
575 dump_registers(pInt
);
582 /* Various extensions */
593 #define SUCCESSFUL 0x00
594 #define DEVICE_NOT_FOUND 0x86
595 #define BAD_REGISTER_NUMBER 0x87
597 #ifdef SHOW_ALL_DEVICES
599 * These functions are meant to be used by the PCI BIOS emulation. Some
600 * BIOSes need to see if there are \b other chips of the same type around so
601 * by setting \c exclude one PCI device can be explicitely excluded, if
604 static struct pci_device
*
605 do_find(const struct pci_id_match
*m
, char n
, const struct pci_device
*exclude
)
607 struct pci_device
*dev
;
608 struct pci_device_iterator
*iter
;
612 iter
= pci_id_match_iterator_create(m
);
613 while ((dev
= pci_device_next(iter
)) != NULL
) {
614 if ((dev
!= exclude
) && !(--n
)) {
619 pci_iterator_destroy(iter
);
624 static struct pci_device
*
625 find_pci_device_vendor(CARD16 vendorID
, CARD16 deviceID
,
626 char n
, const struct pci_device
*exclude
)
628 struct pci_id_match m
;
630 m
.vendor_id
= vendorID
;
631 m
.device_id
= deviceID
;
632 m
.subvendor_id
= PCI_MATCH_ANY
;
633 m
.subdevice_id
= PCI_MATCH_ANY
;
635 m
.device_class_mask
= 0;
637 return do_find(&m
, n
, exclude
);
640 static struct pci_device
*
641 find_pci_class(CARD8 intf
, CARD8 subClass
, CARD16 _class
,
642 char n
, const struct pci_device
*exclude
)
644 struct pci_id_match m
;
646 m
.vendor_id
= PCI_MATCH_ANY
;
647 m
.device_id
= PCI_MATCH_ANY
;
648 m
.subvendor_id
= PCI_MATCH_ANY
;
649 m
.subdevice_id
= PCI_MATCH_ANY
;
650 m
.device_class
= (((uint32_t) _class
) << 16)
651 | (((uint32_t) subClass
) << 8) | intf
;
652 m
.device_class_mask
= 0x00ffffff;
654 return do_find(&m
, n
, exclude
);
659 * Return the last bus number in the same domain as dev. Only look at the
660 * one domain since this is going into %cl, and VGA I/O is per-domain anyway.
663 int1A_last_bus_number(struct pci_device
*dev
)
665 struct pci_device
*d
;
667 struct pci_slot_match m
= { dev
->domain
,
672 struct pci_device_iterator
*iter
;
675 iter
= pci_slot_match_iterator_create(&m
);
677 while ((d
= pci_device_next(iter
)))
681 pci_iterator_destroy(iter
);
687 int1A_handler(xf86Int10InfoPtr pInt
)
689 struct pci_device
*const pvp
= xf86GetPciInfoForEntity(pInt
->entityIndex
);
690 struct pci_device
*dev
;
696 ErrorF("int 0x1a: ax=0x%x bx=0x%x cx=0x%x dx=0x%x di=0x%x es=0x%x\n",
697 X86_EAX
, X86_EBX
, X86_ECX
, X86_EDX
, X86_EDI
, X86_ESI
);
701 X86_EAX
&= 0xFF00; /* no config space/special cycle support */
702 X86_EDX
= 0x20494350; /* " ICP" */
703 X86_EBX
= 0x0210; /* Version 2.10 */
705 X86_ECX
|= int1A_last_bus_number(pvp
);
706 X86_EFLAGS
&= ~((unsigned long) 0x01); /* clear carry flag */
708 ErrorF("ax=0x%x dx=0x%x bx=0x%x cx=0x%x flags=0x%x\n",
709 X86_EAX
, X86_EDX
, X86_EBX
, X86_ECX
, X86_EFLAGS
);
713 if ((X86_DX
== pvp
->vendor_id
)
714 && (X86_CX
== pvp
->device_id
)
716 X86_EAX
= X86_AL
| (SUCCESSFUL
<< 8);
717 X86_EFLAGS
&= ~((unsigned long) 0x01); /* clear carry flag */
718 X86_EBX
= pciSlotBX(pvp
);
720 #ifdef SHOW_ALL_DEVICES
721 else if ((dev
= find_pci_device_vendor(X86_EDX
, X86_ECX
, X86_ESI
, pvp
))) {
722 X86_EAX
= X86_AL
| (SUCCESSFUL
<< 8);
723 X86_EFLAGS
&= ~((unsigned long) 0x01); /* clear carry flag */
724 X86_EBX
= pciSlotBX(dev
);
728 X86_EAX
= X86_AL
| (DEVICE_NOT_FOUND
<< 8);
729 X86_EFLAGS
|= ((unsigned long) 0x01); /* set carry flag */
732 ErrorF("ax=0x%x bx=0x%x flags=0x%x\n", X86_EAX
, X86_EBX
, X86_EFLAGS
);
736 if ((X86_ECX
& 0x00FFFFFF) == pvp
->device_class
) {
737 X86_EAX
= X86_AL
| (SUCCESSFUL
<< 8);
738 X86_EBX
= pciSlotBX(pvp
);
739 X86_EFLAGS
&= ~((unsigned long) 0x01); /* clear carry flag */
741 #ifdef SHOW_ALL_DEVICES
742 else if ((dev
= find_pci_class(X86_CL
, X86_CH
,
743 (X86_ECX
& 0xffff0000) >> 16,
745 X86_EAX
= X86_AL
| (SUCCESSFUL
<< 8);
746 X86_EFLAGS
&= ~((unsigned long) 0x01); /* clear carry flag */
747 X86_EBX
= pciSlotBX(dev
);
751 X86_EAX
= X86_AL
| (DEVICE_NOT_FOUND
<< 8);
752 X86_EFLAGS
|= ((unsigned long) 0x01); /* set carry flag */
755 ErrorF("ax=0x%x flags=0x%x\n", X86_EAX
, X86_EFLAGS
);
759 if ((dev
= findPci(pInt
, X86_EBX
)) != NULL
) {
760 pci_device_cfg_read_u8(dev
, &X86_CL
, X86_DI
);
761 X86_EAX
= X86_AL
| (SUCCESSFUL
<< 8);
762 X86_EFLAGS
&= ~((unsigned long) 0x01); /* clear carry flag */
765 X86_EAX
= X86_AL
| (BAD_REGISTER_NUMBER
<< 8);
766 X86_EFLAGS
|= ((unsigned long) 0x01); /* set carry flag */
769 ErrorF("ax=0x%x cx=0x%x flags=0x%x\n", X86_EAX
, X86_ECX
, X86_EFLAGS
);
773 if ((dev
= findPci(pInt
, X86_EBX
)) != NULL
) {
774 pci_device_cfg_read_u16(dev
, &X86_CX
, X86_DI
);
775 X86_EAX
= X86_AL
| (SUCCESSFUL
<< 8);
776 X86_EFLAGS
&= ~((unsigned long) 0x01); /* clear carry flag */
779 X86_EAX
= X86_AL
| (BAD_REGISTER_NUMBER
<< 8);
780 X86_EFLAGS
|= ((unsigned long) 0x01); /* set carry flag */
783 ErrorF("ax=0x%x cx=0x%x flags=0x%x\n", X86_EAX
, X86_ECX
, X86_EFLAGS
);
787 if ((dev
= findPci(pInt
, X86_EBX
)) != NULL
) {
788 pci_device_cfg_read_u32(dev
, &X86_ECX
, X86_DI
);
789 X86_EAX
= X86_AL
| (SUCCESSFUL
<< 8);
790 X86_EFLAGS
&= ~((unsigned long) 0x01); /* clear carry flag */
793 X86_EAX
= X86_AL
| (BAD_REGISTER_NUMBER
<< 8);
794 X86_EFLAGS
|= ((unsigned long) 0x01); /* set carry flag */
797 ErrorF("ax=0x%x cx=0x%x flags=0x%x\n", X86_EAX
, X86_ECX
, X86_EFLAGS
);
801 if ((dev
= findPci(pInt
, X86_EBX
)) != NULL
) {
802 pci_device_cfg_write_u8(dev
, X86_CL
, X86_DI
);
803 X86_EAX
= X86_AL
| (SUCCESSFUL
<< 8);
804 X86_EFLAGS
&= ~((unsigned long) 0x01); /* clear carry flag */
807 X86_EAX
= X86_AL
| (BAD_REGISTER_NUMBER
<< 8);
808 X86_EFLAGS
|= ((unsigned long) 0x01); /* set carry flag */
811 ErrorF("ax=0x%x flags=0x%x\n", X86_EAX
, X86_EFLAGS
);
815 if ((dev
= findPci(pInt
, X86_EBX
)) != NULL
) {
816 pci_device_cfg_write_u16(dev
, X86_CX
, X86_DI
);
817 X86_EAX
= X86_AL
| (SUCCESSFUL
<< 8);
818 X86_EFLAGS
&= ~((unsigned long) 0x01); /* clear carry flag */
821 X86_EAX
= X86_AL
| (BAD_REGISTER_NUMBER
<< 8);
822 X86_EFLAGS
|= ((unsigned long) 0x01); /* set carry flag */
825 ErrorF("ax=0x%x flags=0x%x\n", X86_EAX
, X86_EFLAGS
);
829 if ((dev
= findPci(pInt
, X86_EBX
)) != NULL
) {
830 pci_device_cfg_write_u32(dev
, X86_ECX
, X86_DI
);
831 X86_EAX
= X86_AL
| (SUCCESSFUL
<< 8);
832 X86_EFLAGS
&= ~((unsigned long) 0x01); /* clear carry flag */
835 X86_EAX
= X86_AL
| (BAD_REGISTER_NUMBER
<< 8);
836 X86_EFLAGS
|= ((unsigned long) 0x01); /* set carry flag */
839 ErrorF("ax=0x%x flags=0x%x\n", X86_EAX
, X86_EFLAGS
);
843 xf86DrvMsgVerb(pInt
->pScrn
->scrnIndex
, X_NOT_IMPLEMENTED
, 2,
844 "int 0x1a subfunction\n");
845 dump_registers(pInt
);
846 if (xf86GetVerbosity() > 3)
852 static struct pci_device
*
853 findPci(xf86Int10InfoPtr pInt
, unsigned short bx
)
855 const unsigned bus
= (bx
>> 8) & 0x00FF;
856 const unsigned dev
= (bx
>> 3) & 0x001F;
857 const unsigned func
= (bx
) & 0x0007;
859 return pci_device_find_by_slot(pInt
->dev
->domain
, bus
, dev
, func
);
863 pciSlotBX(const struct pci_device
*pvp
)
865 return ((pvp
->bus
<< 8) & 0x00FF00) | (pvp
->dev
<< 3) | (pvp
->func
);
869 * handle initialization
872 intE6_handler(xf86Int10InfoPtr pInt
)
874 struct pci_device
*pvp
;
876 if ((pvp
= xf86GetPciInfoForEntity(pInt
->entityIndex
)))
877 X86_AX
= (pvp
->bus
<< 8) | (pvp
->dev
<< 3) | (pvp
->func
& 0x7);
880 X86_CS
= pInt
->BIOSseg
;
882 X86_ES
= 0; /* standard pc es */