service.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include <fmt/format.h>
  4. #include "common/assert.h"
  5. #include "common/logging/log.h"
  6. #include "common/settings.h"
  7. #include "core/core.h"
  8. #include "core/hle/ipc.h"
  9. #include "core/hle/kernel/k_process.h"
  10. #include "core/hle/kernel/k_server_port.h"
  11. #include "core/hle/kernel/kernel.h"
  12. #include "core/hle/service/acc/acc.h"
  13. #include "core/hle/service/am/am.h"
  14. #include "core/hle/service/aoc/aoc_u.h"
  15. #include "core/hle/service/apm/apm.h"
  16. #include "core/hle/service/audio/audio.h"
  17. #include "core/hle/service/bcat/bcat_module.h"
  18. #include "core/hle/service/bpc/bpc.h"
  19. #include "core/hle/service/btdrv/btdrv.h"
  20. #include "core/hle/service/btm/btm.h"
  21. #include "core/hle/service/caps/caps.h"
  22. #include "core/hle/service/erpt/erpt.h"
  23. #include "core/hle/service/es/es.h"
  24. #include "core/hle/service/eupld/eupld.h"
  25. #include "core/hle/service/fatal/fatal.h"
  26. #include "core/hle/service/fgm/fgm.h"
  27. #include "core/hle/service/filesystem/filesystem.h"
  28. #include "core/hle/service/friend/friend.h"
  29. #include "core/hle/service/glue/glue.h"
  30. #include "core/hle/service/grc/grc.h"
  31. #include "core/hle/service/hid/hid.h"
  32. #include "core/hle/service/ipc_helpers.h"
  33. #include "core/hle/service/jit/jit.h"
  34. #include "core/hle/service/lbl/lbl.h"
  35. #include "core/hle/service/ldn/ldn.h"
  36. #include "core/hle/service/ldr/ldr.h"
  37. #include "core/hle/service/lm/lm.h"
  38. #include "core/hle/service/mig/mig.h"
  39. #include "core/hle/service/mii/mii.h"
  40. #include "core/hle/service/mm/mm_u.h"
  41. #include "core/hle/service/mnpp/mnpp_app.h"
  42. #include "core/hle/service/ncm/ncm.h"
  43. #include "core/hle/service/nfc/nfc.h"
  44. #include "core/hle/service/nfp/nfp.h"
  45. #include "core/hle/service/ngc/ngc.h"
  46. #include "core/hle/service/nifm/nifm.h"
  47. #include "core/hle/service/nim/nim.h"
  48. #include "core/hle/service/npns/npns.h"
  49. #include "core/hle/service/ns/ns.h"
  50. #include "core/hle/service/nvdrv/nvdrv.h"
  51. #include "core/hle/service/nvnflinger/hos_binder_driver_server.h"
  52. #include "core/hle/service/nvnflinger/nvnflinger.h"
  53. #include "core/hle/service/olsc/olsc.h"
  54. #include "core/hle/service/pcie/pcie.h"
  55. #include "core/hle/service/pctl/pctl_module.h"
  56. #include "core/hle/service/pcv/pcv.h"
  57. #include "core/hle/service/pm/pm.h"
  58. #include "core/hle/service/prepo/prepo.h"
  59. #include "core/hle/service/psc/psc.h"
  60. #include "core/hle/service/ptm/ptm.h"
  61. #include "core/hle/service/ro/ro.h"
  62. #include "core/hle/service/service.h"
  63. #include "core/hle/service/set/settings.h"
  64. #include "core/hle/service/sm/sm.h"
  65. #include "core/hle/service/sockets/sockets.h"
  66. #include "core/hle/service/spl/spl_module.h"
  67. #include "core/hle/service/ssl/ssl.h"
  68. #include "core/hle/service/time/time.h"
  69. #include "core/hle/service/usb/usb.h"
  70. #include "core/hle/service/vi/vi.h"
  71. #include "core/reporter.h"
  72. namespace Service {
  73. /**
  74. * Creates a function string for logging, complete with the name (or header code, depending
  75. * on what's passed in) the port name, and all the cmd_buff arguments.
  76. */
  77. [[maybe_unused]] static std::string MakeFunctionString(std::string_view name,
  78. std::string_view port_name,
  79. const u32* cmd_buff) {
  80. // Number of params == bits 0-5 + bits 6-11
  81. int num_params = (cmd_buff[0] & 0x3F) + ((cmd_buff[0] >> 6) & 0x3F);
  82. std::string function_string = fmt::format("function '{}': port={}", name, port_name);
  83. for (int i = 1; i <= num_params; ++i) {
  84. function_string += fmt::format(", cmd_buff[{}]=0x{:X}", i, cmd_buff[i]);
  85. }
  86. return function_string;
  87. }
  88. ServiceFrameworkBase::ServiceFrameworkBase(Core::System& system_, const char* service_name_,
  89. u32 max_sessions_, InvokerFn* handler_invoker_)
  90. : SessionRequestHandler(system_.Kernel(), service_name_), system{system_},
  91. service_name{service_name_}, max_sessions{max_sessions_}, handler_invoker{handler_invoker_} {}
  92. ServiceFrameworkBase::~ServiceFrameworkBase() {
  93. // Wait for other threads to release access before destroying
  94. const auto guard = LockService();
  95. }
  96. void ServiceFrameworkBase::RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n) {
  97. handlers.reserve(handlers.size() + n);
  98. for (std::size_t i = 0; i < n; ++i) {
  99. // Usually this array is sorted by id already, so hint to insert at the end
  100. handlers.emplace_hint(handlers.cend(), functions[i].expected_header, functions[i]);
  101. }
  102. }
  103. void ServiceFrameworkBase::RegisterHandlersBaseTipc(const FunctionInfoBase* functions,
  104. std::size_t n) {
  105. handlers_tipc.reserve(handlers_tipc.size() + n);
  106. for (std::size_t i = 0; i < n; ++i) {
  107. // Usually this array is sorted by id already, so hint to insert at the end
  108. handlers_tipc.emplace_hint(handlers_tipc.cend(), functions[i].expected_header,
  109. functions[i]);
  110. }
  111. }
  112. void ServiceFrameworkBase::ReportUnimplementedFunction(HLERequestContext& ctx,
  113. const FunctionInfoBase* info) {
  114. auto cmd_buf = ctx.CommandBuffer();
  115. std::string function_name = info == nullptr ? fmt::format("{}", ctx.GetCommand()) : info->name;
  116. fmt::memory_buffer buf;
  117. fmt::format_to(std::back_inserter(buf), "function '{}': port='{}' cmd_buf={{[0]=0x{:X}",
  118. function_name, service_name, cmd_buf[0]);
  119. for (int i = 1; i <= 8; ++i) {
  120. fmt::format_to(std::back_inserter(buf), ", [{}]=0x{:X}", i, cmd_buf[i]);
  121. }
  122. buf.push_back('}');
  123. system.GetReporter().SaveUnimplementedFunctionReport(ctx, ctx.GetCommand(), function_name,
  124. service_name);
  125. UNIMPLEMENTED_MSG("Unknown / unimplemented {}", fmt::to_string(buf));
  126. if (Settings::values.use_auto_stub) {
  127. LOG_WARNING(Service, "Using auto stub fallback!");
  128. IPC::ResponseBuilder rb{ctx, 2};
  129. rb.Push(ResultSuccess);
  130. }
  131. }
  132. void ServiceFrameworkBase::InvokeRequest(HLERequestContext& ctx) {
  133. auto itr = handlers.find(ctx.GetCommand());
  134. const FunctionInfoBase* info = itr == handlers.end() ? nullptr : &itr->second;
  135. if (info == nullptr || info->handler_callback == nullptr) {
  136. return ReportUnimplementedFunction(ctx, info);
  137. }
  138. LOG_TRACE(Service, "{}", MakeFunctionString(info->name, GetServiceName(), ctx.CommandBuffer()));
  139. handler_invoker(this, info->handler_callback, ctx);
  140. }
  141. void ServiceFrameworkBase::InvokeRequestTipc(HLERequestContext& ctx) {
  142. boost::container::flat_map<u32, FunctionInfoBase>::iterator itr;
  143. itr = handlers_tipc.find(ctx.GetCommand());
  144. const FunctionInfoBase* info = itr == handlers_tipc.end() ? nullptr : &itr->second;
  145. if (info == nullptr || info->handler_callback == nullptr) {
  146. return ReportUnimplementedFunction(ctx, info);
  147. }
  148. LOG_TRACE(Service, "{}", MakeFunctionString(info->name, GetServiceName(), ctx.CommandBuffer()));
  149. handler_invoker(this, info->handler_callback, ctx);
  150. }
  151. Result ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& session,
  152. HLERequestContext& ctx) {
  153. const auto guard = LockService();
  154. Result result = ResultSuccess;
  155. switch (ctx.GetCommandType()) {
  156. case IPC::CommandType::Close:
  157. case IPC::CommandType::TIPC_Close: {
  158. IPC::ResponseBuilder rb{ctx, 2};
  159. rb.Push(ResultSuccess);
  160. result = IPC::ResultSessionClosed;
  161. break;
  162. }
  163. case IPC::CommandType::ControlWithContext:
  164. case IPC::CommandType::Control: {
  165. system.ServiceManager().InvokeControlRequest(ctx);
  166. break;
  167. }
  168. case IPC::CommandType::RequestWithContext:
  169. case IPC::CommandType::Request: {
  170. InvokeRequest(ctx);
  171. break;
  172. }
  173. default:
  174. if (ctx.IsTipc()) {
  175. InvokeRequestTipc(ctx);
  176. break;
  177. }
  178. UNIMPLEMENTED_MSG("command_type={}", ctx.GetCommandType());
  179. break;
  180. }
  181. // If emulation was shutdown, we are closing service threads, do not write the response back to
  182. // memory that may be shutting down as well.
  183. if (system.IsPoweredOn()) {
  184. ctx.WriteToOutgoingCommandBuffer();
  185. }
  186. return result;
  187. }
  188. /// Initialize Services
  189. Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system)
  190. : hos_binder_driver_server{std::make_unique<Nvnflinger::HosBinderDriverServer>(system)},
  191. nv_flinger{std::make_unique<Nvnflinger::Nvnflinger>(system, *hos_binder_driver_server)} {
  192. auto& kernel = system.Kernel();
  193. // Nvnflinger needs to be accessed by several services like Vi and AppletOE so we instantiate it
  194. // here and pass it into the respective InstallInterfaces functions.
  195. system.GetFileSystemController().CreateFactories(*system.GetFilesystem(), false);
  196. // clang-format off
  197. kernel.RunOnHostCoreProcess("audio", [&] { Audio::LoopProcess(system); }).detach();
  198. kernel.RunOnHostCoreProcess("FS", [&] { FileSystem::LoopProcess(system); }).detach();
  199. kernel.RunOnHostCoreProcess("jit", [&] { JIT::LoopProcess(system); }).detach();
  200. kernel.RunOnHostCoreProcess("ldn", [&] { LDN::LoopProcess(system); }).detach();
  201. kernel.RunOnHostCoreProcess("Loader", [&] { LDR::LoopProcess(system); }).detach();
  202. kernel.RunOnHostCoreProcess("nvservices", [&] { Nvidia::LoopProcess(*nv_flinger, system); }).detach();
  203. kernel.RunOnHostCoreProcess("bsdsocket", [&] { Sockets::LoopProcess(system); }).detach();
  204. kernel.RunOnHostCoreProcess("vi", [&] { VI::LoopProcess(system, *nv_flinger, *hos_binder_driver_server); }).detach();
  205. kernel.RunOnGuestCoreProcess("sm", [&] { SM::LoopProcess(system); });
  206. kernel.RunOnGuestCoreProcess("account", [&] { Account::LoopProcess(system); });
  207. kernel.RunOnGuestCoreProcess("am", [&] { AM::LoopProcess(*nv_flinger, system); });
  208. kernel.RunOnGuestCoreProcess("aoc", [&] { AOC::LoopProcess(system); });
  209. kernel.RunOnGuestCoreProcess("apm", [&] { APM::LoopProcess(system); });
  210. kernel.RunOnGuestCoreProcess("bcat", [&] { BCAT::LoopProcess(system); });
  211. kernel.RunOnGuestCoreProcess("bpc", [&] { BPC::LoopProcess(system); });
  212. kernel.RunOnGuestCoreProcess("btdrv", [&] { BtDrv::LoopProcess(system); });
  213. kernel.RunOnGuestCoreProcess("btm", [&] { BTM::LoopProcess(system); });
  214. kernel.RunOnGuestCoreProcess("capsrv", [&] { Capture::LoopProcess(system); });
  215. kernel.RunOnGuestCoreProcess("erpt", [&] { ERPT::LoopProcess(system); });
  216. kernel.RunOnGuestCoreProcess("es", [&] { ES::LoopProcess(system); });
  217. kernel.RunOnGuestCoreProcess("eupld", [&] { EUPLD::LoopProcess(system); });
  218. kernel.RunOnGuestCoreProcess("fatal", [&] { Fatal::LoopProcess(system); });
  219. kernel.RunOnGuestCoreProcess("fgm", [&] { FGM::LoopProcess(system); });
  220. kernel.RunOnGuestCoreProcess("friends", [&] { Friend::LoopProcess(system); });
  221. kernel.RunOnGuestCoreProcess("glue", [&] { Glue::LoopProcess(system); });
  222. kernel.RunOnGuestCoreProcess("grc", [&] { GRC::LoopProcess(system); });
  223. kernel.RunOnGuestCoreProcess("hid", [&] { HID::LoopProcess(system); });
  224. kernel.RunOnGuestCoreProcess("lbl", [&] { LBL::LoopProcess(system); });
  225. kernel.RunOnGuestCoreProcess("LogManager.Prod", [&] { LM::LoopProcess(system); });
  226. kernel.RunOnGuestCoreProcess("mig", [&] { Migration::LoopProcess(system); });
  227. kernel.RunOnGuestCoreProcess("mii", [&] { Mii::LoopProcess(system); });
  228. kernel.RunOnGuestCoreProcess("mm", [&] { MM::LoopProcess(system); });
  229. kernel.RunOnGuestCoreProcess("mnpp", [&] { MNPP::LoopProcess(system); });
  230. kernel.RunOnGuestCoreProcess("NCM", [&] { NCM::LoopProcess(system); });
  231. kernel.RunOnGuestCoreProcess("nfc", [&] { NFC::LoopProcess(system); });
  232. kernel.RunOnGuestCoreProcess("nfp", [&] { NFP::LoopProcess(system); });
  233. kernel.RunOnGuestCoreProcess("ngc", [&] { NGC::LoopProcess(system); });
  234. kernel.RunOnGuestCoreProcess("nifm", [&] { NIFM::LoopProcess(system); });
  235. kernel.RunOnGuestCoreProcess("nim", [&] { NIM::LoopProcess(system); });
  236. kernel.RunOnGuestCoreProcess("npns", [&] { NPNS::LoopProcess(system); });
  237. kernel.RunOnGuestCoreProcess("ns", [&] { NS::LoopProcess(system); });
  238. kernel.RunOnGuestCoreProcess("olsc", [&] { OLSC::LoopProcess(system); });
  239. kernel.RunOnGuestCoreProcess("pcie", [&] { PCIe::LoopProcess(system); });
  240. kernel.RunOnGuestCoreProcess("pctl", [&] { PCTL::LoopProcess(system); });
  241. kernel.RunOnGuestCoreProcess("pcv", [&] { PCV::LoopProcess(system); });
  242. kernel.RunOnGuestCoreProcess("prepo", [&] { PlayReport::LoopProcess(system); });
  243. kernel.RunOnGuestCoreProcess("ProcessManager", [&] { PM::LoopProcess(system); });
  244. kernel.RunOnGuestCoreProcess("psc", [&] { PSC::LoopProcess(system); });
  245. kernel.RunOnGuestCoreProcess("ptm", [&] { PTM::LoopProcess(system); });
  246. kernel.RunOnGuestCoreProcess("ro", [&] { RO::LoopProcess(system); });
  247. kernel.RunOnGuestCoreProcess("settings", [&] { Set::LoopProcess(system); });
  248. kernel.RunOnGuestCoreProcess("spl", [&] { SPL::LoopProcess(system); });
  249. kernel.RunOnGuestCoreProcess("ssl", [&] { SSL::LoopProcess(system); });
  250. kernel.RunOnGuestCoreProcess("time", [&] { Time::LoopProcess(system); });
  251. kernel.RunOnGuestCoreProcess("usb", [&] { USB::LoopProcess(system); });
  252. // clang-format on
  253. }
  254. Services::~Services() = default;
  255. void Services::KillNVNFlinger() {
  256. nv_flinger->ShutdownLayers();
  257. }
  258. } // namespace Service