SvcSystem.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. using ChocolArm64.Memory;
  2. using ChocolArm64.State;
  3. using Ryujinx.OsHle.Exceptions;
  4. using Ryujinx.OsHle.Handles;
  5. using Ryujinx.OsHle.Ipc;
  6. using System;
  7. namespace Ryujinx.OsHle.Svc
  8. {
  9. partial class SvcHandler
  10. {
  11. private void SvcCloseHandle(ARegisters Registers)
  12. {
  13. int Handle = (int)Registers.X0;
  14. Ns.Os.CloseHandle(Handle);
  15. Registers.X0 = (int)SvcResult.Success;
  16. }
  17. private void SvcResetSignal(ARegisters Registers)
  18. {
  19. int Handle = (int)Registers.X0;
  20. //TODO: Implement events.
  21. Registers.X0 = (int)SvcResult.Success;
  22. }
  23. private void SvcWaitSynchronization(ARegisters Registers)
  24. {
  25. long HandlesPtr = (long)Registers.X0;
  26. int HandlesCount = (int)Registers.X2;
  27. long Timeout = (long)Registers.X3;
  28. //TODO: Implement events.
  29. //Logging.Info($"SvcWaitSynchronization Thread {Registers.ThreadId}");
  30. if (Process.TryGetThread(Registers.Tpidr, out HThread Thread))
  31. {
  32. Process.Scheduler.Yield(Thread);
  33. }
  34. else
  35. {
  36. Logging.Error($"Thread with TPIDR_EL0 0x{Registers.Tpidr:x16} not found!");
  37. }
  38. Registers.X0 = (int)SvcResult.Success;
  39. }
  40. private void SvcGetSystemTick(ARegisters Registers)
  41. {
  42. Registers.X0 = (ulong)Registers.CntpctEl0;
  43. }
  44. private void SvcConnectToNamedPort(ARegisters Registers)
  45. {
  46. long StackPtr = (long)Registers.X0;
  47. long NamePtr = (long)Registers.X1;
  48. string Name = AMemoryHelper.ReadAsciiString(Memory, NamePtr, 8);
  49. //TODO: Validate that app has perms to access the service, and that the service
  50. //actually exists, return error codes otherwise.
  51. HSession Session = new HSession(Name);
  52. Registers.X1 = (ulong)Ns.Os.Handles.GenerateId(Session);
  53. Registers.X0 = (int)SvcResult.Success;
  54. }
  55. private void SvcSendSyncRequest(ARegisters Registers)
  56. {
  57. SendSyncRequest(Registers, false);
  58. }
  59. private void SvcSendSyncRequestWithUserBuffer(ARegisters Registers)
  60. {
  61. SendSyncRequest(Registers, true);
  62. }
  63. private void SendSyncRequest(ARegisters Registers, bool UserBuffer)
  64. {
  65. long CmdPtr = Registers.Tpidr;
  66. long Size = 0x100;
  67. int Handle = 0;
  68. if (UserBuffer)
  69. {
  70. CmdPtr = (long)Registers.X0;
  71. Size = (long)Registers.X1;
  72. Handle = (int)Registers.X2;
  73. }
  74. else
  75. {
  76. Handle = (int)Registers.X0;
  77. }
  78. byte[] CmdData = AMemoryHelper.ReadBytes(Memory, CmdPtr, (int)Size);
  79. HSession Session = Ns.Os.Handles.GetData<HSession>(Handle);
  80. IpcMessage Cmd = new IpcMessage(CmdData, CmdPtr, Session is HDomain);
  81. if (Session != null)
  82. {
  83. IpcHandler.IpcCall(Ns, Memory, Session, Cmd, CmdPtr, Handle);
  84. byte[] Response = AMemoryHelper.ReadBytes(Memory, CmdPtr, (int)Size);
  85. Registers.X0 = (int)SvcResult.Success;
  86. }
  87. else
  88. {
  89. Registers.X0 = (int)SvcResult.ErrBadIpcReq;
  90. }
  91. }
  92. private void SvcBreak(ARegisters Registers)
  93. {
  94. long Reason = (long)Registers.X0;
  95. long Unknown = (long)Registers.X1;
  96. long Info = (long)Registers.X2;
  97. throw new GuestBrokeExecutionException();
  98. }
  99. private void SvcOutputDebugString(ARegisters Registers)
  100. {
  101. long Position = (long)Registers.X0;
  102. long Size = (long)Registers.X1;
  103. string Str = AMemoryHelper.ReadAsciiString(Memory, Position, (int)Size);
  104. Logging.Info($"SvcOutputDebugString: {Str}");
  105. Registers.X0 = (int)SvcResult.Success;
  106. }
  107. private void SvcGetInfo(ARegisters Registers)
  108. {
  109. long StackPtr = (long)Registers.X0;
  110. int InfoType = (int)Registers.X1;
  111. long Handle = (long)Registers.X2;
  112. int InfoId = (int)Registers.X3;
  113. //Fail for info not available on older Kernel versions.
  114. if (InfoType == 18 ||
  115. InfoType == 19)
  116. {
  117. Registers.X0 = (int)SvcResult.ErrBadInfo;
  118. return;
  119. }
  120. switch (InfoType)
  121. {
  122. case 2: Registers.X1 = GetMapRegionBaseAddr(); break;
  123. case 3: Registers.X1 = GetMapRegionSize(); break;
  124. case 4: Registers.X1 = GetHeapRegionBaseAddr(); break;
  125. case 5: Registers.X1 = GetHeapRegionSize(); break;
  126. case 6: Registers.X1 = GetTotalMem(); break;
  127. case 7: Registers.X1 = GetUsedMem(); break;
  128. case 11: Registers.X1 = GetRnd64(); break;
  129. case 12: Registers.X1 = GetAddrSpaceBaseAddr(); break;
  130. case 13: Registers.X1 = GetAddrSpaceSize(); break;
  131. case 14: Registers.X1 = GetMapRegionBaseAddr(); break;
  132. case 15: Registers.X1 = GetMapRegionSize(); break;
  133. default: throw new NotImplementedException($"SvcGetInfo: {InfoType} {Handle} {InfoId}");
  134. }
  135. Registers.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. }