diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/arm/arm_interface.h | 29 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic.cpp | 19 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic.h | 5 | ||||
| -rw-r--r-- | src/core/arm/unicorn/arm_unicorn.cpp | 9 | ||||
| -rw-r--r-- | src/core/arm/unicorn/arm_unicorn.h | 4 | ||||
| -rw-r--r-- | src/core/core.cpp | 12 | ||||
| -rw-r--r-- | src/core/core.h | 4 |
7 files changed, 41 insertions, 41 deletions
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 6667c7dba..32ff3c345 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h | |||
| @@ -25,19 +25,11 @@ public: | |||
| 25 | VAddr tls_address; | 25 | VAddr tls_address; |
| 26 | }; | 26 | }; |
| 27 | 27 | ||
| 28 | /** | 28 | /// Runs the CPU until an event happens |
| 29 | * Runs the CPU for the given number of instructions | 29 | virtual void Run() = 0; |
| 30 | * @param num_instructions Number of instructions to run | ||
| 31 | */ | ||
| 32 | void Run(int num_instructions) { | ||
| 33 | ExecuteInstructions(num_instructions); | ||
| 34 | this->num_instructions += num_instructions; | ||
| 35 | } | ||
| 36 | 30 | ||
| 37 | /// Step CPU by one instruction | 31 | /// Step CPU by one instruction |
| 38 | void Step() { | 32 | virtual void Step() = 0; |
| 39 | Run(1); | ||
| 40 | } | ||
| 41 | 33 | ||
| 42 | /// Maps a backing memory region for the CPU | 34 | /// Maps a backing memory region for the CPU |
| 43 | virtual void MapBackingMemory(VAddr address, size_t size, u8* memory, | 35 | virtual void MapBackingMemory(VAddr address, size_t size, u8* memory, |
| @@ -126,19 +118,4 @@ public: | |||
| 126 | 118 | ||
| 127 | /// Prepare core for thread reschedule (if needed to correctly handle state) | 119 | /// Prepare core for thread reschedule (if needed to correctly handle state) |
| 128 | virtual void PrepareReschedule() = 0; | 120 | virtual void PrepareReschedule() = 0; |
| 129 | |||
| 130 | /// Getter for num_instructions | ||
| 131 | u64 GetNumInstructions() const { | ||
| 132 | return num_instructions; | ||
| 133 | } | ||
| 134 | |||
| 135 | protected: | ||
| 136 | /** | ||
| 137 | * Executes the given number of instructions | ||
| 138 | * @param num_instructions Number of instructions to executes | ||
| 139 | */ | ||
| 140 | virtual void ExecuteInstructions(int num_instructions) = 0; | ||
| 141 | |||
| 142 | private: | ||
| 143 | u64 num_instructions = 0; ///< Number of instructions executed | ||
| 144 | }; | 121 | }; |
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index 0902c6df3..7d83f9717 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp | |||
| @@ -122,11 +122,22 @@ std::unique_ptr<Dynarmic::A64::Jit> MakeJit(const std::unique_ptr<ARM_Dynarmic_C | |||
| 122 | return std::make_unique<Dynarmic::A64::Jit>(config); | 122 | return std::make_unique<Dynarmic::A64::Jit>(config); |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | void ARM_Dynarmic::Run() { | ||
| 126 | ASSERT(Memory::GetCurrentPageTable() == current_page_table); | ||
| 127 | |||
| 128 | jit->Run(); | ||
| 129 | } | ||
| 130 | |||
| 131 | void ARM_Dynarmic::Step() { | ||
| 132 | cb->InterpreterFallback(jit->GetPC(), 1); | ||
| 133 | } | ||
| 134 | |||
| 125 | ARM_Dynarmic::ARM_Dynarmic() | 135 | ARM_Dynarmic::ARM_Dynarmic() |
| 126 | : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), jit(MakeJit(cb)) { | 136 | : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), jit(MakeJit(cb)) { |
| 127 | ARM_Interface::ThreadContext ctx; | 137 | ARM_Interface::ThreadContext ctx; |
| 128 | inner_unicorn.SaveContext(ctx); | 138 | inner_unicorn.SaveContext(ctx); |
| 129 | LoadContext(ctx); | 139 | LoadContext(ctx); |
| 140 | PageTableChanged(); | ||
| 130 | } | 141 | } |
| 131 | 142 | ||
| 132 | ARM_Dynarmic::~ARM_Dynarmic() = default; | 143 | ARM_Dynarmic::~ARM_Dynarmic() = default; |
| @@ -189,13 +200,6 @@ void ARM_Dynarmic::SetTlsAddress(u64 address) { | |||
| 189 | cb->tpidrro_el0 = address; | 200 | cb->tpidrro_el0 = address; |
| 190 | } | 201 | } |
| 191 | 202 | ||
| 192 | void ARM_Dynarmic::ExecuteInstructions(int num_instructions) { | ||
| 193 | cb->ticks_remaining = num_instructions; | ||
| 194 | jit->Run(); | ||
| 195 | CoreTiming::AddTicks(num_instructions - cb->num_interpreted_instructions); | ||
| 196 | cb->num_interpreted_instructions = 0; | ||
| 197 | } | ||
| 198 | |||
| 199 | void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) { | 203 | void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) { |
| 200 | ctx.cpu_registers = jit->GetRegisters(); | 204 | ctx.cpu_registers = jit->GetRegisters(); |
| 201 | ctx.sp = jit->GetSP(); | 205 | ctx.sp = jit->GetSP(); |
| @@ -228,4 +232,5 @@ void ARM_Dynarmic::ClearInstructionCache() { | |||
| 228 | 232 | ||
| 229 | void ARM_Dynarmic::PageTableChanged() { | 233 | void ARM_Dynarmic::PageTableChanged() { |
| 230 | jit = MakeJit(cb); | 234 | jit = MakeJit(cb); |
| 235 | current_page_table = Memory::GetCurrentPageTable(); | ||
| 231 | } | 236 | } |
diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index fd1a44802..128669d01 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h | |||
| @@ -29,6 +29,8 @@ public: | |||
| 29 | u32 GetVFPReg(int index) const override; | 29 | u32 GetVFPReg(int index) const override; |
| 30 | void SetVFPReg(int index, u32 value) override; | 30 | void SetVFPReg(int index, u32 value) override; |
| 31 | u32 GetCPSR() const override; | 31 | u32 GetCPSR() const override; |
| 32 | void Run() override; | ||
| 33 | void Step() override; | ||
| 32 | void SetCPSR(u32 cpsr) override; | 34 | void SetCPSR(u32 cpsr) override; |
| 33 | VAddr GetTlsAddress() const override; | 35 | VAddr GetTlsAddress() const override; |
| 34 | void SetTlsAddress(VAddr address) override; | 36 | void SetTlsAddress(VAddr address) override; |
| @@ -37,7 +39,6 @@ public: | |||
| 37 | void LoadContext(const ThreadContext& ctx) override; | 39 | void LoadContext(const ThreadContext& ctx) override; |
| 38 | 40 | ||
| 39 | void PrepareReschedule() override; | 41 | void PrepareReschedule() override; |
| 40 | void ExecuteInstructions(int num_instructions) override; | ||
| 41 | 42 | ||
| 42 | void ClearInstructionCache() override; | 43 | void ClearInstructionCache() override; |
| 43 | void PageTableChanged() override; | 44 | void PageTableChanged() override; |
| @@ -47,4 +48,6 @@ private: | |||
| 47 | std::unique_ptr<ARM_Dynarmic_Callbacks> cb; | 48 | std::unique_ptr<ARM_Dynarmic_Callbacks> cb; |
| 48 | std::unique_ptr<Dynarmic::A64::Jit> jit; | 49 | std::unique_ptr<Dynarmic::A64::Jit> jit; |
| 49 | ARM_Unicorn inner_unicorn; | 50 | ARM_Unicorn inner_unicorn; |
| 51 | |||
| 52 | Memory::PageTable* current_page_table = nullptr; | ||
| 50 | }; | 53 | }; |
diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp index 162c766fd..bd98cb160 100644 --- a/src/core/arm/unicorn/arm_unicorn.cpp +++ b/src/core/arm/unicorn/arm_unicorn.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | ||
| 5 | #include <unicorn/arm64.h> | 6 | #include <unicorn/arm64.h> |
| 6 | #include "common/assert.h" | 7 | #include "common/assert.h" |
| 7 | #include "common/microprofile.h" | 8 | #include "common/microprofile.h" |
| @@ -153,6 +154,14 @@ void ARM_Unicorn::SetTlsAddress(VAddr base) { | |||
| 153 | CHECKED(uc_reg_write(uc, UC_ARM64_REG_TPIDRRO_EL0, &base)); | 154 | CHECKED(uc_reg_write(uc, UC_ARM64_REG_TPIDRRO_EL0, &base)); |
| 154 | } | 155 | } |
| 155 | 156 | ||
| 157 | void ARM_Unicorn::Run() { | ||
| 158 | ExecuteInstructions(std::max(CoreTiming::GetDowncount(), 0)); | ||
| 159 | } | ||
| 160 | |||
| 161 | void ARM_Unicorn::Step() { | ||
| 162 | ExecuteInstructions(1); | ||
| 163 | } | ||
| 164 | |||
| 156 | MICROPROFILE_DEFINE(ARM_Jit, "ARM JIT", "ARM JIT", MP_RGB(255, 64, 64)); | 165 | MICROPROFILE_DEFINE(ARM_Jit, "ARM JIT", "ARM JIT", MP_RGB(255, 64, 64)); |
| 157 | 166 | ||
| 158 | void ARM_Unicorn::ExecuteInstructions(int num_instructions) { | 167 | 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 00b5b1865..b99b58e4c 100644 --- a/src/core/arm/unicorn/arm_unicorn.h +++ b/src/core/arm/unicorn/arm_unicorn.h | |||
| @@ -30,7 +30,9 @@ public: | |||
| 30 | void SaveContext(ThreadContext& ctx) override; | 30 | void SaveContext(ThreadContext& ctx) override; |
| 31 | void LoadContext(const ThreadContext& ctx) override; | 31 | void LoadContext(const ThreadContext& ctx) override; |
| 32 | void PrepareReschedule() override; | 32 | void PrepareReschedule() override; |
| 33 | void ExecuteInstructions(int num_instructions) override; | 33 | void ExecuteInstructions(int num_instructions); |
| 34 | void Run() override; | ||
| 35 | void Step() override; | ||
| 34 | void ClearInstructionCache() override; | 36 | void ClearInstructionCache() override; |
| 35 | void PageTableChanged() override{}; | 37 | void PageTableChanged() override{}; |
| 36 | 38 | ||
diff --git a/src/core/core.cpp b/src/core/core.cpp index ac6cb9e6e..183c5109c 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -26,7 +26,7 @@ namespace Core { | |||
| 26 | 26 | ||
| 27 | /*static*/ System System::s_instance; | 27 | /*static*/ System System::s_instance; |
| 28 | 28 | ||
| 29 | System::ResultStatus System::RunLoop(int tight_loop) { | 29 | System::ResultStatus System::RunLoop(bool tight_loop) { |
| 30 | status = ResultStatus::Success; | 30 | status = ResultStatus::Success; |
| 31 | if (!cpu_core) { | 31 | if (!cpu_core) { |
| 32 | return ResultStatus::ErrorNotInitialized; | 32 | return ResultStatus::ErrorNotInitialized; |
| @@ -40,7 +40,7 @@ System::ResultStatus System::RunLoop(int tight_loop) { | |||
| 40 | if (GDBStub::GetCpuHaltFlag()) { | 40 | if (GDBStub::GetCpuHaltFlag()) { |
| 41 | if (GDBStub::GetCpuStepFlag()) { | 41 | if (GDBStub::GetCpuStepFlag()) { |
| 42 | GDBStub::SetCpuStepFlag(false); | 42 | GDBStub::SetCpuStepFlag(false); |
| 43 | tight_loop = 1; | 43 | tight_loop = false; |
| 44 | } else { | 44 | } else { |
| 45 | return ResultStatus::Success; | 45 | return ResultStatus::Success; |
| 46 | } | 46 | } |
| @@ -56,7 +56,11 @@ System::ResultStatus System::RunLoop(int tight_loop) { | |||
| 56 | PrepareReschedule(); | 56 | PrepareReschedule(); |
| 57 | } else { | 57 | } else { |
| 58 | CoreTiming::Advance(); | 58 | CoreTiming::Advance(); |
| 59 | cpu_core->Run(tight_loop); | 59 | if (tight_loop) { |
| 60 | cpu_core->Run(); | ||
| 61 | } else { | ||
| 62 | cpu_core->Step(); | ||
| 63 | } | ||
| 60 | } | 64 | } |
| 61 | 65 | ||
| 62 | HW::Update(); | 66 | HW::Update(); |
| @@ -66,7 +70,7 @@ System::ResultStatus System::RunLoop(int tight_loop) { | |||
| 66 | } | 70 | } |
| 67 | 71 | ||
| 68 | System::ResultStatus System::SingleStep() { | 72 | System::ResultStatus System::SingleStep() { |
| 69 | return RunLoop(1); | 73 | return RunLoop(false); |
| 70 | } | 74 | } |
| 71 | 75 | ||
| 72 | System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& filepath) { | 76 | System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& filepath) { |
diff --git a/src/core/core.h b/src/core/core.h index 635109b21..552c8f5ee 100644 --- a/src/core/core.h +++ b/src/core/core.h | |||
| @@ -53,10 +53,10 @@ public: | |||
| 53 | * is not required to do a full dispatch with each instruction. NOTE: the number of instructions | 53 | * is not required to do a full dispatch with each instruction. NOTE: the number of instructions |
| 54 | * requested is not guaranteed to run, as this will be interrupted preemptively if a hardware | 54 | * requested is not guaranteed to run, as this will be interrupted preemptively if a hardware |
| 55 | * update is requested (e.g. on a thread switch). | 55 | * update is requested (e.g. on a thread switch). |
| 56 | * @param tight_loop Number of instructions to execute. | 56 | * @param tight_loop If false, the CPU single-steps. |
| 57 | * @return Result status, indicating whether or not the operation succeeded. | 57 | * @return Result status, indicating whether or not the operation succeeded. |
| 58 | */ | 58 | */ |
| 59 | ResultStatus RunLoop(int tight_loop = 100000); | 59 | ResultStatus RunLoop(bool tight_loop = true); |
| 60 | 60 | ||
| 61 | /** | 61 | /** |
| 62 | * Step the CPU one instruction | 62 | * Step the CPU one instruction |