NvHostChannelIoctl.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. using ChocolArm64.Memory;
  2. using Ryujinx.HLE.Gpu.Memory;
  3. using Ryujinx.HLE.Logging;
  4. using Ryujinx.HLE.OsHle.Services.Nv.NvGpuAS;
  5. using System;
  6. using System.Collections.Concurrent;
  7. namespace Ryujinx.HLE.OsHle.Services.Nv.NvHostChannel
  8. {
  9. class NvHostChannelIoctl
  10. {
  11. private class ChannelsPerProcess
  12. {
  13. public ConcurrentDictionary<NvChannelName, NvChannel> Channels { get; private set; }
  14. public ChannelsPerProcess()
  15. {
  16. Channels = new ConcurrentDictionary<NvChannelName, NvChannel>();
  17. Channels.TryAdd(NvChannelName.Gpu, new NvChannel());
  18. }
  19. }
  20. private static ConcurrentDictionary<Process, ChannelsPerProcess> Channels;
  21. static NvHostChannelIoctl()
  22. {
  23. Channels = new ConcurrentDictionary<Process, ChannelsPerProcess>();
  24. }
  25. public static int ProcessIoctlGpu(ServiceCtx Context, int Cmd)
  26. {
  27. return ProcessIoctl(Context, NvChannelName.Gpu, Cmd);
  28. }
  29. public static int ProcessIoctl(ServiceCtx Context, NvChannelName Channel, int Cmd)
  30. {
  31. switch (Cmd & 0xffff)
  32. {
  33. case 0x4714: return SetUserData (Context);
  34. case 0x4801: return SetNvMap (Context);
  35. case 0x4803: return SetTimeout (Context, Channel);
  36. case 0x4808: return SubmitGpfifo (Context);
  37. case 0x4809: return AllocObjCtx (Context);
  38. case 0x480b: return ZcullBind (Context);
  39. case 0x480c: return SetErrorNotifier (Context);
  40. case 0x480d: return SetPriority (Context);
  41. case 0x481a: return AllocGpfifoEx2 (Context);
  42. case 0x481b: return KickoffPbWithAttr(Context);
  43. }
  44. throw new NotImplementedException(Cmd.ToString("x8"));
  45. }
  46. private static int SetUserData(ServiceCtx Context)
  47. {
  48. long InputPosition = Context.Request.GetBufferType0x21().Position;
  49. long OutputPosition = Context.Request.GetBufferType0x22().Position;
  50. Context.Ns.Log.PrintStub(LogClass.ServiceNv, "Stubbed.");
  51. return NvResult.Success;
  52. }
  53. private static int SetNvMap(ServiceCtx Context)
  54. {
  55. long InputPosition = Context.Request.GetBufferType0x21().Position;
  56. long OutputPosition = Context.Request.GetBufferType0x22().Position;
  57. Context.Ns.Log.PrintStub(LogClass.ServiceNv, "Stubbed.");
  58. return NvResult.Success;
  59. }
  60. private static int SetTimeout(ServiceCtx Context, NvChannelName Channel)
  61. {
  62. long InputPosition = Context.Request.GetBufferType0x21().Position;
  63. GetChannel(Context, Channel).Timeout = Context.Memory.ReadInt32(InputPosition);
  64. return NvResult.Success;
  65. }
  66. private static int SubmitGpfifo(ServiceCtx Context)
  67. {
  68. long InputPosition = Context.Request.GetBufferType0x21().Position;
  69. long OutputPosition = Context.Request.GetBufferType0x22().Position;
  70. NvHostChannelSubmitGpfifo Args = AMemoryHelper.Read<NvHostChannelSubmitGpfifo>(Context.Memory, InputPosition);
  71. NvGpuVmm Vmm = NvGpuASIoctl.GetVmm(Context);
  72. for (int Index = 0; Index < Args.NumEntries; Index++)
  73. {
  74. long Gpfifo = Context.Memory.ReadInt64(InputPosition + 0x18 + Index * 8);
  75. PushGpfifo(Context, Vmm, Gpfifo);
  76. }
  77. Args.SyncptId = 0;
  78. Args.SyncptValue = 0;
  79. AMemoryHelper.Write(Context.Memory, OutputPosition, Args);
  80. return NvResult.Success;
  81. }
  82. private static int AllocObjCtx(ServiceCtx Context)
  83. {
  84. long InputPosition = Context.Request.GetBufferType0x21().Position;
  85. long OutputPosition = Context.Request.GetBufferType0x22().Position;
  86. Context.Ns.Log.PrintStub(LogClass.ServiceNv, "Stubbed.");
  87. return NvResult.Success;
  88. }
  89. private static int ZcullBind(ServiceCtx Context)
  90. {
  91. long InputPosition = Context.Request.GetBufferType0x21().Position;
  92. long OutputPosition = Context.Request.GetBufferType0x22().Position;
  93. Context.Ns.Log.PrintStub(LogClass.ServiceNv, "Stubbed.");
  94. return NvResult.Success;
  95. }
  96. private static int SetErrorNotifier(ServiceCtx Context)
  97. {
  98. long InputPosition = Context.Request.GetBufferType0x21().Position;
  99. long OutputPosition = Context.Request.GetBufferType0x22().Position;
  100. Context.Ns.Log.PrintStub(LogClass.ServiceNv, "Stubbed.");
  101. return NvResult.Success;
  102. }
  103. private static int SetPriority(ServiceCtx Context)
  104. {
  105. long InputPosition = Context.Request.GetBufferType0x21().Position;
  106. long OutputPosition = Context.Request.GetBufferType0x22().Position;
  107. Context.Ns.Log.PrintStub(LogClass.ServiceNv, "Stubbed.");
  108. return NvResult.Success;
  109. }
  110. private static int AllocGpfifoEx2(ServiceCtx Context)
  111. {
  112. long InputPosition = Context.Request.GetBufferType0x21().Position;
  113. long OutputPosition = Context.Request.GetBufferType0x22().Position;
  114. Context.Ns.Log.PrintStub(LogClass.ServiceNv, "Stubbed.");
  115. return NvResult.Success;
  116. }
  117. private static int KickoffPbWithAttr(ServiceCtx Context)
  118. {
  119. long InputPosition = Context.Request.GetBufferType0x21().Position;
  120. long OutputPosition = Context.Request.GetBufferType0x22().Position;
  121. NvHostChannelSubmitGpfifo Args = AMemoryHelper.Read<NvHostChannelSubmitGpfifo>(Context.Memory, InputPosition);
  122. NvGpuVmm Vmm = NvGpuASIoctl.GetVmm(Context);
  123. for (int Index = 0; Index < Args.NumEntries; Index++)
  124. {
  125. long Gpfifo = Context.Memory.ReadInt64(Args.Address + Index * 8);
  126. PushGpfifo(Context, Vmm, Gpfifo);
  127. }
  128. Args.SyncptId = 0;
  129. Args.SyncptValue = 0;
  130. AMemoryHelper.Write(Context.Memory, OutputPosition, Args);
  131. return NvResult.Success;
  132. }
  133. private static void PushGpfifo(ServiceCtx Context, NvGpuVmm Vmm, long Gpfifo)
  134. {
  135. long VA = Gpfifo & 0xff_ffff_ffff;
  136. int Size = (int)(Gpfifo >> 40) & 0x7ffffc;
  137. byte[] Data = Vmm.ReadBytes(VA, Size);
  138. NvGpuPBEntry[] PushBuffer = NvGpuPushBuffer.Decode(Data);
  139. Context.Ns.Gpu.Fifo.PushBuffer(Vmm, PushBuffer);
  140. }
  141. public static NvChannel GetChannel(ServiceCtx Context, NvChannelName Channel)
  142. {
  143. ChannelsPerProcess Cpp = Channels.GetOrAdd(Context.Process, (Key) =>
  144. {
  145. return new ChannelsPerProcess();
  146. });
  147. return Cpp.Channels[Channel];
  148. }
  149. public static void UnloadProcess(Process Process)
  150. {
  151. Channels.TryRemove(Process, out _);
  152. }
  153. }
  154. }