SceKernelIntrMgr

From Vita Development Wiki
Jump to navigation Jump to search

SceKernelIntrMgr is a kernel module that is primary responsible for setting up external and internal interrupts. Notably, it facilitates communication with the F00D Processor.

Module

This module exists in both non-secure and secure world. The non-secure world SELF can be found in os0:kd/intrmgr.skprx. It also can be found in the Boot Image (SKBL).

Version World Privilege
1.69-3.60 Non-secure Kernel
1.69 Secure Kernel

Libraries

This module only exports kernel libraries.

Known NIDs

Version Name World Visibility NID
1.69-3.60 SceIntrmgrForDriver Non-secure Kernel 0x9DF04041
1.69-3.60 SceIntrmgrForKernel Non-secure Kernel 0x07AC5E3A
1.69-1.80 SceIntrmgrForTZS Secure Kernel 0xEC3056FE

Data segment layout

Static VA Offset Length Description
0x81004000 0x0 0x842F8 entire
0x81004000 0x0 0x40 * 0x100 Intr entry info
0x81008000 0x4000 0x80 * 4 Intr nest info
0x81008200 0x4200 0x80(?) some memblock/misc info
0x81008280 0x4280 0x2000 * 0x10 * 4 Intr register store area
0x81088280 0x84280 0x78 Something

SceIntrmgrForDriver

sceKernelIsSubInterruptOccurredForDriver

Version NID
0.990-3.60 0x950B864B

sceKernelRegisterIntrHandlerForDriver

Version NID
0.990-3.60 0x5C1FEB29
typedef struct SceKernelRegisterInterruptOptionsExtended
{
	unsigned int size;
	unsigned int unk_4;
	unsigned int unk_8;
	SceKernelIntrOptParam2Callback1 *release_subintr_cb;
	SceKernelIntrOptParam2Callback1 *fptr0;
	SceKernelIntrOptParam2Callback1 *enable_subintr_cb;
	SceKernelIntrOptParam2Callback1 *disable_subintr_cb;
	SceKernelIntrOptParam2Callback2 *fptr3;
	unsigned int unk_20;
	unsigned int unk_24;
} SceKernelRegisterInterruptOptionsExtended; /* size = 0x28 */

typedef struct SceKernelRegisterInterruptOptions
{
	unsigned int size;
	unsigned int num;
	SceKernelRegisterInterruptOptionsExtended *opt2;
	unsigned int flags; /* 0b1 = use sensitivity param */
	unsigned int sensitivity;
} SceKernelRegisterInterruptOptions; /* size = 0x14 */

typedef int (SceKernelIntrHandler)(int intr_code, void* userCtx);

int sceKernelRegisterIntrHandlerForDriver(int code, const char *name, int interrupt_type, SceKernelIntrHandler *handler, void* userCtx, int priority, int targetcpu, SceKernelRegisterInterruptOptions *opt);

sceKernelReleaseIntrHandlerForDriver

Version NID
0.990-3.60 0xD6009B98

This function first performs a disable and then removes the current interrupt handler associated with the interrupt intr_code.

int sceKernelReleaseIntrHandlerForDriver(int intr_code);

sceKernelDisableIntrForDriver

Version NID
0.990-3.60 0x180435EC
int sceKernelDisableIntrForDriver(int intr_code);

This function writes 1 << (intr_code % 32) to the Interrupt Disable Registers (offset 0x180 from the Interrupt Distributor registers) at 0x180 + (intr_code / 32) * 4.

sceKernelEnableIntrForDriver

Version NID
0.990-3.60 0x7117E827
int sceKernelEnableIntrForDriver(int intr_code);

This function writes 1 << (intr_code % 32) to the Interrupt Enable Registers (offset 0x100 from the Interrupt Distributor registers) at 0x100 + (intr_code / 32) * 4.

sceKernelResumeIntrForDriver

Version NID
0.990-3.60 0xA4C772AF
int sceKernelResumeIntrForDriver(int intr_code, int enabled);

Enables or disables an interrupt. If a 0 is passed to enabled, it acts as sceKernelDisableIntrForDriver, and if a 1 is passed, it acts as sceKernelEnableIntrForDriver.

sceKernelSuspendIntrForDriver

Version NID
0.990-3.60 0x6EC07C56
int sceKernelSuspendIntrForDriver(int intr_code, int *enabled);

