Difference between revisions of "SceExcpmgr"

From Vita Development Wiki
Jump to navigation Jump to search
(30 intermediate revisions by 2 users not shown)
Line 4: Line 4:
 
This module exists in both non-secure and secure world. The non-secure world SELF can be found in <code>os0:kd/excpmgr.skprx</code>.
 
This module exists in both non-secure and secure world. The non-secure world SELF can be found in <code>os0:kd/excpmgr.skprx</code>.
  
=== Known NIDs ===
 
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! Version !! Name !! World !! Privilege !! NID
+
! Version !! World !! Privilege
|-
 
| 1.69 || SceExcpmgr || Non-secure || Kernel || 0xBBCA9AB6
 
|-
 
| 3.60 || SceExcpmgr || Non-secure || Kernel || 0xF3D9E37C
 
 
|-
 
|-
| 3.65 || SceExcpmgr || Non-secure || Kernel || 0xB5616C8A
+
| 1.69-3.65 || Non-secure || Kernel
 
|-
 
|-
| 1.69 || SceExcpmgr || Secure || Kernel || 0x93332B9A
+
| 1.69 || Secure || Kernel
 
|}
 
|}
  
Line 39: Line 34:
 
     sceKernelDefaultHandlerIrqCfunc
 
     sceKernelDefaultHandlerIrqCfunc
 
     sceKernelDefaultHandlerReservedCfunc
 
     sceKernelDefaultHandlerReservedCfunc
   
 
 
     sceKernelPanicHandlerUndefCfunc
 
     sceKernelPanicHandlerUndefCfunc
 
     sceKernelPanicHandlerDabtCfunc
 
     sceKernelPanicHandlerDabtCfunc
    sceKernelPanicHandlerUndefCfunc
 
 
     sceKernelPanicHandlerPabtCfunc
 
     sceKernelPanicHandlerPabtCfunc
  
These 8 function names must be of the following NIDs:
+
These 7 function names must be of the following NIDs:
  
 
           sceExcpmgrGetDataForKernel: 0x08CB30E6
 
           sceExcpmgrGetDataForKernel: 0x08CB30E6
Line 66: Line 59:
 
|}
 
|}
  
Wrong name was ksceExcpmgrRegisterHandler.
+
Temp name was sceExcpmgrRegisterHandlerForKernel.
  
 
Installs an exception handler.
 
Installs an exception handler.
Line 75: Line 68:
  
 
Where excpcode can be:
 
Where excpcode can be:
* Reset: excpcode = 0
+
* Reset (RESET): 0
* Undefined Instruction: excpcode = 1
+
* Undefined Instruction (UNDEF): 1
* Supervisor Call: excpcode = 2
+
* Supervisor Call (SVC): 2
* Prefetch Abort: excpcode = 3
+
* Prefetch Abort (PABT): 3
* Data Abort: excpcode = 4
+
* Data Abort (DABT): 4
* Not used: excpcode = 5
+
* Reserved (RESERVED): 5
* IRQ interrupt: excpcode = 6
+
* Interrupt (IRQ): 6
* FIQ interrupt: excpcode = 7
+
* Fast Interrupt (FIQ): 7
  
The syscall handler at 1.50 is SceExcpmgr_func_0x81000E40
+
The syscall handler in FW 1.50 is SceExcpmgr_func_0x81000E40.
  
 
=== sceKernelRegisterDefaultExceptionHandlerForKernel ===
 
=== sceKernelRegisterDefaultExceptionHandlerForKernel ===
Line 207: Line 200:
 
! Version !! NID
 
! Version !! NID
 
|-
 
|-
| 0.931-1.80 || 0xAC297406
+
| 0.931-3.60 || 0xAC297406
 
|}
 
|}
 +
 +
<source lang="C">
 +
// some_id must be in the 0-7 range
 +
int sceKernelRegisterMonitorEntryForTZS(int some_id, void *pParam);
 +
</source>
  
 
=== sceKernelRegisterExceptionHandlerForTZS ===
 
=== sceKernelRegisterExceptionHandlerForTZS ===
Line 219: Line 217:
  
 
== Exceptions ==
 
== Exceptions ==
 +
 
=== SVC ===
 
=== SVC ===
  
