From 3c3ca709de03e9363b990c9d0003f692eb5e67b8 Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 24 Sep 2023 20:29:13 -0600 Subject: [PATCH] I'm steady --- src/core/CMakeLists.txt | 48 +- src/core/core.cpp | 16 +- src/core/core.h | 7 - src/core/hle/service/nfc/common/device.cpp | 34 +- src/core/hle/service/nfc/common/device.h | 5 +- .../hle/service/nfc/common/device_manager.cpp | 58 +- .../hle/service/nfc/common/device_manager.h | 5 +- src/core/hle/service/nfc/nfc_interface.cpp | 10 +- .../time/clock_interfaces/steady_clock.cpp | 40 + .../time/clock_interfaces/steady_clock.h | 29 + .../time/clock_interfaces/system_clock.cpp | 48 + .../time/clock_interfaces/system_clock.h | 31 + .../time/clock_types/local_system_clock.cpp | 9 + .../time/clock_types/local_system_clock.h | 21 + .../time/clock_types/network_system_clock.cpp | 9 + .../time/clock_types/network_system_clock.h | 21 + .../service/time/clock_types/steady_clock.cpp | 9 + .../service/time/clock_types/steady_clock.h | 21 + .../time/clock_types/user_system_clock.cpp | 9 + .../time/clock_types/user_system_clock.h | 21 + ...eral_network_system_clock_context_writer.h | 15 - .../ephemeral_network_system_clock_core.h | 16 - src/core/hle/service/time/errors.h | 21 - .../time/local_system_clock_context_writer.h | 26 - .../network_system_clock_context_writer.h | 27 - .../time/standard_local_system_clock_core.h | 16 - .../time/standard_network_system_clock_core.h | 45 - .../time/standard_steady_clock_core.cpp | 24 - .../service/time/standard_steady_clock_core.h | 41 - .../time/standard_user_system_clock_core.cpp | 81 -- .../time/standard_user_system_clock_core.h | 63 - src/core/hle/service/time/steady_clock_core.h | 55 - .../system_clock_context_update_callback.cpp | 54 - .../system_clock_context_update_callback.h | 43 - .../hle/service/time/system_clock_core.cpp | 71 - src/core/hle/service/time/system_clock_core.h | 72 - .../time/tick_based_steady_clock_core.cpp | 22 - .../time/tick_based_steady_clock_core.h | 28 - src/core/hle/service/time/time.cpp | 635 ++++----- src/core/hle/service/time/time.h | 37 - src/core/hle/service/time/time_interface.cpp | 41 - src/core/hle/service/time/time_interface.h | 20 - src/core/hle/service/time/time_manager.cpp | 294 +--- src/core/hle/service/time/time_manager.h | 80 +- src/core/hle/service/time/time_result.h | 21 + .../hle/service/time/time_sharedmemory.cpp | 69 - src/core/hle/service/time/time_sharedmemory.h | 89 -- .../time/{clock_types.h => time_types.h} | 31 +- src/core/hle/service/time/time_util.h | 41 + .../time/time_zone/time_zone_service.cpp | 32 + .../time/{ => time_zone}/time_zone_service.h | 15 +- .../time/{ => time_zone}/time_zone_types.h | 0 .../time/time_zone_content_manager.cpp | 151 --- .../service/time/time_zone_content_manager.h | 49 - .../hle/service/time/time_zone_manager.cpp | 1182 ----------------- src/core/hle/service/time/time_zone_manager.h | 61 - .../hle/service/time/time_zone_service.cpp | 217 --- src/yuzu/configuration/configure_system.cpp | 1 - 58 files changed, 754 insertions(+), 3483 deletions(-) create mode 100644 src/core/hle/service/time/clock_interfaces/steady_clock.cpp create mode 100644 src/core/hle/service/time/clock_interfaces/steady_clock.h create mode 100644 src/core/hle/service/time/clock_interfaces/system_clock.cpp create mode 100644 src/core/hle/service/time/clock_interfaces/system_clock.h create mode 100644 src/core/hle/service/time/clock_types/local_system_clock.cpp create mode 100644 src/core/hle/service/time/clock_types/local_system_clock.h create mode 100644 src/core/hle/service/time/clock_types/network_system_clock.cpp create mode 100644 src/core/hle/service/time/clock_types/network_system_clock.h create mode 100644 src/core/hle/service/time/clock_types/steady_clock.cpp create mode 100644 src/core/hle/service/time/clock_types/steady_clock.h create mode 100644 src/core/hle/service/time/clock_types/user_system_clock.cpp create mode 100644 src/core/hle/service/time/clock_types/user_system_clock.h delete mode 100644 src/core/hle/service/time/ephemeral_network_system_clock_context_writer.h delete mode 100644 src/core/hle/service/time/ephemeral_network_system_clock_core.h delete mode 100644 src/core/hle/service/time/errors.h delete mode 100644 src/core/hle/service/time/local_system_clock_context_writer.h delete mode 100644 src/core/hle/service/time/network_system_clock_context_writer.h delete mode 100644 src/core/hle/service/time/standard_local_system_clock_core.h delete mode 100644 src/core/hle/service/time/standard_network_system_clock_core.h delete mode 100644 src/core/hle/service/time/standard_steady_clock_core.cpp delete mode 100644 src/core/hle/service/time/standard_steady_clock_core.h delete mode 100644 src/core/hle/service/time/standard_user_system_clock_core.cpp delete mode 100644 src/core/hle/service/time/standard_user_system_clock_core.h delete mode 100644 src/core/hle/service/time/steady_clock_core.h delete mode 100644 src/core/hle/service/time/system_clock_context_update_callback.cpp delete mode 100644 src/core/hle/service/time/system_clock_context_update_callback.h delete mode 100644 src/core/hle/service/time/system_clock_core.cpp delete mode 100644 src/core/hle/service/time/system_clock_core.h delete mode 100644 src/core/hle/service/time/tick_based_steady_clock_core.cpp delete mode 100644 src/core/hle/service/time/tick_based_steady_clock_core.h delete mode 100644 src/core/hle/service/time/time_interface.cpp delete mode 100644 src/core/hle/service/time/time_interface.h create mode 100644 src/core/hle/service/time/time_result.h delete mode 100644 src/core/hle/service/time/time_sharedmemory.cpp delete mode 100644 src/core/hle/service/time/time_sharedmemory.h rename src/core/hle/service/time/{clock_types.h => time_types.h} (76%) create mode 100644 src/core/hle/service/time/time_util.h create mode 100644 src/core/hle/service/time/time_zone/time_zone_service.cpp rename src/core/hle/service/time/{ => time_zone}/time_zone_service.h (63%) rename src/core/hle/service/time/{ => time_zone}/time_zone_types.h (100%) delete mode 100644 src/core/hle/service/time/time_zone_content_manager.cpp delete mode 100644 src/core/hle/service/time/time_zone_content_manager.h delete mode 100644 src/core/hle/service/time/time_zone_manager.cpp delete mode 100644 src/core/hle/service/time/time_zone_manager.h delete mode 100644 src/core/hle/service/time/time_zone_service.cpp diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index e02ededfc..5d06a767f 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -781,40 +781,28 @@ add_library(core STATIC hle/service/ssl/ssl.cpp hle/service/ssl/ssl.h hle/service/ssl/ssl_backend.h - hle/service/time/clock_types.h - hle/service/time/ephemeral_network_system_clock_context_writer.h - hle/service/time/ephemeral_network_system_clock_core.h - hle/service/time/errors.h - hle/service/time/local_system_clock_context_writer.h - hle/service/time/network_system_clock_context_writer.h - hle/service/time/standard_local_system_clock_core.h - hle/service/time/standard_network_system_clock_core.h - hle/service/time/standard_steady_clock_core.cpp - hle/service/time/standard_steady_clock_core.h - hle/service/time/standard_user_system_clock_core.cpp - hle/service/time/standard_user_system_clock_core.h - hle/service/time/steady_clock_core.h - hle/service/time/system_clock_context_update_callback.cpp - hle/service/time/system_clock_context_update_callback.h - hle/service/time/system_clock_core.cpp - hle/service/time/system_clock_core.h - hle/service/time/tick_based_steady_clock_core.cpp - hle/service/time/tick_based_steady_clock_core.h + hle/service/time/clock_interfaces/steady_clock.cpp + hle/service/time/clock_interfaces/steady_clock.h + hle/service/time/clock_interfaces/system_clock.cpp + hle/service/time/clock_interfaces/system_clock.h + hle/service/time/clock_types/local_system_clock.cpp + hle/service/time/clock_types/local_system_clock.h + hle/service/time/clock_types/network_system_clock.cpp + hle/service/time/clock_types/network_system_clock.h + hle/service/time/clock_types/steady_clock.cpp + hle/service/time/clock_types/steady_clock.h + hle/service/time/clock_types/user_system_clock.cpp + hle/service/time/clock_types/user_system_clock.h + hle/service/time/time_zone/time_zone_service.cpp + hle/service/time/time_zone/time_zone_service.h + hle/service/time/time_zone/time_zone_types.h hle/service/time/time.cpp hle/service/time/time.h - hle/service/time/time_interface.cpp - hle/service/time/time_interface.h hle/service/time/time_manager.cpp hle/service/time/time_manager.h - hle/service/time/time_sharedmemory.cpp - hle/service/time/time_sharedmemory.h - hle/service/time/time_zone_content_manager.cpp - hle/service/time/time_zone_content_manager.h - hle/service/time/time_zone_manager.cpp - hle/service/time/time_zone_manager.h - hle/service/time/time_zone_service.cpp - hle/service/time/time_zone_service.h - hle/service/time/time_zone_types.h + hle/service/time/time_result.h + hle/service/time/time_types.h + hle/service/time/time_util.h hle/service/usb/usb.cpp hle/service/usb/usb.h hle/service/vi/display/vi_display.cpp diff --git a/src/core/core.cpp b/src/core/core.cpp index 0ab2e3b76..1b5c892e4 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -42,7 +42,6 @@ #include "core/hle/service/glue/glue_manager.h" #include "core/hle/service/service.h" #include "core/hle/service/sm/sm.h" -#include "core/hle/service/time/time_manager.h" #include "core/internal_network/network.h" #include "core/loader/loader.h" #include "core/memory.h" @@ -133,7 +132,7 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, struct System::Impl { explicit Impl(System& system) : kernel{system}, fs_controller{system}, memory{system}, hid_core{}, room_network{}, - cpu_manager{system}, reporter{system}, applet_manager{system}, time_manager{system}, + cpu_manager{system}, reporter{system}, applet_manager{system}, gpu_dirty_memory_write_manager{} { memory.SetGPUDirtyManagers(gpu_dirty_memory_write_manager); } @@ -270,9 +269,6 @@ struct System::Impl { service_manager = std::make_shared(kernel); services = std::make_unique(service_manager, system); - // Initialize time manager, which must happen after kernel is created - time_manager.Initialize(); - is_powered_on = true; exit_locked = false; exit_requested = false; @@ -425,7 +421,6 @@ struct System::Impl { service_manager.reset(); cheat_engine.reset(); telemetry_session.reset(); - time_manager.Shutdown(); core_timing.ClearPendingEvents(); app_loader.reset(); audio_core.reset(); @@ -543,7 +538,6 @@ struct System::Impl { /// Service State Service::Glue::ARPManager arp_manager; - Service::Time::TimeManager time_manager; /// Service manager std::shared_ptr service_manager; @@ -956,14 +950,6 @@ const Service::APM::Controller& System::GetAPMController() const { return impl->apm_controller; } -Service::Time::TimeManager& System::GetTimeManager() { - return impl->time_manager; -} - -const Service::Time::TimeManager& System::GetTimeManager() const { - return impl->time_manager; -} - void System::SetExitLocked(bool locked) { impl->exit_locked = locked; } diff --git a/src/core/core.h b/src/core/core.h index df20f26f3..4d8da6229 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -68,10 +68,6 @@ namespace SM { class ServiceManager; } // namespace SM -namespace Time { -class TimeManager; -} // namespace Time - } // namespace Service namespace Tegra { @@ -405,9 +401,6 @@ public: [[nodiscard]] Service::APM::Controller& GetAPMController(); [[nodiscard]] const Service::APM::Controller& GetAPMController() const; - [[nodiscard]] Service::Time::TimeManager& GetTimeManager(); - [[nodiscard]] const Service::Time::TimeManager& GetTimeManager() const; - [[nodiscard]] Core::Debugger& GetDebugger(); [[nodiscard]] const Core::Debugger& GetDebugger() const; diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp index e7a00deb3..923f299e3 100644 --- a/src/core/hle/service/nfc/common/device.cpp +++ b/src/core/hle/service/nfc/common/device.cpp @@ -32,7 +32,6 @@ #include "core/hle/service/nfc/common/device.h" #include "core/hle/service/nfc/mifare_result.h" #include "core/hle/service/nfc/nfc_result.h" -#include "core/hle/service/time/time_manager.h" namespace Service::NFC { NfcDevice::NfcDevice(Core::HID::NpadIdType npad_id_, Core::System& system_, @@ -393,12 +392,12 @@ Result NfcDevice::WriteMifare(std::span paramet return result; } -Result NfcDevice::SendCommandByPassThrough(const Time::Clock::TimeSpanType& timeout, - std::span command_data, - std::span out_data) { - // Not implemented - return ResultSuccess; -} +//Result NfcDevice::SendCommandByPassThrough(const Time::Clock::TimeSpanType& timeout, +// std::span command_data, +// std::span out_data) { +// // Not implemented +// return ResultSuccess; +//} Result NfcDevice::Mount(NFP::ModelType model_type, NFP::MountTarget mount_target_) { if (device_state != DeviceState::TagFound) { @@ -1390,27 +1389,28 @@ void NfcDevice::SetAmiiboName(NFP::AmiiboSettings& settings, } NFP::AmiiboDate NfcDevice::GetAmiiboDate(s64 posix_time) const { - const auto& time_zone_manager = - system.GetTimeManager().GetTimeZoneContentManager().GetTimeZoneManager(); - Time::TimeZone::CalendarInfo calendar_info{}; + //const auto& time_zone_manager = + // system.GetTimeManager().GetTimeZoneContentManager().GetTimeZoneManager(); + //Time::TimeZone::CalendarInfo calendar_info{}; NFP::AmiiboDate amiibo_date{}; amiibo_date.SetYear(2000); amiibo_date.SetMonth(1); amiibo_date.SetDay(1); - if (time_zone_manager.ToCalendarTime({}, posix_time, calendar_info) == ResultSuccess) { - amiibo_date.SetYear(calendar_info.time.year); - amiibo_date.SetMonth(calendar_info.time.month); - amiibo_date.SetDay(calendar_info.time.day); - } + //if (time_zone_manager.ToCalendarTime({}, posix_time, calendar_info) == ResultSuccess) { + // amiibo_date.SetYear(calendar_info.time.year); + // amiibo_date.SetMonth(calendar_info.time.month); + // amiibo_date.SetDay(calendar_info.time.day); + //} return amiibo_date; } u64 NfcDevice::GetCurrentPosixTime() const { - auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()}; - return standard_steady_clock.GetCurrentTimePoint(system).time_point; + //auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()}; + //return standard_steady_clock.GetCurrentTimePoint(system).time_point; + return 0; } u64 NfcDevice::RemoveVersionByte(u64 application_id) const { diff --git a/src/core/hle/service/nfc/common/device.h b/src/core/hle/service/nfc/common/device.h index 0ed1ff34c..d3630c89f 100644 --- a/src/core/hle/service/nfc/common/device.h +++ b/src/core/hle/service/nfc/common/device.h @@ -11,7 +11,6 @@ #include "core/hle/service/nfc/nfc_types.h" #include "core/hle/service/nfp/nfp_types.h" #include "core/hle/service/service.h" -#include "core/hle/service/time/clock_types.h" namespace Kernel { class KEvent; @@ -49,8 +48,8 @@ public: Result WriteMifare(std::span parameters); - Result SendCommandByPassThrough(const Time::Clock::TimeSpanType& timeout, - std::span command_data, std::span out_data); + //Result SendCommandByPassThrough(const Time::Clock::TimeSpanType& timeout, + // std::span command_data, std::span out_data); Result Mount(NFP::ModelType model_type, NFP::MountTarget mount_target); Result Unmount(); diff --git a/src/core/hle/service/nfc/common/device_manager.cpp b/src/core/hle/service/nfc/common/device_manager.cpp index a71d26157..c66e782b5 100644 --- a/src/core/hle/service/nfc/common/device_manager.cpp +++ b/src/core/hle/service/nfc/common/device_manager.cpp @@ -11,8 +11,6 @@ #include "core/hle/service/nfc/common/device.h" #include "core/hle/service/nfc/common/device_manager.h" #include "core/hle/service/nfc/nfc_result.h" -#include "core/hle/service/time/clock_types.h" -#include "core/hle/service/time/time_manager.h" namespace Service::NFC { @@ -81,14 +79,14 @@ Result DeviceManager::ListDevices(std::vector& nfp_devices, std::size_t max continue; } if (skip_fatal_errors) { - constexpr u64 MinimumRecoveryTime = 60; - auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()}; - const u64 elapsed_time = standard_steady_clock.GetCurrentTimePoint(system).time_point - - time_since_last_error; + //constexpr u64 MinimumRecoveryTime = 60; + //auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()}; + //const u64 elapsed_time = standard_steady_clock.GetCurrentTimePoint(system).time_point - + // time_since_last_error; - if (time_since_last_error != 0 && elapsed_time < MinimumRecoveryTime) { - continue; - } + //if (time_since_last_error != 0 && elapsed_time < MinimumRecoveryTime) { + // continue; + //} } if (device->GetCurrentState() == DeviceState::Unavailable) { continue; @@ -249,22 +247,22 @@ Result DeviceManager::WriteMifare(u64 device_handle, return result; } -Result DeviceManager::SendCommandByPassThrough(u64 device_handle, - const Time::Clock::TimeSpanType& timeout, - std::span command_data, - std::span out_data) { - std::scoped_lock lock{mutex}; - - std::shared_ptr device = nullptr; - auto result = GetDeviceHandle(device_handle, device); - - if (result.IsSuccess()) { - result = device->SendCommandByPassThrough(timeout, command_data, out_data); - result = VerifyDeviceResult(device, result); - } - - return result; -} +//Result DeviceManager::SendCommandByPassThrough(u64 device_handle, +// const Time::Clock::TimeSpanType& timeout, +// std::span command_data, +// std::span out_data) { +// std::scoped_lock lock{mutex}; +// +// std::shared_ptr device = nullptr; +// auto result = GetDeviceHandle(device_handle, device); +// +// if (result.IsSuccess()) { +// result = device->SendCommandByPassThrough(timeout, command_data, out_data); +// result = VerifyDeviceResult(device, result); +// } +// +// return result; +//} Result DeviceManager::Mount(u64 device_handle, NFP::ModelType model_type, NFP::MountTarget mount_target) { @@ -738,11 +736,11 @@ Result DeviceManager::VerifyDeviceResult(std::shared_ptr device, return device_state; } - if (operation_result == ResultUnknown112 || operation_result == ResultUnknown114 || - operation_result == ResultUnknown115) { - auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()}; - time_since_last_error = standard_steady_clock.GetCurrentTimePoint(system).time_point; - } + //if (operation_result == ResultUnknown112 || operation_result == ResultUnknown114 || + // operation_result == ResultUnknown115) { + // auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()}; + // time_since_last_error = standard_steady_clock.GetCurrentTimePoint(system).time_point; + //} return operation_result; } diff --git a/src/core/hle/service/nfc/common/device_manager.h b/src/core/hle/service/nfc/common/device_manager.h index c9f038e32..a17e7c995 100644 --- a/src/core/hle/service/nfc/common/device_manager.h +++ b/src/core/hle/service/nfc/common/device_manager.h @@ -14,7 +14,6 @@ #include "core/hle/service/nfc/nfc_types.h" #include "core/hle/service/nfp/nfp_types.h" #include "core/hle/service/service.h" -#include "core/hle/service/time/clock_types.h" namespace Service::NFC { class NfcDevice; @@ -42,8 +41,8 @@ public: std::span read_data); Result WriteMifare(u64 device_handle, std::span write_parameters); - Result SendCommandByPassThrough(u64 device_handle, const Time::Clock::TimeSpanType& timeout, - std::span command_data, std::span out_data); + //Result SendCommandByPassThrough(u64 device_handle, const Time::Clock::TimeSpanType& timeout, + // std::span command_data, std::span out_data); // Nfp device manager Result Mount(u64 device_handle, NFP::ModelType model_type, NFP::MountTarget mount_target); diff --git a/src/core/hle/service/nfc/nfc_interface.cpp b/src/core/hle/service/nfc/nfc_interface.cpp index 179c7ba2c..dc73d7b2e 100644 --- a/src/core/hle/service/nfc/nfc_interface.cpp +++ b/src/core/hle/service/nfc/nfc_interface.cpp @@ -14,7 +14,6 @@ #include "core/hle/service/nfc/nfc_result.h" #include "core/hle/service/nfc/nfc_types.h" #include "core/hle/service/nfp/nfp_result.h" -#include "core/hle/service/time/clock_types.h" namespace Service::NFC { @@ -261,14 +260,15 @@ void NfcInterface::WriteMifare(HLERequestContext& ctx) { void NfcInterface::SendCommandByPassThrough(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; - const auto timeout{rp.PopRaw()}; + //const auto timeout{rp.PopRaw()}; const auto command_data{ctx.ReadBuffer()}; LOG_INFO(Service_NFC, "(STUBBED) called, device_handle={}, timeout={}, data_size={}", - device_handle, timeout.ToSeconds(), command_data.size()); + device_handle, 0, command_data.size()); std::vector out_data(1); - auto result = - GetManager()->SendCommandByPassThrough(device_handle, timeout, command_data, out_data); + //auto result = + // GetManager()->SendCommandByPassThrough(device_handle, timeout, command_data, out_data); + Result result = ResultSuccess; result = TranslateResultToServiceError(result); if (result.IsError()) { diff --git a/src/core/hle/service/time/clock_interfaces/steady_clock.cpp b/src/core/hle/service/time/clock_interfaces/steady_clock.cpp new file mode 100644 index 000000000..917e02756 --- /dev/null +++ b/src/core/hle/service/time/clock_interfaces/steady_clock.cpp @@ -0,0 +1,40 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/logging/log.h" +#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/time/clock_types/steady_clock.h" + +namespace Service::Time { +ISteadyClock::ISteadyClock(Core::System& system_) : ServiceFramework{system_, "ISteadyClock"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &ISteadyClock::GetCurrentTimePoint, "GetCurrentTimePoint"}, + {2, nullptr, "GetTestOffset"}, + {3, nullptr, "SetTestOffset"}, + {100, nullptr, "GetRtcValue"}, + {101, nullptr, "IsRtcResetDetected"}, + {102, nullptr, "GetSetupResultValue"}, + {200, nullptr, "GetInternalOffset"}, + {201, nullptr, "SetInternalOffset"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +ISteadyClock::~ISteadyClock() = default; + +void ISteadyClock::GetCurrentTimePoint(HLERequestContext& ctx) { + LOG_DEBUG(Service_Time, "called"); + + IPC::ResponseBuilder rb{ctx, 6}; + rb.Push(ResultSuccess); + rb.PushRaw(0); +} + +bool ISteadyClock::IsInitialized() { + return is_initialized; +} + +} // namespace Service::Time diff --git a/src/core/hle/service/time/clock_interfaces/steady_clock.h b/src/core/hle/service/time/clock_interfaces/steady_clock.h new file mode 100644 index 000000000..9ddafc5b9 --- /dev/null +++ b/src/core/hle/service/time/clock_interfaces/steady_clock.h @@ -0,0 +1,29 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/result.h" +#include "core/hle/service/service.h" +#include "core/hle/service/time/time_types.h" + +namespace Core { +class System; +} + +namespace Service::Time { + +class ISteadyClock : public ServiceFramework { +public: + explicit ISteadyClock(Core::System& system_); + ~ISteadyClock(); + + bool IsInitialized(); + +private: + void GetCurrentTimePoint(HLERequestContext& ctx); + + bool is_initialized{}; +}; + +} // namespace Service::Time diff --git a/src/core/hle/service/time/clock_interfaces/system_clock.cpp b/src/core/hle/service/time/clock_interfaces/system_clock.cpp new file mode 100644 index 000000000..c05c0039a --- /dev/null +++ b/src/core/hle/service/time/clock_interfaces/system_clock.cpp @@ -0,0 +1,48 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/logging/log.h" +#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/time/clock_interfaces/system_clock.h" + +namespace Service::Time { +ISystemClock::ISystemClock(Core::System& system_) : ServiceFramework{system_, "ISystemClock"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &ISystemClock::GetCurrentTime, "GetCurrentTime"}, + {1, nullptr, "SetCurrentTime"}, + {2, &ISystemClock::GetSystemClockContext, "GetSystemClockContext"}, + {3, nullptr, "SetSystemClockContext"}, + {4, nullptr, "GetOperationEventReadableHandle"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +ISystemClock::~ISystemClock() = default; + +void ISystemClock::GetCurrentTime(HLERequestContext& ctx) { + LOG_DEBUG(Service_Time, "called"); + + s64 posix_time{}; + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(posix_time); +} + +void ISystemClock::GetSystemClockContext(HLERequestContext& ctx) { + LOG_DEBUG(Service_Time, "called"); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.PushRaw(0); +} + +Result ISystemClock::GetClockContext(SystemClockContext& out_context) { + out_context = context; + return ResultSuccess; +} + +} // namespace Service::Time diff --git a/src/core/hle/service/time/clock_interfaces/system_clock.h b/src/core/hle/service/time/clock_interfaces/system_clock.h new file mode 100644 index 000000000..95c4d5262 --- /dev/null +++ b/src/core/hle/service/time/clock_interfaces/system_clock.h @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/result.h" +#include "core/hle/service/service.h" +#include "core/hle/service/time/time_types.h" + +namespace Core { +class System; +} + +namespace Service::Time { + +class ISystemClock : public ServiceFramework { +public: + explicit ISystemClock(Core::System& system_); + ~ISystemClock(); + + Result GetClockContext(SystemClockContext& out_context); + bool IsStandardNetworkSystemClockAccuracySufficient(); + +private: + void GetCurrentTime(HLERequestContext& ctx); + void GetSystemClockContext(HLERequestContext& ctx); + + SystemClockContext context; +}; + +} // namespace Service::Time diff --git a/src/core/hle/service/time/clock_types/local_system_clock.cpp b/src/core/hle/service/time/clock_types/local_system_clock.cpp new file mode 100644 index 000000000..e90b98998 --- /dev/null +++ b/src/core/hle/service/time/clock_types/local_system_clock.cpp @@ -0,0 +1,9 @@ +// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/logging/log.h" +#include "core/core.h" +#include "core/hle/service/time/clock_types/steady_clock.h" +#include "core/hle/service/time/clock_types/system_clock.h" + +namespace Service::Time {} // namespace Service::Time diff --git a/src/core/hle/service/time/clock_types/local_system_clock.h b/src/core/hle/service/time/clock_types/local_system_clock.h new file mode 100644 index 000000000..7df58f7bc --- /dev/null +++ b/src/core/hle/service/time/clock_types/local_system_clock.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/time/clock_interfaces/system_clock.h" +#include "core/hle/service/time/time_types.h" + +namespace Core { +class System; +} + +namespace Service::Time { + +class LocalSystemClock : public ISystemClock { +public: + explicit LocalSystemClock(); + ~LocalSystemClock(); +}; + +} // namespace Service::Time diff --git a/src/core/hle/service/time/clock_types/network_system_clock.cpp b/src/core/hle/service/time/clock_types/network_system_clock.cpp new file mode 100644 index 000000000..e90b98998 --- /dev/null +++ b/src/core/hle/service/time/clock_types/network_system_clock.cpp @@ -0,0 +1,9 @@ +// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/logging/log.h" +#include "core/core.h" +#include "core/hle/service/time/clock_types/steady_clock.h" +#include "core/hle/service/time/clock_types/system_clock.h" + +namespace Service::Time {} // namespace Service::Time diff --git a/src/core/hle/service/time/clock_types/network_system_clock.h b/src/core/hle/service/time/clock_types/network_system_clock.h new file mode 100644 index 000000000..91b5637df --- /dev/null +++ b/src/core/hle/service/time/clock_types/network_system_clock.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/time/clock_interfaces/system_clock.h" +#include "core/hle/service/time/time_types.h" + +namespace Core { +class System; +} + +namespace Service::Time { + +class NetworkSystemClock : public ISystemClock { +public: + explicit NetworkSystemClock(); + ~NetworkSystemClock(); +}; + +} // namespace Service::Time diff --git a/src/core/hle/service/time/clock_types/steady_clock.cpp b/src/core/hle/service/time/clock_types/steady_clock.cpp new file mode 100644 index 000000000..e90b98998 --- /dev/null +++ b/src/core/hle/service/time/clock_types/steady_clock.cpp @@ -0,0 +1,9 @@ +// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/logging/log.h" +#include "core/core.h" +#include "core/hle/service/time/clock_types/steady_clock.h" +#include "core/hle/service/time/clock_types/system_clock.h" + +namespace Service::Time {} // namespace Service::Time diff --git a/src/core/hle/service/time/clock_types/steady_clock.h b/src/core/hle/service/time/clock_types/steady_clock.h new file mode 100644 index 000000000..3b2bb27ca --- /dev/null +++ b/src/core/hle/service/time/clock_types/steady_clock.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/time/clock_interfaces/steady_clock.h" +#include "core/hle/service/time/time_types.h" + +namespace Core { +class System; +} + +namespace Service::Time { + +class SteadyClock : public ISteadyClock { +public: + explicit SteadyClock(); + ~SteadyClock(); +}; + +} // namespace Service::Time diff --git a/src/core/hle/service/time/clock_types/user_system_clock.cpp b/src/core/hle/service/time/clock_types/user_system_clock.cpp new file mode 100644 index 000000000..e90b98998 --- /dev/null +++ b/src/core/hle/service/time/clock_types/user_system_clock.cpp @@ -0,0 +1,9 @@ +// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/logging/log.h" +#include "core/core.h" +#include "core/hle/service/time/clock_types/steady_clock.h" +#include "core/hle/service/time/clock_types/system_clock.h" + +namespace Service::Time {} // namespace Service::Time diff --git a/src/core/hle/service/time/clock_types/user_system_clock.h b/src/core/hle/service/time/clock_types/user_system_clock.h new file mode 100644 index 000000000..6cb5f0469 --- /dev/null +++ b/src/core/hle/service/time/clock_types/user_system_clock.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/time/clock_interfaces/system_clock.h" +#include "core/hle/service/time/time_types.h" + +namespace Core { +class System; +} + +namespace Service::Time { + +class UserSystemClock : public ISystemClock { +public: + explicit UserSystemClock(); + ~UserSystemClock(); +}; + +} // namespace Service::Time diff --git a/src/core/hle/service/time/ephemeral_network_system_clock_context_writer.h b/src/core/hle/service/time/ephemeral_network_system_clock_context_writer.h deleted file mode 100644 index 0f928a5a5..000000000 --- a/src/core/hle/service/time/ephemeral_network_system_clock_context_writer.h +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/time/system_clock_context_update_callback.h" - -namespace Service::Time::Clock { - -class EphemeralNetworkSystemClockContextWriter final : public SystemClockContextUpdateCallback { -public: - EphemeralNetworkSystemClockContextWriter() : SystemClockContextUpdateCallback{} {} -}; - -} // namespace Service::Time::Clock diff --git a/src/core/hle/service/time/ephemeral_network_system_clock_core.h b/src/core/hle/service/time/ephemeral_network_system_clock_core.h deleted file mode 100644 index 0a5f5aafb..000000000 --- a/src/core/hle/service/time/ephemeral_network_system_clock_core.h +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/time/system_clock_core.h" - -namespace Service::Time::Clock { - -class EphemeralNetworkSystemClockCore final : public SystemClockCore { -public: - explicit EphemeralNetworkSystemClockCore(SteadyClockCore& steady_clock_core_) - : SystemClockCore{steady_clock_core_} {} -}; - -} // namespace Service::Time::Clock diff --git a/src/core/hle/service/time/errors.h b/src/core/hle/service/time/errors.h deleted file mode 100644 index 6655d30e1..000000000 --- a/src/core/hle/service/time/errors.h +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/result.h" - -namespace Service::Time { - -constexpr Result ERROR_PERMISSION_DENIED{ErrorModule::Time, 1}; -constexpr Result ERROR_TIME_MISMATCH{ErrorModule::Time, 102}; -constexpr Result ERROR_UNINITIALIZED_CLOCK{ErrorModule::Time, 103}; -constexpr Result ERROR_TIME_NOT_FOUND{ErrorModule::Time, 200}; -constexpr Result ERROR_OVERFLOW{ErrorModule::Time, 201}; -constexpr Result ERROR_LOCATION_NAME_TOO_LONG{ErrorModule::Time, 801}; -constexpr Result ERROR_OUT_OF_RANGE{ErrorModule::Time, 902}; -constexpr Result ERROR_TIME_ZONE_CONVERSION_FAILED{ErrorModule::Time, 903}; -constexpr Result ERROR_TIME_ZONE_NOT_FOUND{ErrorModule::Time, 989}; -constexpr Result ERROR_NOT_IMPLEMENTED{ErrorModule::Time, 990}; - -} // namespace Service::Time diff --git a/src/core/hle/service/time/local_system_clock_context_writer.h b/src/core/hle/service/time/local_system_clock_context_writer.h deleted file mode 100644 index 1639ef2b9..000000000 --- a/src/core/hle/service/time/local_system_clock_context_writer.h +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/time/system_clock_context_update_callback.h" -#include "core/hle/service/time/time_sharedmemory.h" - -namespace Service::Time::Clock { - -class LocalSystemClockContextWriter final : public SystemClockContextUpdateCallback { -public: - explicit LocalSystemClockContextWriter(SharedMemory& shared_memory_) - : SystemClockContextUpdateCallback{}, shared_memory{shared_memory_} {} - -protected: - Result Update() override { - shared_memory.UpdateLocalSystemClockContext(context); - return ResultSuccess; - } - -private: - SharedMemory& shared_memory; -}; - -} // namespace Service::Time::Clock diff --git a/src/core/hle/service/time/network_system_clock_context_writer.h b/src/core/hle/service/time/network_system_clock_context_writer.h deleted file mode 100644 index 655e4c06d..000000000 --- a/src/core/hle/service/time/network_system_clock_context_writer.h +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/time/errors.h" -#include "core/hle/service/time/system_clock_context_update_callback.h" -#include "core/hle/service/time/time_sharedmemory.h" - -namespace Service::Time::Clock { - -class NetworkSystemClockContextWriter final : public SystemClockContextUpdateCallback { -public: - explicit NetworkSystemClockContextWriter(SharedMemory& shared_memory_) - : SystemClockContextUpdateCallback{}, shared_memory{shared_memory_} {} - -protected: - Result Update() override { - shared_memory.UpdateNetworkSystemClockContext(context); - return ResultSuccess; - } - -private: - SharedMemory& shared_memory; -}; - -} // namespace Service::Time::Clock diff --git a/src/core/hle/service/time/standard_local_system_clock_core.h b/src/core/hle/service/time/standard_local_system_clock_core.h deleted file mode 100644 index ae2ff1bfd..000000000 --- a/src/core/hle/service/time/standard_local_system_clock_core.h +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/time/system_clock_core.h" - -namespace Service::Time::Clock { - -class StandardLocalSystemClockCore final : public SystemClockCore { -public: - explicit StandardLocalSystemClockCore(SteadyClockCore& steady_clock_core_) - : SystemClockCore{steady_clock_core_} {} -}; - -} // namespace Service::Time::Clock diff --git a/src/core/hle/service/time/standard_network_system_clock_core.h b/src/core/hle/service/time/standard_network_system_clock_core.h deleted file mode 100644 index c1ec5252b..000000000 --- a/src/core/hle/service/time/standard_network_system_clock_core.h +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/time/clock_types.h" -#include "core/hle/service/time/steady_clock_core.h" -#include "core/hle/service/time/system_clock_core.h" - -namespace Core { -class System; -} - -namespace Service::Time::Clock { - -class StandardNetworkSystemClockCore final : public SystemClockCore { -public: - explicit StandardNetworkSystemClockCore(SteadyClockCore& steady_clock_core_) - : SystemClockCore{steady_clock_core_} {} - - void SetStandardNetworkClockSufficientAccuracy(TimeSpanType value) { - standard_network_clock_sufficient_accuracy = value; - } - - bool IsStandardNetworkSystemClockAccuracySufficient(Core::System& system) const { - SystemClockContext clock_ctx{}; - if (GetClockContext(system, clock_ctx) != ResultSuccess) { - return {}; - } - - s64 span{}; - if (clock_ctx.steady_time_point.GetSpanBetween( - GetSteadyClockCore().GetCurrentTimePoint(system), span) != ResultSuccess) { - return {}; - } - - return TimeSpanType{span}.nanoseconds < - standard_network_clock_sufficient_accuracy.nanoseconds; - } - -private: - TimeSpanType standard_network_clock_sufficient_accuracy{}; -}; - -} // namespace Service::Time::Clock diff --git a/src/core/hle/service/time/standard_steady_clock_core.cpp b/src/core/hle/service/time/standard_steady_clock_core.cpp deleted file mode 100644 index 5627b7003..000000000 --- a/src/core/hle/service/time/standard_steady_clock_core.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "core/core.h" -#include "core/core_timing.h" -#include "core/hardware_properties.h" -#include "core/hle/service/time/standard_steady_clock_core.h" - -namespace Service::Time::Clock { - -TimeSpanType StandardSteadyClockCore::GetCurrentRawTimePoint(Core::System& system) { - const TimeSpanType ticks_time_span{ - TimeSpanType::FromTicks(system.CoreTiming().GetClockTicks())}; - TimeSpanType raw_time_point{setup_value.nanoseconds + ticks_time_span.nanoseconds}; - - if (raw_time_point.nanoseconds < cached_raw_time_point.nanoseconds) { - raw_time_point.nanoseconds = cached_raw_time_point.nanoseconds; - } - - cached_raw_time_point = raw_time_point; - return raw_time_point; -} - -} // namespace Service::Time::Clock diff --git a/src/core/hle/service/time/standard_steady_clock_core.h b/src/core/hle/service/time/standard_steady_clock_core.h deleted file mode 100644 index 036463b87..000000000 --- a/src/core/hle/service/time/standard_steady_clock_core.h +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/time/clock_types.h" -#include "core/hle/service/time/steady_clock_core.h" - -namespace Core { -class System; -} - -namespace Service::Time::Clock { - -class StandardSteadyClockCore final : public SteadyClockCore { -public: - SteadyClockTimePoint GetTimePoint(Core::System& system) override { - return {GetCurrentRawTimePoint(system).ToSeconds(), GetClockSourceId()}; - } - - TimeSpanType GetInternalOffset() const override { - return internal_offset; - } - - void SetInternalOffset(TimeSpanType value) override { - internal_offset = value; - } - - TimeSpanType GetCurrentRawTimePoint(Core::System& system) override; - - void SetSetupValue(TimeSpanType value) { - setup_value = value; - } - -private: - TimeSpanType setup_value{}; - TimeSpanType internal_offset{}; - TimeSpanType cached_raw_time_point{}; -}; - -} // namespace Service::Time::Clock diff --git a/src/core/hle/service/time/standard_user_system_clock_core.cpp b/src/core/hle/service/time/standard_user_system_clock_core.cpp deleted file mode 100644 index b033757ed..000000000 --- a/src/core/hle/service/time/standard_user_system_clock_core.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "common/assert.h" -#include "core/core.h" -#include "core/hle/kernel/k_event.h" -#include "core/hle/service/time/standard_local_system_clock_core.h" -#include "core/hle/service/time/standard_network_system_clock_core.h" -#include "core/hle/service/time/standard_user_system_clock_core.h" - -namespace Service::Time::Clock { - -StandardUserSystemClockCore::StandardUserSystemClockCore( - StandardLocalSystemClockCore& local_system_clock_core_, - StandardNetworkSystemClockCore& network_system_clock_core_, Core::System& system_) - : SystemClockCore(local_system_clock_core_.GetSteadyClockCore()), - local_system_clock_core{local_system_clock_core_}, - network_system_clock_core{network_system_clock_core_}, - auto_correction_time{SteadyClockTimePoint::GetRandom()}, service_context{ - system_, - "StandardUserSystemClockCore"} { - auto_correction_event = - service_context.CreateEvent("StandardUserSystemClockCore:AutoCorrectionEvent"); -} - -StandardUserSystemClockCore::~StandardUserSystemClockCore() { - service_context.CloseEvent(auto_correction_event); -} - -Result StandardUserSystemClockCore::SetAutomaticCorrectionEnabled(Core::System& system, - bool value) { - if (const Result result{ApplyAutomaticCorrection(system, value)}; result != ResultSuccess) { - return result; - } - - auto_correction_enabled = value; - - return ResultSuccess; -} - -Result StandardUserSystemClockCore::GetClockContext(Core::System& system, - SystemClockContext& ctx) const { - if (const Result result{ApplyAutomaticCorrection(system, false)}; result != ResultSuccess) { - return result; - } - - return local_system_clock_core.GetClockContext(system, ctx); -} - -Result StandardUserSystemClockCore::Flush(const SystemClockContext&) { - UNIMPLEMENTED(); - return ERROR_NOT_IMPLEMENTED; -} - -Result StandardUserSystemClockCore::SetClockContext(const SystemClockContext&) { - UNIMPLEMENTED(); - return ERROR_NOT_IMPLEMENTED; -} - -Result StandardUserSystemClockCore::ApplyAutomaticCorrection(Core::System& system, - bool value) const { - if (auto_correction_enabled == value) { - return ResultSuccess; - } - - if (!network_system_clock_core.IsClockSetup(system)) { - return ERROR_UNINITIALIZED_CLOCK; - } - - SystemClockContext ctx{}; - if (const Result result{network_system_clock_core.GetClockContext(system, ctx)}; - result != ResultSuccess) { - return result; - } - - local_system_clock_core.SetClockContext(ctx); - - return ResultSuccess; -} - -} // namespace Service::Time::Clock diff --git a/src/core/hle/service/time/standard_user_system_clock_core.h b/src/core/hle/service/time/standard_user_system_clock_core.h deleted file mode 100644 index ee6e29487..000000000 --- a/src/core/hle/service/time/standard_user_system_clock_core.h +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/kernel_helpers.h" -#include "core/hle/service/time/clock_types.h" -#include "core/hle/service/time/system_clock_core.h" - -namespace Core { -class System; -} - -namespace Kernel { -class KEvent; -} - -namespace Service::Time::Clock { - -class StandardLocalSystemClockCore; -class StandardNetworkSystemClockCore; - -class StandardUserSystemClockCore final : public SystemClockCore { -public: - StandardUserSystemClockCore(StandardLocalSystemClockCore& local_system_clock_core_, - StandardNetworkSystemClockCore& network_system_clock_core_, - Core::System& system_); - - ~StandardUserSystemClockCore() override; - - Result SetAutomaticCorrectionEnabled(Core::System& system, bool value); - - Result GetClockContext(Core::System& system, SystemClockContext& ctx) const override; - - bool IsAutomaticCorrectionEnabled() const { - return auto_correction_enabled; - } - - void SetAutomaticCorrectionUpdatedTime(SteadyClockTimePoint steady_clock_time_point) { - auto_correction_time = steady_clock_time_point; - } - -protected: - Result Flush(const SystemClockContext&) override; - - Result SetClockContext(const SystemClockContext&) override; - - Result ApplyAutomaticCorrection(Core::System& system, bool value) const; - - const SteadyClockTimePoint& GetAutomaticCorrectionUpdatedTime() const { - return auto_correction_time; - } - -private: - StandardLocalSystemClockCore& local_system_clock_core; - StandardNetworkSystemClockCore& network_system_clock_core; - bool auto_correction_enabled{}; - SteadyClockTimePoint auto_correction_time; - KernelHelpers::ServiceContext service_context; - Kernel::KEvent* auto_correction_event; -}; - -} // namespace Service::Time::Clock diff --git a/src/core/hle/service/time/steady_clock_core.h b/src/core/hle/service/time/steady_clock_core.h deleted file mode 100644 index 2867c351c..000000000 --- a/src/core/hle/service/time/steady_clock_core.h +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "common/uuid.h" -#include "core/hle/service/time/clock_types.h" - -namespace Core { -class System; -} - -namespace Service::Time::Clock { - -class SteadyClockCore { -public: - SteadyClockCore() = default; - virtual ~SteadyClockCore() = default; - - const Common::UUID& GetClockSourceId() const { - return clock_source_id; - } - - void SetClockSourceId(const Common::UUID& value) { - clock_source_id = value; - } - - virtual TimeSpanType GetInternalOffset() const = 0; - - virtual void SetInternalOffset(TimeSpanType internal_offset) = 0; - - virtual SteadyClockTimePoint GetTimePoint(Core::System& system) = 0; - - virtual TimeSpanType GetCurrentRawTimePoint(Core::System& system) = 0; - - SteadyClockTimePoint GetCurrentTimePoint(Core::System& system) { - SteadyClockTimePoint result{GetTimePoint(system)}; - result.time_point += GetInternalOffset().ToSeconds(); - return result; - } - - bool IsInitialized() const { - return is_initialized; - } - - void MarkAsInitialized() { - is_initialized = true; - } - -private: - Common::UUID clock_source_id{Common::UUID::MakeRandom()}; - bool is_initialized{}; -}; - -} // namespace Service::Time::Clock diff --git a/src/core/hle/service/time/system_clock_context_update_callback.cpp b/src/core/hle/service/time/system_clock_context_update_callback.cpp deleted file mode 100644 index cafc04ee7..000000000 --- a/src/core/hle/service/time/system_clock_context_update_callback.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "core/hle/kernel/k_event.h" -#include "core/hle/service/time/errors.h" -#include "core/hle/service/time/system_clock_context_update_callback.h" - -namespace Service::Time::Clock { - -SystemClockContextUpdateCallback::SystemClockContextUpdateCallback() = default; -SystemClockContextUpdateCallback::~SystemClockContextUpdateCallback() = default; - -bool SystemClockContextUpdateCallback::NeedUpdate(const SystemClockContext& value) const { - if (has_context) { - return context.offset != value.offset || - context.steady_time_point.clock_source_id != value.steady_time_point.clock_source_id; - } - - return true; -} - -void SystemClockContextUpdateCallback::RegisterOperationEvent( - std::shared_ptr&& event) { - operation_event_list.emplace_back(std::move(event)); -} - -void SystemClockContextUpdateCallback::BroadcastOperationEvent() { - for (const auto& event : operation_event_list) { - event->Signal(); - } -} - -Result SystemClockContextUpdateCallback::Update(const SystemClockContext& value) { - Result result{ResultSuccess}; - - if (NeedUpdate(value)) { - context = value; - has_context = true; - - result = Update(); - - if (result == ResultSuccess) { - BroadcastOperationEvent(); - } - } - - return result; -} - -Result SystemClockContextUpdateCallback::Update() { - return ResultSuccess; -} - -} // namespace Service::Time::Clock diff --git a/src/core/hle/service/time/system_clock_context_update_callback.h b/src/core/hle/service/time/system_clock_context_update_callback.h deleted file mode 100644 index bf657acd9..000000000 --- a/src/core/hle/service/time/system_clock_context_update_callback.h +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include - -#include "core/hle/service/time/clock_types.h" - -namespace Kernel { -class KEvent; -} - -namespace Service::Time::Clock { - -// Parts of this implementation were based on Ryujinx (https://github.com/Ryujinx/Ryujinx/pull/783). -// This code was released under public domain. - -class SystemClockContextUpdateCallback { -public: - SystemClockContextUpdateCallback(); - virtual ~SystemClockContextUpdateCallback(); - - bool NeedUpdate(const SystemClockContext& value) const; - - void RegisterOperationEvent(std::shared_ptr&& event); - - void BroadcastOperationEvent(); - - Result Update(const SystemClockContext& value); - -protected: - virtual Result Update(); - - SystemClockContext context{}; - -private: - bool has_context{}; - std::vector> operation_event_list; -}; - -} // namespace Service::Time::Clock diff --git a/src/core/hle/service/time/system_clock_core.cpp b/src/core/hle/service/time/system_clock_core.cpp deleted file mode 100644 index da078241f..000000000 --- a/src/core/hle/service/time/system_clock_core.cpp +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "core/hle/service/time/steady_clock_core.h" -#include "core/hle/service/time/system_clock_context_update_callback.h" -#include "core/hle/service/time/system_clock_core.h" - -namespace Service::Time::Clock { - -SystemClockCore::SystemClockCore(SteadyClockCore& steady_clock_core_) - : steady_clock_core{steady_clock_core_} { - context.steady_time_point.clock_source_id = steady_clock_core.GetClockSourceId(); -} - -SystemClockCore::~SystemClockCore() = default; - -Result SystemClockCore::GetCurrentTime(Core::System& system, s64& posix_time) const { - posix_time = 0; - - const SteadyClockTimePoint current_time_point{steady_clock_core.GetCurrentTimePoint(system)}; - - SystemClockContext clock_context{}; - if (const Result result{GetClockContext(system, clock_context)}; result != ResultSuccess) { - return result; - } - - if (current_time_point.clock_source_id != clock_context.steady_time_point.clock_source_id) { - return ERROR_TIME_MISMATCH; - } - - posix_time = clock_context.offset + current_time_point.time_point; - - return ResultSuccess; -} - -Result SystemClockCore::SetCurrentTime(Core::System& system, s64 posix_time) { - const SteadyClockTimePoint current_time_point{steady_clock_core.GetCurrentTimePoint(system)}; - const SystemClockContext clock_context{posix_time - current_time_point.time_point, - current_time_point}; - - if (const Result result{SetClockContext(clock_context)}; result != ResultSuccess) { - return result; - } - return Flush(clock_context); -} - -Result SystemClockCore::Flush(const SystemClockContext& clock_context) { - if (!system_clock_context_update_callback) { - return ResultSuccess; - } - return system_clock_context_update_callback->Update(clock_context); -} - -Result SystemClockCore::SetSystemClockContext(const SystemClockContext& clock_context) { - if (const Result result{SetClockContext(clock_context)}; result != ResultSuccess) { - return result; - } - return Flush(clock_context); -} - -bool SystemClockCore::IsClockSetup(Core::System& system) const { - SystemClockContext value{}; - if (GetClockContext(system, value) == ResultSuccess) { - const SteadyClockTimePoint steady_clock_time_point{ - steady_clock_core.GetCurrentTimePoint(system)}; - return steady_clock_time_point.clock_source_id == value.steady_time_point.clock_source_id; - } - return {}; -} - -} // namespace Service::Time::Clock diff --git a/src/core/hle/service/time/system_clock_core.h b/src/core/hle/service/time/system_clock_core.h deleted file mode 100644 index 8cb34126f..000000000 --- a/src/core/hle/service/time/system_clock_core.h +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include - -#include "common/common_types.h" -#include "core/hle/service/time/clock_types.h" - -namespace Core { -class System; -} - -namespace Service::Time::Clock { - -class SteadyClockCore; -class SystemClockContextUpdateCallback; - -// Parts of this implementation were based on Ryujinx (https://github.com/Ryujinx/Ryujinx/pull/783). -// This code was released under public domain. - -class SystemClockCore { -public: - explicit SystemClockCore(SteadyClockCore& steady_clock_core_); - virtual ~SystemClockCore(); - - SteadyClockCore& GetSteadyClockCore() const { - return steady_clock_core; - } - - Result GetCurrentTime(Core::System& system, s64& posix_time) const; - - Result SetCurrentTime(Core::System& system, s64 posix_time); - - virtual Result GetClockContext([[maybe_unused]] Core::System& system, - SystemClockContext& value) const { - value = context; - return ResultSuccess; - } - - virtual Result SetClockContext(const SystemClockContext& value) { - context = value; - return ResultSuccess; - } - - virtual Result Flush(const SystemClockContext& clock_context); - - void SetUpdateCallbackInstance(std::shared_ptr callback) { - system_clock_context_update_callback = std::move(callback); - } - - Result SetSystemClockContext(const SystemClockContext& context); - - bool IsInitialized() const { - return is_initialized; - } - - void MarkAsInitialized() { - is_initialized = true; - } - - bool IsClockSetup(Core::System& system) const; - -private: - SteadyClockCore& steady_clock_core; - SystemClockContext context{}; - bool is_initialized{}; - std::shared_ptr system_clock_context_update_callback; -}; - -} // namespace Service::Time::Clock diff --git a/src/core/hle/service/time/tick_based_steady_clock_core.cpp b/src/core/hle/service/time/tick_based_steady_clock_core.cpp deleted file mode 100644 index 0d9fb3143..000000000 --- a/src/core/hle/service/time/tick_based_steady_clock_core.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "core/core.h" -#include "core/core_timing.h" -#include "core/hardware_properties.h" -#include "core/hle/service/time/tick_based_steady_clock_core.h" - -namespace Service::Time::Clock { - -SteadyClockTimePoint TickBasedSteadyClockCore::GetTimePoint(Core::System& system) { - const TimeSpanType ticks_time_span{ - TimeSpanType::FromTicks(system.CoreTiming().GetClockTicks())}; - - return {ticks_time_span.ToSeconds(), GetClockSourceId()}; -} - -TimeSpanType TickBasedSteadyClockCore::GetCurrentRawTimePoint(Core::System& system) { - return TimeSpanType::FromSeconds(GetTimePoint(system).time_point); -} - -} // namespace Service::Time::Clock diff --git a/src/core/hle/service/time/tick_based_steady_clock_core.h b/src/core/hle/service/time/tick_based_steady_clock_core.h deleted file mode 100644 index 491185dc3..000000000 --- a/src/core/hle/service/time/tick_based_steady_clock_core.h +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/time/clock_types.h" -#include "core/hle/service/time/steady_clock_core.h" - -namespace Core { -class System; -} - -namespace Service::Time::Clock { - -class TickBasedSteadyClockCore final : public SteadyClockCore { -public: - TimeSpanType GetInternalOffset() const override { - return {}; - } - - void SetInternalOffset(TimeSpanType internal_offset) override {} - - SteadyClockTimePoint GetTimePoint(Core::System& system) override; - - TimeSpanType GetCurrentRawTimePoint(Core::System& system) override; -}; - -} // namespace Service::Time::Clock diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 7197ca30f..15b19d765 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp @@ -4,29 +4,45 @@ #include "common/logging/log.h" #include "core/core.h" #include "core/core_timing.h" -#include "core/hardware_properties.h" -#include "core/hle/kernel/kernel.h" #include "core/hle/service/ipc_helpers.h" -#include "core/hle/service/server_manager.h" +#include "core/hle/service/service.h" +#include "core/hle/service/time/clock_interfaces/steady_clock.h" +#include "core/hle/service/time/clock_interfaces/system_clock.h" #include "core/hle/service/time/time.h" -#include "core/hle/service/time/time_interface.h" #include "core/hle/service/time/time_manager.h" -#include "core/hle/service/time/time_sharedmemory.h" -#include "core/hle/service/time/time_zone_service.h" +#include "core/hle/service/time/time_types.h" +#include "core/hle/service/time/time_util.h" +#include "core/hle/service/time/time_zone/time_zone_service.h" namespace Service::Time { -class ISystemClock final : public ServiceFramework { +class IStaticService final : public ServiceFramework { public: - explicit ISystemClock(Clock::SystemClockCore& clock_core_, Core::System& system_) - : ServiceFramework{system_, "ISystemClock"}, clock_core{clock_core_} { + explicit IStaticService(const char* name, Core::System& system_) + : ServiceFramework{system_, name} { // clang-format off static const FunctionInfo functions[] = { - {0, &ISystemClock::GetCurrentTime, "GetCurrentTime"}, - {1, nullptr, "SetCurrentTime"}, - {2, &ISystemClock::GetSystemClockContext, "GetSystemClockContext"}, - {3, nullptr, "SetSystemClockContext"}, - {4, nullptr, "GetOperationEventReadableHandle"}, + {0, &IStaticService::GetStandardUserSystemClock, "GetStandardUserSystemClock"}, + {1, &IStaticService::GetStandardNetworkSystemClock, "GetStandardNetworkSystemClock"}, + {2, &IStaticService::GetStandardSteadyClock, "GetStandardSteadyClock"}, + {3, &IStaticService::GetTimeZoneService, "GetTimeZoneService"}, + {4, &IStaticService::GetStandardLocalSystemClock, "GetStandardLocalSystemClock"}, + {5, nullptr, "GetEphemeralNetworkSystemClock"}, + {20, &IStaticService::GetSharedMemoryNativeHandle, "GetSharedMemoryNativeHandle"}, + {30, nullptr, "GetStandardNetworkClockOperationEventReadableHandle"}, + {31, nullptr, "GetEphemeralNetworkClockOperationEventReadableHandle"}, + {50, nullptr, "SetStandardSteadyClockInternalOffset"}, + {51, nullptr, "GetStandardSteadyClockRtcValue"}, + {100, nullptr, "IsStandardUserSystemClockAutomaticCorrectionEnabled"}, + {101, nullptr, "SetStandardUserSystemClockAutomaticCorrectionEnabled"}, + {102, nullptr, "GetStandardUserSystemClockInitialYear"}, + {200, &IStaticService::IsStandardNetworkSystemClockAccuracySufficient, "IsStandardNetworkSystemClockAccuracySufficient"}, + {201, nullptr, "GetStandardUserSystemClockAutomaticCorrectionUpdatedTime"}, + {300, &IStaticService::CalculateMonotonicSystemClockBaseTimePoint, "CalculateMonotonicSystemClockBaseTimePoint"}, + {400, &IStaticService::GetClockSnapshot, "GetClockSnapshot"}, + {401, &IStaticService::GetClockSnapshotFromSystemClockContext, "GetClockSnapshotFromSystemClockContext"}, + {500, &IStaticService::CalculateStandardUserSystemClockDifferenceByUser, "CalculateStandardUserSystemClockDifferenceByUser"}, + {501, &IStaticService::CalculateSpanBetween, "CalculateSpanBetween"}, }; // clang-format on @@ -34,378 +50,273 @@ public: } private: - void GetCurrentTime(HLERequestContext& ctx) { + void GetStandardUserSystemClock(HLERequestContext& ctx) { LOG_DEBUG(Service_Time, "called"); - if (!clock_core.IsInitialized()) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_UNINITIALIZED_CLOCK); - return; + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(manager->GetStandardUserSystemClock()); + } + + void GetStandardNetworkSystemClock(HLERequestContext& ctx) { + LOG_DEBUG(Service_Time, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(manager->GetStandardNetworkSystemClock()); + } + + void GetStandardSteadyClock(HLERequestContext& ctx) { + LOG_DEBUG(Service_Time, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(manager->GetStandardSteadyClock()); + } + + void GetTimeZoneService(HLERequestContext& ctx) { + LOG_DEBUG(Service_Time, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(manager->GetTimeZoneService()); + } + + void GetStandardLocalSystemClock(HLERequestContext& ctx) { + LOG_DEBUG(Service_Time, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(manager->GetStandardLocalSystemClock()); + } + + void GetSharedMemoryNativeHandle(HLERequestContext& ctx) { + LOG_DEBUG(Service_Time, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 1}; + rb.Push(ResultSuccess); + rb.PushCopyObjects(&system.Kernel().GetTimeSharedMem()); + } + + void IsStandardNetworkSystemClockAccuracySufficient(HLERequestContext& ctx) { + LOG_DEBUG(Service_Time, "called"); + auto& clock_core{manager->GetStandardNetworkSystemClock()}; + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(clock_core.IsStandardNetworkSystemClockAccuracySufficient()); + } + + void CalculateMonotonicSystemClockBaseTimePoint(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto context{rp.PopRaw()}; + + LOG_DEBUG(Service_Time, "called"); + + Result result = ResultSuccess; + u64 base_time_point{}; + SteadyClockTimePoint current_time_point{}; + auto& steady_clock_core{manager->GetStandardSteadyClock()}; + if (!steady_clock_core.IsInitialized()) { + result = ResultUnitializedClock; } - s64 posix_time{}; - if (const Result result{clock_core.GetCurrentTime(system, posix_time)}; result.IsError()) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - return; + if (result.IsSuccess()) { + result = manager->GetCurrentTimePoint(current_time_point); + } + + if (result.IsSuccess()) { + if (current_time_point.clock_source_id != context.steady_time_point.clock_source_id) { + result = ResultTimeMismatch; + } + } + + if (result.IsSuccess()) { + const auto ticks{TimeSpanType::FromTicks( + system.CoreTiming().GetClockTicks())}; + base_time_point = context.offset + current_time_point.time_point - ticks.ToSeconds(); + } + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(result); + rb.PushRaw(base_time_point); + } + + Result GetClockSnapshotFromSystemClockContextImpl(ClockSnapshot& out_clock_snapshot, + const SystemClockContext& user_context, + const SystemClockContext& network_context, + TimeType type) { + Result result = ResultSuccess; + out_clock_snapshot.user_context = user_context; + out_clock_snapshot.network_context = network_context; + + result = manager->GetCurrentTimePoint(out_clock_snapshot.steady_clock_time_point); + if (result.IsSuccess()) { + out_clock_snapshot.is_automatic_correction_enabled = + manager->IsAutomaticCorrectionEnabled(); + result = manager->GetLocationName(out_clock_snapshot.location_name); + } + + if (result.IsSuccess()) { + result = TimeUtil::GetCurrentTime(out_clock_snapshot.user_time, + out_clock_snapshot.steady_clock_time_point, + out_clock_snapshot.user_context); + } + + if (result.IsSuccess()) { + result = manager->GetCalendarTime(out_clock_snapshot.user_calendar_time, + out_clock_snapshot.user_calendar_additional_time, + out_clock_snapshot.user_time); + } + + if (result.IsSuccess()) { + const Result time_result = TimeUtil::GetCurrentTime( + out_clock_snapshot.network_time, out_clock_snapshot.steady_clock_time_point, + out_clock_snapshot.network_context); + if (time_result.IsError()) { + out_clock_snapshot.network_time = 0; + } + result = manager->GetCalendarTime(out_clock_snapshot.network_calendar_time, + out_clock_snapshot.network_calendar_additional_time, + out_clock_snapshot.network_time); + } + + if (result.IsSuccess()) { + out_clock_snapshot.type = type; + } + + return result; + } + + void GetClockSnapshot(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto type{rp.PopEnum()}; + + LOG_DEBUG(Service_Time, "called, type={}", type); + + Result result = ResultSuccess; + SystemClockContext user_context{}; + SystemClockContext network_context{}; + ClockSnapshot clock_snapshot{}; + + result = manager->GetStandardUserSystemClock().GetClockContext(user_context); + + if (result.IsSuccess()) { + result = manager->GetStandardNetworkSystemClock().GetClockContext(user_context); + } + + if (result.IsSuccess()) { + result = GetClockSnapshotFromSystemClockContextImpl(clock_snapshot, user_context, + network_context, type); + } + + if (result.IsSuccess()) { + ctx.WriteBuffer(clock_snapshot); + } + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); + } + + void GetClockSnapshotFromSystemClockContext(HLERequestContext& ctx) { + struct params { + TimeType type; + }; + IPC::RequestParser rp{ctx}; + const auto type{rp.PopEnum()}; + rp.Skip(1, false); + const SystemClockContext user_context{rp.PopRaw()}; + const SystemClockContext network_context{rp.PopRaw()}; + + LOG_DEBUG(Service_Time, "called, type={}", type); + + ClockSnapshot clock_snapshot{}; + const auto result = GetClockSnapshotFromSystemClockContextImpl(clock_snapshot, user_context, + network_context, type); + + if (result.IsSuccess()) { + ctx.WriteBuffer(clock_snapshot); + } + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); + } + + void CalculateStandardUserSystemClockDifferenceByUser(HLERequestContext& ctx) { + const auto snapshot_a_data = ctx.ReadBuffer(0); + const auto snapshot_b_data = ctx.ReadBuffer(1); + + ClockSnapshot snapshot_a; + ClockSnapshot snapshot_b; + std::memcpy(&snapshot_a, snapshot_a_data.data(), sizeof(ClockSnapshot)); + std::memcpy(&snapshot_b, snapshot_b_data.data(), sizeof(ClockSnapshot)); + + LOG_DEBUG(Service_Time, "called"); + + auto time_span = TimeSpanType::FromSeconds(snapshot_b.user_context.offset - + snapshot_a.user_context.offset); + + if (snapshot_a.user_context.steady_time_point.clock_source_id != + snapshot_b.user_context.steady_time_point.clock_source_id) { + time_span = {}; + } + + if (snapshot_a.is_automatic_correction_enabled && + snapshot_b.is_automatic_correction_enabled) { + if (snapshot_a.network_context.steady_time_point.clock_source_id == + snapshot_a.steady_clock_time_point.clock_source_id) { + time_span = {}; + } + if (snapshot_b.network_context.steady_time_point.clock_source_id == + snapshot_b.steady_clock_time_point.clock_source_id) { + time_span = {}; + } } IPC::ResponseBuilder rb{ctx, 4}; rb.Push(ResultSuccess); - rb.Push(posix_time); + rb.PushRaw(time_span.nanoseconds); } - void GetSystemClockContext(HLERequestContext& ctx) { + void CalculateSpanBetween(HLERequestContext& ctx) { + const auto snapshot_a_data = ctx.ReadBuffer(0); + const auto snapshot_b_data = ctx.ReadBuffer(1); + + ClockSnapshot snapshot_a; + ClockSnapshot snapshot_b; + std::memcpy(&snapshot_a, snapshot_a_data.data(), sizeof(ClockSnapshot)); + std::memcpy(&snapshot_b, snapshot_b_data.data(), sizeof(ClockSnapshot)); + LOG_DEBUG(Service_Time, "called"); - if (!clock_core.IsInitialized()) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_UNINITIALIZED_CLOCK); - return; + TimeSpanType time_span{}; + Result result = TimeUtil::GetSpanBetween(time_span, snapshot_a.steady_clock_time_point, + snapshot_b.steady_clock_time_point); + + if (result.IsError()) { + result = ResultTimeNotFound; + if (snapshot_a.network_time != 0 && snapshot_b.network_time != 0) { + time_span = {snapshot_b.network_time - snapshot_a.network_time}; + result = ResultSuccess; + } } - Clock::SystemClockContext system_clock_context{}; - if (const Result result{clock_core.GetClockContext(system, system_clock_context)}; - result.IsError()) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - return; - } - - IPC::ResponseBuilder rb{ctx, sizeof(Clock::SystemClockContext) / 4 + 2}; - rb.Push(ResultSuccess); - rb.PushRaw(system_clock_context); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(result); + rb.PushRaw(time_span.nanoseconds); } - Clock::SystemClockCore& clock_core; + std::shared_ptr manager; }; -class ISteadyClock final : public ServiceFramework { -public: - explicit ISteadyClock(Clock::SteadyClockCore& clock_core_, Core::System& system_) - : ServiceFramework{system_, "ISteadyClock"}, clock_core{clock_core_} { - static const FunctionInfo functions[] = { - {0, &ISteadyClock::GetCurrentTimePoint, "GetCurrentTimePoint"}, - {2, nullptr, "GetTestOffset"}, - {3, nullptr, "SetTestOffset"}, - {100, nullptr, "GetRtcValue"}, - {101, nullptr, "IsRtcResetDetected"}, - {102, nullptr, "GetSetupResultValue"}, - {200, nullptr, "GetInternalOffset"}, - {201, nullptr, "SetInternalOffset"}, - }; - RegisterHandlers(functions); - } - -private: - void GetCurrentTimePoint(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called"); - - if (!clock_core.IsInitialized()) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_UNINITIALIZED_CLOCK); - return; - } - - const Clock::SteadyClockTimePoint time_point{clock_core.GetCurrentTimePoint(system)}; - IPC::ResponseBuilder rb{ctx, (sizeof(Clock::SteadyClockTimePoint) / 4) + 2}; - rb.Push(ResultSuccess); - rb.PushRaw(time_point); - } - - Clock::SteadyClockCore& clock_core; -}; - -Result Module::Interface::GetClockSnapshotFromSystemClockContextInternal( - Kernel::KThread* thread, Clock::SystemClockContext user_context, - Clock::SystemClockContext network_context, Clock::TimeType type, - Clock::ClockSnapshot& clock_snapshot) { - - auto& time_manager{system.GetTimeManager()}; - - clock_snapshot.steady_clock_time_point = - time_manager.GetStandardSteadyClockCore().GetCurrentTimePoint(system); - clock_snapshot.is_automatic_correction_enabled = - time_manager.GetStandardUserSystemClockCore().IsAutomaticCorrectionEnabled(); - clock_snapshot.type = type; - - if (const Result result{ - time_manager.GetTimeZoneContentManager().GetTimeZoneManager().GetDeviceLocationName( - clock_snapshot.location_name)}; - result != ResultSuccess) { - return result; - } - - clock_snapshot.user_context = user_context; - - if (const Result result{Clock::ClockSnapshot::GetCurrentTime( - clock_snapshot.user_time, clock_snapshot.steady_clock_time_point, - clock_snapshot.user_context)}; - result != ResultSuccess) { - return result; - } - - TimeZone::CalendarInfo userCalendarInfo{}; - if (const Result result{ - time_manager.GetTimeZoneContentManager().GetTimeZoneManager().ToCalendarTimeWithMyRules( - clock_snapshot.user_time, userCalendarInfo)}; - result != ResultSuccess) { - return result; - } - - clock_snapshot.user_calendar_time = userCalendarInfo.time; - clock_snapshot.user_calendar_additional_time = userCalendarInfo.additional_info; - - clock_snapshot.network_context = network_context; - - if (Clock::ClockSnapshot::GetCurrentTime(clock_snapshot.network_time, - clock_snapshot.steady_clock_time_point, - clock_snapshot.network_context) != ResultSuccess) { - clock_snapshot.network_time = 0; - } - - TimeZone::CalendarInfo networkCalendarInfo{}; - if (const Result result{ - time_manager.GetTimeZoneContentManager().GetTimeZoneManager().ToCalendarTimeWithMyRules( - clock_snapshot.network_time, networkCalendarInfo)}; - result != ResultSuccess) { - return result; - } - - clock_snapshot.network_calendar_time = networkCalendarInfo.time; - clock_snapshot.network_calendar_additional_time = networkCalendarInfo.additional_info; - - return ResultSuccess; -} - -void Module::Interface::GetStandardUserSystemClock(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called"); - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(system.GetTimeManager().GetStandardUserSystemClockCore(), - system); -} - -void Module::Interface::GetStandardNetworkSystemClock(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called"); - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(system.GetTimeManager().GetStandardNetworkSystemClockCore(), - system); -} - -void Module::Interface::GetStandardSteadyClock(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called"); - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(system.GetTimeManager().GetStandardSteadyClockCore(), system); -} - -void Module::Interface::GetTimeZoneService(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called"); - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(system, - system.GetTimeManager().GetTimeZoneContentManager()); -} - -void Module::Interface::GetStandardLocalSystemClock(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called"); - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(system.GetTimeManager().GetStandardLocalSystemClockCore(), - system); -} - -void Module::Interface::IsStandardNetworkSystemClockAccuracySufficient(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called"); - auto& clock_core{system.GetTimeManager().GetStandardNetworkSystemClockCore()}; - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(clock_core.IsStandardNetworkSystemClockAccuracySufficient(system)); -} - -void Module::Interface::CalculateMonotonicSystemClockBaseTimePoint(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called"); - - auto& steady_clock_core{system.GetTimeManager().GetStandardSteadyClockCore()}; - if (!steady_clock_core.IsInitialized()) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_UNINITIALIZED_CLOCK); - return; - } - - IPC::RequestParser rp{ctx}; - const auto context{rp.PopRaw()}; - const auto current_time_point{steady_clock_core.GetCurrentTimePoint(system)}; - - if (current_time_point.clock_source_id == context.steady_time_point.clock_source_id) { - const auto ticks{Clock::TimeSpanType::FromTicks( - system.CoreTiming().GetClockTicks())}; - const s64 base_time_point{context.offset + current_time_point.time_point - - ticks.ToSeconds()}; - IPC::ResponseBuilder rb{ctx, (sizeof(s64) / 4) + 2}; - rb.Push(ResultSuccess); - rb.PushRaw(base_time_point); - return; - } - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_TIME_MISMATCH); -} - -void Module::Interface::GetClockSnapshot(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto type{rp.PopEnum()}; - - LOG_DEBUG(Service_Time, "called, type={}", type); - - Clock::SystemClockContext user_context{}; - if (const Result result{ - system.GetTimeManager().GetStandardUserSystemClockCore().GetClockContext(system, - user_context)}; - result.IsError()) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - return; - } - - Clock::SystemClockContext network_context{}; - if (const Result result{ - system.GetTimeManager().GetStandardNetworkSystemClockCore().GetClockContext( - system, network_context)}; - result.IsError()) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - return; - } - - Clock::ClockSnapshot clock_snapshot{}; - if (const Result result{GetClockSnapshotFromSystemClockContextInternal( - &ctx.GetThread(), user_context, network_context, type, clock_snapshot)}; - result.IsError()) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - return; - } - - ctx.WriteBuffer(clock_snapshot); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void Module::Interface::GetClockSnapshotFromSystemClockContext(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto type{rp.PopEnum()}; - - rp.Skip(1, false); - - const Clock::SystemClockContext user_context{rp.PopRaw()}; - const Clock::SystemClockContext network_context{rp.PopRaw()}; - - LOG_DEBUG(Service_Time, "called, type={}", type); - - Clock::ClockSnapshot clock_snapshot{}; - if (const Result result{GetClockSnapshotFromSystemClockContextInternal( - &ctx.GetThread(), user_context, network_context, type, clock_snapshot)}; - result != ResultSuccess) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - return; - } - - ctx.WriteBuffer(clock_snapshot); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void Module::Interface::CalculateStandardUserSystemClockDifferenceByUser(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called"); - - Clock::ClockSnapshot snapshot_a; - Clock::ClockSnapshot snapshot_b; - - const auto snapshot_a_data = ctx.ReadBuffer(0); - const auto snapshot_b_data = ctx.ReadBuffer(1); - - std::memcpy(&snapshot_a, snapshot_a_data.data(), sizeof(Clock::ClockSnapshot)); - std::memcpy(&snapshot_b, snapshot_b_data.data(), sizeof(Clock::ClockSnapshot)); - - auto time_span_type{Clock::TimeSpanType::FromSeconds(snapshot_b.user_context.offset - - snapshot_a.user_context.offset)}; - - if ((snapshot_b.user_context.steady_time_point.clock_source_id != - snapshot_a.user_context.steady_time_point.clock_source_id) || - (snapshot_b.is_automatic_correction_enabled && - snapshot_a.is_automatic_correction_enabled)) { - time_span_type.nanoseconds = 0; - } - - IPC::ResponseBuilder rb{ctx, (sizeof(s64) / 4) + 2}; - rb.Push(ResultSuccess); - rb.PushRaw(time_span_type.nanoseconds); -} - -void Module::Interface::CalculateSpanBetween(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called"); - - Clock::ClockSnapshot snapshot_a; - Clock::ClockSnapshot snapshot_b; - - const auto snapshot_a_data = ctx.ReadBuffer(0); - const auto snapshot_b_data = ctx.ReadBuffer(1); - - std::memcpy(&snapshot_a, snapshot_a_data.data(), sizeof(Clock::ClockSnapshot)); - std::memcpy(&snapshot_b, snapshot_b_data.data(), sizeof(Clock::ClockSnapshot)); - - Clock::TimeSpanType time_span_type{}; - s64 span{}; - - if (const Result result{snapshot_a.steady_clock_time_point.GetSpanBetween( - snapshot_b.steady_clock_time_point, span)}; - result != ResultSuccess) { - if (snapshot_a.network_time && snapshot_b.network_time) { - time_span_type = - Clock::TimeSpanType::FromSeconds(snapshot_b.network_time - snapshot_a.network_time); - } else { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_TIME_NOT_FOUND); - return; - } - } else { - time_span_type = Clock::TimeSpanType::FromSeconds(span); - } - - IPC::ResponseBuilder rb{ctx, (sizeof(s64) / 4) + 2}; - rb.Push(ResultSuccess); - rb.PushRaw(time_span_type.nanoseconds); -} - -void Module::Interface::GetSharedMemoryNativeHandle(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called"); - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(&system.Kernel().GetTimeSharedMem()); -} - -Module::Interface::Interface(std::shared_ptr module_, Core::System& system_, - const char* name) - : ServiceFramework{system_, name}, module{std::move(module_)} {} - -Module::Interface::~Interface() = default; - void LoopProcess(Core::System& system) { auto server_manager = std::make_unique(system); - auto module{std::make_shared()}; server_manager->RegisterNamedService("time:a", - std::make_shared