summaryrefslogtreecommitdiff
path: root/src/northbridge/intel
diff options
context:
space:
mode:
authorMatt DeVillier <matt.devillier@gmail.com>2018-03-04 01:44:15 -0600
committerPatrick Georgi <pgeorgi@google.com>2018-03-08 19:14:17 +0000
commita51e379eaff3652dc64e23bb0d3784222a38723a (patch)
tree5296bfb357dddedc61f585f3bf36c14b351b6044 /src/northbridge/intel
parent8a6377ec24c85bc6a18eb9c57045746d2261ce1a (diff)
downloadcoreboot-a51e379eaff3652dc64e23bb0d3784222a38723a.tar.xz
nb/intel/haswell;sb/intel/lynxpoint: 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 and reserved from the OS. GFXVTBAR/VTVC0BAR policy registers set to be consistent with proprietary vendor firmwares on hardware of same platform (2 different vendor firmwares compared, found to be identical). Change-Id: Ib8f2fed9ae08491779e76f7d1ddc1bd3eed45ac7 Signed-off-by: Matt DeVillier <matt.devillier@gmail.com> Reviewed-on: https://review.coreboot.org/24983 Reviewed-by: Youness Alaoui <snifikino@gmail.com> Reviewed-by: Nico Huber <nico.h@gmx.de> Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/northbridge/intel')
-rw-r--r--src/northbridge/intel/haswell/early_init.c28
-rw-r--r--src/northbridge/intel/haswell/haswell.h18
-rw-r--r--src/northbridge/intel/haswell/northbridge.c19
3 files changed, 62 insertions, 3 deletions
diff --git a/src/northbridge/intel/haswell/early_init.c b/src/northbridge/intel/haswell/early_init.c
index a2b0f7fb88..663812a5ce 100644
--- a/src/northbridge/intel/haswell/early_init.c
+++ b/src/northbridge/intel/haswell/early_init.c
@@ -94,11 +94,39 @@ static void haswell_setup_graphics(void)
MCHBAR32(0x5418) = reg32;
}
+static void haswell_setup_iommu(void)
+{
+ const u32 capid0_a = pci_read_config32(PCI_DEV(0, 0, 0), CAPID0_A);
+
+ if (capid0_a & VTD_DISABLE)
+ return;
+
+ /* setup BARs: zeroize top 32 bits; set enable bit */
+ MCHBAR32(GFXVTBAR + 4) = GFXVT_BASE_ADDRESS >> 32;
+ MCHBAR32(GFXVTBAR) = GFXVT_BASE_ADDRESS | 1;
+ MCHBAR32(VTVC0BAR + 4) = VTVC0_BASE_ADDRESS >> 32;
+ MCHBAR32(VTVC0BAR) = VTVC0_BASE_ADDRESS | 1;
+
+ /* set L3HIT2PEND_DIS, lock GFXVTBAR policy cfg registers */
+ u32 reg32;
+ reg32 = read32((void *)(GFXVT_BASE_ADDRESS + ARCHDIS));
+ write32((void *)(GFXVT_BASE_ADDRESS + ARCHDIS),
+ reg32 | DMAR_LCKDN | L3HIT2PEND_DIS);
+ /* clear SPCAPCTRL */
+ reg32 = read32((void *)(VTVC0_BASE_ADDRESS + ARCHDIS)) & ~SPCAPCTRL;
+ /* set GLBIOTLBINV, GLBCTXTINV; lock VTVC0BAR policy cfg registers */
+ write32((void *)(VTVC0_BASE_ADDRESS + ARCHDIS),
+ reg32 | DMAR_LCKDN | GLBIOTLBINV | GLBCTXTINV);
+}
+
void haswell_early_initialization(int chipset_type)
{
/* Setup all BARs required for early PCIe and raminit */
haswell_setup_bars();
+ /* Setup IOMMU BARs */
+ haswell_setup_iommu();
+
/* Device Enable: IGD and Mini-HD Audio */
pci_write_config32(PCI_DEV(0, 0, 0), DEVEN,
DEVEN_D0EN | DEVEN_D2EN | DEVEN_D3EN);
diff --git a/src/northbridge/intel/haswell/haswell.h b/src/northbridge/intel/haswell/haswell.h
index 25d88966de..5f1530aa05 100644
--- a/src/northbridge/intel/haswell/haswell.h
+++ b/src/northbridge/intel/haswell/haswell.h
@@ -35,6 +35,12 @@
#endif
#define DEFAULT_EPBAR 0xfed19000 /* 4 KB */
+#define GFXVT_BASE_ADDRESS 0xfed90000ULL
+#define GFXVT_BASE_SIZE 0x1000
+
+#define VTVC0_BASE_ADDRESS 0xfed91000ULL
+#define VTVC0_BASE_SIZE 0x1000
+
#include <southbridge/intel/lynxpoint/pch.h>
/* Everything below this line is ignored in the DSDT */
@@ -88,6 +94,16 @@
#define SKPAD 0xdc /* Scratchpad Data */
+#define CAPID0_A 0xe4
+#define VTD_DISABLE (1 << 23)
+#define ARCHDIS 0xff0 /* DMA Remap Engine Policy Control */
+#define DMAR_LCKDN (1 << 31)
+#define SPCAPCTRL (1 << 25)
+#define L3HIT2PEND_DIS (1 << 20)
+#define PRSCAPDIS (1 << 2)
+#define GLBIOTLBINV (1 << 1)
+#define GLBCTXTINV (1 << 0)
+
/* Device 0:1.0 PCI configuration space (PCI Express) */
#define BCTRL1 0x3e /* 16bit */
@@ -107,6 +123,8 @@
#define MCHBAR32_OR(x, or) MCHBAR32(x) = (MCHBAR32(x) | (or))
#define BIOS_RESET_CPL 0x5da8 /* 8bit */
+#define GFXVTBAR 0x5400
+#define VTVC0BAR 0x5410
/* Some power MSRs are also represented in MCHBAR */
#define MCH_PKG_POWER_LIMIT_LO 0x59a0
diff --git a/src/northbridge/intel/haswell/northbridge.c b/src/northbridge/intel/haswell/northbridge.c
index f51eb35ee8..bbf1604b4c 100644
--- a/src/northbridge/intel/haswell/northbridge.c
+++ b/src/northbridge/intel/haswell/northbridge.c
@@ -290,7 +290,7 @@ static void mc_report_map_entries(device_t dev, uint64_t *values)
printk(BIOS_DEBUG, "MC MAP: GGC: 0x%x\n", pci_read_config16(dev, GGC));
}
-static void mc_add_dram_resources(device_t dev)
+static void mc_add_dram_resources(device_t dev, int *resource_cnt)
{
unsigned long base_k, size_k;
unsigned long touud_k;
@@ -332,7 +332,7 @@ static void mc_add_dram_resources(device_t dev)
* The resource index starts low and should not meet or exceed
* PCI_BASE_ADDRESS_0.
*/
- index = 0;
+ index = *resource_cnt;
/* 0 - > 0xa0000 */
base_k = 0;
@@ -380,18 +380,31 @@ static void mc_add_dram_resources(device_t dev)
CONFIG_CHROMEOS_RAMOOPS_RAM_START >> 10,
CONFIG_CHROMEOS_RAMOOPS_RAM_SIZE >> 10);
#endif
+ *resource_cnt = index;
}
static void mc_read_resources(device_t dev)
{
+ int index = 0;
+ const bool vtd_capable =
+ !(pci_read_config32(dev, CAPID0_A) & VTD_DISABLE);
+
/* Read standard PCI resources. */
pci_dev_read_resources(dev);
/* Add all fixed MMIO resources. */
mc_add_fixed_mmio_resources(dev);
+ /* Add VT-d MMIO resources if capable */
+ if (vtd_capable) {
+ mmio_resource(dev, index++, GFXVT_BASE_ADDRESS / KiB,
+ GFXVT_BASE_SIZE / KiB);
+ mmio_resource(dev, index++, VTVC0_BASE_ADDRESS / KiB,
+ VTVC0_BASE_SIZE / KiB);
+ }
+
/* Calculate and add DRAM resources. */
- mc_add_dram_resources(dev);
+ mc_add_dram_resources(dev, &index);
}
static void intel_set_subsystem(device_t dev, unsigned vendor, unsigned device)