mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-23 03:02:53 +01:00
RSXIO memory mapping with strict ordering (draft)
This commit is contained in:
parent
266c3d4753
commit
1dac13be16
@ -3,6 +3,7 @@
|
||||
#include "Utilities/Log.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/RSX/GSManager.h"
|
||||
#include "RSXThread.h"
|
||||
|
||||
#include "Emu/SysCalls/Callback.h"
|
||||
@ -45,15 +46,40 @@ void RSXThread::nativeRescale(float width, float height)
|
||||
|
||||
u32 GetAddress(u32 offset, u32 location)
|
||||
{
|
||||
u32 res = 0;
|
||||
|
||||
switch(location)
|
||||
{
|
||||
case CELL_GCM_LOCATION_LOCAL: return (u32)Memory.RSXFBMem.GetStartAddr() + offset;
|
||||
case CELL_GCM_LOCATION_MAIN: return (u32)Memory.RSXIOMem.RealAddr(offset); // TODO: Error Check?
|
||||
case CELL_GCM_LOCATION_LOCAL:
|
||||
{
|
||||
res = (u32)Memory.RSXFBMem.GetStartAddr() + offset;
|
||||
break;
|
||||
}
|
||||
case CELL_GCM_LOCATION_MAIN:
|
||||
{
|
||||
res = (u32)Memory.RSXIOMem.RealAddr(offset); // TODO: Error Check?
|
||||
if (res == 0)
|
||||
{
|
||||
LOG_ERROR(RSX, "GetAddress(offset=0x%x): RSXIO memory not mapped", offset);
|
||||
Emu.Pause();
|
||||
break;
|
||||
}
|
||||
|
||||
if (Emu.GetGSManager().GetRender().m_strict_ordering[offset >> 20])
|
||||
{
|
||||
_mm_mfence(); // probably doesn't have any effect on current implementation
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
LOG_ERROR(RSX, "GetAddress(offset=0x%x, location=0x%x): invalid location", offset, location);
|
||||
Emu.Pause();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_ERROR(RSX, "GetAddress(offset=0x%x, location=0x%x)", location);
|
||||
assert(0);
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
RSXVertexData::RSXVertexData()
|
||||
|
@ -134,6 +134,7 @@ public:
|
||||
u32 m_report_main_addr;
|
||||
|
||||
u32 m_local_mem_addr, m_main_mem_addr;
|
||||
bool m_strict_ordering[0x1000];
|
||||
|
||||
public:
|
||||
uint m_draw_mode;
|
||||
|
@ -61,11 +61,11 @@ CellGcmOffsetTable offsetTable;
|
||||
|
||||
void InitOffsetTable()
|
||||
{
|
||||
offsetTable.ioAddress = (u32)Memory.Alloc(3072 * sizeof(u16), 1);
|
||||
offsetTable.eaAddress = (u32)Memory.Alloc(512 * sizeof(u16), 1);
|
||||
offsetTable.ioAddress.set(be_t<u32>::make((u32)Memory.Alloc(3072 * sizeof(u16), 1)));
|
||||
offsetTable.eaAddress.set(be_t<u32>::make((u32)Memory.Alloc(512 * sizeof(u16), 1)));
|
||||
|
||||
memset(vm::get_ptr<void>(offsetTable.ioAddress), 0xFF, 3072 * sizeof(u16));
|
||||
memset(vm::get_ptr<void>(offsetTable.eaAddress), 0xFF, 512 * sizeof(u16));
|
||||
memset(offsetTable.ioAddress.get_ptr(), 0xFF, 3072 * sizeof(u16));
|
||||
memset(offsetTable.eaAddress.get_ptr(), 0xFF, 512 * sizeof(u16));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@ -129,7 +129,7 @@ u32 cellGcmGetNotifyDataAddress(u32 index)
|
||||
cellGcmGetOffsetTable(table);
|
||||
|
||||
// If entry not in use, return NULL
|
||||
u16 entry = vm::read16(table->eaAddress + 241 * sizeof(u16));
|
||||
u16 entry = table->eaAddress[241];
|
||||
if (entry == 0xFFFF) {
|
||||
return 0;
|
||||
}
|
||||
@ -814,7 +814,7 @@ s32 cellGcmAddressToOffset(u64 address, vm::ptr<be_t<u32>> offset)
|
||||
// Address in main memory else check
|
||||
else
|
||||
{
|
||||
u16 upper12Bits = vm::read16(offsetTable.ioAddress + sizeof(u16)*(address >> 20));
|
||||
u16 upper12Bits = offsetTable.ioAddress[address >> 20];
|
||||
|
||||
// If the address is mapped in IO
|
||||
if (upper12Bits != 0xFFFF) {
|
||||
@ -858,10 +858,8 @@ s32 cellGcmIoOffsetToAddress(u32 ioOffset, u64 address)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellGcmMapEaIoAddress(u32 ea, u32 io, u32 size)
|
||||
s32 gcmMapEaIoAddress(u32 ea, u32 io, u32 size, bool is_strict)
|
||||
{
|
||||
cellGcmSys->Warning("cellGcmMapEaIoAddress(ea=0x%x, io=0x%x, size=0x%x)", ea, io, size);
|
||||
|
||||
if ((ea & 0xFFFFF) || (io & 0xFFFFF) || (size & 0xFFFFF)) return CELL_GCM_ERROR_FAILURE;
|
||||
|
||||
// Check if the mapping was successfull
|
||||
@ -870,8 +868,9 @@ s32 cellGcmMapEaIoAddress(u32 ea, u32 io, u32 size)
|
||||
// Fill the offset table
|
||||
for (u32 i = 0; i<(size >> 20); i++)
|
||||
{
|
||||
vm::write16(offsetTable.ioAddress + ((ea >> 20) + i)*sizeof(u16), (io >> 20) + i);
|
||||
vm::write16(offsetTable.eaAddress + ((io >> 20) + i)*sizeof(u16), (ea >> 20) + i);
|
||||
offsetTable.ioAddress[(ea >> 20) + i] = (io >> 20) + i;
|
||||
offsetTable.eaAddress[(io >> 20) + i] = (ea >> 20) + i;
|
||||
Emu.GetGSManager().GetRender().m_strict_ordering[(io >> 20) + i] = is_strict;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -883,10 +882,20 @@ s32 cellGcmMapEaIoAddress(u32 ea, u32 io, u32 size)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellGcmMapEaIoAddress(u32 ea, u32 io, u32 size)
|
||||
{
|
||||
cellGcmSys->Warning("cellGcmMapEaIoAddress(ea=0x%x, io=0x%x, size=0x%x)", ea, io, size);
|
||||
|
||||
return gcmMapEaIoAddress(ea, io, size, false);
|
||||
}
|
||||
|
||||
s32 cellGcmMapEaIoAddressWithFlags(u32 ea, u32 io, u32 size, u32 flags)
|
||||
{
|
||||
cellGcmSys->Warning("cellGcmMapEaIoAddressWithFlags(ea=0x%x, io=0x%x, size=0x%x, flags=0x%x)", ea, io, size, flags);
|
||||
return cellGcmMapEaIoAddress(ea, io, size); // TODO: strict ordering
|
||||
|
||||
assert(flags == 2 /*CELL_GCM_IOMAP_FLAG_STRICT_ORDERING*/);
|
||||
|
||||
return gcmMapEaIoAddress(ea, io, size, true);
|
||||
}
|
||||
|
||||
s32 cellGcmMapLocalMemory(u64 address, u64 size)
|
||||
@ -919,13 +928,14 @@ s32 cellGcmMapMainMemory(u32 ea, u32 size, vm::ptr<be_t<u32>> offset)
|
||||
u32 io = Memory.RSXIOMem.Map(ea, size);
|
||||
|
||||
//check if the mapping was successfull
|
||||
if (Memory.RSXIOMem.Write32(io, 0))
|
||||
if (Memory.RSXIOMem.RealAddr(io) == ea)
|
||||
{
|
||||
//fill the offset table
|
||||
for (u32 i = 0; i<(size >> 20); i++)
|
||||
{
|
||||
vm::write16(offsetTable.ioAddress + ((ea >> 20) + i) * sizeof(u16), (u16)(io >> 20) + i);
|
||||
vm::write16(offsetTable.eaAddress + ((io >> 20) + i) * sizeof(u16), (u16)(ea >> 20) + i);
|
||||
offsetTable.ioAddress[(ea >> 20) + i] = (u16)(io >> 20) + i;
|
||||
offsetTable.eaAddress[(io >> 20) + i] = (u16)(ea >> 20) + i;
|
||||
Emu.GetGSManager().GetRender().m_strict_ordering[(io >> 20) + i] = false;
|
||||
}
|
||||
|
||||
*offset = io;
|
||||
@ -970,12 +980,12 @@ s32 cellGcmUnmapEaIoAddress(u64 ea)
|
||||
{
|
||||
u64 io;
|
||||
ea = ea >> 20;
|
||||
io = vm::read16(offsetTable.ioAddress + (ea*sizeof(u16)));
|
||||
io = offsetTable.ioAddress[ea];
|
||||
|
||||
for (u32 i = 0; i<size; i++)
|
||||
{
|
||||
vm::write16(offsetTable.ioAddress + ((ea + i)*sizeof(u16)), 0xFFFF);
|
||||
vm::write16(offsetTable.eaAddress + ((io + i)*sizeof(u16)), 0xFFFF);
|
||||
offsetTable.ioAddress[ea + i] = 0xFFFF;
|
||||
offsetTable.eaAddress[io + i] = 0xFFFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -996,12 +1006,12 @@ s32 cellGcmUnmapIoAddress(u64 io)
|
||||
{
|
||||
u64 ea;
|
||||
io = io >> 20;
|
||||
ea = vm::read16(offsetTable.eaAddress + (io*sizeof(u16)));
|
||||
ea = offsetTable.eaAddress[io];
|
||||
|
||||
for (u32 i = 0; i<size; i++)
|
||||
{
|
||||
vm::write16(offsetTable.ioAddress + ((ea + i)*sizeof(u16)), 0xFFFF);
|
||||
vm::write16(offsetTable.eaAddress + ((io + i)*sizeof(u16)), 0xFFFF);
|
||||
offsetTable.ioAddress[ea + i] = 0xFFFF;
|
||||
offsetTable.eaAddress[io + i] = 0xFFFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -12,8 +12,8 @@ enum
|
||||
|
||||
struct CellGcmOffsetTable
|
||||
{
|
||||
be_t<u32> ioAddress; // u16*
|
||||
be_t<u32> eaAddress; // u16*
|
||||
vm::bptr<u16> ioAddress;
|
||||
vm::bptr<u16> eaAddress;
|
||||
};
|
||||
|
||||
// Auxiliary functions
|
||||
|
@ -34,7 +34,7 @@ void sys_ppu_thread_exit(PPUThread& CPU, u64 errorcode)
|
||||
|
||||
void sys_internal_ppu_thread_exit(PPUThread& CPU, u64 errorcode)
|
||||
{
|
||||
sys_ppu_thread.Log("sys_internal_ppu_thread_exit(0x%llx)", errorcode);
|
||||
sys_ppu_thread.Warning("sys_internal_ppu_thread_exit(0x%llx)", errorcode);
|
||||
|
||||
ppu_thread_exit(CPU, errorcode);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user