Syscall32.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  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(out handle, namePtr);
  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(out serverSessionHandle, out clientSessionHandle, isLight, namePtr);
  33. }
  34. public KernelResult AcceptSession32([R(1)] int portHandle, [R(1)] out int sessionHandle)
  35. {
  36. return _syscall.AcceptSession(out sessionHandle, portHandle);
  37. }
  38. public KernelResult ReplyAndReceive32(
  39. [R(0)] uint timeoutLow,
  40. [R(1)] uint 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(out handleIndex, handlesPtr, handlesCount, replyTargetHandle, timeout);
  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(out serverPortHandle, out clientPortHandle, maxSessions, isLight, namePtr);
  57. }
  58. public KernelResult ManageNamedPort32([R(1)] uint namePtr, [R(2)] int maxSessions, [R(1)] out int handle)
  59. {
  60. return _syscall.ManageNamedPort(out handle, namePtr, maxSessions);
  61. }
  62. public KernelResult ConnectToPort32([R(1)] int clientPortHandle, [R(1)] out int clientSessionHandle)
  63. {
  64. return _syscall.ConnectToPort(out clientSessionHandle, clientPortHandle);
  65. }
  66. // Memory
  67. public KernelResult SetHeapSize32([R(1)] uint size, [R(1)] out uint address)
  68. {
  69. KernelResult result = _syscall.SetHeapSize(out ulong address64, size);
  70. address = (uint)address64;
  71. return result;
  72. }
  73. public KernelResult SetMemoryPermission32(
  74. [R(0)] uint address,
  75. [R(1)] uint size,
  76. [R(2)] KMemoryPermission permission)
  77. {
  78. return _syscall.SetMemoryPermission(address, size, permission);
  79. }
  80. public KernelResult SetMemoryAttribute32(
  81. [R(0)] uint address,
  82. [R(1)] uint size,
  83. [R(2)] MemoryAttribute attributeMask,
  84. [R(3)] MemoryAttribute attributeValue)
  85. {
  86. return _syscall.SetMemoryAttribute(address, size, attributeMask, attributeValue);
  87. }
  88. public KernelResult MapMemory32([R(0)] uint dst, [R(1)] uint src, [R(2)] uint size)
  89. {
  90. return _syscall.MapMemory(dst, src, size);
  91. }
  92. public KernelResult UnmapMemory32([R(0)] uint dst, [R(1)] uint src, [R(2)] uint size)
  93. {
  94. return _syscall.UnmapMemory(dst, src, size);
  95. }
  96. public KernelResult QueryMemory32([R(0)] uint infoPtr, [R(1)] uint r1, [R(2)] uint address, [R(1)] out uint pageInfo)
  97. {
  98. KernelResult result = _syscall.QueryMemory(infoPtr, out ulong pageInfo64, address);
  99. pageInfo = (uint)pageInfo64;
  100. return result;
  101. }
  102. public KernelResult MapSharedMemory32([R(0)] int handle, [R(1)] uint address, [R(2)] uint size, [R(3)] KMemoryPermission permission)
  103. {
  104. return _syscall.MapSharedMemory(handle, address, size, permission);
  105. }
  106. public KernelResult UnmapSharedMemory32([R(0)] int handle, [R(1)] uint address, [R(2)] uint size)
  107. {
  108. return _syscall.UnmapSharedMemory(handle, address, size);
  109. }
  110. public KernelResult CreateTransferMemory32(
  111. [R(1)] uint address,
  112. [R(2)] uint size,
  113. [R(3)] KMemoryPermission permission,
  114. [R(1)] out int handle)
  115. {
  116. return _syscall.CreateTransferMemory(out handle, address, size, permission);
  117. }
  118. public KernelResult CreateCodeMemory32([R(1)] uint address, [R(2)] uint size, [R(1)] out int handle)
  119. {
  120. return _syscall.CreateCodeMemory(address, size, out handle);
  121. }
  122. public KernelResult ControlCodeMemory32(
  123. [R(0)] int handle,
  124. [R(1)] CodeMemoryOperation op,
  125. [R(2)] uint addressLow,
  126. [R(3)] uint addressHigh,
  127. [R(4)] uint sizeLow,
  128. [R(5)] uint sizeHigh,
  129. [R(6)] KMemoryPermission permission)
  130. {
  131. ulong address = addressLow | ((ulong)addressHigh << 32);
  132. ulong size = sizeLow | ((ulong)sizeHigh << 32);
  133. return _syscall.ControlCodeMemory(handle, op, address, size, permission);
  134. }
  135. public KernelResult MapTransferMemory32([R(0)] int handle, [R(1)] uint address, [R(2)] uint size, [R(3)] KMemoryPermission permission)
  136. {
  137. return _syscall.MapTransferMemory(handle, address, size, permission);
  138. }
  139. public KernelResult UnmapTransferMemory32([R(0)] int handle, [R(1)] uint address, [R(2)] uint size)
  140. {
  141. return _syscall.UnmapTransferMemory(handle, address, size);
  142. }
  143. public KernelResult MapPhysicalMemory32([R(0)] uint address, [R(1)] uint size)
  144. {
  145. return _syscall.MapPhysicalMemory(address, size);
  146. }
  147. public KernelResult UnmapPhysicalMemory32([R(0)] uint address, [R(1)] uint size)
  148. {
  149. return _syscall.UnmapPhysicalMemory(address, size);
  150. }
  151. public KernelResult SetProcessMemoryPermission32(
  152. [R(0)] int handle,
  153. [R(1)] uint sizeLow,
  154. [R(2)] uint srcLow,
  155. [R(3)] uint srcHigh,
  156. [R(4)] uint sizeHigh,
  157. [R(5)] KMemoryPermission permission)
  158. {
  159. ulong src = srcLow | ((ulong)srcHigh << 32);
  160. ulong size = sizeLow | ((ulong)sizeHigh << 32);
  161. return _syscall.SetProcessMemoryPermission(handle, src, size, permission);
  162. }
  163. public KernelResult MapProcessMemory32([R(0)] uint dst, [R(1)] int handle, [R(2)] uint srcLow, [R(3)] uint srcHigh, [R(4)] uint size)
  164. {
  165. ulong src = srcLow | ((ulong)srcHigh << 32);
  166. return _syscall.MapProcessMemory(dst, handle, src, size);
  167. }
  168. public KernelResult UnmapProcessMemory32([R(0)] uint dst, [R(1)] int handle, [R(2)] uint srcLow, [R(3)] uint srcHigh, [R(4)] uint size)
  169. {
  170. ulong src = srcLow | ((ulong)srcHigh << 32);
  171. return _syscall.UnmapProcessMemory(dst, handle, src, size);
  172. }
  173. 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)
  174. {
  175. ulong src = srcLow | ((ulong)srcHigh << 32);
  176. ulong dst = dstLow | ((ulong)dstHigh << 32);
  177. ulong size = sizeLow | ((ulong)sizeHigh << 32);
  178. return _syscall.MapProcessCodeMemory(handle, dst, src, size);
  179. }
  180. 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)
  181. {
  182. ulong src = srcLow | ((ulong)srcHigh << 32);
  183. ulong dst = dstLow | ((ulong)dstHigh << 32);
  184. ulong size = sizeLow | ((ulong)sizeHigh << 32);
  185. return _syscall.UnmapProcessCodeMemory(handle, dst, src, size);
  186. }
  187. // System
  188. public void ExitProcess32()
  189. {
  190. _syscall.ExitProcess();
  191. }
  192. public KernelResult TerminateProcess32([R(0)] int handle)
  193. {
  194. return _syscall.TerminateProcess(handle);
  195. }
  196. public KernelResult SignalEvent32([R(0)] int handle)
  197. {
  198. return _syscall.SignalEvent(handle);
  199. }
  200. public KernelResult ClearEvent32([R(0)] int handle)
  201. {
  202. return _syscall.ClearEvent(handle);
  203. }
  204. public KernelResult CloseHandle32([R(0)] int handle)
  205. {
  206. return _syscall.CloseHandle(handle);
  207. }
  208. public KernelResult ResetSignal32([R(0)] int handle)
  209. {
  210. return _syscall.ResetSignal(handle);
  211. }
  212. public void GetSystemTick32([R(0)] out uint resultLow, [R(1)] out uint resultHigh)
  213. {
  214. ulong result = _syscall.GetSystemTick();
  215. resultLow = (uint)(result & uint.MaxValue);
  216. resultHigh = (uint)(result >> 32);
  217. }
  218. public KernelResult GetProcessId32([R(1)] int handle, [R(1)] out uint pidLow, [R(2)] out uint pidHigh)
  219. {
  220. KernelResult result = _syscall.GetProcessId(out ulong pid, handle);
  221. pidLow = (uint)(pid & uint.MaxValue);
  222. pidHigh = (uint)(pid >> 32);
  223. return result;
  224. }
  225. public void Break32([R(0)] uint reason, [R(1)] uint r1, [R(2)] uint info)
  226. {
  227. _syscall.Break(reason);
  228. }
  229. public void OutputDebugString32([R(0)] uint strPtr, [R(1)] uint size)
  230. {
  231. _syscall.OutputDebugString(strPtr, size);
  232. }
  233. public KernelResult GetInfo32(
  234. [R(0)] uint subIdLow,
  235. [R(1)] InfoType id,
  236. [R(2)] int handle,
  237. [R(3)] uint subIdHigh,
  238. [R(1)] out uint valueLow,
  239. [R(2)] out uint valueHigh)
  240. {
  241. long subId = (long)(subIdLow | ((ulong)subIdHigh << 32));
  242. KernelResult result = _syscall.GetInfo(out ulong value, id, handle, subId);
  243. valueHigh = (uint)(value >> 32);
  244. valueLow = (uint)(value & uint.MaxValue);
  245. return result;
  246. }
  247. public KernelResult CreateEvent32([R(1)] out int wEventHandle, [R(2)] out int rEventHandle)
  248. {
  249. return _syscall.CreateEvent(out wEventHandle, out rEventHandle);
  250. }
  251. public KernelResult GetProcessList32([R(1)] ulong address, [R(2)] int maxCount, [R(1)] out int count)
  252. {
  253. return _syscall.GetProcessList(out count, address, maxCount);
  254. }
  255. 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)
  256. {
  257. long subId = (long)(subIdLow | ((ulong)subIdHigh << 32));
  258. KernelResult result = _syscall.GetSystemInfo(out long value, id, handle, subId);
  259. valueHigh = (int)(value >> 32);
  260. valueLow = (int)(value & uint.MaxValue);
  261. return result;
  262. }
  263. public KernelResult GetResourceLimitLimitValue32([R(1)] int handle, [R(2)] LimitableResource resource, [R(1)] out int limitValueLow, [R(2)] out int limitValueHigh)
  264. {
  265. KernelResult result = _syscall.GetResourceLimitLimitValue(out long limitValue, handle, resource);
  266. limitValueHigh = (int)(limitValue >> 32);
  267. limitValueLow = (int)(limitValue & uint.MaxValue);
  268. return result;
  269. }
  270. public KernelResult GetResourceLimitCurrentValue32([R(1)] int handle, [R(2)] LimitableResource resource, [R(1)] out int limitValueLow, [R(2)] out int limitValueHigh)
  271. {
  272. KernelResult result = _syscall.GetResourceLimitCurrentValue(out long limitValue, handle, resource);
  273. limitValueHigh = (int)(limitValue >> 32);
  274. limitValueLow = (int)(limitValue & uint.MaxValue);
  275. return result;
  276. }
  277. public KernelResult GetResourceLimitPeakValue32([R(1)] int handle, [R(2)] LimitableResource resource, [R(1)] out int peakLow, [R(2)] out int peakHigh)
  278. {
  279. KernelResult result = _syscall.GetResourceLimitPeakValue(out long peak, handle, resource);
  280. peakHigh = (int)(peak >> 32);
  281. peakLow = (int)(peak & uint.MaxValue);
  282. return result;
  283. }
  284. public KernelResult CreateResourceLimit32([R(1)] out int handle)
  285. {
  286. return _syscall.CreateResourceLimit(out handle);
  287. }
  288. public KernelResult SetResourceLimitLimitValue32([R(0)] int handle, [R(1)] LimitableResource resource, [R(2)] uint limitValueLow, [R(3)] uint limitValueHigh)
  289. {
  290. long limitValue = (long)(limitValueLow | ((ulong)limitValueHigh << 32));
  291. return _syscall.SetResourceLimitLimitValue(handle, resource, limitValue);
  292. }
  293. public KernelResult FlushProcessDataCache32(
  294. [R(0)] uint processHandle,
  295. [R(2)] uint addressLow,
  296. [R(3)] uint addressHigh,
  297. [R(1)] uint sizeLow,
  298. [R(4)] uint sizeHigh)
  299. {
  300. // FIXME: This needs to be implemented as ARMv7 doesn't have any way to do cache maintenance operations on EL0.
  301. // As we don't support (and don't actually need) to flush the cache, this is stubbed.
  302. return KernelResult.Success;
  303. }
  304. // Thread
  305. public KernelResult CreateThread32(
  306. [R(1)] uint entrypoint,
  307. [R(2)] uint argsPtr,
  308. [R(3)] uint stackTop,
  309. [R(0)] int priority,
  310. [R(4)] int cpuCore,
  311. [R(1)] out int handle)
  312. {
  313. return _syscall.CreateThread(out handle, entrypoint, argsPtr, stackTop, priority, cpuCore);
  314. }
  315. public KernelResult StartThread32([R(0)] int handle)
  316. {
  317. return _syscall.StartThread(handle);
  318. }
  319. public void ExitThread32()
  320. {
  321. _syscall.ExitThread();
  322. }
  323. public void SleepThread32([R(0)] uint timeoutLow, [R(1)] uint timeoutHigh)
  324. {
  325. long timeout = (long)(timeoutLow | ((ulong)timeoutHigh << 32));
  326. _syscall.SleepThread(timeout);
  327. }
  328. public KernelResult GetThreadPriority32([R(1)] int handle, [R(1)] out int priority)
  329. {
  330. return _syscall.GetThreadPriority(out priority, handle);
  331. }
  332. public KernelResult SetThreadPriority32([R(0)] int handle, [R(1)] int priority)
  333. {
  334. return _syscall.SetThreadPriority(handle, priority);
  335. }
  336. public KernelResult GetThreadCoreMask32([R(2)] int handle, [R(1)] out int preferredCore, [R(2)] out uint affinityMaskLow, [R(3)] out uint affinityMaskHigh)
  337. {
  338. KernelResult result = _syscall.GetThreadCoreMask(out preferredCore, out ulong affinityMask, handle);
  339. affinityMaskLow = (uint)(affinityMask & uint.MaxValue);
  340. affinityMaskHigh = (uint)(affinityMask >> 32);
  341. return result;
  342. }
  343. public KernelResult SetThreadCoreMask32([R(0)] int handle, [R(1)] int preferredCore, [R(2)] uint affinityMaskLow, [R(3)] uint affinityMaskHigh)
  344. {
  345. ulong affinityMask = affinityMaskLow | ((ulong)affinityMaskHigh << 32);
  346. return _syscall.SetThreadCoreMask(handle, preferredCore, affinityMask);
  347. }
  348. public int GetCurrentProcessorNumber32()
  349. {
  350. return _syscall.GetCurrentProcessorNumber();
  351. }
  352. public KernelResult GetThreadId32([R(1)] int handle, [R(1)] out uint threadUidLow, [R(2)] out uint threadUidHigh)
  353. {
  354. ulong threadUid;
  355. KernelResult result = _syscall.GetThreadId(out threadUid, handle);
  356. threadUidLow = (uint)(threadUid >> 32);
  357. threadUidHigh = (uint)(threadUid & uint.MaxValue);
  358. return result;
  359. }
  360. public KernelResult SetThreadActivity32([R(0)] int handle, [R(1)] bool pause)
  361. {
  362. return _syscall.SetThreadActivity(handle, pause);
  363. }
  364. public KernelResult GetThreadContext332([R(0)] uint address, [R(1)] int handle)
  365. {
  366. return _syscall.GetThreadContext3(address, handle);
  367. }
  368. // Thread synchronization
  369. public KernelResult WaitSynchronization32(
  370. [R(0)] uint timeoutLow,
  371. [R(1)] uint handlesPtr,
  372. [R(2)] int handlesCount,
  373. [R(3)] uint timeoutHigh,
  374. [R(1)] out int handleIndex)
  375. {
  376. long timeout = (long)(timeoutLow | ((ulong)timeoutHigh << 32));
  377. return _syscall.WaitSynchronization(out handleIndex, handlesPtr, handlesCount, timeout);
  378. }
  379. public KernelResult CancelSynchronization32([R(0)] int handle)
  380. {
  381. return _syscall.CancelSynchronization(handle);
  382. }
  383. public KernelResult ArbitrateLock32([R(0)] int ownerHandle, [R(1)] uint mutexAddress, [R(2)] int requesterHandle)
  384. {
  385. return _syscall.ArbitrateLock(ownerHandle, mutexAddress, requesterHandle);
  386. }
  387. public KernelResult ArbitrateUnlock32([R(0)] uint mutexAddress)
  388. {
  389. return _syscall.ArbitrateUnlock(mutexAddress);
  390. }
  391. public KernelResult WaitProcessWideKeyAtomic32(
  392. [R(0)] uint mutexAddress,
  393. [R(1)] uint condVarAddress,
  394. [R(2)] int handle,
  395. [R(3)] uint timeoutLow,
  396. [R(4)] uint timeoutHigh)
  397. {
  398. long timeout = (long)(timeoutLow | ((ulong)timeoutHigh << 32));
  399. return _syscall.WaitProcessWideKeyAtomic(mutexAddress, condVarAddress, handle, timeout);
  400. }
  401. public KernelResult SignalProcessWideKey32([R(0)] uint address, [R(1)] int count)
  402. {
  403. return _syscall.SignalProcessWideKey(address, count);
  404. }
  405. public KernelResult WaitForAddress32([R(0)] uint address, [R(1)] ArbitrationType type, [R(2)] int value, [R(3)] uint timeoutLow, [R(4)] uint timeoutHigh)
  406. {
  407. long timeout = (long)(timeoutLow | ((ulong)timeoutHigh << 32));
  408. return _syscall.WaitForAddress(address, type, value, timeout);
  409. }
  410. public KernelResult SignalToAddress32([R(0)] uint address, [R(1)] SignalType type, [R(2)] int value, [R(3)] int count)
  411. {
  412. return _syscall.SignalToAddress(address, type, value, count);
  413. }
  414. public KernelResult SynchronizePreemptionState32()
  415. {
  416. return _syscall.SynchronizePreemptionState();
  417. }
  418. }
  419. }