Basic DMA, MFC, channel changes

Added new consts, thread-safe locks for critical resources, removed some
warnings. Modified git-version.h
This commit is contained in:
Nekotekina 2013-12-11 02:58:11 +04:00
parent bba9ea830f
commit c9fc99c388
5 changed files with 93 additions and 71 deletions

View file

@ -3,21 +3,22 @@
enum enum
{ {
MFC_PUT_CMD = 0x20, MFC_PUT_CMD = 0x20, MFC_PUTB_CMD = 0x21, MFC_PUTF_CMD = 0x22,
MFC_GET_CMD = 0x40, MFC_GET_CMD = 0x40, MFC_GETB_CMD = 0x41, MFC_GETF_CMD = 0x42,
MFC_PUTL_CMD = 0x24, MFC_PUTL_CMD = 0x24, MFC_PUTLB_CMD = 0x25, MFC_PUTLF_CMD = 0x26,
MFC_GETL_CMD = 0x44, MFC_GETL_CMD = 0x44, MFC_GETLB_CMD = 0x45, MFC_GETLF_CMD = 0x46,
MFC_GETLLAR_CMD = 0xD0, MFC_GETLLAR_CMD = 0xD0,
MFC_PUTLLC_CMD = 0xB4, MFC_PUTLLC_CMD = 0xB4,
MFC_PUTLLUC_CMD = 0xB0, MFC_PUTLLUC_CMD = 0xB0,
MFC_PUTQLLUC_CMD= 0xB8, MFC_PUTQLLUC_CMD = 0xB8,
MFC_SNDSIG_CMD = 0xA0, MFC_SNDSIG_CMD = 0xA0, MFC_SNDSIGB_CMD = 0xA1, MFC_SNDSIGF_CMD = 0xA2,
MFC_BARRIER_CMD = 0xC0, MFC_BARRIER_CMD = 0xC0,
MFC_EIEIO_CMD = 0xC8, MFC_EIEIO_CMD = 0xC8,
MFC_SYNC_CMD = 0xCC, MFC_SYNC_CMD = 0xCC,
MFC_BARRIER_MASK= 0x01,
MFC_FENCE_MASK = 0x02, MFC_BARRIER_MASK = 0x01,
MFC_MASK_CMD = 0xffff, MFC_FENCE_MASK = 0x02,
MFC_MASK_CMD = 0xffff,
}; };
enum enum
@ -142,11 +143,13 @@ public:
struct DMAC struct DMAC
{ {
DMAC_Queue queue[MFC_SPU_MAX_QUEUE_SPACE]; //DMAC_Queue queue[MFC_SPU_MAX_QUEUE_SPACE]; //not used yet
DMAC_Proxy proxy[MFC_PPU_MAX_QUEUE_SPACE]; DMAC_Proxy proxy[MFC_PPU_MAX_QUEUE_SPACE+MFC_SPU_MAX_QUEUE_SPACE]; //temporarily 24
u64 ls_offset; u64 ls_offset;
std::atomic<u32> queue_pos; u32 queue_pos;
std::atomic<u32> proxy_pos; u32 proxy_pos;
u32 queue_lock;
u32 proxy_lock;
u32 Cmd(u32 cmd, u32 tag, u32 lsa, u64 ea, u32 size) u32 Cmd(u32 cmd, u32 tag, u32 lsa, u64 ea, u32 size)
{ {
@ -160,31 +163,42 @@ struct DMAC
return MFC_PPU_DMA_QUEUE_FULL; return MFC_PPU_DMA_QUEUE_FULL;
} }
DMAC_Proxy& p = proxy[proxy_pos++]; while (_InterlockedCompareExchange(&proxy_lock, 1, 0));
DMAC_Proxy& p = proxy[proxy_pos];
p.cmd = cmd; p.cmd = cmd;
p.tag = tag; p.tag = tag;
p.lsa = lsa; p.lsa = lsa;
p.ea = ea; p.ea = ea;
p.size = size; p.size = size;
proxy_pos++;
proxy_lock = 0;
return MFC_PPU_DMA_CMD_ENQUEUE_SUCCESSFUL; return MFC_PPU_DMA_CMD_ENQUEUE_SUCCESSFUL;
} }
void ClearCmd()
{
while (_InterlockedCompareExchange(&proxy_lock, 1, 0));
memcpy(proxy, proxy + 1, --proxy_pos * sizeof(DMAC_Proxy));
proxy_lock = 0; //release lock
}
void DoCmd() void DoCmd()
{ {
if(proxy_pos) if(proxy_pos)
{ {
DMAC_Proxy p = proxy[0]; const DMAC_Proxy& p = proxy[0];
memcpy(proxy, proxy + 1, --proxy_pos * sizeof(DMAC_Proxy));
switch(p.cmd) switch(p.cmd & ~(MFC_BARRIER_MASK | MFC_FENCE_MASK)) //barrier/fence ignored
{ {
case MFC_PUT_CMD: case MFC_PUT_CMD:
memcpy(Memory + p.ea, Memory + ls_offset + p.lsa, p.size); memcpy(Memory + p.ea, Memory + ls_offset + p.lsa, p.size);
ClearCmd();
break; break;
case MFC_GET_CMD: case MFC_GET_CMD:
memcpy(Memory + ls_offset + p.lsa, Memory + p.ea, p.size); memcpy(Memory + ls_offset + p.lsa, Memory + p.ea, p.size);
ClearCmd();
break; break;
default: default:

View file

@ -57,12 +57,12 @@ bool RawSPUThread::Read32(const u64 addr, u32* value)
u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET;
switch(offset) switch(offset)
{ {
case MFC_LSA_offs: ConLog.Warning("RawSPUThread[%d]: Read32(MFC_LSA)", m_index); *value = MFC.LSA.GetValue(); break; case MFC_LSA_offs: ConLog.Warning("RawSPUThread[%d]: Read32(MFC_LSA)", m_index); *value = MFC2.LSA.GetValue(); break;
case MFC_EAH_offs: ConLog.Warning("RawSPUThread[%d]: Read32(MFC_EAH)", m_index); *value = MFC.EAH.GetValue(); break; case MFC_EAH_offs: ConLog.Warning("RawSPUThread[%d]: Read32(MFC_EAH)", m_index); *value = MFC2.EAH.GetValue(); break;
case MFC_EAL_offs: ConLog.Warning("RawSPUThread[%d]: Read32(MFC_EAL)", m_index); *value = MFC.EAL.GetValue(); break; 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 = MFC.Size_Tag.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 = MFC.CMDStatus.GetValue(); break; case MFC_CMDStatus_offs: ConLog.Warning("RawSPUThread[%d]: Read32(MFC_CMDStatus)", m_index); *value = MFC2.CMDStatus.GetValue(); break;
case MFC_QStatus_offs: ConLog.Warning("RawSPUThread[%d]: Read32(MFC_QStatus)", m_index); *value = MFC.QStatus.GetValue(); break; case MFC_QStatus_offs: *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_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_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 Prxy_TagStatus_offs: ConLog.Warning("RawSPUThread[%d]: Read32(Prxy_TagStatus)", m_index); *value = Prxy.TagStatus.GetValue(); break;
@ -151,16 +151,15 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value)
switch(offset) switch(offset)
{ {
case MFC_LSA_offs: ConLog.Warning("RawSPUThread[%d]: Write32(MFC_LSA, 0x%x)", m_index, value); MFC.LSA.SetValue(value); break; case MFC_LSA_offs: MFC2.LSA.SetValue(value); break;
case MFC_EAH_offs: ConLog.Warning("RawSPUThread[%d]: Write32(MFC_EAH, 0x%x)", m_index, value); MFC.EAH.SetValue(value); break; case MFC_EAH_offs: MFC2.EAH.SetValue(value); break;
case MFC_EAL_offs: ConLog.Warning("RawSPUThread[%d]: Write32(MFC_EAL, 0x%x)", m_index, value); MFC.EAL.SetValue(value); break; case MFC_EAL_offs: MFC2.EAL.SetValue(value); break;
case MFC_Size_Tag_offs: ConLog.Warning("RawSPUThread[%d]: Write32(MFC_Size_Tag, 0x%x)", m_index, value); MFC.Size_Tag.SetValue(value); break; case MFC_Size_Tag_offs: MFC2.Size_Tag.SetValue(value); break;
case MFC_CMDStatus_offs: case MFC_CMDStatus_offs:
ConLog.Warning("RawSPUThread[%d]: Write32(MFC_CMDStatus, 0x%x)", m_index, value); MFC2.CMDStatus.SetValue(value);
MFC.CMDStatus.SetValue(value); EnqMfcCmd(MFC2);
DoMfcCmd();
break; break;
case MFC_QStatus_offs: ConLog.Warning("RawSPUThread[%d]: Write32(MFC_QStatus, 0x%x)", m_index, value); MFC.QStatus.SetValue(value); break; case MFC_QStatus_offs: ConLog.Warning("RawSPUThread[%d]: Write32(MFC_QStatus, 0x%x)", m_index, value); MFC2.QStatus.SetValue(value); break;
case Prxy_QueryType_offs: case Prxy_QueryType_offs:
{ {
ConLog.Warning("RawSPUThread[%d]: Write32(Prxy_QueryType, 0x%x)", m_index, value); ConLog.Warning("RawSPUThread[%d]: Write32(Prxy_QueryType, 0x%x)", m_index, value);
@ -178,7 +177,7 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value)
} }
Prxy.QueryType.SetValue(0); Prxy.QueryType.SetValue(0);
MFC.QStatus.SetValue(Prxy.QueryMask.GetValue()); MFC2.QStatus.SetValue(Prxy.QueryMask.GetValue());
} }
break; break;
case Prxy_QueryMask_offs: ConLog.Warning("RawSPUThread[%d]: Write32(Prxy_QueryMask, 0x%x)", m_index, value); Prxy.QueryMask.SetValue(value); break; case Prxy_QueryMask_offs: ConLog.Warning("RawSPUThread[%d]: Write32(Prxy_QueryMask, 0x%x)", m_index, value); Prxy.QueryMask.SetValue(value); break;

View file

@ -46,11 +46,14 @@ void SPUThread::InitRegs()
dmac.ls_offset = m_offset; dmac.ls_offset = m_offset;
dmac.proxy_pos = 0; dmac.proxy_pos = 0;
dmac.queue_pos = 0; dmac.queue_pos = 0;
dmac.proxy_lock = 0;
dmac.queue_lock = 0;
SPU.RunCntl.SetValue(SPU_RUNCNTL_STOP); SPU.RunCntl.SetValue(SPU_RUNCNTL_STOP);
SPU.Status.SetValue(SPU_STATUS_RUNNING); SPU.Status.SetValue(SPU_STATUS_RUNNING);
Prxy.QueryType.SetValue(0); Prxy.QueryType.SetValue(0);
MFC.CMDStatus.SetValue(0); MFC1.CMDStatus.SetValue(0);
MFC2.CMDStatus.SetValue(0);
//PC = SPU.NPC.GetValue(); //PC = SPU.NPC.GetValue();
} }

View file

@ -265,6 +265,7 @@ public:
private: private:
u32 m_value[max_count]; u32 m_value[max_count];
u32 m_index; u32 m_index;
u32 m_lock;
public: public:
@ -276,19 +277,32 @@ public:
void Init() void Init()
{ {
m_index = 0; m_index = 0;
m_lock = 0; //simple lock
} }
__forceinline bool Pop(u32& res) __forceinline bool Pop(u32& res)
{ {
if(!m_index) return false; while (_InterlockedCompareExchange(&m_lock, 1, 0));
if(!m_index)
{
m_lock = 0; //release lock
return false;
}
res = m_value[--m_index]; res = m_value[--m_index];
m_lock = 0;
return true; return true;
} }
__forceinline bool Push(u32 value) __forceinline bool Push(u32 value)
{ {
if(m_index >= max_count) return false; while (_InterlockedCompareExchange(&m_lock, 1, 0));
if(m_index >= max_count)
{
m_lock = 0; //release lock
return false;
}
m_value[m_index++] = value; m_value[m_index++] = value;
m_lock = 0;
return true; return true;
} }
@ -313,7 +327,7 @@ public:
} }
}; };
struct struct MFCReg
{ {
Channel<1> LSA; Channel<1> LSA;
Channel<1> EAH; Channel<1> EAH;
@ -321,7 +335,7 @@ public:
Channel<1> Size_Tag; Channel<1> Size_Tag;
Channel<1> CMDStatus; Channel<1> CMDStatus;
Channel<1> QStatus; Channel<1> QStatus;
} MFC; } MFC1, MFC2;
struct struct
{ {
@ -353,9 +367,9 @@ public:
DMAC dmac; DMAC dmac;
void DoMfcCmd() void EnqMfcCmd(MFCReg& MFCArgs)
{ {
u32 cmd = MFC.CMDStatus.GetValue(); u32 cmd = MFCArgs.CMDStatus.GetValue();
u16 op = cmd & MFC_MASK_CMD; u16 op = cmd & MFC_MASK_CMD;
switch(op & ~(MFC_BARRIER_MASK | MFC_FENCE_MASK)) switch(op & ~(MFC_BARRIER_MASK | MFC_FENCE_MASK))
@ -363,21 +377,13 @@ public:
case MFC_PUT_CMD: case MFC_PUT_CMD:
case MFC_GET_CMD: case MFC_GET_CMD:
{ {
u32 lsa = MFC.LSA.GetValue(); u32 lsa = MFCArgs.LSA.GetValue();
u64 ea = (u64)MFC.EAL.GetValue() | ((u64)MFC.EAH.GetValue() << 32); u64 ea = (u64)MFCArgs.EAL.GetValue() | ((u64)MFCArgs.EAH.GetValue() << 32);
u32 size_tag = MFC.Size_Tag.GetValue(); u32 size_tag = MFCArgs.Size_Tag.GetValue();
u16 tag = (u16)size_tag; u16 tag = (u16)size_tag;
u16 size = size_tag >> 16; u16 size = size_tag >> 16;
ConLog.Warning("DMA %s:", op & MFC_PUT_CMD ? "PUT" : "GET"); MFCArgs.CMDStatus.SetValue(dmac.Cmd(cmd, tag, lsa, ea, size));
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();
MFC.CMDStatus.SetValue(dmac.Cmd(cmd, tag, lsa, ea, size));
} }
break; break;
@ -401,20 +407,20 @@ public:
return 0;//return SPU.OutIntr_Mbox.GetFreeCount(); return 0;//return SPU.OutIntr_Mbox.GetFreeCount();
case MFC_LSA: case MFC_LSA:
return MFC.LSA.max_count; return MFC1.LSA.max_count;
case MFC_EAH: case MFC_EAH:
return MFC.EAH.max_count; return MFC1.EAH.max_count;
case MFC_EAL: case MFC_EAL:
return MFC.EAL.max_count; return MFC1.EAL.max_count;
case MFC_Size: case MFC_Size:
case MFC_TagID: case MFC_TagID:
return MFC.Size_Tag.max_count; return MFC1.Size_Tag.max_count;
case MFC_Cmd: case MFC_Cmd:
return MFC.CMDStatus.max_count; return MFC1.CMDStatus.max_count;
default: default:
ConLog.Error("%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]); ConLog.Error("%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]);
@ -455,28 +461,28 @@ public:
break; break;
case MFC_LSA: case MFC_LSA:
MFC.LSA.SetValue(v); MFC1.LSA.SetValue(v);
break; break;
case MFC_EAH: case MFC_EAH:
MFC.EAH.SetValue(v); MFC1.EAH.SetValue(v);
break; break;
case MFC_EAL: case MFC_EAL:
MFC.EAL.SetValue(v); MFC1.EAL.SetValue(v);
break; break;
case MFC_Size: case MFC_Size:
MFC.Size_Tag.SetValue((MFC.Size_Tag.GetValue() & 0xffff) | (v << 16)); MFC1.Size_Tag.SetValue((MFC1.Size_Tag.GetValue() & 0xffff) | (v << 16));
break; break;
case MFC_TagID: case MFC_TagID:
MFC.Size_Tag.SetValue((MFC.Size_Tag.GetValue() & ~0xffff) | (v & 0xffff)); MFC1.Size_Tag.SetValue((MFC1.Size_Tag.GetValue() & ~0xffff) | (v & 0xffff));
break; break;
case MFC_Cmd: case MFC_Cmd:
MFC.CMDStatus.SetValue(v); MFC1.CMDStatus.SetValue(v);
DoMfcCmd(); EnqMfcCmd(MFC1);
break; break;
default: default:

View file

@ -1,6 +1,6 @@
// This is a generated file. // This is a generated file.
#define RPCS3_GIT_VERSION "d83a9b1" #define RPCS3_GIT_VERSION "unknown"
// If you don't want this file to update/recompile, change to 1. // If you don't want this file to update/recompile, change to 1.
#define RPCS3_GIT_VERSION_NO_UPDATE 0 #define RPCS3_GIT_VERSION_NO_UPDATE 1