Attention is currently required from: Arthur Heymans, Christian Walter, Johnny Lin, Lean Sheng Tan, Patrick Rudolph, Tim Chu.
Shuo Liu has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/81048?usp=email )
Change subject: soc/intel/xeon_sp: Rewrite acpi_create_drhd ......................................................................
soc/intel/xeon_sp: Rewrite acpi_create_drhd
Change-Id: Idcfa899c764ffe51db5ed202ead07ad7b6868864 Signed-off-by: Shuo Liu shuo.liu@intel.com --- M src/soc/intel/xeon_sp/uncore_acpi.c 1 file changed, 91 insertions(+), 76 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/48/81048/1
diff --git a/src/soc/intel/xeon_sp/uncore_acpi.c b/src/soc/intel/xeon_sp/uncore_acpi.c index b7c6640..1ae6a1f 100644 --- a/src/soc/intel/xeon_sp/uncore_acpi.c +++ b/src/soc/intel/xeon_sp/uncore_acpi.c @@ -248,77 +248,76 @@ return (atsr_size + pci_br_size); }
-static unsigned long acpi_create_drhd(unsigned long current, int socket, - int stack, const IIO_UDS *hob) +static unsigned long acpi_create_drhd(unsigned long current, int socket, const IIO_UDS *hob) { + struct device *domain, *dev = NULL; + struct device *iommu0 = NULL; + struct resource *resource; unsigned long tmp = current; - const STACK_RES *ri = &hob->PlatformData.IIO_resource[socket].StackRes[stack]; - const uint32_t bus = ri->BusBase; - const uint32_t pcie_seg = hob->PlatformData.CpuQpiInfo[socket].PcieSegment; - const uint32_t reg_base = ri->VtdBarAddress; - 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); + int pcie_seg, stack, bus, bus_range; + uint32_t reg_base;
- /* Do not generate DRHD for non-PCIe stack */ - if (!reg_base) - return current; + while ((dev = dev_find_device(PCI_VID_INTEL, MMAP_VTD_CFG_REG_DEVID, dev))) { + /* Only add devices for the current socket */ + if (iio_pci_domain_socket_from_dev(dev) != socket) + continue;
- // Add DRHD Hardware Unit + /* See if there is a resource with the appropriate index. */ + resource = probe_resource(dev, VTD_BAR_CSR); + if (!resource) + continue; + reg_base = (uint32_t) resource->base;
- if (socket == 0 && stack == IioStack0) { - printk(BIOS_DEBUG, "[Hardware Unit Definition] Flags: 0x%x, PCI Segment Number: 0x%x, " - "Register Base Address: 0x%x\n", - DRHD_INCLUDE_PCI_ALL, pcie_seg, reg_base); - current += acpi_create_dmar_drhd(current, DRHD_INCLUDE_PCI_ALL, - pcie_seg, reg_base); - } else { + /* Leave IOMMU0 handling to the latest */ + stack = iio_pci_domain_stack_from_dev(dev); + domain = dev_get_pci_domain(dev); + if (!domain) + continue; + pcie_seg = domain_to_pcie_segment_group(domain); + bus = domain->downstream->secondary; + bus_range = domain->downstream->max_subordinate - bus; + if (socket == 0 && stack == IioStack0) { + iommu0 = dev; + continue; + } + + // Add DRHD Hardware Unit printk(BIOS_DEBUG, "[Hardware Unit Definition] Flags: 0x%x, PCI Segment Number: 0x%x, " "Register Base Address: 0x%x\n", 0, pcie_seg, reg_base); current += acpi_create_dmar_drhd(current, 0, pcie_seg, reg_base); - }
- // Add PCH IOAPIC - if (socket == 0 && stack == IioStack0) { - union p2sb_bdf ioapic_bdf = p2sb_get_ioapic_bdf(); - printk(BIOS_DEBUG, " [IOAPIC Device] Enumeration ID: 0x%x, PCI Bus Number: 0x%x, " - "PCI Path: 0x%x, 0x%x\n", get_ioapic_id(IO_APIC_ADDR), ioapic_bdf.bus, - ioapic_bdf.dev, ioapic_bdf.fn); - current += acpi_create_dmar_ds_ioapic_from_hw(current, - IO_APIC_ADDR, ioapic_bdf.bus, ioapic_bdf.dev, ioapic_bdf.fn); - } - -/* SPR has no per stack IOAPIC or CBDMA devices */ + /* SPR has no per stack IOAPIC or CBDMA devices */ #if CONFIG(SOC_INTEL_SKYLAKE_SP) || CONFIG(SOC_INTEL_COOPERLAKE_SP) - uint32_t enum_id; - // Add IOAPIC entry - enum_id = soc_get_iio_ioapicid(socket, stack); - printk(BIOS_DEBUG, " [IOAPIC Device] Enumeration ID: 0x%x, PCI Bus Number: 0x%x, " - "PCI Path: 0x%x, 0x%x\n", enum_id, bus, APIC_DEV_NUM, APIC_FUNC_NUM); - current += acpi_create_dmar_ds_ioapic(current, enum_id, bus, - APIC_DEV_NUM, APIC_FUNC_NUM); + uint32_t enum_id; + // Add IOAPIC entry + enum_id = soc_get_iio_ioapicid(socket, stack); + printk(BIOS_DEBUG, " [IOAPIC Device] Enumeration ID: 0x%x, PCI Bus Number: 0x%x, " + "PCI Path: 0x%x, 0x%x\n", enum_id, bus, APIC_DEV_NUM, APIC_FUNC_NUM); + current += acpi_create_dmar_ds_ioapic(current, enum_id, bus, + APIC_DEV_NUM, APIC_FUNC_NUM);
- // Add CBDMA devices for CSTACK - if (socket != 0 && stack == CSTACK) { - for (int cbdma_func_id = 0; cbdma_func_id < 8; ++cbdma_func_id) { - printk(BIOS_DEBUG, " [PCI Endpoint Device] Enumeration ID: 0x%x, " - "PCI Bus Number: 0x%x, PCI Path: 0x%x, 0x%x\n", - 0, bus, CBDMA_DEV_NUM, cbdma_func_id); - current += acpi_create_dmar_ds_pci(current, - bus, CBDMA_DEV_NUM, cbdma_func_id); + // Add CBDMA devices for CSTACK + if (socket != 0 && stack == CSTACK) { + for (int cbdma_func_id = 0; cbdma_func_id < 8; ++cbdma_func_id) { + printk(BIOS_DEBUG, " [PCI Endpoint Device] Enumeration ID: 0x%x, " + "PCI Bus Number: 0x%x, PCI Path: 0x%x, 0x%x\n", + 0, bus, CBDMA_DEV_NUM, cbdma_func_id); + current += acpi_create_dmar_ds_pci(current, + bus, CBDMA_DEV_NUM, cbdma_func_id); + } } - } #endif
- // Add PCIe Ports - if (socket != 0 || stack != IioStack0) { - struct device *dev = pcidev_path_on_bus(bus, PCI_DEVFN(0, 0)); - while (dev) { - if ((dev->hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) + // Add PCIe Ports + struct device *dev1; + dev1 = pcidev_path_on_bus(bus, PCI_DEVFN(0, 0)); + while (dev1) { + if ((dev1->hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) current += acpi_create_dmar_ds_pci_br_for_port( - current, dev, pcie_seg, false, NULL); + current, dev1, pcie_seg, false, NULL);
- dev = dev->sibling; + dev1 = dev1->sibling; }
#if CONFIG(SOC_INTEL_SKYLAKE_SP) || CONFIG(SOC_INTEL_COOPERLAKE_SP) @@ -332,32 +331,49 @@ bus, VMD_DEV_NUM, VMD_FUNC_NUM); } #endif - }
- // Add IOAT End Points (with memory resources. We don't report every End Point device.) - if (CONFIG(HAVE_IOAT_DOMAINS) && is_ioat_iio_stack_res(ri)) { - for (int b = ri->BusBase; b <= ri->BusLimit; ++b) { - struct device *dev = pcidev_path_on_bus(b, PCI_DEVFN(0, 0)); - while (dev) { - /* This may also require a check for IORESOURCE_PREFETCH, - * but that would not include the FPU (4942/0) */ - if ((dev->resource_list->flags & - (IORESOURCE_MEM | IORESOURCE_PCI64 | IORESOURCE_ASSIGNED)) == - (IORESOURCE_MEM | IORESOURCE_PCI64 | IORESOURCE_ASSIGNED)) { - const uint32_t d = PCI_SLOT(dev->path.pci.devfn); - const uint32_t f = PCI_FUNC(dev->path.pci.devfn); - printk(BIOS_DEBUG, " [PCIE Endpoint Device] " - "Enumeration ID: 0x%x, PCI Bus Number: 0x%x, " - " PCI Path: 0x%x, 0x%x\n", 0, b, d, f); - current += acpi_create_dmar_ds_pci(current, b, d, f); + // Add IOAT End Points (with memory resources. We don't report every End Point device.) + if (CONFIG(HAVE_IOAT_DOMAINS) && is_dev_on_ioat_domain(domain)) { + for (int b = bus; b <= bus + bus_range; ++b) { + struct device *dev2; + dev2 = pcidev_path_on_bus(b, PCI_DEVFN(0, 0)); + while (dev1) { + /* This may also require a check for IORESOURCE_PREFETCH, + * but that would not include the FPU (4942/0) */ + if ((dev2->resource_list->flags & + (IORESOURCE_MEM | IORESOURCE_PCI64 | IORESOURCE_ASSIGNED)) == + (IORESOURCE_MEM | IORESOURCE_PCI64 | IORESOURCE_ASSIGNED)) { + const uint32_t d = PCI_SLOT(dev2->path.pci.devfn); + const uint32_t f = PCI_FUNC(dev2->path.pci.devfn); + printk(BIOS_DEBUG, " [PCIE Endpoint Device] " + "Enumeration ID: 0x%x, PCI Bus Number: 0x%x, " + " PCI Path: 0x%x, 0x%x\n", 0, b, d, f); + current += acpi_create_dmar_ds_pci(current, b, d, f); + } + dev2 = dev2->sibling; } - dev = dev->sibling; } } + }
- // Add HPET - if (socket == 0 && stack == IioStack0) { + /* Handle IOMMU0 */ + if (iommu0) { + // Add DRHD Hardware Unit + printk(BIOS_DEBUG, "[Hardware Unit Definition] Flags: 0x%x, PCI Segment Number: 0x%x, " + "Register Base Address: 0x%x\n", + DRHD_INCLUDE_PCI_ALL, pcie_seg, reg_base); + current += acpi_create_dmar_drhd(current, DRHD_INCLUDE_PCI_ALL, + pcie_seg, reg_base); + + // Add PCH IOAPIC + union p2sb_bdf ioapic_bdf = p2sb_get_ioapic_bdf(); + printk(BIOS_DEBUG, " [IOAPIC Device] Enumeration ID: 0x%x, PCI Bus Number: 0x%x, " + "PCI Path: 0x%x, 0x%x\n", get_ioapic_id(IO_APIC_ADDR), ioapic_bdf.bus, + ioapic_bdf.dev, ioapic_bdf.fn); + current += acpi_create_dmar_ds_ioapic_from_hw(current, + IO_APIC_ADDR, ioapic_bdf.bus, ioapic_bdf.dev, ioapic_bdf.fn); + uint16_t hpet_capid = read16p(HPET_BASE_ADDRESS); uint16_t num_hpets = (hpet_capid >> 0x08) & 0x1F; // Bits [8:12] has hpet count printk(BIOS_SPEW, "%s hpet_capid: 0x%x, num_hpets: 0x%x\n", @@ -544,8 +560,7 @@ for (int socket = (CONFIG_MAX_SOCKET - 1); socket >= 0; --socket) { if (!soc_cpu_is_enabled(socket)) continue; - for (int stack = (MAX_LOGIC_IIO_STACK - 1); stack >= 0; --stack) - current = acpi_create_drhd(current, socket, stack, hob); + current = acpi_create_drhd(current, socket, hob); }
// RMRR