diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp index 313b91676f..68fb88c772 100644 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -90,7 +90,6 @@ static const g_module_list[] = {0x0050, "cellSpursJq"}, {0x0052, "cellPngEnc"}, {0x0053, "cellMusicDecode2"}, - {0x0054, "cellSync"}, {0x0055, "cellSync2"}, {0x0056, "cellNpUtil"}, {0x0057, "cellRudp"}, diff --git a/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp b/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp index 980d297d53..f97bc3c8d1 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp @@ -186,7 +186,8 @@ struct PamfHeader be_t mux_rate_max; //== 0x01D470 (400 bps per unit, == 48000000 bps) be_t mux_rate_min; //== 0x0107AC (?????) u16 reserved2; // ????? - be_t stream_count; //total stream count + u8 reserved3; + u8 stream_count; //total stream count (reduced to 1 byte) be_t unk1; //== 1 (?????) be_t table_data_size; //== table_size - 0x20 == 0x14 + (0x30 * total_stream_num) (?????) //TODO: check relative offset of stream structs (could be from 0x0c to 0x14, currently 0x14) @@ -245,7 +246,8 @@ int cellPamfGetStreamOffsetAndSize(mem_ptr_t pAddr, u64 fileSize, me cellPamf.Warning("cellPamfGetStreamOffsetAndSize(pAddr=0x%x, fileSize=%d, pOffset_addr=0x%x, pSize_addr=0x%x)", pAddr.GetAddr(), fileSize, pOffset.GetAddr(), pSize.GetAddr()); - pOffset = (u64)pAddr->data_offset << 11; + const u64 size = (u64)pAddr->data_offset << 11; + pOffset = size; pSize = (u64)pAddr->data_size << 11; return CELL_OK; } @@ -327,6 +329,9 @@ int cellPamfReaderGetNumberOfSpecificStreams(mem_ptr_t pSelf, u8 int counts[6] = {0, 0, 0, 0, 0, 0}; + /*if (!pAddr->magic) + return 1; /*hack*/ + for (int i = 0; i < pAddr->stream_count; i++) { switch (pAddr->stream_headers[i].type) @@ -338,6 +343,7 @@ int cellPamfReaderGetNumberOfSpecificStreams(mem_ptr_t pSelf, u8 default: cellPamf.Error("cellPamfReaderGetNumberOfSpecificStreams: unsupported stream type found(0x%x)", pAddr->stream_headers[i].type); + break; } } @@ -356,7 +362,7 @@ int cellPamfReaderGetNumberOfSpecificStreams(mem_ptr_t pSelf, u8 return counts[CELL_PAMF_STREAM_TYPE_ATRAC3PLUS] + counts[CELL_PAMF_STREAM_TYPE_PAMF_LPCM] + counts[CELL_PAMF_STREAM_TYPE_AC3]; default: - return 0; + return 0; } } @@ -394,6 +400,9 @@ int cellPamfReaderSetStreamWithTypeAndIndex(mem_ptr_t pSelf, u8 u32 found = 0; + /*if (!pAddr->magic) + return 0; /*hack*/ + for (int i = 0; i < pAddr->stream_count; i++) { switch (pAddr->stream_headers[i].type) diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index c6e8d163b4..451d61d1cc 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -3,7 +3,7 @@ #include "Emu/SysCalls/SC_FUNC.h" void cellSync_init(); -Module cellSync(0x0054, cellSync_init); +Module cellSync("cellSync", cellSync_init); // Return Codes enum @@ -24,6 +24,7 @@ enum int cellSyncMutexInitialize(mem32_t mutex) { + cellSync.Log("cellSyncMutexInitialize(mutex=0x%x)", mutex.GetAddr()); const u32 mutex_addr = mutex.GetAddr(); if (!mutex_addr) { @@ -34,11 +35,13 @@ int cellSyncMutexInitialize(mem32_t mutex) return CELL_SYNC_ERROR_ALIGN; } mutex = 0; + _mm_sfence(); return CELL_OK; } int cellSyncMutexLock(mem32_t mutex) { + cellSync.Log("cellSyncMutexLock(mutex=0x%x)", mutex.GetAddr()); const u32 mutex_addr = mutex.GetAddr(); if (!mutex_addr) { @@ -48,7 +51,7 @@ int cellSyncMutexLock(mem32_t mutex) { return CELL_SYNC_ERROR_ALIGN; } - while (_InterlockedExchange((volatile long*)Memory.VirtualToRealAddr(mutex_addr), 1 << 24)); + while (_InterlockedExchange((volatile long*)(Memory + mutex_addr), 1 << 24)); //need to check how does SPU work with these mutexes, also obtainment order is not guaranteed _mm_lfence(); return CELL_OK; @@ -56,6 +59,7 @@ int cellSyncMutexLock(mem32_t mutex) int cellSyncMutexTryLock(mem32_t mutex) { + cellSync.Log("cellSyncMutexTryLock(mutex=0x%x)", mutex.GetAddr()); const u32 mutex_addr = mutex.GetAddr(); if (!mutex_addr) { @@ -66,7 +70,7 @@ int cellSyncMutexTryLock(mem32_t mutex) return CELL_SYNC_ERROR_ALIGN; } //check cellSyncMutexLock - if (_InterlockedExchange((volatile long*)Memory.VirtualToRealAddr(mutex_addr), 1 << 24)) + if (_InterlockedExchange((volatile long*)(Memory + mutex_addr), 1 << 24)) { return CELL_SYNC_ERROR_BUSY; } @@ -76,6 +80,7 @@ int cellSyncMutexTryLock(mem32_t mutex) int cellSyncMutexUnlock(mem32_t mutex) { + cellSync.Log("cellSyncMutexUnlock(mutex=0x%x)", mutex.GetAddr()); const u32 mutex_addr = mutex.GetAddr(); if (!mutex_addr) { @@ -87,7 +92,7 @@ int cellSyncMutexUnlock(mem32_t mutex) } //check cellSyncMutexLock _mm_sfence(); - _InterlockedExchange((volatile long*)Memory.VirtualToRealAddr(mutex_addr), 0); + _InterlockedExchange((volatile long*)(Memory + mutex_addr), 0); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index d73bb69ed4..e08e90cae4 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -81,11 +81,12 @@ int sys_spu_image_import(mem_ptr_t img, u32 src, u32 type) } vfsStreamMemory f(src); - u32 entry = LoadSpuImage(f); + u32 entry; + u32 offset = LoadSpuImage(f, entry); - img->type = 1; + img->type = type; img->entry_point = entry; - img->segs_addr = 0x0; + img->segs_addr = offset; img->nsegs = 0; return CELL_OK; @@ -119,15 +120,13 @@ int sys_raw_spu_load(int id, u32 path_addr, mem32_t entry) return CELL_OK; } -extern u64 g_last_spu_offset; - int sys_raw_spu_image_load(int id, mem_ptr_t img) { sysPrxForUser.Warning("sys_raw_spu_image_load(id=0x%x, img_addr=0x%x)", id, img.GetAddr()); - memcpy(Memory + RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id, Memory + g_last_spu_offset, 256 * 1024); + memcpy(Memory + RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id, Memory + (u32)img->segs_addr, 256 * 1024); Memory.Write32(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id + RAW_SPU_PROB_OFFSET + SPU_NPC_offs, - img->entry_point - g_last_spu_offset); + (u32)img->entry_point); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp index 59124cadaf..297335e8e1 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp @@ -135,7 +135,7 @@ int cellFsSdataOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size) return CELL_OK; } -struct CellFsAio +/*struct CellFsAio { be_t fd; be_t offset; @@ -158,6 +158,53 @@ int cellFsAioRead(mem_ptr_t aio, mem32_t id, mem32_t func_addr) callback.Handle(aio.GetAddr(), error, id, *nread); callback.Branch(true); + return CELL_OK; +}*/ + +std::atomic g_FsAioReadID = 0; + +int cellFsAioRead(mem_ptr_t aio, mem32_t aio_id, u32 func_addr) +{ + ID id; + u32 fd = (u32)aio->fd; + if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; + vfsFileBase& orig_file = *(vfsFileBase*)id.m_data; + //open the file again (to prevent access conflicts roughly) + vfsStream& file = vfsLocalFile(orig_file.GetPath().AfterFirst('/'), vfsRead); + + u64 nbytes = (u64)aio->size; + const u32 buf_addr = (u32)aio->buf_addr; + if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes)) + { + MemoryBlock& block = Memory.GetMemByAddr(buf_addr); + nbytes = block.GetSize() - (buf_addr - block.GetStartAddr()); + } + + //read data immediately (actually it should be read in special thread) + file.Seek((u64)aio->offset); + const u64 res = nbytes ? file.Read(Memory.GetMemFromAddr(buf_addr), nbytes) : 0; + file.Close(); + + //get a unique id for the callback + const u32 xid = g_FsAioReadID++; + aio_id = xid; + + sys_fs.Warning("cellFsAioRead(aio_addr: 0x%x[%s], id_addr: 0x%x, func_addr: 0x%x[res=%d, addr=0x%x])", aio.GetAddr(), + orig_file.GetPath().c_str(), aio_id.GetAddr(), func_addr, res, (u32)aio->buf_addr); + + //TODO: init the callback + CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU); + new_thread.SetEntry(func_addr); + new_thread.SetPrio(1001); + new_thread.SetStackSize(0x10000); + new_thread.SetName("FsAioReadCallback"); + new_thread.SetArg(0, aio.GetAddr()); //xaio + new_thread.SetArg(1, CELL_OK); //error code + new_thread.SetArg(2, xid); //xid (unique id) + new_thread.SetArg(3, res); //size (bytes read) + new_thread.Run(); + new_thread.Exec(); + return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp index a99b13a5b7..8e873b7972 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp @@ -385,49 +385,3 @@ int cellFsFGetBlockSize(u32 fd, mem64_t sector_size, mem64_t block_size) return CELL_OK; } - -std::atomic g_FsAioReadID = 0; - -int cellFsAioRead(mem_ptr_t aio, mem32_t aio_id, u32 func_addr) -{ - sys_fs.Warning("cellFsAioRead(aio_addr: 0x%x, id_addr: 0x%x, func_addr: 0x%x)", aio.GetAddr(), aio_id.GetAddr(), func_addr); - - ID id; - u32 fd = (u32)aio->fd; - if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; - vfsFileBase& orig_file = *(vfsFileBase*)id.m_data; - //open the file again (to prevent access conflicts roughly) - vfsStream file = *Emu.GetVFS().Open(orig_file.GetPath(), vfsRead); - - u64 nbytes = (u64)aio->size; - const u32 buf_addr = (u32)aio->buf_addr; - if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes)) - { - MemoryBlock& block = Memory.GetMemByAddr(buf_addr); - nbytes = block.GetSize() - (buf_addr - block.GetStartAddr()); - } - - //read data immediately (actually it should be read in special thread) - file.Seek((u64)aio->offset); - const u64 res = nbytes ? file.Read(Memory.GetMemFromAddr(buf_addr), nbytes) : 0; - file.Close(); - - //get a unique id for the callback - const u32 xid = g_FsAioReadID++; - aio_id = xid; - - //TODO: init the callback - /*CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU); - new_thread.SetEntry(func_addr); - new_thread.SetPrio(1001); - new_thread.SetStackSize(0x10000); - new_thread.SetName("FsAioReadCallback"); - new_thread.SetArg(0, aio.GetAddr()); //xaio - new_thread.SetArg(1, CELL_OK); //error code - new_thread.SetArg(2, xid); //xid (unique id) - new_thread.SetArg(3, res); //size (bytes read) - new_thread.Run(); - new_thread.Exec();*/ - - return CELL_OK; -} diff --git a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp index b66ffbaccb..2f1c27f98c 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp @@ -23,7 +23,17 @@ struct SpuGroupInfo } }; -u64 g_last_spu_offset = 0; +u32 LoadSpuImage(vfsStream& stream, u32& spu_ep) +{ + ELFLoader l(stream); + l.LoadInfo(); + const u32 alloc_size = 256 * 1024 /*0x1000000 - stream.GetSize()*/; + u32 spu_offset = Memory.MainMem.Alloc(alloc_size); + l.LoadData(spu_offset); + spu_ep = l.GetEntry(); + return spu_offset; +} +/*u64 g_last_spu_offset = 0; static const u64 g_spu_alloc_size = 0x1000000; u32 LoadSpuImage(vfsStream& stream, u64 address) @@ -39,7 +49,7 @@ u32 LoadSpuImage(vfsStream& stream) { g_last_spu_offset = Memory.MainMem.Alloc(g_spu_alloc_size); return LoadSpuImage(stream, g_last_spu_offset); -} +}*/ //156 int sys_spu_image_open(mem_ptr_t img, u32 path_addr) @@ -59,11 +69,12 @@ int sys_spu_image_open(mem_ptr_t img, u32 path_addr) return CELL_ENOENT; } - u32 entry = LoadSpuImage(f); + u32 entry; + u32 offset = LoadSpuImage(f, entry); img->type = 1; img->entry_point = entry; - img->segs_addr = 0x0; + img->segs_addr = offset; img->nsegs = 0; return CELL_OK; @@ -102,7 +113,7 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t< return CELL_EBUSY; } - u32 ls_entry = img->entry_point - g_last_spu_offset; + u32 spu_ep = (u32)img->entry_point; std::string name = Memory.ReadString(attr->name_addr, attr->name_len).mb_str(); u64 a1 = arg->arg1; u64 a2 = arg->arg2; @@ -112,10 +123,10 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t< CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_SPU); //copy SPU image: u32 spu_offset = Memory.MainMem.Alloc(256 * 1024); - memcpy(Memory + spu_offset, Memory + g_last_spu_offset, 256 * 1024); + memcpy(Memory + spu_offset, Memory + (u32)img->segs_addr, 256 * 1024); //initialize from new place: new_thread.SetOffset(spu_offset); - new_thread.SetEntry(ls_entry); + new_thread.SetEntry(spu_ep); new_thread.SetName(name); new_thread.SetArg(0, a1); new_thread.SetArg(1, a2); @@ -128,7 +139,8 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t< group_info.threads[spu_num] = &new_thread; ConLog.Write("New SPU Thread:"); - ConLog.Write("ls_entry = 0x%x", ls_entry); + ConLog.Write("SPU img offset = 0x%x", (u32)img->segs_addr); + ConLog.Write("entry_point = 0x%x", spu_ep); ConLog.Write("name = %s", name.c_str()); ConLog.Write("a1 = 0x%x", a1); ConLog.Write("a2 = 0x%x", a2); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.h b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.h index 9c82c6aee9..acac792dc8 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.h +++ b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.h @@ -1,6 +1,6 @@ #pragma once -u32 LoadSpuImage(vfsStream& stream); +u32 LoadSpuImage(vfsStream& stream, u32& spu_ep); enum { @@ -9,6 +9,13 @@ enum SYS_SPU_THREAD_GROUP_JOIN_TERMINATED = 0x0004 }; +enum +{ + SYS_SPU_SEGMENT_TYPE_COPY = 0x0001, + SYS_SPU_SEGMENT_TYPE_FILL = 0x0002, + SYS_SPU_SEGMENT_TYPE_INFO = 0x0004, +}; + struct sys_spu_thread_group_attribute { be_t name_len; @@ -35,8 +42,8 @@ struct sys_spu_thread_argument struct sys_spu_image { be_t type; - be_t entry_point; - be_t segs_addr; + be_t entry_point; + be_t segs_addr; //temporarily used as offset of LS image after elf loading be_t nsegs; };