diff options
| author | Levi <L3ehunin@gmail.com> | 2021-01-10 22:09:56 -0700 |
|---|---|---|
| committer | Levi <L3ehunin@gmail.com> | 2021-01-10 22:09:56 -0700 |
| commit | 7a3c884e39fccfbb498b855080bffabc9ce2e7f1 (patch) | |
| tree | 5056f9406dec188439cb0deb87603498243a9412 /src/core/arm/dynarmic | |
| parent | bc69cc151192326f9b8e18bbda831f1589ba27e0 (diff) | |
| parent | 46cd71d1c773c29cce8b48e7e2b478bdf6d77085 (diff) | |
Merge remote-tracking branch 'upstream/master' into int-flags
Diffstat (limited to 'src/core/arm/dynarmic')
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_32.cpp | 28 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_32.h | 2 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_64.cpp | 60 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_64.h | 4 |
4 files changed, 51 insertions, 43 deletions
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index b5f28a86e..6c4c8e9e4 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -7,6 +7,7 @@ #include <dynarmic/A32/a32.h> #include <dynarmic/A32/config.h> #include <dynarmic/A32/context.h> +#include "common/assert.h" #include "common/logging/log.h" #include "common/page_table.h" #include "core/arm/cpu_interrupt_handler.h" @@ -70,15 +71,8 @@ public: } void ExceptionRaised(u32 pc, Dynarmic::A32::Exception exception) override { - switch (exception) { - case Dynarmic::A32::Exception::UndefinedInstruction: - case Dynarmic::A32::Exception::UnpredictableInstruction: - break; - case Dynarmic::A32::Exception::Breakpoint: - break; - } LOG_CRITICAL(Core_ARM, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})", - static_cast<std::size_t>(exception), pc, MemoryReadCode(pc)); + exception, pc, MemoryReadCode(pc)); UNIMPLEMENTED(); } @@ -132,6 +126,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable& config.page_table = reinterpret_cast<std::array<std::uint8_t*, NUM_PAGE_TABLE_ENTRIES>*>( page_table.pointers.data()); config.absolute_offset_page_table = true; + config.page_table_pointer_mask_bits = Common::PageTable::ATTRIBUTE_BITS; config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128; config.only_detect_misalignment_via_page_table_on_page_boundary = true; @@ -179,6 +174,9 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable& if (Settings::values.cpuopt_unsafe_reduce_fp_error) { config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; } + if (Settings::values.cpuopt_unsafe_inaccurate_nan) { + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; + } } return std::make_unique<Dynarmic::A32::Jit>(config); @@ -188,6 +186,10 @@ void ARM_Dynarmic_32::Run() { jit->Run(); } +void ARM_Dynarmic_32::ExceptionalExit() { + jit->ExceptionalExit(); +} + void ARM_Dynarmic_32::Step() { jit->Step(); } @@ -281,7 +283,17 @@ void ARM_Dynarmic_32::ClearInstructionCache() { jit->ClearCache(); } +void ARM_Dynarmic_32::InvalidateCacheRange(VAddr addr, std::size_t size) { + if (!jit) { + return; + } + jit->InvalidateCacheRange(static_cast<u32>(addr), size); +} + void ARM_Dynarmic_32::ClearExclusiveState() { + if (!jit) { + return; + } jit->ClearExclusiveState(); } diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h index 2bab31b92..35e9ced48 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.h +++ b/src/core/arm/dynarmic/arm_dynarmic_32.h @@ -42,6 +42,7 @@ public: u32 GetPSTATE() const override; void SetPSTATE(u32 pstate) override; void Run() override; + void ExceptionalExit() override; void Step() override; VAddr GetTlsAddress() const override; void SetTlsAddress(VAddr address) override; @@ -58,6 +59,7 @@ public: void ClearExclusiveState() override; void ClearInstructionCache() override; + void InvalidateCacheRange(VAddr addr, std::size_t size) override; void PageTableChanged(Common::PageTable& new_page_table, std::size_t new_address_space_size_in_bits) override; diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index ce9968724..4c5ebca22 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -6,6 +6,7 @@ #include <memory> #include <dynarmic/A64/a64.h> #include <dynarmic/A64/config.h> +#include "common/assert.h" #include "common/logging/log.h" #include "common/page_table.h" #include "core/arm/cpu_interrupt_handler.h" @@ -13,11 +14,9 @@ #include "core/arm/dynarmic/arm_exclusive_monitor.h" #include "core/core.h" #include "core/core_timing.h" -#include "core/core_timing_util.h" -#include "core/gdbstub/gdbstub.h" #include "core/hardware_properties.h" +#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/process.h" -#include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/svc.h" #include "core/memory.h" #include "core/settings.h" @@ -82,16 +81,9 @@ public: } void InterpreterFallback(u64 pc, std::size_t num_instructions) override { - LOG_INFO(Core_ARM, "Unicorn fallback @ 0x{:X} for {} instructions (instr = {:08X})", pc, - num_instructions, MemoryReadCode(pc)); - - ARM_Interface::ThreadContext64 ctx; - parent.SaveContext(ctx); - parent.inner_unicorn.LoadContext(ctx); - parent.inner_unicorn.ExecuteInstructions(num_instructions); - parent.inner_unicorn.SaveContext(ctx); - parent.LoadContext(ctx); - num_interpreted_instructions += num_instructions; + LOG_ERROR(Core_ARM, + "Unimplemented instruction @ 0x{:X} for {} instructions (instr = {:08X})", pc, + num_instructions, MemoryReadCode(pc)); } void ExceptionRaised(u64 pc, Dynarmic::A64::Exception exception) override { @@ -103,16 +95,6 @@ public: case Dynarmic::A64::Exception::Yield: return; case Dynarmic::A64::Exception::Breakpoint: - if (GDBStub::IsServerEnabled()) { - parent.jit->HaltExecution(); - parent.SetPC(pc); - Kernel::Thread* const thread = parent.system.CurrentScheduler().GetCurrentThread(); - parent.SaveContext(thread->GetContext64()); - GDBStub::Break(); - GDBStub::SendTrap(thread, 5); - return; - } - [[fallthrough]]; default: ASSERT_MSG(false, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})", static_cast<std::size_t>(exception), pc, MemoryReadCode(pc)); @@ -127,18 +109,17 @@ public: if (parent.uses_wall_clock) { return; } + // Divide the number of ticks by the amount of CPU cores. TODO(Subv): This yields only a // rough approximation of the amount of executed ticks in the system, it may be thrown off // if not all cores are doing a similar amount of work. Instead of doing this, we should // device a way so that timing is consistent across all cores without increasing the ticks 4 // times. - u64 amortized_ticks = - (ticks - num_interpreted_instructions) / Core::Hardware::NUM_CPU_CORES; + u64 amortized_ticks = ticks / Core::Hardware::NUM_CPU_CORES; // Always execute at least one tick. amortized_ticks = std::max<u64>(amortized_ticks, 1); parent.system.CoreTiming().AddTicks(amortized_ticks); - num_interpreted_instructions = 0; } u64 GetTicksRemaining() override { @@ -156,7 +137,6 @@ public: } ARM_Dynarmic_64& parent; - std::size_t num_interpreted_instructions = 0; u64 tpidrro_el0 = 0; u64 tpidr_el0 = 0; static constexpr u64 minimum_run_cycles = 1000U; @@ -172,6 +152,7 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable& // Memory config.page_table = reinterpret_cast<void**>(page_table.pointers.data()); config.page_table_address_space_bits = address_space_bits; + config.page_table_pointer_mask_bits = Common::PageTable::ATTRIBUTE_BITS; config.silently_mirror_page_table = false; config.absolute_offset_page_table = true; config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128; @@ -231,6 +212,9 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable& if (Settings::values.cpuopt_unsafe_reduce_fp_error) { config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; } + if (Settings::values.cpuopt_unsafe_inaccurate_nan) { + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; + } } return std::make_shared<Dynarmic::A64::Jit>(config); @@ -240,6 +224,10 @@ void ARM_Dynarmic_64::Run() { jit->Run(); } +void ARM_Dynarmic_64::ExceptionalExit() { + jit->ExceptionalExit(); +} + void ARM_Dynarmic_64::Step() { cb->InterpreterFallback(jit->GetPC(), 1); } @@ -248,12 +236,8 @@ ARM_Dynarmic_64::ARM_Dynarmic_64(System& system, CPUInterrupts& interrupt_handle bool uses_wall_clock, ExclusiveMonitor& exclusive_monitor, std::size_t core_index) : ARM_Interface{system, interrupt_handlers, uses_wall_clock}, - cb(std::make_unique<DynarmicCallbacks64>(*this)), inner_unicorn{system, interrupt_handlers, - uses_wall_clock, - ARM_Unicorn::Arch::AArch64, - core_index}, - core_index{core_index}, exclusive_monitor{ - dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {} + cb(std::make_unique<DynarmicCallbacks64>(*this)), core_index{core_index}, + exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {} ARM_Dynarmic_64::~ARM_Dynarmic_64() = default; @@ -342,7 +326,17 @@ void ARM_Dynarmic_64::ClearInstructionCache() { jit->ClearCache(); } +void ARM_Dynarmic_64::InvalidateCacheRange(VAddr addr, std::size_t size) { + if (!jit) { + return; + } + jit->InvalidateCacheRange(addr, size); +} + void ARM_Dynarmic_64::ClearExclusiveState() { + if (!jit) { + return; + } jit->ClearExclusiveState(); } diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h index 403c55961..329b59a32 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.h +++ b/src/core/arm/dynarmic/arm_dynarmic_64.h @@ -12,7 +12,6 @@ #include "common/hash.h" #include "core/arm/arm_interface.h" #include "core/arm/exclusive_monitor.h" -#include "core/arm/unicorn/arm_unicorn.h" namespace Core::Memory { class Memory; @@ -41,6 +40,7 @@ public: void SetPSTATE(u32 pstate) override; void Run() override; void Step() override; + void ExceptionalExit() override; VAddr GetTlsAddress() const override; void SetTlsAddress(VAddr address) override; void SetTPIDR_EL0(u64 value) override; @@ -56,6 +56,7 @@ public: void ClearExclusiveState() override; void ClearInstructionCache() override; + void InvalidateCacheRange(VAddr addr, std::size_t size) override; void PageTableChanged(Common::PageTable& new_page_table, std::size_t new_address_space_size_in_bits) override; @@ -71,7 +72,6 @@ private: std::unique_ptr<DynarmicCallbacks64> cb; JitCacheType jit_cache; std::shared_ptr<Dynarmic::A64::Jit> jit; - ARM_Unicorn inner_unicorn; std::size_t core_index; DynarmicExclusiveMonitor& exclusive_monitor; |
