k_session_request.h 9.4 KB

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