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 = |
| + | |
| + | 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 |
Line 7: |
Line 12: |
| ! Description | | ! Description |
| |- | | |- |
− | | 0-0x7 | + | | 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 |
| + | | 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 |
| | MPCore software-interrupt. Used for scheduling. | | | MPCore software-interrupt. Used for scheduling. |
| |- | | |- |
− | | 0x9-0xF | + | | 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 |
| + | | 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, TwlBg | | | gsp, TwlBg |
− | | ? | + | | PSC0 |
| |- | | |- |
| | 0x29 | | | 0x29 |
| | gsp, TwlBg | | | gsp, TwlBg |
− | | ? | + | | PSC1 |
| |- | | |- |
| | 0x2A | | | 0x2A |
| | gsp, TwlBg | | | gsp, TwlBg |
− | | ? | + | | PDC0 (Top screen VBlank0, HBlank0) |
| |- | | |- |
| | 0x2B | | | 0x2B |
| | gsp, TwlBg | | | gsp, TwlBg |
− | | ? | + | | PDC1 (Bottom screen VBlank1, HBlank1) |
| |- | | |- |
| | 0x2C | | | 0x2C |
| | gsp, TwlBg | | | gsp, TwlBg |
− | | ? | + | | 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 |
− | | ? | + | | 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 | | | 0x40 |
| | nwm | | | nwm |
− | | ? | + | | WIFI SDIO Controller @ 0x10122000 |
| |- | | |- |
| | 0x41 | | | 0x41 |
| | nwm | | | 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 | | | 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 (bit 29 from Arm9's PXI_SYNC) |
| |- | | |- |
| | 0x51 | | | 0x51 |
| | pxi, TwlBg | | | pxi, TwlBg |
− | | ? | + | | Sync 2 (bit 30 from Arm9's PXI_SYNC) |
| |- | | |- |
| | 0x52 | | | 0x52 |
| | pxi, TwlBg | | | pxi, TwlBg |
− | | ? | + | | Send Fifo Empty |
| |- | | |- |
| | 0x53 | | | 0x53 |
| | pxi, TwlBg | | | pxi, TwlBg |
− | | ? | + | | Receive Fifo Not Empty |
| |- | | |- |
| | 0x54 | | | 0x54 |
| | i2c, TwlBg | | | i2c, TwlBg |
− | | ? | + | | I2C Bus0 work done |
| |- | | |- |
| | 0x55 | | | 0x55 |
| | i2c, TwlBg | | | i2c, TwlBg |
− | | ? | + | | I2C Bus1 work done |
| |- | | |- |
| | 0x56 | | | 0x56 |
− | | TwlBg | + | | spi, TwlBg |
− | | ? | + | | SPI bus 3 interrupt status update |
| |- | | |- |
| | 0x57 | | | 0x57 |
− | | TwlBg | + | | spi, TwlBg |
− | | ? | + | | SPI bus 1 interrupt status update |
| + | |- |
| + | | 0x58 |
| + | | Kernel |
| + | | 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 |
− | | ? | + | | Shell opened (GPIO1_2 falling edge) |
| |- | | |- |
| | 0x62 | | | 0x62 |
| | gpio, TwlBg | | | gpio, TwlBg |
− | | ? | + | | Shell closed (GPIO1_2 rising edge) |
| |- | | |- |
| | 0x63 | | | 0x63 |
| | gpio, TwlBg | | | gpio, TwlBg |
− | | ? | + | | Touch Screen pressed (GPIO1_1 falling edge) |
| |- | | |- |
| | 0x64 | | | 0x64 |
| | gpio, TwlBg | | | gpio, TwlBg |
− | | ? | + | | Headphones inserted (GPIO2_0) |
| |- | | |- |
| | 0x66 | | | 0x66 |
| | gpio, TwlBg | | | gpio, TwlBg |
− | | ? | + | | TWL depop circuit (GPIO2_1) |
| |- | | |- |
| | 0x68 | | | 0x68 |
| | gpio, TwlBg | | | gpio, TwlBg |
− | | ? | + | | 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 |
− | | ? | + | | Headphones button/half-inserted (active-low) (GPIO3_8) |
| |- | | |- |
| | 0x71 | | | 0x71 |
| | gpio, TwlBg | | | gpio, TwlBg |
− | | ? | + | | MCU interrupt (GPIO3_9) |
| |- | | |- |
| | 0x72 | | | 0x72 |
| | gpio, TwlBg | | | gpio, TwlBg |
− | | ? | + | | NFC interrupt (?) (GPIO3_10) |
| |- | | |- |
| | 0x73 | | | 0x73 |
| | TwlBg | | | 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): |
| + | |
| + | <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 |
| |} | | |} |