spu_printf fixed

This commit is contained in:
Nekotekina 2014-07-13 22:55:14 +04:00
parent 7370c49ff3
commit 2eafb235ba
7 changed files with 106 additions and 56 deletions

View File

@ -285,7 +285,7 @@ void CPUThread::ExecOnce()
void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp) void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp)
{ {
const u64 addr = (u64)pExp->ExceptionRecord->ExceptionInformation[1] - (u64)Memory.GetBaseAddr(); 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 // TODO: allow recovering from a page fault
//GetCurrentPPUThread().Stop(); //GetCurrentPPUThread().Stop();
@ -317,6 +317,8 @@ void CPUThread::Task()
} }
} }
std::vector<u64> trace;
#ifdef _WIN32 #ifdef _WIN32
_set_se_translator(_se_translator); _set_se_translator(_se_translator);
#else #else
@ -339,6 +341,7 @@ void CPUThread::Task()
} }
Step(); Step();
//if (PC - 0x13ED4 < 0x288) trace.push_back(PC);
NextPc(m_dec->DecodeMemory(PC + m_offset)); NextPc(m_dec->DecodeMemory(PC + m_offset));
if (status == CPUThread_Step) 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()); if (Ini.HLELogging.GetValue()) LOG_NOTICE(PPU, "%s leave", CPUThread::GetFName().c_str());
} }

View File

@ -56,36 +56,36 @@ public:
MemoryBlock* RawSPUMem[(0x100000000 - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]; MemoryBlock* RawSPUMem[(0x100000000 - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET];
VirtualMemoryBlock RSXIOMem; VirtualMemoryBlock RSXIOMem;
struct Reader32LE struct Wrapper32LE
{ {
private: private:
void* m_base_addr; void* m_base_addr;
public: 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 Write8(const u32 addr, const u8 data) { *(u8*)((u8*)m_base_addr + addr) = data; }
void Write16(const u32 addr, const u16 data) { *(u16*)((u64)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*)((u64)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*)((u64)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*)((u64)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); } u8 Read8(const u32 addr) { return *(u8*)((u8*)m_base_addr + addr); }
u16 Read16(const u32 addr) { return *(u16*)((u64)m_base_addr + addr); } u16 Read16(const u32 addr) { return *(u16*)((u8*)m_base_addr + addr); }
u32 Read32(const u32 addr) { return *(u32*)((u64)m_base_addr + addr); } u32 Read32(const u32 addr) { return *(u32*)((u8*)m_base_addr + addr); }
u64 Read64(const u32 addr) { return *(u64*)((u64)m_base_addr + addr); } u64 Read64(const u32 addr) { return *(u64*)((u8*)m_base_addr + addr); }
u128 Read128(const u32 addr) { return *(u128*)((u64)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; } void Init(void* real_addr) { m_base_addr = real_addr; }
}; };
struct : Reader32LE struct : Wrapper32LE
{ {
DynamicMemoryBlockLE RAM; DynamicMemoryBlockLE RAM;
DynamicMemoryBlockLE Userspace; DynamicMemoryBlockLE Userspace;
} PSV; } PSV;
struct : Reader32LE struct : Wrapper32LE
{ {
DynamicMemoryBlockLE Scratchpad; DynamicMemoryBlockLE Scratchpad;
DynamicMemoryBlockLE VRAM; DynamicMemoryBlockLE VRAM;

View File

@ -205,20 +205,19 @@ s32 sys_ppu_thread_create(mem64_t thread_id, u32 entry, u64 arg, s32 prio, u32 s
return CELL_OK; return CELL_OK;
} }
void sys_ppu_thread_once(u32 once_ctrl_addr, u32 entry) void sys_ppu_thread_once(mem_ptr_t<std::atomic<be_t<u32>>> 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<u32> 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); CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU);
new_thread.SetEntry(entry); new_thread.SetEntry(entry);
new_thread.Run(); new_thread.Run();
new_thread.Exec(); new_thread.Exec();
//GetCurrentPPUThread().Wait(new_thread); while (new_thread.IsAlive()) SM_Sleep();
} }
} }

View File

