On Fri, 25 Dec 2020 at 23:45, BALATON Zoltan via <qemu-devel@nongnu.org> wrote: > For the Bamboo board we have 4 interrupts connected to the PCI bus in the > board but also have a comment in ppc4xx_pci.c near the above function > saying: > > /* On Bamboo, all pins from each slot are tied to a single board IRQ. This > * may need further refactoring for other boards. */ > static int ppc4xx_pci_map_irq(PCIDevice *pci_dev, int irq_num) > { > int slot = pci_dev->devfn >> 3; > > trace_ppc4xx_pci_map_irq(pci_dev->devfn, irq_num, slot); > > return slot - 1; > } > > Now I'm not sure what that comment means:
It definitely doesn't match the code, anyway... > 1. All PCI INTA from all slots go to one irq, PCI INTB to another and so on > > or > > 2. All PCI interrupts (INTA-D) from first slot are connected to one irq on > the board, then those from next slot are to another irq and so on I looked at the datasheet for the PPC440EP SoC itself, and it has only a single PCIINT pin, so all boards using this CPU must end up only asserting one interrupt line into the interrupt controller (presumably via an on-board OR gate?) > The slot - 1 mapping seems to correspond more to 2. but that also means we > can only have 4 slots. You can have more than 4 slots -- one common approach is to stripe the 4 interrupts across slots, so that if you have 4 interrupts 0, 1, 2, 3 then in slot 0 they are wired INTA=0, INTB=1, INTC=2, INTD=3, and in slot 1 they are INTA=1, INTB=2, INTC=3, INTD=0, and in slot 2 they are INTA=2, INTB=3, INTC=4, INTD=1, and so on. This just helps to spread the interrupt usage out and minimise sharing of interrupts between devices, because most PCI cards only ever use INTA (though they are permitted to use all 4 if they have a need for it, I think.) This kind of striping is just implemented by how you connect the pins on the PCI slots. (This striping is what function pci_swizzle_map_irq_fn() implements.) In QEMU's PCI implementation, it's OK for the mapping function to reuse IRQ numbers -- PCI IRQ line changes go via pci_change_irq_level(), which first calls the controller-specific map_irq function, and then in pci_bus_change_irq_level() keeps a count of how many different devices have asserted the (mapped) IRQ, so it calls the controller's set_irq method with effectively the logical-OR of all the input levels. (I was wrong about this in another email I just wrote -- I'll go back and correct that in a moment.) > I did not find a picture of the real board so don't > know how many slots that has or how they are connected. I think we need > more info on the real hardware to tell what's the correct mapping here. Yeah, I couldn't find any documentation for the board itself either :-( Incidentally, if guest software like Linux has been written and tested on QEMU and not on the real hardware, then bugs in the mapping of IRQs can be painful to try to fix, because if the kernel was written with the equal-but-opposite bug it will then not run on a bugfixed QEMU. We had a bit of a mess with the QEMU versatilepb PCI controller that way. thanks -- PMM