Fill registers with 0xDEADBEEF after most syscalls.

Some, like sceMpegRingbufferPut(), we don't, since... it's complicated.
But most we do, like a real PSP does.
This commit is contained in:
Unknown W. Brackets 2013-10-29 22:53:25 -07:00
parent 04ec987448
commit 9ebaf7b68b
5 changed files with 43 additions and 0 deletions

View file

@ -52,6 +52,8 @@ enum
HLE_AFTER_RUN_INTERRUPTS = 0x10,
// Switch to CORE_STEPPING after the syscall (for debugging.)
HLE_AFTER_DEBUG_BREAK = 0x20,
// Don't fill temp regs with 0xDEADBEEF.
HLE_AFTER_SKIP_DEADBEEF = 0x40,
};
typedef std::vector<Syscall> SyscallVector;
@ -287,6 +289,11 @@ void hleDebugBreak()
hleAfterSyscall |= HLE_AFTER_DEBUG_BREAK;
}
void hleSkipDeadbeef()
{
hleAfterSyscall |= HLE_AFTER_SKIP_DEADBEEF;
}
// Pauses execution after an HLE call.
bool hleExecuteDebugBreak(const HLEFunction &func)
{
@ -341,8 +348,26 @@ void hleEatMicro(int usec)
hleEatCycles((int) usToCycles(usec));
}
const static u32 deadbeefRegs[12] = {0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF};
inline static void SetDeadbeefRegs()
{
// TODO: Debug setting?
currentMIPS->r[MIPS_REG_COMPILER_SCRATCH] = 0xDEADBEEF;
// Set all the arguments and temp regs.
memcpy(&currentMIPS->r[MIPS_REG_A0], deadbeefRegs, sizeof(deadbeefRegs));
// Using a magic number since there's confusion/disagreement on reg names.
currentMIPS->r[24] = 0xDEADBEEF;
currentMIPS->r[25] = 0xDEADBEEF;
currentMIPS->lo = 0xDEADBEEF;
currentMIPS->hi = 0xDEADBEEF;
}
inline void hleFinishSyscall(int modulenum, int funcnum)
{
if ((hleAfterSyscall & HLE_AFTER_SKIP_DEADBEEF) == 0)
SetDeadbeefRegs();
if ((hleAfterSyscall & HLE_AFTER_CURRENT_CALLBACKS) != 0)
__KernelForceCallbacks();
@ -449,6 +474,8 @@ void CallSyscall(MIPSOpcode op)
if (hleAfterSyscall != HLE_AFTER_NOTHING)
hleFinishSyscall(modulenum, funcnum);
else
SetDeadbeefRegs();
}
else
{

View file

@ -91,6 +91,8 @@ void hleReSchedule(bool callbacks, const char *reason);
void hleRunInterrupts();
// Pause emulation after the syscall finishes.
void hleDebugBreak();
// Don't set temp regs to 0xDEADBEEF.
void hleSkipDeadbeef();
// Delays the result for usec microseconds, allowing other threads to run during this time.
u32 hleDelayResult(u32 result, const char *reason, int usec);

View file

@ -405,6 +405,8 @@ void __KernelReturnFromInterrupt()
{
VERBOSE_LOG(SCEINTC, "Left interrupt handler at %08x", currentMIPS->pc);
hleSkipDeadbeef();
// This is what we just ran.
PendingInterrupt pend = pendingInterrupts.front();
pendingInterrupts.pop_front();

View file

@ -1601,6 +1601,7 @@ u32 sceKernelStopUnloadSelfModuleWithStatus(u32 exitCode, u32 argSize, u32 argp,
void __KernelReturnFromModuleFunc()
{
// Return from the thread as normal.
hleSkipDeadbeef();
__KernelReturnFromThread();
SceUID leftModuleID = __KernelGetCurThreadModuleId();

View file

@ -1284,6 +1284,7 @@ bool __KernelSwitchOffThread(const char *reason)
Thread *t = kernelObjects.GetFast<Thread>(threadIdleID[0]);
if (t)
{
hleSkipDeadbeef();
__KernelSwitchContext(t, reason);
return true;
}
@ -1327,6 +1328,8 @@ bool __KernelSwitchToThread(SceUID threadID, const char *reason)
void __KernelIdle()
{
hleSkipDeadbeef();
CoreTiming::Idle();
// Advance must happen between Idle and Reschedule, so that threads that were waiting for something
// that was triggered at the end of the Idle period must get a chance to be scheduled.
@ -2206,6 +2209,8 @@ int sceKernelGetThreadStackFreeSize(SceUID threadID)
void __KernelReturnFromThread()
{
hleSkipDeadbeef();
int exitStatus = currentMIPS->r[MIPS_REG_V0];
Thread *thread = __GetCurrentThread();
_dbg_assert_msg_(SCEKERNEL, thread != NULL, "Returned from a NULL thread.");
@ -3001,11 +3006,14 @@ u32 sceKernelExtendThreadStack(u32 size, u32 entryAddr, u32 entryParameter)
// Stack should stay aligned even though we saved only 3 regs.
currentMIPS->r[MIPS_REG_SP] = thread->currentStack.end - 0x10;
hleSkipDeadbeef();
return 0;
}
void __KernelReturnFromExtendStack()
{
hleSkipDeadbeef();
Thread *thread = __GetCurrentThread();
if (!thread)
{
@ -3269,6 +3277,7 @@ bool __CanExecuteCallbackNow(Thread *thread) {
void __KernelCallAddress(Thread *thread, u32 entryPoint, Action *afterAction, const u32 args[], int numargs, bool reschedAfter, SceUID cbId)
{
hleSkipDeadbeef();
_dbg_assert_msg_(SCEKERNEL, numargs <= 6, "MipsCalls can only take 6 args.");
if (thread) {
@ -3376,6 +3385,8 @@ void __KernelExecuteMipsCallOnCurrentThread(u32 callId, bool reschedAfter)
void __KernelReturnFromMipsCall()
{
hleSkipDeadbeef();
Thread *cur = __GetCurrentThread();
if (cur == NULL)
{