On Sun, May 04, 2008 at 10:49:22AM -0400, Ward Vandewege wrote:
32663C_lx_gx_pciconfig.pdf page 46-49 seems to suggest that USB is always on INTD# IRQ11. This could be hardwired in LX/5536;
It's not hardwired.
You are correct.
I was reading the LX and 5536 databooks while Tom sent the last message so he has already covered some of this.
Architecture overviews describe 5536 connected to the LX via PCI but the LX has no PCI interrupt balls so that must only be a logical description. 5536 is connected to the LX via the companion connection GLD on one of the two GLIUs in the LX.
The 5536 has GPIO interrupts, which are used for the external PCI bus interrupt signals. That makes sense since the PCI_INTx signals connect to 5536 GPIO balls.
But what about the virtual PCI devices?
GL packets from USB will always trigger IRQ11.
I _think_ this is set by the VSA blob. But what do I know :)
I should have written that as a question. Anyway, you knew.
(And interrupts are not neccessarily connected with any other GL activity from the USB module.)
Or worse they will always trigger PCI_INTD# meaning a well-designed board with 4 PCI slots, or a badly designed board with less slots will always need to share somewhere.
I don't think so.
The 5536 databook does not mention interrupts at all in the USB module chapters, it's all in the interrupt controller chapters.
Ron got his way, he had it coming. Reading geode-vsa shows that you're spot on, Ward.
Hardwarewise, the USB module generates interrupts on what is called "Unrestricted Y Input 2" on the PIC. That input maps to one interrupt group between 1 and 15 per the PIC specific MSR at addr+20h bits 11:8.
The interrupt is OR:ed with any other interrupts mapped to the same group. The group number corresponds to the classic 8259 IRQ number. Interrupt group 10 generates IRQ 10. "Unrestricted" because the input can be mapped to any IRQ 1-15. MFGPT and GPIO interrupts are on the Unrestricted Z inputs.
Reset value for all interrupt group MSRs is 0, ie. disabled.
Simple enough.
Enter PCI emulation cr^W:
VSA allows writes to PCI register 0x3c bits 7:0 (interrupt line) but not bits 15:8 (interrupt pin) for all virtual devices. Since virtual devices are internal and not actually connected to any PCI interrupt pin (the external signals on GPIO balls) that makes sense.
sysmgr/pci_wr.c:Virtual_PCI_Write_Handler() handles writes to all PCI registers for virtual devices but the PIC specific MSR that controls the interrupt group mapping is not touched in this code path.
sysmgr/topology.c has a struct for each virtual device that lists all implemented registers. All devices have register 0x3c and it's value is initialized to the interrupt pin (1..4) in bits 15:8 and somewhat surprisingly the Unrestricted Y Input number (1..15) rather than the interrupt line (1..15) in bits 7:0. Both USB devices have 0x00000402.
legacy/cs5536.c:CS5536_Early_Init() goes through all 5536 functions and for those with non-zero bits 15:0 in register 0x3c the value is copied to the global Y_Sources array and cleared to 0 in the struct. Then a PCI trap is registered for writes to southbridge F0 register 0x5c-0x5d. (5530 PCI Interrupt Steering)
When someone writes to 0x5c, legacy/cs5536.c:PCI_Interrupt_Steering() is called. On the first write the specified GPIO balls are set up to handle PCI_INTx signals, as mentioned the other day. On all writes it calls SYS_MAP_IRQ() with the value saved in Y_Sources for each IRQ in the specified interrupt steering map (ie. each IRQ assigned to a PCI_INTx pin/ball by this write to 0x5c) and now the Y2->IG mapping for the USB module (and all others) is finally written to the PIC specific MSR.
VSA thus forces virtual PCI devices to only ever generate the same interrupts as external PCI devices.
Which of the four PCI_INTx IRQs a device uses is determined by bits 15:8 of the 0x3C value in the corresponding PCI_HEADER_ENTRY struct in sysmgr/topology.c at VSA blob compile time.
Dig out your hex editor if you want to change it.
Whatever is written to 0x3c for virtual devices has no effect on which IRQ is generated. The register value is purely for show.
//Peter