As QEMU gains PCI bridge and PCIe root port support, we won't always find the VGA device on the root bus. We therefore need to add support to find and enable a VGA device and the path to it through the VGA Enable support in the PCI bridge control register.
Signed-off-by: Alex Williamson alex.williamson@redhat.com --- src/optionroms.c | 2 +- src/pciinit.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/util.h | 1 + 3 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/src/optionroms.c b/src/optionroms.c index caa2151..ac92613 100644 --- a/src/optionroms.c +++ b/src/optionroms.c @@ -213,7 +213,7 @@ run_file_roms(const char *prefix, int isvga, u64 *sources) ****************************************************************/
// Verify device is a vga device with legacy address decoding enabled. -static int +int is_pci_vga(struct pci_device *pci) { if (pci->class != PCI_CLASS_DISPLAY_VGA) diff --git a/src/pciinit.c b/src/pciinit.c index ce0a4cc..eb49a76 100644 --- a/src/pciinit.c +++ b/src/pciinit.c @@ -316,6 +316,49 @@ static void pci_bios_init_devices(void) } }
+static void pci_enable_default_vga(void) +{ + struct pci_device *pci; + + foreachpci(pci) { + if (is_pci_vga(pci)) { + dprintf(1, "PCI: Using %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)); + return; + } + } + + pci = pci_find_class(PCI_CLASS_DISPLAY_VGA); + if (!pci) { + dprintf(1, "PCI: No VGA devices found\n"); + return; + } + + dprintf(1, "PCI: Enabling %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); + + while (pci->parent) { + pci = pci->parent; + + dprintf(1, "PCI: Setting VGA enable on 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); + } +}
/**************************************************************** * Platform device initialization @@ -804,4 +847,6 @@ pci_setup(void) pci_bios_init_devices();
free(busses); + + pci_enable_default_vga(); } diff --git a/src/util.h b/src/util.h index 306a8bf..e1df295 100644 --- a/src/util.h +++ b/src/util.h @@ -343,6 +343,7 @@ void vgahook_setup(struct pci_device *pci);
// optionroms.c void call_bcv(u16 seg, u16 ip); +int is_pci_vga(struct pci_device *pci); void optionrom_setup(void); void vgarom_setup(void); void s3_resume_vga(void);