Coreinit.rpl

From WiiUBrew
Jump to navigation Jump to search

coreinit.rpl is the the system library that provides direct access to Cafe OS services. It provides kernel calls, thread scheduling, memory management, and filesystem services. coreinit is the first RPL loaded by the loader, even before the main executable itself.

Functions

Auto Power-Down

The Auto Power-Down feature in the WiiU saves the battery of the console, shutting down in one hour when there is no user activity.

Name Prototype Description
IMEnableAPD void IMEnableAPD(void) Enables the Auto Power-Down system.
IMDisableAPD void IMDisableAPD(void) Disables the Auto Power-Down system.
IMIsAPDEnabled void IMIsAPDEnabled(uint32_t *isEnabled) Writes the current Auto Power-Down setting to isEnabled: 0x0 = off, 0x1 = on.
IMIsAPDEnabledBySysSettings void IMIsAPDEnabledBySysSettings(uint32_t *isEnabled) Writes the current Auto Power-Down setting from system settings to isEnabled: 0x0 = off, 0x1 = on.
IMGetAPDPeriod void IMGetAPDPeriod(uint32_t *apd_secs) Returns the amount of seconds it takes of user inactivity to turn off the WiiU, if the Auto Power-Down setting is True. apd_secs is a pointer to the variable that stores the amount of seconds.
IMGetTimeBeforeAPD void IMGetTimeBeforeAPD(uint32_t *apd_secs) Returns the amount of seconds that are left until the WiiU powers down, if the Auto Power-Down setting is True. apd_secs is a pointer to the variable that stores the amount of seconds.

Driver

Name Prototype Description
OSDriver_Register uint32_t OSDriver_Register(char *drv_name, size_t name_len, void *buf1, void *buf2) Will register an OSDriver entity with the given name and bufs
OSDriver_Deregister uint32_t OSDriver_Deregister(char *drv_name, size_t name_len) Will try to find a OSDriver with the given name (and length because implementing a strlen was too hard), and deregister him
OSDriver_CopyToSaveArea uint32_t OSDriver_CopyToSaveArea(char *drv_name, size_t name_len, void *in_buf, size_t buf_size) Will copy buf to an OSDriver "safe" save area [0x44/4]
OSDriver_CopyFromSaveArea uint32_t OSDriver_CopyFromSaveArea(char *drv_name, size_t name_len, void *out_buf, size_t buf_size) Will copy data from the OSDriver save area to an user controlled buffer

Memory

Name Prototype Description
memset void *memset(void *str, int c, size_t n) Call OSBlockSet (Looks like it does the same thing as standart memset). Copies the character c (an unsigned char) to the first n characters of the String pointed to by the argument str. See [1]
memclr void *memclr(void *str, size_t n) Like memset but sets the memory to 0. Call OSBlockSet (memset) with 0 as second arg (r4).
memcpy void *memcpy(void *str1, const void *str2, size_t n) Call OSBlockMove with 1 as the fourth arg (r6).Copies n characters from memory area str2 to memory area str1. See [2]
memmove void *memmove(void *str1, const void *str2, size_t n) Call OSBlockMove with 1 as the fourth arg (r6) exactly the same as memcpy.
MEMAllocFromDefaultHeapEx void *MEMAllocFromDefaultHeapEx(uint32_t size, int alignment) Allocates memory on the heap with the given size and memory alignment. This is typically in the 0x4??????? memory area
MEMFreeToDefaultHeap void MEMFreeToDefaultHeap(void* addr) Frees previously heap memory. addr is the address returned by MEMAllocFromDefaultHeapEx()
OSAllocFromSystem void *OSAllocFromSystem(uint32_t size, int alignment) Allocates system memory with the given size and memory alignment. This is typically in the 0x10?????? memory area
OSFreeToSystem void OSFreeToSystem(void* addr) Frees previously allocated system memory. addr is the address returned by OSAllocFromSystem()
OSBlockMove void *OSBlockMove(void* dst, const void* src, uint32_t size, bool flush); Will move src to dest (And set the flush flag to flush src in the data cache)
OSBlockSet void *OSBlockSet(void* dst, uint8_t val, uint32_t size); Basic memset (??? Is that uint8_t)

Cache

Name Prototype Description
DCFlushRange void DCFlushRange(const void *addr, size_t length) Flush the specified data cache blocks to memory
DCInvalidateRange void DCInvalidateRange(void *addr, size_t length) Invalidate the specified data cache blocks
ICInvalidateRange void ICInvalidateRange(const void *addr, size_t length) Invalidate the specified instruction cache blocks

Disassembler

Name Prototype Description
DisassemblePPCOpcode void DisassemblePPCOpcode(uint32_t *addr, char *instr_buf, int instr_len, find_symbol_t sym_func, int flags) Disassemble a PPC opcode at addr and place it into instr_buf (instr_len must be 0x40 or lower)
DisassemblePPCRange void DisassemblePPCRange(uint32_t *start, uint32_t *end, printf_t printf_func, find_symbol_t sym_func, int flags) Disassemble PPC instructions from start to end, printing them using printf_func() with various flags applied

Dynamic Linking

