<p>Lubomir Rintel has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/25799">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">x86/mpspec: order the I/O APICs by the APIC Id<br><br>Linux (4.16) assumes that the PIT interrupt is connected to the pin 0 of the<br>IOAPIC[0] and panics otherwise.<br><br>This might be a Linux bug. The MP Specification 1.4 does seem to mandate<br>sequential ordering for Bus entries, but not for the I/O APICs.<br><br>Change-Id: Ibf823eb5b3a29e4590cba915069cdfe5f780edcd<br>Signed-off-by: Lubomir Rintel <lkundrak@v3.sk><br>---<br>M src/arch/x86/mpspec.c<br>1 file changed, 23 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/99/25799/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/arch/x86/mpspec.c b/src/arch/x86/mpspec.c</span><br><span>index d41abaf..fd3d837 100644</span><br><span>--- a/src/arch/x86/mpspec.c</span><br><span>+++ b/src/arch/x86/mpspec.c</span><br><span>@@ -523,6 +523,23 @@</span><br><span>    return smp_next_mpe_entry(mc);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static struct device *find_next_ioapic(unsigned last_ioapic_id)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct device *dev;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct device *result = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned ioapic_id = MAX_APICS;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     for (dev = all_devices; dev; dev = dev->next) {</span><br><span style="color: hsl(120, 100%, 40%);">+            if (dev->path.type == DEVICE_PATH_IOAPIC)</span><br><span style="color: hsl(120, 100%, 40%);">+          if (dev->path.type == DEVICE_PATH_IOAPIC &&</span><br><span style="color: hsl(120, 100%, 40%);">+                    dev->path.ioapic.ioapic_id > last_ioapic_id &&</span><br><span style="color: hsl(120, 100%, 40%);">+                  dev->path.ioapic.ioapic_id <= ioapic_id) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  result = dev;</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 result;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> unsigned long __attribute__((weak)) write_smp_table(unsigned long addr)</span><br><span> {</span><br><span>  struct drivers_generic_ioapic_config *ioapic_config;</span><br><span>@@ -534,6 +551,7 @@</span><br><span>   void *tmp, *v;</span><br><span>       int isaioapic = -1, have_fixed_entries;</span><br><span>      struct pci_irq_info *pci_irq_info;</span><br><span style="color: hsl(120, 100%, 40%);">+    unsigned ioapic_id = 0;</span><br><span> </span><br><span>  v = smp_write_floating_table(addr, 0);</span><br><span>       mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);</span><br><span>@@ -544,17 +562,17 @@</span><br><span> </span><br><span>     mptable_write_buses(mc, NULL, &isa_bus);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        for (dev = all_devices; dev; dev = dev->next) {</span><br><span style="color: hsl(0, 100%, 40%);">-              if (dev->path.type != DEVICE_PATH_IOAPIC)</span><br><span style="color: hsl(0, 100%, 40%);">-                    continue;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+     while ((dev = find_next_ioapic(ioapic_id))) {</span><br><span>                ioapic_config = dev->chip_info;</span><br><span>           if (!ioapic_config) {</span><br><span>                        printk(BIOS_ERR, "%s has no config, ignoring\n",</span><br><span>                           dev_path(dev));</span><br><span style="color: hsl(120, 100%, 40%);">+                       ioapic_id++;</span><br><span>                         continue;</span><br><span>            }</span><br><span style="color: hsl(0, 100%, 40%);">-               smp_write_ioapic(mc, dev->path.ioapic.ioapic_id,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         ioapic_id = dev->path.ioapic.ioapic_id;</span><br><span style="color: hsl(120, 100%, 40%);">+            smp_write_ioapic(mc, ioapic_id,</span><br><span>                                   ioapic_config->version,</span><br><span>                                   ioapic_config->base);</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/25799">change 25799</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/25799"/><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: Ibf823eb5b3a29e4590cba915069cdfe5f780edcd </div>
<div style="display:none"> Gerrit-Change-Number: 25799 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Lubomir Rintel <lkundrak@v3.sk> </div>