From da410506a401abc853ee23e56ca1e25eb47cd6e6 Mon Sep 17 00:00:00 2001
From: Kelebek1 <eeeedddccc@hotmail.co.uk>
Date: Fri, 26 Jan 2024 15:29:04 +0000
Subject: [PATCH] Move time services to new IPC. Add some fixes/improvements to
 usage with the new IPC

---
 externals/tz/tz/tz.cpp                        |   4 +-
 externals/tz/tz/tz.h                          |   4 +-
 src/audio_core/CMakeLists.txt                 |   4 +-
 src/common/CMakeLists.txt                     |   4 +-
 src/core/CMakeLists.txt                       |   4 +-
 src/core/core.cpp                             |  14 +-
 src/core/hle/service/caps/caps_manager.cpp    |  12 +-
 src/core/hle/service/cmif_serialization.h     | 123 ++++-
 src/core/hle/service/cmif_types.h             | 213 ++++----
 .../hle/service/glue/time/alarm_worker.cpp    |   3 +-
 src/core/hle/service/glue/time/alarm_worker.h |   4 +-
 .../glue/time/file_timestamp_worker.cpp       |   4 +-
 src/core/hle/service/glue/time/manager.cpp    |  40 +-
 src/core/hle/service/glue/time/static.cpp     | 400 ++++----------
 src/core/hle/service/glue/time/static.h       |  76 +--
 src/core/hle/service/glue/time/time_zone.cpp  | 347 ++++--------
 src/core/hle/service/glue/time/time_zone.h    |  67 ++-
 .../service/glue/time/time_zone_binary.cpp    |  11 +-
 .../hle/service/glue/time/time_zone_binary.h  |   2 +-
 src/core/hle/service/glue/time/worker.cpp     |  42 +-
 src/core/hle/service/glue/time/worker.h       |   8 +-
 src/core/hle/service/nfc/common/device.cpp    |   8 +-
 .../hle/service/nfc/common/device_manager.cpp |   8 +-
 src/core/hle/service/psc/time/common.h        | 135 ++++-
 .../service/psc/time/power_state_service.cpp  |  28 +-
 .../service/psc/time/power_state_service.h    |   7 +-
 .../hle/service/psc/time/service_manager.cpp  | 444 +++++----------
 .../hle/service/psc/time/service_manager.h    |  60 +--
 src/core/hle/service/psc/time/static.cpp      | 507 ++++++------------
 src/core/hle/service/psc/time/static.h        |  65 +--
 .../hle/service/psc/time/steady_clock.cpp     | 133 ++---
 src/core/hle/service/psc/time/steady_clock.h  |  21 +-
 .../hle/service/psc/time/system_clock.cpp     |  92 +---
 src/core/hle/service/psc/time/system_clock.h  |  13 +-
 src/core/hle/service/psc/time/time_zone.cpp   |  18 +-
 src/core/hle/service/psc/time/time_zone.h     |  15 +-
 .../service/psc/time/time_zone_service.cpp    | 334 ++++--------
 .../hle/service/psc/time/time_zone_service.h  |  57 +-
 src/dedicated_room/CMakeLists.txt             |   4 +-
 src/video_core/CMakeLists.txt                 |   4 +-
 src/yuzu/CMakeLists.txt                       |   4 +-
 src/yuzu_cmd/CMakeLists.txt                   |   4 +-
 42 files changed, 1256 insertions(+), 2091 deletions(-)

diff --git a/externals/tz/tz/tz.cpp b/externals/tz/tz/tz.cpp
index 0c8b682170..04fa6cc8a9 100644
--- a/externals/tz/tz/tz.cpp
+++ b/externals/tz/tz/tz.cpp
@@ -1625,11 +1625,11 @@ s32 ParseTimeZoneBinary(Rule& out_rule, std::span<const u8> binary) {
     return 0;
 }
 
