From 2eafb235ba547b9fddaf916ed45d0882d1201f4b Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sun, 13 Jul 2014 22:55:14 +0400 Subject: [PATCH] spu_printf fixed --- rpcs3/Emu/CPU/CPUThread.cpp | 7 +- rpcs3/Emu/Memory/Memory.h | 28 ++++---- rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp | 11 ++-- rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h | 2 +- rpcs3/Emu/SysCalls/lv2/sys_spu.cpp | 79 ++++++++++++++++------- rpcs3/Emu/SysCalls/lv2/sys_spu.h | 12 ++-- rpcs3/Emu/SysCalls/lv2/sys_timer.cpp | 23 ++++++- 7 files changed, 106 insertions(+), 56 deletions(-) diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index 406721651a..577fcf9c5f 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -285,7 +285,7 @@ void CPUThread::ExecOnce() void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp) { const u64 addr = (u64)pExp->ExceptionRecord->ExceptionInformation[1] - (u64)Memory.GetBaseAddr(); - if (addr < 0x100000000 && u == EXCEPTION_ACCESS_VIOLATION) + if (u == EXCEPTION_ACCESS_VIOLATION && addr < 0x100000000) { // TODO: allow recovering from a page fault //GetCurrentPPUThread().Stop(); @@ -317,6 +317,8 @@ void CPUThread::Task() } } + std::vector trace; + #ifdef _WIN32 _set_se_translator(_se_translator); #else @@ -339,6 +341,7 @@ void CPUThread::Task() } Step(); + //if (PC - 0x13ED4 < 0x288) trace.push_back(PC); NextPc(m_dec->DecodeMemory(PC + m_offset)); if (status == CPUThread_Step) @@ -357,6 +360,8 @@ void CPUThread::Task() } } + for (auto& v : trace) LOG_NOTICE(PPU, "PC = 0x%llx", v); + if (Ini.HLELogging.GetValue()) LOG_NOTICE(PPU, "%s leave", CPUThread::GetFName().c_str()); } diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index b321ecb652..5f7681301b 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -56,36 +56,36 @@ public: MemoryBlock* RawSPUMem[(0x100000000 - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]; VirtualMemoryBlock RSXIOMem; - struct Reader32LE + struct Wrapper32LE { private: void* m_base_addr; public: - Reader32LE() : m_base_addr(nullptr) {} + Wrapper32LE() : m_base_addr(nullptr) {} - void Write8(const u32 addr, const u8 data) { *(u8*)((u64)m_base_addr + addr) = data; } - void Write16(const u32 addr, const u16 data) { *(u16*)((u64)m_base_addr + addr) = data; } - void Write32(const u32 addr, const u32 data) { *(u32*)((u64)m_base_addr + addr) = data; } - void Write64(const u32 addr, const u64 data) { *(u64*)((u64)m_base_addr + addr) = data; } - void Write128(const u32 addr, const u128 data) { *(u128*)((u64)m_base_addr + addr) = data; } + void Write8(const u32 addr, const u8 data) { *(u8*)((u8*)m_base_addr + addr) = data; } + void Write16(const u32 addr, const u16 data) { *(u16*)((u8*)m_base_addr + addr) = data; } + void Write32(const u32 addr, const u32 data) { *(u32*)((u8*)m_base_addr + addr) = data; } + void Write64(const u32 addr, const u64 data) { *(u64*)((u8*)m_base_addr + addr) = data; } + void Write128(const u32 addr, const u128 data) { *(u128*)((u8*)m_base_addr + addr) = data; } - u8 Read8(const u32 addr) { return *(u8*)((u64)m_base_addr + addr); } - u16 Read16(const u32 addr) { return *(u16*)((u64)m_base_addr + addr); } - u32 Read32(const u32 addr) { return *(u32*)((u64)m_base_addr + addr); } - u64 Read64(const u32 addr) { return *(u64*)((u64)m_base_addr + addr); } - u128 Read128(const u32 addr) { return *(u128*)((u64)m_base_addr + addr); } + u8 Read8(const u32 addr) { return *(u8*)((u8*)m_base_addr + addr); } + u16 Read16(const u32 addr) { return *(u16*)((u8*)m_base_addr + addr); } + u32 Read32(const u32 addr) { return *(u32*)((u8*)m_base_addr + addr); } + u64 Read64(const u32 addr) { return *(u64*)((u8*)m_base_addr + addr); } + u128 Read128(const u32 addr) { return *(u128*)((u8*)m_base_addr + addr); } void Init(void* real_addr) { m_base_addr = real_addr; } }; - struct : Reader32LE + struct : Wrapper32LE { DynamicMemoryBlockLE RAM; DynamicMemoryBlockLE Userspace; } PSV; - struct : Reader32LE + struct : Wrapper32LE { DynamicMemoryBlockLE Scratchpad; DynamicMemoryBlockLE VRAM; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp index f42444ee12..ad51e004a0 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp @@ -205,20 +205,19 @@ s32 sys_ppu_thread_create(mem64_t thread_id, u32 entry, u64 arg, s32 prio, u32 s return CELL_OK; } -void sys_ppu_thread_once(u32 once_ctrl_addr, u32 entry) +void sys_ppu_thread_once(mem_ptr_t>> once_ctrl, u32 entry) { - sysPrxForUser->Warning("sys_ppu_thread_once(once_ctrl_addr=0x%x, entry=0x%x)", once_ctrl_addr, entry); + sysPrxForUser->Warning("sys_ppu_thread_once(once_ctrl_addr=0x%x, entry=0x%x)", once_ctrl.GetAddr(), entry); - if(Memory.IsGoodAddr(once_ctrl_addr, 4) && Memory.Read32(once_ctrl_addr) == SYS_PPU_THREAD_ONCE_INIT) + be_t old = SYS_PPU_THREAD_ONCE_INIT; + if (once_ctrl->compare_exchange_weak(old, SYS_PPU_THREAD_DONE_INIT)) { - Memory.Write32(once_ctrl_addr, SYS_PPU_THREAD_DONE_INIT); - CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU); new_thread.SetEntry(entry); new_thread.Run(); new_thread.Exec(); - //GetCurrentPPUThread().Wait(new_thread); + while (new_thread.IsAlive()) SM_Sleep(); } } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h index 5256a9a5dc..ef99ca6012 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h @@ -24,5 +24,5 @@ s32 sys_ppu_thread_get_stack_information(u32 info_addr); s32 sys_ppu_thread_stop(u64 thread_id); s32 sys_ppu_thread_restart(u64 thread_id); s32 sys_ppu_thread_create(mem64_t thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, u32 threadname_addr); -void sys_ppu_thread_once(u32 once_ctrl_addr, u32 entry); +void sys_ppu_thread_once(mem_ptr_t>> once_ctrl, u32 entry); s32 sys_ppu_thread_get_id(const u32 id_addr); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp index b7dae66aec..4a88fb9c48 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp @@ -597,7 +597,7 @@ s32 sys_spu_thread_connect_event(u32 id, u32 eq_id, u32 et, u8 spup) return CELL_EINVAL; } - // TODO: check if can receive this events + // TODO: check if can receive these events SPUThread& spu = *(SPUThread*)thr; @@ -706,51 +706,82 @@ s32 sys_spu_thread_unbind_queue(u32 id, u32 spuq_num) return CELL_OK; } -s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, u32 spup_addr) +s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq_id, u64 req, mem8_t spup) { - sc_spu.Error("sys_spu_thread_group_connect_event_all_threads(id=%d, eq=%d, req=0x%llx, spup_addr=0x%x)", - id, eq, req, spup_addr); + sc_spu.Warning("sys_spu_thread_group_connect_event_all_threads(id=%d, eq_id=%d, req=0x%llx, spup_addr=0x%x)", + id, eq_id, req, spup.GetAddr()); - EventQueue* equeue; - if(!sys_event.CheckId(eq, equeue)) + if (!spup.IsGood()) + { + return CELL_EFAULT; + } + + EventQueue* eq; + if (!Emu.GetIdManager().GetIDData(eq_id, eq)) { return CELL_ESRCH; } - if(!req) + if (!req) { return CELL_EINVAL; } SpuGroupInfo* group; - if(!Emu.GetIdManager().GetIDData(id, group)) + if (!Emu.GetIdManager().GetIDData(id, group)) { return CELL_ESRCH; } - - /* - for(u32 i=0; ilist.size(); ++i) + + std::vector threads; + for (auto& v : group->list) { - CPUThread* t; - if(t = Emu.GetCPU().GetThread(group->list[i])) + if (!v) continue; + CPUThread* thr = Emu.GetCPU().GetThread(v); + if (thr->GetType() != CPU_THREAD_SPU) { - bool finded_port = false; - for(int j=0; jpos; ++j) + sc_spu.Error("sys_spu_thread_group_connect_event_all_threads(): CELL_ESTAT (wrong thread type)"); + return CELL_ESTAT; + } + threads.push_back((SPUThread*)thr); + } + + if (threads.size() != group->m_count) + { + sc_spu.Error("sys_spu_thread_group_connect_event_all_threads(): CELL_ESTAT (%d from %d)", (u32)threads.size(), group->m_count); + return CELL_ESTAT; + } + + for (u32 i = 0; i < 64; i++) // port number + { + bool found = true; + if (req & (1ull << i)) + { + for (auto& t : threads) t->SPUPs[i].m_mutex.lock(); + + for (auto& t : threads) if (t->SPUPs[i].eq) found = false; + + if (found) { - if(!equeue->ports[j]->thread) + for (auto& t : threads) { - finded_port = true; - equeue->ports[j]->thread = t; + eq->ports.add(&(t->SPUPs[i])); + t->SPUPs[i].eq = eq; } + spup = (u8)i; } - if(!finded_port) - { - return CELL_EISCONN; - } + for (auto& t : threads) t->SPUPs[i].m_mutex.unlock(); } - }*/ - return CELL_OK; + else + { + found = false; + } + + if (found) return CELL_OK; + } + + return CELL_EISCONN; } s32 sys_spu_thread_group_disconnect_event_all_threads(u32 id, u8 spup) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.h b/rpcs3/Emu/SysCalls/lv2/sys_spu.h index 72821054b3..3750f151a4 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.h @@ -64,6 +64,7 @@ struct SpuGroupInfo int m_prio; int m_type; int m_ct; + u32 m_count; SpuGroupInfo(const std::string& name, u32 num, int prio, int type, u32 ct) : m_name(name) @@ -71,13 +72,10 @@ struct SpuGroupInfo , m_type(type) , m_ct(ct) , lock(0) + , m_count(num) { - num = 256; - list.resize(num); - for (u32 i = 0; i < num; i++) - { - list[i] = 0; - } + list.resize(256); + for (auto& v : list) v = 0; } }; @@ -95,7 +93,7 @@ s32 sys_spu_thread_create(mem32_t thread_id, mem32_t entry, u64 arg, int prio, u s32 sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status); s32 sys_spu_thread_group_connect_event(u32 id, u32 eq, u32 et); s32 sys_spu_thread_group_disconnect_event(u32 id, u32 et); -s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, u32 spup_addr); +s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq_id, u64 req, mem8_t spup); s32 sys_spu_thread_group_disconnect_event_all_threads(u32 id, u8 spup); s32 sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type); s32 sys_spu_thread_read_ls(u32 id, u32 address, mem64_t value, u32 type); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp b/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp index 7ff925b368..87afef7d75 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp @@ -104,14 +104,31 @@ s32 sys_timer_disconnect_event_queue(u32 timer_id) s32 sys_timer_sleep(u32 sleep_time) { sys_timer.Warning("sys_timer_sleep(sleep_time=%d)", sleep_time); - std::this_thread::sleep_for(std::chrono::seconds(sleep_time)); + for (u32 i = 0; i < sleep_time; i++) + { + if (Emu.IsStopped()) + { + sys_timer.Warning("sys_timer_sleep(sleep_time=%d)", sleep_time); + return CELL_OK; + } + std::this_thread::sleep_for(std::chrono::seconds(1)); + } return CELL_OK; } s32 sys_timer_usleep(u64 sleep_time) { - sys_timer.Log("sys_timer_usleep(sleep_time=%lld)", sleep_time); + sys_timer.Warning("sys_timer_usleep(sleep_time=%lld)", sleep_time); if (sleep_time > 0xFFFFFFFFFFFF) sleep_time = 0xFFFFFFFFFFFF; //2^48-1 - std::this_thread::sleep_for(std::chrono::microseconds(sleep_time)); + for (u64 i = 0; i < sleep_time; i += 1000000) + { + if (Emu.IsStopped()) + { + sys_timer.Warning("sys_timer_usleep(sleep_time=%lld)", sleep_time); + return CELL_OK; + } + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + std::this_thread::sleep_for(std::chrono::microseconds(sleep_time % 1000000)); return CELL_OK; }