mirror of
https://github.com/linuxboot/heads.git
synced 2024-12-23 14:52:27 +00:00
174 lines
5.4 KiB
Diff
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
|
||
|
|