<p>Youness Alaoui has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/23681">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">soc/intel/skylake: Generate ACPI DMAR table<br><br>The DMAR ACPI table gets added if VT-d is supported and if<br>IOMMU is enabled and properly configured.<br><br>This code was influenced by Nico Huber's implementation [1].<br><br>[1] https://review.coreboot.org/#/c/coreboot/+/21588/<br><br>Change-Id: Iea48a349d60bdd2e7d3bc74b4e1036b050d2ae71<br>Signed-off-by: Youness Alaoui <youness.alaoui@puri.sm><br>---<br>M src/soc/intel/skylake/acpi.c<br>M src/soc/intel/skylake/chip.c<br>M src/soc/intel/skylake/chip_fsp20.c<br>M src/soc/intel/skylake/include/soc/acpi.h<br>M src/soc/intel/skylake/include/soc/p2sb.h<br>M src/soc/intel/skylake/include/soc/systemagent.h<br>6 files changed, 79 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/81/23681/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/soc/intel/skylake/acpi.c b/src/soc/intel/skylake/acpi.c</span><br><span>index a0be5f5..42c7350 100644</span><br><span>--- a/src/soc/intel/skylake/acpi.c</span><br><span>+++ b/src/soc/intel/skylake/acpi.c</span><br><span>@@ -39,9 +39,11 @@</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/p2sb.h></span><br><span> #include <soc/pci_devs.h></span><br><span> #include <soc/pm.h></span><br><span> #include <soc/ramstage.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/systemagent.h></span><br><span> #include <string.h></span><br><span> #include <types.h></span><br><span> #include <vendorcode/google/chromeos/gnvs.h></span><br><span>@@ -341,6 +343,51 @@</span><br><span>      fadt->x_gpe1_blk.addrh = 0x0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static unsigned long acpi_fill_dmar(unsigned long current)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct device *const igfx_dev = dev_find_slot(0, SA_DEVFN_IGD);</span><br><span style="color: hsl(120, 100%, 40%);">+       struct device *const p2sb_dev = dev_find_slot(0, PCH_DEVFN_P2SB);</span><br><span style="color: hsl(120, 100%, 40%);">+     const u32 gfx_vtbar = MCHBAR32(IOMMU1BAR) & ~0xfff;</span><br><span style="color: hsl(120, 100%, 40%);">+       const u32 vtdpvc0_bar = MCHBAR32(IOMMU2BAR) & ~0xfff;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* iGFX has to be enabled, GFXVTBAR set and in 32-bit space. */</span><br><span style="color: hsl(120, 100%, 40%);">+       if (igfx_dev && igfx_dev->enabled &&</span><br><span style="color: hsl(120, 100%, 40%);">+               gfx_vtbar && !MCHBAR32(IOMMU1BAR + 4)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              const unsigned long tmp = current;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          current += acpi_create_dmar_drhd(current, 0, 0, gfx_vtbar);</span><br><span style="color: hsl(120, 100%, 40%);">+           current += acpi_create_dmar_drhd_ds_pci(current, 0, 2, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+            acpi_dmar_drhd_fixup(tmp, current);</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%);">+ /* General VTBAR has to be set and in 32-bit space. */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (p2sb_dev && vtdpvc0_bar && !MCHBAR32(IOMMU2BAR + 4)) {</span><br><span style="color: hsl(120, 100%, 40%);">+            const unsigned long tmp = current;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          /* P2SB may already be hidden. There's no clear rule, when. */</span><br><span style="color: hsl(120, 100%, 40%);">+            const u8 p2sb_hidden =</span><br><span style="color: hsl(120, 100%, 40%);">+                        pci_read_config8(p2sb_dev, PCH_P2SB_E0 + 1);</span><br><span style="color: hsl(120, 100%, 40%);">+          pci_write_config8(p2sb_dev, PCH_P2SB_E0 + 1, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            const u16 ibdf = pci_read_config16(p2sb_dev, PCH_P2SB_IBDF);</span><br><span style="color: hsl(120, 100%, 40%);">+          const u16 hbdf = pci_read_config16(p2sb_dev, PCH_P2SB_HBDF);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                pci_write_config8(p2sb_dev, PCH_P2SB_E0 + 1, p2sb_hidden);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          current += acpi_create_dmar_drhd(current,</span><br><span style="color: hsl(120, 100%, 40%);">+                     DRHD_INCLUDE_PCI_ALL, 0, vtdpvc0_bar);</span><br><span style="color: hsl(120, 100%, 40%);">+                current += acpi_create_dmar_drhd_ds_ioapic(current,</span><br><span style="color: hsl(120, 100%, 40%);">+                   2, ibdf >> 8, PCI_SLOT(ibdf), PCI_FUNC(ibdf));</span><br><span style="color: hsl(120, 100%, 40%);">+          current += acpi_create_dmar_drhd_ds_msi_hpet(current,</span><br><span style="color: hsl(120, 100%, 40%);">+                 0, hbdf >> 8, PCI_SLOT(hbdf), PCI_FUNC(hbdf));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                acpi_dmar_drhd_fixup(tmp, current);</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%);">+   return current;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static void generate_c_state_entries(int s0ix_enable, int max_cstate)</span><br><span> {</span><br><span> </span><br><span>@@ -566,6 +613,27 @@</span><br><span>        return acpi_align_current(current);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+unsigned long northbridge_write_acpi_tables(device_t device,</span><br><span style="color: hsl(120, 100%, 40%);">+                                         unsigned long current,</span><br><span style="color: hsl(120, 100%, 40%);">+                                        struct acpi_rsdp *rsdp)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       acpi_dmar_t *const dmar = (acpi_dmar_t *) current;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct device *const root_dev = dev_find_slot(0, SA_DEVFN_ROOT);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Create DMAR table 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%);">+            return current;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     printk(BIOS_DEBUG, "ACPI:    * DMAR\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  acpi_create_dmar(dmar, DMAR_INTR_REMAP, acpi_fill_dmar);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (dmar->header.length > sizeof(acpi_dmar_t)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                current += dmar->header.length;</span><br><span style="color: hsl(120, 100%, 40%);">+            acpi_add_table(rsdp, dmar);</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     return acpi_align_current(current);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> void southbridge_inject_dsdt(device_t device)</span><br><span> {</span><br><span>       global_nvs_t *gnvs;</span><br><span>diff --git a/src/soc/intel/skylake/chip.c b/src/soc/intel/skylake/chip.c</span><br><span>index f60c08d..f2fd9fe 100644</span><br><span>--- a/src/soc/intel/skylake/chip.c</span><br><span>+++ b/src/soc/intel/skylake/chip.c</span><br><span>@@ -49,6 +49,7 @@</span><br><span>         .scan_bus         = &pci_domain_scan_bus,</span><br><span>        .ops_pci_bus      = &pci_bus_default_ops,</span><br><span> #if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)</span><br><span style="color: hsl(120, 100%, 40%);">+      .write_acpi_tables      = &northbridge_write_acpi_tables,</span><br><span>        .acpi_name        = &soc_acpi_name,</span><br><span> #endif</span><br><span> };</span><br><span>diff --git a/src/soc/intel/skylake/chip_fsp20.c b/src/soc/intel/skylake/chip_fsp20.c</span><br><span>index 3bc66b2..abfb049 100644</span><br><span>--- a/src/soc/intel/skylake/chip_fsp20.c</span><br><span>+++ b/src/soc/intel/skylake/chip_fsp20.c</span><br><span>@@ -57,6 +57,7 @@</span><br><span>     .scan_bus         = &pci_domain_scan_bus,</span><br><span>        .ops_pci_bus      = &pci_bus_default_ops,</span><br><span> #if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)</span><br><span style="color: hsl(120, 100%, 40%);">+      .write_acpi_tables      = &northbridge_write_acpi_tables,</span><br><span>        .acpi_name        = &soc_acpi_name,</span><br><span> #endif</span><br><span> };</span><br><span>diff --git a/src/soc/intel/skylake/include/soc/acpi.h b/src/soc/intel/skylake/include/soc/acpi.h</span><br><span>index b0d2194..d9524e6 100644</span><br><span>--- a/src/soc/intel/skylake/include/soc/acpi.h</span><br><span>+++ b/src/soc/intel/skylake/include/soc/acpi.h</span><br><span>@@ -32,5 +32,7 @@</span><br><span> void southbridge_inject_dsdt(device_t device);</span><br><span> unsigned long southbridge_write_acpi_tables(device_t device,</span><br><span>   unsigned long current, struct acpi_rsdp *rsdp);</span><br><span style="color: hsl(120, 100%, 40%);">+unsigned long northbridge_write_acpi_tables(device_t device,</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned long current, struct acpi_rsdp *rsdp);</span><br><span> </span><br><span> #endif /* _SOC_ACPI_H_ */</span><br><span>diff --git a/src/soc/intel/skylake/include/soc/p2sb.h b/src/soc/intel/skylake/include/soc/p2sb.h</span><br><span>index d846dfc..9fb2653 100644</span><br><span>--- a/src/soc/intel/skylake/include/soc/p2sb.h</span><br><span>+++ b/src/soc/intel/skylake/include/soc/p2sb.h</span><br><span>@@ -19,6 +19,9 @@</span><br><span> #define HPTC_OFFSET                0x60</span><br><span> #define HPTC_ADDR_ENABLE_BIT    (1 << 7)</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define PCH_P2SB_IBDF               0x6C</span><br><span style="color: hsl(120, 100%, 40%);">+#define PCH_P2SB_HBDF             0x70</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #define PCH_P2SB_EPMASK0              0xB0</span><br><span> #define PCH_P2SB_EPMASK(mask_number)    (PCH_P2SB_EPMASK0 + ((mask_number) * 4))</span><br><span> </span><br><span>diff --git a/src/soc/intel/skylake/include/soc/systemagent.h b/src/soc/intel/skylake/include/soc/systemagent.h</span><br><span>index d8192a3..54ff121 100644</span><br><span>--- a/src/soc/intel/skylake/include/soc/systemagent.h</span><br><span>+++ b/src/soc/intel/skylake/include/soc/systemagent.h</span><br><span>@@ -32,9 +32,13 @@</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    0x94</span><br><span style="color: hsl(120, 100%, 40%);">+#define  VTDD             (1 << 23)</span><br><span> </span><br><span> #define BIOS_RESET_CPL           0x5da8</span><br><span> #define EDRAMBAR              0x5408</span><br><span style="color: hsl(120, 100%, 40%);">+#define IOMMU1BAR               0x5400</span><br><span style="color: hsl(120, 100%, 40%);">+#define IOMMU2BAR               0x5410</span><br><span> #define GDXCBAR                       0x5420</span><br><span> </span><br><span> #define MCH_PKG_POWER_LIMIT_LO    0x59a0</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/23681">change 23681</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/23681"/><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: Iea48a349d60bdd2e7d3bc74b4e1036b050d2ae71 </div>
<div style="display:none"> Gerrit-Change-Number: 23681 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Youness Alaoui <snifikino@gmail.com> </div>