summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar David Marcec2019-06-26 00:45:53 +1000
committerGravatar David Marcec2019-06-26 00:45:53 +1000
commit19dc36ce066aac58e0ba2aeb315bb709b84a137e (patch)
treec62fe49970c42dfe6d5841f9f6fd051451ab69de /src
parentMerge pull request #2603 from WamWooWam/master (diff)
downloadyuzu-19dc36ce066aac58e0ba2aeb315bb709b84a137e.tar.gz
yuzu-19dc36ce066aac58e0ba2aeb315bb709b84a137e.tar.xz
yuzu-19dc36ce066aac58e0ba2aeb315bb709b84a137e.zip
Implement Time::GetSharedMemoryNativeHandle
This PR attempts to implement the shared memory provided by GetSharedMemoryNativeHandle. There is still more work to be done however that requires a rehaul of the current time module to handle clock contexts. This PR is mainly to get the basic functionality of the SharedMemory working and allow the use of addition to it whilst things get improved on. Things to note: Memory Barriers are used in the SharedMemory and a better solution would need to be done to implement this. Currently in this PR I’m faking the memory barriers as everything is sync and single threaded. They work by incrementing the counter and just populate the two data slots. On data reading, it will read the last added data. Specific values in the shared memory would need to be updated periodically. This isn't included in this PR since we don't actively do this yet. In a later PR when time is refactored this should be done. Finally, as we don't handle clock contexts. When time is refactored, we will need to update the shared memory for specific contexts. This PR does this already however since the contexts are all identical and not separated. We're just updating the same values for each context which in this case is empty. Tiime:SetStandardUserSystemClockAutomaticCorrectionEnabled, Time:IsStandardUserSystemClockAutomaticCorrectionEnabled are also partially implemented in this PR. The reason the implementation is partial is because once again, a lack of clock contexts. This will be improved on in a future PR. This PR closes issue #2556
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.cpp114
-rw-r--r--src/core/hle/service/time/time.h10
-rw-r--r--src/core/hle/service/time/time_sharedmemory.cpp59
-rw-r--r--src/core/hle/service/time/time_sharedmemory.h71
8 files changed, 245 insertions, 29 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index cdb3bf6ab..5430b7169 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -422,6 +422,8 @@ add_library(core STATIC
422 hle/service/time/interface.h 422 hle/service/time/interface.h
423 hle/service/time/time.cpp 423 hle/service/time/time.cpp
424 hle/service/time/time.h 424 hle/service/time/time.h
425 hle/service/time/time_sharedmemory.cpp
426 hle/service/time/time_sharedmemory.h
425 hle/service/usb/usb.cpp 427 hle/service/usb/usb.cpp
426 hle/service/usb/usb.h 428 hle/service/usb/usb.h
427 hle/service/vi/display/vi_display.cpp 429 hle/service/vi/display/vi_display.cpp
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index b2954eb34..545abe9ac 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..407acf960 100644
--- a/src/core/hle/service/time/interface.h
+++ b/src/core/hle/service/time/interface.h
@@ -7,10 +7,11 @@
7#include "core/hle/service/time/time.h" 7#include "core/hle/service/time/time.h"
8 8
9namespace Service::Time { 9namespace Service::Time {
10 10class SharedMemory;
11class Time final : public Module::Interface { 11class Time final : public Module::Interface {
12public: 12public:
13 explicit Time(std::shared_ptr<Module> time, const char* name); 13 explicit Time(std::shared_ptr<Module> time, std::shared_ptr<SharedMemory> shared_memory,
14 const char* name);
14 ~Time() override; 15 ~Time() override;
15}; 16};
16 17
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp
index 346bad80d..10a7e6c97 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,51 @@ 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>(time, shared_mem, "time:u")->InstallAsService(system.ServiceManager());
346} 422}
347 423
348} // namespace Service::Time 424} // namespace Service::Time
diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h
index f11affe95..6a05a22b9 100644
--- a/src/core/hle/service/time/time.h
+++ b/src/core/hle/service/time/time.h
@@ -9,6 +9,7 @@
9#include "core/hle/service/service.h" 9#include "core/hle/service/service.h"
10 10
11namespace Service::Time { 11namespace Service::Time {
12class SharedMemory;
12 13
13struct LocationName { 14struct LocationName {
14 std::array<u8, 0x24> name; 15 std::array<u8, 0x24> name;
@@ -77,7 +78,8 @@ class Module final {
77public: 78public:
78 class Interface : public ServiceFramework<Interface> { 79 class Interface : public ServiceFramework<Interface> {
79 public: 80 public:
80 explicit Interface(std::shared_ptr<Module> time, const char* name); 81 explicit Interface(std::shared_ptr<Module> time,
82 std::shared_ptr<SharedMemory> shared_memory, const char* name);
81 ~Interface() override; 83 ~Interface() override;
82 84
83 void GetStandardUserSystemClock(Kernel::HLERequestContext& ctx); 85 void GetStandardUserSystemClock(Kernel::HLERequestContext& ctx);
@@ -87,13 +89,17 @@ public:
87 void GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx); 89 void GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx);
88 void GetClockSnapshot(Kernel::HLERequestContext& ctx); 90 void GetClockSnapshot(Kernel::HLERequestContext& ctx);
89 void CalculateStandardUserSystemClockDifferenceByUser(Kernel::HLERequestContext& ctx); 91 void CalculateStandardUserSystemClockDifferenceByUser(Kernel::HLERequestContext& ctx);
92 void GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx);
93 void IsStandardUserSystemClockAutomaticCorrectionEnabled(Kernel::HLERequestContext& ctx);
94 void SetStandardUserSystemClockAutomaticCorrectionEnabled(Kernel::HLERequestContext& ctx);
90 95
91 protected: 96 protected:
92 std::shared_ptr<Module> time; 97 std::shared_ptr<Module> time;
98 std::shared_ptr<SharedMemory> shared_memory;
93 }; 99 };
94}; 100};
95 101
96/// Registers all Time services with the specified service manager. 102/// Registers all Time services with the specified service manager.
97void InstallInterfaces(SM::ServiceManager& service_manager); 103void InstallInterfaces(Core::System& system);
98 104
99} // namespace Service::Time 105} // 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..650c9af7a
--- /dev/null
+++ b/src/core/hle/service/time/time_sharedmemory.cpp
@@ -0,0 +1,59 @@
1// Copyright 2018 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 {
9
10SharedMemory::SharedMemory(Core::System& system) : system(system) {
11 shared_memory_holder = Kernel::SharedMemory::Create(
12 system.Kernel(), nullptr, SHARED_MEMORY_SIZE, Kernel::MemoryPermission::ReadWrite,
13 Kernel::MemoryPermission::Read, 0, Kernel::MemoryRegion::BASE, "Time:SharedMemory");
14 shared_memory_format = reinterpret_cast<Format*>(shared_memory_holder->GetPointer());
15 shared_memory_format->format_version =
16 14; // 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}
19
20SharedMemory::~SharedMemory() = default;
21
22Kernel::SharedPtr<Kernel::SharedMemory> SharedMemory::GetSharedMemoryHolder() const {
23 return shared_memory_holder;
24}
25
26void SharedMemory::SetStandardSteadyClockTimepoint(const SteadyClockTimePoint& timepoint) {
27 shared_memory_format->standard_steady_clock_timepoint.StoreData(timepoint);
28}
29
30void SharedMemory::SetStandardLocalSystemClockContext(const SystemClockContext& context) {
31 shared_memory_format->standard_local_system_clock_context.StoreData(context);
32}
33
34void SharedMemory::SetStandardNetworkSystemClockContext(const SystemClockContext& context) {
35 shared_memory_format->standard_network_system_clock_context.StoreData(context);
36}
37
38void SharedMemory::SetStandardUserSystemClockAutomaticCorrectionEnabled(const bool enabled) {
39 shared_memory_format->standard_user_system_clock_automatic_correction.StoreData(enabled ? 1
40 : 0);
41}
42
43SteadyClockTimePoint SharedMemory::GetStandardSteadyClockTimepoint() const {
44 return shared_memory_format->standard_steady_clock_timepoint.ReadData();
45}
46
47SystemClockContext SharedMemory::GetStandardLocalSystemClockContext() const {
48 return shared_memory_format->standard_local_system_clock_context.ReadData();
49}
50
51SystemClockContext SharedMemory::GetStandardNetworkSystemClockContext() const {
52 return shared_memory_format->standard_network_system_clock_context.ReadData();
53}
54
55bool SharedMemory::GetStandardUserSystemClockAutomaticCorrectionEnabled() const {
56 return shared_memory_format->standard_user_system_clock_automatic_correction.ReadData() > 0;
57}
58
59} // 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..ab536005c
--- /dev/null
+++ b/src/core/hle/service/time/time_sharedmemory.h
@@ -0,0 +1,71 @@
1// Copyright 2018 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 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(const bool enabled);
25
26 // Pull from memory barriers in the shared memory
27 SteadyClockTimePoint GetStandardSteadyClockTimepoint() const;
28 SystemClockContext GetStandardLocalSystemClockContext() const;
29 SystemClockContext GetStandardNetworkSystemClockContext() const;
30 bool GetStandardUserSystemClockAutomaticCorrectionEnabled() const;
31
32 // TODO(ogniK): We have to properly simulate memory barriers, how are we going to do this?
33 template <typename T>
34 struct MemoryBarrier {
35 u32_le read_attempt{};
36 T data[2]{};
37
38 // These are not actually memory barriers at the moment as we don't have multicore and all
39 // HLE is mutexed. This will need to properly be implemented when we start updating the time
40 // points on threads. As of right now, we'll be updated both values synchronously and just
41 // incrementing the read_attempt to indicate that we waited.
42 void StoreData(T data_to_store) {
43 read_attempt++;
44 data[read_attempt & 1] = data_to_store;
45 }
46
47 // For reading we're just going to read the last stored value. If there was no value stored
48 // it will just end up reading an empty value as intended.
49 T ReadData() const {
50 return data[(read_attempt - 1) & 1];
51 }
52 };
53
54 // Shared memory format
55 struct Format {
56 MemoryBarrier<SteadyClockTimePoint> standard_steady_clock_timepoint;
57 MemoryBarrier<SystemClockContext> standard_local_system_clock_context;
58 MemoryBarrier<SystemClockContext> standard_network_system_clock_context;
59 MemoryBarrier<u8> standard_user_system_clock_automatic_correction;
60 u32_le format_version;
61 };
62 static_assert(sizeof(Format) == 0xd8, "Format is an invalid size");
63
64private:
65 const std::size_t SHARED_MEMORY_SIZE = 0x1000;
66 Kernel::SharedPtr<Kernel::SharedMemory> shared_memory_holder{};
67 Core::System& system;
68 Format* shared_memory_format;
69};
70
71} // namespace Service::Time