mirror of https://github.com/PCSX2/pcsx2.git
Misc: Pattern match to find the bios thread address
This commit is contained in:
parent
91acaa2555
commit
54590a843a
|
@ -21,10 +21,11 @@ std::vector<EEThread> getEEThreads()
|
||||||
{
|
{
|
||||||
std::vector<EEThread> threads;
|
std::vector<EEThread> threads;
|
||||||
|
|
||||||
if (CurrentBiosInformation == NULL)
|
if (CurrentBiosInformation.threadListAddr <= 0)
|
||||||
return threads;
|
return threads;
|
||||||
|
|
||||||
u32 start = CurrentBiosInformation->threadListAddr & 0x3fffff;
|
const u32 start = CurrentBiosInformation.threadListAddr & 0x3fffff;
|
||||||
|
|
||||||
for (int tid = 0; tid < 256; tid++)
|
for (int tid = 0; tid < 256; tid++)
|
||||||
{
|
{
|
||||||
EEThread thread;
|
EEThread thread;
|
||||||
|
@ -40,4 +41,3 @@ std::vector<EEThread> getEEThreads()
|
||||||
|
|
||||||
return threads;
|
return threads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -982,8 +982,43 @@ void SYSCALL()
|
||||||
case Syscall::SetVTLBRefillHandler:
|
case Syscall::SetVTLBRefillHandler:
|
||||||
DevCon.Warning("A tlb refill handler is set. New handler %x", (u32*)PSM(cpuRegs.GPR.n.a1.UL[0]));
|
DevCon.Warning("A tlb refill handler is set. New handler %x", (u32*)PSM(cpuRegs.GPR.n.a1.UL[0]));
|
||||||
break;
|
break;
|
||||||
|
case Syscall::StartThread:
|
||||||
|
case Syscall::ChangeThreadPriority:
|
||||||
|
{
|
||||||
|
if (CurrentBiosInformation.threadListAddr == 0)
|
||||||
|
{
|
||||||
|
u32 offset = 0x0;
|
||||||
|
// Suprisingly not that slow :)
|
||||||
|
while (offset < 0x5000) // I find that the instructions are in between 0x4000 -> 0x5000
|
||||||
|
{
|
||||||
|
u32 addr = 0x80000000 + offset;
|
||||||
|
const u32 inst1 = memRead32(addr);
|
||||||
|
const u32 inst2 = memRead32(addr += 4);
|
||||||
|
const u32 inst3 = memRead32(addr += 4);
|
||||||
|
|
||||||
|
if (ThreadListInstructions[0] == inst1 && // sw v0,0x0(v0)
|
||||||
|
ThreadListInstructions[1] == inst2 && // no-op
|
||||||
|
ThreadListInstructions[2] == inst3) // no-op
|
||||||
|
{
|
||||||
|
// We've found the instruction pattern!
|
||||||
|
// We (well, I) know that the thread address is always 0x8001 + the immediate of the 6th instruction from here
|
||||||
|
const u32 op = memRead32(0x80000000 + offset + (sizeof(u32) * 6));
|
||||||
|
CurrentBiosInformation.threadListAddr = 0x80010000 + static_cast<u16>(op) - 8; // Subtract 8 because the address here is offset by 8.
|
||||||
|
DevCon.WriteLn("BIOS: Successfully found the instruction pattern. Assuming the thread list is here: %0x", CurrentBiosInformation.threadListAddr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
offset += 4;
|
||||||
|
}
|
||||||
|
if (!CurrentBiosInformation.threadListAddr)
|
||||||
|
{
|
||||||
|
// We couldn't find the address
|
||||||
|
CurrentBiosInformation.threadListAddr = -1;
|
||||||
|
// If you're here because a user has reported this message, this means that the instruction pattern is not present on their bios, or it is aligned weirdly.
|
||||||
|
Console.Warning("BIOS Warning: Unable to get a thread list offset. The debugger thread and stack frame views will not be functional.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case Syscall::sceSifSetDma:
|
case Syscall::sceSifSetDma:
|
||||||
// The only thing this code is used for is the one log message, so don't execute it if we aren't logging bios messages.
|
// The only thing this code is used for is the one log message, so don't execute it if we aren't logging bios messages.
|
||||||
if (SysTraceActive(EE.Bios))
|
if (SysTraceActive(EE.Bios))
|
||||||
|
|
|
@ -21,6 +21,8 @@ enum Syscall : u8
|
||||||
{
|
{
|
||||||
SetGsCrt = 2,
|
SetGsCrt = 2,
|
||||||
SetVTLBRefillHandler = 13,
|
SetVTLBRefillHandler = 13,
|
||||||
|
StartThread = 34,
|
||||||
|
ChangeThreadPriority = 41,
|
||||||
GetOsdConfigParam = 75,
|
GetOsdConfigParam = 75,
|
||||||
GetOsdConfigParam2 = 111,
|
GetOsdConfigParam2 = 111,
|
||||||
sysPrintOut = 117,
|
sysPrintOut = 117,
|
||||||
|
|
|
@ -54,57 +54,7 @@ u32 BiosChecksum;
|
||||||
u32 BiosRegion;
|
u32 BiosRegion;
|
||||||
bool NoOSD;
|
bool NoOSD;
|
||||||
wxString BiosDescription;
|
wxString BiosDescription;
|
||||||
const BiosDebugInformation* CurrentBiosInformation;
|
BiosDebugInformation CurrentBiosInformation;
|
||||||
|
|
||||||
const BiosDebugInformation biosVersions[] = {
|
|
||||||
// Notes: The SCPH versions have not been verified
|
|
||||||
|
|
||||||
// USA v02.00(14/06/2004) SCPH70012
|
|
||||||
{ 0x00000200, 0xD778DB8D, 0x8001A640 },
|
|
||||||
// USA v01.60(19/03/2002) SCPH39004
|
|
||||||
{ 0x0000013C, 0x0B51A16F, 0x8001A280 },
|
|
||||||
// USA v01.60(07/02/2002) SCPH39001
|
|
||||||
{ 0x0000013C, 0x3A75B059, 0x8001A480 },
|
|
||||||
// Europe v02.20(10/02/2006) SCPH77008
|
|
||||||
{ 0x00000214, 0xD7EDD771, 0x8001AC00 },
|
|
||||||
// Europe v02.20(20/06/2005) SCPH75004
|
|
||||||
{ 0x00000214, 0x0E9C22D3, 0x8001AC00 },
|
|
||||||
// Europe v02.00(16/06/2004) SCPH70008
|
|
||||||
{ 0x00000200, 0x3C6AA4F4, 0x8001A640 },
|
|
||||||
// Europe v02.00(14/06/2004) SCPH70004
|
|
||||||
{ 0x00000200, 0x9C7B59D3, 0x8001A640 },
|
|
||||||
{ 0x00000200, 0x8C7B49D3, 0x8001A640 }, // Russian variant
|
|
||||||
// Europe v02.00(04/11/2004) SCPH50003
|
|
||||||
{ 0x00000200, 0xBDE56F8E, 0x8001A580 },
|
|
||||||
// Europe v01.90(23/06/2003) SCPH50004
|
|
||||||
{ 0x0000015A, 0xE36776DC, 0x8001A640 },
|
|
||||||
// Europe v01.70(27/02/2003) SCPH50004
|
|
||||||
{ 0x00000146 ,0x4954F4A2, 0x8001A640 },
|
|
||||||
// Europe v01.60(19/03/2002) SCPH39004
|
|
||||||
{ 0x0000013C, 0xFA3F9E90, 0x8001A280 },
|
|
||||||
// Europe v01.60(04/10/2001) SCPH30004
|
|
||||||
{ 0x0000013C, 0xB8E26E89, 0x8001A580 },
|
|
||||||
// Europe v01.60(04/10/2001) SCPH30004R
|
|
||||||
{ 0x0000013C, 0xEC9058f6, 0x8001A580 },
|
|
||||||
// Europe v01.20(02/09/2000) SCPH30003
|
|
||||||
{ 0x00000114, 0xCF83F17A, 0x80017B40 },
|
|
||||||
// Japan v02.20(05/09/2006) SCPH90006
|
|
||||||
{ 0x00000214, 0x098047D7, 0x8001AC00 },
|
|
||||||
// Japan v02.20(20/06/2005) SCPH75004
|
|
||||||
{ 0x00000214, 0x0E9C22DC, 0x8001AC00 },
|
|
||||||
// Japan v02.00(14/06/2004) SCPH70000
|
|
||||||
{ 0x00000200, 0xC9B61306, 0x8001A640 },
|
|
||||||
// Japan v01.70(06/02/2003) SCPH50000
|
|
||||||
{ 0x00000146, 0x71C7C144, 0x8001A640 },
|
|
||||||
// Japan v01.50(18/01/2001) SCPH30000
|
|
||||||
{ 0x00000132, 0x4FA83C78, 0x80019A00 },
|
|
||||||
// Japan v01.00(17/01/2000) SCPH10000
|
|
||||||
{ 0x00000100, 0x22B99C77, 0x80017400 },
|
|
||||||
// China v01.90(23/06/2003) SCPH50009
|
|
||||||
{ 0x0000015A, 0xE9D87F1F, 0x8001A640 },
|
|
||||||
// HK v02.00(14/06/2004) SCPH70006
|
|
||||||
{ 0x00000200, 0x2E5D0C98, 0x8001A640 }
|
|
||||||
};
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// Exception::BiosLoadFailed (implementations)
|
// Exception::BiosLoadFailed (implementations)
|
||||||
|
@ -354,18 +304,7 @@ void LoadBIOS()
|
||||||
if (g_Conf->CurrentIRX.Length() > 3)
|
if (g_Conf->CurrentIRX.Length() > 3)
|
||||||
LoadIrx(g_Conf->CurrentIRX, &eeMem->ROM[0x3C0000]);
|
LoadIrx(g_Conf->CurrentIRX, &eeMem->ROM[0x3C0000]);
|
||||||
|
|
||||||
CurrentBiosInformation = NULL;
|
CurrentBiosInformation.threadListAddr = 0;
|
||||||
for (size_t i = 0; i < sizeof(biosVersions)/sizeof(biosVersions[0]); i++)
|
|
||||||
{
|
|
||||||
if (biosVersions[i].biosChecksum == BiosChecksum && biosVersions[i].biosVersion == BiosVersion)
|
|
||||||
{
|
|
||||||
CurrentBiosInformation = &biosVersions[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CurrentBiosInformation == NULL)
|
|
||||||
Console.Warning("BIOS Warning: Unknown BIOS version. The debugger thread and stack frame views will not be functional.");
|
|
||||||
}
|
}
|
||||||
catch (Exception::BadStream& ex)
|
catch (Exception::BadStream& ex)
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,19 +28,23 @@ namespace Exception
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const u32 ThreadListInstructions[3] =
|
||||||
|
{
|
||||||
|
0xac420000, // sw v0,0x0(v0)
|
||||||
|
0x00000000, // no-op
|
||||||
|
0x00000000, // no-op
|
||||||
|
};
|
||||||
|
|
||||||
struct BiosDebugInformation
|
struct BiosDebugInformation
|
||||||
{
|
{
|
||||||
u32 biosVersion;
|
|
||||||
u32 biosChecksum;
|
|
||||||
u32 threadListAddr;
|
u32 threadListAddr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern BiosDebugInformation CurrentBiosInformation;
|
||||||
extern u32 BiosVersion; // Used by CDVD
|
extern u32 BiosVersion; // Used by CDVD
|
||||||
extern u32 BiosRegion; // Used by CDVD
|
extern u32 BiosRegion; // Used by CDVD
|
||||||
extern bool NoOSD; // Used for HLE OSD Config Params
|
extern bool NoOSD; // Used for HLE OSD Config Params
|
||||||
extern u32 BiosChecksum;
|
extern u32 BiosChecksum;
|
||||||
extern wxString BiosDescription;
|
extern wxString BiosDescription;
|
||||||
extern const BiosDebugInformation* CurrentBiosInformation;
|
|
||||||
|
|
||||||
extern void LoadBIOS();
|
extern void LoadBIOS();
|
||||||
extern bool IsBIOS(const wxString& filename, wxString& description);
|
extern bool IsBIOS(const wxString& filename, wxString& description);
|
||||||
|
|
Loading…
Reference in New Issue