diff options
| author | Martino Fontana <tinozzo123@gmail.com> | 2025-06-19 15:41:02 +0200 |
|---|---|---|
| committer | Martino Fontana <tinozzo123@gmail.com> | 2025-08-01 23:24:39 +0200 |
| commit | aa7b13f35344d077b43b3be8a368ce3e998d6fb9 (patch) | |
| tree | ca76009b69d4258a1d9089ee44e7574a8cd4957e /Source/Core | |
| parent | 6a55a1bf68981f4ca2545939bd8a59c624b5059e (diff) | |
PPCDebugInterface: Small refactor to ApplyMemoryPatch
Invalidate icache only if target address has a different value. Take separate arguements,
instead of a struct, to allow easier usage elsewhere. Overload with u8,
u16 and u32 values for the same reason.
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/Core/Debugger/PPCDebugInterface.cpp | 37 | ||||
| -rw-r--r-- | Source/Core/Core/Debugger/PPCDebugInterface.h | 14 |
2 files changed, 33 insertions, 18 deletions
diff --git a/Source/Core/Core/Debugger/PPCDebugInterface.cpp b/Source/Core/Core/Debugger/PPCDebugInterface.cpp index 2c840d0ae5..92a0a26ea8 100644 --- a/Source/Core/Core/Debugger/PPCDebugInterface.cpp +++ b/Source/Core/Core/Debugger/PPCDebugInterface.cpp @@ -29,55 +29,58 @@ #include "Core/PowerPC/PowerPC.h" #include "Core/System.h" -void ApplyMemoryPatch(const Core::CPUThreadGuard& guard, Common::Debug::MemoryPatch& patch, +void ApplyMemoryPatch(const Core::CPUThreadGuard& guard, std::span<u8> value, const u32 address, bool store_existing_value) { if (AchievementManager::GetInstance().IsHardcoreModeActive()) return; - if (patch.value.empty()) + if (value.empty()) return; - const u32 address = patch.address; - const std::size_t size = patch.value.size(); + const std::size_t size = value.size(); if (!PowerPC::MMU::HostIsRAMAddress(guard, address)) return; auto& power_pc = guard.GetSystem().GetPowerPC(); + + bool should_invalidate_cache = false; for (u32 offset = 0; offset < size; ++offset) { - if (store_existing_value) - { - const u8 value = PowerPC::MMU::HostRead_U8(guard, address + offset); - PowerPC::MMU::HostWrite_U8(guard, patch.value[offset], address + offset); - patch.value[offset] = value; - } - else + u8 old_value = PowerPC::MMU::HostRead_U8(guard, address + offset); + if (old_value != value[offset]) { - PowerPC::MMU::HostWrite_U8(guard, patch.value[offset], address + offset); + PowerPC::MMU::HostWrite_U8(guard, value[offset], address + offset); + should_invalidate_cache = true; + if (store_existing_value) + value[offset] = old_value; } if (((address + offset) % 4) == 3) - power_pc.ScheduleInvalidateCacheThreadSafe(Common::AlignDown(address + offset, 4)); + { + if (should_invalidate_cache) + power_pc.ScheduleInvalidateCacheThreadSafe(Common::AlignDown(address + offset, 4)); + should_invalidate_cache = false; + } } - if (((address + size) % 4) != 0) + if (should_invalidate_cache) { power_pc.ScheduleInvalidateCacheThreadSafe( - Common::AlignDown(address + static_cast<u32>(size), 4)); + Common::AlignDown(address + static_cast<u32>(size) - 1, 4)); } } void PPCPatches::ApplyExistingPatch(const Core::CPUThreadGuard& guard, std::size_t index) { auto& patch = m_patches[index]; - ApplyMemoryPatch(guard, patch, false); + ApplyMemoryPatch(guard, patch.value, patch.address, false); } void PPCPatches::Patch(const Core::CPUThreadGuard& guard, std::size_t index) { auto& patch = m_patches[index]; if (patch.type == Common::Debug::MemoryPatch::ApplyType::Once) - ApplyMemoryPatch(guard, patch); + ApplyMemoryPatch(guard, patch.value, patch.address); else PatchEngine::AddMemoryPatch(index); } diff --git a/Source/Core/Core/Debugger/PPCDebugInterface.h b/Source/Core/Core/Debugger/PPCDebugInterface.h index 797f2d5254..c68864583d 100644 --- a/Source/Core/Core/Debugger/PPCDebugInterface.h +++ b/Source/Core/Core/Debugger/PPCDebugInterface.h @@ -3,12 +3,15 @@ #pragma once +#include <concepts> #include <cstddef> #include <memory> +#include <span> #include <string> #include "Common/Debug/MemoryPatches.h" #include "Common/Debug/Watches.h" +#include "Common/Swap.h" #include "Core/Debugger/DebugInterface.h" #include "Core/NetworkCaptureLogger.h" @@ -19,9 +22,18 @@ class System; } // namespace Core class PPCSymbolDB; -void ApplyMemoryPatch(const Core::CPUThreadGuard&, Common::Debug::MemoryPatch& patch, +void ApplyMemoryPatch(const Core::CPUThreadGuard& guard, std::span<u8> value, const u32 address, bool store_existing_value = true); +template <std::unsigned_integral T> +void ApplyMemoryPatch(const Core::CPUThreadGuard& guard, T value, const u32 address) +{ + Common::BigEndianValue<T> big_endian{value}; + auto data = + std::span<u8, sizeof(T)>{reinterpret_cast<u8*>(std::addressof(big_endian)), sizeof(T)}; + ApplyMemoryPatch(guard, data, address); +} + class PPCPatches final : public Common::Debug::MemoryPatches { public: |
