summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorMartino Fontana <tinozzo123@gmail.com>2025-06-19 15:41:02 +0200
committerMartino Fontana <tinozzo123@gmail.com>2025-08-01 23:24:39 +0200
commitaa7b13f35344d077b43b3be8a368ce3e998d6fb9 (patch)
treeca76009b69d4258a1d9089ee44e7574a8cd4957e /Source/Core
parent6a55a1bf68981f4ca2545939bd8a59c624b5059e (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.cpp37
-rw-r--r--Source/Core/Core/Debugger/PPCDebugInterface.h14
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: