From a05c0eac2fa90c18b8fff1daba277aeb30d8451c Mon Sep 17 00:00:00 2001 From: FearlessTobi Date: Tue, 27 Feb 2024 18:26:31 +0100 Subject: [PATCH] pm: Split interfaces up into individual files --- src/core/CMakeLists.txt | 9 + .../am/service/common_state_getter.cpp | 4 +- .../service/am/service/common_state_getter.h | 4 +- src/core/hle/service/pm/boot_mode_service.cpp | 33 +++ src/core/hle/service/pm/boot_mode_service.h | 23 ++ .../hle/service/pm/debug_monitor_service.cpp | 97 +++++++ .../hle/service/pm/debug_monitor_service.h | 20 ++ .../hle/service/pm/information_service.cpp | 62 +++++ src/core/hle/service/pm/information_service.h | 20 ++ src/core/hle/service/pm/pm.cpp | 258 +----------------- src/core/hle/service/pm/pm.h | 5 - src/core/hle/service/pm/pm_types.h | 51 ++++ src/core/hle/service/pm/shell_service.cpp | 34 +++ src/core/hle/service/pm/shell_service.h | 19 ++ 14 files changed, 380 insertions(+), 259 deletions(-) create mode 100644 src/core/hle/service/pm/boot_mode_service.cpp create mode 100644 src/core/hle/service/pm/boot_mode_service.h create mode 100644 src/core/hle/service/pm/debug_monitor_service.cpp create mode 100644 src/core/hle/service/pm/debug_monitor_service.h create mode 100644 src/core/hle/service/pm/information_service.cpp create mode 100644 src/core/hle/service/pm/information_service.h create mode 100644 src/core/hle/service/pm/pm_types.h create mode 100644 src/core/hle/service/pm/shell_service.cpp create mode 100644 src/core/hle/service/pm/shell_service.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 63a6da12e6..a0d46d91cf 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -926,8 +926,17 @@ add_library(core STATIC hle/service/pctl/pctl_types.h hle/service/pcv/pcv.cpp hle/service/pcv/pcv.h + hle/service/pm/boot_mode_service.cpp + hle/service/pm/boot_mode_service.h + hle/service/pm/debug_monitor_service.cpp + hle/service/pm/debug_monitor_service.h + hle/service/pm/information_service.cpp + hle/service/pm/information_service.h hle/service/pm/pm.cpp hle/service/pm/pm.h + hle/service/pm/pm_types.h + hle/service/pm/shell_service.cpp + hle/service/pm/shell_service.h hle/service/prepo/prepo.cpp hle/service/prepo/prepo.h hle/service/psc/ovln/ovln_types.h diff --git a/src/core/hle/service/am/service/common_state_getter.cpp b/src/core/hle/service/am/service/common_state_getter.cpp index a32855ffa3..445a1177ea 100644 --- a/src/core/hle/service/am/service/common_state_getter.cpp +++ b/src/core/hle/service/am/service/common_state_getter.cpp @@ -154,9 +154,9 @@ Result ICommonStateGetter::GetPerformanceMode(Out out_perf R_SUCCEED(); } -Result ICommonStateGetter::GetBootMode(Out out_boot_mode) { +Result ICommonStateGetter::GetBootMode(Out out_boot_mode) { LOG_DEBUG(Service_AM, "called"); - *out_boot_mode = Service::PM::SystemBootMode::Normal; + *out_boot_mode = Service::PM::BootMode::Normal; R_SUCCEED(); } diff --git a/src/core/hle/service/am/service/common_state_getter.h b/src/core/hle/service/am/service/common_state_getter.h index 59a46fa94f..3c450d7ff1 100644 --- a/src/core/hle/service/am/service/common_state_getter.h +++ b/src/core/hle/service/am/service/common_state_getter.h @@ -6,7 +6,7 @@ #include "core/hle/service/am/am_types.h" #include "core/hle/service/apm/apm_controller.h" #include "core/hle/service/cmif_types.h" -#include "core/hle/service/pm/pm.h" +#include "core/hle/service/pm/pm_types.h" #include "core/hle/service/service.h" #include "core/hle/service/set/settings_types.h" @@ -37,7 +37,7 @@ private: Result GetDefaultDisplayResolutionChangeEvent(OutCopyHandle out_event); Result GetOperationMode(Out out_operation_mode); Result GetPerformanceMode(Out out_performance_mode); - Result GetBootMode(Out out_boot_mode); + Result GetBootMode(Out out_boot_mode); Result IsVrModeEnabled(Out out_is_vr_mode_enabled); Result SetVrModeEnabled(bool is_vr_mode_enabled); Result SetLcdBacklighOffEnabled(bool is_lcd_backlight_off_enabled); diff --git a/src/core/hle/service/pm/boot_mode_service.cpp b/src/core/hle/service/pm/boot_mode_service.cpp new file mode 100644 index 0000000000..ab22f20411 --- /dev/null +++ b/src/core/hle/service/pm/boot_mode_service.cpp @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/pm/boot_mode_service.h" + +namespace Service::PM { + +BootModeService::BootModeService(Core::System& system_) : ServiceFramework{system_, "pm:bm"} { + static const FunctionInfo functions[] = { + {0, &BootModeService::GetBootMode, "GetBootMode"}, + {1, &BootModeService::SetMaintenanceBoot, "SetMaintenanceBoot"}, + }; + RegisterHandlers(functions); +} + +void BootModeService::GetBootMode(HLERequestContext& ctx) { + LOG_DEBUG(Service_PM, "called"); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.PushEnum(boot_mode); +} + +void BootModeService::SetMaintenanceBoot(HLERequestContext& ctx) { + LOG_DEBUG(Service_PM, "called"); + + boot_mode = BootMode::Maintenance; + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +} // namespace Service::PM diff --git a/src/core/hle/service/pm/boot_mode_service.h b/src/core/hle/service/pm/boot_mode_service.h new file mode 100644 index 0000000000..81d27baba3 --- /dev/null +++ b/src/core/hle/service/pm/boot_mode_service.h @@ -0,0 +1,23 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/pm/pm_types.h" +#include "core/hle/service/service.h" + +namespace Service::PM { + +class BootModeService final : public ServiceFramework { +public: + explicit BootModeService(Core::System& system_); + +private: + void GetBootMode(HLERequestContext& ctx); + void SetMaintenanceBoot(HLERequestContext& ctx); + + BootMode boot_mode = BootMode::Normal; +}; + +} // namespace Service::PM diff --git a/src/core/hle/service/pm/debug_monitor_service.cpp b/src/core/hle/service/pm/debug_monitor_service.cpp new file mode 100644 index 0000000000..9fec74d39e --- /dev/null +++ b/src/core/hle/service/pm/debug_monitor_service.cpp @@ -0,0 +1,97 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/pm/debug_monitor_service.h" +#include "core/hle/service/pm/pm_types.h" + +namespace Service::PM { + +DebugMonitorService::DebugMonitorService(Core::System& system_) + : ServiceFramework{system_, "pm:dmnt"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "GetJitDebugProcessIdList"}, + {1, nullptr, "StartProcess"}, + {2, &DebugMonitorService::GetProcessId, "GetProcessId"}, + {3, nullptr, "HookToCreateProcess"}, + {4, &DebugMonitorService::GetApplicationProcessId, "GetApplicationProcessId"}, + {5, nullptr, "HookToCreateApplicationProgress"}, + {6, nullptr, "ClearHook"}, + {65000, &DebugMonitorService::AtmosphereGetProcessInfo, "AtmosphereGetProcessInfo"}, + {65001, nullptr, "AtmosphereGetCurrentLimitInfo"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +void DebugMonitorService::GetProcessId(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto program_id = rp.PopRaw(); + + LOG_DEBUG(Service_PM, "called, program_id={:016X}", program_id); + + auto list = kernel.GetProcessList(); + auto process = + SearchProcessList(list, [program_id](auto& p) { return p->GetProgramId() == program_id; }); + + if (process.IsNull()) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultProcessNotFound); + return; + } + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(process->GetProcessId()); +} + +void DebugMonitorService::GetApplicationProcessId(HLERequestContext& ctx) { + LOG_DEBUG(Service_PM, "called"); + auto list = kernel.GetProcessList(); + GetApplicationPidGeneric(ctx, list); +} + +void DebugMonitorService::AtmosphereGetProcessInfo(HLERequestContext& ctx) { + // https://github.com/Atmosphere-NX/Atmosphere/blob/master/stratosphere/pm/source/impl/pm_process_manager.cpp#L614 + // This implementation is incomplete; only a handle to the process is returned. + IPC::RequestParser rp{ctx}; + const auto pid = rp.PopRaw(); + + LOG_WARNING(Service_PM, "(Partial Implementation) called, pid={:016X}", pid); + + auto list = kernel.GetProcessList(); + auto process = SearchProcessList(list, [pid](auto& p) { return p->GetProcessId() == pid; }); + + if (process.IsNull()) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultProcessNotFound); + return; + } + + struct ProgramLocation { + u64 program_id; + u8 storage_id; + }; + static_assert(sizeof(ProgramLocation) == 0x10, "ProgramLocation has an invalid size"); + + struct OverrideStatus { + u64 keys_held; + u64 flags; + }; + static_assert(sizeof(OverrideStatus) == 0x10, "OverrideStatus has an invalid size"); + + OverrideStatus override_status{}; + ProgramLocation program_location{ + .program_id = process->GetProgramId(), + .storage_id = 0, + }; + + IPC::ResponseBuilder rb{ctx, 10, 1}; + rb.Push(ResultSuccess); + rb.PushCopyObjects(*process); + rb.PushRaw(program_location); + rb.PushRaw(override_status); +} + +} // namespace Service::PM diff --git a/src/core/hle/service/pm/debug_monitor_service.h b/src/core/hle/service/pm/debug_monitor_service.h new file mode 100644 index 0000000000..4855a98580 --- /dev/null +++ b/src/core/hle/service/pm/debug_monitor_service.h @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/service.h" + +namespace Service::PM { + +class DebugMonitorService final : public ServiceFramework { +public: + explicit DebugMonitorService(Core::System& system_); + +private: + void GetProcessId(HLERequestContext& ctx); + void GetApplicationProcessId(HLERequestContext& ctx); + void AtmosphereGetProcessInfo(HLERequestContext& ctx); +}; +} // namespace Service::PM diff --git a/src/core/hle/service/pm/information_service.cpp b/src/core/hle/service/pm/information_service.cpp new file mode 100644 index 0000000000..8f418a50c9 --- /dev/null +++ b/src/core/hle/service/pm/information_service.cpp @@ -0,0 +1,62 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/pm/information_service.h" +#include "core/hle/service/pm/pm_types.h" + +namespace Service::PM { + +InformationService::InformationService(Core::System& system_) + : ServiceFramework{system_, "pm:info"} { + static const FunctionInfo functions[] = { + {0, &InformationService::GetProgramId, "GetProgramId"}, + {65000, &InformationService::AtmosphereGetProcessId, "AtmosphereGetProcessId"}, + {65001, nullptr, "AtmosphereHasLaunchedProgram"}, + {65002, nullptr, "AtmosphereGetProcessInfo"}, + }; + RegisterHandlers(functions); +} + +void InformationService::GetProgramId(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto process_id = rp.PopRaw(); + + LOG_DEBUG(Service_PM, "called, process_id={:016X}", process_id); + + auto list = kernel.GetProcessList(); + auto process = + SearchProcessList(list, [process_id](auto& p) { return p->GetProcessId() == process_id; }); + + if (process.IsNull()) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultProcessNotFound); + return; + } + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(process->GetProgramId()); +} + +void InformationService::AtmosphereGetProcessId(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto program_id = rp.PopRaw(); + + LOG_DEBUG(Service_PM, "called, program_id={:016X}", program_id); + + auto list = system.Kernel().GetProcessList(); + auto process = + SearchProcessList(list, [program_id](auto& p) { return p->GetProgramId() == program_id; }); + + if (process.IsNull()) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultProcessNotFound); + return; + } + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(process->GetProcessId()); +} + +} // namespace Service::PM diff --git a/src/core/hle/service/pm/information_service.h b/src/core/hle/service/pm/information_service.h new file mode 100644 index 0000000000..82d65302e2 --- /dev/null +++ b/src/core/hle/service/pm/information_service.h @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/service.h" + +namespace Service::PM { + +class InformationService final : public ServiceFramework { +public: + explicit InformationService(Core::System& system_); + +private: + void GetProgramId(HLERequestContext& ctx); + void AtmosphereGetProcessId(HLERequestContext& ctx); +}; + +} // namespace Service::PM diff --git a/src/core/hle/service/pm/pm.cpp b/src/core/hle/service/pm/pm.cpp index b52468e419..e0da6525b7 100644 --- a/src/core/hle/service/pm/pm.cpp +++ b/src/core/hle/service/pm/pm.cpp @@ -2,264 +2,22 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/core.h" -#include "core/hle/kernel/k_process.h" -#include "core/hle/kernel/kernel.h" -#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/pm/boot_mode_service.h" +#include "core/hle/service/pm/debug_monitor_service.h" +#include "core/hle/service/pm/information_service.h" #include "core/hle/service/pm/pm.h" +#include "core/hle/service/pm/shell_service.h" #include "core/hle/service/server_manager.h" -#include "core/hle/service/service.h" namespace Service::PM { -namespace { - -constexpr Result ResultProcessNotFound{ErrorModule::PM, 1}; -[[maybe_unused]] constexpr Result ResultAlreadyStarted{ErrorModule::PM, 2}; -[[maybe_unused]] constexpr Result ResultNotTerminated{ErrorModule::PM, 3}; -[[maybe_unused]] constexpr Result ResultDebugHookInUse{ErrorModule::PM, 4}; -[[maybe_unused]] constexpr Result ResultApplicationRunning{ErrorModule::PM, 5}; -[[maybe_unused]] constexpr Result ResultInvalidSize{ErrorModule::PM, 6}; - -constexpr u64 NO_PROCESS_FOUND_PID{0}; - -using ProcessList = std::list>; - -template -Kernel::KScopedAutoObject SearchProcessList(ProcessList& process_list, - F&& predicate) { - const auto iter = std::find_if(process_list.begin(), process_list.end(), predicate); - - if (iter == process_list.end()) { - return nullptr; - } - - return iter->GetPointerUnsafe(); -} - -void GetApplicationPidGeneric(HLERequestContext& ctx, ProcessList& process_list) { - auto process = SearchProcessList(process_list, [](auto& p) { return p->IsApplication(); }); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push(process.IsNull() ? NO_PROCESS_FOUND_PID : process->GetProcessId()); -} - -} // Anonymous namespace - -class BootMode final : public ServiceFramework { -public: - explicit BootMode(Core::System& system_) : ServiceFramework{system_, "pm:bm"} { - static const FunctionInfo functions[] = { - {0, &BootMode::GetBootMode, "GetBootMode"}, - {1, &BootMode::SetMaintenanceBoot, "SetMaintenanceBoot"}, - }; - RegisterHandlers(functions); - } - -private: - void GetBootMode(HLERequestContext& ctx) { - LOG_DEBUG(Service_PM, "called"); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.PushEnum(boot_mode); - } - - void SetMaintenanceBoot(HLERequestContext& ctx) { - LOG_DEBUG(Service_PM, "called"); - - boot_mode = SystemBootMode::Maintenance; - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - SystemBootMode boot_mode = SystemBootMode::Normal; -}; - -class DebugMonitor final : public ServiceFramework { -public: - explicit DebugMonitor(Core::System& system_) : ServiceFramework{system_, "pm:dmnt"} { - // clang-format off - static const FunctionInfo functions[] = { - {0, nullptr, "GetJitDebugProcessIdList"}, - {1, nullptr, "StartProcess"}, - {2, &DebugMonitor::GetProcessId, "GetProcessId"}, - {3, nullptr, "HookToCreateProcess"}, - {4, &DebugMonitor::GetApplicationProcessId, "GetApplicationProcessId"}, - {5, nullptr, "HookToCreateApplicationProgress"}, - {6, nullptr, "ClearHook"}, - {65000, &DebugMonitor::AtmosphereGetProcessInfo, "AtmosphereGetProcessInfo"}, - {65001, nullptr, "AtmosphereGetCurrentLimitInfo"}, - }; - // clang-format on - - RegisterHandlers(functions); - } - -private: - void GetProcessId(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto program_id = rp.PopRaw(); - - LOG_DEBUG(Service_PM, "called, program_id={:016X}", program_id); - - auto list = kernel.GetProcessList(); - auto process = SearchProcessList( - list, [program_id](auto& p) { return p->GetProgramId() == program_id; }); - - if (process.IsNull()) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultProcessNotFound); - return; - } - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push(process->GetProcessId()); - } - - void GetApplicationProcessId(HLERequestContext& ctx) { - LOG_DEBUG(Service_PM, "called"); - auto list = kernel.GetProcessList(); - GetApplicationPidGeneric(ctx, list); - } - - void AtmosphereGetProcessInfo(HLERequestContext& ctx) { - // https://github.com/Atmosphere-NX/Atmosphere/blob/master/stratosphere/pm/source/impl/pm_process_manager.cpp#L614 - // This implementation is incomplete; only a handle to the process is returned. - IPC::RequestParser rp{ctx}; - const auto pid = rp.PopRaw(); - - LOG_WARNING(Service_PM, "(Partial Implementation) called, pid={:016X}", pid); - - auto list = kernel.GetProcessList(); - auto process = SearchProcessList(list, [pid](auto& p) { return p->GetProcessId() == pid; }); - - if (process.IsNull()) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultProcessNotFound); - return; - } - - struct ProgramLocation { - u64 program_id; - u8 storage_id; - }; - static_assert(sizeof(ProgramLocation) == 0x10, "ProgramLocation has an invalid size"); - - struct OverrideStatus { - u64 keys_held; - u64 flags; - }; - static_assert(sizeof(OverrideStatus) == 0x10, "OverrideStatus has an invalid size"); - - OverrideStatus override_status{}; - ProgramLocation program_location{ - .program_id = process->GetProgramId(), - .storage_id = 0, - }; - - IPC::ResponseBuilder rb{ctx, 10, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(*process); - rb.PushRaw(program_location); - rb.PushRaw(override_status); - } -}; - -class Info final : public ServiceFramework { -public: - explicit Info(Core::System& system_) : ServiceFramework{system_, "pm:info"} { - static const FunctionInfo functions[] = { - {0, &Info::GetProgramId, "GetProgramId"}, - {65000, &Info::AtmosphereGetProcessId, "AtmosphereGetProcessId"}, - {65001, nullptr, "AtmosphereHasLaunchedProgram"}, - {65002, nullptr, "AtmosphereGetProcessInfo"}, - }; - RegisterHandlers(functions); - } - -private: - void GetProgramId(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto process_id = rp.PopRaw(); - - LOG_DEBUG(Service_PM, "called, process_id={:016X}", process_id); - - auto list = kernel.GetProcessList(); - auto process = SearchProcessList( - list, [process_id](auto& p) { return p->GetProcessId() == process_id; }); - - if (process.IsNull()) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultProcessNotFound); - return; - } - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push(process->GetProgramId()); - } - - void AtmosphereGetProcessId(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto program_id = rp.PopRaw(); - - LOG_DEBUG(Service_PM, "called, program_id={:016X}", program_id); - - auto list = system.Kernel().GetProcessList(); - auto process = SearchProcessList( - list, [program_id](auto& p) { return p->GetProgramId() == program_id; }); - - if (process.IsNull()) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultProcessNotFound); - return; - } - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push(process->GetProcessId()); - } -}; - -class Shell final : public ServiceFramework { -public: - explicit Shell(Core::System& system_) : ServiceFramework{system_, "pm:shell"} { - // clang-format off - static const FunctionInfo functions[] = { - {0, nullptr, "LaunchProgram"}, - {1, nullptr, "TerminateProcess"}, - {2, nullptr, "TerminateProgram"}, - {3, nullptr, "GetProcessEventHandle"}, - {4, nullptr, "GetProcessEventInfo"}, - {5, nullptr, "NotifyBootFinished"}, - {6, &Shell::GetApplicationProcessIdForShell, "GetApplicationProcessIdForShell"}, - {7, nullptr, "BoostSystemMemoryResourceLimit"}, - {8, nullptr, "BoostApplicationThreadResourceLimit"}, - {9, nullptr, "GetBootFinishedEventHandle"}, - }; - // clang-format on - - RegisterHandlers(functions); - } - -private: - void GetApplicationProcessIdForShell(HLERequestContext& ctx) { - LOG_DEBUG(Service_PM, "called"); - auto list = kernel.GetProcessList(); - GetApplicationPidGeneric(ctx, list); - } -}; - void LoopProcess(Core::System& system) { auto server_manager = std::make_unique(system); - server_manager->RegisterNamedService("pm:bm", std::make_shared(system)); - server_manager->RegisterNamedService("pm:dmnt", std::make_shared(system)); - server_manager->RegisterNamedService("pm:info", std::make_shared(system)); - server_manager->RegisterNamedService("pm:shell", std::make_shared(system)); + server_manager->RegisterNamedService("pm:bm", std::make_shared(system)); + server_manager->RegisterNamedService("pm:dmnt", std::make_shared(system)); + server_manager->RegisterNamedService("pm:info", std::make_shared(system)); + server_manager->RegisterNamedService("pm:shell", std::make_shared(system)); ServerManager::RunServer(std::move(server_manager)); } diff --git a/src/core/hle/service/pm/pm.h b/src/core/hle/service/pm/pm.h index 5d4a1a171c..00f9701b59 100644 --- a/src/core/hle/service/pm/pm.h +++ b/src/core/hle/service/pm/pm.h @@ -9,11 +9,6 @@ class System; namespace Service::PM { -enum class SystemBootMode { - Normal, - Maintenance, -}; - void LoopProcess(Core::System& system); } // namespace Service::PM diff --git a/src/core/hle/service/pm/pm_types.h b/src/core/hle/service/pm/pm_types.h new file mode 100644 index 0000000000..1785e9d457 --- /dev/null +++ b/src/core/hle/service/pm/pm_types.h @@ -0,0 +1,51 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/common_types.h" +#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/kernel.h" +#include "core/hle/result.h" +#include "core/hle/service/ipc_helpers.h" + +namespace Service::PM { + +constexpr Result ResultProcessNotFound{ErrorModule::PM, 1}; +[[maybe_unused]] constexpr Result ResultAlreadyStarted{ErrorModule::PM, 2}; +[[maybe_unused]] constexpr Result ResultNotTerminated{ErrorModule::PM, 3}; +[[maybe_unused]] constexpr Result ResultDebugHookInUse{ErrorModule::PM, 4}; +[[maybe_unused]] constexpr Result ResultApplicationRunning{ErrorModule::PM, 5}; +[[maybe_unused]] constexpr Result ResultInvalidSize{ErrorModule::PM, 6}; + +constexpr u64 NO_PROCESS_FOUND_PID{0}; + +enum class BootMode { + Normal = 0, + Maintenance = 1, + SafeMode = 2, +}; + +using ProcessList = std::list>; + +template +static inline Kernel::KScopedAutoObject SearchProcessList( + ProcessList& process_list, F&& predicate) { + const auto iter = std::find_if(process_list.begin(), process_list.end(), predicate); + + if (iter == process_list.end()) { + return nullptr; + } + + return iter->GetPointerUnsafe(); +} + +static inline void GetApplicationPidGeneric(HLERequestContext& ctx, ProcessList& process_list) { + auto process = SearchProcessList(process_list, [](auto& p) { return p->IsApplication(); }); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(process.IsNull() ? NO_PROCESS_FOUND_PID : process->GetProcessId()); +} + +} // namespace Service::PM diff --git a/src/core/hle/service/pm/shell_service.cpp b/src/core/hle/service/pm/shell_service.cpp new file mode 100644 index 0000000000..e40903664c --- /dev/null +++ b/src/core/hle/service/pm/shell_service.cpp @@ -0,0 +1,34 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/pm/pm_types.h" +#include "core/hle/service/pm/shell_service.h" + +namespace Service::PM { + +ShellService::ShellService(Core::System& system_) : ServiceFramework{system_, "pm:shell"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "LaunchProgram"}, + {1, nullptr, "TerminateProcess"}, + {2, nullptr, "TerminateProgram"}, + {3, nullptr, "GetProcessEventHandle"}, + {4, nullptr, "GetProcessEventInfo"}, + {5, nullptr, "NotifyBootFinished"}, + {6, &ShellService::GetApplicationProcessIdForShell, "GetApplicationProcessIdForShell"}, + {7, nullptr, "BoostSystemMemoryResourceLimit"}, + {8, nullptr, "BoostApplicationThreadResourceLimit"}, + {9, nullptr, "GetBootFinishedEventHandle"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +void ShellService::GetApplicationProcessIdForShell(HLERequestContext& ctx) { + LOG_DEBUG(Service_PM, "called"); + auto list = kernel.GetProcessList(); + GetApplicationPidGeneric(ctx, list); +} + +} // namespace Service::PM diff --git a/src/core/hle/service/pm/shell_service.h b/src/core/hle/service/pm/shell_service.h new file mode 100644 index 0000000000..81058abfd5 --- /dev/null +++ b/src/core/hle/service/pm/shell_service.h @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/service.h" + +namespace Service::PM { + +class ShellService final : public ServiceFramework { +public: + explicit ShellService(Core::System& system_); + +private: + void GetApplicationProcessIdForShell(HLERequestContext& ctx); +}; + +} // namespace Service::PM