From 2ace21b4db22ecc07363cf850c51173c2f800b9b Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 28 Dec 2015 13:55:49 -0500 Subject: [PATCH] HLE/RO: Clear the dyncom instruction cache when we load a CRO --- src/core/arm/arm_interface.h | 2 ++ src/core/arm/dyncom/arm_dyncom.cpp | 4 ++++ src/core/arm/dyncom/arm_dyncom.h | 2 ++ src/core/hle/service/ldr_ro.cpp | 8 ++++++++ 4 files changed, 16 insertions(+) diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 533067d4f..15c066e53 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -31,6 +31,8 @@ public: Run(1); } + virtual void ClearInstructionCache() { } + /** * Set the Program Counter to an address * @param addr Address to set PC to diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp index f3be2c857..17961615f 100644 --- a/src/core/arm/dyncom/arm_dyncom.cpp +++ b/src/core/arm/dyncom/arm_dyncom.cpp @@ -24,6 +24,10 @@ ARM_DynCom::ARM_DynCom(PrivilegeMode initial_mode) { ARM_DynCom::~ARM_DynCom() { } +void ARM_DynCom::ClearInstructionCache() { + state->instruction_cache.clear(); +} + void ARM_DynCom::SetPC(u32 pc) { state->Reg[15] = pc; } diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h index 3664fd728..e763abc24 100644 --- a/src/core/arm/dyncom/arm_dyncom.h +++ b/src/core/arm/dyncom/arm_dyncom.h @@ -21,6 +21,8 @@ public: ARM_DynCom(PrivilegeMode initial_mode); ~ARM_DynCom(); + void ClearInstructionCache() override; + void SetPC(u32 pc) override; u32 GetPC() const override; u32 GetReg(int index) const override; diff --git a/src/core/hle/service/ldr_ro.cpp b/src/core/hle/service/ldr_ro.cpp index 3e1653290..5aa32dbc9 100644 --- a/src/core/hle/service/ldr_ro.cpp +++ b/src/core/hle/service/ldr_ro.cpp @@ -4,6 +4,8 @@ #include "common/logging/log.h" +#include "core/core.h" +#include "core/arm/arm_interface.h" #include "core/hle/hle.h" #include "core/hle/service/ldr_ro.h" #include "core/hle/kernel/process.h" @@ -837,6 +839,9 @@ static ResultCode LoadCRO(u32 base, u32 size, u8* cro, u32 data_section0, u32 da file.WriteBytes(header, header->file_size); file.Close(); + // Clear the instruction cache + Core::g_app_core->ClearInstructionCache(); + return RESULT_SUCCESS; } @@ -973,6 +978,9 @@ static void LoadExeCRO(Service::Interface* self) { ResultCode result = LoadCRO(address, size, Memory::GetPointer(address), cmd_buff[4], cmd_buff[7], false); + if (result.IsError()) + LOG_CRITICAL(Service_LDR, "Error when loading CRO %08X", result.raw); + cmd_buff[0] = IPC::MakeHeader(4, 2, 0); cmd_buff[1] = result.raw; cmd_buff[2] = 0;