@ -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_stop(u64 thread_id);
s32 sys_ppu_thread_restart(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); 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<std::atomic<be_t<u32>>> once_ctrl, u32 entry);
s32 sys_ppu_thread_get_id(const u32 id_addr); s32 sys_ppu_thread_get_id(const u32 id_addr);

View File

@ -597,7 +597,7 @@ s32 sys_spu_thread_connect_event(u32 id, u32 eq_id, u32 et, u8 spup)
return CELL_EINVAL; return CELL_EINVAL;
} }
// TODO: check if can receive this events // TODO: check if can receive these events
SPUThread& spu = *(SPUThread*)thr; SPUThread& spu = *(SPUThread*)thr;
@ -706,13 +706,18 @@ s32 sys_spu_thread_unbind_queue(u32 id, u32 spuq_num)
return CELL_OK; 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)", 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, req, spup_addr); id, eq_id, req, spup.GetAddr());
EventQueue* equeue; if (!spup.IsGood())
if(!sys_event.CheckId(eq, equeue)) {
return CELL_EFAULT;
}
EventQueue* eq;
if (!Emu.GetIdManager().GetIDData(eq_id, eq))
{ {
return CELL_ESRCH; return CELL_ESRCH;
} }
@ -728,30 +733,56 @@ s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, u32
return CELL_ESRCH; return CELL_ESRCH;
} }
/* std::vector<SPUThread*> threads;
for(u32 i=0; i<group->list.size(); ++i) for (auto& v : group->list)
{ {
CPUThread* t; if (!v) continue;
if(t = Emu.GetCPU().GetThread(group->list[i])) CPUThread* thr = Emu.GetCPU().GetThread(v);
if (thr->GetType() != CPU_THREAD_SPU)
{ {
bool finded_port = false; sc_spu.Error("sys_spu_thread_group_connect_event_all_threads(): CELL_ESTAT (wrong thread type)");
for(int j=0; j<equeue->pos; ++j) return CELL_ESTAT;
{
if(!equeue->ports[j]->thread)
{
finded_port = true;
equeue->ports[j]->thread = t;
} }
threads.push_back((SPUThread*)thr);
} }
if(!finded_port) 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)
{
for (auto& t : threads)
{
eq->ports.add(&(t->SPUPs[i]));
t->SPUPs[i].eq = eq;
}
spup = (u8)i;
}
for (auto& t : threads) t->SPUPs[i].m_mutex.unlock();
}
else
{
found = false;
}
if (found) return CELL_OK;
}
return CELL_EISCONN; return CELL_EISCONN;
} }
}
}*/
return CELL_OK;
}
s32 sys_spu_thread_group_disconnect_event_all_threads(u32 id, u8 spup) s32 sys_spu_thread_group_disconnect_event_all_threads(u32 id, u8 spup)
{ {

View File

@ -64,6 +64,7 @@ struct SpuGroupInfo
int m_prio; int m_prio;
int m_type; int m_type;
int m_ct; int m_ct;
u32 m_count;
SpuGroupInfo(const std::string& name, u32 num, int prio, int type, u32 ct) SpuGroupInfo(const std::string& name, u32 num, int prio, int type, u32 ct)
: m_name(name) : m_name(name)
@ -71,13 +72,10 @@ struct SpuGroupInfo
, m_type(type) , m_type(type)
, m_ct(ct) , m_ct(ct)
, lock(0) , lock(0)
, m_count(num)
{ {
num = 256; list.resize(256);
list.resize(num); for (auto& v : list) v = 0;
for (u32 i = 0; i < num; i++)
{
list[i] = 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_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_connect_event(u32 id, u32 eq, u32 et);
s32 sys_spu_thread_group_disconnect_event(u32 id, 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_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_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); s32 sys_spu_thread_read_ls(u32 id, u32 address, mem64_t value, u32 type);

View File

@ -104,14 +104,31 @@ s32 sys_timer_disconnect_event_queue(u32 timer_id)
s32 sys_timer_sleep(u32 sleep_time) s32 sys_timer_sleep(u32 sleep_time)
{ {
sys_timer.Warning("sys_timer_sleep(sleep_time=%d)", 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; return CELL_OK;
} }
s32 sys_timer_usleep(u64 sleep_time) 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 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; return CELL_OK;
} }