diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index 5479cb6875..fe29ef58dc 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -1396,7 +1396,36 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) return true; } - vm::temporary_unlock(*cpu); + if (cpu->id_type() == 2) + { + LOG_FATAL(MEMORY, "Access violation %s location 0x%x", is_writing ? "writing" : "reading", addr); + + // TODO: + // RawSPU: Send appropriate interrupt + // SPUThread: Send sys_spu exception event + cpu->state += cpu_flag::dbg_pause; + if (cpu->check_state()) + { + // Hack: allocate memory in case the emulator is stopping + auto area = vm::get(vm::any, addr & -0x10000, 0x10000); + + if (area->flags & 0x100) + { + // For 4kb pages + utils::memory_protect(vm::base(addr & -0x1000), 0x1000, utils::protection::rw); + } + else + { + area->falloc(addr & -0x10000, 0x10000); + } + + return true; + } + } + else + { + lv2_obj::sleep(*cpu); + } } LOG_FATAL(MEMORY, "Access violation %s location 0x%x", is_writing ? "writing" : "reading", addr); diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index 1be93a4df2..150a197f78 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -1,4 +1,4 @@ -#include "stdafx.h" +#include "stdafx.h" #include "Emu/System.h" #include "Emu/Memory/vm.h" #include "CPUThread.h" diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index 38fc254e9f..614671ce63 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -903,10 +903,8 @@ namespace vm return nullptr; } - std::shared_ptr map(u32 addr, u32 size, u64 flags) + static std::shared_ptr _map(u32 addr, u32 size, u64 flags) { - vm::writer_lock lock(0); - if (!size || (size | addr) % 4096) { fmt::throw_exception("Invalid arguments (addr=0x%x, size=0x%x)" HERE, addr, size); @@ -932,6 +930,13 @@ namespace vm return block; } + std::shared_ptr map(u32 addr, u32 size, u64 flags) + { + vm::writer_lock lock(0); + + return _map(addr, size, flags); + } + std::shared_ptr find_map(u32 orig_size, u32 align, u64 flags) { vm::writer_lock lock(0); @@ -1030,6 +1035,12 @@ namespace vm } } + if (area_size) + { + lock.upgrade(); + return _map(addr, area_size, 0x200); + } + return nullptr; }