diff options
| author | 2019-06-26 16:52:34 +1000 | |
|---|---|---|
| committer | 2019-06-26 16:52:34 +1000 | |
| commit | f67039c067282e560175b1b346405e898b40e993 (patch) | |
| tree | 664a798153170057b0ebbe9ffe1b3705cefc8e64 | |
| parent | Implement Time::GetSharedMemoryNativeHandle (diff) | |
| download | yuzu-f67039c067282e560175b1b346405e898b40e993.tar.gz yuzu-f67039c067282e560175b1b346405e898b40e993.tar.xz yuzu-f67039c067282e560175b1b346405e898b40e993.zip | |
Addressed issues
| -rw-r--r-- | src/core/hle/service/time/interface.h | 2 | ||||
| -rw-r--r-- | src/core/hle/service/time/time.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/service/time/time.h | 1 | ||||
| -rw-r--r-- | src/core/hle/service/time/time_sharedmemory.cpp | 47 | ||||
| -rw-r--r-- | src/core/hle/service/time/time_sharedmemory.h | 37 |
5 files changed, 53 insertions, 37 deletions
diff --git a/src/core/hle/service/time/interface.h b/src/core/hle/service/time/interface.h index 407acf960..bdf0883e2 100644 --- a/src/core/hle/service/time/interface.h +++ b/src/core/hle/service/time/interface.h | |||
| @@ -7,7 +7,9 @@ | |||
| 7 | #include "core/hle/service/time/time.h" | 7 | #include "core/hle/service/time/time.h" |
| 8 | 8 | ||
| 9 | namespace Service::Time { | 9 | namespace Service::Time { |
| 10 | |||
| 10 | class SharedMemory; | 11 | class SharedMemory; |
| 12 | |||
| 11 | class Time final : public Module::Interface { | 13 | class Time final : public Module::Interface { |
| 12 | public: | 14 | public: |
| 13 | explicit Time(std::shared_ptr<Module> time, std::shared_ptr<SharedMemory> shared_memory, | 15 | explicit Time(std::shared_ptr<Module> time, std::shared_ptr<SharedMemory> shared_memory, |
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 10a7e6c97..ae6446204 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp | |||
| @@ -418,7 +418,8 @@ void InstallInterfaces(Core::System& system) { | |||
| 418 | 418 | ||
| 419 | std::make_shared<Time>(time, shared_mem, "time:a")->InstallAsService(system.ServiceManager()); | 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()); | 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()); | 421 | std::make_shared<Time>(std::move(time), shared_mem, "time:u") |
| 422 | ->InstallAsService(system.ServiceManager()); | ||
| 422 | } | 423 | } |
| 423 | 424 | ||
| 424 | } // 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 6a05a22b9..e0708f856 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 | ||
| 11 | namespace Service::Time { | 11 | namespace Service::Time { |
| 12 | |||
| 12 | class SharedMemory; | 13 | class SharedMemory; |
| 13 | 14 | ||
| 14 | struct LocationName { | 15 | struct LocationName { |
diff --git a/src/core/hle/service/time/time_sharedmemory.cpp b/src/core/hle/service/time/time_sharedmemory.cpp index 650c9af7a..bfc81b83c 100644 --- a/src/core/hle/service/time/time_sharedmemory.cpp +++ b/src/core/hle/service/time/time_sharedmemory.cpp | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | 1 | // Copyright 2019 yuzu emulator team |
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| @@ -6,15 +6,17 @@ | |||
| 6 | #include "core/hle/service/time/time_sharedmemory.h" | 6 | #include "core/hle/service/time/time_sharedmemory.h" |
| 7 | 7 | ||
| 8 | namespace Service::Time { | 8 | namespace Service::Time { |
| 9 | const std::size_t SHARED_MEMORY_SIZE = 0x1000; | ||
| 9 | 10 | ||
| 10 | SharedMemory::SharedMemory(Core::System& system) : system(system) { | 11 | SharedMemory::SharedMemory(Core::System& system) : system(system) { |
| 11 | shared_memory_holder = Kernel::SharedMemory::Create( | 12 | shared_memory_holder = Kernel::SharedMemory::Create( |
| 12 | system.Kernel(), nullptr, SHARED_MEMORY_SIZE, Kernel::MemoryPermission::ReadWrite, | 13 | system.Kernel(), nullptr, SHARED_MEMORY_SIZE, Kernel::MemoryPermission::ReadWrite, |
| 13 | Kernel::MemoryPermission::Read, 0, Kernel::MemoryRegion::BASE, "Time:SharedMemory"); | 14 | Kernel::MemoryPermission::Read, 0, Kernel::MemoryRegion::BASE, "Time:SharedMemory"); |
| 14 | shared_memory_format = reinterpret_cast<Format*>(shared_memory_holder->GetPointer()); | 15 | |
| 15 | shared_memory_format->format_version = | 16 | // Seems static from 1.0.0 -> 8.1.0. Specific games seem to check this value and crash |
| 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 |
| 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)); | ||
| 18 | } | 20 | } |
| 19 | 21 | ||
| 20 | SharedMemory::~SharedMemory() = default; | 22 | SharedMemory::~SharedMemory() = default; |
| @@ -24,36 +26,43 @@ Kernel::SharedPtr<Kernel::SharedMemory> SharedMemory::GetSharedMemoryHolder() co | |||
| 24 | } | 26 | } |
| 25 | 27 | ||
| 26 | void SharedMemory::SetStandardSteadyClockTimepoint(const SteadyClockTimePoint& timepoint) { | 28 | void SharedMemory::SetStandardSteadyClockTimepoint(const SteadyClockTimePoint& timepoint) { |
| 27 | shared_memory_format->standard_steady_clock_timepoint.StoreData(timepoint); | 29 | shared_memory_format.standard_steady_clock_timepoint.StoreData( |
| 30 | shared_memory_holder->GetPointer(), timepoint); | ||
| 28 | } | 31 | } |
| 29 | 32 | ||
| 30 | void SharedMemory::SetStandardLocalSystemClockContext(const SystemClockContext& context) { | 33 | void SharedMemory::SetStandardLocalSystemClockContext(const SystemClockContext& context) { |
| 31 | shared_memory_format->standard_local_system_clock_context.StoreData(context); | 34 | shared_memory_format.standard_local_system_clock_context.StoreData( |
| 35 | shared_memory_holder->GetPointer(), context); | ||
| 32 | } | 36 | } |
| 33 | 37 | ||
| 34 | void SharedMemory::SetStandardNetworkSystemClockContext(const SystemClockContext& context) { | 38 | void SharedMemory::SetStandardNetworkSystemClockContext(const SystemClockContext& context) { |
| 35 | shared_memory_format->standard_network_system_clock_context.StoreData(context); | 39 | shared_memory_format.standard_network_system_clock_context.StoreData( |
| 40 | shared_memory_holder->GetPointer(), context); | ||
| 36 | } | 41 | } |
| 37 | 42 | ||
| 38 | void SharedMemory::SetStandardUserSystemClockAutomaticCorrectionEnabled(const bool enabled) { | 43 | void SharedMemory::SetStandardUserSystemClockAutomaticCorrectionEnabled(bool enabled) { |
| 39 | shared_memory_format->standard_user_system_clock_automatic_correction.StoreData(enabled ? 1 | 44 | shared_memory_format.standard_user_system_clock_automatic_correction.StoreData( |
| 40 | : 0); | 45 | shared_memory_holder->GetPointer(), enabled); |
| 41 | } | 46 | } |
| 42 | 47 | ||
| 43 | SteadyClockTimePoint SharedMemory::GetStandardSteadyClockTimepoint() const { | 48 | SteadyClockTimePoint SharedMemory::GetStandardSteadyClockTimepoint() { |
| 44 | return shared_memory_format->standard_steady_clock_timepoint.ReadData(); | 49 | return shared_memory_format.standard_steady_clock_timepoint.ReadData( |
| 50 | shared_memory_holder->GetPointer()); | ||
| 45 | } | 51 | } |
| 46 | 52 | ||
| 47 | SystemClockContext SharedMemory::GetStandardLocalSystemClockContext() const { | 53 | SystemClockContext SharedMemory::GetStandardLocalSystemClockContext() { |
| 48 | return shared_memory_format->standard_local_system_clock_context.ReadData(); | 54 | return shared_memory_format.standard_local_system_clock_context.ReadData( |
| 55 | shared_memory_holder->GetPointer()); | ||
| 49 | } | 56 | } |
| 50 | 57 | ||
| 51 | SystemClockContext SharedMemory::GetStandardNetworkSystemClockContext() const { | 58 | SystemClockContext SharedMemory::GetStandardNetworkSystemClockContext() { |
| 52 | return shared_memory_format->standard_network_system_clock_context.ReadData(); | 59 | return shared_memory_format.standard_network_system_clock_context.ReadData( |
| 60 | shared_memory_holder->GetPointer()); | ||
| 53 | } | 61 | } |
| 54 | 62 | ||
| 55 | bool SharedMemory::GetStandardUserSystemClockAutomaticCorrectionEnabled() const { | 63 | bool SharedMemory::GetStandardUserSystemClockAutomaticCorrectionEnabled() { |
| 56 | return shared_memory_format->standard_user_system_clock_automatic_correction.ReadData() > 0; | 64 | return shared_memory_format.standard_user_system_clock_automatic_correction.ReadData( |
| 65 | shared_memory_holder->GetPointer()); | ||
| 57 | } | 66 | } |
| 58 | 67 | ||
| 59 | } // namespace Service::Time | 68 | } // namespace Service::Time |
diff --git a/src/core/hle/service/time/time_sharedmemory.h b/src/core/hle/service/time/time_sharedmemory.h index ab536005c..cb8253541 100644 --- a/src/core/hle/service/time/time_sharedmemory.h +++ b/src/core/hle/service/time/time_sharedmemory.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | 1 | // Copyright 2019 yuzu emulator team |
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| @@ -11,7 +11,7 @@ | |||
| 11 | namespace Service::Time { | 11 | namespace Service::Time { |
| 12 | class SharedMemory { | 12 | class SharedMemory { |
| 13 | public: | 13 | public: |
| 14 | SharedMemory(Core::System& system); | 14 | explicit SharedMemory(Core::System& system); |
| 15 | ~SharedMemory(); | 15 | ~SharedMemory(); |
| 16 | 16 | ||
| 17 | // Return the shared memory handle | 17 | // Return the shared memory handle |
| @@ -21,51 +21,54 @@ public: | |||
| 21 | void SetStandardSteadyClockTimepoint(const SteadyClockTimePoint& timepoint); | 21 | void SetStandardSteadyClockTimepoint(const SteadyClockTimePoint& timepoint); |
| 22 | void SetStandardLocalSystemClockContext(const SystemClockContext& context); | 22 | void SetStandardLocalSystemClockContext(const SystemClockContext& context); |
| 23 | void SetStandardNetworkSystemClockContext(const SystemClockContext& context); | 23 | void SetStandardNetworkSystemClockContext(const SystemClockContext& context); |
| 24 | void SetStandardUserSystemClockAutomaticCorrectionEnabled(const bool enabled); | 24 | void SetStandardUserSystemClockAutomaticCorrectionEnabled(bool enabled); |
| 25 | 25 | ||
| 26 | // Pull from memory barriers in the shared memory | 26 | // Pull from memory barriers in the shared memory |
| 27 | SteadyClockTimePoint GetStandardSteadyClockTimepoint() const; | 27 | SteadyClockTimePoint GetStandardSteadyClockTimepoint(); |
| 28 | SystemClockContext GetStandardLocalSystemClockContext() const; | 28 | SystemClockContext GetStandardLocalSystemClockContext(); |
| 29 | SystemClockContext GetStandardNetworkSystemClockContext() const; | 29 | SystemClockContext GetStandardNetworkSystemClockContext(); |
| 30 | bool GetStandardUserSystemClockAutomaticCorrectionEnabled() const; | 30 | bool GetStandardUserSystemClockAutomaticCorrectionEnabled(); |
| 31 | 31 | ||
| 32 | // TODO(ogniK): We have to properly simulate memory barriers, how are we going to do this? | 32 | // TODO(ogniK): We have to properly simulate memory barriers, how are we going to do this? |
| 33 | template <typename T> | 33 | template <typename T, std::size_t Offset> |
| 34 | struct MemoryBarrier { | 34 | struct MemoryBarrier { |
| 35 | static_assert(std::is_trivially_constructible_v<T>, "T must be trivially constructable"); | ||
| 35 | u32_le read_attempt{}; | 36 | u32_le read_attempt{}; |
| 36 | T data[2]{}; | 37 | std::array<T, 2> data{}; |
| 37 | 38 | ||
| 38 | // These are not actually memory barriers at the moment as we don't have multicore and all | 39 | // 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 | // 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 | // 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 | // incrementing the read_attempt to indicate that we waited. |
| 42 | void StoreData(T data_to_store) { | 43 | void StoreData(u8* shared_memory, T data_to_store) { |
| 44 | std::memcpy(this, shared_memory + Offset, sizeof(*this)); | ||
| 43 | read_attempt++; | 45 | read_attempt++; |
| 44 | data[read_attempt & 1] = data_to_store; | 46 | data[read_attempt & 1] = data_to_store; |
| 47 | std::memcpy(shared_memory + Offset, this, sizeof(*this)); | ||
| 45 | } | 48 | } |
| 46 | 49 | ||
| 47 | // For reading we're just going to read the last stored value. If there was no value stored | 50 | // 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. | 51 | // it will just end up reading an empty value as intended. |
| 49 | T ReadData() const { | 52 | T ReadData(u8* shared_memory) { |
| 53 | std::memcpy(this, shared_memory + Offset, sizeof(*this)); | ||
| 50 | return data[(read_attempt - 1) & 1]; | 54 | return data[(read_attempt - 1) & 1]; |
| 51 | } | 55 | } |
| 52 | }; | 56 | }; |
| 53 | 57 | ||
| 54 | // Shared memory format | 58 | // Shared memory format |
| 55 | struct Format { | 59 | struct Format { |
| 56 | MemoryBarrier<SteadyClockTimePoint> standard_steady_clock_timepoint; | 60 | MemoryBarrier<SteadyClockTimePoint, 0x0> standard_steady_clock_timepoint; |
| 57 | MemoryBarrier<SystemClockContext> standard_local_system_clock_context; | 61 | MemoryBarrier<SystemClockContext, 0x38> standard_local_system_clock_context; |
| 58 | MemoryBarrier<SystemClockContext> standard_network_system_clock_context; | 62 | MemoryBarrier<SystemClockContext, 0x80> standard_network_system_clock_context; |
| 59 | MemoryBarrier<u8> standard_user_system_clock_automatic_correction; | 63 | MemoryBarrier<bool, 0xc8> standard_user_system_clock_automatic_correction; |
| 60 | u32_le format_version; | 64 | u32_le format_version; |
| 61 | }; | 65 | }; |
| 62 | static_assert(sizeof(Format) == 0xd8, "Format is an invalid size"); | 66 | static_assert(sizeof(Format) == 0xd8, "Format is an invalid size"); |
| 63 | 67 | ||
| 64 | private: | 68 | private: |
| 65 | const std::size_t SHARED_MEMORY_SIZE = 0x1000; | ||
| 66 | Kernel::SharedPtr<Kernel::SharedMemory> shared_memory_holder{}; | 69 | Kernel::SharedPtr<Kernel::SharedMemory> shared_memory_holder{}; |
| 67 | Core::System& system; | 70 | Core::System& system; |
| 68 | Format* shared_memory_format; | 71 | Format shared_memory_format{}; |
| 69 | }; | 72 | }; |
| 70 | 73 | ||
| 71 | } // namespace Service::Time | 74 | } // namespace Service::Time |