The [[Syscalls]] interface is defined in non-secure kernel as:
+
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:
 +
 
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
Line 252: Line 254:
  
 
=== SMC ===
 
=== 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:
 
The SMC interface for making a non-secure kernel call to secure kernel is:
Line 272: Line 276:
 
|-
 
|-
 
| R12
 
| R12
| Secure service number
+
| SMC number
 
|}
 
|}
  
The SMC interface is very similar to SVC from userland to non-secure kernel. The SMC handler and MVBAR is set up in secure world by [[#SceExcpmgrForTZS|SceExcpmgrForTZS]]. 0x0 - 0xFF are fast service calls. 0x100 - 0xFFF are normal service calls ran with IRQs masked.
+
The SMC interface is very similar to SVC interface. The SMC handler and MVBAR is set up in [[Secure World]] by [[#SceExcpmgrForTZS|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.
+
Secure services are ran in ARM system processor mode (0b11111) in the [[Secure World]].
  
SMC calls are registered by [[SceKernelIntrMgr|SceIntrmgrForTZS]].
+
SMC calls are registered by [[SceKernelIntrMgr|SceIntrmgrForTZS]] functions.
  
 
==== SMC calls ====
 
==== SMC calls ====
Line 286: Line 292:
 
|-
 
|-
 
! Number
 
! Number
 +
! Module
 
! Arguments
 
! Arguments
 
! Notes
 
! Notes
 
|-
 
|-
 
| 0x101
 
| 0x101
| <source lang="c">int smc_set_sce_shared_memory_block_s(unsigned int paddr, unsigned int size);</source>
+
|
 +
| <source lang="C">int AllocSharedMemory_S(void *pPA, SceSize size);</source>
 
|
 
|
 
|-
 
|-
 
| 0x103
 
| 0x103
| <source lang="c">int smc_disable_virtual_ranges(void);</source>
+
|
| Disables the virtual ranges: <code>0x40000000</code>-<code>0x40100000</code>, <code>0x50000000</code>-<code>0x51000000</code> and <code>0x51000000</code>-<code>0x52000000</code> to the context with PID 0x10007.
+
| <source lang="C">int FreeSharedMemory_S(void);</source>
 +
| Frees the allocation of virtual ranges: <code>0x40000000</code>-<code>0x40100000</code>, <code>0x50000000</code>-<code>0x51000000</code> and <code>0x51000000</code>-<code>0x52000000</code> with UID 0x10007. This is SKBL only and does not affect NSKBL.
 +
|-
 +
| 0x104
 +
|
 +
| <source lang="C">int PervasiveAccessMode(int mode, SceBool cmd);</source>
 +
| cmd: 0 clear, 1 set
 +
|-
 +
| 0x105
 +
|
 +
| <source lang="C">int TASAccessMode(int mode, SceBool cmd);</source>
 +
| cmd: 0 clear, 1 set
 +
|-
 +
| 0x106
 +
|
 +
| <source lang="C">int Pervasive2AccessMode(int mode, SceBool cmd);</source>
 +
| cmd: 0 clear, 1 set
 +
|-
 +
| 0x107
 +
|
 +
| <source lang="C">int RegbusAccessMode(int mode, SceBool cmd);</source>
 +
| cmd: 0 clear, 1 set
 +
|-
 +
| 0x10A
 +
|
 +
| <source lang="C">int GetGrabCmpMap(int index);</source>
 +
| Gets GRAB Compatibility Map.
 +
|-
 +
| 0x10B
 +
|
 +
| <source lang="C">int SetGrabCmpMap(int index, int map);</source>
 +
| Sets GRAB Compatibility Map.
 +
|-
 +
| 0x10C
 +
| [[SceKernelBusError]]
 +
| <source lang="C">int BusErrorDump(void);</source>
 +
| Used by [[SceKernelBusError]] when a bus error is handled, just before getting bus error info. Writes bus registers to (shared memory + 0x4000).
 +
|-
 +
| 0x10D
 +
| [[SceKernelBusError]]
 +
| <source lang="C">int BusErrorDump2(void);</source>
 +
| Used by [[SceKernelBusError]] when a bus error is handled, just before getting bus error info. Writes bus registers to (shared memory + 0x6000). Replacement of SMC 0x10C that writes to offset 0x6000 instead of 0x4000 and calls sceKernelDcacheCleanInvalidateRange before returning.
 +
|-
 +
| 0x10E
 +
| [[SceKernelBusError]]
 +
| <source lang="C">int BusErrorClear(void);</source>
 +
| On FW 0.931, prints a tree of all bus states. On FW 3.60, does nothing and return 0.
 
|-
 
|-
 
| 0x10F
 
| 0x10F
| <source lang="c">int smc_ple_flush_kill_and_l1_dcache_clean_invalidate_all(void);</source>
+
|
 +
| <source lang="C">int smc_ple_flush_kill_and_l1_dcache_clean_invalidate_all(void);</source>
 
| Flushes (and kills if there is activity) the PLE (Preload Engine) and then cleans and invalidates all the L1 Dcache.
 
| Flushes (and kills if there is activity) the PLE (Preload Engine) and then cleans and invalidates all the L1 Dcache.
 
|-
 
|-
 
| 0x110
 
| 0x110
| <source lang="c">int smc_set_compat_state(int a1, int a2);</source>
+
| [[SceDriverTzs]]
| With a1=2, used to enable/disable some things used by the PSP Emulator. Maybe the CPU, or memory for example.
+
| <source lang="C">int smc_bus_set_state(int bus, int command);</source>
 +
| bus: 1 -> used by [[SceEnumWakeUp]], 2 -> used to enable/disable some things used by the PSP Emulator; maybe CPU, or memory for example. Command: 0 (stop), 1 (start), 2 (LCD DMAC init).
 +
|-
 +
| 0x111
 +
| [[SceDriverTzs]]
 +
|
 +
| Related to bus.
 +
|-
 +
| 0x113
 +
| [[SceDriverTzs]]
 +
|
 +
| Related to bus.
 
|-
 
|-
 
| 0x114
 
| 0x114
| <source lang="c">int smc_bus_freq_op(int operation, unsigned int freq);</source>
+
| [[SceDriverTzs]]
| op = 0: Set bus frequency, op = 1: Get bus frequency, op = 2: Set GPU Xbar frequency, op = 3: Get GPU Xbar frequency
+
| <source lang="c">int smc_bus_freq_op(SceUInt32 op, SceUInt32 freq_level);</source>
 +
| op: 0 - Set bus frequency, 1 - Get bus frequency, 2 - Set GPU Xbar frequency, 3 - Get GPU Xbar frequency
 
|-
 
|-
 
| 0x117
 
| 0x117
 +
| [[SceDriverTzs]]
 
| <source lang="c">int smc_cdram_enable(void);</source>
 
| <source lang="c">int smc_cdram_enable(void);</source>
 
| Seems to enable the CDRAM (by using the [[Physical Memory|SceEmcTop]] registers).
 
| Seems to enable the CDRAM (by using the [[Physical Memory|SceEmcTop]] registers).
 
|-
 
|-
 
| 0x118
 
| 0x118
| CDRAM related
+
| [[SceDriverTzs]]
 +
| <source lang="c">int smc_0x118(void);</source>
 
| Seems to enable something CDRAM related.
 
| Seems to enable something CDRAM related.
 
|-
 
|-
 
| 0x119
 
| 0x119
| CDRAM related
+
| [[SceDriverTzs]]
 +
| <source lang="c">int smc_0x119(void);</source>
 
| Seems to disable something CDRAM related.
 
| Seems to disable something CDRAM related.
 
|-
 
|-
 
| 0x11A
 
| 0x11A
| <source lang="c">int smc_reset_device(int type, int mode);</source>
+
| [[SceDriverTzs]]
| Reset device (check [https://wiki.henkaku.xyz/vita/SceSyscon#Reset_device] for more info).
+
| <source lang="c">int sceSysconSetPowerMode(int type, int mode);</source>
 +
| Set power mode. See [[SceSyscon#sceSysconSetPowerModeForDriver|sceSysconSetPowerModeForDriver]].
 +
|-
 +
| 0x11B
 +
| [[SceDriverTzs]]
 +
| <source lang="C">int smc_0x11B(int mode, SceBool cmd);</source>
 +
| mode: must be < 0x1000, cmd: 0 set, 1 clear
 +
|-
 +
| 0x11C
 +
| [[SceDriverTzs]]
 +
| <source lang="C">int smc_0x11C(SceUInt32 handle, SceInt32 value);</source>
 +
| Used by [[SceLowio#SceGrabForDriver_188BBCC8]].
 
|-
 
|-
 
| 0x11D
 
| 0x11D
| <source lang="c">int smc_mips_set_memory_bank_start_paddr(int bank, unsigned int paddr);</source>
+
| [[SceDriverTzs]]
| Valid banks 0-7, and paddrs: <code>0x20000000</code>-<code>0x2FFFFFFF</code> and <code>0x42800000</code>-<code>0x7FFFFFFF</code>.
+
| <source lang="c">int smc_compat_set_memory_bank_start_paddr(int bank, void *pPA);</source>
 +
| Valid banks: 0-7, and physical addresses: <code>0x20000000</code>-<code>0x2FFFFFFF</code> and <code>0x42800000</code>-<code>0x7FFFFFFF</code>.
 +
|-
 +
| 0x11E
 +
| [[SceDriverTzs]]
 +
| <source lang="c">int smc_compat_set_state_ex(int command, int ex);</source>
 +
| 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).
 +
|-
 +
| 0x11F
 +
| [[SceDriverTzs]]
 +
| <source lang="c">int smc_0x11F(int unk);</source>
 +
| Valid unk: 1-3. Waits something like a semaphore.
 
|-
 
|-
 
| 0x120
 
| 0x120
| <source lang="c">int smc_mips_get_memory_bank_start_paddr(int bank);</source>
+
| [[SceDriverTzs]]
 +
| <source lang="c">int smc_compat_get_memory_bank_start_paddr(int bank);</source>
 +
| Valid banks 0-7.
 +
|-
 +
| 0x121
 +
| [[SceDriverTzs]]
 +
| <source lang="c">int smc_0x121(int bank1, int bank2);</source>
 
| Valid banks 0-7.
 
| Valid banks 0-7.
 
|-
 
|-
 
| 0x122
 
| 0x122
| <source lang="c">int smc_intr_crash(char *error_type, void *TTBR0, void *VBAR, int sysroot_vaddr);</source>
+
| [[SceDriverTzs]]
|  
+
| <source lang="c">int smc_intr_crash(int type, void *pTTBR0, void *pVBAR, void *pSysbase);</source>
 +
| type: 0 (exception), 1 (panic_or_assertion_failed)
 
|-
 
|-
 
| 0x12D
 
| 0x12D
| <source lang="c">int smc_create_sm_operation(int priority, void *sm_self_data_paddr, unsigned int num_pairs, int block_index);</source>
+
|
 +
| <source lang="C">int sceSblSmSchedInvoke(SceBool priority, void *sm_self_paddr, SceUInt32 num_pa_range, SceSblTzsBridgeArgArea area);</source>
 
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyInvokeForKernel|sceSblSmSchedProxyInvokeForKernel]].
 
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyInvokeForKernel|sceSblSmSchedProxyInvokeForKernel]].
 
|-
 
|-
 
| 0x12E
 
| 0x12E
| <source lang="c">int smc_sched_proxy_wait(SmOperationHandle operation_handle, int block_index);</source>
+
|
 +
| <source lang="C">int sceSblSmSchedWait(SceSmSchedRequestId req_id, SceSblTzsBridgeArgArea area);</source>
 
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyWaitForKernel|sceSblSmSchedProxyWaitForKernel]].
 
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyWaitForKernel|sceSblSmSchedProxyWaitForKernel]].
 
|-
 
|-
 
| 0x12F
 
| 0x12F
| <source lang="c">int smc_sched_proxy_get_status(SmOperationHandle operation_handle, int block_index);</source>
+
|
 +
| <source lang="C">int sceSblSmSchedGetStatus(SceSmSchedRequestId req_id, SceSblTzsBridgeArgArea area);</source>
 
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyGetStatusForKernel|sceSblSmSchedProxyGetStatusForKernel]].
 
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyGetStatusForKernel|sceSblSmSchedProxyGetStatusForKernel]].
 
