Difference between revisions of "ARM11 Interrupts"

From 3dbrew
Jump to navigation Jump to search
(Clarify PDC interrupt use)
 
(82 intermediate revisions by 12 users not shown)
Line 1: Line 1:
 
== Interrupts ==
 
== Interrupts ==
 +
 +
Interrupt priority is 0-0xF. A priority of 0xF means that the interrupt is disabled.
 +
 +
= Private Interrupts =
 +
 +
Each CPU core has 32 software interrupts that are private and belong to that core.  These interrupts are numbers 0-0x1F for each core.  The hardware interrupts are not core-specific and start at interrupt ID 0x20.
 +
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
!  IRQ
 
!  IRQ
 
!  Listener
 
!  Listener
 
!  Description
 
!  Description
 +
|-
 +
| 0
 +
|
 +
| MPCore software-interrupt. Used by Kernel11 to sync cores in crt0.
 +
|-
 +
| 0x1-0x3
 +
|
 +
| MPCore software-interrupt. Used by Boot11 and Kernel11 to kickstart Core1/2/3, and by Kernel11 to sync cores in crt0.
 +
|-
 +
| 0x4
 +
| Kernel
 +
| MPCore software-interrupt. Used to manage the performance counter. Also used by Kernel11 during crt0 to sync up.
 +
|-
 +
| 0x5
 +
| Kernel
 +
| MPCore software-interrupt. Does apparently nothing.
 +
|-
 +
| 0x6
 +
| Kernel
 +
| MPCore software-interrupt. Extensively used by [[SVC|KernelSetState]] (and contains most of the actual code of the latter).
 +
|-
 +
| 0x7
 +
| Kernel
 +
| MPCore software-interrupt. See [[KCacheMaintenanceInterruptEvent]]
 
|-
 
|-
 
| 0x8
 
| 0x8
| kernel
+
| Kernel
| Scheduler software-interrupt.
+
| MPCore software-interrupt. Used for scheduling.
 +
|-
 +
| 0x9
 +
| Kernel
 +
| MPCore software-interrupt. Used when handling exceptions that require termination of a thread or a process, and in some cases by svcSetDebugThreadContext, to store VFP registers in the thread's register storage.
 +
|-
 +
| 0xA
 +
| Kernel
 +
| TLB operations interrupt, see [[KTLBOperationsInterruptEvent]]
 +
|-
 +
| 0xB-0xE
 +
|
 +
| MPCore software-interrupt. Not configured.
 +
|-
 +
| 0xF
 +
| dmnt/debugger
 +
| MPCore software-interrupt. Used to abstract FIQ (debug). This interrupt is never sent to core2 nor core3 on N3DS.
 
|-
 
|-
 
| 0x1D
 
| 0x1D
| kernel
+
| Kernel
 
| MPCore timer.
 
| MPCore timer.
 
|-
 
|-
 
| 0x1E
 
| 0x1E
|
+
| Kernel
| MPCore watchdog.
+
| MPCore watchdog - set when the watchdog counter reaches 0 in timer mode, causes interrupt 30 to set as pending.  Only set on core 1 as core 1's timer is used for everything.
 +
|}
 +
 
 +
= Hardware Interrupts =
 +
 
 +
