diff options
Diffstat (limited to 'src/core/hle')
33 files changed, 1205 insertions, 2040 deletions
diff --git a/src/core/hle/service/caps/caps_manager.cpp b/src/core/hle/service/caps/caps_manager.cpp index e3b8ecf3e..3a22b135f 100644 --- a/src/core/hle/service/caps/caps_manager.cpp +++ b/src/core/hle/service/caps/caps_manager.cpp @@ -246,10 +246,10 @@ Result AlbumManager::SaveScreenShot(ApplicationAlbumEntry& out_entry, system.ServiceManager().GetService<Service::Glue::Time::StaticService>("time:u", true); std::shared_ptr<Service::PSC::Time::SystemClock> user_clock{}; - static_service->GetStandardUserSystemClock(user_clock); + static_service->GetStandardUserSystemClock(&user_clock); s64 posix_time{}; - auto result = user_clock->GetCurrentTime(posix_time); + auto result = user_clock->GetCurrentTime(&posix_time); if (result.IsError()) { return result; @@ -268,10 +268,10 @@ Result AlbumManager::SaveEditedScreenShot(ApplicationAlbumEntry& out_entry, system.ServiceManager().GetService<Service::Glue::Time::StaticService>("time:u", true); std::shared_ptr<Service::PSC::Time::SystemClock> user_clock{}; - static_service->GetStandardUserSystemClock(user_clock); + static_service->GetStandardUserSystemClock(&user_clock); s64 posix_time{}; - auto result = user_clock->GetCurrentTime(posix_time); + auto result = user_clock->GetCurrentTime(&posix_time); if (result.IsError()) { return result; @@ -470,11 +470,11 @@ AlbumFileDateTime AlbumManager::ConvertToAlbumDateTime(u64 posix_time) const { system.ServiceManager().GetService<Service::Glue::Time::StaticService>("time:u", true); std::shared_ptr<Service::Glue::Time::TimeZoneService> timezone_service{}; - static_service->GetTimeZoneService(timezone_service); + static_service->GetTimeZoneService(&timezone_service); Service::PSC::Time::CalendarTime calendar_time{}; Service::PSC::Time::CalendarAdditionalInfo additional_info{}; - timezone_service->ToCalendarTimeWithMyRule(calendar_time, additional_info, posix_time); + timezone_service->ToCalendarTimeWithMyRule(&calendar_time, &additional_info, posix_time); return { .year = calendar_time.year, diff --git a/src/core/hle/service/cmif_serialization.h b/src/core/hle/service/cmif_serialization.h index 9eb10e816..9ee26400d 100644 --- a/src/core/hle/service/cmif_serialization.h +++ b/src/core/hle/service/cmif_serialization.h @@ -12,6 +12,109 @@ namespace Service { // clang-format off +template <typename T> +struct UnwrapArg { + using Type = std::remove_cvref_t<T>; +}; + +template <typename T, int A> +struct UnwrapArg<InLargeData<T, A>> { + using Type = std::remove_cv_t<typename InLargeData<T, A>::Type>; +}; + +template <typename T> +struct UnwrapArg<Out<T>> { + using Type = AutoOut<typename Out<T>::Type>; +}; + +template <typename T> +struct UnwrapArg<OutCopyHandle<T>> { + using Type = AutoOut<typename OutCopyHandle<T>::Type>; +}; + +template <typename T> +struct UnwrapArg<OutMoveHandle<T>> { + using Type = AutoOut<typename OutMoveHandle<T>::Type>; +}; + +template <typename T, int A> +struct UnwrapArg<OutLargeData<T, A>> { + using Type = AutoOut<typename OutLargeData<T, A>::Type>; +}; + +enum class ArgumentType { + InProcessId, + InData, + InInterface, + InCopyHandle, + OutData, + OutInterface, + OutCopyHandle, + OutMoveHandle, + InBuffer, + InLargeData, + OutBuffer, + OutLargeData, +}; + +template <typename T> +struct ArgumentTraits; + +template <> +struct ArgumentTraits<ClientProcessId> { + static constexpr ArgumentType Type = ArgumentType::InProcessId; +}; + +template <typename T> +struct ArgumentTraits<SharedPointer<T>> { + static constexpr ArgumentType Type = ArgumentType::InInterface; +}; + +template <typename T> +struct ArgumentTraits<InCopyHandle<T>> { + static constexpr ArgumentType Type = ArgumentType::InCopyHandle; +}; + +template <typename T> +struct ArgumentTraits<Out<SharedPointer<T>>> { + static constexpr ArgumentType Type = ArgumentType::OutInterface; +}; + +template <typename T> +struct ArgumentTraits<Out<T>> { + static constexpr ArgumentType Type = ArgumentType::OutData; +}; + +template <typename T> +struct ArgumentTraits<OutCopyHandle<T>> { + static constexpr ArgumentType Type = ArgumentType::OutCopyHandle; +}; + +template <typename T> +struct ArgumentTraits<OutMoveHandle<T>> { + static constexpr ArgumentType Type = ArgumentType::OutMoveHandle; +}; + +template <typename T, int A> +struct ArgumentTraits<Buffer<T, A>> { + static constexpr ArgumentType Type = (A & BufferAttr_In) == 0 ? ArgumentType::OutBuffer : ArgumentType::InBuffer; +}; + +template <typename T, int A> +struct ArgumentTraits<InLargeData<T, A>> { + static constexpr ArgumentType Type = ArgumentType::InLargeData; +}; + +template <typename T, int A> +struct ArgumentTraits<OutLargeData<T, A>> { + static constexpr ArgumentType Type = ArgumentType::OutLargeData; +}; + +template <typename T> +struct ArgumentTraits { + static constexpr ArgumentType Type = ArgumentType::InData; +}; + struct RequestLayout { u32 copy_handle_count; u32 move_handle_count; @@ -122,6 +225,8 @@ void ReadInArgument(bool is_domain, CallArguments& args, const u8* raw_data, HLE static_assert(PrevAlign <= ArgAlign, "Input argument is not ordered by alignment"); static_assert(!RawDataFinished, "All input interface arguments must appear after raw data"); + static_assert(!std::is_pointer_v<ArgType>, "Input raw data must not be a pointer"); + static_assert(std::is_trivially_copyable_v<ArgType>, "Input raw data must be trivially copyable"); constexpr size_t ArgOffset = Common::AlignUp(DataOffset, ArgAlign); constexpr size_t ArgEnd = ArgOffset + ArgSize; @@ -198,7 +303,7 @@ void ReadInArgument(bool is_domain, CallArguments& args, const u8* raw_data, HLE constexpr size_t BufferSize = sizeof(ArgType); // Clear the existing data. - std::memset(&std::get<ArgIndex>(args), 0, BufferSize); + std::memset(&std::get<ArgIndex>(args).raw, 0, BufferSize); return ReadInArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex, OutBufferIndex + 1, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp); } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutBuffer) { @@ -237,27 +342,29 @@ void WriteOutArgument(bool is_domain, CallArguments& args, u8* raw_data, HLERequ static_assert(PrevAlign <= ArgAlign, "Output argument is not ordered by alignment"); static_assert(!RawDataFinished, "All output interface arguments must appear after raw data"); + static_assert(!std::is_pointer_v<ArgType>, "Output raw data must not be a pointer"); + static_assert(std::is_trivially_copyable_v<decltype(std::get<ArgIndex>(args).raw)>, "Output raw data must be trivially copyable"); constexpr size_t ArgOffset = Common::AlignUp(DataOffset, ArgAlign); constexpr size_t ArgEnd = ArgOffset + ArgSize; - std::memcpy(raw_data + ArgOffset, &std::get<ArgIndex>(args), ArgSize); + std::memcpy(raw_data + ArgOffset, &std::get<ArgIndex>(args).raw, ArgSize); return WriteOutArgument<MethodArguments, CallArguments, ArgAlign, ArgEnd, OutBufferIndex, false, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp); } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutInterface) { if (is_domain) { - ctx.AddDomainObject(std::get<ArgIndex>(args)); + ctx.AddDomainObject(std::get<ArgIndex>(args).raw); } else { - ctx.AddMoveInterface(std::get<ArgIndex>(args)); + ctx.AddMoveInterface(std::get<ArgIndex>(args).raw); } return WriteOutArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, true, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp); } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutCopyHandle) { - ctx.AddCopyObject(std::get<ArgIndex>(args)); + ctx.AddCopyObject(std::get<ArgIndex>(args).raw); return WriteOutArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp); } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutMoveHandle) { - ctx.AddMoveObject(std::get<ArgIndex>(args)); + ctx.AddMoveObject(std::get<ArgIndex>(args).raw); return WriteOutArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp); } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutLargeData) { @@ -302,10 +409,10 @@ void CmifReplyWrapImpl(HLERequestContext& ctx, T& t, Result (T::*f)(A...)) { } const bool is_domain = Domain ? ctx.GetManager()->IsDomain() : false; - using MethodArguments = std::tuple<std::remove_reference_t<A>...>; + using MethodArguments = std::tuple<std::remove_cvref_t<A>...>; OutTemporaryBuffers buffers{}; - auto call_arguments = std::tuple<typename RemoveOut<A>::Type...>(); + auto call_arguments = std::tuple<typename UnwrapArg<A>::Type...>(); // Read inputs. const size_t offset_plus_command_id = ctx.GetDataPayloadOffset() + 2; diff --git a/src/core/hle/service/cmif_types.h b/src/core/hle/service/cmif_types.h index 2610c49f3..dc06169f4 100644 --- a/src/core/hle/service/cmif_types.h +++ b/src/core/hle/service/cmif_types.h @@ -13,21 +13,30 @@ namespace Service { // clang-format off template <typename T> +struct AutoOut { + T raw; +}; + +template <typename T> class Out { public: using Type = T; - /* implicit */ Out(Type& t) : raw(&t) {} - ~Out() = default; + /* implicit */ Out(AutoOut<Type>& t) : raw(&t.raw) {} + /* implicit */ Out(Type* t) : raw(t) {} Type* Get() const { return raw; } - Type& operator*() { + Type& operator*() const { return *raw; } + Type* operator->() const { + return raw; + } + private: Type* raw; }; @@ -35,6 +44,9 @@ private: template <typename T> using SharedPointer = std::shared_ptr<T>; +template <typename T> +using OutInterface = Out<SharedPointer<T>>; + struct ClientProcessId { explicit operator bool() const { return pid != 0; @@ -101,17 +113,21 @@ class OutCopyHandle { public: using Type = T*; - /* implicit */ OutCopyHandle(Type& t) : raw(&t) {} - ~OutCopyHandle() = default; + /* implicit */ OutCopyHandle(AutoOut<Type>& t) : raw(&t.raw) {} + /* implicit */ OutCopyHandle(Type* t) : raw(t) {} Type* Get() const { return raw; } - Type& operator*() { + Type& operator*() const { return *raw; } + Type* operator->() const { + return raw; + } + private: Type* raw; }; @@ -121,30 +137,34 @@ class OutMoveHandle { public: using Type = T*; - /* implicit */ OutMoveHandle(Type& t) : raw(&t) {} - ~OutMoveHandle() = default; + /* implicit */ OutMoveHandle(AutoOut<Type>& t) : raw(&t.raw) {} + /* implicit */ OutMoveHandle(Type* t) : raw(t) {} Type* Get() const { return raw; } - Type& operator*() { + Type& operator*() const { return *raw; } + Type* operator->() const { + return raw; + } + private: Type* raw; }; enum BufferAttr : int { - BufferAttr_In = (1U << 0), - BufferAttr_Out = (1U << 1), - BufferAttr_HipcMapAlias = (1U << 2), - BufferAttr_HipcPointer = (1U << 3), - BufferAttr_FixedSize = (1U << 4), - BufferAttr_HipcAutoSelect = (1U << 5), - BufferAttr_HipcMapTransferAllowsNonSecure = (1U << 6), - BufferAttr_HipcMapTransferAllowsNonDevice = (1U << 7), + /* 0x01 */ BufferAttr_In = (1U << 0), + /* 0x02 */ BufferAttr_Out = (1U << 1), + /* 0x04 */ BufferAttr_HipcMapAlias = (1U << 2), + /* 0x08 */ BufferAttr_HipcPointer = (1U << 3), + /* 0x10 */ BufferAttr_FixedSize = (1U << 4), + /* 0x20 */ BufferAttr_HipcAutoSelect = (1U << 5), + /* 0x40 */ BufferAttr_HipcMapTransferAllowsNonSecure = (1U << 6), + /* 0x80 */ BufferAttr_HipcMapTransferAllowsNonDevice = (1U << 7), }; template <typename T, int A> @@ -172,123 +192,80 @@ struct Buffer : public std::span<T> { } }; -template <BufferAttr A> +template <int A> using InBuffer = Buffer<const u8, BufferAttr_In | A>; -template <typename T, BufferAttr A> +template <typename T, int A> using InArray = Buffer<T, BufferAttr_In | A>; -template <BufferAttr A> +template <int A> using OutBuffer = Buffer<u8, BufferAttr_Out | A>; -template <typename T, BufferAttr A> +template <typename T, int A> using OutArray = Buffer<T, BufferAttr_Out | A>; template <typename T, int A> -struct LargeData : public T { +class InLargeData { +public: static_assert(std::is_trivially_copyable_v<T>, "LargeData type must be trivially copyable"); - static_assert((A & BufferAttr_FixedSize) != 0, "LargeData attr must contain FixedSize"); - static_assert(((A & BufferAttr_In) == 0) ^ ((A & BufferAttr_Out) == 0), "LargeData attr must be In or Out"); - static constexpr BufferAttr Attr = static_cast<BufferAttr>(A); - using Type = T; - - /* implicit */ LargeData(const T& rhs) : T(rhs) {} - /* implicit */ LargeData() = default; -}; - -template <typename T, BufferAttr A> -using InLargeData = LargeData<T, BufferAttr_FixedSize | BufferAttr_In | A>; - -template <typename T, BufferAttr A> -using OutLargeData = LargeData<T, BufferAttr_FixedSize | BufferAttr_Out | A>; + static_assert((A & BufferAttr_Out) == 0, "InLargeData attr must not be Out"); + static constexpr BufferAttr Attr = static_cast<BufferAttr>(A | BufferAttr_In | BufferAttr_FixedSize); + using Type = const T; -template <typename T> -struct RemoveOut { - using Type = std::remove_reference_t<T>; -}; - -template <typename T> -struct RemoveOut<Out<T>> { - using Type = typename Out<T>::Type; -}; + /* implicit */ InLargeData(Type& t) : raw(&t) {} + ~InLargeData() = default; -template <typename T> -struct RemoveOut<OutCopyHandle<T>> { - using Type = typename OutCopyHandle<T>::Type; -}; - -template <typename T> -struct RemoveOut<OutMoveHandle<T>> { - using Type = typename OutMoveHandle<T>::Type; -}; - -enum class ArgumentType { - InProcessId, - InData, - InInterface, - InCopyHandle, - OutData, - OutInterface, - OutCopyHandle, - OutMoveHandle, - InBuffer, - InLargeData, - OutBuffer, - OutLargeData, -}; + InLargeData& operator=(Type* rhs) { + raw = rhs; + return *this; + } -template <typename T> -struct ArgumentTraits; + Type* Get() const { + return raw; + } -template <> -struct ArgumentTraits<ClientProcessId> { - static constexpr ArgumentType Type = ArgumentType::InProcessId; -}; + Type& operator*() const { + return *raw; + } -template <typename T> -struct ArgumentTraits<SharedPointer<T>> { - static constexpr ArgumentType Type = ArgumentType::InInterface; -}; + Type* operator->() const { + return raw; + } -template <typename T> -struct ArgumentTraits<InCopyHandle<T>> { - static constexpr ArgumentType Type = ArgumentType::InCopyHandle; -}; + explicit operator bool() const { + return raw != nullptr; + } -template <typename T> -struct ArgumentTraits<Out<SharedPointer<T>>> { - static constexpr ArgumentType Type = ArgumentType::OutInterface; +private: + Type* raw; }; -template <typename T> -struct ArgumentTraits<Out<T>> { - static constexpr ArgumentType Type = ArgumentType::OutData; -}; +template <typename T, int A> +class OutLargeData { +public: + static_assert(std::is_trivially_copyable_v<T>, "LargeData type must be trivially copyable"); + static_assert((A & BufferAttr_In) == 0, "OutLargeData attr must not be In"); + static constexpr BufferAttr Attr = static_cast<BufferAttr>(A | BufferAttr_In | BufferAttr_FixedSize); + using Type = T; -template <typename T> -struct ArgumentTraits<OutCopyHandle<T>> { - static constexpr ArgumentType Type = ArgumentType::OutCopyHandle; -}; + /* implicit */ OutLargeData(Type* t) : raw(t) {} + /* implicit */ OutLargeData(AutoOut<T>& t) : raw(&t.raw) {} -template <typename T> -struct ArgumentTraits<OutMoveHandle<T>> { - static constexpr ArgumentType Type = ArgumentType::OutMoveHandle; -}; + Type* Get() const { + return raw; + } -template <typename T, int A> -struct ArgumentTraits<Buffer<T, A>> { - static constexpr ArgumentType Type = (A & BufferAttr_In) == 0 ? ArgumentType::OutBuffer : ArgumentType::InBuffer; -}; + Type& operator*() const { + return *raw; + } -template <typename T, int A> -struct ArgumentTraits<LargeData<T, A>> { - static constexpr ArgumentType Type = (A & BufferAttr_In) == 0 ? ArgumentType::OutLargeData : ArgumentType::InLargeData; -}; + Type* operator->() const { + return raw; + } -template <typename T> -struct ArgumentTraits { - static constexpr ArgumentType Type = ArgumentType::InData; +private: + Type* raw; }; // clang-format on -} // namespace Service +} // namespace Service
\ No newline at end of file diff --git a/src/core/hle/service/glue/time/alarm_worker.cpp b/src/core/hle/service/glue/time/alarm_worker.cpp index f549ed00a..3ff071f4a 100644 --- a/src/core/hle/service/glue/time/alarm_worker.cpp +++ b/src/core/hle/service/glue/time/alarm_worker.cpp @@ -41,7 +41,7 @@ bool AlarmWorker::GetClosestAlarmInfo(Service::PSC::Time::AlarmInfo& out_alarm_i Service::PSC::Time::AlarmInfo alarm_info{}; s64 closest_time{}; - auto res = m_time_m->GetClosestAlarmInfo(is_valid, alarm_info, closest_time); + auto res = m_time_m->GetClosestAlarmInfo(&is_valid, &alarm_info, &closest_time); ASSERT(res == ResultSuccess); if (is_valid) { @@ -76,6 +76,7 @@ void AlarmWorker::OnPowerStateChanged() { Result AlarmWorker::AttachToClosestAlarmEvent() { m_time_m->GetClosestAlarmUpdatedEvent(&m_event); + R_SUCCEED(); } diff --git a/src/core/hle/service/glue/time/alarm_worker.h b/src/core/hle/service/glue/time/alarm_worker.h index f269cffdb..131d012a6 100644 --- a/src/core/hle/service/glue/time/alarm_worker.h +++ b/src/core/hle/service/glue/time/alarm_worker.h @@ -26,7 +26,7 @@ public: void Initialize(std::shared_ptr<Service::PSC::Time::ServiceManager> time_m); - Kernel::KEvent& GetEvent() { + Kernel::KReadableEvent& GetEvent() { return *m_event; } @@ -44,7 +44,7 @@ private: KernelHelpers::ServiceContext m_ctx; std::shared_ptr<Service::PSC::Time::ServiceManager> m_time_m; - Kernel::KEvent* m_event{}; + Kernel::KReadableEvent* m_event{}; Kernel::KEvent* m_timer_event{}; std::shared_ptr<Core::Timing::EventType> m_timer_timing_event; StandardSteadyClockResource& m_steady_clock_resource; diff --git a/src/core/hle/service/glue/time/file_timestamp_worker.cpp b/src/core/hle/service/glue/time/file_timestamp_worker.cpp index 5a6309549..048ff174c 100644 --- a/src/core/hle/service/glue/time/file_timestamp_worker.cpp +++ b/src/core/hle/service/glue/time/file_timestamp_worker.cpp @@ -13,8 +13,8 @@ void FileTimestampWorker::SetFilesystemPosixTime() { Service::PSC::Time::CalendarTime calendar_time{}; Service::PSC::Time::CalendarAdditionalInfo additional_info{}; - if (m_initialized && m_system_clock->GetCurrentTime(time) == ResultSuccess && - m_time_zone->ToCalendarTimeWithMyRule(calendar_time, additional_info, time) == + if (m_initialized && m_system_clock->GetCurrentTime(&time) == ResultSuccess && + m_time_zone->ToCalendarTimeWithMyRule(&calendar_time, &additional_info, time) == ResultSuccess) { // TODO IFileSystemProxy::SetCurrentPosixTime } diff --git a/src/core/hle/service/glue/time/manager.cpp b/src/core/hle/service/glue/time/manager.cpp index b56762941..0c27e8029 100644 --- a/src/core/hle/service/glue/time/manager.cpp +++ b/src/core/hle/service/glue/time/manager.cpp @@ -79,18 +79,18 @@ Service::PSC::Time::LocationName GetTimeZoneString(Service::PSC::Time::LocationN auto configured_zone = Settings::GetTimeZoneString(Settings::values.time_zone_index.GetValue()); Service::PSC::Time::LocationName configured_name{}; - std::memcpy(configured_name.name.data(), configured_zone.data(), - std::min(configured_name.name.size(), configured_zone.size())); + std::memcpy(configured_name.data(), configured_zone.data(), + std::min(configured_name.size(), configured_zone.size())); if (!IsTimeZoneBinaryValid(configured_name)) { configured_zone = Common::TimeZone::FindSystemTimeZone(); configured_name = {}; - std::memcpy(configured_name.name.data(), configured_zone.data(), - std::min(configured_name.name.size(), configured_zone.size())); + std::memcpy(configured_name.data(), configured_zone.data(), + std::min(configured_name.size(), configured_zone.size())); } ASSERT_MSG(IsTimeZoneBinaryValid(configured_name), "Invalid time zone {}!", - configured_name.name.data()); + configured_name.data()); return configured_name; } @@ -103,7 +103,7 @@ TimeManager::TimeManager(Core::System& system) m_time_m = system.ServiceManager().GetService<Service::PSC::Time::ServiceManager>("time:m", true); - auto res = m_time_m->GetStaticServiceAsServiceManager(m_time_sm); + auto res = m_time_m->GetStaticServiceAsServiceManager(&m_time_sm); ASSERT(res == ResultSuccess); m_set_sys = @@ -114,10 +114,10 @@ TimeManager::TimeManager(Core::System& system) m_worker.Initialize(m_time_sm, m_set_sys); - res = m_time_sm->GetStandardUserSystemClock(m_file_timestamp_worker.m_system_clock); + res = m_time_sm->GetStandardUserSystemClock(&m_file_timestamp_worker.m_system_clock); ASSERT(res == ResultSuccess); - res = m_time_sm->GetTimeZoneService(m_file_timestamp_worker.m_time_zone); + res = m_time_sm->GetTimeZoneService(&m_file_timestamp_worker.m_time_zone); ASSERT(res == ResultSuccess); res = SetupStandardSteadyClockCore(); @@ -161,8 +161,8 @@ TimeManager::TimeManager(Core::System& system) automatic_correction_time_point); ASSERT(res == ResultSuccess); - res = m_time_m->SetupStandardUserSystemClockCore(automatic_correction_time_point, - is_automatic_correction_enabled); + res = m_time_m->SetupStandardUserSystemClockCore(is_automatic_correction_enabled, + automatic_correction_time_point); ASSERT(res == ResultSuccess); res = m_time_m->SetupEphemeralNetworkSystemClockCore(); @@ -184,12 +184,12 @@ TimeManager::TimeManager(Core::System& system) m_file_timestamp_worker.m_initialized = true; s64 system_clock_time{}; - if (m_file_timestamp_worker.m_system_clock->GetCurrentTime(system_clock_time) == + if (m_file_timestamp_worker.m_system_clock->GetCurrentTime(&system_clock_time) == ResultSuccess) { Service::PSC::Time::CalendarTime calendar_time{}; Service::PSC::Time::CalendarAdditionalInfo calendar_additional{}; if (m_file_timestamp_worker.m_time_zone->ToCalendarTimeWithMyRule( - calendar_time, calendar_additional, system_clock_time) == ResultSuccess) { + &calendar_time, &calendar_additional, system_clock_time) == ResultSuccess) { // TODO IFileSystemProxy::SetCurrentPosixTime(system_clock_time, // calendar_additional.ut_offset) } @@ -228,10 +228,9 @@ Result TimeManager::SetupStandardSteadyClockCore() { m_set_sys->SetExternalSteadyClockSourceId(clock_source_id); } - res = m_time_m->SetupStandardSteadyClockCore(clock_source_id, m_steady_clock_resource.GetTime(), - external_steady_clock_internal_offset_ns, - standard_steady_clock_test_offset_ns, - reset_detected); + res = m_time_m->SetupStandardSteadyClockCore( + reset_detected, clock_source_id, m_steady_clock_resource.GetTime(), + external_steady_clock_internal_offset_ns, standard_steady_clock_test_offset_ns); ASSERT(res == ResultSuccess); R_SUCCEED(); } @@ -243,14 +242,15 @@ Result TimeManager::SetupTimeZoneServiceCore() { auto configured_zone = GetTimeZoneString(name); - if (configured_zone.name != name.name) { + if (configured_zone != name) { m_set_sys->SetDeviceTimeZoneLocationName(configured_zone); name = configured_zone; std::shared_ptr<Service::PSC::Time::SystemClock> local_clock; - m_time_sm->GetStandardLocalSystemClock(local_clock); + m_time_sm->GetStandardLocalSystemClock(&local_clock); + Service::PSC::Time::SystemClockContext context{}; - local_clock->GetSystemClockContext(context); + local_clock->GetSystemClockContext(&context); m_set_sys->SetDeviceTimeZoneLocationUpdatedTime(context.steady_time_point); } @@ -267,7 +267,7 @@ Result TimeManager::SetupTimeZoneServiceCore() { res = GetTimeZoneRule(rule_buffer, rule_size, name); ASSERT(res == ResultSuccess); - res = m_time_m->SetupTimeZoneServiceCore(name, time_point, rule_version, location_count, + res = m_time_m->SetupTimeZoneServiceCore(name, rule_version, location_count, time_point, rule_buffer); ASSERT(res == ResultSuccess); diff --git a/src/core/hle/service/glue/time/static.cpp b/src/core/hle/service/glue/time/static.cpp index 63b7d91da..f56db76e1 100644 --- a/src/core/hle/service/glue/time/static.cpp +++ b/src/core/hle/service/glue/time/static.cpp @@ -3,9 +3,11 @@ #include <chrono> +#include "common/scope_exit.h" #include "core/core.h" #include "core/hle/kernel/k_shared_memory.h" #include "core/hle/kernel/svc.h" +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/glue/time/file_timestamp_worker.h" #include "core/hle/service/glue/time/static.h" #include "core/hle/service/psc/time/errors.h" @@ -41,25 +43,25 @@ StaticService::StaticService(Core::System& system_, time->m_steady_clock_resource} { // 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 @@ -71,314 +73,80 @@ StaticService::StaticService(Core::System& system_, if (m_setup_info.can_write_local_clock && m_setup_info.can_write_user_clock && !m_setup_info.can_write_network_clock && m_setup_info.can_write_timezone_device_location && !m_setup_info.can_write_steady_clock && !m_setup_info.can_write_uninitialized_clock) { - m_time_m->GetStaticServiceAsAdmin(m_wrapped_service); + m_time_m->GetStaticServiceAsAdmin(&m_wrapped_service); } else if (!m_setup_info.can_write_local_clock && !m_setup_info.can_write_user_clock && !m_setup_info.can_write_network_clock && !m_setup_info.can_write_timezone_device_location && !m_setup_info.can_write_steady_clock && !m_setup_info.can_write_uninitialized_clock) { - m_time_m->GetStaticServiceAsUser(m_wrapped_service); + m_time_m->GetStaticServiceAsUser(&m_wrapped_service); } else if (!m_setup_info.can_write_local_clock && !m_setup_info.can_write_user_clock && !m_setup_info.can_write_network_clock && !m_setup_info.can_write_timezone_device_location && m_setup_info.can_write_steady_clock && !m_setup_info.can_write_uninitialized_clock) { - m_time_m->GetStaticServiceAsRepair(m_wrapped_service); + m_time_m->GetStaticServiceAsRepair(&m_wrapped_service); } else { UNREACHABLE(); } - auto res = m_wrapped_service->GetTimeZoneService(m_time_zone); + auto res = m_wrapped_service->GetTimeZoneService(&m_time_zone); ASSERT(res == ResultSuccess); } -void StaticService::Handle_GetStandardUserSystemClock(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr<Service::PSC::Time::SystemClock> service{}; - auto res = GetStandardUserSystemClock(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface<Service::PSC::Time::SystemClock>(std::move(service)); -} - -void StaticService::Handle_GetStandardNetworkSystemClock(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr<Service::PSC::Time::SystemClock> service{}; - auto res = GetStandardNetworkSystemClock(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface<Service::PSC::Time::SystemClock>(std::move(service)); -} - -void StaticService::Handle_GetStandardSteadyClock(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr<Service::PSC::Time::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<Service::PSC::Time::SystemClock> service{}; - auto res = GetStandardLocalSystemClock(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface<Service::PSC::Time::SystemClock>(std::move(service)); -} - -void StaticService::Handle_GetEphemeralNetworkSystemClock(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr<Service::PSC::Time::SystemClock> service{}; - auto res = GetEphemeralNetworkSystemClock(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface<Service::PSC::Time::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::RequestParser rp{ctx}; - auto offset_ns{rp.Pop<s64>()}; - - auto res = SetStandardSteadyClockInternalOffset(offset_ns); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void StaticService::Handle_GetStandardSteadyClockRtcValue(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - s64 rtc_value{}; - auto res = GetStandardSteadyClockRtcValue(rtc_value); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(res); - rb.Push(rtc_value); -} - -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."); - - s32 initial_year{}; - auto res = GetStandardUserSystemClockInitialYear(initial_year); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.Push(initial_year); -} - -void StaticService::Handle_IsStandardNetworkSystemClockAccuracySufficient(HLERequestContext& ctx) { +Result StaticService::GetStandardUserSystemClock( + OutInterface<Service::PSC::Time::SystemClock> out_service) { 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); + R_RETURN(m_wrapped_service->GetStandardUserSystemClock(out_service)); } -void StaticService::Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedTime( - HLERequestContext& ctx) { +Result StaticService::GetStandardNetworkSystemClock( + OutInterface<Service::PSC::Time::SystemClock> out_service) { LOG_DEBUG(Service_Time, "called."); - Service::PSC::Time::SteadyClockTimePoint time_point{}; - auto res = GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(time_point); - - IPC::ResponseBuilder rb{ctx, - 2 + sizeof(Service::PSC::Time::SteadyClockTimePoint) / sizeof(u32)}; - rb.Push(res); - rb.PushRaw<Service::PSC::Time::SteadyClockTimePoint>(time_point); + R_RETURN(m_wrapped_service->GetStandardNetworkSystemClock(out_service)); } -void StaticService::Handle_CalculateMonotonicSystemClockBaseTimePoint(HLERequestContext& ctx) { +Result StaticService::GetStandardSteadyClock( + OutInterface<Service::PSC::Time::SteadyClock> out_service) { LOG_DEBUG(Service_Time, "called."); - IPC::RequestParser rp{ctx}; - auto context{rp.PopRaw<Service::PSC::Time::SystemClockContext>()}; - - s64 time{}; - auto res = CalculateMonotonicSystemClockBaseTimePoint(time, context); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(res); - rb.Push<s64>(time); + R_RETURN(m_wrapped_service->GetStandardSteadyClock(out_service)); } -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<Service::PSC::Time::TimeType>()}; - - Service::PSC::Time::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_file_timestamp_worker, m_setup_info.can_write_timezone_device_location, + m_time_zone); + R_SUCCEED(); } -void StaticService::Handle_GetClockSnapshotFromSystemClockContext(HLERequestContext& ctx) { +Result StaticService::GetStandardLocalSystemClock( + OutInterface<Service::PSC::Time::SystemClock> out_service) { LOG_DEBUG(Service_Time, "called."); - IPC::RequestParser rp{ctx}; - auto clock_type{rp.PopEnum<Service::PSC::Time::TimeType>()}; - [[maybe_unused]] auto alignment{rp.Pop<u32>()}; - auto user_context{rp.PopRaw<Service::PSC::Time::SystemClockContext>()}; - auto network_context{rp.PopRaw<Service::PSC::Time::SystemClockContext>()}; - - Service::PSC::Time::ClockSnapshot snapshot{}; - auto res = - GetClockSnapshotFromSystemClockContext(snapshot, user_context, network_context, clock_type); - - ctx.WriteBuffer(snapshot); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); + R_RETURN(m_wrapped_service->GetStandardLocalSystemClock(out_service)); } -void StaticService::Handle_CalculateStandardUserSystemClockDifferenceByUser( - HLERequestContext& ctx) { +Result StaticService::GetEphemeralNetworkSystemClock( + OutInterface<Service::PSC::Time::SystemClock> out_service) { LOG_DEBUG(Service_Time, "called."); - Service::PSC::Time::ClockSnapshot a{}; - Service::PSC::Time::ClockSnapshot b{}; - - auto a_buffer{ctx.ReadBuffer(0)}; - auto b_buffer{ctx.ReadBuffer(1)}; - - std::memcpy(&a, a_buffer.data(), sizeof(Service::PSC::Time::ClockSnapshot)); - std::memcpy(&b, b_buffer.data(), sizeof(Service::PSC::Time::ClockSnapshot)); - - s64 difference{}; - auto res = CalculateStandardUserSystemClockDifferenceByUser(difference, a, b); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(res); - rb.Push(difference); + R_RETURN(m_wrapped_service->GetEphemeralNetworkSystemClock(out_service)); } -void StaticService::Handle_CalculateSpanBetween(HLERequestContext& ctx) { +Result StaticService::GetSharedMemoryNativeHandle( + OutCopyHandle<Kernel::KSharedMemory> out_shared_memory) { LOG_DEBUG(Service_Time, "called."); - Service::PSC::Time::ClockSnapshot a{}; - Service::PSC::Time::ClockSnapshot b{}; - - auto a_buffer{ctx.ReadBuffer(0)}; - auto b_buffer{ctx.ReadBuffer(1)}; - - std::memcpy(&a, a_buffer.data(), sizeof(Service::PSC::Time::ClockSnapshot)); - std::memcpy(&b, b_buffer.data(), sizeof(Service::PSC::Time::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<Service::PSC::Time::SystemClock>& out_service) { - R_RETURN(m_wrapped_service->GetStandardUserSystemClock(out_service)); -} - -Result StaticService::GetStandardNetworkSystemClock( - std::shared_ptr<Service::PSC::Time::SystemClock>& out_service) { - R_RETURN(m_wrapped_service->GetStandardNetworkSystemClock(out_service)); -} - -Result StaticService::GetStandardSteadyClock( - std::shared_ptr<Service::PSC::Time::SteadyClock>& out_service) { - R_RETURN(m_wrapped_service->GetStandardSteadyClock(out_service)); -} - -Result StaticService::GetTimeZoneService(std::shared_ptr<TimeZoneService>& out_service) { - out_service = std::make_shared<TimeZoneService>(m_system, m_file_timestamp_worker, - m_setup_info.can_write_timezone_device_location, - m_time_zone); - R_SUCCEED(); -} - -Result StaticService::GetStandardLocalSystemClock( - std::shared_ptr<Service::PSC::Time::SystemClock>& out_service) { - R_RETURN(m_wrapped_service->GetStandardLocalSystemClock(out_service)); -} - -Result StaticService::GetEphemeralNetworkSystemClock( - std::shared_ptr<Service::PSC::Time::SystemClock>& out_service) { - R_RETURN(m_wrapped_service->GetEphemeralNetworkSystemClock(out_service)); -} - -Result StaticService::GetSharedMemoryNativeHandle(Kernel::KSharedMemory** out_shared_memory) { R_RETURN(m_wrapped_service->GetSharedMemoryNativeHandle(out_shared_memory)); } Result StaticService::SetStandardSteadyClockInternalOffset(s64 offset_ns) { + LOG_DEBUG(Service_Time, "called. offset_ns={}", offset_ns); + R_UNLESS(m_setup_info.can_write_steady_clock, Service::PSC::Time::ResultPermissionDenied); R_RETURN(m_set_sys->SetExternalSteadyClockInternalOffset( @@ -386,62 +154,92 @@ Result StaticService::SetStandardSteadyClockInternalOffset(s64 offset_ns) { std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::seconds(1)).count())); } -Result StaticService::GetStandardSteadyClockRtcValue(s64& out_rtc_value) { - R_RETURN(m_standard_steady_clock_resource.GetRtcTimeInSeconds(out_rtc_value)); +Result StaticService::GetStandardSteadyClockRtcValue(Out<s64> out_rtc_value) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_rtc_value={}", *out_rtc_value); }); + + R_RETURN(m_standard_steady_clock_resource.GetRtcTimeInSeconds(*out_rtc_value)); } Result StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled( - bool& out_automatic_correction) { + Out<bool> out_automatic_correction) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, "called. out_automatic_correction={}", *out_automatic_correction); + }); + R_RETURN(m_wrapped_service->IsStandardUserSystemClockAutomaticCorrectionEnabled( out_automatic_correction)); } Result StaticService::SetStandardUserSystemClockAutomaticCorrectionEnabled( bool automatic_correction) { + LOG_DEBUG(Service_Time, "called. automatic_correction={}", automatic_correction); + R_RETURN(m_wrapped_service->SetStandardUserSystemClockAutomaticCorrectionEnabled( automatic_correction)); } -Result StaticService::GetStandardUserSystemClockInitialYear(s32& out_year) { - out_year = GetSettingsItemValue<s32>(m_set_sys, "time", "standard_user_clock_initial_year"); +Result StaticService::GetStandardUserSystemClockInitialYear(Out<s32> out_year) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_year={}", *out_year); }); + + *out_year = GetSettingsItemValue<s32>(m_set_sys, "time", "standard_user_clock_initial_year"); R_SUCCEED(); } -Result StaticService::IsStandardNetworkSystemClockAccuracySufficient(bool& out_is_sufficient) { +Result StaticService::IsStandardNetworkSystemClockAccuracySufficient(Out<bool> out_is_sufficient) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_is_sufficient={}", *out_is_sufficient); }); + R_RETURN(m_wrapped_service->IsStandardNetworkSystemClockAccuracySufficient(out_is_sufficient)); } Result StaticService::GetStandardUserSystemClockAutomaticCorrectionUpdatedTime( - Service::PSC::Time::SteadyClockTimePoint& out_time_point) { + Out<Service::PSC::Time::SteadyClockTimePoint> out_time_point) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_time_point={}", *out_time_point); }); + R_RETURN(m_wrapped_service->GetStandardUserSystemClockAutomaticCorrectionUpdatedTime( out_time_point)); } Result StaticService::CalculateMonotonicSystemClockBaseTimePoint( - s64& out_time, Service::PSC::Time::SystemClockContext& context) { + Out<s64> out_time, Service::PSC::Time::SystemClockContext& context) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. context={} out_time={}", context, *out_time); }); + R_RETURN(m_wrapped_service->CalculateMonotonicSystemClockBaseTimePoint(out_time, context)); } -Result StaticService::GetClockSnapshot(Service::PSC::Time::ClockSnapshot& out_snapshot, +Result StaticService::GetClockSnapshot(OutClockSnapshot out_snapshot, Service::PSC::Time::TimeType type) { + SCOPE_EXIT( + { LOG_DEBUG(Service_Time, "called. type={} out_snapshot={}", type, *out_snapshot); }); + R_RETURN(m_wrapped_service->GetClockSnapshot(out_snapshot, type)); } Result StaticService::GetClockSnapshotFromSystemClockContext( - Service::PSC::Time::ClockSnapshot& out_snapshot, + Service::PSC::Time::TimeType type, OutClockSnapshot out_snapshot, Service::PSC::Time::SystemClockContext& user_context, - Service::PSC::Time::SystemClockContext& network_context, Service::PSC::Time::TimeType type) { - R_RETURN(m_wrapped_service->GetClockSnapshotFromSystemClockContext(out_snapshot, user_context, - network_context, type)); + Service::PSC::Time::SystemClockContext& network_context) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, + "called. type={} out_snapshot={} user_context={} network_context={}", type, + *out_snapshot, user_context, network_context); + }); + + R_RETURN(m_wrapped_service->GetClockSnapshotFromSystemClockContext( + type, out_snapshot, user_context, network_context)); } -Result StaticService::CalculateStandardUserSystemClockDifferenceByUser( - s64& out_time, Service::PSC::Time::ClockSnapshot& a, Service::PSC::Time::ClockSnapshot& b) { +Result StaticService::CalculateStandardUserSystemClockDifferenceByUser(Out<s64> out_time, + InClockSnapshot a, + InClockSnapshot b) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. a={} b={} out_time={}", *a, *b, *out_time); }); + R_RETURN(m_wrapped_service->CalculateStandardUserSystemClockDifferenceByUser(out_time, a, b)); } -Result StaticService::CalculateSpanBetween(s64& out_time, Service::PSC::Time::ClockSnapshot& a, - Service::PSC::Time::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); }); + R_RETURN(m_wrapped_service->CalculateSpanBetween(out_time, a, b)); } diff --git a/src/core/hle/service/glue/time/static.h b/src/core/hle/service/glue/time/static.h index 75fe4e2cd..d3cc0fdd6 100644 --- a/src/core/hle/service/glue/time/static.h +++ b/src/core/hle/service/glue/time/static.h @@ -4,6 +4,7 @@ #pragma once #include "common/common_types.h" +#include "core/hle/service/cmif_types.h" #include "core/hle/service/glue/time/manager.h" #include "core/hle/service/glue/time/time_zone.h" #include "core/hle/service/psc/time/common.h" @@ -29,6 +30,10 @@ class FileTimestampWorker; class StandardSteadyClockResource; class StaticService final : public ServiceFramework<StaticService> { + using InClockSnapshot = InLargeData<Service::PSC::Time::ClockSnapshot, BufferAttr_HipcPointer>; + using OutClockSnapshot = + OutLargeData<Service::PSC::Time::ClockSnapshot, BufferAttr_HipcPointer>; + public: explicit StaticService(Core::System& system, Service::PSC::Time::StaticServiceSetupInfo setup_info, @@ -36,65 +41,34 @@ public: ~StaticService() override = default; - Result GetStandardUserSystemClock( - std::shared_ptr<Service::PSC::Time::SystemClock>& out_service); - Result GetStandardNetworkSystemClock( - std::shared_ptr<Service::PSC::Time::SystemClock>& out_service); - Result GetStandardSteadyClock(std::shared_ptr<Service::PSC::Time::SteadyClock>& out_service); - Result GetTimeZoneService(std::shared_ptr<TimeZoneService>& out_service); - Result GetStandardLocalSystemClock( - std::shared_ptr<Service::PSC::Time::SystemClock>& out_service); + Result GetStandardUserSystemClock(OutInterface<Service::PSC::Time::SystemClock> out_service); + Result GetStandardNetworkSystemClock(OutInterface<Service::PSC::Time::SystemClock> out_service); + Result GetStandardSteadyClock(OutInterface<Service::PSC::Time::SteadyClock> out_service); + Result GetTimeZoneService(OutInterface<TimeZoneService> out_service); + Result GetStandardLocalSystemClock(OutInterface<Service::PSC::Time::SystemClock> out_service); Result GetEphemeralNetworkSystemClock( - std::shared_ptr<Service::PSC::Time::SystemClock>& out_service); - Result GetSharedMemoryNativeHandle(Kernel::KSharedMemory** out_shared_memory); - Result SetStandardSteadyClockInternalOffset(s64 offset); - Result GetStandardSteadyClockRtcValue(s64& out_rtc_value); - Result IsStandardUserSystemClockAutomaticCorrectionEnabled(bool& out_automatic_correction); + OutInterface<Service::PSC::Time::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 GetStandardUserSystemClockInitialYear(s32& out_year); - Result IsStandardNetworkSystemClockAccuracySufficient(bool& out_is_sufficient); + Result GetStandardUserSystemClockInitialYear(Out<s32> out_year); + Result IsStandardNetworkSystemClockAccuracySufficient(Out<bool> out_is_sufficient); Result GetStandardUserSystemClockAutomaticCorrectionUpdatedTime( - Service::PSC::Time::SteadyClockTimePoint& out_time_point); + Out<Service::PSC::Time::SteadyClockTimePoint> out_time_point); Result CalculateMonotonicSystemClockBaseTimePoint( - s64& out_time, Service::PSC::Time::SystemClockContext& context); - Result GetClockSnapshot(Service::PSC::Time::ClockSnapshot& out_snapshot, - Service::PSC::Time::TimeType type); + Out<s64> out_time, Service::PSC::Time::SystemClockContext& context); + Result GetClockSnapshot(OutClockSnapshot out_snapshot, Service::PSC::Time::TimeType type); Result GetClockSnapshotFromSystemClockContext( - Service::PSC::Time::ClockSnapshot& out_snapshot, + Service::PSC::Time::TimeType type, OutClockSnapshot out_snapshot, Service::PSC::Time::SystemClockContext& user_context, - Service::PSC::Time::SystemClockContext& network_context, Service::PSC::Time::TimeType type); - Result CalculateStandardUserSystemClockDifferenceByUser(s64& out_time, - Service::PSC::Time::ClockSnapshot& a, - Service::PSC::Time::ClockSnapshot& b); - Result CalculateSpanBetween(s64& out_time, Service::PSC::Time::ClockSnapshot& a, - Service::PSC::Time::ClockSnapshot& b); + Service::PSC::Time::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(Service::PSC::Time::ClockSnapshot& out_snapshot, - Service::PSC::Time::SystemClockContext& user_context, - Service::PSC::Time::SystemClockContext& network_context, - Service::PSC::Time::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; std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys; diff --git a/src/core/hle/service/glue/time/time_zone.cpp b/src/core/hle/service/glue/time/time_zone.cpp index 503c327dd..5dc1187cb 100644 --- a/src/core/hle/service/glue/time/time_zone.cpp +++ b/src/core/hle/service/glue/time/time_zone.cpp @@ -3,8 +3,10 @@ #include <chrono> +#include "common/scope_exit.h" #include "core/core.h" #include "core/hle/kernel/svc.h" +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/glue/time/file_timestamp_worker.h" #include "core/hle/service/glue/time/time_zone.h" #include "core/hle/service/glue/time/time_zone_binary.h" @@ -28,20 +30,20 @@ TimeZoneService::TimeZoneService( m_wrapped_service{std::move(time_zone_service)}, m_operation_event{m_system} { // 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); @@ -53,220 +55,16 @@ TimeZoneService::TimeZoneService( TimeZoneService::~TimeZoneService() = default; -void TimeZoneService::Handle_GetDeviceLocationName(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Service::PSC::Time::LocationName name{}; - auto res = GetDeviceLocationName(name); - - IPC::ResponseBuilder rb{ctx, 2 + sizeof(Service::PSC::Time::LocationName) / sizeof(u32)}; - rb.Push(res); - rb.PushRaw<Service::PSC::Time::LocationName>(name); -} - -void TimeZoneService::Handle_SetDeviceLocationName(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto name{rp.PopRaw<Service::PSC::Time::LocationName>()}; - - auto res = SetDeviceLocation(name); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -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."); - - IPC::RequestParser rp{ctx}; - auto index{rp.Pop<u32>()}; - - auto max_names{ctx.GetWriteBufferSize() / sizeof(Service::PSC::Time::LocationName)}; - - std::vector<Service::PSC::Time::LocationName> names{}; - u32 count{}; - auto res = LoadLocationNameList(count, names, max_names, index); - - ctx.WriteBuffer(names); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.Push(count); -} - -void TimeZoneService::Handle_LoadTimeZoneRule(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto name{rp.PopRaw<Service::PSC::Time::LocationName>()}; - - Tz::Rule rule{}; - auto res = LoadTimeZoneRule(rule, name); - - ctx.WriteBuffer(rule); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void TimeZoneService::Handle_GetTimeZoneRuleVersion(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Service::PSC::Time::RuleVersion rule_version{}; - auto res = GetTimeZoneRuleVersion(rule_version); - - IPC::ResponseBuilder rb{ctx, 2 + sizeof(Service::PSC::Time::RuleVersion) / sizeof(u32)}; - rb.Push(res); - rb.PushRaw<Service::PSC::Time::RuleVersion>(rule_version); -} - -void TimeZoneService::Handle_GetDeviceLocationNameAndUpdatedTime(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Service::PSC::Time::LocationName name{}; - Service::PSC::Time::SteadyClockTimePoint time_point{}; - auto res = GetDeviceLocationNameAndUpdatedTime(time_point, name); - - IPC::ResponseBuilder rb{ctx, - 2 + (sizeof(Service::PSC::Time::LocationName) / sizeof(u32)) + - (sizeof(Service::PSC::Time::SteadyClockTimePoint) / sizeof(u32))}; - rb.Push(res); - rb.PushRaw<Service::PSC::Time::LocationName>(name); - rb.PushRaw<Service::PSC::Time::SteadyClockTimePoint>(time_point); -} - -void TimeZoneService::Handle_SetDeviceLocationNameWithTimeZoneRule(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - auto res = SetDeviceLocationNameWithTimeZoneRule(); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void TimeZoneService::Handle_ParseTimeZoneBinary(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(Service::PSC::Time::ResultNotImplemented); -} - -void TimeZoneService::Handle_GetDeviceLocationNameOperationEventReadableHandle( - HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Kernel::KEvent* event{}; - auto res = GetDeviceLocationNameOperationEventReadableHandle(&event); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(res); - rb.PushCopyObjects(event->GetReadableEvent()); -} - -void TimeZoneService::Handle_ToCalendarTime(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto time{rp.Pop<s64>()}; - - auto rule_buffer{ctx.ReadBuffer()}; - Tz::Rule rule{}; - std::memcpy(&rule, rule_buffer.data(), sizeof(Tz::Rule)); - - Service::PSC::Time::CalendarTime calendar_time{}; - Service::PSC::Time::CalendarAdditionalInfo additional_info{}; - auto res = ToCalendarTime(calendar_time, additional_info, time, rule); - - IPC::ResponseBuilder rb{ctx, - 2 + (sizeof(Service::PSC::Time::CalendarTime) / sizeof(u32)) + - (sizeof(Service::PSC::Time::CalendarAdditionalInfo) / sizeof(u32))}; - rb.Push(res); - rb.PushRaw<Service::PSC::Time::CalendarTime>(calendar_time); - rb.PushRaw<Service::PSC::Time::CalendarAdditionalInfo>(additional_info); -} - -void TimeZoneService::Handle_ToCalendarTimeWithMyRule(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - auto time{rp.Pop<s64>()}; - - LOG_DEBUG(Service_Time, "called. time={}", time); - - Service::PSC::Time::CalendarTime calendar_time{}; - Service::PSC::Time::CalendarAdditionalInfo additional_info{}; - auto res = ToCalendarTimeWithMyRule(calendar_time, additional_info, time); - - IPC::ResponseBuilder rb{ctx, - 2 + (sizeof(Service::PSC::Time::CalendarTime) / sizeof(u32)) + - (sizeof(Service::PSC::Time::CalendarAdditionalInfo) / sizeof(u32))}; - rb.Push(res); - rb.PushRaw<Service::PSC::Time::CalendarTime>(calendar_time); - rb.PushRaw<Service::PSC::Time::CalendarAdditionalInfo>(additional_info); -} - -void TimeZoneService::Handle_ToPosixTime(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - auto calendar{rp.PopRaw<Service::PSC::Time::CalendarTime>()}; - - LOG_DEBUG(Service_Time, "called. calendar year {} month {} day {} hour {} minute {} second {}", - calendar.year, calendar.month, calendar.day, calendar.hour, calendar.minute, - calendar.second); - - 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); -} - -void TimeZoneService::Handle_ToPosixTimeWithMyRule(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto calendar{rp.PopRaw<Service::PSC::Time::CalendarTime>()}; - - 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); -} +Result TimeZoneService::GetDeviceLocationName( + Out<Service::PSC::Time::LocationName> out_location_name) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_location_name={}", *out_location_name); }); -// =============================== Implementations =========================== - -Result TimeZoneService::GetDeviceLocationName(Service::PSC::Time::LocationName& out_location_name) { R_RETURN(m_wrapped_service->GetDeviceLocationName(out_location_name)); } -Result TimeZoneService::SetDeviceLocation(Service::PSC::Time::LocationName& location_name) { +Result TimeZoneService::SetDeviceLocationName(Service::PSC::Time::LocationName& location_name) { + LOG_DEBUG(Service_Time, "called. location_name={}", location_name); + R_UNLESS(m_can_write_timezone_device_location, Service::PSC::Time::ResultPermissionDenied); R_UNLESS(IsTimeZoneBinaryValid(location_name), Service::PSC::Time::ResultTimeZoneNotFound); @@ -282,7 +80,7 @@ Result TimeZoneService::SetDeviceLocation(Service::PSC::Time::LocationName& loca Service::PSC::Time::SteadyClockTimePoint time_point{}; Service::PSC::Time::LocationName name{}; - R_TRY(m_wrapped_service->GetDeviceLocationNameAndUpdatedTime(time_point, name)); + R_TRY(m_wrapped_service->GetDeviceLocationNameAndUpdatedTime(&name, &time_point)); m_set_sys->SetDeviceTimeZoneLocationName(name); m_set_sys->SetDeviceTimeZoneLocationUpdatedTime(time_point); @@ -294,19 +92,27 @@ Result TimeZoneService::SetDeviceLocation(Service::PSC::Time::LocationName& loca R_SUCCEED(); } -Result TimeZoneService::GetTotalLocationNameCount(u32& out_count) { +Result TimeZoneService::GetTotalLocationNameCount(Out<u32> out_count) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_count={}", *out_count); }); + R_RETURN(m_wrapped_service->GetTotalLocationNameCount(out_count)); } Result TimeZoneService::LoadLocationNameList( - u32& out_count, std::vector<Service::PSC::Time::LocationName>& out_names, size_t max_names, - u32 index) { + Out<u32> out_count, + OutArray<Service::PSC::Time::LocationName, BufferAttr_HipcMapAlias> out_names, u32 index) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, "called. index={} out_count={} out_names[0]={} out_names[1]={}", + index, *out_count, out_names[0], out_names[1]); + }); + std::scoped_lock l{m_mutex}; - R_RETURN(GetTimeZoneLocationList(out_count, out_names, max_names, index)); + R_RETURN(GetTimeZoneLocationList(*out_count, out_names, out_names.size(), index)); } -Result TimeZoneService::LoadTimeZoneRule(Tz::Rule& out_rule, - Service::PSC::Time::LocationName& name) { +Result TimeZoneService::LoadTimeZoneRule(OutRule out_rule, Service::PSC::Time::LocationName& name) { + LOG_DEBUG(Service_Time, "called. name={}", name); + std::scoped_lock l{m_mutex}; std::span<const u8> binary{}; size_t binary_size{}; @@ -314,23 +120,43 @@ Result TimeZoneService::LoadTimeZoneRule(Tz::Rule& out_rule, R_RETURN(m_wrapped_service->ParseTimeZoneBinary(out_rule, binary)); } -Result TimeZoneService::GetTimeZoneRuleVersion(Service::PSC::Time::RuleVersion& out_rule_version) { +Result TimeZoneService::GetTimeZoneRuleVersion( + Out<Service::PSC::Time::RuleVersion> out_rule_version) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_rule_version={}", *out_rule_version); }); + R_RETURN(m_wrapped_service->GetTimeZoneRuleVersion(out_rule_version)); } Result TimeZoneService::GetDeviceLocationNameAndUpdatedTime( - Service::PSC::Time::SteadyClockTimePoint& out_time_point, - Service::PSC::Time::LocationName& location_name) { - R_RETURN(m_wrapped_service->GetDeviceLocationNameAndUpdatedTime(out_time_point, location_name)); + Out<Service::PSC::Time::LocationName> location_name, + Out<Service::PSC::Time::SteadyClockTimePoint> out_time_point) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, "called. location_name={} out_time_point={}", *location_name, + *out_time_point); + }); + + R_RETURN(m_wrapped_service->GetDeviceLocationNameAndUpdatedTime(location_name, out_time_point)); } -Result TimeZoneService::SetDeviceLocationNameWithTimeZoneRule() { +Result TimeZoneService::SetDeviceLocationNameWithTimeZoneRule( + Service::PSC::Time::LocationName& location_name, InBuffer<BufferAttr_HipcAutoSelect> binary) { + LOG_DEBUG(Service_Time, "called. location_name={}", location_name); + R_UNLESS(m_can_write_timezone_device_location, Service::PSC::Time::ResultPermissionDenied); R_RETURN(Service::PSC::Time::ResultNotImplemented); } +Result TimeZoneService::ParseTimeZoneBinary(OutRule out_rule, + InBuffer<BufferAttr_HipcAutoSelect> binary) { + LOG_DEBUG(Service_Time, "called."); + + R_RETURN(Service::PSC::Time::ResultNotImplemented); +} + Result TimeZoneService::GetDeviceLocationNameOperationEventReadableHandle( - Kernel::KEvent** out_event) { + OutCopyHandle<Kernel::KReadableEvent> out_event) { + LOG_DEBUG(Service_Time, "called."); + if (!operation_event_initialized) { operation_event_initialized = false; @@ -342,34 +168,59 @@ Result TimeZoneService::GetDeviceLocationNameOperationEventReadableHandle( g_list_nodes.push_back(m_operation_event); } - *out_event = m_operation_event.m_event; + *out_event = &m_operation_event.m_event->GetReadableEvent(); R_SUCCEED(); } Result TimeZoneService::ToCalendarTime( - Service::PSC::Time::CalendarTime& out_calendar_time, - Service::PSC::Time::CalendarAdditionalInfo& out_additional_info, s64 time, Tz::Rule& rule) { + Out<Service::PSC::Time::CalendarTime> out_calendar_time, + Out<Service::PSC::Time::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); + }); + R_RETURN(m_wrapped_service->ToCalendarTime(out_calendar_time, out_additional_info, time, rule)); } Result TimeZoneService::ToCalendarTimeWithMyRule( - Service::PSC::Time::CalendarTime& out_calendar_time, - Service::PSC::Time::CalendarAdditionalInfo& out_additional_info, s64 time) { + Out<Service::PSC::Time::CalendarTime> out_calendar_time, + Out<Service::PSC::Time::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); + }); + R_RETURN( m_wrapped_service->ToCalendarTimeWithMyRule(out_calendar_time, out_additional_info, time)); } -Result TimeZoneService::ToPosixTime(u32& out_count, std::span<s64, 2> out_times, - u32 out_times_count, - Service::PSC::Time::CalendarTime& calendar_time, - Tz::Rule& rule) { +Result TimeZoneService::ToPosixTime(Out<u32> out_count, + OutArray<s64, BufferAttr_HipcPointer> out_times, + Out<u32> out_times_count, + Service::PSC::Time::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); + }); + R_RETURN( m_wrapped_service->ToPosixTime(out_count, out_times, out_times_count, calendar_time, rule)); } -Result TimeZoneService::ToPosixTimeWithMyRule(u32& out_count, std::span<s64, 2> out_times, - u32 out_times_count, +Result TimeZoneService::ToPosixTimeWithMyRule(Out<u32> out_count, + OutArray<s64, BufferAttr_HipcPointer> out_times, + Out<u32> out_times_count, Service::PSC::Time::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); + }); + R_RETURN(m_wrapped_service->ToPosixTimeWithMyRule(out_count, out_times, out_times_count, calendar_time)); } diff --git a/src/core/hle/service/glue/time/time_zone.h b/src/core/hle/service/glue/time/time_zone.h index 3c8ae4bf8..bf12adbdc 100644 --- a/src/core/hle/service/glue/time/time_zone.h +++ b/src/core/hle/service/glue/time/time_zone.h @@ -8,6 +8,7 @@ #include <span> #include <vector> +#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" @@ -33,6 +34,9 @@ namespace Service::Glue::Time { class FileTimestampWorker; 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, FileTimestampWorker& file_timestamp_worker, @@ -41,46 +45,37 @@ public: ~TimeZoneService() override; - Result GetDeviceLocationName(Service::PSC::Time::LocationName& out_location_name); - Result SetDeviceLocation(Service::PSC::Time::LocationName& location_name); - Result GetTotalLocationNameCount(u32& out_count); - Result LoadLocationNameList(u32& out_count, - std::vector<Service::PSC::Time::LocationName>& out_names, - size_t max_names, u32 index); - Result LoadTimeZoneRule(Tz::Rule& out_rule, Service::PSC::Time::LocationName& name); - Result GetTimeZoneRuleVersion(Service::PSC::Time::RuleVersion& out_rule_version); + Result GetDeviceLocationName(Out<Service::PSC::Time::LocationName> out_location_name); + Result SetDeviceLocationName(Service::PSC::Time::LocationName& location_name); + Result GetTotalLocationNameCount(Out<u32> out_count); + Result LoadLocationNameList( + Out<u32> out_count, + OutArray<Service::PSC::Time::LocationName, BufferAttr_HipcMapAlias> out_names, u32 index); + Result LoadTimeZoneRule(OutRule out_rule, Service::PSC::Time::LocationName& location_name); + Result GetTimeZoneRuleVersion(Out<Service::PSC::Time::RuleVersion> out_rule_version); Result GetDeviceLocationNameAndUpdatedTime( - Service::PSC::Time::SteadyClockTimePoint& out_time_point, - Service::PSC::Time::LocationName& location_name); - Result SetDeviceLocationNameWithTimeZoneRule(); - Result GetDeviceLocationNameOperationEventReadableHandle(Kernel::KEvent** out_event); - Result ToCalendarTime(Service::PSC::Time::CalendarTime& out_calendar_time, - Service::PSC::Time::CalendarAdditionalInfo& out_additional_info, s64 time, - Tz::Rule& rule); - Result ToCalendarTimeWithMyRule(Service::PSC::Time::CalendarTime& out_calendar_time, - Service::PSC::Time::CalendarAdditionalInfo& out_additional_info, - s64 time); - Result ToPosixTime(u32& out_count, std::span<s64, 2> out_times, u32 out_times_count, - Service::PSC::Time::CalendarTime& calendar_time, Tz::Rule& rule); - Result ToPosixTimeWithMyRule(u32& out_count, std::span<s64, 2> out_times, u32 out_times_count, + Out<Service::PSC::Time::LocationName> location_name, + Out<Service::PSC::Time::SteadyClockTimePoint> out_time_point); + Result SetDeviceLocationNameWithTimeZoneRule(Service::PSC::Time::LocationName& location_name, + InBuffer<BufferAttr_HipcAutoSelect> binary); + Result ParseTimeZoneBinary(OutRule out_rule, InBuffer<BufferAttr_HipcAutoSelect> binary); + Result GetDeviceLocationNameOperationEventReadableHandle( + OutCopyHandle<Kernel::KReadableEvent> out_event); + Result ToCalendarTime(Out<Service::PSC::Time::CalendarTime> out_calendar_time, + Out<Service::PSC::Time::CalendarAdditionalInfo> out_additional_info, + s64 time, InRule rule); + Result ToCalendarTimeWithMyRule( + Out<Service::PSC::Time::CalendarTime> out_calendar_time, + Out<Service::PSC::Time::CalendarAdditionalInfo> out_additional_info, s64 time); + Result ToPosixTime(Out<u32> out_count, OutArray<s64, BufferAttr_HipcPointer> out_times, + Out<u32> out_times_count, Service::PSC::Time::CalendarTime& calendar_time, + InRule rule); + Result ToPosixTimeWithMyRule(Out<u32> out_count, + OutArray<s64, BufferAttr_HipcPointer> out_times, + Out<u32> out_times_count, Service::PSC::Time::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; std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys; diff --git a/src/core/hle/service/glue/time/time_zone_binary.cpp b/src/core/hle/service/glue/time/time_zone_binary.cpp index d33f784c0..cc50b6b7b 100644 --- a/src/core/hle/service/glue/time/time_zone_binary.cpp +++ b/src/core/hle/service/glue/time/time_zone_binary.cpp @@ -103,7 +103,7 @@ void GetTimeZoneZonePath(std::string& out_path, Service::PSC::Time::LocationName return; } // out_path = fmt::format("{}:/zoneinfo/{}", "TimeZoneBinary", name); - out_path = fmt::format("/zoneinfo/{}", name.name.data()); + out_path = fmt::format("/zoneinfo/{}", name.data()); } bool IsTimeZoneBinaryValid(Service::PSC::Time::LocationName& name) { @@ -169,7 +169,7 @@ Result GetTimeZoneRule(std::span<const u8>& out_rule, size_t& out_rule_size, } Result GetTimeZoneLocationList(u32& out_count, - std::vector<Service::PSC::Time::LocationName>& out_names, + std::span<Service::PSC::Time::LocationName> out_names, size_t max_names, u32 index) { std::string path{}; GetTimeZoneBinaryListPath(path); @@ -193,7 +193,7 @@ Result GetTimeZoneLocationList(u32& out_count, if (chr == '\n') { if (name_count >= index) { - out_names.push_back(current_name); + out_names[out_count] = current_name; out_count++; if (out_count >= max_names) { break; @@ -209,10 +209,9 @@ Result GetTimeZoneLocationList(u32& out_count, break; } - R_UNLESS(current_name_len <= current_name.name.size() - 2, - Service::PSC::Time::ResultFailed); + R_UNLESS(current_name_len <= current_name.size() - 2, Service::PSC::Time::ResultFailed); - current_name.name[current_name_len++] = chr; + current_name[current_name_len++] = chr; } R_SUCCEED(); diff --git a/src/core/hle/service/glue/time/time_zone_binary.h b/src/core/hle/service/glue/time/time_zone_binary.h index 2cad6b458..461f4577e 100644 --- a/src/core/hle/service/glue/time/time_zone_binary.h +++ b/src/core/hle/service/glue/time/time_zone_binary.h @@ -26,7 +26,7 @@ Result GetTimeZoneVersion(Service::PSC::Time::RuleVersion& out_rule_version); Result GetTimeZoneRule(std::span<const u8>& out_rule, size_t& out_rule_size, Service::PSC::Time::LocationName& name); Result GetTimeZoneLocationList(u32& out_count, - std::vector<Service::PSC::Time::LocationName>& out_names, + std::span<Service::PSC::Time::LocationName> out_names, size_t max_names, u32 index); } // namespace Service::Glue::Time diff --git a/src/core/hle/service/glue/time/worker.cpp b/src/core/hle/service/glue/time/worker.cpp index ea0e49b90..f44f3077e 100644 --- a/src/core/hle/service/glue/time/worker.cpp +++ b/src/core/hle/service/glue/time/worker.cpp @@ -38,11 +38,12 @@ T GetSettingsItemValue(std::shared_ptr<Service::Set::ISystemSettingsServer>& set TimeWorker::TimeWorker(Core::System& system, StandardSteadyClockResource& steady_clock_resource, FileTimestampWorker& file_timestamp_worker) - : m_system{system}, m_ctx{m_system, "Glue:58"}, m_event{m_ctx.CreateEvent("Glue:58:Event")}, + : m_system{system}, m_ctx{m_system, "Glue:TimeWorker"}, m_event{m_ctx.CreateEvent( + "Glue:TimeWorker:Event")}, m_steady_clock_resource{steady_clock_resource}, m_file_timestamp_worker{file_timestamp_worker}, m_timer_steady_clock{m_ctx.CreateEvent( - "Glue:58:SteadyClockTimerEvent")}, - m_timer_file_system{m_ctx.CreateEvent("Glue:58:FileTimeTimerEvent")}, + "Glue:TimeWorker:SteadyClockTimerEvent")}, + m_timer_file_system{m_ctx.CreateEvent("Glue:TimeWorker:FileTimeTimerEvent")}, m_alarm_worker{m_system, m_steady_clock_resource}, m_pm_state_change_handler{m_alarm_worker} { g_ig_report_network_clock_context_set = false; g_report_network_clock_context = {}; @@ -113,17 +114,17 @@ void TimeWorker::Initialize(std::shared_ptr<Service::PSC::Time::StaticService> t std::chrono::nanoseconds(fs_notify_time_ns), m_timer_file_system_timing_event); - auto res = m_time_sm->GetStandardLocalSystemClock(m_local_clock); + auto res = m_time_sm->GetStandardLocalSystemClock(&m_local_clock); ASSERT(res == ResultSuccess); res = m_time_m->GetStandardLocalClockOperationEvent(&m_local_clock_event); ASSERT(res == ResultSuccess); - res = m_time_sm->GetStandardNetworkSystemClock(m_network_clock); + res = m_time_sm->GetStandardNetworkSystemClock(&m_network_clock); ASSERT(res == ResultSuccess); res = m_time_m->GetStandardNetworkClockOperationEventForServiceManager(&m_network_clock_event); ASSERT(res == ResultSuccess); - res = m_time_sm->GetEphemeralNetworkSystemClock(m_ephemeral_clock); + res = m_time_sm->GetEphemeralNetworkSystemClock(&m_ephemeral_clock); ASSERT(res == ResultSuccess); res = m_time_m->GetEphemeralNetworkClockOperationEventForServiceManager(&m_ephemeral_clock_event); @@ -183,22 +184,19 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) { AddWaiter(&m_event->GetReadableEvent(), EventType::Exit); // TODO // AddWaiter(gIPmModuleService::GetEvent(), 1); - AddWaiter(&m_alarm_worker.GetEvent().GetReadableEvent(), EventType::PowerStateChange); + AddWaiter(&m_alarm_worker.GetEvent(), EventType::PowerStateChange); } else { AddWaiter(&m_event->GetReadableEvent(), EventType::Exit); // TODO // AddWaiter(gIPmModuleService::GetEvent(), 1); - AddWaiter(&m_alarm_worker.GetEvent().GetReadableEvent(), EventType::PowerStateChange); + AddWaiter(&m_alarm_worker.GetEvent(), EventType::PowerStateChange); AddWaiter(&m_alarm_worker.GetTimerEvent().GetReadableEvent(), EventType::SignalAlarms); - AddWaiter(&m_local_clock_event->GetReadableEvent(), EventType::UpdateLocalSystemClock); - AddWaiter(&m_network_clock_event->GetReadableEvent(), - EventType::UpdateNetworkSystemClock); - AddWaiter(&m_ephemeral_clock_event->GetReadableEvent(), - EventType::UpdateEphemeralSystemClock); + AddWaiter(m_local_clock_event, EventType::UpdateLocalSystemClock); + AddWaiter(m_network_clock_event, EventType::UpdateNetworkSystemClock); + AddWaiter(m_ephemeral_clock_event, EventType::UpdateEphemeralSystemClock); AddWaiter(&m_timer_steady_clock->GetReadableEvent(), EventType::UpdateSteadyClock); AddWaiter(&m_timer_file_system->GetReadableEvent(), EventType::UpdateFileTimestamp); - AddWaiter(&m_standard_user_auto_correct_clock_event->GetReadableEvent(), - EventType::AutoCorrect); + AddWaiter(m_standard_user_auto_correct_clock_event, EventType::AutoCorrect); } s32 out_index{-1}; @@ -237,7 +235,7 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) { m_local_clock_event->Clear(); Service::PSC::Time::SystemClockContext context{}; - auto res = m_local_clock->GetSystemClockContext(context); + auto res = m_local_clock->GetSystemClockContext(&context); ASSERT(res == ResultSuccess); m_set_sys->SetUserSystemClockContext(context); @@ -248,12 +246,12 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) { case EventType::UpdateNetworkSystemClock: { m_network_clock_event->Clear(); Service::PSC::Time::SystemClockContext context{}; - auto res = m_network_clock->GetSystemClockContext(context); + auto res = m_network_clock->GetSystemClockContext(&context); ASSERT(res == ResultSuccess); m_set_sys->SetNetworkSystemClockContext(context); s64 time{}; - if (m_network_clock->GetCurrentTime(time) != ResultSuccess) { + if (m_network_clock->GetCurrentTime(&time) != ResultSuccess) { break; } @@ -275,13 +273,13 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) { m_ephemeral_clock_event->Clear(); Service::PSC::Time::SystemClockContext context{}; - auto res = m_ephemeral_clock->GetSystemClockContext(context); + auto res = m_ephemeral_clock->GetSystemClockContext(&context); if (res != ResultSuccess) { break; } s64 time{}; - res = m_ephemeral_clock->GetCurrentTime(time); + res = m_ephemeral_clock->GetCurrentTime(&time); if (res != ResultSuccess) { break; } @@ -317,11 +315,11 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) { bool automatic_correction{}; auto res = m_time_sm->IsStandardUserSystemClockAutomaticCorrectionEnabled( - automatic_correction); + &automatic_correction); ASSERT(res == ResultSuccess); Service::PSC::Time::SteadyClockTimePoint time_point{}; - res = m_time_sm->GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(time_point); + res = m_time_sm->GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(&time_point); ASSERT(res == ResultSuccess); m_set_sys->SetUserSystemClockAutomaticCorrectionEnabled(automatic_correction); diff --git a/src/core/hle/service/glue/time/worker.h b/src/core/hle/service/glue/time/worker.h index adbbe6b6d..75e5c4d0f 100644 --- a/src/core/hle/service/glue/time/worker.h +++ b/src/core/hle/service/glue/time/worker.h @@ -49,10 +49,10 @@ private: std::shared_ptr<Service::PSC::Time::SystemClock> m_ephemeral_clock; StandardSteadyClockResource& m_steady_clock_resource; FileTimestampWorker& m_file_timestamp_worker; - Kernel::KEvent* m_local_clock_event{}; - Kernel::KEvent* m_network_clock_event{}; - Kernel::KEvent* m_ephemeral_clock_event{}; - Kernel::KEvent* m_standard_user_auto_correct_clock_event{}; + Kernel::KReadableEvent* m_local_clock_event{}; + Kernel::KReadableEvent* m_network_clock_event{}; + Kernel::KReadableEvent* m_ephemeral_clock_event{}; + Kernel::KReadableEvent* m_standard_user_auto_correct_clock_event{}; Kernel::KEvent* m_timer_steady_clock{}; std::shared_ptr<Core::Timing::EventType> m_timer_steady_clock_timing_event; Kernel::KEvent* m_timer_file_system{}; diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp index 1e2d2d212..28e3000bd 100644 --- a/src/core/hle/service/nfc/common/device.cpp +++ b/src/core/hle/service/nfc/common/device.cpp @@ -1405,7 +1405,7 @@ NFP::AmiiboDate NfcDevice::GetAmiiboDate(s64 posix_time) const { system.ServiceManager().GetService<Service::Glue::Time::StaticService>("time:u", true); std::shared_ptr<Service::Glue::Time::TimeZoneService> timezone_service{}; - static_service->GetTimeZoneService(timezone_service); + static_service->GetTimeZoneService(&timezone_service); Service::PSC::Time::CalendarTime calendar_time{}; Service::PSC::Time::CalendarAdditionalInfo additional_info{}; @@ -1416,7 +1416,7 @@ NFP::AmiiboDate NfcDevice::GetAmiiboDate(s64 posix_time) const { amiibo_date.SetMonth(1); amiibo_date.SetDay(1); - if (timezone_service->ToCalendarTimeWithMyRule(calendar_time, additional_info, posix_time) == + if (timezone_service->ToCalendarTimeWithMyRule(&calendar_time, &additional_info, posix_time) == ResultSuccess) { amiibo_date.SetYear(calendar_time.year); amiibo_date.SetMonth(calendar_time.month); @@ -1431,10 +1431,10 @@ s64 NfcDevice::GetCurrentPosixTime() const { system.ServiceManager().GetService<Service::Glue::Time::StaticService>("time:u", true); std::shared_ptr<Service::PSC::Time::SteadyClock> steady_clock{}; - static_service->GetStandardSteadyClock(steady_clock); + static_service->GetStandardSteadyClock(&steady_clock); Service::PSC::Time::SteadyClockTimePoint time_point{}; - R_ASSERT(steady_clock->GetCurrentTimePoint(time_point)); + R_ASSERT(steady_clock->GetCurrentTimePoint(&time_point)); return time_point.time_point; } diff --git a/src/core/hle/service/nfc/common/device_manager.cpp b/src/core/hle/service/nfc/common/device_manager.cpp index b60699c45..94a8243b5 100644 --- a/src/core/hle/service/nfc/common/device_manager.cpp +++ b/src/core/hle/service/nfc/common/device_manager.cpp @@ -91,10 +91,10 @@ Result DeviceManager::ListDevices(std::vector<u64>& nfp_devices, std::size_t max true); std::shared_ptr<Service::PSC::Time::SteadyClock> steady_clock{}; - static_service->GetStandardSteadyClock(steady_clock); + static_service->GetStandardSteadyClock(&steady_clock); Service::PSC::Time::SteadyClockTimePoint time_point{}; - R_ASSERT(steady_clock->GetCurrentTimePoint(time_point)); + R_ASSERT(steady_clock->GetCurrentTimePoint(&time_point)); const s64 elapsed_time = time_point.time_point - time_since_last_error; if (time_since_last_error != 0 && elapsed_time < MinimumRecoveryTime) { @@ -754,10 +754,10 @@ Result DeviceManager::VerifyDeviceResult(std::shared_ptr<NfcDevice> device, system.ServiceManager().GetService<Service::Glue::Time::StaticService>("time:u", true); std::shared_ptr<Service::PSC::Time::SteadyClock> steady_clock{}; - static_service->GetStandardSteadyClock(steady_clock); + static_service->GetStandardSteadyClock(&steady_clock); Service::PSC::Time::SteadyClockTimePoint time_point{}; - R_ASSERT(steady_clock->GetCurrentTimePoint(time_point)); + R_ASSERT(steady_clock->GetCurrentTimePoint(&time_point)); time_since_last_error = time_point.time_point; } 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; diff --git a/src/core/hle/service/set/setting_formats/system_settings.cpp b/src/core/hle/service/set/setting_formats/system_settings.cpp index 16ded43bf..7231ff78e 100644 --- a/src/core/hle/service/set/setting_formats/system_settings.cpp +++ b/src/core/hle/service/set/setting_formats/system_settings.cpp @@ -45,7 +45,7 @@ SystemSettings DefaultSystemSettings() { .console_sleep_plan = ConsoleSleepPlan::Sleep1Hour, }; - settings.device_time_zone_location_name = {"UTC"}; + settings.device_time_zone_location_name = Service::PSC::Time::LocationName{"UTC"}; settings.user_system_clock_automatic_correction_enabled = true; settings.primary_album_storage = PrimaryAlbumStorage::SdCard; |