Linux Interrupt Architecture

Source: Internet
Author: User

1. Interrupt Processing architecture

The Linux kernel uses an array of IRQ_DESC structures to describe these interrupts by uniformly numbering all interrupts.

array declarations are /linux/kernel/irq/handle.c, in which #define NR_IRQS - , defined in /linux/include/ asm/irq.h in

1 /*2 * Linux has a controller-independent interrupt architecture.3 * Every controller has a ' controller-template ', which is used4 * By the main code to do the right thing. Each driver-visible5 * Interrupt source is transparently wired to the appropriate6 * Controller. Thus drivers need not being aware of the7 * Interrupt-controller.8  *9 * The code is designed to being easily extended with new/differentTen * Interrupt controllers, without have to do assembly magic or One * have to touch the generic code. A  * - * Controller mappings for all interrupt sources: -  */ the structIrq_desc Irq_desc[nr_irqs] __CACHELINE_ALIGNED_IN_SMP = { -[0... nr_irqs-1] = { -. Status =irq_disabled, -. Chip = &No_irq_chip, +. HANDLE_IRQ =Handle_bad_irq, -. depth =1, +.Lock= __spin_lock_unlocked (irq_desc->Lock), A #ifdef CONFIG_SMP at. affinity =Cpu_mask_all - #endif -     } -};
The data type of the IRQ_DESC structure is in/linuxinclude/linux/irq.hDefined in,
1 structIrq_desc {2 irq_flow_handler_t Handle_irq;3     structIrq_chip *chip;4     structMSI_DESC *Msi_desc;5     void*Handler_data;6     void*Chip_data;7     structIrqaction *action;/*IRQ Action list*/8UnsignedintStatus/*IRQ Status*/9 TenUnsignedintDepth/*nested IRQ Disables*/ OneUnsignedintwake_depth;/*nested wake enables*/ AUnsignedintIrq_count;/*For detecting broken IRQs*/ -Unsignedintirqs_unhandled; -spinlock_tLock; the #ifdef CONFIG_SMP - cpumask_t Affinity; -UnsignedintCPU; - #endif + #ifDefined (CONFIG_GENERIC_PENDING_IRQ) | | Defined (config_irqbalance) - cpumask_t Pending_mask; + #endif A #ifdef CONFIG_PROC_FS at     structProc_dir_entry *dir; - #endif -     Const Char*name; -} ____CACHELINE_INTERNODEALIGNED_IN_SMP;

HANDLE_IRQ is the entry for this or this set of interrupt handler functions. When an interrupt occurs, the total entry function ASM_DO_IRQ calls the corresponding Irq_desc array item HANDLE_IRQ According to the break number.

typedef    voidint IRQ,                struct irq_desc *desc);

HANDLE_IRQ uses functions in the chip structure to clear, mask, or re-enable interrupts, and to invoke interrupt handlers that the user registers in the action list. The irq_chip structure type is also defined in Include/linux/irq.h, where the members are mostly used to manipulate the underlying hardware, such as setting registers to mask interrupts, enable interrupts, clear interrupts, and so on. Note that the member name here will appear in the/proc/interrupts.

structIrq_chip {Const Char*name; unsignedint(*startup) (unsignedintIRQ); void(*shutdown) (unsignedintIRQ); void(*enable) (unsignedintIRQ); void(*disable) (unsignedintIRQ); void(*ack) (unsignedintIRQ); void(*mask) (unsignedintIRQ); void(*mask_ack) (unsignedintIRQ); void(*unmask) (unsignedintIRQ); void(*EOI) (unsignedintIRQ); void(*end) (unsignedintIRQ); void(*set_affinity) (unsignedintIRQ, cpumask_t dest); int(*retrigger) (unsignedintIRQ); int(*set_type) (unsignedintIRQ, unsignedintFlow_type); int(*set_wake) (unsignedintIRQ, unsignedintOn ); /*currently used only by UML, might disappear one day.*/#ifdef Config_irq_release_methodvoid(*release) (unsignedintIrqvoid*dev_id);#endif    /** For compatibility,->typename are copied into->name.     * would disappear. */    Const Char*TypeName;};

The irqaction structure type in the IRQ_DESC structure is defined in include/linux/iterrupt.h. Each interrupt handler that is registered by the user is represented by a irqaction structure, where an interrupt, such as a shared interrupt, can have multiple processing functions, and their irqaction structure is linked to a linked list, with the action as the table header. The irqation structure is defined in Linux/include/linux/interrupt.h as follows:

 typedef irqreturn_t (*irq_handler_t) (int ,  void  * struct      irqaction {irq_handler_t handler;    unsigned  long   flags;    cpumask_t Mask;  const  char  *    name;     void  *dev_id;     struct  irqaction *next;     int   IRQ;  struct  proc_dir_entry *dir;};  

IRQ_DESC structure Array, its members "struct irq_chip *chip" "struct irqaction *action", these 3 kinds of data structures constitute the framework of the interrupt processing system. Describes the diagram of the Linxu Interrupt processing architecture:

The interrupt processing process is as follows
(1) When an interrupt occurs, the CPU executes the exception vector VECTOR_IRQ code
(2) in VECTOR_IRQ, the total entry function of interrupt processing is eventually called ASM_DO_IRQ
(3) ASM_DO_IRQ calls the HANDLE_IRQ in the IRQ_DESC array item according to the interrupt number.
(4) HANDLE_IRQ uses the functions in the chip member to set up the hardware, such as clearing interrupts, preventing interrupts, re-enabling interrupts, etc.
(5) Handle_irq one-by-one call to the handler that the user registers in the Aciton linked list
The initialization of the interrupt architecture is the construction of these data structures, such as HANDLE_IRQ, chip, and so on in the Irq_desc array, and the action linked list is constructed when the user registers an outage, and the user unloads the interrupt by removing unwanted items from the action list. 2. Initialization of the interrupt processing architectureThe INIT_IRQ function is used to initialize the interrupt processing architecture, and the code is in ARCH/ARM/KERNEL/IRQ.C
void __init Init_irq (void) {    int  IRQ;      for 0; IRQ < Nr_irqs; irq++)        |= irq_norequest | irq_noprobe, #ifdef CONFIG_SMP     = Cpu_mask_all;     = smp_processor_id (); #endif     Init_arch_irq ();}

Below is a simple analysis of the INIT_ARCH_IRQ (), the acquisition process and the sequence of calls

1 /*2 The origin of Init_arch_irq ()3 defines an empty function pointer void (*INIT_ARCH_IRQ) (void) __initdata = NULL;4 */5Asmlinkagevoid__init Start_kernel (void)6-->setup_arch (&command_line);7--&GT;INIT_ARCH_IRQ = mdesc->Init_irq;8-Init_irq (); 9--&GT;INIT_ARCH_IRQ ()//namely MDESC->INIT_IRQ=S3C24XX_INIT_IRQ

The above MACHINE_DESC structure is obtained in the following macro/linux/arch/arm/mach-s3c2410/mach-bast.c, and the MACHINE_DESC structure is analyzed later.

 Machine_start (BAST,  " simtec-bast  Span style= "COLOR: #800000" > " )  // Span style= "COLOR: #008000" >maintainer:ben dooks <[email protected]> . Phys_io = S3c2410_pa_uart,. Io_pg_offst  = (((u32) s3c24xx_va_uart) >> 18 ) & 0XFFFC  ,. boot_params  = S3c24 10_SDRAM_PA + 0x100  ,. Map_io  = Bast_map_io,. INIT_IRQ  = S3c24xx_init_irq,. Init_machine  = Bast_init,. Timer  = &s3c24xx_ti Mer,machine_end  

For the s3c2440 Development Board, this function is S3C24XX_INIT_IRQ, the INIT_IRQ member in the porting MACHINE_DESC structure points to this function S3c24xx_init_irq function in arch/arm/ PLAT-S3C24XX/IRQ.C, which sets the chip-related data structure (irq_desc[irq].chip) for all interrupts and sets the processing function entry (IRQ_DESC[IRQ].HANDLE_IRQ).

Linux Interrupt Architecture

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.