|
|
Interrupts – Traps – ExceptionsThe PowerPC architecture has a fairly straightforward way of processing exceptions, interrupts at least in the HW sense. Some of the low level routines from the 2.6 locore are very useful. No need to recreate the wheel here. OverviewWe once again looked carefully at 2.11 SPARC, x86 and 2.6 PPC code to get a feel for what was the best route here to start with. It should be noted that much of the interrupt processing was typically done in locore directly but around bld 57 the x86 based interrupt code was moved up into c. We have yet to analyze the performance impact of this approach but from a portability standpoint this worked out for us. We leveraged the x86 based intr.c fairly heavily. The PIC of the Marvell 64360 Northbridge is quite a bit different then the std PC architecture approach. However the way the ODW wired up the routing all of the HW interrupts essentially are piped through the 8259s on the Southbridge. This would surely add a degree of latency in the processing of the onboard NB peripherals, but for now we just go with it. We also understand that moving forward there will be work for just about every platform we encounter. So fully expect to be into this code area for a while. Status 07/19/2007External interrupts are functional on the ODW at least with the onboard RHINE Vt8231 internal MAC. Status 06/06/2007The PIC code is very ODW specific. It is untested as we are still dealing with successfully loading modules. Once we get past that testing of the driver will surely lead to a debugging exercise. The decrementer irq has run through a good portion of interrupt related code but interaction with multiple interrupts will surely prove interesting since debugging external interrupt trap handling has just started. Status 10/19/06As of 10/19/06 level 0, level 1 handlers in locore are functional. We leveraged what was essentially the 2.6 approach to gain a degree of functionality. For all level 0 exception handlers, the following is the state when transferring control to level 1. r1 – points to a MINFRAME sized stack frame, followed by a register save area ("struct regs" described in reg.h) on the current kernel stack. The register save area is filled in with saved values for R1, R2, R4, R5, R6, R20, CR, PC (saved srr0), and MSR (saved srr1). The other registers are saved in the level 1 code. r2 – curthread, r4 – trap type (same as interrupt vector, see trap.h), r5 – value of the DAR (when trap type is a data fault), r6 – value of the DSISR (when trap type is a data fault or an alignment fault), r20 – CPU The other interrupt handlers are invoked with a single argument that was provided when the interrupt routine was registered via ddiaddintr(). When we go from level 0 to level 1 for non-clock interrupts, there is nothing special needed to be done. The level 1 code needs to read the vector number provided in a platform-specific manner, e.g., read a on-board status register. trap() is called as follows: trap(struct *rp, type, dar, dsisr, cpuid) where: rp – pointer to regs structure type – trap type (vector number, e.g., 0x100, 0x200, …) dar – DAR register (traps 0x300 and 0x600) dsisr – DSISR register (traps 0x300 and 0x600) cpuid – processor ID of the CPU that has trapped Common Level 0 Exception handler. This basically saves the state and calls the level 1 common trap handler. Currently the following exceptions are handled by this:
NOTE: When special handling is required for any of the above exceptions then they need seperate handlers. |