SceExcpmgr: Difference between revisions
CelesteBlue (talk | contribs) |
CelesteBlue (talk | contribs) |
||
Line 359: | Line 359: | ||
|- | |- | ||
| 0x12D | | 0x12D | ||
| <source lang="c">int | | <source lang="c">int smc_sm_sched_proxy_invoke(SceBool priority, void *sm_self_paddr, SceUInt32 num_pairs, SceUInt32 block_index);</source> | ||
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyInvokeForKernel|sceSblSmSchedProxyInvokeForKernel]]. | | Used by [[SceSblSmschedProxy#sceSblSmSchedProxyInvokeForKernel|sceSblSmSchedProxyInvokeForKernel]]. | ||
|- | |- | ||
| 0x12E | | 0x12E | ||
| <source lang="c">int | | <source lang="c">int smc_sm_sched_proxy_wait(SmOperationHandle handle, SceUInt32 block_index);</source> | ||
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyWaitForKernel|sceSblSmSchedProxyWaitForKernel]]. | | Used by [[SceSblSmschedProxy#sceSblSmSchedProxyWaitForKernel|sceSblSmSchedProxyWaitForKernel]]. | ||
|- | |- | ||
| 0x12F | | 0x12F | ||
| <source lang="c">int | | <source lang="c">int smc_sm_sched_proxy_get_status(SmOperationHandle handle, SceUInt32 block_index);</source> | ||
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyGetStatusForKernel|sceSblSmSchedProxyGetStatusForKernel]]. | | Used by [[SceSblSmschedProxy#sceSblSmSchedProxyGetStatusForKernel|sceSblSmSchedProxyGetStatusForKernel]]. | ||
|- | |- | ||
| 0x130 | | 0x130 | ||
| <source lang="c">int | | <source lang="c">int smc_sm_sched_proxy_kill(SmOperationHandle handle);</source> | ||
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyKillForKernel|sceSblSmSchedProxyKillForKernel]]. | | Used by [[SceSblSmschedProxy#sceSblSmSchedProxyKillForKernel|sceSblSmSchedProxyKillForKernel]]. | ||
|- | |- | ||
Line 383: | Line 383: | ||
|- | |- | ||
| 0x133 | | 0x133 | ||
| <source lang="c">int smc_set_command_F00D_register(SmOperationHandle | | <source lang="c">int smc_set_command_F00D_register(SmOperationHandle handle, int f00d_fifo_register_index, int f00d_fifo_register_value);</source> | ||
| Used by [[SceSblSmschedProxy#sceSblSmSchedCallFuncForKernel|sceSblSmSchedCallFuncForKernel]]. <code>cmd_paddr</code> is <code>paddr(SceSblSmschedCallFuncCommand) | 1</code>. | | Used by [[SceSblSmschedProxy#sceSblSmSchedCallFuncForKernel|sceSblSmSchedCallFuncForKernel]]. <code>cmd_paddr</code> is <code>paddr(SceSblSmschedCallFuncCommand) | 1</code>. | ||
|- | |- | ||
| 0x134 | | 0x134 | ||
| <source lang="c">int smc_get_command_F00D_register(SmOperationHandle | | <source lang="c">int smc_get_command_F00D_register(SmOperationHandle handle, int f00d_fifo_register_index, SceUInt32 block_index);</source> | ||
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyGetCommandF00DRegisterForKernel|sceSblSmSchedProxyGetCommandF00DRegisterForKernel]]. | | Used by [[SceSblSmschedProxy#sceSblSmSchedProxyGetCommandF00DRegisterForKernel|sceSblSmSchedProxyGetCommandF00DRegisterForKernel]]. | ||
|- | |- | ||
| 0x135 | | 0x135 | ||
| <source lang="c">int smc_set_unknown_F00D_register(SmOperationHandle | | <source lang="c">int smc_set_unknown_F00D_register(SmOperationHandle handle, int f00d_fifo_register_index, int f00d_fifo_register_value);</source> | ||
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxySetUnknownF00DRegisterForKernel|sceSblSmSchedProxySetUnknownF00DRegisterForKernel]]. | | Used by [[SceSblSmschedProxy#sceSblSmSchedProxySetUnknownF00DRegisterForKernel|sceSblSmSchedProxySetUnknownF00DRegisterForKernel]]. | ||
|- | |- | ||
| 0x136 | | 0x136 | ||
| <source lang="c">int | | <source lang="c">int smc_sm_sched_proxy_write_cry2arm(SmOperationHandle handle, int f00d_fifo_register_index, int f00d_fifo_register_value);</source> | ||
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyWriteCry2ArmForKernel|sceSblSmSchedProxyWriteCry2ArmForKernel]]. | | Used by [[SceSblSmschedProxy#sceSblSmSchedProxyWriteCry2ArmForKernel|sceSblSmSchedProxyWriteCry2ArmForKernel]]. | ||
|- | |- | ||
| 0x137 | | 0x137 | ||
| <source lang="c">int | | <source lang="c">int smc_sm_sched_proxy_read_cry2arm(SmOperationHandle handle, int f00d_fifo_register_index, SceUInt32 block_index);</source> | ||
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyReadCry2ArmForKernel|sceSblSmSchedProxyReadCry2ArmForKernel]]. | | Used by [[SceSblSmschedProxy#sceSblSmSchedProxyReadCry2ArmForKernel|sceSblSmSchedProxyReadCry2ArmForKernel]]. | ||
|- | |- | ||
| 0x138 | | 0x138 | ||
| <source lang="c">int | | <source lang="c">int smc_sm_sched_proxy_register_intr_handler(SmOperationHandle handle, SmOperationId req_id);</source> | ||
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyRegisterIntrHandlerForKernel|sceSblSmSchedProxyRegisterIntrHandlerForKernel]]. | | Used by [[SceSblSmschedProxy#sceSblSmSchedProxyRegisterIntrHandlerForKernel|sceSblSmSchedProxyRegisterIntrHandlerForKernel]]. | ||
|- | |- | ||
| 0x139 | | 0x139 | ||
| <source lang="c">int | | <source lang="c">int smc_sm_sched_proxy_release_intr_handler(SmOperationHandle handle, SmOperationId req_id);</source> | ||
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyReleaseIntrHandlerForKernel|sceSblSmSchedProxyReleaseIntrHandlerForKernel]]. | | Used by [[SceSblSmschedProxy#sceSblSmSchedProxyReleaseIntrHandlerForKernel|sceSblSmSchedProxyReleaseIntrHandlerForKernel]]. | ||
|- | |- | ||
| 0x13A | | 0x13A | ||
| <source lang="c">int smc_enable_all_cry2arm_interrupts(SmOperationHandle | | <source lang="c">int smc_enable_all_cry2arm_interrupts(SmOperationHandle handle, SmOperationId req_id, SceUInt32 block_index);</source> | ||
| Interrupt Cry2Arm set enable. | | Interrupt Cry2Arm set enable. | ||
|- | |- | ||
| 0x13B | | 0x13B | ||
| <source lang="c">int | | <source lang="c">int smc_sm_sched_proxy_uninitialize(void);</source> | ||
| Interrupt Cry2Arm clear enable. Used by [[SceSblSmschedProxy#sceSblSmSchedProxyUninitializeForKernel|sceSblSmSchedProxyUninitializeForKernel]]. | | Interrupt Cry2Arm clear enable. Used by [[SceSblSmschedProxy#sceSblSmSchedProxyUninitializeForKernel|sceSblSmSchedProxyUninitializeForKernel]]. | ||
|- | |- | ||
Line 424: | Line 424: | ||
| 0x168 | | 0x168 | ||
| <source lang="c">int smc_0x168_dmac(int index, int value);</source> | | <source lang="c">int smc_0x168_dmac(int index, int value);</source> | ||
| SceDmacmgrDmac related. Writes <code>value</code> to SceDmacmgrDmac<code>N</code> + <code>0x100</code>. | | SceDmacmgrDmac related. Writes <code>value</code> to SceDmacmgrDmac<code>N</code> + <code>0x100</code>. Maybe key_id related. | ||
|- | |- | ||
| 0x169 | | 0x169 | ||
| <source lang="c">int smc_0x169_dmac(int index, int value);</source> | | <source lang="c">int smc_0x169_dmac(int index, int value);</source> | ||
| SceDmacmgrDmac related. Writes <code>value</code> to SceDmacmgrDmac<code>N</code> + <code>0x104</code>. | | SceDmacmgrDmac related. Writes <code>value</code> to SceDmacmgrDmac<code>N</code> + <code>0x104</code>. Maybe key_id related. | ||
|- | |- | ||
| 0x16A | | 0x16A |
Revision as of 20:48, 4 June 2020
SceExcpmgr is a kernel module that sets up exception handling. A version exists in both worlds. In non-secure world, after the kernel is booted up, the exception handlers pointed to by VBAR all jump into code in this module.
Module
This module exists in both non-secure and secure world. The non-secure world SELF can be found in os0:kd/excpmgr.skprx
.
Known NIDs
Version | Name | World | Privilege | NID |
---|---|---|---|---|
1.69 | SceExcpmgr | Non-secure | Kernel | 0xBBCA9AB6 |
3.60 | SceExcpmgr | Non-secure | Kernel | 0xF3D9E37C |
3.65 | SceExcpmgr | Non-secure | Kernel | 0xB5616C8A |
1.69 | SceExcpmgr | Secure | Kernel | 0x93332B9A |
Libraries
This module only exports kernel libraries.
Known NIDs
Version | Name | World | Visibility | NID |
---|---|---|---|---|
1.69-3.60 | SceExcpmgrForKernel | Non-secure | Kernel | 0x4CA0FDD5 |
3.65 | SceExcpmgrForKernel | Non-secure | Kernel | 0x1496A5B5 |
1.69-1.80 | SceExcpmgrForTZS | Secure | Kernel | 0x8F526F35 |
To find
sceKernelDefaultHandlerCfunc sceKernelDefaultHandlerSvcCfunc sceKernelDefaultHandlerIrqCfunc sceKernelDefaultHandlerReservedCfunc sceKernelPanicHandlerUndefCfunc sceKernelPanicHandlerDabtCfunc sceKernelPanicHandlerUndefCfunc sceKernelPanicHandlerPabtCfunc
These 8 function names must be of the following NIDs:
sceExcpmgrGetDataForKernel: 0x08CB30E6 SceExcpmgrForKernel_3AE9AEE1: 0x3AE9AEE1 SceExcpmgrForKernel_4FF90618: 0x4FF90618 SceExcpmgrForKernel_7ADF11DB: 0x7ADF11DB SceExcpmgrForKernel_8D223205: 0x8D223205 SceExcpmgrForKernel_A66DDFA3: 0xA66DDFA3 SceExcpmgrForKernel_C45C0D3D: 0xC45C0D3D SceExcpmgrForKernel_D464A9A7: 0xD464A9A7
SceExcpmgrForKernel
sceKernelRegisterExceptionHandlerForKernel
Version | NID |
---|---|
0.990-3.60 | 0x03499636 |
Wrong name was ksceExcpmgrRegisterHandler.
Installs an exception handler.
int sceKernelRegisterExceptionHandlerForKernel(int excpcode, int priority, void *function);
The function must be ARM and not thumb, and the allowed priority values are from 0 to 7 (including them).
Where excpcode can be:
- Reset: excpcode = 0
- Undefined Instruction: excpcode = 1
- Supervisor Call: excpcode = 2
- Prefetch Abort: excpcode = 3
- Data Abort: excpcode = 4
- Not used: excpcode = 5
- IRQ interrupt: excpcode = 6
- FIQ interrupt: excpcode = 7
The syscall handler at 1.50 is SceExcpmgr_func_0x81000E40
sceKernelRegisterDefaultExceptionHandlerForKernel
Version | NID |
---|---|
0.990-3.60 | 0xFFCCB5F9 |
sceKernelReleaseExceptionHandlerForKernel
Version | NID |
---|---|
0.990-3.60 | 0xE04AE286 |
sceKernelReleaseDefaultExceptionHandlerForKernel
Version | NID |
---|---|
0.990 | 0x917A6D2B |
sceKernelInitialHandlerDebugUndefCfuncForKernel
Version | NID |
---|---|
0.990-3.60 | 0xB77DCBD6 |
sceKernelInitialHandlerDebugPabtCfuncForKernel
Version | NID |
---|---|
0.990-3.60 | 0x25C0C91B |
sceKernelInitialHandlerDebugDabtCfuncForKernel
Version | NID |
---|---|
0.990-3.60 | 0xFFFA3353 |
sceKernelPanicHandlerReturnFromNestedExceptionCfuncForKernel
Version | NID |
---|---|
0.990-3.60 | 0xD17EEE40 |
void sceKernelRegisterExceptionHandlerForKernel(int a1);
sceKernelDefaultHandlerResetCfuncForKernel
Version | NID |
---|---|
0.990-3.60 | 0xA90AC525 |
sceKernelGetExcpStackBottomForKernel
Version | NID |
---|---|
0.990-3.60 | 0x4C603645 |
sceExcpmgrGetDataForKernel
Version | NID |
---|---|
3.60 | 0x08CB30E6 |
SceExcpmgrForTZS
SceExcpmgrForTZS_get_default_excp_handler
Version | NID |
---|---|
0.931-1.80 | 0x07A5790B |
sceKernelReleaseExceptionHandlerForTZS
Version | NID |
---|---|
0.931-1.80 | 0x166C9362 |
sceKernelReleaseDefaultExceptionHandlerForTZS
Version | NID |
---|---|
0.931-1.80 | 0x6282E52C |
sceKernelRegisterDefaultExceptionHandlerForTZS
Version | NID |
---|---|
0.931-1.80 | 0xA0434735 |
sceKernelRegisterMonitorEntryForTZS
Version | NID |
---|---|
0.931-3.60 | 0xAC297406 |
// some_id must be in the 0-7 range int sceKernelRegisterMonitorEntryForTZS(int some_id, void *pParam);
sceKernelRegisterExceptionHandlerForTZS
Version | NID |
---|---|
0.931-1.80 | 0xDD4C680D |
Exceptions
SVC
SVC (Supervisor Call), more commonly called Syscalls (system calls), is what allows to interact with non-secure kernel from usermode.
The SVC interface is defined in non-secure kernel as:
Register | Value |
---|---|
R0 | First argument |
R1 | Second argument |
R2 | Third argument |
R3 | Fourth argument |
R12 | Syscall number |
On return, R1-R3 and R12 are cleared to 0x0 or 0xDEADBEEF to prevent any data leaks. All user pointers passed to syscalls are accessed with ARM instructions LDRT and STRT for hardware forced permission checks. Syscalls 0x0 - 0xFF are likely a "fastcall" interface that do not mask interrupts or set the DACR, however currently are no such fastcalls defined. Syscalls 0x100 - 0xFFF are made with IRQ interrupts masked and DACR set to 0xFFFF0000 (to prevent access to certain memory domains). Any other syscall numbers are invalid.
System calls are handled in "system" mode defined in ARMv7 (mode 0b11111).
User exported functions loaded by SceKernelModulemgr are exported as syscalls. The number assigned to the syscall are randomized with respect to each library but not within a library. That means, for example, two functions exported by a library will always be some syscall number apart even though that number will change on each boot.
There is no SVC in secure world because all code in secure world is running as kernel.
SMC
SMC (Secure Monitor Call) is what allows to interact with ARM TrustZone from non-secure kernel.
The SMC interface for making a non-secure kernel call to secure kernel is:
Register | Value |
---|---|
R0 | First argument |
R1 | Second argument |
R2 | Third argument |
R3 | Fourth argument |
R12 | Secure service number |
The SMC interface is very similar to SVC interface. The SMC handler and MVBAR is set up in Secure World by SceExcpmgrForTZS.
0x0 - 0xFF are fast service calls. 0x100 - 0xFFF are normal service calls ran with IRQs masked.
Secure services are ran in ARM system processor mode (0b11111) in the Secure World.
SMC calls are registered by SceIntrmgrForTZS functions.
SMC calls
Number | Arguments | Notes |
---|---|---|
0x101 | int smc_set_sce_shared_memory_block_s(unsigned int paddr, unsigned int size); |
|
0x103 | int smc_disable_virtual_ranges(void); |
Disables the virtual ranges: 0x40000000 -0x40100000 , 0x50000000 -0x51000000 and 0x51000000 -0x52000000 to the context with PID 0x10007.
|
0x10F | int smc_ple_flush_kill_and_l1_dcache_clean_invalidate_all(void); |
Flushes (and kills if there is activity) the PLE (Preload Engine) and then cleans and invalidates all the L1 Dcache. |
0x110 | int smc_compat_set_state(int a1, int command); |
With a1 set to 2, used to enable/disable some things used by the PSP Emulator. Maybe the CPU, or memory for example. Command: 0 (stop), 1 (start), 2 (LCD DMAC init). |
0x114 | int smc_bus_freq_op(int operation, unsigned int freq); |
op = 0: Set bus frequency, op = 1: Get bus frequency, op = 2: Set GPU Xbar frequency, op = 3: Get GPU Xbar frequency |
0x117 | int smc_cdram_enable(void); |
Seems to enable the CDRAM (by using the SceEmcTop registers). |
0x118 | CDRAM related | Seems to enable something CDRAM related. |
0x119 | CDRAM related | Seems to disable something CDRAM related. |
0x11A | int smc_reset_device(int type, int mode); |
Reset device (check [1] for more info). |
0x11C | Used by SceLowio#SceGrabForDriver_188BBCC8. | |
0x11D | int smc_compat_set_memory_bank_start_paddr(int bank, unsigned int paddr); |
Valid banks 0-7, and paddrs: 0x20000000 -0x2FFFFFFF and 0x42800000 -0x7FFFFFFF .
|
0x11E | int smc_compat_set_state_ex(int command, int ex); |
Replacement for SMC 0x110. Used to enable/disable some things used by the PSP Emulator. Maybe the CPU, or memory for example. Command: 0 (stop), 1 (start), 2 (LCD DMAC init). Ex is only used for start (maybe for resume/suspend). |
0x120 | int smc_compat_get_memory_bank_start_paddr(int bank); |
Valid banks 0-7. |
0x122 | int smc_intr_crash(int type, void *pTTBR0, void *pVBAR, void *pSysbase); |
type: 0 (exception), 1 (panic_or_assertion_failed) |
0x12D | int smc_sm_sched_proxy_invoke(SceBool priority, void *sm_self_paddr, SceUInt32 num_pairs, SceUInt32 block_index); |
Used by sceSblSmSchedProxyInvokeForKernel. |
0x12E | int smc_sm_sched_proxy_wait(SmOperationHandle handle, SceUInt32 block_index); |
Used by sceSblSmSchedProxyWaitForKernel. |
0x12F | int smc_sm_sched_proxy_get_status(SmOperationHandle handle, SceUInt32 block_index); |
Used by sceSblSmSchedProxyGetStatusForKernel. |
0x130 | int smc_sm_sched_proxy_kill(SmOperationHandle handle); |
Used by sceSblSmSchedProxyKillForKernel. |
0x131 | Not implemented | |
0x132 | Not implemented | |
0x133 | int smc_set_command_F00D_register(SmOperationHandle handle, int f00d_fifo_register_index, int f00d_fifo_register_value); |
Used by sceSblSmSchedCallFuncForKernel. cmd_paddr is paddr(SceSblSmschedCallFuncCommand) | 1 .
|
0x134 | int smc_get_command_F00D_register(SmOperationHandle handle, int f00d_fifo_register_index, SceUInt32 block_index); |
Used by sceSblSmSchedProxyGetCommandF00DRegisterForKernel. |
0x135 | int smc_set_unknown_F00D_register(SmOperationHandle handle, int f00d_fifo_register_index, int f00d_fifo_register_value); |
Used by sceSblSmSchedProxySetUnknownF00DRegisterForKernel. |
0x136 | int smc_sm_sched_proxy_write_cry2arm(SmOperationHandle handle, int f00d_fifo_register_index, int f00d_fifo_register_value); |
Used by sceSblSmSchedProxyWriteCry2ArmForKernel. |
0x137 | int smc_sm_sched_proxy_read_cry2arm(SmOperationHandle handle, int f00d_fifo_register_index, SceUInt32 block_index); |
Used by sceSblSmSchedProxyReadCry2ArmForKernel. |
0x138 | int smc_sm_sched_proxy_register_intr_handler(SmOperationHandle handle, SmOperationId req_id); |
Used by sceSblSmSchedProxyRegisterIntrHandlerForKernel. |
0x139 | int smc_sm_sched_proxy_release_intr_handler(SmOperationHandle handle, SmOperationId req_id); |
Used by sceSblSmSchedProxyReleaseIntrHandlerForKernel. |
0x13A | int smc_enable_all_cry2arm_interrupts(SmOperationHandle handle, SmOperationId req_id, SceUInt32 block_index); |
Interrupt Cry2Arm set enable. |
0x13B | int smc_sm_sched_proxy_uninitialize(void); |
Interrupt Cry2Arm clear enable. Used by sceSblSmSchedProxyUninitializeForKernel. |
0x13C | int smc_execute_f00d_command(F00D_cmd_index cmd_index); |
Called by SceSblSsMgr SysEvent handler just before entering suspend mode. Waits by polling. Used by sceSblSmSchedProxyExecuteF00DCommandForKernel. |
0x168 | int smc_0x168_dmac(int index, int value); |
SceDmacmgrDmac related. Writes value to SceDmacmgrDmacN + 0x100 . Maybe key_id related.
|
0x169 | int smc_0x169_dmac(int index, int value); |
SceDmacmgrDmac related. Writes value to SceDmacmgrDmacN + 0x104 . Maybe key_id related.
|
0x16A | int smc_l2_write_control_register(int value); |
Flushes and invalidates the entire L2 Cache (Clean and Invalidate by Way with way = 0xFFFF , offset 0x7FC ), then performs an L2 Cache Sync (offset 0x730 ), and finally writes value to the L2 Control Register (offset 0x100 ).
|
0x16B | int smc_l2_write_auxiliary_control_register(int value); |
Writes value to the L2 Auxiliary Control Register (offset 0x104 ).
|
Aborts
On development units, data and prefetch aborts can handle BKPT instruction for software breakpoints. SceDebug uses this to handle usermode breakpoints. There is no built-in support for BKPT in kernel code.
SceSysmem uses data aborts with the LDRT
and STRT
instructions to implement user pointer checking. When LDRT/STRT throws a MMU data exception because of an invalid access and the exception came from SceSysmem#sceKernelCopyFromUserForDriver or SceSysmem#sceKernelCopyToUserForDriver or related functions, the data abort handler will resume execution.
IRQ
IRQs are only handled in non-secure world. An IRQ in secure world is fatal. See SceKernelIntrMgr.
FIQ
FIQs are only handled in secure world because of the bit set in the SCR. Because of this, it is likely that secure devices such as the F00D Processor use FIQs to communicate with the Cortex A9 cores. See SceKernelIntrMgr.