ISteadyClock.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. using Ryujinx.Common;
  2. using Ryujinx.HLE.HOS.Services.Time.Clock;
  3. namespace Ryujinx.HLE.HOS.Services.Time.StaticService
  4. {
  5. class ISteadyClock : IpcService
  6. {
  7. private SteadyClockCore _steadyClock;
  8. private bool _writePermission;
  9. private bool _bypassUninitializedClock;
  10. public ISteadyClock(SteadyClockCore steadyClock, bool writePermission, bool bypassUninitializedClock)
  11. {
  12. _steadyClock = steadyClock;
  13. _writePermission = writePermission;
  14. _bypassUninitializedClock = bypassUninitializedClock;
  15. }
  16. [Command(0)]
  17. // GetCurrentTimePoint() -> nn::time::SteadyClockTimePoint
  18. public ResultCode GetCurrentTimePoint(ServiceCtx context)
  19. {
  20. if (!_bypassUninitializedClock && !_steadyClock.IsInitialized())
  21. {
  22. return ResultCode.UninitializedClock;
  23. }
  24. SteadyClockTimePoint currentTimePoint = _steadyClock.GetCurrentTimePoint(context.Thread);
  25. context.ResponseData.WriteStruct(currentTimePoint);
  26. return ResultCode.Success;
  27. }
  28. [Command(2)]
  29. // GetTestOffset() -> nn::TimeSpanType
  30. public ResultCode GetTestOffset(ServiceCtx context)
  31. {
  32. if (!_bypassUninitializedClock && !_steadyClock.IsInitialized())
  33. {
  34. return ResultCode.UninitializedClock;
  35. }
  36. context.ResponseData.WriteStruct(_steadyClock.GetTestOffset());
  37. return ResultCode.Success;
  38. }
  39. [Command(3)]
  40. // SetTestOffset(nn::TimeSpanType)
  41. public ResultCode SetTestOffset(ServiceCtx context)
  42. {
  43. if (!_writePermission)
  44. {
  45. return ResultCode.PermissionDenied;
  46. }
  47. if (!_bypassUninitializedClock && !_steadyClock.IsInitialized())
  48. {
  49. return ResultCode.UninitializedClock;
  50. }
  51. TimeSpanType testOffset = context.RequestData.ReadStruct<TimeSpanType>();
  52. _steadyClock.SetTestOffset(testOffset);
  53. return ResultCode.Success;
  54. }
  55. [Command(100)] // 2.0.0+
  56. // GetRtcValue() -> u64
  57. public ResultCode GetRtcValue(ServiceCtx context)
  58. {
  59. if (!_bypassUninitializedClock && !_steadyClock.IsInitialized())
  60. {
  61. return ResultCode.UninitializedClock;
  62. }
  63. ResultCode result = _steadyClock.GetRtcValue(out ulong rtcValue);
  64. if (result == ResultCode.Success)
  65. {
  66. context.ResponseData.Write(rtcValue);
  67. }
  68. return result;
  69. }
  70. [Command(101)] // 2.0.0+
  71. // IsRtcResetDetected() -> bool
  72. public ResultCode IsRtcResetDetected(ServiceCtx context)
  73. {
  74. if (!_bypassUninitializedClock && !_steadyClock.IsInitialized())
  75. {
  76. return ResultCode.UninitializedClock;
  77. }
  78. context.ResponseData.Write(_steadyClock.IsRtcResetDetected());
  79. return ResultCode.Success;
  80. }
  81. [Command(102)] // 2.0.0+
  82. // GetSetupResultValue() -> u32
  83. public ResultCode GetSetupResultValue(ServiceCtx context)
  84. {
  85. if (!_bypassUninitializedClock && !_steadyClock.IsInitialized())
  86. {
  87. return ResultCode.UninitializedClock;
  88. }
  89. context.ResponseData.Write((uint)_steadyClock.GetSetupResultValue());
  90. return ResultCode.Success;
  91. }
  92. [Command(200)] // 3.0.0+
  93. // GetInternalOffset() -> nn::TimeSpanType
  94. public ResultCode GetInternalOffset(ServiceCtx context)
  95. {
  96. if (!_bypassUninitializedClock && !_steadyClock.IsInitialized())
  97. {
  98. return ResultCode.UninitializedClock;
  99. }
  100. context.ResponseData.WriteStruct(_steadyClock.GetInternalOffset());
  101. return ResultCode.Success;
  102. }
  103. [Command(201)] // 3.0.0-3.0.2
  104. // SetInternalOffset(nn::TimeSpanType)
  105. public ResultCode SetInternalOffset(ServiceCtx context)
  106. {
  107. if (!_writePermission)
  108. {
  109. return ResultCode.PermissionDenied;
  110. }
  111. if (!_bypassUninitializedClock && !_steadyClock.IsInitialized())
  112. {
  113. return ResultCode.UninitializedClock;
  114. }
  115. TimeSpanType internalOffset = context.RequestData.ReadStruct<TimeSpanType>();
  116. _steadyClock.SetInternalOffset(internalOffset);
  117. return ResultCode.Success;
  118. }
  119. }
  120. }