Difference between revisions of "Process Manager services"

From Nintendo Switch Brew
Jump to navigation Jump to search
(44 intermediate revisions by 5 users not shown)
Line 1: Line 1:
 +
= LaunchFlags =
 +
 +
On [[5.0.0]]+, the LaunchFlag enum looks like this:
 +
 +
{| class=wikitable
 +
! Bit || Mask || Name
 +
|-
 +
| 0 || 1 || LaunchFlags_SignalOnExit
 +
|-
 +
| 1 || 2 || LaunchFlags_SignalOnStart
 +
|-
 +
| 2 || 4 || LaunchFlags_SignalOnCrash
 +
|-
 +
| 3 || 8 || LaunchFlags_SignalOnDebug
 +
|-
 +
| 4 || 0x10 || LaunchFlags_StartSuspended
 +
|-
 +
| 5 || 0x20 || LaunchFlags_DisableAslr
 +
|}
 +
 +
Prior to system version [[5.0.0]], the LaunchFlag enum had its entries in a different order:
 +
 +
{| class=wikitable
 +
! Bit || Mask || Name
 +
|-
 +
| 0 || 1 || LaunchFlags_SignalOnExit
 +
|-
 +
| 1 || 2 || LaunchFlags_StartSuspended
 +
|-
 +
| 2 || 4 || LaunchFlags_SignalOnCrash
 +
|-
 +
| 3 || 8 || LaunchFlags_DisableAslr
 +
|-
 +
| 4 || 0x10 || LaunchFlags_SignalOnDebug
 +
|-
 +
| 5 || 0x20 || [2.0.0+] LaunchFlags_SignalOnStart
 +
|}
 +
 +
= ProcessEventInfo =
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x4
 +
| ProcessEvent
 +
|-
 +
| 0x4
 +
| 0x4
 +
| Padding/Reserved
 +
|-
 +
| 0x8
 +
| 0x8
 +
| ProcessId
 +
|-
 +
|}
 +
 
= Process Tracker thread =
 
= Process Tracker thread =
 
PM has a separate thread that is waiting for synchronization on process handles.
 
PM has a separate thread that is waiting for synchronization on process handles.
  
 
== State changes ==
 
== State changes ==
When the kernel signals a process handle, it uses svcResetSignal on the process handle and then it uses svcGetProcessInfo to read out the ProcessState.
+
When the kernel signals a process handle, it uses svcResetSignal on the process handle and then it uses svcGetProcessInfo to read out the ProcessEvent.
  
If the process moved state non-3 -> 3 it clears 4 in process flags.
+
If the process moved from non-crashed -> ProcessEvent_Crashed it clears 4 in process flags.
  
 
If process flags has mask 8 set:
 
If process flags has mask 8 set:
* If new state is 2, it clears 0x20 and sets 0x10 in process flags, and signals the ProcessEventWaiter handle.
+
* If event is ProcessEvent_Running or ProcessEvent_DebugDetached, it clears 0x20 and sets 0x10 in process flags, and signals the ProcessEventWaiter handle.
* If new state is 4, it clears 0x20 and sets 0x10 in process flags, and signals the ProcessEventWaiter handle.
+
* If event is ProcessEvent_DebugSuspended, it sets 0x20 and 0x10 in process flags, and signals the ProcessEventWaiter handle.
* If new state is 7, it sets 0x30 in process flags, and signals the ProcessEventWaiter handle.
+
 
 +
[2.0.0+] If new state is ProcessEvent_DebugDetached, and process flags has 0x80 set, it sets mask 0x100 and signals the ProcessEventWaiter handle.
  
 
If process flags has mask 1 set:
 
