Difference between revisions of "ARM11 Interrupts"

From 3dbrew
Jump to navigation Jump to search
(31 intermediate revisions by 6 users not shown)
Line 1: Line 1:
 
== Interrupts ==
 
== Interrupts ==
  
Interrupt priority is 0-0xF
+
Interrupt priority is 0-0xF. A priority of 0xF means that the interrupt is disabled.
  
 
= Private Interrupts =
 
= Private Interrupts =
Line 12: Line 12:
 
!  Description
 
!  Description
 
|-
 
|-
| 0-0x5
+
| 0
 
|  
 
|  
| MPCore software-interrupt.
+
| MPCore software-interrupt. Not configured.
 +
|-
 +
| 0x1
 +
|
 +
| MPCore software-interrupt. Used by BOOT11 to kickstart Core1.
 +
|-
 +
| 0x2-0x3
 +
|
 +
| MPCore software-interrupt. Seem to be unused.
 +
|-
 +
| 0x4
 +
| Kernel
 +
| MPCore software-interrupt. Used to manage the performance counter.
 +
|-
 +
| 0x5
 +
| Kernel
 +
| MPCore software-interrupt. Does apparently nothing.
 
|-
 
|-
 
| 0x6
 
| 0x6
 
| Kernel
 
| Kernel
| MPCore software-interrupt.
+
| MPCore software-interrupt. Extensively used by [[SVC|KernelSetState]] (and contains most of the actual code of the latter).
 
|-
 
|-
 
| 0x7
 
| 0x7
|  
+
| Kernel
| MPCore software-interrupt.
+
| MPCore software-interrupt. See [[KCacheMaintenanceInterruptEvent]]
 
|-
 
|-
 
| 0x8
 
| 0x8
Line 28: Line 44:
 
| MPCore software-interrupt. Used for scheduling.
 
| MPCore software-interrupt. Used for scheduling.
 
|-
 
|-
| 0x9-0xE
+
| 0x9
|  
+
| Kernel
| MPCore software-interrupt.
+
| 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
 
| 0xF
 
| dmnt/debugger
 
| dmnt/debugger
| MPCore software-interrupt. Used to abstract FIQ (debug).
+
| MPCore software-interrupt. Used to abstract FIQ (debug). This interrupt is never sent to core2 nor core3 on N3DS.
 
|-
 
|-
 
| 0x1D
 
| 0x1D
Line 53: Line 77:
 
!  Listener
 
!  Listener
 
!  Description
 
!  Description
 +
|-
 +
| 0x24
 +
| ?
 +
| SPI bus 2 interrupt status update
 
|-
 
|-
 
| 0x28
 
| 0x28
 
| gsp, TwlBg
 
| gsp, TwlBg
| PSC0?
+
| PSC0
 
|-
 
|-
 
| 0x29
 
| 0x29
 
| gsp, TwlBg
 
| gsp, TwlBg
| PSC1?
+
| PSC1
 
|-
 
|-
 
| 0x2A
 
| 0x2A
 
| gsp, TwlBg
 
| gsp, TwlBg
| PDC0?
+
| PDC0 (VBlank0)
 
|-
 
|-
 
| 0x2B
 
| 0x2B
 
| gsp, TwlBg
 
| gsp, TwlBg
| PDC1?
+
| PDC1 (VBlank1)
 
|-
 
|-
 
| 0x2C
 
| 0x2C
 
| gsp, TwlBg
 
| gsp, TwlBg
| PPF?
+
| PPF
 
|-
 
|-
 
| 0x2D
 
| 0x2D
 
| gsp, TwlBg
 
| gsp, TwlBg
| ?
+
| P3D
 
|-
 
|-
 
| 0x30
 
| 0x30
Line 124: Line 152:
 
| 0x4A
 
| 0x4A
 
| dsp
 
| dsp
| ?
+
| General interrupt from DSP, including semaphore and command/reply registers status change
 
