Jonathan Zhang has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/45223 )
Change subject: soc/intel/xeon_sp/cpx: skip DRHD generation for non-PCIe stack ......................................................................
soc/intel/xeon_sp/cpx: skip DRHD generation for non-PCIe stack
Without skipping of DRHD generation for non-PCIe stack, the OS kernel detects incorrect DMRA table with following messages: [ 0.561817] Your BIOS is broken; DMAR reported at address 0!
With this fix, another issue in DMAR table makes OS kernel continuously sending out following messages and OS becomes unusable: [ 123.568748] bnxt_en 0000:67:00.0 enp103s0: Resp cmpl intr err msg: 0x51 [ 123.582337] bnxt_en 0000:67:00.0 enp103s0: hwrm_ring_free type 1 failed. rc:ffffffff err:0 [ 123.600157] DMAR: DRHD: handling fault status reg 202 [ 123.610497] DMAR: [INTR-REMAP] Request device [67:00.0] fault index 2e [fault reason 34] Present field in the IRTE entry is clear
It turns out the PCIe bridge device entries for PCIe ports in the DMAR table have incorrect dev/func values. Those values come from FSP IIO_UDS HOB. Hence a IPS ticket is filed, and we work around this FSP bug through hardcoding dev/func values.
While at this, make some code improvements such as only find IIO_UDS HOB once while generating DMAR table.
Change-Id: If31d2adf8c03bd57ef394834c03293a08dc4b21a Signed-off-by: Jonathan Zhang jonzhang@fb.com --- M src/soc/intel/xeon_sp/cpx/acpi.c 1 file changed, 28 insertions(+), 13 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/23/45223/1
diff --git a/src/soc/intel/xeon_sp/cpx/acpi.c b/src/soc/intel/xeon_sp/cpx/acpi.c index 1328257..de3fcb4 100644 --- a/src/soc/intel/xeon_sp/cpx/acpi.c +++ b/src/soc/intel/xeon_sp/cpx/acpi.c @@ -588,17 +588,20 @@ */ static int get_stack_for_port(int p) { - if (p == 0) + if (p == PORT_0) return CSTACK; else if (p >= PORT_1A && p <= PORT_1D) return PSTACK0; else if (p >= PORT_2A && p <= PORT_2D) return PSTACK1; - else //if (p >= PORT_3A && p <= PORT_3D) + else if (p >= PORT_3A && p <= PORT_3D) return PSTACK2; + else + return -1; }
-static unsigned long acpi_create_drhd(unsigned long current, int socket, int stack) +static unsigned long acpi_create_drhd(unsigned long current, int socket, + int stack, const IIO_UDS *hob) { int IoApicID[] = { // socket 0 @@ -612,12 +615,6 @@ uint32_t enum_id; unsigned long tmp = current;
- size_t hob_size; - const uint8_t fsp_hob_iio_universal_data_guid[16] = FSP_HOB_IIO_UNIVERSAL_DATA_GUID; - const IIO_UDS *hob = fsp_find_extension_hob_by_guid( - fsp_hob_iio_universal_data_guid, &hob_size); - assert(hob != NULL && hob_size != 0); - uint32_t bus = hob->PlatformData.IIO_resource[socket].StackRes[stack].BusBase; uint32_t pcie_seg = hob->PlatformData.CpuQpiInfo[socket].PcieSegment; uint32_t reg_base = @@ -625,6 +622,10 @@ printk(BIOS_SPEW, "%s socket: %d, stack: %d, bus: 0x%x, pcie_seg: 0x%x, reg_base: 0x%x\n", __func__, socket, stack, bus, pcie_seg, reg_base);
+ /* Do not generate DRHD for non-PCIe stack */ + if (reg_base == 0x0) + return current; + // Add DRHD Hardware Unit if (socket == 0 && stack == CSTACK) { printk(BIOS_DEBUG, "[Hardware Unit Definition] Flags: 0x%x, PCI Segment Number: 0x%x, " @@ -670,13 +671,27 @@ if (socket != 0 || stack != CSTACK) { IIO_RESOURCE_INSTANCE iio_resource = hob->PlatformData.IIO_resource[socket]; - for (int p = 0; p < NUMBER_PORTS_PER_SOCKET; ++p) { + for (int p = 0; p < MAX_PORTS; ++p) { if (get_stack_for_port(p) != stack) continue;
uint32_t dev = iio_resource.PcieInfo.PortInfo[p].Device; uint32_t func = iio_resource.PcieInfo.PortInfo[p].Function;
+ /* TODO: remove this workaround when the IPS ticket is resolved. */ + if (p == 1 || p == 5) + dev = 0x0; + else if (p == 2 || p == 6) + dev = 0x1; + else if (p == 3 || p == 7) + dev = 0x2; + else if (p == 4 || p == 8) + dev = 0x3; + else if (p == 9) + dev = 0x0; + + func = 0x0; + uint32_t id = pci_mmio_read_config32(PCI_DEV(bus, dev, func), PCI_VENDOR_ID); if (id == 0xffffffff) @@ -858,11 +873,11 @@
if (socket == 0) { for (int stack = 1; stack <= PSTACK2; ++stack) - current = acpi_create_drhd(current, socket, stack); - current = acpi_create_drhd(current, socket, CSTACK); + current = acpi_create_drhd(current, socket, stack, hob); + current = acpi_create_drhd(current, socket, CSTACK, hob); } else { for (int stack = 0; stack <= PSTACK2; ++stack) - current = acpi_create_drhd(current, socket, stack); + current = acpi_create_drhd(current, socket, stack, hob); } }