ARM: Update Dynarmic and Setup A32 according to latest interface.
This commit is contained in:
parent
22ceaca2f4
commit
b8df61c642
|
@ -1 +1 @@
|
||||||
Subproject commit 3a50d444dcb66c868528dd12057f63dc623d09a5
|
Subproject commit b759773b3b76c62200ecd4e097ec6ecfd825aacb
|
|
@ -9,6 +9,14 @@ add_library(core STATIC
|
||||||
arm/arm_interface.cpp
|
arm/arm_interface.cpp
|
||||||
arm/cpu_interrupt_handler.cpp
|
arm/cpu_interrupt_handler.cpp
|
||||||
arm/cpu_interrupt_handler.h
|
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.cpp
|
||||||
arm/exclusive_monitor.h
|
arm/exclusive_monitor.h
|
||||||
arm/unicorn/arm_unicorn.cpp
|
arm/unicorn/arm_unicorn.cpp
|
||||||
|
|
|
@ -7,14 +7,17 @@
|
||||||
#include <dynarmic/A32/a32.h>
|
#include <dynarmic/A32/a32.h>
|
||||||
#include <dynarmic/A32/config.h>
|
#include <dynarmic/A32/config.h>
|
||||||
#include <dynarmic/A32/context.h>
|
#include <dynarmic/A32/context.h>
|
||||||
|
#include "common/logging/log.h"
|
||||||
|
#include "common/page_table.h"
|
||||||
#include "core/arm/cpu_interrupt_handler.h"
|
#include "core/arm/cpu_interrupt_handler.h"
|
||||||
#include "core/arm/dynarmic/arm_dynarmic_32.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_dynarmic_cp15.h"
|
||||||
|
#include "core/arm/dynarmic/arm_exclusive_monitor.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
#include "core/hle/kernel/svc.h"
|
#include "core/hle/kernel/svc.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
#include "core/settings.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
|
@ -48,6 +51,19 @@ public:
|
||||||
parent.system.Memory().Write64(vaddr, value);
|
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 {
|
void InterpreterFallback(u32 pc, std::size_t num_instructions) override {
|
||||||
UNIMPLEMENTED_MSG("This should never happen, pc = {:08X}, code = {:08X}", pc,
|
UNIMPLEMENTED_MSG("This should never happen, pc = {:08X}, code = {:08X}", pc,
|
||||||
MemoryReadCode(pc));
|
MemoryReadCode(pc));
|
||||||
|
@ -110,6 +126,27 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable&
|
||||||
// config.page_table = &page_table.pointers;
|
// config.page_table = &page_table.pointers;
|
||||||
config.coprocessors[15] = cp15;
|
config.coprocessors[15] = cp15;
|
||||||
config.define_unpredictable_behaviour = true;
|
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<std::array<std::uint8_t*, NUM_PAGE_TABLE_ENTRIES>*>(
|
||||||
|
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<Dynarmic::A32::Jit>(config);
|
return std::make_unique<Dynarmic::A32::Jit>(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +215,7 @@ void ARM_Dynarmic_32::SetTPIDR_EL0(u64 value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARM_Dynarmic_32::ChangeProcessorId(std::size_t new_core_id) {
|
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) {
|
void ARM_Dynarmic_32::SaveContext(ThreadContext32& ctx) {
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
#include <dynarmic/A32/a32.h>
|
#include <dynarmic/A32/a32.h>
|
||||||
#include <dynarmic/A64/a64.h>
|
#include <dynarmic/A64/a64.h>
|
||||||
#include <dynarmic/A64/exclusive_monitor.h>
|
#include <dynarmic/exclusive_monitor.h>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/hash.h"
|
#include "common/hash.h"
|
||||||
#include "core/arm/arm_interface.h"
|
#include "core/arm/arm_interface.h"
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "common/page_table.h"
|
#include "common/page_table.h"
|
||||||
#include "core/arm/cpu_interrupt_handler.h"
|
#include "core/arm/cpu_interrupt_handler.h"
|
||||||
#include "core/arm/dynarmic/arm_dynarmic_64.h"
|
#include "core/arm/dynarmic/arm_dynarmic_64.h"
|
||||||
|
#include "core/arm/dynarmic/arm_exclusive_monitor.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
#include "core/core_timing_util.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);
|
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<u8>(core_index, addr, [&]() -> u8 { return memory.Read8(addr); });
|
|
||||||
}
|
|
||||||
|
|
||||||
u16 DynarmicExclusiveMonitor::ExclusiveRead16(std::size_t core_index, VAddr addr) {
|
|
||||||
return monitor.ReadAndMark<u16>(core_index, addr, [&]() -> u16 { return memory.Read16(addr); });
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 DynarmicExclusiveMonitor::ExclusiveRead32(std::size_t core_index, VAddr addr) {
|
|
||||||
return monitor.ReadAndMark<u32>(core_index, addr, [&]() -> u32 { return memory.Read32(addr); });
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 DynarmicExclusiveMonitor::ExclusiveRead64(std::size_t core_index, VAddr addr) {
|
|
||||||
return monitor.ReadAndMark<u64>(core_index, addr, [&]() -> u64 { return memory.Read64(addr); });
|
|
||||||
}
|
|
||||||
|
|
||||||
u128 DynarmicExclusiveMonitor::ExclusiveRead128(std::size_t core_index, VAddr addr) {
|
|
||||||
return monitor.ReadAndMark<u128>(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<u8>(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<u16>(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<u32>(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<u64>(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<u128>(core_index, vaddr, [&](u128 expected) -> bool {
|
|
||||||
return memory.WriteExclusive128(vaddr, value, expected);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include <dynarmic/A64/a64.h>
|
#include <dynarmic/A64/a64.h>
|
||||||
#include <dynarmic/A64/exclusive_monitor.h>
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/hash.h"
|
#include "common/hash.h"
|
||||||
#include "core/arm/arm_interface.h"
|
#include "core/arm/arm_interface.h"
|
||||||
|
@ -78,28 +77,4 @@ private:
|
||||||
DynarmicExclusiveMonitor& exclusive_monitor;
|
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
|
} // namespace Core
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
// Copyright 2018 yuzu emulator team
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <cinttypes>
|
||||||
|
#include <memory>
|
||||||
|
#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<u8>(core_index, addr, [&]() -> u8 { return memory.Read8(addr); });
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 DynarmicExclusiveMonitor::ExclusiveRead16(std::size_t core_index, VAddr addr) {
|
||||||
|
return monitor.ReadAndMark<u16>(core_index, addr, [&]() -> u16 { return memory.Read16(addr); });
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 DynarmicExclusiveMonitor::ExclusiveRead32(std::size_t core_index, VAddr addr) {
|
||||||
|
return monitor.ReadAndMark<u32>(core_index, addr, [&]() -> u32 { return memory.Read32(addr); });
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 DynarmicExclusiveMonitor::ExclusiveRead64(std::size_t core_index, VAddr addr) {
|
||||||
|
return monitor.ReadAndMark<u64>(core_index, addr, [&]() -> u64 { return memory.Read64(addr); });
|
||||||
|
}
|
||||||
|
|
||||||
|
u128 DynarmicExclusiveMonitor::ExclusiveRead128(std::size_t core_index, VAddr addr) {
|
||||||
|
return monitor.ReadAndMark<u128>(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<u8>(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<u16>(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<u32>(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<u64>(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<u128>(core_index, vaddr, [&](u128 expected) -> bool {
|
||||||
|
return memory.WriteExclusive128(vaddr, value, expected);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Core
|
|
@ -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 <memory>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include <dynarmic/exclusive_monitor.h>
|
||||||
|
|
||||||
|
#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
|
|
@ -3,7 +3,7 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#ifdef ARCHITECTURE_x86_64
|
#ifdef ARCHITECTURE_x86_64
|
||||||
#include "core/arm/dynarmic/arm_dynarmic_64.h"
|
#include "core/arm/dynarmic/arm_exclusive_monitor.h"
|
||||||
#endif
|
#endif
|
||||||
#include "core/arm/exclusive_monitor.h"
|
#include "core/arm/exclusive_monitor.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
Reference in New Issue