mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-09-08 18:45:48 +00:00
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.
This commit is contained in:
parent
6a55a1bf68
commit
aa7b13f353
2 changed files with 33 additions and 18 deletions
|
@ -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)
|
||||
u8 old_value = PowerPC::MMU::HostRead_U8(guard, address + offset);
|
||||
if (old_value != value[offset])
|
||||
{
|
||||
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
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue