diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/arm/arm_interface.cpp | 8 | ||||
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_32.cpp | 21 | ||||
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_64.cpp | 21 | ||||
-rw-r--r-- | src/core/hle/kernel/service_thread.cpp | 3 | ||||
-rw-r--r-- | src/core/memory.cpp | 31 |
5 files changed, 59 insertions, 25 deletions
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp index 29ba562dc..2df7b0ee8 100644 --- a/src/core/arm/arm_interface.cpp +++ b/src/core/arm/arm_interface.cpp @@ -145,11 +145,15 @@ void ARM_Interface::Run() { // Notify the debugger and go to sleep if a breakpoint was hit, // or if the thread is unable to continue for any reason. if (Has(hr, breakpoint) || Has(hr, no_execute)) { - RewindBreakpointInstruction(); + if (!Has(hr, no_execute)) { + RewindBreakpointInstruction(); + } if (system.DebuggerEnabled()) { system.GetDebugger().NotifyThreadStopped(current_thread); + } else { + LogBacktrace(); } - current_thread->RequestSuspend(Kernel::SuspendType::Debug); + current_thread->RequestSuspend(SuspendType::Debug); break; } diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 227e06ea1..947747d36 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -29,7 +29,9 @@ class DynarmicCallbacks32 : public Dynarmic::A32::UserCallbacks { public: explicit DynarmicCallbacks32(ARM_Dynarmic_32& parent_) : parent{parent_}, - memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()} {} + memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()}, + check_memory_access{debugger_enabled || + !Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {} u8 MemoryRead8(u32 vaddr) override { CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Read); @@ -154,6 +156,17 @@ public: } bool CheckMemoryAccess(VAddr addr, u64 size, Kernel::DebugWatchpointType type) { + if (!check_memory_access) { + return true; + } + + if (!memory.IsValidVirtualAddressRange(addr, size)) { + LOG_CRITICAL(Core_ARM, "Stopping execution due to unmapped memory access at {:#x}", + addr); + parent.jit.load()->HaltExecution(ARM_Interface::no_execute); + return false; + } + if (!debugger_enabled) { return true; } @@ -181,7 +194,8 @@ public: ARM_Dynarmic_32& parent; Core::Memory::Memory& memory; std::size_t num_interpreted_instructions{}; - bool debugger_enabled{}; + const bool debugger_enabled{}; + const bool check_memory_access{}; static constexpr u64 minimum_run_cycles = 10000U; }; @@ -264,6 +278,9 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable* if (!Settings::values.cpuopt_recompile_exclusives) { config.recompile_on_exclusive_fastmem_failure = false; } + if (!Settings::values.cpuopt_ignore_memory_aborts) { + config.check_halt_on_memory_access = true; + } } else { // Unsafe optimizations if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) { diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index cb53d64ba..3df943df7 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -29,7 +29,9 @@ class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks { public: explicit DynarmicCallbacks64(ARM_Dynarmic_64& parent_) : parent{parent_}, - memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()} {} + memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()}, + check_memory_access{debugger_enabled || + !Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {} u8 MemoryRead8(u64 vaddr) override { CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Read); @@ -198,6 +200,17 @@ public: } bool CheckMemoryAccess(VAddr addr, u64 size, Kernel::DebugWatchpointType type) { + if (!check_memory_access) { + return true; + } + + if (!memory.IsValidVirtualAddressRange(addr, size)) { + LOG_CRITICAL(Core_ARM, "Stopping execution due to unmapped memory access at {:#x}", + addr); + parent.jit.load()->HaltExecution(ARM_Interface::no_execute); + return false; + } + if (!debugger_enabled) { return true; } @@ -226,7 +239,8 @@ public: Core::Memory::Memory& memory; u64 tpidrro_el0 = 0; u64 tpidr_el0 = 0; - bool debugger_enabled{}; + const bool debugger_enabled{}; + const bool check_memory_access{}; static constexpr u64 minimum_run_cycles = 10000U; }; @@ -323,6 +337,9 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable* if (!Settings::values.cpuopt_recompile_exclusives) { config.recompile_on_exclusive_fastmem_failure = false; } + if (!Settings::values.cpuopt_ignore_memory_aborts) { + config.check_halt_on_memory_access = true; + } } else { // Unsafe optimizations if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) { diff --git a/src/core/hle/kernel/service_thread.cpp b/src/core/hle/kernel/service_thread.cpp index e72c3d35d..38afa720b 100644 --- a/src/core/hle/kernel/service_thread.cpp +++ b/src/core/hle/kernel/service_thread.cpp @@ -163,9 +163,6 @@ ServiceThread::Impl::~Impl() { m_wakeup_event->Signal(); m_host_thread.join(); - // Lock mutex. - m_session_mutex.lock(); - // Close all remaining sessions. for (const auto& [server_session, manager] : m_sessions) { server_session->Close(); diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 3141122f1..26be74df4 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -6,7 +6,6 @@ #include "common/assert.h" #include "common/atomic_ops.h" -#include "common/cache_management.h" #include "common/common_types.h" #include "common/logging/log.h" #include "common/page_table.h" @@ -195,13 +194,11 @@ struct Memory::Impl { break; } case Common::PageType::Memory: { - DEBUG_ASSERT(pointer); u8* mem_ptr = pointer + page_offset + (page_index << YUZU_PAGEBITS); on_memory(copy_amount, mem_ptr); break; } case Common::PageType::DebugMemory: { - DEBUG_ASSERT(pointer); u8* const mem_ptr{GetPointerFromDebugMemory(current_vaddr)}; on_memory(copy_amount, mem_ptr); break; @@ -342,10 +339,9 @@ struct Memory::Impl { LOG_ERROR(HW_Memory, "Unmapped cache maintenance @ {:#018X}", current_vaddr); throw InvalidMemoryException(); }, - [&](const std::size_t block_size, u8* const host_ptr) { cb(block_size, host_ptr); }, + [&](const std::size_t block_size, u8* const host_ptr) {}, [&](const VAddr current_vaddr, const std::size_t block_size, u8* const host_ptr) { - system.GPU().FlushRegion(current_vaddr, block_size); - cb(block_size, host_ptr); + cb(current_vaddr, block_size); }, [](const std::size_t block_size) {}); } catch (InvalidMemoryException&) { @@ -356,27 +352,30 @@ struct Memory::Impl { } Result InvalidateDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size) { - auto perform = [&](const std::size_t block_size, u8* const host_ptr) { - // Do nothing; this operation (dc ivac) cannot be supported - // from EL0 + auto on_rasterizer = [&](const VAddr current_vaddr, const std::size_t block_size) { + // dc ivac: Invalidate to point of coherency + // GPU flush -> CPU invalidate + system.GPU().FlushRegion(current_vaddr, block_size); }; - return PerformCacheOperation(process, dest_addr, size, perform); + return PerformCacheOperation(process, dest_addr, size, on_rasterizer); } Result StoreDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size) { - auto perform = [&](const std::size_t block_size, u8* const host_ptr) { + auto on_rasterizer = [&](const VAddr current_vaddr, const std::size_t block_size) { // dc cvac: Store to point of coherency - Common::DataCacheLineCleanByVAToPoC(host_ptr, block_size); + // CPU flush -> GPU invalidate + system.GPU().InvalidateRegion(current_vaddr, block_size); }; - return PerformCacheOperation(process, dest_addr, size, perform); + return PerformCacheOperation(process, dest_addr, size, on_rasterizer); } Result FlushDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size) { - auto perform = [&](const std::size_t block_size, u8* const host_ptr) { + auto on_rasterizer = [&](const VAddr current_vaddr, const std::size_t block_size) { // dc civac: Store to point of coherency, and invalidate from cache - Common::DataCacheLineCleanAndInvalidateByVAToPoC(host_ptr, block_size); + // CPU flush -> GPU invalidate + system.GPU().InvalidateRegion(current_vaddr, block_size); }; - return PerformCacheOperation(process, dest_addr, size, perform); + return PerformCacheOperation(process, dest_addr, size, on_rasterizer); } void MarkRegionDebug(VAddr vaddr, u64 size, bool debug) { |