Boot: Avoid ppcState global.

This commit is contained in:
Admiral H. Curtiss 2023-01-10 04:22:04 +01:00
parent 51e7980d95
commit 94455ee9e1
No known key found for this signature in database
GPG Key ID: F051B4C4044F33FB
3 changed files with 111 additions and 94 deletions

View File

@ -458,22 +458,23 @@ bool CBoot::Load_BS2(Core::System& system, const std::string& boot_rom_filename)
memory.CopyToEmu(0x01200000, data.data() + 0x100, 0x700);
memory.CopyToEmu(0x01300000, data.data() + 0x820, 0x1AFE00);
PowerPC::ppcState.gpr[3] = 0xfff0001f;
PowerPC::ppcState.gpr[4] = 0x00002030;
PowerPC::ppcState.gpr[5] = 0x0000009c;
auto& ppc_state = system.GetPPCState();
ppc_state.gpr[3] = 0xfff0001f;
ppc_state.gpr[4] = 0x00002030;
ppc_state.gpr[5] = 0x0000009c;
PowerPC::ppcState.msr.FP = 1;
PowerPC::ppcState.msr.DR = 1;
PowerPC::ppcState.msr.IR = 1;
ppc_state.msr.FP = 1;
ppc_state.msr.DR = 1;
ppc_state.msr.IR = 1;
PowerPC::ppcState.spr[SPR_HID0] = 0x0011c464;
PowerPC::ppcState.spr[SPR_IBAT3U] = 0xfff0001f;
PowerPC::ppcState.spr[SPR_IBAT3L] = 0xfff00001;
PowerPC::ppcState.spr[SPR_DBAT3U] = 0xfff0001f;
PowerPC::ppcState.spr[SPR_DBAT3L] = 0xfff00001;
SetupBAT(/*is_wii*/ false);
ppc_state.spr[SPR_HID0] = 0x0011c464;
ppc_state.spr[SPR_IBAT3U] = 0xfff0001f;
ppc_state.spr[SPR_IBAT3L] = 0xfff00001;
ppc_state.spr[SPR_DBAT3U] = 0xfff0001f;
ppc_state.spr[SPR_DBAT3L] = 0xfff00001;
SetupBAT(system, /*is_wii*/ false);
PowerPC::ppcState.pc = 0x81200150;
ppc_state.pc = 0x81200150;
return true;
}
@ -543,16 +544,18 @@ bool CBoot::BootUp(Core::System& system, std::unique_ptr<BootParameters> boot)
SetDefaultDisc();
SetupMSR();
SetupHID(config.bWii);
SetupBAT(config.bWii);
auto& ppc_state = system.GetPPCState();
SetupMSR(ppc_state);
SetupHID(ppc_state, config.bWii);
SetupBAT(system, config.bWii);
CopyDefaultExceptionHandlers(system);
if (config.bWii)
{
// Set a value for the SP. It doesn't matter where this points to,
// as long as it is a valid location. This value is taken from a homebrew binary.
PowerPC::ppcState.gpr[1] = 0x8004d4bc;
ppc_state.gpr[1] = 0x8004d4bc;
// Because there is no TMD to get the requested system (IOS) version from,
// we default to IOS58, which is the version used by the Homebrew Channel.
@ -572,7 +575,7 @@ bool CBoot::BootUp(Core::System& system, std::unique_ptr<BootParameters> boot)
SConfig::OnNewTitleLoad();
PowerPC::ppcState.pc = executable.reader->GetEntryPoint();
ppc_state.pc = executable.reader->GetEntryPoint();
if (executable.reader->LoadSymbols())
{

View File

@ -34,6 +34,11 @@ namespace IOS::HLE::FS
class FileSystem;
}
namespace PowerPC
{
struct PowerPCState;
}
struct RegionSetting
{
std::string area;
@ -167,17 +172,17 @@ private:
static bool DVDRead(const DiscIO::VolumeDisc& disc, u64 dvd_offset, u32 output_address,
u32 length, const DiscIO::Partition& partition);
static bool DVDReadDiscID(const DiscIO::VolumeDisc& disc, u32 output_address);
static void RunFunction(u32 address);
static void RunFunction(Core::System& system, u32 address);
static void UpdateDebugger_MapLoaded();
static bool Boot_WiiWAD(Core::System& system, const DiscIO::VolumeWAD& wad);
static bool BootNANDTitle(Core::System& system, u64 title_id);
static void SetupMSR();
static void SetupHID(bool is_wii);
static void SetupBAT(bool is_wii);
static bool RunApploader(bool is_wii, const DiscIO::VolumeDisc& volume,
static void SetupMSR(PowerPC::PowerPCState& ppc_state);
static void SetupHID(PowerPC::PowerPCState& ppc_state, bool is_wii);
static void SetupBAT(Core::System& system, bool is_wii);
static bool RunApploader(Core::System& system, bool is_wii, const DiscIO::VolumeDisc& volume,
const std::vector<DiscIO::Riivolution::Patch>& riivolution_patches);
static bool EmulatedBS2_GC(Core::System& system, const DiscIO::VolumeDisc& volume,
const std::vector<DiscIO::Riivolution::Patch>& riivolution_patches);

View File

@ -55,80 +55,83 @@ void PresetTimeBaseTicks()
}
} // Anonymous namespace
void CBoot::RunFunction(u32 address)
void CBoot::RunFunction(Core::System& system, u32 address)
{
PowerPC::ppcState.pc = address;
LR(PowerPC::ppcState) = 0x00;
auto& ppc_state = system.GetPPCState();
while (PowerPC::ppcState.pc != 0x00)
ppc_state.pc = address;
LR(ppc_state) = 0x00;
while (ppc_state.pc != 0x00)
PowerPC::SingleStep();
}
void CBoot::SetupMSR()
void CBoot::SetupMSR(PowerPC::PowerPCState& ppc_state)
{
// 0x0002032
PowerPC::ppcState.msr.RI = 1;
PowerPC::ppcState.msr.DR = 1;
PowerPC::ppcState.msr.IR = 1;
PowerPC::ppcState.msr.FP = 1;
ppc_state.msr.RI = 1;
ppc_state.msr.DR = 1;
ppc_state.msr.IR = 1;
ppc_state.msr.FP = 1;
}
void CBoot::SetupHID(bool is_wii)
void CBoot::SetupHID(PowerPC::PowerPCState& ppc_state, bool is_wii)
{
// HID0 is 0x0011c464 on GC, 0x0011c664 on Wii
HID0(PowerPC::ppcState).BHT = 1;
HID0(PowerPC::ppcState).BTIC = 1;
HID0(PowerPC::ppcState).DCFA = 1;
HID0(ppc_state).BHT = 1;
HID0(ppc_state).BTIC = 1;
HID0(ppc_state).DCFA = 1;
if (is_wii)
HID0(PowerPC::ppcState).SPD = 1;
HID0(PowerPC::ppcState).DCFI = 1;
HID0(PowerPC::ppcState).DCE = 1;
HID0(ppc_state).SPD = 1;
HID0(ppc_state).DCFI = 1;
HID0(ppc_state).DCE = 1;
// Note that Datel titles will fail to boot if the instruction cache is not enabled; see
// https://bugs.dolphin-emu.org/issues/8223
HID0(PowerPC::ppcState).ICE = 1;
HID0(PowerPC::ppcState).NHR = 1;
HID0(PowerPC::ppcState).DPM = 1;
HID0(ppc_state).ICE = 1;
HID0(ppc_state).NHR = 1;
HID0(ppc_state).DPM = 1;
// HID1 is initialized in PowerPC.cpp to 0x80000000
// HID2 is 0xe0000000
HID2(PowerPC::ppcState).PSE = 1;
HID2(PowerPC::ppcState).WPE = 1;
HID2(PowerPC::ppcState).LSQE = 1;
HID2(ppc_state).PSE = 1;
HID2(ppc_state).WPE = 1;
HID2(ppc_state).LSQE = 1;
// HID4 is 0 on GC and 0x83900000 on Wii
if (is_wii)
{
HID4(PowerPC::ppcState).L2CFI = 1;
HID4(PowerPC::ppcState).LPE = 1;
HID4(PowerPC::ppcState).ST0 = 1;
HID4(PowerPC::ppcState).SBE = 1;
HID4(PowerPC::ppcState).reserved_3 = 1;
HID4(ppc_state).L2CFI = 1;
HID4(ppc_state).LPE = 1;
HID4(ppc_state).ST0 = 1;
HID4(ppc_state).SBE = 1;
HID4(ppc_state).reserved_3 = 1;
}
}
void CBoot::SetupBAT(bool is_wii)
void CBoot::SetupBAT(Core::System& system, bool is_wii)
{
PowerPC::ppcState.spr[SPR_IBAT0U] = 0x80001fff;
PowerPC::ppcState.spr[SPR_IBAT0L] = 0x00000002;
PowerPC::ppcState.spr[SPR_DBAT0U] = 0x80001fff;
PowerPC::ppcState.spr[SPR_DBAT0L] = 0x00000002;
PowerPC::ppcState.spr[SPR_DBAT1U] = 0xc0001fff;
PowerPC::ppcState.spr[SPR_DBAT1L] = 0x0000002a;
auto& ppc_state = system.GetPPCState();
ppc_state.spr[SPR_IBAT0U] = 0x80001fff;
ppc_state.spr[SPR_IBAT0L] = 0x00000002;
ppc_state.spr[SPR_DBAT0U] = 0x80001fff;
ppc_state.spr[SPR_DBAT0L] = 0x00000002;
ppc_state.spr[SPR_DBAT1U] = 0xc0001fff;
ppc_state.spr[SPR_DBAT1L] = 0x0000002a;
if (is_wii)
{
PowerPC::ppcState.spr[SPR_IBAT4U] = 0x90001fff;
PowerPC::ppcState.spr[SPR_IBAT4L] = 0x10000002;
PowerPC::ppcState.spr[SPR_DBAT4U] = 0x90001fff;
PowerPC::ppcState.spr[SPR_DBAT4L] = 0x10000002;
PowerPC::ppcState.spr[SPR_DBAT5U] = 0xd0001fff;
PowerPC::ppcState.spr[SPR_DBAT5L] = 0x1000002a;
HID4(PowerPC::ppcState).SBE = 1;
ppc_state.spr[SPR_IBAT4U] = 0x90001fff;
ppc_state.spr[SPR_IBAT4L] = 0x10000002;
ppc_state.spr[SPR_DBAT4U] = 0x90001fff;
ppc_state.spr[SPR_DBAT4L] = 0x10000002;
ppc_state.spr[SPR_DBAT5U] = 0xd0001fff;
ppc_state.spr[SPR_DBAT5L] = 0x1000002a;
HID4(ppc_state).SBE = 1;
}
PowerPC::DBATUpdated();
PowerPC::IBATUpdated();
}
bool CBoot::RunApploader(bool is_wii, const DiscIO::VolumeDisc& volume,
bool CBoot::RunApploader(Core::System& system, bool is_wii, const DiscIO::VolumeDisc& volume,
const std::vector<DiscIO::Riivolution::Patch>& riivolution_patches)
{
const DiscIO::Partition partition = volume.GetGamePartition();
@ -148,13 +151,15 @@ bool CBoot::RunApploader(bool is_wii, const DiscIO::VolumeDisc& volume,
// TODO - Make Apploader(or just RunFunction()) debuggable!!!
auto& ppc_state = system.GetPPCState();
// Call iAppLoaderEntry.
DEBUG_LOG_FMT(BOOT, "Call iAppLoaderEntry");
const u32 iAppLoaderFuncAddr = is_wii ? 0x80004000 : 0x80003100;
PowerPC::ppcState.gpr[3] = iAppLoaderFuncAddr + 0;
PowerPC::ppcState.gpr[4] = iAppLoaderFuncAddr + 4;
PowerPC::ppcState.gpr[5] = iAppLoaderFuncAddr + 8;
RunFunction(*entry);
ppc_state.gpr[3] = iAppLoaderFuncAddr + 0;
ppc_state.gpr[4] = iAppLoaderFuncAddr + 4;
ppc_state.gpr[5] = iAppLoaderFuncAddr + 8;
RunFunction(system, *entry);
const u32 iAppLoaderInit = PowerPC::Read_U32(iAppLoaderFuncAddr + 0);
const u32 iAppLoaderMain = PowerPC::Read_U32(iAppLoaderFuncAddr + 4);
const u32 iAppLoaderClose = PowerPC::Read_U32(iAppLoaderFuncAddr + 8);
@ -163,25 +168,25 @@ bool CBoot::RunApploader(bool is_wii, const DiscIO::VolumeDisc& volume,
DEBUG_LOG_FMT(BOOT, "Call iAppLoaderInit");
PowerPC::HostWrite_U32(0x4E800020, 0x81300000); // Write BLR
HLE::Patch(0x81300000, "AppLoaderReport"); // HLE OSReport for Apploader
PowerPC::ppcState.gpr[3] = 0x81300000;
RunFunction(iAppLoaderInit);
ppc_state.gpr[3] = 0x81300000;
RunFunction(system, iAppLoaderInit);
// iAppLoaderMain - Here we load the apploader, the DOL (the exe) and the FST (filesystem).
// To give you an idea about where the stuff is located on the disc take a look at yagcd
// ch 13.
DEBUG_LOG_FMT(BOOT, "Call iAppLoaderMain");
PowerPC::ppcState.gpr[3] = 0x81300004;
PowerPC::ppcState.gpr[4] = 0x81300008;
PowerPC::ppcState.gpr[5] = 0x8130000c;
ppc_state.gpr[3] = 0x81300004;
ppc_state.gpr[4] = 0x81300008;
ppc_state.gpr[5] = 0x8130000c;
RunFunction(iAppLoaderMain);
RunFunction(system, iAppLoaderMain);
// iAppLoaderMain returns 1 if the pointers in R3/R4/R5 were filled with values for DVD copy
// Typical behaviour is doing it once for each section defined in the DOL header. Some unlicensed
// titles don't have a properly constructed DOL and maintain a table of these values in apploader.
// iAppLoaderMain returns 0 when there are no more sections to copy.
while (PowerPC::ppcState.gpr[3] != 0x00)
while (ppc_state.gpr[3] != 0x00)
{
const u32 ram_address = PowerPC::Read_U32(0x81300004);
const u32 length = PowerPC::Read_U32(0x81300008);
@ -193,20 +198,20 @@ bool CBoot::RunApploader(bool is_wii, const DiscIO::VolumeDisc& volume,
DiscIO::Riivolution::ApplyApploaderMemoryPatches(riivolution_patches, ram_address, length);
PowerPC::ppcState.gpr[3] = 0x81300004;
PowerPC::ppcState.gpr[4] = 0x81300008;
PowerPC::ppcState.gpr[5] = 0x8130000c;
ppc_state.gpr[3] = 0x81300004;
ppc_state.gpr[4] = 0x81300008;
ppc_state.gpr[5] = 0x8130000c;
RunFunction(iAppLoaderMain);
RunFunction(system, iAppLoaderMain);
}
// iAppLoaderClose
DEBUG_LOG_FMT(BOOT, "call iAppLoaderClose");
RunFunction(iAppLoaderClose);
RunFunction(system, iAppLoaderClose);
HLE::UnPatch("AppLoaderReport");
// return
PowerPC::ppcState.pc = PowerPC::ppcState.gpr[3];
ppc_state.pc = ppc_state.gpr[3];
return true;
}
@ -255,9 +260,11 @@ bool CBoot::EmulatedBS2_GC(Core::System& system, const DiscIO::VolumeDisc& volum
{
INFO_LOG_FMT(BOOT, "Faking GC BS2...");
SetupMSR();
SetupHID(/*is_wii*/ false);
SetupBAT(/*is_wii*/ false);
auto& ppc_state = system.GetPPCState();
SetupMSR(ppc_state);
SetupHID(ppc_state, /*is_wii*/ false);
SetupBAT(system, /*is_wii*/ false);
SetupGCMemory(system);
@ -296,13 +303,13 @@ bool CBoot::EmulatedBS2_GC(Core::System& system, const DiscIO::VolumeDisc& volum
// Setup pointers like real BS2 does
// StackPointer, used to be set to 0x816ffff0
PowerPC::ppcState.gpr[1] = ntsc ? 0x81566550 : 0x815edca8;
ppc_state.gpr[1] = ntsc ? 0x81566550 : 0x815edca8;
// Global pointer to Small Data Area 2 Base (haven't seen anything use it...meh)
PowerPC::ppcState.gpr[2] = ntsc ? 0x81465cc0 : 0x814b5b20;
ppc_state.gpr[2] = ntsc ? 0x81465cc0 : 0x814b5b20;
// Global pointer to Small Data Area Base (Luigi's Mansion's apploader uses it)
PowerPC::ppcState.gpr[13] = ntsc ? 0x81465320 : 0x814b4fc0;
ppc_state.gpr[13] = ntsc ? 0x81465320 : 0x814b4fc0;
return RunApploader(/*is_wii*/ false, volume, riivolution_patches);
return RunApploader(system, /*is_wii*/ false, volume, riivolution_patches);
}
static DiscIO::Region CodeRegion(char c)
@ -559,17 +566,19 @@ bool CBoot::EmulatedBS2_Wii(Core::System& system, const DiscIO::VolumeDisc& volu
// after this check during booting.
DVDRead(volume, 0, 0x3180, 4, partition);
SetupMSR();
SetupHID(/*is_wii*/ true);
SetupBAT(/*is_wii*/ true);
auto& ppc_state = system.GetPPCState();
SetupMSR(ppc_state);
SetupHID(ppc_state, /*is_wii*/ true);
SetupBAT(system, /*is_wii*/ true);
memory.Write_U32(0x4c000064, 0x00000300); // Write default DSI Handler: rfi
memory.Write_U32(0x4c000064, 0x00000800); // Write default FPU Handler: rfi
memory.Write_U32(0x4c000064, 0x00000C00); // Write default Syscall Handler: rfi
PowerPC::ppcState.gpr[1] = 0x816ffff0; // StackPointer
ppc_state.gpr[1] = 0x816ffff0; // StackPointer
if (!RunApploader(/*is_wii*/ true, volume, riivolution_patches))
if (!RunApploader(system, /*is_wii*/ true, volume, riivolution_patches))
return false;
// The Apploader probably just overwrote values needed for RAM Override. Run this again!