diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp index ec5577408f..dd8eeb5c7d 100644 --- a/Source/Core/Core/Boot/Boot.cpp +++ b/Source/Core/Core/Boot/Boot.cpp @@ -420,9 +420,13 @@ bool CBoot::BootUp() // Poor man's bootup if (_StartupPara.bWii) - SetupWiiMemory(); + { + SetupWiiMemory(0x0000000100000050ULL); + } else + { EmulatedBS2_GC(true); + } Load_FST(_StartupPara.bWii); if (!Boot_ELF(_StartupPara.m_strFilename)) diff --git a/Source/Core/Core/Boot/Boot.h b/Source/Core/Core/Boot/Boot.h index 0388e07f11..6618036e3c 100644 --- a/Source/Core/Core/Boot/Boot.h +++ b/Source/Core/Core/Boot/Boot.h @@ -52,5 +52,5 @@ private: static bool Load_BS2(const std::string& _rBootROMFilename); static void Load_FST(bool _bIsWii); - static bool SetupWiiMemory(); + static bool SetupWiiMemory(u64 ios_title_id); }; diff --git a/Source/Core/Core/Boot/Boot_BS2Emu.cpp b/Source/Core/Core/Boot/Boot_BS2Emu.cpp index d6784b6ec0..78d1b0001d 100644 --- a/Source/Core/Core/Boot/Boot_BS2Emu.cpp +++ b/Source/Core/Core/Boot/Boot_BS2Emu.cpp @@ -17,6 +17,8 @@ #include "Core/HW/DVDInterface.h" #include "Core/HW/EXI/EXI_DeviceIPL.h" #include "Core/HW/Memmap.h" +#include "Core/IOS/ES/Formats.h" +#include "Core/IOS/IPC.h" #include "Core/MemTools.h" #include "Core/PatchEngine.h" #include "Core/PowerPC/PowerPC.h" @@ -182,7 +184,7 @@ bool CBoot::EmulatedBS2_GC(bool skipAppLoader) return true; } -bool CBoot::SetupWiiMemory() +bool CBoot::SetupWiiMemory(u64 ios_title_id) { static const std::map region_settings = { {DiscIO::Region::NTSC_J, {"JPN", "NTSC", "JP", "LJ"}}, @@ -280,25 +282,11 @@ bool CBoot::SetupWiiMemory() Memory::Write_U32(0x00000000, 0x000030d8); // Time 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 - Memory::Write_U32(0x00000000, 0x0000310c); // Init - Memory::Write_U32(0x8179d500, 0x00003110); // Init - Memory::Write_U32(0x04000000, 0x00003118); // Unknown - Memory::Write_U32(0x04000000, 0x0000311c); // BAT - Memory::Write_U32(0x93600000, 0x00003120); // BAT - Memory::Write_U32(0x90000800, 0x00003124); // Init - MEM2 low - Memory::Write_U32(0x935e0000, 0x00003128); // Init - MEM2 high - Memory::Write_U32(0x935e0000, 0x00003130); // IOS MEM2 low - Memory::Write_U32(0x93600000, 0x00003134); // IOS MEM2 high - Memory::Write_U32(0x00000012, 0x00003138); // Console type - // 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_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 + + if (!IOS::HLE::SetupMemory(ios_title_id)) + { + return false; + } Memory::Write_U8(0x80, 0x0000315c); // OSInit Memory::Write_U16(0x0000, 0x000030e0); // PADInit @@ -322,125 +310,119 @@ bool CBoot::SetupWiiMemory() bool CBoot::EmulatedBS2_Wii() { INFO_LOG(BOOT, "Faking Wii BS2..."); + if (!DVDInterface::VolumeIsValid()) + return false; - // Setup Wii memory - if (!SetupWiiMemory()) + if (DVDInterface::GetVolume().GetVolumeType() != DiscIO::Platform::WII_DISC) + return false; + + // This is some kind of consistency check that is compared to the 0x00 + // values as the game boots. This location keeps 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. + DVDRead(0, 0x3180, 4, true); + + // 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; + PowerPC::DBATUpdated(); + PowerPC::IBATUpdated(); + + 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 + + PowerPC::ppcState.gpr[1] = 0x816ffff0; // StackPointer + + std::vector tmd = DVDInterface::GetVolume().GetTMD(); + + IOS::HLE::TMDReader tmd_reader{std::move(tmd)}; + + if (!SetupWiiMemory(tmd_reader.GetIOSId())) return false; // Execute the apploader - bool apploaderRan = false; - if (DVDInterface::VolumeIsValid() && - DVDInterface::GetVolume().GetVolumeType() == DiscIO::Platform::WII_DISC) + const u32 apploader_offset = 0x2440; // 0x1c40; + + // Load Apploader to Memory + const DiscIO::IVolume& volume = DVDInterface::GetVolume(); + u32 apploader_entry, apploader_size; + if (!volume.ReadSwapped(apploader_offset + 0x10, &apploader_entry, true) || + !volume.ReadSwapped(apploader_offset + 0x14, &apploader_size, true) || + apploader_entry == (u32)-1 || apploader_size == (u32)-1) { - // This is some kind of consistency check that is compared to the 0x00 - // values as the game boots. This location keeps 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. - DVDRead(0, 0x3180, 4, true); - - // 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; - PowerPC::DBATUpdated(); - PowerPC::IBATUpdated(); - - 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 - - PowerPC::ppcState.gpr[1] = 0x816ffff0; // StackPointer - - const u32 apploader_offset = 0x2440; // 0x1c40; - - // Load Apploader to Memory - const DiscIO::IVolume& volume = DVDInterface::GetVolume(); - u32 apploader_entry, apploader_size; - if (!volume.ReadSwapped(apploader_offset + 0x10, &apploader_entry, true) || - !volume.ReadSwapped(apploader_offset + 0x14, &apploader_size, true) || - apploader_entry == (u32)-1 || apploader_size == (u32)-1) - { - ERROR_LOG(BOOT, "Invalid apploader. Probably your image is corrupted."); - return false; - } - DVDRead(apploader_offset + 0x20, 0x01200000, apploader_size, true); - - // call iAppLoaderEntry - DEBUG_LOG(BOOT, "Call iAppLoaderEntry"); - - u32 iAppLoaderFuncAddr = 0x80004000; - PowerPC::ppcState.gpr[3] = iAppLoaderFuncAddr + 0; - PowerPC::ppcState.gpr[4] = iAppLoaderFuncAddr + 4; - PowerPC::ppcState.gpr[5] = iAppLoaderFuncAddr + 8; - RunFunction(apploader_entry); - 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"); - PowerPC::ppcState.gpr[3] = 0x81300000; - RunFunction(iAppLoaderInit); - - // Let the apploader load the exe to memory. At this point I get an unknown IPC command - // (command zero) when I load Wii Sports or other games a second time. I don't notice - // any side effects however. It's a little disconcerting however that Start after Stop - // behaves differently than the first Start after starting Dolphin. It means something - // was not reset correctly. - DEBUG_LOG(BOOT, "Run iAppLoaderMain"); - do - { - PowerPC::ppcState.gpr[3] = 0x81300004; - PowerPC::ppcState.gpr[4] = 0x81300008; - PowerPC::ppcState.gpr[5] = 0x8130000c; - - RunFunction(iAppLoaderMain); - - 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); - DVDRead(iDVDOffset, iRamAddress, iLength, true); - } while (PowerPC::ppcState.gpr[3] != 0x00); - - // iAppLoaderClose - DEBUG_LOG(BOOT, "Run iAppLoaderClose"); - RunFunction(iAppLoaderClose); - - apploaderRan = true; - - // 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 = PowerPC::Read_U32(0x80003188); - PowerPC::Write_U32(firmwareVer ? firmwareVer : 0x00090204, 0x80003140); - - // Load patches and run startup patches - PatchEngine::LoadPatches(); - - // return - PC = PowerPC::ppcState.gpr[3]; + ERROR_LOG(BOOT, "Invalid apploader. Probably your image is corrupted."); + return false; } + DVDRead(apploader_offset + 0x20, 0x01200000, apploader_size, true); - return apploaderRan; + // call iAppLoaderEntry + DEBUG_LOG(BOOT, "Call iAppLoaderEntry"); + + u32 iAppLoaderFuncAddr = 0x80004000; + PowerPC::ppcState.gpr[3] = iAppLoaderFuncAddr + 0; + PowerPC::ppcState.gpr[4] = iAppLoaderFuncAddr + 4; + PowerPC::ppcState.gpr[5] = iAppLoaderFuncAddr + 8; + RunFunction(apploader_entry); + 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"); + PowerPC::ppcState.gpr[3] = 0x81300000; + RunFunction(iAppLoaderInit); + + // Let the apploader load the exe to memory. At this point I get an unknown IPC command + // (command zero) when I load Wii Sports or other games a second time. I don't notice + // any side effects however. It's a little disconcerting however that Start after Stop + // behaves differently than the first Start after starting Dolphin. It means something + // was not reset correctly. + DEBUG_LOG(BOOT, "Run iAppLoaderMain"); + do + { + PowerPC::ppcState.gpr[3] = 0x81300004; + PowerPC::ppcState.gpr[4] = 0x81300008; + PowerPC::ppcState.gpr[5] = 0x8130000c; + + RunFunction(iAppLoaderMain); + + 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); + DVDRead(iDVDOffset, iRamAddress, iLength, true); + } while (PowerPC::ppcState.gpr[3] != 0x00); + + // iAppLoaderClose + DEBUG_LOG(BOOT, "Run iAppLoaderClose"); + RunFunction(iAppLoaderClose); + + // Load patches and run startup patches + PatchEngine::LoadPatches(); + + // return + PC = PowerPC::ppcState.gpr[3]; + return true; } // Returns true if apploader has run successfully diff --git a/Source/Core/Core/Boot/Boot_WiiWAD.cpp b/Source/Core/Core/Boot/Boot_WiiWAD.cpp index 4869353bf4..0ebc47de6e 100644 --- a/Source/Core/Core/Boot/Boot_WiiWAD.cpp +++ b/Source/Core/Core/Boot/Boot_WiiWAD.cpp @@ -89,7 +89,9 @@ bool CBoot::Boot_WiiWAD(const std::string& _pFilename) if (titleID == TITLEID_SYSMENU) IOS::HLE::HLE_IPC_CreateVirtualFATFilesystem(); // setup Wii memory - if (!SetupWiiMemory()) + + u64 ios_title_id = 0x0000000100000000ULL | ContentLoader.GetIosVersion(); + if (!SetupWiiMemory(ios_title_id)) return false; // DOL const DiscIO::SNANDContent* pContent = diff --git a/Source/Core/Core/IOS/ES/ES.cpp b/Source/Core/Core/IOS/ES/ES.cpp index 9d069c33e0..048b1a84c5 100644 --- a/Source/Core/Core/IOS/ES/ES.cpp +++ b/Source/Core/Core/IOS/ES/ES.cpp @@ -1030,7 +1030,6 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request) _dbg_assert_(IOS_ES, request.in_vectors.size() == 2); bool bSuccess = false; bool bReset = false; - u16 IOSv = 0xffff; u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); u32 view = Memory::Read_U32(request.in_vectors[1].address); @@ -1075,19 +1074,17 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request) PanicAlertT("IOCTL_ES_LAUNCH: The DOL file is invalid!"); bSuccess = false; } - - IOSv = ContentLoader.GetIosVersion(); } } } else // IOS, MIOS, BC etc { - // TODO: fixme - // The following is obviously a hack - // Lie to mem about loading a different IOS - // someone with an affected game should test - IOSv = TitleID & 0xffff; - bSuccess = true; + // We need to reset any open resources and do the memory setup + // IOS does on launch. + if (SetupMemory(TitleID)) + { + bSuccess = true; + } } if (!bSuccess) { @@ -1128,15 +1125,6 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request) delete[] wiiMoteConnected; SetDefaultContentFile(tContentFile); } - // Pass the "#002 check" - // Apploader should write the IOS version and revision to 0x3140, and compare it - // to 0x3188 to pass the check, but we don't do it, and i don't know where to read the IOS - // rev... - // Currently we just write 0xFFFF for the revision, copy manually and it works fine :p - // TODO : figure it correctly : where should we read the IOS rev that the wad "needs" ? - Memory::Write_U16(IOSv, 0x00003140); - Memory::Write_U16(0xFFFF, 0x00003142); - Memory::Write_U32(Memory::Read_U32(0x00003140), 0x00003188); // Note: If we just reset the PPC, don't write anything to the command buffer. This // could clobber the DOL we just loaded. diff --git a/Source/Core/Core/IOS/IPC.cpp b/Source/Core/Core/IOS/IPC.cpp index b5b054e707..d309ea5c3a 100644 --- a/Source/Core/Core/IOS/IPC.cpp +++ b/Source/Core/Core/IOS/IPC.cpp @@ -16,13 +16,15 @@ // Ioctlv: Depends on the handler // Replies may be sent immediately or asynchronously for ioctls and ioctlvs. +#include +#include +#include #include #include #include #include #include #include -#include #include "Common/Assert.h" #include "Common/ChunkFile.h" @@ -85,6 +87,306 @@ static u64 s_last_reply_time; static constexpr u64 ENQUEUE_REQUEST_FLAG = 0x100000000ULL; static constexpr u64 ENQUEUE_ACKNOWLEDGEMENT_FLAG = 0x200000000ULL; + +struct IosMemoryValues +{ + u16 ios_number; + u32 ios_version; + u32 ios_date; + u32 mem1_physical_size; + u32 mem1_simulated_size; + u32 mem1_end; + u32 mem1_arena_begin; + u32 mem1_arena_end; + u32 mem2_physical_size; + u32 mem2_simulated_size; + u32 mem2_end; + u32 mem2_arena_begin; + u32 mem2_arena_end; + u32 ipc_buffer_begin; + u32 ipc_buffer_end; + u32 hollywood_revision; + u32 ram_vendor; + u32 unknown_begin; + u32 unknown_end; +}; + +constexpr u32 ADDR_MEM1_SIZE = 0x3100; +constexpr u32 ADDR_MEM1_SIM_SIZE = 0x3104; +constexpr u32 ADDR_MEM1_END = 0x3108; +constexpr u32 ADDR_MEM1_ARENA_BEGIN = 0x310c; +constexpr u32 ADDR_MEM1_ARENA_END = 0x3110; +constexpr u32 ADDR_PH1 = 0x3114; +constexpr u32 ADDR_MEM2_SIZE = 0x3118; +constexpr u32 ADDR_MEM2_SIM_SIZE = 0x311c; +constexpr u32 ADDR_MEM2_END = 0x3120; +constexpr u32 ADDR_MEM2_ARENA_BEGIN = 0x3124; +constexpr u32 ADDR_MEM2_ARENA_END = 0x3128; +constexpr u32 ADDR_PH2 = 0x312c; +constexpr u32 ADDR_IPC_BUFFER_BEGIN = 0x3130; +constexpr u32 ADDR_IPC_BUFFER_END = 0x3134; +constexpr u32 ADDR_HOLLYWOOD_REVISION = 0x3138; +constexpr u32 ADDR_PH3 = 0x313c; +constexpr u32 ADDR_IOS_VERSION = 0x3140; +constexpr u32 ADDR_IOS_DATE = 0x3144; +constexpr u32 ADDR_UNKNOWN_BEGIN = 0x3148; +constexpr u32 ADDR_UNKNOWN_END = 0x314c; +constexpr u32 ADDR_PH4 = 0x3150; +constexpr u32 ADDR_PH5 = 0x3154; +constexpr u32 ADDR_RAM_VENDOR = 0x3158; +constexpr u32 ADDR_BOOT_FLAG = 0x315c; +constexpr u32 ADDR_APPLOADER_FLAG = 0x315d; +constexpr u32 ADDR_DEVKIT_BOOT_PROGRAM_VERSION = 0x315e; +constexpr u32 ADDR_SYSMENU_SYNC = 0x3160; + +constexpr u32 MEM1_SIZE = 0x01800000; +constexpr u32 MEM1_END = 0x81800000; +constexpr u32 MEM1_ARENA_BEGIN = 0x00000000; +constexpr u32 MEM1_ARENA_END = 0x81800000; +constexpr u32 MEM2_SIZE = 0x4000000; +constexpr u32 MEM2_ARENA_BEGIN = 0x90000800; +constexpr u32 HOLLYWOOD_REVISION = 0x00000011; +constexpr u32 PLACEHOLDER = 0xDEADBEEF; +constexpr u32 RAM_VENDOR = 0x0000FF01; +constexpr u32 RAM_VENDOR_MIOS = 0xCAFEBABE; + +// These values were manually extracted from the relevant IOS binaries. +// The writes are usually contained in a single function that +// mostly writes raw literals to the relevant locations. +// e.g. IOS9, version 1034, content id 0x00000006, function at 0xffff6884 +constexpr std::array ios_memory_values = { + {{ + 9, 0x9040a, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, + 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, + RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, + }, + { + 12, 0xc020e, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, + 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, + RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, + }, + { + 13, 0xd0408, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, + 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, + RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, + }, + { + 14, 0xe0408, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, + 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, + RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, + }, + { + 15, 0xf0408, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, + 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, + RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, + }, + { + 17, 0x110408, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, + 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, + RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, + }, + { + 21, 0x15040f, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, + 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, + RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, + }, + { + 22, 0x16050e, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, + 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, + RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, + }, + { + 28, 0x1c070f, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93800000, MEM2_ARENA_BEGIN, + 0x937E0000, 0x937E0000, 0x93800000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93800000, 0x93820000, + }, + { + 31, 0x1f0e18, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, + }, + { + 33, 0x210e18, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, + }, + { + 34, 0x220e18, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, + }, + { + 35, 0x230e18, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, + }, + { + 36, 0x240e18, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, + }, + { + 37, 0x25161f, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, + }, + { + 38, 0x26101c, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, + }, + { + 41, 0x290e17, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, + }, + { + 43, 0x2b0e17, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, + }, + { + 45, 0x2d0e17, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, + }, + { + 46, 0x2e0e17, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, + }, + { + 48, 0x30101c, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, + }, + { + 53, 0x35161f, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, + }, + { + 55, 0x37161f, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, + }, + { + 56, 0x38161e, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, + }, + { + 57, 0x39171f, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, + }, + { + 58, 0x311820, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, + }, + { + 59, 0x3b1c21, 0x101811, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, + }, + { + 61, 0x3d161e, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, + }, + { + 62, 0x3e191e, 0x022712, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, + }, + { + 80, 0x501b20, 0x030310, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, + }, + { + 257, + 0x707, + 0x82209, + MEM1_SIZE, + MEM1_SIZE, + MEM1_END, + MEM1_ARENA_BEGIN, + MEM1_ARENA_END, + MEM2_SIZE, + MEM2_SIZE, + 0x93600000, + MEM2_ARENA_BEGIN, + 0x935E0000, + 0x935E0000, + 0x93600000, + HOLLYWOOD_REVISION, + RAM_VENDOR_MIOS, + PLACEHOLDER, + PLACEHOLDER, + }}}; + static void EnqueueEvent(u64 userdata, s64 cycles_late = 0) { if (userdata & ENQUEUE_ACKNOWLEDGEMENT_FLAG) @@ -109,6 +411,48 @@ static void SDIO_EventNotify_CPUThread(u64 userdata, s64 cycles_late) device->EventNotify(); } +bool SetupMemory(u64 ios_title_id) +{ + auto target_imv = std::find_if( + ios_memory_values.begin(), ios_memory_values.end(), + [&](const IosMemoryValues& imv) { return imv.ios_number == (ios_title_id & 0xffff); }); + + if (target_imv == ios_memory_values.end()) + { + ERROR_LOG(IOS, "Unknown IOS version: %016" PRIx64, ios_title_id); + return false; + } + + Memory::Write_U32(target_imv->mem1_physical_size, ADDR_MEM1_SIZE); + Memory::Write_U32(target_imv->mem1_simulated_size, ADDR_MEM1_SIM_SIZE); + Memory::Write_U32(target_imv->mem1_end, ADDR_MEM1_END); + Memory::Write_U32(target_imv->mem1_arena_begin, ADDR_MEM1_ARENA_BEGIN); + Memory::Write_U32(target_imv->mem1_arena_end, ADDR_MEM1_ARENA_END); + Memory::Write_U32(PLACEHOLDER, ADDR_PH1); + Memory::Write_U32(target_imv->mem2_physical_size, ADDR_MEM2_SIZE); + Memory::Write_U32(target_imv->mem2_simulated_size, ADDR_MEM2_SIM_SIZE); + Memory::Write_U32(target_imv->mem2_end, ADDR_MEM2_END); + Memory::Write_U32(target_imv->mem2_arena_begin, ADDR_MEM2_ARENA_BEGIN); + Memory::Write_U32(target_imv->mem2_arena_end, ADDR_MEM2_ARENA_END); + Memory::Write_U32(PLACEHOLDER, ADDR_PH2); + Memory::Write_U32(target_imv->ipc_buffer_begin, ADDR_IPC_BUFFER_BEGIN); + Memory::Write_U32(target_imv->ipc_buffer_end, ADDR_IPC_BUFFER_END); + Memory::Write_U32(target_imv->hollywood_revision, ADDR_HOLLYWOOD_REVISION); + Memory::Write_U32(PLACEHOLDER, ADDR_PH3); + Memory::Write_U32(target_imv->ios_version, ADDR_IOS_VERSION); + Memory::Write_U32(target_imv->ios_date, ADDR_IOS_DATE); + Memory::Write_U32(target_imv->unknown_begin, ADDR_UNKNOWN_BEGIN); + Memory::Write_U32(target_imv->unknown_end, ADDR_UNKNOWN_END); + Memory::Write_U32(PLACEHOLDER, ADDR_PH4); + Memory::Write_U32(PLACEHOLDER, ADDR_PH5); + Memory::Write_U32(target_imv->ram_vendor, ADDR_RAM_VENDOR); + Memory::Write_U8(0xDE, ADDR_BOOT_FLAG); + Memory::Write_U8(0xAD, ADDR_APPLOADER_FLAG); + Memory::Write_U16(0xBEEF, ADDR_DEVKIT_BOOT_PROGRAM_VERSION); + Memory::Write_U32(0x00000000, ADDR_SYSMENU_SYNC); + return true; +} + static u32 num_devices; template diff --git a/Source/Core/Core/IOS/IPC.h b/Source/Core/Core/IOS/IPC.h index c6cea1ef99..1c6146b793 100644 --- a/Source/Core/Core/IOS/IPC.h +++ b/Source/Core/Core/IOS/IPC.h @@ -51,6 +51,8 @@ void Init(); // Needs to be called after Reset(true) to recreate the device tree void Reinit(); +bool SetupMemory(u64 ios_title_id); + // Shutdown void Shutdown();