This is the mail archive of the ecos-discuss@sourceware.cygnus.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: IRQ interrupt at highest priority


>>>>> "Huge" == Hugo 'NOx' Tyson <hmt@cygnus.co.ukx> writes:

    <snip>

    Huge> Interrupt prioritization (as you are thinking of it) is
    Huge> platform dependent. On the PID, it is controlled by this
    Huge> routine from pid_misc.c

    //
    // This routine is called to respond to a hardware interrupt (IRQ).  It
    // should interrogate the hardware and return the IRQ vector number.

    int hal_IRQ_handler(void)
    {
        // Do hardware-level IRQ handling
        int irq_status, vector;
        HAL_READ_UINT32(CYG_DEVICE_IRQ_Status, irq_status);
        //diag_init();  diag_printf("%s, status: %x\n", __PRETTY_FUNCTION__, irq_status); 
        for (vector = 1;  vector < 16;  vector++) {
           if (irq_status & (1<<vector)) return vector;
        }
        return CYGNUM_HAL_INTERRUPT_unused; // This shouldn't happen!
   }

    Huge> which as you can see just picks the first one that's active,
    Huge> starting from number 1 and working upwards to 15, through
    Huge> the bits in the IRQ Status register.

    Huge> So if sources 3,5 and 11 are interrupting, 3 will win.

With some interrupt controllers it is possible to get prioritization
in software, as long as the number of interrupt sources is small. You
have to maintain an array of interrupt controller masks with one entry
for each interrupt source. When interrupt X occurs you use the array
entry to mask out the lower-priority interrupt sources. Care has to be
taken with nested interrupts to make sure things get restored
correctly. Some interrupt controllers do not allow the current mask to
be read back, so you have to keep track of it in software. There is
some additional interrupt handling overhead.

In addition, the above loop would have to be changed slightly to
search in priority order. Something like:

    for (priority = 0; priority < registered_interrupts; priority++) {
        if (irq_status & bit[priority]) {
            return vector[priority];
        }
    }

That copes with the case where interrupts 3 and 5 go off at the same
time but 5 should be handled first. Interrupt 3 would be masked while
5 is being handled, then unmasked causing interrupt 3 to be handled.
Ideally this would not be necessary because the hardware has been
designed such that the highest priority interrupts have been given the
lower numbers, allowing the simpler loop to be used.

I am not sure how this would fit in with the current ARM interrupt
handling code.

Bart

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]