The issue is that at the amdk8 northbridge, we need to know bus/dev/fn for the hardware so we can set up the VGA_EN bit in the right PCIIO pair as well as an MMIO entry for it. It's not enough to just set a bit in the bridge on the K8 -- you have to set up routing to the right Hypertransport bus. You have to know where the device is.
By far the easiest way to do this is to add a simple structure member to the bus structure: struct device *vgadev;
so we have: struct bus { device_t dev; /* This bridge device */ device_t children; /* devices behind this bridge */ unsigned bridge_ctrl; /* Bridge control register */ /* NEW */ struct device *vgadev; /* if bridge_ctl has * PCI_CB_BRIDGE_CTL_VGA set, * this contains pointer to * the device. */ /* END NEW */ unsigned char link; /* The index of this link */ unsigned char secondary; /* secondary bus number */ unsigned char subordinate; /* max subordinate bus number */ unsigned char cap; /* PCi capability offset */ };
Setting vgadev is then trivial in the allocate_vga_resource since in that function you already have a pointer to the vga device; or just set the pointer. Either way, when you are at a bridge and know that the bridge has vga on the bus somewhere, you can easily get the info you need to set up the bridge if it is a complex bridge like the K8.
while(bus) { bus->bridge_ctrl |= PCI_BRIDGE_CTL_VGA; /* NEW */ bus->vgadev = vga; /* END NEW */ bus = (bus == bus->dev->bus)? 0 : bus->dev->bus; }
Unless there is a huge problem with this I will try to get it done tomorrow. It's a new structure member and one line of code and we're on the air.
It is not totally general but ... VGA is "special". As in, really ugly.
ron