diff --git a/sys/dev/pci/vga_pci.c b/sys/dev/pci/vga_pci.c index d7ff20f..ab8823a 100644 --- a/sys/dev/pci/vga_pci.c +++ b/sys/dev/pci/vga_pci.c @@ -156,12 +156,49 @@ vga_pci_unmap_bios(device_t dev, void *bios) vr->vr_res); } +static void +vga_pci_check_if_boot_display(device_t dev) +{ + device_t pcib; + uint16_t config; + + if (vga_pci_default_unit >= 0) + return; + + /* + * The primary video card used as a boot display must have the + * "I/O" and "Memory Address Space Decoding" bits set in its + * Command register. + * + * Furthermore, if the card is attached to a bridge, instead of + * the root PCI bus, the bridge must have the "VGA Enable" bit + * set in its Control register. + */ + + pcib = device_get_parent(device_get_parent(dev)); + if (device_get_devclass(device_get_parent(pcib)) == + devclass_find("pci")) { + /* + * The parent bridge is a PCI-to-PCI bridge: check the + * value of the "VGA Enable" bit. + */ + config = pci_read_config(pcib, PCIR_BRIDGECTL_1, 2); + if ((config & PCIB_BCR_VGA_ENABLE) == 0) + return; + } + + config = pci_read_config(dev, PCIR_COMMAND, 2); + if ((config & (PCIM_CMD_PORTEN | PCIM_CMD_MEMEN)) == 0) + return; + + vga_pci_default_unit = device_get_unit(dev); + device_printf(dev, "Boot video device\n"); +} + static int vga_pci_probe(device_t dev) { - device_t bdev; int unit; - uint16_t bctl; switch (pci_get_class(dev)) { case PCIC_DISPLAY: @@ -175,11 +212,9 @@ vga_pci_probe(device_t dev) } /* Probe default display. */ + vga_pci_check_if_boot_display(dev); + unit = device_get_unit(dev); - bdev = device_get_parent(device_get_parent(dev)); - bctl = pci_read_config(bdev, PCIR_BRIDGECTL_1, 2); - if (vga_pci_default_unit < 0 && (bctl & PCIB_BCR_VGA_ENABLE) != 0) - vga_pci_default_unit = unit; if (vga_pci_default_unit == unit) device_set_flags(dev, 1);