3.6.3. Generic Interrupt Controller

Generic Interrupt Controller (GIC) provides a set of hardware resources for managing interrupts in a single-core or multi-core system, as shown in Figure 3.9.

The GIC provides memory-mapped registers that can be used to manage interrupt sources and, in multi-core systems, for routing interrupts to individual cores.

Figure 3.9. Generic Interrupt Controller

To view this graphic, your browser must support the SVG format. Either install a browser with native support, or install an appropriate plugin such as Adobe SVG Viewer.


The GIC enables software to perform the following tasks:

Interrupts can be of the following types:

Software Generated Interrupt (SGI)

This interrupt is generated explicitly by software by writing to a dedicated distributor register, the Software Generated Interrupt Register. It is most commonly used for inter-core communication. SGIs can be targeted at all, or at a selected group of cores in the system. Interrupt numbers 0-15 are reserved for this. The software manages the exact interrupt number used for communication.

Private Peripheral Interrupt (PPI)

This interrupt is generated by a peripheral that is private to an individual core. Interrupt numbers 16-31 are reserved for this. PPIs identify interrupt sources private to the core, and are independent of the same source on another core, for example, per-core timer.

Shared Peripheral Interrupt (SPI)

This interrupt is generated by a peripheral that the Interrupt Controller can route to more than one core. Interrupt numbers 32-1020 are used for this. SPIs are used to signal interrupts from various peripherals accessible across the whole system.

Initialization

Both the distributor and the CPU interfaces are disabled at reset. The GIC must be initialized after reset, before it can deliver interrupts to the core.

In the distributor, software must configure the priority, target, and security, and enable individual interrupts. The distributor block must subsequently be enabled through its control register. For each CPU interface, software must program the priority mask and preemption settings.

Each CPU interface block must be enabled through its control register. This prepares the GIC to deliver interrupts to the core.

Before interrupts are expected in the core, software prepares the core to take interrupts by setting a valid interrupt vector in the vector table, and clearing interrupt mask bits in the CPSR.

You can disable the entire interrupt mechanism in the system by disabling the distributor block. You can disable interrupt delivery to an individual core by disabling its CPU interface block, or by setting mask bits in the CPSR of that core. You can also disable or enable individual interrupts in the distributor.

For an interrupt to reach the core, the individual interrupt, distributor, and CPU interface must all be enabled, and the CPSR interrupt mask bits must be cleared.

Interrupt handling

When the core takes an interrupt, it jumps to the top-level interrupt vector obtained from the vector table and begins execution.

The top-level interrupt handler reads the Interrupt Acknowledge Register from the CPU Interface block to obtain the interrupt ID.

The read returns the interrupt ID, and causes the interrupt to be marked as active in the distributor. When the interrupt ID is known, the top-level handler can dispatch a device-specific handler to service the interrupt.

When the device-specific handler finishes execution, the top-level handler writes the same interrupt ID to the end of the Interrupt register in the CPU Interface block, indicating the end of interrupt processing.

Apart from removing the active status, which makes the final interrupt status either Inactive or Pending, if the state was Active and Pending, this enables the CPU Interface to forward more pending interrupts to the core. This concludes the processing of a single interrupt.

There can be more than one interrupt waiting to be serviced on the same core. However, the CPU Interface can signal only one interrupt at a time. The top-level interrupt handler repeats the above sequence until it reads the special interrupt ID value 1023, indicating that there are no more interrupts pending at this core. This special interrupt ID is called the spurious interrupt ID.

The spurious interrupt ID is a reserved value, and cannot be assigned to any device in the system. When the top-level handler reads the spurious interrupt ID, it can complete its execution, and prepare the core to resume the task it was doing before taking the interrupt.

Copyright © 2014 ARM. All rights reserved.ARM DAI0425
Non-ConfidentialID080414