<p>Youness Alaoui has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/23682">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">soc/intel/skylake: Add IOMMU support<br><br>Sets up the IOMMU if VT-d is supported by the chipset. Once the<br>MCHBAR and the IBDF/HBDF are set, the ACPI DMAR table should be<br>properly filled with those values.<br><br>This work is based on the IOMMU work on sandybridge [1] by Nico<br>Huber.<br><br>Tested on Purism Librem 13 v2<br><br>[1] Commits bb9469c4 and b2dae793<br><br>Change-Id: Ifadaa11340406d1da0f98813589d20118744cc6f<br>Signed-off-by: Youness Alaoui <youness.alaoui@puri.sm><br>---<br>M src/soc/intel/skylake/Makefile.inc<br>M src/soc/intel/skylake/bootblock/pch.c<br>M src/soc/intel/skylake/include/soc/iomap.h<br>A src/soc/intel/skylake/include/soc/iommu.h<br>A src/soc/intel/skylake/iommu.c<br>M src/soc/intel/skylake/romstage/systemagent.c<br>M src/soc/intel/skylake/systemagent.c<br>7 files changed, 112 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/82/23682/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/soc/intel/skylake/Makefile.inc b/src/soc/intel/skylake/Makefile.inc</span><br><span>index ef95cf7..a358f35 100644</span><br><span>--- a/src/soc/intel/skylake/Makefile.inc</span><br><span>+++ b/src/soc/intel/skylake/Makefile.inc</span><br><span>@@ -37,6 +37,7 @@</span><br><span> romstage-y += pmutil.c</span><br><span> romstage-$(CONFIG_PLATFORM_USES_FSP2_0) += reset.c</span><br><span> romstage-y += spi.c</span><br><span style="color: hsl(120, 100%, 40%);">+romstage-y += iommu.c</span><br><span> romstage-$(CONFIG_UART_DEBUG) += uart.c</span><br><span> </span><br><span> ramstage-$(CONFIG_HAVE_ACPI_TABLES) += acpi.c</span><br><span>diff --git a/src/soc/intel/skylake/bootblock/pch.c b/src/soc/intel/skylake/bootblock/pch.c</span><br><span>index 34cfaa3..0f97d1d 100644</span><br><span>--- a/src/soc/intel/skylake/bootblock/pch.c</span><br><span>+++ b/src/soc/intel/skylake/bootblock/pch.c</span><br><span>@@ -28,6 +28,7 @@</span><br><span> #include <intelblocks/smbus.h></span><br><span> #include <soc/bootblock.h></span><br><span> #include <soc/iomap.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/iommu.h></span><br><span> #include <soc/p2sb.h></span><br><span> #include <soc/pch.h></span><br><span> #include <soc/pci_devs.h></span><br><span>@@ -59,6 +60,13 @@</span><br><span>       * selected by bits 1:0</span><br><span>       */</span><br><span>  pci_write_config8(dev, HPTC_OFFSET, HPTC_ADDR_ENABLE_BIT);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Assign unique bus/dev/fn for I/O APIC and HPET */</span><br><span style="color: hsl(120, 100%, 40%);">+  pci_write_config16(dev, PCH_P2SB_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 style="color: hsl(120, 100%, 40%);">+    pci_write_config16(dev, PCH_P2SB_HBDF,</span><br><span style="color: hsl(120, 100%, 40%);">+                PCH_HPET_PCI_BUS << 8 | PCH_HPET_PCI_SLOT << 3);</span><br><span> }</span><br><span> </span><br><span> void bootblock_pch_early_init(void)</span><br><span>diff --git a/src/soc/intel/skylake/include/soc/iomap.h b/src/soc/intel/skylake/include/soc/iomap.h</span><br><span>index 0a573ac..cc38e2e 100644</span><br><span>--- a/src/soc/intel/skylake/include/soc/iomap.h</span><br><span>+++ b/src/soc/intel/skylake/include/soc/iomap.h</span><br><span>@@ -54,6 +54,10 @@</span><br><span> </span><br><span> #define HPET_BASE_ADDRESS     0xfed00000</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define IOMMU_BASE_ADDRESS1     0xfed90000ULL</span><br><span style="color: hsl(120, 100%, 40%);">+#define IOMMU_BASE_ADDRESS2      0xfed91000ULL</span><br><span style="color: hsl(120, 100%, 40%);">+#define IOMMU_BASE_SIZE          0x1000</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #define PCH_PWRM_BASE_ADDRESS       0xfe000000</span><br><span> #define PCH_PWRM_BASE_SIZE        0x10000</span><br><span> </span><br><span>diff --git a/src/soc/intel/skylake/include/soc/iommu.h b/src/soc/intel/skylake/include/soc/iommu.h</span><br><span>new file mode 100644</span><br><span>index 0000000..56df714</span><br><span>--- /dev/null</span><br><span>+++ b/src/soc/intel/skylake/include/soc/iommu.h</span><br><span>@@ -0,0 +1,30 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2018 Purism SPC</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</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%);">+#ifndef _SOC_IOMMU_H_</span><br><span style="color: hsl(120, 100%, 40%);">+#define _SOC_IOMMU_H_</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define PCH_IOAPIC_PCI_BUS  0xF0</span><br><span style="color: hsl(120, 100%, 40%);">+#define PCH_IOAPIC_PCI_SLOT 0x1F</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define PCH_HPET_PCI_BUS    0x00</span><br><span style="color: hsl(120, 100%, 40%);">+#define PCH_HPET_PCI_SLOT   0x1F</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void skylake_init_iommu(void);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span>diff --git a/src/soc/intel/skylake/iommu.c b/src/soc/intel/skylake/iommu.c</span><br><span>new file mode 100644</span><br><span>index 0000000..81028de</span><br><span>--- /dev/null</span><br><span>+++ b/src/soc/intel/skylake/iommu.c</span><br><span>@@ -0,0 +1,50 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2015 secunet Security Networks AG</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or</span><br><span style="color: hsl(120, 100%, 40%);">+ * modify it under the terms of the GNU General Public License as</span><br><span style="color: hsl(120, 100%, 40%);">+ * published by the Free Software Foundation; version 2 of</span><br><span style="color: hsl(120, 100%, 40%);">+ * the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</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%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <device/device.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <intelblocks/systemagent.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/iomap.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/iommu.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/pci_devs.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/systemagent.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void skylake_init_iommu(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        static const struct sa_mmio_descriptor iommu_fixed_mch_resources[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+                {IOMMU1BAR, IOMMU_BASE_ADDRESS1, IOMMU_BASE_SIZE, "IOMMU1BAR"},</span><br><span style="color: hsl(120, 100%, 40%);">+             {IOMMU2BAR, IOMMU_BASE_ADDRESS2, IOMMU_BASE_SIZE, "IOMMU2BAR"},</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%);">+  if (pci_read_config32(SA_DEV_ROOT, CAPID0_A) & VTDD)</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 */</span><br><span style="color: hsl(120, 100%, 40%);">+      sa_set_mch_bar(iommu_fixed_mch_resources,</span><br><span style="color: hsl(120, 100%, 40%);">+             ARRAY_SIZE(iommu_fixed_mch_resources));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* lock policies */</span><br><span style="color: hsl(120, 100%, 40%);">+   write32((void *)(IOMMU_BASE_ADDRESS1 + 0xff0), 0x80000000);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct device *const azalia = dev_find_slot(0, PCH_DEVFN_HDA);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (azalia && azalia->enabled) {</span><br><span style="color: hsl(120, 100%, 40%);">+           write32((void *)(IOMMU_BASE_ADDRESS2 + 0xff0), 0x20000000);</span><br><span style="color: hsl(120, 100%, 40%);">+           write32((void *)(IOMMU_BASE_ADDRESS2 + 0xff0), 0xa0000000);</span><br><span style="color: hsl(120, 100%, 40%);">+   } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              write32((void *)(IOMMU_BASE_ADDRESS2 + 0xff0), 0x80000000);</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/soc/intel/skylake/romstage/systemagent.c b/src/soc/intel/skylake/romstage/systemagent.c</span><br><span>index 8f2fb33..e7a2f4a 100644</span><br><span>--- a/src/soc/intel/skylake/romstage/systemagent.c</span><br><span>+++ b/src/soc/intel/skylake/romstage/systemagent.c</span><br><span>@@ -18,6 +18,7 @@</span><br><span> #include <device/device.h></span><br><span> #include <intelblocks/systemagent.h></span><br><span> #include <soc/iomap.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/iommu.h></span><br><span> #include <soc/romstage.h></span><br><span> #include <soc/systemagent.h></span><br><span> </span><br><span>@@ -34,12 +35,15 @@</span><br><span>             { EDRAMBAR, EDRAM_BASE_ADDRESS, EDRAM_BASE_SIZE, "EDRAMBAR" },</span><br><span>     };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  /* Set Fixed MMIO addresss into PCI configuration space */</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Set Fixed MMIO addresses into PCI configuration space */</span><br><span>  sa_set_pci_bar(soc_fixed_pci_resources,</span><br><span>                      ARRAY_SIZE(soc_fixed_pci_resources));</span><br><span style="color: hsl(0, 100%, 40%);">-   /* Set Fixed MMIO addresss into MCH base address */</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Set Fixed MMIO addresses into MCH base address */</span><br><span>         sa_set_mch_bar(soc_fixed_mch_resources,</span><br><span>                      ARRAY_SIZE(soc_fixed_mch_resources));</span><br><span style="color: hsl(0, 100%, 40%);">-   /* Enable PAM regisers */</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Enable PAM registers */</span><br><span>   enable_pam_region();</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Enable IOMMU. This will set the IOMMU Fixed MMIO addresses into</span><br><span style="color: hsl(120, 100%, 40%);">+     * MCH base address if device has IOMMU capabilities */</span><br><span style="color: hsl(120, 100%, 40%);">+       skylake_init_iommu();</span><br><span> }</span><br><span>diff --git a/src/soc/intel/skylake/systemagent.c b/src/soc/intel/skylake/systemagent.c</span><br><span>index 8af995d..880593d 100644</span><br><span>--- a/src/soc/intel/skylake/systemagent.c</span><br><span>+++ b/src/soc/intel/skylake/systemagent.c</span><br><span>@@ -15,6 +15,7 @@</span><br><span>  * GNU General Public License for more details.</span><br><span>  */</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <arch/io.h></span><br><span> #include <cpu/x86/msr.h></span><br><span> #include <console/console.h></span><br><span> #include <delay.h></span><br><span>@@ -23,6 +24,7 @@</span><br><span> #include <soc/cpu.h></span><br><span> #include <soc/iomap.h></span><br><span> #include <soc/msr.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/pci_devs.h></span><br><span> #include <soc/systemagent.h></span><br><span> </span><br><span> /*</span><br><span>@@ -42,9 +44,19 @@</span><br><span>          { GDXCBAR, GDXC_BASE_ADDRESS, GDXC_BASE_SIZE, "GDXCBAR" },</span><br><span>                 { EDRAMBAR, EDRAM_BASE_ADDRESS, EDRAM_BASE_SIZE, "EDRAMBAR" },</span><br><span>     };</span><br><span style="color: hsl(120, 100%, 40%);">+    static const struct sa_mmio_descriptor iommu_fixed_resources[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+            { IOMMU1BAR, IOMMU_BASE_ADDRESS1, IOMMU_BASE_SIZE, "IOMMU1" },</span><br><span style="color: hsl(120, 100%, 40%);">+              { IOMMU2BAR, IOMMU_BASE_ADDRESS2, IOMMU_BASE_SIZE, "IOMMU2" },</span><br><span style="color: hsl(120, 100%, 40%);">+      };</span><br><span style="color: hsl(120, 100%, 40%);">+    struct device *const root_dev = dev_find_slot(0, SA_DEVFN_ROOT);</span><br><span> </span><br><span>         sa_add_fixed_mmio_resources(dev, index, soc_fixed_resources,</span><br><span>                         ARRAY_SIZE(soc_fixed_resources));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Add IOMMU Fixed resources only if we have VT-d capability. */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (root_dev && !(pci_read_config32(root_dev, CAPID0_A) & VTDD))</span><br><span style="color: hsl(120, 100%, 40%);">+          sa_add_fixed_mmio_resources(dev, index, iommu_fixed_resources,</span><br><span style="color: hsl(120, 100%, 40%);">+                        ARRAY_SIZE(iommu_fixed_resources));</span><br><span> }</span><br><span> </span><br><span> /*</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/23682">change 23682</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/23682"/><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: Ifadaa11340406d1da0f98813589d20118744cc6f </div>
<div style="display:none"> Gerrit-Change-Number: 23682 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Youness Alaoui <snifikino@gmail.com> </div>