<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>