summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/arm/arm_interface.cpp8
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp21
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp21
-rw-r--r--src/core/hle/kernel/service_thread.cpp3
-rw-r--r--src/core/memory.cpp31
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) {