diff options
Diffstat (limited to 'src/core/hle/service/time/time.cpp')
-rw-r--r-- | src/core/hle/service/time/time.cpp | 105 |
1 files changed, 68 insertions, 37 deletions
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index ce859f18d..7d0474e0b 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp @@ -10,6 +10,7 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" +#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/scheduler.h" #include "core/hle/service/time/interface.h" #include "core/hle/service/time/time.h" @@ -20,8 +21,8 @@ namespace Service::Time { class ISystemClock final : public ServiceFramework<ISystemClock> { public: - ISystemClock(Clock::SystemClockCore& clock_core) - : ServiceFramework("ISystemClock"), clock_core{clock_core} { + explicit ISystemClock(Clock::SystemClockCore& clock_core, Core::System& system) + : ServiceFramework("ISystemClock"), clock_core{clock_core}, system{system} { // clang-format off static const FunctionInfo functions[] = { {0, &ISystemClock::GetCurrentTime, "GetCurrentTime"}, @@ -46,9 +47,8 @@ private: } s64 posix_time{}; - if (const ResultCode result{ - clock_core.GetCurrentTime(Core::System::GetInstance(), posix_time)}; - result != RESULT_SUCCESS) { + if (const ResultCode result{clock_core.GetCurrentTime(system, posix_time)}; + result.IsError()) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); return; @@ -69,9 +69,8 @@ private: } Clock::SystemClockContext system_clock_context{}; - if (const ResultCode result{ - clock_core.GetClockContext(Core::System::GetInstance(), system_clock_context)}; - result != RESULT_SUCCESS) { + if (const ResultCode result{clock_core.GetClockContext(system, system_clock_context)}; + result.IsError()) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); return; @@ -83,14 +82,22 @@ private: } Clock::SystemClockCore& clock_core; + Core::System& system; }; class ISteadyClock final : public ServiceFramework<ISteadyClock> { public: - ISteadyClock(Clock::SteadyClockCore& clock_core) - : ServiceFramework("ISteadyClock"), clock_core{clock_core} { + explicit ISteadyClock(Clock::SteadyClockCore& clock_core, Core::System& system) + : ServiceFramework("ISteadyClock"), clock_core{clock_core}, system{system} { 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); } @@ -105,21 +112,21 @@ private: return; } - const Clock::SteadyClockTimePoint time_point{ - clock_core.GetCurrentTimePoint(Core::System::GetInstance())}; + const Clock::SteadyClockTimePoint time_point{clock_core.GetCurrentTimePoint(system)}; IPC::ResponseBuilder rb{ctx, (sizeof(Clock::SteadyClockTimePoint) / 4) + 2}; rb.Push(RESULT_SUCCESS); rb.PushRaw(time_point); } Clock::SteadyClockCore& clock_core; + Core::System& system; }; ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal( Kernel::Thread* thread, Clock::SystemClockContext user_context, Clock::SystemClockContext network_context, u8 type, Clock::ClockSnapshot& clock_snapshot) { - auto& time_manager{module->GetTimeManager()}; + auto& time_manager{system.GetTimeManager()}; clock_snapshot.is_automatic_correction_enabled = time_manager.GetStandardUserSystemClockCore().IsAutomaticCorrectionEnabled(); @@ -134,7 +141,7 @@ ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal( } const auto current_time_point{ - time_manager.GetStandardSteadyClockCore().GetCurrentTimePoint(Core::System::GetInstance())}; + time_manager.GetStandardSteadyClockCore().GetCurrentTimePoint(system)}; if (const ResultCode result{Clock::ClockSnapshot::GetCurrentTime( clock_snapshot.user_time, current_time_point, clock_snapshot.user_context)}; result != RESULT_SUCCESS) { @@ -176,41 +183,44 @@ void Module::Interface::GetStandardUserSystemClock(Kernel::HLERequestContext& ct LOG_DEBUG(Service_Time, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<ISystemClock>(module->GetTimeManager().GetStandardUserSystemClockCore()); + rb.PushIpcInterface<ISystemClock>(system.GetTimeManager().GetStandardUserSystemClockCore(), + system); } void Module::Interface::GetStandardNetworkSystemClock(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_Time, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<ISystemClock>(module->GetTimeManager().GetStandardNetworkSystemClockCore()); + rb.PushIpcInterface<ISystemClock>(system.GetTimeManager().GetStandardNetworkSystemClockCore(), + system); } void Module::Interface::GetStandardSteadyClock(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_Time, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<ISteadyClock>(module->GetTimeManager().GetStandardSteadyClockCore()); + rb.PushIpcInterface<ISteadyClock>(system.GetTimeManager().GetStandardSteadyClockCore(), system); } void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_Time, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<ITimeZoneService>(module->GetTimeManager().GetTimeZoneContentManager()); + rb.PushIpcInterface<ITimeZoneService>(system.GetTimeManager().GetTimeZoneContentManager()); } void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_Time, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<ISystemClock>(module->GetTimeManager().GetStandardLocalSystemClockCore()); + rb.PushIpcInterface<ISystemClock>(system.GetTimeManager().GetStandardLocalSystemClockCore(), + system); } void Module::Interface::IsStandardNetworkSystemClockAccuracySufficient( Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_Time, "called"); - auto& clock_core{module->GetTimeManager().GetStandardNetworkSystemClockCore()}; + auto& clock_core{system.GetTimeManager().GetStandardNetworkSystemClockCore()}; IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push<u32>(clock_core.IsStandardNetworkSystemClockAccuracySufficient(system)); @@ -219,7 +229,7 @@ void Module::Interface::IsStandardNetworkSystemClockAccuracySufficient( void Module::Interface::CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_Time, "called"); - auto& steady_clock_core{module->GetTimeManager().GetStandardSteadyClockCore()}; + auto& steady_clock_core{system.GetTimeManager().GetStandardSteadyClockCore()}; if (!steady_clock_core.IsInitialized()) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ERROR_UNINITIALIZED_CLOCK); @@ -228,13 +238,11 @@ void Module::Interface::CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERe IPC::RequestParser rp{ctx}; const auto context{rp.PopRaw<Clock::SystemClockContext>()}; - const auto current_time_point{ - steady_clock_core.GetCurrentTimePoint(Core::System::GetInstance())}; + 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( - Core::Timing::CpuCyclesToClockCycles(system.CoreTiming().GetTicks()), - Core::Hardware::CNTFREQ)}; + const auto ticks{Clock::TimeSpanType::FromTicks(system.CoreTiming().GetClockTicks(), + Core::Hardware::CNTFREQ)}; const s64 base_time_point{context.offset + current_time_point.time_point - ticks.ToSeconds()}; IPC::ResponseBuilder rb{ctx, (sizeof(s64) / 4) + 2}; @@ -254,18 +262,18 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) { Clock::SystemClockContext user_context{}; if (const ResultCode result{ - module->GetTimeManager().GetStandardUserSystemClockCore().GetClockContext( - Core::System::GetInstance(), user_context)}; - result != RESULT_SUCCESS) { + system.GetTimeManager().GetStandardUserSystemClockCore().GetClockContext(system, + user_context)}; + result.IsError()) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); return; } Clock::SystemClockContext network_context{}; if (const ResultCode result{ - module->GetTimeManager().GetStandardNetworkSystemClockCore().GetClockContext( - Core::System::GetInstance(), network_context)}; - result != RESULT_SUCCESS) { + system.GetTimeManager().GetStandardNetworkSystemClockCore().GetClockContext( + system, network_context)}; + result.IsError()) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); return; @@ -274,7 +282,7 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) { Clock::ClockSnapshot clock_snapshot{}; if (const ResultCode result{GetClockSnapshotFromSystemClockContextInternal( &ctx.GetThread(), user_context, network_context, type, clock_snapshot)}; - result != RESULT_SUCCESS) { + result.IsError()) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); return; @@ -282,7 +290,7 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - ctx.WriteBuffer(&clock_snapshot, sizeof(Clock::ClockSnapshot)); + ctx.WriteBuffer(clock_snapshot); } void Module::Interface::GetClockSnapshotFromSystemClockContext(Kernel::HLERequestContext& ctx) { @@ -305,7 +313,30 @@ void Module::Interface::GetClockSnapshotFromSystemClockContext(Kernel::HLEReques IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - ctx.WriteBuffer(&clock_snapshot, sizeof(Clock::ClockSnapshot)); + ctx.WriteBuffer(clock_snapshot); +} + +void Module::Interface::CalculateStandardUserSystemClockDifferenceByUser( + Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_Time, "called"); + + IPC::RequestParser rp{ctx}; + const auto snapshot_a = rp.PopRaw<Clock::ClockSnapshot>(); + const auto snapshot_b = rp.PopRaw<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(RESULT_SUCCESS); + rb.PushRaw(time_span_type.nanoseconds); } void Module::Interface::CalculateSpanBetween(Kernel::HLERequestContext& ctx) { @@ -341,7 +372,7 @@ void Module::Interface::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& c LOG_DEBUG(Service_Time, "called"); IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(module->GetTimeManager().GetSharedMemory().GetSharedMemoryHolder()); + rb.PushCopyObjects(SharedFrom(&system.Kernel().GetTimeSharedMem())); } Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& system, const char* name) @@ -350,7 +381,7 @@ Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& syste Module::Interface::~Interface() = default; void InstallInterfaces(Core::System& system) { - auto module{std::make_shared<Module>(system)}; + auto module{std::make_shared<Module>()}; std::make_shared<Time>(module, system, "time:a")->InstallAsService(system.ServiceManager()); std::make_shared<Time>(module, system, "time:s")->InstallAsService(system.ServiceManager()); std::make_shared<Time>(module, system, "time:u")->InstallAsService(system.ServiceManager()); |