Patchwork pci vga: Support VGA behind bridges

login
register
mail settings
Submitter Alex Williamson
Date Feb. 28, 2013, 5:52 p.m.
Message ID <20130228175222.21912.94067.stgit@bling.home>
Download mbox | patch
Permalink /patch/224123/
State New
Headers show

Comments

Alex Williamson - Feb. 28, 2013, 5:52 p.m.
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@redhat.com>
---
 src/optionroms.c |   46 ++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 40 insertions(+), 6 deletions(-)
Kevin O'Connor - March 1, 2013, 4:03 a.m.
On Thu, Feb 28, 2013 at 10:52:49AM -0700, Alex Williamson wrote:
> 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.
[...]
> --- a/src/optionroms.c
> +++ b/src/optionroms.c
> @@ -439,13 +439,47 @@ vgarom_setup(void)

I don't think that optionroms.c is the right place for this logic.  On
coreboot, Xen, and CSM, SeaBIOS shouldn't be touching the PCI config.
It's only QEMU that would need this logic, so something like pciinit.c
is where this logic should go.

-Kevin
Alex Williamson - March 1, 2013, 4:33 p.m.
On Thu, 2013-02-28 at 23:03 -0500, Kevin O'Connor wrote:
> On Thu, Feb 28, 2013 at 10:52:49AM -0700, Alex Williamson wrote:
> > 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.
> [...]
> > --- a/src/optionroms.c
> > +++ b/src/optionroms.c
> > @@ -439,13 +439,47 @@ vgarom_setup(void)
> 
> I don't think that optionroms.c is the right place for this logic.  On
> coreboot, Xen, and CSM, SeaBIOS shouldn't be touching the PCI config.
> It's only QEMU that would need this logic, so something like pciinit.c
> is where this logic should go.

Ok, I can look at finding a spot for it in pciinit.  Note though that
there's nothing QEMU specific about this, if other platforms are already
enabling a route to a VGA device, there's no change.  If something
sneaks through without a VGA device enabled, this should generically
enable the first device.  Thanks,

Alex

Patch

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.