BCM2835 Interrupt Controller

From Embedded Xinu
Revision as of 22:08, 31 July 2013 by Ebiggers (talk | contribs) (Created page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

The BCM2835 Interrupt Controller is a memory-mapped peripheral available on the BCM2835 System-on-a-Chip used in the Raspberry Pi. It allows software to enable or disable specific IRQs. Each IRQ usually corresponds to some sort of device available on the chip.

Hardware Details

It is important to understand that on the BCM2835, some IRQs are shared between the ARM CPU and VideoCore GPU. This interrupt controller controls both these shared IRQs as well as a few ARM-specific IRQs, and the layout of the registers reflects this separation. Some of the shared IRQs are already enabled by the GPU and therefore should not be enabled. However, this interrupt controller is only used by the ARM to control which interrupts actually get routed to the ARM; the GPU most likely has its own interrupt controller.

BCM2835 Interrupt Controller registers
Offset Name Description
0x00 IRQ_basic_pending Bitmask of pending ARM-specific IRQs, as well as additional bits (not currently used by Embedded Xinu) to accelerate interrupt handling.
0x04 IRQ_pending_1 Bitmask of pending shared IRQs 0-31
0x08 IRQ_pending_2 Bitmask of pending shared IRQs 32-63
0x0C FIQ_control TODO
0x10 Enable_IRQs_1 Write 1 to the corresponding bit(s) to enable one or more shared IRQs in the range 0-31
0x14 Enable_IRQs_2 Write 1 to the corresponding bit(s) to enable one or more shared IRQs in the range 32-63
0x18 Enable_Basic_IRQs Write 1 to the corresponding bit(s) to enable one or more ARM-specific IRQs
0x1C Disable_IRQs_1 Write 1 to the corresponding bit(s) to disable one or more shared IRQs in the range 0-31
0x20 Disable_IRQs_2 Write 1 to the corresponding bit(s) to disable one or more shared IRQs in the range 32-63
0x24 Disable_Basic_IRQs Write 1 to the corresponding bit(s) to disable one or more ARM-specific IRQs
BCM2835 IRQs. Note: this currently is an incomplete list and only attempts to document the ones we have actually tested in our work with Embedded Xinu.
IRQ Device Notes
0 System Timer Compare Register 0 Do not enable this IRQ; it's already used by the GPU.
1 System Timer Compare Register 1 See BCM2835 System Timer.
2 System Timer Compare Register 2 Do not enable this IRQ; it's already used by the GPU.
3 System Timer Compare Register 3 See BCM2835 System Timer.
9 USB Controller This is the only USB IRQ because all communication with USB devices happens through the USB Controller. See USB Host Controller (Synopsys DesignWare OTG).
55 PCM Audio
57 PL011 UART See PL011 UART.
62 SD Host Controller

Notes:

  • Software cannot "clear" interrupts using the interrupt controller. Instead, interrupts must be cleared in a device-specific way.
  • Although some shared interrupts appear in the IRQ_Basic_Pending register as well as in the IRQ_Pending_1 or IRQ_Pending_2 registers, they cannot be enabled or disabled in Enable_Basic_IRQs or Disable_Basic_IRQs.

Use in Embedded Xinu

Embedded Xinu uses the BCM2835 Interrupt Controller to implement enable_irq() and disable_irq(). The code is in system/platforms/arm-rpi/dispatch.c. These functions simply are passed the number of the IRQ to enable or disable. Shared IRQs are numbered 0-63, while ARM-specific IRQs (currently not actually used) are numbered starting at 64. Also in this file you will find dispatch(), which is called from the assembly language IRQ handler in system/platforms/arm-rpi/irq_handler.S to handle an interrupt. The point of dispatch() is to figure out which number IRQs are actually pending, then call the registered interrupt handler for each.