From 42e1d4d7525a002c2898fe1b9aa3c52ff323fa3c Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 14 Apr 2016 01:23:53 +0300 Subject: [PATCH] Partial commit: Syscalls --- .../SysCalls.cpp => Cell/lv2/lv2.cpp} | 99 ++++++------ rpcs3/Emu/{SysCalls => Cell}/lv2/sys_cond.cpp | 30 ++-- rpcs3/Emu/{SysCalls => Cell}/lv2/sys_cond.h | 8 +- rpcs3/Emu/{SysCalls => Cell}/lv2/sys_dbg.cpp | 5 +- rpcs3/Emu/{SysCalls => Cell}/lv2/sys_dbg.h | 0 .../Emu/{SysCalls => Cell}/lv2/sys_event.cpp | 121 +++++++------- rpcs3/Emu/{SysCalls => Cell}/lv2/sys_event.h | 55 +++++-- .../{SysCalls => Cell}/lv2/sys_event_flag.cpp | 28 ++-- .../{SysCalls => Cell}/lv2/sys_event_flag.h | 10 +- rpcs3/Emu/{SysCalls => Cell}/lv2/sys_fs.cpp | 151 ++++++++---------- rpcs3/Emu/{SysCalls => Cell}/lv2/sys_fs.h | 56 +++---- .../{SysCalls => Cell}/lv2/sys_interrupt.cpp | 33 ++-- .../{SysCalls => Cell}/lv2/sys_interrupt.h | 17 +- .../Emu/{SysCalls => Cell}/lv2/sys_lwcond.cpp | 25 ++- rpcs3/Emu/{SysCalls => Cell}/lv2/sys_lwcond.h | 4 +- .../{SysCalls => Cell}/lv2/sys_lwmutex.cpp | 21 ++- .../Emu/{SysCalls => Cell}/lv2/sys_lwmutex.h | 12 +- .../Emu/{SysCalls => Cell}/lv2/sys_memory.cpp | 11 +- rpcs3/Emu/{SysCalls => Cell}/lv2/sys_memory.h | 13 +- .../{SysCalls => Cell}/lv2/sys_mmapper.cpp | 14 +- .../Emu/{SysCalls => Cell}/lv2/sys_mmapper.h | 14 +- .../Emu/{SysCalls => Cell}/lv2/sys_mutex.cpp | 26 ++- rpcs3/Emu/{SysCalls => Cell}/lv2/sys_mutex.h | 14 +- .../{SysCalls => Cell}/lv2/sys_ppu_thread.cpp | 41 +++-- .../{SysCalls => Cell}/lv2/sys_ppu_thread.h | 0 .../{SysCalls => Cell}/lv2/sys_process.cpp | 8 +- .../Emu/{SysCalls => Cell}/lv2/sys_process.h | 0 rpcs3/Emu/{SysCalls => Cell}/lv2/sys_prx.cpp | 130 ++------------- rpcs3/Emu/{SysCalls => Cell}/lv2/sys_prx.h | 106 +----------- rpcs3/Emu/{SysCalls => Cell}/lv2/sys_rsx.cpp | 5 +- rpcs3/Emu/{SysCalls => Cell}/lv2/sys_rsx.h | 0 .../Emu/{SysCalls => Cell}/lv2/sys_rwlock.cpp | 38 ++--- rpcs3/Emu/{SysCalls => Cell}/lv2/sys_rwlock.h | 14 +- .../{SysCalls => Cell}/lv2/sys_semaphore.cpp | 17 +- .../{SysCalls => Cell}/lv2/sys_semaphore.h | 8 +- rpcs3/Emu/{SysCalls => Cell}/lv2/sys_spu.cpp | 137 ++++++++-------- rpcs3/Emu/{SysCalls => Cell}/lv2/sys_spu.h | 39 ++--- rpcs3/Emu/Cell/lv2/sys_sync.h | 113 +++++++++++++ rpcs3/Emu/{SysCalls => Cell}/lv2/sys_time.cpp | 5 +- rpcs3/Emu/{SysCalls => Cell}/lv2/sys_time.h | 0 .../Emu/{SysCalls => Cell}/lv2/sys_timer.cpp | 17 +- rpcs3/Emu/{SysCalls => Cell}/lv2/sys_timer.h | 33 ++-- .../Emu/{SysCalls => Cell}/lv2/sys_trace.cpp | 5 +- rpcs3/Emu/{SysCalls => Cell}/lv2/sys_trace.h | 0 rpcs3/Emu/{SysCalls => Cell}/lv2/sys_tty.cpp | 5 +- rpcs3/Emu/{SysCalls => Cell}/lv2/sys_tty.h | 0 rpcs3/Emu/{SysCalls => Cell}/lv2/sys_vm.cpp | 5 +- rpcs3/Emu/{SysCalls => Cell}/lv2/sys_vm.h | 2 +- rpcs3/Emu/SysCalls/SysCalls.h | 14 -- rpcs3/Emu/SysCalls/lv2/sys_sync.h | 42 ----- 50 files changed, 677 insertions(+), 874 deletions(-) rename rpcs3/Emu/{SysCalls/SysCalls.cpp => Cell/lv2/lv2.cpp} (97%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_cond.cpp (87%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_cond.h (81%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_dbg.cpp (59%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_dbg.h (100%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_event.cpp (72%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_event.h (65%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_event_flag.cpp (92%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_event_flag.h (93%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_fs.cpp (76%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_fs.h (87%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_interrupt.cpp (85%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_interrupt.h (65%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_lwcond.cpp (88%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_lwcond.h (84%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_lwmutex.cpp (88%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_lwmutex.h (86%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_memory.cpp (97%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_memory.h (92%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_mmapper.cpp (96%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_mmapper.h (86%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_mutex.cpp (88%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_mutex.h (72%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_ppu_thread.cpp (90%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_ppu_thread.h (100%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_process.cpp (97%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_process.h (100%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_prx.cpp (62%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_prx.h (69%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_rsx.cpp (98%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_rsx.h (100%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_rwlock.cpp (87%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_rwlock.h (70%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_semaphore.cpp (92%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_semaphore.h (87%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_spu.cpp (91%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_spu.h (86%) create mode 100644 rpcs3/Emu/Cell/lv2/sys_sync.h rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_time.cpp (97%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_time.h (100%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_timer.cpp (94%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_timer.h (63%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_trace.cpp (91%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_trace.h (100%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_tty.cpp (89%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_tty.h (100%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_vm.cpp (96%) rename rpcs3/Emu/{SysCalls => Cell}/lv2/sys_vm.h (97%) delete mode 100644 rpcs3/Emu/SysCalls/SysCalls.h delete mode 100644 rpcs3/Emu/SysCalls/lv2/sys_sync.h diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/Cell/lv2/lv2.cpp similarity index 97% rename from rpcs3/Emu/SysCalls/SysCalls.cpp rename to rpcs3/Emu/Cell/lv2/lv2.cpp index bb3ebdde99..771302c551 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/Cell/lv2/lv2.cpp @@ -1,42 +1,39 @@ #include "stdafx.h" #include "Utilities/AutoPause.h" -#include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/state.h" -#include "Modules.h" -#include "lv2/sys_lwmutex.h" -#include "lv2/sys_lwcond.h" -#include "lv2/sys_mutex.h" -#include "lv2/sys_cond.h" -#include "lv2/sys_event.h" -#include "lv2/sys_event_flag.h" -#include "lv2/sys_interrupt.h" -#include "lv2/sys_memory.h" -#include "lv2/sys_mmapper.h" -#include "lv2/sys_ppu_thread.h" -#include "lv2/sys_process.h" -#include "lv2/sys_prx.h" -#include "lv2/sys_rsx.h" -#include "lv2/sys_rwlock.h" -#include "lv2/sys_semaphore.h" -#include "lv2/sys_spu.h" -#include "lv2/sys_time.h" -#include "lv2/sys_timer.h" -#include "lv2/sys_trace.h" -#include "lv2/sys_tty.h" -#include "lv2/sys_vm.h" -#include "lv2/sys_fs.h" -#include "lv2/sys_dbg.h" +#include "Emu/Cell/PPUFunction.h" +#include "Emu/Cell/ErrorCodes.h" +#include "sys_sync.h" +#include "sys_lwmutex.h" +#include "sys_lwcond.h" +#include "sys_mutex.h" +#include "sys_cond.h" +#include "sys_event.h" +#include "sys_event_flag.h" +#include "sys_interrupt.h" +#include "sys_memory.h" +#include "sys_mmapper.h" +#include "sys_ppu_thread.h" +#include "sys_process.h" +#include "sys_prx.h" +#include "sys_rsx.h" +#include "sys_rwlock.h" +#include "sys_semaphore.h" +#include "sys_spu.h" +#include "sys_time.h" +#include "sys_timer.h" +#include "sys_trace.h" +#include "sys_tty.h" +#include "sys_vm.h" +#include "sys_fs.h" +#include "sys_dbg.h" -#include "Emu/SysCalls/Modules/cellGcmSys.h" +extern std::string ppu_get_syscall_name(u64 code); -#include "SysCalls.h" - -void null_func(PPUThread& ppu) +static void null_func(PPUThread& ppu) { - const u64 code = ppu.GPR[11]; - LOG_TODO(HLE, "Unimplemented syscall %lld: %s -> CELL_OK", code, get_ps3_function_name(~code)); + LOG_TODO(HLE, "Unimplemented syscall %s -> CELL_OK", ppu_get_syscall_name(ppu.GPR[11])); ppu.GPR[3] = 0; } @@ -45,7 +42,7 @@ void null_func(PPUThread& ppu) // DBG = Debug // PM = Product Mode // AuthID = Authentication ID -const ppu_func_caller g_sc_table[1024] = +std::array g_ppu_syscall_table { null_func, BIND_FUNC(sys_process_getpid), //1 (0x001) @@ -887,24 +884,34 @@ const ppu_func_caller g_sc_table[1024] = null_func, null_func, null_func, null_func, null_func, //1009 UNS null_func, null_func, null_func, null_func, null_func, //1014 UNS null_func, null_func, null_func, null_func, null_func, //1019 UNS - null_func, null_func, null_func, BIND_FUNC(cellGcmCallback), //1023 UNS + null_func, null_func, null_func, null_func, //1023 UNS }; -void execute_syscall_by_index(PPUThread& ppu, u64 code) +extern void ppu_execute_syscall(PPUThread& ppu, u64 code) { - if (code >= 1024) + if (code >= g_ppu_syscall_table.size()) { - throw EXCEPTION("Invalid syscall number (0x%llx)", code); + throw fmt::exception("Invalid syscall number (%llu)", code); } + + // If autopause occures, check_status() will hold the thread till unpaused. + if (debug::autopause::pause_syscall(code) && ppu.check_status()) throw cpu_state::ret; + + const auto previous_function = ppu.last_function; // TODO: use gsl::finally or something - auto last_code = ppu.hle_code; - ppu.hle_code = ~code; + try + { + g_ppu_syscall_table[code](ppu); + } + catch (...) + { + LOG_WARNING(PPU, "Syscall '%s' (%llu) aborted", ppu_get_syscall_name(code), code); + ppu.last_function = previous_function; + throw; + } - LOG_TRACE(PPU, "Syscall %lld called: %s", code, get_ps3_function_name(~code)); - - g_sc_table[code](ppu); - - LOG_TRACE(PPU, "Syscall %lld finished: %s -> 0x%llx", code, get_ps3_function_name(~code), ppu.GPR[3]); - - ppu.hle_code = last_code; + LOG_TRACE(PPU, "Syscall '%s' (%llu) finished, r3=0x%llx", ppu_get_syscall_name(code), code, ppu.GPR[3]); + ppu.last_function = previous_function; } + +lv2_lock_t::type::mutex_type lv2_lock_t::mutex; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp b/rpcs3/Emu/Cell/lv2/sys_cond.cpp similarity index 87% rename from rpcs3/Emu/SysCalls/lv2/sys_cond.cpp rename to rpcs3/Emu/Cell/lv2/sys_cond.cpp index ceda3643e2..845a3ec097 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_cond.cpp @@ -1,22 +1,20 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/SysCalls/SysCalls.h" +#include "Emu/Cell/ErrorCodes.h" #include "Emu/Cell/PPUThread.h" -#include "sys_sync.h" #include "sys_mutex.h" #include "sys_cond.h" -SysCallBase sys_cond("sys_cond"); +LOG_CHANNEL(sys_cond); extern u64 get_system_time(); -void lv2_cond_t::notify(lv2_lock_t& lv2_lock, sleep_queue_t::value_type& thread) +void lv2_cond_t::notify(lv2_lock_t, cpu_thread* thread) { - CHECK_LV2_LOCK(lv2_lock); - if (mutex->owner) { // add thread to the mutex sleep queue if cannot lock immediately @@ -24,12 +22,10 @@ void lv2_cond_t::notify(lv2_lock_t& lv2_lock, sleep_queue_t::value_type& thread) } else { - mutex->owner = thread; + mutex->owner = std::static_pointer_cast(thread->shared_from_this()); - if (!thread->signal()) - { - throw EXCEPTION("Thread already signaled"); - } + ASSERT(!thread->state.test_and_set(cpu_state::signal)); + thread->cv.notify_one(); } } @@ -150,9 +146,9 @@ s32 sys_cond_signal_to(u32 cond_id, u32 thread_id) return CELL_ESRCH; } - const auto found = std::find_if(cond->sq.begin(), cond->sq.end(), [=](sleep_queue_t::value_type& thread) + const auto found = std::find_if(cond->sq.begin(), cond->sq.end(), [=](cpu_thread* thread) { - return thread->get_id() == thread_id; + return thread->id == thread_id; }); // TODO: check if CELL_ESRCH is returned if thread_id is invalid @@ -196,12 +192,12 @@ s32 sys_cond_wait(PPUThread& ppu, u32 cond_id, u64 timeout) cond->mutex->unlock(lv2_lock); // add waiter; protocol is ignored in current implementation - sleep_queue_entry_t waiter(ppu, cond->sq); + sleep_entry waiter(cond->sq, ppu); // potential mutex waiter (not added immediately) - sleep_queue_entry_t mutex_waiter(ppu, cond->mutex->sq, defer_sleep); + sleep_entry mutex_waiter(cond->mutex->sq, ppu, defer_sleep); - while (!ppu.unsignal()) + while (!ppu.state.test_and_reset(cpu_state::signal)) { CHECK_EMU_STATUS; @@ -215,7 +211,7 @@ s32 sys_cond_wait(PPUThread& ppu, u32 cond_id, u64 timeout) // try to reown mutex and exit if timed out if (!cond->mutex->owner) { - cond->mutex->owner = std::static_pointer_cast(ppu.shared_from_this()); + cond->mutex->owner = std::static_pointer_cast(ppu.shared_from_this()); break; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_cond.h b/rpcs3/Emu/Cell/lv2/sys_cond.h similarity index 81% rename from rpcs3/Emu/SysCalls/lv2/sys_cond.h rename to rpcs3/Emu/Cell/lv2/sys_cond.h index 2b0583cd1e..24b4012c7c 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_cond.h +++ b/rpcs3/Emu/Cell/lv2/sys_cond.h @@ -1,8 +1,6 @@ #pragma once -#include "Utilities/SleepQueue.h" - -namespace vm { using namespace ps3; } +#include "sys_sync.h" struct lv2_mutex_t; @@ -24,7 +22,7 @@ struct lv2_cond_t const u64 name; const std::shared_ptr mutex; // associated mutex - sleep_queue_t sq; + sleep_queue sq; lv2_cond_t(const std::shared_ptr& mutex, u64 name) : mutex(mutex) @@ -32,7 +30,7 @@ struct lv2_cond_t { } - void notify(lv2_lock_t& lv2_lock, sleep_queue_t::value_type& thread); + void notify(lv2_lock_t, cpu_thread* thread); }; class PPUThread; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_dbg.cpp b/rpcs3/Emu/Cell/lv2/sys_dbg.cpp similarity index 59% rename from rpcs3/Emu/SysCalls/lv2/sys_dbg.cpp rename to rpcs3/Emu/Cell/lv2/sys_dbg.cpp index bfa9445bb0..3890fc906f 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_dbg.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_dbg.cpp @@ -1,9 +1,10 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/SysCalls/SysCalls.h" +#include "Emu/Cell/ErrorCodes.h" #include "sys_dbg.h" -SysCallBase sys_dbg("sys_dbg"); +LOG_CHANNEL(sys_dbg); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_dbg.h b/rpcs3/Emu/Cell/lv2/sys_dbg.h similarity index 100% rename from rpcs3/Emu/SysCalls/lv2/sys_dbg.h rename to rpcs3/Emu/Cell/lv2/sys_dbg.h diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event.cpp b/rpcs3/Emu/Cell/lv2/sys_event.cpp similarity index 72% rename from rpcs3/Emu/SysCalls/lv2/sys_event.cpp rename to rpcs3/Emu/Cell/lv2/sys_event.cpp index a0cdd9b182..81a71bdc5d 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_event.cpp @@ -1,49 +1,65 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/SysCalls/SysCalls.h" +#include "Emu/Cell/ErrorCodes.h" #include "Emu/Cell/PPUThread.h" #include "Emu/Cell/SPUThread.h" -#include "Emu/Event.h" -#include "sys_sync.h" #include "sys_process.h" #include "sys_event.h" -SysCallBase sys_event("sys_event"); +LOG_CHANNEL(sys_event); extern u64 get_system_time(); -lv2_event_queue_t::lv2_event_queue_t(u32 protocol, s32 type, u64 name, u64 key, s32 size) - : id(idm::get_last_id()) - , protocol(protocol) - , type(type) - , name(name) - , key(key) - , size(size) +static ipc_manager& get_ipc_manager() { + // Use magic static + static ipc_manager instance; + return instance; } -void lv2_event_queue_t::push(lv2_lock_t& lv2_lock, u64 source, u64 data1, u64 data2, u64 data3) +std::shared_ptr lv2_event_queue_t::make(u32 protocol, s32 type, u64 name, u64 ipc_key, s32 size) { - CHECK_LV2_LOCK(lv2_lock); + auto make_expr = WRAP_EXPR(idm::import(WRAP_EXPR(std::make_shared(protocol, type, name, ipc_key, size)))); - // save event if no waiters - if (sq.empty()) + if (ipc_key == SYS_EVENT_QUEUE_LOCAL) { - return events.emplace_back(source, data1, data2, data3); + // Not an IPC queue + return make_expr(); } - if (events.size()) + // IPC queue + return get_ipc_manager().add(ipc_key, make_expr); +} + +std::shared_ptr lv2_event_queue_t::find(u64 ipc_key) +{ + if (ipc_key == SYS_EVENT_QUEUE_LOCAL) { - throw EXCEPTION("Unexpected"); + // Invalid IPC key + return{}; + } + + return get_ipc_manager().get(ipc_key); +} + +void lv2_event_queue_t::push(lv2_lock_t, u64 source, u64 data1, u64 data2, u64 data3) +{ + Expects(m_sq.empty() || m_events.empty()); + + // save event if no waiters + if (m_sq.empty()) + { + return m_events.emplace_back(source, data1, data2, data3); } // notify waiter; protocol is ignored in current implementation - auto& thread = sq.front(); + auto& thread = m_sq.front(); - if (type == SYS_PPU_QUEUE && thread->get_type() == CPU_THREAD_PPU) + if (type == SYS_PPU_QUEUE && thread->type == cpu_type::ppu) { // store event data in registers auto& ppu = static_cast(*thread); @@ -53,7 +69,7 @@ void lv2_event_queue_t::push(lv2_lock_t& lv2_lock, u64 source, u64 data1, u64 da ppu.GPR[6] = data2; ppu.GPR[7] = data3; } - else if (type == SYS_SPU_QUEUE && thread->get_type() == CPU_THREAD_SPU) + else if (type == SYS_SPU_QUEUE && thread->type == cpu_type::spu) { // store event data in In_MBox auto& spu = static_cast(*thread); @@ -62,15 +78,21 @@ void lv2_event_queue_t::push(lv2_lock_t& lv2_lock, u64 source, u64 data1, u64 da } else { - throw EXCEPTION("Unexpected (queue_type=%d, thread_type=%d)", type, thread->get_type()); + throw fmt::exception("Unexpected (queue.type=%d, thread.type=%d)" HERE, type, thread->type); } - if (!sq.front()->signal()) - { - throw EXCEPTION("Thread already signaled"); - } + ASSERT(!thread->state.test_and_set(cpu_state::signal)); + thread->cv.notify_one(); - return sq.pop_front(); + return m_sq.pop_front(); +} + +lv2_event_queue_t::event_type lv2_event_queue_t::pop(lv2_lock_t) +{ + Expects(m_events.size()); + auto result = m_events.front(); + m_events.pop_front(); + return result; } s32 sys_event_queue_create(vm::ptr equeue_id, vm::ptr attr, u64 event_queue_key, s32 size) @@ -98,7 +120,7 @@ s32 sys_event_queue_create(vm::ptr equeue_id, vm::ptr(attr->name), event_queue_key, size); + const auto queue = lv2_event_queue_t::make(protocol, type, reinterpret_cast(attr->name), event_queue_key, size); if (!queue) { @@ -128,32 +150,32 @@ s32 sys_event_queue_destroy(u32 equeue_id, s32 mode) return CELL_EINVAL; } - if (!mode && queue->sq.size()) + if (!mode && queue->waiters()) { return CELL_EBUSY; } // cleanup - Emu.GetEventManager().UnregisterKey(queue->key); idm::remove(equeue_id); // signal all threads to return CELL_ECANCELED - for (auto& thread : queue->sq) + for (auto& thread : queue->thread_queue(lv2_lock)) { - if (queue->type == SYS_PPU_QUEUE && thread->get_type() == CPU_THREAD_PPU) + if (queue->type == SYS_PPU_QUEUE && thread->type == cpu_type::ppu) { static_cast(*thread).GPR[3] = 1; } - else if (queue->type == SYS_SPU_QUEUE && thread->get_type() == CPU_THREAD_SPU) + else if (queue->type == SYS_SPU_QUEUE && thread->type == cpu_type::spu) { static_cast(*thread).ch_in_mbox.set_values(1, CELL_ECANCELED); } else { - throw EXCEPTION("Unexpected (queue_type=%d, thread_type=%d)", queue->type, thread->get_type()); + throw fmt::exception("Unexpected (queue.type=%d, thread.type=%d)" HERE, queue->type, thread->type); } - thread->signal(); + thread->state += cpu_state::signal; + thread->cv.notify_one(); } return CELL_OK; @@ -174,7 +196,7 @@ s32 sys_event_queue_tryreceive(u32 equeue_id, vm::ptr event_array, if (size < 0) { - throw EXCEPTION("Negative size"); + throw fmt::exception("Negative size (%d)" HERE, size); } if (queue->type != SYS_PPU_QUEUE) @@ -184,13 +206,11 @@ s32 sys_event_queue_tryreceive(u32 equeue_id, vm::ptr event_array, s32 count = 0; - while (queue->sq.empty() && count < size && queue->events.size()) + while (queue->waiters() == 0 && count < size && queue->events()) { auto& dest = event_array[count++]; - std::tie(dest.source, dest.data1, dest.data2, dest.data3) = queue->events.front(); - - queue->events.pop_front(); + std::tie(dest.source, dest.data1, dest.data2, dest.data3) = queue->pop(lv2_lock); } *number = count; @@ -218,13 +238,10 @@ s32 sys_event_queue_receive(PPUThread& ppu, u32 equeue_id, vm::ptr return CELL_EINVAL; } - if (queue->events.size()) + if (queue->events()) { // event data is returned in registers (dummy_event is not used) - std::tie(ppu.GPR[4], ppu.GPR[5], ppu.GPR[6], ppu.GPR[7]) = queue->events.front(); - - queue->events.pop_front(); - + std::tie(ppu.GPR[4], ppu.GPR[5], ppu.GPR[6], ppu.GPR[7]) = queue->pop(lv2_lock); return CELL_OK; } @@ -232,9 +249,9 @@ s32 sys_event_queue_receive(PPUThread& ppu, u32 equeue_id, vm::ptr ppu.GPR[3] = 0; // add waiter; protocol is ignored in current implementation - sleep_queue_entry_t waiter(ppu, queue->sq); + sleep_entry waiter(queue->thread_queue(lv2_lock), ppu); - while (!ppu.unsignal()) + while (!ppu.state.test_and_reset(cpu_state::signal)) { CHECK_EMU_STATUS; @@ -257,11 +274,7 @@ s32 sys_event_queue_receive(PPUThread& ppu, u32 equeue_id, vm::ptr if (ppu.GPR[3]) { - if (idm::check(equeue_id)) - { - throw EXCEPTION("Unexpected"); - } - + Ensures(!idm::check(equeue_id)); return CELL_ECANCELED; } @@ -282,7 +295,7 @@ s32 sys_event_queue_drain(u32 equeue_id) return CELL_ESRCH; } - queue->events.clear(); + queue->clear(lv2_lock); return CELL_OK; } @@ -401,7 +414,7 @@ s32 sys_event_port_send(u32 eport_id, u64 data1, u64 data2, u64 data3) return CELL_ENOTCONN; } - if (queue->events.size() >= queue->size) + if (queue->events() >= queue->size) { return CELL_EBUSY; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event.h b/rpcs3/Emu/Cell/lv2/sys_event.h similarity index 65% rename from rpcs3/Emu/SysCalls/lv2/sys_event.h rename to rpcs3/Emu/Cell/lv2/sys_event.h index 5326e6cff8..e1c088870c 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event.h +++ b/rpcs3/Emu/Cell/lv2/sys_event.h @@ -1,8 +1,6 @@ #pragma once -#include "Utilities/SleepQueue.h" - -namespace vm { using namespace ps3; } +#include "sys_sync.h" // Event Queue Type enum : u32 @@ -65,23 +63,58 @@ struct sys_event_t be_t data3; }; -struct lv2_event_queue_t +class lv2_event_queue_t final { - const u32 id; + // Tuple elements: source, data1, data2, data3 + using event_type = std::tuple; + + std::deque m_events; + + sleep_queue m_sq; + +public: + // Try to make an event queue with specified global key + static std::shared_ptr make(u32 protocol, s32 type, u64 name, u64 ipc_key, s32 size); + + // Get event queue by its global key + static std::shared_ptr find(u64 ipc_key); + const u32 protocol; const s32 type; const u64 name; - const u64 key; + const u64 ipc_key; const s32 size; + const u32 id{}; - // tuple elements: source, data1, data2, data3 - std::deque> events; + lv2_event_queue_t(u32 protocol, s32 type, u64 name, u64 ipc_key, s32 size) + : protocol(protocol) + , type(type) + , name(name) + , ipc_key(ipc_key) + , size(size) + { + } - sleep_queue_t sq; + // Send an event + void push(lv2_lock_t, u64 source, u64 data1, u64 data2, u64 data3); - lv2_event_queue_t(u32 protocol, s32 type, u64 name, u64 key, s32 size); + // Receive an event (queue shouldn't be empty) + event_type pop(lv2_lock_t); - void push(lv2_lock_t& lv2_lock, u64 source, u64 data1, u64 data2, u64 data3); + // Remove all events + void clear(lv2_lock_t) + { + m_events.clear(); + } + + // Get event count + std::size_t events() const { return m_events.size(); } + + // Get waiter count + std::size_t waiters() const { return m_sq.size(); } + + // Get threads (TODO) + auto& thread_queue(lv2_lock_t) { return m_sq; } }; struct lv2_event_port_t diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp b/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp similarity index 92% rename from rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp rename to rpcs3/Emu/Cell/lv2/sys_event_flag.cpp index da3b58edc2..443cc55de3 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp @@ -1,22 +1,20 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/SysCalls/SysCalls.h" +#include "Emu/Cell/ErrorCodes.h" #include "Emu/Cell/PPUThread.h" -#include "sys_sync.h" #include "sys_event_flag.h" -SysCallBase sys_event_flag("sys_event_flag"); +LOG_CHANNEL(sys_event_flag); extern u64 get_system_time(); -void lv2_event_flag_t::notify_all(lv2_lock_t& lv2_lock) +void lv2_event_flag_t::notify_all(lv2_lock_t) { - CHECK_LV2_LOCK(lv2_lock); - - auto pred = [this](sleep_queue_t::value_type& thread) -> bool + auto pred = [this](cpu_thread* thread) -> bool { auto& ppu = static_cast(*thread); @@ -30,10 +28,8 @@ void lv2_event_flag_t::notify_all(lv2_lock_t& lv2_lock) // save pattern ppu.GPR[4] = clear_pattern(bitptn, mode); - if (!ppu.signal()) - { - throw EXCEPTION("Thread already signaled"); - } + ASSERT(!thread->state.test_and_set(cpu_state::signal)); + thread->cv.notify_one(); return true; } @@ -147,9 +143,9 @@ s32 sys_event_flag_wait(PPUThread& ppu, u32 id, u64 bitptn, u32 mode, vm::ptrsq); + sleep_entry waiter(eflag->sq, ppu); - while (!ppu.unsignal()) + while (!ppu.state.test_and_reset(cpu_state::signal)) { CHECK_EMU_STATUS; @@ -295,10 +291,8 @@ s32 sys_event_flag_cancel(u32 id, vm::ptr num) // clear "mode" as a sign of cancellation ppu.GPR[5] = 0; - if (!thread->signal()) - { - throw EXCEPTION("Thread already signaled"); - } + ASSERT(!thread->state.test_and_set(cpu_state::signal)); + thread->cv.notify_one(); } eflag->sq.clear(); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.h b/rpcs3/Emu/Cell/lv2/sys_event_flag.h similarity index 93% rename from rpcs3/Emu/SysCalls/lv2/sys_event_flag.h rename to rpcs3/Emu/Cell/lv2/sys_event_flag.h index 35da424583..31b27947c5 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.h +++ b/rpcs3/Emu/Cell/lv2/sys_event_flag.h @@ -1,8 +1,6 @@ #pragma once -#include "Utilities/SleepQueue.h" - -namespace vm { using namespace ps3; } +#include "sys_sync.h" enum { @@ -37,9 +35,9 @@ struct lv2_event_flag_t const s32 type; const u64 name; - std::atomic pattern; + atomic_t pattern; - sleep_queue_t sq; + sleep_queue sq; lv2_event_flag_t(u64 pattern, u32 protocol, s32 type, u64 name) : pattern(pattern) @@ -105,7 +103,7 @@ struct lv2_event_flag_t } } - void notify_all(lv2_lock_t& lv2_lock); + void notify_all(lv2_lock_t); }; // Aux diff --git a/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp b/rpcs3/Emu/Cell/lv2/sys_fs.cpp similarity index 76% rename from rpcs3/Emu/SysCalls/lv2/sys_fs.cpp rename to rpcs3/Emu/Cell/lv2/sys_fs.cpp index 9b2fef1ae0..f9dc481f4b 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_fs.cpp @@ -1,17 +1,13 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/SysCalls/SysCalls.h" - -#include "Emu/FS/VFS.h" -#include "Emu/FS/vfsFile.h" -#include "Emu/FS/vfsLocalFile.h" -#include "Emu/FS/vfsDir.h" +#include "Emu/Cell/ErrorCodes.h" #include "sys_fs.h" -SysCallBase sys_fs("sys_fs"); +LOG_CHANNEL(sys_fs); s32 sys_fs_test(u32 arg1, u32 arg2, vm::ptr arg3, u32 arg4, vm::ptr arg5, u32 arg6) { @@ -31,11 +27,8 @@ s32 sys_fs_open(vm::cptr path, s32 flags, vm::ptr fd, s32 mode, vm::c return CELL_FS_EINVAL; } - std::string local_path; - - const auto device = Emu.GetVFS().GetDevice(path.get_ptr(), local_path); - - if (!device) + const std::string& local_path = vfs::get(path.get_ptr()); + if (local_path.empty()) { sys_fs.error("sys_fs_open('%s') failed: device not mounted", path.get_ptr()); return CELL_FS_ENOTMOUNTED; @@ -49,50 +42,50 @@ s32 sys_fs_open(vm::cptr path, s32 flags, vm::ptr fd, s32 mode, vm::c return CELL_FS_EISDIR; } - u32 open_mode = 0; + mset open_mode{}; switch (flags & CELL_FS_O_ACCMODE) { - case CELL_FS_O_RDONLY: open_mode |= fom::read; break; - case CELL_FS_O_WRONLY: open_mode |= fom::write; break; - case CELL_FS_O_RDWR: open_mode |= fom::read | fom::write; break; + case CELL_FS_O_RDONLY: open_mode += fs::read; break; + case CELL_FS_O_WRONLY: open_mode += fs::write; break; + case CELL_FS_O_RDWR: open_mode += fs::read + fs::write; break; } if (flags & CELL_FS_O_CREAT) { - open_mode |= fom::create; + open_mode += fs::create; } if (flags & CELL_FS_O_TRUNC) { - open_mode |= fom::trunc; + open_mode += fs::trunc; } if (flags & CELL_FS_O_APPEND) { - open_mode |= fom::append; + open_mode += fs::append; } if (flags & CELL_FS_O_EXCL) { if (flags & CELL_FS_O_CREAT) { - open_mode |= fom::excl; + open_mode += fs::excl; } else { - open_mode = 0; // error + open_mode = {}; // error } } if (flags & ~(CELL_FS_O_ACCMODE | CELL_FS_O_CREAT | CELL_FS_O_TRUNC | CELL_FS_O_APPEND | CELL_FS_O_EXCL)) { - open_mode = 0; // error + open_mode = {}; // error } if ((flags & CELL_FS_O_ACCMODE) == CELL_FS_O_ACCMODE) { - open_mode = 0; // error + open_mode = {}; // error } if (!open_mode) @@ -100,13 +93,13 @@ s32 sys_fs_open(vm::cptr path, s32 flags, vm::ptr fd, s32 mode, vm::c throw EXCEPTION("Invalid or unimplemented flags (%#o): '%s'", flags, path.get_ptr()); } - std::shared_ptr file(Emu.GetVFS().OpenFile(path.get_ptr(), open_mode)); + fs::file file(local_path, open_mode); - if (!file || !file->IsOpened()) + if (!file) { sys_fs.error("sys_fs_open('%s'): failed to open file (flags=%#o, mode=%#o)", path.get_ptr(), flags, mode); - if (open_mode & fom::excl) + if (open_mode & fs::excl) { return CELL_FS_EEXIST; // approximation } @@ -122,7 +115,7 @@ s32 sys_fs_open(vm::cptr path, s32 flags, vm::ptr fd, s32 mode, vm::c return CELL_FS_EMFILE; } - *fd = idm::get_last_id(); + *fd = _file->id; return CELL_OK; } @@ -140,7 +133,7 @@ s32 sys_fs_read(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nread) std::lock_guard lock(file->mutex); - *nread = file->file->Read(buf.get_ptr(), nbytes); + *nread = file->file.read(buf.get_ptr(), nbytes); return CELL_OK; } @@ -160,7 +153,7 @@ s32 sys_fs_write(u32 fd, vm::cptr buf, u64 nbytes, vm::ptr nwrite) std::lock_guard lock(file->mutex); - *nwrite = file->file->Write(buf.get_ptr(), nbytes); + *nwrite = file->file.write(buf.get_ptr(), nbytes); return CELL_OK; } @@ -188,9 +181,9 @@ s32 sys_fs_opendir(vm::cptr path, vm::ptr fd) sys_fs.warning("sys_fs_opendir(path=*0x%x, fd=*0x%x)", path, fd); sys_fs.warning("*** path = '%s'", path.get_ptr()); - std::shared_ptr dir(Emu.GetVFS().OpenDir(path.get_ptr())); + fs::dir dir(vfs::get(path.get_ptr())); - if (!dir || !dir->IsOpened()) + if (!dir) { sys_fs.error("sys_fs_opendir('%s'): failed to open directory", path.get_ptr()); return CELL_FS_ENOENT; @@ -204,7 +197,7 @@ s32 sys_fs_opendir(vm::cptr path, vm::ptr fd) return CELL_FS_EMFILE; } - *fd = idm::get_last_id(); + *fd = _dir->id; return CELL_OK; } @@ -220,13 +213,13 @@ s32 sys_fs_readdir(u32 fd, vm::ptr dir, vm::ptr nread) return CELL_FS_EBADF; } - const DirEntryInfo* info = directory->dir->Read(); + fs::dir_entry info; - if (info) + if (directory->dir.read(info)) { - dir->d_type = (info->flags & DirEntry_TypeFile) ? CELL_FS_TYPE_REGULAR : CELL_FS_TYPE_DIRECTORY; - dir->d_namlen = u8(std::min(info->name.length(), CELL_FS_MAX_FS_FILE_NAME_LENGTH)); - strcpy_trunc(dir->d_name, info->name); + dir->d_type = info.is_directory ? CELL_FS_TYPE_DIRECTORY : CELL_FS_TYPE_REGULAR; + dir->d_namlen = u8(std::min(info.name.size(), CELL_FS_MAX_FS_FILE_NAME_LENGTH)); + strcpy_trunc(dir->d_name, info.name); *nread = sizeof(CellFsDirent); } else @@ -258,9 +251,9 @@ s32 sys_fs_stat(vm::cptr path, vm::ptr sb) sys_fs.warning("sys_fs_stat(path=*0x%x, sb=*0x%x)", path, sb); sys_fs.warning("*** path = '%s'", path.get_ptr()); - std::string local_path; + const std::string& local_path = vfs::get(path.get_ptr()); - if (!Emu.GetVFS().GetDevice(path.get_ptr(), local_path)) + if (local_path.empty()) { sys_fs.warning("sys_fs_stat('%s') failed: not mounted", path.get_ptr()); return CELL_FS_ENOTMOUNTED; @@ -299,20 +292,7 @@ s32 sys_fs_fstat(u32 fd, vm::ptr sb) std::lock_guard lock(file->mutex); - const auto local_file = dynamic_cast(file->file.get()); - - if (!local_file) - { - sys_fs.error("sys_fs_fstat(fd=0x%x): not a local file"); - return CELL_FS_ENOTSUP; - } - - fs::stat_t info; - - if (!local_file->GetFile().stat(info)) - { - return CELL_FS_EIO; // ??? - } + const fs::stat_t& info = file->file.stat(); sb->mode = info.is_directory ? CELL_FS_S_IFDIR | 0777 : CELL_FS_S_IFREG | 0666; sb->uid = 1; // ??? @@ -331,14 +311,14 @@ s32 sys_fs_mkdir(vm::cptr path, s32 mode) sys_fs.warning("sys_fs_mkdir(path=*0x%x, mode=%#o)", path, mode); sys_fs.warning("*** path = '%s'", path.get_ptr()); - std::string ps3_path = path.get_ptr(); + const std::string& local_path = vfs::get(path.get_ptr()); - if (Emu.GetVFS().ExistsDir(ps3_path)) + if (fs::is_dir(local_path)) { return CELL_FS_EEXIST; } - if (!Emu.GetVFS().CreatePath(ps3_path)) + if (!fs::create_path(local_path)) { return CELL_FS_EIO; // ??? } @@ -353,7 +333,7 @@ s32 sys_fs_rename(vm::cptr from, vm::cptr to) sys_fs.warning("*** from = '%s'", from.get_ptr()); sys_fs.warning("*** to = '%s'", to.get_ptr()); - if (!Emu.GetVFS().Rename(from.get_ptr(), to.get_ptr())) + if (!fs::rename(vfs::get(from.get_ptr()), vfs::get(to.get_ptr()))) { return CELL_FS_ENOENT; // ??? } @@ -367,15 +347,14 @@ s32 sys_fs_rmdir(vm::cptr path) sys_fs.warning("sys_fs_rmdir(path=*0x%x)", path); sys_fs.warning("*** path = '%s'", path.get_ptr()); - std::string ps3_path = path.get_ptr(); - - if (!Emu.GetVFS().ExistsDir(ps3_path)) + if (!fs::remove_dir(vfs::get(path.get_ptr()))) { - return CELL_FS_ENOENT; - } + switch (auto error = errno) + { + case ENOENT: return CELL_FS_ENOENT; + default: sys_fs.error("sys_fs_rmdir(): unknown error %d", error); + } - if (!Emu.GetVFS().RemoveDir(ps3_path)) - { return CELL_FS_EIO; // ??? } @@ -388,15 +367,14 @@ s32 sys_fs_unlink(vm::cptr path) sys_fs.warning("sys_fs_unlink(path=*0x%x)", path); sys_fs.warning("*** path = '%s'", path.get_ptr()); - std::string ps3_path = path.get_ptr(); - - if (!Emu.GetVFS().ExistsFile(ps3_path)) + if (!fs::remove_file(vfs::get(path.get_ptr()))) { - return CELL_FS_ENOENT; - } + switch (auto error = errno) + { + case ENOENT: return CELL_FS_ENOENT; + default: sys_fs.error("sys_fs_unlink(): unknown error %d", error); + } - if (!Emu.GetVFS().RemoveFile(ps3_path)) - { return CELL_FS_EIO; // ??? } @@ -417,7 +395,7 @@ s32 sys_fs_lseek(u32 fd, s64 offset, s32 whence, vm::ptr pos) if (whence >= 3) { - sys_fs.error("sys_fs_lseek(): unknown seek whence (%d)", whence); + sys_fs.error("sys_fs_lseek(): invalid seek whence (%d)", whence); return CELL_FS_EINVAL; } @@ -430,7 +408,7 @@ s32 sys_fs_lseek(u32 fd, s64 offset, s32 whence, vm::ptr pos) std::lock_guard lock(file->mutex); - *pos = file->file->Seek(offset, (fs::seek_mode)whence); + *pos = file->file.seek(offset, static_cast(whence)); return CELL_OK; } @@ -468,15 +446,14 @@ s32 sys_fs_truncate(vm::cptr path, u64 size) sys_fs.warning("sys_fs_truncate(path=*0x%x, size=0x%llx)", path, size); sys_fs.warning("*** path = '%s'", path.get_ptr()); - std::string ps3_path = path.get_ptr(); - - if (!Emu.GetVFS().ExistsFile(ps3_path)) + if (!fs::truncate_file(vfs::get(path.get_ptr()), size)) { - return CELL_FS_ENOENT; - } + switch (auto error = errno) + { + case ENOENT: return CELL_FS_ENOENT; + default: sys_fs.error("sys_fs_truncate(): unknown error %d", error); + } - if (!Emu.GetVFS().TruncateFile(ps3_path, size)) - { return CELL_FS_EIO; // ??? } @@ -496,16 +473,14 @@ s32 sys_fs_ftruncate(u32 fd, u64 size) std::lock_guard lock(file->mutex); - const auto local_file = dynamic_cast(file->file.get()); - - if (!local_file) + if (!file->file.trunc(size)) { - sys_fs.error("sys_fs_ftruncate(fd=0x%x): not a local file"); - return CELL_FS_ENOTSUP; - } + switch (auto error = errno) + { + case 0: + default: sys_fs.error("sys_fs_ftruncate(): unknown error %d", error); + } - if (!local_file->GetFile().trunc(size)) - { return CELL_FS_EIO; // ??? } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_fs.h b/rpcs3/Emu/Cell/lv2/sys_fs.h similarity index 87% rename from rpcs3/Emu/SysCalls/lv2/sys_fs.h rename to rpcs3/Emu/Cell/lv2/sys_fs.h index 324958a54a..e943697325 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_fs.h +++ b/rpcs3/Emu/Cell/lv2/sys_fs.h @@ -148,8 +148,6 @@ struct CellFsUtimbuf #pragma pack(pop) -struct vfsStream; - // Stream Support Status (st_status) enum : u32 { @@ -161,16 +159,26 @@ enum : u32 using fs_st_cb_t = vm::ptr; -struct fs_st_cb_rec_t +struct alignas(16) fs_st_cb_rec_t { u64 size; fs_st_cb_t func; u32 pad; }; -struct lv2_file_t +struct lv2_fs_object_t { - const std::shared_ptr file; + using id_base = lv2_fs_object_t; + + static constexpr u32 id_min = 3; + static constexpr u32 id_max = 255; + + const u32 id{}; +}; + +struct lv2_file_t : lv2_fs_object_t +{ + const fs::file file; const s32 mode; const s32 flags; @@ -188,12 +196,12 @@ struct lv2_file_t u32 st_buffer; u64 st_read_size; - std::atomic st_total_read; - std::atomic st_copied; + atomic_t st_total_read; + atomic_t st_copied; atomic_t st_callback; - lv2_file_t(std::shared_ptr file, s32 mode, s32 flags) + lv2_file_t(fs::file file, s32 mode, s32 flags) : file(std::move(file)) , mode(mode) , flags(flags) @@ -203,42 +211,16 @@ struct lv2_file_t } }; -template<> struct id_traits +struct lv2_dir_t : lv2_fs_object_t { - static const u32 base = 0xfddd0000, max = 255; + const fs::dir dir; - static u32 next_id(u32 raw_id) - { - return - raw_id < 0x80000000 ? base + 3 : - raw_id - base < max ? raw_id + 1 : 0; - } - - static u32 in_id(u32 id) - { - return id + base; - } - - static u32 out_id(u32 raw_id) - { - return raw_id - base; - } -}; - -class vfsDirBase; - -struct lv2_dir_t -{ - const std::shared_ptr dir; - - lv2_dir_t(std::shared_ptr dir) + lv2_dir_t(fs::dir dir) : dir(std::move(dir)) { } }; -template<> struct id_traits : public id_traits {}; - // SysCalls s32 sys_fs_test(u32 arg1, u32 arg2, vm::ptr arg3, u32 arg4, vm::ptr arg5, u32 arg6); s32 sys_fs_open(vm::cptr path, s32 flags, vm::ptr fd, s32 mode, vm::cptr arg, u64 size); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp b/rpcs3/Emu/Cell/lv2/sys_interrupt.cpp similarity index 85% rename from rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp rename to rpcs3/Emu/Cell/lv2/sys_interrupt.cpp index 6251f33d00..21c873cc3c 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_interrupt.cpp @@ -1,36 +1,24 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/SysCalls/SysCalls.h" +#include "Emu/Cell/ErrorCodes.h" #include "Emu/Cell/PPUThread.h" #include "sys_interrupt.h" -SysCallBase sys_interrupt("sys_interrupt"); +LOG_CHANNEL(sys_interrupt); -lv2_int_tag_t::lv2_int_tag_t() - : id(idm::get_last_id()) +void lv2_int_serv_t::join(PPUThread& ppu, lv2_lock_t lv2_lock) { -} - -lv2_int_serv_t::lv2_int_serv_t(const std::shared_ptr& thread) - : thread(thread) - , id(idm::get_last_id()) -{ -} - -void lv2_int_serv_t::join(PPUThread& ppu, lv2_lock_t& lv2_lock) -{ - CHECK_LV2_LOCK(lv2_lock); - // Use is_joining to stop interrupt thread and signal thread->is_joining = true; thread->cv.notify_one(); // Start joining - while (thread->is_alive()) + while (!(thread->state & cpu_state::exit)) { CHECK_EMU_STATUS; @@ -39,7 +27,7 @@ void lv2_int_serv_t::join(PPUThread& ppu, lv2_lock_t& lv2_lock) // Cleanup idm::remove(id); - idm::remove(thread->get_id()); + idm::remove(thread->id); } s32 sys_interrupt_tag_destroy(u32 intrtag) @@ -88,7 +76,7 @@ s32 _sys_interrupt_thread_establish(vm::ptr ih, u32 intrtag, u32 intrthread } // If interrupt thread is running, it's already established on another interrupt tag - if (!it->is_stopped()) + if (!(it->state & cpu_state::stop)) { return CELL_EAGAIN; } @@ -137,10 +125,11 @@ s32 _sys_interrupt_thread_establish(vm::ptr ih, u32 intrtag, u32 intrthread ppu.cv.wait(lv2_lock); } - ppu.exit(); + ppu.state += cpu_state::exit; }; - it->exec(); + it->state -= cpu_state::stop; + it->safe_notify(); *ih = handler->id; @@ -177,5 +166,5 @@ void sys_interrupt_thread_eoi(PPUThread& ppu) ppu.GPR[1] = align(ppu.stack_addr + ppu.stack_size, 0x200) - 0x200; // supercrutch to bypass stack check - ppu.fast_stop(); + ppu.state += cpu_state::ret; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_interrupt.h b/rpcs3/Emu/Cell/lv2/sys_interrupt.h similarity index 65% rename from rpcs3/Emu/SysCalls/lv2/sys_interrupt.h rename to rpcs3/Emu/Cell/lv2/sys_interrupt.h index fef802d89d..558aede372 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_interrupt.h +++ b/rpcs3/Emu/Cell/lv2/sys_interrupt.h @@ -1,28 +1,29 @@ #pragma once -namespace vm { using namespace ps3; } +#include "sys_sync.h" class PPUThread; struct lv2_int_tag_t { - const u32 id; + const u32 id{}; std::shared_ptr handler; - - lv2_int_tag_t(); }; struct lv2_int_serv_t { const std::shared_ptr thread; - const u32 id; + const u32 id{}; - std::atomic signal{ 0 }; // signal count + atomic_t signal{ 0 }; // signal count - lv2_int_serv_t(const std::shared_ptr& thread); + lv2_int_serv_t(const std::shared_ptr& thread) + : thread(thread) + { + } - void join(PPUThread& ppu, lv2_lock_t& lv2_lock); + void join(PPUThread& ppu, lv2_lock_t); }; // SysCalls diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp b/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp similarity index 88% rename from rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp rename to rpcs3/Emu/Cell/lv2/sys_lwcond.cpp index ad843cae93..cb77b4b479 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp @@ -1,21 +1,20 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/SysCalls/SysCalls.h" +#include "Emu/Cell/ErrorCodes.h" #include "Emu/Cell/PPUThread.h" #include "sys_lwmutex.h" #include "sys_lwcond.h" -SysCallBase sys_lwcond("sys_lwcond"); +LOG_CHANNEL(sys_lwcond); extern u64 get_system_time(); -void lv2_lwcond_t::notify(lv2_lock_t & lv2_lock, sleep_queue_t::value_type& thread, const std::shared_ptr& mutex, bool mode2) +void lv2_lwcond_t::notify(lv2_lock_t, cpu_thread* thread, const std::shared_ptr& mutex, bool mode2) { - CHECK_LV2_LOCK(lv2_lock); - auto& ppu = static_cast(*thread); ppu.GPR[3] = mode2; // set to return CELL_EBUSY @@ -30,10 +29,8 @@ void lv2_lwcond_t::notify(lv2_lock_t & lv2_lock, sleep_queue_t::value_type& thre mutex->signaled--; } - if (!ppu.signal()) - { - throw EXCEPTION("Thread already signaled"); - } + ASSERT(!thread->state.test_and_set(cpu_state::signal)); + thread->cv.notify_one(); } s32 _sys_lwcond_create(vm::ptr lwcond_id, u32 lwmutex_id, vm::ptr control, u64 name, u32 arg5) @@ -92,9 +89,9 @@ s32 _sys_lwcond_signal(u32 lwcond_id, u32 lwmutex_id, u32 ppu_thread_id, u32 mod // mode 3: lightweight mutex was forcefully owned by the calling thread // pick waiter; protocol is ignored in current implementation - const auto found = !~ppu_thread_id ? cond->sq.begin() : std::find_if(cond->sq.begin(), cond->sq.end(), [=](sleep_queue_t::value_type& thread) + const auto found = !~ppu_thread_id ? cond->sq.begin() : std::find_if(cond->sq.begin(), cond->sq.end(), [=](cpu_thread* thread) { - return thread->get_id() == ppu_thread_id; + return thread->id == ppu_thread_id; }); if (found == cond->sq.end()) @@ -177,12 +174,12 @@ s32 _sys_lwcond_queue_wait(PPUThread& ppu, u32 lwcond_id, u32 lwmutex_id, u64 ti mutex->unlock(lv2_lock); // add waiter; protocol is ignored in current implementation - sleep_queue_entry_t waiter(ppu, cond->sq); + sleep_entry waiter(cond->sq, ppu); // potential mutex waiter (not added immediately) - sleep_queue_entry_t mutex_waiter(ppu, cond->sq, defer_sleep); + sleep_entry mutex_waiter(cond->sq, ppu, defer_sleep); - while (!ppu.unsignal()) + while (!ppu.state.test_and_reset(cpu_state::signal)) { CHECK_EMU_STATUS; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.h b/rpcs3/Emu/Cell/lv2/sys_lwcond.h similarity index 84% rename from rpcs3/Emu/SysCalls/lv2/sys_lwcond.h rename to rpcs3/Emu/Cell/lv2/sys_lwcond.h index 552210ce34..8633318c03 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.h +++ b/rpcs3/Emu/Cell/lv2/sys_lwcond.h @@ -21,14 +21,14 @@ struct lv2_lwcond_t { const u64 name; - sleep_queue_t sq; + sleep_queue sq; lv2_lwcond_t(u64 name) : name(name) { } - void notify(lv2_lock_t& lv2_lock, sleep_queue_t::value_type& thread, const std::shared_ptr& mutex, bool mode2); + void notify(lv2_lock_t, cpu_thread* thread, const std::shared_ptr& mutex, bool mode2); }; // Aux diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp b/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp similarity index 88% rename from rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp rename to rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp index 746f87464b..76833e1a93 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp @@ -1,21 +1,19 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/SysCalls/SysCalls.h" +#include "Emu/Cell/ErrorCodes.h" #include "Emu/Cell/PPUThread.h" -#include "sys_sync.h" #include "sys_lwmutex.h" -SysCallBase sys_lwmutex("sys_lwmutex"); +LOG_CHANNEL(sys_lwmutex); extern u64 get_system_time(); -void lv2_lwmutex_t::unlock(lv2_lock_t& lv2_lock) +void lv2_lwmutex_t::unlock(lv2_lock_t) { - CHECK_LV2_LOCK(lv2_lock); - if (signaled) { throw EXCEPTION("Unexpected"); @@ -23,10 +21,9 @@ void lv2_lwmutex_t::unlock(lv2_lock_t& lv2_lock) if (sq.size()) { - if (!sq.front()->signal()) - { - throw EXCEPTION("Thread already signaled"); - } + auto& thread = sq.front(); + ASSERT(!thread->state.test_and_set(cpu_state::signal)); + thread->cv.notify_one(); sq.pop_front(); } @@ -102,9 +99,9 @@ s32 _sys_lwmutex_lock(PPUThread& ppu, u32 lwmutex_id, u64 timeout) } // add waiter; protocol is ignored in current implementation - sleep_queue_entry_t waiter(ppu, mutex->sq); + sleep_entry waiter(mutex->sq, ppu); - while (!ppu.unsignal()) + while (!ppu.state.test_and_reset(cpu_state::signal)) { CHECK_EMU_STATUS; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.h b/rpcs3/Emu/Cell/lv2/sys_lwmutex.h similarity index 86% rename from rpcs3/Emu/SysCalls/lv2/sys_lwmutex.h rename to rpcs3/Emu/Cell/lv2/sys_lwmutex.h index 4386c83650..775bd11ff6 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.h +++ b/rpcs3/Emu/Cell/lv2/sys_lwmutex.h @@ -1,8 +1,6 @@ #pragma once -#include "Utilities/SleepQueue.h" - -namespace vm { using namespace ps3; } +#include "sys_sync.h" struct sys_lwmutex_attribute_t { @@ -20,7 +18,7 @@ enum : u32 struct sys_lwmutex_t { - struct sync_var_t + struct alignas(8) sync_var_t { be_t owner; be_t waiter; @@ -52,9 +50,9 @@ struct lv2_lwmutex_t const u64 name; // this object is not truly a mutex and its syscall names may be wrong, it's probably a sleep queue or something - std::atomic signaled{ 0 }; + atomic_t signaled{ 0 }; - sleep_queue_t sq; + sleep_queue sq; lv2_lwmutex_t(u32 protocol, u64 name) : protocol(protocol) @@ -62,7 +60,7 @@ struct lv2_lwmutex_t { } - void unlock(lv2_lock_t& lv2_lock); + void unlock(lv2_lock_t); }; // Aux diff --git a/rpcs3/Emu/SysCalls/lv2/sys_memory.cpp b/rpcs3/Emu/Cell/lv2/sys_memory.cpp similarity index 97% rename from rpcs3/Emu/SysCalls/lv2/sys_memory.cpp rename to rpcs3/Emu/Cell/lv2/sys_memory.cpp index 3141092f9f..47a7fc79cc 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_memory.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_memory.cpp @@ -1,18 +1,13 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/SysCalls/SysCalls.h" +#include "Emu/Cell/ErrorCodes.h" #include "sys_memory.h" -SysCallBase sys_memory("sys_memory"); - -lv2_memory_container_t::lv2_memory_container_t(u32 size) - : size(size) - , id(idm::get_last_id()) -{ -} +LOG_CHANNEL(sys_memory); s32 sys_memory_allocate(u32 size, u64 flags, vm::ptr alloc_addr) { diff --git a/rpcs3/Emu/SysCalls/lv2/sys_memory.h b/rpcs3/Emu/Cell/lv2/sys_memory.h similarity index 92% rename from rpcs3/Emu/SysCalls/lv2/sys_memory.h rename to rpcs3/Emu/Cell/lv2/sys_memory.h index da73297264..e99580083d 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_memory.h +++ b/rpcs3/Emu/Cell/lv2/sys_memory.h @@ -1,6 +1,6 @@ #pragma once -namespace vm { using namespace ps3; } +#include "sys_sync.h" enum : u32 { @@ -42,18 +42,23 @@ struct sys_page_attr_t be_t pad; }; +#include + struct lv2_memory_container_t { const u32 size; // amount of "physical" memory in this container - const u32 id; + const u32 id{}; // amount of memory allocated - std::atomic used{ 0 }; + atomic_t used{ 0 }; // allocations (addr -> size) std::map allocs; - lv2_memory_container_t(u32 size); + lv2_memory_container_t(u32 size) + : size(size) + { + } }; // SysCalls diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mmapper.cpp b/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp similarity index 96% rename from rpcs3/Emu/SysCalls/lv2/sys_mmapper.cpp rename to rpcs3/Emu/Cell/lv2/sys_mmapper.cpp index 5ec9fc02ac..c8e70246cd 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mmapper.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp @@ -1,21 +1,13 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/SysCalls/SysCalls.h" +#include "Emu/Cell/ErrorCodes.h" #include "sys_mmapper.h" -SysCallBase sys_mmapper("sys_mmapper"); - -lv2_memory_t::lv2_memory_t(u32 size, u32 align, u64 flags, const std::shared_ptr ct) - : size(size) - , align(align) - , id(idm::get_last_id()) - , flags(flags) - , ct(ct) -{ -} +LOG_CHANNEL(sys_mmapper); s32 sys_mmapper_allocate_address(u64 size, u64 flags, u64 alignment, vm::ptr alloc_addr) { diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mmapper.h b/rpcs3/Emu/Cell/lv2/sys_mmapper.h similarity index 86% rename from rpcs3/Emu/SysCalls/lv2/sys_mmapper.h rename to rpcs3/Emu/Cell/lv2/sys_mmapper.h index 684ac0fdc8..e8d9d9a265 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mmapper.h +++ b/rpcs3/Emu/Cell/lv2/sys_mmapper.h @@ -2,19 +2,23 @@ #include "sys_memory.h" -namespace vm { using namespace ps3; } - struct lv2_memory_t { const u32 size; // memory size const u32 align; // required alignment - const u32 id; const u64 flags; const std::shared_ptr ct; // memory container the physical memory is taken from + const u32 id{}; - std::atomic addr{ 0 }; // actual mapping address + atomic_t addr{ 0 }; // actual mapping address - lv2_memory_t(u32 size, u32 align, u64 flags, const std::shared_ptr ct); + lv2_memory_t(u32 size, u32 align, u64 flags, const std::shared_ptr ct) + : size(size) + , align(align) + , flags(flags) + , ct(ct) + { + } }; // SysCalls diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp b/rpcs3/Emu/Cell/lv2/sys_mutex.cpp similarity index 88% rename from rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp rename to rpcs3/Emu/Cell/lv2/sys_mutex.cpp index f2d50747ee..faf3f21b99 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_mutex.cpp @@ -1,32 +1,28 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/SysCalls/SysCalls.h" +#include "Emu/Cell/ErrorCodes.h" #include "Emu/Cell/PPUThread.h" -#include "sys_sync.h" #include "sys_mutex.h" -SysCallBase sys_mutex("sys_mutex"); +LOG_CHANNEL(sys_mutex); extern u64 get_system_time(); -void lv2_mutex_t::unlock(lv2_lock_t& lv2_lock) +void lv2_mutex_t::unlock(lv2_lock_t) { - CHECK_LV2_LOCK(lv2_lock); - owner.reset(); if (sq.size()) { // pick new owner; protocol is ignored in current implementation - owner = sq.front(); + owner = std::static_pointer_cast(sq.front()->shared_from_this()); - if (!owner->signal()) - { - throw EXCEPTION("Mutex owner already signaled"); - } + ASSERT(!owner->state.test_and_set(cpu_state::signal)); + owner->cv.notify_one(); } } @@ -132,15 +128,15 @@ s32 sys_mutex_lock(PPUThread& ppu, u32 mutex_id, u64 timeout) // lock immediately if not locked if (!mutex->owner) { - mutex->owner = std::static_pointer_cast(ppu.shared_from_this()); + mutex->owner = std::static_pointer_cast(ppu.shared_from_this()); return CELL_OK; } // add waiter; protocol is ignored in current implementation - sleep_queue_entry_t waiter(ppu, mutex->sq); + sleep_entry waiter(mutex->sq, ppu); - while (!ppu.unsignal()) + while (!ppu.state.test_and_reset(cpu_state::signal)) { CHECK_EMU_STATUS; @@ -207,7 +203,7 @@ s32 sys_mutex_trylock(PPUThread& ppu, u32 mutex_id) } // own the mutex if free - mutex->owner = std::static_pointer_cast(ppu.shared_from_this()); + mutex->owner = std::static_pointer_cast(ppu.shared_from_this()); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mutex.h b/rpcs3/Emu/Cell/lv2/sys_mutex.h similarity index 72% rename from rpcs3/Emu/SysCalls/lv2/sys_mutex.h rename to rpcs3/Emu/Cell/lv2/sys_mutex.h index 8e736b5ea9..97f9d7d858 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mutex.h +++ b/rpcs3/Emu/Cell/lv2/sys_mutex.h @@ -1,8 +1,6 @@ #pragma once -#include "Utilities/SleepQueue.h" - -namespace vm { using namespace ps3; } +#include "sys_sync.h" struct sys_mutex_attribute_t { @@ -27,11 +25,11 @@ struct lv2_mutex_t const u32 protocol; const u64 name; - std::atomic cond_count{ 0 }; // count of condition variables associated - std::atomic recursive_count{ 0 }; // count of recursive locks - std::shared_ptr owner; // current mutex owner + atomic_t cond_count{ 0 }; // count of condition variables associated + atomic_t recursive_count{ 0 }; // count of recursive locks + std::shared_ptr owner; // current mutex owner - sleep_queue_t sq; + sleep_queue sq; lv2_mutex_t(bool recursive, u32 protocol, u64 name) : recursive(recursive) @@ -40,7 +38,7 @@ struct lv2_mutex_t { } - void unlock(lv2_lock_t& lv2_lock); + void unlock(lv2_lock_t); }; class PPUThread; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp b/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp similarity index 90% rename from rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp rename to rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp index 51cff30866..f895072977 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp @@ -1,14 +1,15 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/SysCalls/SysCalls.h" +#include "Emu/Cell/ErrorCodes.h" #include "Emu/Cell/PPUThread.h" #include "sys_mutex.h" #include "sys_ppu_thread.h" -SysCallBase sys_ppu_thread("sys_ppu_thread"); +LOG_CHANNEL(sys_ppu_thread); void _sys_ppu_thread_exit(PPUThread& ppu, u64 errorcode) { @@ -28,17 +29,17 @@ void _sys_ppu_thread_exit(PPUThread& ppu, u64 errorcode) if (!ppu.is_joinable) { - idm::remove(ppu.get_id()); + idm::remove(ppu.id); } else { - ppu.exit(); + ppu.state += cpu_state::exit; } - // Throw if this syscall was not called directly by the SC instruction - if (~ppu.hle_code != 41) + // Throw if this syscall was not called directly by the SC instruction (hack) + if (ppu.GPR[11] != 41 || ppu.custom_task) { - throw CPUThreadExit{}; + throw cpu_state::exit; } } @@ -76,7 +77,7 @@ s32 sys_ppu_thread_join(PPUThread& ppu, u32 thread_id, vm::ptr vptr) thread->is_joining = true; // join thread - while (thread->is_alive()) + while (!(thread->state & cpu_state::exit)) { CHECK_EMU_STATUS; @@ -84,10 +85,10 @@ s32 sys_ppu_thread_join(PPUThread& ppu, u32 thread_id, vm::ptr vptr) } // get exit status from the register - *vptr = thread->GPR[3]; + if (vptr) *vptr = thread->GPR[3]; // cleanup - idm::remove(thread->get_id()); + idm::remove(thread->id); return CELL_OK; } @@ -225,7 +226,7 @@ u32 ppu_thread_create(u32 entry, u64 arg, s32 prio, u32 stacksize, const std::st ppu->prio = prio; ppu->stack_size = stacksize; ppu->custom_task = std::move(task); - ppu->run(); + ppu->cpu_init(); if (entry) { @@ -234,9 +235,10 @@ u32 ppu_thread_create(u32 entry, u64 arg, s32 prio, u32 stacksize, const std::st } ppu->GPR[3] = arg; - ppu->exec(); + ppu->state -= cpu_state::stop; + ppu->safe_notify(); - return ppu->get_id(); + return ppu->id; } s32 _sys_ppu_thread_create(vm::ptr thread_id, vm::ptr param, u64 arg, u64 unk, s32 prio, u32 stacksize, u64 flags, vm::cptr threadname) @@ -263,21 +265,17 @@ s32 _sys_ppu_thread_create(vm::ptr thread_id, vm::ptr p ppu->prio = prio; ppu->stack_size = std::max(stacksize, 0x4000); - ppu->run(); + ppu->cpu_init(); ppu->PC = vm::read32(param->entry); ppu->GPR[2] = vm::read32(param->entry + 4); // rtoc ppu->GPR[3] = arg; ppu->GPR[4] = unk; // actually unknown + ppu->GPR[13] = param->tls; ppu->is_joinable = is_joinable; - if (u32 tls = param->tls) // hack - { - ppu->GPR[13] = tls; - } - - *thread_id = ppu->get_id(); + *thread_id = ppu->id; return CELL_OK; } @@ -295,7 +293,8 @@ s32 sys_ppu_thread_start(u32 thread_id) return CELL_ESRCH; } - thread->exec(); + thread->state -= cpu_state::stop; + thread->safe_notify(); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h b/rpcs3/Emu/Cell/lv2/sys_ppu_thread.h similarity index 100% rename from rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h rename to rpcs3/Emu/Cell/lv2/sys_ppu_thread.h diff --git a/rpcs3/Emu/SysCalls/lv2/sys_process.cpp b/rpcs3/Emu/Cell/lv2/sys_process.cpp similarity index 97% rename from rpcs3/Emu/SysCalls/lv2/sys_process.cpp rename to rpcs3/Emu/Cell/lv2/sys_process.cpp index 9de2ae7dbc..8291849120 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_process.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_process.cpp @@ -1,12 +1,10 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/FS/VFS.h" -#include "Emu/FS/vfsFile.h" -#include "Loader/PSF.h" +#include "Emu/Cell/ErrorCodes.h" #include "sys_lwmutex.h" #include "sys_lwcond.h" #include "sys_mutex.h" @@ -24,7 +22,7 @@ #include "sys_fs.h" #include "sys_process.h" -SysCallBase sys_process("sys_process"); +LOG_CHANNEL(sys_process); s32 process_getpid() { diff --git a/rpcs3/Emu/SysCalls/lv2/sys_process.h b/rpcs3/Emu/Cell/lv2/sys_process.h similarity index 100% rename from rpcs3/Emu/SysCalls/lv2/sys_process.h rename to rpcs3/Emu/Cell/lv2/sys_process.h diff --git a/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp b/rpcs3/Emu/Cell/lv2/sys_prx.cpp similarity index 62% rename from rpcs3/Emu/SysCalls/lv2/sys_prx.cpp rename to rpcs3/Emu/Cell/lv2/sys_prx.cpp index 4f39c3059f..99ec5b9ac5 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_prx.cpp @@ -1,142 +1,32 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/CB_FUNC.h" -#include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/ModuleManager.h" -#include "Emu/Cell/PPUInstrTable.h" - -#include "Emu/FS/VFS.h" -#include "Emu/FS/vfsFile.h" #include "Crypto/unself.h" -#include "Loader/ELF64.h" +#include "Loader/ELF.h" + +#include "Emu/Cell/ErrorCodes.h" #include "sys_prx.h" -SysCallBase sys_prx("sys_prx"); - -lv2_prx_t::lv2_prx_t() - : id(idm::get_last_id()) -{ -} +LOG_CHANNEL(sys_prx); s32 prx_load_module(std::string path, u64 flags, vm::ptr pOpt) { sys_prx.warning("prx_load_module(path='%s', flags=0x%llx, pOpt=*0x%x)", path.c_str(), flags, pOpt); - loader::handlers::elf64 loader; + const ppu_prx_loader loader = fs::file(vfs::get(path)); - vfsFile f(path); - if (!f.IsOpened()) - { - return CELL_PRX_ERROR_UNKNOWN_MODULE; - } - - if (loader.init(f) != loader::handler::error_code::ok || !loader.is_sprx()) + if (loader != elf_error::ok) { return CELL_PRX_ERROR_ILLEGAL_LIBRARY; } - loader::handlers::elf64::sprx_info info; - loader.load_sprx(info); + const auto prx = loader.load(); - auto prx = idm::make_ptr(); - - auto meta = info.modules[""]; - prx->start.set(meta.exports[0xBC9A0086]); - prx->stop.set(meta.exports[0xAB779874]); - prx->exit.set(meta.exports[0x3AB9A95E]); - - for (auto &module_ : info.modules) + if (!prx) { - if (module_.first == "") - continue; - - Module<>* module = Emu.GetModuleManager().GetModuleByName(module_.first.c_str()); - - if (!module) - { - sys_prx.error("Unknown module '%s'", module_.first.c_str()); - } - - for (auto& f : module_.second.exports) - { - const u32 nid = f.first; - const u32 addr = f.second; - - u32 index; - - auto func = get_ppu_func_by_nid(nid, &index); - - if (!func) - { - index = add_ppu_func(ModuleFunc(nid, 0, module, nullptr, nullptr, vm::ptr::make(addr))); - } - else - { - func->lle_func.set(addr); - - if (func->flags & MFF_FORCED_HLE) - { - u32 i_addr = 0; - - if (!vm::check_addr(addr, 8) || !vm::check_addr(i_addr = vm::read32(addr), 4)) - { - sys_prx.error("Failed to inject code for exported function '%s' (opd=0x%x, 0x%x)", get_ps3_function_name(nid), addr, i_addr); - } - else - { - vm::write32(i_addr, PPU_instr::HACK(index | EIF_PERFORM_BLR)); - } - } - } - } - - for (auto &import : module_.second.imports) - { - u32 nid = import.first; - u32 addr = import.second; - - u32 index; - - auto func = get_ppu_func_by_nid(nid, &index); - - if (!func) - { - sys_prx.error("Unknown function '%s' in '%s' module (0x%x)", get_ps3_function_name(nid), module_.first); - - index = add_ppu_func(ModuleFunc(nid, 0, module, nullptr, nullptr)); - } - else - { - const bool is_lle = func->lle_func && !(func->flags & MFF_FORCED_HLE); - - sys_prx.error("Imported %sfunction '%s' in '%s' module (0x%x)", (is_lle ? "LLE " : ""), get_ps3_function_name(nid), module_.first, addr); - } - - if (!patch_ppu_import(addr, index)) - { - sys_prx.error("Failed to inject code at address 0x%x", addr); - } - } - } - - const auto decoder_cache = fxm::get(); - - for (auto& seg : info.segments) - { - const u32 addr = seg.begin.addr(); - const u32 size = align(seg.size, 4096); - - if (vm::check_addr(addr, size)) - { - decoder_cache->initialize(addr, size); - } - else - { - sys_prx.error("Failed to process executable area (addr=0x%x, size=0x%x)", addr, size); - } + return CELL_PRX_ERROR_ILLEGAL_LIBRARY; } return prx->id; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_prx.h b/rpcs3/Emu/Cell/lv2/sys_prx.h similarity index 69% rename from rpcs3/Emu/SysCalls/lv2/sys_prx.h rename to rpcs3/Emu/Cell/lv2/sys_prx.h index 89371e63ed..4d513b03b3 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_prx.h +++ b/rpcs3/Emu/Cell/lv2/sys_prx.h @@ -30,114 +30,21 @@ enum CELL_PRX_ERROR_ELF_IS_REGISTERED = 0x80011910, // Fixed ELF is already registered }; -struct sys_stub -{ - u8 s_size; // = 0x2c - u8 s_unk0; - be_t s_version; // = 0x1 - be_t s_unk1; // = 0x9 // flags? - be_t s_imports; - be_t s_unk2; // = 0x0 - be_t s_unk3; // = 0x0 - vm::bcptr s_modulename; - vm::bptr s_nid; - vm::bptr s_text; - be_t s_unk4; // = 0x0 - be_t s_unk5; // = 0x0 - be_t s_unk6; // = 0x0 - be_t s_unk7; // = 0x0 -}; - -struct sys_proc_prx_param -{ - be_t size; - be_t magic; - be_t version; - be_t pad0; - be_t libentstart; - be_t libentend; - vm::bptr libstubstart; - vm::bptr libstubend; - be_t ver; - be_t pad1; - be_t pad2; -}; - -// Information about imported or exported libraries in PRX modules -struct sys_prx_library_info_t -{ - u8 size; - u8 unk0; - be_t version; - be_t attributes; - be_t num_func; - be_t num_var; - be_t num_tlsvar; - u8 info_hash; - u8 info_tlshash; - u8 unk1[2]; - be_t name_addr; - be_t fnid_addr; - be_t fstub_addr; - be_t unk4; - be_t unk5; - be_t unk6; - be_t unk7; -}; - -// ELF file headers -struct sys_prx_param_t -{ - be_t size; - be_t magic; - be_t version; - be_t unk0; - be_t libentstart; - be_t libentend; - vm::bptr libstubstart; - vm::bptr libstubend; - be_t ver; - be_t unk1; - be_t unk2; -}; - struct sys_prx_get_module_id_by_name_option_t { be_t size; vm::ptr base; }; -// PRX file headers -struct sys_prx_module_info_t -{ - be_t attributes; - be_t version; - char name[28]; - be_t toc; - vm::bptr exports_start; - vm::bptr exports_end; - be_t imports_start; - be_t imports_end; -}; - -// Relocation information of the SCE_PPURELA segment -struct sys_prx_relocation_info_t -{ - be_t offset; - be_t unk0; - u8 index_value; - u8 index_addr; - be_t type; - vm::bptr ptr; -}; - -// Data types struct sys_prx_load_module_option_t { be_t size; vm::bptr base_addr; }; +struct sys_prx_segment_info_t;// TODO +struct sys_prx_module_info_t;// TODO + struct sys_prx_start_module_option_t { be_t size; @@ -165,18 +72,17 @@ struct sys_prx_get_module_list_t vm::bptr idlist; }; -// Auxiliary data types struct lv2_prx_t { - const u32 id; + const u32 id{}; bool is_started = false; + std::unordered_map specials; + vm::ptr argv)> start = vm::null; vm::ptr argv)> stop = vm::null; vm::ptr exit = vm::null; - - lv2_prx_t(); }; // SysCalls diff --git a/rpcs3/Emu/SysCalls/lv2/sys_rsx.cpp b/rpcs3/Emu/Cell/lv2/sys_rsx.cpp similarity index 98% rename from rpcs3/Emu/SysCalls/lv2/sys_rsx.cpp rename to rpcs3/Emu/Cell/lv2/sys_rsx.cpp index eb25345942..5d4d8ee83d 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_rsx.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_rsx.cpp @@ -1,11 +1,12 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/SysCalls/SysCalls.h" +#include "Emu/Cell/ErrorCodes.h" #include "sys_rsx.h" -SysCallBase sys_rsx("sys_rsx"); +LOG_CHANNEL(sys_rsx); s32 sys_rsx_device_open() { diff --git a/rpcs3/Emu/SysCalls/lv2/sys_rsx.h b/rpcs3/Emu/Cell/lv2/sys_rsx.h similarity index 100% rename from rpcs3/Emu/SysCalls/lv2/sys_rsx.h rename to rpcs3/Emu/Cell/lv2/sys_rsx.h diff --git a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp b/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp similarity index 87% rename from rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp rename to rpcs3/Emu/Cell/lv2/sys_rwlock.cpp index 1145e6cb31..0188cf7ac6 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp @@ -1,30 +1,26 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/SysCalls/SysCalls.h" +#include "Emu/Cell/ErrorCodes.h" #include "Emu/Cell/PPUThread.h" -#include "sys_sync.h" #include "sys_rwlock.h" -SysCallBase sys_rwlock("sys_rwlock"); +LOG_CHANNEL(sys_rwlock); extern u64 get_system_time(); -void lv2_rwlock_t::notify_all(lv2_lock_t& lv2_lock) +void lv2_rwlock_t::notify_all(lv2_lock_t) { - CHECK_LV2_LOCK(lv2_lock); - // pick a new writer if possible; protocol is ignored in current implementation if (!readers && !writer && wsq.size()) { - writer = wsq.front(); + writer = std::static_pointer_cast(wsq.front()->shared_from_this()); - if (!writer->signal()) - { - throw EXCEPTION("Writer already signaled"); - } + ASSERT(!writer->state.test_and_set(cpu_state::signal)); + writer->cv.notify_one(); return wsq.pop_front(); } @@ -36,10 +32,8 @@ void lv2_rwlock_t::notify_all(lv2_lock_t& lv2_lock) for (auto& thread : rsq) { - if (!thread->signal()) - { - throw EXCEPTION("Reader already signaled"); - } + ASSERT(!thread->state.test_and_set(cpu_state::signal)); + thread->cv.notify_one(); } return rsq.clear(); @@ -123,9 +117,9 @@ s32 sys_rwlock_rlock(PPUThread& ppu, u32 rw_lock_id, u64 timeout) } // add waiter; protocol is ignored in current implementation - sleep_queue_entry_t waiter(ppu, rwlock->rsq); + sleep_entry waiter(rwlock->rsq, ppu); - while (!ppu.unsignal()) + while (!ppu.state.test_and_reset(cpu_state::signal)) { CHECK_EMU_STATUS; @@ -228,15 +222,15 @@ s32 sys_rwlock_wlock(PPUThread& ppu, u32 rw_lock_id, u64 timeout) if (!rwlock->readers && !rwlock->writer) { - rwlock->writer = std::static_pointer_cast(ppu.shared_from_this()); + rwlock->writer = std::static_pointer_cast(ppu.shared_from_this()); return CELL_OK; } // add waiter; protocol is ignored in current implementation - sleep_queue_entry_t waiter(ppu, rwlock->wsq); + sleep_entry waiter(rwlock->wsq, ppu); - while (!ppu.unsignal()) + while (!ppu.state.test_and_reset(cpu_state::signal)) { CHECK_EMU_STATUS; @@ -249,7 +243,7 @@ s32 sys_rwlock_wlock(PPUThread& ppu, u32 rw_lock_id, u64 timeout) // if the last waiter quit the writer sleep queue, readers must acquire the lock if (!rwlock->writer && rwlock->wsq.size() == 1) { - if (rwlock->wsq.front().get() != &ppu) + if (rwlock->wsq.front() != &ppu) { throw EXCEPTION("Unexpected"); } @@ -300,7 +294,7 @@ s32 sys_rwlock_trywlock(PPUThread& ppu, u32 rw_lock_id) return CELL_EBUSY; } - rwlock->writer = std::static_pointer_cast(ppu.shared_from_this()); + rwlock->writer = std::static_pointer_cast(ppu.shared_from_this()); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.h b/rpcs3/Emu/Cell/lv2/sys_rwlock.h similarity index 70% rename from rpcs3/Emu/SysCalls/lv2/sys_rwlock.h rename to rpcs3/Emu/Cell/lv2/sys_rwlock.h index ea9f19f138..596f1ad010 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.h +++ b/rpcs3/Emu/Cell/lv2/sys_rwlock.h @@ -1,8 +1,6 @@ #pragma once -#include "Utilities/SleepQueue.h" - -namespace vm { using namespace ps3; } +#include "sys_sync.h" struct sys_rwlock_attribute_t { @@ -24,11 +22,11 @@ struct lv2_rwlock_t const u64 name; const u32 protocol; - std::atomic readers{ 0 }; // reader lock count - std::shared_ptr writer; // writer lock owner + atomic_t readers{ 0 }; // reader lock count + std::shared_ptr writer; // writer lock owner - sleep_queue_t rsq; // threads trying to acquire readed lock - sleep_queue_t wsq; // threads trying to acquire writer lock + sleep_queue rsq; // threads trying to acquire readed lock + sleep_queue wsq; // threads trying to acquire writer lock lv2_rwlock_t(u32 protocol, u64 name) : protocol(protocol) @@ -36,7 +34,7 @@ struct lv2_rwlock_t { } - void notify_all(lv2_lock_t& lv2_lock); + void notify_all(lv2_lock_t); }; // Aux diff --git a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp b/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp similarity index 92% rename from rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp rename to rpcs3/Emu/Cell/lv2/sys_semaphore.cpp index 089c38f814..04c4a59c9c 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp @@ -1,14 +1,14 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/SysCalls/SysCalls.h" +#include "Emu/Cell/ErrorCodes.h" #include "Emu/Cell/PPUThread.h" -#include "sys_sync.h" #include "sys_semaphore.h" -SysCallBase sys_semaphore("sys_semaphore"); +LOG_CHANNEL(sys_semaphore); extern u64 get_system_time(); @@ -92,9 +92,9 @@ s32 sys_semaphore_wait(PPUThread& ppu, u32 sem_id, u64 timeout) } // add waiter; protocol is ignored in current implementation - sleep_queue_entry_t waiter(ppu, sem->sq); + sleep_entry waiter(sem->sq, ppu); - while (!ppu.unsignal()) + while (!ppu.state.test_and_reset(cpu_state::signal)) { CHECK_EMU_STATUS; @@ -173,10 +173,9 @@ s32 sys_semaphore_post(u32 sem_id, s32 count) { count--; - if (!sem->sq.front()->signal()) - { - throw EXCEPTION("Thread already signaled"); - } + auto& thread = sem->sq.front(); + ASSERT(!thread->state.test_and_set(cpu_state::signal)); + thread->cv.notify_one(); sem->sq.pop_front(); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.h b/rpcs3/Emu/Cell/lv2/sys_semaphore.h similarity index 87% rename from rpcs3/Emu/SysCalls/lv2/sys_semaphore.h rename to rpcs3/Emu/Cell/lv2/sys_semaphore.h index f179b072cd..9885b1a2eb 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.h +++ b/rpcs3/Emu/Cell/lv2/sys_semaphore.h @@ -1,8 +1,6 @@ #pragma once -#include "Utilities/SleepQueue.h" - -namespace vm { using namespace ps3; } +#include "sys_sync.h" struct sys_semaphore_attribute_t { @@ -25,9 +23,9 @@ struct lv2_sema_t const s32 max; const u64 name; - std::atomic value; + atomic_t value; - sleep_queue_t sq; + sleep_queue sq; lv2_sema_t(u32 protocol, s32 max, u64 name, s32 value) : protocol(protocol) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp b/rpcs3/Emu/Cell/lv2/sys_spu.cpp similarity index 91% rename from rpcs3/Emu/SysCalls/lv2/sys_spu.cpp rename to rpcs3/Emu/Cell/lv2/sys_spu.cpp index 470c644dc1..fde8c1320b 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_spu.cpp @@ -1,30 +1,40 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/SysCalls/SysCalls.h" - -#include "Emu/CPU/CPUThreadManager.h" -#include "Emu/Cell/RawSPUThread.h" -#include "Emu/FS/vfsStreamMemory.h" -#include "Emu/FS/vfsFile.h" -#include "Loader/ELF32.h" #include "Crypto/unself.h" +#include "Loader/ELF.h" + +#include "Emu/Cell/ErrorCodes.h" +#include "Emu/Cell/RawSPUThread.h" #include "sys_interrupt.h" #include "sys_event.h" #include "sys_spu.h" -SysCallBase sys_spu("sys_spu"); +LOG_CHANNEL(sys_spu); -void LoadSpuImage(vfsStream& stream, u32& spu_ep, u32 addr) +void LoadSpuImage(const fs::file& stream, u32& spu_ep, u32 addr) { - loader::handlers::elf32 h; - h.init(stream); - h.load_data(addr); - spu_ep = h.m_ehdr.data_be.e_entry; + const spu_exec_loader loader = stream; + + if (loader != elf_error::ok) + { + throw fmt::exception("Failed to load SPU image: %s" HERE, bijective_find(loader, "???")); + } + + for (const auto& prog : loader.progs) + { + if (prog.p_type == 0x1 /* LOAD */) + { + std::memcpy(vm::base(addr + prog.p_vaddr), prog.bin.data(), prog.p_filesz); + } + } + + spu_ep = loader.header.e_entry; } -u32 LoadSpuImage(vfsStream& stream, u32& spu_ep) +u32 LoadSpuImage(const fs::file& stream, u32& spu_ep) { const u32 alloc_size = 256 * 1024; u32 spu_offset = (u32)vm::alloc(alloc_size, vm::main); @@ -33,20 +43,6 @@ u32 LoadSpuImage(vfsStream& stream, u32& spu_ep) return spu_offset; } -s32 spu_image_import(sys_spu_image& img, u32 src, u32 type) -{ - vfsStreamMemory f(src); - u32 entry; - u32 offset = LoadSpuImage(f, entry); - - img.type = SYS_SPU_IMAGE_TYPE_USER; - img.entry_point = entry; - img.addr = offset; // TODO: writing actual segment info - img.nsegs = 1; // wrong value - - return CELL_OK; -} - s32 sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu) { sys_spu.warning("sys_spu_initialize(max_usable_spu=%d, max_raw_spu=%d)", max_usable_spu, max_raw_spu); @@ -59,14 +55,14 @@ s32 sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu) return CELL_OK; } -s32 sys_spu_image_open(vm::ptr img, vm::cptr path) +s32 sys_spu_image_open(vm::ptr img, vm::cptr path) { sys_spu.warning("sys_spu_image_open(img=*0x%x, path=*0x%x)", img, path); - vfsFile f(path.get_ptr()); - if(!f.IsOpened()) + const fs::file f(vfs::get(path.get_ptr())); + if (!f) { - sys_spu.error("sys_spu_image_open error: '%s' not found!", path.get_ptr()); + sys_spu.error("sys_spu_image_open() error: '%s' not found!", path.get_ptr()); return CELL_ENOENT; } @@ -75,25 +71,23 @@ s32 sys_spu_image_open(vm::ptr img, vm::cptr path) if (hdr.CheckMagic()) { - sys_spu.error("sys_spu_image_open error: '%s' is encrypted! Decrypt SELF and try again.", path.get_ptr()); - Emu.Pause(); - return CELL_ENOENT; + throw fmt::exception("sys_spu_image_open() error: '%s' is encrypted! Try to decrypt it manually and try again.", path.get_ptr()); } - f.Seek(0); + f.seek(0); u32 entry; u32 offset = LoadSpuImage(f, entry); img->type = SYS_SPU_IMAGE_TYPE_USER; img->entry_point = entry; - img->addr = offset; // TODO: writing actual segment info + img->segs.set(offset); // TODO: writing actual segment info img->nsegs = 1; // wrong value return CELL_OK; } -u32 spu_thread_initialize(u32 group_id, u32 spu_num, vm::ptr img, const std::string& name, u32 option, u64 a1, u64 a2, u64 a3, u64 a4, std::function task = nullptr) +u32 spu_thread_initialize(u32 group_id, u32 spu_num, vm::ptr img, const std::string& name, u32 option, u64 a1, u64 a2, u64 a3, u64 a4, std::function task = nullptr) { if (option) { @@ -131,10 +125,10 @@ u32 spu_thread_initialize(u32 group_id, u32 spu_num, vm::ptr img, group->state = SPU_THREAD_GROUP_STATUS_INITIALIZED; } - return spu->get_id(); + return spu->id; } -s32 sys_spu_thread_initialize(vm::ptr thread, u32 group_id, u32 spu_num, vm::ptr img, vm::ptr attr, vm::ptr arg) +s32 sys_spu_thread_initialize(vm::ptr thread, u32 group_id, u32 spu_num, vm::ptr img, vm::ptr attr, vm::ptr arg) { sys_spu.warning("sys_spu_thread_initialize(thread=*0x%x, group=0x%x, spu_num=%d, img=*0x%x, attr=*0x%x, arg=*0x%x)", thread, group_id, spu_num, img, attr, arg); @@ -263,7 +257,7 @@ s32 sys_spu_thread_group_destroy(u32 id) { if (t) { - idm::remove(t->get_id()); + idm::remove(t->id); t.reset(); } @@ -312,10 +306,10 @@ s32 sys_spu_thread_group_start(u32 id) // Copy SPU image: // TODO: use segment info - std::memcpy(vm::base(t->offset), vm::base(image->addr), 256 * 1024); + std::memcpy(vm::base(t->offset), image->segs.get_ptr(), 256 * 1024); t->pc = image->entry_point; - t->run(); + t->cpu_init(); t->gpr[3] = v128::from64(0, args.arg1); t->gpr[4] = v128::from64(0, args.arg2); t->gpr[5] = v128::from64(0, args.arg3); @@ -329,9 +323,13 @@ s32 sys_spu_thread_group_start(u32 id) group->send_run_event(lv2_lock, id, 0, 0); // TODO: check data2 and data3 - for (auto& t : group->threads) + for (auto& thread : group->threads) { - if (t) t->exec(); + if (thread) + { + thread->state -= cpu_state::stop; + thread->safe_notify(); + } } return CELL_OK; @@ -379,9 +377,12 @@ s32 sys_spu_thread_group_suspend(u32 id) return CELL_ESTAT; } - for (auto& t : group->threads) + for (auto& thread : group->threads) { - if (t) t->sleep(); // trigger status check + if (thread) + { + thread->state += cpu_state::suspend; + } } return CELL_OK; @@ -420,9 +421,13 @@ s32 sys_spu_thread_group_resume(u32 id) return CELL_ESTAT; } - for (auto& t : group->threads) + for (auto& thread : group->threads) { - if (t) t->awake(); // untrigger status check + if (thread) + { + thread->state -= cpu_state::suspend; + thread->safe_notify(); + } } group->cv.notify_all(); @@ -499,9 +504,13 @@ s32 sys_spu_thread_group_terminate(u32 id, s32 value) return CELL_ESTAT; } - for (auto& t : group->threads) + for (auto& thread : group->threads) { - if (t) t->stop(); + if (thread) + { + thread->state += cpu_state::stop; + thread->safe_notify(); + } } group->state = SPU_THREAD_GROUP_STATUS_INITIALIZED; @@ -1143,14 +1152,14 @@ s32 sys_raw_spu_create(vm::ptr id, vm::ptr attr) // TODO: check number set by sys_spu_initialize() - const auto thread = Emu.GetCPU().NewRawSPUThread(); + const auto thread = idm::make_ptr(""); if (!thread) { return CELL_EAGAIN; } - thread->run(); + thread->cpu_init(); *id = thread->index; @@ -1163,7 +1172,7 @@ s32 sys_raw_spu_destroy(PPUThread& ppu, u32 id) LV2_LOCK; - const auto thread = Emu.GetCPU().GetRawSPUThread(id); + const auto thread = idm::get(id); if (!thread) { @@ -1173,7 +1182,7 @@ s32 sys_raw_spu_destroy(PPUThread& ppu, u32 id) // TODO: CELL_EBUSY is not returned // Stop thread - thread->stop(); + thread->state += cpu_state::stop; // Clear interrupt handlers for (auto& intr : thread->int_ctrl) @@ -1189,7 +1198,7 @@ s32 sys_raw_spu_destroy(PPUThread& ppu, u32 id) } } - idm::remove(thread->get_id()); + idm::remove(thread->id); return CELL_OK; } @@ -1200,7 +1209,7 @@ s32 sys_raw_spu_create_interrupt_tag(u32 id, u32 class_id, u32 hwthread, vm::ptr LV2_LOCK; - const auto thread = Emu.GetCPU().GetRawSPUThread(id); + const auto thread = idm::get(id); if (!thread) { @@ -1235,7 +1244,7 @@ s32 sys_raw_spu_set_int_mask(u32 id, u32 class_id, u64 mask) return CELL_EINVAL; } - const auto thread = Emu.GetCPU().GetRawSPUThread(id); + const auto thread = idm::get(id); if (!thread) { @@ -1256,7 +1265,7 @@ s32 sys_raw_spu_get_int_mask(u32 id, u32 class_id, vm::ptr mask) return CELL_EINVAL; } - const auto thread = Emu.GetCPU().GetRawSPUThread(id); + const auto thread = idm::get(id); if (!thread) { @@ -1277,7 +1286,7 @@ s32 sys_raw_spu_set_int_stat(u32 id, u32 class_id, u64 stat) return CELL_EINVAL; } - const auto thread = Emu.GetCPU().GetRawSPUThread(id); + const auto thread = idm::get(id); if (!thread) { @@ -1298,7 +1307,7 @@ s32 sys_raw_spu_get_int_stat(u32 id, u32 class_id, vm::ptr stat) return CELL_EINVAL; } - const auto thread = Emu.GetCPU().GetRawSPUThread(id); + const auto thread = idm::get(id); if (!thread) { @@ -1314,7 +1323,7 @@ s32 sys_raw_spu_read_puint_mb(u32 id, vm::ptr value) { sys_spu.trace("sys_raw_spu_read_puint_mb(id=%d, value=*0x%x)", id, value); - const auto thread = Emu.GetCPU().GetRawSPUThread(id); + const auto thread = idm::get(id); if (!thread) { @@ -1343,7 +1352,7 @@ s32 sys_raw_spu_set_spu_cfg(u32 id, u32 value) throw EXCEPTION("Unexpected value (0x%x)", value); } - const auto thread = Emu.GetCPU().GetRawSPUThread(id); + const auto thread = idm::get(id); if (!thread) { @@ -1359,7 +1368,7 @@ s32 sys_raw_spu_get_spu_cfg(u32 id, vm::ptr value) { sys_spu.trace("sys_raw_spu_get_spu_afg(id=%d, value=*0x%x)", id, value); - const auto thread = Emu.GetCPU().GetRawSPUThread(id); + const auto thread = idm::get(id); if (!thread) { diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.h b/rpcs3/Emu/Cell/lv2/sys_spu.h similarity index 86% rename from rpcs3/Emu/SysCalls/lv2/sys_spu.h rename to rpcs3/Emu/Cell/lv2/sys_spu.h index 1b720448de..cc6475447b 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.h +++ b/rpcs3/Emu/Cell/lv2/sys_spu.h @@ -1,7 +1,5 @@ #pragma once -namespace vm { using namespace ps3; } - #include "sys_event.h" enum : s32 @@ -107,15 +105,11 @@ enum : u32 SYS_SPU_IMAGE_TYPE_KERNEL = 1, }; -struct sys_spu_image +struct sys_spu_image_t { be_t type; // user, kernel be_t entry_point; - union - { - be_t addr; // temporarily used as offset of the whole LS image (should be removed) - vm::bptr segs; - }; + vm::bptr segs; be_t nsegs; }; @@ -151,14 +145,14 @@ struct lv2_spu_group_t const u32 ct; // Memory Container Id std::array, 256> threads; // SPU Threads - std::array, 256> images; // SPU Images + std::array, 256> images; // SPU Images std::array args; // SPU Thread Arguments s32 prio; // SPU Thread Group Priority volatile u32 state; // SPU Thread Group State s32 exit_status; // SPU Thread Group Exit Status - std::atomic join_state; // flags used to detect exit cause + atomic_t join_state; // flags used to detect exit cause std::condition_variable cv; // used to signal waiting PPU thread std::weak_ptr ep_run; // port for SYS_SPU_THREAD_GROUP_EVENT_RUN events @@ -177,30 +171,24 @@ struct lv2_spu_group_t { } - void send_run_event(lv2_lock_t& lv2_lock, u64 data1, u64 data2, u64 data3) + void send_run_event(lv2_lock_t lv2_lock, u64 data1, u64 data2, u64 data3) { - CHECK_LV2_LOCK(lv2_lock); - if (const auto queue = ep_run.lock()) { queue->push(lv2_lock, SYS_SPU_THREAD_GROUP_EVENT_RUN_KEY, data1, data2, data3); } } - void send_exception_event(lv2_lock_t& lv2_lock, u64 data1, u64 data2, u64 data3) + void send_exception_event(lv2_lock_t lv2_lock, u64 data1, u64 data2, u64 data3) { - CHECK_LV2_LOCK(lv2_lock); - if (const auto queue = ep_exception.lock()) { queue->push(lv2_lock, SYS_SPU_THREAD_GROUP_EVENT_EXCEPTION_KEY, data1, data2, data3); } } - void send_sysmodule_event(lv2_lock_t& lv2_lock, u64 data1, u64 data2, u64 data3) + void send_sysmodule_event(lv2_lock_t lv2_lock, u64 data1, u64 data2, u64 data3) { - CHECK_LV2_LOCK(lv2_lock); - if (const auto queue = ep_sysmodule.lock()) { queue->push(lv2_lock, SYS_SPU_THREAD_GROUP_EVENT_SYSTEM_MODULE_KEY, data1, data2, data3); @@ -208,20 +196,17 @@ struct lv2_spu_group_t } }; -struct vfsStream; class PPUThread; -void LoadSpuImage(vfsStream& stream, u32& spu_ep, u32 addr); -u32 LoadSpuImage(vfsStream& stream, u32& spu_ep); - // Aux -s32 spu_image_import(sys_spu_image& img, u32 src, u32 type); +void LoadSpuImage(const fs::file& stream, u32& spu_ep, u32 addr); +u32 LoadSpuImage(const fs::file& stream, u32& spu_ep); // SysCalls s32 sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu); -s32 sys_spu_image_open(vm::ptr img, vm::cptr path); -s32 sys_spu_image_close(vm::ptr img); -s32 sys_spu_thread_initialize(vm::ptr thread, u32 group, u32 spu_num, vm::ptr img, vm::ptr attr, vm::ptr arg); +s32 sys_spu_image_open(vm::ptr img, vm::cptr path); +s32 sys_spu_image_close(vm::ptr img); +s32 sys_spu_thread_initialize(vm::ptr thread, u32 group, u32 spu_num, vm::ptr img, vm::ptr attr, vm::ptr arg); s32 sys_spu_thread_set_argument(u32 id, vm::ptr arg); s32 sys_spu_thread_group_create(vm::ptr id, u32 num, s32 prio, vm::ptr attr); s32 sys_spu_thread_group_destroy(u32 id); diff --git a/rpcs3/Emu/Cell/lv2/sys_sync.h b/rpcs3/Emu/Cell/lv2/sys_sync.h new file mode 100644 index 0000000000..37b147e472 --- /dev/null +++ b/rpcs3/Emu/Cell/lv2/sys_sync.h @@ -0,0 +1,113 @@ +#pragma once + +#include "Utilities/SharedMutex.h" +#include "Utilities/SleepQueue.h" + +namespace vm { using namespace ps3; } + +// attr_protocol (waiting scheduling policy) +enum +{ + // First In, First Out + SYS_SYNC_FIFO = 1, + // Priority Order + SYS_SYNC_PRIORITY = 2, + // Basic Priority Inheritance Protocol (probably not implemented) + SYS_SYNC_PRIORITY_INHERIT = 3, + // Not selected while unlocking + SYS_SYNC_RETRY = 4, + // + SYS_SYNC_ATTR_PROTOCOL_MASK = 0xF, +}; + +// attr_recursive (recursive locks policy) +enum +{ + // Recursive locks are allowed + SYS_SYNC_RECURSIVE = 0x10, + // Recursive locks are NOT allowed + SYS_SYNC_NOT_RECURSIVE = 0x20, + // + SYS_SYNC_ATTR_RECURSIVE_MASK = 0xF0, //??? +}; + +// attr_pshared +enum +{ + SYS_SYNC_NOT_PROCESS_SHARED = 0x200, +}; + +// attr_adaptive +enum +{ + SYS_SYNC_ADAPTIVE = 0x1000, + SYS_SYNC_NOT_ADAPTIVE = 0x2000, +}; + +// IPC manager collection for lv2 objects of type T +template +class ipc_manager final +{ + mutable shared_mutex m_mutex; + std::unordered_map> m_map; + +public: + // Add new object if specified ipc_key is not used + template + auto add(u64 ipc_key, F&& provider) -> decltype(static_cast>(provider())) + { + std::lock_guard lock(m_mutex); + + // Get object location + std::weak_ptr& wptr = m_map[ipc_key]; + + if (wptr.expired()) + { + // Call a function which must return the object + std::shared_ptr&& result = provider(); + wptr = result; + return result; + } + + return{}; + } + + // Get existing object with specified ipc_key + std::shared_ptr get(u64 ipc_key) const + { + reader_lock lock(m_mutex); + + const auto found = m_map.find(ipc_key); + + if (found != m_map.end()) + { + return found->second.lock(); + } + + return{}; + } +}; + +// Simple class for global mutex to pass unique_lock and check it +struct lv2_lock_t +{ + using type = std::unique_lock; + + type& ref; + + lv2_lock_t(type& lv2_lock) + : ref(lv2_lock) + { + Expects(ref.owns_lock()); + Expects(ref.mutex() == &mutex); + } + + operator type&() const + { + return ref; + } + + static type::mutex_type mutex; +}; + +#define LV2_LOCK lv2_lock_t::type lv2_lock(lv2_lock_t::mutex) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_time.cpp b/rpcs3/Emu/Cell/lv2/sys_time.cpp similarity index 97% rename from rpcs3/Emu/SysCalls/lv2/sys_time.cpp rename to rpcs3/Emu/Cell/lv2/sys_time.cpp index bdaed94974..39f4b1a156 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_time.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_time.cpp @@ -1,8 +1,9 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/SysCalls/SysCalls.h" +#include "Emu/Cell/ErrorCodes.h" #include "sys_time.h" #ifdef _WIN32 @@ -44,7 +45,7 @@ const g_time_aux_info = []() -> time_aux_info_t // initialize time-related value #endif -SysCallBase sys_time("sys_time"); +LOG_CHANNEL(sys_time); static const u64 g_timebase_freq = /*79800000*/ 80000000; // 80 Mhz diff --git a/rpcs3/Emu/SysCalls/lv2/sys_time.h b/rpcs3/Emu/Cell/lv2/sys_time.h similarity index 100% rename from rpcs3/Emu/SysCalls/lv2/sys_time.h rename to rpcs3/Emu/Cell/lv2/sys_time.h diff --git a/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp b/rpcs3/Emu/Cell/lv2/sys_timer.cpp similarity index 94% rename from rpcs3/Emu/SysCalls/lv2/sys_timer.cpp rename to rpcs3/Emu/Cell/lv2/sys_timer.cpp index 6fa2ba5001..3f8c8f78fc 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_timer.cpp @@ -1,15 +1,15 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/SysCalls/SysCalls.h" -#include "Utilities/Thread.h" +#include "Emu/Cell/ErrorCodes.h" #include "sys_event.h" #include "sys_process.h" #include "sys_timer.h" -SysCallBase sys_timer("sys_timer"); +LOG_CHANNEL(sys_timer); extern u64 get_system_time(); @@ -59,11 +59,6 @@ void lv2_timer_t::on_task() } } -lv2_timer_t::lv2_timer_t() - : id(idm::get_last_id()) -{ -} - s32 sys_timer_create(vm::ptr timer_id) { sys_timer.warning("sys_timer_create(timer_id=*0x%x)", timer_id); @@ -199,8 +194,8 @@ s32 sys_timer_connect_event_queue(u32 timer_id, u32 queue_id, u64 name, u64 data LV2_LOCK; - const auto timer(idm::get(timer_id)); - const auto queue(idm::get(queue_id)); + const auto timer = idm::get(timer_id); + const auto queue = idm::get(queue_id); if (!timer || !queue) { @@ -269,7 +264,7 @@ s32 sys_timer_sleep(u32 sleep_time) return CELL_OK; } -s32 sys_timer_usleep(u64 sleep_time) +s32 sys_timer_usleep(const u64 sleep_time) { sys_timer.trace("sys_timer_usleep(sleep_time=0x%llx)", sleep_time); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_timer.h b/rpcs3/Emu/Cell/lv2/sys_timer.h similarity index 63% rename from rpcs3/Emu/SysCalls/lv2/sys_timer.h rename to rpcs3/Emu/Cell/lv2/sys_timer.h index 5d1e32c68c..a0bcbba701 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_timer.h +++ b/rpcs3/Emu/Cell/lv2/sys_timer.h @@ -19,35 +19,36 @@ struct sys_timer_information_t be_t pad; }; -class lv2_timer_t final : public named_thread_t +class lv2_timer_t final : public named_thread { void on_task() override; - void on_id_aux_finalize() override +public: + std::string get_name() const override + { + return fmt::format("Timer Thread[0x%x]", id); + } + + void on_stop() override { // Signal thread using invalid state and join - { std::lock_guard{mutex}, state = -1; } + std::lock_guard{ mutex }, state = -1; cv.notify_one(); join(); } -public: - lv2_timer_t(); + const u32 id{}; // Timer id - std::string get_name() const override { return fmt::format("Timer Thread[0x%x]", id); } + atomic_t state{ SYS_TIMER_STATE_RUN }; // Timer state - const u32 id; - - std::weak_ptr port; // event queue - u64 source; // event source - u64 data1; // event arg 1 - u64 data2; // event arg 2 + std::weak_ptr port; // Event queue + u64 source; // Event source + u64 data1; // Event arg 1 + u64 data2; // Event arg 2 - u64 expire = 0; // next expiration time - u64 period = 0; // period (oneshot if 0) - - std::atomic state{ SYS_TIMER_STATE_RUN }; // timer state + u64 expire = 0; // Next expiration time + u64 period = 0; // Period (oneshot if 0) }; s32 sys_timer_create(vm::ptr timer_id); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_trace.cpp b/rpcs3/Emu/Cell/lv2/sys_trace.cpp similarity index 91% rename from rpcs3/Emu/SysCalls/lv2/sys_trace.cpp rename to rpcs3/Emu/Cell/lv2/sys_trace.cpp index f7b3d29c7e..78a10eb063 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_trace.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_trace.cpp @@ -1,11 +1,12 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/SysCalls/SysCalls.h" +#include "Emu/Cell/ErrorCodes.h" #include "sys_trace.h" -SysCallBase sys_trace("sys_trace"); +LOG_CHANNEL(sys_trace); s32 sys_trace_create() { diff --git a/rpcs3/Emu/SysCalls/lv2/sys_trace.h b/rpcs3/Emu/Cell/lv2/sys_trace.h similarity index 100% rename from rpcs3/Emu/SysCalls/lv2/sys_trace.h rename to rpcs3/Emu/Cell/lv2/sys_trace.h diff --git a/rpcs3/Emu/SysCalls/lv2/sys_tty.cpp b/rpcs3/Emu/Cell/lv2/sys_tty.cpp similarity index 89% rename from rpcs3/Emu/SysCalls/lv2/sys_tty.cpp rename to rpcs3/Emu/Cell/lv2/sys_tty.cpp index 8dadf61685..bdbe5fa49f 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_tty.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_tty.cpp @@ -1,11 +1,12 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/SysCalls/SysCalls.h" +#include "Emu/Cell/ErrorCodes.h" #include "sys_tty.h" -SysCallBase sys_tty("sys_tty"); +LOG_CHANNEL(sys_tty); s32 sys_tty_read(s32 ch, vm::ptr buf, u32 len, vm::ptr preadlen) { diff --git a/rpcs3/Emu/SysCalls/lv2/sys_tty.h b/rpcs3/Emu/Cell/lv2/sys_tty.h similarity index 100% rename from rpcs3/Emu/SysCalls/lv2/sys_tty.h rename to rpcs3/Emu/Cell/lv2/sys_tty.h diff --git a/rpcs3/Emu/SysCalls/lv2/sys_vm.cpp b/rpcs3/Emu/Cell/lv2/sys_vm.cpp similarity index 96% rename from rpcs3/Emu/SysCalls/lv2/sys_vm.cpp rename to rpcs3/Emu/Cell/lv2/sys_vm.cpp index 3e9361bedb..22492efb6e 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_vm.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_vm.cpp @@ -1,13 +1,14 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/SysCalls/SysCalls.h" +#include "Emu/Cell/ErrorCodes.h" #include "sys_memory.h" #include "sys_vm.h" -SysCallBase sys_vm("sys_vm"); +LOG_CHANNEL(sys_vm); s32 sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, vm::ptr addr) { diff --git a/rpcs3/Emu/SysCalls/lv2/sys_vm.h b/rpcs3/Emu/Cell/lv2/sys_vm.h similarity index 97% rename from rpcs3/Emu/SysCalls/lv2/sys_vm.h rename to rpcs3/Emu/Cell/lv2/sys_vm.h index cce3134611..5c03b588d1 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_vm.h +++ b/rpcs3/Emu/Cell/lv2/sys_vm.h @@ -1,6 +1,6 @@ #pragma once -namespace vm { using namespace ps3; } +#include "sys_sync.h" enum : u64 { diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h deleted file mode 100644 index 2415401100..0000000000 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "ErrorCodes.h" - -struct SysCallBase : public _log::channel -{ - SysCallBase(const std::string& name) - : _log::channel(name, _log::level::notice) - { - } -}; - -void execute_syscall_by_index(class PPUThread& ppu, u64 code); -std::string get_ps3_function_name(u64 fid); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_sync.h b/rpcs3/Emu/SysCalls/lv2/sys_sync.h deleted file mode 100644 index 76fc562eae..0000000000 --- a/rpcs3/Emu/SysCalls/lv2/sys_sync.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -namespace vm { using namespace ps3; } - -// attr_protocol (waiting scheduling policy) -enum -{ - // First In, First Out - SYS_SYNC_FIFO = 1, - // Priority Order - SYS_SYNC_PRIORITY = 2, - // Basic Priority Inheritance Protocol (probably not implemented) - SYS_SYNC_PRIORITY_INHERIT = 3, - // Not selected while unlocking - SYS_SYNC_RETRY = 4, - // - SYS_SYNC_ATTR_PROTOCOL_MASK = 0xF, -}; - -// attr_recursive (recursive locks policy) -enum -{ - // Recursive locks are allowed - SYS_SYNC_RECURSIVE = 0x10, - // Recursive locks are NOT allowed - SYS_SYNC_NOT_RECURSIVE = 0x20, - // - SYS_SYNC_ATTR_RECURSIVE_MASK = 0xF0, //??? -}; - -// attr_pshared -enum -{ - SYS_SYNC_NOT_PROCESS_SHARED = 0x200, -}; - -// attr_adaptive -enum -{ - SYS_SYNC_ADAPTIVE = 0x1000, - SYS_SYNC_NOT_ADAPTIVE = 0x2000, -};