diff options
author | Kelebek1 <eeeedddccc@hotmail.co.uk> | 2024-01-26 16:29:04 +0100 |
---|---|---|
committer | Kelebek1 <eeeedddccc@hotmail.co.uk> | 2024-01-27 04:30:09 +0100 |
commit | da410506a401abc853ee23e56ca1e25eb47cd6e6 (patch) | |
tree | 6a42e537b6bfbdb460e7f542e4731fc5cad40dd8 /src/core/hle/service/psc | |
parent | Merge pull request #12808 from t895/uri-moment (diff) | |
download | yuzu-da410506a401abc853ee23e56ca1e25eb47cd6e6.tar yuzu-da410506a401abc853ee23e56ca1e25eb47cd6e6.tar.gz yuzu-da410506a401abc853ee23e56ca1e25eb47cd6e6.tar.bz2 yuzu-da410506a401abc853ee23e56ca1e25eb47cd6e6.tar.lz yuzu-da410506a401abc853ee23e56ca1e25eb47cd6e6.tar.xz yuzu-da410506a401abc853ee23e56ca1e25eb47cd6e6.tar.zst yuzu-da410506a401abc853ee23e56ca1e25eb47cd6e6.zip |
Diffstat (limited to '')
-rw-r--r-- | src/core/hle/service/psc/time/common.h | 135 | ||||
-rw-r--r-- | src/core/hle/service/psc/time/power_state_service.cpp | 28 | ||||
-rw-r--r-- | src/core/hle/service/psc/time/power_state_service.h | 7 | ||||
-rw-r--r-- | src/core/hle/service/psc/time/service_manager.cpp | 438 | ||||
-rw-r--r-- | src/core/hle/service/psc/time/service_manager.h | 60 | ||||
-rw-r--r-- | src/core/hle/service/psc/time/static.cpp | 493 | ||||
-rw-r--r-- | src/core/hle/service/psc/time/static.h | 65 | ||||
-rw-r--r-- | src/core/hle/service/psc/time/steady_clock.cpp | 133 | ||||
-rw-r--r-- | src/core/hle/service/psc/time/steady_clock.h | 21 | ||||
-rw-r--r-- | src/core/hle/service/psc/time/system_clock.cpp | 92 | ||||
-rw-r--r-- | src/core/hle/service/psc/time/system_clock.h | 13 | ||||
-rw-r--r-- | src/core/hle/service/psc/time/time_zone.cpp | 18 | ||||
-rw-r--r-- | src/core/hle/service/psc/time/time_zone.h | 15 | ||||
-rw-r--r-- | src/core/hle/service/psc/time/time_zone_service.cpp | 322 | ||||
-rw-r--r-- | src/core/hle/service/psc/time/time_zone_service.h | 57 |
15 files changed, 681 insertions, 1216 deletions
diff --git a/src/core/hle/service/psc/time/common.h b/src/core/hle/service/psc/time/common.h index d17b31143..596828b8b 100644 --- a/src/core/hle/service/psc/time/common.h +++ b/src/core/hle/service/psc/time/common.h @@ -5,6 +5,7 @@ #include <array> #include <chrono> +#include <fmt/format.h> #include "common/common_types.h" #include "common/intrusive_list.h" @@ -21,8 +22,14 @@ class System; namespace Service::PSC::Time { using ClockSourceId = Common::UUID; +enum class TimeType : u8 { + UserSystemClock = 0, + NetworkSystemClock = 1, + LocalSystemClock = 2, +}; + struct SteadyClockTimePoint { - constexpr bool IdMatches(SteadyClockTimePoint& other) { + constexpr bool IdMatches(const SteadyClockTimePoint& other) const { return clock_source_id == other.clock_source_id; } bool operator==(const SteadyClockTimePoint& other) const = default; @@ -42,12 +49,6 @@ struct SystemClockContext { static_assert(sizeof(SystemClockContext) == 0x20, "SystemClockContext has the wrong size!"); static_assert(std::is_trivial_v<SystemClockContext>); -enum class TimeType : u8 { - UserSystemClock, - NetworkSystemClock, - LocalSystemClock, -}; - struct CalendarTime { s16 year; s8 month; @@ -67,14 +68,10 @@ struct CalendarAdditionalInfo { }; static_assert(sizeof(CalendarAdditionalInfo) == 0x18, "CalendarAdditionalInfo has the wrong size!"); -struct LocationName { - std::array<char, 36> name; -}; +using LocationName = std::array<char, 0x24>; static_assert(sizeof(LocationName) == 0x24, "LocationName has the wrong size!"); -struct RuleVersion { - std::array<char, 16> version; -}; +using RuleVersion = std::array<char, 0x10>; static_assert(sizeof(RuleVersion) == 0x10, "RuleVersion has the wrong size!"); struct ClockSnapshot { @@ -152,8 +149,8 @@ constexpr inline std::chrono::nanoseconds ConvertToTimeSpan(s64 ticks) { return std::chrono::nanoseconds(a + b); } -constexpr inline Result GetSpanBetweenTimePoints(s64* out_seconds, SteadyClockTimePoint& a, - SteadyClockTimePoint& b) { +constexpr inline Result GetSpanBetweenTimePoints(s64* out_seconds, const SteadyClockTimePoint& a, + const SteadyClockTimePoint& b) { R_UNLESS(out_seconds, ResultInvalidArgument); R_UNLESS(a.IdMatches(b), ResultInvalidArgument); R_UNLESS(a.time_point >= 0 || b.time_point <= a.time_point + std::numeric_limits<s64>::max(), @@ -166,3 +163,111 @@ constexpr inline Result GetSpanBetweenTimePoints(s64* out_seconds, SteadyClockTi } } // namespace Service::PSC::Time + +template <> +struct fmt::formatter<Service::PSC::Time::TimeType> : fmt::formatter<fmt::string_view> { + template <typename FormatContext> + auto format(Service::PSC::Time::TimeType type, FormatContext& ctx) { + const string_view name = [type] { + using Service::PSC::Time::TimeType; + switch (type) { + case TimeType::UserSystemClock: + return "UserSystemClock"; + case TimeType::NetworkSystemClock: + return "NetworkSystemClock"; + case TimeType::LocalSystemClock: + return "LocalSystemClock"; + } + return "Invalid"; + }(); + return formatter<string_view>::format(name, ctx); + } +}; + +template <> +struct fmt::formatter<Service::PSC::Time::SteadyClockTimePoint> : fmt::formatter<fmt::string_view> { + template <typename FormatContext> + auto format(const Service::PSC::Time::SteadyClockTimePoint& time_point, + FormatContext& ctx) const { + return fmt::format_to(ctx.out(), "time_point={}", time_point.time_point); + } +}; + +template <> +struct fmt::formatter<Service::PSC::Time::SystemClockContext> : fmt::formatter<fmt::string_view> { + template <typename FormatContext> + auto format(const Service::PSC::Time::SystemClockContext& context, FormatContext& ctx) const { + return fmt::format_to(ctx.out(), "offset={} steady_time_point={}", context.offset, + context.steady_time_point.time_point); + } +}; + +template <> +struct fmt::formatter<Service::PSC::Time::CalendarTime> : fmt::formatter<fmt::string_view> { + template <typename FormatContext> + auto format(const Service::PSC::Time::CalendarTime& calendar, FormatContext& ctx) const { + return fmt::format_to(ctx.out(), "{}/{}/{} {}:{}:{}", calendar.day, calendar.month, + calendar.year, calendar.hour, calendar.minute, calendar.second); + } +}; + +template <> +struct fmt::formatter<Service::PSC::Time::CalendarAdditionalInfo> + : fmt::formatter<fmt::string_view> { + template <typename FormatContext> + auto format(const Service::PSC::Time::CalendarAdditionalInfo& additional, + FormatContext& ctx) const { + return fmt::format_to(ctx.out(), "weekday={} yearday={} name={} is_dst={} ut_offset={}", + additional.day_of_week, additional.day_of_year, + additional.name.data(), additional.is_dst, additional.ut_offset); + } +}; + +template <> +struct fmt::formatter<Service::PSC::Time::LocationName> : fmt::formatter<fmt::string_view> { + template <typename FormatContext> + auto format(const Service::PSC::Time::LocationName& name, FormatContext& ctx) const { + std::string_view n{name.data(), name.size()}; + return formatter<string_view>::format(n, ctx); + } +}; + +template <> +struct fmt::formatter<Service::PSC::Time::RuleVersion> : fmt::formatter<fmt::string_view> { + template <typename FormatContext> + auto format(const Service::PSC::Time::RuleVersion& version, FormatContext& ctx) const { + std::string_view v{version.data(), version.size()}; + return formatter<string_view>::format(v, ctx); + } +}; + +template <> +struct fmt::formatter<Service::PSC::Time::ClockSnapshot> : fmt::formatter<fmt::string_view> { + template <typename FormatContext> + auto format(const Service::PSC::Time::ClockSnapshot& snapshot, FormatContext& ctx) const { + return fmt::format_to( + ctx.out(), + "user_context={} network_context={} user_time={} network_time={} user_calendar_time={} " + "network_calendar_time={} user_calendar_additional_time={} " + "network_calendar_additional_time={} steady_clock_time_point={} location={} " + "is_automatic_correction_enabled={} type={}", + snapshot.user_context, snapshot.network_context, snapshot.user_time, + snapshot.network_time, snapshot.user_calendar_time, snapshot.network_calendar_time, + snapshot.user_calendar_additional_time, snapshot.network_calendar_additional_time, + snapshot.steady_clock_time_point, snapshot.location_name, + snapshot.is_automatic_correction_enabled, snapshot.type); + } +}; + +template <> +struct fmt::formatter<Service::PSC::Time::ContinuousAdjustmentTimePoint> + : fmt::formatter<fmt::string_view> { + template <typename FormatContext> + auto format(const Service::PSC::Time::ContinuousAdjustmentTimePoint& time_point, + FormatContext& ctx) const { + return fmt::format_to(ctx.out(), + "rtc_offset={} diff_scale={} shift_amount={} lower={} upper={}", + time_point.rtc_offset, time_point.diff_scale, time_point.shift_amount, + time_point.lower, time_point.upper); + } +};
\ No newline at end of file diff --git a/src/core/hle/service/psc/time/power_state_service.cpp b/src/core/hle/service/psc/time/power_state_service.cpp index b0ae71bf9..ab1d32c70 100644 --- a/src/core/hle/service/psc/time/power_state_service.cpp +++ b/src/core/hle/service/psc/time/power_state_service.cpp @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/psc/time/power_state_service.h" namespace Service::PSC::Time { @@ -11,39 +12,34 @@ IPowerStateRequestHandler::IPowerStateRequestHandler( power_state_request_manager} { // clang-format off static const FunctionInfo functions[] = { - {0, &IPowerStateRequestHandler::GetPowerStateRequestEventReadableHandle, "GetPowerStateRequestEventReadableHandle"}, - {1, &IPowerStateRequestHandler::GetAndClearPowerStateRequest, "GetAndClearPowerStateRequest"}, + {0, D<&IPowerStateRequestHandler::GetPowerStateRequestEventReadableHandle>, "GetPowerStateRequestEventReadableHandle"}, + {1, D<&IPowerStateRequestHandler::GetAndClearPowerStateRequest>, "GetAndClearPowerStateRequest"}, }; // clang-format on RegisterHandlers(functions); } -void IPowerStateRequestHandler::GetPowerStateRequestEventReadableHandle(HLERequestContext& ctx) { +Result IPowerStateRequestHandler::GetPowerStateRequestEventReadableHandle( + OutCopyHandle<Kernel::KReadableEvent> out_event) { LOG_DEBUG(Service_Time, "called."); - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(m_power_state_request_manager.GetReadableEvent()); + *out_event = &m_power_state_request_manager.GetReadableEvent(); + R_SUCCEED(); } -void IPowerStateRequestHandler::GetAndClearPowerStateRequest(HLERequestContext& ctx) { +Result IPowerStateRequestHandler::GetAndClearPowerStateRequest(Out<bool> out_cleared, + Out<u32> out_priority) { LOG_DEBUG(Service_Time, "called."); u32 priority{}; auto cleared = m_power_state_request_manager.GetAndClearPowerStateRequest(priority); + *out_cleared = cleared; if (cleared) { - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push(priority); - rb.Push(cleared); - return; + *out_priority = priority; } - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(cleared); + R_SUCCEED(); } } // namespace Service::PSC::Time diff --git a/src/core/hle/service/psc/time/power_state_service.h b/src/core/hle/service/psc/time/power_state_service.h index 3ebfddb79..56e2c4b87 100644 --- a/src/core/hle/service/psc/time/power_state_service.h +++ b/src/core/hle/service/psc/time/power_state_service.h @@ -3,6 +3,7 @@ #pragma once +#include "core/hle/service/cmif_types.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/psc/time/power_state_request_manager.h" #include "core/hle/service/server_manager.h" @@ -21,10 +22,10 @@ public: ~IPowerStateRequestHandler() override = default; -private: - void GetPowerStateRequestEventReadableHandle(HLERequestContext& ctx); - void GetAndClearPowerStateRequest(HLERequestContext& ctx); + Result GetPowerStateRequestEventReadableHandle(OutCopyHandle<Kernel::KReadableEvent> out_event); + Result GetAndClearPowerStateRequest(Out<bool> out_cleared, Out<u32> out_priority); +private: Core::System& m_system; PowerStateRequestManager& m_power_state_request_manager; }; diff --git a/src/core/hle/service/psc/time/service_manager.cpp b/src/core/hle/service/psc/time/service_manager.cpp index 60820aa9b..ec906b723 100644 --- a/src/core/hle/service/psc/time/service_manager.cpp +++ b/src/core/hle/service/psc/time/service_manager.cpp @@ -3,6 +3,7 @@ #include "core/core.h" #include "core/core_timing.h" +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/psc/time/power_state_service.h" #include "core/hle/service/psc/time/service_manager.h" #include "core/hle/service/psc/time/static.h" @@ -25,24 +26,24 @@ ServiceManager::ServiceManager(Core::System& system_, std::shared_ptr<TimeManage m_local_operation{m_system}, m_network_operation{m_system}, m_ephemeral_operation{m_system} { // clang-format off static const FunctionInfo functions[] = { - {0, &ServiceManager::Handle_GetStaticServiceAsUser, "GetStaticServiceAsUser"}, - {5, &ServiceManager::Handle_GetStaticServiceAsAdmin, "GetStaticServiceAsAdmin"}, - {6, &ServiceManager::Handle_GetStaticServiceAsRepair, "GetStaticServiceAsRepair"}, - {9, &ServiceManager::Handle_GetStaticServiceAsServiceManager, "GetStaticServiceAsServiceManager"}, - {10, &ServiceManager::Handle_SetupStandardSteadyClockCore, "SetupStandardSteadyClockCore"}, - {11, &ServiceManager::Handle_SetupStandardLocalSystemClockCore, "SetupStandardLocalSystemClockCore"}, - {12, &ServiceManager::Handle_SetupStandardNetworkSystemClockCore, "SetupStandardNetworkSystemClockCore"}, - {13, &ServiceManager::Handle_SetupStandardUserSystemClockCore, "SetupStandardUserSystemClockCore"}, - {14, &ServiceManager::Handle_SetupTimeZoneServiceCore, "SetupTimeZoneServiceCore"}, - {15, &ServiceManager::Handle_SetupEphemeralNetworkSystemClockCore, "SetupEphemeralNetworkSystemClockCore"}, - {50, &ServiceManager::Handle_GetStandardLocalClockOperationEvent, "GetStandardLocalClockOperationEvent"}, - {51, &ServiceManager::Handle_GetStandardNetworkClockOperationEventForServiceManager, "GetStandardNetworkClockOperationEventForServiceManager"}, - {52, &ServiceManager::Handle_GetEphemeralNetworkClockOperationEventForServiceManager, "GetEphemeralNetworkClockOperationEventForServiceManager"}, - {60, &ServiceManager::Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent, "GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent"}, - {100, &ServiceManager::Handle_SetStandardSteadyClockBaseTime, "SetStandardSteadyClockBaseTime"}, - {200, &ServiceManager::Handle_GetClosestAlarmUpdatedEvent, "GetClosestAlarmUpdatedEvent"}, - {201, &ServiceManager::Handle_CheckAndSignalAlarms, "CheckAndSignalAlarms"}, - {202, &ServiceManager::Handle_GetClosestAlarmInfo, "GetClosestAlarmInfo "}, + {0, D<&ServiceManager::GetStaticServiceAsUser>, "GetStaticServiceAsUser"}, + {5, D<&ServiceManager::GetStaticServiceAsAdmin>, "GetStaticServiceAsAdmin"}, + {6, D<&ServiceManager::GetStaticServiceAsRepair>, "GetStaticServiceAsRepair"}, + {9, D<&ServiceManager::GetStaticServiceAsServiceManager>, "GetStaticServiceAsServiceManager"}, + {10, D<&ServiceManager::SetupStandardSteadyClockCore>, "SetupStandardSteadyClockCore"}, + {11, D<&ServiceManager::SetupStandardLocalSystemClockCore>, "SetupStandardLocalSystemClockCore"}, + {12, D<&ServiceManager::SetupStandardNetworkSystemClockCore>, "SetupStandardNetworkSystemClockCore"}, + {13, D<&ServiceManager::SetupStandardUserSystemClockCore>, "SetupStandardUserSystemClockCore"}, + {14, D<&ServiceManager::SetupTimeZoneServiceCore>, "SetupTimeZoneServiceCore"}, + {15, D<&ServiceManager::SetupEphemeralNetworkSystemClockCore>, "SetupEphemeralNetworkSystemClockCore"}, + {50, D<&ServiceManager::GetStandardLocalClockOperationEvent>, "GetStandardLocalClockOperationEvent"}, + {51, D<&ServiceManager::GetStandardNetworkClockOperationEventForServiceManager>, "GetStandardNetworkClockOperationEventForServiceManager"}, + {52, D<&ServiceManager::GetEphemeralNetworkClockOperationEventForServiceManager>, "GetEphemeralNetworkClockOperationEventForServiceManager"}, + {60, D<&ServiceManager::GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent>, "GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent"}, + {100, D<&ServiceManager::SetStandardSteadyClockBaseTime>, "SetStandardSteadyClockBaseTime"}, + {200, D<&ServiceManager::GetClosestAlarmUpdatedEvent>, "GetClosestAlarmUpdatedEvent"}, + {201, D<&ServiceManager::CheckAndSignalAlarms>, "CheckAndSignalAlarms"}, + {202, D<&ServiceManager::GetClosestAlarmInfo>, "GetClosestAlarmInfo "}, }; // clang-format on RegisterHandlers(functions); @@ -52,302 +53,39 @@ ServiceManager::ServiceManager(Core::System& system_, std::shared_ptr<TimeManage m_ephemeral_system_context_writer.Link(m_ephemeral_operation); } -void ServiceManager::SetupSAndP() { - if (!m_is_s_and_p_setup) { - m_is_s_and_p_setup = true; - m_server_manager.RegisterNamedService( - "time:s", std::make_shared<StaticService>( - m_system, StaticServiceSetupInfo{0, 0, 1, 0, 0, 0}, m_time, "time:s")); - m_server_manager.RegisterNamedService("time:p", - std::make_shared<IPowerStateRequestHandler>( - m_system, m_time->m_power_state_request_manager)); - } -} - -void ServiceManager::CheckAndSetupServicesSAndP() { - if (m_local_system_clock.IsInitialized() && m_user_system_clock.IsInitialized() && - m_network_system_clock.IsInitialized() && m_steady_clock.IsInitialized() && - m_time_zone.IsInitialized() && m_ephemeral_network_clock.IsInitialized()) { - SetupSAndP(); - } -} - -void ServiceManager::Handle_GetStaticServiceAsUser(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr<StaticService> service{}; - auto res = GetStaticServiceAsUser(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface<StaticService>(std::move(service)); -} - -void ServiceManager::Handle_GetStaticServiceAsAdmin(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr<StaticService> service{}; - auto res = GetStaticServiceAsAdmin(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface<StaticService>(std::move(service)); -} - -void ServiceManager::Handle_GetStaticServiceAsRepair(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr<StaticService> service{}; - auto res = GetStaticServiceAsRepair(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface<StaticService>(std::move(service)); -} - -void ServiceManager::Handle_GetStaticServiceAsServiceManager(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr<StaticService> service{}; - auto res = GetStaticServiceAsServiceManager(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface<StaticService>(std::move(service)); -} - -void ServiceManager::Handle_SetupStandardSteadyClockCore(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - struct Parameters { - bool reset_detected; - Common::UUID clock_source_id; - s64 rtc_offset; - s64 internal_offset; - s64 test_offset; - }; - static_assert(sizeof(Parameters) == 0x30); - - IPC::RequestParser rp{ctx}; - auto params{rp.PopRaw<Parameters>()}; - - auto res = SetupStandardSteadyClockCore(params.clock_source_id, params.rtc_offset, - params.internal_offset, params.test_offset, - params.reset_detected); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void ServiceManager::Handle_SetupStandardLocalSystemClockCore(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto context{rp.PopRaw<SystemClockContext>()}; - auto time{rp.Pop<s64>()}; - - auto res = SetupStandardLocalSystemClockCore(context, time); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void ServiceManager::Handle_SetupStandardNetworkSystemClockCore(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto context{rp.PopRaw<SystemClockContext>()}; - auto accuracy{rp.Pop<s64>()}; - - auto res = SetupStandardNetworkSystemClockCore(context, accuracy); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void ServiceManager::Handle_SetupStandardUserSystemClockCore(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - struct Parameters { - bool automatic_correction; - SteadyClockTimePoint time_point; - }; - static_assert(sizeof(Parameters) == 0x20); - - IPC::RequestParser rp{ctx}; - auto params{rp.PopRaw<Parameters>()}; - - auto res = SetupStandardUserSystemClockCore(params.time_point, params.automatic_correction); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void ServiceManager::Handle_SetupTimeZoneServiceCore(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - struct Parameters { - u32 location_count; - LocationName name; - SteadyClockTimePoint time_point; - RuleVersion rule_version; - }; - static_assert(sizeof(Parameters) == 0x50); - - IPC::RequestParser rp{ctx}; - auto params{rp.PopRaw<Parameters>()}; - - auto rule_buffer{ctx.ReadBuffer()}; - - auto res = SetupTimeZoneServiceCore(params.name, params.time_point, params.rule_version, - params.location_count, rule_buffer); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void ServiceManager::Handle_SetupEphemeralNetworkSystemClockCore(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - auto res = SetupEphemeralNetworkSystemClockCore(); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void ServiceManager::Handle_GetStandardLocalClockOperationEvent(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Kernel::KEvent* event{}; - auto res = GetStandardLocalClockOperationEvent(&event); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(res); - rb.PushCopyObjects(event->GetReadableEvent()); -} - -void ServiceManager::Handle_GetStandardNetworkClockOperationEventForServiceManager( - HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Kernel::KEvent* event{}; - auto res = GetStandardNetworkClockOperationEventForServiceManager(&event); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(res); - rb.PushCopyObjects(event); -} - -void ServiceManager::Handle_GetEphemeralNetworkClockOperationEventForServiceManager( - HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Kernel::KEvent* event{}; - auto res = GetEphemeralNetworkClockOperationEventForServiceManager(&event); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(res); - rb.PushCopyObjects(event); -} - -void ServiceManager::Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent( - HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Kernel::KEvent* event{}; - auto res = GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent(&event); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(res); - rb.PushCopyObjects(event); -} - -void ServiceManager::Handle_SetStandardSteadyClockBaseTime(HLERequestContext& ctx) { +Result ServiceManager::GetStaticServiceAsUser(OutInterface<StaticService> out_service) { LOG_DEBUG(Service_Time, "called."); - IPC::RequestParser rp{ctx}; - auto base_time{rp.Pop<s64>()}; - - auto res = SetStandardSteadyClockBaseTime(base_time); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); + R_RETURN(GetStaticService(out_service, StaticServiceSetupInfo{0, 0, 0, 0, 0, 0}, "time:u")); } -void ServiceManager::Handle_GetClosestAlarmUpdatedEvent(HLERequestContext& ctx) { +Result ServiceManager::GetStaticServiceAsAdmin(OutInterface<StaticService> out_service) { LOG_DEBUG(Service_Time, "called."); - Kernel::KEvent* event{}; - auto res = GetClosestAlarmUpdatedEvent(&event); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.PushCopyObjects(event->GetReadableEvent()); + R_RETURN(GetStaticService(out_service, StaticServiceSetupInfo{1, 1, 0, 1, 0, 0}, "time:a")); } -void ServiceManager::Handle_CheckAndSignalAlarms(HLERequestContext& ctx) { +Result ServiceManager::GetStaticServiceAsRepair(OutInterface<StaticService> out_service) { LOG_DEBUG(Service_Time, "called."); - auto res = CheckAndSignalAlarms(); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); + R_RETURN(GetStaticService(out_service, StaticServiceSetupInfo{0, 0, 0, 0, 1, 0}, "time:r")); } -void ServiceManager::Handle_GetClosestAlarmInfo(HLERequestContext& ctx) { +Result ServiceManager::GetStaticServiceAsServiceManager(OutInterface<StaticService> out_service) { LOG_DEBUG(Service_Time, "called."); - AlarmInfo alarm_info{}; - bool is_valid{}; - s64 time{}; - auto res = GetClosestAlarmInfo(is_valid, alarm_info, time); - - struct OutParameters { - bool is_valid; - AlarmInfo alarm_info; - s64 time; - }; - static_assert(sizeof(OutParameters) == 0x20); - - OutParameters out_params{ - .is_valid = is_valid, - .alarm_info = alarm_info, - .time = time, - }; - - IPC::ResponseBuilder rb{ctx, 2 + sizeof(OutParameters) / sizeof(u32)}; - rb.Push(res); - rb.PushRaw<OutParameters>(out_params); -} - -// =============================== Implementations =========================== - -Result ServiceManager::GetStaticService(std::shared_ptr<StaticService>& out_service, - StaticServiceSetupInfo setup_info, const char* name) { - out_service = std::make_shared<StaticService>(m_system, setup_info, m_time, name); - R_SUCCEED(); -} - -Result ServiceManager::GetStaticServiceAsUser(std::shared_ptr<StaticService>& out_service) { - R_RETURN(GetStaticService(out_service, StaticServiceSetupInfo{0, 0, 0, 0, 0, 0}, "time:u")); -} - -Result ServiceManager::GetStaticServiceAsAdmin(std::shared_ptr<StaticService>& out_service) { - R_RETURN(GetStaticService(out_service, StaticServiceSetupInfo{1, 1, 0, 1, 0, 0}, "time:a")); -} - -Result ServiceManager::GetStaticServiceAsRepair(std::shared_ptr<StaticService>& out_service) { - R_RETURN(GetStaticService(out_service, StaticServiceSetupInfo{0, 0, 0, 0, 1, 0}, "time:r")); -} - -Result ServiceManager::GetStaticServiceAsServiceManager( - std::shared_ptr<StaticService>& out_service) { R_RETURN(GetStaticService(out_service, StaticServiceSetupInfo{1, 1, 1, 1, 1, 0}, "time:sm")); } -Result ServiceManager::SetupStandardSteadyClockCore(Common::UUID& clock_source_id, s64 rtc_offset, - s64 internal_offset, s64 test_offset, - bool is_rtc_reset_detected) { +Result ServiceManager::SetupStandardSteadyClockCore(bool is_rtc_reset_detected, + Common::UUID& clock_source_id, s64 rtc_offset, + s64 internal_offset, s64 test_offset) { + LOG_DEBUG(Service_Time, + "called. is_rtc_reset_detected={} clock_source_id={} rtc_offset={} " + "internal_offset={} test_offset={}", + is_rtc_reset_detected, clock_source_id.RawString(), rtc_offset, internal_offset, + test_offset); + m_steady_clock.Initialize(clock_source_id, rtc_offset, internal_offset, test_offset, is_rtc_reset_detected); auto time = m_steady_clock.GetRawTime(); @@ -365,6 +103,10 @@ Result ServiceManager::SetupStandardSteadyClockCore(Common::UUID& clock_source_i } Result ServiceManager::SetupStandardLocalSystemClockCore(SystemClockContext& context, s64 time) { + LOG_DEBUG(Service_Time, + "called. context={} context.steady_time_point.clock_source_id={} time={}", context, + context.steady_time_point.clock_source_id.RawString(), time); + m_local_system_clock.SetContextWriter(m_local_system_context_writer); m_local_system_clock.Initialize(context, time); @@ -374,6 +116,9 @@ Result ServiceManager::SetupStandardLocalSystemClockCore(SystemClockContext& con Result ServiceManager::SetupStandardNetworkSystemClockCore(SystemClockContext& context, s64 accuracy) { + LOG_DEBUG(Service_Time, "called. context={} steady_time_point.clock_source_id={} accuracy={}", + context, context.steady_time_point.clock_source_id.RawString(), accuracy); + // TODO this is a hack! The network clock should be updated independently, from the ntc service // and maybe elsewhere. We do not do that, so fix the clock to the local clock on first boot // to avoid it being stuck at 0. @@ -388,8 +133,11 @@ Result ServiceManager::SetupStandardNetworkSystemClockCore(SystemClockContext& c R_SUCCEED(); } -Result ServiceManager::SetupStandardUserSystemClockCore(SteadyClockTimePoint& time_point, - bool automatic_correction) { +Result ServiceManager::SetupStandardUserSystemClockCore(bool automatic_correction, + SteadyClockTimePoint& time_point) { + LOG_DEBUG(Service_Time, "called. automatic_correction={} time_point={} clock_source_id={}", + automatic_correction, time_point, time_point.clock_source_id.RawString()); + // TODO this is a hack! The user clock should be updated independently, from the ntc service // and maybe elsewhere. We do not do that, so fix the clock to the local clock on first boot // to avoid it being stuck at 0. @@ -406,10 +154,16 @@ Result ServiceManager::SetupStandardUserSystemClockCore(SteadyClockTimePoint& ti R_SUCCEED(); } -Result ServiceManager::SetupTimeZoneServiceCore(LocationName& name, +Result ServiceManager::SetupTimeZoneServiceCore(LocationName& name, RuleVersion& rule_version, + u32 location_count, SteadyClockTimePoint& time_point, - RuleVersion& rule_version, u32 location_count, - std::span<const u8> rule_buffer) { + InBuffer<BufferAttr_HipcAutoSelect> rule_buffer) { + LOG_DEBUG(Service_Time, + "called. name={} rule_version={} location_count={} time_point={} " + "clock_source_id={}", + name, rule_version, location_count, time_point, + time_point.clock_source_id.RawString()); + if (m_time_zone.ParseBinary(name, rule_buffer) != ResultSuccess) { LOG_ERROR(Service_Time, "Failed to parse time zone binary!"); } @@ -424,6 +178,8 @@ Result ServiceManager::SetupTimeZoneServiceCore(LocationName& name, } Result ServiceManager::SetupEphemeralNetworkSystemClockCore() { + LOG_DEBUG(Service_Time, "called."); + m_ephemeral_network_clock.SetContextWriter(m_ephemeral_system_context_writer); m_ephemeral_network_clock.SetInitialized(); @@ -431,30 +187,41 @@ Result ServiceManager::SetupEphemeralNetworkSystemClockCore() { R_SUCCEED(); } -Result ServiceManager::GetStandardLocalClockOperationEvent(Kernel::KEvent** out_event) { - *out_event = m_local_operation.m_event; +Result ServiceManager::GetStandardLocalClockOperationEvent( + OutCopyHandle<Kernel::KReadableEvent> out_event) { + LOG_DEBUG(Service_Time, "called."); + + *out_event = &m_local_operation.m_event->GetReadableEvent(); R_SUCCEED(); } Result ServiceManager::GetStandardNetworkClockOperationEventForServiceManager( - Kernel::KEvent** out_event) { - *out_event = m_network_operation.m_event; + OutCopyHandle<Kernel::KReadableEvent> out_event) { + LOG_DEBUG(Service_Time, "called."); + + *out_event = &m_network_operation.m_event->GetReadableEvent(); R_SUCCEED(); } Result ServiceManager::GetEphemeralNetworkClockOperationEventForServiceManager( - Kernel::KEvent** out_event) { - *out_event = m_ephemeral_operation.m_event; + OutCopyHandle<Kernel::KReadableEvent> out_event) { + LOG_DEBUG(Service_Time, "called."); + + *out_event = &m_ephemeral_operation.m_event->GetReadableEvent(); R_SUCCEED(); } Result ServiceManager::GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent( - Kernel::KEvent** out_event) { - *out_event = &m_user_system_clock.GetEvent(); + OutCopyHandle<Kernel::KReadableEvent> out_event) { + LOG_DEBUG(Service_Time, "called."); + + *out_event = &m_user_system_clock.GetEvent().GetReadableEvent(); R_SUCCEED(); } Result ServiceManager::SetStandardSteadyClockBaseTime(s64 base_time) { + LOG_DEBUG(Service_Time, "called. base_time={}", base_time); + m_steady_clock.SetRtcOffset(base_time); auto time = m_steady_clock.GetRawTime(); auto ticks = m_system.CoreTiming().GetClockTicks(); @@ -468,26 +235,63 @@ Result ServiceManager::SetStandardSteadyClockBaseTime(s64 base_time) { R_SUCCEED(); } -Result ServiceManager::GetClosestAlarmUpdatedEvent(Kernel::KEvent** out_event) { - *out_event = &m_alarms.GetEvent(); +Result ServiceManager::GetClosestAlarmUpdatedEvent( + OutCopyHandle<Kernel::KReadableEvent> out_event) { + LOG_DEBUG(Service_Time, "called."); + + *out_event = &m_alarms.GetEvent().GetReadableEvent(); R_SUCCEED(); } Result ServiceManager::CheckAndSignalAlarms() { + LOG_DEBUG(Service_Time, "called."); + m_alarms.CheckAndSignal(); R_SUCCEED(); } -Result ServiceManager::GetClosestAlarmInfo(bool& out_is_valid, AlarmInfo& out_info, s64& out_time) { +Result ServiceManager::GetClosestAlarmInfo(Out<bool> out_is_valid, Out<AlarmInfo> out_info, + Out<s64> out_time) { Alarm* alarm{nullptr}; - out_is_valid = m_alarms.GetClosestAlarm(&alarm); - if (out_is_valid) { - out_info = { + *out_is_valid = m_alarms.GetClosestAlarm(&alarm); + if (*out_is_valid) { + *out_info = { .alert_time = alarm->GetAlertTime(), .priority = alarm->GetPriority(), }; - out_time = m_alarms.GetRawTime(); + *out_time = m_alarms.GetRawTime(); + } + + LOG_DEBUG(Service_Time, + "called. out_is_valid={} out_info.alert_time={} out_info.priority={}, out_time={}", + *out_is_valid, out_info->alert_time, out_info->priority, *out_time); + + R_SUCCEED(); +} + +void ServiceManager::CheckAndSetupServicesSAndP() { + if (m_local_system_clock.IsInitialized() && m_user_system_clock.IsInitialized() && + m_network_system_clock.IsInitialized() && m_steady_clock.IsInitialized() && + m_time_zone.IsInitialized() && m_ephemeral_network_clock.IsInitialized()) { + SetupSAndP(); + } +} + +void ServiceManager::SetupSAndP() { + if (!m_is_s_and_p_setup) { + m_is_s_and_p_setup = true; + m_server_manager.RegisterNamedService( + "time:s", std::make_shared<StaticService>( + m_system, StaticServiceSetupInfo{0, 0, 1, 0, 0, 0}, m_time, "time:s")); + m_server_manager.RegisterNamedService("time:p", + std::make_shared<IPowerStateRequestHandler>( + m_system, m_time->m_power_state_request_manager)); } +} + +Result ServiceManager::GetStaticService(OutInterface<StaticService> out_service, + StaticServiceSetupInfo setup_info, const char* name) { + *out_service = std::make_shared<StaticService>(m_system, setup_info, m_time, name); R_SUCCEED(); } diff --git a/src/core/hle/service/psc/time/service_manager.h b/src/core/hle/service/psc/time/service_manager.h index 1d9952317..25d361d4f 100644 --- a/src/core/hle/service/psc/time/service_manager.h +++ b/src/core/hle/service/psc/time/service_manager.h @@ -6,6 +6,7 @@ #include <list> #include <memory> +#include "core/hle/service/cmif_types.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/psc/time/common.h" #include "core/hle/service/psc/time/manager.h" @@ -29,55 +30,38 @@ public: ServerManager* server_manager); ~ServiceManager() override = default; - Result GetStaticServiceAsUser(std::shared_ptr<StaticService>& out_service); - Result GetStaticServiceAsAdmin(std::shared_ptr<StaticService>& out_service); - Result GetStaticServiceAsRepair(std::shared_ptr<StaticService>& out_service); - Result GetStaticServiceAsServiceManager(std::shared_ptr<StaticService>& out_service); - Result SetupStandardSteadyClockCore(Common::UUID& clock_source_id, s64 rtc_offset, - s64 internal_offset, s64 test_offset, - bool is_rtc_reset_detected); + Result GetStaticServiceAsUser(OutInterface<StaticService> out_service); + Result GetStaticServiceAsAdmin(OutInterface<StaticService> out_service); + Result GetStaticServiceAsRepair(OutInterface<StaticService> out_service); + Result GetStaticServiceAsServiceManager(OutInterface<StaticService> out_service); + Result SetupStandardSteadyClockCore(bool is_rtc_reset_detected, Common::UUID& clock_source_id, + s64 rtc_offset, s64 internal_offset, s64 test_offset); Result SetupStandardLocalSystemClockCore(SystemClockContext& context, s64 time); Result SetupStandardNetworkSystemClockCore(SystemClockContext& context, s64 accuracy); - Result SetupStandardUserSystemClockCore(SteadyClockTimePoint& time_point, - bool automatic_correction); - Result SetupTimeZoneServiceCore(LocationName& name, SteadyClockTimePoint& time_point, - RuleVersion& rule_version, u32 location_count, - std::span<const u8> rule_buffer); + Result SetupStandardUserSystemClockCore(bool automatic_correction, + SteadyClockTimePoint& time_point); + Result SetupTimeZoneServiceCore(LocationName& name, RuleVersion& rule_version, + u32 location_count, SteadyClockTimePoint& time_point, + InBuffer<BufferAttr_HipcAutoSelect> rule_buffer); Result SetupEphemeralNetworkSystemClockCore(); - Result GetStandardLocalClockOperationEvent(Kernel::KEvent** out_event); - Result GetStandardNetworkClockOperationEventForServiceManager(Kernel::KEvent** out_event); - Result GetEphemeralNetworkClockOperationEventForServiceManager(Kernel::KEvent** out_event); - Result GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent(Kernel::KEvent** out_event); + Result GetStandardLocalClockOperationEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); + Result GetStandardNetworkClockOperationEventForServiceManager( + OutCopyHandle<Kernel::KReadableEvent> out_event); + Result GetEphemeralNetworkClockOperationEventForServiceManager( + OutCopyHandle<Kernel::KReadableEvent> out_event); + Result GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent( + OutCopyHandle<Kernel::KReadableEvent> out_event); Result SetStandardSteadyClockBaseTime(s64 base_time); - Result GetClosestAlarmUpdatedEvent(Kernel::KEvent** out_event); + Result GetClosestAlarmUpdatedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); Result CheckAndSignalAlarms(); - Result GetClosestAlarmInfo(bool& out_is_valid, AlarmInfo& out_info, s64& out_time); + Result GetClosestAlarmInfo(Out<bool> out_is_valid, Out<AlarmInfo> out_info, Out<s64> out_time); private: void CheckAndSetupServicesSAndP(); void SetupSAndP(); - Result GetStaticService(std::shared_ptr<StaticService>& out_service, + Result GetStaticService(OutInterface<StaticService> out_service, StaticServiceSetupInfo setup_info, const char* name); - void Handle_GetStaticServiceAsUser(HLERequestContext& ctx); - void Handle_GetStaticServiceAsAdmin(HLERequestContext& ctx); - void Handle_GetStaticServiceAsRepair(HLERequestContext& ctx); - void Handle_GetStaticServiceAsServiceManager(HLERequestContext& ctx); - void Handle_SetupStandardSteadyClockCore(HLERequestContext& ctx); - void Handle_SetupStandardLocalSystemClockCore(HLERequestContext& ctx); - void Handle_SetupStandardNetworkSystemClockCore(HLERequestContext& ctx); - void Handle_SetupStandardUserSystemClockCore(HLERequestContext& ctx); - void Handle_SetupTimeZoneServiceCore(HLERequestContext& ctx); - void Handle_SetupEphemeralNetworkSystemClockCore(HLERequestContext& ctx); - void Handle_GetStandardLocalClockOperationEvent(HLERequestContext& ctx); - void Handle_GetStandardNetworkClockOperationEventForServiceManager(HLERequestContext& ctx); - void Handle_GetEphemeralNetworkClockOperationEventForServiceManager(HLERequestContext& ctx); - void Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent(HLERequestContext& ctx); - void Handle_SetStandardSteadyClockBaseTime(HLERequestContext& ctx); - void Handle_GetClosestAlarmUpdatedEvent(HLERequestContext& ctx); - void Handle_CheckAndSignalAlarms(HLERequestContext& ctx); - void Handle_GetClosestAlarmInfo(HLERequestContext& ctx); - Core::System& m_system; std::shared_ptr<TimeManager> m_time; ServerManager& m_server_manager; diff --git a/src/core/hle/service/psc/time/static.cpp b/src/core/hle/service/psc/time/static.cpp index 6f8cf3f88..3ca3311af 100644 --- a/src/core/hle/service/psc/time/static.cpp +++ b/src/core/hle/service/psc/time/static.cpp @@ -1,9 +1,11 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "common/scope_exit.h" #include "core/core.h" #include "core/core_timing.h" #include "core/hle/kernel/k_shared_memory.h" +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/psc/time/clocks/ephemeral_network_system_clock_core.h" #include "core/hle/service/psc/time/clocks/standard_local_system_clock_core.h" #include "core/hle/service/psc/time/clocks/standard_network_system_clock_core.h" @@ -39,358 +41,122 @@ StaticService::StaticService(Core::System& system_, StaticServiceSetupInfo setup m_time->m_shared_memory} { // clang-format off static const FunctionInfo functions[] = { - {0, &StaticService::Handle_GetStandardUserSystemClock, "GetStandardUserSystemClock"}, - {1, &StaticService::Handle_GetStandardNetworkSystemClock, "GetStandardNetworkSystemClock"}, - {2, &StaticService::Handle_GetStandardSteadyClock, "GetStandardSteadyClock"}, - {3, &StaticService::Handle_GetTimeZoneService, "GetTimeZoneService"}, - {4, &StaticService::Handle_GetStandardLocalSystemClock, "GetStandardLocalSystemClock"}, - {5, &StaticService::Handle_GetEphemeralNetworkSystemClock, "GetEphemeralNetworkSystemClock"}, - {20, &StaticService::Handle_GetSharedMemoryNativeHandle, "GetSharedMemoryNativeHandle"}, - {50, &StaticService::Handle_SetStandardSteadyClockInternalOffset, "SetStandardSteadyClockInternalOffset"}, - {51, &StaticService::Handle_GetStandardSteadyClockRtcValue, "GetStandardSteadyClockRtcValue"}, - {100, &StaticService::Handle_IsStandardUserSystemClockAutomaticCorrectionEnabled, "IsStandardUserSystemClockAutomaticCorrectionEnabled"}, - {101, &StaticService::Handle_SetStandardUserSystemClockAutomaticCorrectionEnabled, "SetStandardUserSystemClockAutomaticCorrectionEnabled"}, - {102, &StaticService::Handle_GetStandardUserSystemClockInitialYear, "GetStandardUserSystemClockInitialYear"}, - {200, &StaticService::Handle_IsStandardNetworkSystemClockAccuracySufficient, "IsStandardNetworkSystemClockAccuracySufficient"}, - {201, &StaticService::Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedTime, "GetStandardUserSystemClockAutomaticCorrectionUpdatedTime"}, - {300, &StaticService::Handle_CalculateMonotonicSystemClockBaseTimePoint, "CalculateMonotonicSystemClockBaseTimePoint"}, - {400, &StaticService::Handle_GetClockSnapshot, "GetClockSnapshot"}, - {401, &StaticService::Handle_GetClockSnapshotFromSystemClockContext, "GetClockSnapshotFromSystemClockContext"}, - {500, &StaticService::Handle_CalculateStandardUserSystemClockDifferenceByUser, "CalculateStandardUserSystemClockDifferenceByUser"}, - {501, &StaticService::Handle_CalculateSpanBetween, "CalculateSpanBetween"}, + {0, D<&StaticService::GetStandardUserSystemClock>, "GetStandardUserSystemClock"}, + {1, D<&StaticService::GetStandardNetworkSystemClock>, "GetStandardNetworkSystemClock"}, + {2, D<&StaticService::GetStandardSteadyClock>, "GetStandardSteadyClock"}, + {3, D<&StaticService::GetTimeZoneService>, "GetTimeZoneService"}, + {4, D<&StaticService::GetStandardLocalSystemClock>, "GetStandardLocalSystemClock"}, + {5, D<&StaticService::GetEphemeralNetworkSystemClock>, "GetEphemeralNetworkSystemClock"}, + {20, D<&StaticService::GetSharedMemoryNativeHandle>, "GetSharedMemoryNativeHandle"}, + {50, D<&StaticService::SetStandardSteadyClockInternalOffset>, "SetStandardSteadyClockInternalOffset"}, + {51, D<&StaticService::GetStandardSteadyClockRtcValue>, "GetStandardSteadyClockRtcValue"}, + {100, D<&StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled>, "IsStandardUserSystemClockAutomaticCorrectionEnabled"}, + {101, D<&StaticService::SetStandardUserSystemClockAutomaticCorrectionEnabled>, "SetStandardUserSystemClockAutomaticCorrectionEnabled"}, + {102, D<&StaticService::GetStandardUserSystemClockInitialYear>, "GetStandardUserSystemClockInitialYear"}, + {200, D<&StaticService::IsStandardNetworkSystemClockAccuracySufficient>, "IsStandardNetworkSystemClockAccuracySufficient"}, + {201, D<&StaticService::GetStandardUserSystemClockAutomaticCorrectionUpdatedTime>, "GetStandardUserSystemClockAutomaticCorrectionUpdatedTime"}, + {300, D<&StaticService::CalculateMonotonicSystemClockBaseTimePoint>, "CalculateMonotonicSystemClockBaseTimePoint"}, + {400, D<&StaticService::GetClockSnapshot>, "GetClockSnapshot"}, + {401, D<&StaticService::GetClockSnapshotFromSystemClockContext>, "GetClockSnapshotFromSystemClockContext"}, + {500, D<&StaticService::CalculateStandardUserSystemClockDifferenceByUser>, "CalculateStandardUserSystemClockDifferenceByUser"}, + {501, D<&StaticService::CalculateSpanBetween>, "CalculateSpanBetween"}, }; // clang-format on RegisterHandlers(functions); } -Result StaticService::GetClockSnapshotImpl(ClockSnapshot& out_snapshot, - SystemClockContext& user_context, - SystemClockContext& network_context, TimeType type) { - out_snapshot.user_context = user_context; - out_snapshot.network_context = network_context; - - R_TRY( - m_time->m_standard_steady_clock.GetCurrentTimePoint(out_snapshot.steady_clock_time_point)); - - out_snapshot.is_automatic_correction_enabled = m_user_system_clock.GetAutomaticCorrection(); - - R_TRY(m_time_zone.GetLocationName(out_snapshot.location_name)); - - R_TRY(GetTimeFromTimePointAndContext( - &out_snapshot.user_time, out_snapshot.steady_clock_time_point, out_snapshot.user_context)); - - R_TRY(m_time_zone.ToCalendarTimeWithMyRule(out_snapshot.user_calendar_time, - out_snapshot.user_calendar_additional_time, - out_snapshot.user_time)); - - if (GetTimeFromTimePointAndContext(&out_snapshot.network_time, - out_snapshot.steady_clock_time_point, - out_snapshot.network_context) != ResultSuccess) { - out_snapshot.network_time = 0; - } - - R_TRY(m_time_zone.ToCalendarTimeWithMyRule(out_snapshot.network_calendar_time, - out_snapshot.network_calendar_additional_time, - out_snapshot.network_time)); - out_snapshot.type = type; - out_snapshot.unk_CE = 0; - R_SUCCEED(); -} - -void StaticService::Handle_GetStandardUserSystemClock(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr<SystemClock> service{}; - auto res = GetStandardUserSystemClock(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface<SystemClock>(std::move(service)); -} - -void StaticService::Handle_GetStandardNetworkSystemClock(HLERequestContext& ctx) { +Result StaticService::GetStandardUserSystemClock(OutInterface<SystemClock> out_service) { LOG_DEBUG(Service_Time, "called."); - std::shared_ptr<SystemClock> service{}; - auto res = GetStandardNetworkSystemClock(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface<SystemClock>(std::move(service)); -} - -void StaticService::Handle_GetStandardSteadyClock(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr<SteadyClock> service{}; - auto res = GetStandardSteadyClock(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface(std::move(service)); -} - -void StaticService::Handle_GetTimeZoneService(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr<TimeZoneService> service{}; - auto res = GetTimeZoneService(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface(std::move(service)); -} - -void StaticService::Handle_GetStandardLocalSystemClock(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr<SystemClock> service{}; - auto res = GetStandardLocalSystemClock(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface<SystemClock>(std::move(service)); -} - -void StaticService::Handle_GetEphemeralNetworkSystemClock(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr<SystemClock> service{}; - auto res = GetEphemeralNetworkSystemClock(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface<SystemClock>(std::move(service)); -} - -void StaticService::Handle_GetSharedMemoryNativeHandle(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Kernel::KSharedMemory* shared_memory{}; - auto res = GetSharedMemoryNativeHandle(&shared_memory); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(res); - rb.PushCopyObjects(shared_memory); -} - -void StaticService::Handle_SetStandardSteadyClockInternalOffset(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(m_setup_info.can_write_steady_clock ? ResultNotImplemented : ResultPermissionDenied); -} - -void StaticService::Handle_GetStandardSteadyClockRtcValue(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultNotImplemented); -} - -void StaticService::Handle_IsStandardUserSystemClockAutomaticCorrectionEnabled( - HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - bool is_enabled{}; - auto res = IsStandardUserSystemClockAutomaticCorrectionEnabled(is_enabled); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.Push<bool>(is_enabled); -} - -void StaticService::Handle_SetStandardUserSystemClockAutomaticCorrectionEnabled( - HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto automatic_correction{rp.Pop<bool>()}; - - auto res = SetStandardUserSystemClockAutomaticCorrectionEnabled(automatic_correction); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void StaticService::Handle_GetStandardUserSystemClockInitialYear(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultNotImplemented); -} - -void StaticService::Handle_IsStandardNetworkSystemClockAccuracySufficient(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - bool is_sufficient{}; - auto res = IsStandardNetworkSystemClockAccuracySufficient(is_sufficient); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.Push<bool>(is_sufficient); + *out_service = std::make_shared<SystemClock>(m_system, m_user_system_clock, + m_setup_info.can_write_user_clock, + m_setup_info.can_write_uninitialized_clock); + R_SUCCEED(); } -void StaticService::Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedTime( - HLERequestContext& ctx) { +Result StaticService::GetStandardNetworkSystemClock(OutInterface<SystemClock> out_service) { LOG_DEBUG(Service_Time, "called."); - SteadyClockTimePoint time_point{}; - auto res = GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(time_point); - - IPC::ResponseBuilder rb{ctx, 2 + sizeof(SteadyClockTimePoint) / sizeof(u32)}; - rb.Push(res); - rb.PushRaw<SteadyClockTimePoint>(time_point); + *out_service = std::make_shared<SystemClock>(m_system, m_network_system_clock, + m_setup_info.can_write_network_clock, + m_setup_info.can_write_uninitialized_clock); + R_SUCCEED(); } -void StaticService::Handle_CalculateMonotonicSystemClockBaseTimePoint(HLERequestContext& ctx) { +Result StaticService::GetStandardSteadyClock(OutInterface<SteadyClock> out_service) { LOG_DEBUG(Service_Time, "called."); - IPC::RequestParser rp{ctx}; - auto context{rp.PopRaw<SystemClockContext>()}; - - s64 time{}; - auto res = CalculateMonotonicSystemClockBaseTimePoint(time, context); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(res); - rb.Push<s64>(time); + *out_service = + std::make_shared<SteadyClock>(m_system, m_time, m_setup_info.can_write_steady_clock, + m_setup_info.can_write_uninitialized_clock); + R_SUCCEED(); } -void StaticService::Handle_GetClockSnapshot(HLERequestContext& ctx) { +Result StaticService::GetTimeZoneService(OutInterface<TimeZoneService> out_service) { LOG_DEBUG(Service_Time, "called."); - IPC::RequestParser rp{ctx}; - auto type{rp.PopEnum<TimeType>()}; - - ClockSnapshot snapshot{}; - auto res = GetClockSnapshot(snapshot, type); - - ctx.WriteBuffer(snapshot); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); + *out_service = + std::make_shared<TimeZoneService>(m_system, m_time->m_standard_steady_clock, m_time_zone, + m_setup_info.can_write_timezone_device_location); + R_SUCCEED(); } -void StaticService::Handle_GetClockSnapshotFromSystemClockContext(HLERequestContext& ctx) { +Result StaticService::GetStandardLocalSystemClock(OutInterface<SystemClock> out_service) { LOG_DEBUG(Service_Time, "called."); - IPC::RequestParser rp{ctx}; - auto clock_type{rp.PopEnum<TimeType>()}; - [[maybe_unused]] auto alignment{rp.Pop<u32>()}; - auto user_context{rp.PopRaw<SystemClockContext>()}; - auto network_context{rp.PopRaw<SystemClockContext>()}; - - ClockSnapshot snapshot{}; - auto res = - GetClockSnapshotFromSystemClockContext(snapshot, user_context, network_context, clock_type); - - ctx.WriteBuffer(snapshot); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); + *out_service = std::make_shared<SystemClock>(m_system, m_local_system_clock, + m_setup_info.can_write_local_clock, + m_setup_info.can_write_uninitialized_clock); + R_SUCCEED(); } -void StaticService::Handle_CalculateStandardUserSystemClockDifferenceByUser( - HLERequestContext& ctx) { +Result StaticService::GetEphemeralNetworkSystemClock(OutInterface<SystemClock> out_service) { LOG_DEBUG(Service_Time, "called."); - ClockSnapshot a{}; - ClockSnapshot b{}; - - auto a_buffer{ctx.ReadBuffer(0)}; - auto b_buffer{ctx.ReadBuffer(1)}; - - std::memcpy(&a, a_buffer.data(), sizeof(ClockSnapshot)); - std::memcpy(&b, b_buffer.data(), sizeof(ClockSnapshot)); - - s64 difference{}; - auto res = CalculateStandardUserSystemClockDifferenceByUser(difference, a, b); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(res); - rb.Push(difference); + *out_service = std::make_shared<SystemClock>(m_system, m_ephemeral_network_clock, + m_setup_info.can_write_network_clock, + m_setup_info.can_write_uninitialized_clock); + R_SUCCEED(); } -void StaticService::Handle_CalculateSpanBetween(HLERequestContext& ctx) { +Result StaticService::GetSharedMemoryNativeHandle( + OutCopyHandle<Kernel::KSharedMemory> out_shared_memory) { LOG_DEBUG(Service_Time, "called."); - ClockSnapshot a{}; - ClockSnapshot b{}; - - auto a_buffer{ctx.ReadBuffer(0)}; - auto b_buffer{ctx.ReadBuffer(1)}; - - std::memcpy(&a, a_buffer.data(), sizeof(ClockSnapshot)); - std::memcpy(&b, b_buffer.data(), sizeof(ClockSnapshot)); - - s64 time{}; - auto res = CalculateSpanBetween(time, a, b); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(res); - rb.Push(time); -} - -// =============================== Implementations =========================== - -Result StaticService::GetStandardUserSystemClock(std::shared_ptr<SystemClock>& out_service) { - out_service = std::make_shared<SystemClock>(m_system, m_user_system_clock, - m_setup_info.can_write_user_clock, - m_setup_info.can_write_uninitialized_clock); + *out_shared_memory = &m_shared_memory.GetKSharedMemory(); R_SUCCEED(); } -Result StaticService::GetStandardNetworkSystemClock(std::shared_ptr<SystemClock>& out_service) { - out_service = std::make_shared<SystemClock>(m_system, m_network_system_clock, - m_setup_info.can_write_network_clock, - m_setup_info.can_write_uninitialized_clock); - R_SUCCEED(); -} +Result StaticService::SetStandardSteadyClockInternalOffset(s64 offset_ns) { + LOG_DEBUG(Service_Time, "called. This function is not implemented!"); -Result StaticService::GetStandardSteadyClock(std::shared_ptr<SteadyClock>& out_service) { - out_service = - std::make_shared<SteadyClock>(m_system, m_time, m_setup_info.can_write_steady_clock, - m_setup_info.can_write_uninitialized_clock); - R_SUCCEED(); -} + R_UNLESS(m_setup_info.can_write_steady_clock, ResultPermissionDenied); -Result StaticService::GetTimeZoneService(std::shared_ptr<TimeZoneService>& out_service) { - out_service = - std::make_shared<TimeZoneService>(m_system, m_time->m_standard_steady_clock, m_time_zone, - m_setup_info.can_write_timezone_device_location); - R_SUCCEED(); + R_RETURN(ResultNotImplemented); } -Result StaticService::GetStandardLocalSystemClock(std::shared_ptr<SystemClock>& out_service) { - out_service = std::make_shared<SystemClock>(m_system, m_local_system_clock, - m_setup_info.can_write_local_clock, - m_setup_info.can_write_uninitialized_clock); - R_SUCCEED(); -} +Result StaticService::GetStandardSteadyClockRtcValue(Out<s64> out_rtc_value) { + LOG_DEBUG(Service_Time, "called. This function is not implemented!"); -Result StaticService::GetEphemeralNetworkSystemClock(std::shared_ptr<SystemClock>& out_service) { - out_service = std::make_shared<SystemClock>(m_system, m_ephemeral_network_clock, - m_setup_info.can_write_network_clock, - m_setup_info.can_write_uninitialized_clock); - R_SUCCEED(); + R_RETURN(ResultNotImplemented); } -Result StaticService::GetSharedMemoryNativeHandle(Kernel::KSharedMemory** out_shared_memory) { - *out_shared_memory = &m_shared_memory.GetKSharedMemory(); - R_SUCCEED(); -} +Result StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled( + Out<bool> out_is_enabled) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_is_enabled={}", *out_is_enabled); }); -Result StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled(bool& out_is_enabled) { R_UNLESS(m_user_system_clock.IsInitialized(), ResultClockUninitialized); - out_is_enabled = m_user_system_clock.GetAutomaticCorrection(); + *out_is_enabled = m_user_system_clock.GetAutomaticCorrection(); + R_SUCCEED(); } Result StaticService::SetStandardUserSystemClockAutomaticCorrectionEnabled( bool automatic_correction) { + LOG_DEBUG(Service_Time, "called. automatic_correction={}", automatic_correction); + R_UNLESS(m_user_system_clock.IsInitialized() && m_time->m_standard_steady_clock.IsInitialized(), ResultClockUninitialized); R_UNLESS(m_setup_info.can_write_user_clock, ResultPermissionDenied); @@ -407,22 +173,35 @@ Result StaticService::SetStandardUserSystemClockAutomaticCorrectionEnabled( R_SUCCEED(); } -Result StaticService::IsStandardNetworkSystemClockAccuracySufficient(bool& out_is_sufficient) { - out_is_sufficient = m_network_system_clock.IsAccuracySufficient(); +Result StaticService::GetStandardUserSystemClockInitialYear(Out<s32> out_year) { + LOG_DEBUG(Service_Time, "called. This function is not implemented!"); + + R_RETURN(ResultNotImplemented); +} + +Result StaticService::IsStandardNetworkSystemClockAccuracySufficient(Out<bool> out_is_sufficient) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_is_sufficient={}", *out_is_sufficient); }); + + *out_is_sufficient = m_network_system_clock.IsAccuracySufficient(); + R_SUCCEED(); } Result StaticService::GetStandardUserSystemClockAutomaticCorrectionUpdatedTime( - SteadyClockTimePoint& out_time_point) { + Out<SteadyClockTimePoint> out_time_point) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_time_point={}", *out_time_point); }); + R_UNLESS(m_user_system_clock.IsInitialized(), ResultClockUninitialized); - m_user_system_clock.GetTimePoint(out_time_point); + m_user_system_clock.GetTimePoint(*out_time_point); R_SUCCEED(); } -Result StaticService::CalculateMonotonicSystemClockBaseTimePoint(s64& out_time, +Result StaticService::CalculateMonotonicSystemClockBaseTimePoint(Out<s64> out_time, SystemClockContext& context) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. context={} out_time={}", context, *out_time); }); + R_UNLESS(m_time->m_standard_steady_clock.IsInitialized(), ResultClockUninitialized); SteadyClockTimePoint time_point{}; @@ -433,12 +212,16 @@ Result StaticService::CalculateMonotonicSystemClockBaseTimePoint(s64& out_time, auto one_second_ns{ std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::seconds(1)).count()}; auto ticks{m_system.CoreTiming().GetClockTicks()}; - auto current_time{ConvertToTimeSpan(ticks).count()}; - out_time = ((context.offset + time_point.time_point) - (current_time / one_second_ns)); + auto current_time_ns{ConvertToTimeSpan(ticks).count()}; + *out_time = ((context.offset + time_point.time_point) - (current_time_ns / one_second_ns)); + R_SUCCEED(); } -Result StaticService::GetClockSnapshot(ClockSnapshot& out_snapshot, TimeType type) { +Result StaticService::GetClockSnapshot(OutClockSnapshot out_snapshot, TimeType type) { + SCOPE_EXIT( + { LOG_DEBUG(Service_Time, "called. type={} out_snapshot={}", type, *out_snapshot); }); + SystemClockContext user_context{}; R_TRY(m_user_system_clock.GetContext(user_context)); @@ -448,53 +231,101 @@ Result StaticService::GetClockSnapshot(ClockSnapshot& out_snapshot, TimeType typ R_RETURN(GetClockSnapshotImpl(out_snapshot, user_context, network_context, type)); } -Result StaticService::GetClockSnapshotFromSystemClockContext(ClockSnapshot& out_snapshot, +Result StaticService::GetClockSnapshotFromSystemClockContext(TimeType type, + OutClockSnapshot out_snapshot, SystemClockContext& user_context, - SystemClockContext& network_context, - TimeType type) { + SystemClockContext& network_context) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, + "called. type={} user_context={} network_context={} out_snapshot={}", type, + user_context, network_context, *out_snapshot); + }); + R_RETURN(GetClockSnapshotImpl(out_snapshot, user_context, network_context, type)); } -Result StaticService::CalculateStandardUserSystemClockDifferenceByUser(s64& out_time, - ClockSnapshot& a, - ClockSnapshot& b) { +Result StaticService::CalculateStandardUserSystemClockDifferenceByUser(Out<s64> out_difference, + InClockSnapshot a, + InClockSnapshot b) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, "called. a={} b={} out_difference={}", *a, *b, *out_difference); + }); + auto diff_s = - std::chrono::seconds(b.user_context.offset) - std::chrono::seconds(a.user_context.offset); + std::chrono::seconds(b->user_context.offset) - std::chrono::seconds(a->user_context.offset); - if (a.user_context == b.user_context || - !a.user_context.steady_time_point.IdMatches(b.user_context.steady_time_point)) { - out_time = 0; + if (a->user_context == b->user_context || + !a->user_context.steady_time_point.IdMatches(b->user_context.steady_time_point)) { + *out_difference = 0; R_SUCCEED(); } - if (!a.is_automatic_correction_enabled || !b.is_automatic_correction_enabled) { - out_time = std::chrono::duration_cast<std::chrono::nanoseconds>(diff_s).count(); + if (!a->is_automatic_correction_enabled || !b->is_automatic_correction_enabled) { + *out_difference = std::chrono::duration_cast<std::chrono::nanoseconds>(diff_s).count(); R_SUCCEED(); } - if (a.network_context.steady_time_point.IdMatches(a.steady_clock_time_point) || - b.network_context.steady_time_point.IdMatches(b.steady_clock_time_point)) { - out_time = 0; + if (a->network_context.steady_time_point.IdMatches(a->steady_clock_time_point) || + b->network_context.steady_time_point.IdMatches(b->steady_clock_time_point)) { + *out_difference = 0; R_SUCCEED(); } - out_time = std::chrono::duration_cast<std::chrono::nanoseconds>(diff_s).count(); + *out_difference = std::chrono::duration_cast<std::chrono::nanoseconds>(diff_s).count(); R_SUCCEED(); } -Result StaticService::CalculateSpanBetween(s64& out_time, ClockSnapshot& a, ClockSnapshot& b) { +Result StaticService::CalculateSpanBetween(Out<s64> out_time, InClockSnapshot a, + InClockSnapshot b) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. a={} b={} out_time={}", *a, *b, *out_time); }); + s64 time_s{}; auto res = - GetSpanBetweenTimePoints(&time_s, a.steady_clock_time_point, b.steady_clock_time_point); + GetSpanBetweenTimePoints(&time_s, a->steady_clock_time_point, b->steady_clock_time_point); if (res != ResultSuccess) { - R_UNLESS(a.network_time != 0 && b.network_time != 0, ResultTimeNotFound); - time_s = b.network_time - a.network_time; + R_UNLESS(a->network_time != 0 && b->network_time != 0, ResultTimeNotFound); + time_s = b->network_time - a->network_time; } - out_time = + *out_time = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::seconds(time_s)).count(); R_SUCCEED(); } +Result StaticService::GetClockSnapshotImpl(OutClockSnapshot out_snapshot, + SystemClockContext& user_context, + SystemClockContext& network_context, TimeType type) { + out_snapshot->user_context = user_context; + out_snapshot->network_context = network_context; + + R_TRY( + m_time->m_standard_steady_clock.GetCurrentTimePoint(out_snapshot->steady_clock_time_point)); + + out_snapshot->is_automatic_correction_enabled = m_user_system_clock.GetAutomaticCorrection(); + + R_TRY(m_time_zone.GetLocationName(out_snapshot->location_name)); + + R_TRY(GetTimeFromTimePointAndContext(&out_snapshot->user_time, + out_snapshot->steady_clock_time_point, + out_snapshot->user_context)); + + R_TRY(m_time_zone.ToCalendarTimeWithMyRule(out_snapshot->user_calendar_time, + out_snapshot->user_calendar_additional_time, + out_snapshot->user_time)); + + if (GetTimeFromTimePointAndContext(&out_snapshot->network_time, + out_snapshot->steady_clock_time_point, + out_snapshot->network_context) != ResultSuccess) { + out_snapshot->network_time = 0; + } + + R_TRY(m_time_zone.ToCalendarTimeWithMyRule(out_snapshot->network_calendar_time, + out_snapshot->network_calendar_additional_time, + out_snapshot->network_time)); + out_snapshot->type = type; + out_snapshot->unk_CE = 0; + R_SUCCEED(); +} + } // namespace Service::PSC::Time diff --git a/src/core/hle/service/psc/time/static.h b/src/core/hle/service/psc/time/static.h index 498cd5ab5..120bab259 100644 --- a/src/core/hle/service/psc/time/static.h +++ b/src/core/hle/service/psc/time/static.h @@ -3,6 +3,7 @@ #pragma once +#include "core/hle/service/cmif_types.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/psc/time/common.h" #include "core/hle/service/server_manager.h" @@ -29,58 +30,44 @@ class EphemeralNetworkSystemClockCore; class SharedMemory; class StaticService final : public ServiceFramework<StaticService> { + using InClockSnapshot = InLargeData<ClockSnapshot, BufferAttr_HipcPointer>; + using OutClockSnapshot = OutLargeData<ClockSnapshot, BufferAttr_HipcPointer>; + public: explicit StaticService(Core::System& system, StaticServiceSetupInfo setup_info, std::shared_ptr<TimeManager> time, const char* name); ~StaticService() override = default; - Result GetStandardUserSystemClock(std::shared_ptr<SystemClock>& out_service); - Result GetStandardNetworkSystemClock(std::shared_ptr<SystemClock>& out_service); - Result GetStandardSteadyClock(std::shared_ptr<SteadyClock>& out_service); - Result GetTimeZoneService(std::shared_ptr<TimeZoneService>& out_service); - Result GetStandardLocalSystemClock(std::shared_ptr<SystemClock>& out_service); - Result GetEphemeralNetworkSystemClock(std::shared_ptr<SystemClock>& out_service); - Result GetSharedMemoryNativeHandle(Kernel::KSharedMemory** out_shared_memory); - Result IsStandardUserSystemClockAutomaticCorrectionEnabled(bool& out_is_enabled); + Result GetStandardUserSystemClock(OutInterface<SystemClock> out_service); + Result GetStandardNetworkSystemClock(OutInterface<SystemClock> out_service); + Result GetStandardSteadyClock(OutInterface<SteadyClock> out_service); + Result GetTimeZoneService(OutInterface<TimeZoneService> out_service); + Result GetStandardLocalSystemClock(OutInterface<SystemClock> out_service); + Result GetEphemeralNetworkSystemClock(OutInterface<SystemClock> out_service); + Result GetSharedMemoryNativeHandle(OutCopyHandle<Kernel::KSharedMemory> out_shared_memory); + Result SetStandardSteadyClockInternalOffset(s64 offset_ns); + Result GetStandardSteadyClockRtcValue(Out<s64> out_rtc_value); + Result IsStandardUserSystemClockAutomaticCorrectionEnabled(Out<bool> out_is_enabled); Result SetStandardUserSystemClockAutomaticCorrectionEnabled(bool automatic_correction); - Result IsStandardNetworkSystemClockAccuracySufficient(bool& out_is_sufficient); + Result GetStandardUserSystemClockInitialYear(Out<s32> out_year); + Result IsStandardNetworkSystemClockAccuracySufficient(Out<bool> out_is_sufficient); Result GetStandardUserSystemClockAutomaticCorrectionUpdatedTime( - SteadyClockTimePoint& out_time_point); - Result CalculateMonotonicSystemClockBaseTimePoint(s64& out_time, SystemClockContext& context); - Result GetClockSnapshot(ClockSnapshot& out_snapshot, TimeType type); - Result GetClockSnapshotFromSystemClockContext(ClockSnapshot& out_snapshot, + Out<SteadyClockTimePoint> out_time_point); + Result CalculateMonotonicSystemClockBaseTimePoint(Out<s64> out_time, + SystemClockContext& context); + Result GetClockSnapshot(OutClockSnapshot out_snapshot, TimeType type); + Result GetClockSnapshotFromSystemClockContext(TimeType type, OutClockSnapshot out_snapshot, SystemClockContext& user_context, - SystemClockContext& network_context, - TimeType type); - Result CalculateStandardUserSystemClockDifferenceByUser(s64& out_time, ClockSnapshot& a, - ClockSnapshot& b); - Result CalculateSpanBetween(s64& out_time, ClockSnapshot& a, ClockSnapshot& b); + SystemClockContext& network_context); + Result CalculateStandardUserSystemClockDifferenceByUser(Out<s64> out_difference, + InClockSnapshot a, InClockSnapshot b); + Result CalculateSpanBetween(Out<s64> out_time, InClockSnapshot a, InClockSnapshot b); private: - Result GetClockSnapshotImpl(ClockSnapshot& out_snapshot, SystemClockContext& user_context, + Result GetClockSnapshotImpl(OutClockSnapshot out_snapshot, SystemClockContext& user_context, SystemClockContext& network_context, TimeType type); - void Handle_GetStandardUserSystemClock(HLERequestContext& ctx); - void Handle_GetStandardNetworkSystemClock(HLERequestContext& ctx); - void Handle_GetStandardSteadyClock(HLERequestContext& ctx); - void Handle_GetTimeZoneService(HLERequestContext& ctx); - void Handle_GetStandardLocalSystemClock(HLERequestContext& ctx); - void Handle_GetEphemeralNetworkSystemClock(HLERequestContext& ctx); - void Handle_GetSharedMemoryNativeHandle(HLERequestContext& ctx); - void Handle_SetStandardSteadyClockInternalOffset(HLERequestContext& ctx); - void Handle_GetStandardSteadyClockRtcValue(HLERequestContext& ctx); - void Handle_IsStandardUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx); - void Handle_SetStandardUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx); - void Handle_GetStandardUserSystemClockInitialYear(HLERequestContext& ctx); - void Handle_IsStandardNetworkSystemClockAccuracySufficient(HLERequestContext& ctx); - void Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(HLERequestContext& ctx); - void Handle_CalculateMonotonicSystemClockBaseTimePoint(HLERequestContext& ctx); - void Handle_GetClockSnapshot(HLERequestContext& ctx); - void Handle_GetClockSnapshotFromSystemClockContext(HLERequestContext& ctx); - void Handle_CalculateStandardUserSystemClockDifferenceByUser(HLERequestContext& ctx); - void Handle_CalculateSpanBetween(HLERequestContext& ctx); - Core::System& m_system; StaticServiceSetupInfo m_setup_info; std::shared_ptr<TimeManager> m_time; diff --git a/src/core/hle/service/psc/time/steady_clock.cpp b/src/core/hle/service/psc/time/steady_clock.cpp index 1ed5c7679..948610a2b 100644 --- a/src/core/hle/service/psc/time/steady_clock.cpp +++ b/src/core/hle/service/psc/time/steady_clock.cpp @@ -1,7 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "common/scope_exit.h" #include "core/core.h" +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/psc/time/steady_clock.h" namespace Service::PSC::Time { @@ -14,114 +16,40 @@ SteadyClock::SteadyClock(Core::System& system_, std::shared_ptr<TimeManager> man can_write_uninitialized_clock} { // clang-format off static const FunctionInfo functions[] = { - {0, &SteadyClock::Handle_GetCurrentTimePoint, "GetCurrentTimePoint"}, - {2, &SteadyClock::Handle_GetTestOffset, "GetTestOffset"}, - {3, &SteadyClock::Handle_SetTestOffset, "SetTestOffset"}, - {100, &SteadyClock::Handle_GetRtcValue, "GetRtcValue"}, - {101, &SteadyClock::Handle_IsRtcResetDetected, "IsRtcResetDetected"}, - {102, &SteadyClock::Handle_GetSetupResultValue, "GetSetupResultValue"}, - {200, &SteadyClock::Handle_GetInternalOffset, "GetInternalOffset"}, + {0, D<&SteadyClock::GetCurrentTimePoint>, "GetCurrentTimePoint"}, + {2, D<&SteadyClock::GetTestOffset>, "GetTestOffset"}, + {3, D<&SteadyClock::SetTestOffset>, "SetTestOffset"}, + {100, D<&SteadyClock::GetRtcValue>, "GetRtcValue"}, + {101, D<&SteadyClock::IsRtcResetDetected>, "IsRtcResetDetected"}, + {102, D<&SteadyClock::GetSetupResultValue>, "GetSetupResultValue"}, + {200, D<&SteadyClock::GetInternalOffset>, "GetInternalOffset"}, }; // clang-format on RegisterHandlers(functions); } -void SteadyClock::Handle_GetCurrentTimePoint(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); +Result SteadyClock::GetCurrentTimePoint(Out<SteadyClockTimePoint> out_time_point) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_time_point={}", *out_time_point); }); - SteadyClockTimePoint time_point{}; - auto res = GetCurrentTimePoint(time_point); - - IPC::ResponseBuilder rb{ctx, 2 + sizeof(SteadyClockTimePoint) / sizeof(u32)}; - rb.Push(res); - rb.PushRaw<SteadyClockTimePoint>(time_point); -} - -void SteadyClock::Handle_GetTestOffset(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - s64 test_offset{}; - auto res = GetTestOffset(test_offset); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(res); - rb.Push(test_offset); -} - -void SteadyClock::Handle_SetTestOffset(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto test_offset{rp.Pop<s64>()}; - - auto res = SetTestOffset(test_offset); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void SteadyClock::Handle_GetRtcValue(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - s64 rtc_value{}; - auto res = GetRtcValue(rtc_value); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(res); - rb.Push(rtc_value); -} - -void SteadyClock::Handle_IsRtcResetDetected(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - bool reset_detected{false}; - auto res = IsRtcResetDetected(reset_detected); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.Push(reset_detected); -} - -void SteadyClock::Handle_GetSetupResultValue(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Result result_value{ResultSuccess}; - auto res = GetSetupResultValue(result_value); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.Push(result_value); -} - -void SteadyClock::Handle_GetInternalOffset(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - s64 internal_offset{}; - auto res = GetInternalOffset(internal_offset); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(res); - rb.Push(internal_offset); -} - -// =============================== Implementations =========================== - -Result SteadyClock::GetCurrentTimePoint(SteadyClockTimePoint& out_time_point) { R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), ResultClockUninitialized); - R_RETURN(m_clock_core.GetCurrentTimePoint(out_time_point)); + R_RETURN(m_clock_core.GetCurrentTimePoint(*out_time_point)); } -Result SteadyClock::GetTestOffset(s64& out_test_offset) { +Result SteadyClock::GetTestOffset(Out<s64> out_test_offset) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_test_offset={}", *out_test_offset); }); + R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), ResultClockUninitialized); - out_test_offset = m_clock_core.GetTestOffset(); + *out_test_offset = m_clock_core.GetTestOffset(); R_SUCCEED(); } Result SteadyClock::SetTestOffset(s64 test_offset) { + LOG_DEBUG(Service_Time, "called. test_offset={}", test_offset); + R_UNLESS(m_can_write_steady_clock, ResultPermissionDenied); R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), ResultClockUninitialized); @@ -130,34 +58,43 @@ Result SteadyClock::SetTestOffset(s64 test_offset) { R_SUCCEED(); } -Result SteadyClock::GetRtcValue(s64& out_rtc_value) { +Result SteadyClock::GetRtcValue(Out<s64> out_rtc_value) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_rtc_value={}", *out_rtc_value); }); + R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), ResultClockUninitialized); - R_RETURN(m_clock_core.GetRtcValue(out_rtc_value)); + R_RETURN(m_clock_core.GetRtcValue(*out_rtc_value)); } -Result SteadyClock::IsRtcResetDetected(bool& out_is_detected) { +Result SteadyClock::IsRtcResetDetected(Out<bool> out_is_detected) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_is_detected={}", *out_is_detected); }); + R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), ResultClockUninitialized); - out_is_detected = m_clock_core.IsResetDetected(); + *out_is_detected = m_clock_core.IsResetDetected(); R_SUCCEED(); } -Result SteadyClock::GetSetupResultValue(Result& out_result) { +Result SteadyClock::GetSetupResultValue(Out<Result> out_result) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_result=0x{:X}", out_result->raw); }); + R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), ResultClockUninitialized); - out_result = m_clock_core.GetSetupResultValue(); + *out_result = m_clock_core.GetSetupResultValue(); R_SUCCEED(); } -Result SteadyClock::GetInternalOffset(s64& out_internal_offset) { +Result SteadyClock::GetInternalOffset(Out<s64> out_internal_offset) { + SCOPE_EXIT( + { LOG_DEBUG(Service_Time, "called. out_internal_offset={}", *out_internal_offset); }); + R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), ResultClockUninitialized); - out_internal_offset = m_clock_core.GetInternalOffset(); + *out_internal_offset = m_clock_core.GetInternalOffset(); R_SUCCEED(); } diff --git a/src/core/hle/service/psc/time/steady_clock.h b/src/core/hle/service/psc/time/steady_clock.h index 115e9b138..025d758a6 100644 --- a/src/core/hle/service/psc/time/steady_clock.h +++ b/src/core/hle/service/psc/time/steady_clock.h @@ -3,6 +3,7 @@ #pragma once +#include "core/hle/service/cmif_types.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/psc/time/common.h" #include "core/hle/service/psc/time/manager.h" @@ -22,23 +23,15 @@ public: ~SteadyClock() override = default; - Result GetCurrentTimePoint(SteadyClockTimePoint& out_time_point); - Result GetTestOffset(s64& out_test_offset); + Result GetCurrentTimePoint(Out<SteadyClockTimePoint> out_time_point); + Result GetTestOffset(Out<s64> out_test_offset); Result SetTestOffset(s64 test_offset); - Result GetRtcValue(s64& out_rtc_value); - Result IsRtcResetDetected(bool& out_is_detected); - Result GetSetupResultValue(Result& out_result); - Result GetInternalOffset(s64& out_internal_offset); + Result GetRtcValue(Out<s64> out_rtc_value); + Result IsRtcResetDetected(Out<bool> out_is_detected); + Result GetSetupResultValue(Out<Result> out_result); + Result GetInternalOffset(Out<s64> out_internal_offset); private: - void Handle_GetCurrentTimePoint(HLERequestContext& ctx); - void Handle_GetTestOffset(HLERequestContext& ctx); - void Handle_SetTestOffset(HLERequestContext& ctx); - void Handle_GetRtcValue(HLERequestContext& ctx); - void Handle_IsRtcResetDetected(HLERequestContext& ctx); - void Handle_GetSetupResultValue(HLERequestContext& ctx); - void Handle_GetInternalOffset(HLERequestContext& ctx); - Core::System& m_system; StandardSteadyClockCore& m_clock_core; diff --git a/src/core/hle/service/psc/time/system_clock.cpp b/src/core/hle/service/psc/time/system_clock.cpp index 13d2f1d11..0695502d5 100644 --- a/src/core/hle/service/psc/time/system_clock.cpp +++ b/src/core/hle/service/psc/time/system_clock.cpp @@ -1,7 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "common/scope_exit.h" #include "core/core.h" +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/psc/time/system_clock.h" namespace Service::PSC::Time { @@ -13,83 +15,28 @@ SystemClock::SystemClock(Core::System& system_, SystemClockCore& clock_core, boo can_write_uninitialized_clock} { // clang-format off static const FunctionInfo functions[] = { - {0, &SystemClock::Handle_GetCurrentTime, "GetCurrentTime"}, - {1, &SystemClock::Handle_SetCurrentTime, "SetCurrentTime"}, - {2, &SystemClock::Handle_GetSystemClockContext, "GetSystemClockContext"}, - {3, &SystemClock::Handle_SetSystemClockContext, "SetSystemClockContext"}, - {4, &SystemClock::Handle_GetOperationEventReadableHandle, "GetOperationEventReadableHandle"}, + {0, D<&SystemClock::GetCurrentTime>, "GetCurrentTime"}, + {1, D<&SystemClock::SetCurrentTime>, "SetCurrentTime"}, + {2, D<&SystemClock::GetSystemClockContext>, "GetSystemClockContext"}, + {3, D<&SystemClock::SetSystemClockContext>, "SetSystemClockContext"}, + {4, D<&SystemClock::GetOperationEventReadableHandle>, "GetOperationEventReadableHandle"}, }; // clang-format on RegisterHandlers(functions); } -void SystemClock::Handle_GetCurrentTime(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - s64 time{}; - auto res = GetCurrentTime(time); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(res); - rb.Push<s64>(time); -} - -void SystemClock::Handle_SetCurrentTime(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto time{rp.Pop<s64>()}; - - auto res = SetCurrentTime(time); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void SystemClock::Handle_GetSystemClockContext(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - SystemClockContext context{}; - auto res = GetSystemClockContext(context); - - IPC::ResponseBuilder rb{ctx, 2 + sizeof(SystemClockContext) / sizeof(u32)}; - rb.Push(res); - rb.PushRaw<SystemClockContext>(context); -} - -void SystemClock::Handle_SetSystemClockContext(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto context{rp.PopRaw<SystemClockContext>()}; - - auto res = SetSystemClockContext(context); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void SystemClock::Handle_GetOperationEventReadableHandle(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Kernel::KEvent* event{}; - auto res = GetOperationEventReadableHandle(&event); +Result SystemClock::GetCurrentTime(Out<s64> out_time) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_time={}", *out_time); }); - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(res); - rb.PushCopyObjects(event->GetReadableEvent()); -} - -// =============================== Implementations =========================== - -Result SystemClock::GetCurrentTime(s64& out_time) { R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), ResultClockUninitialized); - R_RETURN(m_clock_core.GetCurrentTime(&out_time)); + R_RETURN(m_clock_core.GetCurrentTime(out_time.Get())); } Result SystemClock::SetCurrentTime(s64 time) { + LOG_DEBUG(Service_Time, "called. time={}", time); + R_UNLESS(m_can_write_clock, ResultPermissionDenied); R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), ResultClockUninitialized); @@ -97,14 +44,18 @@ Result SystemClock::SetCurrentTime(s64 time) { R_RETURN(m_clock_core.SetCurrentTime(time)); } -Result SystemClock::GetSystemClockContext(SystemClockContext& out_context) { +Result SystemClock::GetSystemClockContext(Out<SystemClockContext> out_context) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_context={}", *out_context); }); + R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), ResultClockUninitialized); - R_RETURN(m_clock_core.GetContext(out_context)); + R_RETURN(m_clock_core.GetContext(*out_context)); } Result SystemClock::SetSystemClockContext(SystemClockContext& context) { + LOG_DEBUG(Service_Time, "called. context={}", context); + R_UNLESS(m_can_write_clock, ResultPermissionDenied); R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), ResultClockUninitialized); @@ -112,7 +63,10 @@ Result SystemClock::SetSystemClockContext(SystemClockContext& context) { R_RETURN(m_clock_core.SetContextAndWrite(context)); } -Result SystemClock::GetOperationEventReadableHandle(Kernel::KEvent** out_event) { +Result SystemClock::GetOperationEventReadableHandle( + OutCopyHandle<Kernel::KReadableEvent> out_event) { + LOG_DEBUG(Service_Time, "called."); + if (!m_operation_event) { m_operation_event = std::make_unique<OperationEvent>(m_system); R_UNLESS(m_operation_event != nullptr, ResultFailed); @@ -120,7 +74,7 @@ Result SystemClock::GetOperationEventReadableHandle(Kernel::KEvent** out_event) m_clock_core.LinkOperationEvent(*m_operation_event); } - *out_event = m_operation_event->m_event; + *out_event = &m_operation_event->m_event->GetReadableEvent(); R_SUCCEED(); } diff --git a/src/core/hle/service/psc/time/system_clock.h b/src/core/hle/service/psc/time/system_clock.h index f30027e7b..b40d73595 100644 --- a/src/core/hle/service/psc/time/system_clock.h +++ b/src/core/hle/service/psc/time/system_clock.h @@ -3,6 +3,7 @@ #pragma once +#include "core/hle/service/cmif_types.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/psc/time/common.h" #include "core/hle/service/psc/time/manager.h" @@ -22,19 +23,13 @@ public: ~SystemClock() override = default; - Result GetCurrentTime(s64& out_time); + Result GetCurrentTime(Out<s64> out_time); Result SetCurrentTime(s64 time); - Result GetSystemClockContext(SystemClockContext& out_context); + Result GetSystemClockContext(Out<SystemClockContext> out_context); Result SetSystemClockContext(SystemClockContext& context); - Result GetOperationEventReadableHandle(Kernel::KEvent** out_event); + Result GetOperationEventReadableHandle(OutCopyHandle<Kernel::KReadableEvent> out_event); private: - void Handle_GetCurrentTime(HLERequestContext& ctx); - void Handle_SetCurrentTime(HLERequestContext& ctx); - void Handle_GetSystemClockContext(HLERequestContext& ctx); - void Handle_SetSystemClockContext(HLERequestContext& ctx); - void Handle_GetOperationEventReadableHandle(HLERequestContext& ctx); - Core::System& m_system; SystemClockCore& m_clock_core; diff --git a/src/core/hle/service/psc/time/time_zone.cpp b/src/core/hle/service/psc/time/time_zone.cpp index cfee8f866..82ddba42f 100644 --- a/src/core/hle/service/psc/time/time_zone.cpp +++ b/src/core/hle/service/psc/time/time_zone.cpp @@ -5,7 +5,7 @@ namespace Service::PSC::Time { namespace { -constexpr Result ValidateRule(Tz::Rule& rule) { +constexpr Result ValidateRule(const Tz::Rule& rule) { if (rule.typecnt > static_cast<s32>(Tz::TZ_MAX_TYPES) || rule.timecnt > static_cast<s32>(Tz::TZ_MAX_TIMES) || rule.charcnt > static_cast<s32>(Tz::TZ_MAX_CHARS)) { @@ -26,7 +26,7 @@ constexpr Result ValidateRule(Tz::Rule& rule) { R_SUCCEED(); } -constexpr bool GetTimeZoneTime(s64& out_time, Tz::Rule& rule, s64 time, s32 index, +constexpr bool GetTimeZoneTime(s64& out_time, const Tz::Rule& rule, s64 time, s32 index, s32 index_offset) { s32 found_idx{}; s32 expected_index{index + index_offset}; @@ -107,7 +107,7 @@ Result TimeZone::GetTimePoint(SteadyClockTimePoint& out_time_point) { Result TimeZone::ToCalendarTime(CalendarTime& out_calendar_time, CalendarAdditionalInfo& out_additional_info, s64 time, - Tz::Rule& rule) { + const Tz::Rule& rule) { std::scoped_lock l{m_mutex}; R_RETURN(ToCalendarTimeImpl(out_calendar_time, out_additional_info, time, rule)); } @@ -140,8 +140,8 @@ Result TimeZone::ParseBinaryInto(Tz::Rule& out_rule, std::span<const u8> binary) R_RETURN(ParseBinaryImpl(out_rule, binary)); } -Result TimeZone::ToPosixTime(u32& out_count, std::span<s64, 2> out_times, u32 out_times_count, - CalendarTime& calendar, Tz::Rule& rule) { +Result TimeZone::ToPosixTime(u32& out_count, std::span<s64> out_times, u32 out_times_count, + CalendarTime& calendar, const Tz::Rule& rule) { std::scoped_lock l{m_mutex}; auto res = ToPosixTimeImpl(out_count, out_times, out_times_count, calendar, rule, -1); @@ -157,7 +157,7 @@ Result TimeZone::ToPosixTime(u32& out_count, std::span<s64, 2> out_times, u32 ou R_RETURN(res); } -Result TimeZone::ToPosixTimeWithMyRule(u32& out_count, std::span<s64, 2> out_times, +Result TimeZone::ToPosixTimeWithMyRule(u32& out_count, std::span<s64> out_times, u32 out_times_count, CalendarTime& calendar) { std::scoped_lock l{m_mutex}; @@ -183,7 +183,7 @@ Result TimeZone::ParseBinaryImpl(Tz::Rule& out_rule, std::span<const u8> binary) Result TimeZone::ToCalendarTimeImpl(CalendarTime& out_calendar_time, CalendarAdditionalInfo& out_additional_info, s64 time, - Tz::Rule& rule) { + const Tz::Rule& rule) { R_TRY(ValidateRule(rule)); Tz::CalendarTimeInternal calendar_internal{}; @@ -212,8 +212,8 @@ Result TimeZone::ToCalendarTimeImpl(CalendarTime& out_calendar_time, R_SUCCEED(); } -Result TimeZone::ToPosixTimeImpl(u32& out_count, std::span<s64, 2> out_times, u32 out_times_count, - CalendarTime& calendar, Tz::Rule& rule, s32 is_dst) { +Result TimeZone::ToPosixTimeImpl(u32& out_count, std::span<s64> out_times, u32 out_times_count, + CalendarTime& calendar, const Tz::Rule& rule, s32 is_dst) { R_TRY(ValidateRule(rule)); calendar.month -= 1; diff --git a/src/core/hle/service/psc/time/time_zone.h b/src/core/hle/service/psc/time/time_zone.h index ce2acca17..6bd8f2fda 100644 --- a/src/core/hle/service/psc/time/time_zone.h +++ b/src/core/hle/service/psc/time/time_zone.h @@ -32,23 +32,24 @@ public: Result GetTimePoint(SteadyClockTimePoint& out_time_point); Result ToCalendarTime(CalendarTime& out_calendar_time, - CalendarAdditionalInfo& out_additional_info, s64 time, Tz::Rule& rule); + CalendarAdditionalInfo& out_additional_info, s64 time, + const Tz::Rule& rule); Result ToCalendarTimeWithMyRule(CalendarTime& calendar_time, CalendarAdditionalInfo& calendar_additional, s64 time); Result ParseBinary(LocationName& name, std::span<const u8> binary); Result ParseBinaryInto(Tz::Rule& out_rule, std::span<const u8> binary); - Result ToPosixTime(u32& out_count, std::span<s64, 2> out_times, u32 out_times_count, - CalendarTime& calendar, Tz::Rule& rule); - Result ToPosixTimeWithMyRule(u32& out_count, std::span<s64, 2> out_times, u32 out_times_count, + Result ToPosixTime(u32& out_count, std::span<s64> out_times, u32 out_times_count, + CalendarTime& calendar, const Tz::Rule& rule); + Result ToPosixTimeWithMyRule(u32& out_count, std::span<s64> out_times, u32 out_times_count, CalendarTime& calendar); private: Result ParseBinaryImpl(Tz::Rule& out_rule, std::span<const u8> binary); Result ToCalendarTimeImpl(CalendarTime& out_calendar_time, CalendarAdditionalInfo& out_additional_info, s64 time, - Tz::Rule& rule); - Result ToPosixTimeImpl(u32& out_count, std::span<s64, 2> out_times, u32 out_times_count, - CalendarTime& calendar, Tz::Rule& rule, s32 is_dst); + const Tz::Rule& rule); + Result ToPosixTimeImpl(u32& out_count, std::span<s64> out_times, u32 out_times_count, + CalendarTime& calendar, const Tz::Rule& rule, s32 is_dst); bool m_initialized{}; std::recursive_mutex m_mutex; diff --git a/src/core/hle/service/psc/time/time_zone_service.cpp b/src/core/hle/service/psc/time/time_zone_service.cpp index e304c8387..9376a0324 100644 --- a/src/core/hle/service/psc/time/time_zone_service.cpp +++ b/src/core/hle/service/psc/time/time_zone_service.cpp @@ -2,7 +2,10 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include <tz/tz.h> + +#include "common/scope_exit.h" #include "core/core.h" +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/psc/time/time_zone_service.h" namespace Service::PSC::Time { @@ -14,276 +17,153 @@ TimeZoneService::TimeZoneService(Core::System& system_, StandardSteadyClockCore& can_write_timezone_device_location} { // clang-format off static const FunctionInfo functions[] = { - {0, &TimeZoneService::Handle_GetDeviceLocationName, "GetDeviceLocationName"}, - {1, &TimeZoneService::Handle_SetDeviceLocationName, "SetDeviceLocationName"}, - {2, &TimeZoneService::Handle_GetTotalLocationNameCount, "GetTotalLocationNameCount"}, - {3, &TimeZoneService::Handle_LoadLocationNameList, "LoadLocationNameList"}, - {4, &TimeZoneService::Handle_LoadTimeZoneRule, "LoadTimeZoneRule"}, - {5, &TimeZoneService::Handle_GetTimeZoneRuleVersion, "GetTimeZoneRuleVersion"}, - {6, &TimeZoneService::Handle_GetDeviceLocationNameAndUpdatedTime, "GetDeviceLocationNameAndUpdatedTime"}, - {7, &TimeZoneService::Handle_SetDeviceLocationNameWithTimeZoneRule, "SetDeviceLocationNameWithTimeZoneRule"}, - {8, &TimeZoneService::Handle_ParseTimeZoneBinary, "ParseTimeZoneBinary"}, - {20, &TimeZoneService::Handle_GetDeviceLocationNameOperationEventReadableHandle, "GetDeviceLocationNameOperationEventReadableHandle"}, - {100, &TimeZoneService::Handle_ToCalendarTime, "ToCalendarTime"}, - {101, &TimeZoneService::Handle_ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"}, - {201, &TimeZoneService::Handle_ToPosixTime, "ToPosixTime"}, - {202, &TimeZoneService::Handle_ToPosixTimeWithMyRule, "ToPosixTimeWithMyRule"}, + {0, D<&TimeZoneService::GetDeviceLocationName>, "GetDeviceLocationName"}, + {1, D<&TimeZoneService::SetDeviceLocationName>, "SetDeviceLocationName"}, + {2, D<&TimeZoneService::GetTotalLocationNameCount>, "GetTotalLocationNameCount"}, + {3, D<&TimeZoneService::LoadLocationNameList>, "LoadLocationNameList"}, + {4, D<&TimeZoneService::LoadTimeZoneRule>, "LoadTimeZoneRule"}, + {5, D<&TimeZoneService::GetTimeZoneRuleVersion>, "GetTimeZoneRuleVersion"}, + {6, D<&TimeZoneService::GetDeviceLocationNameAndUpdatedTime>, "GetDeviceLocationNameAndUpdatedTime"}, + {7, D<&TimeZoneService::SetDeviceLocationNameWithTimeZoneRule>, "SetDeviceLocationNameWithTimeZoneRule"}, + {8, D<&TimeZoneService::ParseTimeZoneBinary>, "ParseTimeZoneBinary"}, + {20, D<&TimeZoneService::GetDeviceLocationNameOperationEventReadableHandle>, "GetDeviceLocationNameOperationEventReadableHandle"}, + {100, D<&TimeZoneService::ToCalendarTime>, "ToCalendarTime"}, + {101, D<&TimeZoneService::ToCalendarTimeWithMyRule>, "ToCalendarTimeWithMyRule"}, + {201, D<&TimeZoneService::ToPosixTime>, "ToPosixTime"}, + {202, D<&TimeZoneService::ToPosixTimeWithMyRule>, "ToPosixTimeWithMyRule"}, }; // clang-format on RegisterHandlers(functions); } -void TimeZoneService::Handle_GetDeviceLocationName(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - LocationName name{}; - auto res = GetDeviceLocationName(name); - - IPC::ResponseBuilder rb{ctx, 2 + sizeof(LocationName) / sizeof(u32)}; - rb.Push(res); - rb.PushRaw<LocationName>(name); -} - -void TimeZoneService::Handle_SetDeviceLocationName(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - [[maybe_unused]] auto name{rp.PopRaw<LocationName>()}; - - if (!m_can_write_timezone_device_location) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultPermissionDenied); - return; - } - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultNotImplemented); -} - -void TimeZoneService::Handle_GetTotalLocationNameCount(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - u32 count{}; - auto res = GetTotalLocationNameCount(count); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.Push(count); -} - -void TimeZoneService::Handle_LoadLocationNameList(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); +Result TimeZoneService::GetDeviceLocationName(Out<LocationName> out_location_name) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_location_name={}", *out_location_name); }); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultNotImplemented); + R_RETURN(m_time_zone.GetLocationName(*out_location_name)); } -void TimeZoneService::Handle_LoadTimeZoneRule(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); +Result TimeZoneService::SetDeviceLocationName(LocationName& location_name) { + LOG_DEBUG(Service_Time, "called. This function is not implemented!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultNotImplemented); + R_UNLESS(m_can_write_timezone_device_location, ResultPermissionDenied); + R_RETURN(ResultNotImplemented); } -void TimeZoneService::Handle_GetTimeZoneRuleVersion(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - RuleVersion rule_version{}; - auto res = GetTimeZoneRuleVersion(rule_version); +Result TimeZoneService::GetTotalLocationNameCount(Out<u32> out_count) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_count={}", *out_count); }); - IPC::ResponseBuilder rb{ctx, 2 + sizeof(RuleVersion) / sizeof(u32)}; - rb.Push(res); - rb.PushRaw<RuleVersion>(rule_version); + R_RETURN(m_time_zone.GetTotalLocationCount(*out_count)); } -void TimeZoneService::Handle_GetDeviceLocationNameAndUpdatedTime(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - LocationName name{}; - SteadyClockTimePoint time_point{}; - auto res = GetDeviceLocationNameAndUpdatedTime(time_point, name); +Result TimeZoneService::LoadLocationNameList( + Out<u32> out_count, OutArray<LocationName, BufferAttr_HipcMapAlias> out_names, u32 index) { + LOG_DEBUG(Service_Time, "called. This function is not implemented!"); - IPC::ResponseBuilder rb{ctx, 2 + (sizeof(LocationName) / sizeof(u32)) + - (sizeof(SteadyClockTimePoint) / sizeof(u32))}; - rb.Push(res); - rb.PushRaw<LocationName>(name); - rb.PushRaw<SteadyClockTimePoint>(time_point); + R_RETURN(ResultNotImplemented); } -void TimeZoneService::Handle_SetDeviceLocationNameWithTimeZoneRule(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto name{rp.PopRaw<LocationName>()}; - - auto binary{ctx.ReadBuffer()}; - auto res = SetDeviceLocationNameWithTimeZoneRule(name, binary); +Result TimeZoneService::LoadTimeZoneRule(OutRule out_rule, LocationName& location_name) { + LOG_DEBUG(Service_Time, "called. This function is not implemented!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); + R_RETURN(ResultNotImplemented); } -void TimeZoneService::Handle_ParseTimeZoneBinary(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - auto binary{ctx.ReadBuffer()}; +Result TimeZoneService::GetTimeZoneRuleVersion(Out<RuleVersion> out_rule_version) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_rule_version={}", *out_rule_version); }); - Tz::Rule rule{}; - auto res = ParseTimeZoneBinary(rule, binary); - - ctx.WriteBuffer(rule); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); + R_RETURN(m_time_zone.GetRuleVersion(*out_rule_version)); } -void TimeZoneService::Handle_GetDeviceLocationNameOperationEventReadableHandle( - HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); +Result TimeZoneService::GetDeviceLocationNameAndUpdatedTime( + Out<LocationName> out_location_name, Out<SteadyClockTimePoint> out_time_point) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, "called. out_location_name={} out_time_point={}", + *out_location_name, *out_time_point); + }); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultNotImplemented); + R_TRY(m_time_zone.GetLocationName(*out_location_name)); + R_RETURN(m_time_zone.GetTimePoint(*out_time_point)); } -void TimeZoneService::Handle_ToCalendarTime(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto time{rp.Pop<s64>()}; +Result TimeZoneService::SetDeviceLocationNameWithTimeZoneRule( + LocationName& location_name, InBuffer<BufferAttr_HipcAutoSelect> binary) { + LOG_DEBUG(Service_Time, "called. location_name={}", location_name); - auto rule_buffer{ctx.ReadBuffer()}; - Tz::Rule rule{}; - std::memcpy(&rule, rule_buffer.data(), sizeof(Tz::Rule)); - - CalendarTime calendar_time{}; - CalendarAdditionalInfo additional_info{}; - auto res = ToCalendarTime(calendar_time, additional_info, time, rule); - - IPC::ResponseBuilder rb{ctx, 2 + (sizeof(CalendarTime) / sizeof(u32)) + - (sizeof(CalendarAdditionalInfo) / sizeof(u32))}; - rb.Push(res); - rb.PushRaw<CalendarTime>(calendar_time); - rb.PushRaw<CalendarAdditionalInfo>(additional_info); -} - -void TimeZoneService::Handle_ToCalendarTimeWithMyRule(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto time{rp.Pop<s64>()}; + R_UNLESS(m_can_write_timezone_device_location, ResultPermissionDenied); + R_TRY(m_time_zone.ParseBinary(location_name, binary)); - CalendarTime calendar_time{}; - CalendarAdditionalInfo additional_info{}; - auto res = ToCalendarTimeWithMyRule(calendar_time, additional_info, time); + SteadyClockTimePoint time_point{}; + R_TRY(m_clock_core.GetCurrentTimePoint(time_point)); - IPC::ResponseBuilder rb{ctx, 2 + (sizeof(CalendarTime) / sizeof(u32)) + - (sizeof(CalendarAdditionalInfo) / sizeof(u32))}; - rb.Push(res); - rb.PushRaw<CalendarTime>(calendar_time); - rb.PushRaw<CalendarAdditionalInfo>(additional_info); + m_time_zone.SetTimePoint(time_point); + R_SUCCEED(); } -void TimeZoneService::Handle_ToPosixTime(HLERequestContext& ctx) { +Result TimeZoneService::ParseTimeZoneBinary(OutRule out_rule, + InBuffer<BufferAttr_HipcAutoSelect> binary) { LOG_DEBUG(Service_Time, "called."); - IPC::RequestParser rp{ctx}; - auto calendar{rp.PopRaw<CalendarTime>()}; - - auto binary{ctx.ReadBuffer()}; - - Tz::Rule rule{}; - std::memcpy(&rule, binary.data(), sizeof(Tz::Rule)); - - u32 count{}; - std::array<s64, 2> times{}; - u32 times_count{static_cast<u32>(ctx.GetWriteBufferSize() / sizeof(s64))}; - - auto res = ToPosixTime(count, times, times_count, calendar, rule); - - ctx.WriteBuffer(times); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.Push(count); + R_RETURN(m_time_zone.ParseBinaryInto(*out_rule, binary)); } -void TimeZoneService::Handle_ToPosixTimeWithMyRule(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto calendar{rp.PopRaw<CalendarTime>()}; +Result TimeZoneService::GetDeviceLocationNameOperationEventReadableHandle( + OutCopyHandle<Kernel::KReadableEvent> out_event) { + LOG_DEBUG(Service_Time, "called. This function is not implemented!"); - u32 count{}; - std::array<s64, 2> times{}; - u32 times_count{static_cast<u32>(ctx.GetWriteBufferSize() / sizeof(s64))}; - - auto res = ToPosixTimeWithMyRule(count, times, times_count, calendar); - - ctx.WriteBuffer(times); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.Push(count); + R_RETURN(ResultNotImplemented); } -// =============================== Implementations =========================== - -Result TimeZoneService::GetDeviceLocationName(LocationName& out_location_name) { - R_RETURN(m_time_zone.GetLocationName(out_location_name)); -} +Result TimeZoneService::ToCalendarTime(Out<CalendarTime> out_calendar_time, + Out<CalendarAdditionalInfo> out_additional_info, s64 time, + InRule rule) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, "called. time={} out_calendar_time={} out_additional_info={}", time, + *out_calendar_time, *out_additional_info); + }); -Result TimeZoneService::GetTotalLocationNameCount(u32& out_count) { - R_RETURN(m_time_zone.GetTotalLocationCount(out_count)); -} - -Result TimeZoneService::GetTimeZoneRuleVersion(RuleVersion& out_rule_version) { - R_RETURN(m_time_zone.GetRuleVersion(out_rule_version)); -} - -Result TimeZoneService::GetDeviceLocationNameAndUpdatedTime(SteadyClockTimePoint& out_time_point, - LocationName& location_name) { - R_TRY(m_time_zone.GetLocationName(location_name)); - R_RETURN(m_time_zone.GetTimePoint(out_time_point)); + R_RETURN( + m_time_zone.ToCalendarTime(*out_calendar_time, *out_additional_info, time, *rule.Get())); } -Result TimeZoneService::SetDeviceLocationNameWithTimeZoneRule(LocationName& location_name, - std::span<const u8> binary) { - R_UNLESS(m_can_write_timezone_device_location, ResultPermissionDenied); - R_TRY(m_time_zone.ParseBinary(location_name, binary)); - - SteadyClockTimePoint time_point{}; - R_TRY(m_clock_core.GetCurrentTimePoint(time_point)); +Result TimeZoneService::ToCalendarTimeWithMyRule(Out<CalendarTime> out_calendar_time, + Out<CalendarAdditionalInfo> out_additional_info, + s64 time) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, "called. time={} out_calendar_time={} out_additional_info={}", time, + *out_calendar_time, *out_additional_info); + }); - m_time_zone.SetTimePoint(time_point); - R_SUCCEED(); + R_RETURN(m_time_zone.ToCalendarTimeWithMyRule(*out_calendar_time, *out_additional_info, time)); } -Result TimeZoneService::ParseTimeZoneBinary(Tz::Rule& out_rule, std::span<const u8> binary) { - R_RETURN(m_time_zone.ParseBinaryInto(out_rule, binary)); -} +Result TimeZoneService::ToPosixTime(Out<u32> out_count, + OutArray<s64, BufferAttr_HipcPointer> out_times, + Out<u32> out_times_count, CalendarTime& calendar_time, + InRule rule) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, + "called. calendar_time={} out_count={} out_times[0]={} out_times[1]={} " + "out_times_count={}", + calendar_time, *out_count, out_times[0], out_times[1], *out_times_count); + }); -Result TimeZoneService::ToCalendarTime(CalendarTime& out_calendar_time, - CalendarAdditionalInfo& out_additional_info, s64 time, - Tz::Rule& rule) { - R_RETURN(m_time_zone.ToCalendarTime(out_calendar_time, out_additional_info, time, rule)); -} - -Result TimeZoneService::ToCalendarTimeWithMyRule(CalendarTime& out_calendar_time, - CalendarAdditionalInfo& out_additional_info, - s64 time) { - R_RETURN(m_time_zone.ToCalendarTimeWithMyRule(out_calendar_time, out_additional_info, time)); + R_RETURN( + m_time_zone.ToPosixTime(*out_count, out_times, *out_times_count, calendar_time, *rule)); } -Result TimeZoneService::ToPosixTime(u32& out_count, std::span<s64, 2> out_times, - u32 out_times_count, CalendarTime& calendar_time, - Tz::Rule& rule) { - R_RETURN(m_time_zone.ToPosixTime(out_count, out_times, out_times_count, calendar_time, rule)); -} +Result TimeZoneService::ToPosixTimeWithMyRule(Out<u32> out_count, + OutArray<s64, BufferAttr_HipcPointer> out_times, + Out<u32> out_times_count, + CalendarTime& calendar_time) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, + "called. calendar_time={} out_count={} out_times[0]={} out_times[1]={} " + "out_times_count={}", + calendar_time, *out_count, out_times[0], out_times[1], *out_times_count); + }); -Result TimeZoneService::ToPosixTimeWithMyRule(u32& out_count, std::span<s64, 2> out_times, - u32 out_times_count, CalendarTime& calendar_time) { R_RETURN( - m_time_zone.ToPosixTimeWithMyRule(out_count, out_times, out_times_count, calendar_time)); + m_time_zone.ToPosixTimeWithMyRule(*out_count, out_times, *out_times_count, calendar_time)); } } // namespace Service::PSC::Time diff --git a/src/core/hle/service/psc/time/time_zone_service.h b/src/core/hle/service/psc/time/time_zone_service.h index 074c1d4ae..084e3f907 100644 --- a/src/core/hle/service/psc/time/time_zone_service.h +++ b/src/core/hle/service/psc/time/time_zone_service.h @@ -3,6 +3,7 @@ #pragma once +#include "core/hle/service/cmif_types.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/psc/time/common.h" #include "core/hle/service/psc/time/manager.h" @@ -20,45 +21,41 @@ struct Rule; namespace Service::PSC::Time { class TimeZoneService final : public ServiceFramework<TimeZoneService> { + using InRule = InLargeData<Tz::Rule, BufferAttr_HipcMapAlias>; + using OutRule = OutLargeData<Tz::Rule, BufferAttr_HipcMapAlias>; + public: explicit TimeZoneService(Core::System& system, StandardSteadyClockCore& clock_core, TimeZone& time_zone, bool can_write_timezone_device_location); ~TimeZoneService() override = default; - Result GetDeviceLocationName(LocationName& out_location_name); - Result GetTotalLocationNameCount(u32& out_count); - Result GetTimeZoneRuleVersion(RuleVersion& out_rule_version); - Result GetDeviceLocationNameAndUpdatedTime(SteadyClockTimePoint& out_time_point, - LocationName& location_name); + Result GetDeviceLocationName(Out<LocationName> out_location_name); + Result SetDeviceLocationName(LocationName& location_name); + Result GetTotalLocationNameCount(Out<u32> out_count); + Result LoadLocationNameList(Out<u32> out_count, + OutArray<LocationName, BufferAttr_HipcMapAlias> out_names, + u32 index); + Result LoadTimeZoneRule(OutRule out_rule, LocationName& location_name); + Result GetTimeZoneRuleVersion(Out<RuleVersion> out_rule_version); + Result GetDeviceLocationNameAndUpdatedTime(Out<LocationName> location_name, + Out<SteadyClockTimePoint> out_time_point); Result SetDeviceLocationNameWithTimeZoneRule(LocationName& location_name, - std::span<const u8> binary); - Result ParseTimeZoneBinary(Tz::Rule& out_rule, std::span<const u8> binary); - Result ToCalendarTime(CalendarTime& out_calendar_time, - CalendarAdditionalInfo& out_additional_info, s64 time, Tz::Rule& rule); - Result ToCalendarTimeWithMyRule(CalendarTime& out_calendar_time, - CalendarAdditionalInfo& out_additional_info, s64 time); - Result ToPosixTime(u32& out_count, std::span<s64, 2> out_times, u32 out_times_count, - CalendarTime& calendar_time, Tz::Rule& rule); - Result ToPosixTimeWithMyRule(u32& out_count, std::span<s64, 2> out_times, u32 out_times_count, - CalendarTime& calendar_time); + InBuffer<BufferAttr_HipcAutoSelect> binary); + Result ParseTimeZoneBinary(OutRule out_rule, InBuffer<BufferAttr_HipcAutoSelect> binary); + Result GetDeviceLocationNameOperationEventReadableHandle( + OutCopyHandle<Kernel::KReadableEvent> out_event); + Result ToCalendarTime(Out<CalendarTime> out_calendar_time, + Out<CalendarAdditionalInfo> out_additional_info, s64 time, InRule rule); + Result ToCalendarTimeWithMyRule(Out<CalendarTime> out_calendar_time, + Out<CalendarAdditionalInfo> out_additional_info, s64 time); + Result ToPosixTime(Out<u32> out_count, OutArray<s64, BufferAttr_HipcPointer> out_times, + Out<u32> out_times_count, CalendarTime& calendar_time, InRule rule); + Result ToPosixTimeWithMyRule(Out<u32> out_count, + OutArray<s64, BufferAttr_HipcPointer> out_times, + Out<u32> out_times_count, CalendarTime& calendar_time); private: - void Handle_GetDeviceLocationName(HLERequestContext& ctx); - void Handle_SetDeviceLocationName(HLERequestContext& ctx); - void Handle_GetTotalLocationNameCount(HLERequestContext& ctx); - void Handle_LoadLocationNameList(HLERequestContext& ctx); - void Handle_LoadTimeZoneRule(HLERequestContext& ctx); - void Handle_GetTimeZoneRuleVersion(HLERequestContext& ctx); - void Handle_GetDeviceLocationNameAndUpdatedTime(HLERequestContext& ctx); - void Handle_SetDeviceLocationNameWithTimeZoneRule(HLERequestContext& ctx); - void Handle_ParseTimeZoneBinary(HLERequestContext& ctx); - void Handle_GetDeviceLocationNameOperationEventReadableHandle(HLERequestContext& ctx); - void Handle_ToCalendarTime(HLERequestContext& ctx); - void Handle_ToCalendarTimeWithMyRule(HLERequestContext& ctx); - void Handle_ToPosixTime(HLERequestContext& ctx); - void Handle_ToPosixTimeWithMyRule(HLERequestContext& ctx); - Core::System& m_system; StandardSteadyClockCore& m_clock_core; |