199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
199767f8919635c4928607450d9e0abb932109ceToomas Soome * All rights reserved.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Redistribution and use in source and binary forms, with or without
199767f8919635c4928607450d9e0abb932109ceToomas Soome * modification, are permitted provided that the following conditions
199767f8919635c4928607450d9e0abb932109ceToomas Soome * 1. Redistributions of source code must retain the above copyright
199767f8919635c4928607450d9e0abb932109ceToomas Soome * notice, this list of conditions and the following disclaimer.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * 2. Redistributions in binary form must reproduce the above copyright
199767f8919635c4928607450d9e0abb932109ceToomas Soome * notice, this list of conditions and the following disclaimer in the
199767f8919635c4928607450d9e0abb932109ceToomas Soome * documentation and/or other materials provided with the distribution.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
199767f8919635c4928607450d9e0abb932109ceToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
199767f8919635c4928607450d9e0abb932109ceToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
199767f8919635c4928607450d9e0abb932109ceToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
199767f8919635c4928607450d9e0abb932109ceToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
199767f8919635c4928607450d9e0abb932109ceToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
199767f8919635c4928607450d9e0abb932109ceToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
199767f8919635c4928607450d9e0abb932109ceToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
199767f8919635c4928607450d9e0abb932109ceToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
199767f8919635c4928607450d9e0abb932109ceToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
199767f8919635c4928607450d9e0abb932109ceToomas Soome * SUCH DAMAGE.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * PnP enumerator using the PCI BIOS.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Stupid PCI BIOS interface doesn't let you simply enumerate everything
199767f8919635c4928607450d9e0abb932109ceToomas Soome * that's there, instead you have to ask it if it has something.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * So we have to scan by class code, subclass code and sometimes programming
199767f8919635c4928607450d9e0abb932109ceToomas Soome * interface.
199767f8919635c4928607450d9e0abb932109ceToomas Soome struct pci_progif *ps_progif; /* if set, use for programming interface value(s) */
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic struct pci_subclass subclass_display[] = {
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic struct pci_subclass subclass_serial[] = {
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void biospci_enumerate(void);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void biospci_addinfo(int devid, struct pci_class *pc, struct pci_subclass *psc, struct pci_progif *ppi);
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define PCI_SIGNATURE 0x20494350 /* AKA "PCI " */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Find the PCI BIOS */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Check for OK response */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (V86_CY(v86.efl) || ((v86.eax & 0xff00) != 0) ||
199767f8919635c4928607450d9e0abb932109ceToomas Soome bcd2bin((version >> 8) & 0xf), bcd2bin(version & 0xf),
199767f8919635c4928607450d9e0abb932109ceToomas Soome (hwcap & 1) ? " config1" : "", (hwcap & 2) ? " config2" : "",
199767f8919635c4928607450d9e0abb932109ceToomas Soome sprintf(buf, "%d", bcd2bin((version >> 8) & 0xf));
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Iterate over known classes */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (pc = pci_classes; pc->pc_class >= 0; pc++) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Iterate over subclasses */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (psc = pc->pc_subclass; psc->ps_subclass >= 0; psc++) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Iterate over programming interfaces */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (ppi = psc->ps_progif; ppi->pi_code >= 0; ppi++) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Scan for matches */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Look for a match */
199767f8919635c4928607450d9e0abb932109ceToomas Soome err = biospci_find_devclass((pc->pc_class << 16)
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Read the device identifier from the nominated device */
199767f8919635c4928607450d9e0abb932109ceToomas Soome err = biospci_read_config(locator, 0, 2, &devid);
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* We have the device ID, create a PnP object and save everything */
199767f8919635c4928607450d9e0abb932109ceToomas Soomebiospci_addinfo(int devid, struct pci_class *pc, struct pci_subclass *psc, struct pci_progif *ppi)
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* build the description */
199767f8919635c4928607450d9e0abb932109ceToomas Soomebiospci_find_devclass(uint32_t class, int index, uint32_t *locator)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (-1);
199767f8919635c4928607450d9e0abb932109ceToomas Soomebiospci_find_device(uint32_t devid, int index, uint32_t *locator)
199767f8919635c4928607450d9e0abb932109ceToomas Soome v86.edx = devid & 0xffff; /* EDX - Vendor ID */
199767f8919635c4928607450d9e0abb932109ceToomas Soome v86.ecx = (devid >> 16) & 0xffff; /* ECX - Device ID */
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (-1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Configuration space access methods.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * width = 0(byte), 1(word) or 2(dword).
199767f8919635c4928607450d9e0abb932109ceToomas Soomebiospci_write_config(uint32_t locator, int offset, int width, uint32_t val)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (-1);
199767f8919635c4928607450d9e0abb932109ceToomas Soomebiospci_read_config(uint32_t locator, int offset, int width, uint32_t *val)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (-1);
199767f8919635c4928607450d9e0abb932109ceToomas Soomebiospci_locator(int8_t bus, uint8_t device, uint8_t function)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return ((bus << 8) | ((device & 0x1f) << 3) | (function & 0x7));
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Counts the number of instances of devid we have in the system, as least as
199767f8919635c4928607450d9e0abb932109ceToomas Soome * far as the PCI BIOS is able to tell.
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (i = 0; 1; i++) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome v86.edx = devid & 0xffff; /* EDX - Vendor ID */
199767f8919635c4928607450d9e0abb932109ceToomas Soome v86.ecx = (devid >> 16) & 0xffff; /* ECX - Device ID */