ipc.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. // SPDX-FileCopyrightText: 2016 Citra Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include "common/bit_field.h"
  5. #include "common/common_funcs.h"
  6. #include "common/common_types.h"
  7. #include "common/swap.h"
  8. namespace IPC {
  9. /// Size of the command buffer area, in 32-bit words.
  10. constexpr std::size_t COMMAND_BUFFER_LENGTH = 0x100 / sizeof(u32);
  11. enum class ControlCommand : u32 {
  12. ConvertSessionToDomain = 0,
  13. ConvertDomainToSession = 1,
  14. DuplicateSession = 2,
  15. QueryPointerBufferSize = 3,
  16. DuplicateSessionEx = 4,
  17. Unspecified,
  18. };
  19. enum class CommandType : u32 {
  20. Invalid = 0,
  21. LegacyRequest = 1,
  22. Close = 2,
  23. LegacyControl = 3,
  24. Request = 4,
  25. Control = 5,
  26. RequestWithContext = 6,
  27. ControlWithContext = 7,
  28. TIPC_Close = 15,
  29. TIPC_CommandRegion = 16, // Start of TIPC commands, this is an offset.
  30. };
  31. struct CommandHeader {
  32. union {
  33. u32_le raw_low;
  34. BitField<0, 16, CommandType> type;
  35. BitField<16, 4, u32> num_buf_x_descriptors;
  36. BitField<20, 4, u32> num_buf_a_descriptors;
  37. BitField<24, 4, u32> num_buf_b_descriptors;
  38. BitField<28, 4, u32> num_buf_w_descriptors;
  39. };
  40. enum class BufferDescriptorCFlag : u32 {
  41. Disabled = 0,
  42. InlineDescriptor = 1,
  43. OneDescriptor = 2,
  44. };
  45. union {
  46. u32_le raw_high;
  47. BitField<0, 10, u32> data_size;
  48. BitField<10, 4, BufferDescriptorCFlag> buf_c_descriptor_flags;
  49. BitField<31, 1, u32> enable_handle_descriptor;
  50. };
  51. bool IsTipc() const {
  52. return type.Value() >= CommandType::TIPC_CommandRegion;
  53. }
  54. bool IsCloseCommand() const {
  55. switch (type.Value()) {
  56. case CommandType::Close:
  57. case CommandType::TIPC_Close:
  58. return true;
  59. default:
  60. return false;
  61. }
  62. }
  63. };
  64. static_assert(sizeof(CommandHeader) == 8, "CommandHeader size is incorrect");
  65. union HandleDescriptorHeader {
  66. u32_le raw_high;
  67. BitField<0, 1, u32> send_current_pid;
  68. BitField<1, 4, u32> num_handles_to_copy;
  69. BitField<5, 4, u32> num_handles_to_move;
  70. };
  71. static_assert(sizeof(HandleDescriptorHeader) == 4, "HandleDescriptorHeader size is incorrect");
  72. struct BufferDescriptorX {
  73. union {
  74. BitField<0, 6, u32> counter_bits_0_5;
  75. BitField<6, 3, u32> address_bits_36_38;
  76. BitField<9, 3, u32> counter_bits_9_11;
  77. BitField<12, 4, u32> address_bits_32_35;
  78. BitField<16, 16, u32> size;
  79. };
  80. u32_le address_bits_0_31;
  81. u32_le Counter() const {
  82. u32_le counter{counter_bits_0_5};
  83. counter |= counter_bits_9_11 << 9;
  84. return counter;
  85. }
  86. VAddr Address() const {
  87. VAddr address{address_bits_0_31};
  88. address |= static_cast<VAddr>(address_bits_32_35) << 32;
  89. address |= static_cast<VAddr>(address_bits_36_38) << 36;
  90. return address;
  91. }
  92. u64 Size() const {
  93. return static_cast<u64>(size);
  94. }
  95. };
  96. static_assert(sizeof(BufferDescriptorX) == 8, "BufferDescriptorX size is incorrect");
  97. struct BufferDescriptorABW {
  98. u32_le size_bits_0_31;
  99. u32_le address_bits_0_31;
  100. union {
  101. BitField<0, 2, u32> flags;
  102. BitField<2, 3, u32> address_bits_36_38;
  103. BitField<24, 4, u32> size_bits_32_35;
  104. BitField<28, 4, u32> address_bits_32_35;
  105. };
  106. VAddr Address() const {
  107. VAddr address{address_bits_0_31};
  108. address |= static_cast<VAddr>(address_bits_32_35) << 32;
  109. address |= static_cast<VAddr>(address_bits_36_38) << 36;
  110. return address;
  111. }
  112. u64 Size() const {
  113. u64 size{size_bits_0_31};
  114. size |= static_cast<u64>(size_bits_32_35) << 32;
  115. return size;
  116. }
  117. };
  118. static_assert(sizeof(BufferDescriptorABW) == 12, "BufferDescriptorABW size is incorrect");
  119. struct BufferDescriptorC {
  120. u32_le address_bits_0_31;
  121. union {
  122. BitField<0, 16, u32> address_bits_32_47;
  123. BitField<16, 16, u32> size;
  124. };
  125. VAddr Address() const {
  126. VAddr address{address_bits_0_31};
  127. address |= static_cast<VAddr>(address_bits_32_47) << 32;
  128. return address;
  129. }
  130. u64 Size() const {
  131. return static_cast<u64>(size);
  132. }
  133. };
  134. static_assert(sizeof(BufferDescriptorC) == 8, "BufferDescriptorC size is incorrect");
  135. struct DataPayloadHeader {
  136. u32_le magic;
  137. INSERT_PADDING_WORDS_NOINIT(1);
  138. };
  139. static_assert(sizeof(DataPayloadHeader) == 8, "DataPayloadHeader size is incorrect");
  140. struct DomainMessageHeader {
  141. enum class CommandType : u32_le {
  142. SendMessage = 1,
  143. CloseVirtualHandle = 2,
  144. };
  145. union {
  146. // Used when responding to an IPC request, Server -> Client.
  147. struct {
  148. u32_le num_objects;
  149. INSERT_PADDING_WORDS_NOINIT(3);
  150. };
  151. // Used when performing an IPC request, Client -> Server.
  152. struct {
  153. union {
  154. BitField<0, 8, CommandType> command;
  155. BitField<8, 8, u32> input_object_count;
  156. BitField<16, 16, u32> size;
  157. };
  158. u32_le object_id;
  159. INSERT_PADDING_WORDS_NOINIT(2);
  160. };
  161. std::array<u32, 4> raw;
  162. };
  163. };
  164. static_assert(sizeof(DomainMessageHeader) == 16, "DomainMessageHeader size is incorrect");
  165. } // namespace IPC