rsx: make dmactrl get 'readonly'

This commit is contained in:
Jake 2017-09-14 17:59:00 -05:00 committed by kd-11
parent 53f9defb07
commit 626b9f93c4
3 changed files with 20 additions and 17 deletions

View File

@ -242,6 +242,7 @@ s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u6
case 0x001: // FIFO case 0x001: // FIFO
render->ctrl->get = a3; render->ctrl->get = a3;
render->ctrl->put = a4; render->ctrl->put = a4;
render->internal_get = a3;
break; break;
case 0x100: // Display mode set case 0x100: // Display mode set

View File

@ -477,10 +477,10 @@ namespace rsx
//Execute backend-local tasks first //Execute backend-local tasks first
do_local_task(); do_local_task();
const u32 get = ctrl->get; ctrl->get.store(internal_get.load());
const u32 put = ctrl->put; const u32 put = ctrl->put;
if (put == get || !Emu.IsRunning()) if (put == internal_get || !Emu.IsRunning())
{ {
if (has_deferred_call) if (has_deferred_call)
flush_command_queue(); flush_command_queue();
@ -491,16 +491,16 @@ namespace rsx
//Validate put and get registers //Validate put and get registers
//TODO: Who should handle graphics exceptions?? //TODO: Who should handle graphics exceptions??
const u32 get_address = RSXIOMem.RealAddr(get); const u32 get_address = RSXIOMem.RealAddr(internal_get);
if (!get_address) 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) if (mem_faults_count >= 3)
{ {
LOG_ERROR(RSX, "Application has failed to recover, discarding FIFO queue"); LOG_ERROR(RSX, "Application has failed to recover, discarding FIFO queue");
ctrl->get = put; internal_get = put;
} }
else else
{ {
@ -512,29 +512,29 @@ namespace rsx
continue; continue;
} }
const u32 cmd = ReadIO32(get); const u32 cmd = ReadIO32(internal_get);
const u32 count = (cmd >> 18) & 0x7ff; const u32 count = (cmd >> 18) & 0x7ff;
if ((cmd & RSX_METHOD_OLD_JUMP_CMD_MASK) == RSX_METHOD_OLD_JUMP_CMD) if ((cmd & RSX_METHOD_OLD_JUMP_CMD_MASK) == RSX_METHOD_OLD_JUMP_CMD)
{ {
u32 offs = cmd & 0x1ffffffc; 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); //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; continue;
} }
if ((cmd & RSX_METHOD_NEW_JUMP_CMD_MASK) == RSX_METHOD_NEW_JUMP_CMD) if ((cmd & RSX_METHOD_NEW_JUMP_CMD_MASK) == RSX_METHOD_NEW_JUMP_CMD)
{ {
u32 offs = cmd & 0xfffffffc; 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); //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; continue;
} }
if ((cmd & RSX_METHOD_CALL_CMD_MASK) == RSX_METHOD_CALL_CMD) 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; u32 offs = cmd & ~3;
//LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x", offs, cmd, get); //LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x", offs, cmd, get);
ctrl->get = offs; internal_get = offs;
continue; continue;
} }
if (cmd == RSX_METHOD_RETURN_CMD) if (cmd == RSX_METHOD_RETURN_CMD)
@ -542,26 +542,26 @@ namespace rsx
u32 get = m_call_stack.top(); u32 get = m_call_stack.top();
m_call_stack.pop(); m_call_stack.pop();
//LOG_WARNING(RSX, "rsx return(0x%x)", get); //LOG_WARNING(RSX, "rsx return(0x%x)", get);
ctrl->get = get; internal_get = get;
continue; continue;
} }
if (cmd == 0) //nop if (cmd == 0) //nop
{ {
ctrl->get = get + 4; internal_get += 4;
continue; continue;
} }
//Validate the args ptr if the command attempts to read from it //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) 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) if (mem_faults_count >= 3)
{ {
LOG_ERROR(RSX, "Application has failed to recover, discarding FIFO queue"); LOG_ERROR(RSX, "Application has failed to recover, discarding FIFO queue");
ctrl->get = put; internal_get = put;
} }
else else
{ {
@ -706,6 +706,7 @@ namespace rsx
if (invalid_command_interrupt_raised) if (invalid_command_interrupt_raised)
{ {
//Skip the rest of this command //Skip the rest of this command
internal_get = put;
break; break;
} }
} }
@ -714,11 +715,11 @@ namespace rsx
{ {
//This is almost guaranteed to be heap corruption at this point //This is almost guaranteed to be heap corruption at this point
//Ignore the rest of the chain //Ignore the rest of the chain
ctrl->get = put; internal_get = put;
continue; continue;
} }
ctrl->get = get + (count + 1) * 4; internal_get += (count + 1) * 4;
} }
} }

View File

@ -151,6 +151,7 @@ namespace rsx
public: public:
RsxDmaControl* ctrl = nullptr; RsxDmaControl* ctrl = nullptr;
atomic_t<u32> internal_get{ 0 };
Timer timer_sync; Timer timer_sync;