Browse Source

Core: Refactor ARM Interface.

Fernando Sahmkow 6 years ago
parent
commit
1b82ccec22

+ 6 - 3
src/core/arm/arm_interface.h

@@ -7,6 +7,7 @@
 #include <array>
 #include <vector>
 #include "common/common_types.h"
+#include "core/hardware_properties.h"
 
 namespace Common {
 struct PageTable;
@@ -20,11 +21,13 @@ namespace Core {
 class System;
 class CPUInterruptHandler;
 
+using CPUInterrupts = std::array<CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>;
+
 /// Generic ARMv8 CPU interface
 class ARM_Interface : NonCopyable {
 public:
-    explicit ARM_Interface(System& system_, CPUInterruptHandler& interrupt_handler)
-        : system{system_}, interrupt_handler{interrupt_handler} {}
+    explicit ARM_Interface(System& system_, CPUInterrupts& interrupt_handlers)
+        : system{system_}, interrupt_handlers{interrupt_handlers} {}
     virtual ~ARM_Interface() = default;
 
     struct ThreadContext32 {
@@ -180,7 +183,7 @@ public:
 protected:
     /// System context that this ARM interface is running under.
     System& system;
-    CPUInterruptHandler& interrupt_handler;
+    CPUInterrupts& interrupt_handlers;
 };
 
 } // namespace Core

+ 3 - 3
src/core/arm/dynarmic/arm_dynarmic_32.cpp

@@ -76,7 +76,7 @@ public:
     }
 
     u64 GetTicksRemaining() override {
-        if (!parent.interrupt_handler.IsInterrupted()) {
+        if (!parent.interrupt_handlers[parent.core_index].IsInterrupted()) {
             return std::max<s64>(ticks, 0);
         }
         return 0ULL;
@@ -111,9 +111,9 @@ void ARM_Dynarmic_32::Step() {
     jit->Step();
 }
 
-ARM_Dynarmic_32::ARM_Dynarmic_32(System& system, CPUInterruptHandler& interrupt_handler,
+ARM_Dynarmic_32::ARM_Dynarmic_32(System& system, CPUInterrupts& interrupt_handlers,
                                  ExclusiveMonitor& exclusive_monitor, std::size_t core_index)
-    : ARM_Interface{system, interrupt_handler}, cb(std::make_unique<DynarmicCallbacks32>(*this)),
+    : ARM_Interface{system, interrupt_handlers}, cb(std::make_unique<DynarmicCallbacks32>(*this)),
       cp15(std::make_shared<DynarmicCP15>(*this)), core_index{core_index},
       exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {}
 

+ 1 - 1
src/core/arm/dynarmic/arm_dynarmic_32.h

@@ -29,7 +29,7 @@ class System;
 
 class ARM_Dynarmic_32 final : public ARM_Interface {
 public:
-    ARM_Dynarmic_32(System& system, CPUInterruptHandler& interrupt_handler,
+    ARM_Dynarmic_32(System& system, CPUInterrupts& interrupt_handlers,
                     ExclusiveMonitor& exclusive_monitor, std::size_t core_index);
     ~ARM_Dynarmic_32() override;
 

+ 8 - 5
src/core/arm/dynarmic/arm_dynarmic_64.cpp

@@ -128,7 +128,7 @@ public:
     }
 
     u64 GetTicksRemaining() override {
-        if (!parent.interrupt_handler.IsInterrupted()) {
+        if (!parent.interrupt_handlers[parent.core_index].IsInterrupted()) {
             return std::max<s64>(ticks, 0);
         }
         return 0ULL;
@@ -199,11 +199,14 @@ void ARM_Dynarmic_64::Step() {
     cb->InterpreterFallback(jit->GetPC(), 1);
 }
 
-ARM_Dynarmic_64::ARM_Dynarmic_64(System& system, CPUInterruptHandler& interrupt_handler,
+ARM_Dynarmic_64::ARM_Dynarmic_64(System& system, CPUInterrupts& interrupt_handlers,
                                  ExclusiveMonitor& exclusive_monitor, std::size_t core_index)
-    : ARM_Interface{system, interrupt_handler}, cb(std::make_unique<DynarmicCallbacks64>(*this)),
-      inner_unicorn{system, interrupt_handler, ARM_Unicorn::Arch::AArch64}, core_index{core_index},
-      exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {}
+    : ARM_Interface{system, interrupt_handler},
+      cb(std::make_unique<DynarmicCallbacks64>(*this)), inner_unicorn{system, interrupt_handler,
+                                                                      ARM_Unicorn::Arch::AArch64,
+                                                                      core_index},
+      core_index{core_index}, exclusive_monitor{
+                                  dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {}
 
 ARM_Dynarmic_64::~ARM_Dynarmic_64() = default;
 

+ 1 - 1
src/core/arm/dynarmic/arm_dynarmic_64.h

@@ -28,7 +28,7 @@ class System;
 
 class ARM_Dynarmic_64 final : public ARM_Interface {
 public:
-    ARM_Dynarmic_64(System& system, CPUInterruptHandler& interrupt_handler,
+    ARM_Dynarmic_64(System& system, CPUInterrupts& interrupt_handlers,
                     ExclusiveMonitor& exclusive_monitor, std::size_t core_index);
     ~ARM_Dynarmic_64() override;
 

+ 4 - 3
src/core/arm/unicorn/arm_unicorn.cpp

@@ -63,8 +63,9 @@ static bool UnmappedMemoryHook(uc_engine* uc, uc_mem_type type, u64 addr, int si
     return false;
 }
 
-ARM_Unicorn::ARM_Unicorn(System& system, CPUInterruptHandler& interrupt_handler, Arch architecture)
-    : ARM_Interface{system, interrupt_handler} {
+ARM_Unicorn::ARM_Unicorn(System& system, CPUInterruptHandler& interrupt_handler, Arch architecture,
+                         std::size_t core_index)
+    : ARM_Interface{system, interrupt_handler}, core_index{core_index} {
     const auto arch = architecture == Arch::AArch32 ? UC_ARCH_ARM : UC_ARCH_ARM64;
     CHECKED(uc_open(arch, UC_MODE_ARM, &uc));
 
@@ -163,7 +164,7 @@ void ARM_Unicorn::Run() {
         ExecuteInstructions(std::max(4000000U, 0U));
     } else {
         while (true) {
-            if (interrupt_handler.IsInterrupted()) {
+            if (interrupt_handlers[core_index].IsInterrupted()) {
                 return;
             }
             ExecuteInstructions(10);

+ 3 - 2
src/core/arm/unicorn/arm_unicorn.h

@@ -11,7 +11,6 @@
 
 namespace Core {
 
-class CPUInterruptHandler;
 class System;
 
 class ARM_Unicorn final : public ARM_Interface {
@@ -21,7 +20,8 @@ public:
         AArch64, // 64-bit ARM
     };
 
-    explicit ARM_Unicorn(System& system, CPUInterruptHandler& interrupt_handler, Arch architecture);
+    explicit ARM_Unicorn(System& system, CPUInterruptHandler& interrupt_handler, Arch architecture,
+                         std::size_t core_index);
     ~ARM_Unicorn() override;
 
     void SetPC(u64 pc) override;
@@ -56,6 +56,7 @@ private:
     uc_engine* uc{};
     GDBStub::BreakpointAddress last_bkpt{};
     bool last_bkpt_hit = false;
+    std::size_t core_index;
 };
 
 } // namespace Core

+ 27 - 1
src/core/hle/kernel/kernel.cpp

@@ -2,6 +2,7 @@
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 
+#include <array>
 #include <atomic>
 #include <bitset>
 #include <functional>
@@ -16,7 +17,9 @@
 #include "common/microprofile.h"
 #include "common/thread.h"
 #include "core/arm/arm_interface.h"
+#include "core/arm/cpu_interrupt_handler.h"
 #include "core/arm/exclusive_monitor.h"
+#include "core/arm/unicorn/arm_unicorn.h"
 #include "core/core.h"
 #include "core/core_timing.h"
 #include "core/core_timing_util.h"
@@ -42,6 +45,11 @@
 #include "core/hle/result.h"
 #include "core/memory.h"
 
+#ifdef ARCHITECTURE_x86_64
+#include "core/arm/dynarmic/arm_dynarmic_32.h"
+#include "core/arm/dynarmic/arm_dynarmic_64.h"
+#endif
+
 MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70));
 
 namespace Kernel {
@@ -178,7 +186,20 @@ struct KernelCore::Impl {
         exclusive_monitor =
             Core::MakeExclusiveMonitor(system.Memory(), Core::Hardware::NUM_CPU_CORES);
         for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
-            cores.emplace_back(system, i, *exclusive_monitor);
+#ifdef ARCHITECTURE_x86_64
+            arm_interfaces_32[i] =
+                std::make_unique<Core::ARM_Dynarmic_32>(system, interrupts, *exclusive_monitor, i);
+            arm_interfaces_64[i] =
+                std::make_unique<Core::ARM_Dynarmic_64>(system, interrupts, *exclusive_monitor, i);
+#else
+            arm_interfaces_32[i] = std::make_shared<Core::ARM_Unicorn>(
+                system, interrupts, ARM_Unicorn::Arch::AArch32, i);
+            arm_interfaces_64[i] = std::make_shared<Core::ARM_Unicorn>(
+                system, interrupts, ARM_Unicorn::Arch::AArch64, i);
+            LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available");
+#endif
+            cores.emplace_back(system, i, *exclusive_monitor, interrupts[i], *arm_interfaces_32[i],
+                               *arm_interfaces_64[i]);
         }
     }
 
@@ -407,6 +428,11 @@ struct KernelCore::Impl {
     std::shared_ptr<Kernel::SharedMemory> time_shared_mem;
 
     std::array<std::shared_ptr<Thread>, Core::Hardware::NUM_CPU_CORES> suspend_threads{};
+    std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{};
+    std::array<std::unique_ptr<Core::ARM_Interface>, Core::Hardware::NUM_CPU_CORES>
+        arm_interfaces_32{};
+    std::array<std::unique_ptr<Core::ARM_Interface>, Core::Hardware::NUM_CPU_CORES>
+        arm_interfaces_64{};
 
     bool is_multicore{};
     std::thread::id single_core_thread_id{};

+ 8 - 17
src/core/hle/kernel/physical_core.cpp

@@ -21,21 +21,12 @@
 namespace Kernel {
 
 PhysicalCore::PhysicalCore(Core::System& system, std::size_t id,
-                           Core::ExclusiveMonitor& exclusive_monitor)
-    : interrupt_handler{}, core_index{id} {
-#ifdef ARCHITECTURE_x86_64
-    arm_interface_32 = std::make_unique<Core::ARM_Dynarmic_32>(system, interrupt_handler,
-                                                               exclusive_monitor, core_index);
-    arm_interface_64 = std::make_unique<Core::ARM_Dynarmic_64>(system, interrupt_handler,
-                                                               exclusive_monitor, core_index);
-#else
-    using Core::ARM_Unicorn;
-    arm_interface_32 =
-        std::make_unique<ARM_Unicorn>(system, interrupt_handler, ARM_Unicorn::Arch::AArch32);
-    arm_interface_64 =
-        std::make_unique<ARM_Unicorn>(system, interrupt_handler, ARM_Unicorn::Arch::AArch64);
-    LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available");
-#endif
+                           Core::ExclusiveMonitor& exclusive_monitor,
+                           Core::CPUInterruptHandler& interrupt_handler,
+                           Core::ARM_Interface& arm_interface32,
+                           Core::ARM_Interface& arm_interface64)
+    : interrupt_handler{interrupt_handler}, core_index{id}, arm_interface_32{arm_interface32},
+      arm_interface_64{arm_interface64} {
 
     scheduler = std::make_unique<Kernel::Scheduler>(system, core_index);
     guard = std::make_unique<Common::SpinLock>();
@@ -69,9 +60,9 @@ void PhysicalCore::Shutdown() {
 
 void PhysicalCore::SetIs64Bit(bool is_64_bit) {
     if (is_64_bit) {
-        arm_interface = arm_interface_64.get();
+        arm_interface = &arm_interface_64;
     } else {
-        arm_interface = arm_interface_32.get();
+        arm_interface = &arm_interface_32;
     }
 }
 

+ 8 - 6
src/core/hle/kernel/physical_core.h

@@ -10,7 +10,7 @@
 #include "core/arm/cpu_interrupt_handler.h"
 
 namespace Common {
-    class SpinLock;
+class SpinLock;
 }
 
 namespace Kernel {
@@ -27,7 +27,9 @@ namespace Kernel {
 
 class PhysicalCore {
 public:
-    PhysicalCore(Core::System& system, std::size_t id, Core::ExclusiveMonitor& exclusive_monitor);
+    PhysicalCore(Core::System& system, std::size_t id, Core::ExclusiveMonitor& exclusive_monitor,
+                 Core::CPUInterruptHandler& interrupt_handler, Core::ARM_Interface& arm_interface32,
+                 Core::ARM_Interface& arm_interface64);
     ~PhysicalCore();
 
     PhysicalCore(const PhysicalCore&) = delete;
@@ -92,13 +94,13 @@ public:
     void SetIs64Bit(bool is_64_bit);
 
 private:
-    Core::CPUInterruptHandler interrupt_handler;
+    Core::CPUInterruptHandler& interrupt_handler;
     std::size_t core_index;
-    std::unique_ptr<Core::ARM_Interface> arm_interface_32;
-    std::unique_ptr<Core::ARM_Interface> arm_interface_64;
+    Core::ARM_Interface& arm_interface_32;
+    Core::ARM_Interface& arm_interface_64;
     std::unique_ptr<Kernel::Scheduler> scheduler;
     Core::ARM_Interface* arm_interface{};
-    std::unique_ptr<Common::SpinLock> guard;
+    std::unique_ptr<Common::SpinLock> guard;
 };
 
 } // namespace Kernel