Processing on AMD64 Systems
Let us first turn our attention to how do_IRQ is implemented on AMD64 systems. This variant is simpler as compared to IA-32, and many other modern architectures use a similar approach. The code flow diagram is shown in Figure 14-9.
set_irq_regs irq_enter generic_handle_irq irq_exit
Figure 14-9: Code flow diagram for do_iRQ. on AMD64 systems.
The prototype of the function is as follows: arch/x86/kernel/irq_64.c asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
The low-level assembler code is responsible to pass the current state of the register set to the function, and the first task of do_IRQ is to save a pointer to them in a global per-CPU variable using set_irq_regs (the old pointer that was active before the interrupt occurred is preserved for later). Interrupt handlers that require access to the register set can access them from there.
irq_enter is then responsible to update some statistics; for systems with dynamic ticks, the global jiffies time-keeping variable is updated if the system has been in a tickless state for some time (more about dynamic ticks follows in Section 15.5.). Calling the ISRs registered for the IRQ in question is then delegated to the architecture-independent function generic_handle_irq which calls irq_desc[irq]->handle_irq to activate the flow control handler.
irq_exit is then responsible for some statistics bookkeeping, but also calls (assuming the kernel is not still in interrupt mode because it is processing a nested interrupt) do_softirq to service any pending software IRQs. This mechanism is discussed in more detail in Section 14.2. Finally, another call to set_irq_regs restores the pointer to struct regs to the setting that was active before the call. This ensures that nested handlers work correctly.
Continue reading here: Processing on IA32 Systems
Was this article helpful?