static.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include <chrono>
  4. #include "common/scope_exit.h"
  5. #include "core/core.h"
  6. #include "core/hle/kernel/k_shared_memory.h"
  7. #include "core/hle/kernel/svc.h"
  8. #include "core/hle/service/cmif_serialization.h"
  9. #include "core/hle/service/glue/time/file_timestamp_worker.h"
  10. #include "core/hle/service/glue/time/static.h"
  11. #include "core/hle/service/psc/time/errors.h"
  12. #include "core/hle/service/psc/time/service_manager.h"
  13. #include "core/hle/service/psc/time/static.h"
  14. #include "core/hle/service/psc/time/steady_clock.h"
  15. #include "core/hle/service/psc/time/system_clock.h"
  16. #include "core/hle/service/psc/time/time_zone_service.h"
  17. #include "core/hle/service/set/system_settings_server.h"
  18. #include "core/hle/service/sm/sm.h"
  19. namespace Service::Glue::Time {
  20. namespace {
  21. template <typename T>
  22. T GetSettingsItemValue(std::shared_ptr<Service::Set::ISystemSettingsServer>& set_sys,
  23. const char* category, const char* name) {
  24. std::vector<u8> interval_buf;
  25. auto res = set_sys->GetSettingsItemValue(interval_buf, category, name);
  26. ASSERT(res == ResultSuccess);
  27. T v{};
  28. std::memcpy(&v, interval_buf.data(), sizeof(T));
  29. return v;
  30. }
  31. } // namespace
  32. StaticService::StaticService(Core::System& system_,
  33. Service::PSC::Time::StaticServiceSetupInfo setup_info,
  34. std::shared_ptr<TimeManager> time, const char* name)
  35. : ServiceFramework{system_, name}, m_system{system_}, m_time_m{time->m_time_m},
  36. m_setup_info{setup_info}, m_time_sm{time->m_time_sm},
  37. m_file_timestamp_worker{time->m_file_timestamp_worker}, m_standard_steady_clock_resource{
  38. time->m_steady_clock_resource} {
  39. // clang-format off
  40. static const FunctionInfo functions[] = {
  41. {0, D<&StaticService::GetStandardUserSystemClock>, "GetStandardUserSystemClock"},
  42. {1, D<&StaticService::GetStandardNetworkSystemClock>, "GetStandardNetworkSystemClock"},
  43. {2, D<&StaticService::GetStandardSteadyClock>, "GetStandardSteadyClock"},
  44. {3, D<&StaticService::GetTimeZoneService>, "GetTimeZoneService"},
  45. {4, D<&StaticService::GetStandardLocalSystemClock>, "GetStandardLocalSystemClock"},
  46. {5, D<&StaticService::GetEphemeralNetworkSystemClock>, "GetEphemeralNetworkSystemClock"},
  47. {20, D<&StaticService::GetSharedMemoryNativeHandle>, "GetSharedMemoryNativeHandle"},
  48. {50, D<&StaticService::SetStandardSteadyClockInternalOffset>, "SetStandardSteadyClockInternalOffset"},
  49. {51, D<&StaticService::GetStandardSteadyClockRtcValue>, "GetStandardSteadyClockRtcValue"},
  50. {100, D<&StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled>, "IsStandardUserSystemClockAutomaticCorrectionEnabled"},
  51. {101, D<&StaticService::SetStandardUserSystemClockAutomaticCorrectionEnabled>, "SetStandardUserSystemClockAutomaticCorrectionEnabled"},
  52. {102, D<&StaticService::GetStandardUserSystemClockInitialYear>, "GetStandardUserSystemClockInitialYear"},
  53. {200, D<&StaticService::IsStandardNetworkSystemClockAccuracySufficient>, "IsStandardNetworkSystemClockAccuracySufficient"},
  54. {201, D<&StaticService::GetStandardUserSystemClockAutomaticCorrectionUpdatedTime>, "GetStandardUserSystemClockAutomaticCorrectionUpdatedTime"},
  55. {300, D<&StaticService::CalculateMonotonicSystemClockBaseTimePoint>, "CalculateMonotonicSystemClockBaseTimePoint"},
  56. {400, D<&StaticService::GetClockSnapshot>, "GetClockSnapshot"},
  57. {401, D<&StaticService::GetClockSnapshotFromSystemClockContext>, "GetClockSnapshotFromSystemClockContext"},
  58. {500, D<&StaticService::CalculateStandardUserSystemClockDifferenceByUser>, "CalculateStandardUserSystemClockDifferenceByUser"},
  59. {501, D<&StaticService::CalculateSpanBetween>, "CalculateSpanBetween"},
  60. };
  61. // clang-format on
  62. RegisterHandlers(functions);
  63. m_set_sys =
  64. m_system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true);
  65. if (m_setup_info.can_write_local_clock && m_setup_info.can_write_user_clock &&
  66. !m_setup_info.can_write_network_clock && m_setup_info.can_write_timezone_device_location &&
  67. !m_setup_info.can_write_steady_clock && !m_setup_info.can_write_uninitialized_clock) {
  68. m_time_m->GetStaticServiceAsAdmin(&m_wrapped_service);
  69. } else if (!m_setup_info.can_write_local_clock && !m_setup_info.can_write_user_clock &&
  70. !m_setup_info.can_write_network_clock &&
  71. !m_setup_info.can_write_timezone_device_location &&
  72. !m_setup_info.can_write_steady_clock &&
  73. !m_setup_info.can_write_uninitialized_clock) {
  74. m_time_m->GetStaticServiceAsUser(&m_wrapped_service);
  75. } else if (!m_setup_info.can_write_local_clock && !m_setup_info.can_write_user_clock &&
  76. !m_setup_info.can_write_network_clock &&
  77. !m_setup_info.can_write_timezone_device_location &&
  78. m_setup_info.can_write_steady_clock && !m_setup_info.can_write_uninitialized_clock) {
  79. m_time_m->GetStaticServiceAsRepair(&m_wrapped_service);
  80. } else {
  81. UNREACHABLE();
  82. }
  83. auto res = m_wrapped_service->GetTimeZoneService(&m_time_zone);
  84. ASSERT(res == ResultSuccess);
  85. }
  86. Result StaticService::GetStandardUserSystemClock(
  87. OutInterface<Service::PSC::Time::SystemClock> out_service) {
  88. LOG_DEBUG(Service_Time, "called.");
  89. R_RETURN(m_wrapped_service->GetStandardUserSystemClock(out_service));
  90. }
  91. Result StaticService::GetStandardNetworkSystemClock(
  92. OutInterface<Service::PSC::Time::SystemClock> out_service) {
  93. LOG_DEBUG(Service_Time, "called.");
  94. R_RETURN(m_wrapped_service->GetStandardNetworkSystemClock(out_service));
  95. }
  96. Result StaticService::GetStandardSteadyClock(
  97. OutInterface<Service::PSC::Time::SteadyClock> out_service) {
  98. LOG_DEBUG(Service_Time, "called.");
  99. R_RETURN(m_wrapped_service->GetStandardSteadyClock(out_service));
  100. }
  101. Result StaticService::GetTimeZoneService(OutInterface<TimeZoneService> out_service) {
  102. LOG_DEBUG(Service_Time, "called.");
  103. *out_service = std::make_shared<TimeZoneService>(
  104. m_system, m_file_timestamp_worker, m_setup_info.can_write_timezone_device_location,
  105. m_time_zone);
  106. R_SUCCEED();
  107. }
  108. Result StaticService::GetStandardLocalSystemClock(
  109. OutInterface<Service::PSC::Time::SystemClock> out_service) {
  110. LOG_DEBUG(Service_Time, "called.");
  111. R_RETURN(m_wrapped_service->GetStandardLocalSystemClock(out_service));
  112. }
  113. Result StaticService::GetEphemeralNetworkSystemClock(
  114. OutInterface<Service::PSC::Time::SystemClock> out_service) {
  115. LOG_DEBUG(Service_Time, "called.");
  116. R_RETURN(m_wrapped_service->GetEphemeralNetworkSystemClock(out_service));
  117. }
  118. Result StaticService::GetSharedMemoryNativeHandle(
  119. OutCopyHandle<Kernel::KSharedMemory> out_shared_memory) {
  120. LOG_DEBUG(Service_Time, "called.");
  121. R_RETURN(m_wrapped_service->GetSharedMemoryNativeHandle(out_shared_memory));
  122. }
  123. Result StaticService::SetStandardSteadyClockInternalOffset(s64 offset_ns) {
  124. LOG_DEBUG(Service_Time, "called. offset_ns={}", offset_ns);
  125. R_UNLESS(m_setup_info.can_write_steady_clock, Service::PSC::Time::ResultPermissionDenied);
  126. R_RETURN(m_set_sys->SetExternalSteadyClockInternalOffset(
  127. offset_ns /
  128. std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::seconds(1)).count()));
  129. }
  130. Result StaticService::GetStandardSteadyClockRtcValue(Out<s64> out_rtc_value) {
  131. SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_rtc_value={}", *out_rtc_value); });
  132. R_RETURN(m_standard_steady_clock_resource.GetRtcTimeInSeconds(*out_rtc_value));
  133. }
  134. Result StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled(
  135. Out<bool> out_automatic_correction) {
  136. SCOPE_EXIT({
  137. LOG_DEBUG(Service_Time, "called. out_automatic_correction={}", *out_automatic_correction);
  138. });
  139. R_RETURN(m_wrapped_service->IsStandardUserSystemClockAutomaticCorrectionEnabled(
  140. out_automatic_correction));
  141. }
  142. Result StaticService::SetStandardUserSystemClockAutomaticCorrectionEnabled(
  143. bool automatic_correction) {
  144. LOG_DEBUG(Service_Time, "called. automatic_correction={}", automatic_correction);
  145. R_RETURN(m_wrapped_service->SetStandardUserSystemClockAutomaticCorrectionEnabled(
  146. automatic_correction));
  147. }
  148. Result StaticService::GetStandardUserSystemClockInitialYear(Out<s32> out_year) {
  149. SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_year={}", *out_year); });
  150. *out_year = GetSettingsItemValue<s32>(m_set_sys, "time", "standard_user_clock_initial_year");
  151. R_SUCCEED();
  152. }
  153. Result StaticService::IsStandardNetworkSystemClockAccuracySufficient(Out<bool> out_is_sufficient) {
  154. SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_is_sufficient={}", *out_is_sufficient); });
  155. R_RETURN(m_wrapped_service->IsStandardNetworkSystemClockAccuracySufficient(out_is_sufficient));
  156. }
  157. Result StaticService::GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(
  158. Out<Service::PSC::Time::SteadyClockTimePoint> out_time_point) {
  159. SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_time_point={}", *out_time_point); });
  160. R_RETURN(m_wrapped_service->GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(
  161. out_time_point));
  162. }
  163. Result StaticService::CalculateMonotonicSystemClockBaseTimePoint(
  164. Out<s64> out_time, Service::PSC::Time::SystemClockContext& context) {
  165. SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. context={} out_time={}", context, *out_time); });
  166. R_RETURN(m_wrapped_service->CalculateMonotonicSystemClockBaseTimePoint(out_time, context));
  167. }
  168. Result StaticService::GetClockSnapshot(OutClockSnapshot out_snapshot,
  169. Service::PSC::Time::TimeType type) {
  170. SCOPE_EXIT(
  171. { LOG_DEBUG(Service_Time, "called. type={} out_snapshot={}", type, *out_snapshot); });
  172. R_RETURN(m_wrapped_service->GetClockSnapshot(out_snapshot, type));
  173. }
  174. Result StaticService::GetClockSnapshotFromSystemClockContext(
  175. Service::PSC::Time::TimeType type, OutClockSnapshot out_snapshot,
  176. Service::PSC::Time::SystemClockContext& user_context,
  177. Service::PSC::Time::SystemClockContext& network_context) {
  178. SCOPE_EXIT({
  179. LOG_DEBUG(Service_Time,
  180. "called. type={} out_snapshot={} user_context={} network_context={}", type,
  181. *out_snapshot, user_context, network_context);
  182. });
  183. R_RETURN(m_wrapped_service->GetClockSnapshotFromSystemClockContext(
  184. type, out_snapshot, user_context, network_context));
  185. }
  186. Result StaticService::CalculateStandardUserSystemClockDifferenceByUser(Out<s64> out_time,
  187. InClockSnapshot a,
  188. InClockSnapshot b) {
  189. SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. a={} b={} out_time={}", *a, *b, *out_time); });
  190. R_RETURN(m_wrapped_service->CalculateStandardUserSystemClockDifferenceByUser(out_time, a, b));
  191. }
  192. Result StaticService::CalculateSpanBetween(Out<s64> out_time, InClockSnapshot a,
  193. InClockSnapshot b) {
  194. SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. a={} b={} out_time={}", *a, *b, *out_time); });
  195. R_RETURN(m_wrapped_service->CalculateSpanBetween(out_time, a, b));
  196. }
  197. } // namespace Service::Glue::Time