mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 11:36:13 +00:00
allow deallocations to unmap rsx mapped memory
This commit is contained in:
parent
ce98c962f8
commit
23b380eb41
7 changed files with 84 additions and 64 deletions
|
@ -997,31 +997,39 @@ s32 cellGcmMapMainMemory(u32 ea, u32 size, vm::ptr<u32> offset)
|
|||
|
||||
if (!size || (ea & 0xFFFFF) || (size & 0xFFFFF)) return CELL_GCM_ERROR_FAILURE;
|
||||
|
||||
u32 io = RSXIOMem.Map(ea, size);
|
||||
|
||||
const auto render = rsx::get_current_renderer();
|
||||
|
||||
//check if the mapping was successfull
|
||||
if (RSXIOMem.RealAddr(io) == ea)
|
||||
// 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++)
|
||||
{
|
||||
//fill the offset table
|
||||
for (u32 i = 0; i<(size >> 20); i++)
|
||||
if (static_cast<s16>(offsetTable.eaAddress[io]) < 0)
|
||||
{
|
||||
offsetTable.ioAddress[(ea >> 20) + i] = (u16)((io >> 20) + i);
|
||||
offsetTable.eaAddress[(io >> 20) + i] = (u16)((ea >> 20) + i);
|
||||
if (unmap_count >= (size >> 20))
|
||||
{
|
||||
io <<= 20;
|
||||
|
||||
RSXIOMem.Map(ea, size, io);
|
||||
*offset = io;
|
||||
|
||||
io >>= 20, ea >>= 20;
|
||||
|
||||
//fill the offset table
|
||||
for (u32 i = 0; i<(size >> 20); ++i)
|
||||
{
|
||||
offsetTable.ioAddress[ea + i] = io + i;
|
||||
offsetTable.eaAddress[io + i] = ea + i;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
io += unmap_count;
|
||||
unmap_count = 0;
|
||||
}
|
||||
|
||||
*offset = io;
|
||||
}
|
||||
else
|
||||
{
|
||||
cellGcmSys.error("cellGcmMapMainMemory: CELL_GCM_ERROR_NO_IO_PAGE_TABLE");
|
||||
return CELL_GCM_ERROR_NO_IO_PAGE_TABLE;
|
||||
}
|
||||
|
||||
render->main_mem_addr = render->ioAddress;
|
||||
|
||||
return CELL_OK;
|
||||
cellGcmSys.error("cellGcmMapMainMemory: CELL_GCM_ERROR_NO_IO_PAGE_TABLE");
|
||||
return CELL_GCM_ERROR_NO_IO_PAGE_TABLE;
|
||||
}
|
||||
|
||||
s32 cellGcmReserveIoMapSize(u32 size)
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
|
||||
|
||||
#include "Emu/RSX/GCM.h"
|
||||
|
||||
enum
|
||||
|
@ -20,5 +18,7 @@ struct CellGcmOffsetTable
|
|||
vm::bptr<u16> eaAddress;
|
||||
};
|
||||
|
||||
void InitOffsetTable();
|
||||
|
||||
// Auxiliary functions
|
||||
s32 gcmMapEaIoAddress(u32 ea, u32 io, u32 size, bool is_strict);
|
||||
|
|
|
@ -9,16 +9,10 @@
|
|||
#include "sys_event.h"
|
||||
|
||||
|
||||
|
||||
logs::channel sys_rsx("sys_rsx");
|
||||
|
||||
extern u64 get_timebased_time();
|
||||
|
||||
struct SysRsxConfig {
|
||||
be_t<u32> rsx_event_port{ 0 };
|
||||
u32 driverInfo{ 0 };
|
||||
};
|
||||
|
||||
u64 rsxTimeStamp() {
|
||||
return get_timebased_time();
|
||||
}
|
||||
|
|
|
@ -99,6 +99,12 @@ struct RsxDisplayInfo
|
|||
be_t<u32> height;
|
||||
};
|
||||
|
||||
struct SysRsxConfig
|
||||
{
|
||||
be_t<u32> rsx_event_port{ 0 };
|
||||
u32 driverInfo{ 0 };
|
||||
};
|
||||
|
||||
// SysCalls
|
||||
s32 sys_rsx_device_open();
|
||||
s32 sys_rsx_device_close();
|
||||
|
|
|
@ -13,35 +13,7 @@ VirtualMemoryBlock* VirtualMemoryBlock::SetRange(const u32 start, const u32 size
|
|||
|
||||
bool VirtualMemoryBlock::IsInMyRange(const u32 addr, const u32 size)
|
||||
{
|
||||
return addr >= m_range_start && addr + size - 1 <= m_range_start + m_range_size - 1 - GetReservedAmount();
|
||||
}
|
||||
|
||||
u32 VirtualMemoryBlock::Map(u32 realaddr, u32 size)
|
||||
{
|
||||
for (u32 addr = m_range_start; addr <= m_range_start + m_range_size - 1 - GetReservedAmount() - size;)
|
||||
{
|
||||
bool is_good_addr = true;
|
||||
|
||||
// check if address is already mapped
|
||||
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) ||
|
||||
(m_mapped_memory[i].addr >= addr && m_mapped_memory[i].addr < addr + size))
|
||||
{
|
||||
is_good_addr = false;
|
||||
addr = m_mapped_memory[i].addr + m_mapped_memory[i].size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_good_addr) continue;
|
||||
|
||||
m_mapped_memory.emplace_back(addr, realaddr, size);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return addr >= m_range_start && addr + size <= m_range_start + m_range_size - GetReservedAmount();
|
||||
}
|
||||
|
||||
bool VirtualMemoryBlock::Map(u32 realaddr, u32 size, u32 addr)
|
||||
|
@ -117,7 +89,7 @@ bool VirtualMemoryBlock::getRealAddr(u32 addr, u32& result)
|
|||
return false;
|
||||
}
|
||||
|
||||
u32 VirtualMemoryBlock::getMappedAddress(u32 realAddress)
|
||||
s32 VirtualMemoryBlock::getMappedAddress(u32 realAddress)
|
||||
{
|
||||
for (u32 i = 0; i<m_mapped_memory.size(); ++i)
|
||||
{
|
||||
|
@ -127,7 +99,7 @@ u32 VirtualMemoryBlock::getMappedAddress(u32 realAddress)
|
|||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool VirtualMemoryBlock::Reserve(u32 size)
|
||||
|
@ -152,3 +124,13 @@ 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();
|
||||
}
|
||||
|
|
|
@ -51,10 +51,8 @@ public:
|
|||
u32 GetSize() const { return m_range_size; }
|
||||
bool IsInMyRange(const u32 addr, const u32 size);
|
||||
|
||||
// maps real address to virtual address space, returns the mapped address or 0 on failure (if no address is specified the
|
||||
// first mappable space is used)
|
||||
// maps real address to virtual address space
|
||||
bool Map(u32 realaddr, u32 size, u32 addr);
|
||||
u32 Map(u32 realaddr, u32 size);
|
||||
|
||||
// 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);
|
||||
|
@ -71,6 +69,12 @@ public:
|
|||
// 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);
|
||||
|
@ -92,6 +96,6 @@ public:
|
|||
return realAddr;
|
||||
}
|
||||
|
||||
// return the mapped address given a real address, if not mapped return 0
|
||||
u32 getMappedAddress(u32 realAddress);
|
||||
// return the mapped address given a real address, if not mapped return minus one
|
||||
s32 getMappedAddress(u32 realAddress);
|
||||
};
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include "Capture/rsx_capture.h"
|
||||
#include "rsx_methods.h"
|
||||
#include "rsx_utils.h"
|
||||
#include "Emu/Cell/lv2/sys_event.h"
|
||||
#include "Emu/Cell/Modules/cellGcmSys.h"
|
||||
|
||||
#include "Utilities/GSL.h"
|
||||
#include "Utilities/StrUtil.h"
|
||||
|
@ -27,6 +29,8 @@ bool user_asked_for_frame_capture = false;
|
|||
rsx::frame_trace_data frame_debug;
|
||||
rsx::frame_capture_data frame_capture;
|
||||
|
||||
extern CellGcmOffsetTable offsetTable;
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
std::function<bool(u32 addr, bool is_writing)> g_access_violation_handler;
|
||||
|
@ -2332,6 +2336,28 @@ namespace rsx
|
|||
|
||||
void thread::on_notify_memory_unmapped(u32 base_address, u32 size)
|
||||
{
|
||||
{
|
||||
s32 io_addr = RSXIOMem.getMappedAddress(base_address);
|
||||
if (io_addr >= 0)
|
||||
{
|
||||
if (!isHLE)
|
||||
{
|
||||
const u64 unmap_key = u64((1ull << (size >> 20)) - 1) << ((io_addr >> 20) & 0x3f);
|
||||
const u64 gcm_flag = 0x100000000ull << (io_addr >> 26);
|
||||
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;)
|
||||
{
|
||||
offsetTable.ioAddress[base_address++] = 0xFFFF;
|
||||
offsetTable.eaAddress[io_addr++] = 0xFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
writer_lock lock(m_mtx_task);
|
||||
m_invalidated_memory_ranges.push_back({ base_address, size });
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue