NvHostCtrlGpuDeviceFile.cs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. using Ryujinx.Common.Logging;
  2. using Ryujinx.HLE.HOS.Kernel.Common;
  3. using Ryujinx.HLE.HOS.Kernel.Threading;
  4. using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu.Types;
  5. using Ryujinx.Memory;
  6. using System;
  7. using System.Diagnostics;
  8. namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu
  9. {
  10. class NvHostCtrlGpuDeviceFile : NvDeviceFile
  11. {
  12. private static Stopwatch _pTimer = new Stopwatch();
  13. private static double _ticksToNs = (1.0 / Stopwatch.Frequency) * 1_000_000_000;
  14. private KEvent _errorEvent;
  15. private KEvent _unknownEvent;
  16. public NvHostCtrlGpuDeviceFile(ServiceCtx context, IVirtualMemoryManager memory, long owner) : base(context, owner)
  17. {
  18. _errorEvent = new KEvent(context.Device.System.KernelContext);
  19. _unknownEvent = new KEvent(context.Device.System.KernelContext);
  20. }
  21. static NvHostCtrlGpuDeviceFile()
  22. {
  23. _pTimer.Start();
  24. }
  25. public override NvInternalResult Ioctl(NvIoctl command, Span<byte> arguments)
  26. {
  27. NvInternalResult result = NvInternalResult.NotImplemented;
  28. if (command.Type == NvIoctl.NvGpuMagic)
  29. {
  30. switch (command.Number)
  31. {
  32. case 0x01:
  33. result = CallIoctlMethod<ZcullGetCtxSizeArguments>(ZcullGetCtxSize, arguments);
  34. break;
  35. case 0x02:
  36. result = CallIoctlMethod<ZcullGetInfoArguments>(ZcullGetInfo, arguments);
  37. break;
  38. case 0x03:
  39. result = CallIoctlMethod<ZbcSetTableArguments>(ZbcSetTable, arguments);
  40. break;
  41. case 0x05:
  42. result = CallIoctlMethod<GetCharacteristicsArguments>(GetCharacteristics, arguments);
  43. break;
  44. case 0x06:
  45. result = CallIoctlMethod<GetTpcMasksArguments>(GetTpcMasks, arguments);
  46. break;
  47. case 0x14:
  48. result = CallIoctlMethod<GetActiveSlotMaskArguments>(GetActiveSlotMask, arguments);
  49. break;
  50. case 0x1c:
  51. result = CallIoctlMethod<GetGpuTimeArguments>(GetGpuTime, arguments);
  52. break;
  53. }
  54. }
  55. return result;
  56. }
  57. public override NvInternalResult Ioctl3(NvIoctl command, Span<byte> arguments, Span<byte> inlineOutBuffer)
  58. {
  59. NvInternalResult result = NvInternalResult.NotImplemented;
  60. if (command.Type == NvIoctl.NvGpuMagic)
  61. {
  62. switch (command.Number)
  63. {
  64. case 0x05:
  65. result = CallIoctlMethod<GetCharacteristicsArguments, GpuCharacteristics>(GetCharacteristics, arguments, inlineOutBuffer);
  66. break;
  67. case 0x06:
  68. result = CallIoctlMethod<GetTpcMasksArguments, int>(GetTpcMasks, arguments, inlineOutBuffer);
  69. break;
  70. }
  71. }
  72. return result;
  73. }
  74. public override NvInternalResult QueryEvent(out int eventHandle, uint eventId)
  75. {
  76. // TODO: accurately represent and implement those events.
  77. KEvent targetEvent = null;
  78. switch (eventId)
  79. {
  80. case 0x1:
  81. targetEvent = _errorEvent;
  82. break;
  83. case 0x2:
  84. targetEvent = _unknownEvent;
  85. break;
  86. }
  87. if (targetEvent != null)
  88. {
  89. if (Context.Process.HandleTable.GenerateHandle(targetEvent.ReadableEvent, out eventHandle) != KernelResult.Success)
  90. {
  91. throw new InvalidOperationException("Out of handles!");
  92. }
  93. }
  94. else
  95. {
  96. eventHandle = 0;
  97. return NvInternalResult.InvalidInput;
  98. }
  99. return NvInternalResult.Success;
  100. }
  101. public override void Close() { }
  102. private NvInternalResult ZcullGetCtxSize(ref ZcullGetCtxSizeArguments arguments)
  103. {
  104. arguments.Size = 1;
  105. return NvInternalResult.Success;
  106. }
  107. private NvInternalResult ZcullGetInfo(ref ZcullGetInfoArguments arguments)
  108. {
  109. arguments.WidthAlignPixels = 0x20;
  110. arguments.HeightAlignPixels = 0x20;
  111. arguments.PixelSquaresByAliquots = 0x400;
  112. arguments.AliquotTotal = 0x800;
  113. arguments.RegionByteMultiplier = 0x20;
  114. arguments.RegionHeaderSize = 0x20;
  115. arguments.SubregionHeaderSize = 0xc0;
  116. arguments.SubregionWidthAlignPixels = 0x20;
  117. arguments.SubregionHeightAlignPixels = 0x40;
  118. arguments.SubregionCount = 0x10;
  119. return NvInternalResult.Success;
  120. }
  121. private NvInternalResult ZbcSetTable(ref ZbcSetTableArguments arguments)
  122. {
  123. Logger.Stub?.PrintStub(LogClass.ServiceNv);
  124. return NvInternalResult.Success;
  125. }
  126. private NvInternalResult GetCharacteristics(ref GetCharacteristicsArguments arguments)
  127. {
  128. return GetCharacteristics(ref arguments, ref arguments.Characteristics);
  129. }
  130. private NvInternalResult GetCharacteristics(ref GetCharacteristicsArguments arguments, ref GpuCharacteristics characteristics)
  131. {
  132. arguments.Header.BufferSize = 0xa0;
  133. characteristics.Arch = 0x120;
  134. characteristics.Impl = 0xb;
  135. characteristics.Rev = 0xa1;
  136. characteristics.NumGpc = 0x1;
  137. characteristics.L2CacheSize = 0x40000;
  138. characteristics.OnBoardVideoMemorySize = 0x0;
  139. characteristics.NumTpcPerGpc = 0x2;
  140. characteristics.BusType = 0x20;
  141. characteristics.BigPageSize = 0x20000;
  142. characteristics.CompressionPageSize = 0x20000;
  143. characteristics.PdeCoverageBitCount = 0x1b;
  144. characteristics.AvailableBigPageSizes = 0x30000;
  145. characteristics.GpcMask = 0x1;
  146. characteristics.SmArchSmVersion = 0x503;
  147. characteristics.SmArchSpaVersion = 0x503;
  148. characteristics.SmArchWarpCount = 0x80;
  149. characteristics.GpuVaBitCount = 0x28;
  150. characteristics.Reserved = 0x0;
  151. characteristics.Flags = 0x55;
  152. characteristics.TwodClass = 0x902d;
  153. characteristics.ThreedClass = 0xb197;
  154. characteristics.ComputeClass = 0xb1c0;
  155. characteristics.GpfifoClass = 0xb06f;
  156. characteristics.InlineToMemoryClass = 0xa140;
  157. characteristics.DmaCopyClass = 0xb0b5;
  158. characteristics.MaxFbpsCount = 0x1;
  159. characteristics.FbpEnMask = 0x0;
  160. characteristics.MaxLtcPerFbp = 0x2;
  161. characteristics.MaxLtsPerLtc = 0x1;
  162. characteristics.MaxTexPerTpc = 0x0;
  163. characteristics.MaxGpcCount = 0x1;
  164. characteristics.RopL2EnMask0 = 0x21d70;
  165. characteristics.RopL2EnMask1 = 0x0;
  166. characteristics.ChipName = 0x6230326d67;
  167. characteristics.GrCompbitStoreBaseHw = 0x0;
  168. arguments.Characteristics = characteristics;
  169. return NvInternalResult.Success;
  170. }
  171. private NvInternalResult GetTpcMasks(ref GetTpcMasksArguments arguments)
  172. {
  173. return GetTpcMasks(ref arguments, ref arguments.TpcMask);
  174. }
  175. private NvInternalResult GetTpcMasks(ref GetTpcMasksArguments arguments, ref int tpcMask)
  176. {
  177. if (arguments.MaskBufferSize != 0)
  178. {
  179. tpcMask = 3;
  180. arguments.TpcMask = tpcMask;
  181. }
  182. return NvInternalResult.Success;
  183. }
  184. private NvInternalResult GetActiveSlotMask(ref GetActiveSlotMaskArguments arguments)
  185. {
  186. Logger.Stub?.PrintStub(LogClass.ServiceNv);
  187. arguments.Slot = 0x07;
  188. arguments.Mask = 0x01;
  189. return NvInternalResult.Success;
  190. }
  191. private NvInternalResult GetGpuTime(ref GetGpuTimeArguments arguments)
  192. {
  193. arguments.Timestamp = GetPTimerNanoSeconds();
  194. return NvInternalResult.Success;
  195. }
  196. private static ulong GetPTimerNanoSeconds()
  197. {
  198. double ticks = _pTimer.ElapsedTicks;
  199. return (ulong)(ticks * _ticksToNs) & 0xff_ffff_ffff_ffff;
  200. }
  201. }
  202. }