mirror of
https://github.com/citra-emu/citra.git
synced 2024-12-18 20:00:05 +00:00
Merge pull request #3227 from MerryMage/cro
Allow for partial invalidation of instruction cache
This commit is contained in:
commit
d8ba07a430
2
externals/dynarmic
vendored
2
externals/dynarmic
vendored
@ -1 +1 @@
|
|||||||
Subproject commit f343c56268ef3f8fbed5bbc513fbc56430a47255
|
Subproject commit 4110494ac4edc83f74c65834ab3ba6ddd166f42e
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/arm/skyeye_common/arm_regformat.h"
|
#include "core/arm/skyeye_common/arm_regformat.h"
|
||||||
#include "core/arm/skyeye_common/vfp/asm_vfp.h"
|
#include "core/arm/skyeye_common/vfp/asm_vfp.h"
|
||||||
@ -33,6 +34,13 @@ public:
|
|||||||
/// Clear all instruction cache
|
/// Clear all instruction cache
|
||||||
virtual void ClearInstructionCache() = 0;
|
virtual void ClearInstructionCache() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidate the code cache at a range of addresses.
|
||||||
|
* @param start_address The starting address of the range to invalidate.
|
||||||
|
* @param length The length (in bytes) of the range to invalidate.
|
||||||
|
*/
|
||||||
|
virtual void InvalidateCacheRange(u32 start_address, size_t length) = 0;
|
||||||
|
|
||||||
/// Notify CPU emulation that page tables have changed
|
/// Notify CPU emulation that page tables have changed
|
||||||
virtual void PageTableChanged() = 0;
|
virtual void PageTableChanged() = 0;
|
||||||
|
|
||||||
|
@ -187,6 +187,10 @@ void ARM_Dynarmic::ClearInstructionCache() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ARM_Dynarmic::InvalidateCacheRange(u32 start_address, size_t length) {
|
||||||
|
jit->InvalidateCacheRange(start_address, length);
|
||||||
|
}
|
||||||
|
|
||||||
void ARM_Dynarmic::PageTableChanged() {
|
void ARM_Dynarmic::PageTableChanged() {
|
||||||
current_page_table = Memory::GetCurrentPageTable();
|
current_page_table = Memory::GetCurrentPageTable();
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ public:
|
|||||||
void PrepareReschedule() override;
|
void PrepareReschedule() override;
|
||||||
|
|
||||||
void ClearInstructionCache() override;
|
void ClearInstructionCache() override;
|
||||||
|
void InvalidateCacheRange(u32 start_address, size_t length) override;
|
||||||
void PageTableChanged() override;
|
void PageTableChanged() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -34,6 +34,10 @@ void ARM_DynCom::ClearInstructionCache() {
|
|||||||
trans_cache_buf_top = 0;
|
trans_cache_buf_top = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ARM_DynCom::InvalidateCacheRange(u32, size_t) {
|
||||||
|
ClearInstructionCache();
|
||||||
|
}
|
||||||
|
|
||||||
void ARM_DynCom::PageTableChanged() {
|
void ARM_DynCom::PageTableChanged() {
|
||||||
ClearInstructionCache();
|
ClearInstructionCache();
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ public:
|
|||||||
void Step() override;
|
void Step() override;
|
||||||
|
|
||||||
void ClearInstructionCache() override;
|
void ClearInstructionCache() override;
|
||||||
|
void InvalidateCacheRange(u32 start_address, size_t length) override;
|
||||||
void PageTableChanged() override;
|
void PageTableChanged() override;
|
||||||
|
|
||||||
void SetPC(u32 pc) override;
|
void SetPC(u32 pc) override;
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#include "common/alignment.h"
|
#include "common/alignment.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/scope_exit.h"
|
#include "common/scope_exit.h"
|
||||||
|
#include "core/arm/arm_interface.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/hle/service/ldr_ro/cro_helper.h"
|
#include "core/hle/service/ldr_ro/cro_helper.h"
|
||||||
|
|
||||||
namespace Service {
|
namespace Service {
|
||||||
@ -61,9 +63,11 @@ ResultCode CROHelper::ApplyRelocation(VAddr target_address, RelocationType reloc
|
|||||||
case RelocationType::AbsoluteAddress:
|
case RelocationType::AbsoluteAddress:
|
||||||
case RelocationType::AbsoluteAddress2:
|
case RelocationType::AbsoluteAddress2:
|
||||||
Memory::Write32(target_address, symbol_address + addend);
|
Memory::Write32(target_address, symbol_address + addend);
|
||||||
|
Core::CPU().InvalidateCacheRange(target_address, sizeof(u32));
|
||||||
break;
|
break;
|
||||||
case RelocationType::RelativeAddress:
|
case RelocationType::RelativeAddress:
|
||||||
Memory::Write32(target_address, symbol_address + addend - target_future_address);
|
Memory::Write32(target_address, symbol_address + addend - target_future_address);
|
||||||
|
Core::CPU().InvalidateCacheRange(target_address, sizeof(u32));
|
||||||
break;
|
break;
|
||||||
case RelocationType::ThumbBranch:
|
case RelocationType::ThumbBranch:
|
||||||
case RelocationType::ArmBranch:
|
case RelocationType::ArmBranch:
|
||||||
@ -86,6 +90,7 @@ ResultCode CROHelper::ClearRelocation(VAddr target_address, RelocationType reloc
|
|||||||
case RelocationType::AbsoluteAddress2:
|
case RelocationType::AbsoluteAddress2:
|
||||||
case RelocationType::RelativeAddress:
|
case RelocationType::RelativeAddress:
|
||||||
Memory::Write32(target_address, 0);
|
Memory::Write32(target_address, 0);
|
||||||
|
Core::CPU().InvalidateCacheRange(target_address, sizeof(u32));
|
||||||
break;
|
break;
|
||||||
case RelocationType::ThumbBranch:
|
case RelocationType::ThumbBranch:
|
||||||
case RelocationType::ArmBranch:
|
case RelocationType::ArmBranch:
|
||||||
|
@ -439,7 +439,7 @@ static void LoadCRO(Interface* self, bool link_on_load_bug_fix) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::CPU().ClearInstructionCache();
|
Core::CPU().InvalidateCacheRange(cro_address, cro_size);
|
||||||
|
|
||||||
LOG_INFO(Service_LDR, "CRO \"%s\" loaded at 0x%08X, fixed_end=0x%08X", cro.ModuleName().data(),
|
LOG_INFO(Service_LDR, "CRO \"%s\" loaded at 0x%08X, fixed_end=0x%08X", cro.ModuleName().data(),
|
||||||
cro_address, cro_address + fix_size);
|
cro_address, cro_address + fix_size);
|
||||||
@ -535,7 +535,7 @@ static void UnloadCRO(Interface* self) {
|
|||||||
memory_synchronizer.RemoveMemoryBlock(cro_address, cro_buffer_ptr);
|
memory_synchronizer.RemoveMemoryBlock(cro_address, cro_buffer_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::CPU().ClearInstructionCache();
|
Core::CPU().InvalidateCacheRange(cro_address, fixed_size);
|
||||||
|
|
||||||
rb.Push(result);
|
rb.Push(result);
|
||||||
}
|
}
|
||||||
@ -588,7 +588,6 @@ static void LinkCRO(Interface* self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
memory_synchronizer.SynchronizeOriginalMemory();
|
memory_synchronizer.SynchronizeOriginalMemory();
|
||||||
Core::CPU().ClearInstructionCache();
|
|
||||||
|
|
||||||
rb.Push(result);
|
rb.Push(result);
|
||||||
}
|
}
|
||||||
@ -641,7 +640,6 @@ static void UnlinkCRO(Interface* self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
memory_synchronizer.SynchronizeOriginalMemory();
|
memory_synchronizer.SynchronizeOriginalMemory();
|
||||||
Core::CPU().ClearInstructionCache();
|
|
||||||
|
|
||||||
rb.Push(result);
|
rb.Push(result);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user