1. 10 Apr, 2022 4 commits
    • Maciej W. Rozycki's avatar
      x86/PCI: Handle IRQ swizzling with PIRQ routers · d88a8b1c
      Maciej W. Rozycki authored
      Similarly to MP-tables PIRQ routing tables may not list devices behind 
      PCI-to-PCI bridges, leading to interrupt routing failures, e.g.:
      
      pci 0000:00:07.0: PIIX/ICH IRQ router [8086:7000]
      pci 0000:02:00.0: ignoring bogus IRQ 255
      pci 0000:02:01.0: ignoring bogus IRQ 255
      pci 0000:02:02.0: ignoring bogus IRQ 255
      pci 0000:04:00.0: ignoring bogus IRQ 255
      pci 0000:04:00.3: ignoring bogus IRQ 255
      pci 0000:00:11.0: PCI INT A -> PIRQ 63, mask deb8, excl 0c20
      pci 0000:00:11.0: PCI INT A -> newirq 0
      PCI: setting IRQ 11 as level-triggered
      pci 0000:00:11.0: found PCI INT A -> IRQ 11
      pci 0000:00:11.0: sharing IRQ 11 with 0000:00:07.2
      pci 0000:02:00.0: PCI INT A not found in routing table
      pci 0000:02:01.0: PCI INT A not found in routing table
      pci 0000:02:02.0: PCI INT A not found in routing table
      pci 0000:04:00.0: PCI INT A not found in routing table
      pci 0000:04:00.3: PCI INT D not found in routing table
      pci 0000:06:05.0: PCI INT A not found in routing table
      pci 0000:06:08.0: PCI INT A not found in routing table
      pci 0000:06:08.1: PCI INT B not found in routing table
      pci 0000:06:08.2: PCI INT C not found in routing table
      
      and consequently non-working devices.  Since PCI-to-PCI bridges have a 
      standardised way of routing interrupts by the means of swizzling do it 
      for configurations that use a PIRQ router as well, like with APIC-based 
      setups, and use the determined corresponding topmost bridge's interrupt 
      pin assignment to route a given device's interrupt:
      
      pci 0000:00:07.0: PIIX/ICH IRQ router [8086:7000]
      pci 0000:02:00.0: ignoring bogus IRQ 255
      pci 0000:02:01.0: ignoring bogus IRQ 255
      pci 0000:02:02.0: ignoring bogus IRQ 255
      pci 0000:04:00.0: ignoring bogus IRQ 255
      pci 0000:04:00.3: ignoring bogus IRQ 255
      pci 0000:00:11.0: PCI INT A -> PIRQ 63, mask deb8, excl 0c20
      pci 0000:00:11.0: PCI INT A -> newirq 0
      PCI: setting IRQ 11 as level-triggered
      pci 0000:00:11.0: found PCI INT A -> IRQ 11
      pci 0000:00:11.0: sharing IRQ 11 with 0000:00:07.2
      pci 0000:02:00.0: using bridge 0000:00:11.0 INT A to get INT A
      pci 0000:00:11.0: sharing IRQ 11 with 0000:02:00.0
      pci 0000:02:01.0: using bridge 0000:00:11.0 INT B to get INT A
      pci 0000:02:02.0: using bridge 0000:00:11.0 INT C to get INT A
      pci 0000:04:00.0: using bridge 0000:00:11.0 INT B to get INT A
      pci 0000:04:00.3: using bridge 0000:00:11.0 INT A to get INT D
      pci 0000:00:11.0: sharing IRQ 11 with 0000:04:00.3
      pci 0000:06:05.0: using bridge 0000:00:11.0 INT D to get INT A
      pci 0000:06:08.0: using bridge 0000:00:11.0 INT C to get INT A
      pci 0000:06:08.1: using bridge 0000:00:11.0 INT D to get INT B
      pci 0000:06:08.2: using bridge 0000:00:11.0 INT A to get INT C
      pci 0000:00:11.0: sharing IRQ 11 with 0000:06:08.2
      pci 0000:02:01.0: using bridge 0000:00:11.0 INT B to get INT A
      pci 0000:02:01.0: PCI INT A -> PIRQ 60, mask deb8, excl 0c20
      pci 0000:02:01.0: PCI INT A -> newirq 0
      PCI: setting IRQ 10 as level-triggered
      pci 0000:02:01.0: found PCI INT A -> IRQ 10
      pci 0000:02:01.0: sharing IRQ 10 with 0000:00:14.0
      pci 0000:02:00.0: using bridge 0000:00:11.0 INT A to get INT A
      pci 0000:02:01.0: using bridge 0000:00:11.0 INT B to get INT A
      pci 0000:02:02.0: using bridge 0000:00:11.0 INT C to get INT A
      pci 0000:04:00.0: using bridge 0000:00:11.0 INT B to get INT A
      pci 0000:02:01.0: sharing IRQ 10 with 0000:04:00.0
      pci 0000:04:00.3: using bridge 0000:00:11.0 INT A to get INT D
      pci 0000:06:05.0: using bridge 0000:00:11.0 INT D to get INT A
      pci 0000:06:08.0: using bridge 0000:00:11.0 INT C to get INT A
      pci 0000:06:08.1: using bridge 0000:00:11.0 INT D to get INT B
      pci 0000:06:08.2: using bridge 0000:00:11.0 INT A to get INT C
      pci 0000:02:02.0: using bridge 0000:00:11.0 INT C to get INT A
      pci 0000:02:02.0: PCI INT A -> PIRQ 61, mask deb8, excl 0c20
      pci 0000:02:02.0: PCI INT A -> newirq 0
      PCI: setting IRQ 5 as level-triggered
      pci 0000:02:02.0: found PCI INT A -> IRQ 5
      pci 0000:02:02.0: sharing IRQ 5 with 0000:00:13.0
      pci 0000:02:00.0: using bridge 0000:00:11.0 INT A to get INT A
      pci 0000:02:01.0: using bridge 0000:00:11.0 INT B to get INT A
      pci 0000:02:02.0: using bridge 0000:00:11.0 INT C to get INT A
      pci 0000:04:00.0: using bridge 0000:00:11.0 INT B to get INT A
      pci 0000:04:00.3: using bridge 0000:00:11.0 INT A to get INT D
      pci 0000:06:05.0: using bridge 0000:00:11.0 INT D to get INT A
      pci 0000:06:08.0: using bridge 0000:00:11.0 INT C to get INT A
      pci 0000:02:02.0: sharing IRQ 5 with 0000:06:08.0
      pci 0000:06:08.1: using bridge 0000:00:11.0 INT D to get INT B
      pci 0000:06:08.2: using bridge 0000:00:11.0 INT A to get INT C
      pci 0000:06:05.0: using bridge 0000:00:11.0 INT D to get INT A
      pci 0000:06:05.0: PCI INT A -> PIRQ 62, mask deb8, excl 0c20
      pci 0000:06:05.0: PCI INT A -> newirq 0
      pci 0000:06:05.0: found PCI INT A -> IRQ 5
      pci 0000:06:05.0: sharing IRQ 5 with 0000:00:12.0
      pci 0000:02:00.0: using bridge 0000:00:11.0 INT A to get INT A
      pci 0000:02:01.0: using bridge 0000:00:11.0 INT B to get INT A
      pci 0000:02:02.0: using bridge 0000:00:11.0 INT C to get INT A
      pci 0000:04:00.0: using bridge 0000:00:11.0 INT B to get INT A
      pci 0000:04:00.3: using bridge 0000:00:11.0 INT A to get INT D
      pci 0000:06:05.0: using bridge 0000:00:11.0 INT D to get INT A
      pci 0000:06:08.0: using bridge 0000:00:11.0 INT C to get INT A
      pci 0000:06:08.1: using bridge 0000:00:11.0 INT D to get INT B
      pci 0000:06:05.0: sharing IRQ 5 with 0000:06:08.1
      pci 0000:06:08.2: using bridge 0000:00:11.0 INT A to get INT C
      
      Adjust log messages accordingly.
      Signed-off-by: default avatarMaciej W. Rozycki <macro@orcam.me.uk>
      Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Link: https://lore.kernel.org/r/alpine.DEB.2.21.2203301538440.22465@angie.orcam.me.uk
      d88a8b1c
    • Maciej W. Rozycki's avatar
      x86/PCI: Also match function number in $PIR table · 31324502
      Maciej W. Rozycki authored
      Contrary to the PCI BIOS specification[1] some systems include the PCI 
      function number for onboard devices in their $PIR table.  Consequently 
      the wrong entry can be matched leading to interrupt routing failures.
      
      For example the Tyan Tomcat IV S1564D board has:
      
      00:07.1 slot=00
       0:00/deb8
       1:00/deb8
       2:00/deb8
       3:00/deb8
      
      00:07.2 slot=00
       0:00/deb8
       1:00/deb8
       2:00/deb8
       3:63/deb8
      
      for its IDE interface and USB controller functions of the 82371SB PIIX3 
      southbridge.  Consequently the first entry matches causing the inability 
      to route the USB interrupt in the `noapic' mode, in which case we need 
      to rely on the interrupt line set by the BIOS:
      
      uhci_hcd 0000:00:07.2: runtime IRQ mapping not provided by arch
      uhci_hcd 0000:00:07.2: PCI INT D not routed
      uhci_hcd 0000:00:07.2: enabling bus mastering
      uhci_hcd 0000:00:07.2: UHCI Host Controller
      uhci_hcd 0000:00:07.2: new USB bus registered, assigned bus number 1
      uhci_hcd 0000:00:07.2: irq 11, io base 0x00006000
      
      Try to match the PCI device and function combined then and if that fails 
      move on to PCI device matching only.  Compliant systems will only have a 
      single $PIR table entry per PCI device, so this update does not change 
      the semantics with them, while systems that have several entries for 
      individual functions of a single PCI device each will match the correct 
      entry:
      
      uhci_hcd 0000:00:07.2: runtime IRQ mapping not provided by arch
      uhci_hcd 0000:00:07.2: PCI INT D -> PIRQ 63, mask deb8, excl 0c20
      uhci_hcd 0000:00:07.2: PCI INT D -> newirq 11
      uhci_hcd 0000:00:07.2: found PCI INT D -> IRQ 11
      uhci_hcd 0000:00:07.2: sharing IRQ 11 with 0000:00:11.0
      uhci_hcd 0000:00:07.2: enabling bus mastering
      uhci_hcd 0000:00:07.2: UHCI Host Controller
      uhci_hcd 0000:00:07.2: new USB bus registered, assigned bus number 1
      uhci_hcd 0000:00:07.2: irq 11, io base 0x00006000
      
      [1] "PCI BIOS Specification", Revision 2.1, PCI Special Interest Group,
          August 26, 1994, Table 4-1 "Layout of IRQ routing table entry.", p.
          12
      Signed-off-by: default avatarMaciej W. Rozycki <macro@orcam.me.uk>
      Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Link: https://lore.kernel.org/r/alpine.DEB.2.21.2203301536020.22465@angie.orcam.me.uk
      31324502
    • Maciej W. Rozycki's avatar
      x86/PCI: Include function number in $PIR table dump · dc0e6408
      Maciej W. Rozycki authored
      Contrary to the PCI BIOS specification[1] some systems include the PCI 
      function number for motherboard devices in their $PIR table, e.g. this 
      is what the Tyan Tomcat IV S1564D board reports:
      
      00:14 slot=01
       0:60/deb8
       1:61/deb8
       2:62/deb8
       3:63/deb8
      
      00:13 slot=02
       0:61/deb8
       1:62/deb8
       2:63/deb8
       3:60/deb8
      
      00:12 slot=03
       0:62/deb8
       1:63/deb8
       2:60/deb8
       3:61/deb8
      
      00:11 slot=04
       0:63/deb8
       1:60/deb8
       2:61/deb8
       3:62/deb8
      
      00:07 slot=00
       0:00/deb8
       1:00/deb8
       2:00/deb8
       3:00/deb8
      
      00:07 slot=00
       0:00/deb8
       1:00/deb8
       2:00/deb8
       3:63/deb8
      
      Print the function number then in the debug $PIR table dump:
      
      00:14.0 slot=01
       0:60/deb8
       1:61/deb8
       2:62/deb8
       3:63/deb8
      
      00:13.0 slot=02
       0:61/deb8
       1:62/deb8
       2:63/deb8
       3:60/deb8
      
      00:12.0 slot=03
       0:62/deb8
       1:63/deb8
       2:60/deb8
       3:61/deb8
      
      00:11.0 slot=04
       0:63/deb8
       1:60/deb8
       2:61/deb8
       3:62/deb8
      
      00:07.1 slot=00
       0:00/deb8
       1:00/deb8
       2:00/deb8
       3:00/deb8
      
      00:07.2 slot=00
       0:00/deb8
       1:00/deb8
       2:00/deb8
       3:63/deb8
      
      References:
      
      [1] "PCI BIOS Specification", Revision 2.1, PCI Special Interest Group, 
          August 26, 1994, Table 4-1 "Layout of IRQ routing table entry.", p. 
          12
      Signed-off-by: default avatarMaciej W. Rozycki <macro@orcam.me.uk>
      Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Link: https://lore.kernel.org/r/alpine.DEB.2.21.2203301534440.22465@angie.orcam.me.uk
      dc0e6408
    • Maciej W. Rozycki's avatar
      x86/PCI: Show the physical address of the $PIR table · 613fa6e2
      Maciej W. Rozycki authored
      It makes no sense to hide the address of the $PIR table in a debug dump:
      
      PCI: Interrupt Routing Table found at 0x(ptrval)
      
      let alone print its virtual address, given that this is a BIOS entity at 
      a fixed location in the system's memory map.  Show the physical address 
      instead then, e.g.:
      
      PCI: Interrupt Routing Table found at 0xfde10
      Signed-off-by: default avatarMaciej W. Rozycki <macro@orcam.me.uk>
      Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Link: https://lore.kernel.org/r/alpine.DEB.2.21.2203301532330.22465@angie.orcam.me.uk
      613fa6e2
  2. 03 Apr, 2022 8 commits
  3. 02 Apr, 2022 28 commits