-bool localtime_rz(CalendarTimeInternal* tmp, Rule* sp, time_t* timep) {
+bool localtime_rz(CalendarTimeInternal* tmp, Rule const* sp, time_t* timep) {
     return localsub(sp, timep, 0, tmp) == nullptr;
 }
 
-u32 mktime_tzname(time_t* out_time, Rule* sp, CalendarTimeInternal* tmp) {
+u32 mktime_tzname(time_t* out_time, Rule const* sp, CalendarTimeInternal* tmp) {
     return time1(out_time, tmp, localsub, sp, 0);
 }
 
diff --git a/externals/tz/tz/tz.h b/externals/tz/tz/tz.h
index 38605cfb10..dae4459bcb 100644
--- a/externals/tz/tz/tz.h
+++ b/externals/tz/tz/tz.h
@@ -75,7 +75,7 @@ static_assert(sizeof(CalendarTimeInternal) == 0x3C, "CalendarTimeInternal has th
 
 s32 ParseTimeZoneBinary(Rule& out_rule, std::span<const u8> binary);
 
-bool localtime_rz(CalendarTimeInternal* tmp, Rule* sp, time_t* timep);
-u32 mktime_tzname(time_t* out_time, Rule* sp, CalendarTimeInternal* tmp);
+bool localtime_rz(CalendarTimeInternal* tmp, Rule const* sp, time_t* timep);
+u32 mktime_tzname(time_t* out_time, Rule const* sp, CalendarTimeInternal* tmp);
 
 } // namespace Tz
diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt
index e982d03bef..4e4ed1789f 100644
--- a/src/audio_core/CMakeLists.txt
+++ b/src/audio_core/CMakeLists.txt
@@ -210,8 +210,6 @@ add_library(audio_core STATIC
     sink/sink_stream.h
 )
 
-create_target_directory_groups(audio_core)
-
 if (MSVC)
     target_compile_options(audio_core PRIVATE
         /we4242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data
@@ -267,3 +265,5 @@ endif()
 if (YUZU_USE_PRECOMPILED_HEADERS)
     target_precompile_headers(audio_core PRIVATE precompiled_headers.h)
 endif()
+
+create_target_directory_groups(audio_core)
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 8c57d47c6f..e30fea268d 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -244,8 +244,6 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
   )
 endif()
 
-create_target_directory_groups(common)
-
 target_link_libraries(common PUBLIC Boost::context Boost::headers fmt::fmt microprofile stb::headers Threads::Threads)
 target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd LLVM::Demangle)
 
@@ -257,3 +255,5 @@ endif()
 if (YUZU_USE_PRECOMPILED_HEADERS)
     target_precompile_headers(common PRIVATE precompiled_headers.h)
 endif()
+
+create_target_directory_groups(common)
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 347bbf2d09..ea6b2c285a 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -915,8 +915,6 @@ else()
     )
 endif()
 
-create_target_directory_groups(core)
-
 target_link_libraries(core PUBLIC common PRIVATE audio_core hid_core network video_core nx_tzdb tz)
 target_link_libraries(core PUBLIC Boost::headers PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls RenderDoc::API)
 if (MINGW)
