Understanding the linux kernel-ch4-Interrupt Handling

Interrupt handling depends on the type of interrupt.  three main classes of interrupts:
I/O interrupts
An I/O device requires attention; the corresponding interrupt handler 
must query the device to determine the proper course of action.

Timer interrupts





Some timer, either a local APIC timer or an external timer, has issued an interrupt; 
this kind of interrupt tells the kernel that a fixed-time interval has elapsed. 
These interrupts are handled mostly as I/O interrupts; 


Interprocessor interrupts




A CPU issued an interrupt to another CPU of a multiprocessor system








I/O Interrupt Handling





Interrupt handler flexibility is achieved in two distinct ways


IRQ sharing





IRQ dynamic allocation













Linux divides the actions to be performed following an interrupt into three classes:
Critical






Noncritical





Noncritical deferrable













all I/O interrupt handlers perform the same four basic actions:

1. Save the IRQ value and the register's contents on the Kernel Mode stack.
2. Send an acknowledgment to the PIC that is servicing the IRQ line, 

   thus allowing it to issue further interrupts



3. Execute the interrupt service routines (ISRs) associated with all the devices that share the IRQ.
4. Terminate by jumping to the ret_from_intr( ) address.










Interrupt vectors





physical IRQs may be assigned any vector in the range 32-238. 
However, Linux uses vector 128 to implement system calls.

The IBM-compatible PC architecture requires that some devices 

be statically connected to specific IRQ lines. In particular:

· The interval timer device must be connected to the IRQ 0 line

· The slave 8259A PIC must be connected to the IRQ 2 line 

   (although more advanced PICs are now being used, Linux still supports 8259A-style PICs)
· The external mathematical coprocessor must be connected to the IRQ 13 line
· In general, an I/O device can be connected to a limited number of IRQ lines.








There are three ways to select a line for an IRQ-configurable device:

· By setting hardware jumpers (only on very old device cards).


· By a utility program shipped with the device and executed when installing it. 
  Such a program may either ask the user to select an available IRQ number 
  or probe the system to determine an available number by itself

· By a hardware protocol executed at system startup.


   Peripheral devices declare which interrupt lines they are ready to use;









IRQ data structures





irq_desc_t






irq_desc














/*






 * Interrupt controller descriptor. This is all we need


 * to describe about the low-level hardware. 



 */






struct hw_interrupt_type {






const char * typename;





unsigned int (*startup)(unsigned int irq);




void (*shutdown)(unsigned int irq);




void (*enable)(unsigned int irq);




void (*disable)(unsigned int irq);




void (*ack)(unsigned int irq);




void (*end)(unsigned int irq);




void (*set_affinity)(unsigned int irq, cpumask_t dest);

};






typedef struct irq_desc {






unsigned int status; /* IRQ status */



hw_irq_controller *handler;




struct irqaction *action; /* IRQ action list */




unsigned int depth; /* nested irq disables */



unsigned int irq_count; /* For detecting broken interrupts */

unsigned int irqs_unhandled;




spinlock_t lock;




} ____cacheline_aligned irq_desc_t;




















/*






 * IRQ line status.





 */






#define IRQ_INPROGRESS 1 /* IRQ handler active - do not enter! */

#define IRQ_DISABLED 2 /* IRQ disabled - do not enter! */


#define IRQ_PENDING 4 /* IRQ pending - replay on enable */

#define IRQ_REPLAY 8 /* IRQ has been replayed but not acked yet */

#define IRQ_AUTODETECT 16 /* IRQ is being autodetected */


#define IRQ_WAITING 32 /* IRQ not yet seen - for autodetection */

#define IRQ_LEVEL 64 /* IRQ level triggered */



#define IRQ_MASKED 128 /* IRQ masked - shouldn't be seen again */

#define IRQ_PER_CPU 256 /* IRQ is per CPU */











void disable_irq(unsigned int irq)




void enable_irq(unsigned int irq)




void __init init_IRQ(void)            
               
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章