mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-27 18:41:10 +00:00
spu: Fix interrupt jump check - also change interrupt variable to atomic bool for ease of setting/checking
This commit is contained in:
parent
34e01ba3d8
commit
d17093e65b
@ -21,7 +21,7 @@ void RawSPUThread::cpu_task()
|
||||
SPUThread::cpu_task();
|
||||
|
||||
// save next PC and current SPU Interrupt status
|
||||
npc = pc | ((ch_event_stat & SPU_EVENT_INTR_ENABLED) != 0);
|
||||
npc = pc | (interrupts_enabled);
|
||||
}
|
||||
|
||||
void RawSPUThread::on_init(const std::shared_ptr<void>& _this)
|
||||
|
@ -376,12 +376,12 @@ void spu_recompiler::FunctionCall()
|
||||
fmt::throw_exception("Undefined behaviour" HERE);
|
||||
}
|
||||
|
||||
_spu->set_interrupt_status(true);
|
||||
_spu->interrupts_enabled = true;
|
||||
_spu->pc &= ~0x4000000;
|
||||
}
|
||||
else if (_spu->pc & 0x8000000)
|
||||
{
|
||||
_spu->set_interrupt_status(false);
|
||||
_spu->interrupts_enabled = false;
|
||||
_spu->pc &= ~0x8000000;
|
||||
}
|
||||
|
||||
|
@ -50,9 +50,9 @@ void spu_interpreter::set_interrupt_status(SPUThread& spu, spu_opcode_t op)
|
||||
spu.set_interrupt_status(false);
|
||||
}
|
||||
|
||||
if ((spu.ch_event_stat & SPU_EVENT_INTR_TEST & spu.ch_event_mask) > SPU_EVENT_INTR_ENABLED)
|
||||
if (spu.interrupts_enabled && (spu.ch_event_mask & spu.ch_event_stat & SPU_EVENT_INTR_IMPLEMENTED) > 0)
|
||||
{
|
||||
spu.ch_event_stat &= ~SPU_EVENT_INTR_ENABLED;
|
||||
spu.interrupts_enabled = false;
|
||||
spu.srr0 = std::exchange(spu.pc, -4) + 4;
|
||||
}
|
||||
}
|
||||
|
@ -86,9 +86,9 @@ void spu_recompiler_base::enter(SPUThread& spu)
|
||||
|
||||
spu.pc = res & 0x3fffc;
|
||||
|
||||
if ((spu.ch_event_stat & SPU_EVENT_INTR_TEST & spu.ch_event_mask) > SPU_EVENT_INTR_ENABLED)
|
||||
if (spu.interrupts_enabled && (spu.ch_event_mask & spu.ch_event_stat & SPU_EVENT_INTR_IMPLEMENTED) > 0)
|
||||
{
|
||||
spu.ch_event_stat &= ~SPU_EVENT_INTR_ENABLED;
|
||||
spu.interrupts_enabled = false;
|
||||
spu.srr0 = std::exchange(spu.pc, 0);
|
||||
}
|
||||
}
|
||||
|
@ -292,6 +292,7 @@ void SPUThread::cpu_init()
|
||||
|
||||
ch_event_mask = 0;
|
||||
ch_event_stat = 0;
|
||||
interrupts_enabled = false;
|
||||
raddr = 0;
|
||||
|
||||
ch_dec_start_timestamp = get_timebased_time(); // ???
|
||||
@ -974,12 +975,11 @@ void SPUThread::set_interrupt_status(bool enable)
|
||||
{
|
||||
fmt::throw_exception("SPU Interrupts not implemented (mask=0x%x)" HERE, mask);
|
||||
}
|
||||
|
||||
ch_event_stat |= SPU_EVENT_INTR_ENABLED;
|
||||
interrupts_enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ch_event_stat &= ~SPU_EVENT_INTR_ENABLED;
|
||||
interrupts_enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1165,7 +1165,7 @@ bool SPUThread::get_ch_value(u32 ch, u32& out)
|
||||
{
|
||||
// HACK: "Not isolated" status
|
||||
// Return SPU Interrupt status in LSB
|
||||
out = (ch_event_stat & SPU_EVENT_INTR_ENABLED) != 0;
|
||||
out = interrupts_enabled == true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1467,7 +1467,7 @@ bool SPUThread::set_ch_value(u32 ch, u32 value)
|
||||
case SPU_WrEventMask:
|
||||
{
|
||||
// detect masking events with enabled interrupt status
|
||||
if (value & ~SPU_EVENT_INTR_IMPLEMENTED && ch_event_stat & SPU_EVENT_INTR_ENABLED)
|
||||
if (value & ~SPU_EVENT_INTR_IMPLEMENTED && interrupts_enabled)
|
||||
{
|
||||
fmt::throw_exception("SPU Interrupts not implemented (mask=0x%x)" HERE, value);
|
||||
}
|
||||
|
@ -68,9 +68,9 @@ enum : u32
|
||||
|
||||
SPU_EVENT_WAITING = 0x80000000, // Originally unused, set when SPU thread starts waiting on ch_event_stat
|
||||
//SPU_EVENT_AVAILABLE = 0x40000000, // Originally unused, channel count of the SPU_RdEventStat channel
|
||||
SPU_EVENT_INTR_ENABLED = 0x20000000, // Originally unused, represents "SPU Interrupts Enabled" status
|
||||
//SPU_EVENT_INTR_ENABLED = 0x20000000, // Originally unused, represents "SPU Interrupts Enabled" status
|
||||
|
||||
SPU_EVENT_INTR_TEST = SPU_EVENT_INTR_ENABLED | SPU_EVENT_INTR_IMPLEMENTED
|
||||
SPU_EVENT_INTR_TEST = SPU_EVENT_INTR_IMPLEMENTED
|
||||
};
|
||||
|
||||
// SPU Class 0 Interrupts
|
||||
@ -562,6 +562,7 @@ public:
|
||||
|
||||
atomic_t<u32> ch_event_mask;
|
||||
atomic_t<u32> ch_event_stat;
|
||||
atomic_t<bool> interrupts_enabled;
|
||||
|
||||
u64 ch_dec_start_timestamp; // timestamp of writing decrementer value
|
||||
u32 ch_dec_value; // written decrementer value
|
||||
|
Loading…
x
Reference in New Issue
Block a user