|-
 
|-
 
| 0x130
 
| 0x130
| <source lang="c">int smc_change_F00D_status(SmOperationHandle operation_handle);</source>
+
|
 +
| <source lang="C">int sceSblSmSchedKill(SceSmSchedRequestId req_id);</source>
 
|  Used by [[SceSblSmschedProxy#sceSblSmSchedProxyKillForKernel|sceSblSmSchedProxyKillForKernel]].
 
|  Used by [[SceSblSmschedProxy#sceSblSmSchedProxyKillForKernel|sceSblSmSchedProxyKillForKernel]].
 
|-
 
|-
 
| 0x131
 
| 0x131
| Not implemented
+
|
 +
| Reserved (on FWs 0.931-3.60).
 
|  
 
|  
 
|-
 
|-
 
| 0x132
 
| 0x132
| Not implemented
+
|
 +
| Reserved (on FWs 0.931-3.60).
 
|  
 
|  
 
|-
 
|-
 
| 0x133
 
| 0x133
| <source lang="c">int smc_set_command_F00D_register(SmOperationHandle operation_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>.
+
| <source lang="C">int smc_sm_sched_proxy_call_func(SceSmSchedRequestId req_id, int mailbox_id, SceUInt32 mailval);</source>
 +
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyCallFuncForKernel|sceSblSmSchedProxyCallFuncForKernel]]. <code>mailval</code> is <code>paddr(SceSblSmschedCallFuncCommand) | 1</code>.
 
|-
 
|-
 
| 0x134
 
| 0x134
| <source lang="c">int smc_get_command_F00D_register(SmOperationHandle operation_handle, int f00d_fifo_register_index, int block_index);</source>
+
|
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyGetCommandF00DRegisterForKernel|sceSblSmSchedProxyGetCommandF00DRegisterForKernel]].
+
| <source lang="C">int sceSblSmSchedReadArm2Cry(SceSmSchedRequestId req_id, int mailbox_id, SceUInt32 *pMailval);</source>
 +
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyReadArm2CryForKernel|sceSblSmSchedProxyReadArm2CryForKernel]].
 
