Alexandru Gagniuc ([email protected]) just uploaded a new patch set to 
gerrit, which you can find at http://review.coreboot.org/1461

-gerrit

commit 5ff70e835e2d52a08f072972bc2ba576fa067174
Author: Sven Schnelle <[email protected]>
Date:   Mon Aug 20 11:19:00 2012 +0200

    MPTABLE: check for fixed IRQ entries on all pins
    
    Don't derive the IRQ pin from the function number. Especially onboard
    chipset devices don't follow that rule. Instead check and add all
    fixed IRQ entries.
    
    Change-Id: I46c88bad39104c1d9b4154f180f8b3c42df28262
    Signed-off-by: Sven Schnelle <[email protected]>
---
 src/arch/x86/boot/mpspec.c | 89 ++++++++++++++++++++++++----------------------
 1 file changed, 47 insertions(+), 42 deletions(-)

diff --git a/src/arch/x86/boot/mpspec.c b/src/arch/x86/boot/mpspec.c
index 78996c7..cf346a5 100644
--- a/src/arch/x86/boot/mpspec.c
+++ b/src/arch/x86/boot/mpspec.c
@@ -419,7 +419,7 @@ unsigned long __attribute__((weak)) 
write_smp_table(unsigned long addr)
        int isa_bus, pin, parentpin;
        device_t dev, parent, oldparent;
        void *tmp, *v;
-       int isaioapic = -1;
+       int isaioapic = -1, have_fixed_entries;
 
        v = smp_write_floating_table(addr, 0);
         mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
@@ -461,48 +461,53 @@ unsigned long __attribute__((weak)) 
write_smp_table(unsigned long addr)
                if (dev->path.type != DEVICE_PATH_PCI || !dev->enabled)
                        continue;
 
-               pin = (dev->path.pci.devfn & 7) % 4;
-
-               if (dev->pci_irq_info[pin].ioapic_dst_id) {
-                       printk(BIOS_DEBUG, "fixed IRQ entry for: %s: INT%c# -> 
IOAPIC %d PIN %d\n", dev_path(dev),
-                              pin + 'A',
-                              dev->pci_irq_info[pin].ioapic_dst_id,
-                              dev->pci_irq_info[pin].ioapic_irq_pin);
-                       smp_write_intsrc(mc, mp_INT,
-                                        dev->pci_irq_info[pin].ioapic_flags,
-                                        dev->bus->secondary,
-                                        ((dev->path.pci.devfn & 0xf8) >> 1) | 
pin,
-                                        dev->pci_irq_info[pin].ioapic_dst_id,
-                                        dev->pci_irq_info[pin].ioapic_irq_pin);
-               } else {
-                               oldparent = parent = dev;
-                               while((parent = parent->bus->dev)) {
-                                       parentpin = (oldparent->path.pci.devfn 
>> 3) + (oldparent->path.pci.devfn & 7);
-                                       parentpin += dev->path.pci.devfn & 7;
-                                       parentpin += dev->path.pci.devfn >> 3;
-                                       parentpin %= 4;
-
-                                       if 
(parent->pci_irq_info[parentpin].ioapic_dst_id) {
-                                               printk(BIOS_DEBUG, "automatic 
IRQ entry for %s: INT%c# -> IOAPIC %d PIN %d\n",
-                                                      dev_path(dev), pin + 'A',
-                                                      
parent->pci_irq_info[parentpin].ioapic_dst_id,
-                                                      
parent->pci_irq_info[parentpin].ioapic_irq_pin);
-                                               smp_write_intsrc(mc, mp_INT,
-                                                                
parent->pci_irq_info[parentpin].ioapic_flags,
-                                                                
dev->bus->secondary,
-                                                                
((dev->path.pci.devfn & 0xf8) >> 1) | pin,
-                                                                
parent->pci_irq_info[parentpin].ioapic_dst_id,
-                                                                
parent->pci_irq_info[parentpin].ioapic_irq_pin);
-
-                                               break;
-                                       }
-
-                                       if (parent->path.type == 
DEVICE_PATH_PCI_DOMAIN) {
-                                               printk(BIOS_WARNING, "no IRQ 
found for %s\n", dev_path(dev));
-                                               break;
-                                       }
-                                       oldparent = parent;
+               have_fixed_entries = 0;
+               for (pin = 0; pin < 4; pin++) {
+                       if (dev->pci_irq_info[pin].ioapic_dst_id) {
+                               printk(BIOS_DEBUG, "fixed IRQ entry for: %s: 
INT%c# -> IOAPIC %d PIN %d\n", dev_path(dev),
+                                      pin + 'A',
+                                      dev->pci_irq_info[pin].ioapic_dst_id,
+                                      dev->pci_irq_info[pin].ioapic_irq_pin);
+                               smp_write_intsrc(mc, mp_INT,
+                                                
dev->pci_irq_info[pin].ioapic_flags,
+                                                dev->bus->secondary,
+                                                ((dev->path.pci.devfn & 0xf8) 
>> 1) | pin,
+                                                
dev->pci_irq_info[pin].ioapic_dst_id,
+                                                
dev->pci_irq_info[pin].ioapic_irq_pin);
+                               have_fixed_entries = 1;
+                       }
+               }
+
+               if (!have_fixed_entries) {
+                       pin = (dev->path.pci.devfn & 7) % 4;
+                       oldparent = parent = dev;
+                       while((parent = parent->bus->dev)) {
+                               parentpin = (oldparent->path.pci.devfn >> 3) + 
(oldparent->path.pci.devfn & 7);
+                               parentpin += dev->path.pci.devfn & 7;
+                               parentpin += dev->path.pci.devfn >> 3;
+                               parentpin %= 4;
+
+                               if 
(parent->pci_irq_info[parentpin].ioapic_dst_id) {
+                                       printk(BIOS_DEBUG, "automatic IRQ entry 
for %s: INT%c# -> IOAPIC %d PIN %d\n",
+                                              dev_path(dev), pin + 'A',
+                                              
parent->pci_irq_info[parentpin].ioapic_dst_id,
+                                              
parent->pci_irq_info[parentpin].ioapic_irq_pin);
+                                       smp_write_intsrc(mc, mp_INT,
+                                                        
parent->pci_irq_info[parentpin].ioapic_flags,
+                                                        dev->bus->secondary,
+                                                        ((dev->path.pci.devfn 
& 0xf8) >> 1) | pin,
+                                                        
parent->pci_irq_info[parentpin].ioapic_dst_id,
+                                                        
parent->pci_irq_info[parentpin].ioapic_irq_pin);
+
+                                       break;
                                }
+
+                               if (parent->path.type == 
DEVICE_PATH_PCI_DOMAIN) {
+                                       printk(BIOS_WARNING, "no IRQ found for 
%s\n", dev_path(dev));
+                                       break;
+                               }
+                               oldparent = parent;
+                       }
                }
        }
 

-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to