Question

I wanted to know how interrupt handling works from the point any device is interrupted.I know of interrupt handling in bits and pieces and would like to have clear end to end picture of interrupt handing.Let me put across what little I know about interrupt handling.

Suppose an FPGA device is interrupted through electrical lines and get some data .Device driver for this FPGA device already had code (Interrupt handler) registered using request_irq function.

So now FPGA device have an IRQ line which it get after to call request_irq ,using this IRQ line device send data to the General Interrupt controller and GIC will do many to one translation of IRQ lines and send the signal to CPU core which then call below minimal code

IRQ_handler
SUB       lr, lr, #4       ; modify LR
SRSFD     #0x12!           ; store SPSR and LR to IRQ mode stack
PUSH      {r0-r3, r12}     ; store AAPCS registers on to the IRQ mode stack
BL        IRQ_handler_to_specific_device
POP       {r0-r3, r12}     ; restore registers
RFEFD     sp!              ; and return from the exception using pre-modified LR 

IRQ_handler_to_specific_device is nothing is what we registered in Device driver using request_irq() call.

I still don't how CPU core comes to know about the interrupt source?(from which device interrupt is coming)

Also what is role of call like do_irq and shared interrupts works?

Need some help in understanding end to end picture on how interrupts are handled on ARM architecture?

Was it helpful?

Solution

The GIC is divided into two sections. The first is called the distributor. This is global to the system. It has several interrupt sources physically routed to it; although it maybe within an SOC package. The second section is replicated per-CPU and it called the cpu interface. The distributor has logic on how to distribute the shared peripheral interrupts or SPI. These are the type of interrupt your question is asking about. They are global hardware interrupts.

In the context of Linux, this is implemented in irq-gic.c. There is some documentation in gic.txt. Of specific interest,

  • reg : Specifies base physical address(s) and size of the GIC registers. The first region is the GIC distributor register base and size. The 2nd region is the GIC cpu interface register base and size.

The distributor must be accessed globally, so care must be taken to manage it's registers. The CPU interface has the same physical address for each CPU, but each CPU has a separate implementation. The distributor can be set up to route interrupts to specific CPUs (including multiples). See: gic_set_affinity() for example. It is also possible for any CPU to handle the interrupt. The ACK register will allocate IRQ; the first CPU to read it, gets the interrupt. If multiple IRQs pend and there are two ACK reads from different CPUs, then each will get a different interrupt. A third CPU reading would get a spurious IRQ.

As well, each CPU interface has some private interrupt sources, that are used for CPU-to-CPU interrupts as well as private timers and the like. But I believe the focus of the question is how a physical peripheral (unique to a system) gets routed to a CPU in an SMP system.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top