<p>Matt DeVillier has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/23820">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">soc/intel/broadwell: Enable VT-d and X2APIC<br><br>We use the usual static addresses 0xfed90000/0xfed91000 for the GFX<br>IOMMU and the general IOMMU respectively. These addresses have to be<br>configured in MCHBAR registers and reserved from the OS.<br><br>Change-Id: I7afcce0da028a160174db2cf6b4b6735bcd59165<br>Signed-off-by: Matt DeVillier <matt.devillier@gmail.com><br>---<br>M src/soc/intel/broadwell/include/soc/iomap.h<br>M src/soc/intel/broadwell/include/soc/pci_devs.h<br>M src/soc/intel/broadwell/include/soc/systemagent.h<br>M src/soc/intel/broadwell/lpc.c<br>M src/soc/intel/broadwell/romstage/systemagent.c<br>M src/soc/intel/broadwell/systemagent.c<br>6 files changed, 105 insertions(+), 3 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/23820/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/soc/intel/broadwell/include/soc/iomap.h b/src/soc/intel/broadwell/include/soc/iomap.h</span><br><span>index fe8e78b..3afd653 100644</span><br><span>--- a/src/soc/intel/broadwell/include/soc/iomap.h</span><br><span>+++ b/src/soc/intel/broadwell/include/soc/iomap.h</span><br><span>@@ -39,6 +39,12 @@</span><br><span> </span><br><span> #define HPET_BASE_ADDRESS 0xfed00000</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define GFXVT_BASE_ADDRESS 0xfed90000</span><br><span style="color: hsl(120, 100%, 40%);">+#define GFXVT_BASE_SIZE 0x1000</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define VTVC0_BASE_ADDRESS 0xfed91000</span><br><span style="color: hsl(120, 100%, 40%);">+#define VTVC0_BASE_SIZE 0x1000</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #define ACPI_BASE_ADDRESS 0x1000</span><br><span> #define ACPI_BASE_SIZE 0x100</span><br><span> </span><br><span>diff --git a/src/soc/intel/broadwell/include/soc/pci_devs.h b/src/soc/intel/broadwell/include/soc/pci_devs.h</span><br><span>index 59c64ce..6fb1562 100644</span><br><span>--- a/src/soc/intel/broadwell/include/soc/pci_devs.h</span><br><span>+++ b/src/soc/intel/broadwell/include/soc/pci_devs.h</span><br><span>@@ -112,4 +112,12 @@</span><br><span> #define PCH_DEV_SATA2 _PCH_DEV(LPC, 5)</span><br><span> #define PCH_DEV_THERMAL _PCH_DEV(LPC, 6)</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define PCH_IOAPIC_PCI_BUS 250</span><br><span style="color: hsl(120, 100%, 40%);">+#define PCH_IOAPIC_PCI_SLOT 31</span><br><span style="color: hsl(120, 100%, 40%);">+#define PCH_HPET_PCI_BUS 250</span><br><span style="color: hsl(120, 100%, 40%);">+#define PCH_HPET_PCI_SLOT 15</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define LPC_IBDF 0x6C /* I/O APIC bus/dev/fn */</span><br><span style="color: hsl(120, 100%, 40%);">+#define LPC_HnBDF(n) (0x70 + n * 2) /* HPET n bus/dev/fn */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #endif</span><br><span>diff --git a/src/soc/intel/broadwell/include/soc/systemagent.h b/src/soc/intel/broadwell/include/soc/systemagent.h</span><br><span>index 125ba47..cf8c998 100644</span><br><span>--- a/src/soc/intel/broadwell/include/soc/systemagent.h</span><br><span>+++ b/src/soc/intel/broadwell/include/soc/systemagent.h</span><br><span>@@ -74,6 +74,8 @@</span><br><span> #define D_LCK (1 << 4)</span><br><span> #define G_SMRAME (1 << 3)</span><br><span> #define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0))</span><br><span style="color: hsl(120, 100%, 40%);">+#define CAPID0_A 0xe4</span><br><span style="color: hsl(120, 100%, 40%);">+#define VTD_DISABLE (1 << 23)</span><br><span> </span><br><span> #define MESEG_BASE 0x70 /* Management Engine Base. */</span><br><span> #define MESEG_LIMIT 0x78 /* Management Engine Limit. */</span><br><span>@@ -95,7 +97,9 @@</span><br><span> </span><br><span> #define MCHBAR_PEI_VERSION 0x5034</span><br><span> #define BIOS_RESET_CPL 0x5da8</span><br><span style="color: hsl(120, 100%, 40%);">+#define GFXVTBAR 0x5400</span><br><span> #define EDRAMBAR 0x5408</span><br><span style="color: hsl(120, 100%, 40%);">+#define VTVC0BAR 0x5410</span><br><span> #define MCH_PAIR 0x5418</span><br><span> #define GDXCBAR 0x5420</span><br><span> </span><br><span>@@ -130,4 +134,25 @@</span><br><span> /* System Agent identification */</span><br><span> u8 systemagent_revision(void);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Fixed MMIO range</span><br><span style="color: hsl(120, 100%, 40%);">+ * INDEX = Either PCI configuration space registers or MMIO offsets</span><br><span style="color: hsl(120, 100%, 40%);">+ * mapped from REG.</span><br><span style="color: hsl(120, 100%, 40%);">+ * BASE = 32 bit Address.</span><br><span style="color: hsl(120, 100%, 40%);">+ * SIZE = base length</span><br><span style="color: hsl(120, 100%, 40%);">+ * DESCRIPTION = Name of the register/offset.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+struct sa_mmio_descriptor {</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int index;</span><br><span style="color: hsl(120, 100%, 40%);">+ uintptr_t base;</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t size;</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *description;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifndef __BOOTBLOCK__</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct sa_mmio_descriptor soc_vtd_resources[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ { GFXVTBAR, GFXVT_BASE_ADDRESS, GFXVT_BASE_SIZE, "GFXVTBAR" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { VTVC0BAR, VTVC0_BASE_ADDRESS, VTVC0_BASE_SIZE, "VTVC0BAR" },</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span> #endif</span><br><span>diff --git a/src/soc/intel/broadwell/lpc.c b/src/soc/intel/broadwell/lpc.c</span><br><span>index d1c4242..8e7f4de 100644</span><br><span>--- a/src/soc/intel/broadwell/lpc.c</span><br><span>+++ b/src/soc/intel/broadwell/lpc.c</span><br><span>@@ -49,6 +49,10 @@</span><br><span> {</span><br><span> u32 reg32;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* Assign unique bus/dev/fn for I/O APIC */</span><br><span style="color: hsl(120, 100%, 40%);">+ pci_write_config16(dev, LPC_IBDF,</span><br><span style="color: hsl(120, 100%, 40%);">+ PCH_IOAPIC_PCI_BUS << 8 | PCH_IOAPIC_PCI_SLOT << 3);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> set_ioapic_id(VIO_APIC_VADDR, 0x02);</span><br><span> </span><br><span> /* affirm full set of redirection table entries ("write once") */</span><br><span>@@ -67,6 +71,16 @@</span><br><span> io_apic_write(VIO_APIC_VADDR, 0x03, 0x01);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void enable_hpet(struct device *dev)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Assign unique bus/dev/fn for each HPET */</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < 8; ++i)</span><br><span style="color: hsl(120, 100%, 40%);">+ pci_write_config16(dev, LPC_HnBDF(i),</span><br><span style="color: hsl(120, 100%, 40%);">+ PCH_HPET_PCI_BUS << 8 | PCH_HPET_PCI_SLOT << 3 | i);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* PIRQ[n]_ROUT[3:0] - PIRQ Routing Control</span><br><span> * 0x00 - 0000 = Reserved</span><br><span> * 0x01 - 0001 = Reserved</span><br><span>@@ -436,6 +450,7 @@</span><br><span> pch_pirq_init(dev);</span><br><span> setup_i8259();</span><br><span> i8259_configure_irq_trigger(9, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ enable_hpet(dev);</span><br><span> </span><br><span> /* Initialize power management */</span><br><span> pch_power_options(dev);</span><br><span>diff --git a/src/soc/intel/broadwell/romstage/systemagent.c b/src/soc/intel/broadwell/romstage/systemagent.c</span><br><span>index e7dbbc8..e83d65b 100644</span><br><span>--- a/src/soc/intel/broadwell/romstage/systemagent.c</span><br><span>+++ b/src/soc/intel/broadwell/romstage/systemagent.c</span><br><span>@@ -47,5 +47,21 @@</span><br><span> </span><br><span> void systemagent_early_init(void)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+ const bool vtd_capable =</span><br><span style="color: hsl(120, 100%, 40%);">+ !(pci_read_config32(SA_DEV_ROOT, CAPID0_A) & VTD_DISABLE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> reg_script_run_on_dev(SA_DEV_ROOT, systemagent_early_init_script);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (vtd_capable) {</span><br><span style="color: hsl(120, 100%, 40%);">+ int i;</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t count = ARRAY_SIZE(soc_vtd_resources);</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < count; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+ uintptr_t base;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int index;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ base = soc_vtd_resources[i].base;</span><br><span style="color: hsl(120, 100%, 40%);">+ index = soc_vtd_resources[i].index;</span><br><span style="color: hsl(120, 100%, 40%);">+ write32((void *)(MCH_BASE_ADDRESS + index), base | 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> }</span><br><span>diff --git a/src/soc/intel/broadwell/systemagent.c b/src/soc/intel/broadwell/systemagent.c</span><br><span>index f46f5ea..47addeb 100644</span><br><span>--- a/src/soc/intel/broadwell/systemagent.c</span><br><span>+++ b/src/soc/intel/broadwell/systemagent.c</span><br><span>@@ -127,6 +127,29 @@</span><br><span> * Add all known fixed MMIO ranges that hang off the host bridge/memory</span><br><span> * controller device.</span><br><span> */</span><br><span style="color: hsl(120, 100%, 40%);">+static void sa_add_fixed_mmio_resources(struct device *dev, int *resource_cnt,</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct sa_mmio_descriptor *sa_fixed_resources, size_t count)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int i;</span><br><span style="color: hsl(120, 100%, 40%);">+ int index = *resource_cnt;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < count; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+ uintptr_t base;</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t size;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ size = sa_fixed_resources[i].size;</span><br><span style="color: hsl(120, 100%, 40%);">+ base = sa_fixed_resources[i].base;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ mmio_resource(dev, index++, base / KiB, size / KiB);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ *resource_cnt = index;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Add all known fixed MMIO ranges that hang off the host bridge/memory</span><br><span style="color: hsl(120, 100%, 40%);">+ * controller device.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span> static void mc_add_fixed_mmio_resources(device_t dev)</span><br><span> {</span><br><span> int i;</span><br><span>@@ -271,7 +294,7 @@</span><br><span> printk(BIOS_DEBUG, "MC MAP: GGC: 0x%x\n", pci_read_config16(dev, GGC));</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void mc_add_dram_resources(device_t dev)</span><br><span style="color: hsl(120, 100%, 40%);">+static void mc_add_dram_resources(device_t dev, int *resource_cnt)</span><br><span> {</span><br><span> unsigned long base_k, size_k;</span><br><span> unsigned long touud_k;</span><br><span>@@ -327,7 +350,7 @@</span><br><span> * The resource index starts low and should not meet or exceed</span><br><span> * PCI_BASE_ADDRESS_0.</span><br><span> */</span><br><span style="color: hsl(0, 100%, 40%);">- index = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ index = *resource_cnt;</span><br><span> </span><br><span> /* 0 - > 0xa0000 */</span><br><span> base_k = 0;</span><br><span>@@ -377,14 +400,23 @@</span><br><span> </span><br><span> static void systemagent_read_resources(device_t dev)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct device *const root_dev = SA_DEV_ROOT;</span><br><span style="color: hsl(120, 100%, 40%);">+ bool soc_is_vtd_capable = root_dev &&</span><br><span style="color: hsl(120, 100%, 40%);">+ !(pci_read_config32(root_dev, CAPID0_A) & VTD_DISABLE);</span><br><span style="color: hsl(120, 100%, 40%);">+ int index = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Read standard PCI resources. */</span><br><span> pci_dev_read_resources(dev);</span><br><span> </span><br><span> /* Add all fixed MMIO resources. */</span><br><span> mc_add_fixed_mmio_resources(dev);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if (soc_is_vtd_capable)</span><br><span style="color: hsl(120, 100%, 40%);">+ sa_add_fixed_mmio_resources(dev, &index, soc_vtd_resources,</span><br><span style="color: hsl(120, 100%, 40%);">+ ARRAY_SIZE(soc_vtd_resources));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Calculate and add DRAM resources. */</span><br><span style="color: hsl(0, 100%, 40%);">- mc_add_dram_resources(dev);</span><br><span style="color: hsl(120, 100%, 40%);">+ mc_add_dram_resources(dev, &index);</span><br><span> }</span><br><span> </span><br><span> static void systemagent_init(struct device *dev)</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/23820">change 23820</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/23820"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I7afcce0da028a160174db2cf6b4b6735bcd59165 </div>
<div style="display:none"> Gerrit-Change-Number: 23820 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Matt DeVillier <matt.devillier@gmail.com> </div>