Boot: Avoid ppcState global.
This commit is contained in:
parent
51e7980d95
commit
94455ee9e1
|
@ -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())
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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!
|
||||
|
|
Loading…
Reference in New Issue