SceExcpmgr is a kernel module that sets up exception handling and 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.
This module exists in both non-secure and secure world. The non-secure world SELF can be found in
This module only exports kernel libraries.
Installs an exception handler.
int sceKernelRegisterPriorityExceptionHandlerForKernel(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 Syscalls interface is defined in non-secure kernel as:
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.
The SMC interface for making a non-secure kernel call to secure-kernel is:
|R12||Secure service 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. 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.
int smc_set_sce_shared_memory_block_s(unsigned int paddr, unsigned int size);
|Disables the virtual ranges: |
|Flushes (and kills if there is activity) the PLE (Preload Engine) and then cleans and invalidates all the L1 Dcache.|
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|
|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.|
int smc_reset_device(int type, int mode);
|Reset device (check  for more info).|
int smc_mips_set_memory_bank_start_paddr(int bank, unsigned int paddr);
|Valid banks 0-7, and paddrs: |
int smc_mips_get_memory_bank_start_paddr(int bank);
|Valid banks 0-7.|
int smc_intr_crash(char *error_type, void *TTBR0, void *VBAR, int sysroot_vaddr);
int smc_sbl_sm_sched_proxy_invoke(int priority, uintptr_t paddr, unsigned int num_pairs, int id);
|Used by sceSblSmSchedProxyInvoke.|
int smc_sbl_sm_sched_proxy_wait(int id, int idx);
|Used by sceSblSmSchedProxyWait.|
int smc_sbl_sm_sched_proxy_get_status(int id, int idx);
|Used by sceSblSmSchedProxyGetStatus.|
|0x130||SBL SM Sched related|
int smc_sbl_sm_sched_call_func(int id, int unk, uintptr_t cmd_paddr);
|Used by sceSblSmSchedCallFunc. |
|0x134||SBL SM Sched related|
|0x135||SBL SM Sched related|
|0x136||SBL SM Sched related|
|0x137||SBL SM Sched related|
|0x138||SBL SM Sched related|
|0x139||SBL SM Sched related|
|0x13A||SBL SM Sched related. Interrupt Cry2Arm set enable.|
|0x13B||SBL SM Sched related. Interrupt Cry2Arm clear enable.|
|0x13C||SBL SM Sched related. Waits polling.||Called by SceSblSsMgr SysEvent handler just before entering suspend mode.|
int smc_0x168_dmac(int index, int value);
|SceDmacmgrDmac related. Writes |
int smc_0x169_dmac(int index, int value);
|SceDmacmgrDmac related. Writes |
int smc_l2_write_control_register(int value);
|Flushes and invalidates the entire L2 Cache (Clean and Invalidate by Way with |
int smc_l2_write_auxiliary_control_register(int value);
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
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 the
sceKernelMemcpyKernelToUser (or related functions), the data abort handler will resume execution.
IRQs are only handled in non-secure world. An IRQ in secure world is fatal. 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.