Subject: Re: Interrupts
To: Michael <macallan18@earthlink.net>
From: Tim Kelly <hockey@dialectronics.com>
List: port-macppc
Date: 12/06/2004 12:38:25
At 12:25 PM -0500 12/6/04, Tim Kelly wrote:
>
>Adding to this, if the interrupt is enabled, then gc ought to let another
>device request the interrupt to be asserted, but since the interrupt in the
>state register was already enabled, this is not a state change, and if the
>call to ext_intr() is only done when the register goes lo->hi, the device's
>handlers will not get called until something manages to cycle through the
>virq again, as the iteration already passed it by.

Yes, look at the code in ext_intr():


        int_state = gc_read_irq();

        if (int_state == 0)
                return;

start:

        irq = 31 - cntlzw(int_state);
        r_imen = 1 << irq;

        is = &intrsources[irq];

        if ((pcpl & r_imen) != 0) {
                ci->ci_ipending |= r_imen;      /* Masked! Mark this as
pending$
                gc_disable_irq(is->is_hwirq);
        } else {

            (handle it immediately)

        }

        int_state &= ~r_imen;
        if (int_state)
                goto start;



It doesn't check if the interrupt has been deasserted after handling it
immediately. It just checks other interrupts. The late interrupt request
keeps the interrupt asserted, but it doesn't get noticed until some state
change from another (non-shared) hwirq triggers the cycle again.

I think it would help if the code read:

start:
        int_state = gc_read_irq();

        if (int_state == 0)
                return;

That way the state is always re-examined.

tim