|-
 
|-
 
| 0x135
 
| 0x135
| <source lang="c">int smc_set_unknown_F00D_register(SmOperationHandle operation_handle, int f00d_fifo_register_index, int f00d_fifo_register_value);</source>
+
|
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyGetUnknownF00DRegisterForKernel|sceSblSmSchedProxyGetUnknownF00DRegisterForKernel]].
+
| <source lang="C">int sceSblSmSchedWriteArm2Cry(SceSmSchedRequestId req_id, int mailbox_id, SceUInt32 mailval);</source>
 +
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyWriteArm2CryForKernel|sceSblSmSchedProxyWriteArm2CryForKernel]].
 
|-
 
|-
 
| 0x136
 
| 0x136
| <source lang="c">int smc_write_cry2arm(SmOperationHandle operation_handle, int f00d_fifo_register_index, int f00d_fifo_register_value);</source>
+
|
 +
| <source lang="C">int sceSblSmSchedWriteCry2Arm(SceSmSchedRequestId req_id, int mailbox_id, SceUInt32 mailval);</source>
 
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyWriteCry2ArmForKernel|sceSblSmSchedProxyWriteCry2ArmForKernel]].
 
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyWriteCry2ArmForKernel|sceSblSmSchedProxyWriteCry2ArmForKernel]].
 