|-
 
|-
 
| 0x4B
 
| 0x4B
Line 140: Line 168:
 
| 0x4E
 
| 0x4E
 
| mvd (New3DS)
 
| mvd (New3DS)
| ?
+
| Y2R2 End Event
 
|-
 
|-
 
| 0x4F
 
| 0x4F
 
| mvd (New3DS)
 
| mvd (New3DS)
| ?
+
| Related to mvd services
 
|-
 
|-
 
| 0x50
 
| 0x50
Line 164: Line 192:
 
| 0x54
 
| 0x54
 
| i2c, TwlBg
 
| i2c, TwlBg
| ?
+
| I2C Bus0 work done
 
|-
 
|-
 
| 0x55
 
| 0x55
 
| i2c, TwlBg
 
| i2c, TwlBg
| ?
+
| I2C Bus1 work done
 
|-
 
|-
 
| 0x56
 
| 0x56
 
| spi, TwlBg
 
| spi, TwlBg
| ?
+
| SPI bus 3 interrupt status update
 
|-
 
|-
 
| 0x57
 
| 0x57
 
| spi, TwlBg
 
| spi, TwlBg
| ?
+
| SPI bus 1 interrupt status update
 
|-
 
|-
 
| 0x58
 
| 0x58
Line 192: Line 220:
 
| 0x5C
 
| 0x5C
 
| i2c, TwlBg
 
| i2c, TwlBg
| ?
+
| I2C Bus2 work done
 
|-
 
|-
 
| 0x60
 
| 0x60
 
| gpio, TwlBg
 
| gpio, TwlBg
| Asserted when shell is opened?
+
| Shell opened
 
|-
 
|-
 
| 0x62
 
| 0x62
 
| gpio, TwlBg
 
| gpio, TwlBg
| Asserted when shell is closed?
+
| Shell closed
 
|-
 
|-
 
| 0x63
 
| 0x63
Line 208: Line 236:
 
| 0x64
 
| 0x64
 
| gpio, TwlBg
 
| gpio, TwlBg
| Headphone jack plugged in
+
| Headphone jack plugged in/out
 
|-
 
|-
 
| 0x66
 
| 0x66
Line 216: Line 244:
 
| 0x68
 
| 0x68
 
| gpio, TwlBg
 
| gpio, TwlBg
| IR?
+
| IR
 
|-
 
|-
 
| 0x69
 
| 0x69
Line 248: Line 276:
 
| 0x70
 
| 0x70
 
| gpio, TwlBg
 
| gpio, TwlBg
| Headphone jack plugged out
+
| ?
 
|-
 
|-
 
| 0x71
 
| 0x71
 
| gpio, TwlBg
 
| gpio, TwlBg
| MCU (HOME/POWER pressed)
+
| MCU (HOME/POWER pressed/released or WiFi switch pressed)
 
|-
 
|-
 
| 0x72
 
| 0x72
Line 269: Line 297:
 
| ?
 
| ?
 
| Gamecard inserted
 
| Gamecard inserted
 +
|-
 +
| 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
 +
| ?
 
|}
 
|}
 +
(interrupts from 0x80 and up can't be mapped in available builds of the kernel)
  
  
Line 282: Line 320:
 
|-
 
|-
 
| 0x0
 
| 0x0
| InterruptEvent *
+
| [[KBaseInterruptEvent]] *
| Pointer to the InterruptEvent object for that interrupt  
+
| Pointer to the KBaseInterruptEvent object for this interrupt  
 
|-
 
|-
 
| 0x4
 
| 0x4
 
| u8
 
| u8
| Interrupt will be masked by the IRQ handler as soon as it is acknowledged
+
| 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
 
| 0x5
 
| u8
 
| u8
| Interrupt is masked
+
| Interrupt is disabled
 
|-
 
|-
 
| 0x6
 
| 0x6
Line 315: Line 354:
 
|-
 
|-
 
| 0x700
 
| 0x700
| KThread*
+
| [[KObjectMutex]]
| Thread currently acting on the interrupt table
+
| Mutex
|-
 
| 0x704
 
| s16
 
| Error tracker for thread above
 
|-
 
| 0x706
 
| u16
 
| Alignment
 
|}
 
 
 
 
 