This function returns whether the interrupt intr_code is enabled or not. If it's enabled, a 1 will be written to enabled and a 0 otherwise. To check the enable status, the function checks the bit number intr_code % 32 of the Interrupt Enable register (offset 0x100 from the Interrupt Distributor registers) at 0x100 + (intr_code / 32) * 4.

sceKernelGetIntrPendingStatusForDebuggerForDriver

Version NID
0.990-3.60 0xA269003D
int sceKernelGetIntrPendingStatusForDebuggerForDriver(int intr_code);

This function returns whether the interrupt intr_code is pending or not. If it's pending, a 1 will be returned, and a 0 will be returned otherwise. To check the pending status, the function checks the bit number intr_code % 32 of the Interrupt Set-Pending Registers (offset 0x200 from the Interrupt Distributor registers) at 0x200 + (intr_code / 32) * 4.

sceKernelClearIntrPendingStatusForDebuggerForDriver

Version NID
0.990-3.60 0x4DC48A01
int sceKernelClearIntrPendingStatusForDebuggerForDriver(int intr_code);

This function writes 1 << (intr_code % 32) to the Interrupt Clear-Pending Registers (offset 0x280 from the Interrupt Distributor registers) at 0x280 + (intr_code / 32) * 4.

sceKernelSetIntrPriorityForDriver

Version NID
0.990-3.60 0x71020E29
int sceKernelSetIntrPriorityForDriver(int intr_code, unsigned char priority);

This function writes priority to the Interrupt Priority Registers (offset 0x400 from the Interrupt Distributor registers) at 0x400 + intr_code.

sceKernelGetIntrPriorityForDriver

Version NID
0.990-3.60 0xE427D050
int sceKernelGetIntrPriorityForDriver(int intr_code, int *priority);

sceKernelSetIntrTargetCpuForDriver

Version NID
0.990-3.60 0x973BACCC
int sceKernelSetIntrTargetCpuForDriver(int intr_code, int cpu_mask);

This function writes the bits 0-8 or 16-24 of cpu_mask, depending on whether the mask is in former or the latter bits, to the Interrupt Processor Targets Registers (offset 0x800 from the Interrupt Distributor registers) at 0x800 + intr_code

sceKernelGetIntrTargetCpuForDriver

Version NID
0.990-3.60 0x353CFAAE
int sceKernelGetIntrTargetCpuForDriver(int intr_code, int *cpu_mask);

sceKernelGenerateSoftIntrForDriver

Version NID
0.990-3.60 0x29F62500
int sceKernelGenerateSoftIntrForDriver(int intr_code, unsigned int target_list_filter, unsigned int cpu_target_list);

This function triggers a SGI (software generated interrupt) by writing (target_list_filter << 24) | (cpu_target_list << 16) | intr_code to the Software Generated Interrupt Register (offset 0xF00 from the Interrupt Distributor registers, physical address 0x1A001F00). Note: intr_code must be between 0x0 and 0xF.

sceKernelIsIntrContextForDriver

Version NID
0.931-3.60 0x182EE3E3

Indicates whether or not the thread is currently handling an interrupt.

SceBool sceKernelIsIntrContextForDriver(void);

Returns SCE_FALSE if the current TPIDRPRW (PL1-only Thread ID Register, holds a pointer to the current ThreadCB) is non-NULL, or if an internal structure field is not set for the current CPU.

sceKernelRegisterSubIntrHandlerForDriver

Version NID
0.990-3.60 0x96576C18
int sceKernelRegisterSubIntrHandlerForDriver(int intr_code, int subintr_code, const char *name, void *handler, void *register_arg);

sceKernelReleaseSubIntrHandlerForDriver

Version NID
0.990-3.60 0x7B9657B3
int sceKernelReleaseSubIntrHandlerForDriver(int intr_code, int subintr_code);

sceKernelCallSubIntrHandlerForDriver

Version NID
0.990-3.60 0xCC94B294

Triggers a subinterrupt by directly calling it.

int sceKernelCallSubIntrHandlerForDriver(int intr_code, int subintr_code, void *subintr_arg);

sceKernelEnableSubIntrForDriver

Version NID
0.990-3.60 0x901E41D8

It also calls fptr1 of the registered reg_intr_opt2 as: reg_intr_opt2.fptr1(intrcode, subintr_code).

int sceKernelEnableSubIntrForDriver(unsigned int intrcode, unsigned int subintr_code);

sceKernelDisableSubIntrForDriver

Version NID
0.990-3.60 0x259C6D9E

Calls fptr2 of the registered reg_intr_opt2 as: reg_intr_opt2.fptr2(intr_code, subintr_code).

