aboutsummaryrefslogtreecommitdiff
path: root/src/core/memory.cpp
diff options
context:
space:
mode:
authorTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-28 04:56:14 -0400
committerTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-28 04:56:14 -0400
commit64c91974f4455a63a025149a4ba8e2c46894bdc7 (patch)
tree3712d1c121e020e6a0eabb883f47745bbb8cd89a /src/core/memory.cpp
parent1517ba02d3247a8deaad9ac493b9ad4a3deb7506 (diff)
nx2: frame-locked input replay and quieter logs
EDEN_NX2_KEY_RECORD records keyboard transitions as "f<frame>:code" against a global count of guest presents; EDEN_NX2_KEY_SCRIPT replays them on the same frames (or by seconds, as before), so a played session reproduces exactly. Debug aids: the PC/LR/SP of the first unmapped reads, NSO load addresses, EDEN_NX2_IPC_SUMMARY (request counts every 5 s), EDEN_NX2_FORCE_LOD0. Unmapped-access logging is rate limited and the per-draw/semaphore spam is demoted, so long sessions stay under the log size cap.
Diffstat (limited to 'src/core/memory.cpp')
-rw-r--r--src/core/memory.cpp14
1 files changed, 13 insertions, 1 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index eabc6dfccb..6e0ab0ee6d 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -5,6 +5,7 @@
// SPDX-FileCopyrightText: 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
+#include <atomic>
#include <algorithm>
#include <cstring>
#include <mutex>
@@ -36,6 +37,11 @@
namespace Core::Memory {
+u32& UnmappedReadFlag() {
+ thread_local u32 flag{};
+ return flag;
+}
+
static inline bool AddressSpaceContains(const Common::PageTable& table, const Common::ProcessAddress addr, const std::size_t size) {
const Common::ProcessAddress max_addr = 1ULL << table.GetAddressSpaceBits();
return addr + size >= addr && addr + size <= max_addr;
@@ -623,7 +629,13 @@ struct Memory::Impl {
inline T Read(Common::ProcessAddress vaddr) noexcept requires(std::is_trivially_copyable_v<T>) {
const u64 addr = GetInteger(vaddr);
if (auto const ptr = GetPointerImpl(addr, [addr]() {
- LOG_ERROR(HW_Memory, "Unmapped Read{} @ {:#016x}", sizeof(T) * 8, addr);
+ // A guest spinning on a bad pointer reads unmapped memory tens of thousands of times
+ // a second: keep the first ones and then a sample.
+ static std::atomic<u64> unmapped_reads{};
+ if (const u64 count = unmapped_reads.fetch_add(1); count < 1000 || count % 100000 == 0) {
+ LOG_ERROR(HW_Memory, "Unmapped Read{} @ {:#016x} (#{})", sizeof(T) * 8, addr, count);
+ }
+ ++UnmappedReadFlag();
}, [&]() {
HandleRasterizerDownload(addr, sizeof(T));
}); ptr) [[likely]] {