Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 7be6379 in mainline


Ignore:
Timestamp:
2013-02-06T08:00:50Z (9 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master
Children:
d5b9e8d
Parents:
b5e17b1
Message:

Handle only unmasked pending interrupts.

Location:
kernel/arch/mips32
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/mips32/include/cp0.h

    rb5e17b1 r7be6379  
    4545#define cp0_status_im_shift  8
    4646#define cp0_status_im_mask   0xff00
     47
     48#define cp0_cause_ip_shift  8
     49#define cp0_cause_ip_mask   0xff00
    4750
    4851#define cp0_cause_excno(cause)   ((cause >> 2) & 0x1f)
  • kernel/arch/mips32/src/exception.c

    rb5e17b1 r7be6379  
    165165static void interrupt_exception(unsigned int n, istate_t *istate)
    166166{
     167        uint32_t ip;
     168        uint32_t im;
     169
    167170        /* Decode interrupt number and process the interrupt */
    168         uint32_t cause = (cp0_cause_read() >> 8) & 0xff;
     171        ip = (cp0_cause_read() & cp0_cause_ip_mask) >> cp0_cause_ip_shift;
     172        im = (cp0_status_read() & cp0_status_im_mask) >> cp0_status_im_shift;
    169173       
    170174        unsigned int i;
    171175        for (i = 0; i < 8; i++) {
    172                 if (cause & (1 << i)) {
     176
     177                /*
     178                 * The interrupt could only occur if it is unmasked in the
     179                 * status register. On the other hand, an interrupt can be
     180                 * apparently pending even if it is masked, so we need to
     181                 * check both the masked and pending interrupts.
     182                 */
     183                if (im & ip & (1 << i)) {
    173184                        irq_t *irq = irq_dispatch_and_lock(i);
    174185                        if (irq) {
Note: See TracChangeset for help on using the changeset viewer.