<p>Piotr Król has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/27602">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">nb/amd/pi/00730F01: use MMIO and performance counters from AGESA<br><br>This patch contain minimal set of changes to initial IVRS implementation<br>to make it work reliably. Code in this patch was tested with Xen 4.8 and<br>Debian 4.14.y - this software stack survived 100x reboots without any<br>hang. Previously using IVRS provided by AGESA lead to 29/100 hangs.<br><br>MMIO base shall not be hard coded since this value depends on platform<br>design.<br><br>Performance counters were selected experimentally, since lack of<br>them cause 4.14.y panic:<br>[    1.064229] AMD-Vi: IOMMU performance counters supported<br>[    1.069579] BUG: unable to handle kernel paging request at ffffaffc4065c000<br>[    1.073554] IP: iommu_go_to_state+0xf8a/0x1260<br>[    1.073554] PGD 12a11f067 P4D 12a11f067 PUD 12a120067 PMD 129b69067 PTE 0<br>[    1.073554] Oops: 0000 [#1] SMP NOPTI<br>[    1.073554] Modules linked in:<br>[    1.073554] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.14.50 #13<br>[    1.073554] Hardware name: PC Engines apu2/apu2, BIOS 4.8-1174-gf12b3046f0-d2<br>[    1.073554] task: ffff8d5d69b9f040 task.stack: ffffaffc40648000<br>[    1.073554] RIP: 0010:iommu_go_to_state+0xf8a/0x1260<br>[    1.073554] RSP: 0018:ffffaffc4064be28 EFLAGS: 00010282<br>[    1.073554] RAX: ffffaffc40658000 RBX: ffff8d5d69bae000 RCX: ffffffff99e57b88<br>[    1.073554] RDX: 0000000000000000 RSI: 0000000000000092 RDI: 0000000000000246<br>[    1.073554] RBP: 0000000000000040 R08: 0000000000000001 R09: 0000000000000170<br>[    1.073554] R10: 0000000000000000 R11: ffffffff9a435e2d R12: 0000000000000000<br>[    1.073554] R13: ffffffff9a29a830 R14: 0000000000000000 R15: 0000000000000000<br>[    1.073554] FS:  0000000000000000(0000) GS:ffff8d5d6ec80000(0000) knlGS:00000<br>[    1.073554] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033<br>[    1.073554] CR2: ffffaffc4065c000 CR3: 000000010fa0a000 CR4: 00000000000406e0<br>[    1.073554] Call Trace:<br>[    1.073554]  ? set_debug_rodata+0x11/0x11<br>[    1.073554]  amd_iommu_init+0x11/0x89<br>[    1.073554]  pci_iommu_init+0x16/0x3f<br>[    1.073554]  ? e820__memblock_setup+0x60/0x60<br>[    1.073554]  do_one_initcall+0x51/0x190<br>[    1.073554]  ? set_debug_rodata+0x11/0x11<br>[    1.073554]  kernel_init_freeable+0x16b/0x1ec<br>[    1.073554]  ? rest_init+0xb0/0xb0<br>[    1.073554]  kernel_init+0xa/0xf7<br>[    1.073554]  ret_from_fork+0x22/0x40<br>[    1.073554] Code: d2 31 f6 48 89 df e8 d8 15 02 ff 85 c0 75 d1 48 8b 44 24 2<br>[    1.073554] RIP: iommu_go_to_state+0xf8a/0x1260 RSP: ffffaffc4064be28<br>[    1.073554] CR2: ffffaffc4065c000<br>[    1.073554] ---[ end trace 44588f98aa7c7c0b ]---<br>[    1.255973] Kernel panic - not syncing: Attempted to kill init! exitcode=0x09<br>[    1.255973]<br>[    1.259934] ---[ end Kernel panic - not syncing: Attempted to kill init! exi9<br><br>Possible future improvements:<br>- compare device entries with values returned by AGESA<br>- enable EFRSup (this is enabled in AGESA)<br>- try various IVHD flags (there is difference between initial<br>implementation and AGESA)<br><br>Change-Id: I7e3a3d21f295ae96962d7718b9568fc4b67eb23d<br>Signed-off-by: Piotr Król <piotr.krol@3mdeb.com><br>---<br>M src/northbridge/amd/pi/00730F01/northbridge.c<br>1 file changed, 36 insertions(+), 12 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/02/27602/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/northbridge/amd/pi/00730F01/northbridge.c b/src/northbridge/amd/pi/00730F01/northbridge.c</span><br><span>index 50d4a24..d3d7981 100644</span><br><span>--- a/src/northbridge/amd/pi/00730F01/northbridge.c</span><br><span>+++ b/src/northbridge/amd/pi/00730F01/northbridge.c</span><br><span>@@ -613,6 +613,7 @@</span><br><span> static unsigned long acpi_fill_ivrs(acpi_ivrs_t* ivrs, unsigned long current)</span><br><span> {</span><br><span>        uint8_t *p;</span><br><span style="color: hsl(120, 100%, 40%);">+   acpi_ivrs_t *ivrs_agesa;</span><br><span> </span><br><span>         device_t nb_dev = dev_find_slot(0, PCI_DEVFN(0, 0));</span><br><span>         if (!nb_dev) {</span><br><span>@@ -625,18 +626,41 @@</span><br><span>       ivrs->iv_info |= (0x30 << 8);  /* Maximum supported physical address size */</span><br><span>        ivrs->iv_info |= (0x2 << 5);   /* Guest virtual address width */</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ivrs->ivhd.type = 0x10;</span><br><span style="color: hsl(0, 100%, 40%);">-      ivrs->ivhd.flags = 0x0e;</span><br><span style="color: hsl(0, 100%, 40%);">-     ivrs->ivhd.flags |= 0x10;                                    /* Enable ATS support */</span><br><span style="color: hsl(0, 100%, 40%);">-        ivrs->ivhd.length = sizeof(struct acpi_ivrs_ivhd);</span><br><span style="color: hsl(0, 100%, 40%);">-   ivrs->ivhd.device_id = 0x2 | (nb_dev->bus->secondary << 8);      /* BDF <bus>:00.2 */</span><br><span style="color: hsl(0, 100%, 40%);">-      ivrs->ivhd.capability_offset = 0x40;                         /* Capability block 0x40 (type 0xf, "Secure device") */</span><br><span style="color: hsl(0, 100%, 40%);">-       ivrs->ivhd.iommu_base_low = 0xfeb00000;</span><br><span style="color: hsl(0, 100%, 40%);">-      ivrs->ivhd.iommu_base_high = 0x0;</span><br><span style="color: hsl(0, 100%, 40%);">-    ivrs->ivhd.pci_segment_group = 0x0;</span><br><span style="color: hsl(0, 100%, 40%);">-  ivrs->ivhd.iommu_info = 0x0;</span><br><span style="color: hsl(0, 100%, 40%);">- ivrs->ivhd.iommu_info |= (0x13 << 8);</span><br><span style="color: hsl(0, 100%, 40%);">-  ivrs->ivhd.iommu_feature_info = 0x0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* obtain IOMMU base address */</span><br><span style="color: hsl(120, 100%, 40%);">+       ivrs_agesa = agesawrapper_getlateinitptr(PICK_IVRS);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (ivrs_agesa != NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+             ivrs->ivhd.type = 0x10;</span><br><span style="color: hsl(120, 100%, 40%);">+            ivrs->ivhd.flags = 0x0e;</span><br><span style="color: hsl(120, 100%, 40%);">+           ivrs->ivhd.flags |= 0x10;                                    /* Enable ATS support */</span><br><span style="color: hsl(120, 100%, 40%);">+              ivrs->ivhd.length = sizeof(struct acpi_ivrs_ivhd);</span><br><span style="color: hsl(120, 100%, 40%);">+         ivrs->ivhd.device_id = 0x2 | (nb_dev->bus->secondary << 8);      /* BDF <bus>:00.2 */</span><br><span style="color: hsl(120, 100%, 40%);">+            ivrs->ivhd.capability_offset = 0x40;                         /* Capability block 0x40 (type 0xf, "Secure device") */</span><br><span style="color: hsl(120, 100%, 40%);">+             ivrs->ivhd.iommu_base_low = ivrs_agesa->ivhd.iommu_base_low;</span><br><span style="color: hsl(120, 100%, 40%);">+            ivrs->ivhd.iommu_base_high = ivrs_agesa->ivhd.iommu_base_high;</span><br><span style="color: hsl(120, 100%, 40%);">+          ivrs->ivhd.pci_segment_group = 0x0;</span><br><span style="color: hsl(120, 100%, 40%);">+                ivrs->ivhd.iommu_info = 0x0;</span><br><span style="color: hsl(120, 100%, 40%);">+               ivrs->ivhd.iommu_info |= (0x13 << 8);</span><br><span style="color: hsl(120, 100%, 40%);">+                /* puse only performance counters related bits:</span><br><span style="color: hsl(120, 100%, 40%);">+                * PNCounters[16:13] and</span><br><span style="color: hsl(120, 100%, 40%);">+               * PNBanks[22:17],</span><br><span style="color: hsl(120, 100%, 40%);">+             * otherwise 0 */</span><br><span style="color: hsl(120, 100%, 40%);">+             ivrs->ivhd.iommu_feature_info = ivrs_agesa->ivhd.iommu_feature_info & 0x7fe000;</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              /* TODO: what we can do here? */</span><br><span style="color: hsl(120, 100%, 40%);">+              ivrs->ivhd.type = 0x10;</span><br><span style="color: hsl(120, 100%, 40%);">+            ivrs->ivhd.flags = 0x0e;</span><br><span style="color: hsl(120, 100%, 40%);">+           ivrs->ivhd.flags |= 0x10;                                    /* Enable ATS support */</span><br><span style="color: hsl(120, 100%, 40%);">+              ivrs->ivhd.length = sizeof(struct acpi_ivrs_ivhd);</span><br><span style="color: hsl(120, 100%, 40%);">+         ivrs->ivhd.device_id = 0x2 | (nb_dev->bus->secondary << 8);      /* BDF <bus>:00.2 */</span><br><span style="color: hsl(120, 100%, 40%);">+            ivrs->ivhd.capability_offset = 0x40;                         /* Capability block 0x40 (type 0xf, "Secure device") */</span><br><span style="color: hsl(120, 100%, 40%);">+             ivrs->ivhd.iommu_base_low = 0xfeb00000;</span><br><span style="color: hsl(120, 100%, 40%);">+            ivrs->ivhd.iommu_base_high = 0x0;</span><br><span style="color: hsl(120, 100%, 40%);">+          ivrs->ivhd.pci_segment_group = 0x0;</span><br><span style="color: hsl(120, 100%, 40%);">+                ivrs->ivhd.iommu_info = 0x0;</span><br><span style="color: hsl(120, 100%, 40%);">+               ivrs->ivhd.iommu_info |= (0x13 << 8);</span><br><span style="color: hsl(120, 100%, 40%);">+                ivrs->ivhd.iommu_feature_info = 0x0;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span> </span><br><span>        /* Describe HPET */</span><br><span>  p = (uint8_t *)current;</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/27602">change 27602</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/27602"/><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: I7e3a3d21f295ae96962d7718b9568fc4b67eb23d </div>
<div style="display:none"> Gerrit-Change-Number: 27602 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Piotr Król <piotr.krol@3mdeb.com> </div>