SceKernelIntrMgr

From Vita Development Wiki
Revision as of 13:24, 8 November 2022 by CelesteBlue (talk | contribs)
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.

Code World Registered names Core Handler Priority
0 Non-secure SceSDfMgrBreakSgiHandler 0 16
1 Non-secure SceSDfMgrThreadSgiHandler 0 32
2 Non-secure SceThreadmgrSGI 0 48
4 Non-secure SceSblSmSchedProxySGI 0 128
6 Non-secure SceKernelProcessmgr 0 80
8 Non-secure SceDisplayVbStartSGI, SceCtrlVblank 0 160
10 Non-secure ScePowerMain 0 80
11 Secure ScePervasive 0 80
32 Non-secure SceBusError All 16
33 Secure SceBusErrorSecure All 16
34 Secure SceEmcTop All 80
36 Non-secure SceIntrmgrVfpException0 All 16
37 Non-secure SceIntrmgrVfpException1 All 16
38 Non-secure SceIntrmgrVfpException2 All 16
39 Non-secure SceIntrmgrVfpException3 All 16
49 Non-secure SceGpio1Gate2 All 160
50 Non-secure SceGpio1Gate3 All 192
51 Non-secure SceGpio1Gate4 All 208
52 Non-secure SceGpuLisr All 80
56 Non-secure SceVipMailbox0 All 208
60 Non-secure SceMsifIns All 128
61 Non-secure SceMsifSmshc All 128
68 Non-secure SceCompat4 / SceCompat0c 0 160
69 Non-secure SceCompat5 / SceCompat1c 1 160
70 Non-secure SceCompat6 / SceCompat2c 2 160
71 Non-secure SceCompat7 / SceCompat0r 0 160
72 Non-secure SceCompat8 / SceCompat1r 1 160
73 Non-secure SceCompat9 / SceCompat2r 2 160
74 Non-secure SceCompat10 / SceCompatLcdc 0 160
80 Non-secure SceVeneziaMailbox00 All 208
81 Non-secure SceVeneziaMailbox01 All 208
82 Non-secure SceVeneziaMailbox02 All 208
83 Non-secure SceVeneziaMailbox03 All 208
84 Non-secure SceVeneziaMailbox04 All 208
85 Non-secure SceVeneziaMailbox05 All 208
86 Non-secure SceVeneziaMailbox06 All 208
87 Non-secure SceVeneziaMailbox07 All 208
88 Non-secure SceVeneziaMailbox08 All 208
89 Non-secure SceVeneziaMailbox09 All 208
90 Non-secure SceVeneziaMailbox10 All 208
91 Non-secure SceVeneziaMailbox11 All 208
92 Non-secure SceVeneziaMailbox12 All 208
93 Non-secure SceVeneziaMailbox13 All 208
94 Non-secure SceVeneziaMailbox14 All 208
95 Non-secure SceVeneziaMailbox15 All 208
112 Non-secure SceDmacmgrDmac0Ch0 All 128
113 Non-secure SceDmacmgrDmac0Ch1 All 128
114 Non-secure SceDmacmgrDmac1Ch0 All 128
115 Non-secure SceDmacmgrDmac1Ch1 All 128
116 Non-secure SceDmacmgrDmac2Ch0 All 128
117 Non-secure SceDmacmgrDmac2Ch1 All 128
118 Non-secure SceDmacmgrDmac3Ch0 All 128
119 Non-secure SceDmacmgrDmac3Ch1 All 128
120 Non-secure SceDmacmgrDmac4Gate0 3 128
121 Non-secure SceDmacmgrDmac4Gate1 3 128
122 Non-secure SceDmacmgrDmac4Gate2 3 128
123 Non-secure SceDmacmgrDmac4Gate3 3 128
124 Non-secure SceDmacmgrDmac5Ch0 All 128
125 Non-secure SceDmacmgrDmac5Ch1 All 128
126 Non-secure SceDmacmgrDmac6Ch0 All 128
127 Non-secure SceDmacmgrDmac6Ch1 All 128
128 Non-secure SceSystimerWordTimer0 All 128
129 Non-secure SceSystimerWordTimer1 All 128
130 Non-secure SceSystimerWordTimer2 All 128
131 Non-secure SceSystimerWordTimer3 All 128
132 Non-secure SceSystimerWordTimer4 All 128
133 Non-secure SceSystimerWordTimer5 All 128
134 Non-secure SceSystimerWordTimer6 All 128
135 Secure SceTimerForUsleep 2 128
136 Non-secure SceSystimerLongrangeTimer0 All 128
137 Non-secure SceSystimerLongrangeTimer1 All 128
138 Non-secure SceSystimerLongrangeTimer2 All 128
139 Non-secure SceSystimerLongrangeTimer3 All 128
140 Non-secure SceSystimerLongrangeTimer4 All 128
141 Non-secure SceThreadmgrTimer All 48
142 Non-secure SceI2c0 All 160
143 Non-secure SceI2c1 All 160
145 Non-secure ? All 160
146 Non-secure SceUsbEhci0 All 160
147 Non-secure ? All 160
148 Non-secure SceUsbEhci1 All 160
149 Non-secure ? All 160
150 Non-secure SceUsbEhci2 All 160
151 Non-secure SceUdcd1_EP0 All 128
152 Non-secure SceUdcd1_EP1-7 All 128
155 Non-secure SceUdcd2_EP0 All 128
156 Non-secure SceUdcd2_EP1-7 All 128
160 Non-secure SceCsi0 All 160
162 Non-secure SceCsi1 All 160
164 Non-secure SceUdcd1_phy-ready All 128
165 Non-secure SceUdcd1_vbus All 128
166 Non-secure SceCif0 All 160
168 Non-secure SceCif1 All 160
170 Non-secure SceUdcd2_phy-ready All 128
171 Non-secure SceUdcd2_vbus All 128
176 Non-secure SceSDbgSdio0Mbox 0 16
177 Non-secure SceSDbgSdio0Mbox 1 16
178 Non-secure SceSDbgSdio0Mbox 2 16
179 Non-secure SceSDbgSdio0Mbox 3 16
181 Non-secure SceUdcd0_EP0 All 128
182 Non-secure SceUdcd0_EP1-7 All 128
184 Non-secure ? All 128
190 Non-secure SceUdcd0_phy-ready All 128
191 Non-secure SceUdcd0_vbus All 128
193 Non-secure ? 3 160
194 Non-secure SceI2s1 3 160
193 Non-secure SceI2s0 3 160
196 Non-secure SceI2s2 3 160
200 Secure SceSblSmSchedCry2Arm0 3 128
201 Secure SceSblSmSchedCry2Arm123 3 128
202 Secure SceSblSmSchedCry2Arm123 3 128
203 Secure SceSblSmSchedCry2Arm123 3 128
204 Non-secure SceIftu0a All 80
205 Non-secure SceIftu0b All 80
206 Non-secure SceIftu1a All 80
207 Non-secure SceIftu1b All 80
210 Non-secure SceDisplayVbStartHDMI / SceDsi1 All 160
213 Non-secure SceDisplayVbStartMainLCD / SceDsi0 All 160
220 Non-secure SceSdif0 All 128
221 Non-secure SceSdif1 All 128
222 Non-secure SceSdif2 All 128
223 ? SceSdif3 (not present on 1.69) ? ?
225 Non-secure SceUart1 All 80
248 Non-secure SceGpio0Gate0 All 80
249 Non-secure SceGpio0Gate1 All 112
250 Non-secure SceGpio0Gate2 All 160
251 Non-secure SceGpio0Gate3 All 192
252 Non-secure SceGpio0Gate4 All 208
253 Non-secure SceGpio1Gate0 All 80
254 Non-secure SceGpio1Gate1 All 112
255 Non-secure SceIftu2 All 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