summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--src/audio_core/device/device_session.cpp4
-rw-r--r--src/audio_core/renderer/adsp/adsp.cpp2
-rw-r--r--src/audio_core/renderer/adsp/command_list_processor.cpp2
-rw-r--r--src/audio_core/renderer/system.cpp3
-rw-r--r--src/common/CMakeLists.txt3
-rw-r--r--src/common/container_hash.h92
-rw-r--r--src/common/telemetry.cpp1
-rw-r--r--src/common/x64/cpu_detect.cpp1
-rw-r--r--src/common/x64/cpu_detect.h1
-rw-r--r--src/common/x64/cpu_wait.cpp69
-rw-r--r--src/common/x64/cpu_wait.h10
-rw-r--r--src/common/x64/native_clock.cpp13
-rw-r--r--src/core/arm/arm_interface.cpp2
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp6
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp6
-rw-r--r--src/core/core.cpp6
-rw-r--r--src/core/core.h4
-rw-r--r--src/core/core_timing.cpp8
-rw-r--r--src/core/debugger/gdbstub.cpp34
-rw-r--r--src/core/hle/kernel/k_address_arbiter.cpp10
-rw-r--r--src/core/hle/kernel/k_condition_variable.cpp18
-rw-r--r--src/core/hle/kernel/k_page_table.cpp54
-rw-r--r--src/core/hle/kernel/k_page_table.h4
-rw-r--r--src/core/hle/kernel/k_process.cpp22
-rw-r--r--src/core/hle/kernel/k_process.h15
-rw-r--r--src/core/hle/kernel/k_server_session.cpp4
-rw-r--r--src/core/hle/kernel/k_thread.cpp11
-rw-r--r--src/core/hle/kernel/k_thread.h4
-rw-r--r--src/core/hle/kernel/kernel.cpp4
-rw-r--r--src/core/hle/kernel/svc/svc_cache.cpp2
-rw-r--r--src/core/hle/kernel/svc/svc_debug_string.cpp3
-rw-r--r--src/core/hle/kernel/svc/svc_exception.cpp2
-rw-r--r--src/core/hle/kernel/svc/svc_ipc.cpp4
-rw-r--r--src/core/hle/kernel/svc/svc_port.cpp6
-rw-r--r--src/core/hle/kernel/svc/svc_process.cpp2
-rw-r--r--src/core/hle/kernel/svc/svc_query_memory.cpp4
-rw-r--r--src/core/hle/kernel/svc/svc_synchronization.cpp3
-rw-r--r--src/core/hle/kernel/svc/svc_thread.cpp4
-rw-r--r--src/core/hle/service/am/am.cpp6
-rw-r--r--src/core/hle/service/hid/controllers/console_sixaxis.cpp3
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp3
-rw-r--r--src/core/hle/service/hid/hidbus/ringcon.cpp4
-rw-r--r--src/core/hle/service/hid/irsensor/image_transfer_processor.cpp18
-rw-r--r--src/core/hle/service/hle_ipc.cpp3
-rw-r--r--src/core/hle/service/jit/jit.cpp4
-rw-r--r--src/core/hle/service/ldr/ldr.cpp10
-rw-r--r--src/core/hle/service/nfp/amiibo_crypto.cpp4
-rw-r--r--src/core/hle/service/nfp/amiibo_crypto.h3
-rw-r--r--src/core/hle/service/nfp/nfp_device.cpp34
-rw-r--r--src/core/hle/service/nfp/nfp_device.h1
-rw-r--r--src/core/hle/service/nfp/nfp_types.h3
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp4
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp4
-rw-r--r--src/core/memory.cpp36
-rw-r--r--src/core/memory.h64
-rw-r--r--src/core/memory/cheat_engine.cpp4
-rw-r--r--src/core/reporter.cpp2
-rw-r--r--src/tests/CMakeLists.txt1
-rw-r--r--src/tests/common/container_hash.cpp44
-rw-r--r--src/video_core/macro/macro.cpp6
-rw-r--r--src/video_core/memory_manager.cpp2
-rw-r--r--src/video_core/video_core.cpp2
-rw-r--r--src/yuzu/main.cpp4
-rw-r--r--vcpkg.json2
65 files changed, 466 insertions, 250 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 61c95444f..a6c43f401 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -210,7 +210,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
# =======================================================================
# Enforce the search mode of non-required packages for better and shorter failure messages
-find_package(Boost 1.81.0 REQUIRED context)
+find_package(Boost 1.79.0 REQUIRED context)
find_package(enet 1.3 MODULE)
find_package(fmt 9 REQUIRED)
find_package(inih 52 MODULE COMPONENTS INIReader)
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 {
stream->AppendBuffer(new_buffer, samples);
} else {
std::vector<s16> samples(buffer.size / sizeof(s16));
- system.Memory().ReadBlockUnsafe(buffer.samples, samples.data(), buffer.size);
+ system.ApplicationMemory().ReadBlockUnsafe(buffer.samples, samples.data(), buffer.size);
stream->AppendBuffer(new_buffer, samples);
}
}
@@ -102,7 +102,7 @@ void DeviceSession::AppendBuffers(std::span<const AudioBuffer> buffers) const {
void DeviceSession::ReleaseBuffer(const AudioBuffer& buffer) const {
if (type == Sink::StreamType::In) {
auto samples{stream->ReleaseBuffer(buffer.size / sizeof(s16))};
- system.Memory().WriteBlockUnsafe(buffer.samples, samples.data(), buffer.size);
+ system.ApplicationMemory().WriteBlockUnsafe(buffer.samples, samples.data(), buffer.size);
}
}
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 @@
namespace AudioCore::AudioRenderer::ADSP {
ADSP::ADSP(Core::System& system_, Sink::Sink& sink_)
- : system{system_}, memory{system.Memory()}, sink{sink_} {}
+ : system{system_}, memory{system.ApplicationMemory()}, sink{sink_} {}
ADSP::~ADSP() {
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 {
void CommandListProcessor::Initialize(Core::System& system_, CpuAddr buffer, u64 size,
Sink::SinkStream* stream_) {
system = &system_;
- memory = &system->Memory();
+ memory = &system->ApplicationMemory();
stream = stream_;
header = reinterpret_cast<CommandListHeader*>(buffer);
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,
render_device = params.rendering_device;
execution_mode = params.execution_mode;
- core.Memory().ZeroBlock(*core.ApplicationProcess(), transfer_memory->GetSourceAddress(),
- transfer_memory_size);
+ core.ApplicationMemory().ZeroBlock(transfer_memory->GetSourceAddress(), transfer_memory_size);
// Note: We're not actually using the transfer memory because it's a pain to code for.
// 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
common_precompiled_headers.h
common_types.h
concepts.h
+ container_hash.h
demangle.cpp
demangle.h
div_ceil.h
@@ -159,6 +160,8 @@ if(ARCHITECTURE_x86_64)
PRIVATE
x64/cpu_detect.cpp
x64/cpu_detect.h
+ x64/cpu_wait.cpp
+ x64/cpu_wait.h
x64/native_clock.cpp
x64/native_clock.h
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 @@
+// SPDX-FileCopyrightText: 2005-2014 Daniel James
+// SPDX-FileCopyrightText: 2016 Austin Appleby
+// SPDX-License-Identifier: BSL-1.0
+
+#include <array>
+#include <climits>
+#include <cstdint>
+#include <limits>
+#include <type_traits>
+#include <vector>
+
+namespace Common {
+
+namespace detail {
+
+template <typename T>
+ requires std::is_unsigned_v<T>
+inline std::size_t HashValue(T val) {
+ const unsigned int size_t_bits = std::numeric_limits<std::size_t>::digits;
+ const unsigned int length =
+ (std::numeric_limits<T>::digits - 1) / static_cast<unsigned int>(size_t_bits);
+
+ std::size_t seed = 0;
+
+ for (unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits) {
+ seed ^= static_cast<size_t>(val >> i) + (seed << 6) + (seed >> 2);
+ }
+
+ seed ^= static_cast<size_t>(val) + (seed << 6) + (seed >> 2);
+
+ return seed;
+}
+
+template <size_t Bits>
+struct HashCombineImpl {
+ template <typename T>
+ static inline T fn(T seed, T value) {
+ seed ^= value + 0x9e3779b9 + (seed << 6) + (seed >> 2);
+ return seed;
+ }
+};
+
+template <>
+struct HashCombineImpl<64> {
+ static inline std::uint64_t fn(std::uint64_t h, std::uint64_t k) {
+ const std::uint64_t m = (std::uint64_t(0xc6a4a793) << 32) + 0x5bd1e995;
+ const int r = 47;
+
+ k *= m;
+ k ^= k >> r;
+ k *= m;
+
+ h ^= k;
+ h *= m;
+
+ // Completely arbitrary number, to prevent 0's
+ // from hashing to 0.
+ h += 0xe6546b64;
+
+ return h;
+ }
+};
+
+} // namespace detail
+
+template <typename T>
+inline void HashCombine(std::size_t& seed, const T& v) {
+ seed = detail::HashCombineImpl<sizeof(std::size_t) * CHAR_BIT>::fn(seed, detail::HashValue(v));
+}
+
+template <typename It>
+inline std::size_t HashRange(It first, It last) {
+ std::size_t seed = 0;
+
+ for (; first != last; ++first) {
+ HashCombine<typename std::iterator_traits<It>::value_type>(seed, *first);
+ }
+
+ return seed;
+}
+
+template <typename T, size_t Size>
+std::size_t HashValue(const std::array<T, Size>& v) {
+ return HashRange(v.cbegin(), v.cend());
+}
+
+template <typename T, typename Allocator>
+std::size_t HashValue(const std::vector<T, Allocator>& v) {
+ return HashRange(v.cbegin(), v.cend());
+}
+
+} // 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) {
add_field("CPU_Extension_x64_PCLMULQDQ", caps.pclmulqdq);
add_field("CPU_Extension_x64_POPCNT", caps.popcnt);
add_field("CPU_Extension_x64_SHA", caps.sha);
+ add_field("CPU_Extension_x64_WAITPKG", caps.waitpkg);
#else
fc.AddField(FieldType::UserSystem, "CPU_Model", "Other");
#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() {
caps.bmi2 = Common::Bit<8>(cpu_id[1]);
caps.sha = Common::Bit<29>(cpu_id[1]);
+ caps.waitpkg = Common::Bit<5>(cpu_id[2]);
caps.gfni = Common::Bit<8>(cpu_id[2]);
__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 {
bool pclmulqdq : 1;
bool popcnt : 1;
bool sha : 1;
+ bool waitpkg : 1;
};
/**
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 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <thread>
+
+#ifdef _MSC_VER
+#include <intrin.h>
+#endif
+
+#include "common/x64/cpu_detect.h"
+#include "common/x64/cpu_wait.h"
+
+namespace Common::X64 {
+
+#ifdef _MSC_VER
+__forceinline static u64 FencedRDTSC() {
+ _mm_lfence();
+ _ReadWriteBarrier();
+ const u64 result = __rdtsc();
+ _mm_lfence();
+ _ReadWriteBarrier();
+ return result;
+}
+
+__forceinline static void TPAUSE() {
+ // 100,000 cycles is a reasonable amount of time to wait to save on CPU resources.
+ // For reference:
+ // At 1 GHz, 100K cycles is 100us
+ // At 2 GHz, 100K cycles is 50us
+ // At 4 GHz, 100K cycles is 25us
+ static constexpr auto PauseCycles = 100'000;
+ _tpause(0, FencedRDTSC() + PauseCycles);
+}
+#else
+static u64 FencedRDTSC() {
+ u64 eax;
+ u64 edx;
+ asm volatile("lfence\n\t"
+ "rdtsc\n\t"
+ "lfence\n\t"
+ : "=a"(eax), "=d"(edx));
+ return (edx << 32) | eax;
+}
+
+static void TPAUSE() {
+ // 100,000 cycles is a reasonable amount of time to wait to save on CPU resources.
+ // For reference:
+ // At 1 GHz, 100K cycles is 100us
+ // At 2 GHz, 100K cycles is 50us
+ // At 4 GHz, 100K cycles is 25us
+ static constexpr auto PauseCycles = 100'000;
+ const auto tsc = FencedRDTSC() + PauseCycles;
+ const auto eax = static_cast<u32>(tsc & 0xFFFFFFFF);
+ const auto edx = static_cast<u32>(tsc >> 32);
+ asm volatile("tpause %0" : : "r"(0), "d"(edx), "a"(eax));
+}
+#endif
+
+void MicroSleep() {
+ static const bool has_waitpkg = GetCPUCaps().waitpkg;
+
+ if (has_waitpkg) {
+ TPAUSE();
+ } else {
+ std::this_thread::yield();
+ }
+}
+
+} // 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 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+namespace Common::X64 {
+
+void MicroSleep();
+
+} // 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() {
}
#else
static u64 FencedRDTSC() {
- u64 result;
+ u64 eax;
+ u64 edx;
asm volatile("lfence\n\t"
"rdtsc\n\t"
- "shl $32, %%rdx\n\t"
- "or %%rdx, %0\n\t"
- "lfence"
- : "=a"(result)
- :
- : "rdx", "memory", "cc");
- return result;
+ "lfence\n\t"
+ : "=a"(eax), "=d"(edx));
+ return (edx << 32) | eax;
}
#endif
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
std::map<std::string, Symbols::Symbols> symbols;
for (const auto& module : modules) {
symbols.insert_or_assign(
- module.second, Symbols::GetSymbols(module.first, system.Memory(),
+ module.second, Symbols::GetSymbols(module.first, system.ApplicationMemory(),
system.ApplicationProcess()->Is64BitProcess()));
}
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;
class DynarmicCallbacks32 : public Dynarmic::A32::UserCallbacks {
public:
explicit DynarmicCallbacks32(ARM_Dynarmic_32& parent_)
- : parent{parent_},
- memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()},
+ : parent{parent_}, memory(parent.system.ApplicationMemory()),
+ debugger_enabled{parent.system.DebuggerEnabled()},
check_memory_access{debugger_enabled ||
!Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {}
@@ -468,7 +468,7 @@ void ARM_Dynarmic_32::PageTableChanged(Common::PageTable& page_table,
std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_32::GetBacktrace(Core::System& system,
u64 fp, u64 lr, u64 pc) {
std::vector<BacktraceEntry> out;
- auto& memory = system.Memory();
+ auto& memory = system.ApplicationMemory();
out.push_back({"", 0, pc, 0, ""});
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;
class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks {
public:
explicit DynarmicCallbacks64(ARM_Dynarmic_64& parent_)
- : parent{parent_},
- memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()},
+ : parent{parent_}, memory(parent.system.ApplicationMemory()),
+ debugger_enabled{parent.system.DebuggerEnabled()},
check_memory_access{debugger_enabled ||
!Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {}
@@ -529,7 +529,7 @@ void ARM_Dynarmic_64::PageTableChanged(Common::PageTable& page_table,
std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_64::GetBacktrace(Core::System& system,
u64 fp, u64 lr, u64 pc) {
std::vector<BacktraceEntry> out;
- auto& memory = system.Memory();
+ auto& memory = system.ApplicationMemory();
out.push_back({"", 0, pc, 0, ""});
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 {
ASSERT(Kernel::KProcess::Initialize(main_process, system, "main",
Kernel::KProcess::ProcessType::Userland, resource_limit)
.IsSuccess());
+ kernel.MakeApplicationProcess(main_process);
const auto [load_result, load_parameters] = app_loader->Load(*main_process, system);
if (load_result != Loader::ResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result);
@@ -302,7 +303,6 @@ struct System::Impl {
static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result));
}
AddGlueRegistrationForProcess(*app_loader, *main_process);
- kernel.MakeApplicationProcess(main_process);
kernel.InitializeCores();
// Initialize cheat engine
@@ -681,11 +681,11 @@ const ExclusiveMonitor& System::Monitor() const {
return impl->kernel.GetExclusiveMonitor();
}
-Memory::Memory& System::Memory() {
+Memory::Memory& System::ApplicationMemory() {
return impl->memory;
}
-const Core::Memory::Memory& System::Memory() const {
+const Core::Memory::Memory& System::ApplicationMemory() const {
return impl->memory;
}
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:
[[nodiscard]] const ExclusiveMonitor& Monitor() const;
/// Gets a mutable reference to the system memory instance.
- [[nodiscard]] Core::Memory::Memory& Memory();
+ [[nodiscard]] Core::Memory::Memory& ApplicationMemory();
/// Gets a constant reference to the system memory instance.
- [[nodiscard]] const Core::Memory::Memory& Memory() const;
+ [[nodiscard]] const Core::Memory::Memory& ApplicationMemory() const;
/// Gets a mutable reference to the GPU interface
[[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 @@
#include "common/windows/timer_resolution.h"
#endif
+#ifdef ARCHITECTURE_x86_64
+#include "common/x64/cpu_wait.h"
+#endif
+
#include "common/microprofile.h"
#include "core/core_timing.h"
#include "core/core_timing_util.h"
@@ -269,7 +273,11 @@ void CoreTiming::ThreadLoop() {
if (wait_time >= timer_resolution_ns) {
Common::Windows::SleepForOneTick();
} else {
+#ifdef ARCHITECTURE_x86_64
+ Common::X64::MicroSleep();
+#else
std::this_thread::yield();
+#endif
}
}
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
const size_t addr{static_cast<size_t>(strtoll(command.data(), nullptr, 16))};
const size_t size{static_cast<size_t>(strtoll(command.data() + sep, nullptr, 16))};
- if (system.Memory().IsValidVirtualAddressRange(addr, size)) {
+ if (system.ApplicationMemory().IsValidVirtualAddressRange(addr, size)) {
std::vector<u8> mem(size);
- system.Memory().ReadBlock(addr, mem.data(), size);
+ system.ApplicationMemory().ReadBlock(addr, mem.data(), size);
SendReply(Common::HexToString(mem));
} else {
@@ -281,8 +281,8 @@ void GDBStub::ExecuteCommand(std::string_view packet, std::vector<DebuggerAction
const auto mem_substr{std::string_view(command).substr(mem_sep)};
const auto mem{Common::HexStringToVector(mem_substr, false)};
- if (system.Memory().IsValidVirtualAddressRange(addr, size)) {
- system.Memory().WriteBlock(addr, mem.data(), size);
+ if (system.ApplicationMemory().IsValidVirtualAddressRange(addr, size)) {
+ system.ApplicationMemory().WriteBlock(addr, mem.data(), size);
system.InvalidateCpuInstructionCacheRange(addr, size);
SendReply(GDB_STUB_REPLY_OK);
} else {
@@ -325,7 +325,7 @@ void GDBStub::HandleBreakpointInsert(std::string_view command) {
const size_t addr{static_cast<size_t>(strtoll(command.data() + addr_sep, nullptr, 16))};
const size_t size{static_cast<size_t>(strtoll(command.data() + size_sep, nullptr, 16))};
- if (!system.Memory().IsValidVirtualAddressRange(addr, size)) {
+ if (!system.ApplicationMemory().IsValidVirtualAddressRange(addr, size)) {
SendReply(GDB_STUB_REPLY_ERR);
return;
}
@@ -334,22 +334,22 @@ void GDBStub::HandleBreakpointInsert(std::string_view command) {
switch (type) {
case BreakpointType::Software:
- replaced_instructions[addr] = system.Memory().Read32(addr);
- system.Memory().Write32(addr, arch->BreakpointInstruction());
+ replaced_instructions[addr] = system.ApplicationMemory().Read32(addr);
+ system.ApplicationMemory().Write32(addr, arch->BreakpointInstruction());
system.InvalidateCpuInstructionCacheRange(addr, sizeof(u32));
success = true;
break;
case BreakpointType::WriteWatch:
- success = system.ApplicationProcess()->InsertWatchpoint(system, addr, size,
+ success = system.ApplicationProcess()->InsertWatchpoint(addr, size,
Kernel::DebugWatchpointType::Write);
break;
case BreakpointType::ReadWatch:
- success = system.ApplicationProcess()->InsertWatchpoint(system, addr, size,
+ success = system.ApplicationProcess()->InsertWatchpoint(addr, size,
Kernel::DebugWatchpointType::Read);
break;
case BreakpointType::AccessWatch:
success = system.ApplicationProcess()->InsertWatchpoint(
- system, addr, size, Kernel::DebugWatchpointType::ReadOrWrite);
+ addr, size, Kernel::DebugWatchpointType::ReadOrWrite);
break;
case BreakpointType::Hardware:
default:
@@ -372,7 +372,7 @@ void GDBStub::HandleBreakpointRemove(std::string_view command) {
const size_t addr{static_cast<size_t>(strtoll(command.data() + addr_sep, nullptr, 16))};
const size_t size{static_cast<size_t>(strtoll(command.data() + size_sep, nullptr, 16))};
- if (!system.Memory().IsValidVirtualAddressRange(addr, size)) {
+ if (!system.ApplicationMemory().IsValidVirtualAddressRange(addr, size)) {
SendReply(GDB_STUB_REPLY_ERR);
return;
}
@@ -383,7 +383,7 @@ void GDBStub::HandleBreakpointRemove(std::string_view command) {
case BreakpointType::Software: {
const auto orig_insn{replaced_instructions.find(addr)};
if (orig_insn != replaced_instructions.end()) {
- system.Memory().Write32(addr, orig_insn->second);
+ system.ApplicationMemory().Write32(addr, orig_insn->second);
system.InvalidateCpuInstructionCacheRange(addr, sizeof(u32));
replaced_instructions.erase(addr);
success = true;
@@ -391,16 +391,16 @@ void GDBStub::HandleBreakpointRemove(std::string_view command) {
break;
}
case BreakpointType::WriteWatch:
- success = system.ApplicationProcess()->RemoveWatchpoint(system, addr, size,
+ success = system.ApplicationProcess()->RemoveWatchpoint(addr, size,
Kernel::DebugWatchpointType::Write);
break;
case BreakpointType::ReadWatch:
- success = system.ApplicationProcess()->RemoveWatchpoint(system, addr, size,
+ success = system.ApplicationProcess()->RemoveWatchpoint(addr, size,
Kernel::DebugWatchpointType::Read);
break;
case BreakpointType::AccessWatch:
success = system.ApplicationProcess()->RemoveWatchpoint(
- system, addr, size, Kernel::DebugWatchpointType::ReadOrWrite);
+ addr, size, Kernel::DebugWatchpointType::ReadOrWrite);
break;
case BreakpointType::Hardware:
default:
@@ -483,9 +483,9 @@ static std::optional<std::string> GetNameFromThreadType64(Core::Memory::Memory&
static std::optional<std::string> GetThreadName(Core::System& system,
const Kernel::KThread* thread) {
if (system.ApplicationProcess()->Is64BitProcess()) {
- return GetNameFromThreadType64(system.Memory(), thread);
+ return GetNameFromThreadType64(system.ApplicationMemory(), thread);
} else {
- return GetNameFromThreadType32(system.Memory(), thread);
+ return GetNameFromThreadType32(system.ApplicationMemory(), thread);
}
}
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;
namespace {
-bool ReadFromUser(Core::System& system, s32* out, KProcessAddress address) {
- *out = system.Memory().Read32(GetInteger(address));
+bool ReadFromUser(KernelCore& kernel, s32* out, KProcessAddress address) {
+ *out = GetCurrentMemory(kernel).Read32(GetInteger(address));
return true;
}
@@ -209,7 +209,7 @@ Result KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(uint64_t addr, s32
if (value != new_value) {
succeeded = UpdateIfEqual(m_system, std::addressof(user_value), addr, value, new_value);
} else {
- succeeded = ReadFromUser(m_system, std::addressof(user_value), addr);
+ succeeded = ReadFromUser(m_kernel, std::addressof(user_value), addr);
}
R_UNLESS(succeeded, ResultInvalidCurrentMemory);
@@ -252,7 +252,7 @@ Result KAddressArbiter::WaitIfLessThan(uint64_t addr, s32 value, bool decrement,
if (decrement) {
succeeded = DecrementIfLessThan(m_system, std::addressof(user_value), addr, value);
} else {
- succeeded = ReadFromUser(m_system, std::addressof(user_value), addr);
+ succeeded = ReadFromUser(m_kernel, std::addressof(user_value), addr);
}
if (!succeeded) {
@@ -303,7 +303,7 @@ Result KAddressArbiter::WaitIfEqual(uint64_t addr, s32 value, s64 timeout) {
// Read the value from userspace.
s32 user_value{};
- if (!ReadFromUser(m_system, std::addressof(user_value), addr)) {
+ if (!ReadFromUser(m_kernel, std::addressof(user_value), addr)) {
slp.CancelSleep();
R_THROW(ResultInvalidCurrentMemory);
}
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 {
namespace {
-bool ReadFromUser(Core::System& system, u32* out, KProcessAddress address) {
- *out = system.Memory().Read32(GetInteger(address));
+bool ReadFromUser(KernelCore& kernel, u32* out, KProcessAddress address) {
+ *out = GetCurrentMemory(kernel).Read32(GetInteger(address));
return true;
}
-bool WriteToUser(Core::System& system, KProcessAddress address, const u32* p) {
- system.Memory().Write32(GetInteger(address), *p);
+bool WriteToUser(KernelCore& kernel, KProcessAddress address, const u32* p) {
+ GetCurrentMemory(kernel).Write32(GetInteger(address), *p);
return true;
}
@@ -128,7 +128,7 @@ Result KConditionVariable::SignalToAddress(KProcessAddress addr) {
// Write the value to userspace.
Result result{ResultSuccess};
- if (WriteToUser(m_system, addr, std::addressof(next_value))) [[likely]] {
+ if (WriteToUser(m_kernel, addr, std::addressof(next_value))) [[likely]] {
result = ResultSuccess;
} else {
result = ResultInvalidCurrentMemory;
@@ -157,7 +157,7 @@ Result KConditionVariable::WaitForAddress(Handle handle, KProcessAddress addr, u
// Read the tag from userspace.
u32 test_tag{};
- R_UNLESS(ReadFromUser(m_system, std::addressof(test_tag), addr),
+ R_UNLESS(ReadFromUser(m_kernel, std::addressof(test_tag), addr),
ResultInvalidCurrentMemory);
// 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) {
// If we have no waiters, clear the has waiter flag.
if (it == m_tree.end() || it->GetConditionVariableKey() != cv_key) {
const u32 has_waiter_flag{};
- WriteToUser(m_system, cv_key, std::addressof(has_waiter_flag));
+ WriteToUser(m_kernel, cv_key, std::addressof(has_waiter_flag));
}
}
}
@@ -301,12 +301,12 @@ Result KConditionVariable::Wait(KProcessAddress addr, u64 key, u32 value, s64 ti
// Write to the cv key.
{
const u32 has_waiter_flag = 1;
- WriteToUser(m_system, key, std::addressof(has_waiter_flag));
+ WriteToUser(m_kernel, key, std::addressof(has_waiter_flag));
std::atomic_thread_fence(std::memory_order_seq_cst);
}
// Write the value to userspace.
- if (!WriteToUser(m_system, addr, std::addressof(next_value))) {
+ if (!WriteToUser(m_kernel, addr, std::addressof(next_value))) {
slp.CancelSleep();
R_THROW(ResultInvalidCurrentMemory);
}
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
bool enable_das_merge, bool from_back,
KMemoryManager::Pool pool, KProcessAddress code_addr,
size_t code_size, KSystemResource* system_resource,
- KResourceLimit* resource_limit) {
+ KResourceLimit* resource_limit,
+ Core::Memory::Memory& memory) {
const auto GetSpaceStart = [this](KAddressSpaceInfo::Type type) {
return KAddressSpaceInfo::GetAddressSpaceStart(m_address_space_width, type);
@@ -117,6 +118,9 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type
return KAddressSpaceInfo::GetAddressSpaceSize(m_address_space_width, type);
};
+ // Set the tracking memory
+ m_memory = std::addressof(memory);
+
// Set our width and heap/alias sizes
m_address_space_width = GetAddressSpaceWidthFromType(as_type);
const KProcessAddress start = 0;
@@ -334,10 +338,10 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type
void KPageTable::Finalize() {
// Finalize memory blocks.
- m_memory_block_manager.Finalize(
- m_memory_block_slab_manager, [&](KProcessAddress addr, u64 size) {
- m_system.Memory().UnmapRegion(*m_page_table_impl, addr, size);
- });
+ m_memory_block_manager.Finalize(m_memory_block_slab_manager,
+ [&](KProcessAddress addr, u64 size) {
+ m_memory->UnmapRegion(*m_page_table_impl, addr, size);
+ });
// Release any insecure mapped memory.
if (m_mapped_insecure_memory) {
@@ -1010,23 +1014,22 @@ Result KPageTable::SetupForIpcServer(KProcessAddress* out_addr, size_t size,
clear_size = 0;
}
- std::memset(m_system.Memory().GetPointer<void>(GetInteger(start_partial_virt)),
- fill_val, partial_offset);
+ std::memset(m_memory->GetPointer<void>(GetInteger(start_partial_virt)), fill_val,
+ partial_offset);
std::memcpy(
- m_system.Memory().GetPointer<void>(GetInteger(start_partial_virt) + partial_offset),
- m_system.Memory().GetPointer<void>(
- GetInteger(
- GetHeapVirtualAddress(m_system.Kernel().MemoryLayout(), cur_block_addr)) +
- partial_offset),
+ m_memory->GetPointer<void>(GetInteger(start_partial_virt) + partial_offset),
+ m_memory->GetPointer<void>(GetInteger(GetHeapVirtualAddress(
+ m_system.Kernel().MemoryLayout(), cur_block_addr)) +
+ partial_offset),
copy_size);
if (clear_size > 0) {
- std::memset(m_system.Memory().GetPointer<void>(GetInteger(start_partial_virt) +
- partial_offset + copy_size),
+ std::memset(m_memory->GetPointer<void>(GetInteger(start_partial_virt) +
+ partial_offset + copy_size),
fill_val, clear_size);
}
} else {
- std::memset(m_system.Memory().GetPointer<void>(GetInteger(start_partial_virt)),
- fill_val, PageSize);
+ std::memset(m_memory->GetPointer<void>(GetInteger(start_partial_virt)), fill_val,
+ PageSize);
}
// Map the page.
@@ -1099,15 +1102,14 @@ Result KPageTable::SetupForIpcServer(KProcessAddress* out_addr, size_t size,
GetHeapVirtualAddress(m_system.Kernel().MemoryLayout(), end_partial_page);
if (send) {
const size_t copy_size = src_end - mapping_src_end;
- std::memcpy(m_system.Memory().GetPointer<void>(GetInteger(end_partial_virt)),
- m_system.Memory().GetPointer<void>(GetInteger(GetHeapVirtualAddress(
+ std::memcpy(m_memory->GetPointer<void>(GetInteger(end_partial_virt)),
+ m_memory->GetPointer<void>(GetInteger(GetHeapVirtualAddress(
m_system.Kernel().MemoryLayout(), cur_block_addr))),
copy_size);
- std::memset(
- m_system.Memory().GetPointer<void>(GetInteger(end_partial_virt) + copy_size),
- fill_val, PageSize - copy_size);
+ std::memset(m_memory->GetPointer<void>(GetInteger(end_partial_virt) + copy_size),
+ fill_val, PageSize - copy_size);
} else {
- std::memset(m_system.Memory().GetPointer<void>(GetInteger(end_partial_virt)), fill_val,
+ std::memset(m_memory->GetPointer<void>(GetInteger(end_partial_virt)), fill_val,
PageSize);
}
@@ -2800,7 +2802,7 @@ Result KPageTable::SetHeapSize(u64* out, size_t size) {
// Clear all the newly allocated pages.
for (size_t cur_page = 0; cur_page < num_pages; ++cur_page) {
- std::memset(m_system.Memory().GetPointer(m_current_heap_end + (cur_page * PageSize)), 0,
+ std::memset(m_memory->GetPointer(m_current_heap_end + (cur_page * PageSize)), 0,
PageSize);
}
@@ -3006,7 +3008,7 @@ Result KPageTable::Operate(KProcessAddress addr, size_t num_pages, const KPageGr
const size_t size{node.GetNumPages() * PageSize};
// Map the pages.
- m_system.Memory().MapMemoryRegion(*m_page_table_impl, addr, size, node.GetAddress());
+ m_memory->MapMemoryRegion(*m_page_table_impl, addr, size, node.GetAddress());
addr += size;
}
@@ -3039,14 +3041,14 @@ Result KPageTable::Operate(KProcessAddress addr, size_t num_pages, KMemoryPermis
SCOPE_EXIT({ pages_to_close.CloseAndReset(); });
this->AddRegionToPages(addr, num_pages, pages_to_close);
- m_system.Memory().UnmapRegion(*m_page_table_impl, addr, num_pages * PageSize);
+ m_memory->UnmapRegion(*m_page_table_impl, addr, num_pages * PageSize);
break;
}
case OperationType::MapFirst:
case OperationType::Map: {
ASSERT(map_addr);
ASSERT(Common::IsAligned(GetInteger(map_addr), PageSize));
- m_system.Memory().MapMemoryRegion(*m_page_table_impl, addr, num_pages * PageSize, map_addr);
+ m_memory->MapMemoryRegion(*m_page_table_impl, addr, num_pages * PageSize, map_addr);
// Open references to pages, if we should.
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:
Result InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr,
bool enable_das_merge, bool from_back, KMemoryManager::Pool pool,
KProcessAddress code_addr, size_t code_size,
- KSystemResource* system_resource, KResourceLimit* resource_limit);
+ KSystemResource* system_resource, KResourceLimit* resource_limit,
+ Core::Memory::Memory& memory);
void Finalize();
@@ -546,6 +547,7 @@ private:
Core::System& m_system;
KernelCore& m_kernel;
+ Core::Memory::Memory* m_memory{};
};
} // 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:
// Initialize process address space
if (const Result result{m_page_table.InitializeForProcess(
metadata.GetAddressSpaceType(), false, false, false, KMemoryManager::Pool::Application,
- 0x8000000, code_size, std::addressof(m_kernel.GetAppSystemResource()),
- m_resource_limit)};
+ 0x8000000, code_size, std::addressof(m_kernel.GetAppSystemResource()), m_resource_limit,
+ m_kernel.System().ApplicationMemory())};
result.IsError()) {
R_RETURN(result);
}
@@ -592,8 +592,7 @@ Result KProcess::DeleteThreadLocalRegion(KProcessAddress addr) {
R_SUCCEED();
}
-bool KProcess::InsertWatchpoint(Core::System& system, KProcessAddress addr, u64 size,
- DebugWatchpointType type) {
+bool KProcess::InsertWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type) {
const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) {
return wp.type == DebugWatchpointType::None;
})};
@@ -609,14 +608,13 @@ bool KProcess::InsertWatchpoint(Core::System& system, KProcessAddress addr, u64
for (KProcessAddress page = Common::AlignDown(GetInteger(addr), PageSize); page < addr + size;
page += PageSize) {
m_debug_page_refcounts[page]++;
- system.Memory().MarkRegionDebug(page, PageSize, true);
+ this->GetMemory().MarkRegionDebug(page, PageSize, true);
}
return true;
}
-bool KProcess::RemoveWatchpoint(Core::System& system, KProcessAddress addr, u64 size,
- DebugWatchpointType type) {
+bool KProcess::RemoveWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type) {
const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) {
return wp.start_address == addr && wp.end_address == addr + size && wp.type == type;
})};
@@ -633,7 +631,7 @@ bool KProcess::RemoveWatchpoint(Core::System& system, KProcessAddress addr, u64
page += PageSize) {
m_debug_page_refcounts[page]--;
if (!m_debug_page_refcounts[page]) {
- system.Memory().MarkRegionDebug(page, PageSize, false);
+ this->GetMemory().MarkRegionDebug(page, PageSize, false);
}
}
@@ -646,8 +644,7 @@ void KProcess::LoadModule(CodeSet code_set, KProcessAddress base_addr) {
m_page_table.SetProcessMemoryPermission(segment.addr + base_addr, segment.size, permission);
};
- m_kernel.System().Memory().WriteBlock(*this, base_addr, code_set.memory.data(),
- code_set.memory.size());
+ this->GetMemory().WriteBlock(base_addr, code_set.memory.data(), code_set.memory.size());
ReprotectSegment(code_set.CodeSegment(), Svc::MemoryPermission::ReadExecute);
ReprotectSegment(code_set.RODataSegment(), Svc::MemoryPermission::Read);
@@ -706,4 +703,9 @@ Result KProcess::AllocateMainThreadStack(std::size_t stack_size) {
R_SUCCEED();
}
+Core::Memory::Memory& KProcess::GetMemory() const {
+ // TODO: per-process memory
+ return m_kernel.System().ApplicationMemory();
+}
+
} // 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 @@
#include "core/hle/result.h"
namespace Core {
+namespace Memory {
+class Memory;
+};
+
class System;
-}
+} // namespace Core
namespace FileSys {
class ProgramMetadata;
@@ -135,6 +139,9 @@ public:
return m_handle_table;
}
+ /// Gets a reference to process's memory.
+ Core::Memory::Memory& GetMemory() const;
+
Result SignalToAddress(KProcessAddress address) {
return m_condition_var.SignalToAddress(address);
}
@@ -397,12 +404,10 @@ public:
// Debug watchpoint management
// Attempts to insert a watchpoint into a free slot. Returns false if none are available.
- bool InsertWatchpoint(Core::System& system, KProcessAddress addr, u64 size,
- DebugWatchpointType type);
+ bool InsertWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type);
// Attempts to remove the watchpoint specified by the given parameters.
- bool RemoveWatchpoint(Core::System& system, KProcessAddress addr, u64 size,
- DebugWatchpointType type);
+ bool RemoveWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type);
const std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS>& GetWatchpoints() const {
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) {
// HLE servers write directly to a pointer to the thread command buffer. Therefore
// the reply has already been written in this case.
} else {
- Core::Memory::Memory& memory{m_kernel.System().Memory()};
+ Core::Memory::Memory& memory{client_thread->GetOwnerProcess()->GetMemory()};
KThread* server_thread{GetCurrentThreadPointer(m_kernel)};
UNIMPLEMENTED_IF(server_thread->GetOwnerProcess() != client_thread->GetOwnerProcess());
@@ -319,7 +319,7 @@ Result KServerSession::ReceiveRequest(std::shared_ptr<Service::HLERequestContext
// bool recv_list_broken = false;
// Receive the message.
- Core::Memory::Memory& memory{m_kernel.System().Memory()};
+ Core::Memory::Memory& memory{client_thread->GetOwnerProcess()->GetMemory()};
if (out_context != nullptr) {
// HLE request.
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 {
return {};
}
- auto& memory = m_kernel.System().Memory();
+ auto& memory = this->GetOwnerProcess()->GetMemory();
return memory.Read16(m_tls_address + offsetof(ThreadLocalRegion, disable_count));
}
@@ -556,7 +556,7 @@ void KThread::SetInterruptFlag() {
return;
}
- auto& memory = m_kernel.System().Memory();
+ auto& memory = this->GetOwnerProcess()->GetMemory();
memory.Write16(m_tls_address + offsetof(ThreadLocalRegion, interrupt_flag), 1);
}
@@ -566,7 +566,7 @@ void KThread::ClearInterruptFlag() {
return;
}
- auto& memory = m_kernel.System().Memory();
+ auto& memory = this->GetOwnerProcess()->GetMemory();
memory.Write16(m_tls_address + offsetof(ThreadLocalRegion, interrupt_flag), 0);
}
@@ -1422,6 +1422,11 @@ s32 GetCurrentCoreId(KernelCore& kernel) {
return GetCurrentThread(kernel).GetCurrentCore();
}
+Core::Memory::Memory& GetCurrentMemory(KernelCore& kernel) {
+ // TODO: per-process memory
+ return kernel.System().ApplicationMemory();
+}
+
KScopedDisableDispatch::~KScopedDisableDispatch() {
// If we are shutting down the kernel, none of this is relevant anymore.
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;
}
namespace Core {
+namespace Memory {
+class Memory;
+}
class ARM_Interface;
class System;
} // namespace Core
@@ -113,6 +116,7 @@ KThread& GetCurrentThread(KernelCore& kernel);
KProcess* GetCurrentProcessPointer(KernelCore& kernel);
KProcess& GetCurrentProcess(KernelCore& kernel);
s32 GetCurrentCoreId(KernelCore& kernel);
+Core::Memory::Memory& GetCurrentMemory(KernelCore& kernel);
class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KWorkerTask>,
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 {
void InitializeCores() {
for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) {
cores[core_id]->Initialize((*application_process).Is64BitProcess());
- system.Memory().SetCurrentPageTable(*application_process, core_id);
+ system.ApplicationMemory().SetCurrentPageTable(*application_process, core_id);
}
}
@@ -206,7 +206,7 @@ struct KernelCore::Impl {
void InitializePhysicalCores() {
exclusive_monitor =
- Core::MakeExclusiveMonitor(system.Memory(), Core::Hardware::NUM_CPU_CORES);
+ Core::MakeExclusiveMonitor(system.ApplicationMemory(), Core::Hardware::NUM_CPU_CORES);
for (u32 i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
const s32 core{static_cast<s32>(i)};
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
R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory);
// Perform the operation.
- R_RETURN(system.Memory().FlushDataCache(*process, address, size));
+ R_RETURN(GetCurrentMemory(system.Kernel()).FlushDataCache(address, size));
}
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 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/core.h"
+#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/svc.h"
#include "core/memory.h"
@@ -12,7 +13,7 @@ Result OutputDebugString(Core::System& system, u64 address, u64 len) {
R_SUCCEED_IF(len == 0);
std::string str(len, '\0');
- system.Memory().ReadBlock(address, str.data(), str.size());
+ GetCurrentMemory(system.Kernel()).ReadBlock(address, str.data(), str.size());
LOG_DEBUG(Debug_Emulated, "{}", str);
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) {
return;
}
- auto& memory = system.Memory();
+ auto& memory = GetCurrentMemory(system.Kernel());
// This typically is an error code so we're going to assume this is the case
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
auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
R_UNLESS(0 <= num_handles && num_handles <= ArgumentHandleCountMax, ResultOutOfRange);
- R_UNLESS(system.Memory().IsValidVirtualAddressRange(
+ R_UNLESS(GetCurrentMemory(kernel).IsValidVirtualAddressRange(
handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)),
ResultInvalidPointer);
std::vector<Handle> handles(num_handles);
- system.Memory().ReadBlock(handles_addr, handles.data(), sizeof(Handle) * num_handles);
+ GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(), sizeof(Handle) * num_handles);
// Convert handle list to object table.
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 {
Result ConnectToNamedPort(Core::System& system, Handle* out, u64 user_name) {
// Copy the provided name from user memory to kernel memory.
- auto string_name = system.Memory().ReadCString(user_name, KObjectName::NameLengthMax);
+ auto string_name =
+ GetCurrentMemory(system.Kernel()).ReadCString(user_name, KObjectName::NameLengthMax);
std::array<char, KObjectName::NameLengthMax> name{};
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) {
Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name,
int32_t max_sessions) {
// Copy the provided name from user memory to kernel memory.
- auto string_name = system.Memory().ReadCString(user_name, KObjectName::NameLengthMax);
+ auto string_name =
+ GetCurrentMemory(system.Kernel()).ReadCString(user_name, KObjectName::NameLengthMax);
// Copy the provided name from user memory to kernel memory.
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
R_THROW(ResultInvalidCurrentMemory);
}
- auto& memory = system.Memory();
+ auto& memory = GetCurrentMemory(kernel);
const auto& process_list = kernel.GetProcessList();
const auto num_processes = process_list.size();
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
R_THROW(ResultInvalidHandle);
}
- auto& memory{system.Memory()};
+ auto& current_memory{GetCurrentMemory(system.Kernel())};
const auto memory_info{process->PageTable().QueryInfo(address).GetSvcMemoryInfo()};
- memory.WriteBlock(out_memory_info, std::addressof(memory_info), sizeof(memory_info));
+ current_memory.WriteBlock(out_memory_info, std::addressof(memory_info), sizeof(memory_info));
//! This is supposed to be part of the QueryInfo call.
*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
std::vector<Handle> handles(num_handles);
if (num_handles > 0) {
- system.Memory().ReadBlock(user_handles, handles.data(), num_handles * sizeof(Handle));
+ GetCurrentMemory(system.Kernel())
+ .ReadBlock(user_handles, handles.data(), num_handles * sizeof(Handle));
}
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
R_TRY(thread->GetThreadContext3(context));
// Copy the thread context to user space.
- system.Memory().WriteBlock(out_context, context.data(), context.size());
+ GetCurrentMemory(kernel).WriteBlock(out_context, context.data(), context.size());
R_SUCCEED();
}
@@ -242,7 +242,7 @@ Result GetThreadList(Core::System& system, s32* out_num_threads, u64 out_thread_
R_THROW(ResultInvalidCurrentMemory);
}
- auto& memory = system.Memory();
+ auto& memory = GetCurrentMemory(system.Kernel());
const auto& thread_list = current_process->GetThreadList();
const auto num_threads = thread_list.size();
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)
}
std::vector<u8> memory(transfer_mem->GetSize());
- system.Memory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(), memory.size());
+ system.ApplicationMemory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(),
+ memory.size());
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
@@ -1307,7 +1308,8 @@ void ILibraryAppletCreator::CreateHandleStorage(HLERequestContext& ctx) {
}
std::vector<u8> memory(transfer_mem->GetSize());
- system.Memory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(), memory.size());
+ system.ApplicationMemory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(),
+ memory.size());
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
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
// Update seven six axis transfer memory
seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state);
- system.Memory().WriteBlock(transfer_memory, &seven_sixaxis_lifo, sizeof(seven_sixaxis_lifo));
+ system.ApplicationMemory().WriteBlock(transfer_memory, &seven_sixaxis_lifo,
+ sizeof(seven_sixaxis_lifo));
}
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,
return NpadIsDualJoycon;
}
- // Disconnect the joycon at the second id and connect the dual joycon at the first index.
+ // Disconnect the joycons and connect them as dual joycon at the first index.
+ DisconnectNpad(npad_id_1);
DisconnectNpad(npad_id_2);
controller_1.is_dual_left_connected = true;
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() {
curr_entry.polling_data.out_size = sizeof(ringcon_value);
std::memcpy(curr_entry.polling_data.data.data(), &ringcon_value, sizeof(ringcon_value));
- system.Memory().WriteBlock(transfer_memory, &enable_sixaxis_data,
- sizeof(enable_sixaxis_data));
+ system.ApplicationMemory().WriteBlock(transfer_memory, &enable_sixaxis_data,
+ sizeof(enable_sixaxis_data));
break;
}
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
if (camera_data.format != current_config.origin_format) {
LOG_WARNING(Service_IRS, "Wrong Input format {} expected {}", camera_data.format,
current_config.origin_format);
- system.Memory().ZeroBlock(*system.ApplicationProcess(), transfer_memory,
- GetDataSize(current_config.trimming_format));
+ system.ApplicationMemory().ZeroBlock(transfer_memory,
+ GetDataSize(current_config.trimming_format));
return;
}
if (current_config.origin_format > current_config.trimming_format) {
LOG_WARNING(Service_IRS, "Origin format {} is smaller than trimming format {}",
current_config.origin_format, current_config.trimming_format);
- system.Memory().ZeroBlock(*system.ApplicationProcess(), transfer_memory,
- GetDataSize(current_config.trimming_format));
+ system.ApplicationMemory().ZeroBlock(transfer_memory,
+ GetDataSize(current_config.trimming_format));
return;
}
@@ -84,8 +84,8 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType
"Trimming area ({}, {}, {}, {}) is outside of origin area ({}, {})",
current_config.trimming_start_x, current_config.trimming_start_y,
trimming_width, trimming_height, origin_width, origin_height);
- system.Memory().ZeroBlock(*system.ApplicationProcess(), transfer_memory,
- GetDataSize(current_config.trimming_format));
+ system.ApplicationMemory().ZeroBlock(transfer_memory,
+ GetDataSize(current_config.trimming_format));
return;
}
@@ -99,8 +99,8 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType
}
}
- system.Memory().WriteBlock(transfer_memory, window_data.data(),
- GetDataSize(current_config.trimming_format));
+ system.ApplicationMemory().WriteBlock(transfer_memory, window_data.data(),
+ GetDataSize(current_config.trimming_format));
if (!IsProcessorActive()) {
StartProcessor();
@@ -148,7 +148,7 @@ Core::IrSensor::ImageTransferProcessorState ImageTransferProcessor::GetState(
std::vector<u8>& data) const {
const auto size = GetDataSize(current_config.trimming_format);
data.resize(size);
- system.Memory().ReadBlock(transfer_memory, data.data(), size);
+ system.ApplicationMemory().ReadBlock(transfer_memory, data.data(), size);
return processor_state;
}
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
}
// Copy the translated command buffer back into the thread's command buffer area.
- memory.WriteBlock(owner_process, requesting_thread.GetTlsAddress(), cmd_buf.data(),
- write_size * sizeof(u32));
+ memory.WriteBlock(requesting_thread.GetTlsAddress(), cmd_buf.data(), write_size * sizeof(u32));
return ResultSuccess;
}
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> {
public:
explicit IJitEnvironment(Core::System& system_, Kernel::KProcess& process_, CodeRange user_rx,
CodeRange user_ro)
- : ServiceFramework{system_, "IJitEnvironment"}, process{&process_}, context{
- system_.Memory()} {
+ : ServiceFramework{system_, "IJitEnvironment"}, process{&process_},
+ context{system_.ApplicationMemory()} {
// clang-format off
static const FunctionInfo functions[] = {
{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:
// Read NRR data from memory
std::vector<u8> nrr_data(nrr_size);
- system.Memory().ReadBlock(nrr_address, nrr_data.data(), nrr_size);
+ system.ApplicationMemory().ReadBlock(nrr_address, nrr_data.data(), nrr_size);
NRRHeader header;
std::memcpy(&header, nrr_data.data(), sizeof(NRRHeader));
@@ -314,7 +314,7 @@ public:
const auto is_region_available = [&](VAddr addr) {
const auto end_addr = addr + size;
while (addr < end_addr) {
- if (system.Memory().IsValidVirtualAddress(addr)) {
+ if (system.ApplicationMemory().IsValidVirtualAddress(addr)) {
return false;
}
@@ -427,8 +427,8 @@ public:
const VAddr bss_end_addr{
Common::AlignUp(bss_start + nro_header.bss_size, Kernel::PageSize)};
- const auto CopyCode = [this, process](VAddr src_addr, VAddr dst_addr, u64 size) {
- system.Memory().CopyBlock(*process, dst_addr, src_addr, size);
+ const auto CopyCode = [this](VAddr src_addr, VAddr dst_addr, u64 size) {
+ system.ApplicationMemory().CopyBlock(dst_addr, src_addr, size);
};
CopyCode(nro_addr + nro_header.segment_headers[TEXT_INDEX].memory_offset, text_start,
nro_header.segment_headers[TEXT_INDEX].memory_size);
@@ -506,7 +506,7 @@ public:
// Read NRO data from memory
std::vector<u8> nro_data(nro_size);
- system.Memory().ReadBlock(nro_address, nro_data.data(), nro_size);
+ system.ApplicationMemory().ReadBlock(nro_address, nro_data.data(), nro_size);
SHA256Hash hash{};
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) {
return true;
}
+bool IsAmiiboValid(const NTAG215File& ntag_file) {
+ return IsAmiiboValid(EncodedDataToNfcData(ntag_file));
+}
+
NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) {
NTAG215File encoded_data{};
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");
/// Validates that the amiibo file is not corrupted
bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file);
+/// Validates that the amiibo file is not corrupted
+bool IsAmiiboValid(const NTAG215File& ntag_file);
+
/// Converts from encrypted file format to encoded file format
NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data);
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) {
// TODO: Filter by allowed_protocols here
- memcpy(&encrypted_tag_data, data.data(), sizeof(EncryptedNTAG215File));
+ memcpy(&tag_data, data.data(), sizeof(EncryptedNTAG215File));
+ is_plain_amiibo = AmiiboCrypto::IsAmiiboValid(tag_data);
+
+ if (is_plain_amiibo) {
+ encrypted_tag_data = AmiiboCrypto::EncodedDataToNfcData(tag_data);
+ LOG_INFO(Service_NFP, "Using plain amiibo");
+ } else {
+ tag_data = {};
+ memcpy(&encrypted_tag_data, data.data(), sizeof(EncryptedNTAG215File));
+ }
device_state = DeviceState::TagFound;
deactivate_event->GetReadableEvent().Clear();
@@ -232,13 +241,17 @@ Result NfpDevice::Flush() {
tag_data.write_counter++;
- if (!AmiiboCrypto::EncodeAmiibo(tag_data, encrypted_tag_data)) {
- LOG_ERROR(Service_NFP, "Failed to encode data");
- return WriteAmiiboFailed;
- }
+ std::vector<u8> data(sizeof(EncryptedNTAG215File));
+ if (is_plain_amiibo) {
+ memcpy(data.data(), &tag_data, sizeof(tag_data));
+ } else {
+ if (!AmiiboCrypto::EncodeAmiibo(tag_data, encrypted_tag_data)) {
+ LOG_ERROR(Service_NFP, "Failed to encode data");
+ return WriteAmiiboFailed;
+ }
- std::vector<u8> data(sizeof(encrypted_tag_data));
- memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data));
+ memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data));
+ }
if (!npad_device->WriteNfc(data)) {
LOG_ERROR(Service_NFP, "Error writing to file");
@@ -256,6 +269,13 @@ Result NfpDevice::Mount(MountTarget mount_target_) {
return WrongDeviceState;
}
+ // The loaded amiibo is not encrypted
+ if (is_plain_amiibo) {
+ device_state = DeviceState::TagMounted;
+ mount_target = mount_target_;
+ return ResultSuccess;
+ }
+
if (!AmiiboCrypto::IsAmiiboValid(encrypted_tag_data)) {
LOG_ERROR(Service_NFP, "Not an amiibo");
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:
bool is_initalized{};
bool is_data_moddified{};
bool is_app_area_open{};
+ bool is_plain_amiibo{};
TagProtocol allowed_protocols{};
s64 current_posix_time{};
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 {
u32 CFG1; // Defines number of verification attempts
NTAG215Password password; // Password data
};
-static_assert(sizeof(EncryptedNTAG215File) == 0x21C, "EncryptedNTAG215File is an invalid size");
+static_assert(sizeof(EncryptedNTAG215File) == sizeof(NTAG215File),
+ "EncryptedNTAG215File is an invalid size");
static_assert(std::is_trivially_copyable_v<EncryptedNTAG215File>,
"EncryptedNTAG215File must be trivially copyable.");
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>
Tegra::CommandList entries(params.num_entries);
if (kickoff) {
- system.Memory().ReadBlock(params.address, entries.command_lists.data(),
- params.num_entries * sizeof(Tegra::CommandListHeader));
+ system.ApplicationMemory().ReadBlock(params.address, entries.command_lists.data(),
+ params.num_entries * sizeof(Tegra::CommandListHeader));
} else {
std::memcpy(entries.command_lists.data(), &input[sizeof(IoctlSubmitGpfifo)],
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,
const auto object = nvmap.GetHandle(cmd_buffer.memory_id);
ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;);
Tegra::ChCommandHeaderList cmdlist(cmd_buffer.word_count);
- system.Memory().ReadBlock(object->address + cmd_buffer.offset, cmdlist.data(),
- cmdlist.size() * sizeof(u32));
+ system.ApplicationMemory().ReadBlock(object->address + cmd_buffer.offset, cmdlist.data(),
+ cmdlist.size() * sizeof(u32));
gpu.PushCommandBuffer(core.Host1xDeviceFile().fd_to_id[fd], cmdlist);
}
std::memcpy(output.data(), &params, 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
return impl->ReadCString(vaddr, max_length);
}
-void Memory::ReadBlock(const Kernel::KProcess& process, const Common::ProcessAddress src_addr,
- void* dest_buffer, const std::size_t size) {
- impl->ReadBlockImpl<false>(process, src_addr, dest_buffer, size);
-}
-
void Memory::ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
const std::size_t size) {
impl->ReadBlock(src_addr, dest_buffer, size);
@@ -847,11 +842,6 @@ void Memory::ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_b
impl->ReadBlockUnsafe(src_addr, dest_buffer, size);
}
-void Memory::WriteBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
- const void* src_buffer, std::size_t size) {
- impl->WriteBlockImpl<false>(process, dest_addr, src_buffer, size);
-}
-
void Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer,
const std::size_t size) {
impl->WriteBlock(dest_addr, src_buffer, size);
@@ -862,29 +852,25 @@ void Memory::WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void
impl->WriteBlockUnsafe(dest_addr, src_buffer, size);
}
-void Memory::CopyBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
- Common::ProcessAddress src_addr, const std::size_t size) {
- impl->CopyBlock(process, dest_addr, src_addr, size);
+void Memory::CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
+ const std::size_t size) {
+ impl->CopyBlock(*system.ApplicationProcess(), dest_addr, src_addr, size);
}
-void Memory::ZeroBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
- const std::size_t size) {
- impl->ZeroBlock(process, dest_addr, size);
+void Memory::ZeroBlock(Common::ProcessAddress dest_addr, const std::size_t size) {
+ impl->ZeroBlock(*system.ApplicationProcess(), dest_addr, size);
}
-Result Memory::InvalidateDataCache(const Kernel::KProcess& process,
- Common::ProcessAddress dest_addr, const std::size_t size) {
- return impl->InvalidateDataCache(process, dest_addr, size);
+Result Memory::InvalidateDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
+ return impl->InvalidateDataCache(*system.ApplicationProcess(), dest_addr, size);
}
-Result Memory::StoreDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
- const std::size_t size) {
- return impl->StoreDataCache(process, dest_addr, size);
+Result Memory::StoreDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
+ return impl->StoreDataCache(*system.ApplicationProcess(), dest_addr, size);
}
-Result Memory::FlushDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
- const std::size_t size) {
- return impl->FlushDataCache(process, dest_addr, size);
+Result Memory::FlushDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
+ return impl->FlushDataCache(*system.ApplicationProcess(), dest_addr, size);
}
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:
std::string ReadCString(Common::ProcessAddress vaddr, std::size_t max_length);
/**
- * Reads a contiguous block of bytes from a specified process' address space.
- *
- * @param process The process to read the data from.
- * @param src_addr The virtual address to begin reading from.
- * @param dest_buffer The buffer to place the read bytes into.
- * @param size The amount of data to read, in bytes.
- *
- * @note If a size of 0 is specified, then this function reads nothing and
- * no attempts to access memory are made at all.
- *
- * @pre dest_buffer must be at least size bytes in length, otherwise a
- * buffer overrun will occur.
- *
- * @post The range [dest_buffer, size) contains the read bytes from the
- * process' address space.
- */
- void ReadBlock(const Kernel::KProcess& process, Common::ProcessAddress src_addr,
- void* dest_buffer, std::size_t size);
-
- /**
* Reads a contiguous block of bytes from the current process' address space.
*
* @param src_addr The virtual address to begin reading from.
@@ -362,29 +342,6 @@ public:
void ReadBlockUnsafe(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size);
/**
- * Writes a range of bytes into a given process' address space at the specified
- * virtual address.
- *
- * @param process The process to write data into the address space of.
- * @param dest_addr The destination virtual address to begin writing the data at.
- * @param src_buffer The data to write into the process' address space.
- * @param size The size of the data to write, in bytes.
- *
- * @post The address range [dest_addr, size) in the process' address space
- * contains the data that was within src_buffer.
- *
- * @post If an attempt is made to write into an unmapped region of memory, the writes
- * will be ignored and an error will be logged.
- *
- * @post If a write is performed into a region of memory that is considered cached
- * rasterizer memory, will cause the currently active rasterizer to be notified
- * and will mark that region as invalidated to caches that the active
- * graphics backend may be maintaining over the course of execution.
- */
- void WriteBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
- const void* src_buffer, std::size_t size);
-
- /**
* Writes a range of bytes into the current process' address space at the specified
* virtual address.
*
@@ -428,7 +385,6 @@ public:
* Copies data within a process' address space to another location within the
* same address space.
*
- * @param process The process that will have data copied within its address space.
* @param dest_addr The destination virtual address to begin copying the data into.
* @param src_addr The source virtual address to begin copying the data from.
* @param size The size of the data to copy, in bytes.
@@ -436,58 +392,50 @@ public:
* @post The range [dest_addr, size) within the process' address space contains the
* same data within the range [src_addr, size).
*/
- void CopyBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
- Common::ProcessAddress src_addr, std::size_t size);
+ void CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
+ std::size_t size);
/**
* Zeros a range of bytes within the current process' address space at the specified
* virtual address.
*
- * @param process The process that will have data zeroed within its address space.
* @param dest_addr The destination virtual address to zero the data from.
* @param size The size of the range to zero out, in bytes.
*
* @post The range [dest_addr, size) within the process' address space contains the
* value 0.
*/
- void ZeroBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
- std::size_t size);
+ void ZeroBlock(Common::ProcessAddress dest_addr, std::size_t size);
/**
* Invalidates a range of bytes within the current process' address space at the specified
* virtual address.
*
- * @param process The process that will have data invalidated within its address space.
* @param dest_addr The destination virtual address to invalidate the data from.
* @param size The size of the range to invalidate, in bytes.
*
*/
- Result InvalidateDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
- std::size_t size);
+ Result InvalidateDataCache(Common::ProcessAddress dest_addr, std::size_t size);
/**
* Stores a range of bytes within the current process' address space at the specified
* virtual address.
*
- * @param process The process that will have data stored within its address space.
* @param dest_addr The destination virtual address to store the data from.
* @param size The size of the range to store, in bytes.
*
*/
- Result StoreDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
- std::size_t size);
+ Result StoreDataCache(Common::ProcessAddress dest_addr, std::size_t size);
/**
* Flushes a range of bytes within the current process' address space at the specified
* virtual address.
*
- * @param process The process that will have data flushed within its address space.
* @param dest_addr The destination virtual address to flush the data from.
* @param size The size of the range to flush, in bytes.
*
*/
- Result FlushDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
- std::size_t size);
+ Result FlushDataCache(Common::ProcessAddress dest_addr, std::size_t size);
/**
* 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
StandardVmCallbacks::~StandardVmCallbacks() = default;
void StandardVmCallbacks::MemoryRead(VAddr address, void* data, u64 size) {
- system.Memory().ReadBlock(SanitizeAddress(address), data, size);
+ system.ApplicationMemory().ReadBlock(SanitizeAddress(address), data, size);
}
void StandardVmCallbacks::MemoryWrite(VAddr address, const void* data, u64 size) {
- system.Memory().WriteBlock(SanitizeAddress(address), data, size);
+ system.ApplicationMemory().WriteBlock(SanitizeAddress(address), data, size);
}
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,
const auto title_id = system.GetApplicationProcessProgramID();
auto out = GetFullDataAuto(timestamp, title_id, system);
- auto function_out = GetHLERequestContextData(ctx, system.Memory());
+ auto function_out = GetHLERequestContextData(ctx, system.ApplicationMemory());
function_out["command_id"] = command_id;
function_out["function_name"] = name;
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 @@
add_executable(tests
common/bit_field.cpp
common/cityhash.cpp
+ common/container_hash.cpp
common/fibers.cpp
common/host_memory.cpp
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 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <catch2/catch_test_macros.hpp>
+
+#include "common/common_types.h"
+#include "common/container_hash.h"
+
+TEST_CASE("ContainerHash", "[common]") {
+ constexpr std::array<u8, 32> U8Values{
+ 114, 10, 238, 189, 199, 242, 86, 96, 53, 193, 195, 247, 249, 56, 253, 61,
+ 205, 3, 172, 4, 210, 197, 43, 72, 103, 8, 99, 89, 5, 97, 68, 196,
+ };
+ constexpr std::array<u16, 32> U16Values{
+ 61586, 49151, 3313, 11641, 31695, 54795, 46764, 20965, 23287, 14039, 19265,
+ 49093, 58932, 22518, 27139, 42825, 57417, 54237, 48057, 14586, 42813, 32994,
+ 33970, 45501, 5619, 15895, 33227, 27509, 25391, 37275, 60218, 17599,
+ };
+ constexpr std::array<u32, 32> U32Values{
+ 3838402410U, 2029146863U, 1730869921U, 985528872U, 186773874U, 2094639868U, 3324775932U,
+ 1795512424U, 2571165571U, 3256934519U, 2358691590U, 2752682538U, 1484336451U, 378124520U,
+ 3463015699U, 3395942161U, 1263211979U, 3473632889U, 3039822212U, 2068707357U, 2223837919U,
+ 1823232191U, 1583884041U, 1264393380U, 4087566993U, 3188607101U, 3933680362U, 1464520765U,
+ 1786838406U, 1311734848U, 2773642241U, 3993641692U,
+ };
+ constexpr std::array<u64, 32> U64Values{
+ 5908025796157537817ULL, 10947547850358315100ULL, 844798943576724669ULL,
+ 7999662937458523703ULL, 4006550374705895164ULL, 1832550525423503632ULL,
+ 9323088254855830976ULL, 12028890075598379412ULL, 6021511300787826236ULL,
+ 7864675007938747948ULL, 18099387408859708806ULL, 6438638299316820708ULL,
+ 9029399285648501543ULL, 18195459433089960253ULL, 17214335092761966083ULL,
+ 5549347964591337833ULL, 14899526073304962015ULL, 5058883181561464475ULL,
+ 7436311795731206973ULL, 7535129567768649864ULL, 1287169596809258072ULL,
+ 8237671246353565927ULL, 1715230541978016153ULL, 8443157615068813300ULL,
+ 6098675262328527839ULL, 704652094100376853ULL, 1303411723202926503ULL,
+ 7808312933946424854ULL, 6863726670433556594ULL, 9870361541383217495ULL,
+ 9273671094091079488ULL, 17541434976160119010ULL,
+ };
+
+ REQUIRE(Common::HashValue(U8Values) == 5867183267093890552ULL);
+ REQUIRE(Common::HashValue(U16Values) == 9594135570564347135ULL);
+ REQUIRE(Common::HashValue(U32Values) == 13123757214696618460ULL);
+ REQUIRE(Common::HashValue(U64Values) == 7296500016546938380ULL);
+}
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 @@
#include <optional>
#include <span>
-#include <boost/container_hash/hash.hpp>
+#include "common/container_hash.h"
#include <fstream>
#include "common/assert.h"
@@ -89,7 +89,7 @@ void MacroEngine::Execute(u32 method, const std::vector<u32>& parameters) {
if (!mid_method.has_value()) {
cache_info.lle_program = Compile(macro_code->second);
- cache_info.hash = boost::hash_value(macro_code->second);
+ cache_info.hash = Common::HashValue(macro_code->second);
if (Settings::values.dump_macros) {
Dump(cache_info.hash, macro_code->second);
}
@@ -100,7 +100,7 @@ void MacroEngine::Execute(u32 method, const std::vector<u32>& parameters) {
code.resize(macro_cached.size() - rebased_method);
std::memcpy(code.data(), macro_cached.data() + rebased_method,
code.size() * sizeof(u32));
- cache_info.hash = boost::hash_value(code);
+ cache_info.hash = Common::HashValue(code);
cache_info.lle_program = Compile(code);
if (Settings::values.dump_macros) {
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{};
MemoryManager::MemoryManager(Core::System& system_, u64 address_space_bits_, u64 big_page_bits_,
u64 page_bits_)
- : system{system_}, memory{system.Memory()}, device_memory{system.DeviceMemory()},
+ : system{system_}, memory{system.ApplicationMemory()}, device_memory{system.DeviceMemory()},
address_space_bits{address_space_bits_}, page_bits{page_bits_}, big_page_bits{big_page_bits_},
entries{}, big_entries{}, page_table{address_space_bits, address_space_bits + page_bits - 38,
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(
Core::System& system, Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu,
std::unique_ptr<Core::Frontend::GraphicsContext> context) {
auto& telemetry_session = system.TelemetrySession();
- auto& cpu_memory = system.Memory();
+ auto& cpu_memory = system.ApplicationMemory();
switch (Settings::values.renderer_backend.GetValue()) {
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
system->Initialize();
Common::Log::Initialize();
+ Common::Log::Start();
+
LoadTranslation();
setAcceptDrops(true);
@@ -449,8 +451,6 @@ GMainWindow::GMainWindow(std::unique_ptr<Config> config_, bool has_broken_vulkan
SetupPrepareForSleep();
- Common::Log::Start();
-
QStringList args = QApplication::arguments();
if (args.size() < 2) {
diff --git a/vcpkg.json b/vcpkg.json
index 9aadd367c..0352dab77 100644
--- a/vcpkg.json
+++ b/vcpkg.json
@@ -1,7 +1,7 @@
{
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json",
"name": "yuzu",
- "builtin-baseline": "a7b6122f6b6504d16d96117336a0562693579933",
+ "builtin-baseline": "acc3bcf76b84ae5041c86ab55fe138ae7b8255c7",
"version": "1.0",
"dependencies": [
"boost-algorithm",