Subject: Interrupts
To: netbsd-macppc <port-macppc@NetBSD.ORG>
From: Michael <macallan18@earthlink.net>
List: port-macppc
Date: 12/05/2004 22:40:09
Hello,

I've found something but it's pretty ugly so I need confirmation, maybe I'm thinking in the wrong direction.
Apparently NetBSD/macppc loses masses of interrupts all the time and nearly everywhere, things only seem to work because most drivers are fairly tolerant about this. I could work around the lockup between USB and audio on my box with this pseudo patch:

int gc_read_irq()
{
	int rv = 0;
	int lo, hi, p, pp, np;

	lo = in32rb(INT_STATE_REG_L);
+	pp = (in32rb(INT_LEVEL_REG_L) & in32rb(INT_ENABLE_REG_L));
+	np=(pp & ~lo);
+	if(np&0x2000000)
+		lo|=0x2000000;
	if (lo)
		out32rb(INT_CLEAR_REG_L, lo);
	while (lo) {

basically it looks into the interrupt level register for interrupts that are enabled but didn't fire, if one of them happens to be IRQ 25 which is in my box shared between USB and audio it acts as if it did fire - clears it and returns it. With this I could repeatedly fsck an USB disk with audio playing, before it reliably locked up after a few seconds. Audio played fine, only had a few glitches.
It looks like everything that produces lots of interrupts is prone to lose a lot, I'd almost bet my patch for mesh wouldn't be necessary if there weren't lots of lost interrupts. 
This 'solution' is far from optimal - an active line without the corresponding interrupt bit set doesn't always mean a lost interrupt, and just ORing the level register on the interrupt register also locks things up - no idea why though.
But I think we need something like this - better call IRQ handlers a little more often than lose interupts and get all kinds of nastiness.

have fun
Michael