Changes

Jump to navigation Jump to search
5,247 bytes added ,  21:39, 25 November 2021
Clarify PDC interrupt use
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. 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
 
| 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 40:  
| 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 73:  
!  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 (Top screen VBlank0, HBlank0)
 
|-
 
|-
 
| 0x2B
 
| 0x2B
 
| gsp, TwlBg
 
| gsp, TwlBg
| PDC1?
+
| PDC1 (Bottom screen VBlank1, HBlank1)
 
|-
 
|-
 
| 0x2C
 
| 0x2C
 
| gsp, TwlBg
 
| gsp, TwlBg
| PPF?
+
| PPF
 
|-
 
|-
 
| 0x2D
 
| 0x2D
 
| gsp, TwlBg
 
| gsp, TwlBg
| ?
+
| P3D
 
|-
 
|-
| 0x30
+
| 0x30-0x38
 
| Kernel
 
| Kernel
| ?
+
| Old CDMA Event 0..8 (9 separate IRQ lines)
 
|-
 
|-
 
| 0x39
 
| 0x39
 
| Kernel
 
| Kernel
| DMA
+
| Old CDMA Faulting (eg. CCR=0, or event>15)
 
|-
 
|-
 
| 0x3A
 
| 0x3A
 
| Kernel
 
| Kernel
| DMA
+
| New CDMA Event 0..31 (shared IRQ line)
 
|-
 
|-
 
| 0x3B
 
| 0x3B
 
| Kernel
 
| Kernel
| DMA
+
| New CDMA Faulting (eg. CCR=0)
 
|-
 
|-
 
| 0x40
 
| 0x40
Line 100: Line 124:  
| 0x41
 
| 0x41
 
| nwm
 
| nwm
| ?
+
| WIFI SDIO Controller IRQ pin @ 0x10122000
 
|-
 
|-
 
| 0x42
 
| 0x42
 
| nwm_dev?
 
| nwm_dev?
| WIFI SDIO Controller @ 0x10100000
+
| 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
Line 132: Line 164:  
| 0x4C
 
| 0x4C
 
| TwlBg
 
| TwlBg
| ?
+
| LGYFB_0 Legacy GBA/NDS Video
 
|-
 
|-
 
| 0x4D
 
| 0x4D
 
| TwlBg
 
| 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, TwlBg
 
