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-kern
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");
}