diff options
Diffstat (limited to 'sys/boot/i386/libi386/biospci.c')
-rw-r--r-- | sys/boot/i386/libi386/biospci.c | 94 |
1 files changed, 71 insertions, 23 deletions
diff --git a/sys/boot/i386/libi386/biospci.c b/sys/boot/i386/libi386/biospci.c index 5717bdc..d844b7e 100644 --- a/sys/boot/i386/libi386/biospci.c +++ b/sys/boot/i386/libi386/biospci.c @@ -112,6 +112,10 @@ static struct pci_progif progif_parallel[] = { {-1, NULL} }; +static struct pci_progif progif_firewire[] = { + {0x10, "OHCI"}, + {-1, NULL} +}; struct pci_subclass { @@ -160,7 +164,7 @@ static struct pci_subclass subclass_comms[] = { }; static struct pci_subclass subclass_serial[] = { - {0x0, "Firewire", progif_null}, + {0x0, "FireWire", progif_firewire}, {0x1, "ACCESS.bus", progif_null}, {0x2, "SSA", progif_null}, {0x3, "USB", progif_null}, @@ -199,7 +203,8 @@ struct pnphandler biospcihandler = static void biospci_enumerate(void) { - int device_index, locator, devid; + int device_index, err; + uint32_t locator, devid; struct pci_class *pc; struct pci_subclass *psc; struct pci_progif *ppi; @@ -231,34 +236,19 @@ biospci_enumerate(void) /* Scan for matches */ for (device_index = 0; ; device_index++) { - /* Look for a match */ - v86.ctl = V86_FLAGS; - v86.addr = 0x1a; - v86.eax = 0xb103; - v86.ecx = (pc->pc_class << 16) + (psc->ps_subclass << 8) + ppi->pi_code; - v86.esi = device_index; - v86int(); - /* error/end of matches */ - if ((v86.efl & 1) || (v86.eax & 0xff00)) + err = biospci_find_devclass((pc->pc_class << 16) + + (psc->ps_subclass << 8) + ppi->pi_code, + device_index, &locator); + if (err != 0) break; - /* Got something */ - locator = v86.ebx; - /* Read the device identifier from the nominated device */ - v86.ctl = V86_FLAGS; - v86.addr = 0x1a; - v86.eax = 0xb10a; - v86.ebx = locator; - v86.edi = 0x0; - v86int(); - /* error */ - if ((v86.efl & 1) || (v86.eax & 0xff00)) + err = biospci_read_config(locator, 0, 2, &devid); + if (err != 0) break; /* We have the device ID, create a PnP object and save everything */ - devid = v86.ecx; biospci_addinfo(devid, pc, psc, ppi); } } @@ -292,3 +282,61 @@ biospci_addinfo(int devid, struct pci_class *pc, struct pci_subclass *psc, struc pnp_addident(pi, desc); pnp_addinfo(pi); } + +int +biospci_find_devclass(uint32_t class, int index, uint32_t *locator) +{ + v86.ctl = V86_FLAGS; + v86.addr = 0x1a; + v86.eax = 0xb103; + v86.ecx = class; + v86.esi = index; + v86int(); + + /* error */ + if ((v86.efl & 1) || (v86.eax & 0xff00)) + return (-1); + + *locator = v86.ebx; + return (0); +} +/* + * Configuration space access methods. + * width = 0(byte), 1(word) or 2(dword). + */ +int +biospci_write_config(uint32_t locator, int offset, int width, uint32_t val) +{ + v86.ctl = V86_FLAGS; + v86.addr = 0x1a; + v86.eax = 0xb10b + width; + v86.ebx = locator; + v86.edi = offset; + v86.ecx = val; + v86int(); + + /* error */ + if ((v86.efl & 1) || (v86.eax & 0xff00)) + return (-1); + + return(0); +} + +int +biospci_read_config(uint32_t locator, int offset, int width, uint32_t *val) +{ + v86.ctl = V86_FLAGS; + v86.addr = 0x1a; + v86.eax = 0xb108 + width; + v86.ebx = locator; + v86.edi = offset; + v86int(); + + /* error */ + if ((v86.efl & 1) || (v86.eax & 0xff00)) + return (-1); + + *val = v86.ecx; + return (0); +} + |