Friday, October 14, 2011

FIQ debugger, redux.

I found myself (temporarily, thanks Chris!) in the posession of an OLPC XO 1.75 . Very interesting hardware. The Marvell chip isn't something to particularly rave about (compared to the Xoom's dual Cortex-A9s), but at the end of the day it's a completely open platform (hardware and software), that runs an OS based on Fedora. Plus it uses OpenFirmware instead of some half-baked ROM monitor or a UEFI.. Totally cool. The other great thing is that the kernel is a 3.0-based kernel (not mainline, but w/e), which makes this that much more interesting, especially in light of my interests in MMC flash block core and ARM KGDB/KDB support.

Anyway, while playing with it I had the system wedge up in some totally useless state. Given a lack of a FIQ watchdog or debugger code, I decided to port the FIQ debugger over...

Update: Looks like the XO folks found it useful to hunt for some bugs, cool!

Enable FIQ support for the MMP2 platform, i.e. add an OOB interface for enabling/disabling FIQ triggering on a particular INT# line.

Bring over Google's FIQ glue, which lets you write FIQ handlers in a normal C environment (and deals with suspend/resume and MP support). Not sure I understand why this stuff isn't in mainline yet - I presume because nothing uses it. It certainly has no dependency on Android.

Implement the FIQ debugger platform device for MMP2. This is the platform-specific driver which is used the FIQ debugger core, and provides UART access, FIQ INT# manipulation, and the ability to force an IRQ. The later is crucial, since the UART is managed entirely by the FIQ handler, and getting stuff to happen in normal "kernel context" needs code to run in at least IRQ level, so you need to be able to trigger a hardware IRQ.

Turn on the FIQ debugger platform device for the XO 1.75 kernel, binding it to a specific UART.

Port Google's FIQ debugger into a non-Android environment, at the same time bringing it up to date (from K36 to K3.0) and improving the interface to the platform device.

Add my KGDB/KGDB FIQ patch on top.

Some of the better functionality not seen elsewhere ;-):

Ability to override baud rate from boot parameter.

Ability to implement platform-specific commands.

Ability to specify OOB struct clk that is not associated with the pdev.

Of course, the ability to enter into KDB/KGDB mode.

Forcing a hardware IRQ posed an interesting problem. Many thanks to Mitch Bradley (*the* OpenFirmware guy), who suggested using the IPC block to trigger a particular IRQ. The mechanism pretty much triggers only that one IRQ, but that in itself is sufficient. The IPC block should really be exposed as a secondary interrupt controller, as it effectively implements more interrupt lines chained off that one IRQ, but the Marvell documentation for this is clearly not available for me. Ran into an issue where the IRQ would instantly fire as soon as I would enable it, but I guessed there were some extra lines in the IPC block which needed to be masked away, and looks like I was right.