@@ -994,3 +992,5 @@ endif()
 if (YUZU_ENABLE_LTO)
   set_property(TARGET core PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
 endif()
+
+create_target_directory_groups(core)
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 1b412ac986..11bf8d2f69 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -200,22 +200,22 @@ struct System::Impl {
             system.ServiceManager().GetService<Service::PSC::Time::StaticService>("time:s", true);
 
         std::shared_ptr<Service::PSC::Time::SystemClock> user_clock;
-        static_service_a->GetStandardUserSystemClock(user_clock);
+        static_service_a->GetStandardUserSystemClock(&user_clock);
 
         std::shared_ptr<Service::PSC::Time::SystemClock> local_clock;
-        static_service_a->GetStandardLocalSystemClock(local_clock);
+        static_service_a->GetStandardLocalSystemClock(&local_clock);
 
         std::shared_ptr<Service::PSC::Time::SystemClock> network_clock;
-        static_service_s->GetStandardNetworkSystemClock(network_clock);
+        static_service_s->GetStandardNetworkSystemClock(&network_clock);
 
         std::shared_ptr<Service::Glue::Time::TimeZoneService> timezone_service;
-        static_service_a->GetTimeZoneService(timezone_service);
+        static_service_a->GetTimeZoneService(&timezone_service);
 
         Service::PSC::Time::LocationName name{};
         auto new_name = Settings::GetTimeZoneString(Settings::values.time_zone_index.GetValue());
-        std::memcpy(name.name.data(), new_name.data(), std::min(name.name.size(), new_name.size()));
+        std::memcpy(name.data(), new_name.data(), std::min(name.size(), new_name.size()));
 
-        timezone_service->SetDeviceLocation(name);
+        timezone_service->SetDeviceLocationName(name);
 
         u64 time_offset = 0;
         if (Settings::values.custom_rtc_enabled) {
@@ -233,7 +233,7 @@ struct System::Impl {
 
         local_clock->SetCurrentTime(new_time);
 
-        network_clock->GetSystemClockContext(context);
+        network_clock->GetSystemClockContext(&context);
         settings_service->SetNetworkSystemClockContext(context);
         network_clock->SetCurrentTime(new_time);
     }
diff --git a/src/core/hle/service/caps/caps_manager.cpp b/src/core/hle/service/caps/caps_manager.cpp
index e3b8ecf3ef..3a22b135f1 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 9eb10e8168..9ee26400de 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 2610c49f3d..dc06169f44 100644
--- a/src/core/hle/service/cmif_types.h
+++ b/src/core/hle/service/cmif_types.h
@@ -12,22 +12,31 @@
 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);
+    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;
+
+    /* implicit */ InLargeData(Type& t) : raw(&t) {}
+    ~InLargeData() = default;
+
+    InLargeData& operator=(Type* rhs) {
+        raw = rhs;
+        return *this;
+    }
+
+    Type* Get() const {
+        return raw;
+    }
+
+    Type& operator*() const {
+        return *raw;
+    }
+
+    Type* operator->() const {
+        return raw;
+    }
+
+    explicit operator bool() const {
+        return raw != nullptr;
+    }
+
+private:
+    Type* raw;
+};
+
+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;
 
-    /* implicit */ LargeData(const T& rhs) : T(rhs) {}
-    /* implicit */ LargeData() = default;
-};
+    /* implicit */ OutLargeData(Type* t) : raw(t) {}
+    /* implicit */ OutLargeData(AutoOut<T>& t) : raw(&t.raw) {}
 
-template <typename T, BufferAttr A>
-using InLargeData = LargeData<T, BufferAttr_FixedSize | BufferAttr_In | A>;
+    Type* Get() const {
+        return raw;
+    }
 
-template <typename T, BufferAttr A>
-using OutLargeData = LargeData<T, BufferAttr_FixedSize | BufferAttr_Out | A>;
+    Type& operator*() const {
+        return *raw;
+    }
 
-template <typename T>
-struct RemoveOut {
-    using Type = std::remove_reference_t<T>;
-};
+    Type* operator->() const {
+        return raw;
+    }
 
-template <typename T>
-struct RemoveOut<Out<T>> {
-    using Type = typename Out<T>::Type;
-};
-
-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,
-};
-
-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<LargeData<T, A>> {
-    static constexpr ArgumentType Type = (A & BufferAttr_In) == 0 ? ArgumentType::OutLargeData : ArgumentType::InLargeData;
-};
-
-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 f549ed00ac..3ff071f4a0 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 f269cffdbc..131d012a6a 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 5a63095498..048ff174c9 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 b567629411..0c27e80298 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 63b7d91da3..f56db76e1f 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) {
-    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);
-}
-
-void StaticService::Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(
-    HLERequestContext& ctx) {
-    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);
-}
-
-void StaticService::Handle_CalculateMonotonicSystemClockBaseTimePoint(HLERequestContext& ctx) {
-    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);
-}
-
-void StaticService::Handle_GetClockSnapshot(HLERequestContext& ctx) {
-    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);
-}
-
-void StaticService::Handle_GetClockSnapshotFromSystemClockContext(HLERequestContext& ctx) {
-    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);
-}
-
-void StaticService::Handle_CalculateStandardUserSystemClockDifferenceByUser(
-    HLERequestContext& ctx) {
-    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);
-}
-
-void StaticService::Handle_CalculateSpanBetween(HLERequestContext& ctx) {
-    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) {
+    OutInterface<Service::PSC::Time::SystemClock> out_service) {
+    LOG_DEBUG(Service_Time, "called.");
+
     R_RETURN(m_wrapped_service->GetStandardUserSystemClock(out_service));
 }
 
 Result StaticService::GetStandardNetworkSystemClock(
-    std::shared_ptr<Service::PSC::Time::SystemClock>& out_service) {
+    OutInterface<Service::PSC::Time::SystemClock> out_service) {
+    LOG_DEBUG(Service_Time, "called.");
+
     R_RETURN(m_wrapped_service->GetStandardNetworkSystemClock(out_service));
 }
 
 Result StaticService::GetStandardSteadyClock(
-    std::shared_ptr<Service::PSC::Time::SteadyClock>& out_service) {
+    OutInterface<Service::PSC::Time::SteadyClock> out_service) {
+    LOG_DEBUG(Service_Time, "called.");
+
     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);