int sceKernelDisableSubIntrForDriver(int intr_code, int subintr_code);

sceKernelSuspendSubIntrForDriver

Version NID
0.990-3.60 0x3A9EA7D1

Calls fptr3 of the registered reg_intr_opt2 as: reg_intr_opt2.fptr3(intr_code, subintr_code, arg).

int sceKernelSuspendSubIntrForDriver(int intr_code, int subintr_code, void *arg);

sceKernelResumeSubIntrForDriver

Version NID
0.990-3.60 0x957023D0

sceKernelRegisterIntrHookHandlerForDriver

Version NID
0.990-3.60 0x99048AEC

sceKernelReleaseIntrHookHandlerForDriver

Version NID
0.990-3.60 0xA0B7F44E

invoke_callback_842B45DC

Version NID
0.990 not present
3.60 0xC568F145

invoke callback that was set with 0x842B45DC

int invoke_callback_842B45DC(int arg1);

SceIntrmgrForKernel

SceIntrmgrForKernel_A60D79A4

Version NID
0.940-3.60 0xA60D79A4
3.65 0xBCD3BB05

Enables interrupts (cpsie i).

void SceIntrmgrForKernel_A60D79A4(void);

set_callback_842B45DC

Version NID
3.60 0x842B45DC

sets callback function to global variable

void set_callback_842B45DC(void* fptr);

sceKernelGetIntrPendingStatusForDebuggerForKernel

Version NID
0.990-3.60 0xA269003D

sceKernelClearIntrPendingStatusForDebuggerForKernel

Version NID
0.990-3.60 0x4DC48A01

sceKernelAllocSystemCallTableForKernel

Version NID
0.990-3.60 0xB60ACF4B
3.65 0xB5A665C7

Temp name was sceKernelAllocSyscallTableForKernel.

Calls sceKernelAllocPartitionMemBlockForKernel(0x10009, "SceSyscallTable", 0x1020D006, 4 * numSyscalls, 0).

0x10009 is the UID of the "SceKernelRoot" partition.

/**
 * @brief Allocates the system call table.
 *
 * @param[in]	  numSyscalls     Number of syscalls the allocated table should be able to hold
 * @param[in,out] ppTableBase     Pointer to a variable that will recieve the syscall table's base address (must not be NULL)
 * @retval	(-1) numSyscalls is 0, or the table has already been allocated
 * @retval      (<0) Error code
 * @retval	(>0) UID of the syscall table memory block
 */
SceUID sceKernelAllocSystemCallTableForKernel(SceUInt32 numSyscalls, void** ppTableBase);

sceKernelQueryIntrHandlerInfoForKernel

Version NID
0.990-3.60 0xB5AFAE49
int sceKernelQueryIntrHandlerInfoForKernel(unsigned int intr_code, unsigned int a2, int a3);

get_intr_logs

Version NID
0.990 0xB04086C6
3.60 not present

Read Physical_Memory#Interrupt_registers and writes logs to str_buf.

int get_intr_logs(char *str_buf, unsigned int max_len);

sceKernelPMonSetThreadModeMaskForKernel

Version NID
0.990 0x730CB409
3.60 not present
int sceKernelPMonSetThreadModeMaskForKernel(unsigned int mask);

sceKernelGetVfpIntRegsAddrForKernel

Version NID
? 0xB2497FBC

SceIntrmgrForTZS

sceKernelUsleepForTZS

Version NID
0.931 0xC0908EA9

sceKernelRegisterMonitorCallHandlerForTZS

Version NID
0.931-1.80 0xC188114F

Register a SMC (secure only).

int sceKernelRegisterMonitorCallHandlerForTZS(int smc_id, void **func);

sceKernelRegisterIntrHandlerForTZS

Version NID
0.931-1.80 0x6B84DA8F
typedef struct SceKernelRegisterInterruptOptionsExtended { // size is 0x28
	unsigned int size;
	unsigned int unk_4;
	unsigned int unk_8;
	SceKernelIntrOptParam2Callback1 *release_subintr_cb;
	SceKernelIntrOptParam2Callback1 *fptr0;
	SceKernelIntrOptParam2Callback1 *enable_subintr_cb;
	SceKernelIntrOptParam2Callback1 *disable_subintr_cb;
	SceKernelIntrOptParam2Callback2 *fptr3;
	unsigned int unk_20;
	unsigned int unk_24;
} SceKernelRegisterInterruptOptionsExtended;

