Merge pull request #4369 from unknownbrackets/deadbeef

Fill regs with 0xDEADBEEF after syscalls...
This commit is contained in:
Henrik Rydgård 2013-11-01 14:15:53 -07:00
commit 590ad5c6df
8 changed files with 63 additions and 9 deletions

View File

@ -286,6 +286,7 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) {
debugConfig->Get("DisplayStatusBar", &bDisplayStatusBar, true);
debugConfig->Get("ShowBottomTabTitles",&bShowBottomTabTitles,true);
debugConfig->Get("ShowDeveloperMenu", &bShowDeveloperMenu, false);
debugConfig->Get("SkipDeadbeefFilling", &bSkipDeadbeefFilling, false);
IniFile::Section *speedhacks = iniFile.GetOrCreateSection("SpeedHacks");
speedhacks->Get("PrescaleUV", &bPrescaleUV, false);
@ -482,6 +483,7 @@ void Config::Save() {
debugConfig->Set("DisplayStatusBar", bDisplayStatusBar);
debugConfig->Set("ShowBottomTabTitles",bShowBottomTabTitles);
debugConfig->Set("ShowDeveloperMenu", bShowDeveloperMenu);
debugConfig->Set("SkipDeadbeefFilling", bSkipDeadbeefFilling);
IniFile::Section *speedhacks = iniFile.GetOrCreateSection("SpeedHacks");
speedhacks->Set("PrescaleUV", bPrescaleUV);

View File

@ -216,6 +216,8 @@ public:
bool bDisplayStatusBar;
bool bShowBottomTabTitles;
bool bShowDeveloperMenu;
// Double edged sword: much easier debugging, but not accurate.
bool bSkipDeadbeefFilling;
std::string currentDirectory;
std::string externalDirectory;

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,28 @@ 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()
{
if (g_Config.bSkipDeadbeefFilling)
return;
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 +476,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.
@ -1892,9 +1895,10 @@ void ThreadContext::reset()
{
for (int i = 0; i<32; i++)
{
r[i] = 0;
f[i] = 0.0f;
r[i] = 0xDEADBEEF;
fi[i] = 0x7f800001;
}
r[0] = 0;
for (int i = 0; i<128; i++)
{
v[i] = 0.0f;
@ -1919,15 +1923,13 @@ void ThreadContext::reset()
fpcond = 0;
fcr0 = 0;
fcr31 = 0;
hi = 0;
lo = 0;
hi = 0xDEADBEEF;
lo = 0xDEADBEEF;
}
void __KernelResetThread(Thread *t, int lowestPriority)
{
t->context.reset();
t->context.hi = 0;
t->context.lo = 0;
t->context.pc = t->nt.entrypoint;
// If the thread would be better than lowestPriority, reset to its initial. Yes, kinda odd...
@ -2207,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.");
@ -3002,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)
{
@ -3270,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) {
@ -3377,6 +3385,8 @@ void __KernelExecuteMipsCallOnCurrentThread(u32 callId, bool reschedAfter)
void __KernelReturnFromMipsCall()
{
hleSkipDeadbeef();
Thread *cur = __GetCurrentThread();
if (cur == NULL)
{

View File

@ -114,9 +114,15 @@ struct ThreadContext
// r must be followed by f.
u32 r[32];
float f[32];
float v[128];
union {
float f[32];
u32 fi[32];
int fs[32];
};
union {
float v[128];
u32 vi[128];
};
u32 vfpuCtrl[16];
union {