mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 10:42:36 +01:00
MBox, some improvements
Some changes reverted (warnings), multi-thread safety fixed, MBox MMIO modified
This commit is contained in:
parent
c9fc99c388
commit
ee137323aa
@ -163,14 +163,17 @@ struct DMAC
|
||||
return MFC_PPU_DMA_QUEUE_FULL;
|
||||
}
|
||||
|
||||
while (_InterlockedCompareExchange(&proxy_lock, 1, 0));
|
||||
while (_InterlockedExchange(&proxy_lock, 1));
|
||||
_mm_lfence();
|
||||
DMAC_Proxy& p = proxy[proxy_pos];
|
||||
p.cmd = cmd;
|
||||
p.tag = tag;
|
||||
p.lsa = lsa;
|
||||
p.ea = ea;
|
||||
p.size = size;
|
||||
_mm_sfence(); //for DoCmd()
|
||||
proxy_pos++;
|
||||
_mm_sfence();
|
||||
proxy_lock = 0;
|
||||
|
||||
return MFC_PPU_DMA_CMD_ENQUEUE_SUCCESSFUL;
|
||||
@ -178,8 +181,10 @@ struct DMAC
|
||||
|
||||
void ClearCmd()
|
||||
{
|
||||
while (_InterlockedCompareExchange(&proxy_lock, 1, 0));
|
||||
while (_InterlockedExchange(&proxy_lock, 1));
|
||||
_mm_lfence();
|
||||
memcpy(proxy, proxy + 1, --proxy_pos * sizeof(DMAC_Proxy));
|
||||
_mm_sfence();
|
||||
proxy_lock = 0; //release lock
|
||||
}
|
||||
|
||||
|
@ -62,11 +62,17 @@ bool RawSPUThread::Read32(const u64 addr, u32* value)
|
||||
case MFC_EAL_offs: ConLog.Warning("RawSPUThread[%d]: Read32(MFC_EAL)", m_index); *value = MFC2.EAL.GetValue(); break;
|
||||
case MFC_Size_Tag_offs: ConLog.Warning("RawSPUThread[%d]: Read32(MFC_Size_Tag)", m_index); *value = MFC2.Size_Tag.GetValue(); break;
|
||||
case MFC_CMDStatus_offs: ConLog.Warning("RawSPUThread[%d]: Read32(MFC_CMDStatus)", m_index); *value = MFC2.CMDStatus.GetValue(); break;
|
||||
case MFC_QStatus_offs: *value = MFC2.QStatus.GetValue(); break;
|
||||
case MFC_QStatus_offs:
|
||||
ConLog.Warning("RawSPUThread[%d]: Read32(MFC_QStatus)", m_index);
|
||||
*value = MFC2.QStatus.GetValue();
|
||||
break;
|
||||
case Prxy_QueryType_offs: ConLog.Warning("RawSPUThread[%d]: Read32(Prxy_QueryType)", m_index); *value = Prxy.QueryType.GetValue(); break;
|
||||
case Prxy_QueryMask_offs: ConLog.Warning("RawSPUThread[%d]: Read32(Prxy_QueryMask)", m_index); *value = Prxy.QueryMask.GetValue(); break;
|
||||
case Prxy_TagStatus_offs: ConLog.Warning("RawSPUThread[%d]: Read32(Prxy_TagStatus)", m_index); *value = Prxy.TagStatus.GetValue(); break;
|
||||
case SPU_Out_MBox_offs: ConLog.Warning("RawSPUThread[%d]: Read32(SPU_Out_MBox)", m_index); while(!SPU.Out_MBox.Pop(*value) && !Emu.IsStopped()) Sleep(1); break;
|
||||
case SPU_Out_MBox_offs:
|
||||
ConLog.Warning("RawSPUThread[%d]: Read32(SPU_Out_MBox)", m_index);
|
||||
SPU.Out_MBox.PopUncond(*value); //if Out_MBox is empty yet, the result will be undefined
|
||||
break;
|
||||
case SPU_In_MBox_offs: ConLog.Warning("RawSPUThread[%d]: Read32(SPU_In_MBox)", m_index); while(!SPU.In_MBox.Pop(*value) && !Emu.IsStopped()) Sleep(1); break;
|
||||
case SPU_MBox_Status_offs: //ConLog.Warning("RawSPUThread[%d]: Read32(SPU_MBox_Status)", m_index);
|
||||
//SPU.MBox_Status.SetValue(SPU.Out_MBox.GetCount() ? SPU.MBox_Status.GetValue() | 1 : SPU.MBox_Status.GetValue() & ~1);
|
||||
@ -183,7 +189,10 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value)
|
||||
case Prxy_QueryMask_offs: ConLog.Warning("RawSPUThread[%d]: Write32(Prxy_QueryMask, 0x%x)", m_index, value); Prxy.QueryMask.SetValue(value); break;
|
||||
case Prxy_TagStatus_offs: ConLog.Warning("RawSPUThread[%d]: Write32(Prxy_TagStatus, 0x%x)", m_index, value); Prxy.TagStatus.SetValue(value); break;
|
||||
case SPU_Out_MBox_offs: ConLog.Warning("RawSPUThread[%d]: Write32(SPU_Out_MBox, 0x%x)", m_index, value); while(!SPU.Out_MBox.Push(value) && !Emu.IsStopped()) Sleep(1); break;
|
||||
case SPU_In_MBox_offs: ConLog.Warning("RawSPUThread[%d]: Write32(SPU_In_MBox, 0x%x)", m_index, value); while(!SPU.In_MBox.Push(value) && !Emu.IsStopped()) Sleep(1); break;
|
||||
case SPU_In_MBox_offs:
|
||||
ConLog.Warning("RawSPUThread[%d]: Write32(SPU_In_MBox, 0x%x)", m_index, value);
|
||||
SPU.In_MBox.PushUncond(value); //if In_MBox is already full, the last message will be overwritten
|
||||
break;
|
||||
case SPU_MBox_Status_offs: ConLog.Warning("RawSPUThread[%d]: Write32(SPU_MBox_Status, 0x%x)", m_index, value); SPU.MBox_Status.SetValue(value); break;
|
||||
case SPU_RunCntl_offs: ConLog.Warning("RawSPUThread[%d]: Write32(SPU_RunCntl, 0x%x)", m_index, value); SPU.RunCntl.SetValue(value); break;
|
||||
case SPU_Status_offs: ConLog.Warning("RawSPUThread[%d]: Write32(SPU_Status, 0x%x)", m_index, value); SPU.Status.SetValue(value); break;
|
||||
|
@ -282,37 +282,69 @@ public:
|
||||
|
||||
__forceinline bool Pop(u32& res)
|
||||
{
|
||||
while (_InterlockedCompareExchange(&m_lock, 1, 0));
|
||||
while (_InterlockedExchange(&m_lock, 1));
|
||||
_mm_lfence();
|
||||
if(!m_index)
|
||||
{
|
||||
m_lock = 0; //release lock
|
||||
return false;
|
||||
}
|
||||
res = m_value[--m_index];
|
||||
_mm_sfence();
|
||||
m_lock = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
__forceinline bool Push(u32 value)
|
||||
{
|
||||
while (_InterlockedCompareExchange(&m_lock, 1, 0));
|
||||
while (_InterlockedExchange(&m_lock, 1));
|
||||
_mm_lfence();
|
||||
if(m_index >= max_count)
|
||||
{
|
||||
m_lock = 0; //release lock
|
||||
return false;
|
||||
}
|
||||
m_value[m_index++] = value;
|
||||
_mm_sfence();
|
||||
m_lock = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
__forceinline void PushUncond(u32 value)
|
||||
{
|
||||
while (_InterlockedExchange(&m_lock, 1));
|
||||
_mm_lfence();
|
||||
if(m_index >= max_count)
|
||||
m_value[max_count-1] = value; //last message is overwritten
|
||||
else
|
||||
m_value[m_index++] = value;
|
||||
_mm_sfence();
|
||||
m_lock = 0;
|
||||
}
|
||||
|
||||
__forceinline void PopUncond(u32& res)
|
||||
{
|
||||
while (_InterlockedExchange(&m_lock, 1));
|
||||
_mm_lfence();
|
||||
if(!m_index)
|
||||
res = 0; //result is undefined
|
||||
else
|
||||
res = m_value[--m_index];
|
||||
_mm_sfence();
|
||||
m_lock = 0;
|
||||
}
|
||||
|
||||
u32 GetCount() const
|
||||
{
|
||||
while (m_lock);
|
||||
_mm_lfence();
|
||||
return m_index;
|
||||
}
|
||||
|
||||
u32 GetFreeCount() const
|
||||
{
|
||||
while (m_lock);
|
||||
_mm_lfence();
|
||||
return max_count - m_index;
|
||||
}
|
||||
|
||||
@ -383,6 +415,14 @@ public:
|
||||
u16 tag = (u16)size_tag;
|
||||
u16 size = size_tag >> 16;
|
||||
|
||||
ConLog.Warning("DMA %s:", op & MFC_PUT_CMD ? "PUT" : "GET");
|
||||
ConLog.Warning("*** lsa = 0x%x", lsa);
|
||||
ConLog.Warning("*** ea = 0x%llx", ea);
|
||||
ConLog.Warning("*** tag = 0x%x", tag);
|
||||
ConLog.Warning("*** size = 0x%x", size);
|
||||
ConLog.Warning("*** cmd = 0x%x", cmd);
|
||||
ConLog.SkipLn();
|
||||
|
||||
MFCArgs.CMDStatus.SetValue(dmac.Cmd(cmd, tag, lsa, ea, size));
|
||||
}
|
||||
break;
|
||||
@ -406,22 +446,6 @@ public:
|
||||
case SPU_WrOutIntrMbox:
|
||||
return 0;//return SPU.OutIntr_Mbox.GetFreeCount();
|
||||
|
||||
case MFC_LSA:
|
||||
return MFC1.LSA.max_count;
|
||||
|
||||
case MFC_EAH:
|
||||
return MFC1.EAH.max_count;
|
||||
|
||||
case MFC_EAL:
|
||||
return MFC1.EAL.max_count;
|
||||
|
||||
case MFC_Size:
|
||||
case MFC_TagID:
|
||||
return MFC1.Size_Tag.max_count;
|
||||
|
||||
case MFC_Cmd:
|
||||
return MFC1.CMDStatus.max_count;
|
||||
|
||||
default:
|
||||
ConLog.Error("%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user