heads/patches/coreboot-4.7/0003-soc-intel-skylake-Enable-VT-d-and-X2APIC.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

174 lines
5.4 KiB
Diff

From 403242fbaf2c3b8c12f4b1d55a581513aabf02a3 Mon Sep 17 00:00:00 2001
From: Nico Huber <nico.h@gmx.de>
Date: Tue, 19 Sep 2017 09:36:03 +0200
Subject: [PATCH 3/9] soc/intel/skylake: Enable VT-d and X2APIC
We use the usual static addresses 0xfed90000/0xfed91000 for the GFX
IOMMU and the general IOMMU respectively. These addresses have to be
configured in MCHBAR registers (maybe, who knows, the blob is undocu-
mented), advertised to FSP and reserved from the OS.
Change-Id: I77f87c385736615c127143760bbd144f97986b37
Signed-off-by: Nico Huber <nico.h@gmx.de>
---
src/soc/intel/skylake/chip_fsp20.c | 10 ++++++++++
src/soc/intel/skylake/include/soc/iomap.h | 6 ++++++
src/soc/intel/skylake/include/soc/systemagent.h | 11 +++++++++++
src/soc/intel/skylake/romstage/systemagent.c | 8 ++++++++
src/soc/intel/skylake/systemagent.c | 13 +++++++++++++
5 files changed, 48 insertions(+)
diff --git a/src/soc/intel/skylake/chip_fsp20.c b/src/soc/intel/skylake/chip_fsp20.c
index ccda3032c5..875542c9c6 100644
--- a/src/soc/intel/skylake/chip_fsp20.c
+++ b/src/soc/intel/skylake/chip_fsp20.c
@@ -30,9 +30,11 @@
#include <soc/acpi.h>
#include <soc/intel/common/vbt.h>
#include <soc/interrupt.h>
+#include <soc/iomap.h>
#include <soc/irq.h>
#include <soc/pci_devs.h>
#include <soc/ramstage.h>
+#include <soc/systemagent.h>
#include <string.h>
void soc_init_pre_device(void *chip_info)
@@ -313,6 +315,14 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd)
/* Set TccActivationOffset */
tconfig->TccActivationOffset = config->tcc_offset;
+ /* Enable VT-d and X2APIC */
+ if (soc_is_vtd_capable()) {
+ params->VtdBaseAddress[0] = GFXVT_BASE_ADDRESS;
+ params->VtdBaseAddress[1] = VTVC0_BASE_ADDRESS;
+ params->X2ApicOptOut = 0;
+ tconfig->VtdDisable = 0;
+ }
+
soc_irq_settings(params);
}
diff --git a/src/soc/intel/skylake/include/soc/iomap.h b/src/soc/intel/skylake/include/soc/iomap.h
index 0a573acb38..5f868061ec 100644
--- a/src/soc/intel/skylake/include/soc/iomap.h
+++ b/src/soc/intel/skylake/include/soc/iomap.h
@@ -52,6 +52,12 @@
#define GDXC_BASE_ADDRESS 0xfed84000
#define GDXC_BASE_SIZE 0x1000
+#define GFXVT_BASE_ADDRESS 0xfed90000
+#define GFXVT_BASE_SIZE 0x1000
+
+#define VTVC0_BASE_ADDRESS 0xfed91000
+#define VTVC0_BASE_SIZE 0x1000
+
#define HPET_BASE_ADDRESS 0xfed00000
#define PCH_PWRM_BASE_ADDRESS 0xfe000000
diff --git a/src/soc/intel/skylake/include/soc/systemagent.h b/src/soc/intel/skylake/include/soc/systemagent.h
index d8192a3e75..8e53f54b75 100644
--- a/src/soc/intel/skylake/include/soc/systemagent.h
+++ b/src/soc/intel/skylake/include/soc/systemagent.h
@@ -32,9 +32,13 @@
#define D_LCK (1 << 4)
#define G_SMRAME (1 << 3)
#define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0))
+#define CAPID0_A 0xe4
+#define VTD_DISABLE (1 << 23)
#define BIOS_RESET_CPL 0x5da8
+#define GFXVTBAR 0x5400
#define EDRAMBAR 0x5408
+#define VTVC0BAR 0x5410
#define GDXCBAR 0x5420
#define MCH_PKG_POWER_LIMIT_LO 0x59a0
@@ -42,4 +46,11 @@
#define MCH_DDR_POWER_LIMIT_LO 0x58e0
#define MCH_DDR_POWER_LIMIT_HI 0x58e4
+bool soc_is_vtd_capable(void);
+
+static const struct sa_mmio_descriptor soc_vtd_resources[] = {
+ { GFXVTBAR, GFXVT_BASE_ADDRESS, GFXVT_BASE_SIZE, "GFXVTBAR" },
+ { VTVC0BAR, VTVC0_BASE_ADDRESS, VTVC0_BASE_SIZE, "VTVC0BAR" },
+};
+
#endif
diff --git a/src/soc/intel/skylake/romstage/systemagent.c b/src/soc/intel/skylake/romstage/systemagent.c
index 8f2fb337ed..66676c1fbf 100644
--- a/src/soc/intel/skylake/romstage/systemagent.c
+++ b/src/soc/intel/skylake/romstage/systemagent.c
@@ -18,6 +18,7 @@
#include <device/device.h>
#include <intelblocks/systemagent.h>
#include <soc/iomap.h>
+#include <soc/pci_devs.h>
#include <soc/romstage.h>
#include <soc/systemagent.h>
@@ -34,12 +35,19 @@ void systemagent_early_init(void)
{ EDRAMBAR, EDRAM_BASE_ADDRESS, EDRAM_BASE_SIZE, "EDRAMBAR" },
};
+ const bool vtd_capable =
+ !(pci_read_config32(SA_DEV_ROOT, CAPID0_A) & VTD_DISABLE);
+
/* Set Fixed MMIO addresss into PCI configuration space */
sa_set_pci_bar(soc_fixed_pci_resources,
ARRAY_SIZE(soc_fixed_pci_resources));
/* Set Fixed MMIO addresss into MCH base address */
sa_set_mch_bar(soc_fixed_mch_resources,
ARRAY_SIZE(soc_fixed_mch_resources));
+ if (vtd_capable)
+ sa_set_mch_bar(soc_vtd_resources,
+ ARRAY_SIZE(soc_vtd_resources));
+
/* Enable PAM regisers */
enable_pam_region();
}
diff --git a/src/soc/intel/skylake/systemagent.c b/src/soc/intel/skylake/systemagent.c
index 8af995d133..796e7ae131 100644
--- a/src/soc/intel/skylake/systemagent.c
+++ b/src/soc/intel/skylake/systemagent.c
@@ -15,6 +15,7 @@
* GNU General Public License for more details.
*/
+#include <arch/io.h>
#include <cpu/x86/msr.h>
#include <console/console.h>
#include <delay.h>
@@ -23,8 +24,16 @@
#include <soc/cpu.h>
#include <soc/iomap.h>
#include <soc/msr.h>
+#include <soc/pci_devs.h>
#include <soc/systemagent.h>
+bool soc_is_vtd_capable(void)
+{
+ struct device *const root_dev = SA_DEV_ROOT;
+ return root_dev &&
+ !(pci_read_config32(root_dev, CAPID0_A) & VTD_DISABLE);
+}
+
/*
* SoC implementation
*
@@ -45,6 +54,10 @@ void soc_add_fixed_mmio_resources(struct device *dev, int *index)
sa_add_fixed_mmio_resources(dev, index, soc_fixed_resources,
ARRAY_SIZE(soc_fixed_resources));
+
+ if (soc_is_vtd_capable())
+ sa_add_fixed_mmio_resources(dev, index, soc_vtd_resources,
+ ARRAY_SIZE(soc_vtd_resources));
}
/*
--
2.14.3