From 48726e8fed12f299b4af1dd5cf1e4a365cdd1437 Mon Sep 17 00:00:00 2001 From: elisha464 Date: Sat, 18 Jan 2014 23:36:22 +0200 Subject: [PATCH] More memory mapping functions for libgcm --- rpcs3/Emu/Memory/Memory.cpp | 13 ++ rpcs3/Emu/Memory/MemoryBlock.h | 3 + rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 142 +++++++++++----------- 3 files changed, 90 insertions(+), 68 deletions(-) diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 40622641fe..4188cb3170 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -686,6 +686,19 @@ u64 VirtualMemoryBlock::getRealAddr(u64 addr) return 0; } +u64 VirtualMemoryBlock::getMappedAddress(u64 realAddress) +{ + for(u32 i=0; i= 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 0; +} + void VirtualMemoryBlock::Delete() { m_mapped_memory.Clear(); diff --git a/rpcs3/Emu/Memory/MemoryBlock.h b/rpcs3/Emu/Memory/MemoryBlock.h index ad06f14c33..793af5ca4d 100644 --- a/rpcs3/Emu/Memory/MemoryBlock.h +++ b/rpcs3/Emu/Memory/MemoryBlock.h @@ -259,6 +259,9 @@ public: // return the real address given a mapped address, if not mapped return 0 u64 getRealAddr(u64 addr); + + // return the mapped address given a real address, if not mapped return 0 + u64 getMappedAddress(u64 realAddress); }; #include "DynamicMemoryBlockBase.inl" diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index 1458bd2da2..26776ad67b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -17,16 +17,29 @@ enum CELL_GCM_ERROR_INVALID_ALIGNMENT = 0x80210004, }; +/*------------------------------------------------------------ + Memory Mapping +------------------------------------------------------------*/ + +struct gcm_offset +{ + u64 io; + u64 ea; +}; + +void InitOffsetTable(); +int cellGcmAddressToOffset(u32 address, mem32_t offset); +u32 cellGcmGetMaxIoMapSize(); +void cellGcmGetOffsetTable(mem_ptr_t table); +int32_t cellGcmIoOffsetToAddress(u32 ioOffset, mem_ptr_t address); +int cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size); + + +//------------------------------------------------------------ + CellGcmConfig current_config; CellGcmContextData current_context; gcmInfo gcm_info; -struct gcm_offset -{ - mem_ptr_t io; - mem_ptr_t ea; -}; - -//gcm_offset offsetTable; u32 map_offset_addr = 0; u32 map_offset_pos = 0; @@ -44,26 +57,14 @@ int cellGcmMapMainMemory(u32 address, u32 size, mem32_t offset) return CELL_OK; } -int cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size) -{ - cellGcmSys.Warning("cellGcmMapEaIoAddress(ea=0x%x, io=0x%x, size=0x%x)", ea, io, size); - - if(io % 0x100000 != 0 || size % 0x100000 != 0) return CELL_GCM_ERROR_FAILURE; - - //Memory.Map(io, ea, size); - //Emu.GetGSManager().GetRender().m_ioAddress = io; - Emu.GetGSManager().GetRender().m_report_main_addr = ea; - return CELL_OK; -} - int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress) { cellGcmSys.Warning("cellGcmInit(context_addr=0x%x,cmdSize=0x%x,ioSize=0x%x,ioAddress=0x%x)", context_addr, cmdSize, ioSize, ioAddress); if(!local_size && !local_addr) { - u32 local_size = 0xf900000; //TODO - u32 local_addr = Memory.RSXFBMem.GetStartAddr(); + local_size = 0xf900000; //TODO + local_addr = Memory.RSXFBMem.GetStartAddr(); Memory.RSXFBMem.Alloc(local_size); } @@ -78,9 +79,10 @@ int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress) current_config.memoryFrequency = re32(650000000); current_config.coreFrequency = re32(500000000); + InitOffsetTable(); Memory.RSXCMDMem.Alloc(cmdSize); - Memory.MemoryBlocks.Add(Memory.RSXIOMem.SetRange(0xD0000000, 0x10000000/*256MB*/)); - Memory.RSXIOMem.Map(ioAddress, ioSize); + Memory.MemoryBlocks.Add(Memory.RSXIOMem.SetRange(0xE0000000, 0x10000000/*256MB*/));//TODO: implement allocateAdressSpace in memoryBase + cellGcmMapEaIoAddress(ioAddress, ioSize, 0); u32 ctx_begin = ioAddress/* + 0x1000*/; u32 ctx_size = 0x6ffc; @@ -539,6 +541,23 @@ int cellGcmSetSecondVFrequency (u32 freq) Memory Mapping ------------------------------------------------------------*/ +gcm_offset offsetTable = {0, 0}; + +void InitOffsetTable() +{ + offsetTable.io = Memory.Alloc(3072*sizeof(u16), 1); + for(int i=0; i<3072; i++) + { + Memory.Write16(offsetTable.io + sizeof(u16)*i, 0xFFFF); + } + + offsetTable.ea = Memory.Alloc(256*sizeof(u16), 1);//TODO: check flags + for(int i=0; i<256; i++) + { + Memory.Write16(offsetTable.ea + sizeof(u16)*i, 0xFFFF); + } +} + int cellGcmAddressToOffset(u32 address, mem32_t offset) { cellGcmSys.Log("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset.GetAddr()); @@ -598,47 +617,8 @@ u32 cellGcmGetMaxIoMapSize() void cellGcmGetOffsetTable(mem_ptr_t table) { - static gcm_offset temp = {NULL, NULL}; - - if(!temp.io.IsGood()) - { - u32 mem = Memory.Alloc(sizeof(u16) * 0xBFF, 1); - - for(int i=0; i<0xBFF; i++) - { - Memory.Write16(mem + i*sizeof(u16), 0xFFFF); - } - - temp.io = re(mem); - } - - if(!temp.ea.IsGood()) - { - u32 mem = Memory.Alloc(sizeof(u16) * 511, 1); - - for(int i=0; i<511; i++) - { - Memory.Write16(mem + i*sizeof(u16), 0xFFFF); - } - - temp.ea = re(mem); - } - - *table = temp; - - if(!current_config.localAddress) - { - /*Memory.Write16((table->io), 0xFFFF); - Memory.Write16(table->io + (uint)2, 0xFFFF);*/ - } - - if(!current_config.ioAddress) - { - /*Memory.Write16(table->ea, 0xFFFF); - Memory.Write16(table->ea + (uint)2, 0xFFFF);*/ - } - - UNIMPLEMENTED_FUNC(cellGcmSys); + table->io = re(offsetTable.io); + table->ea = re(offsetTable.ea); } int32_t cellGcmIoOffsetToAddress(u32 ioOffset, mem_ptr_t address) @@ -655,12 +635,38 @@ int32_t cellGcmIoOffsetToAddress(u32 ioOffset, mem_ptr_t address) return CELL_OK; } +int cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size) +{ + 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 + if(Memory.RSXIOMem.Map(ea, size, Memory.RSXIOMem.GetStartAddr() + io)) + { + //fill the offset table + for(int i=0; i address, mem_ptr_t size) { if(!local_size && !local_addr) { - u32 local_size = 0xf900000; //TODO - u32 local_addr = Memory.RSXFBMem.GetStartAddr(); + local_size = 0xf900000; //TODO + local_addr = Memory.RSXFBMem.GetStartAddr(); Memory.RSXFBMem.Alloc(local_size); Memory.Write32(address.GetAddr(), local_addr); Memory.Write32(size.GetAddr(), local_size); @@ -685,7 +691,6 @@ void cellGcmSys_init() cellGcmSys.AddFunc(0x21397818, cellGcmSetFlipCommand); cellGcmSys.AddFunc(0x3a33c1fd, cellGcmFunc15); cellGcmSys.AddFunc(0x4ae8d215, cellGcmSetFlipMode); - cellGcmSys.AddFunc(0x63441cb4, cellGcmMapEaIoAddress); cellGcmSys.AddFunc(0x5e2ee0f0, cellGcmGetDefaultCommandWordSize); cellGcmSys.AddFunc(0x72a577ce, cellGcmGetFlipStatus); cellGcmSys.AddFunc(0x8cdf8c70, cellGcmGetDefaultSegmentWordSize); @@ -725,11 +730,12 @@ void cellGcmSys_init() cellGcmSys.AddFunc(0x4d7ce993, cellGcmSetSecondVFrequency); cellGcmSys.AddFunc(0xdc09357e, cellGcmSetFlip); cellGcmSys.AddFunc(0x983fb9aa, cellGcmSetWaitFlip); - cellGcmSys.AddFunc(0xdb769b32, cellGcmMapLocalMemory); //Memory Mapping cellGcmSys.AddFunc(0x21ac3697, cellGcmAddressToOffset); cellGcmSys.AddFunc(0xfb81c03e, cellGcmGetMaxIoMapSize); cellGcmSys.AddFunc(0x2922aed0, cellGcmGetOffsetTable); cellGcmSys.AddFunc(0x2a6fba9c, cellGcmIoOffsetToAddress); + cellGcmSys.AddFunc(0x63441cb4, cellGcmMapEaIoAddress); + cellGcmSys.AddFunc(0xdb769b32, cellGcmMapLocalMemory); }