Cafe OS syscalls
Syscalls
Cafe OS syscalls are issued by doing the following:
li r0, 0x0100 # load syscall value->r0 sc # syscall instruction blr # return control to program
When you send a call to the kernel, it goes to 0xFFF00C00, which then jumps to 0xFFF021A0 + (fastcall << 5).
Normal syscalls are divisible by 0x100, so all of them will jump to 0xFFF0021A0 itself, which is a jump to the table dispatcher.
The dispatcher uses a RAMPID and the syscall dispatch tables at 0xFFEAAA40 (user table in 5.5.1) and 0xFFE84850 (loader table in 5.5.1) to get the secondary table each RAMPID is able to access.
RAMPIDs 0 (Kernel), 2, and 3 all use an empty table, while RAMPID 1 (root.rpx) has its own table with a few unique calls. RAMPIDs 4 (background app), 5 (home menu), and 6 (error display) share the same table and RAMPID 7 (foreground app) has it's own. See Cafe OS wiki page for more info.
Below is a list of what all of them, as well as the loader which has its own bare-bones table, have access to call. (sp) indicates that the loader uses a separate function for that syscall. Additionally, the loader uses the same function for IPCKDriver_Open/Close.
# | Name | root | Sys | App | Ldr |
---|---|---|---|---|---|
0x0000 | ConsoleWrite | X | X | X | X (sp) |
0x0100 | AppPanic | X | X | X | X |
0x0200 | EffectiveToPhysical | X | X | X | |
0x0300 | PhysicalToEffectiveCached | X | X | X | |
0x0400 | PhysicalToEffectiveUncached | X | X | X | |
0x0500 | ValidateAddrRange | X | X | X | X |
0x0600 | UpdateCoreTime | X | X | X | |
0x0800 | SetUserModeExHandler | X | X | X | |
0x0B00 | AllocateTimer | X | X | X | |
0x0C00 | FreeTimer | X | X | X | |
0x0D00 | PrimeTimer | X | X | X | |
0x0E00 | StopTimer | X | X | X | |
0x0F00 | DumpModuleList | X | X | X | |
0x1000 | SetInterruptHandler | X | X | X | |
0x1100 | GetInterruptHandler | X | X | X | |
0x1200 | DisableInterrupt | X | X | X | |
0x1300 | EnableInterrupt | X | X | X | |
0x1400 | ClearAndEnableInterrupt | X | X | X | |
0x1500 | GetInterruptStatus | X | X | X | |
0x1600 | ClearInterruptStatus | X | X | X | |
0x1700 | FindClosestSymbol | X | X | X | X (sp) |
0x1900 | Exit/Halt | X | X | X | |
0x1A00 | GetInfo | X | X | X | |
0x1B00 | SetInfo | X | X | X | |
0x1C00 | ReleaseCore | X | X | X | |
0x1D00 | SendICI | X | X | X | |
0x1E00 | IPCKDriver_{Loader|User}Open | X | X | X | X (sp) |
0x1F00 | IPCKDriver_{Loader|User}Close | X | X | X | X (sp) |
0x2000 | IPCKDriver_SubmitRequest | X | X | X | X (sp) |
0x2200 | GetEnvironmentVariable | X | X | X | |
0x2700 | GetNotifyTarget | X | X | X | |
0x2800 | ReleaseForeground | X | X | X | |
0x2900 | GetForegroundBucket | X | X | X | |
0x2A00 | RequestSwitch | X | X | X | |
0x2B00 | LaunchTitleArgvStr | X | X | X | |
0x2C00 | ProcYield | X | X | X | |
0x2E00 | GetSystemMessage | X | X | X | |
0x2F00 | GetCallArgs | X | X | X | |
0x3000 | GetAbsoluteSystemTimeInternal | X | X | X | |
0x3100 | SetAbsoluteSystemTimeInternal | X | X | X | |
0x3200 | Driver_Register | X | X | X | |
0x3300 | Driver_Deregister | X | X | X | |
0x3800 | AllocVirtAddr | X | X | X | |
0x3900 | FreeVirtAddr | X | X | X | |
0x3A00 | GetMapVirtAddrRange | X | X | X | |
0x3B00 | GetDataPhysAddrRange | X | X | X | |
0x3C00 | GetAvailPhysAddrRange | X | X | X | |
0x3D00 | MapMemory | X | X | X | |
0x3E00 | UnmapMemory | X | X | X | |
0x3F00 | LogBuffer | X | X | X | X |
0x4000 | LogArgs | X | X | X | X |
0x4100 | LogFunc | X | X | X | X |
0x4200 | LogReportKernel | X | X | X | X |
0x4300 | LogRetrieve | X | X | X | X |
0x4400 | (unknown) | X | X | X | |
0x4500 | (unknown) | X | X | X | |
0x4600 | save_fpu | X | X | X | |
0x4700 | Driver_CopyFromSaveArea | X | X | X | |
0x4800 | Driver_CopyToSaveArea | X | X | X | |
0x4900 | SavesDone_ReadyToRelease | X | X | X | |
0x4A00 | SetAlarm | X | X | X | |
0x4B00 | SetDABR | X | X | X | |
0x4C00 | SetIABR | X | X | X | |
0x4D00 | GetProcessInfo | X | X | X | |
0x4E00 | GetCodegenVirtAddrRange | X | X | X | |
0x4F00 | LoaderCall | X | X | X | |
0x5000 | RPLLoaderResumeContext | X | |||
0x5200 | WaitIopComplete | X | |||
0x5300 | FlushCode | X | |||
0x5400 | FlushData | X | |||
0x5500 | UpdateHeartbeat | X | |||
0x5600 | LogEntry | X | |||
0x5700 | FastClearMemory | X | |||
0x5800 | GetBusClockSpeed | X | |||
0x5900 | GetSharedArea | X | X | X | |
0x5A00 | SendPolicy | X | X | X | |
0x5B00 | GetProcessIndex | X | |||
0x5C00 | IPCKDriver_PollLoaderCompletion | X | |||
0x5D00 | BlockLogSave | X | X | X | |
0x5E00 | FinishInitandPreload | X | |||
0x5F00 | ContinueStartProcess | X | |||
0x6000 | OpenMCP | X | |||
0x6100 | QuerySwitchReady | X | X | X | |
0x6200 | launch_title | X | X | X | |
0x6300 | call_title | X | X | X | |
0x6400 | SetTimeInternal | X | |||
0x6500 | do_nothing (blr) | X | X | X | |
0x6600 | ProfileEntry (blr) | X | |||
0x6700 | RequestFastExit | X | X | X | |
0x6800 | CoreInitDone | X | X | X | |
0x6900 | GetSwitchTarget | X | X | X | |
0x6A00 | AcquireDone | X | X | X | |
0x6B00 | GetBuiltSDKVersion | X | X | X | |
0x6C00 | SystemFatal | X | X | X | |
0x6E00 | SwitchSecCodeGenMode | X | X | X | |
0x6F00 | IopShell_RegisterCallback | X | X | X | |
0x7000 | GetTitleVersion | X | X | X | |
0x7100 | IsTestKernel | X | X | X | |
0x7200 | ForceFullRelaunch | X | X | X | |
0x7300 | Recycle | X | |||
0x7400 | get_mode_flags | X | X | X | X |
0x7500 | QueryVirtAddr | X | X | X | |
0x7600 | GetCodegenCore | X | X | X | |
0x7700 | GetSecCodeGenMode | X | X | X | |
0x7800 | CodegenCopy | X | X | X | |
0x7900 | LoadShared | X | |||
0x7A00 | SetExceptionCallback | X | X | X | |
0x7B00 | IopShell_InjectCommand | X | X | X | |
0x7C00 | Kill | X | X | X | |
0x7D00 | EnableOverlayArena | X | X | X | |
0x7E00 | DisableOverlayArena | X | X | X | |
0x7F00 | GetSystemMode | X | X | X | |
0x8000 | SystemMode_RegisterCallback | X | X | X | |
0x8100 | ZeroProcessMemory | X | |||
0x8200 | HandleIopPowerEvents | X | |||
0x8300 | ConsoleTimestamp | X | X | X | X |
0x8400 | ValidateOverlayRange | X | |||
0x8500 | BadSysCall (jump to null on purpose) | X | X | X | X |
Fastcalls
Fastcalls, on the other hand, are system calls that aren't routed through the dispatcher and can be accessed by any RAMPID. Attempting to access an unimplemented fastcall will redirect the code flow to syscall 0x0100 (AppPanic).
Below is a list of all the currently supported fastcalls.
# | Name |
---|---|
0x0000 | (default branch to syscall dispatcher) |
0x0001 | SyncEIEIO |
0x0006 | LoadContext |
0x0007 | SaveContext |
0x0008 | SetCurrentContext |
0x0009 | GetCurrentFPUContext |
0x000A | SetCurrentFPUContext |
0x000B | CompareAndSwapCurrentFPUContext |
0x000C | WriteGatherInit |
0x000D | SetPerformanceMonitor |
0x000E | FlushDMAQueue |
0x000F | do_nothing (rfi) |
0x0010 | DisableFPU (???) |
0x0011 | ReadRegister32Ex |
0x0012 | WriteRegister32Ex |
0x0013 | Unknown (FPU?) |
0x0014 | Unknown (FPU?) |
0x0015 | Unknown (FPU?) |
0x0016 | Unknown (FPU?) |
0x0017 | WriteGatherGetPtr |
0x0018 | EnableFPU (???) |
0x0019 | GetSecurityLevel (always zero) |
0x001A | BadFastCall (jump to error on purpose) |