From 10f8da4a13750852df7e3ecc08215f98a91cf0f4 Mon Sep 17 00:00:00 2001 From: Christian Helmuth Date: Fri, 21 Oct 2022 15:00:33 +0200 Subject: [PATCH] pci_decode: fixup Intel LPSS (I2C) PCI BARs Discovered on Tigerlake (Fujitsu U7411) and Alderlake (Framework Gen12) notebook devices. Issue #5195 --- repos/os/src/app/pci_decode/main.cc | 30 +++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/repos/os/src/app/pci_decode/main.cc b/repos/os/src/app/pci_decode/main.cc index 3ab186d3f6..01d36c3aa4 100644 --- a/repos/os/src/app/pci_decode/main.cc +++ b/repos/os/src/app/pci_decode/main.cc @@ -75,6 +75,32 @@ struct Main }; +/* + * If PCI devices happen to miss complete configuration after boot, i.e., have + * a zero base address, we report a fixed address for known devices. + * platform_drv in turn, will setup the address from the report when enabling + * the device. + * + * The issue was discovered with Intel LPSS devices in Fujitsu notebooks. + * + * XXX static fixup list should be replaced by dynamic mapping of BAR + */ +static uint64_t fixup_bar_base_address(Bdf bdf, unsigned bar, uint64_t addr, size_t size) +{ + auto base_address = addr; + + /* Intel LPSS (I2C) devices - values taken from Linux boot */ + if (bdf == Bdf { 0, 0x15, 0 } && bar == 0) base_address = 0x4017000000; + if (bdf == Bdf { 0, 0x15, 1 } && bar == 0) base_address = 0x4017001000; + if (bdf == Bdf { 0, 0x15, 2 } && bar == 0) base_address = 0x4017001000; + if (bdf == Bdf { 0, 0x15, 3 } && bar == 0) base_address = 0x4017002000; + + if (addr != base_address) + log(bdf, " remap MEM BAR", bar, " ", Hex_range(addr, size), " to ", Hex(base_address)); + + return base_address; +} + /* * The bus and function parsers return either the current bus number or the * subordinate bus number (highest bus number of all of the busses that can be @@ -153,6 +179,10 @@ bus_t Main::parse_pci_function(Bdf bdf, cfg.for_each_bar([&] (uint64_t addr, uint64_t size, unsigned bar, bool pf) { + addr = fixup_bar_base_address(bdf, bar, addr, size); + if (!addr) + warning(bdf, " MEM BAR", bar, " ", Hex_range(addr, size), + " has invalid base address - consider pci-fixup in parse_pci_function()"); gen.node("io_mem", [&] { gen.attribute("pci_bar", bar);