Skip to content

Commit

Permalink
PPU: Add decrementer exception. Fix IIC behavior according to what li…
Browse files Browse the repository at this point in the history
…nux expects.
  • Loading branch information
bitsh1ft3r committed Jan 19, 2025
1 parent 81a60aa commit 248db5e
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 8 deletions.
20 changes: 14 additions & 6 deletions Xenon/Core/XCPU/IIC/IIC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,22 @@ void Xe::XCPU::IIC::XenonIIC::readInterrupt(u64 intAddress, u64* intData)
*intData = _byteswap_uint64((u64)iicState.ppeIntCtrlBlck[ppeIntCtrlBlckID].REG_CPU_CURRENT_TSK_PRI);
break;
case Xe::XCPU::IIC::ACK:
// Check if the queue isn't empty (this probably isn't necessary)
// Check if the queue isn't empty (this probably isn't necessary).
if (iicState.ppeIntCtrlBlck[ppeIntCtrlBlckID].intQueue.empty() != true)
{
// Signal the Top Priority interrupt.
*intData = _byteswap_uint64(iicState.ppeIntCtrlBlck[ppeIntCtrlBlckID].intQueue.top());
// Set the ACK flag.
iicState.ppeIntCtrlBlck[ppeIntCtrlBlckID].intAck = true;
return;
// If the first interrupt is ACK'd we return PRIO_NONE.
if (iicState.ppeIntCtrlBlck[ppeIntCtrlBlckID].intAck)
{
*intData = _byteswap_uint64(PRIO_NONE);
}
else
{
// Signal the Top Priority interrupt.
*intData = _byteswap_uint64(iicState.ppeIntCtrlBlck[ppeIntCtrlBlckID].intQueue.top());
// Set the ACK flag.
iicState.ppeIntCtrlBlck[ppeIntCtrlBlckID].intAck = true;
return;
}
}
*intData = _byteswap_uint64(PRIO_NONE);
break;
Expand Down
17 changes: 16 additions & 1 deletion Xenon/Core/XCPU/PPU/PPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,17 @@ void PPU::StartExecution()
}
}

// Check if the IIC has an external interrupt pending if External interrupts are enabled.
// Check if External interrupts are enabled.
if (ppuState->ppuThread[ppuState->currentThread].SPR.MSR.EE)
{
// Check the decrementer.
// DEC[0] = 0 and a Decrementer exception does not exist.
if (ppuState->ppuThread[ppuState->currentThread].SPR.DEC == 0 &&
((ppuState->ppuThread[ppuState->currentThread].exceptReg & PPU_EX_DEC) == 0))
{
ppuState->ppuThread[ppuState->currentThread].exceptReg |= PPU_EX_DEC;
}
// Check if the IIC has an external interrupt pending.
if (xenonContext->xenonIIC.checkExtInterrupt(ppuState->ppuThread[ppuState->currentThread].SPR.PIR))
{
ppuState->ppuThread[ppuState->currentThread].exceptReg |= PPU_EX_EXT;
Expand Down Expand Up @@ -158,6 +166,13 @@ void PPU::StartExecution()
// Check if the IIC has an external interrupt pending if External interrupts are enabled.
if (ppuState->ppuThread[ppuState->currentThread].SPR.MSR.EE)
{
// Check the decrementer.
// DEC[0] = 0 and a Decrementer exception does not exist.
if (ppuState->ppuThread[ppuState->currentThread].SPR.DEC == 0 &&
((ppuState->ppuThread[ppuState->currentThread].exceptReg & PPU_EX_DEC) == 0))
{
ppuState->ppuThread[ppuState->currentThread].exceptReg |= PPU_EX_DEC;
}
if (xenonContext->xenonIIC.checkExtInterrupt(ppuState->ppuThread[ppuState->currentThread].SPR.PIR))
{
ppuState->ppuThread[ppuState->currentThread].exceptReg |= PPU_EX_EXT;
Expand Down
3 changes: 2 additions & 1 deletion Xenon/Core/XCPU/PPU/PowerPC.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,8 @@ struct PPU_THREAD_SPRS
// Data Address Register
u64 DAR;
// Decrementer Register
u32 DEC;
// The contents of the Decrementer are treated as a signed integer.
s32 DEC;
// Machine Status Save/Restore Register 0
u64 SRR0;
// Machine Status Save/Restore Register 1
Expand Down

0 comments on commit 248db5e

Please sign in to comment.