1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 02:32:36 +01:00

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

@ -4,7 +4,7 @@
#include "GDBDebugServer.h"
#include "Log.h"
#include <algorithm>
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include "Emu/IdManager.h"
#include "Emu/CPU/CPUThread.h"

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 "Emu/Cell/RawSPUThread.h"

View File

@ -4,7 +4,7 @@
#include "Emu/Cell/PPUModule.h"
#include "Emu/Cell/PPUOpcodes.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/RSX/GSRender.h"
#include "cellGcmSys.h"
@ -37,6 +37,7 @@ struct CellGcmSysConfig {
};
u64 system_mode = 0;
u32 reserved_size = 0;
u32 local_size = 0;
u32 local_addr = 0;
@ -68,6 +69,7 @@ u32 gcmGetLocalMemorySize(u32 sdk_version)
}
CellGcmOffsetTable offsetTable;
u16 IoMapTable[0xC00];
void InitOffsetTable()
{
@ -76,6 +78,10 @@ void InitOffsetTable()
memset(offsetTable.ioAddress.get_ptr(), 0xFF, 3072 * sizeof(u16));
memset(offsetTable.eaAddress.get_ptr(), 0xFF, 512 * sizeof(u16));
memset(IoMapTable, 0, 3072 * sizeof(u16));
memset(RSXIOMem.ea, 0xFF, 512 * sizeof(u16));
memset(RSXIOMem.io, 0xFF, 3072 * sizeof(u16));
}
//----------------------------------------------------------------------------
@ -364,15 +370,17 @@ s32 _cellGcmInitBody(vm::pptr<CellGcmContextData> context, u32 cmdSize, u32 ioSi
cellGcmSys.warning("*** local memory(addr=0x%x, size=0x%x)", local_addr, local_size);
InitOffsetTable();
const auto render = rsx::get_current_renderer();
if (system_mode == CELL_GCM_SYSTEM_MODE_IOMAP_512MB)
{
cellGcmSys.warning("cellGcmInit(): 512MB io address space used");
RSXIOMem.SetRange(0, 0x20000000 /*512MB*/);
render->main_mem_size = 0x20000000;
}
else
{
cellGcmSys.warning("cellGcmInit(): 256MB io address space used");
RSXIOMem.SetRange(0, 0x10000000 /*256MB*/);
render->main_mem_size = 0x10000000;
}
if (gcmMapEaIoAddress(ioAddress, 0, ioSize, false) != CELL_OK)
@ -430,7 +438,6 @@ s32 _cellGcmInitBody(vm::pptr<CellGcmContextData> context, u32 cmdSize, u32 ioSi
ctrl.get = 0;
ctrl.ref = -1;
const auto render = rsx::get_current_renderer();
render->intr_thread = idm::make_ptr<ppu_thread>("_gcm_intr_thread", 1, 0x4000);
render->intr_thread->run();
render->main_mem_addr = 0;
@ -915,7 +922,7 @@ u32 cellGcmGetMaxIoMapSize()
{
cellGcmSys.trace("cellGcmGetMaxIoMapSize()");
return RSXIOMem.GetSize() - RSXIOMem.GetReservedAmount();
return rsx::get_current_renderer()->main_mem_size - reserved_size;
}
void cellGcmGetOffsetTable(vm::ptr<CellGcmOffsetTable> table)
@ -945,24 +952,21 @@ s32 cellGcmIoOffsetToAddress(u32 ioOffset, vm::ptr<u32> address)
s32 gcmMapEaIoAddress(u32 ea, u32 io, u32 size, bool is_strict)
{
if ((ea & 0xFFFFF) || (io & 0xFFFFF) || (size & 0xFFFFF)) return CELL_GCM_ERROR_FAILURE;
const auto render = rsx::get_current_renderer();
// Check if the mapping was successfull
if (RSXIOMem.Map(ea, size, io))
if (!size || (ea & 0xFFFFF) || (io & 0xFFFFF) || (size & 0xFFFFF)
|| rsx::get_current_renderer()->main_mem_size < io + size)
{
// Fill the offset table
for (u32 i = 0; i<(size >> 20); i++)
{
offsetTable.ioAddress[(ea >> 20) + i] = (io >> 20) + i;
offsetTable.eaAddress[(io >> 20) + i] = (ea >> 20) + i;
}
return CELL_GCM_ERROR_FAILURE;
}
else
ea >>=20, io >>= 20, size >>= 20;
IoMapTable[ea] = size;
// Fill the offset table and map memory
for (u32 i = 0; i < size; i++)
{
cellGcmSys.error("gcmMapEaIoAddress: CELL_GCM_ERROR_FAILURE");
return CELL_GCM_ERROR_FAILURE;
RSXIOMem.io[ea + i] = offsetTable.ioAddress[ea + i] = io + i;
RSXIOMem.ea[io + i] = offsetTable.eaAddress[io + i] = ea + i;
}
return CELL_OK;
@ -1009,24 +1013,23 @@ s32 cellGcmMapMainMemory(u32 ea, u32 size, vm::ptr<u32> offset)
if (!size || (ea & 0xFFFFF) || (size & 0xFFFFF)) return CELL_GCM_ERROR_FAILURE;
// Use the offset table to find the next free io address
for (u32 io = RSXIOMem.GetRangeStart() >> 20, end = RSXIOMem.GetRangeEnd() >> 20, unmap_count = 1; io < end; unmap_count++)
for (u32 io = 0, end = (rsx::get_current_renderer()->main_mem_size - reserved_size) >> 20, unmap_count = 1; io < end; unmap_count++)
{
if (static_cast<s16>(offsetTable.eaAddress[io + unmap_count - 1]) < 0)
{
if (unmap_count >= (size >> 20))
{
io <<= 20;
*offset = io << 20;
RSXIOMem.Map(ea, size, io);
*offset = io;
ea >>= 20, size >>= 20;
io >>= 20, ea >>= 20;
IoMapTable[ea] = size;
//fill the offset table
for (u32 i = 0; i<(size >> 20); ++i)
// Fill the offset table and map memory
for (u32 i = 0; i < size; i++)
{
offsetTable.ioAddress[ea + i] = io + i;
offsetTable.eaAddress[io + i] = ea + i;
RSXIOMem.io[ea + i] = offsetTable.ioAddress[ea + i] = io + i;
RSXIOMem.ea[io + i] = offsetTable.eaAddress[io + i] = ea + i;
}
return CELL_OK;
@ -1059,7 +1062,7 @@ s32 cellGcmReserveIoMapSize(u32 size)
return CELL_GCM_ERROR_INVALID_VALUE;
}
RSXIOMem.Reserve(size);
reserved_size += size;
return CELL_OK;
}
@ -1067,15 +1070,14 @@ s32 cellGcmUnmapEaIoAddress(u32 ea)
{
cellGcmSys.trace("cellGcmUnmapEaIoAddress(ea=0x%x)", ea);
u32 size;
if (RSXIOMem.UnmapRealAddress(ea, size))
if (const u32 size = std::exchange(IoMapTable[ea >>= 20], 0))
{
const u32 io = offsetTable.ioAddress[ea >>= 20];
const u32 io = offsetTable.ioAddress[ea];
for (u32 i = 0; i < size >> 20; i++)
for (u32 i = 0; i < size; i++)
{
offsetTable.ioAddress[ea + i] = 0xFFFF;
offsetTable.eaAddress[io + i] = 0xFFFF;
RSXIOMem.io[ea + i] = offsetTable.ioAddress[ea + i] = 0xFFFF;
RSXIOMem.ea[io + i] = offsetTable.eaAddress[io + i] = 0xFFFF;
}
}
else
@ -1091,15 +1093,14 @@ s32 cellGcmUnmapIoAddress(u32 io)
{
cellGcmSys.trace("cellGcmUnmapIoAddress(io=0x%x)", io);
u32 size;
if (RSXIOMem.UnmapAddress(io, size))
if (u32 size = std::exchange(IoMapTable[RSXIOMem.ea[io >>= 20]], 0))
{
const u32 ea = offsetTable.eaAddress[io >>= 20];
const u32 ea = offsetTable.eaAddress[io];
for (u32 i = 0; i < size >> 20; i++)
for (u32 i = 0; i < size; i++)
{
offsetTable.ioAddress[ea + i] = 0xFFFF;
offsetTable.eaAddress[io + i] = 0xFFFF;
RSXIOMem.io[ea + i] = offsetTable.ioAddress[ea + i] = 0xFFFF;
RSXIOMem.ea[io + i] = offsetTable.eaAddress[io + i] = 0xFFFF;
}
}
else
@ -1121,13 +1122,13 @@ s32 cellGcmUnreserveIoMapSize(u32 size)
return CELL_GCM_ERROR_INVALID_ALIGNMENT;
}
if (size > RSXIOMem.GetReservedAmount())
if (size > reserved_size)
{
cellGcmSys.error("cellGcmUnreserveIoMapSize: CELL_GCM_ERROR_INVALID_VALUE");
return CELL_GCM_ERROR_INVALID_VALUE;
}
RSXIOMem.Unreserve(size);
reserved_size -= size;
return CELL_OK;
}

View File

@ -1,5 +1,5 @@
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/IdManager.h"
#include "Emu/System.h"
#include "Emu/Cell/PPUModule.h"

View File

@ -3,7 +3,7 @@
#include "Utilities/sysinfo.h"
#include "Utilities/JIT.h"
#include "Crypto/sha1.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include "Emu/IdManager.h"
#include "PPUThread.h"

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 "Loader/ELF.h"

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"

View File

@ -1,5 +1,5 @@
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include "Utilities/JIT.h"
#include "Utilities/sysinfo.h"

View File

@ -1,7 +1,7 @@
#include "stdafx.h"
#include "Emu/System.h"
#include "Emu/IdManager.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Crypto/sha1.h"
#include "Utilities/StrUtil.h"

View File

@ -2,7 +2,7 @@
#include "Utilities/JIT.h"
#include "Utilities/lockless.h"
#include "Utilities/sysinfo.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include "Emu/IdManager.h"

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 "Emu/IPC.h"

View File

@ -1,7 +1,7 @@
#include "stdafx.h"
#include "Emu/Cell/ErrorCodes.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "sys_dbg.h"
#include "Emu/Cell/Modules/sys_lv2dbg.h"

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 "Emu/IPC.h"

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 "Emu/IPC.h"

View File

@ -1,6 +1,6 @@
#pragma once
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/Cell/ErrorCodes.h"
// Open Flags

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"

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"

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"

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"

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"

View File

@ -1,6 +1,6 @@
#pragma once
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/Cell/ErrorCodes.h"
#include "Emu/IdManager.h"

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 "Emu/IPC.h"

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 "Emu/Cell/PPUThread.h"

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"

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"

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 "Crypto/unself.h"

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/Cell/PPUModule.h"
#include "Emu/RSX/GSRender.h"
@ -124,10 +124,13 @@ s32 sys_rsx_context_allocate(vm::ptr<u32> context_id, vm::ptr<u64> lpar_dma_cont
dmaControl.put = 0;
dmaControl.ref = 0xFFFFFFFF;
memset(RSXIOMem.ea, 0xFF, 512 * sizeof(u16));
memset(RSXIOMem.io, 0xFF, 3072 * sizeof(u16));
if (false/*system_mode == CELL_GCM_SYSTEM_MODE_IOMAP_512MB*/)
RSXIOMem.SetRange(0, 0x20000000 /*512MB*/);
rsx::get_current_renderer()->main_mem_size = 0x20000000; //512MB
else
RSXIOMem.SetRange(0, 0x10000000 /*256MB*/);
rsx::get_current_renderer()->main_mem_size = 0x10000000; //256MB
sys_event_queue_attribute_t attr;
attr.protocol = SYS_SYNC_PRIORITY;
@ -175,26 +178,46 @@ s32 sys_rsx_context_iomap(u32 context_id, u32 io, u32 ea, u32 size, u64 flags)
{
sys_rsx.warning("sys_rsx_context_iomap(context_id=0x%x, io=0x%x, ea=0x%x, size=0x%x, flags=0x%llx)", context_id, io, ea, size, flags);
if (!RSXIOMem.Map(ea, size, io))
if (!size || io & 0xFFFFF || ea & 0xFFFFF || size & 0xFFFFF
|| rsx::get_current_renderer()->main_mem_size < io + size)
{
return CELL_EINVAL;
}
io >>= 20, ea >>= 20, size >>= 20;
for (u32 i = 0; i < size; i++)
{
RSXIOMem.io[ea + i] = io + i;
RSXIOMem.ea[io + i] = ea + i;
}
return CELL_OK;
}
/*
* lv2 SysCall 673 (0x2A1): sys_rsx_context_iounmap
* @param context_id (IN): RSX context, E.g. 0x55555555 (in vsh.self)
* @param io_addr (IN): IO address. E.g. 0x00600000 (Start page 6)
* @param io (IN): IO address. E.g. 0x00600000 (Start page 6)
* @param size (IN): Size to unmap in byte. E.g. 0x00200000
*/
s32 sys_rsx_context_iounmap(u32 context_id, u32 io_addr, u32 size)
s32 sys_rsx_context_iounmap(u32 context_id, u32 io, u32 size)
{
sys_rsx.warning("sys_rsx_context_iounmap(context_id=0x%x, io_addr=0x%x, size=0x%x)", context_id, io_addr, size);
if (RSXIOMem.UnmapAddress(io_addr, size))
return CELL_OK;
return CELL_EINVAL;
sys_rsx.warning("sys_rsx_context_iounmap(context_id=0x%x, io=0x%x, size=0x%x)", context_id, io, size);
if (!size || rsx::get_current_renderer()->main_mem_size < io + size)
{
return CELL_EINVAL;
}
const u32 end = (io >>= 20) + (size >>= 20);
for (u32 ea = RSXIOMem.ea[io]; io < end;)
{
RSXIOMem.io[ea++] = 0xFFFF;
RSXIOMem.ea[io++] = 0xFFFF;
}
return CELL_OK;
}
/*

View File

@ -114,7 +114,7 @@ s32 sys_rsx_memory_free(u32 mem_handle);
s32 sys_rsx_context_allocate(vm::ptr<u32> context_id, vm::ptr<u64> lpar_dma_control, vm::ptr<u64> lpar_driver_info, vm::ptr<u64> lpar_reports, u64 mem_ctx, u64 system_mode);
s32 sys_rsx_context_free(u32 context_id);
s32 sys_rsx_context_iomap(u32 context_id, u32 io, u32 ea, u32 size, u64 flags);
s32 sys_rsx_context_iounmap(u32 context_id, u32 io_addr, u32 size);
s32 sys_rsx_context_iounmap(u32 context_id, u32 io, u32 size);
s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u64 a5, u64 a6);
s32 sys_rsx_device_map(vm::ptr<u64> dev_addr, vm::ptr<u64> a2, u32 dev_id);
s32 sys_rsx_device_unmap(u32 dev_id);

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 "Emu/IPC.h"

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 "Emu/IPC.h"

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 "Crypto/unself.h"

View File

@ -1,6 +1,6 @@
#pragma once
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/Cell/ErrorCodes.h"
struct CellSsOpenPSID

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/Cell/ErrorCodes.h"

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"

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/Cell/ErrorCodes.h"

View File

@ -1,6 +1,6 @@
#pragma once
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/Cell/ErrorCodes.h"
// TTY channels

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/Cell/ErrorCodes.h"

View File

@ -1,6 +1,6 @@
#pragma once
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/Cell/ErrorCodes.h"
#include "Emu/IdManager.h"

View File

@ -1,136 +0,0 @@
#include "stdafx.h"
#include "Memory.h"
VirtualMemoryBlock RSXIOMem;
VirtualMemoryBlock* VirtualMemoryBlock::SetRange(const u32 start, const u32 size)
{
m_range_start = start;
m_range_size = size;
return this;
}
bool VirtualMemoryBlock::IsInMyRange(const u32 addr, const u32 size)
{
return addr >= m_range_start && addr + size <= m_range_start + m_range_size - GetReservedAmount();
}
bool VirtualMemoryBlock::Map(u32 realaddr, u32 size, u32 addr)
{
if (!size || !IsInMyRange(addr, size))
{
return false;
}
m_mapped_memory.emplace_back(addr, realaddr, size);
return true;
}
bool VirtualMemoryBlock::UnmapRealAddress(u32 realaddr, u32& size)
{
for (u32 i = 0; i<m_mapped_memory.size(); ++i)
{
if (m_mapped_memory[i].realAddress == realaddr && IsInMyRange(m_mapped_memory[i].addr, m_mapped_memory[i].size))
{
size = m_mapped_memory[i].size;
m_mapped_memory.erase(m_mapped_memory.begin() + i);
return true;
}
}
return false;
}
bool VirtualMemoryBlock::UnmapAddress(u32 addr, u32& size)
{
for (u32 i = 0; i<m_mapped_memory.size(); ++i)
{
if (m_mapped_memory[i].addr == addr && IsInMyRange(m_mapped_memory[i].addr, m_mapped_memory[i].size))
{
size = m_mapped_memory[i].size;
m_mapped_memory.erase(m_mapped_memory.begin() + i);
return true;
}
}
return false;
}
bool VirtualMemoryBlock::Read32(const u32 addr, u32* value)
{
u32 realAddr;
if (!getRealAddr(addr, realAddr))
return false;
*value = vm::read32(realAddr);
return true;
}
bool VirtualMemoryBlock::Write32(const u32 addr, const u32 value)
{
u32 realAddr;
if (!getRealAddr(addr, realAddr))
return false;
vm::write32(realAddr, value);
return true;
}
bool VirtualMemoryBlock::getRealAddr(u32 addr, u32& result)
{
for (u32 i = 0; i<m_mapped_memory.size(); ++i)
{
if (addr >= m_mapped_memory[i].addr && addr < m_mapped_memory[i].addr + m_mapped_memory[i].size)
{
result = m_mapped_memory[i].realAddress + (addr - m_mapped_memory[i].addr);
return true;
}
}
return false;
}
s32 VirtualMemoryBlock::getMappedAddress(u32 realAddress)
{
for (u32 i = 0; i<m_mapped_memory.size(); ++i)
{
if (realAddress >= m_mapped_memory[i].realAddress && realAddress < m_mapped_memory[i].realAddress + m_mapped_memory[i].size)
{
return m_mapped_memory[i].addr + (realAddress - m_mapped_memory[i].realAddress);
}
}
return -1;
}
bool VirtualMemoryBlock::Reserve(u32 size)
{
if (size + GetReservedAmount() > m_range_size)
return false;
m_reserve_size += size;
return true;
}
bool VirtualMemoryBlock::Unreserve(u32 size)
{
if (size > GetReservedAmount())
return false;
m_reserve_size -= size;
return true;
}
u32 VirtualMemoryBlock::GetReservedAmount()
{
return m_reserve_size;
}
u32 VirtualMemoryBlock::GetRangeStart()
{
return m_range_start;
}
u32 VirtualMemoryBlock::GetRangeEnd()
{
return m_range_start + m_range_size - GetReservedAmount();
}

View File

@ -1,7 +0,0 @@
#pragma once
#include "MemoryBlock.h"
extern VirtualMemoryBlock RSXIOMem;
#include "vm.h"

View File

@ -1,101 +0,0 @@
#pragma once
struct MemInfo
{
u32 addr;
u32 size;
MemInfo(u32 addr, u32 size)
: addr(addr)
, size(size)
{
}
MemInfo()
: addr(0)
, size(0)
{
}
};
struct VirtualMemInfo : public MemInfo
{
u32 realAddress;
VirtualMemInfo(u32 addr, u32 realaddr, u32 size)
: MemInfo(addr, size)
, realAddress(realaddr)
{
}
VirtualMemInfo()
: MemInfo(0, 0)
, realAddress(0)
{
}
};
class VirtualMemoryBlock
{
std::vector<VirtualMemInfo> m_mapped_memory;
u32 m_reserve_size = 0;
u32 m_range_start = 0;
u32 m_range_size = 0;
public:
VirtualMemoryBlock() = default;
VirtualMemoryBlock* SetRange(const u32 start, const u32 size);
void Clear() { m_mapped_memory.clear(); m_reserve_size = 0; m_range_start = 0; m_range_size = 0; }
u32 GetStartAddr() const { return m_range_start; }
u32 GetSize() const { return m_range_size; }
bool IsInMyRange(const u32 addr, const u32 size);
// maps real address to virtual address space
bool Map(u32 realaddr, u32 size, u32 addr);
// Unmap real address (please specify only starting point, no midway memory will be unmapped), returns the size of the unmapped area
bool UnmapRealAddress(u32 realaddr, u32& size);
// Unmap address (please specify only starting point, no midway memory will be unmapped), returns the size of the unmapped area
bool UnmapAddress(u32 addr, u32& size);
// Reserve a certain amount so no one can use it, returns true on success, false on failure
bool Reserve(u32 size);
// Unreserve a certain amount of bytes, returns true on success, false if size is bigger than the reserved amount
bool Unreserve(u32 size);
// Return the total amount of reserved memory
u32 GetReservedAmount();
// Return the start of the mapped space
u32 GetRangeStart();
// Return the end of the mapped space
u32 GetRangeEnd();
bool Read32(const u32 addr, u32* value);
bool Write32(const u32 addr, const u32 value);
// try to get the real address given a mapped address
// return true for success
bool getRealAddr(u32 addr, u32& result);
u32 RealAddr(u32 addr)
{
u32 realAddr = 0;
if (!getRealAddr(addr, realAddr))
{
LOG_ERROR(HLE, "Getting the real address failed. (addr=0x%x)", addr);
return 0;
}
return realAddr;
}
// return the mapped address given a real address, if not mapped return minus one
s32 getMappedAddress(u32 realAddress);
};

View File

@ -1,5 +1,4 @@
#include "stdafx.h"
#include "Memory.h"
#include "Emu/System.h"
#include "Utilities/mutex.h"
#include "Utilities/cond.h"

View File

@ -5,7 +5,7 @@
#include "Emu/RSX/Common/surface_store.h"
#include "Emu/RSX/GCM.h"
#include "Emu/RSX/RSXThread.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "xxhash.h"

View File

@ -3,7 +3,7 @@
#include "Emu/System.h"
#include "Emu/Cell/lv2/sys_rsx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/RSX/GSRender.h"
#include <map>
@ -104,12 +104,12 @@ namespace rsx
fmt::throw_exception("Capture Replay: no space in io for fifo commands! size: 0x%x, lowest in capture: 0x%x, largest_free_block: 0x%x", fifo_size, lowest_iooffset, largest_free_block);
}
return std::make_tuple(fifo_start_addr, fifo_size);
return std::make_tuple(fifo_start_addr, ::align<u32>(fifo_size, 0x100000));
}
std::vector<u32> rsx_replay_thread::alloc_write_fifo(be_t<u32> context_id, u32 fifo_start_addr, u32 fifo_size)
{
const u32 fifo_mem = vm::alloc(fifo_size, vm::main);
const u32 fifo_mem = vm::alloc(fifo_size, vm::main, 0x100000);
if (fifo_mem == 0)
fmt::throw_exception("Capture Replay: fifo alloc failed! size: 0x%x", fifo_size);
@ -282,7 +282,7 @@ namespace rsx
if (memblock.ioOffset <= fifo_start_addr + fifo_size && fifo_start_addr <= memblock.size + memblock.offset)
fmt::throw_exception("Capture Replay: overlap detected between game io allocs and fifo alloc, algorithms botched.");
if (sys_rsx_context_iomap(context_id, memblock.ioOffset, memblock.addr, memblock.size + memblock.offset, 0) != CELL_OK)
if (sys_rsx_context_iomap(context_id, memblock.ioOffset & ~0xFFFFF, memblock.addr & ~0xFFFFF, ::align<u32>(memblock.size + memblock.offset, 0x100000), 0) != CELL_OK)
fmt::throw_exception("rsx io map failed for block");
}

View File

@ -1,6 +1,6 @@
#pragma once
#include <sstream>
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/RSX/GL/GLVertexProgram.h"
#include "Emu/RSX/GL/GLFragmentProgram.h"

View File

@ -1,5 +1,5 @@
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include "FragmentProgramDecompiler.h"

View File

@ -3,7 +3,7 @@
#include "stdafx_d3d12.h"
#include "D3D12FragmentProgramDecompiler.h"
#include "D3D12CommonDecompiler.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include <set>

View File

@ -1,7 +1,7 @@
#pragma once
#include "D3D12Utils.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include "Emu/RSX/GSRender.h"

View File

@ -2,7 +2,7 @@
#include "stdafx.h"
#include "stdafx_d3d12.h"
#include "D3D12RenderTargetSets.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include "Emu/RSX/GSRender.h"
#include "../rsx_methods.h"

View File

@ -1,6 +1,6 @@
#include "stdafx.h"
#include <set>
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include "GLFragmentProgram.h"
#include "../Common/ProgramStateCache.h"

View File

@ -1,5 +1,5 @@
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include "GLGSRender.h"
#include "GLVertexProgram.h"

View File

@ -1,5 +1,5 @@
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include "GSRender.h"

View File

@ -1,5 +1,5 @@
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "RSXThread.h"
#include "RSXTexture.h"
#include "rsx_methods.h"

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!

View File

@ -27,9 +27,35 @@
extern u64 get_system_time();
struct RSXIOTable
{
u16 ea[512];
u16 io[3072];
// try to get the real address given a mapped address
// return non zero on success
inline u32 RealAddr(u32 offs)
{
if (offs & 0xE0000000)
{
return 0; // offset is beyond the limit
}
const s32 upper = this->ea[offs >> 20] << 20;
if (upper < 0)
{
return 0;
}
return upper | (offs & 0xFFFFF);
}
};
extern bool user_asked_for_frame_capture;
extern rsx::frame_trace_data frame_debug;
extern rsx::frame_capture_data frame_capture;
extern RSXIOTable RSXIOMem;
namespace rsx
{
@ -278,7 +304,7 @@ namespace rsx
std::shared_ptr<thread_ctrl> m_decompiler_thread;
protected:
atomic_t<bool> m_rsx_thread_exiting{false};
atomic_t<bool> m_rsx_thread_exiting{true};
s32 m_return_addr{-1}, restore_ret_addr{-1};
std::array<push_buffer_vertex_info, 16> vertex_push_buffers;
std::vector<u32> element_push_buffer;
@ -354,7 +380,7 @@ namespace rsx
u32 ctxt_addr;
u32 label_addr;
u32 local_mem_addr, main_mem_addr;
u32 local_mem_addr, main_mem_addr, main_mem_size{0};
bool m_rtts_dirty;
bool m_textures_dirty[16];

View File

@ -1,5 +1,5 @@
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include "VKFragmentProgram.h"

View File

@ -1,5 +1,5 @@
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include "VKGSRender.h"
#include "../rsx_methods.h"

View File

@ -1,5 +1,5 @@
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include "VKGSRender.h"
#include "../rsx_methods.h"

View File

@ -1,7 +1,7 @@
#include "stdafx.h"
#include "rsx_methods.h"
#include "RSXThread.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include "rsx_utils.h"
#include "rsx_decode.h"

View File

@ -1,6 +1,6 @@
#include "stdafx.h"
#include "Utilities/bin_patch.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include "Emu/Cell/PPUThread.h"
@ -1403,7 +1403,6 @@ void Emulator::Stop(bool restart)
LOG_NOTICE(GENERAL, "Objects cleared...");
RSXIOMem.Clear();
vm::close();
if (do_exit)

View File

@ -327,9 +327,6 @@
<ClCompile Include="Emu\Cell\SPUThread.cpp" />
<ClCompile Include="Emu\CPU\CPUThread.cpp" />
<ClCompile Include="Emu\VFS.cpp" />
<ClCompile Include="Emu\Memory\Memory.cpp">
<ObjectFileName>$(IntDir)OldMemory.obj</ObjectFileName>
</ClCompile>
<ClCompile Include="Emu\RSX\GSRender.cpp" />
<ClCompile Include="Emu\RSX\RSXTexture.cpp" />
<ClCompile Include="Emu\RSX\RSXThread.cpp" />
@ -546,8 +543,6 @@
<ClInclude Include="Emu\Io\Null\NullMouseHandler.h" />
<ClInclude Include="Emu\Io\Null\NullPadHandler.h" />
<ClInclude Include="Emu\Io\PadHandler.h" />
<ClInclude Include="Emu\Memory\Memory.h" />
<ClInclude Include="Emu\Memory\MemoryBlock.h" />
<ClInclude Include="Emu\RSX\CgBinaryProgram.h" />
<ClInclude Include="Emu\RSX\Common\BufferUtils.h" />
<ClInclude Include="Emu\RSX\Common\FragmentProgramDecompiler.h" />

View File

@ -116,9 +116,6 @@
<ClCompile Include="Emu\Audio\AudioDumper.cpp">
<Filter>Emu\Audio</Filter>
</ClCompile>
<ClCompile Include="Emu\Memory\Memory.cpp">
<Filter>Emu\Memory</Filter>
</ClCompile>
<ClCompile Include="Emu\Memory\vm.cpp">
<Filter>Emu\Memory</Filter>
</ClCompile>
@ -838,12 +835,6 @@
<ClInclude Include="Emu\Audio\AudioDumper.h">
<Filter>Emu\Audio</Filter>
</ClInclude>
<ClInclude Include="Emu\Memory\Memory.h">
<Filter>Emu\Memory</Filter>
</ClInclude>
<ClInclude Include="Emu\Memory\MemoryBlock.h">
<Filter>Emu\Memory</Filter>
</ClInclude>
<ClInclude Include="Loader\PSF.h">
<Filter>Loader</Filter>
</ClInclude>

View File

@ -2,7 +2,7 @@
#include "stdafx.h"
#include "Emu/System.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "table_item_delegate.h"
#include <QDialog>

View File

@ -1,7 +1,7 @@
#pragma once
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include "Emu/IdManager.h"
#include "Emu/CPU/CPUThread.h"

View File

@ -4,7 +4,7 @@
#include "table_item_delegate.h"
#include "custom_table_widget_item.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include "Loader/PSF.h"
#include "Utilities/types.h"

View File

@ -2,7 +2,7 @@
#include "stdafx.h"
#include "Emu/System.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/CPU/CPUThread.h"
#include "Emu/CPU/CPUDisAsm.h"
#include "Emu/Cell/PPUThread.h"

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"

View File

@ -37,7 +37,7 @@
#include "stdafx.h"
#include "Emu/System.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Crypto/unpkg.h"
#include "Crypto/unself.h"

View File

@ -1,7 +1,7 @@
#pragma once
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include <QDialog>

View File

@ -1,5 +1,5 @@
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "memory_viewer_panel.h"

View File

@ -4,7 +4,7 @@
#include "Emu/Memory/vm.h"
#include "Emu/Cell/Modules/cellMsgDialog.h"
#include "Emu/System.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/Cell/lv2/sys_time.h"
#include <QPushButton>

View File

@ -215,8 +215,7 @@ rsx_debugger::rsx_debugger(std::shared_ptr<gui_settings> gui_settings, QWidget*
{
if (const auto render = rsx::get_current_renderer())
{
u32 realAddr;
if (RSXIOMem.getRealAddr(render->ctrl->get.load(), realAddr))
if (u32 realAddr = RSXIOMem.RealAddr(render->ctrl->get.load()))
{
m_addr = realAddr;
UpdateInformation();
@ -227,8 +226,7 @@ rsx_debugger::rsx_debugger(std::shared_ptr<gui_settings> gui_settings, QWidget*
{
if (const auto render = rsx::get_current_renderer())
{
u32 realAddr;
if (RSXIOMem.getRealAddr(render->ctrl->put.load(), realAddr))
if (u32 realAddr = RSXIOMem.RealAddr(render->ctrl->put.load()))
{
m_addr = realAddr;
UpdateInformation();

View File

@ -2,7 +2,7 @@
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include "Emu/IdManager.h"
#include "Emu/RSX/GSRender.h"

View File

@ -1,7 +1,7 @@
#pragma once
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/Cell/Modules/cellSaveData.h"
class save_data_dialog : public SaveDialogBase

View File

@ -2,7 +2,7 @@
// I just want the struct for the save data.
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/Cell/Modules/cellSaveData.h"
#include <QDialog>

View File

@ -3,7 +3,7 @@
// I just want the struct for the save data.
#include "stdafx.h"
#include "Emu/System.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/Cell/Modules/cellSaveData.h"
#include "gui_settings.h"

View File

@ -1,7 +1,7 @@
#pragma once
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/Cell/Modules/cellSaveData.h"
#include "gui_settings.h"

View File

@ -11,7 +11,7 @@
#include "rpcs3/Emu/VFS.h"
#include "Emu/System.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/Cell/Modules/sceNpTrophy.h"
#include "yaml-cpp/yaml.h"

View File

@ -1,7 +1,7 @@
#pragma once
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/Cell/Modules/sceNpTrophy.h"
#include <QWidget>

View File

@ -1,7 +1,7 @@
#pragma once
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/vm.h"
#include "Emu/Cell/Modules/sceNpTrophy.h"
#include <QWindow>