From 626b9f93c49e0fd07820851e215617f7179886b2 Mon Sep 17 00:00:00 2001 From: Jake Date: Thu, 14 Sep 2017 17:59:00 -0500 Subject: [PATCH] rsx: make dmactrl get 'readonly' --- rpcs3/Emu/Cell/lv2/sys_rsx.cpp | 1 + rpcs3/Emu/RSX/RSXThread.cpp | 35 +++++++++++++++++----------------- rpcs3/Emu/RSX/RSXThread.h | 1 + 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/sys_rsx.cpp b/rpcs3/Emu/Cell/lv2/sys_rsx.cpp index 4a145f1d93..a9929f4c32 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rsx.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_rsx.cpp @@ -242,6 +242,7 @@ s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u6 case 0x001: // FIFO render->ctrl->get = a3; render->ctrl->put = a4; + render->internal_get = a3; break; case 0x100: // Display mode set diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index f8191f66f8..075d50ee7f 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -477,10 +477,10 @@ namespace rsx //Execute backend-local tasks first do_local_task(); - const u32 get = ctrl->get; + ctrl->get.store(internal_get.load()); const u32 put = ctrl->put; - if (put == get || !Emu.IsRunning()) + if (put == internal_get || !Emu.IsRunning()) { if (has_deferred_call) flush_command_queue(); @@ -491,16 +491,16 @@ namespace rsx //Validate put and get registers //TODO: Who should handle graphics exceptions?? - const u32 get_address = RSXIOMem.RealAddr(get); + const u32 get_address = RSXIOMem.RealAddr(internal_get); if (!get_address) { - LOG_ERROR(RSX, "Invalid FIFO queue get/put registers found, get=0x%X, put=0x%X", get, put); + LOG_ERROR(RSX, "Invalid FIFO queue get/put registers found, get=0x%X, put=0x%X", internal_get.load(), put); if (mem_faults_count >= 3) { LOG_ERROR(RSX, "Application has failed to recover, discarding FIFO queue"); - ctrl->get = put; + internal_get = put; } else { @@ -512,29 +512,29 @@ namespace rsx continue; } - const u32 cmd = ReadIO32(get); + const u32 cmd = ReadIO32(internal_get); const u32 count = (cmd >> 18) & 0x7ff; if ((cmd & RSX_METHOD_OLD_JUMP_CMD_MASK) == RSX_METHOD_OLD_JUMP_CMD) { u32 offs = cmd & 0x1ffffffc; //LOG_WARNING(RSX, "rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", offs, m_ioAddress + get, cmd, get, put); - ctrl->get = offs; + internal_get = offs; continue; } if ((cmd & RSX_METHOD_NEW_JUMP_CMD_MASK) == RSX_METHOD_NEW_JUMP_CMD) { u32 offs = cmd & 0xfffffffc; //LOG_WARNING(RSX, "rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", offs, m_ioAddress + get, cmd, get, put); - ctrl->get = offs; + internal_get = offs; continue; } if ((cmd & RSX_METHOD_CALL_CMD_MASK) == RSX_METHOD_CALL_CMD) { - m_call_stack.push(get + 4); + m_call_stack.push(internal_get + 4); u32 offs = cmd & ~3; //LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x", offs, cmd, get); - ctrl->get = offs; + internal_get = offs; continue; } if (cmd == RSX_METHOD_RETURN_CMD) @@ -542,26 +542,26 @@ namespace rsx u32 get = m_call_stack.top(); m_call_stack.pop(); //LOG_WARNING(RSX, "rsx return(0x%x)", get); - ctrl->get = get; + internal_get = get; continue; } if (cmd == 0) //nop { - ctrl->get = get + 4; + internal_get += 4; continue; } //Validate the args ptr if the command attempts to read from it - const u32 args_address = RSXIOMem.RealAddr(get + 4); + const u32 args_address = RSXIOMem.RealAddr(internal_get + 4); if (!args_address && count) { - LOG_ERROR(RSX, "Invalid FIFO queue args ptr found, get=0x%X, cmd=0x%X, count=%d", get, cmd, count); + LOG_ERROR(RSX, "Invalid FIFO queue args ptr found, get=0x%X, cmd=0x%X, count=%d", internal_get.load(), cmd, count); if (mem_faults_count >= 3) { LOG_ERROR(RSX, "Application has failed to recover, discarding FIFO queue"); - ctrl->get = put; + internal_get = put; } else { @@ -706,6 +706,7 @@ namespace rsx if (invalid_command_interrupt_raised) { //Skip the rest of this command + internal_get = put; break; } } @@ -714,11 +715,11 @@ namespace rsx { //This is almost guaranteed to be heap corruption at this point //Ignore the rest of the chain - ctrl->get = put; + internal_get = put; continue; } - ctrl->get = get + (count + 1) * 4; + internal_get += (count + 1) * 4; } } diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 960c1bd8db..085e393140 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -151,6 +151,7 @@ namespace rsx public: RsxDmaControl* ctrl = nullptr; + atomic_t internal_get{ 0 }; Timer timer_sync;