Subject: PCI interrupt pins and i386mp
To: None <tech-kern@netbsd.org, tech-smp@netbsd.org>
From: Matthias Drochner <M.Drochner@fz-juelich.de>
List: tech-smp
Date: 01/07/2002 19:17:48
Just got a kernel from the sommerfeld_i386mp_1 branch working on
a dual processor PICMG slot CPU board.
There was a little problem with the interrupt routing on secondary
PCI busses: the "pa_intrpin" member isn't what the name implies
but refers to a (virtual) slot where the interrupt meets PCI
bus #0 (which it doesn't do in the general case, so the design is
a bit flawed, but appears to be sufficient for current hardware...).
Anyway, the MPBIOS entries refer to "real" interrupt pins, and the
appended patch fixes this in a least-intrusive way.

Here are boot messages before:

ioapic0: int10 attached to pci2 device 5 INT_A (type 0<type=0> flags 
f<pol=3=Act
 Lo,trig=3=Level>)
[...]
ex0 at pci2 dev 5 function 0: 3Com 3c905-TX 10/100 Ethernet (rev. 0x0)
pci_intr_map: bus 2 dev 5 func 0 pin 2; line 10
pci_intr_map: no MP mapping found
isa_intr_establish: no MP mapping found
ex0: interrupting at irq 10

and after:

ex0 at pci2 dev 5 function 0: 3Com 3c905-TX 10/100 Ethernet (rev. 0x0)
ex0: interrupting at apic 2 int 10 (irq 10)

best regards
Matthias

btw, the question raised in a comment in pci_machdep.c:
		/*
		 * Assumes 1:1 mapping between PCI bus numbers and
		 * the numbers given by the MP bios.
		 * XXX Is this a valid assumption?
		 */
can be answered "yes" - see appendix D.2 of the Intel MP Spec rev. 1.4.


Index: pci_machdep.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/pci/pci_machdep.c,v
retrieving revision 1.35.2.10
diff -c -r1.35.2.10 pci_machdep.c
*** pci_machdep.c	2001/12/29 21:09:10	1.35.2.10
--- pci_machdep.c	2002/01/07 17:46:07
***************
*** 532,538 ****
  		 * the numbers given by the MP bios.
  		 * XXX Is this a valid assumption?
  		 */
! 		int mpspec_pin = (dev<<2)|(pin-1);
  		
  		
  		for (mip = mp_busses[bus].mb_intrs; mip != NULL; mip=mip->next) {
--- 532,540 ----
  		 * the numbers given by the MP bios.
  		 * XXX Is this a valid assumption?
  		 */
! 		int realpin = PCI_INTERRUPT_PIN(pci_conf_read(pa->pa_pc,
! 				  pa->pa_tag, PCI_INTERRUPT_REG));
! 		int mpspec_pin = (dev<<2)|(realpin - 1);
  		
  		
  		for (mip = mp_busses[bus].mb_intrs; mip != NULL; mip=mip->next) {
***************
*** 543,549 ****
  		}
  		if (mip == NULL) {
  			printf("pci_intr_map: bus %d dev %d func %d pin %d; line %d\n",
! 			    bus, dev, func, pin, line);
  			
  			printf("pci_intr_map: no MP mapping found\n");
  		}
--- 545,551 ----
  		}
  		if (mip == NULL) {
  			printf("pci_intr_map: bus %d dev %d func %d pin %d; line %d\n",
! 			    bus, dev, func, realpin, line);
  			
  			printf("pci_intr_map: no MP mapping found\n");
  		}