[coreboot-gerrit] Patch set updated for coreboot: fsp_broadwell_de: Add DMAR table to ACPI

Werner Zeh (werner.zeh@siemens.com) gerrit at coreboot.org
Wed Jul 27 14:50:59 CEST 2016


Werner Zeh (werner.zeh at siemens.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15913

-gerrit

commit 06890668a164ed415f18cfbf7fe9d1b0fe7f094d
Author: Werner Zeh <werner.zeh at siemens.com>
Date:   Wed Jul 27 08:22:50 2016 +0200

    fsp_broadwell_de: Add DMAR table to ACPI
    
    Create DMAR table for Broadwell-DE SoC.
    
    TEST=Booted MC BDX1 into lubuntu15, dumped ACPI tables with acpidump and
         disassembled DMAR table using iasl. The table contents are as
         expected and the kernel loads DMAR table without errors.
    
    Change-Id: I7933ba4f5f0539a50f2ab9a5571e502c84873ec6
    Signed-off-by: Werner Zeh <werner.zeh at siemens.com>
---
 src/soc/intel/fsp_broadwell_de/acpi.c             | 97 +++++++++++++++++++++++
 src/soc/intel/fsp_broadwell_de/include/soc/acpi.h |  3 +
 src/soc/intel/fsp_broadwell_de/northcluster.c     | 18 +++--
 3 files changed, 110 insertions(+), 8 deletions(-)

diff --git a/src/soc/intel/fsp_broadwell_de/acpi.c b/src/soc/intel/fsp_broadwell_de/acpi.c
index 1e08868..3406ad2 100644
--- a/src/soc/intel/fsp_broadwell_de/acpi.c
+++ b/src/soc/intel/fsp_broadwell_de/acpi.c
@@ -312,6 +312,103 @@ void acpi_fill_in_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt)
 	header->checksum = acpi_checksum((void *) fadt, sizeof(acpi_fadt_t));
 }
 
+static unsigned long acpi_fill_dmar(unsigned long current)
+{
+	uint32_t vtbar = 0, tmp = current;
+	device_t dev = dev_find_slot(0, PCI_DEVFN(5, 0));
+	uint16_t bdf = 0, hpet_bdf[8];
+	uint8_t i = 0, j = 0;
+
+	if (!dev)
+		return current;
+
+	vtbar = pci_read_config32(dev, 0x180) & 0xffffe000;
+	if (!vtbar)
+		return current;
+
+	current += acpi_create_dmar_drhd(current,
+			DRHD_INCLUDE_PCI_ALL, 0, vtbar);
+	/* The IIO I/O APIC is fixed on PCI 00:05.4 on Broadwell-DE */
+	current += acpi_create_dmar_drhd_ds_ioapic(current,
+			9, 0, 5, 4);
+	/* Get the PCI BDF for the PCH I/O APIC */
+	dev = dev_find_slot(0, LPC_DEV_FUNC);
+	bdf = pci_read_config16(dev, 0x6c);
+	current += acpi_create_dmar_drhd_ds_ioapic(current,
+			8, (bdf >> 8), PCI_SLOT(bdf), PCI_FUNC(bdf));
+
+	/*
+	 * Check if there are different PCI paths for the 8 HPET timers
+	 * and add every different PCI path as a separate HPET entry.
+	 * Although the DMAR specification talks about HPET block for this
+	 * entry, it is possible to assign a unique PCI BDF to every single
+	 * timer within a HPET block which will result in different source
+	 * IDs reported by a generated MSI.
+	 * In default configuration every single timer will have the same
+	 * PCI BDF which will result in a single HPET entry in DMAR table.
+	 * I have checked several different systems and all of them had one
+	 * single entry for HPET in DMAR.
+	 */
+	memset(hpet_bdf, 0, sizeof(hpet_bdf));
+	/* Get all unique HPET paths. */
+	for (i = 0; i < 8; i++) {
+		bdf = pci_read_config16(dev, 0x70 + (i * 2));
+		for (j = 0; j < ARRAY_SIZE(hpet_bdf); j++) {
+			if (hpet_bdf[j] == bdf)
+				break;
+		}
+		if (j == ARRAY_SIZE(hpet_bdf))
+			hpet_bdf[i] = bdf;
+	}
+	/* Create one HPET entry in DMAR for every unique HPET PCI path. */
+	for (i = 0; i < 8; i++) {
+		if (hpet_bdf[i])
+			current += acpi_create_dmar_drhd_ds_msi_hpet(current,
+				0, (hpet_bdf[i] >> 8), PCI_SLOT(hpet_bdf[i]),
+				PCI_FUNC(hpet_bdf[i]));
+	}
+	acpi_dmar_drhd_fixup(tmp, current);
+
+	/* Create Root Port ATS capability */
+	tmp = current;
+	current += acpi_create_dmar_atsr(current, 0, 0);
+	/* Add one entry to ATSR for each PCI root port */
+	dev = all_devices;
+	do {
+		dev = dev_find_class(PCI_CLASS_BRIDGE_PCI << 8, dev);
+		if (dev && dev->bus->secondary == 0 &&
+		    PCI_SLOT(dev->path.pci.devfn) <= 3)
+			current += acpi_create_dmar_drhd_ds_pci_br(current,
+					dev->bus->secondary,
+					PCI_SLOT(dev->path.pci.devfn),
+					PCI_FUNC(dev->path.pci.devfn));
+	} while (dev);
+	acpi_dmar_atsr_fixup(tmp, current);
+
+	return current;
+}
+
+unsigned long northcluster_write_acpi_tables(struct device *const dev,
+					     unsigned long current,
+					     struct acpi_rsdp *const rsdp)
+{
+	acpi_dmar_t *const dmar = (acpi_dmar_t *)current;
+	device_t vtdev = dev_find_slot(0, PCI_DEVFN(5, 0));
+
+	/* Create DMAR table only if virtualization is enabled */
+	if (!(pci_read_config32(vtdev, 0x180) & 0x01))
+		return current;
+
+	printk(BIOS_DEBUG, "ACPI:    * DMAR\n");
+	acpi_create_dmar(dmar, DMAR_INTR_REMAP, acpi_fill_dmar);
+	current += dmar->header.length;
+	current = acpi_align_current(current);
+	acpi_add_table(rsdp, dmar);
+	current = acpi_align_current(current);
+
+	return current;
+}
+
 static int calculate_power(int tdp, int p1_ratio, int ratio)
 {
 	u32 m;
diff --git a/src/soc/intel/fsp_broadwell_de/include/soc/acpi.h b/src/soc/intel/fsp_broadwell_de/include/soc/acpi.h
index f717d15..8693041 100644
--- a/src/soc/intel/fsp_broadwell_de/include/soc/acpi.h
+++ b/src/soc/intel/fsp_broadwell_de/include/soc/acpi.h
@@ -23,5 +23,8 @@ void acpi_create_intel_hpet(acpi_hpet_t *hpet);
 void acpi_fill_in_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt);
 unsigned long acpi_madt_irq_overrides(unsigned long current);
 uint16_t get_pmbase(void);
