pm.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. // Copyright 2018 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include "core/hle/ipc_helpers.h"
  5. #include "core/hle/kernel/kernel.h"
  6. #include "core/hle/kernel/process.h"
  7. #include "core/hle/service/pm/pm.h"
  8. #include "core/hle/service/service.h"
  9. namespace Service::PM {
  10. namespace {
  11. constexpr ResultCode ERROR_PROCESS_NOT_FOUND{ErrorModule::PM, 1};
  12. constexpr u64 NO_PROCESS_FOUND_PID{0};
  13. std::optional<Kernel::SharedPtr<Kernel::Process>> SearchProcessList(
  14. const std::vector<Kernel::SharedPtr<Kernel::Process>>& process_list,
  15. std::function<bool(const Kernel::SharedPtr<Kernel::Process>&)> predicate) {
  16. const auto iter = std::find_if(process_list.begin(), process_list.end(), predicate);
  17. if (iter == process_list.end()) {
  18. return std::nullopt;
  19. }
  20. return *iter;
  21. }
  22. void GetApplicationPidGeneric(Kernel::HLERequestContext& ctx,
  23. const std::vector<Kernel::SharedPtr<Kernel::Process>>& process_list) {
  24. const auto process = SearchProcessList(process_list, [](const auto& process) {
  25. return process->GetProcessID() == Kernel::Process::ProcessIDMin;
  26. });
  27. IPC::ResponseBuilder rb{ctx, 4};
  28. rb.Push(RESULT_SUCCESS);
  29. rb.Push(process.has_value() ? (*process)->GetProcessID() : NO_PROCESS_FOUND_PID);
  30. }
  31. } // Anonymous namespace
  32. class BootMode final : public ServiceFramework<BootMode> {
  33. public:
  34. explicit BootMode() : ServiceFramework{"pm:bm"} {
  35. static const FunctionInfo functions[] = {
  36. {0, &BootMode::GetBootMode, "GetBootMode"},
  37. {1, &BootMode::SetMaintenanceBoot, "SetMaintenanceBoot"},
  38. };
  39. RegisterHandlers(functions);
  40. }
  41. private:
  42. void GetBootMode(Kernel::HLERequestContext& ctx) {
  43. LOG_DEBUG(Service_PM, "called");
  44. IPC::ResponseBuilder rb{ctx, 3};
  45. rb.Push(RESULT_SUCCESS);
  46. rb.PushEnum(boot_mode);
  47. }
  48. void SetMaintenanceBoot(Kernel::HLERequestContext& ctx) {
  49. LOG_DEBUG(Service_PM, "called");
  50. boot_mode = SystemBootMode::Maintenance;
  51. IPC::ResponseBuilder rb{ctx, 2};
  52. rb.Push(RESULT_SUCCESS);
  53. }
  54. SystemBootMode boot_mode = SystemBootMode::Normal;
  55. };
  56. class DebugMonitor final : public ServiceFramework<DebugMonitor> {
  57. public:
  58. explicit DebugMonitor(const Kernel::KernelCore& kernel)
  59. : ServiceFramework{"pm:dmnt"}, kernel(kernel) {
  60. // clang-format off
  61. static const FunctionInfo functions[] = {
  62. {0, nullptr, "GetDebugProcesses"},
  63. {1, nullptr, "StartDebugProcess"},
  64. {2, &DebugMonitor::GetTitlePid, "GetTitlePid"},
  65. {3, nullptr, "EnableDebugForTitleId"},
  66. {4, &DebugMonitor::GetApplicationPid, "GetApplicationPid"},
  67. {5, nullptr, "EnableDebugForApplication"},
  68. {6, nullptr, "DisableDebug"},
  69. };
  70. // clang-format on
  71. RegisterHandlers(functions);
  72. }
  73. private:
  74. void GetTitlePid(Kernel::HLERequestContext& ctx) {
  75. IPC::RequestParser rp{ctx};
  76. const auto title_id = rp.PopRaw<u64>();
  77. LOG_DEBUG(Service_PM, "called, title_id={:016X}", title_id);
  78. const auto process =
  79. SearchProcessList(kernel.GetProcessList(), [title_id](const auto& process) {
  80. return process->GetTitleID() == title_id;
  81. });
  82. if (!process.has_value()) {
  83. IPC::ResponseBuilder rb{ctx, 2};
  84. rb.Push(ERROR_PROCESS_NOT_FOUND);
  85. return;
  86. }
  87. IPC::ResponseBuilder rb{ctx, 4};
  88. rb.Push(RESULT_SUCCESS);
  89. rb.Push((*process)->GetProcessID());
  90. }
  91. void GetApplicationPid(Kernel::HLERequestContext& ctx) {
  92. LOG_DEBUG(Service_PM, "called");
  93. GetApplicationPidGeneric(ctx, kernel.GetProcessList());
  94. }
  95. const Kernel::KernelCore& kernel;
  96. };
  97. class Info final : public ServiceFramework<Info> {
  98. public:
  99. explicit Info(const std::vector<Kernel::SharedPtr<Kernel::Process>>& process_list)
  100. : ServiceFramework{"pm:info"}, process_list(process_list) {
  101. static const FunctionInfo functions[] = {
  102. {0, &Info::GetTitleId, "GetTitleId"},
  103. };
  104. RegisterHandlers(functions);
  105. }
  106. private:
  107. void GetTitleId(Kernel::HLERequestContext& ctx) {
  108. IPC::RequestParser rp{ctx};
  109. const auto process_id = rp.PopRaw<u64>();
  110. LOG_DEBUG(Service_PM, "called, process_id={:016X}", process_id);
  111. const auto process = SearchProcessList(process_list, [process_id](const auto& process) {
  112. return process->GetProcessID() == process_id;
  113. });
  114. if (!process.has_value()) {
  115. IPC::ResponseBuilder rb{ctx, 2};
  116. rb.Push(ERROR_PROCESS_NOT_FOUND);
  117. return;
  118. }
  119. IPC::ResponseBuilder rb{ctx, 4};
  120. rb.Push(RESULT_SUCCESS);
  121. rb.Push((*process)->GetTitleID());
  122. }
  123. const std::vector<Kernel::SharedPtr<Kernel::Process>>& process_list;
  124. };
  125. class Shell final : public ServiceFramework<Shell> {
  126. public:
  127. explicit Shell(const Kernel::KernelCore& kernel)
  128. : ServiceFramework{"pm:shell"}, kernel(kernel) {
  129. // clang-format off
  130. static const FunctionInfo functions[] = {
  131. {0, nullptr, "LaunchProcess"},
  132. {1, nullptr, "TerminateProcessByPid"},
  133. {2, nullptr, "TerminateProcessByTitleId"},
  134. {3, nullptr, "GetProcessEventWaiter"},
  135. {4, nullptr, "GetProcessEventType"},
  136. {5, nullptr, "NotifyBootFinished"},
  137. {6, &Shell::GetApplicationPid, "GetApplicationPid"},
  138. {7, nullptr, "BoostSystemMemoryResourceLimit"},
  139. {8, nullptr, "EnableAdditionalSystemThreads"},
  140. {9, nullptr, "GetBootFinishedEventHandle"},
  141. };
  142. // clang-format on
  143. RegisterHandlers(functions);
  144. }
  145. private:
  146. void GetApplicationPid(Kernel::HLERequestContext& ctx) {
  147. LOG_DEBUG(Service_PM, "called");
  148. GetApplicationPidGeneric(ctx, kernel.GetProcessList());
  149. }
  150. const Kernel::KernelCore& kernel;
  151. };
  152. void InstallInterfaces(Core::System& system) {
  153. std::make_shared<BootMode>()->InstallAsService(system.ServiceManager());
  154. std::make_shared<DebugMonitor>(system.Kernel())->InstallAsService(system.ServiceManager());
  155. std::make_shared<Info>(system.Kernel().GetProcessList())
  156. ->InstallAsService(system.ServiceManager());
  157. std::make_shared<Shell>(system.Kernel())->InstallAsService(system.ServiceManager());
  158. }
  159. } // namespace Service::PM