diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 6667c7dbae..32ff3c3454 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -25,19 +25,11 @@ public: VAddr tls_address; }; - /** - * Runs the CPU for the given number of instructions - * @param num_instructions Number of instructions to run - */ - void Run(int num_instructions) { - ExecuteInstructions(num_instructions); - this->num_instructions += num_instructions; - } + /// Runs the CPU until an event happens + virtual void Run() = 0; /// Step CPU by one instruction - void Step() { - Run(1); - } + virtual void Step() = 0; /// Maps a backing memory region for the CPU virtual void MapBackingMemory(VAddr address, size_t size, u8* memory, @@ -126,19 +118,4 @@ public: /// Prepare core for thread reschedule (if needed to correctly handle state) virtual void PrepareReschedule() = 0; - - /// Getter for num_instructions - u64 GetNumInstructions() const { - return num_instructions; - } - -protected: - /** - * Executes the given number of instructions - * @param num_instructions Number of instructions to executes - */ - virtual void ExecuteInstructions(int num_instructions) = 0; - -private: - u64 num_instructions = 0; ///< Number of instructions executed }; diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index 0902c6df33..7d83f97173 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -122,11 +122,22 @@ std::unique_ptr MakeJit(const std::unique_ptr(config); } +void ARM_Dynarmic::Run() { + ASSERT(Memory::GetCurrentPageTable() == current_page_table); + + jit->Run(); +} + +void ARM_Dynarmic::Step() { + cb->InterpreterFallback(jit->GetPC(), 1); +} + ARM_Dynarmic::ARM_Dynarmic() : cb(std::make_unique(*this)), jit(MakeJit(cb)) { ARM_Interface::ThreadContext ctx; inner_unicorn.SaveContext(ctx); LoadContext(ctx); + PageTableChanged(); } ARM_Dynarmic::~ARM_Dynarmic() = default; @@ -189,13 +200,6 @@ void ARM_Dynarmic::SetTlsAddress(u64 address) { cb->tpidrro_el0 = address; } -void ARM_Dynarmic::ExecuteInstructions(int num_instructions) { - cb->ticks_remaining = num_instructions; - jit->Run(); - CoreTiming::AddTicks(num_instructions - cb->num_interpreted_instructions); - cb->num_interpreted_instructions = 0; -} - void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) { ctx.cpu_registers = jit->GetRegisters(); ctx.sp = jit->GetSP(); @@ -228,4 +232,5 @@ void ARM_Dynarmic::ClearInstructionCache() { void ARM_Dynarmic::PageTableChanged() { jit = MakeJit(cb); + current_page_table = Memory::GetCurrentPageTable(); } diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index fd1a44802a..128669d016 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h @@ -29,6 +29,8 @@ public: u32 GetVFPReg(int index) const override; void SetVFPReg(int index, u32 value) override; u32 GetCPSR() const override; + void Run() override; + void Step() override; void SetCPSR(u32 cpsr) override; VAddr GetTlsAddress() const override; void SetTlsAddress(VAddr address) override; @@ -37,7 +39,6 @@ public: void LoadContext(const ThreadContext& ctx) override; void PrepareReschedule() override; - void ExecuteInstructions(int num_instructions) override; void ClearInstructionCache() override; void PageTableChanged() override; @@ -47,4 +48,6 @@ private: std::unique_ptr cb; std::unique_ptr jit; ARM_Unicorn inner_unicorn; + + Memory::PageTable* current_page_table = nullptr; }; diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp index 162c766fd6..bd98cb1607 100644 --- a/src/core/arm/unicorn/arm_unicorn.cpp +++ b/src/core/arm/unicorn/arm_unicorn.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include #include #include "common/assert.h" #include "common/microprofile.h" @@ -153,6 +154,14 @@ void ARM_Unicorn::SetTlsAddress(VAddr base) { CHECKED(uc_reg_write(uc, UC_ARM64_REG_TPIDRRO_EL0, &base)); } +void ARM_Unicorn::Run() { + ExecuteInstructions(std::max(CoreTiming::GetDowncount(), 0)); +} + +void ARM_Unicorn::Step() { + ExecuteInstructions(1); +} + MICROPROFILE_DEFINE(ARM_Jit, "ARM JIT", "ARM JIT", MP_RGB(255, 64, 64)); void ARM_Unicorn::ExecuteInstructions(int num_instructions) { diff --git a/src/core/arm/unicorn/arm_unicorn.h b/src/core/arm/unicorn/arm_unicorn.h index 00b5b1865b..b99b58e4c6 100644 --- a/src/core/arm/unicorn/arm_unicorn.h +++ b/src/core/arm/unicorn/arm_unicorn.h @@ -30,7 +30,9 @@ public: void SaveContext(ThreadContext& ctx) override; void LoadContext(const ThreadContext& ctx) override; void PrepareReschedule() override; - void ExecuteInstructions(int num_instructions) override; + void ExecuteInstructions(int num_instructions); + void Run() override; + void Step() override; void ClearInstructionCache() override; void PageTableChanged() override{}; diff --git a/src/core/core.cpp b/src/core/core.cpp index ac6cb9e6e9..183c5109c8 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -26,7 +26,7 @@ namespace Core { /*static*/ System System::s_instance; -System::ResultStatus System::RunLoop(int tight_loop) { +System::ResultStatus System::RunLoop(bool tight_loop) { status = ResultStatus::Success; if (!cpu_core) { return ResultStatus::ErrorNotInitialized; @@ -40,7 +40,7 @@ System::ResultStatus System::RunLoop(int tight_loop) { if (GDBStub::GetCpuHaltFlag()) { if (GDBStub::GetCpuStepFlag()) { GDBStub::SetCpuStepFlag(false); - tight_loop = 1; + tight_loop = false; } else { return ResultStatus::Success; } @@ -56,7 +56,11 @@ System::ResultStatus System::RunLoop(int tight_loop) { PrepareReschedule(); } else { CoreTiming::Advance(); - cpu_core->Run(tight_loop); + if (tight_loop) { + cpu_core->Run(); + } else { + cpu_core->Step(); + } } HW::Update(); @@ -66,7 +70,7 @@ System::ResultStatus System::RunLoop(int tight_loop) { } System::ResultStatus System::SingleStep() { - return RunLoop(1); + return RunLoop(false); } System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& filepath) { diff --git a/src/core/core.h b/src/core/core.h index 635109b210..552c8f5eee 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -53,10 +53,10 @@ public: * is not required to do a full dispatch with each instruction. NOTE: the number of instructions * requested is not guaranteed to run, as this will be interrupted preemptively if a hardware * update is requested (e.g. on a thread switch). - * @param tight_loop Number of instructions to execute. + * @param tight_loop If false, the CPU single-steps. * @return Result status, indicating whether or not the operation succeeded. */ - ResultStatus RunLoop(int tight_loop = 100000); + ResultStatus RunLoop(bool tight_loop = true); /** * Step the CPU one instruction