diff --git a/stratosphere/pm/pm.json b/stratosphere/pm/pm.json index a7bd7e8a9..e9f28ad36 100644 --- a/stratosphere/pm/pm.json +++ b/stratosphere/pm/pm.json @@ -1,7 +1,7 @@ { "name": "ProcessMana", "title_id": "0x0100000000000003", - "main_thread_stack_size": "0x00001000", + "main_thread_stack_size": "0x00002000", "main_thread_priority": 49, "default_cpu_id": 3, "process_category": 1, diff --git a/stratosphere/pm/source/pm_boot2.cpp b/stratosphere/pm/source/pm_boot2.cpp index 2f22c9d11..3a6844621 100644 --- a/stratosphere/pm/source/pm_boot2.cpp +++ b/stratosphere/pm/source/pm_boot2.cpp @@ -173,7 +173,7 @@ void EmbeddedBoot2::Main() { } closedir(titles_dir); } - + /* We no longer need the SD card. */ fsdevUnmountAll(); } diff --git a/stratosphere/pm/source/pm_boot_mode.cpp b/stratosphere/pm/source/pm_boot_mode.cpp index 7b83ee1e8..7268660cc 100644 --- a/stratosphere/pm/source/pm_boot_mode.cpp +++ b/stratosphere/pm/source/pm_boot_mode.cpp @@ -20,33 +20,10 @@ static bool g_is_maintenance_boot = false; -Result BootModeService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) { - Result rc = 0xF601; - - switch ((BootModeCmd)cmd_id) { - case BootMode_Cmd_GetBootMode: - rc = WrapIpcCommandImpl<&BootModeService::get_boot_mode>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case BootMode_Cmd_SetMaintenanceBoot: - rc = WrapIpcCommandImpl<&BootModeService::set_maintenance_boot>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - default: - break; - } - - return rc; +void BootModeService::GetBootMode(Out out) { + out.SetValue(g_is_maintenance_boot); } -Result BootModeService::handle_deferred() { - /* This service is never deferrable. */ - return 0; -} - -std::tuple BootModeService::get_boot_mode() { - return {0, g_is_maintenance_boot}; -} - -std::tuple BootModeService::set_maintenance_boot() { +void BootModeService::SetMaintenanceBoot() { g_is_maintenance_boot = true; - return {0}; } diff --git a/stratosphere/pm/source/pm_boot_mode.hpp b/stratosphere/pm/source/pm_boot_mode.hpp index 097dace3a..96572797f 100644 --- a/stratosphere/pm/source/pm_boot_mode.hpp +++ b/stratosphere/pm/source/pm_boot_mode.hpp @@ -16,24 +16,21 @@ #pragma once #include -#include +#include enum BootModeCmd { BootMode_Cmd_GetBootMode = 0, BootMode_Cmd_SetMaintenanceBoot = 1 }; -class BootModeService final : public IServiceObject { - public: - Result dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) override; - Result handle_deferred() override; - - BootModeService *clone() override { - return new BootModeService(*this); - } - +class BootModeService final : public IServiceObject { private: /* Actual commands. */ - std::tuple get_boot_mode(); - std::tuple set_maintenance_boot(); + void GetBootMode(Out out); + void SetMaintenanceBoot(); + public: + DEFINE_SERVICE_DISPATCH_TABLE { + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + }; }; diff --git a/stratosphere/pm/source/pm_debug_monitor.cpp b/stratosphere/pm/source/pm_debug_monitor.cpp index 8555fc8dd..a9d4312d2 100644 --- a/stratosphere/pm/source/pm_debug_monitor.cpp +++ b/stratosphere/pm/source/pm_debug_monitor.cpp @@ -20,172 +20,88 @@ #include "pm_resource_limits.hpp" #include "pm_debug_monitor.hpp" -Result DebugMonitorService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) { - Result rc = 0xF601; - if (kernelAbove500()) { - switch ((DmntCmd_5X)cmd_id) { - case Dmnt_Cmd_5X_GetDebugProcessIds: - rc = WrapIpcCommandImpl<&DebugMonitorService::get_debug_process_ids>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Dmnt_Cmd_5X_LaunchDebugProcess: - rc = WrapIpcCommandImpl<&DebugMonitorService::launch_debug_process>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Dmnt_Cmd_5X_GetTitleProcessId: - rc = WrapIpcCommandImpl<&DebugMonitorService::get_title_process_id>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Dmnt_Cmd_5X_EnableDebugForTitleId: - rc = WrapIpcCommandImpl<&DebugMonitorService::enable_debug_for_tid>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Dmnt_Cmd_5X_GetApplicationProcessId: - rc = WrapIpcCommandImpl<&DebugMonitorService::get_application_process_id>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Dmnt_Cmd_5X_EnableDebugForApplication: - rc = WrapIpcCommandImpl<&DebugMonitorService::enable_debug_for_application>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Dmnt_Cmd_6X_DisableDebug: - if (kernelAbove600()) { - rc = WrapIpcCommandImpl<&DebugMonitorService::disable_debug>(this, r, out_c, pointer_buffer, pointer_buffer_size); - } - break; - case Dmnt_Cmd_5X_AtmosphereGetProcessHandle: - rc = WrapIpcCommandImpl<&DebugMonitorService::get_process_handle>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Dmnt_Cmd_5X_AtmosphereGetCurrentLimitInfo: - rc = WrapIpcCommandImpl<&DebugMonitorService::get_current_limit_info>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - default: - break; - } - } else { - switch ((DmntCmd)cmd_id) { - case Dmnt_Cmd_GetUnknownStub: - rc = WrapIpcCommandImpl<&DebugMonitorService::get_unknown_stub>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Dmnt_Cmd_GetDebugProcessIds: - rc = WrapIpcCommandImpl<&DebugMonitorService::get_debug_process_ids>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Dmnt_Cmd_LaunchDebugProcess: - rc = WrapIpcCommandImpl<&DebugMonitorService::launch_debug_process>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Dmnt_Cmd_GetTitleProcessId: - rc = WrapIpcCommandImpl<&DebugMonitorService::get_title_process_id>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Dmnt_Cmd_EnableDebugForTitleId: - rc = WrapIpcCommandImpl<&DebugMonitorService::enable_debug_for_tid>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Dmnt_Cmd_GetApplicationProcessId: - rc = WrapIpcCommandImpl<&DebugMonitorService::get_application_process_id>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Dmnt_Cmd_EnableDebugForApplication: - rc = WrapIpcCommandImpl<&DebugMonitorService::enable_debug_for_application>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Dmnt_Cmd_AtmosphereGetProcessHandle: - rc = WrapIpcCommandImpl<&DebugMonitorService::get_process_handle>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Dmnt_Cmd_AtmosphereGetCurrentLimitInfo: - rc = WrapIpcCommandImpl<&DebugMonitorService::get_current_limit_info>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - default: - break; - } + +Result DebugMonitorService::GetUnknownStub(Out count, OutBuffer out_buf, u64 in_unk) { + /* This command seems stubbed. */ + if (out_buf.num_elements >> 31) { + return 0xC0F; } - return rc; + count.SetValue(0); + return 0x0; } -Result DebugMonitorService::handle_deferred() { - /* This service is never deferrable. */ - return 0; -} - - -std::tuple DebugMonitorService::get_unknown_stub(u64 unknown, OutBuffer out_unknown) { - /* This command seem stubbed on retail. */ - if (out_unknown.num_elements >> 31) { - return {0xC0F, 0}; - } - return {0x0, 0}; -} - -std::tuple DebugMonitorService::get_debug_process_ids(OutBuffer out_pids) { - u32 num_out = 0; - Result rc; +Result DebugMonitorService::GetDebugProcessIds(Out count, OutBuffer out_pids) { if (out_pids.num_elements >> 31) { - return {0xC0F, 0}; + return 0xC0F; } - rc = Registration::GetDebugProcessIds(out_pids.buffer, out_pids.num_elements, &num_out); - return {rc, num_out}; + return Registration::GetDebugProcessIds(out_pids.buffer, out_pids.num_elements, count.GetPointer()); } -std::tuple DebugMonitorService::launch_debug_process(u64 pid) { - return {Registration::LaunchDebugProcess(pid)}; +Result DebugMonitorService::LaunchDebugProcess(u64 pid) { + return Registration::LaunchDebugProcess(pid); } -std::tuple DebugMonitorService::get_title_process_id(u64 tid) { +Result DebugMonitorService::GetTitleProcessId(Out pid, u64 tid) { auto auto_lock = Registration::GetProcessListUniqueLock(); std::shared_ptr proc = Registration::GetProcessByTitleId(tid); if (proc != nullptr) { - return {0, proc->pid}; - } else { - return {0x20F, 0}; + pid.SetValue(proc->pid); + return 0; } + return 0x20F; } -std::tuple DebugMonitorService::enable_debug_for_tid(u64 tid) { - Handle h = 0; - Result rc = Registration::EnableDebugForTitleId(tid, &h); - return {rc, h}; +Result DebugMonitorService::EnableDebugForTitleId(Out event, u64 tid) { + return Registration::EnableDebugForTitleId(tid, event.GetHandlePointer()); } -std::tuple DebugMonitorService::get_application_process_id() { +Result DebugMonitorService::GetApplicationProcessId(Out pid) { auto auto_lock = Registration::GetProcessListUniqueLock(); std::shared_ptr app_proc; if (Registration::HasApplicationProcess(&app_proc)) { - return {0, app_proc->pid}; + pid.SetValue(app_proc->pid); + return 0x0; } - return {0x20F, 0}; + return 0x20F; } -std::tuple DebugMonitorService::enable_debug_for_application() { - Handle h = 0; - Result rc = Registration::EnableDebugForApplication(&h); - return {rc, h}; +Result DebugMonitorService::EnableDebugForApplication(Out event) { + return Registration::EnableDebugForApplication(event.GetHandlePointer()); } -std::tuple DebugMonitorService::disable_debug(u32 which) { - return {Registration::DisableDebug(which)}; +Result DebugMonitorService::DisableDebug(u32 which) { + return Registration::DisableDebug(which); } -std::tuple DebugMonitorService::get_process_handle(u64 pid) { - std::shared_ptr proc = Registration::GetProcess(pid); - if(proc == NULL) { - return {0x20F, 0}; +Result DebugMonitorService::AtmosphereGetProcessHandle(Out proc_hand, u64 pid) { + auto proc = Registration::GetProcess(pid); + if(proc != nullptr) { + proc_hand.SetValue(proc->handle); + return 0; } - return {0, proc->handle}; + return 0x20F; } -std::tuple DebugMonitorService::get_current_limit_info(u32 category, u32 resource) { +Result DebugMonitorService::AtmosphereGetCurrentLimitInfo(Out cur_val, Out lim_val, u32 category, u32 resource) { + Result rc; if(category > ResourceLimitUtils::ResourceLimitCategory::ResourceLimitCategory_Applet) { - return {0xf001, 0, 0}; + return 0xF001; } Handle limit_h = ResourceLimitUtils::GetResourceLimitHandleByCategory((ResourceLimitUtils::ResourceLimitCategory) category); - uint64_t current_value, limit_value; - - Result r; - - r = svcGetResourceLimitCurrentValue(¤t_value, limit_h, (LimitableResource) resource); - if(R_FAILED(r)) { - return {r, 0, 0}; + rc = svcGetResourceLimitCurrentValue(cur_val.GetPointer(), limit_h, (LimitableResource) resource); + if(R_FAILED(rc)) { + return rc; } - r = svcGetResourceLimitLimitValue(&limit_value, limit_h, (LimitableResource) resource); - if(R_FAILED(r)) { - return {r, 0, 0}; + rc = svcGetResourceLimitLimitValue(lim_val.GetPointer(), limit_h, (LimitableResource) resource); + if(R_FAILED(rc)) { + return rc; } - return {0, current_value, limit_value}; + return 0; } diff --git a/stratosphere/pm/source/pm_debug_monitor.hpp b/stratosphere/pm/source/pm_debug_monitor.hpp index 24c2d7839..88445bc60 100644 --- a/stratosphere/pm/source/pm_debug_monitor.hpp +++ b/stratosphere/pm/source/pm_debug_monitor.hpp @@ -16,7 +16,7 @@ #pragma once #include -#include +#include #include "pm_registration.hpp" @@ -28,12 +28,7 @@ enum DmntCmd { Dmnt_Cmd_EnableDebugForTitleId = 4, Dmnt_Cmd_GetApplicationProcessId = 5, Dmnt_Cmd_EnableDebugForApplication = 6, - - Dmnt_Cmd_AtmosphereGetProcessHandle = 65000, - Dmnt_Cmd_AtmosphereGetCurrentLimitInfo = 65001, -}; - -enum DmntCmd_5X { + Dmnt_Cmd_5X_GetDebugProcessIds = 0, Dmnt_Cmd_5X_LaunchDebugProcess = 1, Dmnt_Cmd_5X_GetTitleProcessId = 2, @@ -43,31 +38,49 @@ enum DmntCmd_5X { Dmnt_Cmd_6X_DisableDebug = 6, - Dmnt_Cmd_5X_AtmosphereGetProcessHandle = 65000, - Dmnt_Cmd_5X_AtmosphereGetCurrentLimitInfo = 65001, + Dmnt_Cmd_AtmosphereGetProcessHandle = 65000, + Dmnt_Cmd_AtmosphereGetCurrentLimitInfo = 65001, }; class DebugMonitorService final : public IServiceObject { - public: - Result dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) override; - Result handle_deferred() override; - - DebugMonitorService *clone() override { - return new DebugMonitorService(*this); - } - private: /* Actual commands. */ - std::tuple get_unknown_stub(u64 unknown, OutBuffer out_unknown); - std::tuple get_debug_process_ids(OutBuffer out_processes); - std::tuple launch_debug_process(u64 pid); - std::tuple get_title_process_id(u64 tid); - std::tuple enable_debug_for_tid(u64 tid); - std::tuple get_application_process_id(); - std::tuple enable_debug_for_application(); - std::tuple disable_debug(u32 which); + Result GetUnknownStub(Out count, OutBuffer out_buf, u64 in_unk); + Result GetDebugProcessIds(Out count, OutBuffer out_pids); + Result LaunchDebugProcess(u64 pid); + Result GetTitleProcessId(Out pid, u64 tid); + Result EnableDebugForTitleId(Out event, u64 tid); + Result GetApplicationProcessId(Out pid); + Result EnableDebugForApplication(Out event); + Result DisableDebug(u32 which); /* Atmosphere commands. */ - std::tuple get_process_handle(u64 pid); - std::tuple get_current_limit_info(u32 category, u32 resource); + Result AtmosphereGetProcessHandle(Out proc_hand, u64 pid); + Result AtmosphereGetCurrentLimitInfo(Out cur_val, Out lim_val, u32 category, u32 resource); + public: + DEFINE_SERVICE_DISPATCH_TABLE { + /* 1.0.0-4.1.0 */ + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + + /* 5.0.0-* */ + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + + /* 6.0.0-* */ + MakeServiceCommandMeta(), + + /* Atmosphere extensions. */ + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + }; }; diff --git a/stratosphere/pm/source/pm_info.cpp b/stratosphere/pm/source/pm_info.cpp index 437c75a8c..4498a9f1a 100644 --- a/stratosphere/pm/source/pm_info.cpp +++ b/stratosphere/pm/source/pm_info.cpp @@ -18,32 +18,13 @@ #include "pm_registration.hpp" #include "pm_info.hpp" -Result InformationService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) { - Result rc = 0xF601; - - switch ((InformationCmd)cmd_id) { - case Information_Cmd_GetTitleId: - rc = WrapIpcCommandImpl<&InformationService::get_title_id>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - default: - break; - } - - return rc; -} - -Result InformationService::handle_deferred() { - /* This service is never deferrable. */ - return 0; -} - -std::tuple InformationService::get_title_id(u64 pid) { +Result InformationService::GetTitleId(Out tid, u64 pid) { auto auto_lock = Registration::GetProcessListUniqueLock(); std::shared_ptr proc = Registration::GetProcess(pid); if (proc != NULL) { - return {0x0, proc->tid_sid.title_id}; - } else { - return {0x20F, 0x0}; + tid.SetValue(proc->tid_sid.title_id); + return 0; } + return 0x20F; } diff --git a/stratosphere/pm/source/pm_info.hpp b/stratosphere/pm/source/pm_info.hpp index bc7ce5cd9..ea0879576 100644 --- a/stratosphere/pm/source/pm_info.hpp +++ b/stratosphere/pm/source/pm_info.hpp @@ -17,22 +17,17 @@ #pragma once #include #include -#include enum InformationCmd { Information_Cmd_GetTitleId = 0, }; class InformationService final : public IServiceObject { - public: - Result dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) override; - Result handle_deferred() override; - - InformationService *clone() override { - return new InformationService(*this); - } - private: /* Actual commands. */ - std::tuple get_title_id(u64 pid); + Result GetTitleId(Out tid, u64 pid); + public: + DEFINE_SERVICE_DISPATCH_TABLE { + MakeServiceCommandMeta(), + }; }; diff --git a/stratosphere/pm/source/pm_main.cpp b/stratosphere/pm/source/pm_main.cpp index 034567ecf..2e15f12c8 100644 --- a/stratosphere/pm/source/pm_main.cpp +++ b/stratosphere/pm/source/pm_main.cpp @@ -28,7 +28,6 @@ #include "pm_process_track.hpp" #include "pm_registration.hpp" #include "pm_debug_monitor.hpp" -#include "smm_ams.h" extern "C" { extern u32 __start__; @@ -150,16 +149,16 @@ int main(int argc, char **argv) } /* TODO: What's a good timeout value to use here? */ - WaitableManager *server_manager = new WaitableManager(U64_MAX); + auto server_manager = new WaitableManager(1); /* TODO: Create services. */ - server_manager->add_waitable(new ServiceServer("pm:shell", 3)); - server_manager->add_waitable(new ServiceServer("pm:dmnt", 2)); - server_manager->add_waitable(new ServiceServer("pm:bm", 5)); - server_manager->add_waitable(new ServiceServer("pm:info", 1)); + server_manager->AddWaitable(new ServiceServer("pm:shell", 3)); + server_manager->AddWaitable(new ServiceServer("pm:dmnt", 2)); + server_manager->AddWaitable(new ServiceServer("pm:bm", 5)); + server_manager->AddWaitable(new ServiceServer("pm:info", 1)); /* Loop forever, servicing our services. */ - server_manager->process(); + server_manager->Process(); /* Cleanup. */ delete server_manager; diff --git a/stratosphere/pm/source/pm_process_track.cpp b/stratosphere/pm/source/pm_process_track.cpp index 6de7f8603..bfb2aa623 100644 --- a/stratosphere/pm/source/pm_process_track.cpp +++ b/stratosphere/pm/source/pm_process_track.cpp @@ -21,12 +21,11 @@ void ProcessTracking::MainLoop(void *arg) { /* Make a new waitable manager. */ - MultiThreadedWaitableManager *process_waiter = new MultiThreadedWaitableManager(1, U64_MAX); - process_waiter->add_waitable(Registration::GetProcessLaunchStartEvent()); - Registration::SetProcessListManager(process_waiter); + auto process_waiter = new WaitableManager(1); + process_waiter->AddWaitable(Registration::GetProcessLaunchStartEvent()); /* Service processes. */ - process_waiter->process(); + process_waiter->Process(); delete process_waiter; svcExitThread(); diff --git a/stratosphere/pm/source/pm_process_wait.hpp b/stratosphere/pm/source/pm_process_wait.hpp index 49a85a594..14df0468a 100644 --- a/stratosphere/pm/source/pm_process_wait.hpp +++ b/stratosphere/pm/source/pm_process_wait.hpp @@ -28,41 +28,28 @@ class ProcessWaiter final : public IWaitable { /* ... */ } - std::shared_ptr get_process() { + std::shared_ptr GetProcess() { return this->process; } /* IWaitable */ - Handle get_handle() override { + Handle GetHandle() override { return this->process->handle; } - void handle_deferred() override { - /* TODO: Panic, because we can never be deferred. */ - } - - Result handle_signaled(u64 timeout) override { - return Registration::HandleSignaledProcess(this->get_process()); + Result HandleSignaled(u64 timeout) override { + return Registration::HandleSignaledProcess(this->GetProcess()); } }; class ProcessList final { private: HosRecursiveMutex mutex; - WaitableManager *manager; public: std::vector> processes; - auto get_unique_lock() { + auto GetUniqueLock() { return std::unique_lock{this->mutex}; } - - void set_manager(WaitableManager *manager) { - this->manager = manager; - } - - WaitableManager *get_manager() { - return this->manager; - } }; diff --git a/stratosphere/pm/source/pm_registration.cpp b/stratosphere/pm/source/pm_registration.cpp index 7db40e156..529b892e8 100644 --- a/stratosphere/pm/source/pm_registration.cpp +++ b/stratosphere/pm/source/pm_registration.cpp @@ -25,7 +25,7 @@ static ProcessList g_process_list; static ProcessList g_dead_process_list; -static SystemEvent *g_process_launch_start_event = NULL; +static IEvent *g_process_launch_start_event = nullptr; static HosSemaphore g_sema_finish_launch; static HosMutex g_process_launch_mutex; @@ -34,29 +34,27 @@ static Registration::ProcessLaunchState g_process_launch_state; static std::atomic_bool g_debug_next_application(false); static std::atomic g_debug_on_launch_tid(0); -static SystemEvent *g_process_event = NULL; -static SystemEvent *g_debug_title_event = NULL; -static SystemEvent *g_debug_application_event = NULL; +static IEvent *g_process_event = nullptr; +static IEvent *g_debug_title_event = nullptr; +static IEvent *g_debug_application_event = nullptr; std::unique_lock Registration::GetProcessListUniqueLock() { - return g_process_list.get_unique_lock(); -} - -void Registration::SetProcessListManager(WaitableManager *m) { - g_process_list.set_manager(m); + return g_process_list.GetUniqueLock(); } void Registration::InitializeSystemResources() { - g_process_event = new SystemEvent(NULL, &IEvent::PanicCallback); - g_debug_title_event = new SystemEvent(NULL, &IEvent::PanicCallback); - g_debug_application_event = new SystemEvent(NULL, &IEvent::PanicCallback); - g_process_launch_start_event = new SystemEvent(NULL, &Registration::ProcessLaunchStartCallback); + g_process_event = CreateWriteOnlySystemEvent(); + g_debug_title_event = CreateWriteOnlySystemEvent(); + g_debug_application_event = CreateWriteOnlySystemEvent(); + + /* Auto-clear non-system event. */ + g_process_launch_start_event = CreateSystemEvent(&Registration::ProcessLaunchStartCallback); ResourceLimitUtils::InitializeLimits(); } -Result Registration::ProcessLaunchStartCallback(void *arg, Handle *handles, size_t num_handles, u64 timeout) { - svcClearEvent(handles[0]); +Result Registration::ProcessLaunchStartCallback(u64 timeout) { + g_process_launch_start_event->Clear(); Registration::HandleProcessLaunch(); return 0; } @@ -138,11 +136,11 @@ void Registration::HandleProcessLaunch() { /* Signal, if relevant. */ if (new_process.tid_sid.title_id == g_debug_on_launch_tid.load()) { - g_debug_title_event->signal_event(); + g_debug_title_event->Signal(); g_debug_on_launch_tid = 0; rc = 0; } else if ((new_process.flags & PROCESSFLAGS_APPLICATION) && g_debug_next_application.load()) { - g_debug_application_event->signal_event(); + g_debug_application_event->Signal(); g_debug_next_application = false; rc = 0; } else if (LAUNCHFLAGS_STARTSUSPENDED(launch_flags)) { @@ -181,6 +179,7 @@ HANDLE_PROCESS_LAUNCH_END: if (R_SUCCEEDED(rc)) { *out_pid = new_process.pid; } + g_sema_finish_launch.Signal(); } @@ -220,9 +219,9 @@ Result Registration::LaunchProcess(u64 title_id, FsStorageId storage_id, u64 lau g_process_launch_state.out_pid = out_pid; /* Start a launch, and wait for it to exit. */ - g_process_launch_start_event->signal_event(); + g_process_launch_start_event->Signal(); g_sema_finish_launch.Wait(); - + return g_process_launch_state.result; } @@ -253,7 +252,7 @@ Result Registration::HandleSignaledProcess(std::shared_ptrflags & PROCESSFLAGS_NOTIFYDEBUGEVENTS) { process->flags &= ~(PROCESSFLAGS_DEBUGEVENTPENDING | PROCESSFLAGS_DEBUGSUSPENDED); process->flags |= PROCESSFLAGS_DEBUGEVENTPENDING; - g_process_event->signal_event(); + g_process_event->Signal(); } if (kernelAbove200() && process->flags & PROCESSFLAGS_NOTIFYDEBUGSPECIAL) { process->flags &= ~(PROCESSFLAGS_NOTIFYDEBUGSPECIAL | PROCESSFLAGS_DEBUGDETACHED); @@ -262,18 +261,18 @@ Result Registration::HandleSignaledProcess(std::shared_ptrflags |= (PROCESSFLAGS_CRASHED | PROCESSFLAGS_CRASH_DEBUG); - g_process_event->signal_event(); + g_process_event->Signal(); break; case ProcessState_RunningAttached: if (process->flags & PROCESSFLAGS_NOTIFYDEBUGEVENTS) { process->flags &= ~(PROCESSFLAGS_DEBUGEVENTPENDING | PROCESSFLAGS_DEBUGSUSPENDED); process->flags |= PROCESSFLAGS_DEBUGEVENTPENDING; - g_process_event->signal_event(); + g_process_event->Signal(); } break; case ProcessState_Exited: if (process->flags & PROCESSFLAGS_NOTIFYWHENEXITED && !kernelAbove500()) { - g_process_event->signal_event(); + g_process_event->Signal(); } else { FinalizeExitedProcess(process); } @@ -281,7 +280,7 @@ Result Registration::HandleSignaledProcess(std::shared_ptrflags & PROCESSFLAGS_NOTIFYDEBUGEVENTS) { process->flags |= (PROCESSFLAGS_DEBUGEVENTPENDING | PROCESSFLAGS_DEBUGSUSPENDED); - g_process_event->signal_event(); + g_process_event->Signal(); } break; } @@ -310,7 +309,7 @@ void Registration::FinalizeExitedProcess(std::shared_ptr /* Insert into dead process list, if relevant. */ if (signal_debug_process_5x) { - auto lk = g_dead_process_list.get_unique_lock(); + auto lk = g_dead_process_list.GetUniqueLock(); g_dead_process_list.processes.push_back(process); } @@ -319,14 +318,14 @@ void Registration::FinalizeExitedProcess(std::shared_ptr auto_lock.unlock(); if (signal_debug_process_5x) { - g_process_event->signal_event(); + g_process_event->Signal(); } } void Registration::AddProcessToList(std::shared_ptr process) { auto auto_lock = GetProcessListUniqueLock(); g_process_list.processes.push_back(process); - g_process_list.get_manager()->add_waitable(new ProcessWaiter(process)); + g_process_launch_start_event->GetManager()->AddWaitable(new ProcessWaiter(process)); } void Registration::RemoveProcessFromList(u64 pid) { @@ -412,7 +411,7 @@ Result Registration::GetDebugProcessIds(u64 *out_pids, u32 max_out, u32 *num_out } Handle Registration::GetProcessEventHandle() { - return g_process_event->get_handle(); + return g_process_event->GetHandle(); } void Registration::GetProcessEventType(u64 *out_pid, u64 *out_type) { @@ -451,7 +450,7 @@ void Registration::GetProcessEventType(u64 *out_pid, u64 *out_type) { } if (kernelAbove500()) { auto_lock.unlock(); - auto dead_process_list_lock = g_dead_process_list.get_unique_lock(); + auto dead_process_list_lock = g_dead_process_list.GetUniqueLock(); if (g_dead_process_list.processes.size()) { std::shared_ptr process = g_dead_process_list.processes[0]; g_dead_process_list.processes.erase(g_dead_process_list.processes.begin()); @@ -471,13 +470,13 @@ Result Registration::EnableDebugForTitleId(u64 tid, Handle *out) { g_debug_on_launch_tid = old; return 0x80F; } - *out = g_debug_title_event->get_handle(); + *out = g_debug_title_event->GetHandle(); return 0x0; } Result Registration::EnableDebugForApplication(Handle *out) { g_debug_next_application = true; - *out = g_debug_application_event->get_handle(); + *out = g_debug_application_event->GetHandle(); return 0; } diff --git a/stratosphere/pm/source/pm_registration.hpp b/stratosphere/pm/source/pm_registration.hpp index 6f0459124..8b440ade4 100644 --- a/stratosphere/pm/source/pm_registration.hpp +++ b/stratosphere/pm/source/pm_registration.hpp @@ -172,8 +172,7 @@ class Registration { static void InitializeSystemResources(); static IWaitable *GetProcessLaunchStartEvent(); static std::unique_lock GetProcessListUniqueLock(); - static void SetProcessListManager(WaitableManager *m); - static Result ProcessLaunchStartCallback(void *arg, Handle *handles, size_t num_handles, u64 timeout); + static Result ProcessLaunchStartCallback(u64 timeout); static Result HandleSignaledProcess(std::shared_ptr process); static void FinalizeExitedProcess(std::shared_ptr process); diff --git a/stratosphere/pm/source/pm_shell.cpp b/stratosphere/pm/source/pm_shell.cpp index 4a9653367..aa03b0c68 100644 --- a/stratosphere/pm/source/pm_shell.cpp +++ b/stratosphere/pm/source/pm_shell.cpp @@ -23,170 +23,84 @@ static bool g_has_boot_finished = false; -Result ShellService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) { - Result rc = 0xF601; - - if (kernelAbove500()) { - switch ((ShellCmd_5X)cmd_id) { - case Shell_Cmd_5X_LaunchProcess: - rc = WrapIpcCommandImpl<&ShellService::launch_process>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Shell_Cmd_5X_TerminateProcessId: - rc = WrapIpcCommandImpl<&ShellService::terminate_process_id>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Shell_Cmd_5X_TerminateTitleId: - rc = WrapIpcCommandImpl<&ShellService::terminate_title_id>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Shell_Cmd_5X_GetProcessWaitEvent: - rc = WrapIpcCommandImpl<&ShellService::get_process_wait_event>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Shell_Cmd_5X_GetProcessEventType: - rc = WrapIpcCommandImpl<&ShellService::get_process_event_type>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Shell_Cmd_5X_NotifyBootFinished: - rc = WrapIpcCommandImpl<&ShellService::notify_boot_finished>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Shell_Cmd_5X_GetApplicationProcessId: - rc = WrapIpcCommandImpl<&ShellService::get_application_process_id>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Shell_Cmd_5X_BoostSystemMemoryResourceLimit: - rc = WrapIpcCommandImpl<&ShellService::boost_system_memory_resource_limit>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - default: - break; - } - } else { - switch ((ShellCmd)cmd_id) { - case Shell_Cmd_LaunchProcess: - rc = WrapIpcCommandImpl<&ShellService::launch_process>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Shell_Cmd_TerminateProcessId: - rc = WrapIpcCommandImpl<&ShellService::terminate_process_id>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Shell_Cmd_TerminateTitleId: - rc = WrapIpcCommandImpl<&ShellService::terminate_title_id>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Shell_Cmd_GetProcessWaitEvent: - rc = WrapIpcCommandImpl<&ShellService::get_process_wait_event>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Shell_Cmd_GetProcessEventType: - rc = WrapIpcCommandImpl<&ShellService::get_process_event_type>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Shell_Cmd_FinalizeExitedProcess: - rc = WrapIpcCommandImpl<&ShellService::finalize_exited_process>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Shell_Cmd_ClearProcessNotificationFlag: - rc = WrapIpcCommandImpl<&ShellService::clear_process_notification_flag>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Shell_Cmd_NotifyBootFinished: - rc = WrapIpcCommandImpl<&ShellService::notify_boot_finished>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Shell_Cmd_GetApplicationProcessId: - rc = WrapIpcCommandImpl<&ShellService::get_application_process_id>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Shell_Cmd_BoostSystemMemoryResourceLimit: - rc = WrapIpcCommandImpl<&ShellService::boost_system_memory_resource_limit>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - default: - break; - } - } - - return rc; +Result ShellService::LaunchProcess(Out pid, u64 launch_flags, Registration::TidSid tid_sid) { + return Registration::LaunchProcessByTidSid(tid_sid, launch_flags, pid.GetPointer()); } -Result ShellService::handle_deferred() { - /* This service is never deferrable. */ - return 0; -} - -std::tuple ShellService::launch_process(u64 launch_flags, Registration::TidSid tid_sid) { - u64 pid = 0; - Result rc = Registration::LaunchProcessByTidSid(tid_sid, launch_flags, &pid); - return {rc, pid}; -} - -std::tuple ShellService::terminate_process_id(u64 pid) { +Result ShellService::TerminateProcessId(u64 pid) { auto auto_lock = Registration::GetProcessListUniqueLock(); - std::shared_ptr proc = Registration::GetProcess(pid); + auto proc = Registration::GetProcess(pid); + if (proc != nullptr) { + return svcTerminateProcess(proc->handle); + } else { + return 0x20F; + } +} + +Result ShellService::TerminateTitleId(u64 tid) { + auto auto_lock = Registration::GetProcessListUniqueLock(); + + auto proc = Registration::GetProcessByTitleId(tid); if (proc != NULL) { - return {svcTerminateProcess(proc->handle)}; + return svcTerminateProcess(proc->handle); } else { - return {0x20F}; + return 0x20F; } } -std::tuple ShellService::terminate_title_id(u64 tid) { +void ShellService::GetProcessWaitEvent(Out event) { + event.SetValue(Registration::GetProcessEventHandle()); +} + +void ShellService::GetProcessEventType(Out type, Out pid) { + Registration::GetProcessEventType(pid.GetPointer(), type.GetPointer()); +} + +Result ShellService::FinalizeExitedProcess(u64 pid) { auto auto_lock = Registration::GetProcessListUniqueLock(); - std::shared_ptr proc = Registration::GetProcessByTitleId(tid); - if (proc != NULL) { - return {svcTerminateProcess(proc->handle)}; - } else { - return {0x20F}; - } -} - -std::tuple ShellService::get_process_wait_event() { - return {0x0, Registration::GetProcessEventHandle()}; -} - -std::tuple ShellService::get_process_event_type() { - u64 type, pid; - Registration::GetProcessEventType(&pid, &type); - return {0x0, type, pid}; -} - -std::tuple ShellService::finalize_exited_process(u64 pid) { - auto auto_lock = Registration::GetProcessListUniqueLock(); - - std::shared_ptr proc = Registration::GetProcess(pid); + auto proc = Registration::GetProcess(pid); if (proc == NULL) { - return {0x20F}; + return 0x20F; } else if (proc->state != ProcessState_Exited) { - return {0x60F}; + return 0x60F; } else { Registration::FinalizeExitedProcess(proc); - return {0x0}; + return 0x0; } } -std::tuple ShellService::clear_process_notification_flag(u64 pid) { +Result ShellService::ClearProcessNotificationFlag(u64 pid) { auto auto_lock = Registration::GetProcessListUniqueLock(); - std::shared_ptr proc = Registration::GetProcess(pid); + auto proc = Registration::GetProcess(pid); if (proc != NULL) { proc->flags &= ~PROCESSFLAGS_CRASHED; - return {0x0}; + return 0x0; } else { - return {0x20F}; + return 0x20F; } } -std::tuple ShellService::notify_boot_finished() { +void ShellService::NotifyBootFinished() { if (!g_has_boot_finished) { g_has_boot_finished = true; EmbeddedBoot2::Main(); } - return {0}; } -std::tuple ShellService::get_application_process_id() { +Result ShellService::GetApplicationProcessId(Out pid) { auto auto_lock = Registration::GetProcessListUniqueLock(); std::shared_ptr app_proc; if (Registration::HasApplicationProcess(&app_proc)) { - return {0, app_proc->pid}; + pid.SetValue(app_proc->pid); + return 0; } - return {0x20F, 0}; + return 0x20F; } -std::tuple ShellService::boost_system_memory_resource_limit(u64 sysmem_size) { - if (!kernelAbove400()) { - return {0xF601}; - } - - /* TODO */ - return {ResourceLimitUtils::BoostSystemMemoryResourceLimit(sysmem_size)}; +Result ShellService::BoostSystemMemoryResourceLimit(u64 sysmem_size) { + return ResourceLimitUtils::BoostSystemMemoryResourceLimit(sysmem_size); } diff --git a/stratosphere/pm/source/pm_shell.hpp b/stratosphere/pm/source/pm_shell.hpp index c5b63c030..b488107fd 100644 --- a/stratosphere/pm/source/pm_shell.hpp +++ b/stratosphere/pm/source/pm_shell.hpp @@ -16,7 +16,7 @@ #pragma once #include -#include +#include #include "pm_registration.hpp" @@ -46,26 +46,43 @@ enum ShellCmd_5X { Shell_Cmd_5X_BoostSystemMemoryResourceLimit = 7 }; -class ShellService final : public IServiceObject { - public: - Result dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) override; - Result handle_deferred() override; - - ShellService *clone() override { - return new ShellService(*this); - } - - +class ShellService final : public IServiceObject { private: /* Actual commands. */ - std::tuple launch_process(u64 launch_flags, Registration::TidSid tid_sid); - std::tuple terminate_process_id(u64 pid); - std::tuple terminate_title_id(u64 tid); - std::tuple get_process_wait_event(); - std::tuple get_process_event_type(); - std::tuple finalize_exited_process(u64 pid); - std::tuple clear_process_notification_flag(u64 pid); - std::tuple notify_boot_finished(); - std::tuple get_application_process_id(); - std::tuple boost_system_memory_resource_limit(u64 sysmem_size); + Result LaunchProcess(Out pid, u64 launch_flags, Registration::TidSid tid_sid); + Result TerminateProcessId(u64 pid); + Result TerminateTitleId(u64 tid); + void GetProcessWaitEvent(Out event); + void GetProcessEventType(Out type, Out pid); + Result FinalizeExitedProcess(u64 pid); + Result ClearProcessNotificationFlag(u64 pid); + void NotifyBootFinished(); + Result GetApplicationProcessId(Out pid); + Result BoostSystemMemoryResourceLimit(u64 sysmem_size); + public: + DEFINE_SERVICE_DISPATCH_TABLE { + /* 1.0.0-4.0.0 */ + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + + /* 4.0.0-4.0.0 */ + MakeServiceCommandMeta(), + + /* 5.0.0-* */ + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + }; }; diff --git a/stratosphere/pm/source/smm_ams.c b/stratosphere/pm/source/smm_ams.c deleted file mode 100644 index 4437ba949..000000000 --- a/stratosphere/pm/source/smm_ams.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2018 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include "smm_ams.h" - -static Service g_smManagerAmsSrv; -static u64 g_smManagerAmsRefcnt; - -Result smManagerAmsInitialize(void) { - atomicIncrement64(&g_smManagerAmsRefcnt); - - if (serviceIsActive(&g_smManagerAmsSrv)) - return 0; - - return smGetService(&g_smManagerAmsSrv, "sm:m"); -} - -void smManagerAmsExit(void) { - if (atomicDecrement64(&g_smManagerAmsRefcnt) == 0) - serviceClose(&g_smManagerAmsSrv); -} - -Result smManagerAmsEndInitialDefers(void) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - } *raw; - - raw = serviceIpcPrepareHeader(&g_smManagerAmsSrv, &c, sizeof(*raw)); - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65000; - - - Result rc = serviceIpcDispatch(&g_smManagerAmsSrv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(&g_smManagerAmsSrv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - } - - return rc; - -} \ No newline at end of file diff --git a/stratosphere/pm/source/smm_ams.h b/stratosphere/pm/source/smm_ams.h deleted file mode 100644 index 6d6dd5ed0..000000000 --- a/stratosphere/pm/source/smm_ams.h +++ /dev/null @@ -1,21 +0,0 @@ -/** - * @file smm_ams.h - * @brief Service manager (sm:m) IPC wrapper for Atmosphere extensions. - * @author SciresM - * @copyright libnx Authors - */ -#pragma once -#include - -#ifdef __cplusplus -extern "C" { -#endif - -Result smManagerAmsInitialize(void); -void smManagerAmsExit(void); - -Result smManagerAmsEndInitialDefers(void); - -#ifdef __cplusplus -} -#endif \ No newline at end of file