ARM Interrupt Controllers - The gateway to CPU's attention

Saravana Pandian Annamalai
14 April 2024
Categories:Technology,  Embedded Hardware,  Embedded Software,  Protocols

With an understanding of ARM registers and Exception model, now we are ready to explore the ARM interrupt controllers. These are the modules that sit in between the interrupt sources (peripherals) and ARM cores deciding how to route the interrupts to. ARM interrupt controllers are a fundamental part of ARM architecture design and must be well understood before diving into firmware-level interrupt handling. Embien's product engineering services include ARM Cortex-A based embedded design spanning interrupt controller configuration, ARM interrupt controllers selection, and BSP bringup for custom SoCs. Consulting with the NXP partner and design house team at Embien covers ARM interrupt controllers integration for NXP i.MX and LPC product families.

The ARM core accepts only two input signals handling unscheduled interrupts from the external systems – nIRQ and nFIQ. If IRQ (interrupts) is asserted, the system enters IRQ mode as discussed in the ARM architecture exception model or if FIQ (Fast Interrupt) is asserted, FIQ mode is entered.

It is up to the ARM licensees i.e. SoC/MCU manufacturer to decide the mechanism to route the interpret signals to the core. There are many ways to implement the ARM interrupt controllers, each of which is discussed in detail in this blog.

Vendor Specific Model

In the early ARM implementations where there used to be only one core in general, the logic for this routing of interrupts to the core is done by the SoC manufacturer mostly based on their design philosophy. Unlike standardized ARM interrupt controllers such as GIC or NVIC, vendor-specific models use a custom set of ARM registers for interrupt management. More likely there will be a set of following registers

  • RAW Interrupt Status register
  • Interrupt Enable Register
  • Interrupt Status Register
  • IRQ Priority Encoding
  • FIQ/IRQ Selection

Up on assertion of any interrupt line, the interrupt source is checked if it is configured as FIQ. If so, the signal is routed to the core immediately. If it is an IRQ interrupt, ARM interrupt status is updated. If multiple interrupts occur simultaneously, the priority is resolved between other pending interrupts and finally the core is given the interrupt signal.

The below diagram gives a model implementation for the Interrupt Controller by Freescale called the Interrupt Collector (ICOLL) used in Freescale/NXP iMx233/iMx28 series of MCUs.

Freescale Interrupt Collector

Vendor specific Interrupt Controller

Vectored Interrupt Controller – VIC

ARM itself came up with a model called Vectored Interrupt Controller (VIC) — one of the earliest standardized ARM interrupt controllers. Sitting directly on the AMBA High Speed bus, the latency is significantly reduced. Being an early generation controller, it supports 32 interrupt sources, each of which can be routed to either FIQ or IRQ signals. A unique feature of VIC is that, as its name suggests, it supports 16 vectored interrupts. In this there are 16 registers where the address of the corresponding interrupt service routines (ISR) can be saved. Based on the priority, the VIC identifies the high priority interrupt and loads its ISR address to a register called VICVectAddr. The firmware can simply use a LDR PC instruction to jump to this ISR. This saves a lot of software effort in branching to the ISR there by reducing latency.

Interrupt Controller from ARM

Vectored Interrupt Controller (VIC)

But VIC supports only level sensitive interrupts that must remain active HIGH till the ISR services it. Thus, for these reasons, many SoC designers preferred their own implementation rather than the VIC.

Generic Interrupt Controller – GIC

As processors evolved, soon the number of interrupts became quite large and also it was not uncommon to have more than 1 core (either symmetric or asymmetric), there was a need for a more standardized way of handling interrupts across ARM interrupt controllers.

ARM defines the Generic Interrupt Controller GIC for ARM processors that suits this need. Though vendors are still free to choose their own mechanism, the Generic Interrupt Controller GIC for ARM processors has become very popular and is almost present in all modern SoCs. It consists of primarily two components – Distributor and CPU interfaces. The primary functionalities of the same include

Distributor:

This is the peripheral facing component of the Generic Interrupt Controller GIC for ARM processors that is available as only one implementation (instance). It is responsible for managing interrupts in the whole system and decides priorities between them and routing mechanism of the same.

CPU Interfaces:

For each CPU core available, there is a corresponding CPU Interface present bridging the Distributor interface with the core. It implements the priority masking for the processor. This per-core architecture is what makes the Generic Interrupt Controller GIC for ARM processors essential for ARM Cortex-A based embedded design with multiple cores.

The below diagram explains the same.

ARM\

ARM Generic Interrupt Controller (GIC)

The interrupts are identified by unique ID and could be in any one of the following 4 states (as explained by the GIC Architecture Specification):

  • Inactive: An interrupt that is not active or pending.
  • Pending: An interrupt from a source to the GIC that is recognized as asserted in hardware or generated by software and is waiting to be serviced by a target processor.
  • Active: An interrupt from a source to the GIC that has been acknowledged by a processor, and is being serviced but has not completed.
  • Active and pending: A processor is servicing the interrupt and the GIC has a pending interrupt from the same source.

Based on the source, there are three major types of interrupts are defined.

Shared Peripheral Interrupts – SPI: These interrupts sources are typically from different peripherals in the system. They can be routed to (i.e shared with) any one or more of the cores as per the requirement and will be handled suitably. For example, UART0 and UART1 interrupts could be SPI and configured in the Distributor to be routed to two available cores. Up on UART0 interrupt, the signal is routed to first available processor. If at that instance, UART1 interrupt is received, the distributor routes it to the other core for handling.

These are assigned Interrupt ID from 32 to 1019.

Software Generated Interrupts – SGI: ARM defines interrupt IDs 0 through 15 specifically for Inter processor communication. It is possible an SGI can be routed to one or more processors through the Distributor.

The Interrupts 0 to 31 are banked by the distributor for each CPU Interface i.e. each processor sees them differently and are identified by the CPUID. For example, PPI 16 could be pending in CPU0 but not in CPU1. Whereas, in case of the SPI, it will be same across the CPU's as they are not banked.

Irrespective of all these, each core is provided signal through either nIRQ or nFIQ lines for interrupting program execution.

Later ARM introduced different versions of GIC such as GICv2, GICv3 and GICv4. Each of the revisions increased the capability of the IP such as increased number of supported cores, larger Interrupt ID, support for virtualization, and so on. These enhancements make the Generic Interrupt Controller GIC for ARM processors suitable for even the largest heterogeneous SoCs used in ARM Cortex-A based embedded design.

Nested Vectored Interrupt Controller – NVIC

While the above implementations of ARM interrupt controllers are suitable for powerful processors, there is a need for specialized handling in microcontroller profiles that typically run at sub-100MHz speed and with few tens of kilobytes of RAM and flash. It is important to reduce the interrupt latency and to leverage the fact that the number of peripherals is less and hence fewer interrupt sources. For that, ARM defines a NVIC model for the Cortex-M implementations as one of the specialized ARM interrupt controllers.

In Cortex-M implementation, the interrupt service routine addresses are to be provided in a set of consecutive addresses at offsets corresponding to the vector number. As soon as the interrupt signals are received, the NVIC finds the ISR corresponding to the highest priority interrupt and jumps to it. The ARM registers involved in NVIC operation include NVIC_ISER (enable), NVIC_ICER (clear), NVIC_ISPR (set pending), and NVIC_IPR (priority) — all memory-mapped ARM registers in the System Control Space.

The Cortex-M core accepts only nIRQ interrupt and there is no option for a FIQ.

With our understanding of the hardware implementation of ARM interrupt controllers and ARM architecture principles, in the upcoming blogs, we will discuss software mechanism in handling interrupts in ARM architectures.

Related Pages

DIGITAL TRANSFORMATION SERVICES

Embien's digital transformation services include ARM Cortex-A based embedded design with Generic Interrupt Controller GIC for ARM processors and full ARM interrupt controllers integration.

Read More

SEMICONDUCTOR DEVELOPMENT SUPPORT

Semiconductor development support covering ARM architecture bring-up, ARM registers configuration, and ARM interrupt controllers integration for custom SoC designs.

Read More

FPGA-BASED CONTROLLER FOR ANTENNA FRONT-END (AFE) SYSTEM

Case study: FPGA-based controller development for antenna front-end system using ARM interrupt controllers and ARM architecture for real-time signal processing.

Read More

Subscribe to our Blog