typedef struct SceKernelRegisterInterruptOptions { // size is 0x14
	unsigned int size;
	unsigned int num;
	SceKernelRegisterInterruptOptionsExtended *opt2;
	unsigned int flags; /* 0b1 = use sensitivity param */
	unsigned int sensitivity;
} SceKernelRegisterInterruptOptions;

typedef int (SceKernelIntrHandler)(int intr_code, void* userCtx);

int sceKernelRegisterIntrHandlerForTZS(int code, const char *name, int interrupt_type, SceKernelIntrHandler *handler, void* userCtx, int priority, int targetcpu, SceKernelRegisterInterruptOptions *pOpt);

sceKernelReleaseIntrHandlerForTZS

Version NID
0.931 0x75A0F189

sceKernelSetIntrPriorityForTZS

Version NID
0.931 0x9168E78E

sceKernelGetIntrPriorityForTZS

Version NID
0.931 0xFEAC9841

sceKernelSetIntrTargetCpuForTZS

Version NID
0.931 0xAA3C4787

sceKernelGetIntrTargetCpuForTZS

Version NID
0.931 0xF3B92D98

sceKernelDisableIntrForTZS

Version NID
0.931 0x4F39B381

sceKernelEnableIntrForTZS

Version NID
0.931 0x98E38390

sceKernelResumeIntrForTZS

Version NID
0.931 0x92DE2E92

sceKernelSuspendIntrForTZS

Version NID
0.931 0xBFBEAB5C

sceKernelIsIntrContextForTZS

Version NID
0.931 0x636F4549

sceKernelGenerateSoftIntrForTZS

Version NID
0.931 0x28BBA975
int sceKernelGenerateSoftIntrForTZS(SceUInt32 intr_code, SceUInt32 filter, SceUInt32 target);

Controller

The interrupt controller is defined in the MPCore TRM [1]. The PERIPHBASE address (physical) is 0x1A000000.

Registered Interrupts

As specified in GIC Architecture, interrupt 0-15 are software generated interrupts. There are also no private peripheral interrupts (16-31) implemented. Core Handler indicates which core handles the exception. "All" means it can be handled by any core.

Secure

Code Name Target CPU Priority
11 ScePervasive 0 80
33 SceBusErrorSecure All 16
34 SceEmcTop All 80
135 SceTimerForUsleep 2 128
200 SceSblSmSchedCry2Arm0 3 128
201 SceSblSmSchedCry2Arm123 3 128
202 SceSblSmSchedCry2Arm123 3 128
203 SceSblSmSchedCry2Arm123 3 128

Non-secure

