<p>Matt DeVillier has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/24983">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">nb/intel/haswell;sb/intel/lynxpoint: 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: Ib8f2fed9ae08491779e76f7d1ddc1bd3eed45ac7<br>Signed-off-by: Matt DeVillier <matt.devillier@gmail.com><br>---<br>M src/northbridge/intel/haswell/early_init.c<br>M src/northbridge/intel/haswell/haswell.h<br>M src/northbridge/intel/haswell/northbridge.c<br>M src/southbridge/intel/lynxpoint/lpc.c<br>M src/southbridge/intel/lynxpoint/pch.h<br>5 files changed, 81 insertions(+), 5 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/83/24983/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/northbridge/intel/haswell/early_init.c b/src/northbridge/intel/haswell/early_init.c</span><br><span>index a2b0f7f..663812a 100644</span><br><span>--- a/src/northbridge/intel/haswell/early_init.c</span><br><span>+++ b/src/northbridge/intel/haswell/early_init.c</span><br><span>@@ -94,11 +94,39 @@</span><br><span>       MCHBAR32(0x5418) = reg32;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void haswell_setup_iommu(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  const u32 capid0_a = pci_read_config32(PCI_DEV(0, 0, 0), CAPID0_A);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (capid0_a & VTD_DISABLE)</span><br><span style="color: hsl(120, 100%, 40%);">+               return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* setup BARs: zeroize top 32 bits; set enable bit */</span><br><span style="color: hsl(120, 100%, 40%);">+ MCHBAR32(GFXVTBAR + 4) = GFXVT_BASE_ADDRESS >> 32;</span><br><span style="color: hsl(120, 100%, 40%);">+      MCHBAR32(GFXVTBAR) = GFXVT_BASE_ADDRESS | 1;</span><br><span style="color: hsl(120, 100%, 40%);">+  MCHBAR32(VTVC0BAR + 4) = VTVC0_BASE_ADDRESS >> 32;</span><br><span style="color: hsl(120, 100%, 40%);">+      MCHBAR32(VTVC0BAR) = VTVC0_BASE_ADDRESS | 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* set L3HIT2PEND_DIS, lock GFXVTBAR policy cfg registers */</span><br><span style="color: hsl(120, 100%, 40%);">+  u32 reg32;</span><br><span style="color: hsl(120, 100%, 40%);">+    reg32 = read32((void *)(GFXVT_BASE_ADDRESS + ARCHDIS));</span><br><span style="color: hsl(120, 100%, 40%);">+       write32((void *)(GFXVT_BASE_ADDRESS + ARCHDIS),</span><br><span style="color: hsl(120, 100%, 40%);">+                       reg32 | DMAR_LCKDN | L3HIT2PEND_DIS);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* clear SPCAPCTRL */</span><br><span style="color: hsl(120, 100%, 40%);">+ reg32 = read32((void *)(VTVC0_BASE_ADDRESS + ARCHDIS)) & ~SPCAPCTRL;</span><br><span style="color: hsl(120, 100%, 40%);">+      /* set GLBIOTLBINV, GLBCTXTINV; lock VTVC0BAR policy cfg registers */</span><br><span style="color: hsl(120, 100%, 40%);">+ write32((void *)(VTVC0_BASE_ADDRESS + ARCHDIS),</span><br><span style="color: hsl(120, 100%, 40%);">+                       reg32 | DMAR_LCKDN | GLBIOTLBINV | GLBCTXTINV);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> void haswell_early_initialization(int chipset_type)</span><br><span> {</span><br><span>     /* Setup all BARs required for early PCIe and raminit */</span><br><span>     haswell_setup_bars();</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+     /* Setup IOMMU BARs */</span><br><span style="color: hsl(120, 100%, 40%);">+        haswell_setup_iommu();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     /* Device Enable: IGD and Mini-HD Audio */</span><br><span>   pci_write_config32(PCI_DEV(0, 0, 0), DEVEN,</span><br><span>                     DEVEN_D0EN | DEVEN_D2EN | DEVEN_D3EN);</span><br><span>diff --git a/src/northbridge/intel/haswell/haswell.h b/src/northbridge/intel/haswell/haswell.h</span><br><span>index b7954e8..97ee363 100644</span><br><span>--- a/src/northbridge/intel/haswell/haswell.h</span><br><span>+++ b/src/northbridge/intel/haswell/haswell.h</span><br><span>@@ -35,6 +35,12 @@</span><br><span> #endif</span><br><span> #define DEFAULT_EPBAR              0xfed19000      /* 4 KB */</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define GFXVT_BASE_ADDRESS      0xfed90000ULL</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    0xfed91000ULL</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> #include <southbridge/intel/lynxpoint/pch.h></span><br><span> </span><br><span> /* Everything below this line is ignored in the DSDT */</span><br><span>@@ -88,6 +94,16 @@</span><br><span> </span><br><span> #define SKPAD         0xdc    /* Scratchpad Data */</span><br><span> </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 style="color: hsl(120, 100%, 40%);">+#define ARCHDIS                0xff0   /* DMA Remap Engine Policy Control */</span><br><span style="color: hsl(120, 100%, 40%);">+#define  DMAR_LCKDN      (1 << 31)</span><br><span style="color: hsl(120, 100%, 40%);">+#define  SPCAPCTRL     (1 << 25)</span><br><span style="color: hsl(120, 100%, 40%);">+#define  L3HIT2PEND_DIS        (1 << 20)</span><br><span style="color: hsl(120, 100%, 40%);">+#define  PRSCAPDIS     (1 << 2)</span><br><span style="color: hsl(120, 100%, 40%);">+#define  GLBIOTLBINV    (1 << 1)</span><br><span style="color: hsl(120, 100%, 40%);">+#define  GLBCTXTINV     (1 << 0)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Device 0:1.0 PCI configuration space (PCI Express) */</span><br><span> </span><br><span> #define BCTRL1              0x3e    /* 16bit */</span><br><span>@@ -107,6 +123,8 @@</span><br><span> #define MCHBAR32_OR(x, or) MCHBAR32(x) = (MCHBAR32(x) | (or))</span><br><span> </span><br><span> #define BIOS_RESET_CPL        0x5da8  /* 8bit */</span><br><span style="color: hsl(120, 100%, 40%);">+#define GFXVTBAR    0x5400</span><br><span style="color: hsl(120, 100%, 40%);">+#define VTVC0BAR        0x5410</span><br><span> </span><br><span> /* Some power MSRs are also represented in MCHBAR */</span><br><span> #define MCH_PKG_POWER_LIMIT_LO    0x59a0</span><br><span>diff --git a/src/northbridge/intel/haswell/northbridge.c b/src/northbridge/intel/haswell/northbridge.c</span><br><span>index 32be916..93e711d 100644</span><br><span>--- a/src/northbridge/intel/haswell/northbridge.c</span><br><span>+++ b/src/northbridge/intel/haswell/northbridge.c</span><br><span>@@ -289,7 +289,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>@@ -331,7 +331,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>@@ -379,18 +379,31 @@</span><br><span>                  CONFIG_CHROMEOS_RAMOOPS_RAM_START >> 10,</span><br><span>                       CONFIG_CHROMEOS_RAMOOPS_RAM_SIZE >> 10);</span><br><span> #endif</span><br><span style="color: hsl(120, 100%, 40%);">+      *resource_cnt = index;</span><br><span> }</span><br><span> </span><br><span> static void mc_read_resources(device_t dev)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+   int index = 0;</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(dev, CAPID0_A) & VTD_DISABLE);</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%);">+ /* Add VT-d MMIO resources if capable */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (vtd_capable) {</span><br><span style="color: hsl(120, 100%, 40%);">+            mmio_resource(dev, index++, GFXVT_BASE_ADDRESS / KiB,</span><br><span style="color: hsl(120, 100%, 40%);">+                 GFXVT_BASE_SIZE / KiB);</span><br><span style="color: hsl(120, 100%, 40%);">+               mmio_resource(dev, index++, VTVC0_BASE_ADDRESS / KiB,</span><br><span style="color: hsl(120, 100%, 40%);">+                 VTVC0_BASE_SIZE / KiB);</span><br><span style="color: hsl(120, 100%, 40%);">+       }</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 intel_set_subsystem(device_t dev, unsigned vendor, unsigned device)</span><br><span>diff --git a/src/southbridge/intel/lynxpoint/lpc.c b/src/southbridge/intel/lynxpoint/lpc.c</span><br><span>index a5c2351..03a77d9 100644</span><br><span>--- a/src/southbridge/intel/lynxpoint/lpc.c</span><br><span>+++ b/src/southbridge/intel/lynxpoint/lpc.c</span><br><span>@@ -51,6 +51,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>   /* Enable ACPI I/O range decode */</span><br><span>   pci_write_config8(dev, ACPI_CNTL, ACPI_EN);</span><br><span> </span><br><span>@@ -396,9 +400,15 @@</span><br><span>       RCBA32_OR(0x33c8, (1 << 15));</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void enable_hpet(void)</span><br><span style="color: hsl(120, 100%, 40%);">+static void enable_hpet(struct device *const dev)</span><br><span> {</span><br><span>    u32 reg32;</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> </span><br><span>         /* Move HPET to default address 0xfed00000 and enable it */</span><br><span>  reg32 = RCBA32(HPTC);</span><br><span>@@ -570,7 +580,7 @@</span><br><span>  isa_dma_init();</span><br><span> </span><br><span>  /* Initialize the High Precision Event Timers, if present. */</span><br><span style="color: hsl(0, 100%, 40%);">-   enable_hpet();</span><br><span style="color: hsl(120, 100%, 40%);">+        enable_hpet(dev);</span><br><span> </span><br><span>        setup_i8259();</span><br><span> </span><br><span>diff --git a/src/southbridge/intel/lynxpoint/pch.h b/src/southbridge/intel/lynxpoint/pch.h</span><br><span>index af9e954..f14a339 100644</span><br><span>--- a/src/southbridge/intel/lynxpoint/pch.h</span><br><span>+++ b/src/southbridge/intel/lynxpoint/pch.h</span><br><span>@@ -282,6 +282,8 @@</span><br><span> #define  LPT_LPC_EN                (1 << 2)  /* LPC_IO_DEC[9:8] */</span><br><span> #define  COMB_LPC_EN           (1 << 1)  /* LPC_IO_DEC[6:4] */</span><br><span> #define  COMA_LPC_EN           (1 << 0)  /* LPC_IO_DEC[2:0] */</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> #define LPC_GEN1_DEC          0x84 /* LPC IF Generic Decode Range 1 */</span><br><span> #define LPC_GEN2_DEC                0x88 /* LPC IF Generic Decode Range 2 */</span><br><span> #define LPC_GEN3_DEC                0x8c /* LPC IF Generic Decode Range 3 */</span><br><span>@@ -670,6 +672,11 @@</span><br><span> #define PCH_DISABLE_MEI1     (1 << 1)</span><br><span> #define PCH_ENABLE_DBDF               (1 << 0)</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> /* ICH7 PMBASE */</span><br><span> #define PM1_STS            0x00</span><br><span> #define   WAK_STS       (1 << 15)</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/24983">change 24983</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/24983"/><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: Ib8f2fed9ae08491779e76f7d1ddc1bd3eed45ac7 </div>
<div style="display:none"> Gerrit-Change-Number: 24983 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Matt DeVillier <matt.devillier@gmail.com> </div>