+Result StaticService::GetTimeZoneService(OutInterface<TimeZoneService> out_service) {
+    LOG_DEBUG(Service_Time, "called.");
+
+    *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) {
+    OutInterface<Service::PSC::Time::SystemClock> out_service) {
+    LOG_DEBUG(Service_Time, "called.");
+
     R_RETURN(m_wrapped_service->GetStandardLocalSystemClock(out_service));
 }
 
 Result StaticService::GetEphemeralNetworkSystemClock(
-    std::shared_ptr<Service::PSC::Time::SystemClock>& out_service) {
+    OutInterface<Service::PSC::Time::SystemClock> out_service) {
+    LOG_DEBUG(Service_Time, "called.");
+
     R_RETURN(m_wrapped_service->GetEphemeralNetworkSystemClock(out_service));
 }
 
-Result StaticService::GetSharedMemoryNativeHandle(Kernel::KSharedMemory** out_shared_memory) {
+Result StaticService::GetSharedMemoryNativeHandle(
+    OutCopyHandle<Kernel::KSharedMemory> out_shared_memory) {
+    LOG_DEBUG(Service_Time, "called.");
+
     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 75fe4e2cdb..d3cc0fdd67 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 503c327ddb..5dc1187cb3 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.");
+Result TimeZoneService::GetDeviceLocationName(
+    Out<Service::PSC::Time::LocationName> out_location_name) {
+    SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_location_name={}", *out_location_name); });
 
-    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);
-}
-
-// =============================== 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 3c8ae4bf81..bf12adbdca 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 d33f784c05..cc50b6b7ba 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 2cad6b458a..461f4577e6 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 ea0e49b90b..f44f3077e4 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 adbbe6b6dc..75e5c4d0f1 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 1e2d2d2124..28e3000bd9 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 b60699c452..94a8243b55 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 d17b311438..596828b8b0 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 b0ae71bf9f..ab1d32c703 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 3ebfddb798..56e2c4b87e 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 60820aa9b3..ec906b7238 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) {
+Result ServiceManager::GetStaticServiceAsUser(OutInterface<StaticService> out_service) {
     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) {
-    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);
-}
-
-void ServiceManager::Handle_GetClosestAlarmUpdatedEvent(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_Time, "called.");
-
-    Kernel::KEvent* event{};
-    auto res = GetClosestAlarmUpdatedEvent(&event);
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(res);
-    rb.PushCopyObjects(event->GetReadableEvent());
-}
-
-void ServiceManager::Handle_CheckAndSignalAlarms(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_Time, "called.");
-
-    auto res = CheckAndSignalAlarms();
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(res);
-}
-
-void ServiceManager::Handle_GetClosestAlarmInfo(HLERequestContext& ctx) {
-    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) {
+Result ServiceManager::GetStaticServiceAsAdmin(OutInterface<StaticService> out_service) {
+    LOG_DEBUG(Service_Time, "called.");
+
     R_RETURN(GetStaticService(out_service, StaticServiceSetupInfo{1, 1, 0, 1, 0, 0}, "time:a"));
 }
 
-Result ServiceManager::GetStaticServiceAsRepair(std::shared_ptr<StaticService>& out_service) {
+Result ServiceManager::GetStaticServiceAsRepair(OutInterface<StaticService> out_service) {
+    LOG_DEBUG(Service_Time, "called.");
+
     R_RETURN(GetStaticService(out_service, StaticServiceSetupInfo{0, 0, 0, 0, 1, 0}, "time:r"));
 }
 
-Result ServiceManager::GetStaticServiceAsServiceManager(
-    std::shared_ptr<StaticService>& out_service) {
+Result ServiceManager::GetStaticServiceAsServiceManager(OutInterface<StaticService> out_service) {
+    LOG_DEBUG(Service_Time, "called.");
+
     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 1d99523172..25d361d4f8 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 6f8cf3f889..3ca3311af9 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;
+Result StaticService::GetStandardUserSystemClock(OutInterface<SystemClock> out_service) {
+    LOG_DEBUG(Service_Time, "called.");
 
-    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;
+    *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_GetStandardUserSystemClock(HLERequestContext& ctx) {
+Result StaticService::GetStandardNetworkSystemClock(OutInterface<SystemClock> out_service) {
     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) {
-    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);
-}
-
-void StaticService::Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(
-    HLERequestContext& ctx) {
-    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);
-}
-
-void StaticService::Handle_CalculateMonotonicSystemClockBaseTimePoint(HLERequestContext& ctx) {
-    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);
-}
-
-void StaticService::Handle_GetClockSnapshot(HLERequestContext& ctx) {
-    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);
-}
-
-void StaticService::Handle_GetClockSnapshotFromSystemClockContext(HLERequestContext& ctx) {
-    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);
-}
-
-void StaticService::Handle_CalculateStandardUserSystemClockDifferenceByUser(
-    HLERequestContext& ctx) {
-    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);
-}
-
-void StaticService::Handle_CalculateSpanBetween(HLERequestContext& ctx) {
-    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_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::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::GetStandardSteadyClock(OutInterface<SteadyClock> out_service) {
+    LOG_DEBUG(Service_Time, "called.");
 
-Result StaticService::GetStandardSteadyClock(std::shared_ptr<SteadyClock>& out_service) {
-    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();
 }
 
-Result StaticService::GetTimeZoneService(std::shared_ptr<TimeZoneService>& out_service) {
-    out_service =
+Result StaticService::GetTimeZoneService(OutInterface<TimeZoneService> out_service) {
+    LOG_DEBUG(Service_Time, "called.");
+
+    *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();
 }
 
-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);
+Result StaticService::GetStandardLocalSystemClock(OutInterface<SystemClock> out_service) {
+    LOG_DEBUG(Service_Time, "called.");
+
+    *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::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);
+Result StaticService::GetEphemeralNetworkSystemClock(OutInterface<SystemClock> out_service) {
+    LOG_DEBUG(Service_Time, "called.");
+
+    *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();
 }
 
-Result StaticService::GetSharedMemoryNativeHandle(Kernel::KSharedMemory** out_shared_memory) {
+Result StaticService::GetSharedMemoryNativeHandle(
+    OutCopyHandle<Kernel::KSharedMemory> out_shared_memory) {
+    LOG_DEBUG(Service_Time, "called.");
+
     *out_shared_memory = &m_shared_memory.GetKSharedMemory();
     R_SUCCEED();
 }
 
-Result StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled(bool& out_is_enabled) {
+Result StaticService::SetStandardSteadyClockInternalOffset(s64 offset_ns) {
+    LOG_DEBUG(Service_Time, "called. This function is not implemented!");
+
+    R_UNLESS(m_setup_info.can_write_steady_clock, ResultPermissionDenied);
+
+    R_RETURN(ResultNotImplemented);
+}
+
+Result StaticService::GetStandardSteadyClockRtcValue(Out<s64> out_rtc_value) {
+    LOG_DEBUG(Service_Time, "called. This function is not implemented!");
+
+    R_RETURN(ResultNotImplemented);
+}
+
+Result StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled(
+    Out<bool> out_is_enabled) {
+    SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_is_enabled={}", *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 498cd5ab58..120bab259f 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 1ed5c76799..948610a2b0 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 115e9b138c..025d758a6a 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 13d2f1d114..0695502d5e 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.");
+Result SystemClock::GetCurrentTime(Out<s64> out_time) {
+    SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_time={}", *out_time); });
 
-    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);
-
-    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 f30027e7b4..b40d735953 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 cfee8f866f..82ddba42f9 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 ce2acca179..6bd8f2fda5 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 e304c83877..9376a03240 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,240 +17,78 @@ 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.");
+Result TimeZoneService::GetDeviceLocationName(Out<LocationName> out_location_name) {
+    SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_location_name={}", *out_location_name); });
 
-    LocationName name{};
-    auto res = GetDeviceLocationName(name);
-
-    IPC::ResponseBuilder rb{ctx, 2 + sizeof(LocationName) / sizeof(u32)};
-    rb.Push(res);
-    rb.PushRaw<LocationName>(name);
+    R_RETURN(m_time_zone.GetLocationName(*out_location_name));
 }
 
-void TimeZoneService::Handle_SetDeviceLocationName(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_Time, "called.");
+Result TimeZoneService::SetDeviceLocationName(LocationName& location_name) {
+    LOG_DEBUG(Service_Time, "called. This function is not implemented!");
 
-    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);
+    R_UNLESS(m_can_write_timezone_device_location, ResultPermissionDenied);
+    R_RETURN(ResultNotImplemented);
 }
 
-void TimeZoneService::Handle_GetTotalLocationNameCount(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_Time, "called.");
+Result TimeZoneService::GetTotalLocationNameCount(Out<u32> out_count) {
+    SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_count={}", *out_count); });
 
-    u32 count{};
-    auto res = GetTotalLocationNameCount(count);
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(res);
-    rb.Push(count);
+    R_RETURN(m_time_zone.GetTotalLocationCount(*out_count));
 }
 
-void TimeZoneService::Handle_LoadLocationNameList(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_Time, "called.");
+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};
-    rb.Push(ResultNotImplemented);
+    R_RETURN(ResultNotImplemented);
 }
 
-void TimeZoneService::Handle_LoadTimeZoneRule(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_Time, "called.");
+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(ResultNotImplemented);
+    R_RETURN(ResultNotImplemented);
 }
 
