User Tools

Site Tools


irq_controller

Table of Contents

IRQ controller

The IRQ controller is presumably able to schedule and distribute IRQs based on a priority order.

Registers

The IRQ controller has the following registers:

Address Desc.
0xF0001200 Shorthand IRQ enable for IRQ 0x00..0x0F
0xF0001204 Shorthand IRQ enable for IRQ 0x10..0x1F
0xF0001208+(N*4) IRQ enable for IRQ N
0xF00013F0 Current IRQ index
0xF00013F4 Last IRQ index?
0xF00013F8 IRQ priority mask and acknowledge
0xF00013FC IRQ priority mask read and clear
0xF0001420+(N*4) IRQ trigger type for IRQ N
0xF00019D8 General IRQ enable?
0xF00019DC Unknown, set to 0
0xF00019F8 Read-only mirror of 0xF00013F8
0xF00019FC Read-only mirror of 0xF00013FC

Stock firmware tries to initialize registers 0xF0001520..0xF000153C. These registers don't seem to actually exist. Likely, this is a mistake, and that code was intended to access registers 0xF00014A0..0xF00014BC.

0xF0001200

Shorthand IRQ enable for IRQ 0x00..0x0F.

Bits 0..15 correspond to IRQ 0x00..0x0F respectively. A 0 bit enables an IRQ, a 1 bit disables it.

Changing this register changes bit 6 in the corresponding IRQs' enable registers, and vice versa. This register is useful for quickly enabling or disabling multiple IRQs in a row.

0xF0001204

Shorthand IRQ enable for IRQ 0x10..0x1F.

Function same as 0xF0001200.

0xF0001208+(N*4)

IRQ enable.

Bits Desc.
0-3 Priority
4 ??
5 ??
6 IRQ disable; 0=enable, 1=disable
8 ??
12 ?? line value? (read only; for IRQ 0x20-0x28, maybe others?)
13 ??
14 ??

0xF00013F0

Index of the source of the IRQ currently being serviced.

When there is a pending IRQ, reading from this register resets the IRQ priority mask at 0xF00013F8 to zero, effectively masking out all interrupts until the current interrupt is handled. Register 0xF00013F0 is also reset to 0x80 after a read.

Reads as 0x80 when there is no pending IRQ.

0xF00013F4

Seems to be the index of the last IRQ? When reading 0xF00013F0, the value that is read out is copied to 0xF00013F4.

However, reading 0xF00013F4 has no side effect.

0xF00013F8

4-bit IRQ priority “mask”. Actually a number that masks out interrupts with priority equal to or above it. 0xF is the lightest setting, which only masks out priority 0xF.

This register is copied to 0xF00013FC upon IRQ.

Writing to this register also acknowledges the current interrupt.

0xF00013FC

4-bit IRQ priority “mask” read and clear. This value is meant to be written back to 0xF00013F8 once the current interrupt is handled.

This register is read-only.

0xF0001420+(N*4)

Affects the way each IRQ is triggered, but it is not yet known in which way exactly. Observed values are 1 and 5. It appears that 1 means edge trigger and 5 means level trigger. Not sure if other values are possible.

Some IRQ sources will not function correctly without the correct trigger type. For example, VBlank IRQs will only fire once if their trigger type is set to 5.

In practice, some IRQ lines likely stay active only for a very short time, while others will stay active as long as the underlying IRQ conditions are met (ie. from hardware components that have their own IRQ status registers; the IRQ line may stay active until the IRQ status register is cleared).

IRQ trigger type 5 seems to fail to register an interrupt when the pulse is too short (ie. doesn't work for VBlank IRQ).

The trigger type might also play a role in whether/how the IRQ line is buffered or treated? Values 0-7 are possible. Different values affect the different bits (8/12/13/14) in the IRQ enable registers. Some values don't work at all.

Typically, it seems that 1 is used for IRQ sources that are “self-acknowledging” (ie. VBlank, timers, DMA, …), and 5 is used for IRQ sources that need explicit acknowledgement (ie. SPI, I2C, audio, …).

0xF00019D8

Initialized to 1. Setting to 0 disables interrupts.

0xF00019DC

Initialized to 0. Setting to 1 disables interrupts.

Unlike 0xF00019D8, this register seems to completely disable IRQ input/processing.

0xF00019F8

Read-only mirror of 0xF00013F8.

0xF00019FC

Mirror of 0xF00013FC.

IRQ sources

Here are the indexes of the possible IRQ sources, and the settings the stock firmware assigns them:

IRQ index Trigger Desc.
0x00 1 Timer 0
0x01 1 Timer 1
0x02 1 SDIO
0x03 5 UART0
0x04 5 UART1
0x05 5 UART2
0x06 5 SPI
0x07 5 SPI related?
0x08 1 DMA0
0x09 1 DMA1
0x0A 1 ???
0x0B 1 ???
0x0C 1 DMA4
0x0D 1 DMA2
0x0E 1 DMA3
0x0F 5 I2C
0x10 5 vcapt/camera
0x11 5 vcapt/camera
0x12 5 vout
0x13 5 ???
0x14 5 vcapt/camera
0x15 1 VBlank end
0x16 1 VBlank start
0x17 5 Audio output event
0x18 5 Audio input event
0x19 5 ???
0x1A 5 ???
0x1B 5 ???
0x1C 5 ???
0x1D 5 vcapt/camera
0x1E 1 VCount match
0x1F 1 ???
0x20 1? ???
0x21 1? ???
0x22 1? ???
0x23 1? ???
0x24 1? ??? (video related, 0xF00094F8)
0x25 1? ???
0x26 1? ??? (video related, 0xF000940C)
0x27 1? ???

Note: trigger type for IRQ 0x02 is set to 1, which can cause a SDIO IRQ to be missed if it fires while another SDIO IRQ is being processed. Changing it to 5 fixes that problem. The stock firmware doesn't have that problem because it only uses the SDIO IRQ for the wifi card IRQ, and uses busy-loop polling to sense the end of SDIO transfers.

IRQ 0x20..0x27 are actually FIQ sources. Not known what they're all about. Also unknown how to acknowledge a FIQ? Register 0xF00013F0 reads as 0x80 during a FIQ.

The stock firmware doesn't use FIQs, and doesn't even have a FIQ handler (FIQ is redirected to the general exception handler).

irq_controller.txt · Last modified: 2025/04/21 10:07 by arisotura

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki