heads/patches/coreboot-4.7/0004-soc-intel-skylake-Generate-ACPI-DMAR-table.patch
Youness Alaoui 8bf187b50a
Add patches to coreboot to support Librem 13 v2 with TPM
Add a new series of patches which add measurement support for skylake,
add IOMMU for skylake, fix TPM support, and add support for TPM for
the Librem 13v2 and Librem 15v3 hardware.
2018-03-14 16:27:25 -04:00

155 lines
5.2 KiB
Diff

From 65b3bf5a7d211f7e1e37d73d0b59ed053dff85a8 Mon Sep 17 00:00:00 2001
From: Nico Huber <nico.h@gmx.de>
Date: Mon, 18 Sep 2017 20:03:46 +0200
Subject: [PATCH 4/9] soc/intel/skylake: Generate ACPI DMAR table
If the SoC is VT-d capable, write an ACPI DMAR table. The entry for the
GFXVTBAR is only generated if the IGD is enabled.
Change-Id: I8176401dd19aee7ad09a8a145b7a3801fe5b2ae1
Signed-off-by: Nico Huber <nico.h@gmx.de>
---
src/soc/intel/skylake/acpi.c | 68 ++++++++++++++++++++++++++++++++
src/soc/intel/skylake/chip_fsp20.c | 3 +-
src/soc/intel/skylake/include/soc/acpi.h | 2 +
src/soc/intel/skylake/include/soc/p2sb.h | 3 ++
4 files changed, 75 insertions(+), 1 deletion(-)
diff --git a/src/soc/intel/skylake/acpi.c b/src/soc/intel/skylake/acpi.c
index 61360dafae..45061aba6f 100644
--- a/src/soc/intel/skylake/acpi.c
+++ b/src/soc/intel/skylake/acpi.c
@@ -34,14 +34,17 @@
#include <intelblocks/lpc_lib.h>
#include <intelblocks/sgx.h>
#include <intelblocks/uart.h>
+#include <intelblocks/systemagent.h>
#include <soc/intel/common/acpi.h>
#include <soc/acpi.h>
#include <soc/cpu.h>
#include <soc/iomap.h>
#include <soc/msr.h>
+#include <soc/p2sb.h>
#include <soc/pci_devs.h>
#include <soc/pm.h>
#include <soc/ramstage.h>
+#include <soc/systemagent.h>
#include <string.h>
#include <types.h>
#include <vendorcode/google/chromeos/gnvs.h>
@@ -539,6 +542,71 @@ void generate_cpu_entries(device_t device)
}
}
+static unsigned long acpi_fill_dmar(unsigned long current)
+{
+ struct device *const igfx_dev = dev_find_slot(0, SA_DEVFN_IGD);
+ const u32 gfx_vtbar = MCHBAR32(GFXVTBAR) & ~0xfff;
+
+ /* iGFX has to be enabled, GFXVTBAR set and in 32-bit space. */
+ if (igfx_dev && igfx_dev->enabled &&
+ gfx_vtbar && !MCHBAR32(GFXVTBAR + 4)) {
+ const unsigned long tmp = current;
+
+ current += acpi_create_dmar_drhd(current, 0, 0, gfx_vtbar);
+ current += acpi_create_dmar_drhd_ds_pci(current, 0, 2, 0);
+
+ acpi_dmar_drhd_fixup(tmp, current);
+ }
+
+ struct device *const p2sb_dev = dev_find_slot(0, PCH_DEVFN_P2SB);
+ const u32 vtvc0bar = MCHBAR32(VTVC0BAR) & ~0xfff;
+
+ /* General VTBAR has to be set and in 32-bit space. */
+ if (p2sb_dev && vtvc0bar && !MCHBAR32(VTVC0BAR + 4)) {
+ const unsigned long tmp = current;
+
+ /* P2SB may already be hidden. There's no clear rule, when. */
+ const u8 p2sb_hidden =
+ pci_read_config8(p2sb_dev, PCH_P2SB_E0 + 1);
+ pci_write_config8(p2sb_dev, PCH_P2SB_E0 + 1, 0);
+
+ const u16 ibdf = pci_read_config16(p2sb_dev, PCH_P2SB_IBDF);
+ const u16 hbdf = pci_read_config16(p2sb_dev, PCH_P2SB_HBDF);
+
+ pci_write_config8(p2sb_dev, PCH_P2SB_E0 + 1, p2sb_hidden);
+
+ current += acpi_create_dmar_drhd(current,
+ DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar);
+ current += acpi_create_dmar_drhd_ds_ioapic(current,
+ 2, ibdf >> 8, PCI_SLOT(ibdf), PCI_FUNC(ibdf));
+ current += acpi_create_dmar_drhd_ds_msi_hpet(current,
+ 0, hbdf >> 8, PCI_SLOT(hbdf), PCI_FUNC(hbdf));
+
+ acpi_dmar_drhd_fixup(tmp, current);
+ }
+
+ return current;
+}
+
+unsigned long northbridge_write_acpi_tables(struct device *const dev,
+ unsigned long current,
+ struct acpi_rsdp *const rsdp)
+{
+ acpi_dmar_t *const dmar = (acpi_dmar_t *)current;
+
+ /* Create DMAR table only if we have VT-d capability. */
+ if (!soc_is_vtd_capable())
+ 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);
+
+ return current;
+}
+
unsigned long acpi_madt_irq_overrides(unsigned long current)
{
int sci = acpi_sci_irq();
diff --git a/src/soc/intel/skylake/chip_fsp20.c b/src/soc/intel/skylake/chip_fsp20.c
index 875542c9c6..9fbc3da8dc 100644
--- a/src/soc/intel/skylake/chip_fsp20.c
+++ b/src/soc/intel/skylake/chip_fsp20.c
@@ -59,7 +59,8 @@ static struct device_operations pci_domain_ops = {
.scan_bus = &pci_domain_scan_bus,
.ops_pci_bus = &pci_bus_default_ops,
#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
- .acpi_name = &soc_acpi_name,
+ .write_acpi_tables = &northbridge_write_acpi_tables,
+ .acpi_name = &soc_acpi_name,
#endif
};
diff --git a/src/soc/intel/skylake/include/soc/acpi.h b/src/soc/intel/skylake/include/soc/acpi.h
index b0d2194612..6d492acd67 100644
--- a/src/soc/intel/skylake/include/soc/acpi.h
+++ b/src/soc/intel/skylake/include/soc/acpi.h
@@ -32,5 +32,7 @@ void acpi_mainboard_gnvs(global_nvs_t *gnvs);
void southbridge_inject_dsdt(device_t device);
unsigned long southbridge_write_acpi_tables(device_t device,
unsigned long current, struct acpi_rsdp *rsdp);
+unsigned long northbridge_write_acpi_tables(struct device *,
+ unsigned long current, struct acpi_rsdp *);
#endif /* _SOC_ACPI_H_ */
diff --git a/src/soc/intel/skylake/include/soc/p2sb.h b/src/soc/intel/skylake/include/soc/p2sb.h
index d846dfc8f5..09e73fc254 100644
--- a/src/soc/intel/skylake/include/soc/p2sb.h
+++ b/src/soc/intel/skylake/include/soc/p2sb.h
@@ -19,6 +19,9 @@
#define HPTC_OFFSET 0x60
#define HPTC_ADDR_ENABLE_BIT (1 << 7)
+#define PCH_P2SB_IBDF 0x6c
+#define PCH_P2SB_HBDF 0x70
+
#define PCH_P2SB_EPMASK0 0xB0
#define PCH_P2SB_EPMASK(mask_number) (PCH_P2SB_EPMASK0 + ((mask_number) * 4))
--
2.14.3