From b8df61c642310aeab3118f2637d4447740b8fcd3 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Thu, 18 Jun 2020 19:56:59 -0400 Subject: [PATCH] ARM: Update Dynarmic and Setup A32 according to latest interface. --- externals/dynarmic | 2 +- src/core/CMakeLists.txt | 8 ++ src/core/arm/dynarmic/arm_dynarmic_32.cpp | 41 +++++++++- src/core/arm/dynarmic/arm_dynarmic_32.h | 2 +- src/core/arm/dynarmic/arm_dynarmic_64.cpp | 65 +--------------- src/core/arm/dynarmic/arm_dynarmic_64.h | 25 ------ .../arm/dynarmic/arm_exclusive_monitor.cpp | 76 +++++++++++++++++++ src/core/arm/dynarmic/arm_exclusive_monitor.h | 48 ++++++++++++ src/core/arm/exclusive_monitor.cpp | 2 +- 9 files changed, 175 insertions(+), 94 deletions(-) create mode 100644 src/core/arm/dynarmic/arm_exclusive_monitor.cpp create mode 100644 src/core/arm/dynarmic/arm_exclusive_monitor.h diff --git a/externals/dynarmic b/externals/dynarmic index 3a50d444d..b759773b3 160000 --- a/externals/dynarmic +++ b/externals/dynarmic @@ -1 +1 @@ -Subproject commit 3a50d444dcb66c868528dd12057f63dc623d09a5 +Subproject commit b759773b3b76c62200ecd4e097ec6ecfd825aacb diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 653b7620b..f87d67db5 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -9,6 +9,14 @@ add_library(core STATIC arm/arm_interface.cpp arm/cpu_interrupt_handler.cpp arm/cpu_interrupt_handler.h + arm/dynarmic/arm_dynarmic_32.cpp + arm/dynarmic/arm_dynarmic_32.h + arm/dynarmic/arm_dynarmic_64.cpp + arm/dynarmic/arm_dynarmic_64.h + arm/dynarmic/arm_dynarmic_cp15.cpp + arm/dynarmic/arm_dynarmic_cp15.h + arm/dynarmic/arm_exclusive_monitor.cpp + arm/dynarmic/arm_exclusive_monitor.h arm/exclusive_monitor.cpp arm/exclusive_monitor.h arm/unicorn/arm_unicorn.cpp diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 71d7e169a..5df4fc079 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -7,14 +7,17 @@ #include #include #include +#include "common/logging/log.h" +#include "common/page_table.h" #include "core/arm/cpu_interrupt_handler.h" #include "core/arm/dynarmic/arm_dynarmic_32.h" -#include "core/arm/dynarmic/arm_dynarmic_64.h" #include "core/arm/dynarmic/arm_dynarmic_cp15.h" +#include "core/arm/dynarmic/arm_exclusive_monitor.h" #include "core/core.h" #include "core/core_timing.h" #include "core/hle/kernel/svc.h" #include "core/memory.h" +#include "core/settings.h" namespace Core { @@ -48,6 +51,19 @@ public: parent.system.Memory().Write64(vaddr, value); } + bool MemoryWriteExclusive8(u32 vaddr, u8 value, u8 expected) override { + return parent.system.Memory().WriteExclusive8(vaddr, value, expected); + } + bool MemoryWriteExclusive16(u32 vaddr, u16 value, u16 expected) override { + return parent.system.Memory().WriteExclusive16(vaddr, value, expected); + } + bool MemoryWriteExclusive32(u32 vaddr, u32 value, u32 expected) override { + return parent.system.Memory().WriteExclusive32(vaddr, value, expected); + } + bool MemoryWriteExclusive64(u32 vaddr, u64 value, u64 expected) override { + return parent.system.Memory().WriteExclusive64(vaddr, value, expected); + } + void InterpreterFallback(u32 pc, std::size_t num_instructions) override { UNIMPLEMENTED_MSG("This should never happen, pc = {:08X}, code = {:08X}", pc, MemoryReadCode(pc)); @@ -110,6 +126,27 @@ std::shared_ptr ARM_Dynarmic_32::MakeJit(Common::PageTable& // config.page_table = &page_table.pointers; config.coprocessors[15] = cp15; config.define_unpredictable_behaviour = true; + static constexpr std::size_t PAGE_BITS = 12; + static constexpr std::size_t NUM_PAGE_TABLE_ENTRIES = 1 << (32 - PAGE_BITS); + config.page_table = reinterpret_cast*>( + page_table.pointers.data()); + config.absolute_offset_page_table = true; + config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128; + config.only_detect_misalignment_via_page_table_on_page_boundary = true; + + // Multi-process state + config.processor_id = core_index; + config.global_monitor = &exclusive_monitor.monitor; + + // Timing + config.wall_clock_cntpct = uses_wall_clock; + + // Optimizations + if (Settings::values.disable_cpu_opt) { + config.enable_optimizations = false; + config.enable_fast_dispatch = false; + } + return std::make_unique(config); } @@ -178,7 +215,7 @@ void ARM_Dynarmic_32::SetTPIDR_EL0(u64 value) { } void ARM_Dynarmic_32::ChangeProcessorId(std::size_t new_core_id) { - // jit->ChangeProcessorId(new_core_id); + jit->ChangeProcessorID(new_core_id); } void ARM_Dynarmic_32::SaveContext(ThreadContext32& ctx) { diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h index 8afd15c8b..d9c0bfede 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.h +++ b/src/core/arm/dynarmic/arm_dynarmic_32.h @@ -9,7 +9,7 @@ #include #include -#include +#include #include "common/common_types.h" #include "common/hash.h" #include "core/arm/arm_interface.h" diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 8e8f7ce0a..35a99e28a 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -10,6 +10,7 @@ #include "common/page_table.h" #include "core/arm/cpu_interrupt_handler.h" #include "core/arm/dynarmic/arm_dynarmic_64.h" +#include "core/arm/dynarmic/arm_exclusive_monitor.h" #include "core/core.h" #include "core/core_timing.h" #include "core/core_timing_util.h" @@ -323,68 +324,4 @@ void ARM_Dynarmic_64::PageTableChanged(Common::PageTable& page_table, jit_cache.emplace(key, jit); } -DynarmicExclusiveMonitor::DynarmicExclusiveMonitor(Memory::Memory& memory, std::size_t core_count) - : monitor(core_count), memory{memory} {} - -DynarmicExclusiveMonitor::~DynarmicExclusiveMonitor() = default; - -u8 DynarmicExclusiveMonitor::ExclusiveRead8(std::size_t core_index, VAddr addr) { - return monitor.ReadAndMark(core_index, addr, [&]() -> u8 { return memory.Read8(addr); }); -} - -u16 DynarmicExclusiveMonitor::ExclusiveRead16(std::size_t core_index, VAddr addr) { - return monitor.ReadAndMark(core_index, addr, [&]() -> u16 { return memory.Read16(addr); }); -} - -u32 DynarmicExclusiveMonitor::ExclusiveRead32(std::size_t core_index, VAddr addr) { - return monitor.ReadAndMark(core_index, addr, [&]() -> u32 { return memory.Read32(addr); }); -} - -u64 DynarmicExclusiveMonitor::ExclusiveRead64(std::size_t core_index, VAddr addr) { - return monitor.ReadAndMark(core_index, addr, [&]() -> u64 { return memory.Read64(addr); }); -} - -u128 DynarmicExclusiveMonitor::ExclusiveRead128(std::size_t core_index, VAddr addr) { - return monitor.ReadAndMark(core_index, addr, [&]() -> u128 { - u128 result; - result[0] = memory.Read64(addr); - result[1] = memory.Read64(addr + 8); - return result; - }); -} - -void DynarmicExclusiveMonitor::ClearExclusive() { - monitor.Clear(); -} - -bool DynarmicExclusiveMonitor::ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) { - return monitor.DoExclusiveOperation(core_index, vaddr, [&](u8 expected) -> bool { - return memory.WriteExclusive8(vaddr, value, expected); - }); -} - -bool DynarmicExclusiveMonitor::ExclusiveWrite16(std::size_t core_index, VAddr vaddr, u16 value) { - return monitor.DoExclusiveOperation(core_index, vaddr, [&](u16 expected) -> bool { - return memory.WriteExclusive16(vaddr, value, expected); - }); -} - -bool DynarmicExclusiveMonitor::ExclusiveWrite32(std::size_t core_index, VAddr vaddr, u32 value) { - return monitor.DoExclusiveOperation(core_index, vaddr, [&](u32 expected) -> bool { - return memory.WriteExclusive32(vaddr, value, expected); - }); -} - -bool DynarmicExclusiveMonitor::ExclusiveWrite64(std::size_t core_index, VAddr vaddr, u64 value) { - return monitor.DoExclusiveOperation(core_index, vaddr, [&](u64 expected) -> bool { - return memory.WriteExclusive64(vaddr, value, expected); - }); -} - -bool DynarmicExclusiveMonitor::ExclusiveWrite128(std::size_t core_index, VAddr vaddr, u128 value) { - return monitor.DoExclusiveOperation(core_index, vaddr, [&](u128 expected) -> bool { - return memory.WriteExclusive128(vaddr, value, expected); - }); -} - } // namespace Core diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h index 31ec16521..c74fcbcea 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.h +++ b/src/core/arm/dynarmic/arm_dynarmic_64.h @@ -8,7 +8,6 @@ #include #include -#include #include "common/common_types.h" #include "common/hash.h" #include "core/arm/arm_interface.h" @@ -78,28 +77,4 @@ private: DynarmicExclusiveMonitor& exclusive_monitor; }; -class DynarmicExclusiveMonitor final : public ExclusiveMonitor { -public: - explicit DynarmicExclusiveMonitor(Memory::Memory& memory, std::size_t core_count); - ~DynarmicExclusiveMonitor() override; - - u8 ExclusiveRead8(std::size_t core_index, VAddr addr) override; - u16 ExclusiveRead16(std::size_t core_index, VAddr addr) override; - u32 ExclusiveRead32(std::size_t core_index, VAddr addr) override; - u64 ExclusiveRead64(std::size_t core_index, VAddr addr) override; - u128 ExclusiveRead128(std::size_t core_index, VAddr addr) override; - void ClearExclusive() override; - - bool ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) override; - bool ExclusiveWrite16(std::size_t core_index, VAddr vaddr, u16 value) override; - bool ExclusiveWrite32(std::size_t core_index, VAddr vaddr, u32 value) override; - bool ExclusiveWrite64(std::size_t core_index, VAddr vaddr, u64 value) override; - bool ExclusiveWrite128(std::size_t core_index, VAddr vaddr, u128 value) override; - -private: - friend class ARM_Dynarmic_64; - Dynarmic::A64::ExclusiveMonitor monitor; - Core::Memory::Memory& memory; -}; - } // namespace Core diff --git a/src/core/arm/dynarmic/arm_exclusive_monitor.cpp b/src/core/arm/dynarmic/arm_exclusive_monitor.cpp new file mode 100644 index 000000000..4e209f6a5 --- /dev/null +++ b/src/core/arm/dynarmic/arm_exclusive_monitor.cpp @@ -0,0 +1,76 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include +#include "core/arm/dynarmic/arm_exclusive_monitor.h" +#include "core/memory.h" + +namespace Core { + +DynarmicExclusiveMonitor::DynarmicExclusiveMonitor(Memory::Memory& memory, std::size_t core_count) + : monitor(core_count), memory{memory} {} + +DynarmicExclusiveMonitor::~DynarmicExclusiveMonitor() = default; + +u8 DynarmicExclusiveMonitor::ExclusiveRead8(std::size_t core_index, VAddr addr) { + return monitor.ReadAndMark(core_index, addr, [&]() -> u8 { return memory.Read8(addr); }); +} + +u16 DynarmicExclusiveMonitor::ExclusiveRead16(std::size_t core_index, VAddr addr) { + return monitor.ReadAndMark(core_index, addr, [&]() -> u16 { return memory.Read16(addr); }); +} + +u32 DynarmicExclusiveMonitor::ExclusiveRead32(std::size_t core_index, VAddr addr) { + return monitor.ReadAndMark(core_index, addr, [&]() -> u32 { return memory.Read32(addr); }); +} + +u64 DynarmicExclusiveMonitor::ExclusiveRead64(std::size_t core_index, VAddr addr) { + return monitor.ReadAndMark(core_index, addr, [&]() -> u64 { return memory.Read64(addr); }); +} + +u128 DynarmicExclusiveMonitor::ExclusiveRead128(std::size_t core_index, VAddr addr) { + return monitor.ReadAndMark(core_index, addr, [&]() -> u128 { + u128 result; + result[0] = memory.Read64(addr); + result[1] = memory.Read64(addr + 8); + return result; + }); +} + +void DynarmicExclusiveMonitor::ClearExclusive() { + monitor.Clear(); +} + +bool DynarmicExclusiveMonitor::ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) { + return monitor.DoExclusiveOperation(core_index, vaddr, [&](u8 expected) -> bool { + return memory.WriteExclusive8(vaddr, value, expected); + }); +} + +bool DynarmicExclusiveMonitor::ExclusiveWrite16(std::size_t core_index, VAddr vaddr, u16 value) { + return monitor.DoExclusiveOperation(core_index, vaddr, [&](u16 expected) -> bool { + return memory.WriteExclusive16(vaddr, value, expected); + }); +} + +bool DynarmicExclusiveMonitor::ExclusiveWrite32(std::size_t core_index, VAddr vaddr, u32 value) { + return monitor.DoExclusiveOperation(core_index, vaddr, [&](u32 expected) -> bool { + return memory.WriteExclusive32(vaddr, value, expected); + }); +} + +bool DynarmicExclusiveMonitor::ExclusiveWrite64(std::size_t core_index, VAddr vaddr, u64 value) { + return monitor.DoExclusiveOperation(core_index, vaddr, [&](u64 expected) -> bool { + return memory.WriteExclusive64(vaddr, value, expected); + }); +} + +bool DynarmicExclusiveMonitor::ExclusiveWrite128(std::size_t core_index, VAddr vaddr, u128 value) { + return monitor.DoExclusiveOperation(core_index, vaddr, [&](u128 expected) -> bool { + return memory.WriteExclusive128(vaddr, value, expected); + }); +} + +} // namespace Core diff --git a/src/core/arm/dynarmic/arm_exclusive_monitor.h b/src/core/arm/dynarmic/arm_exclusive_monitor.h new file mode 100644 index 000000000..964f4a55d --- /dev/null +++ b/src/core/arm/dynarmic/arm_exclusive_monitor.h @@ -0,0 +1,48 @@ +// Copyright 2020 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include +#include + +#include + +#include "common/common_types.h" +#include "core/arm/dynarmic/arm_dynarmic_32.h" +#include "core/arm/dynarmic/arm_dynarmic_64.h" +#include "core/arm/exclusive_monitor.h" + +namespace Core::Memory { +class Memory; +} + +namespace Core { + +class DynarmicExclusiveMonitor final : public ExclusiveMonitor { +public: + explicit DynarmicExclusiveMonitor(Memory::Memory& memory, std::size_t core_count); + ~DynarmicExclusiveMonitor() override; + + u8 ExclusiveRead8(std::size_t core_index, VAddr addr) override; + u16 ExclusiveRead16(std::size_t core_index, VAddr addr) override; + u32 ExclusiveRead32(std::size_t core_index, VAddr addr) override; + u64 ExclusiveRead64(std::size_t core_index, VAddr addr) override; + u128 ExclusiveRead128(std::size_t core_index, VAddr addr) override; + void ClearExclusive() override; + + bool ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) override; + bool ExclusiveWrite16(std::size_t core_index, VAddr vaddr, u16 value) override; + bool ExclusiveWrite32(std::size_t core_index, VAddr vaddr, u32 value) override; + bool ExclusiveWrite64(std::size_t core_index, VAddr vaddr, u64 value) override; + bool ExclusiveWrite128(std::size_t core_index, VAddr vaddr, u128 value) override; + +private: + friend class ARM_Dynarmic_32; + friend class ARM_Dynarmic_64; + Dynarmic::ExclusiveMonitor monitor; + Core::Memory::Memory& memory; +}; + +} // namespace Core diff --git a/src/core/arm/exclusive_monitor.cpp b/src/core/arm/exclusive_monitor.cpp index b32401e0b..d8cba369d 100644 --- a/src/core/arm/exclusive_monitor.cpp +++ b/src/core/arm/exclusive_monitor.cpp @@ -3,7 +3,7 @@ // Refer to the license.txt file included. #ifdef ARCHITECTURE_x86_64 -#include "core/arm/dynarmic/arm_dynarmic_64.h" +#include "core/arm/dynarmic/arm_exclusive_monitor.h" #endif #include "core/arm/exclusive_monitor.h" #include "core/memory.h"