summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Zach Hilman2019-07-03 20:22:23 -0400
committerGravatar GitHub2019-07-03 20:22:23 -0400
commite86af37ecbe3b8728a9c92a406bcce5ad419bc29 (patch)
tree776514641a5784ad1fdef1f2d0a06d22629bc622 /src
parentMerge pull request #2563 from ReinUsesLisp/shader-initializers (diff)
parentAddressed issues (diff)
downloadyuzu-e86af37ecbe3b8728a9c92a406bcce5ad419bc29.tar.gz
yuzu-e86af37ecbe3b8728a9c92a406bcce5ad419bc29.tar.xz
yuzu-e86af37ecbe3b8728a9c92a406bcce5ad419bc29.zip
Merge pull request #2608 from ogniK5377/Time_GetSharedMemoryNativeHandle
Implement Time::GetSharedMemoryNativeHandle
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/hle/service/service.cpp2
-rw-r--r--src/core/hle/service/time/interface.cpp11
-rw-r--r--src/core/hle/service/time/interface.h5
-rw-r--r--src/core/hle/service/time/time.cpp115
-rw-r--r--src/core/hle/service/time/time.h11
-rw-r--r--src/core/hle/service/time/time_sharedmemory.cpp68
-rw-r--r--src/core/hle/service/time/time_sharedmemory.h74
8 files changed, 260 insertions, 28 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index a35e6066a..686262702 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -430,6 +430,8 @@ add_library(core STATIC
430 hle/service/time/interface.h 430 hle/service/time/interface.h
431 hle/service/time/time.cpp 431 hle/service/time/time.cpp
432 hle/service/time/time.h 432 hle/service/time/time.h
433 hle/service/time/time_sharedmemory.cpp
434 hle/service/time/time_sharedmemory.h
433 hle/service/usb/usb.cpp 435 hle/service/usb/usb.cpp
434 hle/service/usb/usb.h 436 hle/service/usb/usb.h
435 hle/service/vi/display/vi_display.cpp 437 hle/service/vi/display/vi_display.cpp
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index ec9d755b7..5fc7d3cab 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -249,7 +249,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system,
249 Sockets::InstallInterfaces(*sm); 249 Sockets::InstallInterfaces(*sm);
250 SPL::InstallInterfaces(*sm); 250 SPL::InstallInterfaces(*sm);
251 SSL::InstallInterfaces(*sm); 251 SSL::InstallInterfaces(*sm);
252 Time::InstallInterfaces(*sm); 252 Time::InstallInterfaces(system);
253 USB::InstallInterfaces(*sm); 253 USB::InstallInterfaces(*sm);
254 VI::InstallInterfaces(*sm, nv_flinger); 254 VI::InstallInterfaces(*sm, nv_flinger);
255 WLAN::InstallInterfaces(*sm); 255 WLAN::InstallInterfaces(*sm);
diff --git a/src/core/hle/service/time/interface.cpp b/src/core/hle/service/time/interface.cpp
index 8d122ae33..1030185e0 100644
--- a/src/core/hle/service/time/interface.cpp
+++ b/src/core/hle/service/time/interface.cpp
@@ -6,8 +6,9 @@
6 6
7namespace Service::Time { 7namespace Service::Time {
8 8
9Time::Time(std::shared_ptr<Module> time, const char* name) 9Time::Time(std::shared_ptr<Module> time, std::shared_ptr<SharedMemory> shared_memory,
10 : Module::Interface(std::move(time), name) { 10 const char* name)
11 : Module::Interface(std::move(time), std::move(shared_memory), name) {
11 // clang-format off 12 // clang-format off
12 static const FunctionInfo functions[] = { 13 static const FunctionInfo functions[] = {
13 {0, &Time::GetStandardUserSystemClock, "GetStandardUserSystemClock"}, 14 {0, &Time::GetStandardUserSystemClock, "GetStandardUserSystemClock"},
@@ -16,12 +17,12 @@ Time::Time(std::shared_ptr<Module> time, const char* name)
16 {3, &Time::GetTimeZoneService, "GetTimeZoneService"}, 17 {3, &Time::GetTimeZoneService, "GetTimeZoneService"},
17 {4, &Time::GetStandardLocalSystemClock, "GetStandardLocalSystemClock"}, 18 {4, &Time::GetStandardLocalSystemClock, "GetStandardLocalSystemClock"},
18 {5, nullptr, "GetEphemeralNetworkSystemClock"}, 19 {5, nullptr, "GetEphemeralNetworkSystemClock"},
19 {20, nullptr, "GetSharedMemoryNativeHandle"}, 20 {20, &Time::GetSharedMemoryNativeHandle, "GetSharedMemoryNativeHandle"},
20 {30, nullptr, "GetStandardNetworkClockOperationEventReadableHandle"}, 21 {30, nullptr, "GetStandardNetworkClockOperationEventReadableHandle"},
21 {31, nullptr, "GetEphemeralNetworkClockOperationEventReadableHandle"}, 22 {31, nullptr, "GetEphemeralNetworkClockOperationEventReadableHandle"},
22 {50, nullptr, "SetStandardSteadyClockInternalOffset"}, 23 {50, nullptr, "SetStandardSteadyClockInternalOffset"},
23 {100, nullptr, "IsStandardUserSystemClockAutomaticCorrectionEnabled"}, 24 {100, &Time::IsStandardUserSystemClockAutomaticCorrectionEnabled, "IsStandardUserSystemClockAutomaticCorrectionEnabled"},
24 {101, nullptr, "SetStandardUserSystemClockAutomaticCorrectionEnabled"}, 25 {101, &Time::SetStandardUserSystemClockAutomaticCorrectionEnabled, "SetStandardUserSystemClockAutomaticCorrectionEnabled"},
25 {102, nullptr, "GetStandardUserSystemClockInitialYear"}, 26 {102, nullptr, "GetStandardUserSystemClockInitialYear"},
26 {200, nullptr, "IsStandardNetworkSystemClockAccuracySufficient"}, 27 {200, nullptr, "IsStandardNetworkSystemClockAccuracySufficient"},
27 {201, nullptr, "GetStandardUserSystemClockAutomaticCorrectionUpdatedTime"}, 28 {201, nullptr, "GetStandardUserSystemClockAutomaticCorrectionUpdatedTime"},
diff --git a/src/core/hle/service/time/interface.h b/src/core/hle/service/time/interface.h
index cd6b44dec..bdf0883e2 100644
--- a/src/core/hle/service/time/interface.h
+++ b/src/core/hle/service/time/interface.h
@@ -8,9 +8,12 @@
8 8
9namespace Service::Time { 9namespace Service::Time {
10 10
11class SharedMemory;
12
11class Time final : public Module::Interface { 13class Time final : public Module::Interface {
12public: 14public:
13 explicit Time(std::shared_ptr<Module> time, const char* name); 15 explicit Time(std::shared_ptr<Module> time, std::shared_ptr<SharedMemory> shared_memory,
16 const char* name);
14 ~Time() override; 17 ~Time() override;
15}; 18};
16 19
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp
index 346bad80d..ae6446204 100644
--- a/src/core/hle/service/time/time.cpp
+++ b/src/core/hle/service/time/time.cpp
@@ -13,6 +13,7 @@
13#include "core/hle/kernel/client_session.h" 13#include "core/hle/kernel/client_session.h"
14#include "core/hle/service/time/interface.h" 14#include "core/hle/service/time/interface.h"
15#include "core/hle/service/time/time.h" 15#include "core/hle/service/time/time.h"
16#include "core/hle/service/time/time_sharedmemory.h"
16#include "core/settings.h" 17#include "core/settings.h"
17 18
18namespace Service::Time { 19namespace Service::Time {
@@ -61,9 +62,18 @@ static u64 CalendarToPosix(const CalendarTime& calendar_time,
61 return static_cast<u64>(epoch_time); 62 return static_cast<u64>(epoch_time);
62} 63}
63 64
65enum class ClockContextType {
66 StandardSteady,
67 StandardUserSystem,
68 StandardNetworkSystem,
69 StandardLocalSystem,
70};
71
64class ISystemClock final : public ServiceFramework<ISystemClock> { 72class ISystemClock final : public ServiceFramework<ISystemClock> {
65public: 73public:
66 ISystemClock() : ServiceFramework("ISystemClock") { 74 ISystemClock(std::shared_ptr<Service::Time::SharedMemory> shared_memory,
75 ClockContextType clock_type)
76 : ServiceFramework("ISystemClock"), shared_memory(shared_memory), clock_type(clock_type) {
67 static const FunctionInfo functions[] = { 77 static const FunctionInfo functions[] = {
68 {0, &ISystemClock::GetCurrentTime, "GetCurrentTime"}, 78 {0, &ISystemClock::GetCurrentTime, "GetCurrentTime"},
69 {1, nullptr, "SetCurrentTime"}, 79 {1, nullptr, "SetCurrentTime"},
@@ -72,6 +82,8 @@ public:
72 82
73 }; 83 };
74 RegisterHandlers(functions); 84 RegisterHandlers(functions);
85
86 UpdateSharedMemoryContext(system_clock_context);
75 } 87 }
76 88
77private: 89private:
@@ -87,34 +99,63 @@ private:
87 void GetSystemClockContext(Kernel::HLERequestContext& ctx) { 99 void GetSystemClockContext(Kernel::HLERequestContext& ctx) {
88 LOG_WARNING(Service_Time, "(STUBBED) called"); 100 LOG_WARNING(Service_Time, "(STUBBED) called");
89 101
90 SystemClockContext system_clock_ontext{}; 102 // TODO(ogniK): This should be updated periodically however since we have it stubbed we'll
103 // only update when we get a new context
104 UpdateSharedMemoryContext(system_clock_context);
105
91 IPC::ResponseBuilder rb{ctx, (sizeof(SystemClockContext) / 4) + 2}; 106 IPC::ResponseBuilder rb{ctx, (sizeof(SystemClockContext) / 4) + 2};
92 rb.Push(RESULT_SUCCESS); 107 rb.Push(RESULT_SUCCESS);
93 rb.PushRaw(system_clock_ontext); 108 rb.PushRaw(system_clock_context);
94 } 109 }
110
111 void UpdateSharedMemoryContext(const SystemClockContext& clock_context) {
112 switch (clock_type) {
113 case ClockContextType::StandardLocalSystem:
114 shared_memory->SetStandardLocalSystemClockContext(clock_context);
115 break;
116 case ClockContextType::StandardNetworkSystem:
117 shared_memory->SetStandardNetworkSystemClockContext(clock_context);
118 break;
119 }
120 }
121
122 SystemClockContext system_clock_context{};
123 std::shared_ptr<Service::Time::SharedMemory> shared_memory;
124 ClockContextType clock_type;
95}; 125};
96 126
97class ISteadyClock final : public ServiceFramework<ISteadyClock> { 127class ISteadyClock final : public ServiceFramework<ISteadyClock> {
98public: 128public:
99 ISteadyClock() : ServiceFramework("ISteadyClock") { 129 ISteadyClock(std::shared_ptr<SharedMemory> shared_memory)
130 : ServiceFramework("ISteadyClock"), shared_memory(shared_memory) {
100 static const FunctionInfo functions[] = { 131 static const FunctionInfo functions[] = {
101 {0, &ISteadyClock::GetCurrentTimePoint, "GetCurrentTimePoint"}, 132 {0, &ISteadyClock::GetCurrentTimePoint, "GetCurrentTimePoint"},
102 }; 133 };
103 RegisterHandlers(functions); 134 RegisterHandlers(functions);
135
136 shared_memory->SetStandardSteadyClockTimepoint(GetCurrentTimePoint());
104 } 137 }
105 138
106private: 139private:
107 void GetCurrentTimePoint(Kernel::HLERequestContext& ctx) { 140 void GetCurrentTimePoint(Kernel::HLERequestContext& ctx) {
108 LOG_DEBUG(Service_Time, "called"); 141 LOG_DEBUG(Service_Time, "called");
109 142
110 const auto& core_timing = Core::System::GetInstance().CoreTiming(); 143 const auto time_point = GetCurrentTimePoint();
111 const auto ms = Core::Timing::CyclesToMs(core_timing.GetTicks()); 144 // TODO(ogniK): This should be updated periodically
112 const SteadyClockTimePoint steady_clock_time_point{static_cast<u64_le>(ms.count() / 1000), 145 shared_memory->SetStandardSteadyClockTimepoint(time_point);
113 {}}; 146
114 IPC::ResponseBuilder rb{ctx, (sizeof(SteadyClockTimePoint) / 4) + 2}; 147 IPC::ResponseBuilder rb{ctx, (sizeof(SteadyClockTimePoint) / 4) + 2};
115 rb.Push(RESULT_SUCCESS); 148 rb.Push(RESULT_SUCCESS);
116 rb.PushRaw(steady_clock_time_point); 149 rb.PushRaw(time_point);
117 } 150 }
151
152 SteadyClockTimePoint GetCurrentTimePoint() const {
153 const auto& core_timing = Core::System::GetInstance().CoreTiming();
154 const auto ms = Core::Timing::CyclesToMs(core_timing.GetTicks());
155 return {static_cast<u64_le>(ms.count() / 1000), {}};
156 }
157
158 std::shared_ptr<SharedMemory> shared_memory;
118}; 159};
119 160
120class ITimeZoneService final : public ServiceFramework<ITimeZoneService> { 161class ITimeZoneService final : public ServiceFramework<ITimeZoneService> {
@@ -233,7 +274,7 @@ void Module::Interface::GetStandardUserSystemClock(Kernel::HLERequestContext& ct
233 274
234 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 275 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
235 rb.Push(RESULT_SUCCESS); 276 rb.Push(RESULT_SUCCESS);
236 rb.PushIpcInterface<ISystemClock>(); 277 rb.PushIpcInterface<ISystemClock>(shared_memory, ClockContextType::StandardUserSystem);
237} 278}
238 279
239void Module::Interface::GetStandardNetworkSystemClock(Kernel::HLERequestContext& ctx) { 280void Module::Interface::GetStandardNetworkSystemClock(Kernel::HLERequestContext& ctx) {
@@ -241,7 +282,7 @@ void Module::Interface::GetStandardNetworkSystemClock(Kernel::HLERequestContext&
241 282
242 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 283 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
243 rb.Push(RESULT_SUCCESS); 284 rb.Push(RESULT_SUCCESS);
244 rb.PushIpcInterface<ISystemClock>(); 285 rb.PushIpcInterface<ISystemClock>(shared_memory, ClockContextType::StandardNetworkSystem);
245} 286}
246 287
247void Module::Interface::GetStandardSteadyClock(Kernel::HLERequestContext& ctx) { 288void Module::Interface::GetStandardSteadyClock(Kernel::HLERequestContext& ctx) {
@@ -249,7 +290,7 @@ void Module::Interface::GetStandardSteadyClock(Kernel::HLERequestContext& ctx) {
249 290
250 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 291 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
251 rb.Push(RESULT_SUCCESS); 292 rb.Push(RESULT_SUCCESS);
252 rb.PushIpcInterface<ISteadyClock>(); 293 rb.PushIpcInterface<ISteadyClock>(shared_memory);
253} 294}
254 295
255void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) { 296void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) {
@@ -265,7 +306,7 @@ void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& c
265 306
266 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 307 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
267 rb.Push(RESULT_SUCCESS); 308 rb.Push(RESULT_SUCCESS);
268 rb.PushIpcInterface<ISystemClock>(); 309 rb.PushIpcInterface<ISystemClock>(shared_memory, ClockContextType::StandardLocalSystem);
269} 310}
270 311
271void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) { 312void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) {
@@ -333,16 +374,52 @@ void Module::Interface::CalculateStandardUserSystemClockDifferenceByUser(
333 rb.PushRaw<u64>(difference); 374 rb.PushRaw<u64>(difference);
334} 375}
335 376
336Module::Interface::Interface(std::shared_ptr<Module> time, const char* name) 377void Module::Interface::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) {
337 : ServiceFramework(name), time(std::move(time)) {} 378 LOG_DEBUG(Service_Time, "called");
379 IPC::ResponseBuilder rb{ctx, 2, 1};
380 rb.Push(RESULT_SUCCESS);
381 rb.PushCopyObjects(shared_memory->GetSharedMemoryHolder());
382}
383
384void Module::Interface::IsStandardUserSystemClockAutomaticCorrectionEnabled(
385 Kernel::HLERequestContext& ctx) {
386 // ogniK(TODO): When clock contexts are implemented, the value should be read from the context
387 // instead of our shared memory holder
388 LOG_DEBUG(Service_Time, "called");
389
390 IPC::ResponseBuilder rb{ctx, 3};
391 rb.Push(RESULT_SUCCESS);
392 rb.Push<u8>(shared_memory->GetStandardUserSystemClockAutomaticCorrectionEnabled());
393}
394
395void Module::Interface::SetStandardUserSystemClockAutomaticCorrectionEnabled(
396 Kernel::HLERequestContext& ctx) {
397 IPC::RequestParser rp{ctx};
398 const auto enabled = rp.Pop<u8>();
399
400 LOG_WARNING(Service_Time, "(PARTIAL IMPLEMENTATION) called");
401
402 // TODO(ogniK): Update clock contexts and correct timespans
403
404 shared_memory->SetStandardUserSystemClockAutomaticCorrectionEnabled(enabled > 0);
405 IPC::ResponseBuilder rb{ctx, 2};
406 rb.Push(RESULT_SUCCESS);
407}
408
409Module::Interface::Interface(std::shared_ptr<Module> time,
410 std::shared_ptr<SharedMemory> shared_memory, const char* name)
411 : ServiceFramework(name), time(std::move(time)), shared_memory(std::move(shared_memory)) {}
338 412
339Module::Interface::~Interface() = default; 413Module::Interface::~Interface() = default;
340 414
341void InstallInterfaces(SM::ServiceManager& service_manager) { 415void InstallInterfaces(Core::System& system) {
342 auto time = std::make_shared<Module>(); 416 auto time = std::make_shared<Module>();
343 std::make_shared<Time>(time, "time:a")->InstallAsService(service_manager); 417 auto shared_mem = std::make_shared<SharedMemory>(system);
344 std::make_shared<Time>(time, "time:s")->InstallAsService(service_manager); 418
345 std::make_shared<Time>(time, "time:u")->InstallAsService(service_manager); 419 std::make_shared<Time>(time, shared_mem, "time:a")->InstallAsService(system.ServiceManager());
420 std::make_shared<Time>(time, shared_mem, "time:s")->InstallAsService(system.ServiceManager());
421 std::make_shared<Time>(std::move(time), shared_mem, "time:u")
422 ->InstallAsService(system.ServiceManager());
346} 423}
347 424
348} // namespace Service::Time 425} // namespace Service::Time
diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h
index f11affe95..e0708f856 100644
--- a/src/core/hle/service/time/time.h
+++ b/src/core/hle/service/time/time.h
@@ -10,6 +10,8 @@
10 10
11namespace Service::Time { 11namespace Service::Time {
12 12
13class SharedMemory;
14
13struct LocationName { 15struct LocationName {
14 std::array<u8, 0x24> name; 16 std::array<u8, 0x24> name;
15}; 17};
@@ -77,7 +79,8 @@ class Module final {
77public: 79public:
78 class Interface : public ServiceFramework<Interface> { 80 class Interface : public ServiceFramework<Interface> {
79 public: 81 public:
80 explicit Interface(std::shared_ptr<Module> time, const char* name); 82 explicit Interface(std::shared_ptr<Module> time,
83 std::shared_ptr<SharedMemory> shared_memory, const char* name);
81 ~Interface() override; 84 ~Interface() override;
82 85
83 void GetStandardUserSystemClock(Kernel::HLERequestContext& ctx); 86 void GetStandardUserSystemClock(Kernel::HLERequestContext& ctx);
@@ -87,13 +90,17 @@ public:
87 void GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx); 90 void GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx);
88 void GetClockSnapshot(Kernel::HLERequestContext& ctx); 91 void GetClockSnapshot(Kernel::HLERequestContext& ctx);
89 void CalculateStandardUserSystemClockDifferenceByUser(Kernel::HLERequestContext& ctx); 92 void CalculateStandardUserSystemClockDifferenceByUser(Kernel::HLERequestContext& ctx);
93 void GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx);
94 void IsStandardUserSystemClockAutomaticCorrectionEnabled(Kernel::HLERequestContext& ctx);
95 void SetStandardUserSystemClockAutomaticCorrectionEnabled(Kernel::HLERequestContext& ctx);
90 96
91 protected: 97 protected:
92 std::shared_ptr<Module> time; 98 std::shared_ptr<Module> time;
99 std::shared_ptr<SharedMemory> shared_memory;
93 }; 100 };
94}; 101};
95 102
96/// Registers all Time services with the specified service manager. 103/// Registers all Time services with the specified service manager.
97void InstallInterfaces(SM::ServiceManager& service_manager); 104void InstallInterfaces(Core::System& system);
98 105
99} // namespace Service::Time 106} // namespace Service::Time
diff --git a/src/core/hle/service/time/time_sharedmemory.cpp b/src/core/hle/service/time/time_sharedmemory.cpp
new file mode 100644
index 000000000..bfc81b83c
--- /dev/null
+++ b/src/core/hle/service/time/time_sharedmemory.cpp
@@ -0,0 +1,68 @@
1// Copyright 2019 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/core.h"
6#include "core/hle/service/time/time_sharedmemory.h"
7
8namespace Service::Time {
9const std::size_t SHARED_MEMORY_SIZE = 0x1000;
10
11SharedMemory::SharedMemory(Core::System& system) : system(system) {
12 shared_memory_holder = Kernel::SharedMemory::Create(
13 system.Kernel(), nullptr, SHARED_MEMORY_SIZE, Kernel::MemoryPermission::ReadWrite,
14 Kernel::MemoryPermission::Read, 0, Kernel::MemoryRegion::BASE, "Time:SharedMemory");
15
16 // Seems static from 1.0.0 -> 8.1.0. Specific games seem to check this value and crash
17 // if it's set to anything else
18 shared_memory_format.format_version = 14;
19 std::memcpy(shared_memory_holder->GetPointer(), &shared_memory_format, sizeof(Format));
20}
21
22SharedMemory::~SharedMemory() = default;
23
24Kernel::SharedPtr<Kernel::SharedMemory> SharedMemory::GetSharedMemoryHolder() const {
25 return shared_memory_holder;
26}
27
28void SharedMemory::SetStandardSteadyClockTimepoint(const SteadyClockTimePoint& timepoint) {
29 shared_memory_format.standard_steady_clock_timepoint.StoreData(
30 shared_memory_holder->GetPointer(), timepoint);
31}
32
33void SharedMemory::SetStandardLocalSystemClockContext(const SystemClockContext& context) {
34 shared_memory_format.standard_local_system_clock_context.StoreData(
35 shared_memory_holder->GetPointer(), context);
36}
37
38void SharedMemory::SetStandardNetworkSystemClockContext(const SystemClockContext& context) {
39 shared_memory_format.standard_network_system_clock_context.StoreData(
40 shared_memory_holder->GetPointer(), context);
41}
42
43void SharedMemory::SetStandardUserSystemClockAutomaticCorrectionEnabled(bool enabled) {
44 shared_memory_format.standard_user_system_clock_automatic_correction.StoreData(
45 shared_memory_holder->GetPointer(), enabled);
46}
47
48SteadyClockTimePoint SharedMemory::GetStandardSteadyClockTimepoint() {
49 return shared_memory_format.standard_steady_clock_timepoint.ReadData(
50 shared_memory_holder->GetPointer());
51}
52
53SystemClockContext SharedMemory::GetStandardLocalSystemClockContext() {
54 return shared_memory_format.standard_local_system_clock_context.ReadData(
55 shared_memory_holder->GetPointer());
56}
57
58SystemClockContext SharedMemory::GetStandardNetworkSystemClockContext() {
59 return shared_memory_format.standard_network_system_clock_context.ReadData(
60 shared_memory_holder->GetPointer());
61}
62
63bool SharedMemory::GetStandardUserSystemClockAutomaticCorrectionEnabled() {
64 return shared_memory_format.standard_user_system_clock_automatic_correction.ReadData(
65 shared_memory_holder->GetPointer());
66}
67
68} // namespace Service::Time
diff --git a/src/core/hle/service/time/time_sharedmemory.h b/src/core/hle/service/time/time_sharedmemory.h
new file mode 100644
index 000000000..cb8253541
--- /dev/null
+++ b/src/core/hle/service/time/time_sharedmemory.h
@@ -0,0 +1,74 @@
1// Copyright 2019 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_types.h"
8#include "core/hle/kernel/shared_memory.h"
9#include "core/hle/service/time/time.h"
10
11namespace Service::Time {
12class SharedMemory {
13public:
14 explicit SharedMemory(Core::System& system);
15 ~SharedMemory();
16
17 // Return the shared memory handle
18 Kernel::SharedPtr<Kernel::SharedMemory> GetSharedMemoryHolder() const;
19
20 // Set memory barriers in shared memory and update them
21 void SetStandardSteadyClockTimepoint(const SteadyClockTimePoint& timepoint);
22 void SetStandardLocalSystemClockContext(const SystemClockContext& context);
23 void SetStandardNetworkSystemClockContext(const SystemClockContext& context);
24 void SetStandardUserSystemClockAutomaticCorrectionEnabled(bool enabled);
25
26 // Pull from memory barriers in the shared memory
27 SteadyClockTimePoint GetStandardSteadyClockTimepoint();
28 SystemClockContext GetStandardLocalSystemClockContext();
29 SystemClockContext GetStandardNetworkSystemClockContext();
30 bool GetStandardUserSystemClockAutomaticCorrectionEnabled();
31
32 // TODO(ogniK): We have to properly simulate memory barriers, how are we going to do this?
33 template <typename T, std::size_t Offset>
34 struct MemoryBarrier {
35 static_assert(std::is_trivially_constructible_v<T>, "T must be trivially constructable");
36 u32_le read_attempt{};
37 std::array<T, 2> data{};
38
39 // These are not actually memory barriers at the moment as we don't have multicore and all
40 // HLE is mutexed. This will need to properly be implemented when we start updating the time
41 // points on threads. As of right now, we'll be updated both values synchronously and just
42 // incrementing the read_attempt to indicate that we waited.
43 void StoreData(u8* shared_memory, T data_to_store) {
44 std::memcpy(this, shared_memory + Offset, sizeof(*this));
45 read_attempt++;
46 data[read_attempt & 1] = data_to_store;
47 std::memcpy(shared_memory + Offset, this, sizeof(*this));
48 }
49
50 // For reading we're just going to read the last stored value. If there was no value stored
51 // it will just end up reading an empty value as intended.
52 T ReadData(u8* shared_memory) {
53 std::memcpy(this, shared_memory + Offset, sizeof(*this));
54 return data[(read_attempt - 1) & 1];
55 }
56 };
57
58 // Shared memory format
59 struct Format {
60 MemoryBarrier<SteadyClockTimePoint, 0x0> standard_steady_clock_timepoint;
61 MemoryBarrier<SystemClockContext, 0x38> standard_local_system_clock_context;
62 MemoryBarrier<SystemClockContext, 0x80> standard_network_system_clock_context;
63 MemoryBarrier<bool, 0xc8> standard_user_system_clock_automatic_correction;
64 u32_le format_version;
65 };
66 static_assert(sizeof(Format) == 0xd8, "Format is an invalid size");
67
68private:
69 Kernel::SharedPtr<Kernel::SharedMemory> shared_memory_holder{};
70 Core::System& system;
71 Format shared_memory_format{};
72};
73
74} // namespace Service::Time