SvcSystem.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. using ChocolArm64.Memory;
  2. using ChocolArm64.State;
  3. using Ryujinx.Core.OsHle.Exceptions;
  4. using Ryujinx.Core.OsHle.Handles;
  5. using Ryujinx.Core.OsHle.Ipc;
  6. using System;
  7. using System.Threading;
  8. namespace Ryujinx.Core.OsHle.Svc
  9. {
  10. partial class SvcHandler
  11. {
  12. private void SvcExitProcess(AThreadState ThreadState) => Ns.Os.ExitProcess(ThreadState.ProcessId);
  13. private void SvcCloseHandle(AThreadState ThreadState)
  14. {
  15. int Handle = (int)ThreadState.X0;
  16. Ns.Os.CloseHandle(Handle);
  17. ThreadState.X0 = (int)SvcResult.Success;
  18. }
  19. private void SvcResetSignal(AThreadState ThreadState)
  20. {
  21. int Handle = (int)ThreadState.X0;
  22. //TODO: Implement events.
  23. ThreadState.X0 = (int)SvcResult.Success;
  24. }
  25. private void SvcWaitSynchronization(AThreadState ThreadState)
  26. {
  27. long HandlesPtr = (long)ThreadState.X0;
  28. int HandlesCount = (int)ThreadState.X2;
  29. long Timeout = (long)ThreadState.X3;
  30. //TODO: Implement events.
  31. HThread CurrThread = Process.GetThread(ThreadState.Tpidr);
  32. Process.Scheduler.Suspend(CurrThread.ProcessorId);
  33. Process.Scheduler.Resume(CurrThread);
  34. ThreadState.X0 = (int)SvcResult.Success;
  35. }
  36. private void SvcGetSystemTick(AThreadState ThreadState)
  37. {
  38. ThreadState.X0 = (ulong)ThreadState.CntpctEl0;
  39. }
  40. private void SvcConnectToNamedPort(AThreadState ThreadState)
  41. {
  42. long StackPtr = (long)ThreadState.X0;
  43. long NamePtr = (long)ThreadState.X1;
  44. string Name = AMemoryHelper.ReadAsciiString(Memory, NamePtr, 8);
  45. //TODO: Validate that app has perms to access the service, and that the service
  46. //actually exists, return error codes otherwise.
  47. HSession Session = new HSession(Name);
  48. ThreadState.X1 = (ulong)Ns.Os.Handles.GenerateId(Session);
  49. ThreadState.X0 = (int)SvcResult.Success;
  50. }
  51. private void SvcSendSyncRequest(AThreadState ThreadState)
  52. {
  53. SendSyncRequest(ThreadState, false);
  54. }
  55. private void SvcSendSyncRequestWithUserBuffer(AThreadState ThreadState)
  56. {
  57. SendSyncRequest(ThreadState, true);
  58. }
  59. private void SendSyncRequest(AThreadState ThreadState, bool UserBuffer)
  60. {
  61. long CmdPtr = ThreadState.Tpidr;
  62. long Size = 0x100;
  63. int Handle = 0;
  64. if (UserBuffer)
  65. {
  66. CmdPtr = (long)ThreadState.X0;
  67. Size = (long)ThreadState.X1;
  68. Handle = (int)ThreadState.X2;
  69. }
  70. else
  71. {
  72. Handle = (int)ThreadState.X0;
  73. }
  74. HThread CurrThread = Process.GetThread(ThreadState.Tpidr);
  75. Process.Scheduler.Suspend(CurrThread.ProcessorId);
  76. byte[] CmdData = AMemoryHelper.ReadBytes(Memory, CmdPtr, (int)Size);
  77. HSession Session = Ns.Os.Handles.GetData<HSession>(Handle);
  78. IpcMessage Cmd = new IpcMessage(CmdData, CmdPtr, Session is HDomain);
  79. if (Session != null)
  80. {
  81. IpcHandler.IpcCall(Ns, Memory, Session, Cmd, ThreadState.ThreadId, CmdPtr, Handle);
  82. byte[] Response = AMemoryHelper.ReadBytes(Memory, CmdPtr, (int)Size);
  83. ThreadState.X0 = (int)SvcResult.Success;
  84. }
  85. else
  86. {
  87. ThreadState.X0 = (int)SvcResult.ErrBadIpcReq;
  88. }
  89. Thread.Yield();
  90. Process.Scheduler.Resume(CurrThread);
  91. }
  92. private void SvcBreak(AThreadState ThreadState)
  93. {
  94. long Reason = (long)ThreadState.X0;
  95. long Unknown = (long)ThreadState.X1;
  96. long Info = (long)ThreadState.X2;
  97. throw new GuestBrokeExecutionException();
  98. }
  99. private void SvcOutputDebugString(AThreadState ThreadState)
  100. {
  101. long Position = (long)ThreadState.X0;
  102. long Size = (long)ThreadState.X1;
  103. string Str = AMemoryHelper.ReadAsciiString(Memory, Position, (int)Size);
  104. Logging.Info($"SvcOutputDebugString: {Str}");
  105. ThreadState.X0 = (int)SvcResult.Success;
  106. }
  107. private void SvcGetInfo(AThreadState ThreadState)
  108. {
  109. long StackPtr = (long)ThreadState.X0;
  110. int InfoType = (int)ThreadState.X1;
  111. long Handle = (long)ThreadState.X2;
  112. int InfoId = (int)ThreadState.X3;
  113. //Fail for info not available on older Kernel versions.
  114. if (InfoType == 18 ||
  115. InfoType == 19)
  116. {
  117. ThreadState.X0 = (int)SvcResult.ErrBadInfo;
  118. return;
  119. }
  120. switch (InfoType)
  121. {
  122. case 2: ThreadState.X1 = GetMapRegionBaseAddr(); break;
  123. case 3: ThreadState.X1 = GetMapRegionSize(); break;
  124. case 4: ThreadState.X1 = GetHeapRegionBaseAddr(); break;
  125. case 5: ThreadState.X1 = GetHeapRegionSize(); break;
  126. case 6: ThreadState.X1 = GetTotalMem(); break;
  127. case 7: ThreadState.X1 = GetUsedMem(); break;
  128. case 11: ThreadState.X1 = GetRnd64(); break;
  129. case 12: ThreadState.X1 = GetAddrSpaceBaseAddr(); break;
  130. case 13: ThreadState.X1 = GetAddrSpaceSize(); break;
  131. case 14: ThreadState.X1 = GetMapRegionBaseAddr(); break;
  132. case 15: ThreadState.X1 = GetMapRegionSize(); break;
  133. default: throw new NotImplementedException($"SvcGetInfo: {InfoType} {Handle} {InfoId}");
  134. }
  135. ThreadState.X0 = (int)SvcResult.Success;
  136. }
  137. private ulong GetTotalMem()
  138. {
  139. return (ulong)Memory.Manager.GetTotalMemorySize();
  140. }
  141. private ulong GetUsedMem()
  142. {
  143. return (ulong)Memory.Manager.GetUsedMemorySize();
  144. }
  145. private ulong GetRnd64()
  146. {
  147. return (ulong)Rng.Next() + ((ulong)Rng.Next() << 32);
  148. }
  149. private ulong GetAddrSpaceBaseAddr()
  150. {
  151. return 0x08000000;
  152. }
  153. private ulong GetAddrSpaceSize()
  154. {
  155. return AMemoryMgr.AddrSize - GetAddrSpaceBaseAddr();
  156. }
  157. private ulong GetMapRegionBaseAddr()
  158. {
  159. return 0x80000000;
  160. }
  161. private ulong GetMapRegionSize()
  162. {
  163. return 0x40000000;
  164. }
  165. private ulong GetHeapRegionBaseAddr()
  166. {
  167. return GetMapRegionBaseAddr() + GetMapRegionSize();
  168. }
  169. private ulong GetHeapRegionSize()
  170. {
  171. return 0x40000000;
  172. }
  173. }
  174. }