time.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // Copyright 2018 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <chrono>
  5. #include "common/logging/log.h"
  6. #include "core/core_timing.h"
  7. #include "core/hle/ipc_helpers.h"
  8. #include "core/hle/kernel/client_port.h"
  9. #include "core/hle/kernel/client_session.h"
  10. #include "core/hle/service/time/time.h"
  11. #include "core/hle/service/time/time_s.h"
  12. #include "core/hle/service/time/time_u.h"
  13. namespace Service {
  14. namespace Time {
  15. class ISystemClock final : public ServiceFramework<ISystemClock> {
  16. public:
  17. ISystemClock() : ServiceFramework("ISystemClock") {
  18. static const FunctionInfo functions[] = {
  19. {0, &ISystemClock::GetCurrentTime, "GetCurrentTime"},
  20. {1, nullptr, "SetCurrentTime"},
  21. {2, &ISystemClock::GetSystemClockContext, "GetSystemClockContext"},
  22. {3, nullptr, "SetSystemClockContext"},
  23. };
  24. RegisterHandlers(functions);
  25. }
  26. private:
  27. void GetCurrentTime(Kernel::HLERequestContext& ctx) {
  28. const s64 time_since_epoch{std::chrono::duration_cast<std::chrono::seconds>(
  29. std::chrono::system_clock::now().time_since_epoch())
  30. .count()};
  31. LOG_DEBUG(Service_Time, "called");
  32. IPC::ResponseBuilder rb{ctx, 4};
  33. rb.Push(RESULT_SUCCESS);
  34. rb.Push<u64>(time_since_epoch);
  35. }
  36. void GetSystemClockContext(Kernel::HLERequestContext& ctx) {
  37. LOG_WARNING(Service_Time, "(STUBBED) called");
  38. SystemClockContext system_clock_ontext{};
  39. IPC::ResponseBuilder rb{ctx, (sizeof(SystemClockContext) / 4) + 2};
  40. rb.Push(RESULT_SUCCESS);
  41. rb.PushRaw(system_clock_ontext);
  42. }
  43. };
  44. class ISteadyClock final : public ServiceFramework<ISteadyClock> {
  45. public:
  46. ISteadyClock() : ServiceFramework("ISteadyClock") {
  47. static const FunctionInfo functions[] = {
  48. {0, &ISteadyClock::GetCurrentTimePoint, "GetCurrentTimePoint"},
  49. };
  50. RegisterHandlers(functions);
  51. }
  52. private:
  53. void GetCurrentTimePoint(Kernel::HLERequestContext& ctx) {
  54. LOG_DEBUG(Service_Time, "called");
  55. SteadyClockTimePoint steady_clock_time_point{cyclesToMs(CoreTiming::GetTicks()) / 1000};
  56. IPC::ResponseBuilder rb{ctx, (sizeof(SteadyClockTimePoint) / 4) + 2};
  57. rb.Push(RESULT_SUCCESS);
  58. rb.PushRaw(steady_clock_time_point);
  59. }
  60. };
  61. class ITimeZoneService final : public ServiceFramework<ITimeZoneService> {
  62. public:
  63. ITimeZoneService() : ServiceFramework("ITimeZoneService") {
  64. static const FunctionInfo functions[] = {
  65. {0, &ITimeZoneService::GetDeviceLocationName, "GetDeviceLocationName"},
  66. {1, nullptr, "SetDeviceLocationName"},
  67. {2, &ITimeZoneService::GetTotalLocationNameCount, "GetTotalLocationNameCount"},
  68. {3, nullptr, "LoadLocationNameList"},
  69. {4, &ITimeZoneService::LoadTimeZoneRule, "LoadTimeZoneRule"},
  70. {5, nullptr, "GetTimeZoneRuleVersion"},
  71. {100, nullptr, "ToCalendarTime"},
  72. {101, &ITimeZoneService::ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"},
  73. {200, nullptr, "ToPosixTime"},
  74. {201, nullptr, "ToPosixTimeWithMyRule"},
  75. };
  76. RegisterHandlers(functions);
  77. }
  78. private:
  79. void GetDeviceLocationName(Kernel::HLERequestContext& ctx) {
  80. LOG_WARNING(Service_Time, "(STUBBED) called");
  81. LocationName location_name{};
  82. IPC::ResponseBuilder rb{ctx, (sizeof(LocationName) / 4) + 2};
  83. rb.Push(RESULT_SUCCESS);
  84. rb.PushRaw(location_name);
  85. }
  86. void GetTotalLocationNameCount(Kernel::HLERequestContext& ctx) {
  87. LOG_WARNING(Service_Time, "(STUBBED) called");
  88. IPC::ResponseBuilder rb{ctx, 3};
  89. rb.Push(RESULT_SUCCESS);
  90. rb.Push<u32>(0);
  91. }
  92. void LoadTimeZoneRule(Kernel::HLERequestContext& ctx) {
  93. LOG_WARNING(Service_Time, "(STUBBED) called");
  94. IPC::ResponseBuilder rb{ctx, 2};
  95. rb.Push(RESULT_SUCCESS);
  96. }
  97. void ToCalendarTimeWithMyRule(Kernel::HLERequestContext& ctx) {
  98. IPC::RequestParser rp{ctx};
  99. u64 posix_time = rp.Pop<u64>();
  100. LOG_WARNING(Service_Time, "(STUBBED) called, posix_time=0x%016lX", posix_time);
  101. CalendarTime calendar_time{2018, 1, 1, 0, 0, 0};
  102. CalendarAdditionalInfo additional_info{};
  103. IPC::ResponseBuilder rb{ctx, 10};
  104. rb.Push(RESULT_SUCCESS);
  105. rb.PushRaw(calendar_time);
  106. rb.PushRaw(additional_info);
  107. }
  108. };
  109. void Module::Interface::GetStandardUserSystemClock(Kernel::HLERequestContext& ctx) {
  110. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  111. rb.Push(RESULT_SUCCESS);
  112. rb.PushIpcInterface<ISystemClock>();
  113. LOG_DEBUG(Service_Time, "called");
  114. }
  115. void Module::Interface::GetStandardNetworkSystemClock(Kernel::HLERequestContext& ctx) {
  116. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  117. rb.Push(RESULT_SUCCESS);
  118. rb.PushIpcInterface<ISystemClock>();
  119. LOG_DEBUG(Service_Time, "called");
  120. }
  121. void Module::Interface::GetStandardSteadyClock(Kernel::HLERequestContext& ctx) {
  122. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  123. rb.Push(RESULT_SUCCESS);
  124. rb.PushIpcInterface<ISteadyClock>();
  125. LOG_DEBUG(Service_Time, "called");
  126. }
  127. void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) {
  128. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  129. rb.Push(RESULT_SUCCESS);
  130. rb.PushIpcInterface<ITimeZoneService>();
  131. LOG_DEBUG(Service_Time, "called");
  132. }
  133. void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx) {
  134. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  135. rb.Push(RESULT_SUCCESS);
  136. rb.PushIpcInterface<ISystemClock>();
  137. LOG_DEBUG(Service_Time, "called");
  138. }
  139. Module::Interface::Interface(std::shared_ptr<Module> time, const char* name)
  140. : ServiceFramework(name), time(std::move(time)) {}
  141. void InstallInterfaces(SM::ServiceManager& service_manager) {
  142. auto time = std::make_shared<Module>();
  143. std::make_shared<TIME_S>(time)->InstallAsService(service_manager);
  144. std::make_shared<TIME_U>(time)->InstallAsService(service_manager);
  145. }
  146. } // namespace Time
  147. } // namespace Service