mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-24 14:49:42 -06:00
Make address translation respect the CPU translation mode.
The PowerPC CPU has bits in MSR (DR and IR) which control whether addresses are translated. We should respect these instead of mixing physical addresses and translated addresses into the same address space. This is mostly mass-renaming calls to memory accesses APIs from places which expect address translation to use a different version from those which do not expect address translation. This does very little on its own, but it's the first step to a correct BAT implementation.
This commit is contained in:
@ -39,10 +39,10 @@ void CBoot::Load_FST(bool _bIsWii)
|
||||
return;
|
||||
|
||||
// copy first 20 bytes of disc to start of Mem 1
|
||||
VolumeHandler::ReadToPtr(Memory::GetPointer(0x80000000), 0, 0x20, false);
|
||||
DVDInterface::DVDRead(/*offset*/0, /*address*/0, /*length*/0x20, false);
|
||||
|
||||
// copy of game id
|
||||
Memory::Write_U32(Memory::Read_U32(0x80000000), 0x80003180);
|
||||
Memory::Write_U32(Memory::Read_U32(0x0000), 0x3180);
|
||||
|
||||
u32 shift = 0;
|
||||
if (_bIsWii)
|
||||
@ -56,7 +56,7 @@ void CBoot::Load_FST(bool _bIsWii)
|
||||
Memory::Write_U32(arenaHigh, 0x00000034);
|
||||
|
||||
// load FST
|
||||
VolumeHandler::ReadToPtr(Memory::GetPointer(arenaHigh), fstOffset, fstSize, _bIsWii);
|
||||
DVDInterface::DVDRead(fstOffset, arenaHigh, fstSize, _bIsWii);
|
||||
Memory::Write_U32(arenaHigh, 0x00000038);
|
||||
Memory::Write_U32(maxFstSize, 0x0000003c);
|
||||
}
|
||||
@ -188,9 +188,9 @@ bool CBoot::Load_BS2(const std::string& _rBootROMFilename)
|
||||
// Run the descrambler over the encrypted section containing BS1/BS2
|
||||
CEXIIPL::Descrambler((u8*)data.data()+0x100, 0x1AFE00);
|
||||
|
||||
Memory::CopyToEmu(0x81200000, data.data() + 0x100, 0x700);
|
||||
Memory::CopyToEmu(0x81300000, data.data() + 0x820, 0x1AFE00);
|
||||
PC = 0x81200000;
|
||||
Memory::CopyToEmu(0x01200000, data.data() + 0x100, 0x700);
|
||||
Memory::CopyToEmu(0x01300000, data.data() + 0x820, 0x1AFE00);
|
||||
PC = 0x01200000;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -255,7 +255,7 @@ bool CBoot::BootUp()
|
||||
}
|
||||
|
||||
// Scan for common HLE functions
|
||||
if (_StartupPara.bSkipIdle && !_StartupPara.bEnableDebugging)
|
||||
if (_StartupPara.bSkipIdle && _StartupPara.bHLE_BS2 && !_StartupPara.bEnableDebugging)
|
||||
{
|
||||
PPCAnalyst::FindFunctions(0x80004000, 0x811fffff, &g_symbolDB);
|
||||
SignatureDB db;
|
||||
@ -309,6 +309,25 @@ bool CBoot::BootUp()
|
||||
|
||||
if (!BS2Success)
|
||||
{
|
||||
// Set up MSR and the BAT SPR registers.
|
||||
UReg_MSR& m_MSR = ((UReg_MSR&)PowerPC::ppcState.msr);
|
||||
m_MSR.FP = 1;
|
||||
m_MSR.DR = 1;
|
||||
m_MSR.IR = 1;
|
||||
m_MSR.EE = 1;
|
||||
PowerPC::ppcState.spr[SPR_IBAT0U] = 0x80001fff;
|
||||
PowerPC::ppcState.spr[SPR_IBAT0L] = 0x00000002;
|
||||
PowerPC::ppcState.spr[SPR_IBAT4U] = 0x90001fff;
|
||||
PowerPC::ppcState.spr[SPR_IBAT4L] = 0x10000002;
|
||||
PowerPC::ppcState.spr[SPR_DBAT0U] = 0x80001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT0L] = 0x00000002;
|
||||
PowerPC::ppcState.spr[SPR_DBAT1U] = 0xc0001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT1L] = 0x0000002a;
|
||||
PowerPC::ppcState.spr[SPR_DBAT4U] = 0x90001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT4L] = 0x10000002;
|
||||
PowerPC::ppcState.spr[SPR_DBAT5U] = 0xd0001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT5L] = 0x1000002a;
|
||||
|
||||
dolLoader.Load();
|
||||
PC = dolLoader.GetEntryPoint();
|
||||
}
|
||||
@ -403,7 +422,7 @@ bool CBoot::BootUp()
|
||||
if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableCheats)
|
||||
{
|
||||
HLE::Patch(0x80001800, "HBReload");
|
||||
Memory::CopyToEmu(0x80001804, "STUBHAXX", 8);
|
||||
Memory::CopyToEmu(0x00001804, "STUBHAXX", 8);
|
||||
}
|
||||
|
||||
// Not part of the binary itself, but either we or Gecko OS might insert
|
||||
|
@ -41,6 +41,9 @@ bool CBoot::EmulatedBS2_GC(bool skipAppLoader)
|
||||
// Set up MSR and the BAT SPR registers.
|
||||
UReg_MSR& m_MSR = ((UReg_MSR&)PowerPC::ppcState.msr);
|
||||
m_MSR.FP = 1;
|
||||
m_MSR.DR = 1;
|
||||
m_MSR.IR = 1;
|
||||
m_MSR.EE = 1;
|
||||
PowerPC::ppcState.spr[SPR_IBAT0U] = 0x80001fff;
|
||||
PowerPC::ppcState.spr[SPR_IBAT0L] = 0x00000002;
|
||||
PowerPC::ppcState.spr[SPR_DBAT0U] = 0x80001fff;
|
||||
@ -54,28 +57,28 @@ bool CBoot::EmulatedBS2_GC(bool skipAppLoader)
|
||||
// Write necessary values
|
||||
// Here we write values to memory that the apploader does not take care of. Game info goes
|
||||
// to 0x80000000 according to YAGCD 4.2.
|
||||
DVDInterface::DVDRead(0x00000000, 0x80000000, 0x20, false); // write disc info
|
||||
DVDInterface::DVDRead(/*offset*/0x00000000, /*address*/0x00000000, 0x20, false); // write disc info
|
||||
|
||||
Memory::Write_U32(0x0D15EA5E, 0x80000020); // Booted from bootrom. 0xE5207C22 = booted from jtag
|
||||
Memory::Write_U32(Memory::REALRAM_SIZE, 0x80000028); // Physical Memory Size (24MB on retail)
|
||||
PowerPC::HostWrite_U32(0x0D15EA5E, 0x80000020); // Booted from bootrom. 0xE5207C22 = booted from jtag
|
||||
PowerPC::HostWrite_U32(Memory::REALRAM_SIZE, 0x80000028); // Physical Memory Size (24MB on retail)
|
||||
// TODO determine why some games fail when using a retail ID. (Seem to take different EXI paths, see Ikaruga for example)
|
||||
Memory::Write_U32(0x10000006, 0x8000002C); // Console type - DevKit (retail ID == 0x00000003) see YAGCD 4.2.1.1.2
|
||||
PowerPC::HostWrite_U32(0x10000006, 0x8000002C); // Console type - DevKit (retail ID == 0x00000003) see YAGCD 4.2.1.1.2
|
||||
|
||||
Memory::Write_U32(SConfig::GetInstance().m_LocalCoreStartupParameter.bNTSC
|
||||
PowerPC::HostWrite_U32(SConfig::GetInstance().m_LocalCoreStartupParameter.bNTSC
|
||||
? 0 : 1, 0x800000CC); // Fake the VI Init of the IPL (YAGCD 4.2.1.4)
|
||||
|
||||
Memory::Write_U32(0x01000000, 0x800000d0); // ARAM Size. 16MB main + 4/16/32MB external (retail consoles have no external ARAM)
|
||||
PowerPC::HostWrite_U32(0x01000000, 0x800000d0); // ARAM Size. 16MB main + 4/16/32MB external (retail consoles have no external ARAM)
|
||||
|
||||
Memory::Write_U32(0x09a7ec80, 0x800000F8); // Bus Clock Speed
|
||||
Memory::Write_U32(0x1cf7c580, 0x800000FC); // CPU Clock Speed
|
||||
PowerPC::HostWrite_U32(0x09a7ec80, 0x800000F8); // Bus Clock Speed
|
||||
PowerPC::HostWrite_U32(0x1cf7c580, 0x800000FC); // CPU Clock Speed
|
||||
|
||||
Memory::Write_U32(0x4c000064, 0x80000300); // Write default DFI Handler: rfi
|
||||
Memory::Write_U32(0x4c000064, 0x80000800); // Write default FPU Handler: rfi
|
||||
Memory::Write_U32(0x4c000064, 0x80000C00); // Write default Syscall Handler: rfi
|
||||
PowerPC::HostWrite_U32(0x4c000064, 0x80000300); // Write default DFI Handler: rfi
|
||||
PowerPC::HostWrite_U32(0x4c000064, 0x80000800); // Write default FPU Handler: rfi
|
||||
PowerPC::HostWrite_U32(0x4c000064, 0x80000C00); // Write default Syscall Handler: rfi
|
||||
|
||||
Memory::Write_U64((u64)CEXIIPL::GetGCTime() * (u64)40500000, 0x800030D8); // Preset time base ticks
|
||||
PowerPC::HostWrite_U64((u64)CEXIIPL::GetGCTime() * (u64)40500000, 0x800030D8); // Preset time base ticks
|
||||
// HIO checks this
|
||||
//Memory::Write_U16(0x8200, 0x000030e6); // Console type
|
||||
//PowerPC::HostWrite_U16(0x8200, 0x000030e6); // Console type
|
||||
|
||||
HLE::Patch(0x81300000, "OSReport"); // HLE OSReport for Apploader
|
||||
|
||||
@ -89,7 +92,7 @@ bool CBoot::EmulatedBS2_GC(bool skipAppLoader)
|
||||
INFO_LOG(BOOT, "GC BS2: Not running apploader!");
|
||||
return false;
|
||||
}
|
||||
VolumeHandler::ReadToPtr(Memory::GetPointer(0x81200000), iAppLoaderOffset + 0x20, iAppLoaderSize, false);
|
||||
DVDInterface::DVDRead(iAppLoaderOffset + 0x20, 0x01200000, iAppLoaderSize, false);
|
||||
|
||||
// Setup pointers like real BS2 does
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bNTSC)
|
||||
@ -114,9 +117,9 @@ bool CBoot::EmulatedBS2_GC(bool skipAppLoader)
|
||||
PowerPC::ppcState.gpr[4] = iAppLoaderFuncAddr + 4;
|
||||
PowerPC::ppcState.gpr[5] = iAppLoaderFuncAddr + 8;
|
||||
RunFunction(iAppLoaderEntry);
|
||||
u32 iAppLoaderInit = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr + 0);
|
||||
u32 iAppLoaderMain = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr + 4);
|
||||
u32 iAppLoaderClose = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr + 8);
|
||||
u32 iAppLoaderInit = PowerPC::Read_U32(iAppLoaderFuncAddr + 0);
|
||||
u32 iAppLoaderMain = PowerPC::Read_U32(iAppLoaderFuncAddr + 4);
|
||||
u32 iAppLoaderClose = PowerPC::Read_U32(iAppLoaderFuncAddr + 8);
|
||||
|
||||
// iAppLoaderInit
|
||||
DEBUG_LOG(MASTER_LOG, "Call iAppLoaderInit");
|
||||
@ -135,9 +138,9 @@ bool CBoot::EmulatedBS2_GC(bool skipAppLoader)
|
||||
|
||||
RunFunction(iAppLoaderMain);
|
||||
|
||||
u32 iRamAddress = Memory::ReadUnchecked_U32(0x81300004);
|
||||
u32 iLength = Memory::ReadUnchecked_U32(0x81300008);
|
||||
u32 iDVDOffset = Memory::ReadUnchecked_U32(0x8130000c);
|
||||
u32 iRamAddress = PowerPC::Read_U32(0x81300004);
|
||||
u32 iLength = PowerPC::Read_U32(0x81300008);
|
||||
u32 iDVDOffset = PowerPC::Read_U32(0x8130000c);
|
||||
|
||||
INFO_LOG(MASTER_LOG, "DVDRead: offset: %08x memOffset: %08x length: %i", iDVDOffset, iRamAddress, iLength);
|
||||
DVDInterface::DVDRead(iDVDOffset, iRamAddress, iLength, false);
|
||||
@ -239,7 +242,7 @@ bool CBoot::SetupWiiMemory(IVolume::ECountry country)
|
||||
0x80000060 Copyright code
|
||||
*/
|
||||
|
||||
DVDInterface::DVDRead(0x00000000, 0x00000000, 0x20, false); // Game Code
|
||||
DVDInterface::DVDRead(0x00000000, 0x00000000, 0x20, false); // Game Code
|
||||
Memory::Write_U32(0x0D15EA5E, 0x00000020); // Another magic word
|
||||
Memory::Write_U32(0x00000001, 0x00000024); // Unknown
|
||||
Memory::Write_U32(Memory::REALRAM_SIZE, 0x00000028); // MEM1 size 24MB
|
||||
@ -253,12 +256,12 @@ bool CBoot::SetupWiiMemory(IVolume::ECountry country)
|
||||
Memory::Write_U32(0x8179b500, 0x000000f4); // __start
|
||||
Memory::Write_U32(0x0e7be2c0, 0x000000f8); // Bus speed
|
||||
Memory::Write_U32(0x2B73A840, 0x000000fc); // CPU speed
|
||||
Memory::Write_U16(0x0000, 0x000030e6); // Console type
|
||||
Memory::Write_U16(0x0000, 0x000030e6); // Console type
|
||||
Memory::Write_U32(0x00000000, 0x000030c0); // EXI
|
||||
Memory::Write_U32(0x00000000, 0x000030c4); // EXI
|
||||
Memory::Write_U32(0x00000000, 0x000030dc); // Time
|
||||
Memory::Write_U32(0x00000000, 0x000030d8); // Time
|
||||
Memory::Write_U16(0x8201, 0x000030e6); // Dev console / debug capable
|
||||
Memory::Write_U16(0x8201, 0x000030e6); // Dev console / debug capable
|
||||
Memory::Write_U32(0x00000000, 0x000030f0); // Apploader
|
||||
Memory::Write_U32(0x01800000, 0x00003100); // BAT
|
||||
Memory::Write_U32(0x01800000, 0x00003104); // BAT
|
||||
@ -275,7 +278,7 @@ bool CBoot::SetupWiiMemory(IVolume::ECountry country)
|
||||
// 40 is copied from 88 after running apploader
|
||||
Memory::Write_U32(0x00090204, 0x00003140); // IOS revision (IOS9, v2.4)
|
||||
Memory::Write_U32(0x00062507, 0x00003144); // IOS date in USA format (June 25, 2007)
|
||||
Memory::Write_U16(0x0113, 0x0000315e); // Apploader
|
||||
Memory::Write_U16(0x0113, 0x0000315e); // Apploader
|
||||
Memory::Write_U32(0x0000FF16, 0x00003158); // DDR ram vendor code
|
||||
Memory::Write_U32(0x00000000, 0x00003160); // Init semaphore (sysmenu waits for this to clear)
|
||||
Memory::Write_U32(0x00090204, 0x00003188); // Expected IOS revision
|
||||
@ -290,7 +293,7 @@ bool CBoot::SetupWiiMemory(IVolume::ECountry country)
|
||||
// Clear exception handler. Why? Don't we begin with only zeros?
|
||||
for (int i = 0x3000; i <= 0x3038; i += 4)
|
||||
{
|
||||
Memory::Write_U32(0x00000000, 0x80000000 + i);
|
||||
Memory::Write_U32(0x00000000, i);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -314,7 +317,7 @@ bool CBoot::EmulatedBS2_Wii()
|
||||
// values as the game boots. This location keep the 4 byte ID for as long
|
||||
// as the game is running. The 6 byte ID at 0x00 is overwritten sometime
|
||||
// after this check during booting.
|
||||
VolumeHandler::ReadToPtr(Memory::GetPointer(0x3180), 0, 4, true);
|
||||
DVDInterface::DVDRead(0, 0x3180, 4, true);
|
||||
|
||||
// Execute the apploader
|
||||
bool apploaderRan = false;
|
||||
@ -323,9 +326,12 @@ bool CBoot::EmulatedBS2_Wii()
|
||||
// Set up MSR and the BAT SPR registers.
|
||||
UReg_MSR& m_MSR = ((UReg_MSR&)PowerPC::ppcState.msr);
|
||||
m_MSR.FP = 1;
|
||||
m_MSR.DR = 1;
|
||||
m_MSR.IR = 1;
|
||||
m_MSR.EE = 1;
|
||||
PowerPC::ppcState.spr[SPR_IBAT0U] = 0x80001fff;
|
||||
PowerPC::ppcState.spr[SPR_IBAT0L] = 0x00000002;
|
||||
PowerPC::ppcState.spr[SPR_IBAT4L] = 0x90001fff;
|
||||
PowerPC::ppcState.spr[SPR_IBAT4U] = 0x90001fff;
|
||||
PowerPC::ppcState.spr[SPR_IBAT4L] = 0x10000002;
|
||||
PowerPC::ppcState.spr[SPR_DBAT0U] = 0x80001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT0L] = 0x00000002;
|
||||
@ -336,9 +342,9 @@ bool CBoot::EmulatedBS2_Wii()
|
||||
PowerPC::ppcState.spr[SPR_DBAT5U] = 0xd0001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT5L] = 0x1000002a;
|
||||
|
||||
Memory::Write_U32(0x4c000064, 0x80000300); // Write default DFI Handler: rfi
|
||||
Memory::Write_U32(0x4c000064, 0x80000800); // Write default FPU Handler: rfi
|
||||
Memory::Write_U32(0x4c000064, 0x80000C00); // Write default Syscall Handler: rfi
|
||||
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
|
||||
|
||||
HLE::Patch(0x81300000, "OSReport"); // HLE OSReport for Apploader
|
||||
|
||||
@ -354,7 +360,7 @@ bool CBoot::EmulatedBS2_Wii()
|
||||
ERROR_LOG(BOOT, "Invalid apploader. Probably your image is corrupted.");
|
||||
return false;
|
||||
}
|
||||
VolumeHandler::ReadToPtr(Memory::GetPointer(0x81200000), iAppLoaderOffset + 0x20, iAppLoaderSize, true);
|
||||
DVDInterface::DVDRead(iAppLoaderOffset + 0x20, 0x01200000, iAppLoaderSize, true);
|
||||
|
||||
//call iAppLoaderEntry
|
||||
DEBUG_LOG(BOOT, "Call iAppLoaderEntry");
|
||||
@ -364,9 +370,9 @@ bool CBoot::EmulatedBS2_Wii()
|
||||
PowerPC::ppcState.gpr[4] = iAppLoaderFuncAddr + 4;
|
||||
PowerPC::ppcState.gpr[5] = iAppLoaderFuncAddr + 8;
|
||||
RunFunction(iAppLoaderEntry);
|
||||
u32 iAppLoaderInit = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr+0);
|
||||
u32 iAppLoaderMain = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr+4);
|
||||
u32 iAppLoaderClose = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr+8);
|
||||
u32 iAppLoaderInit = PowerPC::Read_U32(iAppLoaderFuncAddr + 0);
|
||||
u32 iAppLoaderMain = PowerPC::Read_U32(iAppLoaderFuncAddr + 4);
|
||||
u32 iAppLoaderClose = PowerPC::Read_U32(iAppLoaderFuncAddr + 8);
|
||||
|
||||
// iAppLoaderInit
|
||||
DEBUG_LOG(BOOT, "Run iAppLoaderInit");
|
||||
@ -387,9 +393,9 @@ bool CBoot::EmulatedBS2_Wii()
|
||||
|
||||
RunFunction(iAppLoaderMain);
|
||||
|
||||
u32 iRamAddress = Memory::ReadUnchecked_U32(0x81300004);
|
||||
u32 iLength = Memory::ReadUnchecked_U32(0x81300008);
|
||||
u32 iDVDOffset = Memory::ReadUnchecked_U32(0x8130000c) << 2;
|
||||
u32 iRamAddress = PowerPC::Read_U32(0x81300004);
|
||||
u32 iLength = PowerPC::Read_U32(0x81300008);
|
||||
u32 iDVDOffset = PowerPC::Read_U32(0x8130000c) << 2;
|
||||
|
||||
INFO_LOG(BOOT, "DVDRead: offset: %08x memOffset: %08x length: %i", iDVDOffset, iRamAddress, iLength);
|
||||
DVDInterface::DVDRead(iDVDOffset, iRamAddress, iLength, true);
|
||||
@ -404,8 +410,8 @@ bool CBoot::EmulatedBS2_Wii()
|
||||
// Pass the "#002 check"
|
||||
// Apploader writes the IOS version and revision here, we copy it
|
||||
// Fake IOSv9 r2.4 if no version is found (elf loading)
|
||||
u32 firmwareVer = Memory::Read_U32(0x80003188);
|
||||
Memory::Write_U32(firmwareVer ? firmwareVer : 0x00090204, 0x00003140);
|
||||
u32 firmwareVer = PowerPC::Read_U32(0x80003188);
|
||||
PowerPC::Write_U32(firmwareVer ? firmwareVer : 0x00090204, 0x80003140);
|
||||
|
||||
// Load patches and run startup patches
|
||||
PatchEngine::LoadPatches();
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "Core/Boot/Boot_DOL.h"
|
||||
#include "Core/HW/Memmap.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
CDolLoader::CDolLoader(u8* _pBuffer, u32 _Size)
|
||||
: m_isWii(false)
|
||||
|
@ -107,7 +107,7 @@ bool CBoot::Boot_WiiWAD(const std::string& _pFilename)
|
||||
pDolLoader = std::make_unique<CDolLoader>(pContent->m_Filename);
|
||||
}
|
||||
pDolLoader->Load();
|
||||
PC = pDolLoader->GetEntryPoint() | 0x80000000;
|
||||
PC = pDolLoader->GetEntryPoint();
|
||||
|
||||
// Pass the "#002 check"
|
||||
// Apploader should write the IOS version and revision to 0x3140, and compare it
|
||||
|
Reference in New Issue
Block a user