Просмотр исходного кода

Merge pull request #210 from MerryMage/f/dynarmic/sysreg

arm_dynarmic: Implement system registers and provide more hooks
bunnei 8 лет назад
Родитель
Сommit
6bf7108545
3 измененных файлов с 34 добавлено и 3 удалено
  1. 1 1
      externals/dynarmic
  2. 22 2
      src/core/arm/dynarmic/arm_dynarmic.cpp
  3. 11 0
      src/core/memory.cpp

+ 1 - 1
externals/dynarmic

@@ -1 +1 @@
-Subproject commit e585e1d49ed65c31edd567510e00508d42decb1c
+Subproject commit 6b4c6b06a94290690d2132adfa45a8087958c2c7

+ 22 - 2
src/core/arm/dynarmic/arm_dynarmic.cpp

@@ -6,6 +6,7 @@
 #include <memory>
 #include <dynarmic/A64/a64.h>
 #include <dynarmic/A64/config.h>
+#include "common/logging/log.h"
 #include "core/arm/dynarmic/arm_dynarmic.h"
 #include "core/core_timing.h"
 #include "core/hle/kernel/memory.h"
@@ -53,6 +54,9 @@ public:
     }
 
     void InterpreterFallback(u64 pc, size_t num_instructions) override {
+        LOG_INFO(Core_ARM, "Unicorn fallback @ 0x%" PRIx64 " for %zu instructions (instr = %08x)",
+                 pc, num_instructions, MemoryReadCode(pc));
+
         ARM_Interface::ThreadContext ctx;
         parent.SaveContext(ctx);
         parent.inner_unicorn.LoadContext(ctx);
@@ -63,8 +67,17 @@ public:
     }
 
     void ExceptionRaised(u64 pc, Dynarmic::A64::Exception exception) override {
-        ASSERT_MSG(false, "ExceptionRaised(exception = %zu, pc = %" PRIx64 ")",
-                   static_cast<size_t>(exception), pc);
+        switch (exception) {
+        case Dynarmic::A64::Exception::WaitForInterrupt:
+        case Dynarmic::A64::Exception::WaitForEvent:
+        case Dynarmic::A64::Exception::SendEvent:
+        case Dynarmic::A64::Exception::SendEventLocal:
+        case Dynarmic::A64::Exception::Yield:
+            return;
+        default:
+            ASSERT_MSG(false, "ExceptionRaised(exception = %zu, pc = %" PRIx64 ")",
+                       static_cast<size_t>(exception), pc);
+        }
     }
 
     void CallSVC(u32 swi) override {
@@ -81,11 +94,15 @@ public:
     u64 GetTicksRemaining() override {
         return ticks_remaining;
     }
+    u64 GetCNTPCT() override {
+        return CoreTiming::GetTicks();
+    }
 
     ARM_Dynarmic& parent;
     size_t ticks_remaining = 0;
     size_t num_interpreted_instructions = 0;
     u64 tpidrro_el0 = 0;
+    u64 tpidr_el0 = 0;
 };
 
 std::unique_ptr<Dynarmic::A64::Jit> MakeJit(const std::unique_ptr<ARM_Dynarmic_Callbacks>& cb) {
@@ -94,10 +111,13 @@ std::unique_ptr<Dynarmic::A64::Jit> MakeJit(const std::unique_ptr<ARM_Dynarmic_C
     Dynarmic::A64::UserConfig config;
     config.callbacks = cb.get();
     config.tpidrro_el0 = &cb->tpidrro_el0;
+    config.tpidr_el0 = &cb->tpidr_el0;
     config.dczid_el0 = 4;
+    config.ctr_el0 = 0x8444c004;
     config.page_table = reinterpret_cast<void**>(page_table);
     config.page_table_address_space_bits = Memory::ADDRESS_SPACE_BITS;
     config.silently_mirror_page_table = false;
+
     return std::make_unique<Dynarmic::A64::Jit>(config);
 }
 

+ 11 - 0
src/core/memory.cpp

@@ -118,6 +118,11 @@ boost::optional<T> ReadSpecial(VAddr addr);
 
 template <typename T>
 T Read(const VAddr vaddr) {
+    if ((vaddr >> PAGE_BITS) >= PAGE_TABLE_NUM_ENTRIES) {
+        LOG_ERROR(HW_Memory, "Read%lu after page table @ 0x%016" PRIX64, sizeof(T) * 8, vaddr);
+        return 0;
+    }
+
     const PageType type = current_page_table->attributes[vaddr >> PAGE_BITS];
     switch (type) {
     case PageType::Unmapped:
@@ -146,6 +151,12 @@ bool WriteSpecial(VAddr addr, const T data);
 
 template <typename T>
 void Write(const VAddr vaddr, const T data) {
+    if ((vaddr >> PAGE_BITS) >= PAGE_TABLE_NUM_ENTRIES) {
+        LOG_ERROR(HW_Memory, "Write%lu after page table 0x%08X @ 0x%016" PRIX64, sizeof(data) * 8,
+                  (u32)data, vaddr);
+        return;
+    }
+
     const PageType type = current_page_table->attributes[vaddr >> PAGE_BITS];
     switch (type) {
     case PageType::Unmapped: