Merge pull request #3227 from MerryMage/cro

Allow for partial invalidation of instruction cache
This commit is contained in:
bunnei 2017-12-06 22:43:58 -05:00 committed by GitHub
commit d8ba07a430
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 26 additions and 5 deletions

2
externals/dynarmic vendored

@ -1 +1 @@
Subproject commit f343c56268ef3f8fbed5bbc513fbc56430a47255
Subproject commit 4110494ac4edc83f74c65834ab3ba6ddd166f42e

View File

@ -4,6 +4,7 @@
#pragma once
#include <cstddef>
#include "common/common_types.h"
#include "core/arm/skyeye_common/arm_regformat.h"
#include "core/arm/skyeye_common/vfp/asm_vfp.h"
@ -33,6 +34,13 @@ public:
/// Clear all instruction cache
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
virtual void PageTableChanged() = 0;

View File

@ -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() {
current_page_table = Memory::GetCurrentPageTable();

View File

@ -41,6 +41,7 @@ public:
void PrepareReschedule() override;
void ClearInstructionCache() override;
void InvalidateCacheRange(u32 start_address, size_t length) override;
void PageTableChanged() override;
private:

View File

@ -34,6 +34,10 @@ void ARM_DynCom::ClearInstructionCache() {
trans_cache_buf_top = 0;
}
void ARM_DynCom::InvalidateCacheRange(u32, size_t) {
ClearInstructionCache();
}
void ARM_DynCom::PageTableChanged() {
ClearInstructionCache();
}

View File

@ -19,6 +19,7 @@ public:
void Step() override;
void ClearInstructionCache() override;
void InvalidateCacheRange(u32 start_address, size_t length) override;
void PageTableChanged() override;
void SetPC(u32 pc) override;

View File

@ -5,6 +5,8 @@
#include "common/alignment.h"
#include "common/logging/log.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"
namespace Service {
@ -61,9 +63,11 @@ ResultCode CROHelper::ApplyRelocation(VAddr target_address, RelocationType reloc
case RelocationType::AbsoluteAddress:
case RelocationType::AbsoluteAddress2:
Memory::Write32(target_address, symbol_address + addend);
Core::CPU().InvalidateCacheRange(target_address, sizeof(u32));
break;
case RelocationType::RelativeAddress:
Memory::Write32(target_address, symbol_address + addend - target_future_address);
Core::CPU().InvalidateCacheRange(target_address, sizeof(u32));
break;
case RelocationType::ThumbBranch:
case RelocationType::ArmBranch:
@ -86,6 +90,7 @@ ResultCode CROHelper::ClearRelocation(VAddr target_address, RelocationType reloc
case RelocationType::AbsoluteAddress2:
case RelocationType::RelativeAddress:
Memory::Write32(target_address, 0);
Core::CPU().InvalidateCacheRange(target_address, sizeof(u32));
break;
case RelocationType::ThumbBranch:
case RelocationType::ArmBranch:

View File

@ -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(),
cro_address, cro_address + fix_size);
@ -535,7 +535,7 @@ static void UnloadCRO(Interface* self) {
memory_synchronizer.RemoveMemoryBlock(cro_address, cro_buffer_ptr);
}
Core::CPU().ClearInstructionCache();
Core::CPU().InvalidateCacheRange(cro_address, fixed_size);
rb.Push(result);
}
@ -588,7 +588,6 @@ static void LinkCRO(Interface* self) {
}
memory_synchronizer.SynchronizeOriginalMemory();
Core::CPU().ClearInstructionCache();
rb.Push(result);
}
@ -641,7 +640,6 @@ static void UnlinkCRO(Interface* self) {
}
memory_synchronizer.SynchronizeOriginalMemory();
Core::CPU().ClearInstructionCache();
rb.Push(result);
}