| pxi, TwlBg
| Sync
+
| Sync (bit 29 from Arm9's PXI_SYNC)
 
|-
 
|-
 
| 0x51
 
| 0x51
 
| pxi, TwlBg
 
| pxi, TwlBg
| ?
+
| Sync 2 (bit 30 from Arm9's PXI_SYNC)
 
|-
 
|-
 
| 0x52
 
| 0x52
Line 164: Line 196:  
| 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
 
| Kernel
 
| Kernel
| PDN
+
| PDN (wake event or SoC mode changed)
 
|-
 
|-
 
| 0x59
 
| 0x59
 
| TwlBg
 
| TwlBg
| ?
+
| PDN Legacy Sleep
 
|-
 
|-
 
| 0x5A
 
| 0x5A
 
| mic
 
| mic
| ?
+
| General microphone interrupt (?)
 +
|-
 +
| 0x5B
 +
| -
 +
| [[HID_Registers#HID_PAD_CNT|HID_PAD_CNT]]
 
|-
 
|-
 
| 0x5C
 
| 0x5C
 
| i2c, TwlBg
 
| i2c, TwlBg
| ?
+
| I2C Bus2 work done
 +
|-
 +
| 0x5F
 +
| mp
 +
| DS WiFi registers
 
|-
 
|-
 
| 0x60
 
| 0x60
 
| gpio, TwlBg
 
| gpio, TwlBg
| Asserted when shell is opened?
+
| Shell opened (GPIO1_2 falling edge)
 
|-
 
|-
 
| 0x62
 
| 0x62
 
| gpio, TwlBg
 
| gpio, TwlBg
| Asserted when shell is closed?
+
| Shell closed (GPIO1_2 rising edge)
 
|-
 
|-
 
| 0x63
 
| 0x63
 
| gpio, TwlBg
 
| gpio, TwlBg
| Touchscreen
+
| Touch Screen pressed (GPIO1_1 falling edge)
 
|-
 
|-
 
| 0x64
 
| 0x64
 
| gpio, TwlBg
 
| gpio, TwlBg
| Headphone jack plugged in
+
| Headphones inserted (GPIO2_0)
 
|-
 
|-
 
| 0x66
 
| 0x66
 
| gpio, TwlBg
 
| gpio, TwlBg
| ?
+
| TWL depop circuit (GPIO2_1)
 
|-
 
|-
 
| 0x68
 
| 0x68
 
| gpio, TwlBg
 
| gpio, TwlBg
| IR?
+
| C-stick interrupt (GPIO3_0)
 
|-
 
|-
 
| 0x69
 
| 0x69
 
| gpio, TwlBg
 
| gpio, TwlBg
| ?
+
| IrDA interrupt (active-low) (GPIO3_1)
 
|-
 
|-
 
| 0x6A
 
| 0x6A
 
| gpio, TwlBg
 
| gpio, TwlBg
| ?
+
| Gyro interrupt (GPIO3_2)
 
|-
 
|-
 
| 0x6B
 
| 0x6B
 
| gpio, TwlBg
 
| gpio, TwlBg
| ?
+
| C-stick "stop" (output) (GPIO3_3)
 
|-
 
|-
 
| 0x6C
 
| 0x6C
 
| gpio, TwlBg
 
| gpio, TwlBg
| ?
+
| IrDA TX-RC (output) (GPIO3_4)
 
|-
 
|-
 
| 0x6D
 
| 0x6D
 
| gpio, TwlBg
 
| gpio, TwlBg
| ?
+
| IrDA RXD (GPIO3_5)
 
|-
 
|-
 
| 0x6E
 
| 0x6E
 
| gpio, TwlBg
 
| gpio, TwlBg
| ?
+
| NFC output1 (?) (GPIO3_6)
 
|-
 
|-
 
| 0x6F
 
| 0x6F
 
| gpio, TwlBg
 
| gpio, TwlBg
| ?
+
| NFC output2 (?) (GPIO3_7)
 
|-
 
|-
 
| 0x70
 
| 0x70
 
| gpio, TwlBg
 
| gpio, TwlBg
| Headphone jack plugged out
+
| Headphones button/half-inserted (active-low) (GPIO3_8)
 
|-
 
|-
 
| 0x71
 
| 0x71
 
| gpio, TwlBg
 
| gpio, TwlBg
| MCU (HOME/POWER pressed)
+
| MCU interrupt (GPIO3_9)
 
|-
 
|-
 
| 0x72
 
| 0x72
 
| gpio, TwlBg
 
| gpio, TwlBg
| ?
+
| NFC interrupt (?) (GPIO3_10)
 
|-
 
|-
 
| 0x73
 
| 0x73
 
| TwlBg
 
| TwlBg
| ?
+
| QTM output (?) (GPIO3_11)
 
|-
 
|-
 
| 0x74
 
| 0x74
Line 269: Line 309:  
| ?
 
| ?
 
| Gamecard inserted
 
| 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).
+
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 =
 
= InterruptData =
Line 282: Line 419:  
|-
 
|-
 
| 0x0
 
| 0x0
| u32
+
| [[KBaseInterruptEvent]] *
| Pointer to interrupt data object for interrupt number
+
| Pointer to the KBaseInterruptEvent object for this interrupt  
 
|-
 
|-
 
| 0x4
 
| 0x4
 
| u8
 
| u8
| Interrupt is pending
+
| 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 enabled, about to execute
+
| Interrupt is disabled
 
|-
 
|-
 
| 0x6
 
| 0x6
Line 301: Line 439:  
| Unused, alignment
 
| Unused, alignment
 
|}
 
|}
  −
The interrupt data pointer is a pointer to the object that handles that interrupt.  The first first word in the object is a pointer to the object's vtable and the first function in the vtable is the interrupt handler for that interrupt number.  When an interrupt runs, the function is passed its object in r0 and the interrupt number in r1.
      
= Interrupt Table (New3DS) =
 
= Interrupt Table (New3DS) =
Line 313: Line 449:  
|-
 
|-
 
| 0x0
 
| 0x0
| InterruptEvent[224]
+
| InterruptData[224]
| Table of interrupt event objects for all hardware and software interrupts
+
| Data for all hardware and software interrupts
 
|-
 
|-
 
| 0x700
 
| 0x700
| KThread*
+
| [[KObjectMutex]]
| Thread currently acting on the interrupt table
+
| Mutex
|-
  −
| 0x704
  −
| s16
  −
| Error tracker for thread above
  −
|-
  −
| 0x706
  −
| u16
  −
| Alignment
  −
|}
  −
 
  −
 
  −
= InterruptEvent =
  −
{| class="wikitable" border="1"
  −
|-
  −
!  Offset
  −
!  Type
  −
!  Description
  −
|-
  −
| 0x0
  −
| u32
  −
| Pointer to interrupt event object
  −
|-
  −
| 0x4
  −
| u32
  −
| Interrupt flags
   
|}
 
|}
215

edits

Navigation menu