+unsigned long northcluster_write_acpi_tables(struct device *const dev,
+					     unsigned long current,
+					     struct acpi_rsdp *const rsdp);
 
 #endif /* _SOC_ACPI_H_ */
diff --git a/src/soc/intel/fsp_broadwell_de/northcluster.c b/src/soc/intel/fsp_broadwell_de/northcluster.c
index 307137b..fcaccd1 100644
--- a/src/soc/intel/fsp_broadwell_de/northcluster.c
+++ b/src/soc/intel/fsp_broadwell_de/northcluster.c
@@ -24,6 +24,7 @@
 #include <soc/iomap.h>
 #include <soc/pci_devs.h>
 #include <soc/ramstage.h>
+#include <soc/acpi.h>
 
 static const int legacy_hole_base_k = 0xa0000 / 1024;
 static const int legacy_hole_size_k = 384;
@@ -133,14 +134,15 @@ static void nc_enable(device_t dev)
 }
 
 static struct device_operations nc_ops = {
-	.read_resources   = nc_read_resources,
+	.read_resources           = nc_read_resources,
 	.acpi_fill_ssdt_generator = generate_cpu_entries,
-	.set_resources    = pci_dev_set_resources,
-	.enable_resources = pci_dev_enable_resources,
-	.init             = NULL,
-	.enable           = &nc_enable,
-	.scan_bus         = 0,
-	.ops_pci          = &soc_pci_ops,
+	.write_acpi_tables        = northcluster_write_acpi_tables,
+	.set_resources            = pci_dev_set_resources,
+	.enable_resources         = pci_dev_enable_resources,
+	.init                     = NULL,
+	.enable                   = &nc_enable,
+	.scan_bus                 = 0,
+	.ops_pci                  = &soc_pci_ops,
 };
 
 static const struct pci_driver nc_driver __pci_driver = {
@@ -153,4 +155,4 @@ static const struct pci_driver nc_driver_es2 __pci_driver = {
 	.ops    = &nc_ops,
 	.vendor = PCI_VENDOR_ID_INTEL,
 	.device = SOC_DEVID_ES2,
-};
\ No newline at end of file
+};



More information about the coreboot-gerrit mailing list