diff --git a/rpcs3/Emu/RSX/GCM.h b/rpcs3/Emu/RSX/GCM.h index ac37e04a83..b0d16bc667 100644 --- a/rpcs3/Emu/RSX/GCM.h +++ b/rpcs3/Emu/RSX/GCM.h @@ -255,7 +255,7 @@ struct CellGcmReportData { u64 timer; u32 value; - u32 pad; + u32 padding; }; struct CellGcmZcullInfo diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index f7ff06beed..4a19c37968 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -2,6 +2,7 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" +#include "sysPrxForUser.h" //#include "Emu/RSX/GCM.h" #include "Emu/RSX/GSManager.h" @@ -60,6 +61,17 @@ u32 gcmGetLocalMemorySize(u32 sdk_version) return 0x0E000000; // 224MB } +CellGcmOffsetTable offsetTable; + +void InitOffsetTable() +{ + offsetTable.ioAddress = Memory.Alloc(3072 * sizeof(u16), 1); + offsetTable.eaAddress = Memory.Alloc(512 * sizeof(u16), 1); + + _sys_memset(offsetTable.ioAddress, 0xFF, 3072 * sizeof(u16)); + _sys_memset(offsetTable.eaAddress, 0xFF, 512 * sizeof(u16)); +} + //---------------------------------------------------------------------------- // Data Retrieval //---------------------------------------------------------------------------- @@ -112,10 +124,29 @@ int cellGcmGetCurrentField() return CELL_OK; } -int cellGcmGetNotifyDataAddress() +u32 cellGcmGetNotifyDataAddress(u32 index) { - UNIMPLEMENTED_FUNC(cellGcmSys); - return CELL_OK; + cellGcmSys->Warning("cellGcmGetNotifyDataAddress(index=%d)", index); + + // Get address of 'IO table' and 'EA table' + MemoryAllocator table; + cellGcmGetOffsetTable(table.GetAddr()); + + // If entry not in use, return NULL + u16 entry = mem_ptr_t(table->eaAddress)[241]; + if (entry == 0xFFFF) { + return 0; + } + + return (entry << 20) + (index * 0x20); +} + +/* + * Get base address of local report data area + */ +u32 _cellGcmFunc12() +{ + return Memory.RSXFBMem.GetStartAddr(); // TODO } u32 cellGcmGetReport(u32 type, u32 index) @@ -124,10 +155,15 @@ u32 cellGcmGetReport(u32 type, u32 index) if (index >= 2048) { cellGcmSys->Error("cellGcmGetReport: Wrong local index (%d)", index); - return 0; + return -1; } - // TODO: What does the argument type do? - return Memory.Read32(Memory.RSXFBMem.GetStartAddr() + index * 0x10 + 0x8); + + if (type < 1 || type > 5) { + return -1; + } + + mem_ptr_t local_reports = _cellGcmFunc12(); + return local_reports[index].value; } u32 cellGcmGetReportDataAddress(u32 index) @@ -145,25 +181,8 @@ u32 cellGcmGetReportDataLocation(u32 index, u32 location) { cellGcmSys->Warning("cellGcmGetReportDataLocation(index=%d, location=%d)", index, location); - if (location == CELL_GCM_LOCATION_LOCAL) { - if (index >= 2048) { - cellGcmSys->Error("cellGcmGetReportDataLocation: Wrong local index (%d)", index); - return 0; - } - return Memory.Read32(Memory.RSXFBMem.GetStartAddr() + index * 0x10 + 0x8); - } - - if (location == CELL_GCM_LOCATION_MAIN) { - if (index >= 1024*1024) { - cellGcmSys->Error("cellGcmGetReportDataLocation: Wrong main index (%d)", index); - return 0; - } - // TODO: It seems m_report_main_addr is not initialized - return Memory.Read32(Emu.GetGSManager().GetRender().m_report_main_addr + index * 0x10 + 0x8); - } - - cellGcmSys->Error("cellGcmGetReportDataLocation: Wrong location (%d)", location); - return 0; + mem_ptr_t report = cellGcmGetReportDataAddressLocation(index, location); + return report->value; } u64 cellGcmGetTimeStampLocation(u32 index, u32 location) @@ -782,47 +801,30 @@ int cellGcmSortRemapEaIoAddress() //---------------------------------------------------------------------------- // 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); - } -} - s32 cellGcmAddressToOffset(u64 address, mem32_t offset) { cellGcmSys->Log("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset.GetAddr()); - if (address >= 0xD0000000/*not on main memory or local*/) + // Address not on main memory or local memory + if (address >= 0xD0000000) { return CELL_GCM_ERROR_FAILURE; + } u32 result; - // If address is in range of local memory - if (Memory.RSXFBMem.IsInMyRange(address)) - { + // Address in local memory + if (Memory.RSXFBMem.IsInMyRange(address)) { result = address - Memory.RSXFBMem.GetStartAddr(); } - // else check if the adress (main memory) is mapped in IO + // Address in main memory else check else { - u16 upper12Bits = Memory.Read16(offsetTable.io + sizeof(u16)*(address >> 20)); + u16 upper12Bits = Memory.Read16(offsetTable.ioAddress + sizeof(u16)*(address >> 20)); + // If the address is mapped in IO if (upper12Bits != 0xFFFF) { - result = (((u64)upper12Bits << 20) | (address & (0xFFFFF))); + result = ((u64)upper12Bits << 20) | (address & 0xFFFFF); } - // address is not mapped in IO else { return CELL_GCM_ERROR_FAILURE; } @@ -839,12 +841,12 @@ u32 cellGcmGetMaxIoMapSize() return Memory.RSXIOMem.GetEndAddr() - Memory.RSXIOMem.GetStartAddr() - Memory.RSXIOMem.GetReservedAmount(); } -void cellGcmGetOffsetTable(mem_ptr_t table) +void cellGcmGetOffsetTable(mem_ptr_t table) { cellGcmSys->Log("cellGcmGetOffsetTable(table_addr=0x%x)", table.GetAddr()); - table->io = re(offsetTable.io); - table->ea = re(offsetTable.ea); + table->ioAddress = offsetTable.ioAddress; + table->eaAddress = offsetTable.eaAddress; } s32 cellGcmIoOffsetToAddress(u32 ioOffset, u64 address) @@ -867,14 +869,14 @@ s32 cellGcmMapEaIoAddress(u32 ea, u32 io, u32 size) if ((ea & 0xFFFFF) || (io & 0xFFFFF) || (size & 0xFFFFF)) return CELL_GCM_ERROR_FAILURE; - //check if the mapping was successfull + // Check if the mapping was successfull if (Memory.RSXIOMem.Map(ea, size, Memory.RSXIOMem.GetStartAddr() + io)) { - //fill the offset table + // 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); + Memory.Write16(offsetTable.ioAddress + ((ea >> 20) + i)*sizeof(u16), (io >> 20) + i); + Memory.Write16(offsetTable.eaAddress + ((io >> 20) + i)*sizeof(u16), (ea >> 20) + i); } } else @@ -930,8 +932,8 @@ s32 cellGcmMapMainMemory(u64 ea, u32 size, mem32_t offset) //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); + Memory.Write16(offsetTable.ioAddress + ((ea >> 20) + i)*sizeof(u16), (io >> 20) + i); + Memory.Write16(offsetTable.eaAddress + ((io >> 20) + i)*sizeof(u16), (ea >> 20) + i); } offset = io; @@ -976,12 +978,12 @@ s32 cellGcmUnmapEaIoAddress(u64 ea) { u64 io; ea = ea >> 20; - io = Memory.Read16(offsetTable.io + (ea*sizeof(u16))); + io = Memory.Read16(offsetTable.ioAddress + (ea*sizeof(u16))); for (u32 i = 0; i> 20; - ea = Memory.Read16(offsetTable.ea + (io*sizeof(u16))); + ea = Memory.Read16(offsetTable.eaAddress + (io*sizeof(u16))); for (u32 i = 0; iAddFunc(0xc8f3bd09, cellGcmGetCurrentField); cellGcmSys->AddFunc(0xf80196c1, cellGcmGetLabelAddress); cellGcmSys->AddFunc(0x21cee035, cellGcmGetNotifyDataAddress); + cellGcmSys->AddFunc(0x661fe266, _cellGcmFunc12); cellGcmSys->AddFunc(0x99d397ac, cellGcmGetReport); cellGcmSys->AddFunc(0x9a0159af, cellGcmGetReportDataAddress); cellGcmSys->AddFunc(0x8572bce2, cellGcmGetReportDataAddressLocation); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.h b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.h index 0ae68c3451..66b1448a80 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.h +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.h @@ -10,10 +10,10 @@ enum CELL_GCM_ERROR_ADDRESS_OVERWRAP = 0x80210005, }; -struct gcm_offset +struct CellGcmOffsetTable { - u64 io; - u64 ea; + be_t ioAddress; // u16* + be_t eaAddress; // u16* }; // Auxiliary functions @@ -26,7 +26,7 @@ s32 cellGcmSetPrepareFlip(mem_ptr_t ctxt, u32 id); s32 cellGcmAddressToOffset(u64 address, mem32_t offset); u32 cellGcmGetMaxIoMapSize(); -void cellGcmGetOffsetTable(mem_ptr_t table); +void cellGcmGetOffsetTable(mem_ptr_t table); s32 cellGcmIoOffsetToAddress(u32 ioOffset, u64 address); s32 cellGcmMapEaIoAddress(u32 ea, u32 io, u32 size); s32 cellGcmMapEaIoAddressWithFlags(u32 ea, u32 io, u32 size, u32 flags); diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.h b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.h index 3dc3697ce9..527549f990 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.h +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.h @@ -13,3 +13,6 @@ struct HeapInfo { } }; + +// SysCalls +u32 _sys_memset(u32 addr, s32 value, u32 size); diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index 54ce826b74..ec87d6c287 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -99,7 +99,7 @@ static func_caller* sc_table[kSyscallTableLength] = null_func,//bind_func(sys_ppu_thread_start), //53 (0x035) null_func,//bind_func(sys_ppu_...), //54 (0x036) ROOT null_func,//bind_func(sys_ppu_...), //55 (0x037) ROOT - null_func,//bind_func(sys_ppu_thread_rename), //56 (0x038) + bind_func(sys_ppu_thread_rename), //56 (0x038) null_func,//bind_func(sys_ppu_thread_recover_page_fault)//57 (0x039) null_func,//bind_func(sys_ppu_thread_get_page_fault_context),//58 (0x03A) null_func, //59 (0x03B) UNS diff --git a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp index 496725d203..d036beea57 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp @@ -211,10 +211,23 @@ void sys_ppu_thread_once(mem_ptr_t>> once_ctrl, u32 entry) } } -s32 sys_ppu_thread_get_id(const u32 id_addr) +s32 sys_ppu_thread_get_id(mem64_t thread_id) { - sys_ppu_thread.Log("sys_ppu_thread_get_id(id_addr=0x%x)", id_addr); + sys_ppu_thread.Log("sys_ppu_thread_get_id(thread_id_addr=0x%x)", thread_id.GetAddr()); - Memory.Write64(id_addr, GetCurrentPPUThread().GetId()); + thread_id = GetCurrentPPUThread().GetId(); + return CELL_OK; +} + +s32 sys_ppu_thread_rename(u64 thread_id, u32 name_addr) +{ + sys_ppu_thread.Log("sys_ppu_thread_rename(thread_id=%d, name_addr=0x%x)", thread_id, name_addr); + + CPUThread* thr = Emu.GetCPU().GetThread(thread_id); + if (!thr) { + return CELL_ESRCH; + } + + thr->SetThreadName(Memory.ReadString(name_addr)); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h index 7918118e99..ef1be8cc49 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h @@ -26,4 +26,5 @@ s32 sys_ppu_thread_stop(u64 thread_id); s32 sys_ppu_thread_restart(u64 thread_id); s32 sys_ppu_thread_create(mem64_t thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, u32 threadname_addr); void sys_ppu_thread_once(mem_ptr_t>> once_ctrl, u32 entry); -s32 sys_ppu_thread_get_id(const u32 id_addr); +s32 sys_ppu_thread_get_id(mem64_t thread_id); +s32 sys_ppu_thread_rename(u64 thread_id, u32 name_addr); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_rsx.cpp b/rpcs3/Emu/SysCalls/lv2/sys_rsx.cpp index 7ffba5fd2c..a8bdcf76e5 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_rsx.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_rsx.cpp @@ -48,7 +48,7 @@ s32 sys_rsx_memory_free(u32 mem_handle) /* * lv2 SysCall 670 (0x29E): sys_rsx_context_allocate - * @param context_id (OUT): RSX_context, E.g. 0x55555555 (in vsh.self) + * @param context_id (OUT): RSX context, E.g. 0x55555555 (in vsh.self) * @param lpar_dma_control (OUT): Control register area. E.g. 0x60100000 (in vsh.self) * @param lpar_driver_info (OUT): RSX data like frequencies, sizes, version... E.g. 0x60200000 (in vsh.self) * @param lpar_reports (OUT): Report data area. E.g. 0x60300000 (in vsh.self) @@ -65,7 +65,7 @@ s32 sys_rsx_context_allocate(mem32_t context_id, mem32_t lpar_dma_control, mem32 /* * lv2 SysCall 671 (0x29F): sys_rsx_context_free - * @param a1 (IN): RSX_context generated by sys_rsx_context_allocate to free the context. + * @param context_id (IN): RSX context generated by sys_rsx_context_allocate to free the context. */ s32 sys_rsx_context_free(u32 context_id) { @@ -73,15 +73,32 @@ s32 sys_rsx_context_free(u32 context_id) return CELL_OK; } -s32 sys_rsx_context_iomap() +/* + * lv2 SysCall 672 (0x2A0): sys_rsx_context_iomap + * @param context_id (IN): RSX context, E.g. 0x55555555 (in vsh.self) + * @param io (IN): IO offset mapping area. E.g. 0x00600000 + * @param ea (IN): Start address of mapping area. E.g. 0x20400000 + * @param size (IN): Size of mapping area in bytes. E.g. 0x00200000 + * @param flags (IN): + */ +s32 sys_rsx_context_iomap(u32 context_id, u32 io, u32 ea, u32 size, u64 flags) { - sys_rsx.Todo("sys_rsx_context_iomap()"); + sys_rsx.Todo("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); return CELL_OK; } -s32 sys_rsx_context_iounmap() +/* + * lv2 SysCall 673 (0x2A1): sys_rsx_context_iounmap + * @param context_id (IN): RSX context, E.g. 0x55555555 (in vsh.self) + * @param a2 (IN): ? + * @param io_addr (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 a2, u32 io_addr, u32 size) { - sys_rsx.Todo("sys_rsx_context_iounmap()"); + sys_rsx.Todo("sys_rsx_context_iounmap(context_id=0x%x, a2=0x%x, io_addr=0x%x, size=0x%x)", + context_id, a2, io_addr, size); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_rsx.h b/rpcs3/Emu/SysCalls/lv2/sys_rsx.h index 995aa29952..cba4e38c0c 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_rsx.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_rsx.h @@ -7,8 +7,8 @@ s32 sys_rsx_memory_allocate(mem32_t mem_handle, mem32_t mem_addr, u32 size, u64 s32 sys_rsx_memory_free(u32 mem_handle); s32 sys_rsx_context_allocate(mem32_t context_id, mem32_t lpar_dma_control, mem32_t lpar_driver_info, mem32_t lpar_reports, u64 mem_ctx, u64 system_mode); s32 sys_rsx_context_free(u32 context_id); -s32 sys_rsx_context_iomap(); -s32 sys_rsx_context_iounmap(); +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 a2, u32 io_addr, 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(mem32_t a1, mem32_t a2, u32 dev_id); s32 sys_rsx_device_unmap(u32 dev_id); diff --git a/rpcs3/rpcs3.cpp b/rpcs3/rpcs3.cpp index 222b8c8bb9..9aeb33c2f4 100644 --- a/rpcs3/rpcs3.cpp +++ b/rpcs3/rpcs3.cpp @@ -21,6 +21,7 @@ #endif #include "Gui/GLGSFrame.h" +#include #ifdef _WIN32 #include @@ -117,10 +118,13 @@ bool Rpcs3App::OnInit() SetAppName(_PRGNAME_); wxInitAllImageHandlers(); + // RPCS3 assumes the current working directory is the folder where it is contained, so we make sure this is true + const wxString executablePath = wxStandardPaths::Get().GetExecutablePath(); + wxSetWorkingDirectory(wxPathOnly(executablePath)); + main_thread = std::this_thread::get_id(); Ini.Load(); - m_MainFrame = new MainFrame(); SetTopWindow(m_MainFrame); Emu.Init();