Small fixes

This commit is contained in:
Nekotekina 2014-06-25 02:16:44 +04:00
parent 336442eeba
commit 2200e6f4d9
5 changed files with 110 additions and 55 deletions

View file

@ -1,29 +1,38 @@
#include "stdafx.h" #include "stdafx.h"
#include "Utilities/SSemaphore.h" #include "Utilities/SSemaphore.h"
bool SSemaphore::wait(u64 timeout) void SSemaphore::wait()
{ {
std::unique_lock<std::mutex> lock(m_cv_mutex); u32 order;
{
std::lock_guard<std::mutex> lock(m_mutex);
order = m_in_order++;
}
std::unique_lock<std::mutex> cv_lock(m_cv_mutex);
u64 counter = 0;
while (true) while (true)
{ {
if (Emu.IsStopped()) if (Emu.IsStopped())
{ {
return false; return;
} }
if (timeout && counter >= timeout)
{ m_cond.wait_for(cv_lock, std::chrono::milliseconds(1));
return false;
}
m_cond.wait_for(lock, std::chrono::milliseconds(1));
counter++;
std::lock_guard<std::mutex> lock(m_mutex); std::lock_guard<std::mutex> lock(m_mutex);
if (m_count) if (m_count)
{
if (m_out_order == order)
{ {
m_count--; m_count--;
return true; m_out_order++;
return;
}
else
{
m_cond.notify_one();
}
} }
} }
} }
@ -32,7 +41,8 @@ bool SSemaphore::try_wait()
{ {
std::lock_guard<std::mutex> lock(m_mutex); std::lock_guard<std::mutex> lock(m_mutex);
if (m_count) // TODO: ordering?
if (m_count && m_in_order == m_out_order)
{ {
m_count--; m_count--;
return true; return true;

View file

@ -4,6 +4,8 @@ class SSemaphore
{ {
const u32 m_max; const u32 m_max;
u32 m_count; u32 m_count;
u32 m_in_order;
u32 m_out_order;
std::mutex m_mutex, m_cv_mutex; std::mutex m_mutex, m_cv_mutex;
std::condition_variable m_cond; std::condition_variable m_cond;
@ -11,12 +13,16 @@ public:
SSemaphore(u32 value, u32 max = 1) SSemaphore(u32 value, u32 max = 1)
: m_max(max > 0 ? max : 0xffffffff) : m_max(max > 0 ? max : 0xffffffff)
, m_count(value > m_max ? m_max : value) , m_count(value > m_max ? m_max : value)
, m_in_order(0)
, m_out_order(0)
{ {
} }
SSemaphore() SSemaphore()
: m_max(0xffffffff) : m_max(0xffffffff)
, m_count(0) , m_count(0)
, m_in_order(0)
, m_out_order(0)
{ {
} }
@ -24,7 +30,7 @@ public:
{ {
} }
bool wait(u64 timeout = 0); void wait();
bool try_wait(); bool try_wait();

View file

@ -2,36 +2,6 @@
#include "SPUThread.h" #include "SPUThread.h"
#include "Emu/event.h" #include "Emu/event.h"
enum
{
MFC_LSA_offs = 0x3004,
MFC_EAH_offs = 0x3008,
MFC_EAL_offs = 0x300C,
MFC_Size_Tag_offs = 0x3010,
MFC_Class_CMD_offs = 0x3014,
MFC_CMDStatus_offs = 0x3014,
MFC_QStatus_offs = 0x3104,
Prxy_QueryType_offs = 0x3204,
Prxy_QueryMask_offs = 0x321C,
Prxy_TagStatus_offs = 0x322C,
SPU_Out_MBox_offs = 0x4004,
SPU_In_MBox_offs = 0x400C,
SPU_MBox_Status_offs = 0x4014,
SPU_RunCntl_offs = 0x401C,
SPU_Status_offs = 0x4024,
SPU_NPC_offs = 0x4034,
SPU_RdSigNotify1_offs = 0x1400C,
SPU_RdSigNotify2_offs = 0x1C00C,
};
enum : u64
{
RAW_SPU_OFFSET = 0x0000000000100000,
RAW_SPU_BASE_ADDR = 0x00000000E0000000,
RAW_SPU_LS_OFFSET = 0x0000000000000000,
RAW_SPU_PROB_OFFSET = 0x0000000000040000,
};
__forceinline static u32 GetRawSPURegAddrByNum(int num, int offset) __forceinline static u32 GetRawSPURegAddrByNum(int num, int offset)
{ {
return RAW_SPU_OFFSET * num + RAW_SPU_BASE_ADDR + RAW_SPU_PROB_OFFSET + offset; return RAW_SPU_OFFSET * num + RAW_SPU_BASE_ADDR + RAW_SPU_PROB_OFFSET + offset;

View file

@ -129,6 +129,36 @@ enum : u32
SYS_SPU_THREAD_SNR2 = 0x05C00c, SYS_SPU_THREAD_SNR2 = 0x05C00c,
}; };
enum
{
MFC_LSA_offs = 0x3004,
MFC_EAH_offs = 0x3008,
MFC_EAL_offs = 0x300C,
MFC_Size_Tag_offs = 0x3010,
MFC_Class_CMD_offs = 0x3014,
MFC_CMDStatus_offs = 0x3014,
MFC_QStatus_offs = 0x3104,
Prxy_QueryType_offs = 0x3204,
Prxy_QueryMask_offs = 0x321C,
Prxy_TagStatus_offs = 0x322C,
SPU_Out_MBox_offs = 0x4004,
SPU_In_MBox_offs = 0x400C,
SPU_MBox_Status_offs = 0x4014,
SPU_RunCntl_offs = 0x401C,
SPU_Status_offs = 0x4024,
SPU_NPC_offs = 0x4034,
SPU_RdSigNotify1_offs = 0x1400C,
SPU_RdSigNotify2_offs = 0x1C00C,
};
enum : u64
{
RAW_SPU_OFFSET = 0x0000000000100000,
RAW_SPU_BASE_ADDR = 0x00000000E0000000,
RAW_SPU_LS_OFFSET = 0x0000000000000000,
RAW_SPU_PROB_OFFSET = 0x0000000000040000,
};
//Floating point status and control register. Unsure if this is one of the GPRs or SPRs //Floating point status and control register. Unsure if this is one of the GPRs or SPRs
//Is 128 bits, but bits 0-19, 24-28, 32-49, 56-60, 64-81, 88-92, 96-115, 120-124 are unused //Is 128 bits, but bits 0-19, 24-28, 32-49, 56-60, 64-81, 88-92, 96-115, 120-124 are unused
class FPSCR class FPSCR
@ -598,6 +628,29 @@ public:
return false; return false;
} }
} }
else if (ea >= RAW_SPU_BASE_ADDR && size == 4)
{
switch (cmd & ~(MFC_BARRIER_MASK | MFC_FENCE_MASK | MFC_LIST_MASK | MFC_RESULT_MASK))
{
case MFC_PUT_CMD:
{
Memory.Write32(ea, ReadLS32(lsa));
return true;
}
case MFC_GET_CMD:
{
WriteLS32(lsa, Memory.Read32(ea));
return true;
}
default:
{
ConLog.Error("DMAC::ProcessCmd(): Unknown DMA cmd.");
return false;
}
}
}
//Sleep(1); // hack //Sleep(1); // hack
@ -605,18 +658,34 @@ public:
{ {
case MFC_PUT_CMD: case MFC_PUT_CMD:
{ {
return Memory.Copy(ea, dmac.ls_offset + lsa, size); if (Memory.Copy(ea, dmac.ls_offset + lsa, size))
{
return true;
}
else
{
ConLog.Error("DMAC::ProcessCmd(): PUT* cmd failed (ea=0x%llx, lsa=0x%x, size=%d)", ea, lsa, size);
return false; // TODO: page fault (?)
}
} }
case MFC_GET_CMD: case MFC_GET_CMD:
{ {
return Memory.Copy(dmac.ls_offset + lsa, ea, size); if (Memory.Copy(dmac.ls_offset + lsa, ea, size))
{
return true;
}
else
{
ConLog.Error("DMAC::ProcessCmd(): GET* cmd failed (ea=0x%llx, lsa=0x%x, size=%d)", ea, lsa, size);
return false; // TODO: page fault (?)
}
} }
default: default:
{ {
ConLog.Error("DMAC::ProcessCmd(): Unknown DMA cmd."); ConLog.Error("DMAC::ProcessCmd(): Unknown DMA cmd.");
return false; return false; // ???
} }
} }
} }