There are 0x60 hardware interrupts starting at 0x20 and continuing up to 0x7F.  These are not private and are accessible from any core.
 +
 
 +
{| class="wikitable" border="1"
 +
!  IRQ
 +
!  Listener
 +
!  Description
 +
|-
 +
| 0x24
 +
| ?
 +
| SPI bus 2 interrupt status update
 
|-
 
|-
 
| 0x28
 
| 0x28
| gsp
+
| gsp, TwlBg
| ?
+
| PSC0
 
|-
 
|-
 
| 0x29
 
| 0x29
| gsp
+
| gsp, TwlBg
| ?
+
| PSC1
 
|-
 
|-
 
| 0x2A
 
| 0x2A
| gsp
+
| gsp, TwlBg
| ?
+
| PDC0 (Top screen VBlank0, HBlank0)
 
|-
 
|-
 
| 0x2B
 
| 0x2B
| gsp
+
| gsp, TwlBg
| ?
+
| PDC1 (Bottom screen VBlank1, HBlank1)
 
|-
 
|-
 
| 0x2C
 
| 0x2C
| gsp
+
| gsp, TwlBg
| ?
+
| PPF
 
|-
 
|-
 
| 0x2D
 
| 0x2D
| gsp
+
| gsp, TwlBg
| ?
+
| P3D
 
|-
 
|-
| 0x30
+
| 0x30-0x38
| kernel
+
| Kernel
| ?
+
| Old CDMA Event 0..8 (9 separate IRQ lines)
 
|-
 
|-
 
| 0x39
 
| 0x39
| kernel
+
| Kernel
 +
| Old CDMA Faulting (eg. CCR=0, or event>15)
 +
|-
 +
| 0x3A
 +
| Kernel
 +
| New CDMA Event 0..31 (shared IRQ line)
 +
|-
 +
| 0x3B
 +
| Kernel
 +
| New CDMA Faulting (eg. CCR=0)
 +
|-
 +
| 0x40
 +
| nwm
 +
| WIFI SDIO Controller @ 0x10122000
 +
|-
 +
| 0x41
 +
| nwm
 +
| WIFI SDIO Controller IRQ pin @ 0x10122000
 +
|-
 +
| 0x42
 +
| nwm_dev?
 +
| Debug WIFI SDIO Controller @ 0x10100000 ?
 +
|-
 +
| 0x43
 +
| nwm_dev?
 +
| Debug WIFI SDIO Controller @ 0x10100000 ?
 +
|-
 +
| 0x44
 
| ?
 
| ?
 +
| NTRCARD (maybe?)
 
|-
 
|-
 
| 0x45
 
| 0x45
 
| mvd (New3DS)
 
| mvd (New3DS)
| ?
+
| L2B_0 (First RGB-to-RGBA Converter)
 
|-
 
|-
 
| 0x46
 
| 0x46
 
| mvd (New3DS)
 
| mvd (New3DS)
| ?
+
| L2B_1 (Second RGB-to-RGBA Converter)
 
|-
 
|-
 
| 0x48
 
| 0x48
 
| camera
 
| camera
| ?
+
| Camera Bus 0 (DSi cameras)
 
|-
 
|-
 
| 0x49
 
| 0x49
 
| camera
 
| camera
| ?
+
| Camera Bus 1 (left-eye)
 
|-
 
|-
 
| 0x4A
 
| 0x4A
 
| dsp
 
| dsp
| ?
+
| General interrupt from DSP, including semaphore and command/reply registers status change
 
|-
 
|-
 
| 0x4B
 
| 0x4B
 
| camera
 
| camera
| ?
+
| Y2R Conversion Finished
 +
|-
 +
| 0x4C
 +
| TwlBg
 +
| LGYFB_0 Legacy GBA/NDS Video
 +
|-
 +
| 0x4D
 +
| TwlBg
 +
| LGYFB_1 Legacy GBA/NDS Video
 
|-
 
|-
 
| 0x4E
 
| 0x4E
 
| mvd (New3DS)
 
| mvd (New3DS)
| ?
+
| Y2R2 End Event
 
|-
 
|-
 
| 0x4F
 
| 0x4F
 
| mvd (New3DS)
 
| mvd (New3DS)
| ?
+
| MVD general interrupt?
 
|-
 
|-
 
| 0x50
 
| 0x50
| pxi
+
| pxi, TwlBg
| ?
+
| Sync (bit 29 from Arm9's PXI_SYNC)
 
|-
 
|-
 
| 0x51
 
| 0x51
| pxi
+
| pxi, TwlBg
| ?
+
| Sync 2 (bit 30 from Arm9's PXI_SYNC)
 
|-
 
|-
 
| 0x52
 
| 0x52
| pxi
+
| pxi, TwlBg
| ?
+
| Send Fifo Empty
 
|-
 
|-
 
| 0x53
 
| 0x53
| pxi
+
| pxi, TwlBg
| ?
+
| Receive Fifo Not Empty
 
|-
 
|-
 
| 0x54
 
| 0x54
| i2c
+
| i2c, TwlBg
| ?
+
| I2C Bus0 work done
 
|-
 
|-
 
| 0x55
 
| 0x55
| i2c
+
| i2c, TwlBg
| ?
+
| I2C Bus1 work done
 +
|-
 +
| 0x56
 +
| spi, TwlBg
 +
| SPI bus 3 interrupt status update
 +
|-
 +
| 0x57
 +
| spi, TwlBg
 +
| SPI bus 1 interrupt status update
 +
|-
 +
| 0x58
 +
| Kernel
 +
| PDN (wake event or SoC mode changed)
 +
|-
 +
| 0x59
 +
| TwlBg
 +
| PDN Legacy Sleep
 
|-
 
|-
 
| 0x5A
 
| 0x5A
 
| mic
 
| mic
| ?
+
| General microphone interrupt (?)
 +
|-
 +
| 0x5B
 +
| -
 +
| [[HID_Registers#HID_PAD_CNT|HID_PAD_CNT]]
 
|-
 
|-
 
| 0x5C
 
| 0x5C
| i2c
+
| i2c, TwlBg
| ?
+
| I2C Bus2 work done
 +
|-
 +
| 0x5F
 +
| mp
 +
| DS WiFi registers
 
|-
 
|-
 
| 0x60
 
| 0x60
| gpio
+
| gpio, TwlBg
| ?
+
| Shell opened (GPIO1_2 falling edge)
 
|-
 
|-
 
| 0x62
 
| 0x62
| gpio
+
| gpio, TwlBg
| ?
+
| Shell closed (GPIO1_2 rising edge)
 
|-
 
|-
 
| 0x63
 
| 0x63
| gpio
+
| gpio, TwlBg
| ?
+
| Touch Screen pressed (GPIO1_1 falling edge)
 
|-
 
|-
 
| 0x64
 
| 0x64
| gpio
+
| gpio, TwlBg
| ?
+
| Headphones inserted (GPIO2_0)
 
|-
 
|-
 
| 0x66
 
| 0x66
| gpio
+
| gpio, TwlBg
| ?
+
| TWL depop circuit (GPIO2_1)
 
|-
 
|-
 
| 0x68
 
| 0x68
| gpio
+
| gpio, TwlBg
| ?
+
| C-stick interrupt (GPIO3_0)
 
|-
 
|-
 
| 0x69
 
| 0x69
| gpio
+
| gpio, TwlBg
| ?
+
| IrDA interrupt (active-low) (GPIO3_1)
 
|-
 
|-
 
| 0x6A
 
| 0x6A
| gpio
+
| gpio, TwlBg
| ?
+
| Gyro interrupt (GPIO3_2)
 
|-
 
|-
 
| 0x6B
 
| 0x6B
| gpio
+
| gpio, TwlBg
| ?
+
| C-stick "stop" (output) (GPIO3_3)
 
|-
 
|-
 
| 0x6C
 
| 0x6C
| gpio
+
| gpio, TwlBg
| ?
+
| IrDA TX-RC (output) (GPIO3_4)
 
|-
 
|-
 
| 0x6D
 
| 0x6D
| gpio
+
| gpio, TwlBg
| ?
+
| IrDA RXD (GPIO3_5)
 
|-
 
|-
 
| 0x6E
 
| 0x6E
| gpio
+
| gpio, TwlBg
| ?
+
| NFC output1 (?) (GPIO3_6)
 
|-
 
|-
 
| 0x6F
 
| 0x6F
| gpio
+
| gpio, TwlBg
| ?
+
| NFC output2 (?) (GPIO3_7)
 
|-
 
|-
 
| 0x70
 
| 0x70
| gpio
+
| gpio, TwlBg
| ?
+
| Headphones button/half-inserted (active-low) (GPIO3_8)
 
|-
 
|-
 
| 0x71
 
| 0x71
| gpio
+
| gpio, TwlBg
 +
| MCU interrupt (GPIO3_9)
 +
|-
 +
| 0x72
 +
| gpio, TwlBg
 +
| NFC interrupt (?) (GPIO3_10)
 +
|-
 +
| 0x73
 +
| TwlBg
 +
| QTM output (?) (GPIO3_11)
 +
|-
 +
| 0x74
 
| ?
 
| ?
 +
| Gamecard related
 
|-
 
|-
| 0x72
+
| 0x75
| gpio
 
 
| ?
 
| ?
 +
| Gamecard inserted
 +
|-
 +
| 0x76
 +
| -
 +
| L2C
 +
|-
 +
| 0x78 to 0x7B
 +
| Kernel
 +
| Core 0-3 Performance monitor counter (any) overflow
 +
|-
 +
| 0x7A to 0x82 (PDN_MPCORE_CFG bit2 set) or
 +
0x7C to 0x84 (bit2 clear)
 +
| Kernel
 +
| Other PMU interrupts (line may not exist at all)
 +
|}
 +
(interrupts from 0x80 and up can't be mapped in available builds of the kernel)
 +
 +
 +
There are 2 tables in the Arm11 kernel: the first has 32 * 2(or 32 * 4) 8-byte entries. This table is for the private interrupts that belong to each core.  The data for each interrupt can be found by doing table_base + (core_num * 0x100) + (intr_num * 8).  The second table is for public hardware interrupts and the data for each interrupt can be retrieved by doing table_base + (intr_num * 8).
 +
 +
The Arm11 kernel configures interrupts the following way (it seems the GPIO IRQ layout doesn't match released 3DS models):
 +
 +
<nowiki>Interrupts 0x00 to 0x1F: edge-triggered, N-N
 +
Interrupt 0x20: level-sensitive, 1-N
 +
Interrupt 0x21: level-sensitive, 1-N
 +
Interrupt 0x22: level-sensitive, 1-N
 +
Interrupt 0x23: level-sensitive, 1-N
 +
Interrupt 0x24: edge-triggered, 1-N
 +
Interrupt 0x25: level-sensitive, 1-N
 +
Interrupt 0x28: level-sensitive, 1-N
 +
Interrupt 0x29: level-sensitive, 1-N
 +
Interrupt 0x2a: level-sensitive, 1-N
 +
Interrupt 0x2b: level-sensitive, 1-N
 +
Interrupt 0x2c: level-sensitive, 1-N
 +
Interrupt 0x2d: level-sensitive, 1-N
 +
Interrupt 0x30: level-sensitive, 1-N
 +
Interrupt 0x31: level-sensitive, 1-N
 +
Interrupt 0x32: level-sensitive, 1-N
 +
Interrupt 0x33: level-sensitive, 1-N
 +
Interrupt 0x34: level-sensitive, 1-N
 +
Interrupt 0x35: level-sensitive, 1-N
 +
Interrupt 0x36: level-sensitive, 1-N
 +
Interrupt 0x37: level-sensitive, 1-N
 +
Interrupt 0x38: level-sensitive, 1-N
 +
Interrupt 0x39: level-sensitive, 1-N
 +
Interrupt 0x3a: level-sensitive, 1-N
 +
Interrupt 0x3b: level-sensitive, 1-N
 +
Interrupt 0x40: edge-triggered, 1-N
 +
Interrupt 0x41: edge-triggered, 1-N
 +
Interrupt 0x42: edge-triggered, 1-N
 +
Interrupt 0x43: edge-triggered, 1-N
 +
Interrupt 0x44: edge-triggered, 1-N
 +
Interrupt 0x45: edge-triggered, 1-N
 +
Interrupt 0x46: edge-triggered, 1-N
 +
Interrupt 0x48: edge-triggered, 1-N
 +
Interrupt 0x49: edge-triggered, 1-N
 +
Interrupt 0x4a: edge-triggered, 1-N
 +
Interrupt 0x4b: edge-triggered, 1-N
 +
Interrupt 0x4c: edge-triggered, 1-N
 +
Interrupt 0x4d: edge-triggered, 1-N
 +
Interrupt 0x4e: edge-triggered, 1-N
 +
Interrupt 0x4f: level-sensitive, 1-N
 +
Interrupt 0x50: edge-triggered, 1-N
 +
Interrupt 0x51: edge-triggered, 1-N
 +
Interrupt 0x52: edge-triggered, 1-N
 +
Interrupt 0x53: edge-triggered, 1-N
 +
Interrupt 0x54: edge-triggered, 1-N
 +
Interrupt 0x55: edge-triggered, 1-N
 +
Interrupt 0x56: edge-triggered, 1-N
 +
Interrupt 0x57: edge-triggered, 1-N
 +
Interrupt 0x58: level-sensitive, 1-N
 +
Interrupt 0x59: edge-triggered, 1-N
 +
Interrupt 0x5a: edge-triggered, 1-N
 +
Interrupt 0x5b: edge-triggered, 1-N
 +
Interrupt 0x5f: edge-triggered, 1-N
 +
Interrupt 0x60: edge-triggered, 1-N
 +
Interrupt 0x61: edge-triggered, 1-N
 +
Interrupt 0x64: edge-triggered, 1-N
 +
Interrupt 0x65: edge-triggered, 1-N
 +
Interrupt 0x66: edge-triggered, 1-N
 +
Interrupt 0x68: edge-triggered, 1-N
 +
Interrupt 0x69: edge-triggered, 1-N
 +
Interrupt 0x6a: edge-triggered, 1-N
 +
Interrupt 0x6b: edge-triggered, 1-N
 +
Interrupt 0x6c: edge-triggered, 1-N
 +
Interrupt 0x6d: edge-triggered, 1-N
 +
Interrupt 0x6e: edge-triggered, 1-N
 +
Interrupt 0x6f: edge-triggered, 1-N
 +
Interrupt 0x70: edge-triggered, 1-N
 +
Interrupt 0x71: edge-triggered, 1-N
 +
Interrupt 0x72: edge-triggered, 1-N
 +
Interrupt 0x73: edge-triggered, 1-N
 +
Interrupt 0x74: edge-triggered, 1-N
 +
Interrupt 0x75: edge-triggered, 1-N
 +
Interrupt 0x76: level-sensitive, 1-N
 +
Interrupt 0x77: level-sensitive, 1-N
 +
Interrupt 0x78: edge-triggered, 1-N
 +
Interrupt 0x79: level-sensitive, 1-N
 +
Interrupt 0x7a: level-sensitive, 1-N
 +
Interrupt 0x7b: level-sensitive, 1-N
 +
Interrupt 0x7c: level-sensitive, 1-N
 +
Interrupt 0x7d: level-sensitive, 1-N</nowiki>
 +
 +
= InterruptData =
 +
{| class="wikitable" border="1"
 +
|-
 +
!  Offset
 +
!  Type
 +
!  Description
 +
|-
 +
| 0x0
 +
| [[KBaseInterruptEvent]] *
 +
| Pointer to the KBaseInterruptEvent object for this interrupt
 +
|-
 +
| 0x4
 +
| u8
 +
| Interrupt will be disabled by the IRQ handler as soon as it is acknowledged.
 +
Ignored for FIQ: the FIQ handler always sets bit2 of [[PDN_Registers#PDN_FIQ_CNT|PDN_FIQ_CNT]]
 +
|-
 +
| 0x5
 +
| u8
 +
| Interrupt is disabled
 +
|-
 +
| 0x6
 +
| u8
 +
| Interrupt priority
 +
|-
 +
| 0x7
 +
| u8
 +
| Unused, alignment
 +
|}
 +
 +
= Interrupt Table (New3DS) =
 +
(0xFFF318F4 in 10.3)
 +
 +
{| class="wikitable" border="1"
 +
!  Offset
 +
!  Type
 +
!  Description
 +
|-
 +
| 0x0
 +
| InterruptData[224]
 +
| Data for all hardware and software interrupts
 +
|-
 +
| 0x700
 +
| [[KObjectMutex]]
 +
| Mutex
 
|}
 
|}

Latest revision as of 20:39, 25 November 2021

Interrupts[edit]

Interrupt priority is 0-0xF. A priority of 0xF means that the interrupt is disabled.

Private Interrupts[edit]

Each CPU core has 32 software interrupts that are private and belong to that core. These interrupts are numbers 0-0x1F for each core. The hardware interrupts are not core-specific and start at interrupt ID 0x20.

IRQ Listener Description
0 MPCore software-interrupt. Used by Kernel11 to sync cores in crt0.
0x1-0x3 MPCore software-interrupt. Used by Boot11 and Kernel11 to kickstart Core1/2/3, and by Kernel11 to sync cores in crt0.
0x4 Kernel MPCore software-interrupt. Used to manage the performance counter. Also used by Kernel11 during crt0 to sync up.
0x5 Kernel MPCore software-interrupt. Does apparently nothing.
0x6 Kernel MPCore software-interrupt. Extensively used by KernelSetState (and contains most of the actual code of the latter).
0x7 Kernel MPCore software-interrupt. See KCacheMaintenanceInterruptEvent
0x8 Kernel MPCore software-interrupt. Used for scheduling.
0x9 Kernel MPCore software-interrupt. Used when handling exceptions that require termination of a thread or a process, and in some cases by svcSetDebugThreadContext, to store VFP registers in the thread's register storage.
0xA Kernel TLB operations interrupt, see KTLBOperationsInterruptEvent
0xB-0xE MPCore software-interrupt. Not configured.
0xF dmnt/debugger MPCore software-interrupt. Used to abstract FIQ (debug). This interrupt is never sent to core2 nor core3 on N3DS.
0x1D Kernel MPCore timer.
0x1E Kernel MPCore watchdog - set when the watchdog counter reaches 0 in timer mode, causes interrupt 30 to set as pending. Only set on core 1 as core 1's timer is used for everything.

Hardware Interrupts[edit]

There are 0x60 hardware interrupts starting at 0x20 and continuing up to 0x7F. These are not private and are accessible from any core.

IRQ Listener Description
0x24 ? SPI bus 2 interrupt status update
0x28 gsp, TwlBg PSC0
0x29 gsp, TwlBg PSC1
0x2A gsp, TwlBg PDC0 (Top screen VBlank0, HBlank0)
0x2B gsp, TwlBg PDC1 (Bottom screen VBlank1, HBlank1)
0x2C gsp, TwlBg PPF
0x2D gsp, TwlBg P3D
0x30-0x38 Kernel Old CDMA Event 0..8 (9 separate IRQ lines)
0x39 Kernel Old CDMA Faulting (eg. CCR=0, or event>15)
0x3A Kernel New CDMA Event 0..31 (shared IRQ line)
0x3B Kernel New CDMA Faulting (eg. CCR=0)
0x40 nwm WIFI SDIO Controller @ 0x10122000
0x41 nwm WIFI SDIO Controller IRQ pin @ 0x10122000
0x42 nwm_dev? Debug WIFI SDIO Controller @ 0x10100000 ?
0x43 nwm_dev? Debug WIFI SDIO Controller @ 0x10100000 ?
0x44 ? NTRCARD (maybe?)
0x45 mvd (New3DS) L2B_0 (First RGB-to-RGBA Converter)
0x46 mvd (New3DS) L2B_1 (Second RGB-to-RGBA Converter)
0x48 camera Camera Bus 0 (DSi cameras)
0x49 camera Camera Bus 1 (left-eye)
0x4A dsp General interrupt from DSP, including semaphore and command/reply registers status change
0x4B camera Y2R Conversion Finished
0x4C TwlBg LGYFB_0 Legacy GBA/NDS Video
0x4D TwlBg LGYFB_1 Legacy GBA/NDS Video
0x4E mvd (New3DS) Y2R2 End Event
0x4F mvd (New3DS) MVD general interrupt?
0x50 pxi, TwlBg Sync (bit 29 from Arm9's PXI_SYNC)
0x51 pxi, TwlBg Sync 2 (bit 30 from Arm9's PXI_SYNC)
0x52 pxi, TwlBg Send Fifo Empty
0x53 pxi, TwlBg Receive Fifo Not Empty
0x54 i2c, TwlBg I2C Bus0 work done
0x55 i2c, TwlBg I2C Bus1 work done
0x56 spi, TwlBg SPI bus 3 interrupt status update
0x57 spi, TwlBg SPI bus 1 interrupt status update
0x58 Kernel PDN (wake event or SoC mode changed)
0x59 TwlBg PDN Legacy Sleep
0x5A mic General microphone interrupt (?)
0x5B - HID_PAD_CNT
0x5C i2c, TwlBg I2C Bus2 work done
0x5F mp DS WiFi registers
0x60 gpio, TwlBg Shell opened (GPIO1_2 falling edge)
0x62 gpio, TwlBg Shell closed (GPIO1_2 rising edge)
0x63 gpio, TwlBg Touch Screen pressed (GPIO1_1 falling edge)
0x64 gpio, TwlBg Headphones inserted (GPIO2_0)
0x66 gpio, TwlBg TWL depop circuit (GPIO2_1)
0x68 gpio, TwlBg C-stick interrupt (GPIO3_0)
0x69 gpio, TwlBg IrDA interrupt (active-low) (GPIO3_1)
0x6A gpio, TwlBg Gyro interrupt (GPIO3_2)
0x6B gpio, TwlBg C-stick "stop" (output) (GPIO3_3)
0x6C gpio, TwlBg IrDA TX-RC (output) (GPIO3_4)
0x6D gpio, TwlBg IrDA RXD (GPIO3_5)
0x6E gpio, TwlBg NFC output1 (?) (GPIO3_6)
0x6F gpio, TwlBg NFC output2 (?) (GPIO3_7)
0x70 gpio, TwlBg Headphones button/half-inserted (active-low) (GPIO3_8)
0x71 gpio, TwlBg MCU interrupt (GPIO3_9)
0x72 gpio, TwlBg NFC interrupt (?) (GPIO3_10)
0x73 TwlBg QTM output (?) (GPIO3_11)
0x74 ? Gamecard related
0x75 ? Gamecard inserted
0x76 - L2C
0x78 to 0x7B Kernel Core 0-3 Performance monitor counter (any) overflow
0x7A to 0x82 (PDN_MPCORE_CFG bit2 set) or

0x7C to 0x84 (bit2 clear)

Kernel Other PMU interrupts (line may not exist at all)

(interrupts from 0x80 and up can't be mapped in available builds of the kernel)


There are 2 tables in the Arm11 kernel: the first has 32 * 2(or 32 * 4) 8-byte entries. This table is for the private interrupts that belong to each core. The data for each interrupt can be found by doing table_base + (core_num * 0x100) + (intr_num * 8). The second table is for public hardware interrupts and the data for each interrupt can be retrieved by doing table_base + (intr_num * 8).

The Arm11 kernel configures interrupts the following way (it seems the GPIO IRQ layout doesn't match released 3DS models):

Interrupts 0x00 to 0x1F: edge-triggered, N-N
Interrupt 0x20: level-sensitive, 1-N
Interrupt 0x21: level-sensitive, 1-N
Interrupt 0x22: level-sensitive, 1-N
Interrupt 0x23: level-sensitive, 1-N
Interrupt 0x24: edge-triggered, 1-N
Interrupt 0x25: level-sensitive, 1-N
Interrupt 0x28: level-sensitive, 1-N
Interrupt 0x29: level-sensitive, 1-N
Interrupt 0x2a: level-sensitive, 1-N
Interrupt 0x2b: level-sensitive, 1-N
Interrupt 0x2c: level-sensitive, 1-N
Interrupt 0x2d: level-sensitive, 1-N
Interrupt 0x30: level-sensitive, 1-N
Interrupt 0x31: level-sensitive, 1-N
Interrupt 0x32: level-sensitive, 1-N
Interrupt 0x33: level-sensitive, 1-N
Interrupt 0x34: level-sensitive, 1-N
Interrupt 0x35: level-sensitive, 1-N
Interrupt 0x36: level-sensitive, 1-N
Interrupt 0x37: level-sensitive, 1-N
Interrupt 0x38: level-sensitive, 1-N
Interrupt 0x39: level-sensitive, 1-N
Interrupt 0x3a: level-sensitive, 1-N
Interrupt 0x3b: level-sensitive, 1-N
Interrupt 0x40: edge-triggered, 1-N
Interrupt 0x41: edge-triggered, 1-N
Interrupt 0x42: edge-triggered, 1-N
Interrupt 0x43: edge-triggered, 1-N
Interrupt 0x44: edge-triggered, 1-N
Interrupt 0x45: edge-triggered, 1-N
Interrupt 0x46: edge-triggered, 1-N
Interrupt 0x48: edge-triggered, 1-N
Interrupt 0x49: edge-triggered, 1-N
Interrupt 0x4a: edge-triggered, 1-N
Interrupt 0x4b: edge-triggered, 1-N
Interrupt 0x4c: edge-triggered, 1-N
Interrupt 0x4d: edge-triggered, 1-N
Interrupt 0x4e: edge-triggered, 1-N
Interrupt 0x4f: level-sensitive, 1-N
Interrupt 0x50: edge-triggered, 1-N
Interrupt 0x51: edge-triggered, 1-N
Interrupt 0x52: edge-triggered, 1-N
Interrupt 0x53: edge-triggered, 1-N
Interrupt 0x54: edge-triggered, 1-N
Interrupt 0x55: edge-triggered, 1-N
Interrupt 0x56: edge-triggered, 1-N
Interrupt 0x57: edge-triggered, 1-N
Interrupt 0x58: level-sensitive, 1-N
Interrupt 0x59: edge-triggered, 1-N
Interrupt 0x5a: edge-triggered, 1-N
Interrupt 0x5b: edge-triggered, 1-N
Interrupt 0x5f: edge-triggered, 1-N
Interrupt 0x60: edge-triggered, 1-N
Interrupt 0x61: edge-triggered, 1-N
Interrupt 0x64: edge-triggered, 1-N
Interrupt 0x65: edge-triggered, 1-N
Interrupt 0x66: edge-triggered, 1-N
Interrupt 0x68: edge-triggered, 1-N
Interrupt 0x69: edge-triggered, 1-N
Interrupt 0x6a: edge-triggered, 1-N
Interrupt 0x6b: edge-triggered, 1-N
Interrupt 0x6c: edge-triggered, 1-N
Interrupt 0x6d: edge-triggered, 1-N
Interrupt 0x6e: edge-triggered, 1-N
Interrupt 0x6f: edge-triggered, 1-N
Interrupt 0x70: edge-triggered, 1-N
Interrupt 0x71: edge-triggered, 1-N
Interrupt 0x72: edge-triggered, 1-N
Interrupt 0x73: edge-triggered, 1-N
Interrupt 0x74: edge-triggered, 1-N
Interrupt 0x75: edge-triggered, 1-N
Interrupt 0x76: level-sensitive, 1-N
Interrupt 0x77: level-sensitive, 1-N
Interrupt 0x78: edge-triggered, 1-N
Interrupt 0x79: level-sensitive, 1-N
Interrupt 0x7a: level-sensitive, 1-N
Interrupt 0x7b: level-sensitive, 1-N
Interrupt 0x7c: level-sensitive, 1-N
Interrupt 0x7d: level-sensitive, 1-N

InterruptData[edit]

Offset Type Description
0x0 KBaseInterruptEvent * Pointer to the KBaseInterruptEvent object for this interrupt
0x4 u8 Interrupt will be disabled by the IRQ handler as soon as it is acknowledged.

Ignored for FIQ: the FIQ handler always sets bit2 of PDN_FIQ_CNT

0x5 u8 Interrupt is disabled
0x6 u8 Interrupt priority
0x7 u8 Unused, alignment

Interrupt Table (New3DS)[edit]

(0xFFF318F4 in 10.3)

Offset Type Description
0x0 InterruptData[224] Data for all hardware and software interrupts
0x700 KObjectMutex Mutex