Merge pull request #1036 from Nekotekina/master

sys_fs bugfixes
This commit is contained in:
Raul Tambre 2015-03-16 20:31:50 +02:00
commit b5a4e21c81
26 changed files with 1303 additions and 460 deletions

View File

@ -125,10 +125,15 @@ bool rRename(const std::string &from, const std::string &to)
{
// TODO: Deal with case-sensitivity
#ifdef _WIN32
return (MoveFile(ConvertUTF8ToWString(from).c_str(), ConvertUTF8ToWString(to).c_str()) == TRUE);
if (!MoveFile(ConvertUTF8ToWString(from).c_str(), ConvertUTF8ToWString(to).c_str()))
#else
return (0 == rename(from.c_str(), to.c_str()));
if (rename(from.c_str(), to.c_str()))
#endif
{
LOG_ERROR(GENERAL, "Error renaming '%s' to '%s': 0x%llx", from.c_str(), to.c_str(), (u64)GET_API_ERROR);
return false;
}
return true;
}
bool rExists(const std::string &file)

View File

@ -65,28 +65,14 @@ void CPUThread::DumpInformation()
case CPU_THREAD_PPU:
{
if ((u32)syscall == syscall)
if (syscall)
{
if (syscall)
{
if (syscall < 1024)
{
// TODO:
//return SysCalls::GetSyscallName((u32)syscall);
return "unknown syscall";
}
else
{
return SysCalls::GetHLEFuncName((u32)syscall);
}
}
else
{
return{};
}
return SysCalls::GetFuncName(syscall);
}
else
{
return{};
}
return "unknown function";
}
case CPU_THREAD_SPU:

View File

@ -141,8 +141,6 @@ void PPUThread::DoStop()
m_dec = nullptr;
}
bool dump_enable = false;
bool FPRdouble::IsINF(PPCdouble d)
{
return ((u64&)d & 0x7FFFFFFFFFFFFFFFULL) == 0x7FF0000000000000ULL;

View File

@ -259,14 +259,18 @@ bool VFS::ExistsDir(const std::string& ps3_path) const
bool VFS::RenameFile(const std::string& ps3_path_from, const std::string& ps3_path_to) const
{
std::string path;
if (vfsDevice* dev = GetDevice(ps3_path_from, path))
{
std::shared_ptr<vfsFileBase> res(dev->GetNewFileStream());
std::string path_from, path_to;
if (res)
if (vfsDevice* dev = GetDevice(ps3_path_from, path_from))
{
if (vfsDevice* dev_ = GetDevice(ps3_path_to, path_to))
{
return res->Rename(path, ps3_path_to);
std::shared_ptr<vfsFileBase> res(dev->GetNewFileStream());
if (res)
{
return res->Rename(path_from, path_to);
}
}
}
@ -275,14 +279,18 @@ bool VFS::RenameFile(const std::string& ps3_path_from, const std::string& ps3_pa
bool VFS::RenameDir(const std::string& ps3_path_from, const std::string& ps3_path_to) const
{
std::string path;
if (vfsDevice* dev = GetDevice(ps3_path_from, path))
{
std::shared_ptr<vfsDirBase> res(dev->GetNewDirStream());
std::string path_from, path_to;
if (res)
if (vfsDevice* dev = GetDevice(ps3_path_from, path_from))
{
if (vfsDevice* dev_ = GetDevice(ps3_path_to, path_to))
{
return res->Rename(path, ps3_path_to);
std::shared_ptr<vfsDirBase> res(dev->GetNewDirStream());
if (res)
{
return res->Rename(path_from, path_to);
}
}
}

View File

@ -43,7 +43,7 @@ bool vfsLocalDir::Open(const std::string& path)
bool vfsLocalDir::Create(const std::string& path)
{
return rMkpath(path);
return rMkdir(path);
}
bool vfsLocalDir::IsExists(const std::string& path) const
@ -53,7 +53,7 @@ bool vfsLocalDir::IsExists(const std::string& path) const
bool vfsLocalDir::Rename(const std::string& from, const std::string& to)
{
return false;
return rRename(from, to);
}
bool vfsLocalDir::Remove(const std::string& path)

View File

@ -124,4 +124,14 @@ bool vfsLocalFile::IsOpened() const
bool vfsLocalFile::Exists(const std::string& path)
{
return rExists(path);
}
}
bool vfsLocalFile::Rename(const std::string& from, const std::string& to)
{
return rRename(from, to);
}
bool vfsLocalFile::Remove(const std::string& path)
{
return rRemoveFile(path);
}

View File

@ -14,6 +14,8 @@ public:
virtual bool Create(const std::string& path, bool overwrite = false) override;
virtual bool Close() override;
virtual bool Exists(const std::string& path) override;
virtual bool Rename(const std::string& from, const std::string& to) override;
virtual bool Remove(const std::string& path) override;
virtual u64 GetSize() override;

View File

@ -29,48 +29,24 @@ enum IDType
TYPE_OTHER,
};
class IDData
{
protected:
void* m_ptr;
std::function<void(void*)> m_destr;
public:
IDData(void* ptr, std::function<void(void*)> destr)
: m_ptr(ptr)
, m_destr(destr)
{
}
~IDData()
{
m_destr(m_ptr);
}
template<typename T> std::shared_ptr<T> get() const
{
return *(std::shared_ptr<T>*)m_ptr;
}
};
class ID
class ID final
{
const std::type_info& m_info;
IDData* m_data;
std::shared_ptr<void> m_data;
IDType m_type;
public:
template<typename T>
ID(std::shared_ptr<T>& data, const IDType type)
template<typename T> ID(std::shared_ptr<T>& data, const IDType type)
: m_info(typeid(T))
, m_data(data)
, m_type(type)
{
m_data = new IDData(new std::shared_ptr<T>(data), [](void *ptr) -> void { delete (std::shared_ptr<T>*)ptr; });
}
ID()
: m_info(typeid(nullptr_t))
: m_info(typeid(void))
, m_data(nullptr)
, m_type(TYPE_OTHER)
{
}
@ -82,26 +58,19 @@ public:
, m_type(right.m_type)
{
right.m_data = nullptr;
right.m_type = TYPE_OTHER;
}
ID& operator=(ID&& other) = delete;
~ID()
{
if (m_data)
{
delete m_data;
}
}
const std::type_info& GetInfo() const
{
return m_info;
}
IDData* GetData() const
template<typename T> std::shared_ptr<T> GetData() const
{
return m_data;
return std::static_pointer_cast<T>(m_data);
}
IDType GetType() const
@ -117,23 +86,14 @@ class IdManager
std::unordered_map<u32, ID> m_id_map;
std::set<u32> m_types[TYPE_OTHER];
std::mutex m_mtx_main;
std::mutex m_mutex;
u32 m_cur_id;
u32 m_cur_id = s_first_id;
public:
IdManager() : m_cur_id(s_first_id)
{
}
~IdManager()
{
Clear();
}
template<typename T> bool CheckID(const u32 id)
{
std::lock_guard<std::mutex> lock(m_mtx_main);
std::lock_guard<std::mutex> lock(m_mutex);
auto f = m_id_map.find(id);
@ -142,7 +102,7 @@ public:
void Clear()
{
std::lock_guard<std::mutex> lock(m_mtx_main);
std::lock_guard<std::mutex> lock(m_mutex);
m_id_map.clear();
m_cur_id = s_first_id;
@ -150,7 +110,7 @@ public:
template<typename T> u32 GetNewID(std::shared_ptr<T>& data, const IDType type = TYPE_OTHER)
{
std::lock_guard<std::mutex> lock(m_mtx_main);
std::lock_guard<std::mutex> lock(m_mutex);
m_id_map.emplace(m_cur_id, ID(data, type));
@ -161,17 +121,10 @@ public:
return m_cur_id++;
}
ID& GetID(const u32 id)
{
std::lock_guard<std::mutex> lock(m_mtx_main);
return m_id_map[id];
}
template<typename T> bool GetIDData(const u32 id, std::shared_ptr<T>& result)
{
std::lock_guard<std::mutex> lock(m_mtx_main);
std::lock_guard<std::mutex> lock(m_mutex);
auto f = m_id_map.find(id);
@ -180,14 +133,14 @@ public:
return false;
}
result = f->second.GetData()->get<T>();
result = f->second.GetData<T>();
return true;
}
template<typename T> std::shared_ptr<T> GetIDData(const u32 id)
{
std::lock_guard<std::mutex> lock(m_mtx_main);
std::lock_guard<std::mutex> lock(m_mutex);
auto f = m_id_map.find(id);
@ -196,19 +149,33 @@ public:
return nullptr;
}
return f->second.GetData()->get<T>();
return f->second.GetData<T>();
}
bool HasID(const u32 id)
{
std::lock_guard<std::mutex> lock(m_mtx_main);
std::lock_guard<std::mutex> lock(m_mutex);
return m_id_map.find(id) != m_id_map.end();
}
IDType GetIDType(const u32 id)
{
std::lock_guard<std::mutex> lock(m_mutex);
auto item = m_id_map.find(id);
if (item == m_id_map.end())
{
return TYPE_OTHER;
}
return item->second.GetType();
}
template<typename T> bool RemoveID(const u32 id)
{
std::lock_guard<std::mutex> lock(m_mtx_main);
std::lock_guard<std::mutex> lock(m_mutex);
auto item = m_id_map.find(id);
@ -229,7 +196,7 @@ public:
u32 GetTypeCount(IDType type)
{
std::lock_guard<std::mutex> lock(m_mtx_main);
std::lock_guard<std::mutex> lock(m_mutex);
if (type < TYPE_OTHER)
{
@ -245,7 +212,7 @@ public:
std::set<u32> GetTypeIDs(IDType type)
{
// you cannot simply return reference to existing set
std::lock_guard<std::mutex> lock(m_mtx_main);
std::lock_guard<std::mutex> lock(m_mutex);
if (type < TYPE_OTHER)
{

View File

@ -9,31 +9,36 @@
void CallbackManager::Register(const std::function<s32(PPUThread& PPU)>& func)
{
std::lock_guard<std::mutex> lock(m_mutex);
m_cb_list.push_back([=](CPUThread& CPU) -> s32
{
assert(CPU.GetType() == CPU_THREAD_PPU);
return func(static_cast<PPUThread&>(CPU));
});
std::lock_guard<std::mutex> lock(m_mutex);
m_cb_list.push_back([=](CPUThread& CPU) -> s32
{
assert(CPU.GetType() == CPU_THREAD_PPU);
return func(static_cast<PPUThread&>(CPU));
});
}
}
void CallbackManager::Async(const std::function<void(PPUThread& PPU)>& func)
{
std::lock_guard<std::mutex> lock(m_mutex);
m_async_list.push_back([=](CPUThread& CPU)
{
assert(CPU.GetType() == CPU_THREAD_PPU);
func(static_cast<PPUThread&>(CPU));
});
std::lock_guard<std::mutex> lock(m_mutex);
m_cb_thread->Notify();
m_async_list.push_back([=](CPUThread& CPU)
{
assert(CPU.GetType() == CPU_THREAD_PPU);
func(static_cast<PPUThread&>(CPU));
});
}
m_cv.notify_one();
}
bool CallbackManager::Check(CPUThread& CPU, s32& result)
{
std::function<s32(CPUThread& CPU)> func;
{
std::lock_guard<std::mutex> lock(m_mutex);
@ -44,15 +49,7 @@ bool CallbackManager::Check(CPUThread& CPU, s32& result)
}
}
if (func)
{
result = func(CPU);
return true;
}
else
{
return false;
}
return func ? result = func(CPU), true : false;
}
void CallbackManager::Init()
@ -86,26 +83,27 @@ void CallbackManager::Init()
{
SetCurrentNamedThread(&*m_cb_thread);
std::unique_lock<std::mutex> lock(m_mutex);
while (!Emu.IsStopped())
{
std::function<void(CPUThread& CPU)> func;
{
std::lock_guard<std::mutex> lock(m_mutex);
if (m_async_list.size())
{
func = m_async_list[0];
m_async_list.erase(m_async_list.begin());
}
if (m_async_list.size())
{
func = m_async_list[0];
m_async_list.erase(m_async_list.begin());
}
if (func)
{
lock.unlock();
func(*m_cb_thread);
lock.lock();
continue;
}
m_cb_thread->WaitForAnySignal();
m_cv.wait_for(lock, std::chrono::milliseconds(1));
}
});
}

View File

@ -8,6 +8,8 @@ typedef void(PauseResumeCB)(bool is_paused);
class CallbackManager
{
std::mutex m_mutex;
std::condition_variable m_cv;
std::vector<std::function<s32(CPUThread&)>> m_cb_list;
std::vector<std::function<void(CPUThread&)>> m_async_list;
std::shared_ptr<CPUThread> m_cb_thread;

View File

@ -1,9 +1,569 @@
#include "stdafx.h"
#include "Modules.h"
#include "SysCalls.h"
std::string SysCalls::GetHLEFuncName(const u32 fid)
std::string SysCalls::GetFuncName(const u64 fid)
{
switch(fid)
// check syscalls
switch (fid)
{
case 1: return "sys_process_getpid";
case 2: return "sys_process_wait_for_child";
case 3: return "sys_process_exit";
case 4: return "sys_process_get_status";
case 5: return "sys_process_detach_child";
case 12: return "sys_process_get_number_of_object";
case 13: return "sys_process_get_id";
case 14: return "sys_process_is_spu_lock_line_reservation_address";
case 18: return "sys_process_getppid";
case 19: return "sys_process_kill";
case 21: return "_sys_process_spawn";
case 22: return "sys_process_exit";
case 23: return "sys_process_wait_for_child2";
case 25: return "sys_process_get_sdk_version";
case 26: return "_sys_process_exit";
case 28: return "_sys_process_get_number_of_object";
case 29: return "sys_process_get_id";
case 30: return "_sys_process_get_paramsfo";
case 31: return "sys_process_get_ppu_guid";
case 41: return "sys_internal_ppu_thread_exit";
case 43: return "sys_ppu_thread_yield";
case 44: return "sys_ppu_thread_join";
case 45: return "sys_ppu_thread_detach";
case 46: return "sys_ppu_thread_get_join_state";
case 47: return "sys_ppu_thread_set_priority";
case 48: return "sys_ppu_thread_get_priority";
case 49: return "sys_ppu_thread_get_stack_information";
case 50: return "sys_ppu_thread_stop";
case 51: return "sys_ppu_thread_restart";
case 52: return "sys_ppu_thread_create";
case 53: return "sys_ppu_thread_start";
case 56: return "sys_ppu_thread_rename";
case 57: return "sys_ppu_thread_recover_page_fault";
case 58: return "sys_ppu_thread_get_page_fault_context";
case 60: return "sys_trace_create";
case 61: return "sys_trace_start";
case 62: return "sys_trace_stop";
case 63: return "sys_trace_update_top_index";
case 64: return "sys_trace_destroy";
case 65: return "sys_trace_drain";
case 66: return "sys_trace_attach_process";
case 67: return "sys_trace_allocate_buffer";
case 68: return "sys_trace_free_buffer";
case 69: return "sys_trace_create2";
case 70: return "sys_timer_create";
case 71: return "sys_timer_destroy";
case 72: return "sys_timer_get_information";
case 73: return "_sys_timer_start";
case 74: return "sys_timer_stop";
case 75: return "sys_timer_connect_event_queue";
case 76: return "sys_timer_disconnect_event_queue";
case 77: return "sys_trace_create2_in_cbepm";
case 80: return "sys_interrupt_tag_create";
case 81: return "sys_interrupt_tag_destroy";
case 82: return "sys_event_flag_create";
case 83: return "sys_event_flag_destroy";
case 84: return "sys_interrupt_thread_establish";
case 85: return "sys_event_flag_wait";
case 86: return "sys_event_flag_trywait";
case 87: return "sys_event_flag_set";
case 88: return "sys_interrupt_thread_eoi";
case 89: return "_sys_interrupt_thread_disestablish";
case 90: return "sys_semaphore_create";
case 91: return "sys_semaphore_destroy";
case 92: return "sys_semaphore_wait";
case 93: return "sys_semaphore_trywait";
case 94: return "sys_semaphore_post";
case 95: return "_sys_lwmutex_create";
case 96: return "_sys_lwmutex_destroy";
case 97: return "_sys_lwmutex_lock";
case 98: return "_sys_lwmutex_unlock";
case 99: return "_sys_lwmutex_trylock";
case 100: return "sys_mutex_create";
case 101: return "sys_mutex_destroy";
case 102: return "sys_mutex_lock";
case 103: return "sys_mutex_trylock";
case 104: return "sys_mutex_unlock";
case 105: return "sys_cond_create";
case 106: return "sys_cond_destroy";
case 107: return "sys_cond_wait";
case 108: return "sys_cond_signal";
case 109: return "sys_cond_signal_all";
case 110: return "sys_cond_signal_to";
case 111: return "_sys_lwcond_create";
case 112: return "_sys_lwcond_destroy";
case 113: return "_sys_lwcond_queue_wait";
case 114: return "sys_semaphore_get_value";
case 115: return "_sys_lwcond_signal";
case 116: return "_sys_lwcond_signal_all";
case 118: return "sys_event_flag_clear";
case 120: return "sys_rwlock_create";
case 121: return "sys_rwlock_destroy";
case 122: return "sys_rwlock_rlock";
case 123: return "sys_rwlock_tryrlock";
case 124: return "sys_rwlock_runlock";
case 125: return "sys_rwlock_wlock";
case 126: return "sys_rwlock_trywlock";
case 127: return "sys_rwlock_wunlock";
case 128: return "sys_event_queue_create";
case 129: return "sys_event_queue_destroy";
case 130: return "sys_event_queue_receive";
case 131: return "sys_event_queue_tryreceive";
case 132: return "sys_event_flag_cancel";
case 133: return "sys_event_queue_drain";
case 134: return "sys_event_port_create";
case 135: return "sys_event_port_destroy";
case 136: return "sys_event_port_connect_local";
case 137: return "sys_event_port_disconnect";
case 138: return "sys_event_port_send";
case 139: return "sys_event_flag_get";
case 140: return "sys_event_port_connect_ipc";
case 141: return "sys_timer_usleep";
case 142: return "sys_timer_sleep";
case 143: return "sys_time_set_timezone";
case 144: return "sys_time_get_timezone";
case 145: return "sys_time_get_current_time";
case 146: return "sys_time_get_system_time";
case 147: return "sys_time_get_timebase_frequency";
case 148: return "sys_rwlock_trywlock";
case 150: return "sys_raw_spu_create_interrupt_tag";
case 151: return "sys_raw_spu_set_int_mask";
case 152: return "sys_raw_spu_get_int_mask";
case 153: return "sys_raw_spu_set_int_stat";
case 154: return "sys_raw_spu_get_int_stat";
case 155: return "sys_spu_image_get_information?";
case 156: return "sys_spu_image_open";
case 157: return "sys_spu_image_import";
case 158: return "sys_spu_image_close";
case 159: return "sys_raw_spu_load";
case 160: return "sys_raw_spu_create";
case 161: return "sys_raw_spu_destroy";
case 163: return "sys_raw_spu_read_puint_mb";
case 165: return "sys_spu_thread_get_exit_status";
case 166: return "sys_spu_thread_set_argument";
case 167: return "sys_spu_thread_group_start_on_exit";
case 169: return "sys_spu_initialize";
case 170: return "sys_spu_thread_group_create";
case 171: return "sys_spu_thread_group_destroy";
case 172: return "sys_spu_thread_initialize";
case 173: return "sys_spu_thread_group_start";
case 174: return "sys_spu_thread_group_suspend";
case 175: return "sys_spu_thread_group_resume";
case 176: return "sys_spu_thread_group_yield";
case 177: return "sys_spu_thread_group_terminate";
case 178: return "sys_spu_thread_group_join";
case 179: return "sys_spu_thread_group_set_priority";
case 180: return "sys_spu_thread_group_get_priority";
case 181: return "sys_spu_thread_write_ls";
case 182: return "sys_spu_thread_read_ls";
case 184: return "sys_spu_thread_write_snr";
case 185: return "sys_spu_thread_group_connect_event";
case 186: return "sys_spu_thread_group_disconnect_event";
case 187: return "sys_spu_thread_set_spu_cfg";
case 188: return "sys_spu_thread_get_spu_cfg";
case 190: return "sys_spu_thread_write_spu_mb";
case 191: return "sys_spu_thread_connect_event";
case 192: return "sys_spu_thread_disconnect_event";
case 193: return "sys_spu_thread_bind_queue";
case 194: return "sys_spu_thread_unbind_queue";
case 196: return "sys_raw_spu_set_spu_cfg";
case 197: return "sys_raw_spu_get_spu_cfg";
case 198: return "sys_spu_thread_recover_page_fault";
case 199: return "sys_raw_spu_recover_page_fault";
case 215: return "sys_dbg_mat_set_condition";
case 216: return "sys_dbg_mat_get_condition";
case 230: return "sys_isolated_spu_create";
case 231: return "sys_isolated_spu_destroy";
case 232: return "sys_isolated_spu_start";
case 233: return "sys_isolated_spu_create_interrupt_tag";
case 234: return "sys_isolated_spu_set_int_mask";
case 235: return "sys_isolated_spu_get_int_mask";
case 236: return "sys_isolated_spu_set_int_stat";
case 237: return "sys_isolated_spu_get_int_stat";
case 238: return "sys_isolated_spu_set_spu_cfg";
case 239: return "sys_isolated_spu_get_spu_cfg";
case 240: return "sys_isolated_spu_read_puint_mb";
case 244: return "sys_spu_thread_group_system_set_next_group";
case 245: return "sys_spu_thread_group_system_unset_next_group";
case 246: return "sys_spu_thread_group_system_set_switch_group";
case 247: return "sys_spu_thread_group_system_unset_switch_group";
case 250: return "sys_spu_thread_group_set_cooperative_victims";
case 251: return "sys_spu_thread_group_connect_event_all_threads";
case 252: return "sys_spu_thread_group_disconnect_event_all_threads";
case 254: return "sys_spu_thread_group_log";
case 260: return "sys_spu_image_open_by_fd";
case 300: return "sys_vm_memory_map";
case 301: return "sys_vm_unmap";
case 302: return "sys_vm_append_memory";
case 303: return "sys_vm_return_memory";
case 304: return "sys_vm_lock";
case 305: return "sys_vm_unlock";
case 306: return "sys_vm_touch";
case 307: return "sys_vm_flush";
case 308: return "sys_vm_invalidate";
case 309: return "sys_vm_store";
case 310: return "sys_vm_sync";
case 311: return "sys_vm_test";
case 312: return "sys_vm_get_statistics";
case 324: return "sys_memory_container_create";
case 325: return "sys_memory_container_destroy";
case 326: return "sys_mmapper_allocate_fixed_address";
case 327: return "sys_mmapper_enable_page_fault_notification";
case 329: return "sys_mmapper_free_shared_memory";
case 330: return "sys_mmapper_allocate_address";
case 331: return "sys_mmapper_free_address";
case 332: return "sys_mmapper_allocate_shared_memory";
case 333: return "sys_mmapper_set_shared_memory_flag";
case 334: return "sys_mmapper_map_shared_memory";
case 335: return "sys_mmapper_unmap_shared_memory";
case 336: return "sys_mmapper_change_address_access_right";
case 337: return "sys_mmapper_search_and_map";
case 338: return "sys_mmapper_get_shared_memory_attribute";
case 341: return "sys_memory_container_create";
case 342: return "sys_memory_container_destroy";
case 343: return "sys_memory_container_get_size";
case 344: return "sys_memory_budget_set";
case 348: return "sys_memory_allocate";
case 349: return "sys_memory_free";
case 350: return "sys_memory_allocate_from_container";
case 351: return "sys_memory_get_page_attribute";
case 352: return "sys_memory_get_user_memory_size";
case 353: return "sys_memory_get_user_memory_stat";
case 356: return "sys_memory_allocate_colored";
case 361: return "sys_memory_allocate_from_container_colored";
case 362: return "sys_mmapper_allocate_memory_from_container";
case 367: return "sys_uart_initialize";
case 368: return "sys_uart_receive";
case 369: return "sys_uart_send";
case 370: return "sys_uart_get_params";
case 372: return "sys_game_watchdog_start";
case 373: return "sys_game_watchdog_stop";
case 374: return "sys_game_watchdog_clear";
case 375: return "sys_game_set_system_sw_version";
case 376: return "sys_game_get_system_sw_version";
case 377: return "sys_sm_set_shop_mode";
case 378: return "sys_sm_get_ext_event2";
case 379: return "sys_sm_shutdown";
case 380: return "sys_sm_get_params";
case 381: return "sys_sm_get_inter_lpar_parameter";
case 383: return "sys_game_get_temperature";
case 384: return "sys_sm_get_tzpb";
case 385: return "sys_sm_request_led";
case 386: return "sys_sm_control_led";
case 387: return "sys_sm_get_platform_info";
case 388: return "sys_sm_ring_buzzer";
case 389: return "sys_sm_set_fan_policy";
case 390: return "sys_sm_request_error_log";
case 391: return "sys_sm_request_be_count";
case 392: return "sys_sm_ring_buzzer";
case 393: return "sys_sm_get_hw_config";
case 394: return "sys_sm_request_scversion";
case 395: return "sys_sm_request_system_event_log";
case 396: return "sys_sm_set_rtc_alarm";
case 397: return "sys_sm_get_rtc_alarm";
case 398: return "sys_console_write";
case 402: return "sys_tty_read";
case 403: return "sys_tty_write";
case 408: return "sys_sm_get_tzpb";
case 409: return "sys_sm_get_fan_policy";
case 410: return "sys_game_board_storage_read";
case 411: return "sys_game_board_storage_write";
case 412: return "sys_game_get_rtc_status";
case 450: return "sys_overlay_load_module";
case 451: return "sys_overlay_unload_module";
case 452: return "sys_overlay_get_module_list";
case 453: return "sys_overlay_get_module_info";
case 454: return "sys_overlay_load_module_by_fd";
case 455: return "sys_overlay_get_module_info2";
case 456: return "sys_overlay_get_sdk_version";
case 457: return "sys_overlay_get_module_dbg_info";
case 458: return "sys_overlay_get_module_dbg_info";
case 460: return "sys_prx_dbg_get_module_id_list";
case 461: return "sys_prx_get_module_id_by_address";
case 463: return "sys_prx_load_module_by_fd";
case 464: return "sys_prx_load_module_on_memcontainer_by_fd";
case 465: return "sys_prx_load_module_list";
case 466: return "sys_prx_load_module_list_on_memcontainer";
case 467: return "sys_prx_get_ppu_guid";
case 480: return "sys_prx_load_module";
case 481: return "sys_prx_start_module";
case 482: return "sys_prx_stop_module";
case 483: return "sys_prx_unload_module";
case 484: return "sys_prx_register_module";
case 485: return "sys_prx_query_module";
case 486: return "sys_prx_register_library";
case 487: return "sys_prx_unregister_library";
case 488: return "sys_prx_link_library";
case 489: return "sys_prx_unlink_library";
case 490: return "sys_prx_query_library";
case 493: return "sys_prx_dbg_get_module_info";
case 494: return "sys_prx_get_module_list";
case 495: return "sys_prx_get_module_info";
case 496: return "sys_prx_get_module_id_by_name";
case 497: return "sys_prx_load_module_on_memcontainer";
case 498: return "sys_prx_start";
case 499: return "sys_prx_stop";
case 500: return "sys_hid_manager_open";
case 501: return "sys_hid_manager_close";
case 502: return "sys_hid_manager_read";
case 503: return "sys_hid_manager_ioctl";
case 504: return "sys_hid_manager_map_logical_id_to_port_id";
case 505: return "sys_hid_manager_unmap_logical_id_to_port_id";
case 506: return "sys_hid_manager_add_hot_key_observer";
case 507: return "sys_hid_manager_remove_hot_key_observer";
case 508: return "sys_hid_manager_grab_focus";
case 509: return "sys_hid_manager_release_focus";
case 516: return "sys_config_open";
case 517: return "sys_config_close";
case 518: return "sys_config_get_service_event";
case 519: return "sys_config_add_service_listener";
case 520: return "sys_config_remove_service_listener";
case 521: return "sys_config_register_service";
case 522: return "sys_config_unregister_service";
case 523: return "sys_config_io_event";
case 530: return "sys_usbd_initialize";
case 531: return "sys_usbd_finalize";
case 532: return "sys_usbd_get_device_list";
case 533: return "sys_usbd_get_descriptor_size";
case 534: return "sys_usbd_get_descriptor";
case 535: return "sys_usbd_register_ldd";
case 536: return "sys_usbd_unregister_ldd";
case 537: return "sys_usbd_open_pipe";
case 538: return "sys_usbd_open_default_pipe";
case 539: return "sys_usbd_close_pipe";
case 540: return "sys_usbd_receive_event";
case 541: return "sys_usbd_detect_event";
case 542: return "sys_usbd_attach";
case 543: return "sys_usbd_transfer_data";
case 544: return "sys_usbd_isochronous_transfer_data";
case 545: return "sys_usbd_get_transfer_status";
case 546: return "sys_usbd_get_isochronous_transfer_status";
case 547: return "sys_usbd_get_device_location";
case 548: return "sys_usbd_send_event";
case 550: return "sys_usbd_allocate_memory";
case 551: return "sys_usbd_free_memory";
case 556: return "sys_usbd_get_device_speed";
case 559: return "sys_usbd_register_extra_ldd";
case 571: return "sys_pad_ldd_unregister_controller";
case 572: return "sys_pad_ldd_data_insert";
case 573: return "sys_pad_dbg_ldd_set_data_insert_mode";
case 574: return "sys_pad_ldd_register_controller";
case 575: return "sys_pad_ldd_get_port_no";
case 577: return "sys_pad_manager_...";
case 600: return "sys_storage_open";
case 601: return "sys_storage_close";
case 602: return "sys_storage_read";
case 603: return "sys_storage_write";
case 604: return "sys_storage_send_device_command";
case 605: return "sys_storage_async_configure";
case 606: return "sys_storage_async_read";
case 607: return "sys_storage_async_write";
case 608: return "sys_storage_async_cancel";
case 609: return "sys_storage_get_device_info";
case 610: return "sys_storage_get_device_config";
case 611: return "sys_storage_report_devices";
case 612: return "sys_storage_configure_medium_event";
case 613: return "sys_storage_set_medium_polling_interval";
case 614: return "sys_storage_create_region";
case 615: return "sys_storage_delete_region";
case 616: return "sys_storage_execute_device_command";
case 617: return "sys_storage_check_region_acl";
case 618: return "sys_storage_set_region_acl";
case 619: return "sys_storage_async_send_device_command";
case 621: return "sys_gamepad_ycon_if";
case 622: return "sys_storage_get_region_offset";
case 623: return "sys_storage_set_emulated_speed";
case 624: return "sys_io_buffer_create";
case 625: return "sys_io_buffer_destroy";
case 626: return "sys_io_buffer_allocate";
case 627: return "sys_io_buffer_free";
case 630: return "sys_gpio_set";
case 631: return "sys_gpio_get";
case 633: return "sys_fsw_connect_event";
case 634: return "sys_fsw_disconnect_event";
case 635: return "sys_btsetting_if";
case 650: return "sys_rsxaudio_initialize";
case 651: return "sys_rsxaudio_finalize";
case 652: return "sys_rsxaudio_import_shared_memory";
case 653: return "sys_rsxaudio_unimport_shared_memory";
case 654: return "sys_rsxaudio_create_connection";
case 655: return "sys_rsxaudio_close_connection";
case 656: return "sys_rsxaudio_prepare_process";
case 657: return "sys_rsxaudio_start_process";
case 666: return "sys_rsx_device_open";
case 667: return "sys_rsx_device_close";
case 668: return "sys_rsx_memory_allocate";
case 669: return "sys_rsx_memory_free";
case 670: return "sys_rsx_context_allocate";
case 671: return "sys_rsx_context_free";
case 672: return "sys_rsx_context_iomap";
case 673: return "sys_rsx_context_iounmap";
case 674: return "sys_rsx_context_attribute";
case 675: return "sys_rsx_device_map";
case 676: return "sys_rsx_device_unmap";
case 677: return "sys_rsx_attribute";
case 699: return "sys_bdemu_send_command";
case 700: return "sys_net_bnet_accept";
case 701: return "sys_net_bnet_bind";
case 702: return "sys_net_bnet_connect";
case 703: return "sys_net_bnet_getpeername";
case 704: return "sys_net_bnet_getsockname";
case 705: return "sys_net_bnet_getsockopt";
case 706: return "sys_net_bnet_listen";
case 707: return "sys_net_bnet_recvfrom";
case 708: return "sys_net_bnet_recvmsg";
case 709: return "sys_net_bnet_sendmsg";
case 710: return "sys_net_bnet_sendto";
case 711: return "sys_net_bnet_setsockop";
case 712: return "sys_net_bnet_shutdown";
case 713: return "sys_net_bnet_socket";
case 714: return "sys_net_bnet_close";
case 715: return "sys_net_bnet_poll";
case 716: return "sys_net_bnet_select";
case 717: return "sys_net_open_dump";
case 718: return "sys_net_read_dump";
case 719: return "sys_net_close_dump";
case 720: return "sys_net_write_dump";
case 721: return "sys_net_abort";
case 722: return "sys_net_infoctl";
case 723: return "sys_net_control";
case 724: return "sys_net_bnet_ioctl";
case 725: return "sys_net_bnet_sysctl";
case 726: return "sys_net_eurus_post_command";
case 800: return "sys_fs_test";
case 801: return "sys_fs_open";
case 802: return "sys_fs_read";
case 803: return "sys_fs_write";
case 804: return "sys_fs_close";
case 805: return "sys_fs_opendir";
case 806: return "sys_fs_readdir";
case 807: return "sys_fs_closedir";
case 808: return "sys_fs_stat";
case 809: return "sys_fs_fstat";
case 810: return "sys_fs_link";
case 811: return "sys_fs_mkdir";
case 812: return "sys_fs_rename";
case 813: return "sys_fs_rmdir";
case 814: return "sys_fs_unlink";
case 815: return "sys_fs_utime";
case 816: return "sys_fs_access";
case 817: return "sys_fs_fcntl";
case 818: return "sys_fs_lseek";
case 819: return "sys_fs_fdatasync";
case 820: return "sys_fs_fsync";
case 821: return "sys_fs_fget_block_size";
case 822: return "sys_fs_get_block_size";
case 823: return "sys_fs_acl_read";
case 824: return "sys_fs_acl_write";
case 825: return "sys_fs_lsn_get_cda_size";
case 826: return "sys_fs_lsn_get_cda";
case 827: return "sys_fs_lsn_lock";
case 828: return "sys_fs_lsn_unlock";
case 829: return "sys_fs_lsn_read";
case 830: return "sys_fs_lsn_write";
case 831: return "sys_fs_truncate";
case 832: return "sys_fs_ftruncate";
case 833: return "sys_fs_symbolic_link";
case 834: return "sys_fs_chmod";
case 835: return "sys_fs_chown";
case 836: return "sys_fs_newfs";
case 837: return "sys_fs_mount";
case 838: return "sys_fs_unmount";
case 839: return "sys_fs_sync";
case 840: return "sys_fs_disk_free";
case 841: return "sys_fs_get_mount_info_size";
case 842: return "sys_fs_get_mount_info";
case 843: return "sys_fs_get_fs_info_size";
case 844: return "sys_fs_get_fs_info";
case 845: return "sys_fs_mapped_allocate";
case 846: return "sys_fs_mapped_free";
case 847: return "sys_fs_truncate2";
case 860: return "sys_ss_get_cache_of_analog_sunset_flag";
case 865: return "sys_ss_random_number_generator";
case 870: return "sys_ss_get_console_id";
case 871: return "sys_ss_access_control_engine";
case 872: return "sys_ss_get_open_psid";
case 873: return "sys_ss_get_cache_of_product_mode";
case 874: return "sys_ss_get_cache_of_flash_ext_flag";
case 875: return "sys_ss_get_boot_device";
case 876: return "sys_ss_disc_access_control";
case 877: return "sys_ss_~utoken_if";
case 878: return "sys_ss_ad_sign";
case 879: return "sys_ss_media_id";
case 880: return "sys_deci3_open";
case 881: return "sys_deci3_create_event_path";
case 882: return "sys_deci3_close";
case 883: return "sys_deci3_send";
case 884: return "sys_deci3_receive";
case 885: return "sys_deci3_open2";
case 890: return "sys_deci3_initialize";
case 891: return "sys_deci3_terminate";
case 892: return "sys_deci3_debug_mode";
case 893: return "sys_deci3_show_status";
case 894: return "sys_deci3_echo_test";
case 895: return "sys_deci3_send_dcmp_packet";
case 896: return "sys_deci3_dump_cp_register";
case 897: return "sys_deci3_dump_cp_buffer";
case 899: return "sys_deci3_test";
case 900: return "sys_dbg_stop_processes";
case 901: return "sys_dbg_continue_processes";
case 902: return "sys_dbg_stop_threads";
case 903: return "sys_dbg_continue_threads";
case 904: return "sys_dbg_read_process_memory";
case 905: return "sys_dbg_write_process_memory";
case 906: return "sys_dbg_read_thread_register";
case 907: return "sys_dbg_write_thread_register";
case 908: return "sys_dbg_get_process_list";
case 909: return "sys_dbg_get_thread_list";
case 910: return "sys_dbg_get_thread_info";
case 911: return "sys_dbg_spu_thread_read_from_ls";
case 912: return "sys_dbg_spu_thread_write_to_ls";
case 913: return "sys_dbg_kill_process";
case 914: return "sys_dbg_get_process_info";
case 915: return "sys_dbg_set_run_control_bit_to_spu";
case 916: return "sys_dbg_spu_thread_get_exception_cause";
case 917: return "sys_dbg_create_kernel_event_queue";
case 918: return "sys_dbg_read_kernel_event_queue";
case 919: return "sys_dbg_destroy_kernel_event_queue";
case 920: return "sys_dbg_get_process_event_ctrl_flag";
case 921: return "sys_dbg_set_process_event_cntl_flag";
case 922: return "sys_dbg_get_spu_thread_group_event_cntl_flag";
case 923: return "sys_dbg_set_spu_thread_group_event_cntl_flag";
case 925: return "sys_dbg_get_raw_spu_list";
case 932: return "sys_dbg_get_mutex_list";
case 933: return "sys_dbg_get_mutex_information";
case 934: return "sys_dbg_get_cond_list";
case 935: return "sys_dbg_get_cond_information";
case 936: return "sys_dbg_get_rwlock_list";
case 937: return "sys_dbg_get_rwlock_information";
case 938: return "sys_dbg_get_lwmutex_list";
case 939: return "sys_dbg_get_address_from_dabr";
case 940: return "sys_dbg_set_address_to_dabr";
case 941: return "sys_dbg_get_lwmutex_information";
case 942: return "sys_dbg_get_event_queue_list";
case 943: return "sys_dbg_get_event_queue_information";
case 944: return "sys_dbg_initialize_ppu_exception_handler";
case 945: return "sys_dbg_finalize_ppu_exception_handler";
case 946: return "sys_dbg_get_semaphore_list";
case 947: return "sys_dbg_get_semaphore_information";
case 948: return "sys_dbg_get_kernel_thread_list";
case 949: return "sys_dbg_get_kernel_thread_info";
case 950: return "sys_dbg_get_lwcond_list";
case 951: return "sys_dbg_get_lwcond_information";
case 952: return "sys_dbg_create_scratch_data_area_ext";
case 953: return "sys_dbg_vm_get_page_information";
case 954: return "sys_dbg_vm_get_info";
case 955: return "sys_dbg_enable_floating_point_enabled_exception";
case 956: return "sys_dbg_disable_floating_point_enabled_exception";
case 960: return "sys_dbg_perfomance_monitor";
case 970: return "sys_dbg_get_event_flag_list";
case 971: return "sys_dbg_get_event_flag_information";
case 975: return "sys_dbg_read_spu_thread_context2";
case 985: return "sys_dbg_get_console_type";
}
// check HLE functions
switch (fid)
{
case 0x1529e506: return "cellAdecDecodeAu";
case 0x487b613e: return "cellAdecStartSeq";
@ -3842,5 +4402,17 @@ std::string SysCalls::GetHLEFuncName(const u32 fid)
case 0xfc52a7a9: return "sys_game_process_exitspawn";
}
return fmt::Format("Unknown func id: 0x%08x", fid);
// check registered functions
if (fid < 0x100000000ull)
{
if (const auto func = get_ppu_func_by_nid(static_cast<u32>(fid)))
{
if (func->name)
{
return func->name;
}
}
}
return fmt::format("0x%08llX", fid);
}

View File

@ -40,7 +40,7 @@ u32 add_ppu_func_sub(const char group[8], const SearchPatternEntry ops[], const
}
StaticFunc sf;
sf.index = add_ppu_func(ModuleFunc(get_function_id(name), 0, module, func));
sf.index = add_ppu_func(ModuleFunc(get_function_id(name), 0, module, name, func));
sf.name = name;
sf.group = *(u64*)group_name;
sf.found = 0;
@ -108,33 +108,33 @@ void execute_ppu_func_by_index(PPUThread& CPU, u32 index)
if (Ini.HLELogging.GetValue())
{
LOG_NOTICE(HLE, "LLE function called: %s", SysCalls::GetHLEFuncName(func->id));
LOG_NOTICE(HLE, "LLE function called: %s", SysCalls::GetFuncName(func->id));
}
func->lle_func(CPU);
if (Ini.HLELogging.GetValue())
{
LOG_NOTICE(HLE, "LLE function finished: %s -> 0x%llx", SysCalls::GetHLEFuncName(func->id), CPU.GPR[3]);
LOG_NOTICE(HLE, "LLE function finished: %s -> 0x%llx", SysCalls::GetFuncName(func->id), CPU.GPR[3]);
}
}
else if (func->func)
{
if (Ini.HLELogging.GetValue())
{
LOG_NOTICE(HLE, "HLE function called: %s", SysCalls::GetHLEFuncName(func->id));
LOG_NOTICE(HLE, "HLE function called: %s", SysCalls::GetFuncName(func->id));
}
func->func(CPU);
if (Ini.HLELogging.GetValue())
{
LOG_NOTICE(HLE, "HLE function finished: %s -> 0x%llx", SysCalls::GetHLEFuncName(func->id), CPU.GPR[3]);
LOG_NOTICE(HLE, "HLE function finished: %s -> 0x%llx", SysCalls::GetFuncName(func->id), CPU.GPR[3]);
}
}
else
{
LOG_ERROR(HLE, "Unimplemented function: %s -> CELL_OK", SysCalls::GetHLEFuncName(func->id));
LOG_ERROR(HLE, "Unimplemented function: %s -> CELL_OK", SysCalls::GetFuncName(func->id));
CPU.GPR[3] = 0;
}

View File

@ -25,6 +25,7 @@ struct ModuleFunc
u32 id;
u32 flags;
Module* module;
const char* name;
ppu_func_caller func;
vm::ptr<void()> lle_func;
@ -32,10 +33,11 @@ struct ModuleFunc
{
}
ModuleFunc(u32 id, u32 flags, Module* module, ppu_func_caller func, vm::ptr<void()> lle_func = vm::ptr<void()>::make(0))
ModuleFunc(u32 id, u32 flags, Module* module, const char* name, ppu_func_caller func, vm::ptr<void()> lle_func = vm::ptr<void()>::make(0))
: id(id)
, flags(flags)
, module(module)
, name(name)
, func(func)
, lle_func(lle_func)
{
@ -117,10 +119,10 @@ void hook_ppu_funcs(vm::ptr<u32> base, u32 size);
bool patch_ppu_import(u32 addr, u32 index);
#define REG_FUNC(module, name) add_ppu_func(ModuleFunc(get_function_id(#name), 0, &module, bind_func(name)))
#define REG_FUNC_FH(module, name) add_ppu_func(ModuleFunc(get_function_id(#name), MFF_FORCED_HLE, &module, bind_func(name)))
#define REG_FUNC(module, name) add_ppu_func(ModuleFunc(get_function_id(#name), 0, &module, #name, bind_func(name)))
#define REG_FUNC_FH(module, name) add_ppu_func(ModuleFunc(get_function_id(#name), MFF_FORCED_HLE, &module, #name, bind_func(name)))
#define REG_UNNAMED(module, nid) add_ppu_func(ModuleFunc(0x##nid, 0, &module, bind_func(_nid_##nid)))
#define REG_UNNAMED(module, nid) add_ppu_func(ModuleFunc(0x##nid, 0, &module, "_nid_"#nid, bind_func(_nid_##nid)))
#define REG_SUB(module, group, ns, name, ...) \
const SearchPatternEntry name##_table[] = {__VA_ARGS__}; \

View File

@ -73,8 +73,6 @@ s32 cellAudioInit()
squeue_t<float*, BUFFER_NUM - 1> out_queue;
std::vector<u64> keys;
thread_t iat("Internal Audio Thread", true /* autojoin */, [&out_queue]()
{
const bool use_u16 = Ini.AudioConvertToU16.GetValue();
@ -374,11 +372,13 @@ s32 cellAudioInit()
//const u64 stamp2 = get_system_time();
// send aftermix event (normal audio event)
{
std::lock_guard<std::mutex> lock(g_audio.mutex);
// update indexes:
// update indices:
auto indexes = vm::ptr<u64>::make(g_audio.indexes);
for (u32 i = 0; i < AUDIO_PORT_COUNT; i++)
{
AudioPortConfig& port = g_audio.ports[i];
@ -390,16 +390,14 @@ s32 cellAudioInit()
port.tag++; // absolute index of block that will be read
indexes[i] = (position + 1) % port.block; // write new value
}
// load keys:
keys.resize(g_audio.keys.size());
memcpy(keys.data(), g_audio.keys.data(), sizeof(u64) * keys.size());
}
{
// send aftermix event (normal audio event)
LV2_LOCK;
for (u32 i = 0; i < keys.size(); i++)
for (auto key : g_audio.keys)
{
if (std::shared_ptr<event_queue_t> queue = Emu.GetEventManager().GetEventQueue(keys[i]))
if (std::shared_ptr<event_queue_t> queue = Emu.GetEventManager().GetEventQueue(key))
{
queue->push(0, 0, 0, 0); // TODO: check arguments
}
@ -455,7 +453,7 @@ s32 cellAudioQuit()
s32 cellAudioPortOpen(vm::ptr<CellAudioPortParam> audioParam, vm::ptr<u32> portNum)
{
cellAudio.Warning("cellAudioPortOpen(audioParam=0x%x, portNum=0x%x)", audioParam, portNum);
cellAudio.Warning("cellAudioPortOpen(audioParam=*0x%x, portNum=*0x%x)", audioParam, portNum);
if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED)
{
@ -519,7 +517,7 @@ s32 cellAudioPortOpen(vm::ptr<CellAudioPortParam> audioParam, vm::ptr<u32> portN
}
if (attr & 0xFFFFFFFFF0EFEFEEULL)
{
cellAudio.Todo("cellAudioPortOpen(): unknown attributes set (0x%llx)", attr);
cellAudio.Todo("cellAudioPortOpen(): unknown attributes (0x%llx)", attr);
}
// open audio port
@ -560,7 +558,7 @@ s32 cellAudioPortOpen(vm::ptr<CellAudioPortParam> audioParam, vm::ptr<u32> portN
s32 cellAudioGetPortConfig(u32 portNum, vm::ptr<CellAudioPortConfig> portConfig)
{
cellAudio.Warning("cellAudioGetPortConfig(portNum=0x%x, portConfig=0x%x)", portNum, portConfig);
cellAudio.Warning("cellAudioGetPortConfig(portNum=%d, portConfig=*0x%x)", portNum, portConfig);
if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED)
{
@ -581,7 +579,7 @@ s32 cellAudioGetPortConfig(u32 portNum, vm::ptr<CellAudioPortConfig> portConfig)
case AUDIO_PORT_STATE_CLOSED: portConfig->status = CELL_AUDIO_STATUS_CLOSE; break;
case AUDIO_PORT_STATE_OPENED: portConfig->status = CELL_AUDIO_STATUS_READY; break;
case AUDIO_PORT_STATE_STARTED: portConfig->status = CELL_AUDIO_STATUS_RUN; break;
default: throw fmt::format("cellAudioGetPortConfig(%d): invalid port state (0x%x)", portNum, state);
default: throw fmt::format("cellAudioGetPortConfig(%d): invalid port state (%d)", portNum, state);
}
portConfig->nChannel = port.channel;
@ -593,7 +591,7 @@ s32 cellAudioGetPortConfig(u32 portNum, vm::ptr<CellAudioPortConfig> portConfig)
s32 cellAudioPortStart(u32 portNum)
{
cellAudio.Warning("cellAudioPortStart(portNum=0x%x)", portNum);
cellAudio.Warning("cellAudioPortStart(portNum=%d)", portNum);
if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED)
{
@ -610,13 +608,13 @@ s32 cellAudioPortStart(u32 portNum)
case AUDIO_PORT_STATE_CLOSED: return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
case AUDIO_PORT_STATE_STARTED: return CELL_AUDIO_ERROR_PORT_ALREADY_RUN;
case AUDIO_PORT_STATE_OPENED: return CELL_OK;
default: throw fmt::format("cellAudioPortStart(%d): invalid port state (0x%x)", portNum, state);
default: throw fmt::format("cellAudioPortStart(%d): invalid port state (%d)", portNum, state);
}
}
s32 cellAudioPortClose(u32 portNum)
{
cellAudio.Warning("cellAudioPortClose(portNum=0x%x)", portNum);
cellAudio.Warning("cellAudioPortClose(portNum=%d)", portNum);
if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED)
{
@ -633,13 +631,13 @@ s32 cellAudioPortClose(u32 portNum)
case AUDIO_PORT_STATE_CLOSED: return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
case AUDIO_PORT_STATE_STARTED: return CELL_OK;
case AUDIO_PORT_STATE_OPENED: return CELL_OK;
default: throw fmt::format("cellAudioPortClose(%d): invalid port state (0x%x)", portNum, state);
default: throw fmt::format("cellAudioPortClose(%d): invalid port state (%d)", portNum, state);
}
}
s32 cellAudioPortStop(u32 portNum)
{
cellAudio.Warning("cellAudioPortStop(portNum=0x%x)", portNum);
cellAudio.Warning("cellAudioPortStop(portNum=%d)", portNum);
if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED)
{
@ -656,13 +654,13 @@ s32 cellAudioPortStop(u32 portNum)
case AUDIO_PORT_STATE_CLOSED: return CELL_AUDIO_ERROR_PORT_NOT_RUN;
case AUDIO_PORT_STATE_STARTED: return CELL_OK;
case AUDIO_PORT_STATE_OPENED: return CELL_AUDIO_ERROR_PORT_NOT_RUN;
default: throw fmt::format("cellAudioPortStop(%d): invalid port state (0x%x)", portNum, state);
default: throw fmt::format("cellAudioPortStop(%d): invalid port state (%d)", portNum, state);
}
}
s32 cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr<u64> stamp)
{
cellAudio.Log("cellAudioGetPortTimestamp(portNum=0x%x, tag=0x%llx, stamp=0x%x)", portNum, tag, stamp);
cellAudio.Log("cellAudioGetPortTimestamp(portNum=%d, tag=0x%llx, stamp=*0x%x)", portNum, tag, stamp);
if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED)
{
@ -692,7 +690,7 @@ s32 cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr<u64> stamp)
s32 cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr<u64> tag)
{
cellAudio.Log("cellAudioGetPortBlockTag(portNum=0x%x, blockNo=0x%llx, tag=0x%x)", portNum, blockNo, tag);
cellAudio.Log("cellAudioGetPortBlockTag(portNum=%d, blockNo=0x%llx, tag=*0x%x)", portNum, blockNo, tag);
if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED)
{
@ -735,7 +733,7 @@ s32 cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr<u64> tag)
s32 cellAudioSetPortLevel(u32 portNum, float level)
{
cellAudio.Log("cellAudioSetPortLevel(portNum=0x%x, level=%f)", portNum, level);
cellAudio.Log("cellAudioSetPortLevel(portNum=%d, level=%f)", portNum, level);
if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED)
{
@ -763,121 +761,118 @@ s32 cellAudioSetPortLevel(u32 portNum, float level)
}
else
{
cellAudio.Todo("cellAudioSetPortLevel(portNum=0x%x): negative level value (%f)", portNum, level);
cellAudio.Todo("cellAudioSetPortLevel(%d): negative level value (%f)", portNum, level);
}
return CELL_OK;
}
// Utility Functions
int cellAudioCreateNotifyEventQueue(vm::ptr<u32> id, vm::ptr<u64> key)
s32 cellAudioCreateNotifyEventQueue(vm::ptr<u32> id, vm::ptr<u64> key)
{
cellAudio.Warning("cellAudioCreateNotifyEventQueue(id_addr=0x%x, key_addr=0x%x)", id.addr(), key.addr());
cellAudio.Warning("cellAudioCreateNotifyEventQueue(id=*0x%x, key=*0x%x)", id, key);
std::lock_guard<std::mutex> lock(g_audio.mutex);
u64 event_key = 0;
while (Emu.GetEventManager().CheckKey((event_key << 48) | 0x80004d494f323221))
for (u64 k = 0; k < 100; k++)
{
event_key++; // experimental
//return CELL_AUDIO_ERROR_EVENT_QUEUE;
}
event_key = (event_key << 48) | 0x80004d494f323221; // left part: 0x8000, 0x8001, 0x8002 ...
const u64 key_value = 0x80004d494f323221ull + k;
std::shared_ptr<event_queue_t> eq(new event_queue_t(SYS_SYNC_FIFO, SYS_PPU_QUEUE, event_key, event_key, 32));
std::shared_ptr<event_queue_t> queue(new event_queue_t(SYS_SYNC_FIFO, SYS_PPU_QUEUE, 0, key_value, 32));
if (!Emu.GetEventManager().RegisterKey(eq, event_key))
{
return CELL_AUDIO_ERROR_EVENT_QUEUE;
}
*id = Emu.GetIdManager().GetNewID(eq);
*key = event_key;
return CELL_OK;
}
int cellAudioCreateNotifyEventQueueEx(vm::ptr<u32> id, vm::ptr<u64> key, u32 iFlags)
{
cellAudio.Todo("cellAudioCreateNotifyEventQueueEx(id_addr=0x%x, key_addr=0x%x, iFlags=0x%x)", id.addr(), key.addr(), iFlags);
return CELL_OK;
}
int cellAudioSetNotifyEventQueue(u64 key)
{
cellAudio.Warning("cellAudioSetNotifyEventQueue(key=0x%llx)", key);
std::lock_guard<std::mutex> lock(g_audio.mutex);
for (u32 i = 0; i < g_audio.keys.size(); i++) // check for duplicates
{
if (g_audio.keys[i] == key)
// register key if not used yet
if (Emu.GetEventManager().RegisterKey(queue, key_value))
{
return CELL_AUDIO_ERROR_PARAM;
}
}
g_audio.keys.push_back(key);
*id = Emu.GetIdManager().GetNewID(queue, TYPE_EVENT_QUEUE);
*key = key_value;
/*EventQueue* eq;
if (!Emu.GetEventManager().GetEventQueue(key, eq))
{
return CELL_AUDIO_ERROR_PARAM;
}*/
// TODO: connect port (?????)
return CELL_OK;
}
int cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags)
{
cellAudio.Todo("cellAudioSetNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags);
return CELL_OK;
}
int cellAudioRemoveNotifyEventQueue(u64 key)
{
cellAudio.Warning("cellAudioRemoveNotifyEventQueue(key=0x%llx)", key);
std::lock_guard<std::mutex> lock(g_audio.mutex);
bool found = false;
for (u32 i = 0; i < g_audio.keys.size(); i++)
{
if (g_audio.keys[i] == key)
{
g_audio.keys.erase(g_audio.keys.begin() + i);
found = true;
break;
return CELL_OK;
}
}
if (!found)
return CELL_AUDIO_ERROR_EVENT_QUEUE;
}
s32 cellAudioCreateNotifyEventQueueEx(vm::ptr<u32> id, vm::ptr<u64> key, u32 iFlags)
{
cellAudio.Todo("cellAudioCreateNotifyEventQueueEx(id=*0x%x, key=*0x%x, iFlags=0x%x)", id, key, iFlags);
if (iFlags & ~CELL_AUDIO_CREATEEVENTFLAG_SPU)
{
// ???
return CELL_AUDIO_ERROR_PARAM;
}
/*EventQueue* eq;
if (!Emu.GetEventManager().GetEventQueue(key, eq))
{
return CELL_AUDIO_ERROR_PARAM;
}*/
// TODO
// TODO: disconnect port
return CELL_AUDIO_ERROR_EVENT_QUEUE;
}
s32 cellAudioSetNotifyEventQueue(u64 key)
{
cellAudio.Warning("cellAudioSetNotifyEventQueue(key=0x%llx)", key);
if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED)
{
return CELL_AUDIO_ERROR_NOT_INIT;
}
std::lock_guard<std::mutex> lock(g_audio.mutex);
for (auto k : g_audio.keys) // check for duplicates
{
if (k == key)
{
return CELL_AUDIO_ERROR_TRANS_EVENT;
}
}
g_audio.keys.emplace_back(key);
return CELL_OK;
}
int cellAudioRemoveNotifyEventQueueEx(u64 key, u32 iFlags)
s32 cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags)
{
cellAudio.Todo("cellAudioSetNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags);
// TODO
return CELL_OK;
}
s32 cellAudioRemoveNotifyEventQueue(u64 key)
{
cellAudio.Warning("cellAudioRemoveNotifyEventQueue(key=0x%llx)", key);
if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED)
{
return CELL_AUDIO_ERROR_NOT_INIT;
}
std::lock_guard<std::mutex> lock(g_audio.mutex);
for (auto i = g_audio.keys.begin(); i != g_audio.keys.end(); i++)
{
if (*i == key)
{
g_audio.keys.erase(i);
return CELL_OK;
}
}
return CELL_AUDIO_ERROR_TRANS_EVENT;
}
s32 cellAudioRemoveNotifyEventQueueEx(u64 key, u32 iFlags)
{
cellAudio.Todo("cellAudioRemoveNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags);
// TODO
return CELL_OK;
}
s32 cellAudioAddData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
{
cellAudio.Log("cellAudioAddData(portNum=%d, src=0x%x, samples=%d, volume=%f)", portNum, src, samples, volume);
cellAudio.Log("cellAudioAddData(portNum=%d, src=*0x%x, samples=%d, volume=%f)", portNum, src, samples, volume);
if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED)
{
@ -892,7 +887,7 @@ s32 cellAudioAddData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
if (samples != 256)
{
// despite the docs, seems that only fixed value is supported
cellAudio.Error("cellAudioAddData(): invalid samples value (0x%x)", samples);
cellAudio.Error("cellAudioAddData(): invalid samples value (%d)", samples);
return CELL_AUDIO_ERROR_PARAM;
}
@ -910,7 +905,7 @@ s32 cellAudioAddData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
s32 cellAudioAdd2chData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
{
cellAudio.Log("cellAudioAdd2chData(portNum=%d, src=0x%x, samples=%d, volume=%f)", portNum, src, samples, volume);
cellAudio.Log("cellAudioAdd2chData(portNum=%d, src=*0x%x, samples=%d, volume=%f)", portNum, src, samples, volume);
if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED)
{
@ -925,7 +920,7 @@ s32 cellAudioAdd2chData(u32 portNum, vm::ptr<float> src, u32 samples, float volu
if (samples != 256)
{
// despite the docs, seems that only fixed value is supported
cellAudio.Error("cellAudioAdd2chData(): invalid samples value (0x%x)", samples);
cellAudio.Error("cellAudioAdd2chData(): invalid samples value (%d)", samples);
return CELL_AUDIO_ERROR_PARAM;
}
@ -973,7 +968,7 @@ s32 cellAudioAdd2chData(u32 portNum, vm::ptr<float> src, u32 samples, float volu
s32 cellAudioAdd6chData(u32 portNum, vm::ptr<float> src, float volume)
{
cellAudio.Log("cellAudioAdd6chData(portNum=%d, src=0x%x, volume=%f)", portNum, src, volume);
cellAudio.Log("cellAudioAdd6chData(portNum=%d, src=*0x%x, volume=%f)", portNum, src, volume);
if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED)
{
@ -1015,27 +1010,27 @@ s32 cellAudioAdd6chData(u32 portNum, vm::ptr<float> src, float volume)
return CELL_OK;
}
int cellAudioMiscSetAccessoryVolume(u32 devNum, float volume)
s32 cellAudioMiscSetAccessoryVolume(u32 devNum, float volume)
{
cellAudio.Todo("cellAudioMiscSetAccessoryVolume(devNum=0x%x, volume=%f)", devNum, volume);
cellAudio.Todo("cellAudioMiscSetAccessoryVolume(devNum=%d, volume=%f)", devNum, volume);
return CELL_OK;
}
int cellAudioSendAck(u64 data3)
s32 cellAudioSendAck(u64 data3)
{
cellAudio.Todo("cellAudioSendAck(data3=0x%llx)", data3);
return CELL_OK;
}
int cellAudioSetPersonalDevice(int iPersonalStream, int iDevice)
s32 cellAudioSetPersonalDevice(s32 iPersonalStream, s32 iDevice)
{
cellAudio.Todo("cellAudioSetPersonalDevice(iPersonalStream=0x%x, iDevice=0x%x)", iPersonalStream, iDevice);
cellAudio.Todo("cellAudioSetPersonalDevice(iPersonalStream=%d, iDevice=%d)", iPersonalStream, iDevice);
return CELL_OK;
}
int cellAudioUnsetPersonalDevice(int iPersonalStream)
s32 cellAudioUnsetPersonalDevice(s32 iPersonalStream)
{
cellAudio.Todo("cellAudioUnsetPersonalDevice(iPersonalStream=0x%x)", iPersonalStream);
cellAudio.Todo("cellAudioUnsetPersonalDevice(iPersonalStream=%d)", iPersonalStream);
return CELL_OK;
}

View File

@ -15,31 +15,6 @@
extern Module cellFs;
struct CellFsDirectoryEntry
{
CellFsStat attribute;
CellFsDirent entry_name;
};
struct FsRingBufferConfig
{
CellFsRingBuffer m_ring_buffer; // Currently unused after assignment
u32 m_buffer;
u64 m_fs_status;
u64 m_regid;
u32 m_alloc_mem_size;
u32 m_current_addr;
FsRingBufferConfig()
: m_fs_status(CELL_FS_ST_NOT_INITIALIZED)
, m_regid(0)
, m_alloc_mem_size(0)
, m_current_addr(0)
, m_ring_buffer() { }
} fs_config;
s32 cellFsOpen(vm::ptr<const char> path, s32 flags, vm::ptr<u32> fd, vm::ptr<const void> arg, u64 size)
{
cellFs.Warning("cellFsOpen(path=*0x%x, flags=%#o, fd=*0x%x, arg=*0x%x, size=0x%llx) -> sys_fs_open()", path, flags, fd, arg, size);
@ -89,7 +64,7 @@ s32 cellFsReaddir(u32 fd, vm::ptr<CellFsDirent> dir, vm::ptr<u64> nread)
cellFs.Log("cellFsReaddir(fd=0x%x, dir=*0x%x, nread=*0x%x)", fd, dir, nread);
// call the syscall
return dir && nread ? sys_fs_readdir(fd, dir, nread) : CELL_EFAULT;
return dir && nread ? sys_fs_readdir(fd, dir, nread) : CELL_FS_EFAULT;
}
s32 cellFsClosedir(u32 fd)
@ -163,7 +138,7 @@ s32 cellFsLseek(u32 fd, s64 offset, u32 whence, vm::ptr<u64> pos)
cellFs.Log("cellFsLseek(fd=0x%x, offset=0x%llx, whence=0x%x, pos=*0x%x)", fd, offset, whence, pos);
// call the syscall
return pos ? sys_fs_lseek(fd, offset, whence, pos) : CELL_EFAULT;
return pos ? sys_fs_lseek(fd, offset, whence, pos) : CELL_FS_EFAULT;
}
s32 cellFsFsync(u32 fd)
@ -178,7 +153,7 @@ s32 cellFsFGetBlockSize(PPUThread& CPU, u32 fd, vm::ptr<u64> sector_size, vm::pt
cellFs.Log("cellFsFGetBlockSize(fd=0x%x, sector_size=*0x%x, block_size=*0x%x)", fd, sector_size, block_size);
// call the syscall
return sector_size && block_size ? sys_fs_fget_block_size(fd, sector_size, block_size, vm::stackvar<be_t<u64>>(CPU), vm::stackvar<be_t<u64>>(CPU)) : CELL_EFAULT;
return sector_size && block_size ? sys_fs_fget_block_size(fd, sector_size, block_size, vm::stackvar<be_t<u64>>(CPU), vm::stackvar<be_t<u64>>(CPU)) : CELL_FS_EFAULT;
}
s32 cellFsGetBlockSize(PPUThread& CPU, vm::ptr<const char> path, vm::ptr<u64> sector_size, vm::ptr<u64> block_size)
@ -236,8 +211,11 @@ s32 cellFsGetDirectoryEntries(u32 fd, vm::ptr<CellFsDirectoryEntry> entries, u32
cellFs.Warning("cellFsGetDirectoryEntries(fd=0x%x, entries=*0x%x, entries_size=0x%x, data_count=*0x%x)", fd, entries, entries_size, data_count);
std::shared_ptr<vfsDirBase> directory;
if (!Emu.GetIdManager().GetIDData(fd, directory))
return CELL_ESRCH;
{
return CELL_FS_EBADF;
}
const DirEntryInfo* info = directory->Read();
if (info)
@ -280,6 +258,8 @@ s32 cellFsReadWithOffset(u32 fd, u64 offset, vm::ptr<void> buf, u64 buffer_size,
return CELL_FS_EBADF;
}
std::lock_guard<std::mutex> lock(file->mutex);
const auto old_position = file->file->Tell();
file->file->Seek(offset);
@ -309,6 +289,8 @@ s32 cellFsWriteWithOffset(u32 fd, u64 offset, vm::ptr<const void> buf, u64 data_
return CELL_FS_EBADF;
}
std::lock_guard<std::mutex> lock(file->mutex);
const auto old_position = file->file->Tell();
file->file->Seek(offset);
@ -325,27 +307,55 @@ s32 cellFsWriteWithOffset(u32 fd, u64 offset, vm::ptr<const void> buf, u64 data_
return CELL_OK;
}
s32 cellFsStReadInit(u32 fd, vm::ptr<CellFsRingBuffer> ringbuf)
s32 cellFsStReadInit(u32 fd, vm::ptr<const CellFsRingBuffer> ringbuf)
{
cellFs.Warning("cellFsStReadInit(fd=0x%x, ringbuf=*0x%x)", fd, ringbuf);
if (ringbuf->copy.data() & ~se32(CELL_FS_ST_COPYLESS))
{
return CELL_FS_EINVAL;
}
if (ringbuf->block_size.data() & se64(0xfff)) // check if a multiple of sector size
{
return CELL_FS_EINVAL;
}
if (ringbuf->ringbuf_size % ringbuf->block_size) // check if a multiple of block_size
{
return CELL_FS_EINVAL;
}
std::shared_ptr<fs_file_t> file;
if (!Emu.GetIdManager().GetIDData(fd, file))
return CELL_ESRCH;
{
return CELL_FS_EBADF;
}
if (file->flags & CELL_FS_O_WRONLY)
{
return CELL_FS_EPERM;
}
fs_config.m_ring_buffer = *ringbuf;
std::lock_guard<std::mutex> lock(file->mutex);
// If the size is less than 1MB
if (ringbuf->ringbuf_size < 0x40000000)
fs_config.m_alloc_mem_size = (((u32)ringbuf->ringbuf_size + 64 * 1024 - 1) / (64 * 1024)) * (64 * 1024);
else
fs_config.m_alloc_mem_size = (((u32)ringbuf->ringbuf_size + 1024 * 1024 - 1) / (1024 * 1024)) * (1024 * 1024);
if (!file->st_status.compare_and_swap_test(SSS_NOT_INITIALIZED, SSS_INITIALIZED))
{
return CELL_FS_EBUSY;
}
// alloc memory
fs_config.m_buffer = (u32)Memory.Alloc(fs_config.m_alloc_mem_size, 1024);
memset(vm::get_ptr<void>(fs_config.m_buffer), 0, fs_config.m_alloc_mem_size);
file->st_ringbuf_size = ringbuf->ringbuf_size;
file->st_block_size = ringbuf->ringbuf_size;
file->st_trans_rate = ringbuf->transfer_rate;
file->st_copyless = ringbuf->copy.data() == se32(CELL_FS_ST_COPYLESS);
fs_config.m_fs_status = CELL_FS_ST_INITIALIZED;
const u64 alloc_size = align(file->st_ringbuf_size, file->st_ringbuf_size < 1024 * 1024 ? 64 * 1024 : 1024 * 1024);
file->st_buffer = vm::alloc(static_cast<u32>(alloc_size), vm::main);
file->st_read_size = 0;
file->st_total_read = 0;
file->st_copied = 0;
return CELL_OK;
}
@ -355,11 +365,20 @@ s32 cellFsStReadFinish(u32 fd)
cellFs.Warning("cellFsStReadFinish(fd=0x%x)", fd);
std::shared_ptr<fs_file_t> file;
if (!Emu.GetIdManager().GetIDData(fd, file))
return CELL_ESRCH;
Memory.Free(fs_config.m_buffer);
fs_config.m_fs_status = CELL_FS_ST_NOT_INITIALIZED;
if (!Emu.GetIdManager().GetIDData(fd, file))
{
return CELL_FS_EBADF; // ???
}
std::lock_guard<std::mutex> lock(file->mutex);
if (!file->st_status.compare_and_swap_test(SSS_INITIALIZED, SSS_NOT_INITIALIZED))
{
return CELL_FS_ENXIO;
}
vm::dealloc(file->st_buffer, vm::main);
return CELL_OK;
}
@ -369,13 +388,22 @@ s32 cellFsStReadGetRingBuf(u32 fd, vm::ptr<CellFsRingBuffer> ringbuf)
cellFs.Warning("cellFsStReadGetRingBuf(fd=0x%x, ringbuf=*0x%x)", fd, ringbuf);
std::shared_ptr<fs_file_t> file;
if (!Emu.GetIdManager().GetIDData(fd, file))
return CELL_ESRCH;
{
return CELL_FS_EBADF;
}
*ringbuf = fs_config.m_ring_buffer;
if (file->st_status.read_sync() == SSS_NOT_INITIALIZED)
{
return CELL_FS_ENXIO;
}
ringbuf->ringbuf_size = file->st_ringbuf_size;
ringbuf->block_size = file->st_block_size;
ringbuf->transfer_rate = file->st_trans_rate;
ringbuf->copy = file->st_copyless ? CELL_FS_ST_COPYLESS : CELL_FS_ST_COPY;
cellFs.Warning("*** fs stream config: block_size=0x%llx, copy=0x%x, ringbuf_size=0x%llx, transfer_rate=0x%llx",
ringbuf->block_size, ringbuf->copy, ringbuf->ringbuf_size, ringbuf->transfer_rate);
return CELL_OK;
}
@ -384,10 +412,31 @@ s32 cellFsStReadGetStatus(u32 fd, vm::ptr<u64> status)
cellFs.Warning("cellFsStReadGetRingBuf(fd=0x%x, status=*0x%x)", fd, status);
std::shared_ptr<fs_file_t> file;
if (!Emu.GetIdManager().GetIDData(fd, file))
return CELL_ESRCH;
*status = fs_config.m_fs_status;
if (!Emu.GetIdManager().GetIDData(fd, file))
{
return CELL_FS_EBADF;
}
switch (file->st_status.read_sync())
{
case SSS_INITIALIZED:
case SSS_STOPPED:
{
*status = CELL_FS_ST_INITIALIZED | CELL_FS_ST_STOP;
break;
}
case SSS_STARTED:
{
*status = CELL_FS_ST_INITIALIZED | CELL_FS_ST_PROGRESS;
break;
}
default:
{
*status = CELL_FS_ST_NOT_INITIALIZED | CELL_FS_ST_STOP;
break;
}
}
return CELL_OK;
}
@ -397,24 +446,100 @@ s32 cellFsStReadGetRegid(u32 fd, vm::ptr<u64> regid)
cellFs.Warning("cellFsStReadGetRingBuf(fd=0x%x, regid=*0x%x)", fd, regid);
std::shared_ptr<fs_file_t> file;
if (!Emu.GetIdManager().GetIDData(fd, file))
return CELL_ESRCH;
*regid = fs_config.m_regid;
if (!Emu.GetIdManager().GetIDData(fd, file))
{
return CELL_FS_EBADF;
}
if (file->st_status.read_sync() == SSS_NOT_INITIALIZED)
{
return CELL_FS_ENXIO;
}
*regid = file->st_total_read - file->st_copied;
return CELL_OK;
}
s32 cellFsStReadStart(u32 fd, u64 offset, u64 size)
{
cellFs.Todo("cellFsStReadStart(fd=0x%x, offset=0x%llx, size=0x%llx)", fd, offset, size);
cellFs.Warning("cellFsStReadStart(fd=0x%x, offset=0x%llx, size=0x%llx)", fd, offset, size);
std::shared_ptr<fs_file_t> file;
if (!Emu.GetIdManager().GetIDData(fd, file))
return CELL_ESRCH;
fs_config.m_current_addr = fs_config.m_buffer + (u32)offset;
fs_config.m_fs_status = CELL_FS_ST_PROGRESS;
if (!Emu.GetIdManager().GetIDData(fd, file))
{
return CELL_FS_EBADF;
}
switch (auto status = file->st_status.compare_and_swap(SSS_INITIALIZED, SSS_STARTED))
{
case SSS_NOT_INITIALIZED:
{
return CELL_FS_ENXIO;
}
case SSS_STARTED:
{
return CELL_FS_EBUSY;
}
}
offset = std::min<u64>(file->file->GetSize(), offset);
size = std::min<u64>(file->file->GetSize() - offset, size);
file->st_thread.set_name(fmt::format("FS ST Thread[0x%x]", fd));
file->st_read_size = size;
file->st_thread.start([=]()
{
std::unique_lock<std::mutex> lock(file->mutex);
while (file->st_status.read_relaxed() == SSS_STARTED && !Emu.IsStopped())
{
// check free space in buffer and available data in stream
if (file->st_total_read - file->st_copied <= file->st_ringbuf_size - file->st_block_size && file->st_total_read < file->st_read_size)
{
// get buffer position
const u32 position = vm::cast(file->st_buffer + file->st_total_read % file->st_ringbuf_size);
// read data
auto old = file->file->Tell();
file->file->Seek(offset + file->st_total_read);
auto res = file->file->Read(vm::get_ptr(position), file->st_block_size);
file->file->Seek(old);
// notify
file->st_total_read += res;
file->cv.notify_one();
}
// check callback condition if set
if (file->st_callback.data.func)
{
const u64 available = file->st_total_read - file->st_copied;
if (available >= file->st_callback.data.size)
{
const auto func = file->st_callback.exchange({}).func;
Emu.GetCallbackManager().Async([=](PPUThread& CPU)
{
func(CPU, fd, available);
});
}
}
file->cv.wait_for(lock, std::chrono::milliseconds(1));
}
file->st_status.compare_and_swap(SSS_STOPPED, SSS_INITIALIZED);
file->st_read_size = 0;
file->st_total_read = 0;
file->st_copied = 0;
file->st_callback.data = {};
});
return CELL_OK;
}
@ -424,10 +549,28 @@ s32 cellFsStReadStop(u32 fd)
cellFs.Warning("cellFsStReadStop(fd=0x%x)", fd);
std::shared_ptr<fs_file_t> file;
if (!Emu.GetIdManager().GetIDData(fd, file))
return CELL_ESRCH;
fs_config.m_fs_status = CELL_FS_ST_STOP;
if (!Emu.GetIdManager().GetIDData(fd, file))
{
return CELL_FS_EBADF;
}
switch (auto status = file->st_status.compare_and_swap(SSS_STARTED, SSS_STOPPED))
{
case SSS_NOT_INITIALIZED:
{
return CELL_FS_ENXIO;
}
case SSS_INITIALIZED:
case SSS_STOPPED:
{
return CELL_OK;
}
}
file->cv.notify_all();
file->st_thread.join();
return CELL_OK;
}
@ -437,60 +580,149 @@ s32 cellFsStRead(u32 fd, vm::ptr<u8> buf, u64 size, vm::ptr<u64> rsize)
cellFs.Warning("cellFsStRead(fd=0x%x, buf=*0x%x, size=0x%llx, rsize=*0x%x)", fd, buf, size, rsize);
std::shared_ptr<fs_file_t> file;
if (!Emu.GetIdManager().GetIDData(fd, file))
return CELL_ESRCH;
{
return CELL_FS_EBADF;
}
// TODO: use ringbuffer (fs_config)
fs_config.m_regid += size;
if (file->st_status.read_sync() == SSS_NOT_INITIALIZED || file->st_copyless)
{
return CELL_FS_ENXIO;
}
if (file->file->Eof())
return CELL_FS_ERANGE;
const u64 copied = file->st_copied.load();
const u32 position = vm::cast(file->st_buffer + copied % file->st_ringbuf_size);
const u64 total_read = file->st_total_read.load();
const u32 copy_size = vm::cast(*rsize = std::min<u64>(size, total_read - copied));
// copy data
const u32 first_size = std::min<u32>(copy_size, file->st_ringbuf_size - (position - file->st_buffer));
memcpy(buf.get_ptr(), vm::get_ptr(position), first_size);
memcpy((buf + first_size).get_ptr(), vm::get_ptr(file->st_buffer), copy_size - first_size);
*rsize = file->file->Read(buf.get_ptr(), size);
// notify
file->st_copied += copy_size;
file->cv.notify_one();
return CELL_OK;
// check end of stream
return total_read < file->st_read_size ? CELL_OK : CELL_FS_ERANGE;
}
s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr<vm::ptr<u8>> addr, vm::ptr<u64> size)
s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr<u32> addr, vm::ptr<u64> size)
{
cellFs.Todo("cellFsStReadGetCurrentAddr(fd=0x%x, addr=*0x%x, size=*0x%x)", fd, addr, size);
cellFs.Warning("cellFsStReadGetCurrentAddr(fd=0x%x, addr=*0x%x, size=*0x%x)", fd, addr, size);
std::shared_ptr<fs_file_t> file;
if (!Emu.GetIdManager().GetIDData(fd, file))
return CELL_ESRCH;
return CELL_OK;
if (!Emu.GetIdManager().GetIDData(fd, file))
{
return CELL_FS_EBADF;
}
if (file->st_status.read_sync() == SSS_NOT_INITIALIZED || !file->st_copyless)
{
return CELL_FS_ENXIO;
}
const u64 copied = file->st_copied.load();
const u32 position = vm::cast(file->st_buffer + copied % file->st_ringbuf_size);
const u64 total_read = file->st_total_read.load();
if ((*size = std::min<u64>(file->st_ringbuf_size - (position - file->st_buffer), total_read - copied)).data())
{
*addr = position;
}
else
{
*addr = 0;
}
// check end of stream
return total_read < file->st_read_size ? CELL_OK : CELL_FS_ERANGE;
}
s32 cellFsStReadPutCurrentAddr(u32 fd, vm::ptr<u8> addr, u64 size)
{
cellFs.Todo("cellFsStReadPutCurrentAddr(fd=0x%x, addr=*0x%x, size=0x%llx)", fd, addr, size);
cellFs.Warning("cellFsStReadPutCurrentAddr(fd=0x%x, addr=*0x%x, size=0x%llx)", fd, addr, size);
std::shared_ptr<fs_file_t> file;
if (!Emu.GetIdManager().GetIDData(fd, file))
return CELL_ESRCH;
return CELL_OK;
if (!Emu.GetIdManager().GetIDData(fd, file))
{
return CELL_FS_EBADF;
}
if (file->st_status.read_sync() == SSS_NOT_INITIALIZED || !file->st_copyless)
{
return CELL_FS_ENXIO;
}
const u64 copied = file->st_copied.load();
const u64 total_read = file->st_total_read.load();
// notify
file->st_copied += size;
file->cv.notify_one();
// check end of stream
return total_read < file->st_read_size ? CELL_OK : CELL_FS_ERANGE;
}
s32 cellFsStReadWait(u32 fd, u64 size)
{
cellFs.Todo("cellFsStReadWait(fd=0x%x, size=0x%llx)", fd, size);
cellFs.Warning("cellFsStReadWait(fd=0x%x, size=0x%llx)", fd, size);
std::shared_ptr<fs_file_t> file;
if (!Emu.GetIdManager().GetIDData(fd, file))
return CELL_ESRCH;
{
return CELL_FS_EBADF;
}
if (file->st_status.read_sync() == SSS_NOT_INITIALIZED)
{
return CELL_FS_ENXIO;
}
std::unique_lock<std::mutex> lock(file->mutex);
while (file->st_total_read - file->st_copied < size && file->st_total_read < file->st_read_size)
{
// wait for size availability or stream end
if (Emu.IsStopped())
{
cellFs.Warning("cellFsStReadWait(0x%x) aborted", fd);
return CELL_OK;
}
file->cv.wait_for(lock, std::chrono::milliseconds(1));
}
return CELL_OK;
}
s32 cellFsStReadWaitCallback(u32 fd, u64 size, vm::ptr<void(int xfd, u64 xsize)> func)
s32 cellFsStReadWaitCallback(u32 fd, u64 size, fs_st_cb_t func)
{
cellFs.Todo("cellFsStReadWaitCallback(fd=0x%x, size=0x%llx, func=*0x%x)", fd, size, func);
cellFs.Warning("cellFsStReadWaitCallback(fd=0x%x, size=0x%llx, func=*0x%x)", fd, size, func);
std::shared_ptr<fs_file_t> file;
if (!Emu.GetIdManager().GetIDData(fd, file))
return CELL_ESRCH;
{
return CELL_FS_EBADF;
}
if (file->st_status.read_sync() == SSS_NOT_INITIALIZED)
{
return CELL_FS_ENXIO;
}
if (!file->st_callback.compare_and_swap_test({}, { vm::cast(size, "size"), func }))
{
return CELL_FS_EIO;
}
return CELL_OK;
}
@ -601,7 +833,7 @@ s32 cellFsSdataOpen(PPUThread& CPU, vm::ptr<const char> path, s32 flags, vm::ptr
if (flags != CELL_FS_O_RDONLY)
{
return CELL_EINVAL;
return CELL_FS_EINVAL;
}
return cellFsOpen(path, CELL_FS_O_RDONLY, fd, vm::stackvar<be_t<u64>>(CPU), 8);
@ -634,14 +866,10 @@ s32 cellFsSdataOpenByFd(u32 mself_fd, s32 flags, vm::ptr<u32> sdata_fd, u64 offs
return CELL_OK;
}
std::mutex g_fs_aio_mutex;
using fs_aio_cb_t = vm::ptr<void(vm::ptr<CellFsAio> xaio, s32 error, s32 xid, u64 size)>;
void fsAio(vm::ptr<CellFsAio> aio, bool write, s32 xid, fs_aio_cb_t func)
{
std::lock_guard<std::mutex> lock(g_fs_aio_mutex);
cellFs.Notice("FS AIO Request(%d): fd=0x%x, offset=0x%llx, buf=*0x%x, size=0x%llx, user_data=0x%llx", xid, aio->fd, aio->offset, aio->buf, aio->size, aio->user_data);
s32 error = CELL_OK;
@ -655,6 +883,8 @@ void fsAio(vm::ptr<CellFsAio> aio, bool write, s32 xid, fs_aio_cb_t func)
}
else
{
std::lock_guard<std::mutex> lock(file->mutex);
const auto old_position = file->file->Tell();
file->file->Seek(aio->offset);
@ -704,7 +934,9 @@ s32 cellFsAioRead(vm::ptr<CellFsAio> aio, vm::ptr<s32> id, fs_aio_cb_t func)
// TODO: detect mount point and send AIO request to the AIO thread of this mount point
thread_t("FS AIO Read Thread", std::bind(fsAio, aio, false, (*id = ++g_fs_aio_id), func)).detach();
const s32 xid = (*id = ++g_fs_aio_id);
thread_t("FS AIO Read Thread", std::bind(fsAio, aio, false, xid, func)).detach();
return CELL_OK;
}
@ -720,7 +952,9 @@ s32 cellFsAioWrite(vm::ptr<CellFsAio> aio, vm::ptr<s32> id, fs_aio_cb_t func)
// TODO: detect mount point and send AIO request to the AIO thread of this mount point
thread_t("FS AIO Write Thread", std::bind(fsAio, aio, true, (*id = ++g_fs_aio_id), func)).detach();
const s32 xid = (*id = ++g_fs_aio_id);
thread_t("FS AIO Write Thread", std::bind(fsAio, aio, true, xid, func)).detach();
return CELL_OK;
}
@ -746,8 +980,11 @@ s32 cellFsSetIoBufferFromDefaultContainer(u32 fd, u32 buffer_size, u32 page_type
cellFs.Todo("cellFsSetIoBufferFromDefaultContainer(fd=%d, buffer_size=%d, page_type=%d)", fd, buffer_size, page_type);
std::shared_ptr<fs_file_t> file;
if (!Emu.GetIdManager().GetIDData(fd, file))
return CELL_ESRCH;
{
CELL_FS_EBADF;
}
return CELL_OK;
}

View File

@ -1,5 +1,11 @@
#pragma once
struct CellFsDirectoryEntry
{
CellFsStat attribute;
CellFsDirent entry_name;
};
// CellFsRingBuffer.copy
enum : s32
{
@ -15,7 +21,7 @@ struct CellFsRingBuffer
be_t<s32> copy;
};
// cellFsSt(Read|Write)GetStatus status
// cellFsStReadGetStatus status
enum : u64
{
CELL_FS_ST_INITIALIZED = 0x0001,

View File

@ -45,7 +45,8 @@ int cellGifDecOpen(u32 mainHandle, vm::ptr<u32> subHandle, vm::ptr<CellGifDecSrc
case se32(CELL_GIFDEC_FILE):
{
// Get file descriptor and size
std::shared_ptr<fs_file_t> file(new fs_file_t(std::shared_ptr<vfsStream>(Emu.GetVFS().OpenFile(src->fileName.get_ptr(), vfsRead)), 0, 0));
std::shared_ptr<vfsStream> file_s(Emu.GetVFS().OpenFile(src->fileName.get_ptr(), vfsRead));
std::shared_ptr<fs_file_t> file(new fs_file_t(file_s, 0, 0));
if (!file) return CELL_GIFDEC_ERROR_OPEN_FILE;
current_subHandle->fd = Emu.GetIdManager().GetNewID(file, TYPE_FS_FILE);
current_subHandle->fileSize = file->file->GetSize();

View File

@ -51,7 +51,8 @@ int cellJpgDecOpen(u32 mainHandle, vm::ptr<u32> subHandle, vm::ptr<CellJpgDecSrc
case se32(CELL_JPGDEC_FILE):
{
// Get file descriptor and size
std::shared_ptr<fs_file_t> file(new fs_file_t(std::shared_ptr<vfsStream>(Emu.GetVFS().OpenFile(src->fileName.get_ptr(), vfsRead)), 0, 0));
std::shared_ptr<vfsStream> file_s(Emu.GetVFS().OpenFile(src->fileName.get_ptr(), vfsRead));
std::shared_ptr<fs_file_t> file(new fs_file_t(file_s, 0, 0));
if (!file) return CELL_JPGDEC_ERROR_OPEN_FILE;
current_subHandle->fd = Emu.GetIdManager().GetNewID(file, TYPE_FS_FILE);
current_subHandle->fileSize = file->file->GetSize();

View File

@ -82,7 +82,8 @@ s32 pngDecOpen(
case se32(CELL_PNGDEC_FILE):
{
// Get file descriptor and size
std::shared_ptr<fs_file_t> file(new fs_file_t(std::shared_ptr<vfsStream>(Emu.GetVFS().OpenFile(src->fileName.get_ptr(), vfsRead)), 0, 0));
std::shared_ptr<vfsStream> file_s(Emu.GetVFS().OpenFile(src->fileName.get_ptr(), vfsRead));
std::shared_ptr<fs_file_t> file(new fs_file_t(file_s, 0, 0));
if (!file) return CELL_PNGDEC_ERROR_OPEN_FILE;
stream->fd = Emu.GetIdManager().GetNewID(file, TYPE_FS_FILE);
stream->fileSize = file->file->GetSize();

View File

@ -504,7 +504,7 @@ s32 sys_net_free_thread_context()
}
// define additional macro for specific namespace
#define REG_FUNC_(name) add_ppu_func(ModuleFunc(get_function_id(#name), 0, &sys_net, bind_func(sys_net_func::name)))
#define REG_FUNC_(name) add_ppu_func(ModuleFunc(get_function_id(#name), 0, &sys_net, #name, bind_func(sys_net_func::name)))
Module sys_net("sys_net", []()
{

View File

@ -1,7 +1,7 @@
#pragma once
#include "Emu/Cell/PPUThread.h"
typedef void(*ppu_func_caller)(PPUThread&);
using ppu_func_caller = void(*)(PPUThread&);
namespace ppu_func_detail
{
@ -181,7 +181,7 @@ namespace ppu_func_detail
template<typename... T>
struct func_binder<void, PPUThread&, T...>
{
typedef void(*func_t)(PPUThread&, T...);
using func_t = void(*)(PPUThread&, T...);
static void do_call(PPUThread& CPU, func_t func)
{
@ -192,7 +192,7 @@ namespace ppu_func_detail
template<typename... T>
struct func_binder<void, T...>
{
typedef void(*func_t)(T...);
using func_t = void(*)(T...);
static void do_call(PPUThread& CPU, func_t func)
{
@ -203,7 +203,7 @@ namespace ppu_func_detail
template<typename RT, typename... T>
struct func_binder<RT, PPUThread&, T...>
{
typedef RT(*func_t)(PPUThread&, T...);
using func_t = RT(*)(PPUThread&, T...);
static void do_call(PPUThread& CPU, func_t func)
{
@ -214,7 +214,7 @@ namespace ppu_func_detail
template<typename RT, typename... T>
struct func_binder
{
typedef RT(*func_t)(T...);
using func_t = RT(*)(T...);
static void do_call(PPUThread& CPU, func_t func)
{

View File

@ -36,8 +36,6 @@
void null_func(PPUThread& CPU);
const int kSyscallTableLength = 1024;
// UNS = Unused
// ROOT = Root
// DBG = Debug
@ -695,7 +693,7 @@ const ppu_func_caller sc_table[1024] =
null_func, null_func, null_func, null_func, null_func, //794 UNS
null_func, null_func, null_func, null_func, null_func, //799 UNS
null_func,//bind_func(sys_fs_test), //800 (0x320)
bind_func(sys_fs_test), //800 (0x320)
bind_func(sys_fs_open), //801 (0x321)
bind_func(sys_fs_read), //802 (0x322)
bind_func(sys_fs_write), //803 (0x323)
@ -712,7 +710,7 @@ const ppu_func_caller sc_table[1024] =
bind_func(sys_fs_unlink), //814 (0x32E)
null_func,//bind_func(sys_fs_utime), //815 (0x32F)
null_func,//bind_func(sys_fs_access), //816 (0x330)
null_func,//bind_func(sys_fs_fcntl), //817 (0x331)
bind_func(sys_fs_fcntl), //817 (0x331)
bind_func(sys_fs_lseek), //818 (0x332)
null_func,//bind_func(sys_fs_fdatasync), //819 (0x333)
null_func,//bind_func(sys_fs_fsync), //820 (0x334)
@ -890,30 +888,7 @@ const ppu_func_caller sc_table[1024] =
void null_func(PPUThread& CPU)
{
u32 code = (u32)CPU.GPR[11];
//TODO: remove this
switch(code)
{
//tty
case 988:
LOG_WARNING(HLE, "SysCall 988! r3: 0x%llx, r4: 0x%llx, pc: 0x%x",
CPU.GPR[3], CPU.GPR[4], CPU.PC);
CPU.GPR[3] = 0;
return;
case 999:
dump_enable = !dump_enable;
Emu.Pause();
LOG_WARNING(HLE, "Dump %s", (dump_enable ? "enabled" : "disabled"));
return;
case 1000:
Ini.HLELogging.SetValue(!Ini.HLELogging.GetValue());
LOG_WARNING(HLE, "Log %s", (Ini.HLELogging.GetValue() ? "enabled" : "disabled"));
return;
}
LOG_ERROR(HLE, "Unknown syscall: %d - %08x -> CELL_OK", code, code);
LOG_ERROR(HLE, "Unimplemented syscall %lld: %s -> CELL_OK", CPU.GPR[11], SysCalls::GetFuncName(CPU.GPR[11]));
CPU.GPR[3] = 0;
return;
}
@ -933,14 +908,14 @@ void SysCalls::DoSyscall(PPUThread& CPU, u64 code)
if (Ini.HLELogging.GetValue())
{
LOG_NOTICE(PPU, "SysCall called: %s [0x%llx]", "unknown", code);
LOG_NOTICE(PPU, "Syscall %d called: %s", code, SysCalls::GetFuncName(code));
}
sc_table[code](CPU);
if (Ini.HLELogging.GetValue())
{
LOG_NOTICE(PPU, "SysCall finished: %s [0x%llx] -> 0x%llx", "unknown", code, CPU.GPR[3]);
LOG_NOTICE(PPU, "Syscall %d finished: %s -> 0x%llx", code, SysCalls::GetFuncName(code), CPU.GPR[3]);
}
CPU.m_last_syscall = old_last_syscall;

View File

@ -2,8 +2,6 @@
#include "ErrorCodes.h"
#include "LogBase.h"
//#define SYSCALLS_DEBUG
class SysCallBase : public LogBase
{
private:
@ -21,13 +19,11 @@ public:
}
};
extern bool dump_enable;
class PPUThread;
class SysCalls
{
public:
static void DoSyscall(PPUThread& CPU, u64 code);
static std::string GetHLEFuncName(const u32 fid);
static std::string GetFuncName(const u64 fid);
};

View File

@ -20,6 +20,13 @@
SysCallBase sys_fs("sys_fs");
s32 sys_fs_test(u32 arg1, u32 arg2, vm::ptr<u32> arg3, u32 arg4, vm::ptr<char> arg5, u32 arg6)
{
sys_fs.Todo("sys_fs_test(arg1=0x%x, arg2=0x%x, arg3=*0x%x, arg4=0x%x, arg5=*0x%x, arg6=0x%x) -> CELL_OK", arg1, arg2, arg3, arg4, arg5, arg6);
return CELL_OK;
}
s32 sys_fs_open(vm::ptr<const char> path, s32 flags, vm::ptr<u32> fd, s32 mode, vm::ptr<const void> arg, u64 size)
{
sys_fs.Warning("sys_fs_open(path=*0x%x, flags=%#o, fd=*0x%x, mode=%#o, arg=*0x%x, size=0x%llx)", path, flags, fd, mode, arg, size);
@ -135,6 +142,8 @@ s32 sys_fs_read(u32 fd, vm::ptr<void> buf, u64 nbytes, vm::ptr<u64> nread)
return CELL_FS_EBADF;
}
std::lock_guard<std::mutex> lock(file->mutex);
*nread = file->file->Read(buf.get_ptr(), nbytes);
return CELL_OK;
@ -151,7 +160,9 @@ s32 sys_fs_write(u32 fd, vm::ptr<const void> buf, u64 nbytes, vm::ptr<u64> nwrit
return CELL_FS_EBADF;
}
// TODO: return CELL_FS_EBUSY if locked
// TODO: return CELL_FS_EBUSY if locked by stream
std::lock_guard<std::mutex> lock(file->mutex);
*nwrite = file->file->Write(buf.get_ptr(), nbytes);
@ -202,7 +213,7 @@ s32 sys_fs_readdir(u32 fd, vm::ptr<CellFsDirent> dir, vm::ptr<u64> nread)
if (!Emu.GetIdManager().GetIDData(fd, directory))
{
return CELL_ESRCH;
return CELL_FS_EBADF;
}
const DirEntryInfo* info = directory->Read();
@ -230,7 +241,7 @@ s32 sys_fs_closedir(u32 fd)
if (!Emu.GetIdManager().GetIDData(fd, directory))
{
return CELL_ESRCH;
return CELL_FS_EBADF;
}
Emu.GetIdManager().RemoveID<vfsDirBase>(fd);
@ -318,7 +329,7 @@ s32 sys_fs_stat(vm::ptr<const char> path, vm::ptr<CellFsStat> sb)
sys_fs.Error("sys_fs_stat(): size is the same (0x%x)", size);
sys_fs.Warning("sys_fs_stat(): '%s' not found", path.get_ptr());
return CELL_ENOENT;
return CELL_FS_ENOENT;
}
s32 sys_fs_fstat(u32 fd, vm::ptr<CellFsStat> sb)
@ -326,8 +337,11 @@ s32 sys_fs_fstat(u32 fd, vm::ptr<CellFsStat> sb)
sys_fs.Warning("sys_fs_fstat(fd=0x%x, sb=*0x%x)", fd, sb);
std::shared_ptr<fs_file_t> file;
if (!Emu.GetIdManager().GetIDData(fd, file))
return CELL_ESRCH;
{
return CELL_FS_EBADF;
}
sb->mode =
CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR |
@ -353,11 +367,15 @@ s32 sys_fs_mkdir(vm::ptr<const char> path, s32 mode)
const std::string _path = path.get_ptr();
if (vfsDir().IsExists(_path))
return CELL_EEXIST;
if (Emu.GetVFS().ExistsDir(_path))
{
return CELL_FS_EEXIST;
}
if (!Emu.GetVFS().CreateDir(_path))
return CELL_EBUSY;
{
return CELL_FS_EIO; // ???
}
sys_fs.Notice("sys_fs_mkdir(): directory '%s' created", path.get_ptr());
return CELL_OK;
@ -372,32 +390,29 @@ s32 sys_fs_rename(vm::ptr<const char> from, vm::ptr<const char> to)
std::string _from = from.get_ptr();
std::string _to = to.get_ptr();
if (Emu.GetVFS().ExistsDir(_from))
{
vfsDir dir;
if (dir.IsExists(_from))
if (!Emu.GetVFS().RenameDir(_from, _to))
{
if (!dir.Rename(_from, _to))
return CELL_EBUSY;
sys_fs.Notice("sys_fs_rename(): directory '%s' renamed to '%s'", from.get_ptr(), to.get_ptr());
return CELL_OK;
return CELL_FS_EIO; // ???
}
sys_fs.Notice("sys_fs_rename(): directory '%s' renamed to '%s'", from.get_ptr(), to.get_ptr());
return CELL_OK;
}
if (Emu.GetVFS().ExistsFile(_from))
{
vfsFile f;
if (f.Exists(_from))
if (!Emu.GetVFS().RenameFile(_from, _to))
{
if (!f.Rename(_from, _to))
return CELL_EBUSY;
sys_fs.Notice("sys_fs_rename(): file '%s' renamed to '%s'", from.get_ptr(), to.get_ptr());
return CELL_OK;
return CELL_FS_EIO; // ???
}
sys_fs.Notice("sys_fs_rename(): file '%s' renamed to '%s'", from.get_ptr(), to.get_ptr());
return CELL_OK;
}
return CELL_ENOENT;
return CELL_FS_ENOENT;
}
s32 sys_fs_rmdir(vm::ptr<const char> path)
@ -407,12 +422,15 @@ s32 sys_fs_rmdir(vm::ptr<const char> path)
std::string _path = path.get_ptr();
vfsDir d;
if (!d.IsExists(_path))
return CELL_ENOENT;
if (!Emu.GetVFS().RemoveDir(_path))
{
if (Emu.GetVFS().ExistsDir(_path))
{
return CELL_FS_EIO; // ???
}
if (!d.Remove(_path))
return CELL_EBUSY;
return CELL_FS_ENOENT;
}
sys_fs.Notice("sys_fs_rmdir(): directory '%s' removed", path.get_ptr());
return CELL_OK;
@ -425,24 +443,33 @@ s32 sys_fs_unlink(vm::ptr<const char> path)
std::string _path = path.get_ptr();
if (vfsDir().IsExists(_path))
return CELL_EISDIR;
if (!Emu.GetVFS().ExistsFile(_path))
return CELL_ENOENT;
if (!Emu.GetVFS().RemoveFile(_path))
return CELL_EACCES;
{
if (Emu.GetVFS().ExistsFile(_path))
{
return CELL_FS_EIO; // ???
}
return CELL_FS_ENOENT;
}
sys_fs.Notice("sys_fs_unlink(): file '%s' deleted", path.get_ptr());
return CELL_OK;
}
s32 sys_fs_fcntl(u32 fd, s32 flags, u32 addr, u32 arg4, u32 arg5, u32 arg6)
{
sys_fs.Todo("sys_fs_fcntl(fd=0x%x, flags=0x%x, addr=*0x%x, arg4=0x%x, arg5=0x%x, arg6=0x%x) -> CELL_OK", fd, flags, addr, arg4, arg5, arg6);
return CELL_OK;
}
s32 sys_fs_lseek(u32 fd, s64 offset, s32 whence, vm::ptr<u64> pos)
{
sys_fs.Log("sys_fs_lseek(fd=0x%x, offset=0x%llx, whence=0x%x, pos=*0x%x)", fd, offset, whence, pos);
vfsSeekMode seek_mode;
switch (whence)
{
case CELL_FS_SEEK_SET: seek_mode = vfsSeekSet; break;
@ -450,14 +477,20 @@ s32 sys_fs_lseek(u32 fd, s64 offset, s32 whence, vm::ptr<u64> pos)
case CELL_FS_SEEK_END: seek_mode = vfsSeekEnd; break;
default:
sys_fs.Error("sys_fs_lseek(fd=0x%x): unknown seek whence (0x%x)", fd, whence);
return CELL_EINVAL;
return CELL_FS_EINVAL;
}
std::shared_ptr<fs_file_t> file;
if (!Emu.GetIdManager().GetIDData(fd, file))
return CELL_ESRCH;
{
return CELL_FS_EBADF;
}
std::lock_guard<std::mutex> lock(file->mutex);
*pos = file->file->Seek(offset, seek_mode);
return CELL_OK;
}
@ -466,8 +499,11 @@ s32 sys_fs_fget_block_size(u32 fd, vm::ptr<u64> sector_size, vm::ptr<u64> block_
sys_fs.Todo("sys_fs_fget_block_size(fd=%d, sector_size=*0x%x, block_size=*0x%x, arg4=*0x%x, arg5=*0x%x)", fd, sector_size, block_size, arg4, arg5);
std::shared_ptr<fs_file_t> file;
if (!Emu.GetIdManager().GetIDData(fd, file))
return CELL_ESRCH;
{
CELL_FS_EBADF;
}
*sector_size = 4096; // ?
*block_size = 4096; // ?
@ -495,8 +531,9 @@ s32 sys_fs_truncate(vm::ptr<const char> path, u64 size)
if (!f.IsOpened())
{
sys_fs.Warning("sys_fs_truncate(): '%s' not found", path.get_ptr());
return CELL_ENOENT;
return CELL_FS_ENOENT;
}
u64 initialSize = f.GetSize();
if (initialSize < size)
@ -522,8 +559,11 @@ s32 sys_fs_ftruncate(u32 fd, u64 size)
sys_fs.Warning("sys_fs_ftruncate(fd=0x%x, size=0x%llx)", fd, size);
std::shared_ptr<fs_file_t> file;
if (!Emu.GetIdManager().GetIDData(fd, file))
return CELL_ESRCH;
{
CELL_FS_EBADF;
}
u64 initialSize = file->file->GetSize();

View File

@ -1,4 +1,5 @@
#pragma once
#include "Utilities/Thread.h"
#pragma pack(push, 4)
@ -144,21 +145,60 @@ struct CellFsUtimbuf
#pragma pack(pop)
// Stream Support Status (st_status)
enum : u32
{
SSS_NOT_INITIALIZED = 0,
SSS_INITIALIZED,
SSS_STARTED,
SSS_STOPPED,
};
using fs_st_cb_t = vm::ptr<void(u32 xfd, u64 xsize)>;
struct fs_st_cb_rec_t
{
u32 size;
fs_st_cb_t func;
};
struct fs_file_t
{
const std::shared_ptr<vfsStream> file;
const s32 mode;
const s32 flags;
std::mutex mutex;
std::condition_variable cv;
atomic_le_t<u32> st_status;
u64 st_ringbuf_size;
u64 st_block_size;
u64 st_trans_rate;
bool st_copyless;
thread_t st_thread;
u32 st_buffer;
u64 st_read_size;
std::atomic<u64> st_total_read;
std::atomic<u64> st_copied;
atomic_le_t<fs_st_cb_rec_t> st_callback;
fs_file_t(std::shared_ptr<vfsStream>& file, s32 mode, s32 flags)
: file(file)
, mode(mode)
, flags(flags)
, st_status({ SSS_NOT_INITIALIZED })
, st_callback({})
{
}
};
// SysCalls
s32 sys_fs_test(u32 arg1, u32 arg2, vm::ptr<u32> arg3, u32 arg4, vm::ptr<char> arg5, u32 arg6);
s32 sys_fs_open(vm::ptr<const char> path, s32 flags, vm::ptr<u32> fd, s32 mode, vm::ptr<const void> arg, u64 size);
s32 sys_fs_read(u32 fd, vm::ptr<void> buf, u64 nbytes, vm::ptr<u64> nread);
s32 sys_fs_write(u32 fd, vm::ptr<const void> buf, u64 nbytes, vm::ptr<u64> nwrite);
@ -172,6 +212,7 @@ s32 sys_fs_mkdir(vm::ptr<const char> path, s32 mode);
s32 sys_fs_rename(vm::ptr<const char> from, vm::ptr<const char> to);
s32 sys_fs_rmdir(vm::ptr<const char> path);
s32 sys_fs_unlink(vm::ptr<const char> path);
s32 sys_fs_fcntl(u32 fd, s32 flags, u32 addr, u32 arg4, u32 arg5, u32 arg6);
s32 sys_fs_lseek(u32 fd, s64 offset, s32 whence, vm::ptr<u64> pos);
s32 sys_fs_fget_block_size(u32 fd, vm::ptr<u64> sector_size, vm::ptr<u64> block_size, vm::ptr<u64> arg4, vm::ptr<u64> arg5);
s32 sys_fs_get_block_size(vm::ptr<const char> path, vm::ptr<u64> sector_size, vm::ptr<u64> block_size, vm::ptr<u64> arg4);

View File

@ -167,8 +167,8 @@ namespace loader
module.exports[fnid] = fstub;
//LOG_NOTICE(LOADER, "Exported function '%s' in '%s' module (LLE)", SysCalls::GetHLEFuncName(fnid).c_str(), module_name.c_str());
LOG_WARNING(LOADER, "**** %s: [%s] -> 0x%x", modulename.c_str(), SysCalls::GetHLEFuncName(fnid).c_str(), (u32)fstub);
//LOG_NOTICE(LOADER, "Exported function '%s' in '%s' module (LLE)", SysCalls::GetFuncName(fnid).c_str(), module_name.c_str());
LOG_WARNING(LOADER, "**** %s: [%s] -> 0x%x", modulename.c_str(), SysCalls::GetFuncName(fnid).c_str(), (u32)fstub);
}
}
@ -204,7 +204,7 @@ namespace loader
module.imports[fnid] = fstub;
LOG_WARNING(LOADER, "**** %s: [%s] -> 0x%x", modulename.c_str(), SysCalls::GetHLEFuncName(fnid).c_str(), (u32)fstub);
LOG_WARNING(LOADER, "**** %s: [%s] -> 0x%x", modulename.c_str(), SysCalls::GetFuncName(fnid).c_str(), (u32)fstub);
}
}
}
@ -423,7 +423,7 @@ namespace loader
if (!func)
{
index = add_ppu_func(ModuleFunc(nid, 0, module, nullptr, vm::ptr<void()>::make(addr)));
index = add_ppu_func(ModuleFunc(nid, 0, module, nullptr, nullptr, vm::ptr<void()>::make(addr)));
}
else
{
@ -435,7 +435,7 @@ namespace loader
if (!vm::check_addr(addr, 8) || !vm::check_addr(i_addr = vm::read32(addr), 4))
{
LOG_ERROR(LOADER, "Failed to inject code for exported function '%s' (opd=0x%x, 0x%x)", SysCalls::GetHLEFuncName(nid), addr, i_addr);
LOG_ERROR(LOADER, "Failed to inject code for exported function '%s' (opd=0x%x, 0x%x)", SysCalls::GetFuncName(nid), addr, i_addr);
}
else
{
@ -456,18 +456,18 @@ namespace loader
if (!func)
{
LOG_ERROR(LOADER, "Unimplemented function '%s' (0x%x)", SysCalls::GetHLEFuncName(nid), addr);
LOG_ERROR(LOADER, "Unimplemented function '%s' (0x%x)", SysCalls::GetFuncName(nid), addr);
index = add_ppu_func(ModuleFunc(nid, 0, module, nullptr));
index = add_ppu_func(ModuleFunc(nid, 0, module, nullptr, nullptr));
}
else
{
LOG_NOTICE(LOADER, "Imported function '%s' (0x%x)", SysCalls::GetHLEFuncName(nid), addr);
LOG_NOTICE(LOADER, "Imported function '%s' (0x%x)", SysCalls::GetFuncName(nid), addr);
}
if (!patch_ppu_import(addr, index))
{
LOG_ERROR(LOADER, "Failed to inject code for function '%s' (0x%x)", SysCalls::GetHLEFuncName(nid), addr);
LOG_ERROR(LOADER, "Failed to inject code for function '%s' (0x%x)", SysCalls::GetFuncName(nid), addr);
}
}
}
@ -690,15 +690,15 @@ namespace loader
if (!func)
{
LOG_ERROR(LOADER, "Unimplemented function '%s' in '%s' module (0x%x)", SysCalls::GetHLEFuncName(nid), module_name, addr);
LOG_ERROR(LOADER, "Unimplemented function '%s' in '%s' module (0x%x)", SysCalls::GetFuncName(nid), module_name, addr);
index = add_ppu_func(ModuleFunc(nid, 0, module, nullptr));
index = add_ppu_func(ModuleFunc(nid, 0, module, nullptr, nullptr));
}
else
{
const bool is_lle = func->lle_func && !(func->flags & MFF_FORCED_HLE);
LOG_NOTICE(LOADER, "Imported %sfunction '%s' in '%s' module (0x%x)", is_lle ? "LLE " : "", SysCalls::GetHLEFuncName(nid), module_name, addr);
LOG_NOTICE(LOADER, "Imported %sfunction '%s' in '%s' module (0x%x)", is_lle ? "LLE " : "", SysCalls::GetFuncName(nid), module_name, addr);
}
if (!patch_ppu_import(addr, index))