View file

@ -13,7 +13,7 @@ static SysCallBase sc_int("sys_interrupt");
int sys_interrupt_tag_destroy(u32 intrtag) int sys_interrupt_tag_destroy(u32 intrtag)
{ {
sc_int.Error("sys_interrupt_tag_destroy(intrtag=%d)", intrtag); sc_int.Warning("sys_interrupt_tag_destroy(intrtag=%d)", intrtag);
u32 id = intrtag & 0xff; u32 id = intrtag & 0xff;
u32 class_id = intrtag >> 8; u32 class_id = intrtag >> 8;
@ -40,7 +40,7 @@ int sys_interrupt_tag_destroy(u32 intrtag)
int sys_interrupt_thread_establish(mem32_t ih, u32 intrtag, u64 intrthread, u64 arg) int sys_interrupt_thread_establish(mem32_t ih, u32 intrtag, u64 intrthread, u64 arg)
{ {
sc_int.Error("sys_interrupt_thread_establish(ih_addr=0x%x, intrtag=%d, intrthread=%lld, arg=0x%llx)", ih.GetAddr(), intrtag, intrthread, arg); sc_int.Warning("sys_interrupt_thread_establish(ih_addr=0x%x, intrtag=%d, intrthread=%lld, arg=0x%llx)", ih.GetAddr(), intrtag, intrthread, arg);
if (!ih.IsGood()) if (!ih.IsGood())
{ {