Changeset 7bcfbbc in mainline


Ignore:
Timestamp:
2007-04-07T23:30:59Z (18 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ac88c93
Parents:
7e58979
Message:

support the possibility to send EOI or Interrupt Acknowledgement
prior to processing the interrupt
(this is essential on some architectures to prevent preemption deadlock)

Location:
kernel
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/amd64/src/interrupt.c

    r7e58979 r7bcfbbc  
    157157       
    158158        int inum = n - IVT_IRQBASE;
     159        bool ack = false;
    159160        ASSERT(inum < IRQ_COUNT);
    160161        ASSERT((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1));
    161 
     162       
    162163        irq_t *irq = irq_dispatch_and_lock(inum);
    163164        if (irq) {
     
    165166                 * The IRQ handler was found.
    166167                 */
     168                 
     169                if (irq->preack) {
     170                        /* Send EOI before processing the interrupt */
     171                        trap_virtual_eoi();
     172                        ack = true;
     173                }
    167174                irq->handler(irq, irq->arg);
    168175                spinlock_unlock(&irq->lock);
     
    175182#endif
    176183        }
    177         trap_virtual_eoi();
     184       
     185        if (!ack)
     186                trap_virtual_eoi();
    178187}
    179188
  • kernel/arch/ia32/src/drivers/i8254.c

    r7e58979 r7bcfbbc  
    8383{
    8484        irq_initialize(&i8254_irq);
     85        i8254_irq.preack = true;
    8586        i8254_irq.devno = device_assign_devno();
    8687        i8254_irq.inr = IRQ_CLK;
  • kernel/arch/ia32/src/interrupt.c

    r7e58979 r7bcfbbc  
    177177       
    178178        int inum = n - IVT_IRQBASE;
     179        bool ack = false;
    179180        ASSERT(inum < IRQ_COUNT);
    180181        ASSERT((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1));
    181 
     182       
    182183        irq_t *irq = irq_dispatch_and_lock(inum);
    183184        if (irq) {
     
    185186                 * The IRQ handler was found.
    186187                 */
     188                 
     189                if (irq->preack) {
     190                        /* Send EOI before processing the interrupt */
     191                        trap_virtual_eoi();
     192                        ack = true;
     193                }
    187194                irq->handler(irq, irq->arg);
    188195                spinlock_unlock(&irq->lock);
     
    195202#endif
    196203        }
    197         trap_virtual_eoi();
     204       
     205        if (!ack)
     206                trap_virtual_eoi();
    198207}
    199208
  • kernel/arch/ia32/src/smp/apic.c

    r7e58979 r7bcfbbc  
    170170       
    171171        irq_initialize(&l_apic_timer_irq);
     172        l_apic_timer_irq.preack = true;
    172173        l_apic_timer_irq.devno = device_assign_devno();
    173174        l_apic_timer_irq.inr = IRQ_CLK;
  • kernel/arch/ia32xen/src/interrupt.c

    r7e58979 r7bcfbbc  
    177177       
    178178        int inum = n - IVT_IRQBASE;
     179        bool ack = false;
    179180        ASSERT(inum < IRQ_COUNT);
    180181        ASSERT((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1));
    181 
     182       
    182183        irq_t *irq = irq_dispatch_and_lock(inum);
    183184        if (irq) {
     
    185186                 * The IRQ handler was found.
    186187                 */
     188                 
     189                if (irq->preack) {
     190                        /* Send EOI before processing the interrupt */
     191                        trap_virtual_eoi();
     192                        ack = true;
     193                }
    187194                irq->handler(irq, irq->arg);
    188195                spinlock_unlock(&irq->lock);
     
    195202#endif
    196203        }
    197         trap_virtual_eoi();
     204       
     205        if (!ack)
     206                trap_virtual_eoi();
    198207}
    199208
  • kernel/arch/ppc32/src/interrupt.c

    r7e58979 r7bcfbbc  
    6161       
    6262        while ((inum = pic_get_pending()) != -1) {
     63                bool ack = false;
    6364                irq_t *irq = irq_dispatch_and_lock(inum);
    6465                if (irq) {
     
    6667                         * The IRQ handler was found.
    6768                         */
     69                       
     70                        if (irq->preack) {
     71                                /* Acknowledge the interrupt before processing */
     72                                pic_ack_interrupt(inum);
     73                                ack = true;
     74                        }
     75                       
    6876                        irq->handler(irq, irq->arg);
    6977                        spinlock_unlock(&irq->lock);
     
    7684#endif
    7785                }
    78                 pic_ack_interrupt(inum);
     86               
     87                if (!ack)
     88                        pic_ack_interrupt(inum);
    7989        }
    8090}
  • kernel/arch/ppc64/src/interrupt.c

    r7e58979 r7bcfbbc  
    6161       
    6262        while ((inum = pic_get_pending()) != -1) {
     63                bool ack = false;
    6364                irq_t *irq = irq_dispatch_and_lock(inum);
    6465                if (irq) {
     
    6667                         * The IRQ handler was found.
    6768                         */
     69                       
     70                        if (irq->preack) {
     71                                /* Acknowledge the interrupt before processing */
     72                                pic_ack_interrupt(inum);
     73                                ack = true;
     74                        }
     75                       
    6876                        irq->handler(irq, irq->arg);
    6977                        spinlock_unlock(&irq->lock);
     
    7684#endif
    7785                }
    78                 pic_ack_interrupt(inum);
     86               
     87                if (!ack)
     88                        pic_ack_interrupt(inum);
    7989        }
    8090}
  • kernel/generic/include/ddi/irq.h

    r7e58979 r7bcfbbc  
    122122         */
    123123        SPINLOCK_DECLARE(lock);
     124       
     125        /** Send EOI before processing the interrupt.
     126         *  This is essential for timer interrupt which
     127         *  has to be acknowledged before doing preemption
     128         *  to make sure another timer interrupt will
     129         *  be eventually generated.
     130         */
     131        bool preack;
    124132
    125133        /** Unique device number. -1 if not yet assigned. */
     
    128136        /** Actual IRQ number. -1 if not yet assigned. */
    129137        inr_t inr;
    130         /** Trigger level of the IRQ.*/
     138        /** Trigger level of the IRQ. */
    131139        irq_trigger_t trigger;
    132140        /** Claim ownership of the IRQ. */
  • kernel/generic/src/ddi/irq.c

    r7e58979 r7bcfbbc  
    139139        link_initialize(&irq->link);
    140140        spinlock_initialize(&irq->lock, "irq.lock");
     141        irq->preack = false;
    141142        irq->inr = -1;
    142143        irq->devno = -1;
Note: See TracChangeset for help on using the changeset viewer.