Code Name Target CPU Priority
0 SceSDfMgrBreakSgiHandler 0xF 16
1 SceSDfMgrThreadSgiHandler 0xF 32
2 SceThreadmgrSGI 0xF 48
4 SceSblSmSchedProxySGI 0xF 128
6 SceKernelProcessmgr 0xF 80
7 SceThreadmgrSGILow 0xF 80
8 SceDisplayVbStartSGI 0xF 160
10 ScePowerMain 0xF 80
15 SceUsbMass 0xF 208
32 SceBusError 0xF 16
36 SceThreadmgrVfpException0 0x1 16
37 SceThreadmgrVfpException1 0x2 16
38 SceThreadmgrVfpException2 0x4 16
39 SceThreadmgrVfpException3 0x8 16
49 SceGpio1Gate2 0xF 160
50 SceGpio1Gate3 0xF 192
51 SceGpio1Gate4 0xF 208
52 SceGpuLisr 0xF 80
60 SceMsifIns 0xF 128
61 SceMsifSmshc 0xF 128
68 SceCompat0c 0x1 160
69 SceCompat1c 0x2 160
70 SceCompat2c 0x4 160
71 SceCompat0r 0x1 160
72 SceCompat1r 0x2 160
73 SceCompat2r 0x4 160
74 SceCompatLcdc 0x1 160
80 SceVeneziaMailbox00 0xF 208
81 SceVeneziaMailbox01 0xF 208
82 SceVeneziaMailbox02 0xF 208
83 SceVeneziaMailbox03 0xF 208
84 SceVeneziaMailbox04 0xF 208
85 SceVeneziaMailbox05 0xF 208
86 SceVeneziaMailbox06 0xF 208
87 SceVeneziaMailbox07 0xF 208
88 SceVeneziaMailbox08 0xF 208
89 SceVeneziaMailbox09 0xF 208
90 SceVeneziaMailbox10 0xF 208
91 SceVeneziaMailbox11 0xF 208
92 SceVeneziaMailbox12 0xF 208
93 SceVeneziaMailbox13 0xF 208
94 SceVeneziaMailbox14 0xF 208
95 SceVeneziaMailbox15 0xF 208
112 SceDmacmgrDmac0Ch0 0xF 128
113 SceDmacmgrDmac0Ch1 0xF 128
114 SceDmacmgrDmac1Ch0 0xF 128
115 SceDmacmgrDmac1Ch1 0xF 128
116 SceDmacmgrDmac2Ch0 0xF 128
117 SceDmacmgrDmac2Ch1 0xF 128
118 SceDmacmgrDmac3Ch0 0xF 128
119 SceDmacmgrDmac3Ch1 0xF 128
120 SceDmacmgrDmac4Gate0 0x80000 128
121 SceDmacmgrDmac4Gate1 0x80000 128
122 SceDmacmgrDmac4Gate2 0x80000 128
123 SceDmacmgrDmac4Gate3 0x80000 128
124 SceDmacmgrDmac5Ch0 0xF 128
125 SceDmacmgrDmac5Ch1 0xF 128
126 SceDmacmgrDmac6Ch0 0xF 128
127 SceDmacmgrDmac6Ch1 0xF 128
128 SceSystimerWordTimer0 0xF 128
129 SceSystimerWordTimer1 0xF 128
130 SceSystimerWordTimer2 0xF 128
131 SceSystimerWordTimer3 0xF 128
132 SceSystimerWordTimer4 0xF 128
133 SceSystimerWordTimer5 0xF 128
134 SceSystimerWordTimer7 0xF 128
136 SceSystimerLongrangeTimer0 0xF 128
137 SceSystimerLongrangeTimer1 0xF 128
138 SceSystimerLongrangeTimer2 0xF 128
139 SceSystimerLongrangeTimer3 0xF 128
140 SceSystimerLongrangeTimer4 0xF 128
141 SceThreadmgrTimer 0xF 48
142 SceI2c0 0xF 160
143 SceI2c1 0xF 160
145 SceUsbOhci0 0xF 160
146 SceUsbEhci0 0xF 160
147 SceUsbOhci1 0xF 160
148 SceUsbEhci1 0xF 160
149 SceUsbOhci2 0xF 160
150 SceUsbEhci2 0xF 160
151 SceUdcd1_EP0 0xF 128
152 SceUdcd1_EP1-7 0xF 128
155 SceUdcd2_EP0 0xF 128
156 SceUdcd2_EP1-7 0xF 128
160 SceCsi0 0xF 160
162 SceCsi1 0xF 160
164 SceUdcd1_phy-ready 0xF 128
165 SceUdcd1_vbus 0xF 128
166 SceCif0 0xF 160
168 SceCif1 0xF 160
170 SceUdcd2_phy-ready 0xF 128
171 SceUdcd2_vbus 0xF 128
176 SceSDbgSdio0Mbox 0x1 16
177 SceSDbgSdio0Mbox 0x2 16
178 SceSDbgSdio0Mbox 0x4 16
179 SceSDbgSdio0Mbox 0x8 16
184 SceDbgSdio1Mbox0 0xF 128
193 SceI2s0 0x80000 160
194 SceI2s1 0x80000 160
196 SceI2s2 0x80000 160
204 SceIftu0a 0xF 80
205 SceIftu0b 0xF 80
206 SceIftu1a 0xF 80
207 SceIftu1b 0xF 80
210 SceDsi1 0xF 160
213 SceDsi0 0xF 160
220 SceSdif0 0xF 128
221 SceSdif1 0xF 128
222 SceSdif2 0xF 128
225 SceUart1 0x10000 80
230 SceUart6 0x10000 16
244 SceKernelPaPmoni 0xF 208
248 SceGpio0Gate0 0xF 80
249 SceGpio0Gate1 0xF 112
250 SceGpio0Gate2 0xF 160
251 SceGpio0Gate3 0xF 192
252 SceGpio0Gate4 0xF 208
253 SceGpio1Gate0 0xF 80
254 SceGpio1Gate1 0xF 112
255 SceIftu2 0xF 80

Registered Subinterrupts

Interrupt code Subinterrupt code World Registered names
8 3 Non-secure SceCtrlVblank
8 5 Non-secure SceTouchVblank
8 25 Non-secure SceLedVblank
8 26 Non-secure ScePowerVblank
248 4 Non-secure SceSysconCmdclr
249 13 Non-secure SceHdmiIntr