Jonathan Zhang has uploaded this change for review.

View Change

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);
}
}


To view, visit change 45223. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: If31d2adf8c03bd57ef394834c03293a08dc4b21a
Gerrit-Change-Number: 45223
Gerrit-PatchSet: 1
Gerrit-Owner: Jonathan Zhang <jonzhang@fb.com>
Gerrit-MessageType: newchange