-void TimeZoneService::Handle_GetTimeZoneRuleVersion(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_Time, "called.");
+Result TimeZoneService::GetTimeZoneRuleVersion(Out<RuleVersion> out_rule_version) {
+    SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_rule_version={}", *out_rule_version); });
 
-    RuleVersion rule_version{};
-    auto res = GetTimeZoneRuleVersion(rule_version);
-
-    IPC::ResponseBuilder rb{ctx, 2 + sizeof(RuleVersion) / sizeof(u32)};
-    rb.Push(res);
-    rb.PushRaw<RuleVersion>(rule_version);
+    R_RETURN(m_time_zone.GetRuleVersion(*out_rule_version));
 }
 
-void TimeZoneService::Handle_GetDeviceLocationNameAndUpdatedTime(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);
+    });
 
-    LocationName name{};
-    SteadyClockTimePoint time_point{};
-    auto res = GetDeviceLocationNameAndUpdatedTime(time_point, name);
-
-    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_TRY(m_time_zone.GetLocationName(*out_location_name));
+    R_RETURN(m_time_zone.GetTimePoint(*out_time_point));
 }
 
-void TimeZoneService::Handle_SetDeviceLocationNameWithTimeZoneRule(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_Time, "called.");
+Result TimeZoneService::SetDeviceLocationNameWithTimeZoneRule(
+    LocationName& location_name, InBuffer<BufferAttr_HipcAutoSelect> binary) {
+    LOG_DEBUG(Service_Time, "called. location_name={}", location_name);
 
-    IPC::RequestParser rp{ctx};
-    auto name{rp.PopRaw<LocationName>()};
-
-    auto binary{ctx.ReadBuffer()};
-    auto res = SetDeviceLocationNameWithTimeZoneRule(name, binary);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(res);
-}
-
-void TimeZoneService::Handle_ParseTimeZoneBinary(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_Time, "called.");
-
-    auto binary{ctx.ReadBuffer()};
-
-    Tz::Rule rule{};
-    auto res = ParseTimeZoneBinary(rule, binary);
-
-    ctx.WriteBuffer(rule);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(res);
-}
-
-void TimeZoneService::Handle_GetDeviceLocationNameOperationEventReadableHandle(
-    HLERequestContext& ctx) {
-    LOG_DEBUG(Service_Time, "called.");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultNotImplemented);
-}
-
-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));
-
-    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>()};
-
-    CalendarTime calendar_time{};
-    CalendarAdditionalInfo additional_info{};
-    auto res = ToCalendarTimeWithMyRule(calendar_time, additional_info, time);
-
-    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_ToPosixTime(HLERequestContext& ctx) {
-    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);
-}
-
-void TimeZoneService::Handle_ToPosixTimeWithMyRule(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_Time, "called.");
-
-    IPC::RequestParser rp{ctx};
-    auto calendar{rp.PopRaw<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);
-}
-
-// =============================== Implementations ===========================
-
-Result TimeZoneService::GetDeviceLocationName(LocationName& out_location_name) {
-    R_RETURN(m_time_zone.GetLocationName(out_location_name));
-}
-
-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));
-}
-
-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));
 
