k_session_request.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <array>
  5. #include "core/hle/kernel/k_auto_object.h"
  6. #include "core/hle/kernel/k_event.h"
  7. #include "core/hle/kernel/k_memory_block.h"
  8. #include "core/hle/kernel/k_process.h"
  9. #include "core/hle/kernel/k_thread.h"
  10. #include "core/hle/kernel/slab_helpers.h"
  11. namespace Kernel {
  12. class KSessionRequest final : public KSlabAllocated<KSessionRequest>,
  13. public KAutoObject,
  14. public boost::intrusive::list_base_hook<> {
  15. KERNEL_AUTOOBJECT_TRAITS(KSessionRequest, KAutoObject);
  16. public:
  17. class SessionMappings {
  18. private:
  19. static constexpr size_t NumStaticMappings = 8;
  20. class Mapping {
  21. public:
  22. constexpr void Set(VAddr c, VAddr s, size_t sz, KMemoryState st) {
  23. m_client_address = c;
  24. m_server_address = s;
  25. m_size = sz;
  26. m_state = st;
  27. }
  28. constexpr VAddr GetClientAddress() const {
  29. return m_client_address;
  30. }
  31. constexpr VAddr GetServerAddress() const {
  32. return m_server_address;
  33. }
  34. constexpr size_t GetSize() const {
  35. return m_size;
  36. }
  37. constexpr KMemoryState GetMemoryState() const {
  38. return m_state;
  39. }
  40. private:
  41. VAddr m_client_address;
  42. VAddr m_server_address;
  43. size_t m_size;
  44. KMemoryState m_state;
  45. };
  46. public:
  47. explicit SessionMappings(KernelCore& kernel_) : kernel(kernel_) {}
  48. void Initialize() {}
  49. void Finalize();
  50. size_t GetSendCount() const {
  51. return m_num_send;
  52. }
  53. size_t GetReceiveCount() const {
  54. return m_num_recv;
  55. }
  56. size_t GetExchangeCount() const {
  57. return m_num_exch;
  58. }
  59. Result PushSend(VAddr client, VAddr server, size_t size, KMemoryState state);
  60. Result PushReceive(VAddr client, VAddr server, size_t size, KMemoryState state);
  61. Result PushExchange(VAddr client, VAddr server, size_t size, KMemoryState state);
  62. VAddr GetSendClientAddress(size_t i) const {
  63. return GetSendMapping(i).GetClientAddress();
  64. }
  65. VAddr GetSendServerAddress(size_t i) const {
  66. return GetSendMapping(i).GetServerAddress();
  67. }
  68. size_t GetSendSize(size_t i) const {
  69. return GetSendMapping(i).GetSize();
  70. }
  71. KMemoryState GetSendMemoryState(size_t i) const {
  72. return GetSendMapping(i).GetMemoryState();
  73. }
  74. VAddr GetReceiveClientAddress(size_t i) const {
  75. return GetReceiveMapping(i).GetClientAddress();
  76. }
  77. VAddr GetReceiveServerAddress(size_t i) const {
  78. return GetReceiveMapping(i).GetServerAddress();
  79. }
  80. size_t GetReceiveSize(size_t i) const {
  81. return GetReceiveMapping(i).GetSize();
  82. }
  83. KMemoryState GetReceiveMemoryState(size_t i) const {
  84. return GetReceiveMapping(i).GetMemoryState();
  85. }
  86. VAddr GetExchangeClientAddress(size_t i) const {
  87. return GetExchangeMapping(i).GetClientAddress();
  88. }
  89. VAddr GetExchangeServerAddress(size_t i) const {
  90. return GetExchangeMapping(i).GetServerAddress();
  91. }
  92. size_t GetExchangeSize(size_t i) const {
  93. return GetExchangeMapping(i).GetSize();
  94. }
  95. KMemoryState GetExchangeMemoryState(size_t i) const {
  96. return GetExchangeMapping(i).GetMemoryState();
  97. }
  98. private:
  99. Result PushMap(VAddr client, VAddr server, size_t size, KMemoryState state, size_t index);
  100. const Mapping& GetSendMapping(size_t i) const {
  101. ASSERT(i < m_num_send);
  102. const size_t index = i;
  103. if (index < NumStaticMappings) {
  104. return m_static_mappings[index];
  105. } else {
  106. return m_mappings[index - NumStaticMappings];
  107. }
  108. }
  109. const Mapping& GetReceiveMapping(size_t i) const {
  110. ASSERT(i < m_num_recv);
  111. const size_t index = m_num_send + i;
  112. if (index < NumStaticMappings) {
  113. return m_static_mappings[index];
  114. } else {
  115. return m_mappings[index - NumStaticMappings];
  116. }
  117. }
  118. const Mapping& GetExchangeMapping(size_t i) const {
  119. ASSERT(i < m_num_exch);
  120. const size_t index = m_num_send + m_num_recv + i;
  121. if (index < NumStaticMappings) {
  122. return m_static_mappings[index];
  123. } else {
  124. return m_mappings[index - NumStaticMappings];
  125. }
  126. }
  127. private:
  128. KernelCore& kernel;
  129. std::array<Mapping, NumStaticMappings> m_static_mappings;
  130. Mapping* m_mappings{};
  131. u8 m_num_send{};
  132. u8 m_num_recv{};
  133. u8 m_num_exch{};
  134. };
  135. public:
  136. explicit KSessionRequest(KernelCore& kernel_) : KAutoObject(kernel_), m_mappings(kernel_) {}
  137. static KSessionRequest* Create(KernelCore& kernel) {
  138. KSessionRequest* req = KSessionRequest::Allocate(kernel);
  139. if (req != nullptr) [[likely]] {
  140. KAutoObject::Create(req);
  141. }
  142. return req;
  143. }
  144. void Destroy() override {
  145. this->Finalize();
  146. KSessionRequest::Free(kernel, this);
  147. }
  148. void Initialize(KEvent* event, uintptr_t address, size_t size) {
  149. m_mappings.Initialize();
  150. m_thread = GetCurrentThreadPointer(kernel);
  151. m_event = event;
  152. m_address = address;
  153. m_size = size;
  154. m_thread->Open();
  155. if (m_event != nullptr) {
  156. m_event->Open();
  157. }
  158. }
  159. static void PostDestroy(uintptr_t arg) {}
  160. KThread* GetThread() const {
  161. return m_thread;
  162. }
  163. KEvent* GetEvent() const {
  164. return m_event;
  165. }
  166. uintptr_t GetAddress() const {
  167. return m_address;
  168. }
  169. size_t GetSize() const {
  170. return m_size;
  171. }
  172. KProcess* GetServerProcess() const {
  173. return m_server;
  174. }
  175. void SetServerProcess(KProcess* process) {
  176. m_server = process;
  177. m_server->Open();
  178. }
  179. void ClearThread() {
  180. m_thread = nullptr;
  181. }
  182. void ClearEvent() {
  183. m_event = nullptr;
  184. }
  185. size_t GetSendCount() const {
  186. return m_mappings.GetSendCount();
  187. }
  188. size_t GetReceiveCount() const {
  189. return m_mappings.GetReceiveCount();
  190. }
  191. size_t GetExchangeCount() const {
  192. return m_mappings.GetExchangeCount();
  193. }
  194. Result PushSend(VAddr client, VAddr server, size_t size, KMemoryState state) {
  195. return m_mappings.PushSend(client, server, size, state);
  196. }
  197. Result PushReceive(VAddr client, VAddr server, size_t size, KMemoryState state) {
  198. return m_mappings.PushReceive(client, server, size, state);
  199. }
  200. Result PushExchange(VAddr client, VAddr server, size_t size, KMemoryState state) {
  201. return m_mappings.PushExchange(client, server, size, state);
  202. }
  203. VAddr GetSendClientAddress(size_t i) const {
  204. return m_mappings.GetSendClientAddress(i);
  205. }
  206. VAddr GetSendServerAddress(size_t i) const {
  207. return m_mappings.GetSendServerAddress(i);
  208. }
  209. size_t GetSendSize(size_t i) const {
  210. return m_mappings.GetSendSize(i);
  211. }
  212. KMemoryState GetSendMemoryState(size_t i) const {
  213. return m_mappings.GetSendMemoryState(i);
  214. }
  215. VAddr GetReceiveClientAddress(size_t i) const {
  216. return m_mappings.GetReceiveClientAddress(i);
  217. }
  218. VAddr GetReceiveServerAddress(size_t i) const {
  219. return m_mappings.GetReceiveServerAddress(i);
  220. }
  221. size_t GetReceiveSize(size_t i) const {
  222. return m_mappings.GetReceiveSize(i);
  223. }
  224. KMemoryState GetReceiveMemoryState(size_t i) const {
  225. return m_mappings.GetReceiveMemoryState(i);
  226. }
  227. VAddr GetExchangeClientAddress(size_t i) const {
  228. return m_mappings.GetExchangeClientAddress(i);
  229. }
  230. VAddr GetExchangeServerAddress(size_t i) const {
  231. return m_mappings.GetExchangeServerAddress(i);
  232. }
  233. size_t GetExchangeSize(size_t i) const {
  234. return m_mappings.GetExchangeSize(i);
  235. }
  236. KMemoryState GetExchangeMemoryState(size_t i) const {
  237. return m_mappings.GetExchangeMemoryState(i);
  238. }
  239. private:
  240. // NOTE: This is public and virtual in Nintendo's kernel.
  241. void Finalize() override {
  242. m_mappings.Finalize();
  243. if (m_thread) {
  244. m_thread->Close();
  245. }
  246. if (m_event) {
  247. m_event->Close();
  248. }
  249. if (m_server) {
  250. m_server->Close();
  251. }
  252. }
  253. private:
  254. SessionMappings m_mappings;
  255. KThread* m_thread{};
  256. KProcess* m_server{};
  257. KEvent* m_event{};
  258. uintptr_t m_address{};
  259. size_t m_size{};
  260. };
  261. } // namespace Kernel