ipc.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // Copyright 2016 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include "common/common_types.h"
  6. #include "common/swap.h"
  7. #include "core/hle/kernel/errors.h"
  8. #include "core/memory.h"
  9. namespace IPC {
  10. /// Size of the command buffer area, in 32-bit words.
  11. constexpr size_t COMMAND_BUFFER_LENGTH = 0x100 / sizeof(u32);
  12. // These errors are commonly returned by invalid IPC translations, so alias them here for
  13. // convenience.
  14. // TODO(yuriks): These will probably go away once translation is implemented inside the kernel.
  15. constexpr auto ERR_INVALID_HANDLE = Kernel::ERR_INVALID_HANDLE_OS;
  16. enum class ControlCommand : u32 {
  17. ConvertSessionToDomain = 0,
  18. ConvertDomainToSession = 1,
  19. DuplicateSession = 2,
  20. QueryPointerBufferSize = 3,
  21. DuplicateSessionEx = 4,
  22. Unspecified,
  23. };
  24. enum class CommandType : u32 {
  25. Invalid = 0,
  26. LegacyRequest = 1,
  27. Close = 2,
  28. LegacyControl = 3,
  29. Request = 4,
  30. Control = 5,
  31. RequestWithContext = 6,
  32. ControlWithContext = 7,
  33. Unspecified,
  34. };
  35. struct CommandHeader {
  36. union {
  37. u32_le raw_low;
  38. BitField<0, 16, CommandType> type;
  39. BitField<16, 4, u32_le> num_buf_x_descriptors;
  40. BitField<20, 4, u32_le> num_buf_a_descriptors;
  41. BitField<24, 4, u32_le> num_buf_b_descriptors;
  42. BitField<28, 4, u32_le> num_buf_w_descriptors;
  43. };
  44. enum class BufferDescriptorCFlag : u32 {
  45. Disabled = 0,
  46. InlineDescriptor = 1,
  47. OneDescriptor = 2,
  48. };
  49. union {
  50. u32_le raw_high;
  51. BitField<0, 10, u32_le> data_size;
  52. BitField<10, 4, BufferDescriptorCFlag> buf_c_descriptor_flags;
  53. BitField<31, 1, u32_le> enable_handle_descriptor;
  54. };
  55. };
  56. static_assert(sizeof(CommandHeader) == 8, "CommandHeader size is incorrect");
  57. union HandleDescriptorHeader {
  58. u32_le raw_high;
  59. BitField<0, 1, u32_le> send_current_pid;
  60. BitField<1, 4, u32_le> num_handles_to_copy;
  61. BitField<5, 4, u32_le> num_handles_to_move;
  62. };
  63. static_assert(sizeof(HandleDescriptorHeader) == 4, "HandleDescriptorHeader size is incorrect");
  64. struct BufferDescriptorX {
  65. union {
  66. BitField<0, 6, u32_le> counter_bits_0_5;
  67. BitField<6, 3, u32_le> address_bits_36_38;
  68. BitField<9, 3, u32_le> counter_bits_9_11;
  69. BitField<12, 4, u32_le> address_bits_32_35;
  70. BitField<16, 16, u32_le> size;
  71. };
  72. u32_le address_bits_0_31;
  73. u32_le Counter() const {
  74. u32_le counter{counter_bits_0_5};
  75. counter |= counter_bits_9_11 << 9;
  76. return counter;
  77. }
  78. VAddr Address() const {
  79. VAddr address{address_bits_0_31};
  80. address |= static_cast<VAddr>(address_bits_32_35) << 32;
  81. address |= static_cast<VAddr>(address_bits_36_38) << 36;
  82. return address;
  83. }
  84. u64 Size() const {
  85. return static_cast<u64>(size);
  86. }
  87. };
  88. static_assert(sizeof(BufferDescriptorX) == 8, "BufferDescriptorX size is incorrect");
  89. struct BufferDescriptorABW {
  90. u32_le size_bits_0_31;
  91. u32_le address_bits_0_31;
  92. union {
  93. BitField<0, 2, u32_le> flags;
  94. BitField<2, 3, u32_le> address_bits_36_38;
  95. BitField<24, 4, u32_le> size_bits_32_35;
  96. BitField<28, 4, u32_le> address_bits_32_35;
  97. };
  98. VAddr Address() const {
  99. VAddr address{address_bits_0_31};
  100. address |= static_cast<VAddr>(address_bits_32_35) << 32;
  101. address |= static_cast<VAddr>(address_bits_36_38) << 36;
  102. return address;
  103. }
  104. u64 Size() const {
  105. u64 size{size_bits_0_31};
  106. size |= static_cast<u64>(size_bits_32_35) << 32;
  107. return size;
  108. }
  109. };
  110. static_assert(sizeof(BufferDescriptorABW) == 12, "BufferDescriptorABW size is incorrect");
  111. struct BufferDescriptorC {
  112. u32_le address_bits_0_31;
  113. union {
  114. BitField<0, 16, u32_le> address_bits_32_47;
  115. BitField<16, 16, u32_le> size;
  116. };
  117. VAddr Address() const {
  118. VAddr address{address_bits_0_31};
  119. address |= static_cast<VAddr>(address_bits_32_47) << 32;
  120. return address;
  121. }
  122. u64 Size() const {
  123. return static_cast<u64>(size);
  124. }
  125. };
  126. static_assert(sizeof(BufferDescriptorC) == 8, "BufferDescriptorC size is incorrect");
  127. struct DataPayloadHeader {
  128. u32_le magic;
  129. INSERT_PADDING_WORDS(1);
  130. };
  131. static_assert(sizeof(DataPayloadHeader) == 8, "DataPayloadRequest size is incorrect");
  132. struct DomainMessageHeader {
  133. enum class CommandType : u32_le {
  134. SendMessage = 1,
  135. CloseVirtualHandle = 2,
  136. };
  137. union {
  138. // Used when responding to an IPC request, Server -> Client.
  139. struct {
  140. u32_le num_objects;
  141. INSERT_PADDING_WORDS(3);
  142. };
  143. // Used when performing an IPC request, Client -> Server.
  144. struct {
  145. union {
  146. BitField<0, 8, CommandType> command;
  147. BitField<8, 8, u32_le> input_object_count;
  148. BitField<16, 16, u32_le> size;
  149. };
  150. u32_le object_id;
  151. INSERT_PADDING_WORDS(2);
  152. };
  153. };
  154. };
  155. static_assert(sizeof(DomainMessageHeader) == 16, "DomainMessageHeader size is incorrect");
  156. } // namespace IPC