SceExcpmgr

From Vita Development Wiki
Jump to navigation Jump to search

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.

Module

This module exists in both non-secure and secure world. The non-secure world SELF can be found in os0:kd/sysmem.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 SceExcpmgrForKernel Non-secure Kernel 0x4CA0FDD5
3.60 SceExcpmgrForKernel Non-secure Kernel 0x4CA0FDD5
3.65 SceExcpmgrForKernel Non-secure Kernel 0x1496A5B5
1.69 SceExcpmgrForTZS Secure Kernel 0x8F526F35

SceExcpmgrForKernel

sceKernelRegisterPriorityExceptionHandlerForKernel

Version NID
3.60 0x03499636

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

Unknown functions

         SceExcpmgrForKernel_00063675: 0x00063675
         SceExcpmgrForKernel_1FBF5654: 0x1FBF5654
         SceExcpmgrForKernel_293DFA04: 0x293DFA04
         SceExcpmgrForKernel_3E55B5C3: 0x3E55B5C3
         SceExcpmgrForKernel_416C0E20: 0x416C0E20
         SceExcpmgrForKernel_4337DD78: 0x4337DD78
         SceExcpmgrForKernel_44CE04B8: 0x44CE04B8
         SceExcpmgrForKernel_5420ED8F: 0x5420ED8F
         SceExcpmgrForKernel_58F7212B: 0x58F7212B
         SceExcpmgrForKernel_64A057C7: 0x64A057C7
         SceExcpmgrForKernel_96C2869C: 0x96C2869C
         SceExcpmgrForKernel_9EE59C6E: 0x9EE59C6E
         SceExcpmgrForKernel_B615A7DA: 0xB615A7DA
         SceExcpmgrForKernel_B7B10796: 0xB7B10796
         SceExcpmgrForKernel_D195E55C: 0xD195E55C
         SceExcpmgrForKernel_DA7BB671: 0xDA7BB671
         SceExcpmgrForKernel_E7487AFD: 0xE7487AFD

SceExcpmgrForTZS

Exceptions

SVC

The Syscalls 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

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

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.
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).
0x11D
int smc_mips_set_memory_bank_start_paddr(int bank, unsigned int paddr);
Valid banks 0-7, and paddrs: 0x20000000-0x2FFFFFFF and 0x42800000-0x7FFFFFFF.
0x120
int smc_mips_get_memory_bank_start_paddr(int bank);
Valid banks 0-7.
0x122
int smc_intr_crash(char *error_type, void *TTBR0, void *VBAR, int sysroot_vaddr);
0x12D
int smc_create_sm_operation(int priority, void *sm_self_data_paddr, unsigned int num_pairs, int block_index);
Used by sceSblSmSchedProxyInvoke.
0x12E
int smc_sched_proxy_wait(SmOperationHandle operation_handle, int block_index);
Used by sceSblSmSchedProxyWait.
0x12F
int smc_sched_proxy_get_status(SmOperationHandle operation_handle, int block_index);
Used by sceSblSmSchedProxyGetStatus.
0x130
int smc_change_F00D_status(SmOperationHandle operation_handle);
0x131 Not implemented
0x132 Not implemented
0x133
int smc_set_command_F00D_register(SmOperationHandle operation_handle, int f00d_fifo_register_index, int f00d_fifo_register_value);
Used by sceSblSmSchedCallFunc. cmd_paddr is paddr(SceSblSmschedCallFuncCommand) | 1.
0x134
int smc_get_command_F00D_register(SmOperationHandle operation_handle, int f00d_fifo_register_index, int block_index);
0x135
int smc_set_unknown_F00D_register(SmOperationHandle operation_handle, int f00d_fifo_register_index, int f00d_fifo_register_value);
0x136
int smc_set_status_code_F00D_register(SmOperationHandle operation_handle, int f00d_fifo_register_index, int f00d_fifo_register_value);
0x137
int smc_get_status_code_F00D_register(SmOperationHandle operation_handle, int f00d_fifo_register_index, int block_index);
0x138
int smc_enable_cry2arm_interrupt(SmOperationHandle operation_handle, unsigned int intr_index);
0x139
int smc_disable_cry2arm_interrupt(SmOperationHandle operation_handle, unsigned int intr_index);
0x13A
int smc_enable_all_cry2arm_interrupts(SmOperationHandle operation_handle, int intr_index, int block_index);
0x13B
int smc_sched_proxy_uninitialize();
0x13C
int smc_execute_f00d_command(F00D_cmd_index cmd_index);
Called by SceSblSsMgr SysEvent handler just before entering suspend mode.
0x168
int smc_0x168_dmac(int index, int value);
SceDmacmgrDmac related. Writes value to SceDmacmgrDmacN + 0x100.
0x169
int smc_0x169_dmac(int index, int value);
SceDmacmgrDmac related. Writes value to SceDmacmgrDmacN + 0x104.
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 the sceKernelMemcpyUserToKernel or sceKernelMemcpyKernelToUser (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.