Syscall32.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. using Ryujinx.HLE.HOS.Kernel.Common;
  2. using Ryujinx.HLE.HOS.Kernel.Memory;
  3. using Ryujinx.HLE.HOS.Kernel.Threading;
  4. namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
  5. {
  6. class Syscall32
  7. {
  8. private readonly Syscall _syscall;
  9. public Syscall32(Syscall syscall)
  10. {
  11. _syscall = syscall;
  12. }
  13. // IPC
  14. public KernelResult ConnectToNamedPort32([R(1)] uint namePtr, [R(1)] out int handle)
  15. {
  16. return _syscall.ConnectToNamedPort(namePtr, out handle);
  17. }
  18. public KernelResult SendSyncRequest32([R(0)] int handle)
  19. {
  20. return _syscall.SendSyncRequest(handle);
  21. }
  22. public KernelResult SendSyncRequestWithUserBuffer32([R(0)] uint messagePtr, [R(1)] uint messageSize, [R(2)] int handle)
  23. {
  24. return _syscall.SendSyncRequestWithUserBuffer(messagePtr, messageSize, handle);
  25. }
  26. public KernelResult CreateSession32(
  27. [R(2)] bool isLight,
  28. [R(3)] uint namePtr,
  29. [R(1)] out int serverSessionHandle,
  30. [R(2)] out int clientSessionHandle)
  31. {
  32. return _syscall.CreateSession(isLight, namePtr, out serverSessionHandle, out clientSessionHandle);
  33. }
  34. public KernelResult AcceptSession32([R(1)] int portHandle, [R(1)] out int sessionHandle)
  35. {
  36. return _syscall.AcceptSession(portHandle, out sessionHandle);
  37. }
  38. public KernelResult ReplyAndReceive32(
  39. [R(0)] uint timeoutLow,
  40. [R(1)] ulong handlesPtr,
  41. [R(2)] int handlesCount,
  42. [R(3)] int replyTargetHandle,
  43. [R(4)] uint timeoutHigh,
  44. [R(1)] out int handleIndex)
  45. {
  46. long timeout = (long)(timeoutLow | ((ulong)timeoutHigh << 32));
  47. return _syscall.ReplyAndReceive(handlesPtr, handlesCount, replyTargetHandle, timeout, out handleIndex);
  48. }
  49. public KernelResult CreatePort32(
  50. [R(0)] uint namePtr,
  51. [R(2)] int maxSessions,
  52. [R(3)] bool isLight,
  53. [R(1)] out int serverPortHandle,
  54. [R(2)] out int clientPortHandle)
  55. {
  56. return _syscall.CreatePort(maxSessions, isLight, namePtr, out serverPortHandle, out clientPortHandle);
  57. }
  58. public KernelResult ManageNamedPort32([R(1)] uint namePtr, [R(2)] int maxSessions, [R(1)] out int handle)
  59. {
  60. return _syscall.ManageNamedPort(namePtr, maxSessions, out handle);
  61. }
  62. public KernelResult ConnectToPort32([R(1)] int clientPortHandle, [R(1)] out int clientSessionHandle)
  63. {
  64. return _syscall.ConnectToPort(clientPortHandle, out clientSessionHandle);
  65. }
  66. // Memory
  67. public KernelResult SetHeapSize32([R(1)] uint size, [R(1)] out uint position)
  68. {
  69. KernelResult result = _syscall.SetHeapSize(size, out ulong temporaryPosition);
  70. position = (uint)temporaryPosition;
  71. return result;
  72. }
  73. public KernelResult SetMemoryAttribute32(
  74. [R(0)] uint position,
  75. [R(1)] uint size,
  76. [R(2)] MemoryAttribute attributeMask,
  77. [R(3)] MemoryAttribute attributeValue)
  78. {
  79. return _syscall.SetMemoryAttribute(position, size, attributeMask, attributeValue);
  80. }
  81. public KernelResult MapMemory32([R(0)] uint dst, [R(1)] uint src, [R(2)] uint size)
  82. {
  83. return _syscall.MapMemory(dst, src, size);
  84. }
  85. public KernelResult UnmapMemory32([R(0)] uint dst, [R(1)] uint src, [R(2)] uint size)
  86. {
  87. return _syscall.UnmapMemory(dst, src, size);
  88. }
  89. public KernelResult QueryMemory32([R(0)] uint infoPtr, [R(1)] uint r1, [R(2)] uint position, [R(1)] out uint pageInfo)
  90. {
  91. KernelResult result = _syscall.QueryMemory(infoPtr, position, out ulong pageInfo64);
  92. pageInfo = (uint)pageInfo64;
  93. return result;
  94. }
  95. public KernelResult MapSharedMemory32([R(0)] int handle, [R(1)] uint address, [R(2)] uint size, [R(3)] KMemoryPermission permission)
  96. {
  97. return _syscall.MapSharedMemory(handle, address, size, permission);
  98. }
  99. public KernelResult UnmapSharedMemory32([R(0)] int handle, [R(1)] uint address, [R(2)] uint size)
  100. {
  101. return _syscall.UnmapSharedMemory(handle, address, size);
  102. }
  103. public KernelResult CreateTransferMemory32(
  104. [R(1)] uint address,
  105. [R(2)] uint size,
  106. [R(3)] KMemoryPermission permission,
  107. [R(1)] out int handle)
  108. {
  109. return _syscall.CreateTransferMemory(address, size, permission, out handle);
  110. }
  111. public KernelResult MapTransferMemory32([R(0)] int handle, [R(1)] uint address, [R(2)] uint size, [R(3)] KMemoryPermission permission)
  112. {
  113. return _syscall.MapTransferMemory(handle, address, size, permission);
  114. }
  115. public KernelResult UnmapTransferMemory32([R(0)] int handle, [R(1)] uint address, [R(2)] uint size)
  116. {
  117. return _syscall.UnmapTransferMemory(handle, address, size);
  118. }
  119. public KernelResult MapPhysicalMemory32([R(0)] uint address, [R(1)] uint size)
  120. {
  121. return _syscall.MapPhysicalMemory(address, size);
  122. }
  123. public KernelResult UnmapPhysicalMemory32([R(0)] uint address, [R(1)] uint size)
  124. {
  125. return _syscall.UnmapPhysicalMemory(address, size);
  126. }
  127. public KernelResult MapProcessCodeMemory32([R(0)] int handle, [R(1)] uint srcLow, [R(2)] uint dstLow, [R(3)] uint dstHigh, [R(4)] uint srcHigh, [R(5)] uint sizeLow, [R(6)] uint sizeHigh)
  128. {
  129. ulong src = srcLow | ((ulong)srcHigh << 32);
  130. ulong dst = dstLow | ((ulong)dstHigh << 32);
  131. ulong size = sizeLow | ((ulong)sizeHigh << 32);
  132. return _syscall.MapProcessCodeMemory(handle, dst, src, size);
  133. }
  134. public KernelResult UnmapProcessCodeMemory32([R(0)] int handle, [R(1)] uint srcLow, [R(2)] uint dstLow, [R(3)] uint dstHigh, [R(4)] uint srcHigh, [R(5)] uint sizeLow, [R(6)] uint sizeHigh)
  135. {
  136. ulong src = srcLow | ((ulong)srcHigh << 32);
  137. ulong dst = dstLow | ((ulong)dstHigh << 32);
  138. ulong size = sizeLow | ((ulong)sizeHigh << 32);
  139. return _syscall.UnmapProcessCodeMemory(handle, dst, src, size);
  140. }
  141. public KernelResult SetProcessMemoryPermission32(
  142. [R(0)] int handle,
  143. [R(1)] uint sizeLow,
  144. [R(2)] uint srcLow,
  145. [R(3)] uint srcHigh,
  146. [R(4)] uint sizeHigh,
  147. [R(5)] KMemoryPermission permission)
  148. {
  149. ulong src = srcLow | ((ulong)srcHigh << 32);
  150. ulong size = sizeLow | ((ulong)sizeHigh << 32);
  151. return _syscall.SetProcessMemoryPermission(handle, src, size, permission);
  152. }
  153. // System
  154. public void ExitProcess32()
  155. {
  156. _syscall.ExitProcess();
  157. }
  158. public KernelResult TerminateProcess32([R(0)] int handle)
  159. {
  160. return _syscall.TerminateProcess(handle);
  161. }
  162. public KernelResult SignalEvent32([R(0)] int handle)
  163. {
  164. return _syscall.SignalEvent(handle);
  165. }
  166. public KernelResult ClearEvent32([R(0)] int handle)
  167. {
  168. return _syscall.ClearEvent(handle);
  169. }
  170. public KernelResult CloseHandle32([R(0)] int handle)
  171. {
  172. return _syscall.CloseHandle(handle);
  173. }
  174. public KernelResult ResetSignal32([R(0)] int handle)
  175. {
  176. return _syscall.ResetSignal(handle);
  177. }
  178. public void GetSystemTick32([R(0)] out uint resultLow, [R(1)] out uint resultHigh)
  179. {
  180. ulong result = _syscall.GetSystemTick();
  181. resultLow = (uint)(result & uint.MaxValue);
  182. resultHigh = (uint)(result >> 32);
  183. }
  184. public KernelResult GetProcessId32([R(1)] int handle, [R(1)] out int pidLow, [R(2)] out int pidHigh)
  185. {
  186. KernelResult result = _syscall.GetProcessId(handle, out long pid);
  187. pidLow = (int)(pid & uint.MaxValue);
  188. pidHigh = (int)(pid >> 32);
  189. return result;
  190. }
  191. public void Break32([R(0)] uint reason, [R(1)] uint r1, [R(2)] uint info)
  192. {
  193. _syscall.Break(reason);
  194. }
  195. public void OutputDebugString32([R(0)] uint strPtr, [R(1)] uint size)
  196. {
  197. _syscall.OutputDebugString(strPtr, size);
  198. }
  199. public KernelResult GetInfo32(
  200. [R(0)] uint subIdLow,
  201. [R(1)] uint id,
  202. [R(2)] int handle,
  203. [R(3)] uint subIdHigh,
  204. [R(1)] out uint valueLow,
  205. [R(2)] out uint valueHigh)
  206. {
  207. long subId = (long)(subIdLow | ((ulong)subIdHigh << 32));
  208. KernelResult result = _syscall.GetInfo(id, handle, subId, out long value);
  209. valueHigh = (uint)(value >> 32);
  210. valueLow = (uint)(value & uint.MaxValue);
  211. return result;
  212. }
  213. public KernelResult CreateEvent32([R(1)] out int wEventHandle, [R(2)] out int rEventHandle)
  214. {
  215. return _syscall.CreateEvent(out wEventHandle, out rEventHandle);
  216. }
  217. public KernelResult GetProcessList32([R(1)] ulong address, [R(2)] int maxCount, [R(1)] out int count)
  218. {
  219. return _syscall.GetProcessList(address, maxCount, out count);
  220. }
  221. public KernelResult GetSystemInfo32([R(1)] uint subIdLow, [R(2)] uint id, [R(3)] int handle, [R(3)] uint subIdHigh, [R(1)] out int valueLow, [R(2)] out int valueHigh)
  222. {
  223. long subId = (long)(subIdLow | ((ulong)subIdHigh << 32));
  224. KernelResult result = _syscall.GetSystemInfo(id, handle, subId, out long value);
  225. valueHigh = (int)(value >> 32);
  226. valueLow = (int)(value & uint.MaxValue);
  227. return result;
  228. }
  229. public KernelResult FlushProcessDataCache32(
  230. [R(0)] uint processHandle,
  231. [R(2)] uint addressLow,
  232. [R(3)] uint addressHigh,
  233. [R(1)] uint sizeLow,
  234. [R(4)] uint sizeHigh)
  235. {
  236. // FIXME: This needs to be implemented as ARMv7 doesn't have any way to do cache maintenance operations on EL0.
  237. // As we don't support (and don't actually need) to flush the cache, this is stubbed.
  238. return KernelResult.Success;
  239. }
  240. // Thread
  241. public KernelResult CreateThread32(
  242. [R(1)] uint entrypoint,
  243. [R(2)] uint argsPtr,
  244. [R(3)] uint stackTop,
  245. [R(0)] int priority,
  246. [R(4)] int cpuCore,
  247. [R(1)] out int handle)
  248. {
  249. return _syscall.CreateThread(entrypoint, argsPtr, stackTop, priority, cpuCore, out handle);
  250. }
  251. public KernelResult StartThread32([R(0)] int handle)
  252. {
  253. return _syscall.StartThread(handle);
  254. }
  255. public void ExitThread32()
  256. {
  257. _syscall.ExitThread();
  258. }
  259. public void SleepThread32([R(0)] uint timeoutLow, [R(1)] uint timeoutHigh)
  260. {
  261. long timeout = (long)(timeoutLow | ((ulong)timeoutHigh << 32));
  262. _syscall.SleepThread(timeout);
  263. }
  264. public KernelResult GetThreadPriority32([R(1)] int handle, [R(1)] out int priority)
  265. {
  266. return _syscall.GetThreadPriority(handle, out priority);
  267. }
  268. public KernelResult SetThreadPriority32([R(0)] int handle, [R(1)] int priority)
  269. {
  270. return _syscall.SetThreadPriority(handle, priority);
  271. }
  272. public KernelResult GetThreadCoreMask32([R(2)] int handle, [R(1)] out int preferredCore, [R(2)] out int affinityMaskLow, [R(3)] out int affinityMaskHigh)
  273. {
  274. KernelResult result = _syscall.GetThreadCoreMask(handle, out preferredCore, out long affinityMask);
  275. affinityMaskLow = (int)(affinityMask & uint.MaxValue);
  276. affinityMaskHigh = (int)(affinityMask >> 32);
  277. return result;
  278. }
  279. public KernelResult SetThreadCoreMask32([R(0)] int handle, [R(1)] int preferredCore, [R(2)] uint affinityMaskLow, [R(3)] uint affinityMaskHigh)
  280. {
  281. long affinityMask = (long)(affinityMaskLow | ((ulong)affinityMaskHigh << 32));
  282. return _syscall.SetThreadCoreMask(handle, preferredCore, affinityMask);
  283. }
  284. public int GetCurrentProcessorNumber32()
  285. {
  286. return _syscall.GetCurrentProcessorNumber();
  287. }
  288. public KernelResult GetThreadId32([R(1)] int handle, [R(1)] out uint threadUidLow, [R(2)] out uint threadUidHigh)
  289. {
  290. long threadUid;
  291. KernelResult result = _syscall.GetThreadId(handle, out threadUid);
  292. threadUidLow = (uint)(threadUid >> 32);
  293. threadUidHigh = (uint)(threadUid & uint.MaxValue);
  294. return result;
  295. }
  296. public KernelResult SetThreadActivity32([R(0)] int handle, [R(1)] bool pause)
  297. {
  298. return _syscall.SetThreadActivity(handle, pause);
  299. }
  300. public KernelResult GetThreadContext332([R(0)] uint address, [R(1)] int handle)
  301. {
  302. return _syscall.GetThreadContext3(address, handle);
  303. }
  304. // Thread synchronization
  305. public KernelResult WaitSynchronization32(
  306. [R(0)] uint timeoutLow,
  307. [R(1)] uint handlesPtr,
  308. [R(2)] int handlesCount,
  309. [R(3)] uint timeoutHigh,
  310. [R(1)] out int handleIndex)
  311. {
  312. long timeout = (long)(timeoutLow | ((ulong)timeoutHigh << 32));
  313. return _syscall.WaitSynchronization(handlesPtr, handlesCount, timeout, out handleIndex);
  314. }
  315. public KernelResult CancelSynchronization32([R(0)] int handle)
  316. {
  317. return _syscall.CancelSynchronization(handle);
  318. }
  319. public KernelResult ArbitrateLock32([R(0)] int ownerHandle, [R(1)] uint mutexAddress, [R(2)] int requesterHandle)
  320. {
  321. return _syscall.ArbitrateLock(ownerHandle, mutexAddress, requesterHandle);
  322. }
  323. public KernelResult ArbitrateUnlock32([R(0)] uint mutexAddress)
  324. {
  325. return _syscall.ArbitrateUnlock(mutexAddress);
  326. }
  327. public KernelResult WaitProcessWideKeyAtomic32(
  328. [R(0)] uint mutexAddress,
  329. [R(1)] uint condVarAddress,
  330. [R(2)] int handle,
  331. [R(3)] uint timeoutLow,
  332. [R(4)] uint timeoutHigh)
  333. {
  334. long timeout = (long)(timeoutLow | ((ulong)timeoutHigh << 32));
  335. return _syscall.WaitProcessWideKeyAtomic(mutexAddress, condVarAddress, handle, timeout);
  336. }
  337. public KernelResult SignalProcessWideKey32([R(0)] uint address, [R(1)] int count)
  338. {
  339. return _syscall.SignalProcessWideKey(address, count);
  340. }
  341. public KernelResult WaitForAddress32([R(0)] uint address, [R(1)] ArbitrationType type, [R(2)] int value, [R(3)] uint timeoutLow, [R(4)] uint timeoutHigh)
  342. {
  343. long timeout = (long)(timeoutLow | ((ulong)timeoutHigh << 32));
  344. return _syscall.WaitForAddress(address, type, value, timeout);
  345. }
  346. public KernelResult SignalToAddress32([R(0)] uint address, [R(1)] SignalType type, [R(2)] int value, [R(3)] int count)
  347. {
  348. return _syscall.SignalToAddress(address, type, value, count);
  349. }
  350. }
  351. }