diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index 02a3e2958b..c81f3a911c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -12,9 +12,11 @@ u32 local_addr = NULL; enum { CELL_GCM_ERROR_FAILURE = 0x802100ff, + CELL_GCM_ERROR_NO_IO_PAGE_TABLE = 0x80210001, CELL_GCM_ERROR_INVALID_ENUM = 0x80210002, CELL_GCM_ERROR_INVALID_VALUE = 0x80210003, CELL_GCM_ERROR_INVALID_ALIGNMENT = 0x80210004, + CELL_GCM_ERROR_ADDRESS_OVERWRAP = 0x80210005 }; /*------------------------------------------------------------ @@ -28,11 +30,12 @@ struct gcm_offset }; void InitOffsetTable(); -int cellGcmAddressToOffset(u32 address, mem32_t offset); -u32 cellGcmGetMaxIoMapSize(); +int32_t cellGcmAddressToOffset(u64 address, mem32_t offset); +uint32_t 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); +int32_t cellGcmIoOffsetToAddress(u32 ioOffset, u64 address); +int32_t cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size); +int32_t cellGcmMapMainMemory(u64 ea, u32 size, mem32_t offset); //------------------------------------------------------------ @@ -44,19 +47,6 @@ gcmInfo gcm_info; u32 map_offset_addr = 0; u32 map_offset_pos = 0; -int cellGcmMapMainMemory(u32 address, u32 size, mem32_t offset) -{ - cellGcmSys.Warning("cellGcmMapMainMemory(address=0x%x,size=0x%x,offset_addr=0x%x)", address, size, offset.GetAddr()); - if(!offset.IsGood()) return CELL_EFAULT; - - Emu.GetGSManager().GetRender().m_main_mem_addr = Emu.GetGSManager().GetRender().m_ioAddress; - - offset = address - Emu.GetGSManager().GetRender().m_main_mem_addr; - Emu.GetGSManager().GetRender().m_main_mem_info.AddCpy(MemInfo(address, size)); - - 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); @@ -82,7 +72,7 @@ int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress) InitOffsetTable(); Memory.RSXCMDMem.Alloc(cmdSize); Memory.MemoryBlocks.Add(Memory.RSXIOMem.SetRange(0xE0000000, 0x10000000/*256MB*/));//TODO: implement allocateAdressSpace in memoryBase - cellGcmMapEaIoAddress(ioAddress, ioSize, 0); + cellGcmMapEaIoAddress(ioAddress, 0, ioSize); u32 ctx_begin = ioAddress/* + 0x1000*/; u32 ctx_size = 0x6ffc; @@ -596,61 +586,43 @@ void InitOffsetTable() } } -int cellGcmAddressToOffset(u32 address, mem32_t offset) +int32_t cellGcmAddressToOffset(u64 address, mem32_t offset) { - cellGcmSys.Log("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset.GetAddr()); - if(!offset.IsGood()) return CELL_EFAULT; - - if(!map_offset_addr) - { - map_offset_addr = Memory.Alloc(4*50, 4); - } + cellGcmSys.Warning("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset.GetAddr()); - u32 sa; - bool is_main_mem = false; - const auto& main_mem_info = Emu.GetGSManager().GetRender().m_main_mem_info; - for(u32 i=0; i= 0xD0000000/*not on main memory or local*/) + return CELL_GCM_ERROR_FAILURE; + + u32 result; + + // If address is in range of local memory + if(Memory.RSXFBMem.IsInMyRange(address)) { - //main memory - if(address >= main_mem_info[i].addr && address < main_mem_info[i].addr + main_mem_info[i].size) + result = address - Memory.RSXFBMem.GetStartAddr(); + } + // else check if the adress (main memory) is mapped in IO + else + { + u16 upper12Bits = Memory.Read16(offsetTable.io + sizeof(u16)*(address >> 20)); + + if(upper12Bits != 0xFFFF) { - is_main_mem = true; - break; + result = (((u64)upper12Bits << 20) | (address & (0xFFFFF))); + } + // address is not mapped in IO + else + { + return CELL_GCM_ERROR_FAILURE; } } - if(is_main_mem) - { - //main - sa = Emu.GetGSManager().GetRender().m_main_mem_addr; - //ConLog.Warning("cellGcmAddressToOffset: main memory: offset = 0x%x - 0x%x = 0x%x", address, sa, address - sa); - } - else if(Memory.RSXFBMem.IsMyAddress(address)) - { - //local - sa = Emu.GetGSManager().GetRender().m_local_mem_addr; - //ConLog.Warning("cellGcmAddressToOffset: local memory: offset = 0x%x - 0x%x = 0x%x", address, sa, address - sa); - } - else - { - //io - sa = Emu.GetGSManager().GetRender().m_ioAddress; - //ConLog.Warning("cellGcmAddressToOffset: io memory: offset = 0x%x - 0x%x = 0x%x", address, sa, address - sa); - } - - offset = address - sa; - //ConLog.Warning("Address To Offset: 0x%x -> 0x%x", address, address - sa); - //Memory.Write16(map_offset_addr + map_offset_pos + 0, ea); - //Memory.Write16(map_offset_addr + map_offset_pos + 2, offset); - //map_offset_pos += 4; - + offset = result; return CELL_OK; } -u32 cellGcmGetMaxIoMapSize() +uint32_t cellGcmGetMaxIoMapSize() { - UNIMPLEMENTED_FUNC(cellGcmSys); - return 0x10000000;//256MB TODO + return Memory.RSXIOMem.GetEndAddr() - Memory.RSXIOMem.GetStartAddr() - Memory.RSXIOMem.GetResevedAmount(); } void cellGcmGetOffsetTable(mem_ptr_t table) @@ -659,7 +631,7 @@ void cellGcmGetOffsetTable(mem_ptr_t table) table->ea = re(offsetTable.ea); } -int32_t cellGcmIoOffsetToAddress(u32 ioOffset, mem_ptr_t address) +int32_t cellGcmIoOffsetToAddress(u32 ioOffset, u64 address) { u64 realAddr; @@ -673,7 +645,7 @@ int32_t cellGcmIoOffsetToAddress(u32 ioOffset, mem_ptr_t address) return CELL_OK; } -int cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size) +int32_t 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); @@ -683,10 +655,10 @@ int cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size) if(Memory.RSXIOMem.Map(ea, size, Memory.RSXIOMem.GetStartAddr() + io)) { //fill the offset table - for(int i=0; i> 20); i++) { - Memory.Write16(offsetTable.io + ea/(1024*1024) + i, io/(1024*1024) + i); - Memory.Write16(offsetTable.ea + io/(1024*1024) + i, ea/(1024*1024) + i); + Memory.Write16(offsetTable.io + ((ea >> 20) + i)*sizeof(u16), (io >> 20) + i); + Memory.Write16(offsetTable.ea + ((io >> 20) + i)*sizeof(u16), (ea >> 20) + i); } } else @@ -694,20 +666,18 @@ int cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size) return CELL_GCM_ERROR_FAILURE; } - //Emu.GetGSManager().GetRender().m_ioAddress = io; - Emu.GetGSManager().GetRender().m_report_main_addr = ea; return CELL_OK; } -int32_t cellGcmMapLocalMemory(mem_ptr_t address, mem_ptr_t size) +int32_t cellGcmMapLocalMemory(u64 address, u64 size) { if(!local_size && !local_addr) { 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); + Memory.Write32(address, local_addr); + Memory.Write32(size, local_size); } else { @@ -718,6 +688,35 @@ int32_t cellGcmMapLocalMemory(mem_ptr_t address, mem_ptr_t size return CELL_OK; } +int32_t cellGcmMapMainMemory(u64 ea, u32 size, mem32_t offset) +{ + cellGcmSys.Warning("cellGcmMapMainMemory(ea=0x%x,size=0x%x,offset_addr=0x%x)", ea, size, offset.GetAddr()); + + u64 io; + + if((ea & 0xFFFFF) || (size & 0xFFFFF)) return CELL_GCM_ERROR_FAILURE; + + //check if the mapping was successfull + if(io = Memory.RSXIOMem.Map(ea, size, 0)) + { + //fill the offset table + for(u32 i=0; i<(size >> 20); i++) + { + Memory.Write16(offsetTable.io + ((ea >> 20) + i)*sizeof(u16), (io >> 20) + i); + Memory.Write16(offsetTable.ea + ((io >> 20) + i)*sizeof(u16), (ea >> 20) + i); + } + } + else + { + return CELL_GCM_ERROR_NO_IO_PAGE_TABLE; + } + + Emu.GetGSManager().GetRender().m_main_mem_addr = Emu.GetGSManager().GetRender().m_ioAddress; + Emu.GetGSManager().GetRender().m_main_mem_info.AddCpy(MemInfo(ea, size)); + + return CELL_OK; +} + void cellGcmSys_init() { current_config.ioAddress = NULL; @@ -745,7 +744,6 @@ void cellGcmSys_init() cellGcmSys.AddFunc(0xd9b7653e, cellGcmUnbindTile); cellGcmSys.AddFunc(0xa75640e8, cellGcmUnbindZcull); cellGcmSys.AddFunc(0xa41ef7e8, cellGcmSetFlipHandler); - cellGcmSys.AddFunc(0xa114ec67, cellGcmMapMainMemory); cellGcmSys.AddFunc(0xf80196c1, cellGcmGetLabelAddress); cellGcmSys.AddFunc(0x107bf3a1, cellGcmInitCursor); cellGcmSys.AddFunc(0x1a0de550, cellGcmSetCursorPosition); @@ -777,4 +775,5 @@ void cellGcmSys_init() cellGcmSys.AddFunc(0x2a6fba9c, cellGcmIoOffsetToAddress); cellGcmSys.AddFunc(0x63441cb4, cellGcmMapEaIoAddress); cellGcmSys.AddFunc(0xdb769b32, cellGcmMapLocalMemory); + cellGcmSys.AddFunc(0xa114ec67, cellGcmMapMainMemory); } diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp index 55700fd4fc..24c8971206 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp @@ -76,7 +76,7 @@ CCellRescInternal* s_rescInternalInstance = new CCellRescInternal(); // Extern Functions extern int cellGcmSetFlipMode(u32 mode); extern int cellGcmSetFlipHandler(u32 handler_addr); -extern int cellGcmAddressToOffset(u32 address, mem32_t offset); +extern int32_t cellGcmAddressToOffset(u64 address, mem32_t offset); extern int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height); extern int cellGcmSetPrepareFlip(mem_ptr_t ctx, u32 id); extern int cellGcmSetSecondVFrequency(u32 freq);