mirror of https://github.com/RPCS3/rpcs3.git
SPU Decrementer
This commit is contained in:
parent
061fe50835
commit
d16953d392
|
@ -325,6 +325,9 @@ public:
|
||||||
EventManager SPUQs; // SPU Queue Mapping
|
EventManager SPUQs; // SPU Queue Mapping
|
||||||
SpuGroupInfo* group; // associated SPU Thread Group (null for raw spu)
|
SpuGroupInfo* group; // associated SPU Thread Group (null for raw spu)
|
||||||
|
|
||||||
|
u64 m_dec_start; // timestamp of writing decrementer value
|
||||||
|
u32 m_dec_value; // written decrementer value
|
||||||
|
|
||||||
struct IntrTag
|
struct IntrTag
|
||||||
{
|
{
|
||||||
u32 enabled; // 1 == true
|
u32 enabled; // 1 == true
|
||||||
|
@ -937,47 +940,25 @@ public:
|
||||||
|
|
||||||
u32 GetChannelCount(u32 ch)
|
u32 GetChannelCount(u32 ch)
|
||||||
{
|
{
|
||||||
u32 count;
|
|
||||||
switch(ch)
|
switch(ch)
|
||||||
{
|
{
|
||||||
case SPU_WrOutMbox:
|
case SPU_WrOutMbox: return SPU.Out_MBox.GetFreeCount();
|
||||||
return SPU.Out_MBox.GetFreeCount();
|
case SPU_RdInMbox: return SPU.In_MBox.GetCount();
|
||||||
|
case MFC_RdTagStat: return Prxy.TagStatus.GetCount();
|
||||||
case SPU_RdInMbox:
|
case MFC_RdListStallStat: return StallStat.GetCount();
|
||||||
count = SPU.In_MBox.GetCount();
|
case MFC_WrTagUpdate: return Prxy.TagStatus.GetCount(); // hack
|
||||||
//ConLog.Warning("GetChannelCount(%s) -> %d", spu_ch_name[ch], count);
|
case SPU_RdSigNotify1: return SPU.SNR[0].GetCount();
|
||||||
return count;
|
case SPU_RdSigNotify2: return SPU.SNR[1].GetCount();
|
||||||
|
case MFC_RdAtomicStat: return Prxy.AtomicStat.GetCount();
|
||||||
case SPU_WrOutIntrMbox:
|
|
||||||
LOG_WARNING(Log::SPU, "GetChannelCount(%s) = 0", spu_ch_name[ch]);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case MFC_RdTagStat:
|
|
||||||
return Prxy.TagStatus.GetCount();
|
|
||||||
|
|
||||||
case MFC_RdListStallStat:
|
|
||||||
return StallStat.GetCount();
|
|
||||||
|
|
||||||
case MFC_WrTagUpdate:
|
|
||||||
return Prxy.TagStatus.GetCount(); // hack
|
|
||||||
|
|
||||||
case SPU_RdSigNotify1:
|
|
||||||
return SPU.SNR[0].GetCount();
|
|
||||||
|
|
||||||
case SPU_RdSigNotify2:
|
|
||||||
return SPU.SNR[1].GetCount();
|
|
||||||
|
|
||||||
case MFC_RdAtomicStat:
|
|
||||||
return Prxy.AtomicStat.GetCount();
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
{
|
||||||
LOG_ERROR(Log::SPU, "%s error: unknown/illegal channel (%d [%s]).",
|
LOG_ERROR(Log::SPU, "%s error: unknown/illegal channel (%d [%s]).",
|
||||||
__FUNCTION__, ch, spu_ch_name[ch]);
|
__FUNCTION__, ch, spu_ch_name[ch]);
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WriteChannel(u32 ch, const SPU_GPR_hdr& r)
|
void WriteChannel(u32 ch, const SPU_GPR_hdr& r)
|
||||||
{
|
{
|
||||||
|
@ -986,6 +967,7 @@ public:
|
||||||
switch(ch)
|
switch(ch)
|
||||||
{
|
{
|
||||||
case SPU_WrOutIntrMbox:
|
case SPU_WrOutIntrMbox:
|
||||||
|
{
|
||||||
if (!group) // if RawSPU
|
if (!group) // if RawSPU
|
||||||
{
|
{
|
||||||
if (Ini.HLELogging.GetValue()) LOG_NOTICE(Log::SPU, "SPU_WrOutIntrMbox: interrupt(v=0x%x)", v);
|
if (Ini.HLELogging.GetValue()) LOG_NOTICE(Log::SPU, "SPU_WrOutIntrMbox: interrupt(v=0x%x)", v);
|
||||||
|
@ -1121,46 +1103,66 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case SPU_WrOutMbox:
|
case SPU_WrOutMbox:
|
||||||
|
{
|
||||||
//ConLog.Warning("%s: %s = 0x%x", __FUNCTION__, spu_ch_name[ch], v);
|
//ConLog.Warning("%s: %s = 0x%x", __FUNCTION__, spu_ch_name[ch], v);
|
||||||
while (!SPU.Out_MBox.Push(v) && !Emu.IsStopped()) Sleep(1);
|
while (!SPU.Out_MBox.Push(v) && !Emu.IsStopped()) Sleep(1);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case MFC_WrTagMask:
|
case MFC_WrTagMask:
|
||||||
|
{
|
||||||
//ConLog.Warning("%s: %s = 0x%x", __FUNCTION__, spu_ch_name[ch], v);
|
//ConLog.Warning("%s: %s = 0x%x", __FUNCTION__, spu_ch_name[ch], v);
|
||||||
Prxy.QueryMask.SetValue(v);
|
Prxy.QueryMask.SetValue(v);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case MFC_WrTagUpdate:
|
case MFC_WrTagUpdate:
|
||||||
|
{
|
||||||
//ConLog.Warning("%s: %s = 0x%x", __FUNCTION__, spu_ch_name[ch], v);
|
//ConLog.Warning("%s: %s = 0x%x", __FUNCTION__, spu_ch_name[ch], v);
|
||||||
Prxy.TagStatus.PushUncond(Prxy.QueryMask.GetValue());
|
Prxy.TagStatus.PushUncond(Prxy.QueryMask.GetValue());
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case MFC_LSA:
|
case MFC_LSA:
|
||||||
|
{
|
||||||
MFC1.LSA.SetValue(v);
|
MFC1.LSA.SetValue(v);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case MFC_EAH:
|
case MFC_EAH:
|
||||||
|
{
|
||||||
MFC1.EAH.SetValue(v);
|
MFC1.EAH.SetValue(v);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case MFC_EAL:
|
case MFC_EAL:
|
||||||
|
{
|
||||||
MFC1.EAL.SetValue(v);
|
MFC1.EAL.SetValue(v);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case MFC_Size:
|
case MFC_Size:
|
||||||
|
{
|
||||||
MFC1.Size_Tag.SetValue((MFC1.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:
|
||||||
|
{
|
||||||
MFC1.Size_Tag.SetValue((MFC1.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:
|
||||||
|
{
|
||||||
MFC1.CMDStatus.SetValue(v);
|
MFC1.CMDStatus.SetValue(v);
|
||||||
EnqMfcCmd(MFC1);
|
EnqMfcCmd(MFC1);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case MFC_WrListStallAck:
|
case MFC_WrListStallAck:
|
||||||
{
|
{
|
||||||
|
@ -1177,13 +1179,22 @@ public:
|
||||||
}
|
}
|
||||||
StallList[v].MFCArgs = nullptr;
|
StallList[v].MFCArgs = nullptr;
|
||||||
ListCmd(temp.lsa, temp.ea, temp.tag, temp.size, temp.cmd, *temp.MFCArgs);
|
ListCmd(temp.lsa, temp.ea, temp.tag, temp.size, temp.cmd, *temp.MFCArgs);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SPU_WrDec:
|
||||||
|
{
|
||||||
|
m_dec_start = get_system_time();
|
||||||
|
m_dec_value = v;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
{
|
||||||
LOG_ERROR(Log::SPU, "%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]);
|
LOG_ERROR(Log::SPU, "%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Emu.IsStopped()) LOG_WARNING(Log::SPU, "%s(%s) aborted", __FUNCTION__, spu_ch_name[ch]);
|
if (Emu.IsStopped()) LOG_WARNING(Log::SPU, "%s(%s) aborted", __FUNCTION__, spu_ch_name[ch]);
|
||||||
}
|
}
|
||||||
|
@ -1196,37 +1207,58 @@ public:
|
||||||
switch(ch)
|
switch(ch)
|
||||||
{
|
{
|
||||||
case SPU_RdInMbox:
|
case SPU_RdInMbox:
|
||||||
|
{
|
||||||
while (!SPU.In_MBox.Pop(v) && !Emu.IsStopped()) Sleep(1);
|
while (!SPU.In_MBox.Pop(v) && !Emu.IsStopped()) Sleep(1);
|
||||||
//ConLog.Warning("%s: 0x%x = %s", __FUNCTION__, v, spu_ch_name[ch]);
|
//ConLog.Warning("%s: 0x%x = %s", __FUNCTION__, v, spu_ch_name[ch]);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case MFC_RdTagStat:
|
case MFC_RdTagStat:
|
||||||
|
{
|
||||||
while (!Prxy.TagStatus.Pop(v) && !Emu.IsStopped()) Sleep(1);
|
while (!Prxy.TagStatus.Pop(v) && !Emu.IsStopped()) Sleep(1);
|
||||||
//ConLog.Warning("%s: 0x%x = %s", __FUNCTION__, v, spu_ch_name[ch]);
|
//ConLog.Warning("%s: 0x%x = %s", __FUNCTION__, v, spu_ch_name[ch]);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case SPU_RdSigNotify1:
|
case SPU_RdSigNotify1:
|
||||||
|
{
|
||||||
while (!SPU.SNR[0].Pop(v) && !Emu.IsStopped()) Sleep(1);
|
while (!SPU.SNR[0].Pop(v) && !Emu.IsStopped()) Sleep(1);
|
||||||
//ConLog.Warning("%s: 0x%x = %s", __FUNCTION__, v, spu_ch_name[ch]);
|
//ConLog.Warning("%s: 0x%x = %s", __FUNCTION__, v, spu_ch_name[ch]);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case SPU_RdSigNotify2:
|
case SPU_RdSigNotify2:
|
||||||
|
{
|
||||||
while (!SPU.SNR[1].Pop(v) && !Emu.IsStopped()) Sleep(1);
|
while (!SPU.SNR[1].Pop(v) && !Emu.IsStopped()) Sleep(1);
|
||||||
//ConLog.Warning("%s: 0x%x = %s", __FUNCTION__, v, spu_ch_name[ch]);
|
//ConLog.Warning("%s: 0x%x = %s", __FUNCTION__, v, spu_ch_name[ch]);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case MFC_RdAtomicStat:
|
case MFC_RdAtomicStat:
|
||||||
|
{
|
||||||
while (!Prxy.AtomicStat.Pop(v) && !Emu.IsStopped()) Sleep(1);
|
while (!Prxy.AtomicStat.Pop(v) && !Emu.IsStopped()) Sleep(1);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case MFC_RdListStallStat:
|
case MFC_RdListStallStat:
|
||||||
|
{
|
||||||
while (!StallStat.Pop(v) && !Emu.IsStopped()) Sleep(1);
|
while (!StallStat.Pop(v) && !Emu.IsStopped()) Sleep(1);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SPU_RdDec:
|
||||||
|
{
|
||||||
|
// decrementer freq is probably 80 MHz
|
||||||
|
v = m_dec_value - (u32)(get_system_time() - m_dec_start) * 80;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
{
|
||||||
LOG_ERROR(Log::SPU, "%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]);
|
LOG_ERROR(Log::SPU, "%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Emu.IsStopped()) LOG_WARNING(Log::SPU, "%s(%s) aborted", __FUNCTION__, spu_ch_name[ch]);
|
if (Emu.IsStopped()) LOG_WARNING(Log::SPU, "%s(%s) aborted", __FUNCTION__, spu_ch_name[ch]);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue