summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Lioncash2020-11-03 19:54:53 -0500
committerGravatar Lioncash2020-11-03 20:22:05 -0500
commitfc6db97a09e2de5eff10131ddcab9cf8fb2f736c (patch)
tree32a7b408286eb84360bcaff2961dbaa874f5a5d3 /src
parentMerge pull request #4887 from lioncash/common-build (diff)
downloadyuzu-fc6db97a09e2de5eff10131ddcab9cf8fb2f736c.tar.gz
yuzu-fc6db97a09e2de5eff10131ddcab9cf8fb2f736c.tar.xz
yuzu-fc6db97a09e2de5eff10131ddcab9cf8fb2f736c.zip
core: Remove usage of unicorn
Unicorn long-since lost most of its use, due to dynarmic gaining support for handling most instructions. At this point any further issues encountered should be used to make dynarmic better. This also allows us to remove our dependency on Python.
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt4
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp1
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp29
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.h2
-rw-r--r--src/core/arm/unicorn/arm_unicorn.cpp295
-rw-r--r--src/core/arm/unicorn/arm_unicorn.h63
-rw-r--r--src/core/hle/kernel/physical_core.cpp16
-rw-r--r--src/core/hle/kernel/thread.cpp17
-rw-r--r--src/yuzu/CMakeLists.txt2
-rw-r--r--src/yuzu_cmd/CMakeLists.txt2
-rw-r--r--src/yuzu_tester/CMakeLists.txt2
11 files changed, 15 insertions, 418 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index e0f207f3e..19c926662 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -13,8 +13,6 @@ add_library(core STATIC
13 arm/dynarmic/arm_exclusive_monitor.h 13 arm/dynarmic/arm_exclusive_monitor.h
14 arm/exclusive_monitor.cpp 14 arm/exclusive_monitor.cpp
15 arm/exclusive_monitor.h 15 arm/exclusive_monitor.h
16 arm/unicorn/arm_unicorn.cpp
17 arm/unicorn/arm_unicorn.h
18 constants.cpp 16 constants.cpp
19 constants.h 17 constants.h
20 core.cpp 18 core.cpp
@@ -644,7 +642,7 @@ endif()
644create_target_directory_groups(core) 642create_target_directory_groups(core)
645 643
646target_link_libraries(core PUBLIC common PRIVATE audio_core video_core) 644target_link_libraries(core PUBLIC common PRIVATE audio_core video_core)
647target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls opus unicorn zip) 645target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls opus zip)
648 646
649if (YUZU_ENABLE_BOXCAT) 647if (YUZU_ENABLE_BOXCAT)
650 target_compile_definitions(core PRIVATE -DYUZU_ENABLE_BOXCAT) 648 target_compile_definitions(core PRIVATE -DYUZU_ENABLE_BOXCAT)
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index b5f28a86e..6dc03f3b1 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -7,6 +7,7 @@
7#include <dynarmic/A32/a32.h> 7#include <dynarmic/A32/a32.h>
8#include <dynarmic/A32/config.h> 8#include <dynarmic/A32/config.h>
9#include <dynarmic/A32/context.h> 9#include <dynarmic/A32/context.h>
10#include "common/assert.h"
10#include "common/logging/log.h" 11#include "common/logging/log.h"
11#include "common/page_table.h" 12#include "common/page_table.h"
12#include "core/arm/cpu_interrupt_handler.h" 13#include "core/arm/cpu_interrupt_handler.h"
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index ce9968724..9f170a224 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -6,6 +6,7 @@
6#include <memory> 6#include <memory>
7#include <dynarmic/A64/a64.h> 7#include <dynarmic/A64/a64.h>
8#include <dynarmic/A64/config.h> 8#include <dynarmic/A64/config.h>
9#include "common/assert.h"
9#include "common/logging/log.h" 10#include "common/logging/log.h"
10#include "common/page_table.h" 11#include "common/page_table.h"
11#include "core/arm/cpu_interrupt_handler.h" 12#include "core/arm/cpu_interrupt_handler.h"
@@ -13,7 +14,6 @@
13#include "core/arm/dynarmic/arm_exclusive_monitor.h" 14#include "core/arm/dynarmic/arm_exclusive_monitor.h"
14#include "core/core.h" 15#include "core/core.h"
15#include "core/core_timing.h" 16#include "core/core_timing.h"
16#include "core/core_timing_util.h"
17#include "core/gdbstub/gdbstub.h" 17#include "core/gdbstub/gdbstub.h"
18#include "core/hardware_properties.h" 18#include "core/hardware_properties.h"
19#include "core/hle/kernel/process.h" 19#include "core/hle/kernel/process.h"
@@ -82,16 +82,9 @@ public:
82 } 82 }
83 83
84 void InterpreterFallback(u64 pc, std::size_t num_instructions) override { 84 void InterpreterFallback(u64 pc, std::size_t num_instructions) override {
85 LOG_INFO(Core_ARM, "Unicorn fallback @ 0x{:X} for {} instructions (instr = {:08X})", pc, 85 LOG_ERROR(Core_ARM,
86 num_instructions, MemoryReadCode(pc)); 86 "Unimplemented instruction @ 0x{:X} for {} instructions (instr = {:08X})", pc,
87 87 num_instructions, MemoryReadCode(pc));
88 ARM_Interface::ThreadContext64 ctx;
89 parent.SaveContext(ctx);
90 parent.inner_unicorn.LoadContext(ctx);
91 parent.inner_unicorn.ExecuteInstructions(num_instructions);
92 parent.inner_unicorn.SaveContext(ctx);
93 parent.LoadContext(ctx);
94 num_interpreted_instructions += num_instructions;
95 } 88 }
96 89
97 void ExceptionRaised(u64 pc, Dynarmic::A64::Exception exception) override { 90 void ExceptionRaised(u64 pc, Dynarmic::A64::Exception exception) override {
@@ -127,18 +120,17 @@ public:
127 if (parent.uses_wall_clock) { 120 if (parent.uses_wall_clock) {
128 return; 121 return;
129 } 122 }
123
130 // Divide the number of ticks by the amount of CPU cores. TODO(Subv): This yields only a 124 // Divide the number of ticks by the amount of CPU cores. TODO(Subv): This yields only a
131 // rough approximation of the amount of executed ticks in the system, it may be thrown off 125 // rough approximation of the amount of executed ticks in the system, it may be thrown off
132 // if not all cores are doing a similar amount of work. Instead of doing this, we should 126 // if not all cores are doing a similar amount of work. Instead of doing this, we should
133 // device a way so that timing is consistent across all cores without increasing the ticks 4 127 // device a way so that timing is consistent across all cores without increasing the ticks 4
134 // times. 128 // times.
135 u64 amortized_ticks = 129 u64 amortized_ticks = ticks / Core::Hardware::NUM_CPU_CORES;
136 (ticks - num_interpreted_instructions) / Core::Hardware::NUM_CPU_CORES;
137 // Always execute at least one tick. 130 // Always execute at least one tick.
138 amortized_ticks = std::max<u64>(amortized_ticks, 1); 131 amortized_ticks = std::max<u64>(amortized_ticks, 1);
139 132
140 parent.system.CoreTiming().AddTicks(amortized_ticks); 133 parent.system.CoreTiming().AddTicks(amortized_ticks);
141 num_interpreted_instructions = 0;
142 } 134 }
143 135
144 u64 GetTicksRemaining() override { 136 u64 GetTicksRemaining() override {
@@ -156,7 +148,6 @@ public:
156 } 148 }
157 149
158 ARM_Dynarmic_64& parent; 150 ARM_Dynarmic_64& parent;
159 std::size_t num_interpreted_instructions = 0;
160 u64 tpidrro_el0 = 0; 151 u64 tpidrro_el0 = 0;
161 u64 tpidr_el0 = 0; 152 u64 tpidr_el0 = 0;
162 static constexpr u64 minimum_run_cycles = 1000U; 153 static constexpr u64 minimum_run_cycles = 1000U;
@@ -248,12 +239,8 @@ ARM_Dynarmic_64::ARM_Dynarmic_64(System& system, CPUInterrupts& interrupt_handle
248 bool uses_wall_clock, ExclusiveMonitor& exclusive_monitor, 239 bool uses_wall_clock, ExclusiveMonitor& exclusive_monitor,
249 std::size_t core_index) 240 std::size_t core_index)
250 : ARM_Interface{system, interrupt_handlers, uses_wall_clock}, 241 : ARM_Interface{system, interrupt_handlers, uses_wall_clock},
251 cb(std::make_unique<DynarmicCallbacks64>(*this)), inner_unicorn{system, interrupt_handlers, 242 cb(std::make_unique<DynarmicCallbacks64>(*this)), core_index{core_index},
252 uses_wall_clock, 243 exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {}
253 ARM_Unicorn::Arch::AArch64,
254 core_index},
255 core_index{core_index}, exclusive_monitor{
256 dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {}
257 244
258ARM_Dynarmic_64::~ARM_Dynarmic_64() = default; 245ARM_Dynarmic_64::~ARM_Dynarmic_64() = default;
259 246
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h
index 403c55961..28e11a17d 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.h
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.h
@@ -12,7 +12,6 @@
12#include "common/hash.h" 12#include "common/hash.h"
13#include "core/arm/arm_interface.h" 13#include "core/arm/arm_interface.h"
14#include "core/arm/exclusive_monitor.h" 14#include "core/arm/exclusive_monitor.h"
15#include "core/arm/unicorn/arm_unicorn.h"
16 15
17namespace Core::Memory { 16namespace Core::Memory {
18class Memory; 17class Memory;
@@ -71,7 +70,6 @@ private:
71 std::unique_ptr<DynarmicCallbacks64> cb; 70 std::unique_ptr<DynarmicCallbacks64> cb;
72 JitCacheType jit_cache; 71 JitCacheType jit_cache;
73 std::shared_ptr<Dynarmic::A64::Jit> jit; 72 std::shared_ptr<Dynarmic::A64::Jit> jit;
74 ARM_Unicorn inner_unicorn;
75 73
76 std::size_t core_index; 74 std::size_t core_index;
77 DynarmicExclusiveMonitor& exclusive_monitor; 75 DynarmicExclusiveMonitor& exclusive_monitor;
diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp
deleted file mode 100644
index 1df3f3ed1..000000000
--- a/src/core/arm/unicorn/arm_unicorn.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6#include <unicorn/arm64.h>
7#include "common/assert.h"
8#include "common/microprofile.h"
9#include "core/arm/cpu_interrupt_handler.h"
10#include "core/arm/unicorn/arm_unicorn.h"
11#include "core/core.h"
12#include "core/core_timing.h"
13#include "core/hle/kernel/scheduler.h"
14#include "core/hle/kernel/svc.h"
15#include "core/memory.h"
16
17namespace Core {
18
19// Load Unicorn DLL once on Windows using RAII
20#ifdef _MSC_VER
21#include <unicorn_dynload.h>
22struct LoadDll {
23private:
24 LoadDll() {
25 ASSERT(uc_dyn_load(NULL, 0));
26 }
27 ~LoadDll() {
28 ASSERT(uc_dyn_free());
29 }
30 static LoadDll g_load_dll;
31};
32LoadDll LoadDll::g_load_dll;
33#endif
34
35#define CHECKED(expr) \
36 do { \
37 if (auto _cerr = (expr)) { \
38 ASSERT_MSG(false, "Call " #expr " failed with error: {} ({})\n", _cerr, \
39 uc_strerror(_cerr)); \
40 } \
41 } while (0)
42
43static void CodeHook(uc_engine* uc, uint64_t address, uint32_t size, void* user_data) {
44 GDBStub::BreakpointAddress bkpt =
45 GDBStub::GetNextBreakpointFromAddress(address, GDBStub::BreakpointType::Execute);
46 if (GDBStub::IsMemoryBreak() ||
47 (bkpt.type != GDBStub::BreakpointType::None && address == bkpt.address)) {
48 auto core = static_cast<ARM_Unicorn*>(user_data);
49 core->RecordBreak(bkpt);
50 uc_emu_stop(uc);
51 }
52}
53
54static bool UnmappedMemoryHook(uc_engine* uc, uc_mem_type type, u64 addr, int size, u64 value,
55 void* user_data) {
56 auto* const system = static_cast<System*>(user_data);
57
58 ARM_Interface::ThreadContext64 ctx{};
59 system->CurrentArmInterface().SaveContext(ctx);
60 ASSERT_MSG(false, "Attempted to read from unmapped memory: 0x{:X}, pc=0x{:X}, lr=0x{:X}", addr,
61 ctx.pc, ctx.cpu_registers[30]);
62
63 return false;
64}
65
66ARM_Unicorn::ARM_Unicorn(System& system, CPUInterrupts& interrupt_handlers, bool uses_wall_clock,
67 Arch architecture, std::size_t core_index)
68 : ARM_Interface{system, interrupt_handlers, uses_wall_clock}, core_index{core_index} {
69 const auto arch = architecture == Arch::AArch32 ? UC_ARCH_ARM : UC_ARCH_ARM64;
70 CHECKED(uc_open(arch, UC_MODE_ARM, &uc));
71
72 auto fpv = 3 << 20;
73 CHECKED(uc_reg_write(uc, UC_ARM64_REG_CPACR_EL1, &fpv));
74
75 uc_hook hook{};
76 CHECKED(uc_hook_add(uc, &hook, UC_HOOK_INTR, (void*)InterruptHook, this, 0, UINT64_MAX));
77 CHECKED(uc_hook_add(uc, &hook, UC_HOOK_MEM_INVALID, (void*)UnmappedMemoryHook, &system, 0,
78 UINT64_MAX));
79 if (GDBStub::IsServerEnabled()) {
80 CHECKED(uc_hook_add(uc, &hook, UC_HOOK_CODE, (void*)CodeHook, this, 0, UINT64_MAX));
81 last_bkpt_hit = false;
82 }
83}
84
85ARM_Unicorn::~ARM_Unicorn() {
86 CHECKED(uc_close(uc));
87}
88
89void ARM_Unicorn::SetPC(u64 pc) {
90 CHECKED(uc_reg_write(uc, UC_ARM64_REG_PC, &pc));
91}
92
93u64 ARM_Unicorn::GetPC() const {
94 u64 val{};
95 CHECKED(uc_reg_read(uc, UC_ARM64_REG_PC, &val));
96 return val;
97}
98
99u64 ARM_Unicorn::GetReg(int regn) const {
100 u64 val{};
101 auto treg = UC_ARM64_REG_SP;
102 if (regn <= 28) {
103 treg = (uc_arm64_reg)(UC_ARM64_REG_X0 + regn);
104 } else if (regn < 31) {
105 treg = (uc_arm64_reg)(UC_ARM64_REG_X29 + regn - 29);
106 }
107 CHECKED(uc_reg_read(uc, treg, &val));
108 return val;
109}
110
111void ARM_Unicorn::SetReg(int regn, u64 val) {
112 auto treg = UC_ARM64_REG_SP;
113 if (regn <= 28) {
114 treg = (uc_arm64_reg)(UC_ARM64_REG_X0 + regn);
115 } else if (regn < 31) {
116 treg = (uc_arm64_reg)(UC_ARM64_REG_X29 + regn - 29);
117 }
118 CHECKED(uc_reg_write(uc, treg, &val));
119}
120
121u128 ARM_Unicorn::GetVectorReg(int /*index*/) const {
122 UNIMPLEMENTED();
123 static constexpr u128 res{};
124 return res;
125}
126
127void ARM_Unicorn::SetVectorReg(int /*index*/, u128 /*value*/) {
128 UNIMPLEMENTED();
129}
130
131u32 ARM_Unicorn::GetPSTATE() const {
132 u64 nzcv{};
133 CHECKED(uc_reg_read(uc, UC_ARM64_REG_NZCV, &nzcv));
134 return static_cast<u32>(nzcv);
135}
136
137void ARM_Unicorn::SetPSTATE(u32 pstate) {
138 u64 nzcv = pstate;
139 CHECKED(uc_reg_write(uc, UC_ARM64_REG_NZCV, &nzcv));
140}
141
142VAddr ARM_Unicorn::GetTlsAddress() const {
143 u64 base{};
144 CHECKED(uc_reg_read(uc, UC_ARM64_REG_TPIDRRO_EL0, &base));
145 return base;
146}
147
148void ARM_Unicorn::SetTlsAddress(VAddr base) {
149 CHECKED(uc_reg_write(uc, UC_ARM64_REG_TPIDRRO_EL0, &base));
150}
151
152u64 ARM_Unicorn::GetTPIDR_EL0() const {
153 u64 value{};
154 CHECKED(uc_reg_read(uc, UC_ARM64_REG_TPIDR_EL0, &value));
155 return value;
156}
157
158void ARM_Unicorn::SetTPIDR_EL0(u64 value) {
159 CHECKED(uc_reg_write(uc, UC_ARM64_REG_TPIDR_EL0, &value));
160}
161
162void ARM_Unicorn::ChangeProcessorID(std::size_t new_core_id) {
163 core_index = new_core_id;
164}
165
166void ARM_Unicorn::Run() {
167 if (GDBStub::IsServerEnabled()) {
168 ExecuteInstructions(std::max(4000000U, 0U));
169 } else {
170 while (true) {
171 if (interrupt_handlers[core_index].IsInterrupted()) {
172 return;
173 }
174 ExecuteInstructions(10);
175 }
176 }
177}
178
179void ARM_Unicorn::Step() {
180 ExecuteInstructions(1);
181}
182
183MICROPROFILE_DEFINE(ARM_Jit_Unicorn, "ARM JIT", "Unicorn", MP_RGB(255, 64, 64));
184
185void ARM_Unicorn::ExecuteInstructions(std::size_t num_instructions) {
186 MICROPROFILE_SCOPE(ARM_Jit_Unicorn);
187
188 // Temporarily map the code page for Unicorn
189 u64 map_addr{GetPC() & ~Memory::PAGE_MASK};
190 std::vector<u8> page_buffer(Memory::PAGE_SIZE);
191 system.Memory().ReadBlock(map_addr, page_buffer.data(), page_buffer.size());
192
193 CHECKED(uc_mem_map_ptr(uc, map_addr, page_buffer.size(),
194 UC_PROT_READ | UC_PROT_WRITE | UC_PROT_EXEC, page_buffer.data()));
195 CHECKED(uc_emu_start(uc, GetPC(), 1ULL << 63, 0, num_instructions));
196 CHECKED(uc_mem_unmap(uc, map_addr, page_buffer.size()));
197 if (GDBStub::IsServerEnabled()) {
198 if (last_bkpt_hit && last_bkpt.type == GDBStub::BreakpointType::Execute) {
199 uc_reg_write(uc, UC_ARM64_REG_PC, &last_bkpt.address);
200 }
201
202 Kernel::Thread* const thread = system.CurrentScheduler().GetCurrentThread();
203 SaveContext(thread->GetContext64());
204 if (last_bkpt_hit || GDBStub::IsMemoryBreak() || GDBStub::GetCpuStepFlag()) {
205 last_bkpt_hit = false;
206 GDBStub::Break();
207 GDBStub::SendTrap(thread, 5);
208 }
209 }
210}
211
212void ARM_Unicorn::SaveContext(ThreadContext64& ctx) {
213 int uregs[32];
214 void* tregs[32];
215
216 CHECKED(uc_reg_read(uc, UC_ARM64_REG_SP, &ctx.sp));
217 CHECKED(uc_reg_read(uc, UC_ARM64_REG_PC, &ctx.pc));
218 CHECKED(uc_reg_read(uc, UC_ARM64_REG_NZCV, &ctx.pstate));
219
220 for (auto i = 0; i < 29; ++i) {
221 uregs[i] = UC_ARM64_REG_X0 + i;
222 tregs[i] = &ctx.cpu_registers[i];
223 }
224 uregs[29] = UC_ARM64_REG_X29;
225 tregs[29] = (void*)&ctx.cpu_registers[29];
226 uregs[30] = UC_ARM64_REG_X30;
227 tregs[30] = (void*)&ctx.cpu_registers[30];
228
229 CHECKED(uc_reg_read_batch(uc, uregs, tregs, 31));
230
231 for (int i = 0; i < 32; ++i) {
232 uregs[i] = UC_ARM64_REG_Q0 + i;
233 tregs[i] = &ctx.vector_registers[i];
234 }
235
236 CHECKED(uc_reg_read_batch(uc, uregs, tregs, 32));
237}
238
239void ARM_Unicorn::LoadContext(const ThreadContext64& ctx) {
240 int uregs[32];
241 void* tregs[32];
242
243 CHECKED(uc_reg_write(uc, UC_ARM64_REG_SP, &ctx.sp));
244 CHECKED(uc_reg_write(uc, UC_ARM64_REG_PC, &ctx.pc));
245 CHECKED(uc_reg_write(uc, UC_ARM64_REG_NZCV, &ctx.pstate));
246
247 for (int i = 0; i < 29; ++i) {
248 uregs[i] = UC_ARM64_REG_X0 + i;
249 tregs[i] = (void*)&ctx.cpu_registers[i];
250 }
251 uregs[29] = UC_ARM64_REG_X29;
252 tregs[29] = (void*)&ctx.cpu_registers[29];
253 uregs[30] = UC_ARM64_REG_X30;
254 tregs[30] = (void*)&ctx.cpu_registers[30];
255
256 CHECKED(uc_reg_write_batch(uc, uregs, tregs, 31));
257
258 for (auto i = 0; i < 32; ++i) {
259 uregs[i] = UC_ARM64_REG_Q0 + i;
260 tregs[i] = (void*)&ctx.vector_registers[i];
261 }
262
263 CHECKED(uc_reg_write_batch(uc, uregs, tregs, 32));
264}
265
266void ARM_Unicorn::PrepareReschedule() {
267 CHECKED(uc_emu_stop(uc));
268}
269
270void ARM_Unicorn::ClearExclusiveState() {}
271
272void ARM_Unicorn::ClearInstructionCache() {}
273
274void ARM_Unicorn::RecordBreak(GDBStub::BreakpointAddress bkpt) {
275 last_bkpt = bkpt;
276 last_bkpt_hit = true;
277}
278
279void ARM_Unicorn::InterruptHook(uc_engine* uc, u32 int_no, void* user_data) {
280 u32 esr{};
281 CHECKED(uc_reg_read(uc, UC_ARM64_REG_ESR, &esr));
282
283 const auto ec = esr >> 26;
284 const auto iss = esr & 0xFFFFFF;
285
286 auto* const arm_instance = static_cast<ARM_Unicorn*>(user_data);
287
288 switch (ec) {
289 case 0x15: // SVC
290 Kernel::Svc::Call(arm_instance->system, iss);
291 break;
292 }
293}
294
295} // namespace Core
diff --git a/src/core/arm/unicorn/arm_unicorn.h b/src/core/arm/unicorn/arm_unicorn.h
deleted file mode 100644
index 810aff311..000000000
--- a/src/core/arm/unicorn/arm_unicorn.h
+++ /dev/null
@@ -1,63 +0,0 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <unicorn/unicorn.h>
8#include "common/common_types.h"
9#include "core/arm/arm_interface.h"
10#include "core/gdbstub/gdbstub.h"
11
12namespace Core {
13
14class System;
15
16class ARM_Unicorn final : public ARM_Interface {
17public:
18 enum class Arch {
19 AArch32, // 32-bit ARM
20 AArch64, // 64-bit ARM
21 };
22
23 explicit ARM_Unicorn(System& system, CPUInterrupts& interrupt_handlers, bool uses_wall_clock,
24 Arch architecture, std::size_t core_index);
25 ~ARM_Unicorn() override;
26
27 void SetPC(u64 pc) override;
28 u64 GetPC() const override;
29 u64 GetReg(int index) const override;
30 void SetReg(int index, u64 value) override;
31 u128 GetVectorReg(int index) const override;
32 void SetVectorReg(int index, u128 value) override;
33 u32 GetPSTATE() const override;
34 void SetPSTATE(u32 pstate) override;
35 VAddr GetTlsAddress() const override;
36 void SetTlsAddress(VAddr address) override;
37 void SetTPIDR_EL0(u64 value) override;
38 u64 GetTPIDR_EL0() const override;
39 void ChangeProcessorID(std::size_t new_core_id) override;
40 void PrepareReschedule() override;
41 void ClearExclusiveState() override;
42 void ExecuteInstructions(std::size_t num_instructions);
43 void Run() override;
44 void Step() override;
45 void ClearInstructionCache() override;
46 void PageTableChanged(Common::PageTable&, std::size_t) override {}
47 void RecordBreak(GDBStub::BreakpointAddress bkpt);
48
49 void SaveContext(ThreadContext32& ctx) override {}
50 void SaveContext(ThreadContext64& ctx) override;
51 void LoadContext(const ThreadContext32& ctx) override {}
52 void LoadContext(const ThreadContext64& ctx) override;
53
54private:
55 static void InterruptHook(uc_engine* uc, u32 int_no, void* user_data);
56
57 uc_engine* uc{};
58 GDBStub::BreakpointAddress last_bkpt{};
59 bool last_bkpt_hit = false;
60 std::size_t core_index;
61};
62
63} // namespace Core
diff --git a/src/core/hle/kernel/physical_core.cpp b/src/core/hle/kernel/physical_core.cpp
index c6bbdb080..6e04d025f 100644
--- a/src/core/hle/kernel/physical_core.cpp
+++ b/src/core/hle/kernel/physical_core.cpp
@@ -2,30 +2,18 @@
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 "common/assert.h"
6#include "common/logging/log.h"
7#include "common/spin_lock.h" 5#include "common/spin_lock.h"
8#include "core/arm/arm_interface.h"
9#ifdef ARCHITECTURE_x86_64
10#include "core/arm/dynarmic/arm_dynarmic_32.h"
11#include "core/arm/dynarmic/arm_dynarmic_64.h"
12#endif
13#include "core/arm/cpu_interrupt_handler.h" 6#include "core/arm/cpu_interrupt_handler.h"
14#include "core/arm/exclusive_monitor.h"
15#include "core/arm/unicorn/arm_unicorn.h"
16#include "core/core.h" 7#include "core/core.h"
17#include "core/hle/kernel/physical_core.h" 8#include "core/hle/kernel/physical_core.h"
18#include "core/hle/kernel/scheduler.h" 9#include "core/hle/kernel/scheduler.h"
19#include "core/hle/kernel/thread.h"
20 10
21namespace Kernel { 11namespace Kernel {
22 12
23PhysicalCore::PhysicalCore(Core::System& system, std::size_t id, Kernel::Scheduler& scheduler, 13PhysicalCore::PhysicalCore(Core::System& system, std::size_t id, Kernel::Scheduler& scheduler,
24 Core::CPUInterruptHandler& interrupt_handler) 14 Core::CPUInterruptHandler& interrupt_handler)
25 : interrupt_handler{interrupt_handler}, core_index{id}, scheduler{scheduler} { 15 : interrupt_handler{interrupt_handler},
26 16 core_index{id}, scheduler{scheduler}, guard{std::make_unique<Common::SpinLock>()} {}
27 guard = std::make_unique<Common::SpinLock>();
28}
29 17
30PhysicalCore::~PhysicalCore() = default; 18PhysicalCore::~PhysicalCore() = default;
31 19
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index d132aba34..da0cb26b6 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -13,7 +13,6 @@
13#include "common/logging/log.h" 13#include "common/logging/log.h"
14#include "common/thread_queue_list.h" 14#include "common/thread_queue_list.h"
15#include "core/arm/arm_interface.h" 15#include "core/arm/arm_interface.h"
16#include "core/arm/unicorn/arm_unicorn.h"
17#include "core/core.h" 16#include "core/core.h"
18#include "core/cpu_manager.h" 17#include "core/cpu_manager.h"
19#include "core/hardware_properties.h" 18#include "core/hardware_properties.h"
@@ -217,8 +216,7 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(Core::System& system, ThreadTy
217 } else { 216 } else {
218 thread->tls_address = 0; 217 thread->tls_address = 0;
219 } 218 }
220 // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used 219
221 // to initialize the context
222 thread->arm_interface.reset(); 220 thread->arm_interface.reset();
223 if ((type_flags & THREADTYPE_HLE) == 0) { 221 if ((type_flags & THREADTYPE_HLE) == 0) {
224#ifdef ARCHITECTURE_x86_64 222#ifdef ARCHITECTURE_x86_64
@@ -231,19 +229,10 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(Core::System& system, ThreadTy
231 system, kernel.Interrupts(), kernel.IsMulticore(), kernel.GetExclusiveMonitor(), 229 system, kernel.Interrupts(), kernel.IsMulticore(), kernel.GetExclusiveMonitor(),
232 processor_id); 230 processor_id);
233 } 231 }
234
235#else 232#else
236 if (owner_process && !owner_process->Is64BitProcess()) { 233#error Platform not supported yet.
237 thread->arm_interface = std::make_shared<Core::ARM_Unicorn>(
238 system, kernel.Interrupts(), kernel.IsMulticore(), ARM_Unicorn::Arch::AArch32,
239 processor_id);
240 } else {
241 thread->arm_interface = std::make_shared<Core::ARM_Unicorn>(
242 system, kernel.Interrupts(), kernel.IsMulticore(), ARM_Unicorn::Arch::AArch64,
243 processor_id);
244 }
245 LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available");
246#endif 234#endif
235
247 ResetThreadContext32(thread->context_32, static_cast<u32>(stack_top), 236 ResetThreadContext32(thread->context_32, static_cast<u32>(stack_top),
248 static_cast<u32>(entry_point), static_cast<u32>(arg)); 237 static_cast<u32>(entry_point), static_cast<u32>(arg));
249 ResetThreadContext64(thread->context_64, stack_top, entry_point, arg); 238 ResetThreadContext64(thread->context_64, stack_top, entry_point, arg);
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 4659e1f89..8abb74d56 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -264,11 +264,9 @@ endif()
264if (MSVC) 264if (MSVC)
265 include(CopyYuzuQt5Deps) 265 include(CopyYuzuQt5Deps)
266 include(CopyYuzuSDLDeps) 266 include(CopyYuzuSDLDeps)
267 include(CopyYuzuUnicornDeps)
268 include(CopyYuzuFFmpegDeps) 267 include(CopyYuzuFFmpegDeps)
269 copy_yuzu_Qt5_deps(yuzu) 268 copy_yuzu_Qt5_deps(yuzu)
270 copy_yuzu_SDL_deps(yuzu) 269 copy_yuzu_SDL_deps(yuzu)
271 copy_yuzu_unicorn_deps(yuzu)
272 copy_yuzu_FFmpeg_deps(yuzu) 270 copy_yuzu_FFmpeg_deps(yuzu)
273endif() 271endif()
274 272
diff --git a/src/yuzu_cmd/CMakeLists.txt b/src/yuzu_cmd/CMakeLists.txt
index a15719a0f..57f9916f6 100644
--- a/src/yuzu_cmd/CMakeLists.txt
+++ b/src/yuzu_cmd/CMakeLists.txt
@@ -39,7 +39,5 @@ endif()
39 39
40if (MSVC) 40if (MSVC)
41 include(CopyYuzuSDLDeps) 41 include(CopyYuzuSDLDeps)
42 include(CopyYuzuUnicornDeps)
43 copy_yuzu_SDL_deps(yuzu-cmd) 42 copy_yuzu_SDL_deps(yuzu-cmd)
44 copy_yuzu_unicorn_deps(yuzu-cmd)
45endif() 43endif()
diff --git a/src/yuzu_tester/CMakeLists.txt b/src/yuzu_tester/CMakeLists.txt
index 06c2ee011..d8a2a1511 100644
--- a/src/yuzu_tester/CMakeLists.txt
+++ b/src/yuzu_tester/CMakeLists.txt
@@ -28,7 +28,5 @@ endif()
28 28
29if (MSVC) 29if (MSVC)
30 include(CopyYuzuSDLDeps) 30 include(CopyYuzuSDLDeps)
31 include(CopyYuzuUnicornDeps)
32 copy_yuzu_SDL_deps(yuzu-tester) 31 copy_yuzu_SDL_deps(yuzu-tester)
33 copy_yuzu_unicorn_deps(yuzu-tester)
34endif() 32endif()