@@ -258,32 +99,71 @@ Result TimeZoneService::SetDeviceLocationNameWithTimeZoneRule(LocationName& loca
     R_SUCCEED();
 }
 
-Result TimeZoneService::ParseTimeZoneBinary(Tz::Rule& out_rule, std::span<const u8> binary) {
-    R_RETURN(m_time_zone.ParseBinaryInto(out_rule, binary));
+Result TimeZoneService::ParseTimeZoneBinary(OutRule out_rule,
+                                            InBuffer<BufferAttr_HipcAutoSelect> binary) {
+    LOG_DEBUG(Service_Time, "called.");
+
+    R_RETURN(m_time_zone.ParseBinaryInto(*out_rule, binary));
 }
 
-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::GetDeviceLocationNameOperationEventReadableHandle(
+    OutCopyHandle<Kernel::KReadableEvent> out_event) {
+    LOG_DEBUG(Service_Time, "called. This function is not implemented!");
+
+    R_RETURN(ResultNotImplemented);
 }
 
-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));
-}
+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::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(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.ToCalendarTime(*out_calendar_time, *out_additional_info, time, *rule.Get()));
+}
+
+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);
+    });
+
+    R_RETURN(m_time_zone.ToCalendarTimeWithMyRule(*out_calendar_time, *out_additional_info, time));
+}
+
+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);
+    });
+
+    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);
+    });
+
+    R_RETURN(
+        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 074c1d4ae2..084e3f9077 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/dedicated_room/CMakeLists.txt b/src/dedicated_room/CMakeLists.txt
index 136109a0c8..c0dcc0241f 100644
--- a/src/dedicated_room/CMakeLists.txt
+++ b/src/dedicated_room/CMakeLists.txt
@@ -7,8 +7,6 @@ add_executable(yuzu-room
     yuzu_room.rc
 )
 
-create_target_directory_groups(yuzu-room)
-
 target_link_libraries(yuzu-room PRIVATE common network)
 if (ENABLE_WEB_SERVICE)
     target_compile_definitions(yuzu-room PRIVATE -DENABLE_WEB_SERVICE)
@@ -28,3 +26,5 @@ endif()
 if (YUZU_USE_PRECOMPILED_HEADERS)
     target_precompile_headers(yuzu-room PRIVATE precompiled_headers.h)
 endif()
+
+create_target_directory_groups(yuzu-room)
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 5ed0ad0ed3..521a0e2535 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -289,8 +289,6 @@ add_library(video_core STATIC
     vulkan_common/vulkan.h
 )
 
-create_target_directory_groups(video_core)
-
 target_link_libraries(video_core PUBLIC common core)
 target_link_libraries(video_core PUBLIC glad shader_recompiler stb bc_decoder)
 
@@ -365,3 +363,5 @@ endif()
 if (ANDROID AND ARCHITECTURE_arm64)
     target_link_libraries(video_core PRIVATE adrenotools)
 endif()
+
+create_target_directory_groups(video_core)
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 93b03b9178..b058dba177 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -375,8 +375,6 @@ elseif(WIN32)
     endif()
 endif()
 
-create_target_directory_groups(yuzu)
-
 target_link_libraries(yuzu PRIVATE common core input_common frontend_common network video_core)
 target_link_libraries(yuzu PRIVATE Boost::headers glad Qt${QT_MAJOR_VERSION}::Widgets)
 target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads)
@@ -472,3 +470,5 @@ endif()
 if (YUZU_USE_PRECOMPILED_HEADERS)
     target_precompile_headers(yuzu PRIVATE precompiled_headers.h)
 endif()
+
+create_target_directory_groups(yuzu)
diff --git a/src/yuzu_cmd/CMakeLists.txt b/src/yuzu_cmd/CMakeLists.txt
index fbeba88130..ebd8fd7387 100644
--- a/src/yuzu_cmd/CMakeLists.txt
+++ b/src/yuzu_cmd/CMakeLists.txt
@@ -28,8 +28,6 @@ add_executable(yuzu-cmd
     yuzu.rc
 )
 
-create_target_directory_groups(yuzu-cmd)
-
 target_link_libraries(yuzu-cmd PRIVATE common core input_common frontend_common)
 target_link_libraries(yuzu-cmd PRIVATE glad)
 if (MSVC)
@@ -63,3 +61,5 @@ endif()
 if (YUZU_USE_PRECOMPILED_HEADERS)
     target_precompile_headers(yuzu-cmd PRIVATE precompiled_headers.h)
 endif()
+
+create_target_directory_groups(yuzu-cmd)