summaryrefslogtreecommitdiff
path: root/src/device/device.c
diff options
context:
space:
mode:
authorNico Huber <nico.h@gmx.de>2019-09-21 15:58:23 +0200
committerNico Huber <nico.h@gmx.de>2019-10-06 14:33:54 +0000
commit061b90507db3196a094f3dd88e183552e22f3ff2 (patch)
tree6b60a9fcbeedf19784dbc0c9aaa34796bfab4029 /src/device/device.c
parent2a468d25fc754a21bccb1268fc0898233fd5f6be (diff)
device/pci: Enable full 16-bit VGA port i/o decoding
So, the PCI to PCI bridge specification had a pitfall for us: Originally, when decoding i/o ports for legacy VGA cycles, bridges should only consider the 10 least significant bits of the port address. This means all VGA registers were aliased every 1024 ports! e.g. 0x3b0 was also decoded as 0x7b0, 0xbb0 etc. However, it seems, we never reserved the aliased ports, resulting in silent conflicts we preallocated resources. We neither use much external VGA nor many i/o ports these days, so nobody noticed. To avoid this mess, a bridge control bit (VGA16) was introduced in 2003 to enable decoding of 16-bit port addresses. As older systems seem rather safe and well tested, and newer systems should support this bit, we'll use it if possible and only warn if not. With old (AGP era) hardware one will likely encounter a warning like this: found VGA at PCI: 06:00.0 A bridge on the path doesn't support 16-bit VGA decoding! This is not generally fatal, but makes unnoticed resource conflicts more likely. Change-Id: Id7a07f069dd54331df79f605c6bcda37882a602d Signed-off-by: Nico Huber <nico.h@gmx.de> Reviewed-on: https://review.coreboot.org/c/coreboot/+/35516 Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-by: Michael Niewöhner Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/device/device.c')
-rw-r--r--src/device/device.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/src/device/device.c b/src/device/device.c
index 44d1f95f75..333f1f0f1d 100644
--- a/src/device/device.c
+++ b/src/device/device.c
@@ -759,6 +759,10 @@ static void set_vga_bridge_bits(void)
continue;
printk(BIOS_DEBUG, "found VGA at %s\n", dev_path(dev));
+ if (dev->bus->no_vga16) {
+ printk(BIOS_WARNING,
+ "A bridge on the path doesn't support 16-bit VGA decoding!");
+ }
if (dev->on_mainboard) {
vga_onboard = dev;
@@ -797,7 +801,7 @@ static void set_vga_bridge_bits(void)
while (bus) {
printk(BIOS_DEBUG, "Setting PCI_BRIDGE_CTL_VGA for bridge %s\n",
dev_path(bus->dev));
- bus->bridge_ctrl |= PCI_BRIDGE_CTL_VGA;
+ bus->bridge_ctrl |= PCI_BRIDGE_CTL_VGA | PCI_BRIDGE_CTL_VGA16;
bus = (bus == bus->dev->bus) ? 0 : bus->dev->bus;
}
}