|-
 
|-
 
| 0x137
 
| 0x137
| <source lang="c">int smc_read_cry2arm(SmOperationHandle operation_handle, int f00d_fifo_register_index, int block_index);</source>
+
|
 +
| <source lang="C">int sceSblSmSchedReadCry2Arm(SceSmSchedRequestId req_id, int mailbox_id, SceUInt32 *pMailval);</source>
 
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyReadCry2ArmForKernel|sceSblSmSchedProxyReadCry2ArmForKernel]].
 
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyReadCry2ArmForKernel|sceSblSmSchedProxyReadCry2ArmForKernel]].
 
|-
 
|-
 
| 0x138
 
| 0x138
| <source lang="c">int smc_enable_cry2arm_interrupt(SmOperationHandle operation_handle, unsigned int intr_index);</source>
+
|
 +
| <source lang="C">int sceSblSmSchedRegisterIntrHandler(SceSmSchedRequestId req_id, int mailbox_id);</source>
 
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyRegisterIntrHandlerForKernel|sceSblSmSchedProxyRegisterIntrHandlerForKernel]].
 
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyRegisterIntrHandlerForKernel|sceSblSmSchedProxyRegisterIntrHandlerForKernel]].
 
|-
 
|-
 
| 0x139
 
| 0x139
| <source lang="c">int smc_disable_cry2arm_interrupt(SmOperationHandle operation_handle, unsigned int intr_index);</source>
+
|
 +
