Rsx: rewrite address translation

This commit is contained in:
eladash 2018-07-27 22:07:34 +03:00 committed by kd-11
parent 9e380a4a4a
commit f349695a75
80 changed files with 218 additions and 429 deletions

View file

@ -1,5 +1,5 @@
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include "Emu/IdManager.h"
#include "RSXThread.h"
@ -28,6 +28,7 @@ class GSRender;
bool user_asked_for_frame_capture = false;
rsx::frame_trace_data frame_debug;
rsx::frame_capture_data frame_capture;
RSXIOTable RSXIOMem;
extern CellGcmOffsetTable offsetTable;
@ -613,29 +614,28 @@ namespace rsx
// Validate put and get registers before reading the command
// TODO: Who should handle graphics exceptions??
u32 cmd;
if (u32 addr = RSXIOMem.RealAddr(internal_get))
{
u32 get_address;
cmd = vm::read32(addr);
}
else
{
LOG_ERROR(RSX, "Invalid FIFO queue get/put registers found, get=0x%X, put=0x%X", internal_get.load(), put);
if (!RSXIOMem.getRealAddr(internal_get, get_address))
if (mem_faults_count >= 3)
{
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, resetting FIFO queue");
internal_get = restore_point.load();
m_return_addr = restore_ret_addr;
}
else
{
mem_faults_count++;
std::this_thread::sleep_for(10ms);
}
continue;
LOG_ERROR(RSX, "Application has failed to recover, resetting FIFO queue");
internal_get = restore_point.load();
m_return_addr = restore_ret_addr;
}
else
{
mem_faults_count++;
std::this_thread::sleep_for(10ms);
}
cmd = vm::read32(get_address);
continue;
}
const u32 count = (cmd >> 18) & 0x7ff;
@ -1977,22 +1977,22 @@ namespace rsx
u32 thread::ReadIO32(u32 addr)
{
u32 value;
if (!RSXIOMem.Read32(addr, &value))
if (u32 ea = RSXIOMem.RealAddr(addr))
{
fmt::throw_exception("%s(addr=0x%x): RSXIO memory not mapped" HERE, __FUNCTION__, addr);
return vm::read32(ea);
}
return value;
fmt::throw_exception("%s(addr=0x%x): RSXIO memory not mapped" HERE, __FUNCTION__, addr);
}
void thread::WriteIO32(u32 addr, u32 value)
{
if (!RSXIOMem.Write32(addr, value))
if (u32 ea = RSXIOMem.RealAddr(addr))
{
fmt::throw_exception("%s(addr=0x%x): RSXIO memory not mapped" HERE, __FUNCTION__, addr);
return vm::write32(ea, value);
}
fmt::throw_exception("%s(addr=0x%x): RSXIO memory not mapped" HERE, __FUNCTION__, addr);
}
std::pair<u32, u32> thread::calculate_memory_requirements(const vertex_input_layout& layout, u32 vertex_count)
@ -2422,30 +2422,31 @@ namespace rsx
void thread::on_notify_memory_unmapped(u32 base_address, u32 size)
{
if (!m_rsx_thread_exiting && base_address < 0xC0000000)
{
s32 io_addr = RSXIOMem.getMappedAddress(base_address);
if (io_addr >= 0)
u32 ea = base_address >> 20, io = RSXIOMem.io[ea];
if (io < 512)
{
if (!isHLE)
{
const u64 unmap_key = u64((1ull << (size >> 20)) - 1) << ((io_addr >> 20) & 0x3f);
const u64 gcm_flag = 0x100000000ull << (io_addr >> 26);
const u64 unmap_key = u64((1ull << (size >> 20)) - 1) << (io & 0x3f);
const u64 gcm_flag = 0x100000000ull << (io >> 6);
sys_event_port_send(fxm::get<SysRsxConfig>()->rsx_event_port, 0, gcm_flag, unmap_key);
}
else
{
const u32 end = (base_address + size) >> 20;
for (base_address >>= 20, io_addr >>= 20; base_address < end;)
for (const u32 end = ea + (size >> 20); ea < end;)
{
offsetTable.ioAddress[base_address++] = 0xFFFF;
offsetTable.eaAddress[io_addr++] = 0xFFFF;
offsetTable.ioAddress[ea++] = 0xFFFF;
offsetTable.eaAddress[io++] = 0xFFFF;
}
}
}
}
writer_lock lock(m_mtx_task);
m_invalidated_memory_ranges.push_back({ base_address, size });
writer_lock lock(m_mtx_task);
m_invalidated_memory_ranges.push_back({ base_address, size });
}
}
//Pause/cont wrappers for FIFO ctrl. Never call this from rsx thread itself!