If process flags has mask 1 set:
* If new state is 6, it signals the ProcessEventWaiter handle.
+
* If new state is ProcessEvent_Exited, it signals the ProcessEventWaiter handle.
  
 
If mask 1 is not set, it immediately does what is otherwise done by the [[#FinalizeDeadProcess]] command.
 
If mask 1 is not set, it immediately does what is otherwise done by the [[#FinalizeDeadProcess]] command.
Line 22: Line 82:
 
It uses [[Loader_services|ldr:pm]] GetProgramInfo with the supplied title-id.
 
It uses [[Loader_services|ldr:pm]] GetProgramInfo with the supplied title-id.
  
If ((*(u8*) (info_output+2)) & 3) is == 1, it goes through the process list and errors if any has bit 0x40 set. Thus only one process can have bit 0x40 set at a time.
+
If ApplicationType == Application, it goes through the process list and errors if any has mask 0x40 set. Thus you can only run one Application at a time.
 +
 
 +
Resource limits for the process is selected by ApplicationType.
  
 
It calls [[Loader_services|ldr:pm]] RegisterTitle, then [[Loader_services|ldr:pm]] CreateProcess, then [[Filesystem_services|fsp-pr]] RegisterTitle, then [[Services_API|sm:m]] RegisterTitle.
 
It calls [[Loader_services|ldr:pm]] RegisterTitle, then [[Loader_services|ldr:pm]] CreateProcess, then [[Filesystem_services|fsp-pr]] RegisterTitle, then [[Services_API|sm:m]] RegisterTitle.
  
The second input argument for [[Loader_services|ldr:pm]] CreateProcess is (launch_flags >> 2) & 3.
+
[1.0.0] The second input argument for [[Loader_services|ldr:pm]] CreateProcess is (launch_flags >> 2) & 3.
 +
 
 +
[2.0.0+] The second input argument for [[Loader_services|ldr:pm]] CreateProcess is ((launch_flags >> 2) & 2) | ((launch_flags >> 1) != 1).
  
 
If launch_flags has mask 1 set, it sets mask 1 in process flags.
 
If launch_flags has mask 1 set, it sets mask 1 in process flags.
Line 32: Line 96:
 
If launch_flags has mask 0x10 set, it sets mask 8 in process flags.
 
If launch_flags has mask 0x10 set, it sets mask 8 in process flags.
  
If ((*(u8*) (info_output+2)) & 3) is == 1, it sets 0x40 in the process flags, and signals the event returned by [[#EnableDebug]]. svcStartProcess is not called in this case, it has to be done manually by the [[#StartProcess]] command.
+
[2.0.0+] If launch_flags has mask 0x20 set, it sets mask 0x80 in process flags.
 +
 
 +
[2.0.0+] The launch_flags mask 0x10 and 0x20 will be ignored unless ((*(u8*) (info_output+2)) & 4) is set.
 +
 
 +
If ApplicationType == Application, it sets 0x40 in the process flags, and signals the event returned by [[#EnableDebugForApplication]]. svcStartProcess is not called in this case, it has to be done manually by the [[#StartProcess]] command.
  
 
If the title-id matches the title-id given in [[#EnableDebugForTitleId]], then svcStartProcess is not called. Instead process remains in suspended state, and has to be done manually by the [[#StartProcess]] command.
 
If the title-id matches the title-id given in [[#EnableDebugForTitleId]], then svcStartProcess is not called. Instead process remains in suspended state, and has to be done manually by the [[#StartProcess]] command.
Line 39: Line 107:
  
 
Finally it does svcStartProcess on the process handle that was returned by [[Loader_services|ldr:pm]] CreateProcess, and sets process state to 2.
 
Finally it does svcStartProcess on the process handle that was returned by [[Loader_services|ldr:pm]] CreateProcess, and sets process state to 2.
 +
 +
The arguments for svcStartProcess are process_handle, *(u8*)info_output, *(u8*)(info_output+1), *(u32*)(info_output+4).
  
 
Thus at the point of launch, the pid is already registered in ldr, fs, sm, and pm.
 
Thus at the point of launch, the pid is already registered in ldr, fs, sm, and pm.
  
 
= pm:bm =
 
= pm:bm =
 +
This is "nn::pm::detail::IBootModeInterface".
 +
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
 
! Cmd || Name
 
! Cmd || Name
 
|-
 
|-
| 0 || GetMaintenanceMode
+
| 0 || GetBootMode
 
|-
 
|-
| 1 || EnableMaintenanceMode
+
| 1 || SetMaintenanceBoot
 
|}
 
|}
  
 
= pm:dmnt =
 
= pm:dmnt =
 +
This is "nn::pm::detail::IDebugMonitorInterface".
 +
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
 
! Cmd || Name
 
! Cmd || Name
 
|-
 
|-
| 0 || [[#GetDebugMode]]
+
| [1.0.0-4.1.0] 0 || [[#GetModuleIdList]]
 +
|-
 +
| 0 ([1.0.0-4.1.0] 1) || [[#GetJitDebugProcessIdList]]
 +
|-
 +
| 1 ([1.0.0-4.1.0] 2) || [[#StartProcess]]
 
|-
 
|-
| 1 || [[#GetDebugProcesses]]
+
| 2 ([1.0.0-4.1.0] 3) || [[#GetProcessId]]
 
|-
 
|-
| 2 || [[#StartDebugProcess]]
+
| 3 ([1.0.0-4.1.0] 4) || [[#HookToCreateProcess]]
 
|-
 
|-
| 3 || [[#GetDebugProcessTitleIdByPid]]
+
| 4 ([1.0.0-4.1.0] 5) || [[#GetApplicationProcessId]]
 
|-
 
|-
| 4 || [[#EnableDebugForTitleId]]
+
| 5 ([1.0.0-4.1.0] 6) || [[#HookToCreateApplicationProcess]]
 
|-
 
|-
| 5 || [[#GetCrashingDebugProcessPid]]
+
| [6.0.0+] 6 || [[#ClearHook]]
 
|-
 
|-
| 6 || [[#EnableDebug]]
+
| [14.0.0+] 7 || GetProgramId
 
|}
 
|}
  
== GetDebugMode ==
 
Always returns u32 0 on retail.
 
  
== GetDebugProcesses ==
+
== GetModuleIdList==
 +
Stubbed in all versions of retail firmware (just returns 0).
 +
 
 +
[2.0.0+] When output buffer size is > INT_MAX, returns ResultInvalidSize.
 +
 
 +
== GetJitDebugProcessIdList ==
 
Returns an array of pids of all processes that have mask 4 set in process flags.
 
Returns an array of pids of all processes that have mask 4 set in process flags.
  
== StartDebugProcess ==
+
[2.0.0+] When output buffer size is > INT_MAX, returns ResultInvalidSize.
Takes a pid. Process state must be 0 or 1. Then it uses svcStartProcess(process_handle, u8, u8, u32) with args coming from ldr:pm GetProgramInfo.
+
 
 +
== StartProcess ==
 +
Takes a pid. Last process event must be ProcessEvent_Created or ProcessEvent_DebugAttached.
 +
 
 +
Then it uses svcStartProcess(process_handle, u8, u8, u32) with args coming from ldr:pm GetProgramInfo.
 +
 
 +
After that, it sets last process state to ProcessEvent_DebugDetached.
  
After that, it sets process state to 2.
+
== GetProcessId ==
 +
Takes a title-id and returns the pid.
  
== GetDebugProcessTitleIdByPid ==
+
== HookToCreateProcess ==
Same as [[Process_Manager_services#GetProcessTitleIdByPid|GetProcessTitleIdByPid]] but for debug processes.
+
Takes a title-id of the program to debug. Sets this to a global field.
  
== EnableDebugForTitleId ==
+
Next time it gets launched it will be handled differently.
Takes a title-id of the program to debug. Sets this to a global field. Next time it gets launched it will be handled differently.
 
  
Returns an event handle that is signaled when the requested title is launched.
+
Returns an event handle that is signaled when the requested title is about to be launched.
  
== GetCrashingDebugProcessPid ==
+
== GetApplicationProcessId ==
Same as [[Process_Manager_services#GetCrashingProcessPid|GetCrashingProcessPid]] but for debug processes.
+
Returns the pid of the application process.
  
== EnableDebug ==
+
== HookToCreateApplicationProcess ==
 
Does *not* take a specific title-id as input.
 
Does *not* take a specific title-id as input.
  
Returns an event handle that is triggered for debug titles.
+
Returns an event handle that is triggered for application titles.
 +
 
 +
== ClearHook ==
 +
Takes in a u32 of bitflags.
 +
 
 +
Disables debugging/clears the globally specified tid if bit 0 is set, disables debugging/clears the next application if bit 1 is set.
  
 
= pm:info =
 
= pm:info =
 +
This is "nn::pm::detail::IInformationInterface".
 +
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
 
! Cmd || Name
 
! Cmd || Name
 
|-
 
|-
| 0 || [[#GetProcessTitleIdByPid]]
+
| 0 || [[#GetProgramId]]
 +
|-
 +
| 1 || [14.0.0+] GetAppletCurrentResourceLimitValues
 +
|-
 +
| 2 || [14.0.0+] GetAppletPeakResourceLimitValues
 
|}
 
|}
  
== GetProcessTitleIdByPid ==
+
== GetProgramId ==
 
Takes a pid and returns the title-id associated with the process.
 
Takes a pid and returns the title-id associated with the process.
  
 
= pm:shell =
 
= pm:shell =
 +
This is "nn::pm::detail::IShellInterface".
 +
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
 
! Cmd || Name
 
! Cmd || Name
 
|-
 
|-
| 0 || [[#LaunchProcess]]
+
| 0 || [[#LaunchProgram]]
 +
|-
 +
| 1 || TerminateProcess
 +
|-
 +
| 2 || TerminateProgram
 +
|-
 +
| 3 || GetProcessEventHandle
 +
|-
 +
| 4 || [[#GetProcessEventInfo]]
 
|-
 
|-
| 1 || TerminateProcessByPid
+
| ([1.0.0-4.1.0] 5) || [[#CleanupProcess]]
 
|-
 
|-
| 2 || TerminateProcessByTitleId
+
| ([1.0.0-4.1.0] 6) || [[#ClearJitDebugOccured]]
 
|-
 
|-
| 3 || GetProcessEventWaiter
+
| 5 ([1.0.0-4.1.0] 7) || [[#NotifyBootFinished]]
 
|-
 
|-
| 4 || [[#GetProcessEventType]]
+
| 6 ([1.0.0-4.1.0] 8) || [[#GetApplicationProcessIdForShell]]
 
|-
 
|-
| 5 || [[#FinalizeDeadProcess]]
+
| 7 ([4.0.0-4.1.0] 9) || [4.0.0+] [[#BoostSystemMemoryResourceLimit]]
 
|-
 
|-
| 6 || [[#ClearProcessNotificationFlag]]
+
| 8 || [7.0.0+] [[#BoostApplicationThreadResourceLimit]]
 
|-
 
|-
| 7 || [[#NotifyBootFinished]]
+
| 9 || [8.0.0+] [[#GetBootFinishedEventHandle]]
 
|-
 
|-
| 8 || [[#GetCrashingProcessPid]]
+
| 10 || [14.0.0+] BoostSystemThreadResourceLimit
 
|}
 
|}
  
== LaunchProcess ==
+
== LaunchProgram ==
Takes a title-id and launch_flags. See [[#Process launch]].
+
Takes an u32 launch_flags and [[NCM_services#ProgramLocation|ProgramLocation]]. Returns the u64 title PID.
 +
 
 +
See [[#Process launch]].
  
== GetProcessEventType ==
+
== GetProcessEventInfo ==
Returns 1 if flags has bit1 set.
+
Returns 1 if flags has mask 2 set.
  
Returns 2 if flags has bit0 set and state is 6.
+
Returns 2 if flags has mask 1 set and state is 6.
  
Returns 3 if flags has bit4 set and not bit5.
+
Returns 3 if flags has mask 0x10 set and not 0x20.
  
Returns 4 if flags has both bit4 and bit5 set.
+
Returns 4 if flags has mask 0x30 set.
  
[2.0.0+] returns 5 if state >= 2 and bit8 is set.
+
[2.0.0+] returns 5 if state >= 2 and flags has mask 0x100 set.
  
 
Returns 0 if process is not found.
 
Returns 0 if process is not found.
  
(0=CONTINUE, 1=CRASHING, 2,3,5)
+
== CleanupProcess ==
 
 
== FinalizeDeadProcess ==
 
 
Takes a pid as input. If the process with pid has the state "dead", it unregisters the pid in fsp:pr, sm:m, and ldr:pm.
 
Takes a pid as input. If the process with pid has the state "dead", it unregisters the pid in fsp:pr, sm:m, and ldr:pm.
  
 
Then it removes the process from PMs internal linked-list of active processes.
 
Then it removes the process from PMs internal linked-list of active processes.
  
== ClearProcessNotificationFlag ==
+
[5.0.0+] This command was removed.
Takes a pid as input. Clears 0x10 from process flags.  
+
 
 +
== ClearJitDebugOccured ==
 +
Takes a pid as input. Clears 0x10 from process flags.
 +
 
 +
[5.0.0+] This command was removed.
  
 
== NotifyBootFinished ==
 
== NotifyBootFinished ==
Launches a process with hardcoded [[boot2]] title-id.
+
This launches the [[boot2]] title.
 +
 
 +
[4.0.0+] When booting from SafeMode Firmware, instead of [[boot2]], this launches the following titles in order:
 +
* 0100000000000009 (settings)
 +
* 0100000000000006 (usb)
 +
* 010000000000001D (pcie)
 +
* 0100000000000007 (tma)
 +
* 010000000000001F (ns)
 +
* 0100000000000015 (lm)
 +
* 0100000000000010 (ptm)
 +
* 0100000000000016 (wlan)
 +
* 0100000000000012 (bsdsockets)
 +
* 010000000000000F (nifm)
 +
* 0100000000000024 (ssl)
 +
* 0100000000000025 (nim)
 +
* 0100000000000031 (glue)
 +
* 010000000000003D (safemode)
  
== GetCrashingProcessPid ==
+
== GetApplicationProcessIdForShell ==
 
Loops through the internal linked-list of processes, looks for mask 0x40 set in process flags. Returns pid of first such entry.
 
Loops through the internal linked-list of processes, looks for mask 0x40 set in process flags. Returns pid of first such entry.
 +
 +
== BoostSystemMemoryResourceLimit ==
 +
Takes an u64 '''mem_size''' as input. If the desired memory size doesn't exceed an internal limit (imposed by PM by looking at the [[SPL_services#MemoryArrange|MemoryArrange]] ConfigItem), PM calls svcSetResourceLimitLimitValue to set the new [[SVC#LimitableResource|LimitableResource_Memory]] value.
 +
 +
This is used directly by [[NS_Services#IApplicationManagerInterface|ns:am2 BoostSystemMemoryResourceLimit]].
 +
 +
== BoostApplicationThreadResourceLimit ==
 +
Calls svcSetResourceLimitLimitValue to increase the limit on application threads by an amount calculated dynamically during setup.
 +
 +
This function can only increase the limit once, on further calls it will call svcSetResourceLimitLimitValue with the same value it called the first time.
 +
 +
On normal [[7.0.0]] retail firmware, this will double the limit on application threads from 0x60 to 0xC0.
 +
 +
== GetBootFinishedEventHandle ==
 +
This function returns a handle to an event that is signaled when [[#NotifyBootFinished]] is called.
 +
 +
However, this is only used/available in safe mode; in normal, non-safe FIRM, the implementation for this command just does "abort();".
  
 
[[Category:Services]]
 
[[Category:Services]]

Revision as of 18:59, 22 March 2022

LaunchFlags

On 5.0.0+, the LaunchFlag enum looks like this:

Bit Mask Name
0 1 LaunchFlags_SignalOnExit
1 2 LaunchFlags_SignalOnStart
2 4 LaunchFlags_SignalOnCrash
3 8 LaunchFlags_SignalOnDebug
4 0x10 LaunchFlags_StartSuspended
5 0x20 LaunchFlags_DisableAslr

Prior to system version 5.0.0, the LaunchFlag enum had its entries in a different order:

Bit Mask Name
0 1 LaunchFlags_SignalOnExit
1 2 LaunchFlags_StartSuspended
2 4 LaunchFlags_SignalOnCrash
3 8 LaunchFlags_DisableAslr
4 0x10 LaunchFlags_SignalOnDebug
5 0x20 [2.0.0+] LaunchFlags_SignalOnStart

ProcessEventInfo

Offset Size Description
0x0 0x4 ProcessEvent
0x4 0x4 Padding/Reserved
0x8 0x8 ProcessId

Process Tracker thread

PM has a separate thread that is waiting for synchronization on process handles.

State changes

When the kernel signals a process handle, it uses svcResetSignal on the process handle and then it uses svcGetProcessInfo to read out the ProcessEvent.

If the process moved from non-crashed -> ProcessEvent_Crashed it clears 4 in process flags.

If process flags has mask 8 set:

  • If event is ProcessEvent_Running or ProcessEvent_DebugDetached, it clears 0x20 and sets 0x10 in process flags, and signals the ProcessEventWaiter handle.
  • If event is ProcessEvent_DebugSuspended, it sets 0x20 and 0x10 in process flags, and signals the ProcessEventWaiter handle.

[2.0.0+] If new state is ProcessEvent_DebugDetached, and process flags has 0x80 set, it sets mask 0x100 and signals the ProcessEventWaiter handle.

If process flags has mask 1 set:

  • If new state is ProcessEvent_Exited, it signals the ProcessEventWaiter handle.

If mask 1 is not set, it immediately does what is otherwise done by the #FinalizeDeadProcess command.

Process launch

This thread can also be triggered by the pm:shell #LaunchProcess cmd.

It uses ldr:pm GetProgramInfo with the supplied title-id.

If ApplicationType == Application, it goes through the process list and errors if any has mask 0x40 set. Thus you can only run one Application at a time.

Resource limits for the process is selected by ApplicationType.

It calls ldr:pm RegisterTitle, then ldr:pm CreateProcess, then fsp-pr RegisterTitle, then sm:m RegisterTitle.

[1.0.0] The second input argument for ldr:pm CreateProcess is (launch_flags >> 2) & 3.

[2.0.0+] The second input argument for ldr:pm CreateProcess is ((launch_flags >> 2) & 2) | ((launch_flags >> 1) != 1).

If launch_flags has mask 1 set, it sets mask 1 in process flags.

If launch_flags has mask 0x10 set, it sets mask 8 in process flags.

[2.0.0+] If launch_flags has mask 0x20 set, it sets mask 0x80 in process flags.

[2.0.0+] The launch_flags mask 0x10 and 0x20 will be ignored unless ((*(u8*) (info_output+2)) & 4) is set.

If ApplicationType == Application, it sets 0x40 in the process flags, and signals the event returned by #EnableDebugForApplication. svcStartProcess is not called in this case, it has to be done manually by the #StartProcess command.

If the title-id matches the title-id given in #EnableDebugForTitleId, then svcStartProcess is not called. Instead process remains in suspended state, and has to be done manually by the #StartProcess command.

If launch_flags has mask 2 set, svcStartProcess is skipped.

Finally it does svcStartProcess on the process handle that was returned by ldr:pm CreateProcess, and sets process state to 2.

The arguments for svcStartProcess are process_handle, *(u8*)info_output, *(u8*)(info_output+1), *(u32*)(info_output+4).

Thus at the point of launch, the pid is already registered in ldr, fs, sm, and pm.

pm:bm

This is "nn::pm::detail::IBootModeInterface".

Cmd Name
0 GetBootMode
1 SetMaintenanceBoot

pm:dmnt

This is "nn::pm::detail::IDebugMonitorInterface".

Cmd Name
[1.0.0-4.1.0] 0 #GetModuleIdList
0 ([1.0.0-4.1.0] 1) #GetJitDebugProcessIdList
1 ([1.0.0-4.1.0] 2) #StartProcess
2 ([1.0.0-4.1.0] 3) #GetProcessId
3 ([1.0.0-4.1.0] 4) #HookToCreateProcess
4 ([1.0.0-4.1.0] 5) #GetApplicationProcessId
5 ([1.0.0-4.1.0] 6) #HookToCreateApplicationProcess
[6.0.0+] 6 #ClearHook
[14.0.0+] 7 GetProgramId


GetModuleIdList

Stubbed in all versions of retail firmware (just returns 0).

[2.0.0+] When output buffer size is > INT_MAX, returns ResultInvalidSize.

GetJitDebugProcessIdList

Returns an array of pids of all processes that have mask 4 set in process flags.

[2.0.0+] When output buffer size is > INT_MAX, returns ResultInvalidSize.

StartProcess

Takes a pid. Last process event must be ProcessEvent_Created or ProcessEvent_DebugAttached.

Then it uses svcStartProcess(process_handle, u8, u8, u32) with args coming from ldr:pm GetProgramInfo.

After that, it sets last process state to ProcessEvent_DebugDetached.

GetProcessId

Takes a title-id and returns the pid.

HookToCreateProcess

Takes a title-id of the program to debug. Sets this to a global field.

Next time it gets launched it will be handled differently.

Returns an event handle that is signaled when the requested title is about to be launched.

GetApplicationProcessId

Returns the pid of the application process.

HookToCreateApplicationProcess

Does *not* take a specific title-id as input.

Returns an event handle that is triggered for application titles.

ClearHook

Takes in a u32 of bitflags.

Disables debugging/clears the globally specified tid if bit 0 is set, disables debugging/clears the next application if bit 1 is set.

pm:info

This is "nn::pm::detail::IInformationInterface".

Cmd Name
0 #GetProgramId
1 [14.0.0+] GetAppletCurrentResourceLimitValues
2 [14.0.0+] GetAppletPeakResourceLimitValues

GetProgramId

Takes a pid and returns the title-id associated with the process.

pm:shell

This is "nn::pm::detail::IShellInterface".

Cmd Name
0 #LaunchProgram
1 TerminateProcess
2 TerminateProgram
3 GetProcessEventHandle
4 #GetProcessEventInfo
([1.0.0-4.1.0] 5) #CleanupProcess
([1.0.0-4.1.0] 6) #ClearJitDebugOccured
5 ([1.0.0-4.1.0] 7) #NotifyBootFinished
6 ([1.0.0-4.1.0] 8) #GetApplicationProcessIdForShell
7 ([4.0.0-4.1.0] 9) [4.0.0+] #BoostSystemMemoryResourceLimit
8 [7.0.0+] #BoostApplicationThreadResourceLimit
9 [8.0.0+] #GetBootFinishedEventHandle
10 [14.0.0+] BoostSystemThreadResourceLimit

LaunchProgram

Takes an u32 launch_flags and ProgramLocation. Returns the u64 title PID.

See #Process launch.

GetProcessEventInfo

Returns 1 if flags has mask 2 set.

Returns 2 if flags has mask 1 set and state is 6.

Returns 3 if flags has mask 0x10 set and not 0x20.

Returns 4 if flags has mask 0x30 set.

[2.0.0+] returns 5 if state >= 2 and flags has mask 0x100 set.

Returns 0 if process is not found.

CleanupProcess

Takes a pid as input. If the process with pid has the state "dead", it unregisters the pid in fsp:pr, sm:m, and ldr:pm.

Then it removes the process from PMs internal linked-list of active processes.

[5.0.0+] This command was removed.

ClearJitDebugOccured

Takes a pid as input. Clears 0x10 from process flags.

[5.0.0+] This command was removed.

NotifyBootFinished

This launches the boot2 title.

[4.0.0+] When booting from SafeMode Firmware, instead of boot2, this launches the following titles in order:

  • 0100000000000009 (settings)
  • 0100000000000006 (usb)
  • 010000000000001D (pcie)
  • 0100000000000007 (tma)
  • 010000000000001F (ns)
  • 0100000000000015 (lm)
  • 0100000000000010 (ptm)
  • 0100000000000016 (wlan)
  • 0100000000000012 (bsdsockets)
  • 010000000000000F (nifm)
  • 0100000000000024 (ssl)
  • 0100000000000025 (nim)
  • 0100000000000031 (glue)
  • 010000000000003D (safemode)

GetApplicationProcessIdForShell

Loops through the internal linked-list of processes, looks for mask 0x40 set in process flags. Returns pid of first such entry.

BoostSystemMemoryResourceLimit

Takes an u64 mem_size as input. If the desired memory size doesn't exceed an internal limit (imposed by PM by looking at the MemoryArrange ConfigItem), PM calls svcSetResourceLimitLimitValue to set the new LimitableResource_Memory value.

This is used directly by ns:am2 BoostSystemMemoryResourceLimit.

BoostApplicationThreadResourceLimit

Calls svcSetResourceLimitLimitValue to increase the limit on application threads by an amount calculated dynamically during setup.

This function can only increase the limit once, on further calls it will call svcSetResourceLimitLimitValue with the same value it called the first time.

On normal 7.0.0 retail firmware, this will double the limit on application threads from 0x60 to 0xC0.

GetBootFinishedEventHandle

This function returns a handle to an event that is signaled when #NotifyBootFinished is called.

However, this is only used/available in safe mode; in normal, non-safe FIRM, the implementation for this command just does "abort();".