| <source lang="C">int sceSblSmSchedReleaseIntrHandler(SceSmSchedRequestId req_id, int mailbox_id);</source>
 
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyReleaseIntrHandlerForKernel|sceSblSmSchedProxyReleaseIntrHandlerForKernel]].
 
| Used by [[SceSblSmschedProxy#sceSblSmSchedProxyReleaseIntrHandlerForKernel|sceSblSmSchedProxyReleaseIntrHandlerForKernel]].
 
|-
 
|-
 
| 0x13A
 
| 0x13A
| <source lang="c">int smc_enable_all_cry2arm_interrupts(SmOperationHandle operation_handle, int intr_index, int block_index);</source>
+
|
 +
| <source lang="c">int smc_sm_sched_proxy_enable_all_cry2arm_interrupts(SceSmSchedRequestId req_id, int mailbox_id, SceSblTzsBridgeArgArea area);</source>
 
| Interrupt Cry2Arm set enable.
 
| Interrupt Cry2Arm set enable.
 
|-
 
|-
 
| 0x13B
 
| 0x13B
| <source lang="c">int smc_sched_proxy_uninitialize();</source>
+
|
 +
| <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]].
 
|-
 
|-
 
| 0x13C
 
| 0x13C
| <source lang="c">int smc_execute_f00d_command(F00D_cmd_index cmd_index);</source>
+
|
| Called by [[SceSblSsMgr]] SysEvent handler just before entering suspend mode. Waits by polling. Used by [[SceSblSmschedProxy#sceSblSmSchedProxyExecuteF00DCommandForKernel|sceSblSmSchedProxyExecuteF00DCommandForKernel]].
+
| <source lang="c">int smc_sm_sched_proxy_execute_sk_command(sk_cmd_index cmd_index);</source>
 +
| Executes a [[Secure_Kernel#Secure_Kernel_Commands|Secure Kernel command]]. Used by [[SceSblSmschedProxy#sceSblSmSchedProxyExecuteSKCommandForKernel|sceSblSmSchedProxyExecuteSKCommandForKernel]].
 
|-
 
|-
 
| 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
 +
|
 
| <source lang="c">int smc_l2_write_control_register(int value);</source>
 
| <source lang="c">int smc_l2_write_control_register(int value);</source>
 
| Flushes and invalidates the entire L2 Cache (Clean and Invalidate by Way with <code>way = 0xFFFF</code>, offset <code>0x7FC</code>), then performs an L2 Cache Sync (offset <code>0x730</code>), and finally writes <code>value</code> to the L2 Control Register (offset <code>0x100</code>).
 
| Flushes and invalidates the entire L2 Cache (Clean and Invalidate by Way with <code>way = 0xFFFF</code>, offset <code>0x7FC</code>), then performs an L2 Cache Sync (offset <code>0x730</code>), and finally writes <code>value</code> to the L2 Control Register (offset <code>0x100</code>).
 
|-
 
|-
 
| 0x16B
 
| 0x16B
 +
|
 
| <source lang="c">int smc_l2_write_auxiliary_control_register(int value);</source>
 
| <source lang="c">int smc_l2_write_auxiliary_control_register(int value);</source>
 
| Writes <code>value</code> to the L2 Auxiliary Control Register (offset <code>0x104</code>).
 
| Writes <code>value</code> to the L2 Auxiliary Control Register (offset <code>0x104</code>).
Line 419: Line 538:
  
 
=== Aborts ===
 
=== 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.
 
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 <code>LDRT</code> and <code>STRT</code> instructions to implement user pointer checking. When LDRT/STRT throws a MMU data exception because of an invalid access and the exception came from the <code>sceKernelMemcpyUserToKernel</code> or <code>sceKernelMemcpyKernelToUser</code> (or related functions), the data abort handler will resume execution.
+
[[SceSysmem]] uses data aborts with the <code>LDRT</code> and <code>STRT</code> 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 ===
 
=== IRQ ===
 +
 
IRQs are only handled in non-secure world. An IRQ in secure world is fatal. See [[SceKernelIntrMgr]].
 
IRQs are only handled in non-secure world. An IRQ in secure world is fatal. See [[SceKernelIntrMgr]].
  
 
=== FIQ ===
 
=== 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]].
 
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]].
 +
  
 
