From 5f06f46f3284e58f8d59e28afa31ae4d33bd9e87 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sun, 5 Jan 2014 03:58:03 +0400 Subject: [PATCH] Minor improvements cellFsAioRead partially implemented, cellPadInfoPressMode & cellPadInfoSensorMode stubs --- rpcs3/Emu/Cell/SPUThread.h | 52 ++++++++------------ rpcs3/Emu/SysCalls/Modules/cellSync.cpp | 10 ++-- rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp | 4 +- rpcs3/Emu/SysCalls/Modules/sys_fs.cpp | 2 + rpcs3/Emu/SysCalls/Modules/sys_io.cpp | 2 + rpcs3/Emu/SysCalls/SysCalls.h | 3 ++ rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp | 48 +++++++++++++++++- rpcs3/Emu/SysCalls/lv2/SC_FileSystem.h | 9 ++++ rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp | 12 +++++ rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp | 6 +-- 10 files changed, 106 insertions(+), 42 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index d881fc580c..7dd9b2d636 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -293,7 +293,7 @@ public: }; volatile u64 m_indval; }; - volatile long m_lock; + wxCriticalSection m_lock; public: @@ -305,24 +305,19 @@ public: void Init() { m_index = 0; - m_lock = 0; //simple lock } __forceinline bool Pop(u32& res) { if (max_count > 1 || x86) { - while (_InterlockedExchange(&m_lock, 1)); - _mm_lfence(); + wxCriticalSectionLocker lock(m_lock); if(!m_index) { - m_lock = 0; //release lock return false; } res = m_value[--m_index]; m_value[m_index] = 0; - _mm_sfence(); - m_lock = 0; return true; } else @@ -342,16 +337,12 @@ public: { if (max_count > 1 || x86) { - while (_InterlockedExchange(&m_lock, 1)); - _mm_lfence(); + wxCriticalSectionLocker lock(m_lock); if(m_index >= max_count) { - m_lock = 0; //release lock return false; } m_value[m_index++] = value; - _mm_sfence(); - m_lock = 0; return true; } else @@ -370,14 +361,11 @@ public: { if (max_count > 1 || x86) { - while (_InterlockedExchange(&m_lock, 1)); - _mm_lfence(); + wxCriticalSectionLocker lock(m_lock); if(m_index >= max_count) m_value[max_count-1] = value; //last message is overwritten else m_value[m_index++] = value; - _mm_sfence(); - m_lock = 0; } else { //lock-free @@ -389,14 +377,11 @@ public: { if (max_count > 1 || x86) { - while (_InterlockedExchange(&m_lock, 1)); - _mm_lfence(); + wxCriticalSectionLocker lock(m_lock); if(m_index >= max_count) m_value[max_count-1] |= value; //last message is logically ORed else m_value[m_index++] = value; - _mm_sfence(); - m_lock = 0; } else { @@ -412,8 +397,7 @@ public: { if (max_count > 1 || x86) { - while (_InterlockedExchange(&m_lock, 1)); - _mm_lfence(); + wxCriticalSectionLocker lock(m_lock); if(!m_index) res = 0; //result is undefined else @@ -421,8 +405,6 @@ public: res = m_value[--m_index]; m_value[m_index] = 0; } - _mm_sfence(); - m_lock = 0; } else { //lock-free @@ -436,24 +418,30 @@ public: } } - u32 GetCount() const + __forceinline u32 GetCount() { if (max_count > 1 || x86) { - while (m_lock); - _mm_lfence(); + wxCriticalSectionLocker lock(m_lock); + return m_index; + } + else + { + return m_index; } - return m_index; } - u32 GetFreeCount() const + __forceinline u32 GetFreeCount() { if (max_count > 1 || x86) { - while (m_lock); - _mm_lfence(); + wxCriticalSectionLocker lock(m_lock); + return max_count - m_index; + } + else + { + return max_count - m_index; } - return max_count - m_index; } void SetValue(u32 value) diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index 60ef2d3249..c6e8d163b4 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -48,8 +48,8 @@ int cellSyncMutexLock(mem32_t mutex) { return CELL_SYNC_ERROR_ALIGN; } - //aggressive spin-wait - while (_InterlockedExchange((volatile long*)(Memory + mutex_addr), 1)); + while (_InterlockedExchange((volatile long*)Memory.VirtualToRealAddr(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; } @@ -65,7 +65,8 @@ int cellSyncMutexTryLock(mem32_t mutex) { return CELL_SYNC_ERROR_ALIGN; } - if (_InterlockedExchange((volatile long*)(Memory + mutex_addr), 1)) + //check cellSyncMutexLock + if (_InterlockedExchange((volatile long*)Memory.VirtualToRealAddr(mutex_addr), 1 << 24)) { return CELL_SYNC_ERROR_BUSY; } @@ -84,8 +85,9 @@ int cellSyncMutexUnlock(mem32_t mutex) { return CELL_SYNC_ERROR_ALIGN; } + //check cellSyncMutexLock _mm_sfence(); - mutex = 0; + _InterlockedExchange((volatile long*)Memory.VirtualToRealAddr(mutex_addr), 0); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index 8973d05665..d73bb69ed4 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -101,12 +101,12 @@ int sys_raw_spu_load(int id, u32 path_addr, mem32_t entry) { const wxString path = Memory.ReadString(path_addr).mb_str(); sysPrxForUser.Warning("sys_raw_spu_load(id=0x%x, path=0x%x [%s], entry_addr=0x%x)", - id, path_addr, path, entry.GetAddr()); + id, path_addr, path.c_str(), entry.GetAddr()); vfsFile f(path.c_str()); if(!f.IsOpened()) { - sysPrxForUser.Error("sys_raw_spu_load error: '%s' not found!", path); + sysPrxForUser.Error("sys_raw_spu_load error: '%s' not found!", path.c_str()); return CELL_ENOENT; } diff --git a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp index 45242c6bb1..d904646a77 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp @@ -155,4 +155,6 @@ void sys_fs_init() sys_fs.AddFunc(0x0e2939e5, cellFsFtruncate); sys_fs.AddFunc(0xc9dc3ac5, cellFsTruncate); sys_fs.AddFunc(0xcb588dba, cellFsFGetBlockSize); + + sys_fs.AddFunc(0xc1c507e7, cellFsAioRead); } diff --git a/rpcs3/Emu/SysCalls/Modules/sys_io.cpp b/rpcs3/Emu/SysCalls/Modules/sys_io.cpp index 9485b6f440..e470dee958 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_io.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_io.cpp @@ -16,6 +16,8 @@ void sys_io_init() sys_io.AddFunc(0x3aaad464, cellPadGetInfo); sys_io.AddFunc(0xa703a51d, cellPadGetInfo2); sys_io.AddFunc(0x578e3c98, cellPadSetPortSetting); + sys_io.AddFunc(0x0e2dfaad, cellPadInfoPressMode); + sys_io.AddFunc(0x78200559, cellPadInfoSensorMode); sys_io.AddFunc(0x433f6ec0, cellKbInit); sys_io.AddFunc(0xbfce3285, cellKbEnd); diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index d41dcaf3d7..d9d1eab390 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -225,6 +225,7 @@ extern int cellFsLseek(u32 fd, s64 offset, u32 whence, mem64_t pos); extern int cellFsFtruncate(u32 fd, u64 size); extern int cellFsTruncate(u32 path_addr, u64 size); extern int cellFsFGetBlockSize(u32 fd, mem64_t sector_size, mem64_t block_size); +extern int cellFsAioRead(mem_ptr_t aio, mem32_t id, u32 func_addr); //cellVideo extern int cellVideoOutGetState(u32 videoOut, u32 deviceIndex, u32 state_addr); @@ -244,6 +245,8 @@ extern int cellPadSetActDirect(u32 port_no, u32 param_addr); extern int cellPadGetInfo(u32 info_addr); extern int cellPadGetInfo2(u32 info_addr); extern int cellPadSetPortSetting(u32 port_no, u32 port_setting); +extern int cellPadInfoPressMode(u32 port_no); +extern int cellPadInfoSensorMode(u32 port_no); //cellKb extern int cellKbInit(u32 max_connect); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp index 21f39d886d..d75b301678 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp @@ -177,7 +177,7 @@ int cellFsClosedir(u32 fd) int cellFsStat(const u32 path_addr, mem_ptr_t sb) { const wxString& path = Memory.ReadString(path_addr); - sys_fs.Log("cellFsFstat(path: %s, sb_addr: 0x%x)", path.mb_str(), sb.GetAddr()); + sys_fs.Log("cellFsStat(path: %s, sb_addr: 0x%x)", path.mb_str(), sb.GetAddr()); sb->st_mode = CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR | @@ -373,3 +373,49 @@ 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_FileSystem.h b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.h index 1ed8d84a01..58e0af41f8 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.h +++ b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.h @@ -84,3 +84,12 @@ struct CellFsDirent }; #pragma pack() + +struct CellFsAio +{ + be_t fd; + be_t offset; + be_t buf_addr; + be_t size; + be_t user_data; +}; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp index 087c0bff67..e7e1bed3d0 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp @@ -221,3 +221,15 @@ int cellPadSetPortSetting(u32 port_no, u32 port_setting) return CELL_OK; } + +int cellPadInfoPressMode(u32 port_no) +{ + sys_io.Log("cellPadInfoPressMode(port_no=%d)", port_no); + return CELL_OK; +} + +int cellPadInfoSensorMode(u32 port_no) +{ + sys_io.Log("cellPadInfoSensorMode(port_no=%d)", port_no); + return CELL_OK; +} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp index a74f7cfe69..f0de6b262e 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp @@ -40,7 +40,7 @@ u32 LoadSpuImage(vfsStream& stream) int sys_spu_image_open(mem_ptr_t img, u32 path_addr) { const wxString path = Memory.ReadString(path_addr).mb_str(); - sc_spu.Warning("sys_spu_image_open(img_addr=0x%x, path_addr=0x%x [%s])", img.GetAddr(), path_addr, path); + sc_spu.Warning("sys_spu_image_open(img_addr=0x%x, path_addr=0x%x [%s])", img.GetAddr(), path_addr, path.c_str()); if(!img.IsGood() || !Memory.IsGoodAddr(path_addr)) { @@ -124,7 +124,7 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t< ConLog.Write("New SPU Thread:"); ConLog.Write("ls_entry = 0x%x", ls_entry); - ConLog.Write("name = %s", wxString(name)); + ConLog.Write("name = %s", name.c_str()); ConLog.Write("a1 = 0x%x", a1); ConLog.Write("a2 = 0x%x", a2); ConLog.Write("a3 = 0x%x", a3); @@ -224,7 +224,7 @@ int sys_spu_thread_group_create(mem32_t id, u32 num, int prio, mem_ptr_toption.ct.ToLE()); const wxString name = Memory.ReadString(attr->name_addr, attr->name_len).mb_str(); - ConLog.Write("*** name='%s'", name); + ConLog.Write("*** name='%s'", name.c_str()); id = Emu.GetIdManager().GetNewID(wxString::Format("sys_spu_thread_group '%s'", name), new SpuGroupInfo(*attr));