diff --git a/Utilities/rFile.cpp b/Utilities/rFile.cpp index 39fa91eceb..88db8ad28e 100644 --- a/Utilities/rFile.cpp +++ b/Utilities/rFile.cpp @@ -125,10 +125,15 @@ bool rRename(const std::string &from, const std::string &to) { // TODO: Deal with case-sensitivity #ifdef _WIN32 - return (MoveFile(ConvertUTF8ToWString(from).c_str(), ConvertUTF8ToWString(to).c_str()) == TRUE); + if (!MoveFile(ConvertUTF8ToWString(from).c_str(), ConvertUTF8ToWString(to).c_str())) #else - return (0 == rename(from.c_str(), to.c_str())); + if (rename(from.c_str(), to.c_str())) #endif + { + LOG_ERROR(GENERAL, "Error renaming '%s' to '%s': 0x%llx", from.c_str(), to.c_str(), (u64)GET_API_ERROR); + return false; + } + return true; } bool rExists(const std::string &file) diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index 51d3028060..9710b85c5d 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -65,28 +65,14 @@ void CPUThread::DumpInformation() case CPU_THREAD_PPU: { - if ((u32)syscall == syscall) + if (syscall) { - if (syscall) - { - if (syscall < 1024) - { - // TODO: - //return SysCalls::GetSyscallName((u32)syscall); - return "unknown syscall"; - } - else - { - return SysCalls::GetHLEFuncName((u32)syscall); - } - } - else - { - return{}; - } + return SysCalls::GetFuncName(syscall); + } + else + { + return{}; } - - return "unknown function"; } case CPU_THREAD_SPU: diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 49a8727ea3..412937419e 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -141,8 +141,6 @@ void PPUThread::DoStop() m_dec = nullptr; } -bool dump_enable = false; - bool FPRdouble::IsINF(PPCdouble d) { return ((u64&)d & 0x7FFFFFFFFFFFFFFFULL) == 0x7FF0000000000000ULL; diff --git a/rpcs3/Emu/FS/VFS.cpp b/rpcs3/Emu/FS/VFS.cpp index 6af15b1f47..a44003e460 100644 --- a/rpcs3/Emu/FS/VFS.cpp +++ b/rpcs3/Emu/FS/VFS.cpp @@ -259,14 +259,18 @@ bool VFS::ExistsDir(const std::string& ps3_path) const bool VFS::RenameFile(const std::string& ps3_path_from, const std::string& ps3_path_to) const { - std::string path; - if (vfsDevice* dev = GetDevice(ps3_path_from, path)) - { - std::shared_ptr res(dev->GetNewFileStream()); + std::string path_from, path_to; - if (res) + if (vfsDevice* dev = GetDevice(ps3_path_from, path_from)) + { + if (vfsDevice* dev_ = GetDevice(ps3_path_to, path_to)) { - return res->Rename(path, ps3_path_to); + std::shared_ptr res(dev->GetNewFileStream()); + + if (res) + { + return res->Rename(path_from, path_to); + } } } @@ -275,14 +279,18 @@ bool VFS::RenameFile(const std::string& ps3_path_from, const std::string& ps3_pa bool VFS::RenameDir(const std::string& ps3_path_from, const std::string& ps3_path_to) const { - std::string path; - if (vfsDevice* dev = GetDevice(ps3_path_from, path)) - { - std::shared_ptr res(dev->GetNewDirStream()); + std::string path_from, path_to; - if (res) + if (vfsDevice* dev = GetDevice(ps3_path_from, path_from)) + { + if (vfsDevice* dev_ = GetDevice(ps3_path_to, path_to)) { - return res->Rename(path, ps3_path_to); + std::shared_ptr res(dev->GetNewDirStream()); + + if (res) + { + return res->Rename(path_from, path_to); + } } } diff --git a/rpcs3/Emu/FS/vfsLocalDir.cpp b/rpcs3/Emu/FS/vfsLocalDir.cpp index d6eb9e0e66..cad28f5a64 100644 --- a/rpcs3/Emu/FS/vfsLocalDir.cpp +++ b/rpcs3/Emu/FS/vfsLocalDir.cpp @@ -43,7 +43,7 @@ bool vfsLocalDir::Open(const std::string& path) bool vfsLocalDir::Create(const std::string& path) { - return rMkpath(path); + return rMkdir(path); } bool vfsLocalDir::IsExists(const std::string& path) const @@ -53,7 +53,7 @@ bool vfsLocalDir::IsExists(const std::string& path) const bool vfsLocalDir::Rename(const std::string& from, const std::string& to) { - return false; + return rRename(from, to); } bool vfsLocalDir::Remove(const std::string& path) diff --git a/rpcs3/Emu/FS/vfsLocalFile.cpp b/rpcs3/Emu/FS/vfsLocalFile.cpp index f33639bd1d..1542a49be5 100644 --- a/rpcs3/Emu/FS/vfsLocalFile.cpp +++ b/rpcs3/Emu/FS/vfsLocalFile.cpp @@ -124,4 +124,14 @@ bool vfsLocalFile::IsOpened() const bool vfsLocalFile::Exists(const std::string& path) { return rExists(path); -} \ No newline at end of file +} + +bool vfsLocalFile::Rename(const std::string& from, const std::string& to) +{ + return rRename(from, to); +} + +bool vfsLocalFile::Remove(const std::string& path) +{ + return rRemoveFile(path); +} diff --git a/rpcs3/Emu/FS/vfsLocalFile.h b/rpcs3/Emu/FS/vfsLocalFile.h index efef6328d5..42eb7a90bc 100644 --- a/rpcs3/Emu/FS/vfsLocalFile.h +++ b/rpcs3/Emu/FS/vfsLocalFile.h @@ -14,6 +14,8 @@ public: virtual bool Create(const std::string& path, bool overwrite = false) override; virtual bool Close() override; virtual bool Exists(const std::string& path) override; + virtual bool Rename(const std::string& from, const std::string& to) override; + virtual bool Remove(const std::string& path) override; virtual u64 GetSize() override; diff --git a/rpcs3/Emu/IdManager.h b/rpcs3/Emu/IdManager.h index eddb77e483..2d1966c198 100644 --- a/rpcs3/Emu/IdManager.h +++ b/rpcs3/Emu/IdManager.h @@ -29,48 +29,24 @@ enum IDType TYPE_OTHER, }; -class IDData -{ -protected: - void* m_ptr; - std::function m_destr; - -public: - IDData(void* ptr, std::function destr) - : m_ptr(ptr) - , m_destr(destr) - { - } - - ~IDData() - { - m_destr(m_ptr); - } - - template std::shared_ptr get() const - { - return *(std::shared_ptr*)m_ptr; - } -}; - -class ID +class ID final { const std::type_info& m_info; - IDData* m_data; + std::shared_ptr m_data; IDType m_type; public: - template - ID(std::shared_ptr& data, const IDType type) + template ID(std::shared_ptr& data, const IDType type) : m_info(typeid(T)) + , m_data(data) , m_type(type) { - m_data = new IDData(new std::shared_ptr(data), [](void *ptr) -> void { delete (std::shared_ptr*)ptr; }); } ID() - : m_info(typeid(nullptr_t)) + : m_info(typeid(void)) , m_data(nullptr) + , m_type(TYPE_OTHER) { } @@ -82,26 +58,19 @@ public: , m_type(right.m_type) { right.m_data = nullptr; + right.m_type = TYPE_OTHER; } ID& operator=(ID&& other) = delete; - ~ID() - { - if (m_data) - { - delete m_data; - } - } - const std::type_info& GetInfo() const { return m_info; } - IDData* GetData() const + template std::shared_ptr GetData() const { - return m_data; + return std::static_pointer_cast(m_data); } IDType GetType() const @@ -117,23 +86,14 @@ class IdManager std::unordered_map m_id_map; std::set m_types[TYPE_OTHER]; - std::mutex m_mtx_main; + std::mutex m_mutex; - u32 m_cur_id; + u32 m_cur_id = s_first_id; public: - IdManager() : m_cur_id(s_first_id) - { - } - - ~IdManager() - { - Clear(); - } - template bool CheckID(const u32 id) { - std::lock_guard lock(m_mtx_main); + std::lock_guard lock(m_mutex); auto f = m_id_map.find(id); @@ -142,7 +102,7 @@ public: void Clear() { - std::lock_guard lock(m_mtx_main); + std::lock_guard lock(m_mutex); m_id_map.clear(); m_cur_id = s_first_id; @@ -150,7 +110,7 @@ public: template u32 GetNewID(std::shared_ptr& data, const IDType type = TYPE_OTHER) { - std::lock_guard lock(m_mtx_main); + std::lock_guard lock(m_mutex); m_id_map.emplace(m_cur_id, ID(data, type)); @@ -161,17 +121,10 @@ public: return m_cur_id++; } - - ID& GetID(const u32 id) - { - std::lock_guard lock(m_mtx_main); - - return m_id_map[id]; - } template bool GetIDData(const u32 id, std::shared_ptr& result) { - std::lock_guard lock(m_mtx_main); + std::lock_guard lock(m_mutex); auto f = m_id_map.find(id); @@ -180,14 +133,14 @@ public: return false; } - result = f->second.GetData()->get(); + result = f->second.GetData(); return true; } template std::shared_ptr GetIDData(const u32 id) { - std::lock_guard lock(m_mtx_main); + std::lock_guard lock(m_mutex); auto f = m_id_map.find(id); @@ -196,19 +149,33 @@ public: return nullptr; } - return f->second.GetData()->get(); + return f->second.GetData(); } bool HasID(const u32 id) { - std::lock_guard lock(m_mtx_main); + std::lock_guard lock(m_mutex); return m_id_map.find(id) != m_id_map.end(); } + IDType GetIDType(const u32 id) + { + std::lock_guard lock(m_mutex); + + auto item = m_id_map.find(id); + + if (item == m_id_map.end()) + { + return TYPE_OTHER; + } + + return item->second.GetType(); + } + template bool RemoveID(const u32 id) { - std::lock_guard lock(m_mtx_main); + std::lock_guard lock(m_mutex); auto item = m_id_map.find(id); @@ -229,7 +196,7 @@ public: u32 GetTypeCount(IDType type) { - std::lock_guard lock(m_mtx_main); + std::lock_guard lock(m_mutex); if (type < TYPE_OTHER) { @@ -245,7 +212,7 @@ public: std::set GetTypeIDs(IDType type) { // you cannot simply return reference to existing set - std::lock_guard lock(m_mtx_main); + std::lock_guard lock(m_mutex); if (type < TYPE_OTHER) { diff --git a/rpcs3/Emu/SysCalls/Callback.cpp b/rpcs3/Emu/SysCalls/Callback.cpp index 02c460d975..b8e319ac73 100644 --- a/rpcs3/Emu/SysCalls/Callback.cpp +++ b/rpcs3/Emu/SysCalls/Callback.cpp @@ -9,31 +9,36 @@ void CallbackManager::Register(const std::function& func) { - std::lock_guard lock(m_mutex); - - m_cb_list.push_back([=](CPUThread& CPU) -> s32 { - assert(CPU.GetType() == CPU_THREAD_PPU); - return func(static_cast(CPU)); - }); + std::lock_guard lock(m_mutex); + + m_cb_list.push_back([=](CPUThread& CPU) -> s32 + { + assert(CPU.GetType() == CPU_THREAD_PPU); + return func(static_cast(CPU)); + }); + } } void CallbackManager::Async(const std::function& func) { - std::lock_guard lock(m_mutex); - - m_async_list.push_back([=](CPUThread& CPU) { - assert(CPU.GetType() == CPU_THREAD_PPU); - func(static_cast(CPU)); - }); + std::lock_guard lock(m_mutex); - m_cb_thread->Notify(); + m_async_list.push_back([=](CPUThread& CPU) + { + assert(CPU.GetType() == CPU_THREAD_PPU); + func(static_cast(CPU)); + }); + } + + m_cv.notify_one(); } bool CallbackManager::Check(CPUThread& CPU, s32& result) { std::function func; + { std::lock_guard lock(m_mutex); @@ -44,15 +49,7 @@ bool CallbackManager::Check(CPUThread& CPU, s32& result) } } - if (func) - { - result = func(CPU); - return true; - } - else - { - return false; - } + return func ? result = func(CPU), true : false; } void CallbackManager::Init() @@ -86,26 +83,27 @@ void CallbackManager::Init() { SetCurrentNamedThread(&*m_cb_thread); + std::unique_lock lock(m_mutex); + while (!Emu.IsStopped()) { std::function func; - { - std::lock_guard lock(m_mutex); - if (m_async_list.size()) - { - func = m_async_list[0]; - m_async_list.erase(m_async_list.begin()); - } + if (m_async_list.size()) + { + func = m_async_list[0]; + m_async_list.erase(m_async_list.begin()); } if (func) { + lock.unlock(); func(*m_cb_thread); + lock.lock(); continue; } - m_cb_thread->WaitForAnySignal(); + m_cv.wait_for(lock, std::chrono::milliseconds(1)); } }); } diff --git a/rpcs3/Emu/SysCalls/Callback.h b/rpcs3/Emu/SysCalls/Callback.h index a1250a8acb..2b1cfe59d8 100644 --- a/rpcs3/Emu/SysCalls/Callback.h +++ b/rpcs3/Emu/SysCalls/Callback.h @@ -8,6 +8,8 @@ typedef void(PauseResumeCB)(bool is_paused); class CallbackManager { std::mutex m_mutex; + std::condition_variable m_cv; + std::vector> m_cb_list; std::vector> m_async_list; std::shared_ptr m_cb_thread; diff --git a/rpcs3/Emu/SysCalls/FuncList.cpp b/rpcs3/Emu/SysCalls/FuncList.cpp index 250534f7cd..f6a5eae46d 100644 --- a/rpcs3/Emu/SysCalls/FuncList.cpp +++ b/rpcs3/Emu/SysCalls/FuncList.cpp @@ -1,9 +1,569 @@ #include "stdafx.h" +#include "Modules.h" #include "SysCalls.h" -std::string SysCalls::GetHLEFuncName(const u32 fid) +std::string SysCalls::GetFuncName(const u64 fid) { - switch(fid) + // check syscalls + switch (fid) + { + case 1: return "sys_process_getpid"; + case 2: return "sys_process_wait_for_child"; + case 3: return "sys_process_exit"; + case 4: return "sys_process_get_status"; + case 5: return "sys_process_detach_child"; + case 12: return "sys_process_get_number_of_object"; + case 13: return "sys_process_get_id"; + case 14: return "sys_process_is_spu_lock_line_reservation_address"; + case 18: return "sys_process_getppid"; + case 19: return "sys_process_kill"; + case 21: return "_sys_process_spawn"; + case 22: return "sys_process_exit"; + case 23: return "sys_process_wait_for_child2"; + case 25: return "sys_process_get_sdk_version"; + case 26: return "_sys_process_exit"; + case 28: return "_sys_process_get_number_of_object"; + case 29: return "sys_process_get_id"; + case 30: return "_sys_process_get_paramsfo"; + case 31: return "sys_process_get_ppu_guid"; + case 41: return "sys_internal_ppu_thread_exit"; + case 43: return "sys_ppu_thread_yield"; + case 44: return "sys_ppu_thread_join"; + case 45: return "sys_ppu_thread_detach"; + case 46: return "sys_ppu_thread_get_join_state"; + case 47: return "sys_ppu_thread_set_priority"; + case 48: return "sys_ppu_thread_get_priority"; + case 49: return "sys_ppu_thread_get_stack_information"; + case 50: return "sys_ppu_thread_stop"; + case 51: return "sys_ppu_thread_restart"; + case 52: return "sys_ppu_thread_create"; + case 53: return "sys_ppu_thread_start"; + case 56: return "sys_ppu_thread_rename"; + case 57: return "sys_ppu_thread_recover_page_fault"; + case 58: return "sys_ppu_thread_get_page_fault_context"; + case 60: return "sys_trace_create"; + case 61: return "sys_trace_start"; + case 62: return "sys_trace_stop"; + case 63: return "sys_trace_update_top_index"; + case 64: return "sys_trace_destroy"; + case 65: return "sys_trace_drain"; + case 66: return "sys_trace_attach_process"; + case 67: return "sys_trace_allocate_buffer"; + case 68: return "sys_trace_free_buffer"; + case 69: return "sys_trace_create2"; + case 70: return "sys_timer_create"; + case 71: return "sys_timer_destroy"; + case 72: return "sys_timer_get_information"; + case 73: return "_sys_timer_start"; + case 74: return "sys_timer_stop"; + case 75: return "sys_timer_connect_event_queue"; + case 76: return "sys_timer_disconnect_event_queue"; + case 77: return "sys_trace_create2_in_cbepm"; + case 80: return "sys_interrupt_tag_create"; + case 81: return "sys_interrupt_tag_destroy"; + case 82: return "sys_event_flag_create"; + case 83: return "sys_event_flag_destroy"; + case 84: return "sys_interrupt_thread_establish"; + case 85: return "sys_event_flag_wait"; + case 86: return "sys_event_flag_trywait"; + case 87: return "sys_event_flag_set"; + case 88: return "sys_interrupt_thread_eoi"; + case 89: return "_sys_interrupt_thread_disestablish"; + case 90: return "sys_semaphore_create"; + case 91: return "sys_semaphore_destroy"; + case 92: return "sys_semaphore_wait"; + case 93: return "sys_semaphore_trywait"; + case 94: return "sys_semaphore_post"; + case 95: return "_sys_lwmutex_create"; + case 96: return "_sys_lwmutex_destroy"; + case 97: return "_sys_lwmutex_lock"; + case 98: return "_sys_lwmutex_unlock"; + case 99: return "_sys_lwmutex_trylock"; + case 100: return "sys_mutex_create"; + case 101: return "sys_mutex_destroy"; + case 102: return "sys_mutex_lock"; + case 103: return "sys_mutex_trylock"; + case 104: return "sys_mutex_unlock"; + case 105: return "sys_cond_create"; + case 106: return "sys_cond_destroy"; + case 107: return "sys_cond_wait"; + case 108: return "sys_cond_signal"; + case 109: return "sys_cond_signal_all"; + case 110: return "sys_cond_signal_to"; + case 111: return "_sys_lwcond_create"; + case 112: return "_sys_lwcond_destroy"; + case 113: return "_sys_lwcond_queue_wait"; + case 114: return "sys_semaphore_get_value"; + case 115: return "_sys_lwcond_signal"; + case 116: return "_sys_lwcond_signal_all"; + case 118: return "sys_event_flag_clear"; + case 120: return "sys_rwlock_create"; + case 121: return "sys_rwlock_destroy"; + case 122: return "sys_rwlock_rlock"; + case 123: return "sys_rwlock_tryrlock"; + case 124: return "sys_rwlock_runlock"; + case 125: return "sys_rwlock_wlock"; + case 126: return "sys_rwlock_trywlock"; + case 127: return "sys_rwlock_wunlock"; + case 128: return "sys_event_queue_create"; + case 129: return "sys_event_queue_destroy"; + case 130: return "sys_event_queue_receive"; + case 131: return "sys_event_queue_tryreceive"; + case 132: return "sys_event_flag_cancel"; + case 133: return "sys_event_queue_drain"; + case 134: return "sys_event_port_create"; + case 135: return "sys_event_port_destroy"; + case 136: return "sys_event_port_connect_local"; + case 137: return "sys_event_port_disconnect"; + case 138: return "sys_event_port_send"; + case 139: return "sys_event_flag_get"; + case 140: return "sys_event_port_connect_ipc"; + case 141: return "sys_timer_usleep"; + case 142: return "sys_timer_sleep"; + case 143: return "sys_time_set_timezone"; + case 144: return "sys_time_get_timezone"; + case 145: return "sys_time_get_current_time"; + case 146: return "sys_time_get_system_time"; + case 147: return "sys_time_get_timebase_frequency"; + case 148: return "sys_rwlock_trywlock"; + case 150: return "sys_raw_spu_create_interrupt_tag"; + case 151: return "sys_raw_spu_set_int_mask"; + case 152: return "sys_raw_spu_get_int_mask"; + case 153: return "sys_raw_spu_set_int_stat"; + case 154: return "sys_raw_spu_get_int_stat"; + case 155: return "sys_spu_image_get_information?"; + case 156: return "sys_spu_image_open"; + case 157: return "sys_spu_image_import"; + case 158: return "sys_spu_image_close"; + case 159: return "sys_raw_spu_load"; + case 160: return "sys_raw_spu_create"; + case 161: return "sys_raw_spu_destroy"; + case 163: return "sys_raw_spu_read_puint_mb"; + case 165: return "sys_spu_thread_get_exit_status"; + case 166: return "sys_spu_thread_set_argument"; + case 167: return "sys_spu_thread_group_start_on_exit"; + case 169: return "sys_spu_initialize"; + case 170: return "sys_spu_thread_group_create"; + case 171: return "sys_spu_thread_group_destroy"; + case 172: return "sys_spu_thread_initialize"; + case 173: return "sys_spu_thread_group_start"; + case 174: return "sys_spu_thread_group_suspend"; + case 175: return "sys_spu_thread_group_resume"; + case 176: return "sys_spu_thread_group_yield"; + case 177: return "sys_spu_thread_group_terminate"; + case 178: return "sys_spu_thread_group_join"; + case 179: return "sys_spu_thread_group_set_priority"; + case 180: return "sys_spu_thread_group_get_priority"; + case 181: return "sys_spu_thread_write_ls"; + case 182: return "sys_spu_thread_read_ls"; + case 184: return "sys_spu_thread_write_snr"; + case 185: return "sys_spu_thread_group_connect_event"; + case 186: return "sys_spu_thread_group_disconnect_event"; + case 187: return "sys_spu_thread_set_spu_cfg"; + case 188: return "sys_spu_thread_get_spu_cfg"; + case 190: return "sys_spu_thread_write_spu_mb"; + case 191: return "sys_spu_thread_connect_event"; + case 192: return "sys_spu_thread_disconnect_event"; + case 193: return "sys_spu_thread_bind_queue"; + case 194: return "sys_spu_thread_unbind_queue"; + case 196: return "sys_raw_spu_set_spu_cfg"; + case 197: return "sys_raw_spu_get_spu_cfg"; + case 198: return "sys_spu_thread_recover_page_fault"; + case 199: return "sys_raw_spu_recover_page_fault"; + case 215: return "sys_dbg_mat_set_condition"; + case 216: return "sys_dbg_mat_get_condition"; + case 230: return "sys_isolated_spu_create"; + case 231: return "sys_isolated_spu_destroy"; + case 232: return "sys_isolated_spu_start"; + case 233: return "sys_isolated_spu_create_interrupt_tag"; + case 234: return "sys_isolated_spu_set_int_mask"; + case 235: return "sys_isolated_spu_get_int_mask"; + case 236: return "sys_isolated_spu_set_int_stat"; + case 237: return "sys_isolated_spu_get_int_stat"; + case 238: return "sys_isolated_spu_set_spu_cfg"; + case 239: return "sys_isolated_spu_get_spu_cfg"; + case 240: return "sys_isolated_spu_read_puint_mb"; + case 244: return "sys_spu_thread_group_system_set_next_group"; + case 245: return "sys_spu_thread_group_system_unset_next_group"; + case 246: return "sys_spu_thread_group_system_set_switch_group"; + case 247: return "sys_spu_thread_group_system_unset_switch_group"; + case 250: return "sys_spu_thread_group_set_cooperative_victims"; + case 251: return "sys_spu_thread_group_connect_event_all_threads"; + case 252: return "sys_spu_thread_group_disconnect_event_all_threads"; + case 254: return "sys_spu_thread_group_log"; + case 260: return "sys_spu_image_open_by_fd"; + case 300: return "sys_vm_memory_map"; + case 301: return "sys_vm_unmap"; + case 302: return "sys_vm_append_memory"; + case 303: return "sys_vm_return_memory"; + case 304: return "sys_vm_lock"; + case 305: return "sys_vm_unlock"; + case 306: return "sys_vm_touch"; + case 307: return "sys_vm_flush"; + case 308: return "sys_vm_invalidate"; + case 309: return "sys_vm_store"; + case 310: return "sys_vm_sync"; + case 311: return "sys_vm_test"; + case 312: return "sys_vm_get_statistics"; + case 324: return "sys_memory_container_create"; + case 325: return "sys_memory_container_destroy"; + case 326: return "sys_mmapper_allocate_fixed_address"; + case 327: return "sys_mmapper_enable_page_fault_notification"; + case 329: return "sys_mmapper_free_shared_memory"; + case 330: return "sys_mmapper_allocate_address"; + case 331: return "sys_mmapper_free_address"; + case 332: return "sys_mmapper_allocate_shared_memory"; + case 333: return "sys_mmapper_set_shared_memory_flag"; + case 334: return "sys_mmapper_map_shared_memory"; + case 335: return "sys_mmapper_unmap_shared_memory"; + case 336: return "sys_mmapper_change_address_access_right"; + case 337: return "sys_mmapper_search_and_map"; + case 338: return "sys_mmapper_get_shared_memory_attribute"; + case 341: return "sys_memory_container_create"; + case 342: return "sys_memory_container_destroy"; + case 343: return "sys_memory_container_get_size"; + case 344: return "sys_memory_budget_set"; + case 348: return "sys_memory_allocate"; + case 349: return "sys_memory_free"; + case 350: return "sys_memory_allocate_from_container"; + case 351: return "sys_memory_get_page_attribute"; + case 352: return "sys_memory_get_user_memory_size"; + case 353: return "sys_memory_get_user_memory_stat"; + case 356: return "sys_memory_allocate_colored"; + case 361: return "sys_memory_allocate_from_container_colored"; + case 362: return "sys_mmapper_allocate_memory_from_container"; + case 367: return "sys_uart_initialize"; + case 368: return "sys_uart_receive"; + case 369: return "sys_uart_send"; + case 370: return "sys_uart_get_params"; + case 372: return "sys_game_watchdog_start"; + case 373: return "sys_game_watchdog_stop"; + case 374: return "sys_game_watchdog_clear"; + case 375: return "sys_game_set_system_sw_version"; + case 376: return "sys_game_get_system_sw_version"; + case 377: return "sys_sm_set_shop_mode"; + case 378: return "sys_sm_get_ext_event2"; + case 379: return "sys_sm_shutdown"; + case 380: return "sys_sm_get_params"; + case 381: return "sys_sm_get_inter_lpar_parameter"; + case 383: return "sys_game_get_temperature"; + case 384: return "sys_sm_get_tzpb"; + case 385: return "sys_sm_request_led"; + case 386: return "sys_sm_control_led"; + case 387: return "sys_sm_get_platform_info"; + case 388: return "sys_sm_ring_buzzer"; + case 389: return "sys_sm_set_fan_policy"; + case 390: return "sys_sm_request_error_log"; + case 391: return "sys_sm_request_be_count"; + case 392: return "sys_sm_ring_buzzer"; + case 393: return "sys_sm_get_hw_config"; + case 394: return "sys_sm_request_scversion"; + case 395: return "sys_sm_request_system_event_log"; + case 396: return "sys_sm_set_rtc_alarm"; + case 397: return "sys_sm_get_rtc_alarm"; + case 398: return "sys_console_write"; + case 402: return "sys_tty_read"; + case 403: return "sys_tty_write"; + case 408: return "sys_sm_get_tzpb"; + case 409: return "sys_sm_get_fan_policy"; + case 410: return "sys_game_board_storage_read"; + case 411: return "sys_game_board_storage_write"; + case 412: return "sys_game_get_rtc_status"; + case 450: return "sys_overlay_load_module"; + case 451: return "sys_overlay_unload_module"; + case 452: return "sys_overlay_get_module_list"; + case 453: return "sys_overlay_get_module_info"; + case 454: return "sys_overlay_load_module_by_fd"; + case 455: return "sys_overlay_get_module_info2"; + case 456: return "sys_overlay_get_sdk_version"; + case 457: return "sys_overlay_get_module_dbg_info"; + case 458: return "sys_overlay_get_module_dbg_info"; + case 460: return "sys_prx_dbg_get_module_id_list"; + case 461: return "sys_prx_get_module_id_by_address"; + case 463: return "sys_prx_load_module_by_fd"; + case 464: return "sys_prx_load_module_on_memcontainer_by_fd"; + case 465: return "sys_prx_load_module_list"; + case 466: return "sys_prx_load_module_list_on_memcontainer"; + case 467: return "sys_prx_get_ppu_guid"; + case 480: return "sys_prx_load_module"; + case 481: return "sys_prx_start_module"; + case 482: return "sys_prx_stop_module"; + case 483: return "sys_prx_unload_module"; + case 484: return "sys_prx_register_module"; + case 485: return "sys_prx_query_module"; + case 486: return "sys_prx_register_library"; + case 487: return "sys_prx_unregister_library"; + case 488: return "sys_prx_link_library"; + case 489: return "sys_prx_unlink_library"; + case 490: return "sys_prx_query_library"; + case 493: return "sys_prx_dbg_get_module_info"; + case 494: return "sys_prx_get_module_list"; + case 495: return "sys_prx_get_module_info"; + case 496: return "sys_prx_get_module_id_by_name"; + case 497: return "sys_prx_load_module_on_memcontainer"; + case 498: return "sys_prx_start"; + case 499: return "sys_prx_stop"; + case 500: return "sys_hid_manager_open"; + case 501: return "sys_hid_manager_close"; + case 502: return "sys_hid_manager_read"; + case 503: return "sys_hid_manager_ioctl"; + case 504: return "sys_hid_manager_map_logical_id_to_port_id"; + case 505: return "sys_hid_manager_unmap_logical_id_to_port_id"; + case 506: return "sys_hid_manager_add_hot_key_observer"; + case 507: return "sys_hid_manager_remove_hot_key_observer"; + case 508: return "sys_hid_manager_grab_focus"; + case 509: return "sys_hid_manager_release_focus"; + case 516: return "sys_config_open"; + case 517: return "sys_config_close"; + case 518: return "sys_config_get_service_event"; + case 519: return "sys_config_add_service_listener"; + case 520: return "sys_config_remove_service_listener"; + case 521: return "sys_config_register_service"; + case 522: return "sys_config_unregister_service"; + case 523: return "sys_config_io_event"; + case 530: return "sys_usbd_initialize"; + case 531: return "sys_usbd_finalize"; + case 532: return "sys_usbd_get_device_list"; + case 533: return "sys_usbd_get_descriptor_size"; + case 534: return "sys_usbd_get_descriptor"; + case 535: return "sys_usbd_register_ldd"; + case 536: return "sys_usbd_unregister_ldd"; + case 537: return "sys_usbd_open_pipe"; + case 538: return "sys_usbd_open_default_pipe"; + case 539: return "sys_usbd_close_pipe"; + case 540: return "sys_usbd_receive_event"; + case 541: return "sys_usbd_detect_event"; + case 542: return "sys_usbd_attach"; + case 543: return "sys_usbd_transfer_data"; + case 544: return "sys_usbd_isochronous_transfer_data"; + case 545: return "sys_usbd_get_transfer_status"; + case 546: return "sys_usbd_get_isochronous_transfer_status"; + case 547: return "sys_usbd_get_device_location"; + case 548: return "sys_usbd_send_event"; + case 550: return "sys_usbd_allocate_memory"; + case 551: return "sys_usbd_free_memory"; + case 556: return "sys_usbd_get_device_speed"; + case 559: return "sys_usbd_register_extra_ldd"; + case 571: return "sys_pad_ldd_unregister_controller"; + case 572: return "sys_pad_ldd_data_insert"; + case 573: return "sys_pad_dbg_ldd_set_data_insert_mode"; + case 574: return "sys_pad_ldd_register_controller"; + case 575: return "sys_pad_ldd_get_port_no"; + case 577: return "sys_pad_manager_..."; + case 600: return "sys_storage_open"; + case 601: return "sys_storage_close"; + case 602: return "sys_storage_read"; + case 603: return "sys_storage_write"; + case 604: return "sys_storage_send_device_command"; + case 605: return "sys_storage_async_configure"; + case 606: return "sys_storage_async_read"; + case 607: return "sys_storage_async_write"; + case 608: return "sys_storage_async_cancel"; + case 609: return "sys_storage_get_device_info"; + case 610: return "sys_storage_get_device_config"; + case 611: return "sys_storage_report_devices"; + case 612: return "sys_storage_configure_medium_event"; + case 613: return "sys_storage_set_medium_polling_interval"; + case 614: return "sys_storage_create_region"; + case 615: return "sys_storage_delete_region"; + case 616: return "sys_storage_execute_device_command"; + case 617: return "sys_storage_check_region_acl"; + case 618: return "sys_storage_set_region_acl"; + case 619: return "sys_storage_async_send_device_command"; + case 621: return "sys_gamepad_ycon_if"; + case 622: return "sys_storage_get_region_offset"; + case 623: return "sys_storage_set_emulated_speed"; + case 624: return "sys_io_buffer_create"; + case 625: return "sys_io_buffer_destroy"; + case 626: return "sys_io_buffer_allocate"; + case 627: return "sys_io_buffer_free"; + case 630: return "sys_gpio_set"; + case 631: return "sys_gpio_get"; + case 633: return "sys_fsw_connect_event"; + case 634: return "sys_fsw_disconnect_event"; + case 635: return "sys_btsetting_if"; + case 650: return "sys_rsxaudio_initialize"; + case 651: return "sys_rsxaudio_finalize"; + case 652: return "sys_rsxaudio_import_shared_memory"; + case 653: return "sys_rsxaudio_unimport_shared_memory"; + case 654: return "sys_rsxaudio_create_connection"; + case 655: return "sys_rsxaudio_close_connection"; + case 656: return "sys_rsxaudio_prepare_process"; + case 657: return "sys_rsxaudio_start_process"; + case 666: return "sys_rsx_device_open"; + case 667: return "sys_rsx_device_close"; + case 668: return "sys_rsx_memory_allocate"; + case 669: return "sys_rsx_memory_free"; + case 670: return "sys_rsx_context_allocate"; + case 671: return "sys_rsx_context_free"; + case 672: return "sys_rsx_context_iomap"; + case 673: return "sys_rsx_context_iounmap"; + case 674: return "sys_rsx_context_attribute"; + case 675: return "sys_rsx_device_map"; + case 676: return "sys_rsx_device_unmap"; + case 677: return "sys_rsx_attribute"; + case 699: return "sys_bdemu_send_command"; + case 700: return "sys_net_bnet_accept"; + case 701: return "sys_net_bnet_bind"; + case 702: return "sys_net_bnet_connect"; + case 703: return "sys_net_bnet_getpeername"; + case 704: return "sys_net_bnet_getsockname"; + case 705: return "sys_net_bnet_getsockopt"; + case 706: return "sys_net_bnet_listen"; + case 707: return "sys_net_bnet_recvfrom"; + case 708: return "sys_net_bnet_recvmsg"; + case 709: return "sys_net_bnet_sendmsg"; + case 710: return "sys_net_bnet_sendto"; + case 711: return "sys_net_bnet_setsockop"; + case 712: return "sys_net_bnet_shutdown"; + case 713: return "sys_net_bnet_socket"; + case 714: return "sys_net_bnet_close"; + case 715: return "sys_net_bnet_poll"; + case 716: return "sys_net_bnet_select"; + case 717: return "sys_net_open_dump"; + case 718: return "sys_net_read_dump"; + case 719: return "sys_net_close_dump"; + case 720: return "sys_net_write_dump"; + case 721: return "sys_net_abort"; + case 722: return "sys_net_infoctl"; + case 723: return "sys_net_control"; + case 724: return "sys_net_bnet_ioctl"; + case 725: return "sys_net_bnet_sysctl"; + case 726: return "sys_net_eurus_post_command"; + case 800: return "sys_fs_test"; + case 801: return "sys_fs_open"; + case 802: return "sys_fs_read"; + case 803: return "sys_fs_write"; + case 804: return "sys_fs_close"; + case 805: return "sys_fs_opendir"; + case 806: return "sys_fs_readdir"; + case 807: return "sys_fs_closedir"; + case 808: return "sys_fs_stat"; + case 809: return "sys_fs_fstat"; + case 810: return "sys_fs_link"; + case 811: return "sys_fs_mkdir"; + case 812: return "sys_fs_rename"; + case 813: return "sys_fs_rmdir"; + case 814: return "sys_fs_unlink"; + case 815: return "sys_fs_utime"; + case 816: return "sys_fs_access"; + case 817: return "sys_fs_fcntl"; + case 818: return "sys_fs_lseek"; + case 819: return "sys_fs_fdatasync"; + case 820: return "sys_fs_fsync"; + case 821: return "sys_fs_fget_block_size"; + case 822: return "sys_fs_get_block_size"; + case 823: return "sys_fs_acl_read"; + case 824: return "sys_fs_acl_write"; + case 825: return "sys_fs_lsn_get_cda_size"; + case 826: return "sys_fs_lsn_get_cda"; + case 827: return "sys_fs_lsn_lock"; + case 828: return "sys_fs_lsn_unlock"; + case 829: return "sys_fs_lsn_read"; + case 830: return "sys_fs_lsn_write"; + case 831: return "sys_fs_truncate"; + case 832: return "sys_fs_ftruncate"; + case 833: return "sys_fs_symbolic_link"; + case 834: return "sys_fs_chmod"; + case 835: return "sys_fs_chown"; + case 836: return "sys_fs_newfs"; + case 837: return "sys_fs_mount"; + case 838: return "sys_fs_unmount"; + case 839: return "sys_fs_sync"; + case 840: return "sys_fs_disk_free"; + case 841: return "sys_fs_get_mount_info_size"; + case 842: return "sys_fs_get_mount_info"; + case 843: return "sys_fs_get_fs_info_size"; + case 844: return "sys_fs_get_fs_info"; + case 845: return "sys_fs_mapped_allocate"; + case 846: return "sys_fs_mapped_free"; + case 847: return "sys_fs_truncate2"; + case 860: return "sys_ss_get_cache_of_analog_sunset_flag"; + case 865: return "sys_ss_random_number_generator"; + case 870: return "sys_ss_get_console_id"; + case 871: return "sys_ss_access_control_engine"; + case 872: return "sys_ss_get_open_psid"; + case 873: return "sys_ss_get_cache_of_product_mode"; + case 874: return "sys_ss_get_cache_of_flash_ext_flag"; + case 875: return "sys_ss_get_boot_device"; + case 876: return "sys_ss_disc_access_control"; + case 877: return "sys_ss_~utoken_if"; + case 878: return "sys_ss_ad_sign"; + case 879: return "sys_ss_media_id"; + case 880: return "sys_deci3_open"; + case 881: return "sys_deci3_create_event_path"; + case 882: return "sys_deci3_close"; + case 883: return "sys_deci3_send"; + case 884: return "sys_deci3_receive"; + case 885: return "sys_deci3_open2"; + case 890: return "sys_deci3_initialize"; + case 891: return "sys_deci3_terminate"; + case 892: return "sys_deci3_debug_mode"; + case 893: return "sys_deci3_show_status"; + case 894: return "sys_deci3_echo_test"; + case 895: return "sys_deci3_send_dcmp_packet"; + case 896: return "sys_deci3_dump_cp_register"; + case 897: return "sys_deci3_dump_cp_buffer"; + case 899: return "sys_deci3_test"; + case 900: return "sys_dbg_stop_processes"; + case 901: return "sys_dbg_continue_processes"; + case 902: return "sys_dbg_stop_threads"; + case 903: return "sys_dbg_continue_threads"; + case 904: return "sys_dbg_read_process_memory"; + case 905: return "sys_dbg_write_process_memory"; + case 906: return "sys_dbg_read_thread_register"; + case 907: return "sys_dbg_write_thread_register"; + case 908: return "sys_dbg_get_process_list"; + case 909: return "sys_dbg_get_thread_list"; + case 910: return "sys_dbg_get_thread_info"; + case 911: return "sys_dbg_spu_thread_read_from_ls"; + case 912: return "sys_dbg_spu_thread_write_to_ls"; + case 913: return "sys_dbg_kill_process"; + case 914: return "sys_dbg_get_process_info"; + case 915: return "sys_dbg_set_run_control_bit_to_spu"; + case 916: return "sys_dbg_spu_thread_get_exception_cause"; + case 917: return "sys_dbg_create_kernel_event_queue"; + case 918: return "sys_dbg_read_kernel_event_queue"; + case 919: return "sys_dbg_destroy_kernel_event_queue"; + case 920: return "sys_dbg_get_process_event_ctrl_flag"; + case 921: return "sys_dbg_set_process_event_cntl_flag"; + case 922: return "sys_dbg_get_spu_thread_group_event_cntl_flag"; + case 923: return "sys_dbg_set_spu_thread_group_event_cntl_flag"; + case 925: return "sys_dbg_get_raw_spu_list"; + case 932: return "sys_dbg_get_mutex_list"; + case 933: return "sys_dbg_get_mutex_information"; + case 934: return "sys_dbg_get_cond_list"; + case 935: return "sys_dbg_get_cond_information"; + case 936: return "sys_dbg_get_rwlock_list"; + case 937: return "sys_dbg_get_rwlock_information"; + case 938: return "sys_dbg_get_lwmutex_list"; + case 939: return "sys_dbg_get_address_from_dabr"; + case 940: return "sys_dbg_set_address_to_dabr"; + case 941: return "sys_dbg_get_lwmutex_information"; + case 942: return "sys_dbg_get_event_queue_list"; + case 943: return "sys_dbg_get_event_queue_information"; + case 944: return "sys_dbg_initialize_ppu_exception_handler"; + case 945: return "sys_dbg_finalize_ppu_exception_handler"; + case 946: return "sys_dbg_get_semaphore_list"; + case 947: return "sys_dbg_get_semaphore_information"; + case 948: return "sys_dbg_get_kernel_thread_list"; + case 949: return "sys_dbg_get_kernel_thread_info"; + case 950: return "sys_dbg_get_lwcond_list"; + case 951: return "sys_dbg_get_lwcond_information"; + case 952: return "sys_dbg_create_scratch_data_area_ext"; + case 953: return "sys_dbg_vm_get_page_information"; + case 954: return "sys_dbg_vm_get_info"; + case 955: return "sys_dbg_enable_floating_point_enabled_exception"; + case 956: return "sys_dbg_disable_floating_point_enabled_exception"; + case 960: return "sys_dbg_perfomance_monitor"; + case 970: return "sys_dbg_get_event_flag_list"; + case 971: return "sys_dbg_get_event_flag_information"; + case 975: return "sys_dbg_read_spu_thread_context2"; + case 985: return "sys_dbg_get_console_type"; + } + + // check HLE functions + switch (fid) { case 0x1529e506: return "cellAdecDecodeAu"; case 0x487b613e: return "cellAdecStartSeq"; @@ -3842,5 +4402,17 @@ std::string SysCalls::GetHLEFuncName(const u32 fid) case 0xfc52a7a9: return "sys_game_process_exitspawn"; } - return fmt::Format("Unknown func id: 0x%08x", fid); + // check registered functions + if (fid < 0x100000000ull) + { + if (const auto func = get_ppu_func_by_nid(static_cast(fid))) + { + if (func->name) + { + return func->name; + } + } + } + + return fmt::format("0x%08llX", fid); } diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp index cd15049463..c2cb8f2e0d 100644 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -40,7 +40,7 @@ u32 add_ppu_func_sub(const char group[8], const SearchPatternEntry ops[], const } StaticFunc sf; - sf.index = add_ppu_func(ModuleFunc(get_function_id(name), 0, module, func)); + sf.index = add_ppu_func(ModuleFunc(get_function_id(name), 0, module, name, func)); sf.name = name; sf.group = *(u64*)group_name; sf.found = 0; @@ -108,33 +108,33 @@ void execute_ppu_func_by_index(PPUThread& CPU, u32 index) if (Ini.HLELogging.GetValue()) { - LOG_NOTICE(HLE, "LLE function called: %s", SysCalls::GetHLEFuncName(func->id)); + LOG_NOTICE(HLE, "LLE function called: %s", SysCalls::GetFuncName(func->id)); } func->lle_func(CPU); if (Ini.HLELogging.GetValue()) { - LOG_NOTICE(HLE, "LLE function finished: %s -> 0x%llx", SysCalls::GetHLEFuncName(func->id), CPU.GPR[3]); + LOG_NOTICE(HLE, "LLE function finished: %s -> 0x%llx", SysCalls::GetFuncName(func->id), CPU.GPR[3]); } } else if (func->func) { if (Ini.HLELogging.GetValue()) { - LOG_NOTICE(HLE, "HLE function called: %s", SysCalls::GetHLEFuncName(func->id)); + LOG_NOTICE(HLE, "HLE function called: %s", SysCalls::GetFuncName(func->id)); } func->func(CPU); if (Ini.HLELogging.GetValue()) { - LOG_NOTICE(HLE, "HLE function finished: %s -> 0x%llx", SysCalls::GetHLEFuncName(func->id), CPU.GPR[3]); + LOG_NOTICE(HLE, "HLE function finished: %s -> 0x%llx", SysCalls::GetFuncName(func->id), CPU.GPR[3]); } } else { - LOG_ERROR(HLE, "Unimplemented function: %s -> CELL_OK", SysCalls::GetHLEFuncName(func->id)); + LOG_ERROR(HLE, "Unimplemented function: %s -> CELL_OK", SysCalls::GetFuncName(func->id)); CPU.GPR[3] = 0; } diff --git a/rpcs3/Emu/SysCalls/Modules.h b/rpcs3/Emu/SysCalls/Modules.h index 91a520b10c..49d7b51322 100644 --- a/rpcs3/Emu/SysCalls/Modules.h +++ b/rpcs3/Emu/SysCalls/Modules.h @@ -25,6 +25,7 @@ struct ModuleFunc u32 id; u32 flags; Module* module; + const char* name; ppu_func_caller func; vm::ptr lle_func; @@ -32,10 +33,11 @@ struct ModuleFunc { } - ModuleFunc(u32 id, u32 flags, Module* module, ppu_func_caller func, vm::ptr lle_func = vm::ptr::make(0)) + ModuleFunc(u32 id, u32 flags, Module* module, const char* name, ppu_func_caller func, vm::ptr lle_func = vm::ptr::make(0)) : id(id) , flags(flags) , module(module) + , name(name) , func(func) , lle_func(lle_func) { @@ -117,10 +119,10 @@ void hook_ppu_funcs(vm::ptr base, u32 size); bool patch_ppu_import(u32 addr, u32 index); -#define REG_FUNC(module, name) add_ppu_func(ModuleFunc(get_function_id(#name), 0, &module, bind_func(name))) -#define REG_FUNC_FH(module, name) add_ppu_func(ModuleFunc(get_function_id(#name), MFF_FORCED_HLE, &module, bind_func(name))) +#define REG_FUNC(module, name) add_ppu_func(ModuleFunc(get_function_id(#name), 0, &module, #name, bind_func(name))) +#define REG_FUNC_FH(module, name) add_ppu_func(ModuleFunc(get_function_id(#name), MFF_FORCED_HLE, &module, #name, bind_func(name))) -#define REG_UNNAMED(module, nid) add_ppu_func(ModuleFunc(0x##nid, 0, &module, bind_func(_nid_##nid))) +#define REG_UNNAMED(module, nid) add_ppu_func(ModuleFunc(0x##nid, 0, &module, "_nid_"#nid, bind_func(_nid_##nid))) #define REG_SUB(module, group, ns, name, ...) \ const SearchPatternEntry name##_table[] = {__VA_ARGS__}; \ diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index 0def6405ba..67fd473b3a 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -73,8 +73,6 @@ s32 cellAudioInit() squeue_t out_queue; - std::vector keys; - thread_t iat("Internal Audio Thread", true /* autojoin */, [&out_queue]() { const bool use_u16 = Ini.AudioConvertToU16.GetValue(); @@ -374,11 +372,13 @@ s32 cellAudioInit() //const u64 stamp2 = get_system_time(); - // send aftermix event (normal audio event) { std::lock_guard lock(g_audio.mutex); - // update indexes: + + // update indices: + auto indexes = vm::ptr::make(g_audio.indexes); + for (u32 i = 0; i < AUDIO_PORT_COUNT; i++) { AudioPortConfig& port = g_audio.ports[i]; @@ -390,16 +390,14 @@ s32 cellAudioInit() port.tag++; // absolute index of block that will be read indexes[i] = (position + 1) % port.block; // write new value } - // load keys: - keys.resize(g_audio.keys.size()); - memcpy(keys.data(), g_audio.keys.data(), sizeof(u64) * keys.size()); - } - { + + // send aftermix event (normal audio event) + LV2_LOCK; - for (u32 i = 0; i < keys.size(); i++) + for (auto key : g_audio.keys) { - if (std::shared_ptr queue = Emu.GetEventManager().GetEventQueue(keys[i])) + if (std::shared_ptr queue = Emu.GetEventManager().GetEventQueue(key)) { queue->push(0, 0, 0, 0); // TODO: check arguments } @@ -455,7 +453,7 @@ s32 cellAudioQuit() s32 cellAudioPortOpen(vm::ptr audioParam, vm::ptr portNum) { - cellAudio.Warning("cellAudioPortOpen(audioParam=0x%x, portNum=0x%x)", audioParam, portNum); + cellAudio.Warning("cellAudioPortOpen(audioParam=*0x%x, portNum=*0x%x)", audioParam, portNum); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -519,7 +517,7 @@ s32 cellAudioPortOpen(vm::ptr audioParam, vm::ptr portN } if (attr & 0xFFFFFFFFF0EFEFEEULL) { - cellAudio.Todo("cellAudioPortOpen(): unknown attributes set (0x%llx)", attr); + cellAudio.Todo("cellAudioPortOpen(): unknown attributes (0x%llx)", attr); } // open audio port @@ -560,7 +558,7 @@ s32 cellAudioPortOpen(vm::ptr audioParam, vm::ptr portN s32 cellAudioGetPortConfig(u32 portNum, vm::ptr portConfig) { - cellAudio.Warning("cellAudioGetPortConfig(portNum=0x%x, portConfig=0x%x)", portNum, portConfig); + cellAudio.Warning("cellAudioGetPortConfig(portNum=%d, portConfig=*0x%x)", portNum, portConfig); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -581,7 +579,7 @@ s32 cellAudioGetPortConfig(u32 portNum, vm::ptr portConfig) case AUDIO_PORT_STATE_CLOSED: portConfig->status = CELL_AUDIO_STATUS_CLOSE; break; case AUDIO_PORT_STATE_OPENED: portConfig->status = CELL_AUDIO_STATUS_READY; break; case AUDIO_PORT_STATE_STARTED: portConfig->status = CELL_AUDIO_STATUS_RUN; break; - default: throw fmt::format("cellAudioGetPortConfig(%d): invalid port state (0x%x)", portNum, state); + default: throw fmt::format("cellAudioGetPortConfig(%d): invalid port state (%d)", portNum, state); } portConfig->nChannel = port.channel; @@ -593,7 +591,7 @@ s32 cellAudioGetPortConfig(u32 portNum, vm::ptr portConfig) s32 cellAudioPortStart(u32 portNum) { - cellAudio.Warning("cellAudioPortStart(portNum=0x%x)", portNum); + cellAudio.Warning("cellAudioPortStart(portNum=%d)", portNum); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -610,13 +608,13 @@ s32 cellAudioPortStart(u32 portNum) case AUDIO_PORT_STATE_CLOSED: return CELL_AUDIO_ERROR_PORT_NOT_OPEN; case AUDIO_PORT_STATE_STARTED: return CELL_AUDIO_ERROR_PORT_ALREADY_RUN; case AUDIO_PORT_STATE_OPENED: return CELL_OK; - default: throw fmt::format("cellAudioPortStart(%d): invalid port state (0x%x)", portNum, state); + default: throw fmt::format("cellAudioPortStart(%d): invalid port state (%d)", portNum, state); } } s32 cellAudioPortClose(u32 portNum) { - cellAudio.Warning("cellAudioPortClose(portNum=0x%x)", portNum); + cellAudio.Warning("cellAudioPortClose(portNum=%d)", portNum); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -633,13 +631,13 @@ s32 cellAudioPortClose(u32 portNum) case AUDIO_PORT_STATE_CLOSED: return CELL_AUDIO_ERROR_PORT_NOT_OPEN; case AUDIO_PORT_STATE_STARTED: return CELL_OK; case AUDIO_PORT_STATE_OPENED: return CELL_OK; - default: throw fmt::format("cellAudioPortClose(%d): invalid port state (0x%x)", portNum, state); + default: throw fmt::format("cellAudioPortClose(%d): invalid port state (%d)", portNum, state); } } s32 cellAudioPortStop(u32 portNum) { - cellAudio.Warning("cellAudioPortStop(portNum=0x%x)", portNum); + cellAudio.Warning("cellAudioPortStop(portNum=%d)", portNum); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -656,13 +654,13 @@ s32 cellAudioPortStop(u32 portNum) case AUDIO_PORT_STATE_CLOSED: return CELL_AUDIO_ERROR_PORT_NOT_RUN; case AUDIO_PORT_STATE_STARTED: return CELL_OK; case AUDIO_PORT_STATE_OPENED: return CELL_AUDIO_ERROR_PORT_NOT_RUN; - default: throw fmt::format("cellAudioPortStop(%d): invalid port state (0x%x)", portNum, state); + default: throw fmt::format("cellAudioPortStop(%d): invalid port state (%d)", portNum, state); } } s32 cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr stamp) { - cellAudio.Log("cellAudioGetPortTimestamp(portNum=0x%x, tag=0x%llx, stamp=0x%x)", portNum, tag, stamp); + cellAudio.Log("cellAudioGetPortTimestamp(portNum=%d, tag=0x%llx, stamp=*0x%x)", portNum, tag, stamp); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -692,7 +690,7 @@ s32 cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr stamp) s32 cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr tag) { - cellAudio.Log("cellAudioGetPortBlockTag(portNum=0x%x, blockNo=0x%llx, tag=0x%x)", portNum, blockNo, tag); + cellAudio.Log("cellAudioGetPortBlockTag(portNum=%d, blockNo=0x%llx, tag=*0x%x)", portNum, blockNo, tag); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -735,7 +733,7 @@ s32 cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr tag) s32 cellAudioSetPortLevel(u32 portNum, float level) { - cellAudio.Log("cellAudioSetPortLevel(portNum=0x%x, level=%f)", portNum, level); + cellAudio.Log("cellAudioSetPortLevel(portNum=%d, level=%f)", portNum, level); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -763,121 +761,118 @@ s32 cellAudioSetPortLevel(u32 portNum, float level) } else { - cellAudio.Todo("cellAudioSetPortLevel(portNum=0x%x): negative level value (%f)", portNum, level); + cellAudio.Todo("cellAudioSetPortLevel(%d): negative level value (%f)", portNum, level); } return CELL_OK; } -// Utility Functions -int cellAudioCreateNotifyEventQueue(vm::ptr id, vm::ptr key) +s32 cellAudioCreateNotifyEventQueue(vm::ptr id, vm::ptr key) { - cellAudio.Warning("cellAudioCreateNotifyEventQueue(id_addr=0x%x, key_addr=0x%x)", id.addr(), key.addr()); + cellAudio.Warning("cellAudioCreateNotifyEventQueue(id=*0x%x, key=*0x%x)", id, key); - std::lock_guard lock(g_audio.mutex); - - u64 event_key = 0; - while (Emu.GetEventManager().CheckKey((event_key << 48) | 0x80004d494f323221)) + for (u64 k = 0; k < 100; k++) { - event_key++; // experimental - //return CELL_AUDIO_ERROR_EVENT_QUEUE; - } - event_key = (event_key << 48) | 0x80004d494f323221; // left part: 0x8000, 0x8001, 0x8002 ... + const u64 key_value = 0x80004d494f323221ull + k; - std::shared_ptr eq(new event_queue_t(SYS_SYNC_FIFO, SYS_PPU_QUEUE, event_key, event_key, 32)); + std::shared_ptr queue(new event_queue_t(SYS_SYNC_FIFO, SYS_PPU_QUEUE, 0, key_value, 32)); - if (!Emu.GetEventManager().RegisterKey(eq, event_key)) - { - return CELL_AUDIO_ERROR_EVENT_QUEUE; - } - - *id = Emu.GetIdManager().GetNewID(eq); - *key = event_key; - - return CELL_OK; -} - -int cellAudioCreateNotifyEventQueueEx(vm::ptr id, vm::ptr key, u32 iFlags) -{ - cellAudio.Todo("cellAudioCreateNotifyEventQueueEx(id_addr=0x%x, key_addr=0x%x, iFlags=0x%x)", id.addr(), key.addr(), iFlags); - return CELL_OK; -} - -int cellAudioSetNotifyEventQueue(u64 key) -{ - cellAudio.Warning("cellAudioSetNotifyEventQueue(key=0x%llx)", key); - - std::lock_guard lock(g_audio.mutex); - - for (u32 i = 0; i < g_audio.keys.size(); i++) // check for duplicates - { - if (g_audio.keys[i] == key) + // register key if not used yet + if (Emu.GetEventManager().RegisterKey(queue, key_value)) { - return CELL_AUDIO_ERROR_PARAM; - } - } - g_audio.keys.push_back(key); + *id = Emu.GetIdManager().GetNewID(queue, TYPE_EVENT_QUEUE); + *key = key_value; - /*EventQueue* eq; - if (!Emu.GetEventManager().GetEventQueue(key, eq)) - { - return CELL_AUDIO_ERROR_PARAM; - }*/ - - // TODO: connect port (?????) - - return CELL_OK; -} - -int cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags) -{ - cellAudio.Todo("cellAudioSetNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags); - return CELL_OK; -} - -int cellAudioRemoveNotifyEventQueue(u64 key) -{ - cellAudio.Warning("cellAudioRemoveNotifyEventQueue(key=0x%llx)", key); - - std::lock_guard lock(g_audio.mutex); - - bool found = false; - for (u32 i = 0; i < g_audio.keys.size(); i++) - { - if (g_audio.keys[i] == key) - { - g_audio.keys.erase(g_audio.keys.begin() + i); - found = true; - break; + return CELL_OK; } } - if (!found) + return CELL_AUDIO_ERROR_EVENT_QUEUE; +} + +s32 cellAudioCreateNotifyEventQueueEx(vm::ptr id, vm::ptr key, u32 iFlags) +{ + cellAudio.Todo("cellAudioCreateNotifyEventQueueEx(id=*0x%x, key=*0x%x, iFlags=0x%x)", id, key, iFlags); + + if (iFlags & ~CELL_AUDIO_CREATEEVENTFLAG_SPU) { - // ??? return CELL_AUDIO_ERROR_PARAM; } - /*EventQueue* eq; - if (!Emu.GetEventManager().GetEventQueue(key, eq)) - { - return CELL_AUDIO_ERROR_PARAM; - }*/ + // TODO - // TODO: disconnect port + return CELL_AUDIO_ERROR_EVENT_QUEUE; +} + +s32 cellAudioSetNotifyEventQueue(u64 key) +{ + cellAudio.Warning("cellAudioSetNotifyEventQueue(key=0x%llx)", key); + + if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) + { + return CELL_AUDIO_ERROR_NOT_INIT; + } + + std::lock_guard lock(g_audio.mutex); + + for (auto k : g_audio.keys) // check for duplicates + { + if (k == key) + { + return CELL_AUDIO_ERROR_TRANS_EVENT; + } + } + + g_audio.keys.emplace_back(key); return CELL_OK; } -int cellAudioRemoveNotifyEventQueueEx(u64 key, u32 iFlags) +s32 cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags) +{ + cellAudio.Todo("cellAudioSetNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags); + + // TODO + + return CELL_OK; +} + +s32 cellAudioRemoveNotifyEventQueue(u64 key) +{ + cellAudio.Warning("cellAudioRemoveNotifyEventQueue(key=0x%llx)", key); + + if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) + { + return CELL_AUDIO_ERROR_NOT_INIT; + } + + std::lock_guard lock(g_audio.mutex); + + for (auto i = g_audio.keys.begin(); i != g_audio.keys.end(); i++) + { + if (*i == key) + { + g_audio.keys.erase(i); + + return CELL_OK; + } + } + + return CELL_AUDIO_ERROR_TRANS_EVENT; +} + +s32 cellAudioRemoveNotifyEventQueueEx(u64 key, u32 iFlags) { cellAudio.Todo("cellAudioRemoveNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags); + + // TODO + return CELL_OK; } s32 cellAudioAddData(u32 portNum, vm::ptr src, u32 samples, float volume) { - cellAudio.Log("cellAudioAddData(portNum=%d, src=0x%x, samples=%d, volume=%f)", portNum, src, samples, volume); + cellAudio.Log("cellAudioAddData(portNum=%d, src=*0x%x, samples=%d, volume=%f)", portNum, src, samples, volume); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -892,7 +887,7 @@ s32 cellAudioAddData(u32 portNum, vm::ptr src, u32 samples, float volume) if (samples != 256) { // despite the docs, seems that only fixed value is supported - cellAudio.Error("cellAudioAddData(): invalid samples value (0x%x)", samples); + cellAudio.Error("cellAudioAddData(): invalid samples value (%d)", samples); return CELL_AUDIO_ERROR_PARAM; } @@ -910,7 +905,7 @@ s32 cellAudioAddData(u32 portNum, vm::ptr src, u32 samples, float volume) s32 cellAudioAdd2chData(u32 portNum, vm::ptr src, u32 samples, float volume) { - cellAudio.Log("cellAudioAdd2chData(portNum=%d, src=0x%x, samples=%d, volume=%f)", portNum, src, samples, volume); + cellAudio.Log("cellAudioAdd2chData(portNum=%d, src=*0x%x, samples=%d, volume=%f)", portNum, src, samples, volume); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -925,7 +920,7 @@ s32 cellAudioAdd2chData(u32 portNum, vm::ptr src, u32 samples, float volu if (samples != 256) { // despite the docs, seems that only fixed value is supported - cellAudio.Error("cellAudioAdd2chData(): invalid samples value (0x%x)", samples); + cellAudio.Error("cellAudioAdd2chData(): invalid samples value (%d)", samples); return CELL_AUDIO_ERROR_PARAM; } @@ -973,7 +968,7 @@ s32 cellAudioAdd2chData(u32 portNum, vm::ptr src, u32 samples, float volu s32 cellAudioAdd6chData(u32 portNum, vm::ptr src, float volume) { - cellAudio.Log("cellAudioAdd6chData(portNum=%d, src=0x%x, volume=%f)", portNum, src, volume); + cellAudio.Log("cellAudioAdd6chData(portNum=%d, src=*0x%x, volume=%f)", portNum, src, volume); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -1015,27 +1010,27 @@ s32 cellAudioAdd6chData(u32 portNum, vm::ptr src, float volume) return CELL_OK; } -int cellAudioMiscSetAccessoryVolume(u32 devNum, float volume) +s32 cellAudioMiscSetAccessoryVolume(u32 devNum, float volume) { - cellAudio.Todo("cellAudioMiscSetAccessoryVolume(devNum=0x%x, volume=%f)", devNum, volume); + cellAudio.Todo("cellAudioMiscSetAccessoryVolume(devNum=%d, volume=%f)", devNum, volume); return CELL_OK; } -int cellAudioSendAck(u64 data3) +s32 cellAudioSendAck(u64 data3) { cellAudio.Todo("cellAudioSendAck(data3=0x%llx)", data3); return CELL_OK; } -int cellAudioSetPersonalDevice(int iPersonalStream, int iDevice) +s32 cellAudioSetPersonalDevice(s32 iPersonalStream, s32 iDevice) { - cellAudio.Todo("cellAudioSetPersonalDevice(iPersonalStream=0x%x, iDevice=0x%x)", iPersonalStream, iDevice); + cellAudio.Todo("cellAudioSetPersonalDevice(iPersonalStream=%d, iDevice=%d)", iPersonalStream, iDevice); return CELL_OK; } -int cellAudioUnsetPersonalDevice(int iPersonalStream) +s32 cellAudioUnsetPersonalDevice(s32 iPersonalStream) { - cellAudio.Todo("cellAudioUnsetPersonalDevice(iPersonalStream=0x%x)", iPersonalStream); + cellAudio.Todo("cellAudioUnsetPersonalDevice(iPersonalStream=%d)", iPersonalStream); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellFs.cpp b/rpcs3/Emu/SysCalls/Modules/cellFs.cpp index ab5c8ad85c..d24a129d62 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellFs.cpp @@ -15,31 +15,6 @@ extern Module cellFs; -struct CellFsDirectoryEntry -{ - CellFsStat attribute; - CellFsDirent entry_name; -}; - -struct FsRingBufferConfig -{ - CellFsRingBuffer m_ring_buffer; // Currently unused after assignment - u32 m_buffer; - u64 m_fs_status; - u64 m_regid; - u32 m_alloc_mem_size; - u32 m_current_addr; - - FsRingBufferConfig() - : m_fs_status(CELL_FS_ST_NOT_INITIALIZED) - , m_regid(0) - , m_alloc_mem_size(0) - , m_current_addr(0) - , m_ring_buffer() { } - -} fs_config; - - s32 cellFsOpen(vm::ptr path, s32 flags, vm::ptr fd, vm::ptr arg, u64 size) { cellFs.Warning("cellFsOpen(path=*0x%x, flags=%#o, fd=*0x%x, arg=*0x%x, size=0x%llx) -> sys_fs_open()", path, flags, fd, arg, size); @@ -89,7 +64,7 @@ s32 cellFsReaddir(u32 fd, vm::ptr dir, vm::ptr nread) cellFs.Log("cellFsReaddir(fd=0x%x, dir=*0x%x, nread=*0x%x)", fd, dir, nread); // call the syscall - return dir && nread ? sys_fs_readdir(fd, dir, nread) : CELL_EFAULT; + return dir && nread ? sys_fs_readdir(fd, dir, nread) : CELL_FS_EFAULT; } s32 cellFsClosedir(u32 fd) @@ -163,7 +138,7 @@ s32 cellFsLseek(u32 fd, s64 offset, u32 whence, vm::ptr pos) cellFs.Log("cellFsLseek(fd=0x%x, offset=0x%llx, whence=0x%x, pos=*0x%x)", fd, offset, whence, pos); // call the syscall - return pos ? sys_fs_lseek(fd, offset, whence, pos) : CELL_EFAULT; + return pos ? sys_fs_lseek(fd, offset, whence, pos) : CELL_FS_EFAULT; } s32 cellFsFsync(u32 fd) @@ -178,7 +153,7 @@ s32 cellFsFGetBlockSize(PPUThread& CPU, u32 fd, vm::ptr sector_size, vm::pt cellFs.Log("cellFsFGetBlockSize(fd=0x%x, sector_size=*0x%x, block_size=*0x%x)", fd, sector_size, block_size); // call the syscall - return sector_size && block_size ? sys_fs_fget_block_size(fd, sector_size, block_size, vm::stackvar>(CPU), vm::stackvar>(CPU)) : CELL_EFAULT; + return sector_size && block_size ? sys_fs_fget_block_size(fd, sector_size, block_size, vm::stackvar>(CPU), vm::stackvar>(CPU)) : CELL_FS_EFAULT; } s32 cellFsGetBlockSize(PPUThread& CPU, vm::ptr path, vm::ptr sector_size, vm::ptr block_size) @@ -236,8 +211,11 @@ s32 cellFsGetDirectoryEntries(u32 fd, vm::ptr entries, u32 cellFs.Warning("cellFsGetDirectoryEntries(fd=0x%x, entries=*0x%x, entries_size=0x%x, data_count=*0x%x)", fd, entries, entries_size, data_count); std::shared_ptr directory; + if (!Emu.GetIdManager().GetIDData(fd, directory)) - return CELL_ESRCH; + { + return CELL_FS_EBADF; + } const DirEntryInfo* info = directory->Read(); if (info) @@ -280,6 +258,8 @@ s32 cellFsReadWithOffset(u32 fd, u64 offset, vm::ptr buf, u64 buffer_size, return CELL_FS_EBADF; } + std::lock_guard lock(file->mutex); + const auto old_position = file->file->Tell(); file->file->Seek(offset); @@ -309,6 +289,8 @@ s32 cellFsWriteWithOffset(u32 fd, u64 offset, vm::ptr buf, u64 data_ return CELL_FS_EBADF; } + std::lock_guard lock(file->mutex); + const auto old_position = file->file->Tell(); file->file->Seek(offset); @@ -325,27 +307,55 @@ s32 cellFsWriteWithOffset(u32 fd, u64 offset, vm::ptr buf, u64 data_ return CELL_OK; } -s32 cellFsStReadInit(u32 fd, vm::ptr ringbuf) +s32 cellFsStReadInit(u32 fd, vm::ptr ringbuf) { cellFs.Warning("cellFsStReadInit(fd=0x%x, ringbuf=*0x%x)", fd, ringbuf); + if (ringbuf->copy.data() & ~se32(CELL_FS_ST_COPYLESS)) + { + return CELL_FS_EINVAL; + } + + if (ringbuf->block_size.data() & se64(0xfff)) // check if a multiple of sector size + { + return CELL_FS_EINVAL; + } + + if (ringbuf->ringbuf_size % ringbuf->block_size) // check if a multiple of block_size + { + return CELL_FS_EINVAL; + } + std::shared_ptr file; + if (!Emu.GetIdManager().GetIDData(fd, file)) - return CELL_ESRCH; + { + return CELL_FS_EBADF; + } + + if (file->flags & CELL_FS_O_WRONLY) + { + return CELL_FS_EPERM; + } - fs_config.m_ring_buffer = *ringbuf; + std::lock_guard lock(file->mutex); - // If the size is less than 1MB - if (ringbuf->ringbuf_size < 0x40000000) - fs_config.m_alloc_mem_size = (((u32)ringbuf->ringbuf_size + 64 * 1024 - 1) / (64 * 1024)) * (64 * 1024); - else - fs_config.m_alloc_mem_size = (((u32)ringbuf->ringbuf_size + 1024 * 1024 - 1) / (1024 * 1024)) * (1024 * 1024); + if (!file->st_status.compare_and_swap_test(SSS_NOT_INITIALIZED, SSS_INITIALIZED)) + { + return CELL_FS_EBUSY; + } - // alloc memory - fs_config.m_buffer = (u32)Memory.Alloc(fs_config.m_alloc_mem_size, 1024); - memset(vm::get_ptr(fs_config.m_buffer), 0, fs_config.m_alloc_mem_size); + file->st_ringbuf_size = ringbuf->ringbuf_size; + file->st_block_size = ringbuf->ringbuf_size; + file->st_trans_rate = ringbuf->transfer_rate; + file->st_copyless = ringbuf->copy.data() == se32(CELL_FS_ST_COPYLESS); - fs_config.m_fs_status = CELL_FS_ST_INITIALIZED; + const u64 alloc_size = align(file->st_ringbuf_size, file->st_ringbuf_size < 1024 * 1024 ? 64 * 1024 : 1024 * 1024); + + file->st_buffer = vm::alloc(static_cast(alloc_size), vm::main); + file->st_read_size = 0; + file->st_total_read = 0; + file->st_copied = 0; return CELL_OK; } @@ -355,11 +365,20 @@ s32 cellFsStReadFinish(u32 fd) cellFs.Warning("cellFsStReadFinish(fd=0x%x)", fd); std::shared_ptr file; - if (!Emu.GetIdManager().GetIDData(fd, file)) - return CELL_ESRCH; - Memory.Free(fs_config.m_buffer); - fs_config.m_fs_status = CELL_FS_ST_NOT_INITIALIZED; + if (!Emu.GetIdManager().GetIDData(fd, file)) + { + return CELL_FS_EBADF; // ??? + } + + std::lock_guard lock(file->mutex); + + if (!file->st_status.compare_and_swap_test(SSS_INITIALIZED, SSS_NOT_INITIALIZED)) + { + return CELL_FS_ENXIO; + } + + vm::dealloc(file->st_buffer, vm::main); return CELL_OK; } @@ -369,13 +388,22 @@ s32 cellFsStReadGetRingBuf(u32 fd, vm::ptr ringbuf) cellFs.Warning("cellFsStReadGetRingBuf(fd=0x%x, ringbuf=*0x%x)", fd, ringbuf); std::shared_ptr file; + if (!Emu.GetIdManager().GetIDData(fd, file)) - return CELL_ESRCH; + { + return CELL_FS_EBADF; + } - *ringbuf = fs_config.m_ring_buffer; + if (file->st_status.read_sync() == SSS_NOT_INITIALIZED) + { + return CELL_FS_ENXIO; + } + + ringbuf->ringbuf_size = file->st_ringbuf_size; + ringbuf->block_size = file->st_block_size; + ringbuf->transfer_rate = file->st_trans_rate; + ringbuf->copy = file->st_copyless ? CELL_FS_ST_COPYLESS : CELL_FS_ST_COPY; - cellFs.Warning("*** fs stream config: block_size=0x%llx, copy=0x%x, ringbuf_size=0x%llx, transfer_rate=0x%llx", - ringbuf->block_size, ringbuf->copy, ringbuf->ringbuf_size, ringbuf->transfer_rate); return CELL_OK; } @@ -384,10 +412,31 @@ s32 cellFsStReadGetStatus(u32 fd, vm::ptr status) cellFs.Warning("cellFsStReadGetRingBuf(fd=0x%x, status=*0x%x)", fd, status); std::shared_ptr file; - if (!Emu.GetIdManager().GetIDData(fd, file)) - return CELL_ESRCH; - *status = fs_config.m_fs_status; + if (!Emu.GetIdManager().GetIDData(fd, file)) + { + return CELL_FS_EBADF; + } + + switch (file->st_status.read_sync()) + { + case SSS_INITIALIZED: + case SSS_STOPPED: + { + *status = CELL_FS_ST_INITIALIZED | CELL_FS_ST_STOP; + break; + } + case SSS_STARTED: + { + *status = CELL_FS_ST_INITIALIZED | CELL_FS_ST_PROGRESS; + break; + } + default: + { + *status = CELL_FS_ST_NOT_INITIALIZED | CELL_FS_ST_STOP; + break; + } + } return CELL_OK; } @@ -397,24 +446,100 @@ s32 cellFsStReadGetRegid(u32 fd, vm::ptr regid) cellFs.Warning("cellFsStReadGetRingBuf(fd=0x%x, regid=*0x%x)", fd, regid); std::shared_ptr file; - if (!Emu.GetIdManager().GetIDData(fd, file)) - return CELL_ESRCH; - *regid = fs_config.m_regid; + if (!Emu.GetIdManager().GetIDData(fd, file)) + { + return CELL_FS_EBADF; + } + + if (file->st_status.read_sync() == SSS_NOT_INITIALIZED) + { + return CELL_FS_ENXIO; + } + + *regid = file->st_total_read - file->st_copied; return CELL_OK; } s32 cellFsStReadStart(u32 fd, u64 offset, u64 size) { - cellFs.Todo("cellFsStReadStart(fd=0x%x, offset=0x%llx, size=0x%llx)", fd, offset, size); + cellFs.Warning("cellFsStReadStart(fd=0x%x, offset=0x%llx, size=0x%llx)", fd, offset, size); std::shared_ptr file; - if (!Emu.GetIdManager().GetIDData(fd, file)) - return CELL_ESRCH; - fs_config.m_current_addr = fs_config.m_buffer + (u32)offset; - fs_config.m_fs_status = CELL_FS_ST_PROGRESS; + if (!Emu.GetIdManager().GetIDData(fd, file)) + { + return CELL_FS_EBADF; + } + + switch (auto status = file->st_status.compare_and_swap(SSS_INITIALIZED, SSS_STARTED)) + { + case SSS_NOT_INITIALIZED: + { + return CELL_FS_ENXIO; + } + + case SSS_STARTED: + { + return CELL_FS_EBUSY; + } + } + + offset = std::min(file->file->GetSize(), offset); + size = std::min(file->file->GetSize() - offset, size); + + file->st_thread.set_name(fmt::format("FS ST Thread[0x%x]", fd)); + file->st_read_size = size; + + file->st_thread.start([=]() + { + std::unique_lock lock(file->mutex); + + while (file->st_status.read_relaxed() == SSS_STARTED && !Emu.IsStopped()) + { + // check free space in buffer and available data in stream + if (file->st_total_read - file->st_copied <= file->st_ringbuf_size - file->st_block_size && file->st_total_read < file->st_read_size) + { + // get buffer position + const u32 position = vm::cast(file->st_buffer + file->st_total_read % file->st_ringbuf_size); + + // read data + auto old = file->file->Tell(); + file->file->Seek(offset + file->st_total_read); + auto res = file->file->Read(vm::get_ptr(position), file->st_block_size); + file->file->Seek(old); + + // notify + file->st_total_read += res; + file->cv.notify_one(); + } + + // check callback condition if set + if (file->st_callback.data.func) + { + const u64 available = file->st_total_read - file->st_copied; + + if (available >= file->st_callback.data.size) + { + const auto func = file->st_callback.exchange({}).func; + + Emu.GetCallbackManager().Async([=](PPUThread& CPU) + { + func(CPU, fd, available); + }); + } + } + + file->cv.wait_for(lock, std::chrono::milliseconds(1)); + } + + file->st_status.compare_and_swap(SSS_STOPPED, SSS_INITIALIZED); + file->st_read_size = 0; + file->st_total_read = 0; + file->st_copied = 0; + file->st_callback.data = {}; + }); return CELL_OK; } @@ -424,10 +549,28 @@ s32 cellFsStReadStop(u32 fd) cellFs.Warning("cellFsStReadStop(fd=0x%x)", fd); std::shared_ptr file; - if (!Emu.GetIdManager().GetIDData(fd, file)) - return CELL_ESRCH; - fs_config.m_fs_status = CELL_FS_ST_STOP; + if (!Emu.GetIdManager().GetIDData(fd, file)) + { + return CELL_FS_EBADF; + } + + switch (auto status = file->st_status.compare_and_swap(SSS_STARTED, SSS_STOPPED)) + { + case SSS_NOT_INITIALIZED: + { + return CELL_FS_ENXIO; + } + + case SSS_INITIALIZED: + case SSS_STOPPED: + { + return CELL_OK; + } + } + + file->cv.notify_all(); + file->st_thread.join(); return CELL_OK; } @@ -437,60 +580,149 @@ s32 cellFsStRead(u32 fd, vm::ptr buf, u64 size, vm::ptr rsize) cellFs.Warning("cellFsStRead(fd=0x%x, buf=*0x%x, size=0x%llx, rsize=*0x%x)", fd, buf, size, rsize); std::shared_ptr file; + if (!Emu.GetIdManager().GetIDData(fd, file)) - return CELL_ESRCH; + { + return CELL_FS_EBADF; + } - // TODO: use ringbuffer (fs_config) - fs_config.m_regid += size; + if (file->st_status.read_sync() == SSS_NOT_INITIALIZED || file->st_copyless) + { + return CELL_FS_ENXIO; + } - if (file->file->Eof()) - return CELL_FS_ERANGE; + const u64 copied = file->st_copied.load(); + const u32 position = vm::cast(file->st_buffer + copied % file->st_ringbuf_size); + const u64 total_read = file->st_total_read.load(); + const u32 copy_size = vm::cast(*rsize = std::min(size, total_read - copied)); + + // copy data + const u32 first_size = std::min(copy_size, file->st_ringbuf_size - (position - file->st_buffer)); + memcpy(buf.get_ptr(), vm::get_ptr(position), first_size); + memcpy((buf + first_size).get_ptr(), vm::get_ptr(file->st_buffer), copy_size - first_size); - *rsize = file->file->Read(buf.get_ptr(), size); + // notify + file->st_copied += copy_size; + file->cv.notify_one(); - return CELL_OK; + // check end of stream + return total_read < file->st_read_size ? CELL_OK : CELL_FS_ERANGE; } -s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr> addr, vm::ptr size) +s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr addr, vm::ptr size) { - cellFs.Todo("cellFsStReadGetCurrentAddr(fd=0x%x, addr=*0x%x, size=*0x%x)", fd, addr, size); + cellFs.Warning("cellFsStReadGetCurrentAddr(fd=0x%x, addr=*0x%x, size=*0x%x)", fd, addr, size); std::shared_ptr file; - if (!Emu.GetIdManager().GetIDData(fd, file)) - return CELL_ESRCH; - return CELL_OK; + if (!Emu.GetIdManager().GetIDData(fd, file)) + { + return CELL_FS_EBADF; + } + + if (file->st_status.read_sync() == SSS_NOT_INITIALIZED || !file->st_copyless) + { + return CELL_FS_ENXIO; + } + + const u64 copied = file->st_copied.load(); + const u32 position = vm::cast(file->st_buffer + copied % file->st_ringbuf_size); + const u64 total_read = file->st_total_read.load(); + + if ((*size = std::min(file->st_ringbuf_size - (position - file->st_buffer), total_read - copied)).data()) + { + *addr = position; + } + else + { + *addr = 0; + } + + // check end of stream + return total_read < file->st_read_size ? CELL_OK : CELL_FS_ERANGE; } s32 cellFsStReadPutCurrentAddr(u32 fd, vm::ptr addr, u64 size) { - cellFs.Todo("cellFsStReadPutCurrentAddr(fd=0x%x, addr=*0x%x, size=0x%llx)", fd, addr, size); + cellFs.Warning("cellFsStReadPutCurrentAddr(fd=0x%x, addr=*0x%x, size=0x%llx)", fd, addr, size); std::shared_ptr file; - if (!Emu.GetIdManager().GetIDData(fd, file)) - return CELL_ESRCH; - return CELL_OK; + if (!Emu.GetIdManager().GetIDData(fd, file)) + { + return CELL_FS_EBADF; + } + + if (file->st_status.read_sync() == SSS_NOT_INITIALIZED || !file->st_copyless) + { + return CELL_FS_ENXIO; + } + + const u64 copied = file->st_copied.load(); + const u64 total_read = file->st_total_read.load(); + + // notify + file->st_copied += size; + file->cv.notify_one(); + + // check end of stream + return total_read < file->st_read_size ? CELL_OK : CELL_FS_ERANGE; } s32 cellFsStReadWait(u32 fd, u64 size) { - cellFs.Todo("cellFsStReadWait(fd=0x%x, size=0x%llx)", fd, size); + cellFs.Warning("cellFsStReadWait(fd=0x%x, size=0x%llx)", fd, size); std::shared_ptr file; + if (!Emu.GetIdManager().GetIDData(fd, file)) - return CELL_ESRCH; + { + return CELL_FS_EBADF; + } + + if (file->st_status.read_sync() == SSS_NOT_INITIALIZED) + { + return CELL_FS_ENXIO; + } + + std::unique_lock lock(file->mutex); + + while (file->st_total_read - file->st_copied < size && file->st_total_read < file->st_read_size) + { + // wait for size availability or stream end + + if (Emu.IsStopped()) + { + cellFs.Warning("cellFsStReadWait(0x%x) aborted", fd); + return CELL_OK; + } + + file->cv.wait_for(lock, std::chrono::milliseconds(1)); + } return CELL_OK; } -s32 cellFsStReadWaitCallback(u32 fd, u64 size, vm::ptr func) +s32 cellFsStReadWaitCallback(u32 fd, u64 size, fs_st_cb_t func) { - cellFs.Todo("cellFsStReadWaitCallback(fd=0x%x, size=0x%llx, func=*0x%x)", fd, size, func); + cellFs.Warning("cellFsStReadWaitCallback(fd=0x%x, size=0x%llx, func=*0x%x)", fd, size, func); std::shared_ptr file; + if (!Emu.GetIdManager().GetIDData(fd, file)) - return CELL_ESRCH; + { + return CELL_FS_EBADF; + } + + if (file->st_status.read_sync() == SSS_NOT_INITIALIZED) + { + return CELL_FS_ENXIO; + } + + if (!file->st_callback.compare_and_swap_test({}, { vm::cast(size, "size"), func })) + { + return CELL_FS_EIO; + } return CELL_OK; } @@ -601,7 +833,7 @@ s32 cellFsSdataOpen(PPUThread& CPU, vm::ptr path, s32 flags, vm::ptr if (flags != CELL_FS_O_RDONLY) { - return CELL_EINVAL; + return CELL_FS_EINVAL; } return cellFsOpen(path, CELL_FS_O_RDONLY, fd, vm::stackvar>(CPU), 8); @@ -634,14 +866,10 @@ s32 cellFsSdataOpenByFd(u32 mself_fd, s32 flags, vm::ptr sdata_fd, u64 offs return CELL_OK; } -std::mutex g_fs_aio_mutex; - using fs_aio_cb_t = vm::ptr xaio, s32 error, s32 xid, u64 size)>; void fsAio(vm::ptr aio, bool write, s32 xid, fs_aio_cb_t func) { - std::lock_guard lock(g_fs_aio_mutex); - cellFs.Notice("FS AIO Request(%d): fd=0x%x, offset=0x%llx, buf=*0x%x, size=0x%llx, user_data=0x%llx", xid, aio->fd, aio->offset, aio->buf, aio->size, aio->user_data); s32 error = CELL_OK; @@ -655,6 +883,8 @@ void fsAio(vm::ptr aio, bool write, s32 xid, fs_aio_cb_t func) } else { + std::lock_guard lock(file->mutex); + const auto old_position = file->file->Tell(); file->file->Seek(aio->offset); @@ -704,7 +934,9 @@ s32 cellFsAioRead(vm::ptr aio, vm::ptr id, fs_aio_cb_t func) // TODO: detect mount point and send AIO request to the AIO thread of this mount point - thread_t("FS AIO Read Thread", std::bind(fsAio, aio, false, (*id = ++g_fs_aio_id), func)).detach(); + const s32 xid = (*id = ++g_fs_aio_id); + + thread_t("FS AIO Read Thread", std::bind(fsAio, aio, false, xid, func)).detach(); return CELL_OK; } @@ -720,7 +952,9 @@ s32 cellFsAioWrite(vm::ptr aio, vm::ptr id, fs_aio_cb_t func) // TODO: detect mount point and send AIO request to the AIO thread of this mount point - thread_t("FS AIO Write Thread", std::bind(fsAio, aio, true, (*id = ++g_fs_aio_id), func)).detach(); + const s32 xid = (*id = ++g_fs_aio_id); + + thread_t("FS AIO Write Thread", std::bind(fsAio, aio, true, xid, func)).detach(); return CELL_OK; } @@ -746,8 +980,11 @@ s32 cellFsSetIoBufferFromDefaultContainer(u32 fd, u32 buffer_size, u32 page_type cellFs.Todo("cellFsSetIoBufferFromDefaultContainer(fd=%d, buffer_size=%d, page_type=%d)", fd, buffer_size, page_type); std::shared_ptr file; + if (!Emu.GetIdManager().GetIDData(fd, file)) - return CELL_ESRCH; + { + CELL_FS_EBADF; + } return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellFs.h b/rpcs3/Emu/SysCalls/Modules/cellFs.h index d45512d5ff..c5cc965795 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFs.h +++ b/rpcs3/Emu/SysCalls/Modules/cellFs.h @@ -1,5 +1,11 @@ #pragma once +struct CellFsDirectoryEntry +{ + CellFsStat attribute; + CellFsDirent entry_name; +}; + // CellFsRingBuffer.copy enum : s32 { @@ -15,7 +21,7 @@ struct CellFsRingBuffer be_t copy; }; -// cellFsSt(Read|Write)GetStatus status +// cellFsStReadGetStatus status enum : u64 { CELL_FS_ST_INITIALIZED = 0x0001, diff --git a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp index ce29a0f55e..1ce25e3082 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp @@ -45,7 +45,8 @@ int cellGifDecOpen(u32 mainHandle, vm::ptr subHandle, vm::ptr file(new fs_file_t(std::shared_ptr(Emu.GetVFS().OpenFile(src->fileName.get_ptr(), vfsRead)), 0, 0)); + std::shared_ptr file_s(Emu.GetVFS().OpenFile(src->fileName.get_ptr(), vfsRead)); + std::shared_ptr file(new fs_file_t(file_s, 0, 0)); if (!file) return CELL_GIFDEC_ERROR_OPEN_FILE; current_subHandle->fd = Emu.GetIdManager().GetNewID(file, TYPE_FS_FILE); current_subHandle->fileSize = file->file->GetSize(); diff --git a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp index c2b58805d5..600f58bb40 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp @@ -51,7 +51,8 @@ int cellJpgDecOpen(u32 mainHandle, vm::ptr subHandle, vm::ptr file(new fs_file_t(std::shared_ptr(Emu.GetVFS().OpenFile(src->fileName.get_ptr(), vfsRead)), 0, 0)); + std::shared_ptr file_s(Emu.GetVFS().OpenFile(src->fileName.get_ptr(), vfsRead)); + std::shared_ptr file(new fs_file_t(file_s, 0, 0)); if (!file) return CELL_JPGDEC_ERROR_OPEN_FILE; current_subHandle->fd = Emu.GetIdManager().GetNewID(file, TYPE_FS_FILE); current_subHandle->fileSize = file->file->GetSize(); diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp index b3de15a608..162e7a6ee9 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp @@ -82,7 +82,8 @@ s32 pngDecOpen( case se32(CELL_PNGDEC_FILE): { // Get file descriptor and size - std::shared_ptr file(new fs_file_t(std::shared_ptr(Emu.GetVFS().OpenFile(src->fileName.get_ptr(), vfsRead)), 0, 0)); + std::shared_ptr file_s(Emu.GetVFS().OpenFile(src->fileName.get_ptr(), vfsRead)); + std::shared_ptr file(new fs_file_t(file_s, 0, 0)); if (!file) return CELL_PNGDEC_ERROR_OPEN_FILE; stream->fd = Emu.GetIdManager().GetNewID(file, TYPE_FS_FILE); stream->fileSize = file->file->GetSize(); diff --git a/rpcs3/Emu/SysCalls/Modules/sys_net.cpp b/rpcs3/Emu/SysCalls/Modules/sys_net.cpp index 86f4b2032c..fe69ad6560 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_net.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_net.cpp @@ -504,7 +504,7 @@ s32 sys_net_free_thread_context() } // define additional macro for specific namespace -#define REG_FUNC_(name) add_ppu_func(ModuleFunc(get_function_id(#name), 0, &sys_net, bind_func(sys_net_func::name))) +#define REG_FUNC_(name) add_ppu_func(ModuleFunc(get_function_id(#name), 0, &sys_net, #name, bind_func(sys_net_func::name))) Module sys_net("sys_net", []() { diff --git a/rpcs3/Emu/SysCalls/SC_FUNC.h b/rpcs3/Emu/SysCalls/SC_FUNC.h index aa69811266..a0bf5e87be 100644 --- a/rpcs3/Emu/SysCalls/SC_FUNC.h +++ b/rpcs3/Emu/SysCalls/SC_FUNC.h @@ -1,7 +1,7 @@ #pragma once #include "Emu/Cell/PPUThread.h" -typedef void(*ppu_func_caller)(PPUThread&); +using ppu_func_caller = void(*)(PPUThread&); namespace ppu_func_detail { @@ -181,7 +181,7 @@ namespace ppu_func_detail template struct func_binder { - typedef void(*func_t)(PPUThread&, T...); + using func_t = void(*)(PPUThread&, T...); static void do_call(PPUThread& CPU, func_t func) { @@ -192,7 +192,7 @@ namespace ppu_func_detail template struct func_binder { - typedef void(*func_t)(T...); + using func_t = void(*)(T...); static void do_call(PPUThread& CPU, func_t func) { @@ -203,7 +203,7 @@ namespace ppu_func_detail template struct func_binder { - typedef RT(*func_t)(PPUThread&, T...); + using func_t = RT(*)(PPUThread&, T...); static void do_call(PPUThread& CPU, func_t func) { @@ -214,7 +214,7 @@ namespace ppu_func_detail template struct func_binder { - typedef RT(*func_t)(T...); + using func_t = RT(*)(T...); static void do_call(PPUThread& CPU, func_t func) { diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index 39f94edfd2..fa4a7db522 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -36,8 +36,6 @@ void null_func(PPUThread& CPU); -const int kSyscallTableLength = 1024; - // UNS = Unused // ROOT = Root // DBG = Debug @@ -695,7 +693,7 @@ const ppu_func_caller sc_table[1024] = null_func, null_func, null_func, null_func, null_func, //794 UNS null_func, null_func, null_func, null_func, null_func, //799 UNS - null_func,//bind_func(sys_fs_test), //800 (0x320) + bind_func(sys_fs_test), //800 (0x320) bind_func(sys_fs_open), //801 (0x321) bind_func(sys_fs_read), //802 (0x322) bind_func(sys_fs_write), //803 (0x323) @@ -712,7 +710,7 @@ const ppu_func_caller sc_table[1024] = bind_func(sys_fs_unlink), //814 (0x32E) null_func,//bind_func(sys_fs_utime), //815 (0x32F) null_func,//bind_func(sys_fs_access), //816 (0x330) - null_func,//bind_func(sys_fs_fcntl), //817 (0x331) + bind_func(sys_fs_fcntl), //817 (0x331) bind_func(sys_fs_lseek), //818 (0x332) null_func,//bind_func(sys_fs_fdatasync), //819 (0x333) null_func,//bind_func(sys_fs_fsync), //820 (0x334) @@ -890,30 +888,7 @@ const ppu_func_caller sc_table[1024] = void null_func(PPUThread& CPU) { - u32 code = (u32)CPU.GPR[11]; - //TODO: remove this - switch(code) - { - //tty - case 988: - LOG_WARNING(HLE, "SysCall 988! r3: 0x%llx, r4: 0x%llx, pc: 0x%x", - CPU.GPR[3], CPU.GPR[4], CPU.PC); - CPU.GPR[3] = 0; - return; - - case 999: - dump_enable = !dump_enable; - Emu.Pause(); - LOG_WARNING(HLE, "Dump %s", (dump_enable ? "enabled" : "disabled")); - return; - - case 1000: - Ini.HLELogging.SetValue(!Ini.HLELogging.GetValue()); - LOG_WARNING(HLE, "Log %s", (Ini.HLELogging.GetValue() ? "enabled" : "disabled")); - return; - } - - LOG_ERROR(HLE, "Unknown syscall: %d - %08x -> CELL_OK", code, code); + LOG_ERROR(HLE, "Unimplemented syscall %lld: %s -> CELL_OK", CPU.GPR[11], SysCalls::GetFuncName(CPU.GPR[11])); CPU.GPR[3] = 0; return; } @@ -933,14 +908,14 @@ void SysCalls::DoSyscall(PPUThread& CPU, u64 code) if (Ini.HLELogging.GetValue()) { - LOG_NOTICE(PPU, "SysCall called: %s [0x%llx]", "unknown", code); + LOG_NOTICE(PPU, "Syscall %d called: %s", code, SysCalls::GetFuncName(code)); } sc_table[code](CPU); if (Ini.HLELogging.GetValue()) { - LOG_NOTICE(PPU, "SysCall finished: %s [0x%llx] -> 0x%llx", "unknown", code, CPU.GPR[3]); + LOG_NOTICE(PPU, "Syscall %d finished: %s -> 0x%llx", code, SysCalls::GetFuncName(code), CPU.GPR[3]); } CPU.m_last_syscall = old_last_syscall; diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index 299d0d4507..888f7aa617 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -2,8 +2,6 @@ #include "ErrorCodes.h" #include "LogBase.h" -//#define SYSCALLS_DEBUG - class SysCallBase : public LogBase { private: @@ -21,13 +19,11 @@ public: } }; -extern bool dump_enable; - class PPUThread; class SysCalls { public: static void DoSyscall(PPUThread& CPU, u64 code); - static std::string GetHLEFuncName(const u32 fid); + static std::string GetFuncName(const u64 fid); }; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp b/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp index 4b4a0d5ca6..f252098984 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp @@ -20,6 +20,13 @@ SysCallBase sys_fs("sys_fs"); +s32 sys_fs_test(u32 arg1, u32 arg2, vm::ptr arg3, u32 arg4, vm::ptr arg5, u32 arg6) +{ + sys_fs.Todo("sys_fs_test(arg1=0x%x, arg2=0x%x, arg3=*0x%x, arg4=0x%x, arg5=*0x%x, arg6=0x%x) -> CELL_OK", arg1, arg2, arg3, arg4, arg5, arg6); + + return CELL_OK; +} + s32 sys_fs_open(vm::ptr path, s32 flags, vm::ptr fd, s32 mode, vm::ptr arg, u64 size) { sys_fs.Warning("sys_fs_open(path=*0x%x, flags=%#o, fd=*0x%x, mode=%#o, arg=*0x%x, size=0x%llx)", path, flags, fd, mode, arg, size); @@ -135,6 +142,8 @@ s32 sys_fs_read(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nread) return CELL_FS_EBADF; } + std::lock_guard lock(file->mutex); + *nread = file->file->Read(buf.get_ptr(), nbytes); return CELL_OK; @@ -151,7 +160,9 @@ s32 sys_fs_write(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nwrit return CELL_FS_EBADF; } - // TODO: return CELL_FS_EBUSY if locked + // TODO: return CELL_FS_EBUSY if locked by stream + + std::lock_guard lock(file->mutex); *nwrite = file->file->Write(buf.get_ptr(), nbytes); @@ -202,7 +213,7 @@ s32 sys_fs_readdir(u32 fd, vm::ptr dir, vm::ptr nread) if (!Emu.GetIdManager().GetIDData(fd, directory)) { - return CELL_ESRCH; + return CELL_FS_EBADF; } const DirEntryInfo* info = directory->Read(); @@ -230,7 +241,7 @@ s32 sys_fs_closedir(u32 fd) if (!Emu.GetIdManager().GetIDData(fd, directory)) { - return CELL_ESRCH; + return CELL_FS_EBADF; } Emu.GetIdManager().RemoveID(fd); @@ -318,7 +329,7 @@ s32 sys_fs_stat(vm::ptr path, vm::ptr sb) sys_fs.Error("sys_fs_stat(): size is the same (0x%x)", size); sys_fs.Warning("sys_fs_stat(): '%s' not found", path.get_ptr()); - return CELL_ENOENT; + return CELL_FS_ENOENT; } s32 sys_fs_fstat(u32 fd, vm::ptr sb) @@ -326,8 +337,11 @@ s32 sys_fs_fstat(u32 fd, vm::ptr sb) sys_fs.Warning("sys_fs_fstat(fd=0x%x, sb=*0x%x)", fd, sb); std::shared_ptr file; + if (!Emu.GetIdManager().GetIDData(fd, file)) - return CELL_ESRCH; + { + return CELL_FS_EBADF; + } sb->mode = CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR | @@ -353,11 +367,15 @@ s32 sys_fs_mkdir(vm::ptr path, s32 mode) const std::string _path = path.get_ptr(); - if (vfsDir().IsExists(_path)) - return CELL_EEXIST; + if (Emu.GetVFS().ExistsDir(_path)) + { + return CELL_FS_EEXIST; + } if (!Emu.GetVFS().CreateDir(_path)) - return CELL_EBUSY; + { + return CELL_FS_EIO; // ??? + } sys_fs.Notice("sys_fs_mkdir(): directory '%s' created", path.get_ptr()); return CELL_OK; @@ -372,32 +390,29 @@ s32 sys_fs_rename(vm::ptr from, vm::ptr to) std::string _from = from.get_ptr(); std::string _to = to.get_ptr(); + if (Emu.GetVFS().ExistsDir(_from)) { - vfsDir dir; - if (dir.IsExists(_from)) + if (!Emu.GetVFS().RenameDir(_from, _to)) { - if (!dir.Rename(_from, _to)) - return CELL_EBUSY; - - sys_fs.Notice("sys_fs_rename(): directory '%s' renamed to '%s'", from.get_ptr(), to.get_ptr()); - return CELL_OK; + return CELL_FS_EIO; // ??? } + + sys_fs.Notice("sys_fs_rename(): directory '%s' renamed to '%s'", from.get_ptr(), to.get_ptr()); + return CELL_OK; } + if (Emu.GetVFS().ExistsFile(_from)) { - vfsFile f; - - if (f.Exists(_from)) + if (!Emu.GetVFS().RenameFile(_from, _to)) { - if (!f.Rename(_from, _to)) - return CELL_EBUSY; - - sys_fs.Notice("sys_fs_rename(): file '%s' renamed to '%s'", from.get_ptr(), to.get_ptr()); - return CELL_OK; + return CELL_FS_EIO; // ??? } + + sys_fs.Notice("sys_fs_rename(): file '%s' renamed to '%s'", from.get_ptr(), to.get_ptr()); + return CELL_OK; } - return CELL_ENOENT; + return CELL_FS_ENOENT; } s32 sys_fs_rmdir(vm::ptr path) @@ -407,12 +422,15 @@ s32 sys_fs_rmdir(vm::ptr path) std::string _path = path.get_ptr(); - vfsDir d; - if (!d.IsExists(_path)) - return CELL_ENOENT; + if (!Emu.GetVFS().RemoveDir(_path)) + { + if (Emu.GetVFS().ExistsDir(_path)) + { + return CELL_FS_EIO; // ??? + } - if (!d.Remove(_path)) - return CELL_EBUSY; + return CELL_FS_ENOENT; + } sys_fs.Notice("sys_fs_rmdir(): directory '%s' removed", path.get_ptr()); return CELL_OK; @@ -425,24 +443,33 @@ s32 sys_fs_unlink(vm::ptr path) std::string _path = path.get_ptr(); - if (vfsDir().IsExists(_path)) - return CELL_EISDIR; - - if (!Emu.GetVFS().ExistsFile(_path)) - return CELL_ENOENT; - if (!Emu.GetVFS().RemoveFile(_path)) - return CELL_EACCES; + { + if (Emu.GetVFS().ExistsFile(_path)) + { + return CELL_FS_EIO; // ??? + } + + return CELL_FS_ENOENT; + } sys_fs.Notice("sys_fs_unlink(): file '%s' deleted", path.get_ptr()); return CELL_OK; } +s32 sys_fs_fcntl(u32 fd, s32 flags, u32 addr, u32 arg4, u32 arg5, u32 arg6) +{ + sys_fs.Todo("sys_fs_fcntl(fd=0x%x, flags=0x%x, addr=*0x%x, arg4=0x%x, arg5=0x%x, arg6=0x%x) -> CELL_OK", fd, flags, addr, arg4, arg5, arg6); + + return CELL_OK; +} + s32 sys_fs_lseek(u32 fd, s64 offset, s32 whence, vm::ptr pos) { sys_fs.Log("sys_fs_lseek(fd=0x%x, offset=0x%llx, whence=0x%x, pos=*0x%x)", fd, offset, whence, pos); vfsSeekMode seek_mode; + switch (whence) { case CELL_FS_SEEK_SET: seek_mode = vfsSeekSet; break; @@ -450,14 +477,20 @@ s32 sys_fs_lseek(u32 fd, s64 offset, s32 whence, vm::ptr pos) case CELL_FS_SEEK_END: seek_mode = vfsSeekEnd; break; default: sys_fs.Error("sys_fs_lseek(fd=0x%x): unknown seek whence (0x%x)", fd, whence); - return CELL_EINVAL; + return CELL_FS_EINVAL; } std::shared_ptr file; + if (!Emu.GetIdManager().GetIDData(fd, file)) - return CELL_ESRCH; + { + return CELL_FS_EBADF; + } + + std::lock_guard lock(file->mutex); *pos = file->file->Seek(offset, seek_mode); + return CELL_OK; } @@ -466,8 +499,11 @@ s32 sys_fs_fget_block_size(u32 fd, vm::ptr sector_size, vm::ptr block_ sys_fs.Todo("sys_fs_fget_block_size(fd=%d, sector_size=*0x%x, block_size=*0x%x, arg4=*0x%x, arg5=*0x%x)", fd, sector_size, block_size, arg4, arg5); std::shared_ptr file; + if (!Emu.GetIdManager().GetIDData(fd, file)) - return CELL_ESRCH; + { + CELL_FS_EBADF; + } *sector_size = 4096; // ? *block_size = 4096; // ? @@ -495,8 +531,9 @@ s32 sys_fs_truncate(vm::ptr path, u64 size) if (!f.IsOpened()) { sys_fs.Warning("sys_fs_truncate(): '%s' not found", path.get_ptr()); - return CELL_ENOENT; + return CELL_FS_ENOENT; } + u64 initialSize = f.GetSize(); if (initialSize < size) @@ -522,8 +559,11 @@ s32 sys_fs_ftruncate(u32 fd, u64 size) sys_fs.Warning("sys_fs_ftruncate(fd=0x%x, size=0x%llx)", fd, size); std::shared_ptr file; + if (!Emu.GetIdManager().GetIDData(fd, file)) - return CELL_ESRCH; + { + CELL_FS_EBADF; + } u64 initialSize = file->file->GetSize(); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_fs.h b/rpcs3/Emu/SysCalls/lv2/sys_fs.h index 08f5d86773..7466548234 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_fs.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_fs.h @@ -1,4 +1,5 @@ #pragma once +#include "Utilities/Thread.h" #pragma pack(push, 4) @@ -144,21 +145,60 @@ struct CellFsUtimbuf #pragma pack(pop) +// Stream Support Status (st_status) +enum : u32 +{ + SSS_NOT_INITIALIZED = 0, + SSS_INITIALIZED, + SSS_STARTED, + SSS_STOPPED, +}; + +using fs_st_cb_t = vm::ptr; + +struct fs_st_cb_rec_t +{ + u32 size; + fs_st_cb_t func; +}; + struct fs_file_t { const std::shared_ptr file; const s32 mode; const s32 flags; + std::mutex mutex; + std::condition_variable cv; + + atomic_le_t st_status; + + u64 st_ringbuf_size; + u64 st_block_size; + u64 st_trans_rate; + bool st_copyless; + + thread_t st_thread; + + u32 st_buffer; + u64 st_read_size; + std::atomic st_total_read; + std::atomic st_copied; + + atomic_le_t st_callback; + fs_file_t(std::shared_ptr& file, s32 mode, s32 flags) : file(file) , mode(mode) , flags(flags) + , st_status({ SSS_NOT_INITIALIZED }) + , st_callback({}) { } }; // SysCalls +s32 sys_fs_test(u32 arg1, u32 arg2, vm::ptr arg3, u32 arg4, vm::ptr arg5, u32 arg6); s32 sys_fs_open(vm::ptr path, s32 flags, vm::ptr fd, s32 mode, vm::ptr arg, u64 size); s32 sys_fs_read(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nread); s32 sys_fs_write(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nwrite); @@ -172,6 +212,7 @@ s32 sys_fs_mkdir(vm::ptr path, s32 mode); s32 sys_fs_rename(vm::ptr from, vm::ptr to); s32 sys_fs_rmdir(vm::ptr path); s32 sys_fs_unlink(vm::ptr path); +s32 sys_fs_fcntl(u32 fd, s32 flags, u32 addr, u32 arg4, u32 arg5, u32 arg6); s32 sys_fs_lseek(u32 fd, s64 offset, s32 whence, vm::ptr pos); s32 sys_fs_fget_block_size(u32 fd, vm::ptr sector_size, vm::ptr block_size, vm::ptr arg4, vm::ptr arg5); s32 sys_fs_get_block_size(vm::ptr path, vm::ptr sector_size, vm::ptr block_size, vm::ptr arg4); diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index b75ace91b8..6c89d7cf04 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -167,8 +167,8 @@ namespace loader module.exports[fnid] = fstub; - //LOG_NOTICE(LOADER, "Exported function '%s' in '%s' module (LLE)", SysCalls::GetHLEFuncName(fnid).c_str(), module_name.c_str()); - LOG_WARNING(LOADER, "**** %s: [%s] -> 0x%x", modulename.c_str(), SysCalls::GetHLEFuncName(fnid).c_str(), (u32)fstub); + //LOG_NOTICE(LOADER, "Exported function '%s' in '%s' module (LLE)", SysCalls::GetFuncName(fnid).c_str(), module_name.c_str()); + LOG_WARNING(LOADER, "**** %s: [%s] -> 0x%x", modulename.c_str(), SysCalls::GetFuncName(fnid).c_str(), (u32)fstub); } } @@ -204,7 +204,7 @@ namespace loader module.imports[fnid] = fstub; - LOG_WARNING(LOADER, "**** %s: [%s] -> 0x%x", modulename.c_str(), SysCalls::GetHLEFuncName(fnid).c_str(), (u32)fstub); + LOG_WARNING(LOADER, "**** %s: [%s] -> 0x%x", modulename.c_str(), SysCalls::GetFuncName(fnid).c_str(), (u32)fstub); } } } @@ -423,7 +423,7 @@ namespace loader if (!func) { - index = add_ppu_func(ModuleFunc(nid, 0, module, nullptr, vm::ptr::make(addr))); + index = add_ppu_func(ModuleFunc(nid, 0, module, nullptr, nullptr, vm::ptr::make(addr))); } else { @@ -435,7 +435,7 @@ namespace loader if (!vm::check_addr(addr, 8) || !vm::check_addr(i_addr = vm::read32(addr), 4)) { - LOG_ERROR(LOADER, "Failed to inject code for exported function '%s' (opd=0x%x, 0x%x)", SysCalls::GetHLEFuncName(nid), addr, i_addr); + LOG_ERROR(LOADER, "Failed to inject code for exported function '%s' (opd=0x%x, 0x%x)", SysCalls::GetFuncName(nid), addr, i_addr); } else { @@ -456,18 +456,18 @@ namespace loader if (!func) { - LOG_ERROR(LOADER, "Unimplemented function '%s' (0x%x)", SysCalls::GetHLEFuncName(nid), addr); + LOG_ERROR(LOADER, "Unimplemented function '%s' (0x%x)", SysCalls::GetFuncName(nid), addr); - index = add_ppu_func(ModuleFunc(nid, 0, module, nullptr)); + index = add_ppu_func(ModuleFunc(nid, 0, module, nullptr, nullptr)); } else { - LOG_NOTICE(LOADER, "Imported function '%s' (0x%x)", SysCalls::GetHLEFuncName(nid), addr); + LOG_NOTICE(LOADER, "Imported function '%s' (0x%x)", SysCalls::GetFuncName(nid), addr); } if (!patch_ppu_import(addr, index)) { - LOG_ERROR(LOADER, "Failed to inject code for function '%s' (0x%x)", SysCalls::GetHLEFuncName(nid), addr); + LOG_ERROR(LOADER, "Failed to inject code for function '%s' (0x%x)", SysCalls::GetFuncName(nid), addr); } } } @@ -690,15 +690,15 @@ namespace loader if (!func) { - LOG_ERROR(LOADER, "Unimplemented function '%s' in '%s' module (0x%x)", SysCalls::GetHLEFuncName(nid), module_name, addr); + LOG_ERROR(LOADER, "Unimplemented function '%s' in '%s' module (0x%x)", SysCalls::GetFuncName(nid), module_name, addr); - index = add_ppu_func(ModuleFunc(nid, 0, module, nullptr)); + index = add_ppu_func(ModuleFunc(nid, 0, module, nullptr, nullptr)); } else { const bool is_lle = func->lle_func && !(func->flags & MFF_FORCED_HLE); - LOG_NOTICE(LOADER, "Imported %sfunction '%s' in '%s' module (0x%x)", is_lle ? "LLE " : "", SysCalls::GetHLEFuncName(nid), module_name, addr); + LOG_NOTICE(LOADER, "Imported %sfunction '%s' in '%s' module (0x%x)", is_lle ? "LLE " : "", SysCalls::GetFuncName(nid), module_name, addr); } if (!patch_ppu_import(addr, index))