[[Category:Modules]]
 
[[Category:Modules]]
 
[[Category:Kernel]]
 
[[Category:Kernel]]

Revision as of 07:41, 30 March 2021

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.

Version World Privilege
1.69-3.65 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 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
   sceKernelPanicHandlerPabtCfunc

These 7 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

Temp name was sceExcpmgrRegisterHandlerForKernel.

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 (RESET): 0
  • Undefined Instruction (UNDEF): 1
  • Supervisor Call (SVC): 2
  • Prefetch Abort (PABT): 3
  • Data Abort (DABT): 4
  • Reserved (RESERVED): 5
  • Interrupt (IRQ): 6
  • Fast Interrupt (FIQ): 7

The syscall handler in FW 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 SMC 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 Module Arguments Notes
0x101
int AllocSharedMemory_S(void *pPA, SceSize size);
0x103
int FreeSharedMemory_S(void);
Frees the allocation of virtual ranges: 0x40000000-0x40100000, 0x50000000-0x51000000 and 0x51000000-0x52000000 with UID 0x10007. This is SKBL only and does not affect NSKBL.
0x104
int PervasiveAccessMode(int mode, SceBool cmd);
cmd: 0 clear, 1 set
0x105
int TASAccessMode(int mode, SceBool cmd);
cmd: 0 clear, 1 set
0x106
int Pervasive2AccessMode(int mode, SceBool cmd);
cmd: 0 clear, 1 set
0x107
int RegbusAccessMode(int mode, SceBool cmd);
cmd: 0 clear, 1 set
0x10A
int GetGrabCmpMap(int index);
Gets GRAB Compatibility Map.
0x10B
int SetGrabCmpMap(int index, int map);
Sets GRAB Compatibility Map.
0x10C SceKernelBusError
int BusErrorDump(void);
Used by SceKernelBusError when a bus error is handled, just before getting bus error info. Writes bus registers to (shared memory + 0x4000).
0x10D SceKernelBusError
int BusErrorDump2(void);
Used by SceKernelBusError when a bus error is handled, just before getting bus error info. Writes bus registers to (shared memory + 0x6000). Replacement of SMC 0x10C that writes to offset 0x6000 instead of 0x4000 and calls sceKernelDcacheCleanInvalidateRange before returning.
0x10E SceKernelBusError
int BusErrorClear(void);
On FW 0.931, prints a tree of all bus states. On FW 3.60, does nothing and return 0.
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 SceDriverTzs
int smc_bus_set_state(int bus, int command);
bus: 1 -> used by SceEnumWakeUp, 2 -> used to enable/disable some things used by the PSP Emulator; maybe CPU, or memory for example. Command: 0 (stop), 1 (start), 2 (LCD DMAC init).
0x111 SceDriverTzs Related to bus.
0x113 SceDriverTzs Related to bus.
0x114 SceDriverTzs
int smc_bus_freq_op(SceUInt32 op, SceUInt32 freq_level);
op: 0 - Set bus frequency, 1 - Get bus frequency, 2 - Set GPU Xbar frequency, 3 - Get GPU Xbar frequency
0x117 SceDriverTzs
int smc_cdram_enable(void);
Seems to enable the CDRAM (by using the SceEmcTop registers).
0x118 SceDriverTzs
int smc_0x118(void);
Seems to enable something CDRAM related.
0x119 SceDriverTzs
int smc_0x119(void);
Seems to disable something CDRAM related.
0x11A SceDriverTzs
int sceSysconSetPowerMode(int type, int mode);
Set power mode. See sceSysconSetPowerModeForDriver.
0x11B SceDriverTzs
int smc_0x11B(int mode, SceBool cmd);
mode: must be < 0x1000, cmd: 0 set, 1 clear
0x11C SceDriverTzs
int smc_0x11C(SceUInt32 handle, SceInt32 value);
Used by SceLowio#SceGrabForDriver_188BBCC8.
0x11D SceDriverTzs
int smc_compat_set_memory_bank_start_paddr(int bank, void *pPA);
Valid banks: 0-7, and physical addresses: 0x20000000-0x2FFFFFFF and 0x42800000-0x7FFFFFFF.
0x11E SceDriverTzs
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).
0x11F SceDriverTzs
int smc_0x11F(int unk);
Valid unk: 1-3. Waits something like a semaphore.
0x120 SceDriverTzs
int smc_compat_get_memory_bank_start_paddr(int bank);
Valid banks 0-7.
0x121 SceDriverTzs
int smc_0x121(int bank1, int bank2);
Valid banks 0-7.
0x122 SceDriverTzs
int smc_intr_crash(int type, void *pTTBR0, void *pVBAR, void *pSysbase);
type: 0 (exception), 1 (panic_or_assertion_failed)
0x12D
int sceSblSmSchedInvoke(SceBool priority, void *sm_self_paddr, SceUInt32 num_pa_range, SceSblTzsBridgeArgArea area);
Used by sceSblSmSchedProxyInvokeForKernel.
0x12E
int sceSblSmSchedWait(SceSmSchedRequestId req_id, SceSblTzsBridgeArgArea area);
Used by sceSblSmSchedProxyWaitForKernel.
0x12F
int sceSblSmSchedGetStatus(SceSmSchedRequestId req_id, SceSblTzsBridgeArgArea area);
Used by sceSblSmSchedProxyGetStatusForKernel.
0x130
int sceSblSmSchedKill(SceSmSchedRequestId req_id);
Used by sceSblSmSchedProxyKillForKernel.
0x131 Reserved (on FWs 0.931-3.60).
0x132 Reserved (on FWs 0.931-3.60).
0x133
int smc_sm_sched_proxy_call_func(SceSmSchedRequestId req_id, int mailbox_id, SceUInt32 mailval);
Used by sceSblSmSchedProxyCallFuncForKernel. mailval is paddr(SceSblSmschedCallFuncCommand) | 1.
0x134
int sceSblSmSchedReadArm2Cry(SceSmSchedRequestId req_id, int mailbox_id, SceUInt32 *pMailval);
Used by sceSblSmSchedProxyReadArm2CryForKernel.
0x135
int sceSblSmSchedWriteArm2Cry(SceSmSchedRequestId req_id, int mailbox_id, SceUInt32 mailval);
Used by sceSblSmSchedProxyWriteArm2CryForKernel.
0x136
int sceSblSmSchedWriteCry2Arm(SceSmSchedRequestId req_id, int mailbox_id, SceUInt32 mailval);
Used by sceSblSmSchedProxyWriteCry2ArmForKernel.
0x137
int sceSblSmSchedReadCry2Arm(SceSmSchedRequestId req_id, int mailbox_id, SceUInt32 *pMailval);
Used by sceSblSmSchedProxyReadCry2ArmForKernel.
0x138
int sceSblSmSchedRegisterIntrHandler(SceSmSchedRequestId req_id, int mailbox_id);
Used by sceSblSmSchedProxyRegisterIntrHandlerForKernel.
0x139
int sceSblSmSchedReleaseIntrHandler(SceSmSchedRequestId req_id, int mailbox_id);
Used by sceSblSmSchedProxyReleaseIntrHandlerForKernel.
0x13A
int smc_sm_sched_proxy_enable_all_cry2arm_interrupts(SceSmSchedRequestId req_id, int mailbox_id, SceSblTzsBridgeArgArea area);
Interrupt Cry2Arm set enable.
0x13B
int smc_sm_sched_proxy_uninitialize(void);
Interrupt Cry2Arm clear enable. Used by sceSblSmSchedProxyUninitializeForKernel.
0x13C
int smc_sm_sched_proxy_execute_sk_command(sk_cmd_index cmd_index);
Executes a Secure Kernel command. Used by sceSblSmSchedProxyExecuteSKCommandForKernel.
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.