diff options
Diffstat (limited to 'src')
63 files changed, 464 insertions, 248 deletions
diff --git a/src/audio_core/device/device_session.cpp b/src/audio_core/device/device_session.cpp index 5a327a606..043ce8875 100644 --- a/src/audio_core/device/device_session.cpp +++ b/src/audio_core/device/device_session.cpp | |||
| @@ -93,7 +93,7 @@ void DeviceSession::AppendBuffers(std::span<const AudioBuffer> buffers) const { | |||
| 93 | stream->AppendBuffer(new_buffer, samples); | 93 | stream->AppendBuffer(new_buffer, samples); |
| 94 | } else { | 94 | } else { |
| 95 | std::vector<s16> samples(buffer.size / sizeof(s16)); | 95 | std::vector<s16> samples(buffer.size / sizeof(s16)); |
| 96 | system.Memory().ReadBlockUnsafe(buffer.samples, samples.data(), buffer.size); | 96 | system.ApplicationMemory().ReadBlockUnsafe(buffer.samples, samples.data(), buffer.size); |
| 97 | stream->AppendBuffer(new_buffer, samples); | 97 | stream->AppendBuffer(new_buffer, samples); |
| 98 | } | 98 | } |
| 99 | } | 99 | } |
| @@ -102,7 +102,7 @@ void DeviceSession::AppendBuffers(std::span<const AudioBuffer> buffers) const { | |||
| 102 | void DeviceSession::ReleaseBuffer(const AudioBuffer& buffer) const { | 102 | void DeviceSession::ReleaseBuffer(const AudioBuffer& buffer) const { |
| 103 | if (type == Sink::StreamType::In) { | 103 | if (type == Sink::StreamType::In) { |
| 104 | auto samples{stream->ReleaseBuffer(buffer.size / sizeof(s16))}; | 104 | auto samples{stream->ReleaseBuffer(buffer.size / sizeof(s16))}; |
| 105 | system.Memory().WriteBlockUnsafe(buffer.samples, samples.data(), buffer.size); | 105 | system.ApplicationMemory().WriteBlockUnsafe(buffer.samples, samples.data(), buffer.size); |
| 106 | } | 106 | } |
| 107 | } | 107 | } |
| 108 | 108 | ||
diff --git a/src/audio_core/renderer/adsp/adsp.cpp b/src/audio_core/renderer/adsp/adsp.cpp index a28395663..74772fc50 100644 --- a/src/audio_core/renderer/adsp/adsp.cpp +++ b/src/audio_core/renderer/adsp/adsp.cpp | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | namespace AudioCore::AudioRenderer::ADSP { | 13 | namespace AudioCore::AudioRenderer::ADSP { |
| 14 | 14 | ||
| 15 | ADSP::ADSP(Core::System& system_, Sink::Sink& sink_) | 15 | ADSP::ADSP(Core::System& system_, Sink::Sink& sink_) |
| 16 | : system{system_}, memory{system.Memory()}, sink{sink_} {} | 16 | : system{system_}, memory{system.ApplicationMemory()}, sink{sink_} {} |
| 17 | 17 | ||
| 18 | ADSP::~ADSP() { | 18 | ADSP::~ADSP() { |
| 19 | ClearCommandBuffers(); | 19 | ClearCommandBuffers(); |
diff --git a/src/audio_core/renderer/adsp/command_list_processor.cpp b/src/audio_core/renderer/adsp/command_list_processor.cpp index e3bf2d7ec..7a300d216 100644 --- a/src/audio_core/renderer/adsp/command_list_processor.cpp +++ b/src/audio_core/renderer/adsp/command_list_processor.cpp | |||
| @@ -17,7 +17,7 @@ namespace AudioCore::AudioRenderer::ADSP { | |||
| 17 | void CommandListProcessor::Initialize(Core::System& system_, CpuAddr buffer, u64 size, | 17 | void CommandListProcessor::Initialize(Core::System& system_, CpuAddr buffer, u64 size, |
| 18 | Sink::SinkStream* stream_) { | 18 | Sink::SinkStream* stream_) { |
| 19 | system = &system_; | 19 | system = &system_; |
| 20 | memory = &system->Memory(); | 20 | memory = &system->ApplicationMemory(); |
| 21 | stream = stream_; | 21 | stream = stream_; |
| 22 | header = reinterpret_cast<CommandListHeader*>(buffer); | 22 | header = reinterpret_cast<CommandListHeader*>(buffer); |
| 23 | commands = reinterpret_cast<u8*>(buffer + sizeof(CommandListHeader)); | 23 | commands = reinterpret_cast<u8*>(buffer + sizeof(CommandListHeader)); |
diff --git a/src/audio_core/renderer/system.cpp b/src/audio_core/renderer/system.cpp index 28f063641..ad869facb 100644 --- a/src/audio_core/renderer/system.cpp +++ b/src/audio_core/renderer/system.cpp | |||
| @@ -127,8 +127,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params, | |||
| 127 | render_device = params.rendering_device; | 127 | render_device = params.rendering_device; |
| 128 | execution_mode = params.execution_mode; | 128 | execution_mode = params.execution_mode; |
| 129 | 129 | ||
| 130 | core.Memory().ZeroBlock(*core.ApplicationProcess(), transfer_memory->GetSourceAddress(), | 130 | core.ApplicationMemory().ZeroBlock(transfer_memory->GetSourceAddress(), transfer_memory_size); |
| 131 | transfer_memory_size); | ||
| 132 | 131 | ||
| 133 | // Note: We're not actually using the transfer memory because it's a pain to code for. | 132 | // Note: We're not actually using the transfer memory because it's a pain to code for. |
| 134 | // Allocate the memory normally instead and hope the game doesn't try to read anything back | 133 | // Allocate the memory normally instead and hope the game doesn't try to read anything back |
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 90805babe..13ed68b3f 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt | |||
| @@ -38,6 +38,7 @@ add_library(common STATIC | |||
| 38 | common_precompiled_headers.h | 38 | common_precompiled_headers.h |
| 39 | common_types.h | 39 | common_types.h |
| 40 | concepts.h | 40 | concepts.h |
| 41 | container_hash.h | ||
| 41 | demangle.cpp | 42 | demangle.cpp |
| 42 | demangle.h | 43 | demangle.h |
| 43 | div_ceil.h | 44 | div_ceil.h |
| @@ -159,6 +160,8 @@ if(ARCHITECTURE_x86_64) | |||
| 159 | PRIVATE | 160 | PRIVATE |
| 160 | x64/cpu_detect.cpp | 161 | x64/cpu_detect.cpp |
| 161 | x64/cpu_detect.h | 162 | x64/cpu_detect.h |
| 163 | x64/cpu_wait.cpp | ||
| 164 | x64/cpu_wait.h | ||
| 162 | x64/native_clock.cpp | 165 | x64/native_clock.cpp |
| 163 | x64/native_clock.h | 166 | x64/native_clock.h |
| 164 | x64/xbyak_abi.h | 167 | x64/xbyak_abi.h |
diff --git a/src/common/container_hash.h b/src/common/container_hash.h new file mode 100644 index 000000000..a5e357745 --- /dev/null +++ b/src/common/container_hash.h | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | // SPDX-FileCopyrightText: 2005-2014 Daniel James | ||
| 2 | // SPDX-FileCopyrightText: 2016 Austin Appleby | ||
| 3 | // SPDX-License-Identifier: BSL-1.0 | ||
| 4 | |||
| 5 | #include <array> | ||
| 6 | #include <climits> | ||
| 7 | #include <cstdint> | ||
| 8 | #include <limits> | ||
| 9 | #include <type_traits> | ||
| 10 | #include <vector> | ||
| 11 | |||
| 12 | namespace Common { | ||
| 13 | |||
| 14 | namespace detail { | ||
| 15 | |||
| 16 | template <typename T> | ||
| 17 | requires std::is_unsigned_v<T> | ||
| 18 | inline std::size_t HashValue(T val) { | ||
| 19 | const unsigned int size_t_bits = std::numeric_limits<std::size_t>::digits; | ||
| 20 | const unsigned int length = | ||
| 21 | (std::numeric_limits<T>::digits - 1) / static_cast<unsigned int>(size_t_bits); | ||
| 22 | |||
| 23 | std::size_t seed = 0; | ||
| 24 | |||
| 25 | for (unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits) { | ||
| 26 | seed ^= static_cast<size_t>(val >> i) + (seed << 6) + (seed >> 2); | ||
| 27 | } | ||
| 28 | |||
| 29 | seed ^= static_cast<size_t>(val) + (seed << 6) + (seed >> 2); | ||
| 30 | |||
| 31 | return seed; | ||
| 32 | } | ||
| 33 | |||
| 34 | template <size_t Bits> | ||
| 35 | struct HashCombineImpl { | ||
| 36 | template <typename T> | ||
| 37 | static inline T fn(T seed, T value) { | ||
| 38 | seed ^= value + 0x9e3779b9 + (seed << 6) + (seed >> 2); | ||
| 39 | return seed; | ||
| 40 | } | ||
| 41 | }; | ||
| 42 | |||
| 43 | template <> | ||
| 44 | struct HashCombineImpl<64> { | ||
| 45 | static inline std::uint64_t fn(std::uint64_t h, std::uint64_t k) { | ||
| 46 | const std::uint64_t m = (std::uint64_t(0xc6a4a793) << 32) + 0x5bd1e995; | ||
| 47 | const int r = 47; | ||
| 48 | |||
| 49 | k *= m; | ||
| 50 | k ^= k >> r; | ||
| 51 | k *= m; | ||
| 52 | |||
| 53 | h ^= k; | ||
| 54 | h *= m; | ||
| 55 | |||
| 56 | // Completely arbitrary number, to prevent 0's | ||
| 57 | // from hashing to 0. | ||
| 58 | h += 0xe6546b64; | ||
| 59 | |||
| 60 | return h; | ||
| 61 | } | ||
| 62 | }; | ||
| 63 | |||
| 64 | } // namespace detail | ||
| 65 | |||
| 66 | template <typename T> | ||
| 67 | inline void HashCombine(std::size_t& seed, const T& v) { | ||
| 68 | seed = detail::HashCombineImpl<sizeof(std::size_t) * CHAR_BIT>::fn(seed, detail::HashValue(v)); | ||
| 69 | } | ||
| 70 | |||
| 71 | template <typename It> | ||
| 72 | inline std::size_t HashRange(It first, It last) { | ||
| 73 | std::size_t seed = 0; | ||
| 74 | |||
| 75 | for (; first != last; ++first) { | ||
| 76 | HashCombine<typename std::iterator_traits<It>::value_type>(seed, *first); | ||
| 77 | } | ||
| 78 | |||
| 79 | return seed; | ||
| 80 | } | ||
| 81 | |||
| 82 | template <typename T, size_t Size> | ||
| 83 | std::size_t HashValue(const std::array<T, Size>& v) { | ||
| 84 | return HashRange(v.cbegin(), v.cend()); | ||
| 85 | } | ||
| 86 | |||
| 87 | template <typename T, typename Allocator> | ||
| 88 | std::size_t HashValue(const std::vector<T, Allocator>& v) { | ||
| 89 | return HashRange(v.cbegin(), v.cend()); | ||
| 90 | } | ||
| 91 | |||
| 92 | } // namespace Common | ||
diff --git a/src/common/telemetry.cpp b/src/common/telemetry.cpp index d26394359..91352912d 100644 --- a/src/common/telemetry.cpp +++ b/src/common/telemetry.cpp | |||
| @@ -97,6 +97,7 @@ void AppendCPUInfo(FieldCollection& fc) { | |||
| 97 | add_field("CPU_Extension_x64_PCLMULQDQ", caps.pclmulqdq); | 97 | add_field("CPU_Extension_x64_PCLMULQDQ", caps.pclmulqdq); |
| 98 | add_field("CPU_Extension_x64_POPCNT", caps.popcnt); | 98 | add_field("CPU_Extension_x64_POPCNT", caps.popcnt); |
| 99 | add_field("CPU_Extension_x64_SHA", caps.sha); | 99 | add_field("CPU_Extension_x64_SHA", caps.sha); |
| 100 | add_field("CPU_Extension_x64_WAITPKG", caps.waitpkg); | ||
| 100 | #else | 101 | #else |
| 101 | fc.AddField(FieldType::UserSystem, "CPU_Model", "Other"); | 102 | fc.AddField(FieldType::UserSystem, "CPU_Model", "Other"); |
| 102 | #endif | 103 | #endif |
diff --git a/src/common/x64/cpu_detect.cpp b/src/common/x64/cpu_detect.cpp index e54383a4a..72ed6e96c 100644 --- a/src/common/x64/cpu_detect.cpp +++ b/src/common/x64/cpu_detect.cpp | |||
| @@ -144,6 +144,7 @@ static CPUCaps Detect() { | |||
| 144 | caps.bmi2 = Common::Bit<8>(cpu_id[1]); | 144 | caps.bmi2 = Common::Bit<8>(cpu_id[1]); |
| 145 | caps.sha = Common::Bit<29>(cpu_id[1]); | 145 | caps.sha = Common::Bit<29>(cpu_id[1]); |
| 146 | 146 | ||
| 147 | caps.waitpkg = Common::Bit<5>(cpu_id[2]); | ||
| 147 | caps.gfni = Common::Bit<8>(cpu_id[2]); | 148 | caps.gfni = Common::Bit<8>(cpu_id[2]); |
| 148 | 149 | ||
| 149 | __cpuidex(cpu_id, 0x00000007, 0x00000001); | 150 | __cpuidex(cpu_id, 0x00000007, 0x00000001); |
diff --git a/src/common/x64/cpu_detect.h b/src/common/x64/cpu_detect.h index ca8db19d6..8253944d6 100644 --- a/src/common/x64/cpu_detect.h +++ b/src/common/x64/cpu_detect.h | |||
| @@ -67,6 +67,7 @@ struct CPUCaps { | |||
| 67 | bool pclmulqdq : 1; | 67 | bool pclmulqdq : 1; |
| 68 | bool popcnt : 1; | 68 | bool popcnt : 1; |
| 69 | bool sha : 1; | 69 | bool sha : 1; |
| 70 | bool waitpkg : 1; | ||
| 70 | }; | 71 | }; |
| 71 | 72 | ||
| 72 | /** | 73 | /** |
diff --git a/src/common/x64/cpu_wait.cpp b/src/common/x64/cpu_wait.cpp new file mode 100644 index 000000000..cfeef6a3d --- /dev/null +++ b/src/common/x64/cpu_wait.cpp | |||
| @@ -0,0 +1,69 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include <thread> | ||
| 5 | |||
| 6 | #ifdef _MSC_VER | ||
| 7 | #include <intrin.h> | ||
| 8 | #endif | ||
| 9 | |||
| 10 | #include "common/x64/cpu_detect.h" | ||
| 11 | #include "common/x64/cpu_wait.h" | ||
| 12 | |||
| 13 | namespace Common::X64 { | ||
| 14 | |||
| 15 | #ifdef _MSC_VER | ||
| 16 | __forceinline static u64 FencedRDTSC() { | ||
| 17 | _mm_lfence(); | ||
| 18 | _ReadWriteBarrier(); | ||
| 19 | const u64 result = __rdtsc(); | ||
| 20 | _mm_lfence(); | ||
| 21 | _ReadWriteBarrier(); | ||
| 22 | return result; | ||
| 23 | } | ||
| 24 | |||
| 25 | __forceinline static void TPAUSE() { | ||
| 26 | // 100,000 cycles is a reasonable amount of time to wait to save on CPU resources. | ||
| 27 | // For reference: | ||
| 28 | // At 1 GHz, 100K cycles is 100us | ||
| 29 | // At 2 GHz, 100K cycles is 50us | ||
| 30 | // At 4 GHz, 100K cycles is 25us | ||
| 31 | static constexpr auto PauseCycles = 100'000; | ||
| 32 | _tpause(0, FencedRDTSC() + PauseCycles); | ||
| 33 | } | ||
| 34 | #else | ||
| 35 | static u64 FencedRDTSC() { | ||
| 36 | u64 eax; | ||
| 37 | u64 edx; | ||
| 38 | asm volatile("lfence\n\t" | ||
| 39 | "rdtsc\n\t" | ||
| 40 | "lfence\n\t" | ||
| 41 | : "=a"(eax), "=d"(edx)); | ||
| 42 | return (edx << 32) | eax; | ||
| 43 | } | ||
| 44 | |||
| 45 | static void TPAUSE() { | ||
| 46 | // 100,000 cycles is a reasonable amount of time to wait to save on CPU resources. | ||
| 47 | // For reference: | ||
| 48 | // At 1 GHz, 100K cycles is 100us | ||
| 49 | // At 2 GHz, 100K cycles is 50us | ||
| 50 | // At 4 GHz, 100K cycles is 25us | ||
| 51 | static constexpr auto PauseCycles = 100'000; | ||
| 52 | const auto tsc = FencedRDTSC() + PauseCycles; | ||
| 53 | const auto eax = static_cast<u32>(tsc & 0xFFFFFFFF); | ||
| 54 | const auto edx = static_cast<u32>(tsc >> 32); | ||
| 55 | asm volatile("tpause %0" : : "r"(0), "d"(edx), "a"(eax)); | ||
| 56 | } | ||
| 57 | #endif | ||
| 58 | |||
| 59 | void MicroSleep() { | ||
| 60 | static const bool has_waitpkg = GetCPUCaps().waitpkg; | ||
| 61 | |||
| 62 | if (has_waitpkg) { | ||
| 63 | TPAUSE(); | ||
| 64 | } else { | ||
| 65 | std::this_thread::yield(); | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | } // namespace Common::X64 | ||
diff --git a/src/common/x64/cpu_wait.h b/src/common/x64/cpu_wait.h new file mode 100644 index 000000000..99d3757a7 --- /dev/null +++ b/src/common/x64/cpu_wait.h | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | namespace Common::X64 { | ||
| 7 | |||
| 8 | void MicroSleep(); | ||
| 9 | |||
| 10 | } // namespace Common::X64 | ||
diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp index 76c66e7ee..277b00662 100644 --- a/src/common/x64/native_clock.cpp +++ b/src/common/x64/native_clock.cpp | |||
| @@ -27,16 +27,13 @@ __forceinline static u64 FencedRDTSC() { | |||
| 27 | } | 27 | } |
| 28 | #else | 28 | #else |
| 29 | static u64 FencedRDTSC() { | 29 | static u64 FencedRDTSC() { |
| 30 | u64 result; | 30 | u64 eax; |
| 31 | u64 edx; | ||
| 31 | asm volatile("lfence\n\t" | 32 | asm volatile("lfence\n\t" |
| 32 | "rdtsc\n\t" | 33 | "rdtsc\n\t" |
| 33 | "shl $32, %%rdx\n\t" | 34 | "lfence\n\t" |
| 34 | "or %%rdx, %0\n\t" | 35 | : "=a"(eax), "=d"(edx)); |
| 35 | "lfence" | 36 | return (edx << 32) | eax; |
| 36 | : "=a"(result) | ||
| 37 | : | ||
| 38 | : "rdx", "memory", "cc"); | ||
| 39 | return result; | ||
| 40 | } | 37 | } |
| 41 | #endif | 38 | #endif |
| 42 | 39 | ||
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp index be3f55cd2..d30914b7a 100644 --- a/src/core/arm/arm_interface.cpp +++ b/src/core/arm/arm_interface.cpp | |||
| @@ -44,7 +44,7 @@ void ARM_Interface::SymbolicateBacktrace(Core::System& system, std::vector<Backt | |||
| 44 | std::map<std::string, Symbols::Symbols> symbols; | 44 | std::map<std::string, Symbols::Symbols> symbols; |
| 45 | for (const auto& module : modules) { | 45 | for (const auto& module : modules) { |
| 46 | symbols.insert_or_assign( | 46 | symbols.insert_or_assign( |
| 47 | module.second, Symbols::GetSymbols(module.first, system.Memory(), | 47 | module.second, Symbols::GetSymbols(module.first, system.ApplicationMemory(), |
| 48 | system.ApplicationProcess()->Is64BitProcess())); | 48 | system.ApplicationProcess()->Is64BitProcess())); |
| 49 | } | 49 | } |
| 50 | 50 | ||
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index aa92d3fc3..cab21a88e 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp | |||
| @@ -28,8 +28,8 @@ using namespace Common::Literals; | |||
| 28 | class DynarmicCallbacks32 : public Dynarmic::A32::UserCallbacks { | 28 | class DynarmicCallbacks32 : public Dynarmic::A32::UserCallbacks { |
| 29 | public: | 29 | public: |
| 30 | explicit DynarmicCallbacks32(ARM_Dynarmic_32& parent_) | 30 | explicit DynarmicCallbacks32(ARM_Dynarmic_32& parent_) |
| 31 | : parent{parent_}, | 31 | : parent{parent_}, memory(parent.system.ApplicationMemory()), |
| 32 | memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()}, | 32 | debugger_enabled{parent.system.DebuggerEnabled()}, |
| 33 | check_memory_access{debugger_enabled || | 33 | check_memory_access{debugger_enabled || |
| 34 | !Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {} | 34 | !Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {} |
| 35 | 35 | ||
| @@ -468,7 +468,7 @@ void ARM_Dynarmic_32::PageTableChanged(Common::PageTable& page_table, | |||
| 468 | std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_32::GetBacktrace(Core::System& system, | 468 | std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_32::GetBacktrace(Core::System& system, |
| 469 | u64 fp, u64 lr, u64 pc) { | 469 | u64 fp, u64 lr, u64 pc) { |
| 470 | std::vector<BacktraceEntry> out; | 470 | std::vector<BacktraceEntry> out; |
| 471 | auto& memory = system.Memory(); | 471 | auto& memory = system.ApplicationMemory(); |
| 472 | 472 | ||
| 473 | out.push_back({"", 0, pc, 0, ""}); | 473 | out.push_back({"", 0, pc, 0, ""}); |
| 474 | 474 | ||
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 67073c84d..bbbcb4f9d 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp | |||
| @@ -28,8 +28,8 @@ using namespace Common::Literals; | |||
| 28 | class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks { | 28 | class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks { |
| 29 | public: | 29 | public: |
| 30 | explicit DynarmicCallbacks64(ARM_Dynarmic_64& parent_) | 30 | explicit DynarmicCallbacks64(ARM_Dynarmic_64& parent_) |
| 31 | : parent{parent_}, | 31 | : parent{parent_}, memory(parent.system.ApplicationMemory()), |
| 32 | memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()}, | 32 | debugger_enabled{parent.system.DebuggerEnabled()}, |
| 33 | check_memory_access{debugger_enabled || | 33 | check_memory_access{debugger_enabled || |
| 34 | !Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {} | 34 | !Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {} |
| 35 | 35 | ||
| @@ -529,7 +529,7 @@ void ARM_Dynarmic_64::PageTableChanged(Common::PageTable& page_table, | |||
| 529 | std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_64::GetBacktrace(Core::System& system, | 529 | std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_64::GetBacktrace(Core::System& system, |
| 530 | u64 fp, u64 lr, u64 pc) { | 530 | u64 fp, u64 lr, u64 pc) { |
| 531 | std::vector<BacktraceEntry> out; | 531 | std::vector<BacktraceEntry> out; |
| 532 | auto& memory = system.Memory(); | 532 | auto& memory = system.ApplicationMemory(); |
| 533 | 533 | ||
| 534 | out.push_back({"", 0, pc, 0, ""}); | 534 | out.push_back({"", 0, pc, 0, ""}); |
| 535 | 535 | ||
diff --git a/src/core/core.cpp b/src/core/core.cpp index f6273ac39..caa6a77be 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -293,6 +293,7 @@ struct System::Impl { | |||
| 293 | ASSERT(Kernel::KProcess::Initialize(main_process, system, "main", | 293 | ASSERT(Kernel::KProcess::Initialize(main_process, system, "main", |
| 294 | Kernel::KProcess::ProcessType::Userland, resource_limit) | 294 | Kernel::KProcess::ProcessType::Userland, resource_limit) |
| 295 | .IsSuccess()); | 295 | .IsSuccess()); |
| 296 | kernel.MakeApplicationProcess(main_process); | ||
| 296 | const auto [load_result, load_parameters] = app_loader->Load(*main_process, system); | 297 | const auto [load_result, load_parameters] = app_loader->Load(*main_process, system); |
| 297 | if (load_result != Loader::ResultStatus::Success) { | 298 | if (load_result != Loader::ResultStatus::Success) { |
| 298 | LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result); | 299 | LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result); |
| @@ -302,7 +303,6 @@ struct System::Impl { | |||
| 302 | static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result)); | 303 | static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result)); |
| 303 | } | 304 | } |
| 304 | AddGlueRegistrationForProcess(*app_loader, *main_process); | 305 | AddGlueRegistrationForProcess(*app_loader, *main_process); |
| 305 | kernel.MakeApplicationProcess(main_process); | ||
| 306 | kernel.InitializeCores(); | 306 | kernel.InitializeCores(); |
| 307 | 307 | ||
| 308 | // Initialize cheat engine | 308 | // Initialize cheat engine |
| @@ -681,11 +681,11 @@ const ExclusiveMonitor& System::Monitor() const { | |||
| 681 | return impl->kernel.GetExclusiveMonitor(); | 681 | return impl->kernel.GetExclusiveMonitor(); |
| 682 | } | 682 | } |
| 683 | 683 | ||
| 684 | Memory::Memory& System::Memory() { | 684 | Memory::Memory& System::ApplicationMemory() { |
| 685 | return impl->memory; | 685 | return impl->memory; |
| 686 | } | 686 | } |
| 687 | 687 | ||
| 688 | const Core::Memory::Memory& System::Memory() const { | 688 | const Core::Memory::Memory& System::ApplicationMemory() const { |
| 689 | return impl->memory; | 689 | return impl->memory; |
| 690 | } | 690 | } |
| 691 | 691 | ||
diff --git a/src/core/core.h b/src/core/core.h index 7032240be..4a5aba032 100644 --- a/src/core/core.h +++ b/src/core/core.h | |||
| @@ -256,10 +256,10 @@ public: | |||
| 256 | [[nodiscard]] const ExclusiveMonitor& Monitor() const; | 256 | [[nodiscard]] const ExclusiveMonitor& Monitor() const; |
| 257 | 257 | ||
| 258 | /// Gets a mutable reference to the system memory instance. | 258 | /// Gets a mutable reference to the system memory instance. |
| 259 | [[nodiscard]] Core::Memory::Memory& Memory(); | 259 | [[nodiscard]] Core::Memory::Memory& ApplicationMemory(); |
| 260 | 260 | ||
| 261 | /// Gets a constant reference to the system memory instance. | 261 | /// Gets a constant reference to the system memory instance. |
| 262 | [[nodiscard]] const Core::Memory::Memory& Memory() const; | 262 | [[nodiscard]] const Core::Memory::Memory& ApplicationMemory() const; |
| 263 | 263 | ||
| 264 | /// Gets a mutable reference to the GPU interface | 264 | /// Gets a mutable reference to the GPU interface |
| 265 | [[nodiscard]] Tegra::GPU& GPU(); | 265 | [[nodiscard]] Tegra::GPU& GPU(); |
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index cd4df4522..4f2692b05 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp | |||
| @@ -10,6 +10,10 @@ | |||
| 10 | #include "common/windows/timer_resolution.h" | 10 | #include "common/windows/timer_resolution.h" |
| 11 | #endif | 11 | #endif |
| 12 | 12 | ||
| 13 | #ifdef ARCHITECTURE_x86_64 | ||
| 14 | #include "common/x64/cpu_wait.h" | ||
| 15 | #endif | ||
| 16 | |||
| 13 | #include "common/microprofile.h" | 17 | #include "common/microprofile.h" |
| 14 | #include "core/core_timing.h" | 18 | #include "core/core_timing.h" |
| 15 | #include "core/core_timing_util.h" | 19 | #include "core/core_timing_util.h" |
| @@ -269,7 +273,11 @@ void CoreTiming::ThreadLoop() { | |||
| 269 | if (wait_time >= timer_resolution_ns) { | 273 | if (wait_time >= timer_resolution_ns) { |
| 270 | Common::Windows::SleepForOneTick(); | 274 | Common::Windows::SleepForOneTick(); |
| 271 | } else { | 275 | } else { |
| 276 | #ifdef ARCHITECTURE_x86_64 | ||
| 277 | Common::X64::MicroSleep(); | ||
| 278 | #else | ||
| 272 | std::this_thread::yield(); | 279 | std::this_thread::yield(); |
| 280 | #endif | ||
| 273 | } | 281 | } |
| 274 | } | 282 | } |
| 275 | 283 | ||
diff --git a/src/core/debugger/gdbstub.cpp b/src/core/debugger/gdbstub.cpp index 5cfb66b93..e2a13bbd2 100644 --- a/src/core/debugger/gdbstub.cpp +++ b/src/core/debugger/gdbstub.cpp | |||
| @@ -261,9 +261,9 @@ void GDBStub::ExecuteCommand(std::string_view packet, std::vector<DebuggerAction | |||
| 261 | const size_t addr{static_cast<size_t>(strtoll(command.data(), nullptr, 16))}; | 261 | const size_t addr{static_cast<size_t>(strtoll(command.data(), nullptr, 16))}; |
| 262 | const size_t size{static_cast<size_t>(strtoll(command.data() + sep, nullptr, 16))}; | 262 | const size_t size{static_cast<size_t>(strtoll(command.data() + sep, nullptr, 16))}; |
| 263 | 263 | ||
| 264 | if (system.Memory().IsValidVirtualAddressRange(addr, size)) { | 264 | if (system.ApplicationMemory().IsValidVirtualAddressRange(addr, size)) { |
| 265 | std::vector<u8> mem(size); | 265 | std::vector<u8> mem(size); |
| 266 | system.Memory().ReadBlock(addr, mem.data(), size); | 266 | system.ApplicationMemory().ReadBlock(addr, mem.data(), size); |
| 267 | 267 | ||
| 268 | SendReply(Common::HexToString(mem)); | 268 | SendReply(Common::HexToString(mem)); |
| 269 | } else { | 269 | } else { |
| @@ -281,8 +281,8 @@ void GDBStub::ExecuteCommand(std::string_view packet, std::vector<DebuggerAction | |||
| 281 | const auto mem_substr{std::string_view(command).substr(mem_sep)}; | 281 | const auto mem_substr{std::string_view(command).substr(mem_sep)}; |
| 282 | const auto mem{Common::HexStringToVector(mem_substr, false)}; | 282 | const auto mem{Common::HexStringToVector(mem_substr, false)}; |
| 283 | 283 | ||
| 284 | if (system.Memory().IsValidVirtualAddressRange(addr, size)) { | 284 | if (system.ApplicationMemory().IsValidVirtualAddressRange(addr, size)) { |
| 285 | system.Memory().WriteBlock(addr, mem.data(), size); | 285 | system.ApplicationMemory().WriteBlock(addr, mem.data(), size); |
| 286 | system.InvalidateCpuInstructionCacheRange(addr, size); | 286 | system.InvalidateCpuInstructionCacheRange(addr, size); |
| 287 | SendReply(GDB_STUB_REPLY_OK); | 287 | SendReply(GDB_STUB_REPLY_OK); |
| 288 | } else { | 288 | } else { |
| @@ -325,7 +325,7 @@ void GDBStub::HandleBreakpointInsert(std::string_view command) { | |||
| 325 | const size_t addr{static_cast<size_t>(strtoll(command.data() + addr_sep, nullptr, 16))}; | 325 | const size_t addr{static_cast<size_t>(strtoll(command.data() + addr_sep, nullptr, 16))}; |
| 326 | const size_t size{static_cast<size_t>(strtoll(command.data() + size_sep, nullptr, 16))}; | 326 | const size_t size{static_cast<size_t>(strtoll(command.data() + size_sep, nullptr, 16))}; |
| 327 | 327 | ||
| 328 | if (!system.Memory().IsValidVirtualAddressRange(addr, size)) { | 328 | if (!system.ApplicationMemory().IsValidVirtualAddressRange(addr, size)) { |
| 329 | SendReply(GDB_STUB_REPLY_ERR); | 329 | SendReply(GDB_STUB_REPLY_ERR); |
| 330 | return; | 330 | return; |
| 331 | } | 331 | } |
| @@ -334,22 +334,22 @@ void GDBStub::HandleBreakpointInsert(std::string_view command) { | |||
| 334 | 334 | ||
| 335 | switch (type) { | 335 | switch (type) { |
| 336 | case BreakpointType::Software: | 336 | case BreakpointType::Software: |
| 337 | replaced_instructions[addr] = system.Memory().Read32(addr); | 337 | replaced_instructions[addr] = system.ApplicationMemory().Read32(addr); |
| 338 | system.Memory().Write32(addr, arch->BreakpointInstruction()); | 338 | system.ApplicationMemory().Write32(addr, arch->BreakpointInstruction()); |
| 339 | system.InvalidateCpuInstructionCacheRange(addr, sizeof(u32)); | 339 | system.InvalidateCpuInstructionCacheRange(addr, sizeof(u32)); |
| 340 | success = true; | 340 | success = true; |
| 341 | break; | 341 | break; |
| 342 | case BreakpointType::WriteWatch: | 342 | case BreakpointType::WriteWatch: |
| 343 | success = system.ApplicationProcess()->InsertWatchpoint(system, addr, size, | 343 | success = system.ApplicationProcess()->InsertWatchpoint(addr, size, |
| 344 | Kernel::DebugWatchpointType::Write); | 344 | Kernel::DebugWatchpointType::Write); |
| 345 | break; | 345 | break; |
| 346 | case BreakpointType::ReadWatch: | 346 | case BreakpointType::ReadWatch: |
| 347 | success = system.ApplicationProcess()->InsertWatchpoint(system, addr, size, | 347 | success = system.ApplicationProcess()->InsertWatchpoint(addr, size, |
| 348 | Kernel::DebugWatchpointType::Read); | 348 | Kernel::DebugWatchpointType::Read); |
| 349 | break; | 349 | break; |
| 350 | case BreakpointType::AccessWatch: | 350 | case BreakpointType::AccessWatch: |
| 351 | success = system.ApplicationProcess()->InsertWatchpoint( | 351 | success = system.ApplicationProcess()->InsertWatchpoint( |
| 352 | system, addr, size, Kernel::DebugWatchpointType::ReadOrWrite); | 352 | addr, size, Kernel::DebugWatchpointType::ReadOrWrite); |
| 353 | break; | 353 | break; |
| 354 | case BreakpointType::Hardware: | 354 | case BreakpointType::Hardware: |
| 355 | default: | 355 | default: |
| @@ -372,7 +372,7 @@ void GDBStub::HandleBreakpointRemove(std::string_view command) { | |||
| 372 | const size_t addr{static_cast<size_t>(strtoll(command.data() + addr_sep, nullptr, 16))}; | 372 | const size_t addr{static_cast<size_t>(strtoll(command.data() + addr_sep, nullptr, 16))}; |
| 373 | const size_t size{static_cast<size_t>(strtoll(command.data() + size_sep, nullptr, 16))}; | 373 | const size_t size{static_cast<size_t>(strtoll(command.data() + size_sep, nullptr, 16))}; |
| 374 | 374 | ||
| 375 | if (!system.Memory().IsValidVirtualAddressRange(addr, size)) { | 375 | if (!system.ApplicationMemory().IsValidVirtualAddressRange(addr, size)) { |
| 376 | SendReply(GDB_STUB_REPLY_ERR); | 376 | SendReply(GDB_STUB_REPLY_ERR); |
| 377 | return; | 377 | return; |
| 378 | } | 378 | } |
| @@ -383,7 +383,7 @@ void GDBStub::HandleBreakpointRemove(std::string_view command) { | |||
| 383 | case BreakpointType::Software: { | 383 | case BreakpointType::Software: { |
| 384 | const auto orig_insn{replaced_instructions.find(addr)}; | 384 | const auto orig_insn{replaced_instructions.find(addr)}; |
| 385 | if (orig_insn != replaced_instructions.end()) { | 385 | if (orig_insn != replaced_instructions.end()) { |
| 386 | system.Memory().Write32(addr, orig_insn->second); | 386 | system.ApplicationMemory().Write32(addr, orig_insn->second); |
| 387 | system.InvalidateCpuInstructionCacheRange(addr, sizeof(u32)); | 387 | system.InvalidateCpuInstructionCacheRange(addr, sizeof(u32)); |
| 388 | replaced_instructions.erase(addr); | 388 | replaced_instructions.erase(addr); |
| 389 | success = true; | 389 | success = true; |
| @@ -391,16 +391,16 @@ void GDBStub::HandleBreakpointRemove(std::string_view command) { | |||
| 391 | break; | 391 | break; |
| 392 | } | 392 | } |
| 393 | case BreakpointType::WriteWatch: | 393 | case BreakpointType::WriteWatch: |
| 394 | success = system.ApplicationProcess()->RemoveWatchpoint(system, addr, size, | 394 | success = system.ApplicationProcess()->RemoveWatchpoint(addr, size, |
| 395 | Kernel::DebugWatchpointType::Write); | 395 | Kernel::DebugWatchpointType::Write); |
| 396 | break; | 396 | break; |
| 397 | case BreakpointType::ReadWatch: | 397 | case BreakpointType::ReadWatch: |
| 398 | success = system.ApplicationProcess()->RemoveWatchpoint(system, addr, size, | 398 | success = system.ApplicationProcess()->RemoveWatchpoint(addr, size, |
| 399 | Kernel::DebugWatchpointType::Read); | 399 | Kernel::DebugWatchpointType::Read); |
| 400 | break; | 400 | break; |
| 401 | case BreakpointType::AccessWatch: | 401 | case BreakpointType::AccessWatch: |
| 402 | success = system.ApplicationProcess()->RemoveWatchpoint( | 402 | success = system.ApplicationProcess()->RemoveWatchpoint( |
| 403 | system, addr, size, Kernel::DebugWatchpointType::ReadOrWrite); | 403 | addr, size, Kernel::DebugWatchpointType::ReadOrWrite); |
| 404 | break; | 404 | break; |
| 405 | case BreakpointType::Hardware: | 405 | case BreakpointType::Hardware: |
| 406 | default: | 406 | default: |
| @@ -483,9 +483,9 @@ static std::optional<std::string> GetNameFromThreadType64(Core::Memory::Memory& | |||
| 483 | static std::optional<std::string> GetThreadName(Core::System& system, | 483 | static std::optional<std::string> GetThreadName(Core::System& system, |
| 484 | const Kernel::KThread* thread) { | 484 | const Kernel::KThread* thread) { |
| 485 | if (system.ApplicationProcess()->Is64BitProcess()) { | 485 | if (system.ApplicationProcess()->Is64BitProcess()) { |
| 486 | return GetNameFromThreadType64(system.Memory(), thread); | 486 | return GetNameFromThreadType64(system.ApplicationMemory(), thread); |
| 487 | } else { | 487 | } else { |
| 488 | return GetNameFromThreadType32(system.Memory(), thread); | 488 | return GetNameFromThreadType32(system.ApplicationMemory(), thread); |
| 489 | } | 489 | } |
| 490 | } | 490 | } |
| 491 | 491 | ||
diff --git a/src/core/hle/kernel/k_address_arbiter.cpp b/src/core/hle/kernel/k_address_arbiter.cpp index 274928dcf..08c254028 100644 --- a/src/core/hle/kernel/k_address_arbiter.cpp +++ b/src/core/hle/kernel/k_address_arbiter.cpp | |||
| @@ -21,8 +21,8 @@ KAddressArbiter::~KAddressArbiter() = default; | |||
| 21 | 21 | ||
| 22 | namespace { | 22 | namespace { |
| 23 | 23 | ||
| 24 | bool ReadFromUser(Core::System& system, s32* out, KProcessAddress address) { | 24 | bool ReadFromUser(KernelCore& kernel, s32* out, KProcessAddress address) { |
| 25 | *out = system.Memory().Read32(GetInteger(address)); | 25 | *out = GetCurrentMemory(kernel).Read32(GetInteger(address)); |
| 26 | return true; | 26 | return true; |
| 27 | } | 27 | } |
| 28 | 28 | ||
| @@ -209,7 +209,7 @@ Result KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(uint64_t addr, s32 | |||
| 209 | if (value != new_value) { | 209 | if (value != new_value) { |
| 210 | succeeded = UpdateIfEqual(m_system, std::addressof(user_value), addr, value, new_value); | 210 | succeeded = UpdateIfEqual(m_system, std::addressof(user_value), addr, value, new_value); |
| 211 | } else { | 211 | } else { |
| 212 | succeeded = ReadFromUser(m_system, std::addressof(user_value), addr); | 212 | succeeded = ReadFromUser(m_kernel, std::addressof(user_value), addr); |
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | R_UNLESS(succeeded, ResultInvalidCurrentMemory); | 215 | R_UNLESS(succeeded, ResultInvalidCurrentMemory); |
| @@ -252,7 +252,7 @@ Result KAddressArbiter::WaitIfLessThan(uint64_t addr, s32 value, bool decrement, | |||
| 252 | if (decrement) { | 252 | if (decrement) { |
| 253 | succeeded = DecrementIfLessThan(m_system, std::addressof(user_value), addr, value); | 253 | succeeded = DecrementIfLessThan(m_system, std::addressof(user_value), addr, value); |
| 254 | } else { | 254 | } else { |
| 255 | succeeded = ReadFromUser(m_system, std::addressof(user_value), addr); | 255 | succeeded = ReadFromUser(m_kernel, std::addressof(user_value), addr); |
| 256 | } | 256 | } |
| 257 | 257 | ||
| 258 | if (!succeeded) { | 258 | if (!succeeded) { |
| @@ -303,7 +303,7 @@ Result KAddressArbiter::WaitIfEqual(uint64_t addr, s32 value, s64 timeout) { | |||
| 303 | 303 | ||
| 304 | // Read the value from userspace. | 304 | // Read the value from userspace. |
| 305 | s32 user_value{}; | 305 | s32 user_value{}; |
| 306 | if (!ReadFromUser(m_system, std::addressof(user_value), addr)) { | 306 | if (!ReadFromUser(m_kernel, std::addressof(user_value), addr)) { |
| 307 | slp.CancelSleep(); | 307 | slp.CancelSleep(); |
| 308 | R_THROW(ResultInvalidCurrentMemory); | 308 | R_THROW(ResultInvalidCurrentMemory); |
| 309 | } | 309 | } |
diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp index c6634313f..73017cf99 100644 --- a/src/core/hle/kernel/k_condition_variable.cpp +++ b/src/core/hle/kernel/k_condition_variable.cpp | |||
| @@ -18,13 +18,13 @@ namespace Kernel { | |||
| 18 | 18 | ||
| 19 | namespace { | 19 | namespace { |
| 20 | 20 | ||
| 21 | bool ReadFromUser(Core::System& system, u32* out, KProcessAddress address) { | 21 | bool ReadFromUser(KernelCore& kernel, u32* out, KProcessAddress address) { |
| 22 | *out = system.Memory().Read32(GetInteger(address)); | 22 | *out = GetCurrentMemory(kernel).Read32(GetInteger(address)); |
| 23 | return true; | 23 | return true; |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | bool WriteToUser(Core::System& system, KProcessAddress address, const u32* p) { | 26 | bool WriteToUser(KernelCore& kernel, KProcessAddress address, const u32* p) { |
| 27 | system.Memory().Write32(GetInteger(address), *p); | 27 | GetCurrentMemory(kernel).Write32(GetInteger(address), *p); |
| 28 | return true; | 28 | return true; |
| 29 | } | 29 | } |
| 30 | 30 | ||
| @@ -128,7 +128,7 @@ Result KConditionVariable::SignalToAddress(KProcessAddress addr) { | |||
| 128 | 128 | ||
| 129 | // Write the value to userspace. | 129 | // Write the value to userspace. |
| 130 | Result result{ResultSuccess}; | 130 | Result result{ResultSuccess}; |
| 131 | if (WriteToUser(m_system, addr, std::addressof(next_value))) [[likely]] { | 131 | if (WriteToUser(m_kernel, addr, std::addressof(next_value))) [[likely]] { |
| 132 | result = ResultSuccess; | 132 | result = ResultSuccess; |
| 133 | } else { | 133 | } else { |
| 134 | result = ResultInvalidCurrentMemory; | 134 | result = ResultInvalidCurrentMemory; |
| @@ -157,7 +157,7 @@ Result KConditionVariable::WaitForAddress(Handle handle, KProcessAddress addr, u | |||
| 157 | 157 | ||
| 158 | // Read the tag from userspace. | 158 | // Read the tag from userspace. |
| 159 | u32 test_tag{}; | 159 | u32 test_tag{}; |
| 160 | R_UNLESS(ReadFromUser(m_system, std::addressof(test_tag), addr), | 160 | R_UNLESS(ReadFromUser(m_kernel, std::addressof(test_tag), addr), |
| 161 | ResultInvalidCurrentMemory); | 161 | ResultInvalidCurrentMemory); |
| 162 | 162 | ||
| 163 | // If the tag isn't the handle (with wait mask), we're done. | 163 | // If the tag isn't the handle (with wait mask), we're done. |
| @@ -257,7 +257,7 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) { | |||
| 257 | // If we have no waiters, clear the has waiter flag. | 257 | // If we have no waiters, clear the has waiter flag. |
| 258 | if (it == m_tree.end() || it->GetConditionVariableKey() != cv_key) { | 258 | if (it == m_tree.end() || it->GetConditionVariableKey() != cv_key) { |
| 259 | const u32 has_waiter_flag{}; | 259 | const u32 has_waiter_flag{}; |
| 260 | WriteToUser(m_system, cv_key, std::addressof(has_waiter_flag)); | 260 | WriteToUser(m_kernel, cv_key, std::addressof(has_waiter_flag)); |
| 261 | } | 261 | } |
| 262 | } | 262 | } |
| 263 | } | 263 | } |
| @@ -301,12 +301,12 @@ Result KConditionVariable::Wait(KProcessAddress addr, u64 key, u32 value, s64 ti | |||
| 301 | // Write to the cv key. | 301 | // Write to the cv key. |
| 302 | { | 302 | { |
| 303 | const u32 has_waiter_flag = 1; | 303 | const u32 has_waiter_flag = 1; |
| 304 | WriteToUser(m_system, key, std::addressof(has_waiter_flag)); | 304 | WriteToUser(m_kernel, key, std::addressof(has_waiter_flag)); |
| 305 | std::atomic_thread_fence(std::memory_order_seq_cst); | 305 | std::atomic_thread_fence(std::memory_order_seq_cst); |
| 306 | } | 306 | } |
| 307 | 307 | ||
| 308 | // Write the value to userspace. | 308 | // Write the value to userspace. |
| 309 | if (!WriteToUser(m_system, addr, std::addressof(next_value))) { | 309 | if (!WriteToUser(m_kernel, addr, std::addressof(next_value))) { |
| 310 | slp.CancelSleep(); | 310 | slp.CancelSleep(); |
| 311 | R_THROW(ResultInvalidCurrentMemory); | 311 | R_THROW(ResultInvalidCurrentMemory); |
| 312 | } | 312 | } |
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp index cb39387ea..02b5cada4 100644 --- a/src/core/hle/kernel/k_page_table.cpp +++ b/src/core/hle/kernel/k_page_table.cpp | |||
| @@ -108,7 +108,8 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type | |||
| 108 | bool enable_das_merge, bool from_back, | 108 | bool enable_das_merge, bool from_back, |
| 109 | KMemoryManager::Pool pool, KProcessAddress code_addr, | 109 | KMemoryManager::Pool pool, KProcessAddress code_addr, |
| 110 | size_t code_size, KSystemResource* system_resource, | 110 | size_t code_size, KSystemResource* system_resource, |
| 111 | KResourceLimit* resource_limit) { | 111 | KResourceLimit* resource_limit, |
| 112 | Core::Memory::Memory& memory) { | ||
| 112 | 113 | ||
| 113 | const auto GetSpaceStart = [this](KAddressSpaceInfo::Type type) { | 114 | const auto GetSpaceStart = [this](KAddressSpaceInfo::Type type) { |
| 114 | return KAddressSpaceInfo::GetAddressSpaceStart(m_address_space_width, type); | 115 | return KAddressSpaceInfo::GetAddressSpaceStart(m_address_space_width, type); |
| @@ -117,6 +118,9 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type | |||
| 117 | return KAddressSpaceInfo::GetAddressSpaceSize(m_address_space_width, type); | 118 | return KAddressSpaceInfo::GetAddressSpaceSize(m_address_space_width, type); |
| 118 | }; | 119 | }; |
| 119 | 120 | ||
| 121 | // Set the tracking memory | ||
| 122 | m_memory = std::addressof(memory); | ||
| 123 | |||
| 120 | // Set our width and heap/alias sizes | 124 | // Set our width and heap/alias sizes |
| 121 | m_address_space_width = GetAddressSpaceWidthFromType(as_type); | 125 | m_address_space_width = GetAddressSpaceWidthFromType(as_type); |
| 122 | const KProcessAddress start = 0; | 126 | const KProcessAddress start = 0; |
| @@ -334,10 +338,10 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type | |||
| 334 | 338 | ||
| 335 | void KPageTable::Finalize() { | 339 | void KPageTable::Finalize() { |
| 336 | // Finalize memory blocks. | 340 | // Finalize memory blocks. |
| 337 | m_memory_block_manager.Finalize( | 341 | m_memory_block_manager.Finalize(m_memory_block_slab_manager, |
| 338 | m_memory_block_slab_manager, [&](KProcessAddress addr, u64 size) { | 342 | [&](KProcessAddress addr, u64 size) { |
| 339 | m_system.Memory().UnmapRegion(*m_page_table_impl, addr, size); | 343 | m_memory->UnmapRegion(*m_page_table_impl, addr, size); |
| 340 | }); | 344 | }); |
| 341 | 345 | ||
| 342 | // Release any insecure mapped memory. | 346 | // Release any insecure mapped memory. |
| 343 | if (m_mapped_insecure_memory) { | 347 | if (m_mapped_insecure_memory) { |
| @@ -1010,23 +1014,22 @@ Result KPageTable::SetupForIpcServer(KProcessAddress* out_addr, size_t size, | |||
| 1010 | clear_size = 0; | 1014 | clear_size = 0; |
| 1011 | } | 1015 | } |
| 1012 | 1016 | ||
| 1013 | std::memset(m_system.Memory().GetPointer<void>(GetInteger(start_partial_virt)), | 1017 | std::memset(m_memory->GetPointer<void>(GetInteger(start_partial_virt)), fill_val, |
| 1014 | fill_val, partial_offset); | 1018 | partial_offset); |
| 1015 | std::memcpy( | 1019 | std::memcpy( |
| 1016 | m_system.Memory().GetPointer<void>(GetInteger(start_partial_virt) + partial_offset), | 1020 | m_memory->GetPointer<void>(GetInteger(start_partial_virt) + partial_offset), |
| 1017 | m_system.Memory().GetPointer<void>( | 1021 | m_memory->GetPointer<void>(GetInteger(GetHeapVirtualAddress( |
| 1018 | GetInteger( | 1022 | m_system.Kernel().MemoryLayout(), cur_block_addr)) + |
| 1019 | GetHeapVirtualAddress(m_system.Kernel().MemoryLayout(), cur_block_addr)) + | 1023 | partial_offset), |
| 1020 | partial_offset), | ||
| 1021 | copy_size); | 1024 | copy_size); |
| 1022 | if (clear_size > 0) { | 1025 | if (clear_size > 0) { |
| 1023 | std::memset(m_system.Memory().GetPointer<void>(GetInteger(start_partial_virt) + | 1026 | std::memset(m_memory->GetPointer<void>(GetInteger(start_partial_virt) + |
| 1024 | partial_offset + copy_size), | 1027 | partial_offset + copy_size), |
| 1025 | fill_val, clear_size); | 1028 | fill_val, clear_size); |
| 1026 | } | 1029 | } |
| 1027 | } else { | 1030 | } else { |
| 1028 | std::memset(m_system.Memory().GetPointer<void>(GetInteger(start_partial_virt)), | 1031 | std::memset(m_memory->GetPointer<void>(GetInteger(start_partial_virt)), fill_val, |
| 1029 | fill_val, PageSize); | 1032 | PageSize); |
| 1030 | } | 1033 | } |
| 1031 | 1034 | ||
| 1032 | // Map the page. | 1035 | // Map the page. |
| @@ -1099,15 +1102,14 @@ Result KPageTable::SetupForIpcServer(KProcessAddress* out_addr, size_t size, | |||
| 1099 | GetHeapVirtualAddress(m_system.Kernel().MemoryLayout(), end_partial_page); | 1102 | GetHeapVirtualAddress(m_system.Kernel().MemoryLayout(), end_partial_page); |
| 1100 | if (send) { | 1103 | if (send) { |
| 1101 | const size_t copy_size = src_end - mapping_src_end; | 1104 | const size_t copy_size = src_end - mapping_src_end; |
| 1102 | std::memcpy(m_system.Memory().GetPointer<void>(GetInteger(end_partial_virt)), | 1105 | std::memcpy(m_memory->GetPointer<void>(GetInteger(end_partial_virt)), |
| 1103 | m_system.Memory().GetPointer<void>(GetInteger(GetHeapVirtualAddress( | 1106 | m_memory->GetPointer<void>(GetInteger(GetHeapVirtualAddress( |
| 1104 | m_system.Kernel().MemoryLayout(), cur_block_addr))), | 1107 | m_system.Kernel().MemoryLayout(), cur_block_addr))), |
| 1105 | copy_size); | 1108 | copy_size); |
| 1106 | std::memset( | 1109 | std::memset(m_memory->GetPointer<void>(GetInteger(end_partial_virt) + copy_size), |
| 1107 | m_system.Memory().GetPointer<void>(GetInteger(end_partial_virt) + copy_size), | 1110 | fill_val, PageSize - copy_size); |
| 1108 | fill_val, PageSize - copy_size); | ||
| 1109 | } else { | 1111 | } else { |
| 1110 | std::memset(m_system.Memory().GetPointer<void>(GetInteger(end_partial_virt)), fill_val, | 1112 | std::memset(m_memory->GetPointer<void>(GetInteger(end_partial_virt)), fill_val, |
| 1111 | PageSize); | 1113 | PageSize); |
| 1112 | } | 1114 | } |
| 1113 | 1115 | ||
| @@ -2800,7 +2802,7 @@ Result KPageTable::SetHeapSize(u64* out, size_t size) { | |||
| 2800 | 2802 | ||
| 2801 | // Clear all the newly allocated pages. | 2803 | // Clear all the newly allocated pages. |
| 2802 | for (size_t cur_page = 0; cur_page < num_pages; ++cur_page) { | 2804 | for (size_t cur_page = 0; cur_page < num_pages; ++cur_page) { |
| 2803 | std::memset(m_system.Memory().GetPointer(m_current_heap_end + (cur_page * PageSize)), 0, | 2805 | std::memset(m_memory->GetPointer(m_current_heap_end + (cur_page * PageSize)), 0, |
| 2804 | PageSize); | 2806 | PageSize); |
| 2805 | } | 2807 | } |
| 2806 | 2808 | ||
| @@ -3006,7 +3008,7 @@ Result KPageTable::Operate(KProcessAddress addr, size_t num_pages, const KPageGr | |||
| 3006 | const size_t size{node.GetNumPages() * PageSize}; | 3008 | const size_t size{node.GetNumPages() * PageSize}; |
| 3007 | 3009 | ||
| 3008 | // Map the pages. | 3010 | // Map the pages. |
| 3009 | m_system.Memory().MapMemoryRegion(*m_page_table_impl, addr, size, node.GetAddress()); | 3011 | m_memory->MapMemoryRegion(*m_page_table_impl, addr, size, node.GetAddress()); |
| 3010 | 3012 | ||
| 3011 | addr += size; | 3013 | addr += size; |
| 3012 | } | 3014 | } |
| @@ -3039,14 +3041,14 @@ Result KPageTable::Operate(KProcessAddress addr, size_t num_pages, KMemoryPermis | |||
| 3039 | SCOPE_EXIT({ pages_to_close.CloseAndReset(); }); | 3041 | SCOPE_EXIT({ pages_to_close.CloseAndReset(); }); |
| 3040 | 3042 | ||
| 3041 | this->AddRegionToPages(addr, num_pages, pages_to_close); | 3043 | this->AddRegionToPages(addr, num_pages, pages_to_close); |
| 3042 | m_system.Memory().UnmapRegion(*m_page_table_impl, addr, num_pages * PageSize); | 3044 | m_memory->UnmapRegion(*m_page_table_impl, addr, num_pages * PageSize); |
| 3043 | break; | 3045 | break; |
| 3044 | } | 3046 | } |
| 3045 | case OperationType::MapFirst: | 3047 | case OperationType::MapFirst: |
| 3046 | case OperationType::Map: { | 3048 | case OperationType::Map: { |
| 3047 | ASSERT(map_addr); | 3049 | ASSERT(map_addr); |
| 3048 | ASSERT(Common::IsAligned(GetInteger(map_addr), PageSize)); | 3050 | ASSERT(Common::IsAligned(GetInteger(map_addr), PageSize)); |
| 3049 | m_system.Memory().MapMemoryRegion(*m_page_table_impl, addr, num_pages * PageSize, map_addr); | 3051 | m_memory->MapMemoryRegion(*m_page_table_impl, addr, num_pages * PageSize, map_addr); |
| 3050 | 3052 | ||
| 3051 | // Open references to pages, if we should. | 3053 | // Open references to pages, if we should. |
| 3052 | if (IsHeapPhysicalAddress(m_kernel.MemoryLayout(), map_addr)) { | 3054 | if (IsHeapPhysicalAddress(m_kernel.MemoryLayout(), map_addr)) { |
diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h index 1917b2a98..022d15f35 100644 --- a/src/core/hle/kernel/k_page_table.h +++ b/src/core/hle/kernel/k_page_table.h | |||
| @@ -66,7 +66,8 @@ public: | |||
| 66 | Result InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr, | 66 | Result InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr, |
| 67 | bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, | 67 | bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, |
| 68 | KProcessAddress code_addr, size_t code_size, | 68 | KProcessAddress code_addr, size_t code_size, |
| 69 | KSystemResource* system_resource, KResourceLimit* resource_limit); | 69 | KSystemResource* system_resource, KResourceLimit* resource_limit, |
| 70 | Core::Memory::Memory& memory); | ||
| 70 | 71 | ||
| 71 | void Finalize(); | 72 | void Finalize(); |
| 72 | 73 | ||
| @@ -546,6 +547,7 @@ private: | |||
| 546 | 547 | ||
| 547 | Core::System& m_system; | 548 | Core::System& m_system; |
| 548 | KernelCore& m_kernel; | 549 | KernelCore& m_kernel; |
| 550 | Core::Memory::Memory* m_memory{}; | ||
| 549 | }; | 551 | }; |
| 550 | 552 | ||
| 551 | } // namespace Kernel | 553 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index 53f8139f3..efe86ad27 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp | |||
| @@ -367,8 +367,8 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std: | |||
| 367 | // Initialize process address space | 367 | // Initialize process address space |
| 368 | if (const Result result{m_page_table.InitializeForProcess( | 368 | if (const Result result{m_page_table.InitializeForProcess( |
| 369 | metadata.GetAddressSpaceType(), false, false, false, KMemoryManager::Pool::Application, | 369 | metadata.GetAddressSpaceType(), false, false, false, KMemoryManager::Pool::Application, |
| 370 | 0x8000000, code_size, std::addressof(m_kernel.GetAppSystemResource()), | 370 | 0x8000000, code_size, std::addressof(m_kernel.GetAppSystemResource()), m_resource_limit, |
| 371 | m_resource_limit)}; | 371 | m_kernel.System().ApplicationMemory())}; |
| 372 | result.IsError()) { | 372 | result.IsError()) { |
| 373 | R_RETURN(result); | 373 | R_RETURN(result); |
| 374 | } | 374 | } |
| @@ -592,8 +592,7 @@ Result KProcess::DeleteThreadLocalRegion(KProcessAddress addr) { | |||
| 592 | R_SUCCEED(); | 592 | R_SUCCEED(); |
| 593 | } | 593 | } |
| 594 | 594 | ||
| 595 | bool KProcess::InsertWatchpoint(Core::System& system, KProcessAddress addr, u64 size, | 595 | bool KProcess::InsertWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type) { |
| 596 | DebugWatchpointType type) { | ||
| 597 | const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) { | 596 | const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) { |
| 598 | return wp.type == DebugWatchpointType::None; | 597 | return wp.type == DebugWatchpointType::None; |
| 599 | })}; | 598 | })}; |
| @@ -609,14 +608,13 @@ bool KProcess::InsertWatchpoint(Core::System& system, KProcessAddress addr, u64 | |||
| 609 | for (KProcessAddress page = Common::AlignDown(GetInteger(addr), PageSize); page < addr + size; | 608 | for (KProcessAddress page = Common::AlignDown(GetInteger(addr), PageSize); page < addr + size; |
| 610 | page += PageSize) { | 609 | page += PageSize) { |
| 611 | m_debug_page_refcounts[page]++; | 610 | m_debug_page_refcounts[page]++; |
| 612 | system.Memory().MarkRegionDebug(page, PageSize, true); | 611 | this->GetMemory().MarkRegionDebug(page, PageSize, true); |
| 613 | } | 612 | } |
| 614 | 613 | ||
| 615 | return true; | 614 | return true; |
| 616 | } | 615 | } |
| 617 | 616 | ||
| 618 | bool KProcess::RemoveWatchpoint(Core::System& system, KProcessAddress addr, u64 size, | 617 | bool KProcess::RemoveWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type) { |
| 619 | DebugWatchpointType type) { | ||
| 620 | const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) { | 618 | const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) { |
| 621 | return wp.start_address == addr && wp.end_address == addr + size && wp.type == type; | 619 | return wp.start_address == addr && wp.end_address == addr + size && wp.type == type; |
| 622 | })}; | 620 | })}; |
| @@ -633,7 +631,7 @@ bool KProcess::RemoveWatchpoint(Core::System& system, KProcessAddress addr, u64 | |||
| 633 | page += PageSize) { | 631 | page += PageSize) { |
| 634 | m_debug_page_refcounts[page]--; | 632 | m_debug_page_refcounts[page]--; |
| 635 | if (!m_debug_page_refcounts[page]) { | 633 | if (!m_debug_page_refcounts[page]) { |
| 636 | system.Memory().MarkRegionDebug(page, PageSize, false); | 634 | this->GetMemory().MarkRegionDebug(page, PageSize, false); |
| 637 | } | 635 | } |
| 638 | } | 636 | } |
| 639 | 637 | ||
| @@ -646,8 +644,7 @@ void KProcess::LoadModule(CodeSet code_set, KProcessAddress base_addr) { | |||
| 646 | m_page_table.SetProcessMemoryPermission(segment.addr + base_addr, segment.size, permission); | 644 | m_page_table.SetProcessMemoryPermission(segment.addr + base_addr, segment.size, permission); |
| 647 | }; | 645 | }; |
| 648 | 646 | ||
| 649 | m_kernel.System().Memory().WriteBlock(*this, base_addr, code_set.memory.data(), | 647 | this->GetMemory().WriteBlock(base_addr, code_set.memory.data(), code_set.memory.size()); |
| 650 | code_set.memory.size()); | ||
| 651 | 648 | ||
| 652 | ReprotectSegment(code_set.CodeSegment(), Svc::MemoryPermission::ReadExecute); | 649 | ReprotectSegment(code_set.CodeSegment(), Svc::MemoryPermission::ReadExecute); |
| 653 | ReprotectSegment(code_set.RODataSegment(), Svc::MemoryPermission::Read); | 650 | ReprotectSegment(code_set.RODataSegment(), Svc::MemoryPermission::Read); |
| @@ -706,4 +703,9 @@ Result KProcess::AllocateMainThreadStack(std::size_t stack_size) { | |||
| 706 | R_SUCCEED(); | 703 | R_SUCCEED(); |
| 707 | } | 704 | } |
| 708 | 705 | ||
| 706 | Core::Memory::Memory& KProcess::GetMemory() const { | ||
| 707 | // TODO: per-process memory | ||
| 708 | return m_kernel.System().ApplicationMemory(); | ||
| 709 | } | ||
| 710 | |||
| 709 | } // namespace Kernel | 711 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h index 04b6bbb86..925981d06 100644 --- a/src/core/hle/kernel/k_process.h +++ b/src/core/hle/kernel/k_process.h | |||
| @@ -22,8 +22,12 @@ | |||
| 22 | #include "core/hle/result.h" | 22 | #include "core/hle/result.h" |
| 23 | 23 | ||
| 24 | namespace Core { | 24 | namespace Core { |
| 25 | namespace Memory { | ||
| 26 | class Memory; | ||
| 27 | }; | ||
| 28 | |||
| 25 | class System; | 29 | class System; |
| 26 | } | 30 | } // namespace Core |
| 27 | 31 | ||
| 28 | namespace FileSys { | 32 | namespace FileSys { |
| 29 | class ProgramMetadata; | 33 | class ProgramMetadata; |
| @@ -135,6 +139,9 @@ public: | |||
| 135 | return m_handle_table; | 139 | return m_handle_table; |
| 136 | } | 140 | } |
| 137 | 141 | ||
| 142 | /// Gets a reference to process's memory. | ||
| 143 | Core::Memory::Memory& GetMemory() const; | ||
| 144 | |||
| 138 | Result SignalToAddress(KProcessAddress address) { | 145 | Result SignalToAddress(KProcessAddress address) { |
| 139 | return m_condition_var.SignalToAddress(address); | 146 | return m_condition_var.SignalToAddress(address); |
| 140 | } | 147 | } |
| @@ -397,12 +404,10 @@ public: | |||
| 397 | // Debug watchpoint management | 404 | // Debug watchpoint management |
| 398 | 405 | ||
| 399 | // Attempts to insert a watchpoint into a free slot. Returns false if none are available. | 406 | // Attempts to insert a watchpoint into a free slot. Returns false if none are available. |
| 400 | bool InsertWatchpoint(Core::System& system, KProcessAddress addr, u64 size, | 407 | bool InsertWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type); |
| 401 | DebugWatchpointType type); | ||
| 402 | 408 | ||
| 403 | // Attempts to remove the watchpoint specified by the given parameters. | 409 | // Attempts to remove the watchpoint specified by the given parameters. |
| 404 | bool RemoveWatchpoint(Core::System& system, KProcessAddress addr, u64 size, | 410 | bool RemoveWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type); |
| 405 | DebugWatchpointType type); | ||
| 406 | 411 | ||
| 407 | const std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS>& GetWatchpoints() const { | 412 | const std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS>& GetWatchpoints() const { |
| 408 | return m_watchpoints; | 413 | return m_watchpoints; |
diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp index 2288ee435..c66aff501 100644 --- a/src/core/hle/kernel/k_server_session.cpp +++ b/src/core/hle/kernel/k_server_session.cpp | |||
| @@ -222,7 +222,7 @@ Result KServerSession::SendReply(bool is_hle) { | |||
| 222 | // HLE servers write directly to a pointer to the thread command buffer. Therefore | 222 | // HLE servers write directly to a pointer to the thread command buffer. Therefore |
| 223 | // the reply has already been written in this case. | 223 | // the reply has already been written in this case. |
| 224 | } else { | 224 | } else { |
| 225 | Core::Memory::Memory& memory{m_kernel.System().Memory()}; | 225 | Core::Memory::Memory& memory{client_thread->GetOwnerProcess()->GetMemory()}; |
| 226 | KThread* server_thread{GetCurrentThreadPointer(m_kernel)}; | 226 | KThread* server_thread{GetCurrentThreadPointer(m_kernel)}; |
| 227 | UNIMPLEMENTED_IF(server_thread->GetOwnerProcess() != client_thread->GetOwnerProcess()); | 227 | UNIMPLEMENTED_IF(server_thread->GetOwnerProcess() != client_thread->GetOwnerProcess()); |
| 228 | 228 | ||
| @@ -319,7 +319,7 @@ Result KServerSession::ReceiveRequest(std::shared_ptr<Service::HLERequestContext | |||
| 319 | // bool recv_list_broken = false; | 319 | // bool recv_list_broken = false; |
| 320 | 320 | ||
| 321 | // Receive the message. | 321 | // Receive the message. |
| 322 | Core::Memory::Memory& memory{m_kernel.System().Memory()}; | 322 | Core::Memory::Memory& memory{client_thread->GetOwnerProcess()->GetMemory()}; |
| 323 | if (out_context != nullptr) { | 323 | if (out_context != nullptr) { |
| 324 | // HLE request. | 324 | // HLE request. |
| 325 | u32* cmd_buf{reinterpret_cast<u32*>(memory.GetPointer(client_message))}; | 325 | u32* cmd_buf{reinterpret_cast<u32*>(memory.GetPointer(client_message))}; |
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index 9d101c640..70480b725 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp | |||
| @@ -546,7 +546,7 @@ u16 KThread::GetUserDisableCount() const { | |||
| 546 | return {}; | 546 | return {}; |
| 547 | } | 547 | } |
| 548 | 548 | ||
| 549 | auto& memory = m_kernel.System().Memory(); | 549 | auto& memory = this->GetOwnerProcess()->GetMemory(); |
| 550 | return memory.Read16(m_tls_address + offsetof(ThreadLocalRegion, disable_count)); | 550 | return memory.Read16(m_tls_address + offsetof(ThreadLocalRegion, disable_count)); |
| 551 | } | 551 | } |
| 552 | 552 | ||
| @@ -556,7 +556,7 @@ void KThread::SetInterruptFlag() { | |||
| 556 | return; | 556 | return; |
| 557 | } | 557 | } |
| 558 | 558 | ||
| 559 | auto& memory = m_kernel.System().Memory(); | 559 | auto& memory = this->GetOwnerProcess()->GetMemory(); |
| 560 | memory.Write16(m_tls_address + offsetof(ThreadLocalRegion, interrupt_flag), 1); | 560 | memory.Write16(m_tls_address + offsetof(ThreadLocalRegion, interrupt_flag), 1); |
| 561 | } | 561 | } |
| 562 | 562 | ||
| @@ -566,7 +566,7 @@ void KThread::ClearInterruptFlag() { | |||
| 566 | return; | 566 | return; |
| 567 | } | 567 | } |
| 568 | 568 | ||
| 569 | auto& memory = m_kernel.System().Memory(); | 569 | auto& memory = this->GetOwnerProcess()->GetMemory(); |
| 570 | memory.Write16(m_tls_address + offsetof(ThreadLocalRegion, interrupt_flag), 0); | 570 | memory.Write16(m_tls_address + offsetof(ThreadLocalRegion, interrupt_flag), 0); |
| 571 | } | 571 | } |
| 572 | 572 | ||
| @@ -1422,6 +1422,11 @@ s32 GetCurrentCoreId(KernelCore& kernel) { | |||
| 1422 | return GetCurrentThread(kernel).GetCurrentCore(); | 1422 | return GetCurrentThread(kernel).GetCurrentCore(); |
| 1423 | } | 1423 | } |
| 1424 | 1424 | ||
| 1425 | Core::Memory::Memory& GetCurrentMemory(KernelCore& kernel) { | ||
| 1426 | // TODO: per-process memory | ||
| 1427 | return kernel.System().ApplicationMemory(); | ||
| 1428 | } | ||
| 1429 | |||
| 1425 | KScopedDisableDispatch::~KScopedDisableDispatch() { | 1430 | KScopedDisableDispatch::~KScopedDisableDispatch() { |
| 1426 | // If we are shutting down the kernel, none of this is relevant anymore. | 1431 | // If we are shutting down the kernel, none of this is relevant anymore. |
| 1427 | if (m_kernel.IsShuttingDown()) { | 1432 | if (m_kernel.IsShuttingDown()) { |
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index 0fa9672bf..9c1a41128 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h | |||
| @@ -34,6 +34,9 @@ class Fiber; | |||
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | namespace Core { | 36 | namespace Core { |
| 37 | namespace Memory { | ||
| 38 | class Memory; | ||
| 39 | } | ||
| 37 | class ARM_Interface; | 40 | class ARM_Interface; |
| 38 | class System; | 41 | class System; |
| 39 | } // namespace Core | 42 | } // namespace Core |
| @@ -113,6 +116,7 @@ KThread& GetCurrentThread(KernelCore& kernel); | |||
| 113 | KProcess* GetCurrentProcessPointer(KernelCore& kernel); | 116 | KProcess* GetCurrentProcessPointer(KernelCore& kernel); |
| 114 | KProcess& GetCurrentProcess(KernelCore& kernel); | 117 | KProcess& GetCurrentProcess(KernelCore& kernel); |
| 115 | s32 GetCurrentCoreId(KernelCore& kernel); | 118 | s32 GetCurrentCoreId(KernelCore& kernel); |
| 119 | Core::Memory::Memory& GetCurrentMemory(KernelCore& kernel); | ||
| 116 | 120 | ||
| 117 | class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KWorkerTask>, | 121 | class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KWorkerTask>, |
| 118 | public boost::intrusive::list_base_hook<>, | 122 | public boost::intrusive::list_base_hook<>, |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 29809b2c5..4f3366c9d 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -102,7 +102,7 @@ struct KernelCore::Impl { | |||
| 102 | void InitializeCores() { | 102 | void InitializeCores() { |
| 103 | for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { | 103 | for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { |
| 104 | cores[core_id]->Initialize((*application_process).Is64BitProcess()); | 104 | cores[core_id]->Initialize((*application_process).Is64BitProcess()); |
| 105 | system.Memory().SetCurrentPageTable(*application_process, core_id); | 105 | system.ApplicationMemory().SetCurrentPageTable(*application_process, core_id); |
| 106 | } | 106 | } |
| 107 | } | 107 | } |
| 108 | 108 | ||
| @@ -206,7 +206,7 @@ struct KernelCore::Impl { | |||
| 206 | 206 | ||
| 207 | void InitializePhysicalCores() { | 207 | void InitializePhysicalCores() { |
| 208 | exclusive_monitor = | 208 | exclusive_monitor = |
| 209 | Core::MakeExclusiveMonitor(system.Memory(), Core::Hardware::NUM_CPU_CORES); | 209 | Core::MakeExclusiveMonitor(system.ApplicationMemory(), Core::Hardware::NUM_CPU_CORES); |
| 210 | for (u32 i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { | 210 | for (u32 i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { |
| 211 | const s32 core{static_cast<s32>(i)}; | 211 | const s32 core{static_cast<s32>(i)}; |
| 212 | 212 | ||
diff --git a/src/core/hle/kernel/svc/svc_cache.cpp b/src/core/hle/kernel/svc/svc_cache.cpp index 1779832d3..082942dab 100644 --- a/src/core/hle/kernel/svc/svc_cache.cpp +++ b/src/core/hle/kernel/svc/svc_cache.cpp | |||
| @@ -46,7 +46,7 @@ Result FlushProcessDataCache(Core::System& system, Handle process_handle, u64 ad | |||
| 46 | R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory); | 46 | R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory); |
| 47 | 47 | ||
| 48 | // Perform the operation. | 48 | // Perform the operation. |
| 49 | R_RETURN(system.Memory().FlushDataCache(*process, address, size)); | 49 | R_RETURN(GetCurrentMemory(system.Kernel()).FlushDataCache(address, size)); |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | void FlushEntireDataCache64(Core::System& system) { | 52 | void FlushEntireDataCache64(Core::System& system) { |
diff --git a/src/core/hle/kernel/svc/svc_debug_string.cpp b/src/core/hle/kernel/svc/svc_debug_string.cpp index 8771d2b01..4c14ce668 100644 --- a/src/core/hle/kernel/svc/svc_debug_string.cpp +++ b/src/core/hle/kernel/svc/svc_debug_string.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/core.h" | 4 | #include "core/core.h" |
| 5 | #include "core/hle/kernel/k_thread.h" | ||
| 5 | #include "core/hle/kernel/svc.h" | 6 | #include "core/hle/kernel/svc.h" |
| 6 | #include "core/memory.h" | 7 | #include "core/memory.h" |
| 7 | 8 | ||
| @@ -12,7 +13,7 @@ Result OutputDebugString(Core::System& system, u64 address, u64 len) { | |||
| 12 | R_SUCCEED_IF(len == 0); | 13 | R_SUCCEED_IF(len == 0); |
| 13 | 14 | ||
| 14 | std::string str(len, '\0'); | 15 | std::string str(len, '\0'); |
| 15 | system.Memory().ReadBlock(address, str.data(), str.size()); | 16 | GetCurrentMemory(system.Kernel()).ReadBlock(address, str.data(), str.size()); |
| 16 | LOG_DEBUG(Debug_Emulated, "{}", str); | 17 | LOG_DEBUG(Debug_Emulated, "{}", str); |
| 17 | 18 | ||
| 18 | R_SUCCEED(); | 19 | R_SUCCEED(); |
diff --git a/src/core/hle/kernel/svc/svc_exception.cpp b/src/core/hle/kernel/svc/svc_exception.cpp index 4ab5f471f..580cf2f75 100644 --- a/src/core/hle/kernel/svc/svc_exception.cpp +++ b/src/core/hle/kernel/svc/svc_exception.cpp | |||
| @@ -25,7 +25,7 @@ void Break(Core::System& system, BreakReason reason, u64 info1, u64 info2) { | |||
| 25 | return; | 25 | return; |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | auto& memory = system.Memory(); | 28 | auto& memory = GetCurrentMemory(system.Kernel()); |
| 29 | 29 | ||
| 30 | // This typically is an error code so we're going to assume this is the case | 30 | // This typically is an error code so we're going to assume this is the case |
| 31 | if (sz == sizeof(u32)) { | 31 | if (sz == sizeof(u32)) { |
diff --git a/src/core/hle/kernel/svc/svc_ipc.cpp b/src/core/hle/kernel/svc/svc_ipc.cpp index 2a8c09a79..ea03068aa 100644 --- a/src/core/hle/kernel/svc/svc_ipc.cpp +++ b/src/core/hle/kernel/svc/svc_ipc.cpp | |||
| @@ -41,12 +41,12 @@ Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_ad | |||
| 41 | auto& handle_table = GetCurrentProcess(kernel).GetHandleTable(); | 41 | auto& handle_table = GetCurrentProcess(kernel).GetHandleTable(); |
| 42 | 42 | ||
| 43 | R_UNLESS(0 <= num_handles && num_handles <= ArgumentHandleCountMax, ResultOutOfRange); | 43 | R_UNLESS(0 <= num_handles && num_handles <= ArgumentHandleCountMax, ResultOutOfRange); |
| 44 | R_UNLESS(system.Memory().IsValidVirtualAddressRange( | 44 | R_UNLESS(GetCurrentMemory(kernel).IsValidVirtualAddressRange( |
| 45 | handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)), | 45 | handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)), |
| 46 | ResultInvalidPointer); | 46 | ResultInvalidPointer); |
| 47 | 47 | ||
| 48 | std::vector<Handle> handles(num_handles); | 48 | std::vector<Handle> handles(num_handles); |
| 49 | system.Memory().ReadBlock(handles_addr, handles.data(), sizeof(Handle) * num_handles); | 49 | GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(), sizeof(Handle) * num_handles); |
| 50 | 50 | ||
| 51 | // Convert handle list to object table. | 51 | // Convert handle list to object table. |
| 52 | std::vector<KSynchronizationObject*> objs(num_handles); | 52 | std::vector<KSynchronizationObject*> objs(num_handles); |
diff --git a/src/core/hle/kernel/svc/svc_port.cpp b/src/core/hle/kernel/svc/svc_port.cpp index c6eb70422..abba757c7 100644 --- a/src/core/hle/kernel/svc/svc_port.cpp +++ b/src/core/hle/kernel/svc/svc_port.cpp | |||
| @@ -14,7 +14,8 @@ namespace Kernel::Svc { | |||
| 14 | 14 | ||
| 15 | Result ConnectToNamedPort(Core::System& system, Handle* out, u64 user_name) { | 15 | Result ConnectToNamedPort(Core::System& system, Handle* out, u64 user_name) { |
| 16 | // Copy the provided name from user memory to kernel memory. | 16 | // Copy the provided name from user memory to kernel memory. |
| 17 | auto string_name = system.Memory().ReadCString(user_name, KObjectName::NameLengthMax); | 17 | auto string_name = |
| 18 | GetCurrentMemory(system.Kernel()).ReadCString(user_name, KObjectName::NameLengthMax); | ||
| 18 | 19 | ||
| 19 | std::array<char, KObjectName::NameLengthMax> name{}; | 20 | std::array<char, KObjectName::NameLengthMax> name{}; |
| 20 | std::strncpy(name.data(), string_name.c_str(), KObjectName::NameLengthMax - 1); | 21 | std::strncpy(name.data(), string_name.c_str(), KObjectName::NameLengthMax - 1); |
| @@ -62,7 +63,8 @@ Result ConnectToPort(Core::System& system, Handle* out_handle, Handle port) { | |||
| 62 | Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name, | 63 | Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name, |
| 63 | int32_t max_sessions) { | 64 | int32_t max_sessions) { |
| 64 | // Copy the provided name from user memory to kernel memory. | 65 | // Copy the provided name from user memory to kernel memory. |
| 65 | auto string_name = system.Memory().ReadCString(user_name, KObjectName::NameLengthMax); | 66 | auto string_name = |
| 67 | GetCurrentMemory(system.Kernel()).ReadCString(user_name, KObjectName::NameLengthMax); | ||
| 66 | 68 | ||
| 67 | // Copy the provided name from user memory to kernel memory. | 69 | // Copy the provided name from user memory to kernel memory. |
| 68 | std::array<char, KObjectName::NameLengthMax> name{}; | 70 | std::array<char, KObjectName::NameLengthMax> name{}; |
diff --git a/src/core/hle/kernel/svc/svc_process.cpp b/src/core/hle/kernel/svc/svc_process.cpp index 3c3579947..619ed16a3 100644 --- a/src/core/hle/kernel/svc/svc_process.cpp +++ b/src/core/hle/kernel/svc/svc_process.cpp | |||
| @@ -73,7 +73,7 @@ Result GetProcessList(Core::System& system, s32* out_num_processes, u64 out_proc | |||
| 73 | R_THROW(ResultInvalidCurrentMemory); | 73 | R_THROW(ResultInvalidCurrentMemory); |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | auto& memory = system.Memory(); | 76 | auto& memory = GetCurrentMemory(kernel); |
| 77 | const auto& process_list = kernel.GetProcessList(); | 77 | const auto& process_list = kernel.GetProcessList(); |
| 78 | const auto num_processes = process_list.size(); | 78 | const auto num_processes = process_list.size(); |
| 79 | const auto copy_amount = | 79 | const auto copy_amount = |
diff --git a/src/core/hle/kernel/svc/svc_query_memory.cpp b/src/core/hle/kernel/svc/svc_query_memory.cpp index 5db5611f0..4d9fcd25f 100644 --- a/src/core/hle/kernel/svc/svc_query_memory.cpp +++ b/src/core/hle/kernel/svc/svc_query_memory.cpp | |||
| @@ -30,10 +30,10 @@ Result QueryProcessMemory(Core::System& system, uint64_t out_memory_info, PageIn | |||
| 30 | R_THROW(ResultInvalidHandle); | 30 | R_THROW(ResultInvalidHandle); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | auto& memory{system.Memory()}; | 33 | auto& current_memory{GetCurrentMemory(system.Kernel())}; |
| 34 | const auto memory_info{process->PageTable().QueryInfo(address).GetSvcMemoryInfo()}; | 34 | const auto memory_info{process->PageTable().QueryInfo(address).GetSvcMemoryInfo()}; |
| 35 | 35 | ||
| 36 | memory.WriteBlock(out_memory_info, std::addressof(memory_info), sizeof(memory_info)); | 36 | current_memory.WriteBlock(out_memory_info, std::addressof(memory_info), sizeof(memory_info)); |
| 37 | 37 | ||
| 38 | //! This is supposed to be part of the QueryInfo call. | 38 | //! This is supposed to be part of the QueryInfo call. |
| 39 | *out_page_info = {}; | 39 | *out_page_info = {}; |
diff --git a/src/core/hle/kernel/svc/svc_synchronization.cpp b/src/core/hle/kernel/svc/svc_synchronization.cpp index e490a13ae..04d65f0bd 100644 --- a/src/core/hle/kernel/svc/svc_synchronization.cpp +++ b/src/core/hle/kernel/svc/svc_synchronization.cpp | |||
| @@ -90,7 +90,8 @@ Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_ha | |||
| 90 | 90 | ||
| 91 | std::vector<Handle> handles(num_handles); | 91 | std::vector<Handle> handles(num_handles); |
| 92 | if (num_handles > 0) { | 92 | if (num_handles > 0) { |
| 93 | system.Memory().ReadBlock(user_handles, handles.data(), num_handles * sizeof(Handle)); | 93 | GetCurrentMemory(system.Kernel()) |
| 94 | .ReadBlock(user_handles, handles.data(), num_handles * sizeof(Handle)); | ||
| 94 | } | 95 | } |
| 95 | 96 | ||
| 96 | R_RETURN(WaitSynchronization(system, out_index, handles.data(), num_handles, timeout_ns)); | 97 | R_RETURN(WaitSynchronization(system, out_index, handles.data(), num_handles, timeout_ns)); |
diff --git a/src/core/hle/kernel/svc/svc_thread.cpp b/src/core/hle/kernel/svc/svc_thread.cpp index 0be4858a2..37b54079c 100644 --- a/src/core/hle/kernel/svc/svc_thread.cpp +++ b/src/core/hle/kernel/svc/svc_thread.cpp | |||
| @@ -178,7 +178,7 @@ Result GetThreadContext3(Core::System& system, u64 out_context, Handle thread_ha | |||
| 178 | R_TRY(thread->GetThreadContext3(context)); | 178 | R_TRY(thread->GetThreadContext3(context)); |
| 179 | 179 | ||
| 180 | // Copy the thread context to user space. | 180 | // Copy the thread context to user space. |
| 181 | system.Memory().WriteBlock(out_context, context.data(), context.size()); | 181 | GetCurrentMemory(kernel).WriteBlock(out_context, context.data(), context.size()); |
| 182 | 182 | ||
| 183 | R_SUCCEED(); | 183 | R_SUCCEED(); |
| 184 | } | 184 | } |
| @@ -242,7 +242,7 @@ Result GetThreadList(Core::System& system, s32* out_num_threads, u64 out_thread_ | |||
| 242 | R_THROW(ResultInvalidCurrentMemory); | 242 | R_THROW(ResultInvalidCurrentMemory); |
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | auto& memory = system.Memory(); | 245 | auto& memory = GetCurrentMemory(system.Kernel()); |
| 246 | const auto& thread_list = current_process->GetThreadList(); | 246 | const auto& thread_list = current_process->GetThreadList(); |
| 247 | const auto num_threads = thread_list.size(); | 247 | const auto num_threads = thread_list.size(); |
| 248 | const auto copy_amount = std::min(static_cast<std::size_t>(out_thread_ids_size), num_threads); | 248 | const auto copy_amount = std::min(static_cast<std::size_t>(out_thread_ids_size), num_threads); |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 8943e4a81..a17c46121 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -1274,7 +1274,8 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(HLERequestContext& ctx) | |||
| 1274 | } | 1274 | } |
| 1275 | 1275 | ||
| 1276 | std::vector<u8> memory(transfer_mem->GetSize()); | 1276 | std::vector<u8> memory(transfer_mem->GetSize()); |
| 1277 | system.Memory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(), memory.size()); | 1277 | system.ApplicationMemory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(), |
| 1278 | memory.size()); | ||
| 1278 | 1279 | ||
| 1279 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 1280 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 1280 | rb.Push(ResultSuccess); | 1281 | rb.Push(ResultSuccess); |
| @@ -1307,7 +1308,8 @@ void ILibraryAppletCreator::CreateHandleStorage(HLERequestContext& ctx) { | |||
| 1307 | } | 1308 | } |
| 1308 | 1309 | ||
| 1309 | std::vector<u8> memory(transfer_mem->GetSize()); | 1310 | std::vector<u8> memory(transfer_mem->GetSize()); |
| 1310 | system.Memory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(), memory.size()); | 1311 | system.ApplicationMemory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(), |
| 1312 | memory.size()); | ||
| 1311 | 1313 | ||
| 1312 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 1314 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 1313 | rb.Push(ResultSuccess); | 1315 | rb.Push(ResultSuccess); |
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.cpp b/src/core/hle/service/hid/controllers/console_sixaxis.cpp index 37f2e4405..bcb272eaf 100644 --- a/src/core/hle/service/hid/controllers/console_sixaxis.cpp +++ b/src/core/hle/service/hid/controllers/console_sixaxis.cpp | |||
| @@ -60,7 +60,8 @@ void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_ti | |||
| 60 | 60 | ||
| 61 | // Update seven six axis transfer memory | 61 | // Update seven six axis transfer memory |
| 62 | seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state); | 62 | seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state); |
| 63 | system.Memory().WriteBlock(transfer_memory, &seven_sixaxis_lifo, sizeof(seven_sixaxis_lifo)); | 63 | system.ApplicationMemory().WriteBlock(transfer_memory, &seven_sixaxis_lifo, |
| 64 | sizeof(seven_sixaxis_lifo)); | ||
| 64 | } | 65 | } |
| 65 | 66 | ||
| 66 | void Controller_ConsoleSixAxis::SetTransferMemoryAddress(Common::ProcessAddress t_mem) { | 67 | void Controller_ConsoleSixAxis::SetTransferMemoryAddress(Common::ProcessAddress t_mem) { |
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index ba6f04d8d..21bd7b0c5 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -1388,7 +1388,8 @@ Result Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, | |||
| 1388 | return NpadIsDualJoycon; | 1388 | return NpadIsDualJoycon; |
| 1389 | } | 1389 | } |
| 1390 | 1390 | ||
| 1391 | // Disconnect the joycon at the second id and connect the dual joycon at the first index. | 1391 | // Disconnect the joycons and connect them as dual joycon at the first index. |
| 1392 | DisconnectNpad(npad_id_1); | ||
| 1392 | DisconnectNpad(npad_id_2); | 1393 | DisconnectNpad(npad_id_2); |
| 1393 | controller_1.is_dual_left_connected = true; | 1394 | controller_1.is_dual_left_connected = true; |
| 1394 | controller_1.is_dual_right_connected = true; | 1395 | controller_1.is_dual_right_connected = true; |
diff --git a/src/core/hle/service/hid/hidbus/ringcon.cpp b/src/core/hle/service/hid/hidbus/ringcon.cpp index 65a2dd521..378108012 100644 --- a/src/core/hle/service/hid/hidbus/ringcon.cpp +++ b/src/core/hle/service/hid/hidbus/ringcon.cpp | |||
| @@ -64,8 +64,8 @@ void RingController::OnUpdate() { | |||
| 64 | curr_entry.polling_data.out_size = sizeof(ringcon_value); | 64 | curr_entry.polling_data.out_size = sizeof(ringcon_value); |
| 65 | std::memcpy(curr_entry.polling_data.data.data(), &ringcon_value, sizeof(ringcon_value)); | 65 | std::memcpy(curr_entry.polling_data.data.data(), &ringcon_value, sizeof(ringcon_value)); |
| 66 | 66 | ||
| 67 | system.Memory().WriteBlock(transfer_memory, &enable_sixaxis_data, | 67 | system.ApplicationMemory().WriteBlock(transfer_memory, &enable_sixaxis_data, |
| 68 | sizeof(enable_sixaxis_data)); | 68 | sizeof(enable_sixaxis_data)); |
| 69 | break; | 69 | break; |
| 70 | } | 70 | } |
| 71 | default: | 71 | default: |
diff --git a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp b/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp index ca5d067e8..803a6277c 100644 --- a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp +++ b/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp | |||
| @@ -58,16 +58,16 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType | |||
| 58 | if (camera_data.format != current_config.origin_format) { | 58 | if (camera_data.format != current_config.origin_format) { |
| 59 | LOG_WARNING(Service_IRS, "Wrong Input format {} expected {}", camera_data.format, | 59 | LOG_WARNING(Service_IRS, "Wrong Input format {} expected {}", camera_data.format, |
| 60 | current_config.origin_format); | 60 | current_config.origin_format); |
| 61 | system.Memory().ZeroBlock(*system.ApplicationProcess(), transfer_memory, | 61 | system.ApplicationMemory().ZeroBlock(transfer_memory, |
| 62 | GetDataSize(current_config.trimming_format)); | 62 | GetDataSize(current_config.trimming_format)); |
| 63 | return; | 63 | return; |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | if (current_config.origin_format > current_config.trimming_format) { | 66 | if (current_config.origin_format > current_config.trimming_format) { |
| 67 | LOG_WARNING(Service_IRS, "Origin format {} is smaller than trimming format {}", | 67 | LOG_WARNING(Service_IRS, "Origin format {} is smaller than trimming format {}", |
| 68 | current_config.origin_format, current_config.trimming_format); | 68 | current_config.origin_format, current_config.trimming_format); |
| 69 | system.Memory().ZeroBlock(*system.ApplicationProcess(), transfer_memory, | 69 | system.ApplicationMemory().ZeroBlock(transfer_memory, |
| 70 | GetDataSize(current_config.trimming_format)); | 70 | GetDataSize(current_config.trimming_format)); |
| 71 | return; | 71 | return; |
| 72 | } | 72 | } |
| 73 | 73 | ||
| @@ -84,8 +84,8 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType | |||
| 84 | "Trimming area ({}, {}, {}, {}) is outside of origin area ({}, {})", | 84 | "Trimming area ({}, {}, {}, {}) is outside of origin area ({}, {})", |
| 85 | current_config.trimming_start_x, current_config.trimming_start_y, | 85 | current_config.trimming_start_x, current_config.trimming_start_y, |
| 86 | trimming_width, trimming_height, origin_width, origin_height); | 86 | trimming_width, trimming_height, origin_width, origin_height); |
| 87 | system.Memory().ZeroBlock(*system.ApplicationProcess(), transfer_memory, | 87 | system.ApplicationMemory().ZeroBlock(transfer_memory, |
| 88 | GetDataSize(current_config.trimming_format)); | 88 | GetDataSize(current_config.trimming_format)); |
| 89 | return; | 89 | return; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| @@ -99,8 +99,8 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType | |||
| 99 | } | 99 | } |
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | system.Memory().WriteBlock(transfer_memory, window_data.data(), | 102 | system.ApplicationMemory().WriteBlock(transfer_memory, window_data.data(), |
| 103 | GetDataSize(current_config.trimming_format)); | 103 | GetDataSize(current_config.trimming_format)); |
| 104 | 104 | ||
| 105 | if (!IsProcessorActive()) { | 105 | if (!IsProcessorActive()) { |
| 106 | StartProcessor(); | 106 | StartProcessor(); |
| @@ -148,7 +148,7 @@ Core::IrSensor::ImageTransferProcessorState ImageTransferProcessor::GetState( | |||
| 148 | std::vector<u8>& data) const { | 148 | std::vector<u8>& data) const { |
| 149 | const auto size = GetDataSize(current_config.trimming_format); | 149 | const auto size = GetDataSize(current_config.trimming_format); |
| 150 | data.resize(size); | 150 | data.resize(size); |
| 151 | system.Memory().ReadBlock(transfer_memory, data.data(), size); | 151 | system.ApplicationMemory().ReadBlock(transfer_memory, data.data(), size); |
| 152 | return processor_state; | 152 | return processor_state; |
| 153 | } | 153 | } |
| 154 | 154 | ||
diff --git a/src/core/hle/service/hle_ipc.cpp b/src/core/hle/service/hle_ipc.cpp index cca697c64..2290df705 100644 --- a/src/core/hle/service/hle_ipc.cpp +++ b/src/core/hle/service/hle_ipc.cpp | |||
| @@ -303,8 +303,7 @@ Result HLERequestContext::WriteToOutgoingCommandBuffer(Kernel::KThread& requesti | |||
| 303 | } | 303 | } |
| 304 | 304 | ||
| 305 | // Copy the translated command buffer back into the thread's command buffer area. | 305 | // Copy the translated command buffer back into the thread's command buffer area. |
| 306 | memory.WriteBlock(owner_process, requesting_thread.GetTlsAddress(), cmd_buf.data(), | 306 | memory.WriteBlock(requesting_thread.GetTlsAddress(), cmd_buf.data(), write_size * sizeof(u32)); |
| 307 | write_size * sizeof(u32)); | ||
| 308 | 307 | ||
| 309 | return ResultSuccess; | 308 | return ResultSuccess; |
| 310 | } | 309 | } |
diff --git a/src/core/hle/service/jit/jit.cpp b/src/core/hle/service/jit/jit.cpp index 607f27b21..be996870f 100644 --- a/src/core/hle/service/jit/jit.cpp +++ b/src/core/hle/service/jit/jit.cpp | |||
| @@ -24,8 +24,8 @@ class IJitEnvironment final : public ServiceFramework<IJitEnvironment> { | |||
| 24 | public: | 24 | public: |
| 25 | explicit IJitEnvironment(Core::System& system_, Kernel::KProcess& process_, CodeRange user_rx, | 25 | explicit IJitEnvironment(Core::System& system_, Kernel::KProcess& process_, CodeRange user_rx, |
| 26 | CodeRange user_ro) | 26 | CodeRange user_ro) |
| 27 | : ServiceFramework{system_, "IJitEnvironment"}, process{&process_}, context{ | 27 | : ServiceFramework{system_, "IJitEnvironment"}, process{&process_}, |
| 28 | system_.Memory()} { | 28 | context{system_.ApplicationMemory()} { |
| 29 | // clang-format off | 29 | // clang-format off |
| 30 | static const FunctionInfo functions[] = { | 30 | static const FunctionInfo functions[] = { |
| 31 | {0, &IJitEnvironment::GenerateCode, "GenerateCode"}, | 31 | {0, &IJitEnvironment::GenerateCode, "GenerateCode"}, |
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index 437dc2ea5..c42489ff9 100644 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp | |||
| @@ -225,7 +225,7 @@ public: | |||
| 225 | 225 | ||
| 226 | // Read NRR data from memory | 226 | // Read NRR data from memory |
| 227 | std::vector<u8> nrr_data(nrr_size); | 227 | std::vector<u8> nrr_data(nrr_size); |
| 228 | system.Memory().ReadBlock(nrr_address, nrr_data.data(), nrr_size); | 228 | system.ApplicationMemory().ReadBlock(nrr_address, nrr_data.data(), nrr_size); |
| 229 | NRRHeader header; | 229 | NRRHeader header; |
| 230 | std::memcpy(&header, nrr_data.data(), sizeof(NRRHeader)); | 230 | std::memcpy(&header, nrr_data.data(), sizeof(NRRHeader)); |
| 231 | 231 | ||
| @@ -314,7 +314,7 @@ public: | |||
| 314 | const auto is_region_available = [&](VAddr addr) { | 314 | const auto is_region_available = [&](VAddr addr) { |
| 315 | const auto end_addr = addr + size; | 315 | const auto end_addr = addr + size; |
| 316 | while (addr < end_addr) { | 316 | while (addr < end_addr) { |
| 317 | if (system.Memory().IsValidVirtualAddress(addr)) { | 317 | if (system.ApplicationMemory().IsValidVirtualAddress(addr)) { |
| 318 | return false; | 318 | return false; |
| 319 | } | 319 | } |
| 320 | 320 | ||
| @@ -427,8 +427,8 @@ public: | |||
| 427 | const VAddr bss_end_addr{ | 427 | const VAddr bss_end_addr{ |
| 428 | Common::AlignUp(bss_start + nro_header.bss_size, Kernel::PageSize)}; | 428 | Common::AlignUp(bss_start + nro_header.bss_size, Kernel::PageSize)}; |
| 429 | 429 | ||
| 430 | const auto CopyCode = [this, process](VAddr src_addr, VAddr dst_addr, u64 size) { | 430 | const auto CopyCode = [this](VAddr src_addr, VAddr dst_addr, u64 size) { |
| 431 | system.Memory().CopyBlock(*process, dst_addr, src_addr, size); | 431 | system.ApplicationMemory().CopyBlock(dst_addr, src_addr, size); |
| 432 | }; | 432 | }; |
| 433 | CopyCode(nro_addr + nro_header.segment_headers[TEXT_INDEX].memory_offset, text_start, | 433 | CopyCode(nro_addr + nro_header.segment_headers[TEXT_INDEX].memory_offset, text_start, |
| 434 | nro_header.segment_headers[TEXT_INDEX].memory_size); | 434 | nro_header.segment_headers[TEXT_INDEX].memory_size); |
| @@ -506,7 +506,7 @@ public: | |||
| 506 | 506 | ||
| 507 | // Read NRO data from memory | 507 | // Read NRO data from memory |
| 508 | std::vector<u8> nro_data(nro_size); | 508 | std::vector<u8> nro_data(nro_size); |
| 509 | system.Memory().ReadBlock(nro_address, nro_data.data(), nro_size); | 509 | system.ApplicationMemory().ReadBlock(nro_address, nro_data.data(), nro_size); |
| 510 | 510 | ||
| 511 | SHA256Hash hash{}; | 511 | SHA256Hash hash{}; |
| 512 | mbedtls_sha256_ret(nro_data.data(), nro_data.size(), hash.data(), 0); | 512 | mbedtls_sha256_ret(nro_data.data(), nro_data.size(), hash.data(), 0); |
diff --git a/src/core/hle/service/nfp/amiibo_crypto.cpp b/src/core/hle/service/nfp/amiibo_crypto.cpp index bba862fb2..a3622e792 100644 --- a/src/core/hle/service/nfp/amiibo_crypto.cpp +++ b/src/core/hle/service/nfp/amiibo_crypto.cpp | |||
| @@ -70,6 +70,10 @@ bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file) { | |||
| 70 | return true; | 70 | return true; |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | bool IsAmiiboValid(const NTAG215File& ntag_file) { | ||
| 74 | return IsAmiiboValid(EncodedDataToNfcData(ntag_file)); | ||
| 75 | } | ||
| 76 | |||
| 73 | NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) { | 77 | NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) { |
| 74 | NTAG215File encoded_data{}; | 78 | NTAG215File encoded_data{}; |
| 75 | 79 | ||
diff --git a/src/core/hle/service/nfp/amiibo_crypto.h b/src/core/hle/service/nfp/amiibo_crypto.h index c9fd67a39..f6208ee6b 100644 --- a/src/core/hle/service/nfp/amiibo_crypto.h +++ b/src/core/hle/service/nfp/amiibo_crypto.h | |||
| @@ -60,6 +60,9 @@ static_assert(sizeof(DerivedKeys) == 0x30, "DerivedKeys is an invalid size"); | |||
| 60 | /// Validates that the amiibo file is not corrupted | 60 | /// Validates that the amiibo file is not corrupted |
| 61 | bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file); | 61 | bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file); |
| 62 | 62 | ||
| 63 | /// Validates that the amiibo file is not corrupted | ||
| 64 | bool IsAmiiboValid(const NTAG215File& ntag_file); | ||
| 65 | |||
| 63 | /// Converts from encrypted file format to encoded file format | 66 | /// Converts from encrypted file format to encoded file format |
| 64 | NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data); | 67 | NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data); |
| 65 | 68 | ||
diff --git a/src/core/hle/service/nfp/nfp_device.cpp b/src/core/hle/service/nfp/nfp_device.cpp index 5990e1473..607e70968 100644 --- a/src/core/hle/service/nfp/nfp_device.cpp +++ b/src/core/hle/service/nfp/nfp_device.cpp | |||
| @@ -121,7 +121,16 @@ bool NfpDevice::LoadAmiibo(std::span<const u8> data) { | |||
| 121 | 121 | ||
| 122 | // TODO: Filter by allowed_protocols here | 122 | // TODO: Filter by allowed_protocols here |
| 123 | 123 | ||
| 124 | memcpy(&encrypted_tag_data, data.data(), sizeof(EncryptedNTAG215File)); | 124 | memcpy(&tag_data, data.data(), sizeof(EncryptedNTAG215File)); |
| 125 | is_plain_amiibo = AmiiboCrypto::IsAmiiboValid(tag_data); | ||
| 126 | |||
| 127 | if (is_plain_amiibo) { | ||
| 128 | encrypted_tag_data = AmiiboCrypto::EncodedDataToNfcData(tag_data); | ||
| 129 | LOG_INFO(Service_NFP, "Using plain amiibo"); | ||
| 130 | } else { | ||
| 131 | tag_data = {}; | ||
| 132 | memcpy(&encrypted_tag_data, data.data(), sizeof(EncryptedNTAG215File)); | ||
| 133 | } | ||
| 125 | 134 | ||
| 126 | device_state = DeviceState::TagFound; | 135 | device_state = DeviceState::TagFound; |
| 127 | deactivate_event->GetReadableEvent().Clear(); | 136 | deactivate_event->GetReadableEvent().Clear(); |
| @@ -232,13 +241,17 @@ Result NfpDevice::Flush() { | |||
| 232 | 241 | ||
| 233 | tag_data.write_counter++; | 242 | tag_data.write_counter++; |
| 234 | 243 | ||
| 235 | if (!AmiiboCrypto::EncodeAmiibo(tag_data, encrypted_tag_data)) { | 244 | std::vector<u8> data(sizeof(EncryptedNTAG215File)); |
| 236 | LOG_ERROR(Service_NFP, "Failed to encode data"); | 245 | if (is_plain_amiibo) { |
| 237 | return WriteAmiiboFailed; | 246 | memcpy(data.data(), &tag_data, sizeof(tag_data)); |
| 238 | } | 247 | } else { |
| 248 | if (!AmiiboCrypto::EncodeAmiibo(tag_data, encrypted_tag_data)) { | ||
| 249 | LOG_ERROR(Service_NFP, "Failed to encode data"); | ||
| 250 | return WriteAmiiboFailed; | ||
| 251 | } | ||
| 239 | 252 | ||
| 240 | std::vector<u8> data(sizeof(encrypted_tag_data)); | 253 | memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data)); |
| 241 | memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data)); | 254 | } |
| 242 | 255 | ||
| 243 | if (!npad_device->WriteNfc(data)) { | 256 | if (!npad_device->WriteNfc(data)) { |
| 244 | LOG_ERROR(Service_NFP, "Error writing to file"); | 257 | LOG_ERROR(Service_NFP, "Error writing to file"); |
| @@ -256,6 +269,13 @@ Result NfpDevice::Mount(MountTarget mount_target_) { | |||
| 256 | return WrongDeviceState; | 269 | return WrongDeviceState; |
| 257 | } | 270 | } |
| 258 | 271 | ||
| 272 | // The loaded amiibo is not encrypted | ||
| 273 | if (is_plain_amiibo) { | ||
| 274 | device_state = DeviceState::TagMounted; | ||
| 275 | mount_target = mount_target_; | ||
| 276 | return ResultSuccess; | ||
| 277 | } | ||
| 278 | |||
| 259 | if (!AmiiboCrypto::IsAmiiboValid(encrypted_tag_data)) { | 279 | if (!AmiiboCrypto::IsAmiiboValid(encrypted_tag_data)) { |
| 260 | LOG_ERROR(Service_NFP, "Not an amiibo"); | 280 | LOG_ERROR(Service_NFP, "Not an amiibo"); |
| 261 | return NotAnAmiibo; | 281 | return NotAnAmiibo; |
diff --git a/src/core/hle/service/nfp/nfp_device.h b/src/core/hle/service/nfp/nfp_device.h index 27122e86e..7f963730d 100644 --- a/src/core/hle/service/nfp/nfp_device.h +++ b/src/core/hle/service/nfp/nfp_device.h | |||
| @@ -95,6 +95,7 @@ private: | |||
| 95 | bool is_initalized{}; | 95 | bool is_initalized{}; |
| 96 | bool is_data_moddified{}; | 96 | bool is_data_moddified{}; |
| 97 | bool is_app_area_open{}; | 97 | bool is_app_area_open{}; |
| 98 | bool is_plain_amiibo{}; | ||
| 98 | TagProtocol allowed_protocols{}; | 99 | TagProtocol allowed_protocols{}; |
| 99 | s64 current_posix_time{}; | 100 | s64 current_posix_time{}; |
| 100 | MountTarget mount_target{MountTarget::None}; | 101 | MountTarget mount_target{MountTarget::None}; |
diff --git a/src/core/hle/service/nfp/nfp_types.h b/src/core/hle/service/nfp/nfp_types.h index b3599a513..70c878552 100644 --- a/src/core/hle/service/nfp/nfp_types.h +++ b/src/core/hle/service/nfp/nfp_types.h | |||
| @@ -309,7 +309,8 @@ struct EncryptedNTAG215File { | |||
| 309 | u32 CFG1; // Defines number of verification attempts | 309 | u32 CFG1; // Defines number of verification attempts |
| 310 | NTAG215Password password; // Password data | 310 | NTAG215Password password; // Password data |
| 311 | }; | 311 | }; |
| 312 | static_assert(sizeof(EncryptedNTAG215File) == 0x21C, "EncryptedNTAG215File is an invalid size"); | 312 | static_assert(sizeof(EncryptedNTAG215File) == sizeof(NTAG215File), |
| 313 | "EncryptedNTAG215File is an invalid size"); | ||
| 313 | static_assert(std::is_trivially_copyable_v<EncryptedNTAG215File>, | 314 | static_assert(std::is_trivially_copyable_v<EncryptedNTAG215File>, |
| 314 | "EncryptedNTAG215File must be trivially copyable."); | 315 | "EncryptedNTAG215File must be trivially copyable."); |
| 315 | 316 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index d2308fffc..453a965dc 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | |||
| @@ -304,8 +304,8 @@ NvResult nvhost_gpu::SubmitGPFIFOBase(std::span<const u8> input, std::vector<u8> | |||
| 304 | Tegra::CommandList entries(params.num_entries); | 304 | Tegra::CommandList entries(params.num_entries); |
| 305 | 305 | ||
| 306 | if (kickoff) { | 306 | if (kickoff) { |
| 307 | system.Memory().ReadBlock(params.address, entries.command_lists.data(), | 307 | system.ApplicationMemory().ReadBlock(params.address, entries.command_lists.data(), |
| 308 | params.num_entries * sizeof(Tegra::CommandListHeader)); | 308 | params.num_entries * sizeof(Tegra::CommandListHeader)); |
| 309 | } else { | 309 | } else { |
| 310 | std::memcpy(entries.command_lists.data(), &input[sizeof(IoctlSubmitGpfifo)], | 310 | std::memcpy(entries.command_lists.data(), &input[sizeof(IoctlSubmitGpfifo)], |
| 311 | params.num_entries * sizeof(Tegra::CommandListHeader)); | 311 | params.num_entries * sizeof(Tegra::CommandListHeader)); |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp index 7bcef105b..1ab51f10b 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp | |||
| @@ -105,8 +105,8 @@ NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span<const u8> input, | |||
| 105 | const auto object = nvmap.GetHandle(cmd_buffer.memory_id); | 105 | const auto object = nvmap.GetHandle(cmd_buffer.memory_id); |
| 106 | ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;); | 106 | ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;); |
| 107 | Tegra::ChCommandHeaderList cmdlist(cmd_buffer.word_count); | 107 | Tegra::ChCommandHeaderList cmdlist(cmd_buffer.word_count); |
| 108 | system.Memory().ReadBlock(object->address + cmd_buffer.offset, cmdlist.data(), | 108 | system.ApplicationMemory().ReadBlock(object->address + cmd_buffer.offset, cmdlist.data(), |
| 109 | cmdlist.size() * sizeof(u32)); | 109 | cmdlist.size() * sizeof(u32)); |
| 110 | gpu.PushCommandBuffer(core.Host1xDeviceFile().fd_to_id[fd], cmdlist); | 110 | gpu.PushCommandBuffer(core.Host1xDeviceFile().fd_to_id[fd], cmdlist); |
| 111 | } | 111 | } |
| 112 | std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); | 112 | std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); |
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 95e070825..432310632 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -832,11 +832,6 @@ std::string Memory::ReadCString(Common::ProcessAddress vaddr, std::size_t max_le | |||
| 832 | return impl->ReadCString(vaddr, max_length); | 832 | return impl->ReadCString(vaddr, max_length); |
| 833 | } | 833 | } |
| 834 | 834 | ||
| 835 | void Memory::ReadBlock(const Kernel::KProcess& process, const Common::ProcessAddress src_addr, | ||
| 836 | void* dest_buffer, const std::size_t size) { | ||
| 837 | impl->ReadBlockImpl<false>(process, src_addr, dest_buffer, size); | ||
| 838 | } | ||
| 839 | |||
| 840 | void Memory::ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer, | 835 | void Memory::ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer, |
| 841 | const std::size_t size) { | 836 | const std::size_t size) { |
| 842 | impl->ReadBlock(src_addr, dest_buffer, size); | 837 | impl->ReadBlock(src_addr, dest_buffer, size); |
| @@ -847,11 +842,6 @@ void Memory::ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_b | |||
| 847 | impl->ReadBlockUnsafe(src_addr, dest_buffer, size); | 842 | impl->ReadBlockUnsafe(src_addr, dest_buffer, size); |
| 848 | } | 843 | } |
| 849 | 844 | ||
| 850 | void Memory::WriteBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, | ||
| 851 | const void* src_buffer, std::size_t size) { | ||
| 852 | impl->WriteBlockImpl<false>(process, dest_addr, src_buffer, size); | ||
| 853 | } | ||
| 854 | |||
| 855 | void Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer, | 845 | void Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer, |
| 856 | const std::size_t size) { | 846 | const std::size_t size) { |
| 857 | impl->WriteBlock(dest_addr, src_buffer, size); | 847 | impl->WriteBlock(dest_addr, src_buffer, size); |
| @@ -862,29 +852,25 @@ void Memory::WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void | |||
| 862 | impl->WriteBlockUnsafe(dest_addr, src_buffer, size); | 852 | impl->WriteBlockUnsafe(dest_addr, src_buffer, size); |
| 863 | } | 853 | } |
| 864 | 854 | ||
| 865 | void Memory::CopyBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, | 855 | void Memory::CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr, |
| 866 | Common::ProcessAddress src_addr, const std::size_t size) { | 856 | const std::size_t size) { |
| 867 | impl->CopyBlock(process, dest_addr, src_addr, size); | 857 | impl->CopyBlock(*system.ApplicationProcess(), dest_addr, src_addr, size); |
| 868 | } | 858 | } |
| 869 | 859 | ||
| 870 | void Memory::ZeroBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, | 860 | void Memory::ZeroBlock(Common::ProcessAddress dest_addr, const std::size_t size) { |
| 871 | const std::size_t size) { | 861 | impl->ZeroBlock(*system.ApplicationProcess(), dest_addr, size); |
| 872 | impl->ZeroBlock(process, dest_addr, size); | ||
| 873 | } | 862 | } |
| 874 | 863 | ||
| 875 | Result Memory::InvalidateDataCache(const Kernel::KProcess& process, | 864 | Result Memory::InvalidateDataCache(Common::ProcessAddress dest_addr, const std::size_t size) { |
| 876 | Common::ProcessAddress dest_addr, const std::size_t size) { | 865 | return impl->InvalidateDataCache(*system.ApplicationProcess(), dest_addr, size); |
| 877 | return impl->InvalidateDataCache(process, dest_addr, size); | ||
| 878 | } | 866 | } |
| 879 | 867 | ||
| 880 | Result Memory::StoreDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, | 868 | Result Memory::StoreDataCache(Common::ProcessAddress dest_addr, const std::size_t size) { |
| 881 | const std::size_t size) { | 869 | return impl->StoreDataCache(*system.ApplicationProcess(), dest_addr, size); |
| 882 | return impl->StoreDataCache(process, dest_addr, size); | ||
| 883 | } | 870 | } |
| 884 | 871 | ||
| 885 | Result Memory::FlushDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, | 872 | Result Memory::FlushDataCache(Common::ProcessAddress dest_addr, const std::size_t size) { |
| 886 | const std::size_t size) { | 873 | return impl->FlushDataCache(*system.ApplicationProcess(), dest_addr, size); |
| 887 | return impl->FlushDataCache(process, dest_addr, size); | ||
| 888 | } | 874 | } |
| 889 | 875 | ||
| 890 | void Memory::RasterizerMarkRegionCached(Common::ProcessAddress vaddr, u64 size, bool cached) { | 876 | void Memory::RasterizerMarkRegionCached(Common::ProcessAddress vaddr, u64 size, bool cached) { |
diff --git a/src/core/memory.h b/src/core/memory.h index ed4e87739..72a0be813 100644 --- a/src/core/memory.h +++ b/src/core/memory.h | |||
| @@ -305,26 +305,6 @@ public: | |||
| 305 | std::string ReadCString(Common::ProcessAddress vaddr, std::size_t max_length); | 305 | std::string ReadCString(Common::ProcessAddress vaddr, std::size_t max_length); |
| 306 | 306 | ||
| 307 | /** | 307 | /** |
| 308 | * Reads a contiguous block of bytes from a specified process' address space. | ||
| 309 | * | ||
| 310 | * @param process The process to read the data from. | ||
| 311 | * @param src_addr The virtual address to begin reading from. | ||
| 312 | * @param dest_buffer The buffer to place the read bytes into. | ||
| 313 | * @param size The amount of data to read, in bytes. | ||
| 314 | * | ||
| 315 | * @note If a size of 0 is specified, then this function reads nothing and | ||
| 316 | * no attempts to access memory are made at all. | ||
| 317 | * | ||
| 318 | * @pre dest_buffer must be at least size bytes in length, otherwise a | ||
| 319 | * buffer overrun will occur. | ||
| 320 | * | ||
| 321 | * @post The range [dest_buffer, size) contains the read bytes from the | ||
| 322 | * process' address space. | ||
| 323 | */ | ||
| 324 | void ReadBlock(const Kernel::KProcess& process, Common::ProcessAddress src_addr, | ||
| 325 | void* dest_buffer, std::size_t size); | ||
| 326 | |||
| 327 | /** | ||
| 328 | * Reads a contiguous block of bytes from the current process' address space. | 308 | * Reads a contiguous block of bytes from the current process' address space. |
| 329 | * | 309 | * |
| 330 | * @param src_addr The virtual address to begin reading from. | 310 | * @param src_addr The virtual address to begin reading from. |
| @@ -362,29 +342,6 @@ public: | |||
| 362 | void ReadBlockUnsafe(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size); | 342 | void ReadBlockUnsafe(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size); |
| 363 | 343 | ||
| 364 | /** | 344 | /** |
| 365 | * Writes a range of bytes into a given process' address space at the specified | ||
| 366 | * virtual address. | ||
| 367 | * | ||
| 368 | * @param process The process to write data into the address space of. | ||
| 369 | * @param dest_addr The destination virtual address to begin writing the data at. | ||
| 370 | * @param src_buffer The data to write into the process' address space. | ||
| 371 | * @param size The size of the data to write, in bytes. | ||
| 372 | * | ||
| 373 | * @post The address range [dest_addr, size) in the process' address space | ||
| 374 | * contains the data that was within src_buffer. | ||
| 375 | * | ||
| 376 | * @post If an attempt is made to write into an unmapped region of memory, the writes | ||
| 377 | * will be ignored and an error will be logged. | ||
| 378 | * | ||
| 379 | * @post If a write is performed into a region of memory that is considered cached | ||
| 380 | * rasterizer memory, will cause the currently active rasterizer to be notified | ||
| 381 | * and will mark that region as invalidated to caches that the active | ||
| 382 | * graphics backend may be maintaining over the course of execution. | ||
| 383 | */ | ||
| 384 | void WriteBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, | ||
| 385 | const void* src_buffer, std::size_t size); | ||
| 386 | |||
| 387 | /** | ||
| 388 | * Writes a range of bytes into the current process' address space at the specified | 345 | * Writes a range of bytes into the current process' address space at the specified |
| 389 | * virtual address. | 346 | * virtual address. |
| 390 | * | 347 | * |
| @@ -428,7 +385,6 @@ public: | |||
| 428 | * Copies data within a process' address space to another location within the | 385 | * Copies data within a process' address space to another location within the |
| 429 | * same address space. | 386 | * same address space. |
| 430 | * | 387 | * |
| 431 | * @param process The process that will have data copied within its address space. | ||
| 432 | * @param dest_addr The destination virtual address to begin copying the data into. | 388 | * @param dest_addr The destination virtual address to begin copying the data into. |
| 433 | * @param src_addr The source virtual address to begin copying the data from. | 389 | * @param src_addr The source virtual address to begin copying the data from. |
| 434 | * @param size The size of the data to copy, in bytes. | 390 | * @param size The size of the data to copy, in bytes. |
| @@ -436,58 +392,50 @@ public: | |||
| 436 | * @post The range [dest_addr, size) within the process' address space contains the | 392 | * @post The range [dest_addr, size) within the process' address space contains the |
| 437 | * same data within the range [src_addr, size). | 393 | * same data within the range [src_addr, size). |
| 438 | */ | 394 | */ |
| 439 | void CopyBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, | 395 | void CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr, |
| 440 | Common::ProcessAddress src_addr, std::size_t size); | 396 | std::size_t size); |
| 441 | 397 | ||
| 442 | /** | 398 | /** |
| 443 | * Zeros a range of bytes within the current process' address space at the specified | 399 | * Zeros a range of bytes within the current process' address space at the specified |
| 444 | * virtual address. | 400 | * virtual address. |
| 445 | * | 401 | * |
| 446 | * @param process The process that will have data zeroed within its address space. | ||
| 447 | * @param dest_addr The destination virtual address to zero the data from. | 402 | * @param dest_addr The destination virtual address to zero the data from. |
| 448 | * @param size The size of the range to zero out, in bytes. | 403 | * @param size The size of the range to zero out, in bytes. |
| 449 | * | 404 | * |
| 450 | * @post The range [dest_addr, size) within the process' address space contains the | 405 | * @post The range [dest_addr, size) within the process' address space contains the |
| 451 | * value 0. | 406 | * value 0. |
| 452 | */ | 407 | */ |
| 453 | void ZeroBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, | 408 | void ZeroBlock(Common::ProcessAddress dest_addr, std::size_t size); |
| 454 | std::size_t size); | ||
| 455 | 409 | ||
| 456 | /** | 410 | /** |
| 457 | * Invalidates a range of bytes within the current process' address space at the specified | 411 | * Invalidates a range of bytes within the current process' address space at the specified |
| 458 | * virtual address. | 412 | * virtual address. |
| 459 | * | 413 | * |
| 460 | * @param process The process that will have data invalidated within its address space. | ||
| 461 | * @param dest_addr The destination virtual address to invalidate the data from. | 414 | * @param dest_addr The destination virtual address to invalidate the data from. |
| 462 | * @param size The size of the range to invalidate, in bytes. | 415 | * @param size The size of the range to invalidate, in bytes. |
| 463 | * | 416 | * |
| 464 | */ | 417 | */ |
| 465 | Result InvalidateDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, | 418 | Result InvalidateDataCache(Common::ProcessAddress dest_addr, std::size_t size); |
| 466 | std::size_t size); | ||
| 467 | 419 | ||
| 468 | /** | 420 | /** |
| 469 | * Stores a range of bytes within the current process' address space at the specified | 421 | * Stores a range of bytes within the current process' address space at the specified |
| 470 | * virtual address. | 422 | * virtual address. |
| 471 | * | 423 | * |
| 472 | * @param process The process that will have data stored within its address space. | ||
| 473 | * @param dest_addr The destination virtual address to store the data from. | 424 | * @param dest_addr The destination virtual address to store the data from. |
| 474 | * @param size The size of the range to store, in bytes. | 425 | * @param size The size of the range to store, in bytes. |
| 475 | * | 426 | * |
| 476 | */ | 427 | */ |
| 477 | Result StoreDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, | 428 | Result StoreDataCache(Common::ProcessAddress dest_addr, std::size_t size); |
| 478 | std::size_t size); | ||
| 479 | 429 | ||
| 480 | /** | 430 | /** |
| 481 | * Flushes a range of bytes within the current process' address space at the specified | 431 | * Flushes a range of bytes within the current process' address space at the specified |
| 482 | * virtual address. | 432 | * virtual address. |
| 483 | * | 433 | * |
| 484 | * @param process The process that will have data flushed within its address space. | ||
| 485 | * @param dest_addr The destination virtual address to flush the data from. | 434 | * @param dest_addr The destination virtual address to flush the data from. |
| 486 | * @param size The size of the range to flush, in bytes. | 435 | * @param size The size of the range to flush, in bytes. |
| 487 | * | 436 | * |
| 488 | */ | 437 | */ |
| 489 | Result FlushDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, | 438 | Result FlushDataCache(Common::ProcessAddress dest_addr, std::size_t size); |
| 490 | std::size_t size); | ||
| 491 | 439 | ||
| 492 | /** | 440 | /** |
| 493 | * Marks each page within the specified address range as cached or uncached. | 441 | * Marks each page within the specified address range as cached or uncached. |
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp index d1284a3a7..8742dd164 100644 --- a/src/core/memory/cheat_engine.cpp +++ b/src/core/memory/cheat_engine.cpp | |||
| @@ -39,11 +39,11 @@ StandardVmCallbacks::StandardVmCallbacks(System& system_, const CheatProcessMeta | |||
| 39 | StandardVmCallbacks::~StandardVmCallbacks() = default; | 39 | StandardVmCallbacks::~StandardVmCallbacks() = default; |
| 40 | 40 | ||
| 41 | void StandardVmCallbacks::MemoryRead(VAddr address, void* data, u64 size) { | 41 | void StandardVmCallbacks::MemoryRead(VAddr address, void* data, u64 size) { |
| 42 | system.Memory().ReadBlock(SanitizeAddress(address), data, size); | 42 | system.ApplicationMemory().ReadBlock(SanitizeAddress(address), data, size); |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | void StandardVmCallbacks::MemoryWrite(VAddr address, const void* data, u64 size) { | 45 | void StandardVmCallbacks::MemoryWrite(VAddr address, const void* data, u64 size) { |
| 46 | system.Memory().WriteBlock(SanitizeAddress(address), data, size); | 46 | system.ApplicationMemory().WriteBlock(SanitizeAddress(address), data, size); |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | u64 StandardVmCallbacks::HidKeysDown() { | 49 | u64 StandardVmCallbacks::HidKeysDown() { |
diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp index 146c3f21e..6c3dc7369 100644 --- a/src/core/reporter.cpp +++ b/src/core/reporter.cpp | |||
| @@ -264,7 +264,7 @@ void Reporter::SaveUnimplementedFunctionReport(Service::HLERequestContext& ctx, | |||
| 264 | const auto title_id = system.GetApplicationProcessProgramID(); | 264 | const auto title_id = system.GetApplicationProcessProgramID(); |
| 265 | auto out = GetFullDataAuto(timestamp, title_id, system); | 265 | auto out = GetFullDataAuto(timestamp, title_id, system); |
| 266 | 266 | ||
| 267 | auto function_out = GetHLERequestContextData(ctx, system.Memory()); | 267 | auto function_out = GetHLERequestContextData(ctx, system.ApplicationMemory()); |
| 268 | function_out["command_id"] = command_id; | 268 | function_out["command_id"] = command_id; |
| 269 | function_out["function_name"] = name; | 269 | function_out["function_name"] = name; |
| 270 | function_out["service_name"] = service_name; | 270 | function_out["service_name"] = service_name; |
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index ae84408bc..39b774c98 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | add_executable(tests | 4 | add_executable(tests |
| 5 | common/bit_field.cpp | 5 | common/bit_field.cpp |
| 6 | common/cityhash.cpp | 6 | common/cityhash.cpp |
| 7 | common/container_hash.cpp | ||
| 7 | common/fibers.cpp | 8 | common/fibers.cpp |
| 8 | common/host_memory.cpp | 9 | common/host_memory.cpp |
| 9 | common/param_package.cpp | 10 | common/param_package.cpp |
diff --git a/src/tests/common/container_hash.cpp b/src/tests/common/container_hash.cpp new file mode 100644 index 000000000..dc45565ef --- /dev/null +++ b/src/tests/common/container_hash.cpp | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include <catch2/catch_test_macros.hpp> | ||
| 5 | |||
| 6 | #include "common/common_types.h" | ||
| 7 | #include "common/container_hash.h" | ||
| 8 | |||
| 9 | TEST_CASE("ContainerHash", "[common]") { | ||
| 10 | constexpr std::array<u8, 32> U8Values{ | ||
| 11 | 114, 10, 238, 189, 199, 242, 86, 96, 53, 193, 195, 247, 249, 56, 253, 61, | ||
| 12 | 205, 3, 172, 4, 210, 197, 43, 72, 103, 8, 99, 89, 5, 97, 68, 196, | ||
| 13 | }; | ||
| 14 | constexpr std::array<u16, 32> U16Values{ | ||
| 15 | 61586, 49151, 3313, 11641, 31695, 54795, 46764, 20965, 23287, 14039, 19265, | ||
| 16 | 49093, 58932, 22518, 27139, 42825, 57417, 54237, 48057, 14586, 42813, 32994, | ||
| 17 | 33970, 45501, 5619, 15895, 33227, 27509, 25391, 37275, 60218, 17599, | ||
| 18 | }; | ||
| 19 | constexpr std::array<u32, 32> U32Values{ | ||
| 20 | 3838402410U, 2029146863U, 1730869921U, 985528872U, 186773874U, 2094639868U, 3324775932U, | ||
| 21 | 1795512424U, 2571165571U, 3256934519U, 2358691590U, 2752682538U, 1484336451U, 378124520U, | ||
| 22 | 3463015699U, 3395942161U, 1263211979U, 3473632889U, 3039822212U, 2068707357U, 2223837919U, | ||
| 23 | 1823232191U, 1583884041U, 1264393380U, 4087566993U, 3188607101U, 3933680362U, 1464520765U, | ||
| 24 | 1786838406U, 1311734848U, 2773642241U, 3993641692U, | ||
| 25 | }; | ||
| 26 | constexpr std::array<u64, 32> U64Values{ | ||
| 27 | 5908025796157537817ULL, 10947547850358315100ULL, 844798943576724669ULL, | ||
| 28 | 7999662937458523703ULL, 4006550374705895164ULL, 1832550525423503632ULL, | ||
| 29 | 9323088254855830976ULL, 12028890075598379412ULL, 6021511300787826236ULL, | ||
| 30 | 7864675007938747948ULL, 18099387408859708806ULL, 6438638299316820708ULL, | ||
| 31 | 9029399285648501543ULL, 18195459433089960253ULL, 17214335092761966083ULL, | ||
| 32 | 5549347964591337833ULL, 14899526073304962015ULL, 5058883181561464475ULL, | ||
| 33 | 7436311795731206973ULL, 7535129567768649864ULL, 1287169596809258072ULL, | ||
| 34 | 8237671246353565927ULL, 1715230541978016153ULL, 8443157615068813300ULL, | ||
| 35 | 6098675262328527839ULL, 704652094100376853ULL, 1303411723202926503ULL, | ||
| 36 | 7808312933946424854ULL, 6863726670433556594ULL, 9870361541383217495ULL, | ||
| 37 | 9273671094091079488ULL, 17541434976160119010ULL, | ||
| 38 | }; | ||
| 39 | |||
| 40 | REQUIRE(Common::HashValue(U8Values) == 5867183267093890552ULL); | ||
| 41 | REQUIRE(Common::HashValue(U16Values) == 9594135570564347135ULL); | ||
| 42 | REQUIRE(Common::HashValue(U32Values) == 13123757214696618460ULL); | ||
| 43 | REQUIRE(Common::HashValue(U64Values) == 7296500016546938380ULL); | ||
| 44 | } | ||
diff --git a/src/video_core/macro/macro.cpp b/src/video_core/macro/macro.cpp index 82ad0477d..905505ca1 100644 --- a/src/video_core/macro/macro.cpp +++ b/src/video_core/macro/macro.cpp | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | #include <optional> | 6 | #include <optional> |
| 7 | #include <span> | 7 | #include <span> |
| 8 | 8 | ||
| 9 | #include <boost/container_hash/hash.hpp> | 9 | #include "common/container_hash.h" |
| 10 | 10 | ||
| 11 | #include <fstream> | 11 | #include <fstream> |
| 12 | #include "common/assert.h" | 12 | #include "common/assert.h" |
| @@ -89,7 +89,7 @@ void MacroEngine::Execute(u32 method, const std::vector<u32>& parameters) { | |||
| 89 | 89 | ||
| 90 | if (!mid_method.has_value()) { | 90 | if (!mid_method.has_value()) { |
| 91 | cache_info.lle_program = Compile(macro_code->second); | 91 | cache_info.lle_program = Compile(macro_code->second); |
| 92 | cache_info.hash = boost::hash_value(macro_code->second); | 92 | cache_info.hash = Common::HashValue(macro_code->second); |
| 93 | if (Settings::values.dump_macros) { | 93 | if (Settings::values.dump_macros) { |
| 94 | Dump(cache_info.hash, macro_code->second); | 94 | Dump(cache_info.hash, macro_code->second); |
| 95 | } | 95 | } |
| @@ -100,7 +100,7 @@ void MacroEngine::Execute(u32 method, const std::vector<u32>& parameters) { | |||
| 100 | code.resize(macro_cached.size() - rebased_method); | 100 | code.resize(macro_cached.size() - rebased_method); |
| 101 | std::memcpy(code.data(), macro_cached.data() + rebased_method, | 101 | std::memcpy(code.data(), macro_cached.data() + rebased_method, |
| 102 | code.size() * sizeof(u32)); | 102 | code.size() * sizeof(u32)); |
| 103 | cache_info.hash = boost::hash_value(code); | 103 | cache_info.hash = Common::HashValue(code); |
| 104 | cache_info.lle_program = Compile(code); | 104 | cache_info.lle_program = Compile(code); |
| 105 | if (Settings::values.dump_macros) { | 105 | if (Settings::values.dump_macros) { |
| 106 | Dump(cache_info.hash, code); | 106 | Dump(cache_info.hash, code); |
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 83924475b..015a7d3c1 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp | |||
| @@ -22,7 +22,7 @@ std::atomic<size_t> MemoryManager::unique_identifier_generator{}; | |||
| 22 | 22 | ||
| 23 | MemoryManager::MemoryManager(Core::System& system_, u64 address_space_bits_, u64 big_page_bits_, | 23 | MemoryManager::MemoryManager(Core::System& system_, u64 address_space_bits_, u64 big_page_bits_, |
| 24 | u64 page_bits_) | 24 | u64 page_bits_) |
| 25 | : system{system_}, memory{system.Memory()}, device_memory{system.DeviceMemory()}, | 25 | : system{system_}, memory{system.ApplicationMemory()}, device_memory{system.DeviceMemory()}, |
| 26 | address_space_bits{address_space_bits_}, page_bits{page_bits_}, big_page_bits{big_page_bits_}, | 26 | address_space_bits{address_space_bits_}, page_bits{page_bits_}, big_page_bits{big_page_bits_}, |
| 27 | entries{}, big_entries{}, page_table{address_space_bits, address_space_bits + page_bits - 38, | 27 | entries{}, big_entries{}, page_table{address_space_bits, address_space_bits + page_bits - 38, |
| 28 | page_bits != big_page_bits ? page_bits : 0}, | 28 | page_bits != big_page_bits ? page_bits : 0}, |
diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index fedb4a7bb..b42d48416 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp | |||
| @@ -18,7 +18,7 @@ std::unique_ptr<VideoCore::RendererBase> CreateRenderer( | |||
| 18 | Core::System& system, Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu, | 18 | Core::System& system, Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu, |
| 19 | std::unique_ptr<Core::Frontend::GraphicsContext> context) { | 19 | std::unique_ptr<Core::Frontend::GraphicsContext> context) { |
| 20 | auto& telemetry_session = system.TelemetrySession(); | 20 | auto& telemetry_session = system.TelemetrySession(); |
| 21 | auto& cpu_memory = system.Memory(); | 21 | auto& cpu_memory = system.ApplicationMemory(); |
| 22 | 22 | ||
| 23 | switch (Settings::values.renderer_backend.GetValue()) { | 23 | switch (Settings::values.renderer_backend.GetValue()) { |
| 24 | case Settings::RendererBackend::OpenGL: | 24 | case Settings::RendererBackend::OpenGL: |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 19968bc21..0c60a90cb 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -307,6 +307,8 @@ GMainWindow::GMainWindow(std::unique_ptr<Config> config_, bool has_broken_vulkan | |||
| 307 | system->Initialize(); | 307 | system->Initialize(); |
| 308 | 308 | ||
| 309 | Common::Log::Initialize(); | 309 | Common::Log::Initialize(); |
| 310 | Common::Log::Start(); | ||
| 311 | |||
| 310 | LoadTranslation(); | 312 | LoadTranslation(); |
| 311 | 313 | ||
| 312 | setAcceptDrops(true); | 314 | setAcceptDrops(true); |
| @@ -449,8 +451,6 @@ GMainWindow::GMainWindow(std::unique_ptr<Config> config_, bool has_broken_vulkan | |||
| 449 | 451 | ||
| 450 | SetupPrepareForSleep(); | 452 | SetupPrepareForSleep(); |
| 451 | 453 | ||
| 452 | Common::Log::Start(); | ||
| 453 | |||
| 454 | QStringList args = QApplication::arguments(); | 454 | QStringList args = QApplication::arguments(); |
| 455 | 455 | ||
| 456 | if (args.size() < 2) { | 456 | if (args.size() < 2) { |