We currently expect to find VGA devices on the root bus but we will
also support them below bridges iff the VGA routing across the bridges
is pre-configured. This patch maintains that behavior, but also
enables SeaBIOS to enable VGA routing to the first VGA class device it
finds when there is no preconfigured device. This allows us to
support VGA devices behind root ports and bridges without special
setup from QEMU.
Signed-off-by: Alex Williamson <alex.williamson(a)redhat.com>
---
src/optionroms.c | 46 ++++++++++++++++++++++++++++++++++++++++------
1 file changed, 40 insertions(+), 6 deletions(-)
diff --git a/src/optionroms.c b/src/optionroms.c
index caa2151..1c2a714 100644
--- a/src/optionroms.c
+++ b/src/optionroms.c
@@ -439,13 +439,47 @@ vgarom_setup(void)
memset((void*)BUILD_ROM_START, 0, rom_get_max() - BUILD_ROM_START);
// Find and deploy PCI VGA rom.
- struct pci_device *pci;
+ struct pci_device *pci, *pci_vga = NULL;
+ // Search for devices already enabled
foreachpci(pci) {
- if (!is_pci_vga(pci))
- continue;
- vgahook_setup(pci);
- init_pcirom(pci, 1, NULL);
- break;
+ if (is_pci_vga(pci)) {
+ pci_vga = pci;
+ break;
+ }
+ }
+
+ // Find and enable the first VGA device
+ if (!pci_vga && (pci = pci_find_class(PCI_CLASS_DISPLAY_VGA)) != NULL) {
+ dprintf(4, "Enabling device %02x:%02x.%x for primary VGA\n",
+ pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf),
+ pci_bdf_to_fn(pci->bdf));
+
+ u16 cmd = pci_config_readw(pci->bdf, PCI_COMMAND);
+ cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
+ pci_config_writew(pci->bdf, PCI_COMMAND, cmd);
+
+ pci_vga = pci;
+
+ while (pci->parent) {
+ pci = pci->parent;
+
+ dprintf(4, "Setting VGA enable for bridge %02x:%02x.%x\n",
+ pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf),
+ pci_bdf_to_fn(pci->bdf));
+
+ u8 ctrl = pci_config_readb(pci->bdf, PCI_BRIDGE_CONTROL);
+ ctrl |= PCI_BRIDGE_CTL_VGA;
+ pci_config_writeb(pci->bdf, PCI_BRIDGE_CONTROL, ctrl);
+
+ u16 cmd = pci_config_readw(pci->bdf, PCI_COMMAND);
+ cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
+ pci_config_writew(pci->bdf, PCI_COMMAND, cmd);
+ }
+ }
+
+ if (pci_vga) {
+ vgahook_setup(pci_vga);
+ init_pcirom(pci_vga, 1, NULL);
}
// Find and deploy CBFS vga-style roms not associated with a device.