Name Prototype Description
OSDynLoad_Acquire int OSDynLoad_Acquire(const char *rplname, uint32_t *handle) Acquire a handle to an RPL by name and returns a error code.
OSDynLoad_IsModuleLoaded int OSDynLoad_IsModuleLoaded(const char *rplname, uint32_t *handle) Checks if a module is loaded. If the target module is loaded the function set the existing handle to the module otherwise the handle is not set. Returns a errorcode.
OSDynLoad_FindExport int OSDynLoad_FindExport(uint32_t handle, bool isdata, const char *symname, void **address) Get a symbol address from a loaded RPL and returns a error code.
OSDynLoad_Release void OSDynLoad_Release(uint32_t *handle) Decrease the reference count and release the module if the reference count hit zero. "coreinit.rpl" can´t be released.

Attempting to use OSDynLoad_Acquire() with rplname "nn_uds.rpl" / "test.rpl" (which Internet Browser itself doesn't import) under Internet Browser has the same result: OSDynLoad_Acquire() never returns. Launching a game which uses the former before running Internet Browser has the same result.

Error

Name Prototype Description
OSFatal void OSFatal(const char *msg) Print a message to the screen then halts the system via: OSPanic("OSFatal.c", linenum, OSFatal_inputmsg)

Internal

Name Prototype Description
__os_snprintf int __os_snprintf(char *buf, size_t n, const char *format, ... ) Format a string and place it in a buffer (just like snprintf())

Threads

Name Prototype Description
OSCreateThread bool OSCreateThread(OSThread *thread, void (*entry)(int,void*), int argc, void *args, void *stack, size_t stack_size, int32_t priority, int16_t affinity) Create a (initially-paused) thread that starts at the specified entry point
OSResumeThread void OSResumeThread(OSThread *thread) Resume a paused thread, causing it to be scheduled
OSYieldThread void OSYieldThread(void) Yield control of the CPU, allowing another thread to run
OSGetCurrentThread OSThread *OSGetCurrentThread(void) Get the OSThread structure ptr for the current thread
OSSetThreadName void OSSetThreadName(OSThread *thread, char *name) Sets a new name for the thread
OSGetThreadName char *OSGetThreadName(OSThread *thread) Returns a pointer to the thread's name char array
OSSetThreadAffinity uint32_t OSSetThreadAffinity(OSThread* thread, int16_t affinity) Sets the affinity for the specified thread. Returns 0 for failure, 1 for success
OSGetCoreId uint32_t OSGetCoreId(void) Returns the PowerPC coreid this code is running on(value of spr1007)
OSGetStackPointer uint32_t *OSGetStackPointer(void) Returns the r1 register(aka "sp")
OSSwitchStack void OSSwitchStack(uint32_t *stackptr) This basically sets the current thread's r1(aka sp) to the input address, and also calls internal coreinit functions with input_param=input_stackptr. Note that this overwrites data near the start of the specified address due to stack push/pop. This will return to the address LR was set to at function entry

Codegen

These functions are used for managing the codegen/JIT area which begins at virtual-memory address 0x01800000. The codegen area size, whether codegen can be used at all, and permissions/etc are loaded from cos.xml for the process. Hence, almost all processes which don't use WebKit don't have access to codegen. These permissions include the coreid which is allowed to use codegen at all(with Internet Browser this is core1). These permissions also seem to include whether the process is allowed to use OSCodegenCopy(Internet Browser isn't allowed to use it). Certain Virtual Console titles seem to be the only applications which are allowed to use OSCodegenCopy due to cos.xml(codegen_core is set to 40000001 for these, unlike 80000001 for browser-based titles).

Name Prototype Description
OSGetCodegenVirtAddrRange void OSGetCodegenVirtAddrRange(uint32_t *outaddr, uint32_t *outsize) This calls syscall 0x4e00 then writes the output r3/r4 from the syscall, to outaddr/outsize. The outaddr value is codegen+0, outsize is the size of the entire codegen memory that's currently mapped. When codegen isn't available, the output values are all-zero.
OSGetCodegenCore uint32_t OSGetCodegenCore(void) This returns (syscall_7600() & 0x3), which is the coreid that's allowed to use codegen.
OSGetCodegenMode uint32_t OSGetCodegenMode(void) This returns (syscall_7600() & ~0x3), which contains some of the flags used by the kernel for codegen permission checking. The only bits which the kernel can ever set here are for bitmask 0xC0000000.
OSSwitchSecCodeGenMode uint32_t OSSwitchSecCodeGenMode(bool flag) This adjusts the entire codegen memory permissions, if codegen is available. 0: RW- permissions. Non-zero: R-X permissions. This returns 0 for failure, non-zero for success.
OSGetSecCodeGenMode uint32_t OSGetSecCodeGenMode(void) This just calls syscall 0x7700. Which then returns 1 when codegen is available+mapped, 0 otherwise.
OSCodegenCopy uint32_t OSCodegenCopy(uint32_t *dstaddr, uint32_t *srcaddr, uint32_t size) In coreinit this just executes syscall 0x7800. This returns 0 for failure, 1 for success. The dstaddr(+size) must be within the codegen memory(integer overflow with dstaddr+size is checked for). If all of the permissions/bounds checks pass(size must not be zero), the kernel will then set the codegen permissions to RW- with code used by SwitchSecCodeGenMode internally. Then it copies the input data from userland memory to the dstaddr with the specified size. Lastly, the codegen permissions are set to R-X with the previously mentioned internal function.

Screen

"bufferNum" is the screenid, see the below screen defines for that. OSScreen *only* supports values 0-1 for screenid. "colour" in the form stored in memory is RGBA8. These functions can't be used without crashing, unless OSScreen was properly initialized. The below functions will immediately return if x/y is out-of-bounds.

This uses the hardware registers via the vaddr loaded with __OSPhysicalToEffectiveUncached(0x0C200000). This is the same hardware used for normal framebuffer display with framebuffers rendered by the GPU. The coreinit register r/w access code for this will only access the registers if OSIsECOMode() returns 0(when reading it would always return value 0 if that func-call returns non-zero). Internally the coreinit reg-access functions for this use word-offsets for the registers. The registers are accessed from there with the following: above_vaddr_base + (screenid<<9) + reg_wordoffset.

OSFatal does the following for initializing the framebuffer addresses: "OSScreenSetBufferEx(0, 0xF4000000)" and "OSScreenSetBufferEx(1, 0xF4000000 + OSScreenGetBufferSizeEx(0))".

The framebuffer addresses passed to OSScreenSetBufferEx must be 0x100-byte aligned(bitmask 0xff clear). The byte-size of each scanline in the framebuffers are 0x100-byte aligned as well.

Name Prototype Description
OSScreenInit void OSScreenInit(void) This is the main initialization function, this must be called before any of the other OSScreen functions. This includes register writes which will enable framebuffer display, via the same bit OSScreenEnableEx() uses.
OSScreenShutdown void OSScreenShutdown(void) This just does the following two function calls: "OSScreenEnableEx(0, 0)" and "OSScreenEnableEx(1, 0)".
OSScreenEnableEx void OSScreenEnableEx(int bufferNum, bool flag) flag0: disable framebuffer display(solid-black is displayed instead). flag1: enable framebuffer display. There's no need to call this right after OSScreenInit() for enabling framebuf display, see above.
OSScreenGetBufferSizeEx uint32_t OSScreenGetBufferSizeEx(int bufferNum) This returns the total byte-size of the primary+secondary framebuffers for the specified screen(single_framebufsize*2).
OSScreenSetBufferEx void OSScreenSetBufferEx(int bufferNum, uint32_t *vaddr_framebufptr) This sets the framebuffer addresses for the specified screen(only in coreinit state). primary_framebuf = vaddr_framebufptr+0, secondary_framebuf = vaddr_framebufptr+single_framebuf_bytesize. The physical framebuffer addresses in hardware won't get updated until OSScreenFlipBuffersEx() is called. This function must be called before using any of the other OSScreen functions with this screen(besides OSScreenEnableEx), otherwise a crash will occur due to the framebuf addrs not being initialized.
OSScreenFlipBuffersEx void OSScreenFlipBuffersEx(int bufferNum) Do a buffer-swap, which results in the buffer previously being drawn to being displayed. This flushes data-cache for the framebuffer and updates coreinit + hw-regs state.
OSScreenClearBufferEx void OSScreenClearBufferEx(int bufferNum, uint32_t colour) Fill the specified buffer with a certain color. This writes the input u32 value to coreinit screen state, then copies that u32 in state to every u32 in the single framebuffer(calculated with the total bytesize of a single framebuffer).
OSScreenPutPixelEx void OSScreenPutPixelEx(int bufferNum, uint32_t posX, uint32_t posY, uint32_t colour) Draw a pixel of a certain color to the specified coordinates. This just writes the input u32 to the target location in the framebuffer, nothing is done with the data already stored in the framebuffer.
OSScreenPutFontEx void OSScreenPutFontEx(int bufferNum, uint32_t posX, uint32_t posY, const char *str) Write text to the specified buffer; unlike OSFatal() this doesn't halt your system.

System

Name Prototype Description
OSGetSystemTime OSTime OSGetSystemTime(void) Gets OSTime (which is just an int64_t) from tbu/tb (timebase upper/lower special purpose registers), same as get_timebase in kernel (FFF099E0 on 5.5.X)
OSGetTime OSTime OSGetTime(void) Returns OSTime equal to then number of ticks from 1/1/2000 00:00
OSTicksToCalendarTime void OSTicksToCalendarTime(OSTime time, OSCalendarTime *calendartime) Converts OStime to an OSCalendarTime structure
OSGetSystemInfo uint32_t* OSGetSystemInfo(void) Returns pointer to OSSystemInfo struct (see below)
OSIsDebuggerInitialized int OSIsDebuggerInitialized(void) Returns 1 if GDB has been initialized. Default is 0.
OSIsDebuggerPresent uint32_t OSIsDebuggerPresent(void) Returns 1 if a debugger is present. Default is 0.
OSIsInterruptEnabled int OSIsInterruptEnabled(void) Returns 1 if interrupts are enabled. Default is 1.
OSDisableInterrupts int OSDisableInterrupts(void) Disables interrupts. Returns 1 on success otherwise, if already disabled, returns 0.
OSIsAddressValid int OSIsAddressValid(int addr) Determines whether the given address addr is readable. Returns 1 or 0.
OSIsHomeButtonMenuEnabled int OSIsHomeButtonMenuEnabled(void) Whether the home menu button is enabled. Default is 1.
OSGetConsoleType uint32_t OSGetConsoleType(void) Returns the ConsoleType.
OSSleepTicks void OSSleepTicks(OSTime) Makes the current thread sleep for a specified amount of ticks
_Exit void _Exit(int status) Makes the current process exit. Crashes when invoked in titles like Wii U games
OSEffectiveToPhysical uint32_t OSEffectiveToPhysical(uint32_t addr) Converts an effective address to its physical representation. For example 0x10000000 becomes 0x50000000
OSGetPFID int OSGetPFID(void) Returns the current process PFID e.g. 15 (Game)
OSGetUPID int OSGetUPID(void) Does the same as OSGetPFID
OSGetTitleID uint64_t OSGetTitleID(void) Returns the current title id e.g. 0x0005000E1010ED00 (Mario Kart 8 EUR). See [3]
OSGetOSID uint64_t OSGetOSID(void) Returns the current OS id e.g. 0x000500101000400A (OSv10). See [4]
__OSGetAppFlags uint32_t __OSGetAppFlags(void) Returns the flags set for the current app e.g. 0x00000200. Influences the control flow in OSSDKVersionInits
__OSGetProcessSDKVersion uint32_t __OSGetProcessSDKVersion(void) Returns the SDK version e.g. 0x000050DF
OSSDKVersionInits ? OSSDKVersionInits(?) Initializes the OS SDK version using the results from __OSGetAppFlags and __OSGetProcessSDKVersion. Seems to crash when invoked
OSShutdown int OSShutdown(int status) Shuts down the console. Behaves identical to holding down the power button. Returns 1 on success

Boot

Name Prototype Description
OSIsColdBoot int OSIsColdBoot(void) Probably allows for cold boot attacks. Default is 0.
OSIsSelfRefreshBoot int OSIsSelfRefreshBoot(void) Probably handles memory refreshing. Default is 0.
OSIsNormalBoot int OSIsNormalBoot(void) Determines the boot type (normal and ?). Default is 1.
OSIsECOBoot int OSIsECOBoot(void) Whether to save energy (at the expense of processing power). Default is 0.
OSIsStandbyBoot int OSIsStandbyBoot(void) Whether the boot is in sleep mode. Default is 0.

IOS

Name Prototype Description
IOS_Open int IOS_Open(char *path, uint32_t mode) Gets an handle to an IOS device node at the specified path whith the given mode
IOS_Close int IOS_Close(int fd); Closes an handle to an IOS device node fd (returned by IOS_Open)
IOS_Ioctl int IOS_Ioctl(int fd, uint32_t request, void *input_buf, uint32_t input_buf_len, void *output_buf, uint32_t output_buf_len) Sends an ioctl request to an IOS device node fd; input_buf contains the input data for the request, output_buf cointains what the request returns

MCP

Name Prototype Description
MCP_Open int MCP_Open() Opens an handle to the MCP IOS node
MCP_Close int MCP_Close(int handle) Closes an handle to the MCP IOS node
MCP_DeviceList int MCP_DeviceList(int handle, int *numDevices, MCPDeviceList *outDevices, uint32_t outBufferSize) Gets a list of available devices
MCP_FullDeviceList int MCP_FullDeviceList(int handle, int *numDevices, MCPDeviceList *outDevices, uint32_t outBufferSize) Gets the full list of available devices
MCP_InstallSetTargetDevice int MCP_InstallSetTargetDevice(int handle, MCPInstallTarget device) Sets the the target device for title installation
MCP_InstallGetTargetDevice int MCP_InstallGetTargetDevice(int handle, MCPInstallTarget *deviceOut) Gets the target device for title installation
MCP_InstallSetTargetUsb int MCP_InstallSetTargetUsb(int handle, int usb) Sets the target USB device for installation
MCP_InstallGetInfo int MCP_InstallGetInfo(int handle, char *path, MCPInstallInfo *out) Gets informations about the install operation
MCP_InstallTitleAsync int MCP_InstallTitleAsync(int handle, char *path, MCPInstallInfo *out) Installs a title
MCP_InstallGetProgress int MCP_InstallGetProgress(int handle, MCPInstallProgress *installProgressOut) Gets installation progress
MCP_InstallTitleAbort int MCP_InstallTitleAbort(int handle) Aborts the installation of a title
MCP_UninstallTitleAsync int MCP_UninstallTitleAsync(int handle, char *path, MCPInstallInfo *out) Uninstalls a title

Filesystem

The FS* functions appear to only be used by regular applications, while the FSA* functions appear to only be used by system rpls.

Setup

Name Signature Description Notes
FSInit void FSInit(void) Initializes the FS library Must be called before anything else! Can be called multiple times safely.
FSShutdown void FSShutdown(void) Deinitializes the FS library The current implementation of this function doesn't do anything.
FSAddClient FSStatus FSAddClient(FSClient *client, FSRetflag flag) Registers a new client for use Returns OK or MAX_CLIENTS(-3). Client size is 0x1700 bytes, should be 0x20 byte padded.
FSDelClient FSStatus FSDelClient(FSClient *client, FSRetflag flag) Unregisters an existing client See above for data size. The current implementation of this function never fails.
FSGetClientNum int FSGetClientNum(void) Gets the number of registered clients

Command Blocks

Name Prototype Description Notes
FSInitCmdBlock void FSInitCmdBlock(FSCmdBlock *block) Initializes a command block for use. Command Block size is 0xA80 bytes, should be 0x20 byte padded.
FSCancelCommand void FSCancelCommand(FSClient *client, FSCmdBlock *block) Cancels the pending command Cannot cancel an ongoing command, it has to complete.
FSCancelAllCommands void FSCancelAllCommands(FSClient *client) Cancels all pending commands for the passed client. Cannot cancel an ongoing command, it has to complete.
FSSetUserData void FSSetUserData(FSCmdBlock *block, void *user_data) Sets the user data for the passed command block
FSGetUserData void* FSGetUserData(FSCmdBlock *block) Returns pointer to the user data Can return NULL if invalid, please error check.
FSSetCmdPriority void FSSetCmdPriority(FSCmdBlock *block, uint8_t priority) Sets the priority for the passed command block Priority 0 is highest, 31 is lowest, 16 is default.
FSGetCmdPriority int FSGetCmdPriority(FSCmdBlock *block) Gets the priority for the passed command block Priority 0 is highest, 31 is lowest, 16 is default.
FSGetCurrentCmdBlock FSCmdBlock* FSGetCurrentCmdBlock(FSClient *client) Returns a pointer to the command block being processed. May return NULL if invalid client or if nothing's processed, please error check.

File Commands

Name Prototype Description Return Values: 0=FS_STATUS_OK -or- <0= Error Codes Notes
FSOpenFile FSStatus FSOpenFile( FSClient *client, FSCmdBlock *block, const char *path, const char *mode, FSFileHandle *fileHandle, FSRetFlag errHandling ); Open file stream -1 -3 -4 -6 -7 -8 -9 -10 -12 -13 -15 -17 -18 -19
FSCloseFile FSStatus FSCloseFile( FSClient *client, FSCmdBlock *block, FSFileHandle fileHandle, FSRetFlag errHandling ); Close file stream. -1 -17
FSReadFile FSStatus FSReadFile( FSClient *client, FSCmdBlock *block, void *dest, FSSize size, FSCount count, FSFileHandle fileHandle, FSFlag flag, FSRetFlag errHandling ); Read data from an open file. Non-negative value ( >= 0 ) = Number of elements read or -1 -9 -15 -17 -18
FSWriteFile FSStatus FSWriteFile( FSClient *client, FSCmdBlock *block, const void *source, FSSize size, FSCount count, FSFileHandle fileHandle, FSFlag flag, FSRetFlag errHandling ); Write data to file Non-negative value ( >= 0 ) = Number of elements write or -1 -9 -11 -12 -13 -14 -15 -17 -18
FSAppendFile FSStatus FSAppendFile( FSClient *client, FSCmdBlock *block, FSSize size, FSCount count, FSFileHandle fileHandle, FSRetFlag errHandling ); Append file. Non-negative value ( >= 0 ) = Newly appended size (newly added preallocation area [Byte] divided by size) or -1 -9 -11 -12 -13 -15 -17 -18 -19
FSTruncateFile FSStatus FSTruncateFile( FSClient *client, FSCmdBlock *block, FSFileHandle fileHandle, FSRetFlag errHandling ); Truncate file at file position -1 -9 -12 -13 -14 -15 -17 -18
FSFlushFile FSStatus FSFlushFile( FSClient *client, FSCmdBlock *block, FSFileHandle fileHandle, FSRetFlag errHandling ); Flush file. -1 -9 -15 -17 -18
FSGetPosFile FSStatus FSGetPosFile( FSClient *client, FSCmdBlock *block, FSFileHandle fileHandle, FSFilePosition *returnedFpos, FSRetFlag errHandling ); Get position of specified file stream. -1 -15 -17 -18
FSSetPosFile FSStatus FSSetPosFile( FSClient *client, FSCmdBlock *block, FSFileHandle fileHandle, FSFilePosition fpos, FSRetFlag errHandling ); Set position of specified file stream -1 -15 -17 -18
FSGetStatFile FSStatus FSGetStatFile( FSClient *client, FSCmdBlock *block, FSFileHandle fileHandle, FSStat *returnedStat, FSRetFlag errHandling ); Get stat information of specified file. -1 -15 -17 -18
FSIsEof FSStatus FSIsEof( FSClient *client, FSCmdBlock *block, FSFileHandle fileHandle, FSRetFlag errHandling ); Determine if the current file position of specified file stream is at the end-of-file(EOF). -1 -2 -15 -17 -18
FSOpenDir FSStatus FSOpenDir( FSClient *client, FSCmdBlock *block, const char *path, FSDirHandle *dirHandle, FSRetFlag errHandling ); Open directory stream -1 -3 -6 -8 -10 -15 -17 -18
FSCloseDir FSStatus FSCloseDir( FSClient *client, FSCmdBlock *block, FSDirHandle dirHandle, FSRetFlag errHandling ); Close directory stream. -1 -17
FSReadDir FSStatus FSReadDir( FSClient *client, FSCmdBlock *block, FSDirHandle dirHandle, FSDirEntry *returnedDirEntry, FSRetFlag errHandling ); Read next directory entry. -1 -2 -15 -17 -18
FSRewindDir FSStatus FSRewindDir( FSClient *client, FSCmdBlock *block, FSDirHandle dirHandle, FSRetFlag errHandling ); Set position of specified directory stream to the head. -1 -2 -15 -17 -18
FSGetCwd FSStatus FSGetCwd( FSClient *client, FSCmdBlock *block, char *returnedPath, u32 bytes, FSRetFlag errHandling ); Get current work directory. -1
FSMakeDir FSStatus FSMakeDir( FSClient *client, FSCmdBlock *block, const char*path, FSRetFlag errHandling ); Create directory. -1 -5 -6 -8 -10 -12 -13 -14 -17 -18 -19
FSRemove FSStatus FSRemove( FSClient *client, FSCmdBlock *block, const char *path, FSRetFlag errHandling ); Remove file or directory. -1 -4 -6 -8 -9 -10 -12 -13 -14 -15 -17 -18 -19
FSRename FSStatus FSRename( FSClient *client, FSCmdBlock *block, const char *oldpath, const char *newpath, FSRetFlag errHandling ); Rename file or directory. -1 -4 -5 -6 -8 -10 -12 -13 -14 -15 -17 -18 -19
FSFlushQuota FSStatus FSFlushQuota( FSClient *client, FSCmdBlock *block, const char *path, FSRetFlag errHandling ); Flush journaling data of quota. -1 -6 -14 -15 -17 -18 -19
FSRollbackQuota FSStatus FSRollbackQuota( FSClient *client, FSCmdBlock *block, const char *path, FSRetFlag errHandling ); Rollback journaling data of quota. -1 -4 -6 -14 -15 -17 -18
FSGetStat FSStatus FSGetStat( FSClient *client, FSCmdBlock *block, const char *path, FSStat *returnedStat, FSRetFlag errHandling ); Get stat information of specified entry. -1 -6 -10 -15 -16 -18 -19
FSGetFreeSpaceSize FSStatus FSGetFreeSpaceSize( FSClient *client, FSCmdBlock *block, const char *path, FSFreeSpaceSize *returnedFreeSize, FSRetFlag errHandling ); Get free space size in quota. -1 -6 -10 -15 -17 -18

Structures

Threads

Name Prototype
OSThreadQueue
typedef struct {
    /* 0x00 */ OSThread* headThread;
    /* 0x04 */ OSThread* tailThread;
    /* 0x08 */ void* parent;
    /* 0x0C */ uint32_t _unknown0C;
} OSThreadQueue;                          /* 0x10 total length */


OSThreadLink
typedef struct {
    /* 0x00 */ OSThread* next;
    /* 0x04 */ OSThread* prev;
} OSThreadLink;                           /* 0x8 total length */
OSContext
typedef struct {
    /* 0x000 */ char     contextTag[8];          /* "OSContxt" */
    /* 0x008 */ int32_t  gpr[32];                /* ppc general purpose registers */
    /* 0x088 */ uint32_t cr;                     /* conditional register */
    /* 0x08c */ uint32_t lr;                     /* link register (SPR 8) */
    /* 0x090 */ uint32_t ctr;                    /* counter register (SPR 9) */
    /* 0x094 */ uint32_t xer;                    /* fixed-point exception register */
    /* 0x098 */ uint32_t srr0;                   /* machine status restore register 0, used to store instruction pointer */
    /* 0x09c */ uint32_t srr1;                   /* machine status restore register 1, ? */
    /* 0x0a0 */ uint32_t _unknown0A0;
    /* 0x0a4 */ uint32_t _unknown0A4;
    /* 0x0a8 */ uint32_t _unused0A8;
    /* 0x0ac */ uint32_t _unused0AC;
    /* 0x0b0 */ uint32_t fpscr_high;             /* floating point status & control register */
    /* 0x0b4 */ uint32_t fpscr_low;              /* floating point status & control register */
    /* 0x0b8 */ uint64_t fpr[32];                /* FPR double registers */
    /* 0x1b8 */ uint16_t spinLockCount;          /* counts number of acquired spinlocks? */
    /* 0x1ba */ uint16_t contextState;           /* purpose unknown, there is another state variable for threading logic */
    /* 0x1bc */ uint32_t ugqr[8];                /* user-mode graphics quantization registers (controls paired single load/store) */
    /* 0x1dc */ uint32_t pir;
    /* 0x1e0 */ uint64_t psf[32];                /* FPR registers (paired-single mode) */
    /* 0x2e0 */ int64_t  coretime[3];            /* number of cycles context was active per core? */
    /* 0x2f8 */ int64_t  starttime;              /* set on context creation to value of OSGetSystemTime() */
    /* 0x300 */ int32_t  error;                  /* used by OSGetLastError() and __OSSetLastError() */
    /* 0x304 */ uint32_t attributes;             /* contains per-context flags and affinity, similar to OSThread.attr */
    /* 0x308 */ uint32_t pmc1;
    /* 0x30C */ uint32_t pmc2;
    /* 0x310 */ uint32_t pmc3;
    /* 0x314 */ uint32_t pmc4;
    /* 0x318 */ uint32_t mmcr0;
    /* 0x31C */ uint32_t mmcr1;
} OSContext;                          /* 0x320 total length */
OSThread
typedef struct {
    /* 0x000 */ OSContext context;
    /* 0x320 */ uint32_t threadTag;              /* "tHrD" */
    /* 0x324 */ uint8_t  state;                  /* Thread state (0 None, 1 Ready, 2 Running, 4 Waiting, 8 Dead) */
    /* 0x325 */ uint8_t  attr;                   /* Thread affinity (bits 0-2) and flags */
    /* 0x326 */ int16_t  threadId;
    /* 0x328 */ int32_t  suspend;                /* suspend counter, thread is suspended if greater zero */
    /* 0x32C */ int32_t  priority;               /* effective priority */
    /* 0x330 */ int32_t  base;                   /* base priority, set on thread creation or via OSSetThreadPriority */
    /* 0x334 */ int32_t  val;                    /* thread exit value */
    /* 0x338 */ void*    runQueue[3];
    /* 0x344 */ OSThreadLink linkRun[3];
    /* 0x35C */ void*    queue;
    /* 0x360 */ OSThreadLink link;
    /* 0x368 */ OSThreadQueue queueJoin;	
    /* 0x378 */ void*    mutex;
    /* 0x37C */ OSMutexQueue queueMutex;
    /* 0x38C */ OSThreadLink linkActive; 
    /* 0x394 */ void*    stackBase;              /* high addr of stack area */
    /* 0x398 */ void*    stackEnd;               /* low addr of stack area */
    /* 0x39C */ void*    entryPoint;             /* initial entry point */
    /* 0x3A0 */ __crt    crt;                    /* used by GHS runtime */
    /* 0x578 */ int32_t  _unused578;
    /* 0x57C */ void*    specific[16];           /* used by OSSetThreadSpecific/OSGetThreadSpecific */
    /* 0x5BC */ int32_t  type;                   /* thread type (0 driver, 1 I/O, 2 application) */
    /* 0x5C0 */ char*    name;
    /* 0x5C4 */ void*    waitAlarm;
    /* 0x5C8 */ void*    userStackPointer;       /* initial stack pointer */
    /* 0x5CC */ void*	 cleanupCallback;
    /* 0x5D0 */ void(*deallocator)(OSThread* t, void* stack) /* called on thread termination */
    /* 0x5D4 */ uint32_t cancelState;
    /* 0x5D8 */ uint32_t requestFlag;            /* flags for state change request after timeslice finished */
    /* 0x5DC */ int32_t  pendingSuspend;
    /* 0x5E0 */ int32_t  suspendResult;
    /* 0x5E4 */ OSThreadQueue suspendQueue;
    /* 0x5F4 */ uint32_t _padding5F4;
    /* 0x5F8 */ uint64_t quantum; /* set by OSSetThreadRunQuantum, defines how long the thread will run before being rescheduled */
    /* 0x600 */ uint64_t _unknown600;
    /* 0x608 */ uint64_t wakeCount;
    /* 0x610 */ uint64_t _unknown610;
    /* 0x618 */ uint64_t awakeTimeSum;
    /* 0x620 */ uint64_t _unknown620;
    /* 0x628 */ uint64_t _unknown628;
    /* 0x630 */ char     _unknown630[0x6a0 - 0x630];
} OSThread;                          /* 0x6a0 total length */

System Info

Name Prototype
OSSystemInfo
typedef struct {
    /* 0x00 */ uint32_t busClockSpeed;
    /* 0x04 */ uint32_t coreClockSpeed;
    /* 0x08 */ OSTime   timeBase;
    /* 0x0C */ uint32_t L2Size[3];
    /* 0x18 */ uint32_t cpuRatio;
} OSSystemInfo;

Filesystem

typedef struct {uint8_t buffer[FS_CLIENT_BUFFER_SIZE];} FSClient;
typedef struct {uint8_t buffer[FS_CMD_BLOCK_SIZE];} FSCmdBlock;

typedef enum {
    FS_VOLSTATE_INITIAL = 0,
    FS_VOLSTATE_READY,
	
    FS_VOLSTATE_NO_MEDIA,
	
    FS_VOLSTATE_INVALID_MEDIA,
    FS_VOLSTATE_DIRTY_MEDIA,
    FS_VOLSTATE_WRONG_MEDIA,
    FS_VOLSTATE_MEDIA_ERROR,
    FS_VOLSTATE_DATA_CORRUPTED,
    FS_VOLSTATE_WRITE_PROTECTED,
	
    FS_VOLSTATE_JOURNAL_FULL,
    FS_VOLSTATE_FATAL,
	
    FS_VOLSTATE_INVALID
} FSVolumeState;

Defines

Filesystem

#define FS_CLIENT_BUFFER_SIZE   (5888) /* 0x1700 */
#define FS_CMD_BLOCK_SIZE       (2688) /* 0xA80 */

#define FS_STATUS_OK                0 /* Everything looks good */

#define FS_STATUS_BASE              (0)

#define FS_STATUS_CANCELED          (FS_STATUS_BASE - 1)
#define FS_STATUS_END               (FS_STATUS_BASE - 2)

#define FS_STATUS_MAX               (FS_STATUS_BASE - 3)
#define FS_STATUS_ALREADY_OPEN      (FS_STATUS_BASE - 4)
#define FS_STATUS_EXISTS            (FS_STATUS_BASE - 5)
#define FS_STATUS_NOT_FOUND         (FS_STATUS_BASE - 6)
#define FS_STATUS_NOT_FILE          (FS_STATUS_BASE - 7)
#define FS_STATUS_NOT_DIR           (FS_STATUS_BASE - 8)
#define FS_STATUS_ACCESS_ERROR      (FS_STATUS_BASE - 9)
#define FS_STATUS_PERMISSION_ERROR  (FS_STATUS_BASE -10)
#define FS_STATUS_FILE_TOO_BIG      (FS_STATUS_BASE -11)
#define FS_STATUS_STORAGE_FULL      (FS_STATUS_BASE -12)
#define FS_STATUS_JOURNAL_FULL      (FS_STATUS_BASE -13)
#define FS_STATUS_UNSUPPORTED_CMD   (FS_STATUS_BASE -14)

#define FS_STATUS_MEDIA_NOT_READY   (FS_STATUS_BASE -15)
#define FS_STATUS_INVALID_MEDIA     (FS_STATUS_BASE -16)
#define FS_STATUS_MEDIA_ERROR       (FS_STATUS_BASE -17)
#define FS_STATUS_DATA_CORRUPTED    (FS_STATUS_BASE -18)
#define FS_STATUS_WRITE_PROTECTED   (FS_STATUS_BASE -19)

#define FS_STATUS_FATAL_ERROR       (FS_STATUS_BASE -1024)

#define FS_RET_NO_ERROR         0x0000
#define FS_RET_MAX              0x0001
#define FS_RET_ALREADY_OPEN     0x0002
#define FS_RET_EXISTS           0x0004
#define FS_RET_NOT_FOUND        0x0008
#define FS_RET_NOT_FILE         0x0010
#define FS_RET_NOT_DIR          0x0020
#define FS_RET_ACCESS_ERROR     0x0040
#define FS_RET_PERMISSION_ERROR 0x0080
#define FS_RET_FILE_TOO_BIG     0x0100
#define FS_RET_STORAGE_FULL     0x0200
#define FS_RET_UNSUPPORTED_CMD  0x0400
#define FS_RET_JOURNAL_FULL     0x0800

#define FS_ERROR_BASE                   (-196608)           /* 0xFFFD0000 */
#define FS_ERROR_LIB_NOT_INIT           (FS_ERROR_BASE - 1)
#define FS_ERROR_INVALID_CLIENT_HANDLE  (FS_ERROR_BASE -37) /* ??? */

Disassembler

printf_func() and find_symbol() have the following types:

typedef int (*printf_t)(char *fmt, ...);
typedef uint32_t (*find_symbol_t)(uint32_t addr, char *name_buf, int name_len);

The flags argument of DisassemblePPCRange() and DisassemblePPCOpcode() is a bitmask of the following options:

#define DISASM_OMIT_ADDR      0x40     /* Don't print the address of the instruction */
#define DISASM_OMIT_OPCODE    0x80     /* Don't print the opcode of the instruction */
#define DISASM_GETSYM         0x100    /* Print the nearest symbol and the instruction's offset from it */

System

Time

#define OSTime int64_t /* stored in timebase upper/lower */

typedef struct {
    int sec;
    int min;
    int hour;
    int mday;
    int mon;
    int year;
    int wday;
    int yday;
    int msec;
    int usec;
} OSCalendarTime;

ConsoleType

Value Description
0x03000050 CAFE (Production/Test)
0x11000021 NDEV 2.1
0x11000022 Cortado (HW)
0x11000023 Cortado (BW)
0x11000024 Cortado (ESP-BW SCM)
0x13000040 EV board (Evaluation)
0x13000048 CAT-DEV (Development)
0x13000050 CAFE (Development)
0x23000050 OrchestraX

Driver

#define OSDRIVER_SIZE 0x4c

typedef struct OSDriver {

  char drv_name[0x40];   // 0x00 - 0x40
  uint32_t unknown;      // 0x40 - 0x44
  uint32_t *save_area;   // 0x44 - 0x48
  struct OSDriver *next; // 0x48 - 0x4c

} OSDriver;

Screen

Name Value Description
SCREEN_BUF_TV 0 The buffer number for the TV
SCREEN_BUF_DRC0 1 The buffer number for the first Gamepad

MCP

typedef enum MCPInstallTarget {
   MCP_INSTALL_TARGET_MLC  = 0,
   MCP_INSTALL_TARGET_USB  = 1,
} MCPInstallTarget;

typedef struct MCPInstallProgress {
   uint32_t inProgress;
   uint64_t tid;
   uint64_t sizeTotal;
   uint64_t sizeProgress;
   uint32_t contentsTotal;
   uint32_t contentsProgress;
} MCPInstallProgress;

typedef struct MCPInstallInfo {
   char unknown[0x27F];
} MCPInstallInfo;

typedef struct MCPDevice {
   char name[0x31B];
} MCPDevice;

typedef struct MCPDeviceList {
   MCPDevice devices[32];
} MCPDeviceList;