= InterruptEvent =
 
 
 
Base class for interrupt events.
 
 
 
{| class="wikitable" border="1"
 
|-
 
!  Offset
 
!  Type
 
!  Description
 
|-
 
| 0x0
 
| void **
 
| Pointer to vtable
 
|-
 
| 0x4
 
| u32
 
| Unknown
 
 
|}
 
|}
 
The first method in the table is <code>KInterruptEvent* InterruptEvent::getKInterruptEvent(u32 interruptID)</code>. It's actually the function called by the IRQ handler, which returns a [[KInterruptEvent|KInterruptEvent]] to signal.
 
If NULL or 1 is returned, no event will be signaled. If NULL is returned, no post-interrupt rescheduling will be done.
 
 
The second method is <code>void InterruptEvent::signalEvent(void)</code>, which signals the associated [[KEvent|KEvent]] object.
 
 
The kernel uses the [[KInterruptEvent|KInterruptEvent]] field of a [[KEvent|KEvent]] when binding public interrupts per svcBindInterrupt request, whereas it internally uses a static object of another subclass to bind interrupt 0x0F (FIQ abstraction).
 

Revision as of 22:11, 27 June 2019

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.

IRQ Listener Description
0 MPCore software-interrupt. Not configured.
0x1 MPCore software-interrupt. Used by BOOT11 to kickstart Core1.
0x2-0x3 MPCore software-interrupt. Seem to be unused.
0x4 Kernel MPCore software-interrupt. Used to manage the performance counter.
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

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 (VBlank0)
0x2B gsp, TwlBg PDC1 (VBlank1)
0x2C gsp, TwlBg PPF
0x2D gsp, TwlBg P3D
0x30 Kernel ?
0x39 Kernel DMA
0x3A Kernel DMA
0x3B Kernel DMA
0x40 nwm WIFI SDIO Controller @ 0x10122000
0x41 nwm ?
0x42 nwm_dev? WIFI SDIO Controller @ 0x10100000
0x45 mvd (New3DS) ?
0x46 mvd (New3DS) ?
0x48 camera ?
0x49 camera ?
0x4A dsp General interrupt from DSP, including semaphore and command/reply registers status change
0x4B camera Y2R Conversion Finished
0x4C TwlBg ?
0x4D TwlBg ?
0x4E mvd (New3DS) Y2R2 End Event
0x4F mvd (New3DS) Related to mvd services
0x50 pxi, TwlBg Sync
0x51 pxi, TwlBg ?
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
0x59 TwlBg ?
0x5A mic ?
0x5C i2c, TwlBg I2C Bus2 work done
0x60 gpio, TwlBg Shell opened
0x62 gpio, TwlBg Shell closed
0x63 gpio, TwlBg Touchscreen
0x64 gpio, TwlBg Headphone jack plugged in/out
0x66 gpio, TwlBg ?
0x68 gpio, TwlBg IR
0x69 gpio, TwlBg ?
0x6A gpio, TwlBg ?
0x6B gpio, TwlBg ?
0x6C gpio, TwlBg ?
0x6D gpio, TwlBg ?
0x6E gpio, TwlBg ?
0x6F gpio, TwlBg ?
0x70 gpio, TwlBg ?
0x71 gpio, TwlBg MCU (HOME/POWER pressed/released or WiFi switch pressed)
0x72 gpio, TwlBg ?
0x73 TwlBg ?
0x74 ? Gamecard related
0x75 ? Gamecard inserted
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 ?

(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).

InterruptData

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)

(0xFFF318F4 in 10.3)

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