Changes

17,690 bytes added ,  25 January
→‎ReadRegister32Ex: describe other legacy register blocks
Line 1: Line 1: −
Cafe OS is the operating system running on the PowerPC in Wii U mode. It consists of the Cafe OS kernel, the executable loader, and system libraries. Unlike on the Wii, where games ran with full hardware access, Wii U applications run under the supervision of the kernel, isolating them from each other. All applications are [[RPL|modified ELFs]], as are the libraries themselves, and applications dynamically link with them to gain access to OS services. Cafe OS also contains a few system processes, like the home menu and error handler.
+
Cafe OS is the operating system running on the PowerPC in Wii U mode. It consists of the Cafe OS kernel, the executable loader, and system libraries. Unlike on the Wii, where each game provided its own copy of [https://wiibrew.org/wiki/Revolution_OS Revolution OS] with no isolation between libraries, Wii U applications run under the supervision of a common PowerPC kernel, isolating them from each other. All applications are [[RPL|modified ELFs]], as are the libraries themselves, and applications dynamically link with them to gain access to OS services. Cafe OS also contains a few system processes, like the home menu and error handler.
   −
==Architecture==
+
= Kernel =
===Kernel===
+
The kernel runs in supervisor mode on the PowerPC, and performs the basic tasks of a microkernel. It is responsible for process isolation, memory management, and interrupt dispatching, as well as communication with [[IOSU]]. Cafe OS applications run as user mode processes, with separate address spaces and W^X memory protection.
{{Main|Cafe_OS_Kernel}}
     −
The kernel runs in supervisor mode on the PowerPC, and performs the basic tasks of a microkernel. It is responsible for process isolation, memory management, and interrupt dispatching, as well as communication with [[IOSU]]. Cafe OS applications run as user mode processes, with separate address spaces and W^X memory protection. The kernel provides basic [[Cafe_OS_Syscalls|syscalls]] for running processes.
+
== 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
   −
===Processes===
+
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.
 +
 
 +
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.
 +
 
 +
{| class="wikitable sortable"
 +
|-
 +
! scope="col" | #
 +
! scope="col" | Name
 +
! scope="col" style="width: 24px;" | root
 +
! scope="col" style="width: 24px;" | Sys
 +
! scope="col" style="width: 24px;" | App
 +
! scope="col" style="width: 24px;" | Ldr
 +
|-
 +
| 0x0 || ConsoleWrite || X || X || X || X (sp)
 +
|-
 +
| 0x100 || AppPanic || X || X || X || X
 +
|-
 +
| 0x200 || EffectiveToPhysical || X || X || X ||
 +
|-
 +
| 0x300 || PhysicalToEffectiveCached || X || X || X ||
 +
|-
 +
| 0x400 || PhysicalToEffectiveUncached || X || X || X ||
 +
|-
 +
| 0x500 || ValidateAddressSpaceRange || X || X || X || X
 +
|-
 +
| 0x600 || UpdateCoretime || X || X || X ||
 +
|-
 +
| 0x700 || - || - || - || - || -
 +
|-
 +
| 0x800 || SetUserModeExHandler || X || X || X ||
 +
|-
 +
| 0x900 || - || - || - || - || -
 +
|-
 +
| 0xA00 || - || - || - || - || -
 +
|-
 +
| 0xB00 || AllocateTimer || X || X || X ||
 +
|-
 +
| 0xC00 || FreeTimer || X || X || X ||
 +
|-
 +
| 0xD00 || PrimeTimer || X || X || X ||
 +
|-
 +
| 0xE00 || StopTimer || X || X || X ||
 +
|-
 +
| 0xF00 || DynLoad_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)
 +
|-
 +
| 0x1800 || Test_Assist ||  ||  ||  ||
 +
|-
 +
| 0x1900 || Exit || 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_<nowiki>{Loader|User}</nowiki>Open || X || X || X || X (sp)
 +
|-
 +
| 0x1F00 || IPCKDriver_<nowiki>{Loader|User}</nowiki>Close || X || X || X || X (sp)
 +
|-
 +
| 0x2000 || IPCKDriver_SubmitRequest || X || X || X || X (sp)
 +
|-
 +
| 0x2100 || - || - || - || - || -
 +
|-
 +
| 0x2200 || GetEnvironmentVariable || X || X || X ||
 +
|-
 +
| 0x2300 || - || - || - || - || -
 +
|-
 +
| 0x2400 || - || - || - || - || -
 +
|-
 +
| 0x2500 || - || - || - || - || -
 +
|-
 +
| 0x2600 || - || - || - || - || -
 +
|-
 +
| 0x2700 || Proc_GetNotifyTarget || X || X || X ||
 +
|-
 +
| 0x2800 || Proc_ReleaseForeground || X || X || X ||
 +
|-
 +
| 0x2900 || Proc_GetForegroundBucket || X || X || X ||
 +
|-
 +
| 0x2A00 || Proc_RequestSwitch || X || X || X ||
 +
|-
 +
| 0x2B00 || LaunchTitleArgvStr || X || X || X ||
 +
|-
 +
| 0x2C00 || Proc_YieldCore || X || X || X ||
 +
|-
 +
| 0x2D00 || - || - || - || - || -
 +
|-
 +
| 0x2E00 || Proc_GetSystemMessage || X || X || X ||
 +
|-
 +
| 0x2F00 || Proc_GetCallArgs || X || X || X ||
 +
|-
 +
| 0x3000 || GetAbsoluteSystemTimeInternal || X || X || X ||
 +
|-
 +
| 0x3100 || SetAbsoluteSystemTimeInternal || X || X || X ||
 +
|-
 +
| 0x3200 || Drivers_GetInstance || X || X || X ||
 +
|-
 +
| 0x3300 || Drivers_PurgeMaster || X || X || X ||
 +
|-
 +
| 0x3400 || - || - || - || - || -
 +
|-
 +
| 0x3500 || - || - || - || - || -
 +
|-
 +
| 0x3600 || - || - || - || - || -
 +
|-
 +
| 0x3700 || - || - || - || - || -
 +
|-
 +
| 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 || LoadUserContext || X || X || X ||
 +
|-
 +
| 0x4500 || FlushUserContext || X || X || X ||
 +
|-
 +
| 0x4600 || FlushUserFPUContext || X || X || X ||
 +
|-
 +
| 0x4700 || Drivers_CopyFromSaveArea || X || X || X ||
 +
|-
 +
| 0x4800 || Drivers_CopyToSaveArea || X || X || X ||
 +
|-
 +
| 0x4900 || Proc_ReadyToRelease || X || X || X ||
 +
|-
 +
| 0x4A00 || FlushInterrupts || X || X || X ||
 +
|-
 +
| 0x4B00 || SetDABR || X || X || X ||
 +
|-
 +
| 0x4C00 || SetIABR || X || X || X ||
 +
|-
 +
| 0x4D00 || Proc_GetProcessInfo || X || X || X ||
 +
|-
 +
| 0x4E00 || GetCodegenVirtAddrRange || X || X || X ||
 +
|-
 +
| 0x4F00 || DynLoad_RPLLoaderEntry || X || X || X ||
 +
|-
 +
| 0x5000 || RPLLoaderResumeContext ||  ||  ||  || X
 +
|-
 +
| 0x5100 || - || - || - || - || -
 +
|-
 +
| 0x5200 || WaitIopComplete ||  ||  ||  || X
 +
|-
 +
| 0x5300 || FlushCode ||  ||  ||  || X
 +
|-
 +
| 0x5400 || FlushData ||  ||  ||  || X
 +
|-
 +
| 0x5500 || UpdateHeartbeat ||  ||  ||  || X
 +
|-
 +
| 0x5600 || LogEntry ||  ||  ||  || X
 +
|-
 +
| 0x5700 || FastClearMemory ||  ||  ||  || X
 +
|-
 +
| 0x5800 || GetBusClockSpeed ||  ||  ||  || X
 +
|-
 +
| 0x5900 || Shared_GetArea || X || X || X ||
 +
|-
 +
| 0x5A00 || Proc_SendPolicy || X || X || X ||
 +
|-
 +
| 0x5B00 || GetProcessIndex ||  ||  ||  || X
 +
|-
 +
| 0x5C00 || IPCKDriver_PollLoaderCompletion ||  ||  ||  || X
 +
|-
 +
| 0x5D00 || BlockLogSaveHiLo || X || X || X ||
 +
|-
 +
| 0x5E00 || FinishInitAndPreload ||  ||  ||  || X
 +
|-
 +
| 0x5F00 || ContinueStartProcess ||  ||  ||  || X
 +
|-
 +
| 0x6000 || OpenMCP ||  ||  ||  || X
 +
|-
 +
| 0x6100 || Proc_QuerySwitchReady || X || X || X ||
 +
|-
 +
| 0x6200 || Launch || X || X || X ||
 +
|-
 +
| 0x6300 || Call || X || X || X ||
 +
|-
 +
| 0x6400 || SetTimeInternal ||  || X ||  ||
 +
|-
 +
| 0x6500 || || X || X || X ||
 +
|-
 +
| 0x6600 || ProfileEntry ||  ||  ||  || X
 +
|-
 +
| 0x6700 || Proc_RequestExit || X || X || X ||
 +
|-
 +
| 0x6800 || Proc_CoreInitDone || X || X || X ||
 +
|-
 +
| 0x6900 || Proc_GetSwitchTarget || X || X || X ||
 +
|-
 +
| 0x6A00 || Proc_AcquireDone || X || X || X ||
 +
|-
 +
| 0x6B00 || Proc_GetBuiltSDKVersion || X || X || X ||
 +
|-
 +
| 0x6C00 || Proc_SystemFatal || X || X || X ||
 +
|-
 +
| 0x6D00 || - || - || - || - || -
 +
|-
 +
| 0x6E00 || SwitchSecCodeGenMode || X || X || X ||
 +
|-
 +
| 0x6F00 || IopShell_RegisterCallback || X || X || X ||
 +
|-
 +
| 0x7000 || Proc_GetTitleVersion || X || X || X ||
 +
|-
 +
| 0x7100 || Proc_IsTestKernel || X || X || X ||
 +
|-
 +
| 0x7200 || ForceFullRelaunch || X || X || X ||
 +
|-
 +
| 0x7300 || Proc_Recycle || X ||  ||  ||
 +
|-
 +
| 0x7400 || GetFlags || X || X || X || X
 +
|-
 +
| 0x7500 || QueryVirtAddr || X || X || X ||
 +
|-
 +
| 0x7600 || GetCodegenInfo || X || X || X ||
 +
|-
 +
| 0x7700 || GetSecCodeGenMode || X || X || X ||
 +
|-
 +
| 0x7800 || CodegenCopy || X || X || X ||
 +
|-
 +
| 0x7900 || Proc_LoadShared || X ||  ||  ||
 +
|-
 +
| 0x7A00 || SetExceptionCallback || X || X || X ||
 +
|-
 +
| 0x7B00 || IopShell_InjectCommand || X || X || X ||
 +
|-
 +
| 0x7C00 || Proc_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 || HandlePowerEvents ||  ||  ||  || X
 +
|-
 +
| 0x8300 || ConsoleTimestamp || X || X || X || X
 +
|-
 +
| 0x8400 || ValidateOverlayRange ||  ||  ||  || X
 +
|-
 +
| 0x8500-0xFF00 || 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.
 +
 
 +
{| class="wikitable sortable"
 +
|-
 +
! scope="col" | #
 +
! scope="col" | Name
 +
|-
 +
| 0x0 || SysCall (default branch to syscall dispatcher)
 +
|-
 +
| 0x1 || MemoryBarrier
 +
|-
 +
| 0x2 || EnableInterrupts (deprecated, jumps to error)
 +
|-
 +
| 0x3 || DisableInterrupts (deprecated, jumps to error)
 +
|-
 +
| 0x4 || IsInterruptEnabled (deprecated, jumps to error)
 +
|-
 +
| 0x5 || RestoreInterrupts (deprecated, jumps to error)
 +
|-
 +
| 0x6 || LoadContext
 +
|-
 +
| 0x7 || GetMSR
 +
|-
 +
| 0x8 || SetCurrentContext
 +
|-
 +
| 0x9 || GetCurrentFPUContext
 +
|-
 +
| 0xA || SetCurrentFPUContext
 +
|-
 +
| 0xB || CompareAndSwapCurrentFPUContext
 +
|-
 +
| 0xC || WriteGatherInit
 +
|-
 +
| 0xD || SetPerformanceMonitor
 +
|-
 +
| 0xE || SetUserDMA
 +
|-
 +
| 0xF || ReturnFromInterrupt
 +
|-
 +
| 0x10 || FlushFPUContext
 +
|-
 +
| 0x11 || [[#ReadRegister32Ex|ReadRegister32Ex]]
 +
|-
 +
| 0x12 || [[#WriteRegister32Ex|WriteRegister32Ex]]
 +
|-
 +
| 0x13 ||
 +
|-
 +
| 0x14 ||
 +
|-
 +
| 0x15 || WriteGatherInitWritePtr
 +
|-
 +
| 0x16 ||
 +
|-
 +
| 0x17 || WriteGatherReadWritePtr
 +
|-
 +
| 0x18 || EnableFPU
 +
|-
 +
| 0x19 || GetSecurityLevel
 +
|-
 +
| 0x1A-0x1F || BadFastCall (jump to error on purpose)
 +
|}
 +
 
 +
=== ReadRegister32Ex ===
 +
Takes two u32s '''WhitelistIndex''' and '''RegisterIndex'''. Returns an u32 '''RegisterValue'''.
 +
 
 +
Reads a hardware register from the following whitelist:
 +
0                // Invalid
 +
0xFD020068      // 2 registers at 0x0D000068 (HW_I2CIOPINTEN to HW_I2CIOPINTSTS)
 +
0xFD0100C0      // 1 registers at 0x0D0000C0 (HW_GPIOPPCOUT)
 +
0xFD04021C      // 4 registers at 0x0D00021C
 +
0xFD040250      // 4 registers at 0x0D000250 (HW_I2CMCTRL to HW_I2CMDATARD)
 +
0xFD060520      // 6 registers at 0x0D000520 (LT_GPIOPPCOUT to LT_GPIOPPCINTEN)
 +
0xFD106400      // 16 registers at 0x0D006400 (SI0_OUTBUF to SIEXI_LOCK)
 +
0xFD046C00      // 4 registers at 0x0D006C00 (AI_CR to AI_IT)
 +
0xFD046E00      // 4 registers at 0x0D006E00
 +
0xFD0F6800      // 15 registers at 0x0D006800 (EXI0_CSR to EXI2_DATA)
 +
0                // Invalid
 +
0                // Invalid
 +
0                // Invalid
 +
0                // Invalid
 +
0                // Invalid
 +
0                // Invalid
 +
 
 +
=== WriteRegister32Ex ===
 +
Takes three u32s '''WhitelistIndex''', '''RegisterIndex''' and '''RegisterValue'''. No output.
 +
 
 +
Same as [[#ReadRegister32Ex|ReadRegister32Ex]], but for writing to a whitelisted hardware register instead.
 +
 
 +
== OSPlatformInfo ==
 +
This is a structure mapped to address 0x1FFF000 in MEM1 for communicating with the [[IOSU|MCP]] process.
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x4 || Magic (0x5726)
 +
|-
 +
| 0x4 || 0x4 || Size (0x40C)
 +
|-
 +
| 0x8 || 0x4 || [[#Flags|Flags]]
 +
|-
 +
| 0xC || 0x4 || ConsoleType
 +
|-
 +
| 0x10 || 0x4 || Iop2x
 +
|-
 +
| 0x14 || 0x4 || Bperf
 +
|-
 +
| 0x18 || 0x4 || PpcSystemClockFrequency
 +
|-
 +
| 0x1C || 0x4 || PpcCore0L2Size
 +
|-
 +
| 0x20 || 0x4 || PpcCore0L2LineSize
 +
|-
 +
| 0x24 || 0x4 || PpcCore0L2SectorSize
 +
|-
 +
| 0x28 || 0x4 || PpcCore0L2FetchSize
 +
|-
 +
| 0x2C || 0x4 || PpcCore0L2SetAssociativity
 +
|-
 +
| 0x30 || 0x4 || PpcCore1L2Size
 +
|-
 +
| 0x34 || 0x4 || PpcCore1L2LineSize
 +
|-
 +
| 0x38 || 0x4 || PpcCore1L2SectorSize
 +
|-
 +
| 0x3C || 0x4 || PpcCore1L2FetchSize
 +
|-
 +
| 0x40 || 0x4 || PpcCore1L2SetAssociativity
 +
|-
 +
| 0x44 || 0x4 || PpcCore2L2Size
 +
|-
 +
| 0x48 || 0x4 || PpcCore2L2LineSize
 +
|-
 +
| 0x4C || 0x4 || PpcCore2L2SectorSize
 +
|-
 +
| 0x50 || 0x4 || PpcCore2L2FetchSize
 +
|-
 +
| 0x54 || 0x4 || PpcCore2L2SetAssociativity
 +
|-
 +
| 0x58 || 0x64 || Reserved
 +
|-
 +
| 0xBC || 0x4 || PpcCorePropertiesCount
 +
|-
 +
| 0xC0 || 0x4 || PpcCorePropertiesFlags
 +
|-
 +
| 0xC4 || 0x4 || PpcMem0Id
 +
|-
 +
| 0xC8 || 0x4 || PpcMem0BaseAddress
 +
|-
 +
| 0xCC || 0x4 || PpcMem0Size
 +
|-
 +
| 0xD0 || 0x4 || PpcMem1Id
 +
|-
 +
| 0xD4 || 0x4 || PpcMem1BaseAddress
 +
|-
 +
| 0xD8 || 0x4 || PpcMem1Size
 +
|-
 +
| 0xDC || 0x4 || PpcMem2Id
 +
|-
 +
| 0xE0 || 0x4 || PpcMem2BaseAddress
 +
|-
 +
| 0xE4 || 0x4 || PpcMem2Size
 +
|-
 +
| 0xE8 || 0x3C || Reserved
 +
|-
 +
| 0x124 || 0x4 || PpcMemRegionCount
 +
|-
 +
| 0x128 || 0x4 || PpcMemRegionFlags
 +
|-
 +
| 0x12C || 0x244 || Reserved
 +
|-
 +
| 0x370 || 0x4 || HardwareVersion
 +
|-
 +
| 0x374 || 0x40 || Reserved
 +
|-
 +
| 0x3B4 || 0x4 || SmdBaseAddress
 +
|-
 +
| 0x3B8 || 0x48 || Reserved
 +
|-
 +
| 0x400 || 0x4 || LastPMState
 +
|-
 +
| 0x404 || 0x4 || CurrentPMState
 +
|-
 +
| 0x408 || 0x4 || [[Boot1#PowerFlags|BootPMFlags]]
 +
|}
 +
 
 +
=== Flags ===
 +
{| class="wikitable" border="1"
 +
|-
 +
! Bits
 +
! Description
 +
|-
 +
| 0-25
 +
|
 +
|-
 +
| 26
 +
| IsEnterBgNormalMode
 +
|-
 +
| 27
 +
| IsDevMode
 +
|-
 +
| 28
 +
| IsFastRelaunch
 +
|-
 +
| 29
 +
| IsColdBoot
 +
|-
 +
| 30
 +
| IsSynchronousPrintingEnabled
 +
|-
 +
| 31
 +
|
 +
|}
 +
 
 +
== OSContext ==
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x8 || Tag
 +
|-
 +
| 0x8 || 0x80 || Gpr
 +
|-
 +
| 0x88 || 0x4 || Cr
 +
|-
 +
| 0x8C || 0x4 || Lr
 +
|-
 +
| 0x90 || 0x4 || Ctr
 +
|-
 +
| 0x94 || 0x4 || Xer
 +
|-
 +
| 0x98 || 0x4 || Srr0
 +
|-
 +
| 0x9C || 0x4 || Srr1
 +
|-
 +
| 0xA0 || 0x4 || Dsisr
 +
|-
 +
| 0xA4 || 0x4 || Dar
 +
|-
 +
| 0xA8 || 0x4 || CrashType
 +
|-
 +
| 0xAC || 0x4 || Reserved
 +
|-
 +
| 0xB0 || 0x4 || FpscrHigh
 +
|-
 +
| 0xB4 || 0x4 || FpscrLow
 +
|-
 +
| 0xB8 || 0x100 || Fpr
 +
|-
 +
| 0x1B8 || 0x2 || SpinLockCount
 +
|-
 +
| 0x1BA || 0x2 || ContextState
 +
|-
 +
| 0x1BC || 0x20 || Ugqr
 +
|-
 +
| 0x1DC || 0x4 || Pir
 +
|-
 +
| 0x1E0 || 0x100 || Psf
 +
|-
 +
| 0x2E0 || 0x18 || Coretime
 +
|-
 +
| 0x2F8 || 0x8 || Starttime
 +
|-
 +
| 0x300 || 0x4 || Error
 +
|-
 +
| 0x304 || 0x4 || Attributes
 +
|-
 +
| 0x308 || 0x4 || Pmc1
 +
|-
 +
| 0x30C || 0x4 || Pmc2
 +
|-
 +
| 0x310 || 0x4 || Pmc3
 +
|-
 +
| 0x314 || 0x4 || Pmc4
 +
|-
 +
| 0x318 || 0x4 || Mmcr0
 +
|-
 +
| 0x31C || 0x4 || Mmcr1
 +
|}
 +
 
 +
== CoreControl ==
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x40 ||
 +
|-
 +
| 0x40 || 0x4 || BootStage
 +
|-
 +
| 0x44 || 0x4 || CoreInitFunc
 +
|-
 +
| 0x48 || 0x4 || CoreState
 +
|-
 +
| 0x4C || 0x4 ||
 +
|-
 +
| 0x50 || 0x4 ||
 +
|-
 +
| 0x54 || 0x4 || IsKernelPanic
 +
|-
 +
| 0x58 || 0x4 || InterruptedContext
 +
|-
 +
| 0x5C || 0x4 || CurrentFpuContext
 +
|-
 +
| 0x60 || 0x4 || CurrentCoreControl
 +
|-
 +
| 0x64 || 0x4 || SysCallTableAddress
 +
|-
 +
| 0x68 || 0x4 || FastCallBaseAddress
 +
|-
 +
| 0x6C || 0x4 || NonRecoverableExceptionHandlerTableAddress
 +
|-
 +
| 0x70 || 0x4 || RecoverableExceptionHandlerTableAddress
 +
|-
 +
| 0x74 || 0x2 ||
 +
|-
 +
| 0x76 || 0x2 ||
 +
|-
 +
| 0x78 || 0x4 || LoadPerfMonContext
 +
|-
 +
| 0x7C || 0x4 || CurrentSysCallAddress
 +
|-
 +
| 0x80 || 0x4 || CurrentSysCallCallback
 +
|-
 +
| 0x84 || 0x4 || NonRecoverableExceptionContextAddress
 +
|-
 +
| 0x88 || 0x4 || RecoverableExceptionContextAddress
 +
|-
 +
| 0x8C || 0x4 || NormalSysCalls
 +
|-
 +
| 0x90 || 0x4 || FpuExceptions
 +
|-
 +
| 0x94 || 0x4 || DsiExceptions
 +
|-
 +
| 0x98 || 0x4 || IciExceptions
 +
|-
 +
| 0x9C || 0x4 ||
 +
|-
 +
| 0xA0 || 0x4 || Ps0
 +
|-
 +
| 0xA4 || 0x4 || Ps1
 +
|-
 +
| 0xA8 || 0x8 || ProcessWork
 +
|-
 +
| 0xB0 || 0x4 ||
 +
|-
 +
| 0xB4 || 0x4 || RamPid
 +
|-
 +
| 0xB8 || 0x4 || Upid
 +
|-
 +
| 0xBC || 0x4 || Mem1Address
 +
|-
 +
| 0xC0 || 0x4 || InterceptedLoadContext
 +
|-
 +
| 0xC4 || 0x4 || SintEnableAfterKernelExit
 +
|-
 +
| 0xC8 || 0x4 || AddrConfig
 +
|-
 +
| 0xCC || 0x20 || SysCallCallbackGpr
 +
|-
 +
| 0xEC || 0x4 || EaDataBegin
 +
|-
 +
| 0xF0 || 0x4 || EaDataEnd
 +
|-
 +
| 0xF4 || 0x18 ||
 +
|-
 +
| 0x10C || 0x4 || WriteGatherDataOffset
 +
|-
 +
| 0x110 || 0x30 || [[#ExceptionInfo|ExceptionInfo]]
 +
|-
 +
| 0x140 || 0x4 || OverwriteGprOnExceptionExit
 +
|-
 +
| 0x144 || 0x28 || ExceptionExitGpr
 +
|-
 +
| 0x16C || 0x28 || [[#PostException|PostException]]
 +
|-
 +
| 0x194 || 0x4 ||
 +
|-
 +
| 0x198 || 0x128 || [[#ExceptionContext|RecoverableExceptionContext]]
 +
|-
 +
| 0x2C0 || 0x14 ||
 +
|-
 +
| 0x2D8 || 0x128 || [[#ExceptionContext|NonRecoverableExceptionContext]]
 +
|}
 +
 
 +
== ExceptionContext ==
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x8 || Tbr64
 +
|-
 +
| 0x8 || 0x80 || Gpr
 +
|-
 +
| 0x88 || 0x4 || Cr
 +
|-
 +
| 0x8C || 0x4 || Lr
 +
|-
 +
| 0x90 || 0x4 || Ctr
 +
|-
 +
| 0x94 || 0x4 || Xer
 +
|-
 +
| 0x98 || 0x4 || Srr0
 +
|-
 +
| 0x9C || 0x4 || Srr1
 +
|-
 +
| 0xA0 || 0x88 ||
 +
|}
 +
 
 +
== ExceptionInfo ==
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x4 ||
 +
|-
 +
| 0x4 || 0x4 ||
 +
|-
 +
| 0x8 || 0x4 || UserStackPtr
 +
|-
 +
| 0xC || 0x4 || ExHandler
 +
|-
 +
| 0x10 || 0x4 || Msr
 +
|-
 +
| 0x14 || 0x4 || Sprg0
 +
|-
 +
| 0x18 || 0x4 || Dsisr
 +
|-
 +
| 0x1C || 0x4 || Dar
 +
|-
 +
| 0x20 || 0x4 ||
 +
|-
 +
| 0x24 || 0x4 ||
 +
|-
 +
| 0x28 || 0x4 ||
 +
|-
 +
| 0x2C || 0x4 || CallbackContext
 +
|}
 +
 
 +
== PostException ==
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x4 || OldUpid
 +
|-
 +
| 0x4 || 0x4 || TargetUpid
 +
|-
 +
| 0x8 || 0x4 || Exit
 +
|-
 +
| 0xC || 0x4 || Callback
 +
|-
 +
| 0x10 || 0x4 || CurrentExceptionContext
 +
|-
 +
| 0x14 || 0x4 || InterruptedContext
 +
|-
 +
| 0x18 || 0x4 ||
 +
|-
 +
| 0x1C || 0x4 ||
 +
|-
 +
| 0x20 || 0x4 ||
 +
|-
 +
| 0x24 || 0x4 ||
 +
|}
 +
 
 +
== NewExecCtx ==
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x4 || InterruptedContext
 +
|-
 +
| 0x4 || 0x4 || CurrentFpuContext
 +
|-
 +
| 0x8 || 0x4 ||
 +
|-
 +
| 0xC || 0x4 || FastCallBaseAddress
 +
|-
 +
| 0x10 || 0x4 || SintEnableAfterKernelExit
 +
|-
 +
| 0x14 || 0x4 ||
 +
|-
 +
| 0x18 || 0x4 ||
 +
|-
 +
| 0x1C || 0x4 || Dabr
 +
|-
 +
| 0x20 || 0x4 || Iabr
 +
|-
 +
| 0x24 || 0x4 || EaDataBegin
 +
|-
 +
| 0x24 || 0x4 || EaDataEnd
 +
|-
 +
| 0x28 || 0x1C ||
 +
|-
 +
| 0x48 || 0x4 || AddrConfig
 +
|-
 +
| 0x4C || 0x3C || [[#PerCore|PerCore]]
 +
|}
 +
 
 +
== PerCore ==
 +
This is a structure mapped to address 0xFFFFFFC0.
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x18 ||
 +
|-
 +
| 0x18 || 0x4 || UserHeartBeat
 +
|-
 +
| 0x1C || 0x4 ||
 +
|-
 +
| 0x20 || 0x4 || CurrentThread
 +
|-
 +
| 0x24 || 0x4 || SoftIntEnabled
 +
|-
 +
| 0x28 || 0x4 || SoftIntPending
 +
|-
 +
| 0x2C || 0x4 || CurrentContext
 +
|-
 +
| 0x30 || 0x4 ||
 +
|-
 +
| 0x34 || 0x4 ||
 +
|-
 +
| 0x38 || 0x4 || ThreadQueue
 +
|}
 +
 
 +
= Processes =
 
A process in Cafe OS represents a single running application, with its own code, memory, and permissions. Cafe OS only executes the code of a single process at a time, but it can hold the data of multiple processes in memory simultaneously, and switch between them. Rather than allowing arbitrary process creation, there is RAM reserved for a single foreground app, a single background app, and various other special processes. Each running process is assigned a unique identifier called a RAMPID:
 
A process in Cafe OS represents a single running application, with its own code, memory, and permissions. Cafe OS only executes the code of a single process at a time, but it can hold the data of multiple processes in memory simultaneously, and switch between them. Rather than allowing arbitrary process creation, there is RAM reserved for a single foreground app, a single background app, and various other special processes. Each running process is assigned a unique identifier called a RAMPID:
 
{| class="wikitable"
 
{| class="wikitable"
Line 120: Line 941:  
|}
 
|}
   −
===Loader===
+
= Loader =
 
{{Main|Loader}}
 
{{Main|Loader}}
    
The loader is responsible for loading RPL formatted libraries and executables into memory. It is a standard ELF executable named loader.elf. It includes a statically linked copy of zlib, probably for decompressing sections of RPL files.
 
The loader is responsible for loading RPL formatted libraries and executables into memory. It is a standard ELF executable named loader.elf. It includes a statically linked copy of zlib, probably for decompressing sections of RPL files.
   −
===Libraries===
+
= Libraries =
 
Cafe OS applications dynamically link with system libraries to get access to OS services. These OS services include memory management, graphics, audio, and controller input. All libraries are [[RPL|RPL files]], a modification of the standard ELF format with compressed sections and more Windows-like dynamic linking. The main system libraries are listed below, with some having their own pages of documentation:
 
Cafe OS applications dynamically link with system libraries to get access to OS services. These OS services include memory management, graphics, audio, and controller input. All libraries are [[RPL|RPL files]], a modification of the standard ELF format with compressed sections and more Windows-like dynamic linking. The main system libraries are listed below, with some having their own pages of documentation:
 
*[[avm.rpl]] - Audio/Video Manager
 
*[[avm.rpl]] - Audio/Video Manager
Line 147: Line 968:  
*[[nn_act.rpl]] - Nintendo Network Accounts
 
*[[nn_act.rpl]] - Nintendo Network Accounts
 
*[[nn_aoc.rpl]] - Nintendo Network Add-On Content
 
*[[nn_aoc.rpl]] - Nintendo Network Add-On Content
*[[nn_boss.rpl]] - Nintendo Network BOSS (Streetpass)
+
*[[nn_boss.rpl]] - Nintendo Network BOSS (SpotPass)
 
*[[nn_ccr.rpl]]
 
*[[nn_ccr.rpl]]
 
*[[nn_cmpt.rpl]] - Handles transition into vWii
 
*[[nn_cmpt.rpl]] - Handles transition into vWii
Line 189: Line 1,010:  
*[[usb_mic.rpl]]
 
*[[usb_mic.rpl]]
 
*[[uvc.rpl]] - DRH communication (Gamepad camera)
 
*[[uvc.rpl]] - DRH communication (Gamepad camera)
*[[uvd.rpl]] - [http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2012/10/OpenVideo_Decode_API.PDF AMD's OpenVideo Decode library], with some different function names  
+
*[[uvd.rpl]] - [https://web.archive.org/web/20221108161252/https://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2012/10/OpenVideo_Decode_API.PDF AMD's OpenVideo Decode library], with some different function names  
 
*[[vpad.rpl]] - Gamepad input
 
*[[vpad.rpl]] - Gamepad input
 
*[[vpadbase.rpl]] - Gamepad base library
 
*[[vpadbase.rpl]] - Gamepad base library
 
*[https://github.com/madler/zlib/tree/9712272c78b9d9c93746d9c8e156a3728c65ca72 zlib125.rpl] - ZLIB 1.2.5, functions match official library
 
*[https://github.com/madler/zlib/tree/9712272c78b9d9c93746d9c8e156a3728c65ca72 zlib125.rpl] - ZLIB 1.2.5, functions match official library
   −
==Virtual Memory Map==
+
= Virtual Memory Map =
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! Virtual address range/start
+
! Virtual address start
! Physical address range/start
+
! Virtual address size
! Size
+
! Physical address start
! Userland memory permissions
+
! Flags
! Kernel-mode memory permissions
   
! Description
 
! Description
 
|-
 
|-
| 0x01000000 - 0x01800000
+
| 0x1000000
| 0x32000000 - 0x32800000
   
| 0x800000
 
| 0x800000
|  
+
| 0x32000000
|  
+
| 0x2CE08002
 
| Loader and system libraries
 
| Loader and system libraries
 
|-
 
|-
| 0x01800000
+
| 0x1800000
| ?
+
| 0x20000
|  
+
| 0
|  
+
| 0x28101200
|  
+
| This is the [[Coreinit.rpl|codegen]]/JIT memory area, only available under processes which have it enabled under cos.xml (the size comes from cos.xml too)
| This is the [[Coreinit.rpl|codegen]]/JIT memory area, only available under processes which have it enabled under cos.xml(the size comes from cos.xml too).
   
|-
 
|-
| 0x0??????? - 0x10000000
+
| 0x2000000 (variable)
| End of app MEM2 region (see [[Physical_Memory|here]])
+
| 0xE000000 (variable)
|  
+
| 0x72000000 or 0xB2000000 (variable)
|  
+
| 0x2CF09400
|
   
| App executable and libraries (start varies, but end is always 0x10000000)
 
| App executable and libraries (start varies, but end is always 0x10000000)
 
|-
 
|-
| 0x10000000 - 0x50000000
+
| 0x10000000
| App MEM2 region (see [[Physical_Memory|here]])
+
| 0x52000000 or 0x92000000 (variable)
| 0x40000000
+
| 0x20000000 (variable)
|
+
| 0x28305800
|  
   
| Application/library data area (may be smaller)
 
| Application/library data area (may be smaller)
 
|-
 
|-
| 0xa0000000 - 0xe0000000
+
| 0xA0000000
|
   
| 0x40000000
 
| 0x40000000
|  
+
| 0
|  
+
| 0x2000
 
| Overlay of application memory (used by loader?)
 
| Overlay of application memory (used by loader?)
 
|-
 
|-
| 0xe0000000 - 0xe4000000
+
| 0xE0000000
| 0x14000000 - 0x18000000
+
| 0x4000000
| 0x04000000
+
| 0x14000000
|  
+
| 0x28204004
|  
   
| Some sort of hardware communication area
 
| Some sort of hardware communication area
 
|-
 
|-
| 0xefe00000 - 0xefe80000
+
| 0xE8000000
|  
+
| 0x2000000
|  
+
| 0xD0000000
|  
+
| 0x78200004
 
|  
 
|  
 +
|-
 +
| 0xEFE00000
 +
| 0x80000
 +
| 0x1B900000
 +
| 0x28109010
 
| Loader data area (only mapped when running loader)
 
| Loader data area (only mapped when running loader)
 
|-
 
|-
| 0xf4000000 - 0xf6000000
+
| 0xF4000000
| 0x00000000 - 0x02000000
+
| 0x2000000
| 0x02000000
+
| 0
|  
+
| 0x28204004
|  
   
| MEM1
 
| MEM1
 
|-
 
|-
| 0xf6000000 - 0xf6800000
+
| 0xF6000000
| 0x1b000000 - 0x1b800000
+
| 0x800000
| 0x00800000
+
| 0x1B000000
|  
+
| 0x3CA08002
|  
   
| [[Loader]] chunk buffer
 
| [[Loader]] chunk buffer
 
|-
 
|-
| 0xf8000000 - 0xfb000000
+
| 0xF8000000
| 0x18000000 - 0x1b000000
+
| 0x3000000
| 0x03000000
+
| 0x18000000
|  
+
| 0x2CA08002
|  
   
| Read-only shared data (system fonts mostly)
 
| Read-only shared data (system fonts mostly)
 
|-
 
|-
| 0xfc000000 - 0xfc400000
+
| 0xFB000000
| 0x0c000000 - 0x0c400000
+
| 0x800000
| 0x00400000
+
| 0x1C800000
|  
+
| 0x28200002
 
|  
 
|  
| Espresso IO registers.
   
|-
 
|-
| 0xfc000000 - 0xfc0c0000
+
| 0xFC000000
| 0x0c000000 - 0x0c0c0000
+
| 0xC0000
| 0x000c0000
+
| 0xC000000
|  
+
| 0x70100022
|  
   
| {{hw|Processor Interface}}
 
| {{hw|Processor Interface}}
 
|-
 
|-
| 0xfc200000 - 0xfc280000
+
| 0xFC0C0000
| 0x0c200000 - 0x0c280000
+
| 0x120000
| 0x00080000
+
| 0xC0C0000
 +
| 0x70100022
 
|  
 
|  
|
  −
| GX2 TCL registers
   
|-
 
|-
| 0xfc280000 - 0xfc2a0000
+
| 0xFC1E0000
| 0x0c280000 - 0x0c2a0000
+
| 0x20000
| 0x00020000
+
| 0xC1E0000
|  
+
| 0x78100024
|  
+
| VI
| DSP registers
+
|-
 +
| 0xFC200000
 +
| 0x80000
 +
| 0xC200000
 +
| 0x78100024
 +
| GFXSP
 +
|-
 +
| 0xFC280000
 +
| 0x20000
 +
| 0xC280000
 +
| 0x78100024
 +
| DSP
 +
|-
 +
| 0xFC2A0000
 +
| 0x20000
 +
| 0xC2A0000
 +
| 0x78100023
 +
| Write Gather Pipe
 
|-
 
|-
| 0xfc2a0000 - 0xfc2c0000
+
| 0xFC300000
| 0x0c2a0000 - 0x0c2c0000
+
| 0x20000
| 0x00020000
+
| 0xC300000
|  
+
| 0x78100024
 
|  
 
|  
| GX2 FIFO space? (Radeon PKT3 sent here)
   
|-
 
|-
| 0xfc320000 - 0xfc400000
+
| 0xFC320000
| 0x0c320000 - 0x0c400000
+
| 0xE0000
| 0x000e0000
+
| 0xC320000
|  
+
| 0x70100022
|  
+
| Espresso eFuses
| Espresso OTP (and other stuff?)
   
|-
 
|-
| 0xfd000000 - 0xfd??????
+
| 0xFD000000
| 0x0d000000
+
| 0x400000
|  
+
| 0xD000000
|  
+
| 0x70100022
|  
   
| {{hw|Latte Registers}}
 
| {{hw|Latte Registers}}
 
|-
 
|-
| 0xfd040250 - 0xfd046c00
+
| 0xFE000000
| 0x0d040250 - 0x0d046c00
+
| 0x800000
| 0x000069b0
+
| 0x1C000000
 +
| 0x20200002
 
|  
 
|  
 +
|-
 +
| 0xFF200000
 +
| 0x80000
 +
| 0x1B800000
 +
| 0x20100040
 +
| Kernel heap
 +
|-
 +
| 0xFF280000
 +
| 0x80000
 +
| 0x1B880000
 +
| 0x20100040
 
|  
 
|  
| I2C registers
   
|-
 
|-
| 0xfd046e00 - 0xfd060520
+
| 0xFFC00000
| 0x0d046e00 - 0x0d060520
+
| 0x20000
| 0x00019720
+
| 0xFFC00000
 +
| 0x8100004
 +
| Codegen area used with OSCodegenCopy
 +
|-
 +
| 0xFFC40000
 +
| 0x20000
 +
| 0xFFC40000
 +
| 0x8100004
 +
| Codegen area used with OSCodegenCopy
 +
|-
 +
| 0xFFC80000
 +
| 0x20000
 +
| 0xFFC80000
 +
| 0x810000C
 +
| Codegen area used with OSCodegenCopy
 +
|-
 +
| 0xFFCE0000
 +
| 0x20000
 +
| 0
 +
| 0x50100004
 
|  
 
|  
 +
|-
 +
| 0xFFE00000
 +
| 0x20000
 +
| 0xFFE00000
 +
| 0x20100040
 +
| Kernel ancast image
 +
|-
 +
| 0xFFE40000
 +
| 0x20000
 +
| 0xFFE40000
 +
| 0x20100040
 
|  
 
|  
| AI registers?
   
|-
 
|-
| 0xff200000 - 0xff280000
+
| 0xFFE80000
| 0x1b800000 - 0x1b880000
+
| 0x60000
| 0x00080000
+
| 0xFFE80000
 +
| 0x20100040
 
|  
 
|  
 +
|-
 +
| 0xFFEE0000
 +
| 0x20000
 +
| 0xFFEE0000
 +
| 0x20100040
 
|  
 
|  
| Kernel heap
   
|-
 
|-
| 0xffc00000 - 0xffc20000
+
| 0xFFF00000
| ?
+
| 0x20000
| 0x00020000
+
| 0xFFF00000
 +
| 0x20100040
 
|  
 
|  
 +
|-
 +
| 0xFFF60000
 +
| 0x20000
 +
| 0xFFE20000
 +
| 0x20100080
 
|  
 
|  
| Codegen area used with OSCodegenCopy. It's unknown when this contains actual proper data.
   
|-
 
|-
| 0xffc40000 - 0xffc60000
+
| 0xFFF80000
| ?
+
| 0x20000
| 0x00020000
+
| 0xFFE60000
|  
+
| 0x2C100040
 
|  
 
|  
| Codegen area used with OSCodegenCopy. It's unknown when this contains actual proper data.
   
|-
 
|-
| 0xffc80000 - 0xffca0000
+
| 0xFFFA0000
| ?
+
| 0x20000
| 0x00020000
+
| 0xFFE60000
|  
+
| 0x20100080
 
|  
 
|  
| Codegen area used with OSCodegenCopy. It's unknown when this contains actual proper data.
   
|-
 
|-
| 0xffe00000 - 0xfff20000
+
| 0xFFFC0000
| 0xffe00000 - 0xfff20000
+
| 0x20000
| 0x00120000
+
| 0x1BFE0000
|  
+
| 0x24100002
 
|  
 
|  
| Kernel ancast image
   
|-
 
|-
| 0xffffffe0(?) - 0xfffffffc(?)
+
| 0xFFFE0000
|
+
| 0x20000
|  
+
| 0x1BF80000
|  
+
| 0x28100102
|  
+
| Per-thread data (e.g. pointer to thread descriptor and thread queue) at 0xFFFFFFE0 - 0xFFFFFFFC.
| Per-thread data (e.g. pointer to thread descriptor and thread queue)
   
|}
 
|}
1

edit