diff --git a/Source/Core/Common/MemArena.cpp b/Source/Core/Common/MemArena.cpp index 544f9354cf..fc910daf9c 100644 --- a/Source/Core/Common/MemArena.cpp +++ b/Source/Core/Common/MemArena.cpp @@ -127,12 +127,12 @@ void MemArena::ReleaseView(void* view, size_t size) } -u8* MemArena::Find4GBBase() +u8* MemArena::FindMemoryBase() { #if _ARCH_64 #ifdef _WIN32 // 64 bit - u8* base = (u8*)VirtualAlloc(0, 0xE1000000, MEM_RESERVE, PAGE_READWRITE); + u8* base = (u8*)VirtualAlloc(0, 0x400000000, MEM_RESERVE, PAGE_READWRITE); VirtualFree(base, 0, MEM_RELEASE); return base; #else @@ -250,7 +250,7 @@ u8 *MemoryMap_Setup(MemoryView *views, int num_views, u32 flags, MemArena *arena arena->GrabSHMSegment(total_mem); // Now, create views in high memory where there's plenty of space. - u8 *base = MemArena::Find4GBBase(); + u8 *base = MemArena::FindMemoryBase(); // This really shouldn't fail - in 64-bit, there will always be enough // address space. if (!Memory_TryBase(base, views, num_views, flags, arena)) diff --git a/Source/Core/Common/MemArena.h b/Source/Core/Common/MemArena.h index 67482432fd..c458e86308 100644 --- a/Source/Core/Common/MemArena.h +++ b/Source/Core/Common/MemArena.h @@ -24,8 +24,8 @@ public: void *CreateView(s64 offset, size_t size, void *base = nullptr); void ReleaseView(void *view, size_t size); - // This only finds 1 GB in 32-bit - static u8 *Find4GBBase(); + // This finds 1 GB in 32-bit, 16 GB in 64-bit. + static u8 *FindMemoryBase(); private: #ifdef _WIN32 @@ -44,7 +44,7 @@ enum { struct MemoryView { u8** out_ptr; - u32 virtual_address; + u64 virtual_address; u32 size; u32 flags; void* mapped_ptr; diff --git a/Source/Core/Core/ActionReplay.cpp b/Source/Core/Core/ActionReplay.cpp index 51dd2e25f0..e77af7f5c4 100644 --- a/Source/Core/Core/ActionReplay.cpp +++ b/Source/Core/Core/ActionReplay.cpp @@ -30,7 +30,7 @@ #include "Core/ARDecrypt.h" #include "Core/ConfigManager.h" #include "Core/Core.h" -#include "Core/HW/Memmap.h" +#include "Core/PowerPC/PowerPC.h" namespace ActionReplay { @@ -320,7 +320,7 @@ static bool Subtype_RamWriteAndFill(const ARAddr& addr, const u32 data) u32 repeat = data >> 8; for (u32 i = 0; i <= repeat; ++i) { - Memory::Write_U8(data & 0xFF, new_addr + i); + PowerPC::HostWrite_U8(data & 0xFF, new_addr + i); LogInfo("Wrote %08x to address %08x", data & 0xFF, new_addr + i); } LogInfo("--------"); @@ -334,7 +334,7 @@ static bool Subtype_RamWriteAndFill(const ARAddr& addr, const u32 data) u32 repeat = data >> 16; for (u32 i = 0; i <= repeat; ++i) { - Memory::Write_U16(data & 0xFFFF, new_addr + i * 2); + PowerPC::HostWrite_U16(data & 0xFFFF, new_addr + i * 2); LogInfo("Wrote %08x to address %08x", data & 0xFFFF, new_addr + i * 2); } LogInfo("--------"); @@ -345,7 +345,7 @@ static bool Subtype_RamWriteAndFill(const ARAddr& addr, const u32 data) case DATATYPE_32BIT: // Dword write LogInfo("32-bit Write"); LogInfo("--------"); - Memory::Write_U32(data, new_addr); + PowerPC::HostWrite_U32(data, new_addr); LogInfo("Wrote %08x to address %08x", data, new_addr); LogInfo("--------"); break; @@ -364,7 +364,7 @@ static bool Subtype_RamWriteAndFill(const ARAddr& addr, const u32 data) static bool Subtype_WriteToPointer(const ARAddr& addr, const u32 data) { const u32 new_addr = addr.GCAddress(); - const u32 ptr = Memory::Read_U32(new_addr); + const u32 ptr = PowerPC::HostRead_U32(new_addr); LogInfo("Hardware Address: %08x", new_addr); LogInfo("Size: %08x", addr.size); @@ -380,7 +380,7 @@ static bool Subtype_WriteToPointer(const ARAddr& addr, const u32 data) LogInfo("Pointer: %08x", ptr); LogInfo("Byte: %08x", thebyte); LogInfo("Offset: %08x", offset); - Memory::Write_U8(thebyte, ptr + offset); + PowerPC::HostWrite_U8(thebyte, ptr + offset); LogInfo("Wrote %08x to address %08x", thebyte, ptr + offset); LogInfo("--------"); break; @@ -395,7 +395,7 @@ static bool Subtype_WriteToPointer(const ARAddr& addr, const u32 data) LogInfo("Pointer: %08x", ptr); LogInfo("Byte: %08x", theshort); LogInfo("Offset: %08x", offset); - Memory::Write_U16(theshort, ptr + offset); + PowerPC::HostWrite_U16(theshort, ptr + offset); LogInfo("Wrote %08x to address %08x", theshort, ptr + offset); LogInfo("--------"); break; @@ -405,7 +405,7 @@ static bool Subtype_WriteToPointer(const ARAddr& addr, const u32 data) case DATATYPE_32BIT: LogInfo("Write 32-bit to pointer"); LogInfo("--------"); - Memory::Write_U32(data, ptr); + PowerPC::HostWrite_U32(data, ptr); LogInfo("Wrote %08x to address %08x", data, ptr); LogInfo("--------"); break; @@ -433,24 +433,24 @@ static bool Subtype_AddCode(const ARAddr& addr, const u32 data) case DATATYPE_8BIT: LogInfo("8-bit Add"); LogInfo("--------"); - Memory::Write_U8(Memory::Read_U8(new_addr) + data, new_addr); - LogInfo("Wrote %08x to address %08x", Memory::Read_U8(new_addr) + (data & 0xFF), new_addr); + PowerPC::HostWrite_U8(PowerPC::HostRead_U8(new_addr) + data, new_addr); + LogInfo("Wrote %08x to address %08x", PowerPC::HostRead_U8(new_addr) + (data & 0xFF), new_addr); LogInfo("--------"); break; case DATATYPE_16BIT: LogInfo("16-bit Add"); LogInfo("--------"); - Memory::Write_U16(Memory::Read_U16(new_addr) + data, new_addr); - LogInfo("Wrote %08x to address %08x", Memory::Read_U16(new_addr) + (data & 0xFFFF), new_addr); + PowerPC::HostWrite_U16(PowerPC::HostRead_U16(new_addr) + data, new_addr); + LogInfo("Wrote %08x to address %08x", PowerPC::HostRead_U16(new_addr) + (data & 0xFFFF), new_addr); LogInfo("--------"); break; case DATATYPE_32BIT: LogInfo("32-bit Add"); LogInfo("--------"); - Memory::Write_U32(Memory::Read_U32(new_addr) + data, new_addr); - LogInfo("Wrote %08x to address %08x", Memory::Read_U32(new_addr) + data, new_addr); + PowerPC::HostWrite_U32(PowerPC::HostRead_U32(new_addr) + data, new_addr); + LogInfo("Wrote %08x to address %08x", PowerPC::HostRead_U32(new_addr) + data, new_addr); LogInfo("--------"); break; @@ -459,10 +459,10 @@ static bool Subtype_AddCode(const ARAddr& addr, const u32 data) LogInfo("32-bit floating Add"); LogInfo("--------"); - const u32 read = Memory::Read_U32(new_addr); + const u32 read = PowerPC::HostRead_U32(new_addr); const float fread = *((float*)&read) + (float)data; // data contains an integer value const u32 newval = *((u32*)&fread); - Memory::Write_U32(newval, new_addr); + PowerPC::HostWrite_U32(newval, new_addr); LogInfo("Old Value %08x", read); LogInfo("Increment %08x", data); LogInfo("New value %08x", newval); @@ -517,7 +517,7 @@ static bool ZeroCode_FillAndSlide(const u32 val_last, const ARAddr& addr, const LogInfo("--------"); for (int i = 0; i < write_num; ++i) { - Memory::Write_U8(val & 0xFF, curr_addr); + PowerPC::HostWrite_U8(val & 0xFF, curr_addr); curr_addr += addr_incr; val += val_incr; LogInfo("Write %08x to address %08x", val & 0xFF, curr_addr); @@ -533,7 +533,7 @@ static bool ZeroCode_FillAndSlide(const u32 val_last, const ARAddr& addr, const LogInfo("--------"); for (int i=0; i < write_num; ++i) { - Memory::Write_U16(val & 0xFFFF, curr_addr); + PowerPC::HostWrite_U16(val & 0xFFFF, curr_addr); LogInfo("Write %08x to address %08x", val & 0xFFFF, curr_addr); curr_addr += addr_incr * 2; val += val_incr; @@ -548,7 +548,7 @@ static bool ZeroCode_FillAndSlide(const u32 val_last, const ARAddr& addr, const LogInfo("--------"); for (int i = 0; i < write_num; ++i) { - Memory::Write_U32(val, curr_addr); + PowerPC::HostWrite_U32(val, curr_addr); LogInfo("Write %08x to address %08x", val, curr_addr); curr_addr += addr_incr * 4; val += val_incr; @@ -586,8 +586,8 @@ static bool ZeroCode_MemoryCopy(const u32 val_last, const ARAddr& addr, const u3 LogInfo("--------"); for (int i = 0; i < 138; ++i) { - Memory::Write_U8(Memory::Read_U8(addr_src + i), addr_dest + i); - LogInfo("Wrote %08x to address %08x", Memory::Read_U8(addr_src + i), addr_dest + i); + PowerPC::HostWrite_U8(PowerPC::HostRead_U8(addr_src + i), addr_dest + i); + LogInfo("Wrote %08x to address %08x", PowerPC::HostRead_U8(addr_src + i), addr_dest + i); } LogInfo("--------"); } @@ -597,8 +597,8 @@ static bool ZeroCode_MemoryCopy(const u32 val_last, const ARAddr& addr, const u3 LogInfo("--------"); for (int i=0; i < num_bytes; ++i) { - Memory::Write_U8(Memory::Read_U8(addr_src + i), addr_dest + i); - LogInfo("Wrote %08x to address %08x", Memory::ReadUnchecked_U8(addr_src + i), addr_dest + i); + PowerPC::HostWrite_U8(PowerPC::HostRead_U8(addr_src + i), addr_dest + i); + LogInfo("Wrote %08x to address %08x", PowerPC::HostRead_U8(addr_src + i), addr_dest + i); } LogInfo("--------"); return true; @@ -709,16 +709,16 @@ static bool ConditionalCode(const ARAddr& addr, const u32 data, int* const pSkip switch (addr.size) { case DATATYPE_8BIT: - result = CompareValues((u32)Memory::Read_U8(new_addr), (data & 0xFF), addr.type); + result = CompareValues((u32)PowerPC::HostRead_U8(new_addr), (data & 0xFF), addr.type); break; case DATATYPE_16BIT: - result = CompareValues((u32)Memory::Read_U16(new_addr), (data & 0xFFFF), addr.type); + result = CompareValues((u32)PowerPC::HostRead_U16(new_addr), (data & 0xFFFF), addr.type); break; case DATATYPE_32BIT_FLOAT: case DATATYPE_32BIT: - result = CompareValues(Memory::Read_U32(new_addr), data, addr.type); + result = CompareValues(PowerPC::HostRead_U32(new_addr), data, addr.type); break; default: diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp index d2c8d53840..aecfe96ac8 100644 --- a/Source/Core/Core/Boot/Boot.cpp +++ b/Source/Core/Core/Boot/Boot.cpp @@ -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 diff --git a/Source/Core/Core/Boot/Boot_BS2Emu.cpp b/Source/Core/Core/Boot/Boot_BS2Emu.cpp index 260ae4c67a..8b7f52e5ef 100644 --- a/Source/Core/Core/Boot/Boot_BS2Emu.cpp +++ b/Source/Core/Core/Boot/Boot_BS2Emu.cpp @@ -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(); diff --git a/Source/Core/Core/Boot/Boot_DOL.cpp b/Source/Core/Core/Boot/Boot_DOL.cpp index 31050df12b..fbfa70e0c1 100644 --- a/Source/Core/Core/Boot/Boot_DOL.cpp +++ b/Source/Core/Core/Boot/Boot_DOL.cpp @@ -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) diff --git a/Source/Core/Core/Boot/Boot_WiiWAD.cpp b/Source/Core/Core/Boot/Boot_WiiWAD.cpp index f1afd7a82d..386ee3185a 100644 --- a/Source/Core/Core/Boot/Boot_WiiWAD.cpp +++ b/Source/Core/Core/Boot/Boot_WiiWAD.cpp @@ -107,7 +107,7 @@ bool CBoot::Boot_WiiWAD(const std::string& _pFilename) pDolLoader = std::make_unique(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 diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index 396cfa2a8a..b3c0ec8fba 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -109,7 +109,6 @@ set(SRCS ActionReplay.cpp HW/GPFifo.cpp HW/HW.cpp HW/Memmap.cpp - HW/MemmapFunctions.cpp HW/MemoryInterface.cpp HW/MMIO.cpp HW/ProcessorInterface.cpp @@ -153,6 +152,7 @@ set(SRCS ActionReplay.cpp IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp IPC_HLE/WII_IPC_HLE_WiiMote.cpp IPC_HLE/WiiMote_HID_Attr.cpp + PowerPC/MMU.cpp PowerPC/PowerPC.cpp PowerPC/PPCAnalyst.cpp PowerPC/PPCCache.cpp diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj index 67d8257e2a..ffa5f87a6e 100644 --- a/Source/Core/Core/Core.vcxproj +++ b/Source/Core/Core/Core.vcxproj @@ -140,7 +140,6 @@ - @@ -245,6 +244,7 @@ + diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters index d981320db5..f2d722ff92 100644 --- a/Source/Core/Core/Core.vcxproj.filters +++ b/Source/Core/Core/Core.vcxproj.filters @@ -512,9 +512,6 @@ HW %28Flipper/Hollywood%29 - - HW %28Flipper/Hollywood%29 - HW %28Flipper/Hollywood%29 @@ -726,6 +723,8 @@ HW %28Flipper/Hollywood%29\GCKeyboard + + PowerPC diff --git a/Source/Core/Core/Debugger/Debugger_SymbolMap.cpp b/Source/Core/Core/Debugger/Debugger_SymbolMap.cpp index 29255a307a..4a9ec98117 100644 --- a/Source/Core/Core/Debugger/Debugger_SymbolMap.cpp +++ b/Source/Core/Core/Debugger/Debugger_SymbolMap.cpp @@ -39,27 +39,27 @@ void AddAutoBreakpoints() // Returns true if the address is not a valid RAM address or NULL. static bool IsStackBottom(u32 addr) { - return !addr || !Memory::IsRAMAddress(addr); + return !addr || !PowerPC::HostIsRAMAddress(addr); } static void WalkTheStack(const std::function& stack_step) { if (!IsStackBottom(PowerPC::ppcState.gpr[1])) { - u32 addr = Memory::ReadUnchecked_U32(PowerPC::ppcState.gpr[1]); // SP + u32 addr = PowerPC::HostRead_U32(PowerPC::ppcState.gpr[1]); // SP // Walk the stack chain for (int count = 0; !IsStackBottom(addr + 4) && (count++ < 20); ++count) { - u32 func_addr = Memory::ReadUnchecked_U32(addr + 4); + u32 func_addr = PowerPC::HostRead_U32(addr + 4); stack_step(func_addr); if (IsStackBottom(addr)) break; - addr = Memory::ReadUnchecked_U32(addr); + addr = PowerPC::HostRead_U32(addr); } } } @@ -69,7 +69,7 @@ static void WalkTheStack(const std::function& stack_step) // instead of "pointing ahead" bool GetCallstack(std::vector &output) { - if (!Core::IsRunning() || !Memory::IsRAMAddress(PowerPC::ppcState.gpr[1])) + if (!Core::IsRunning() || !PowerPC::HostIsRAMAddress(PowerPC::ppcState.gpr[1])) return false; if (LR == 0) diff --git a/Source/Core/Core/Debugger/PPCDebugInterface.cpp b/Source/Core/Core/Debugger/PPCDebugInterface.cpp index 1434fdb5bd..2a70213d35 100644 --- a/Source/Core/Core/Debugger/PPCDebugInterface.cpp +++ b/Source/Core/Core/Debugger/PPCDebugInterface.cpp @@ -19,26 +19,22 @@ std::string PPCDebugInterface::Disassemble(unsigned int address) { - // Memory::ReadUnchecked_U32 seemed to crash on shutdown + // PowerPC::HostRead_U32 seemed to crash on shutdown if (PowerPC::GetState() == PowerPC::CPU_POWERDOWN) return ""; - if (Core::GetState() != Core::CORE_UNINITIALIZED) + if (Core::GetState() == Core::CORE_PAUSE) { - if (!Memory::IsRAMAddress(address, true, true)) + if (!PowerPC::HostIsRAMAddress(address)) { - if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bMMU || !((address & JIT_ICACHE_VMEM_BIT) && - Memory::TranslateAddress(address))) - { - return "(No RAM here)"; - } + return "(No RAM here)"; } - u32 op = Memory::Read_Instruction(address); + u32 op = PowerPC::HostRead_Instruction(address); std::string disasm = GekkoDisassembler::Disassemble(op, address); UGeckoInstruction inst; - inst.hex = Memory::ReadUnchecked_U32(address); + inst.hex = PowerPC::HostRead_U32(address); if (inst.OPCD == 1) { @@ -57,7 +53,7 @@ void PPCDebugInterface::GetRawMemoryString(int memory, unsigned int address, cha { if (Core::GetState() != Core::CORE_UNINITIALIZED) { - if (memory || Memory::IsRAMAddress(address, true, true)) + if (memory || PowerPC::HostIsRAMAddress(address)) { snprintf(dest, max_size, "%08X%s", ReadExtraMemory(memory, address), memory ? " (ARAM)" : ""); } @@ -74,7 +70,7 @@ void PPCDebugInterface::GetRawMemoryString(int memory, unsigned int address, cha unsigned int PPCDebugInterface::ReadMemory(unsigned int address) { - return Memory::ReadUnchecked_U32(address); + return PowerPC::HostRead_U32(address); } unsigned int PPCDebugInterface::ReadExtraMemory(int memory, unsigned int address) @@ -82,7 +78,7 @@ unsigned int PPCDebugInterface::ReadExtraMemory(int memory, unsigned int address switch (memory) { case 0: - return Memory::ReadUnchecked_U32(address); + return PowerPC::HostRead_U32(address); case 1: return (DSP::ReadARAM(address) << 24) | (DSP::ReadARAM(address + 1) << 16) | @@ -95,7 +91,7 @@ unsigned int PPCDebugInterface::ReadExtraMemory(int memory, unsigned int address unsigned int PPCDebugInterface::ReadInstruction(unsigned int address) { - return Memory::Read_Instruction(address); + return PowerPC::HostRead_Instruction(address); } bool PPCDebugInterface::IsAlive() @@ -170,7 +166,7 @@ void PPCDebugInterface::ToggleMemCheck(unsigned int address) void PPCDebugInterface::InsertBLR(unsigned int address, unsigned int value) { - Memory::Write_U32(value, address); + PowerPC::HostWrite_U32(value, address); } void PPCDebugInterface::BreakNow() @@ -184,7 +180,9 @@ void PPCDebugInterface::BreakNow() // ------------- int PPCDebugInterface::GetColor(unsigned int address) { - if (!Memory::IsRAMAddress(address, true, true)) + if (!IsAlive()) + return 0xFFFFFF; + if (!PowerPC::HostIsRAMAddress(address)) return 0xeeeeee; static const int colors[6] = { diff --git a/Source/Core/Core/FifoPlayer/FifoPlayer.cpp b/Source/Core/Core/FifoPlayer/FifoPlayer.cpp index fc33bb7552..deb1d01bbe 100644 --- a/Source/Core/Core/FifoPlayer/FifoPlayer.cpp +++ b/Source/Core/Core/FifoPlayer/FifoPlayer.cpp @@ -348,6 +348,17 @@ void FifoPlayer::SetupFifo() void FifoPlayer::LoadMemory() { + UReg_MSR newMSR; + newMSR.DR = 1; + newMSR.IR = 1; + MSR = newMSR.Hex; + 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; + Memory::Clear(); SetupFifo(); @@ -391,12 +402,12 @@ void FifoPlayer::LoadMemory() void FifoPlayer::WriteCP(u32 address, u16 value) { - Memory::Write_U16(value, 0xCC000000 | address); + PowerPC::Write_U16(value, 0xCC000000 | address); } void FifoPlayer::WritePI(u32 address, u32 value) { - Memory::Write_U32(value, 0xCC003000 | address); + PowerPC::Write_U32(value, 0xCC003000 | address); } void FifoPlayer::FlushWGP() diff --git a/Source/Core/Core/GeckoCode.cpp b/Source/Core/Core/GeckoCode.cpp index 47d5b7f171..9fd347050c 100644 --- a/Source/Core/Core/GeckoCode.cpp +++ b/Source/Core/Core/GeckoCode.cpp @@ -90,16 +90,17 @@ static bool InstallCodeHandler() } // Install code handler - Memory::CopyToEmu(INSTALLER_BASE_ADDRESS, data.data(), data.length()); + for (size_t i = 0, e = data.length(); i < e; ++i) + PowerPC::HostWrite_U8(data[i], (u32)(INSTALLER_BASE_ADDRESS + i)); // Patch the code handler to the system starting up for (unsigned int h = 0; h < data.length(); h += 4) { // Patch MMIO address - if (Memory::ReadUnchecked_U32(INSTALLER_BASE_ADDRESS + h) == (0x3f000000u | ((mmioAddr ^ 1) << 8))) + if (PowerPC::HostRead_U32(INSTALLER_BASE_ADDRESS + h) == (0x3f000000u | ((mmioAddr ^ 1) << 8))) { NOTICE_LOG(ACTIONREPLAY, "Patching MMIO access at %08x", INSTALLER_BASE_ADDRESS + h); - Memory::Write_U32(0x3f000000u | mmioAddr << 8, INSTALLER_BASE_ADDRESS + h); + PowerPC::HostWrite_U32(0x3f000000u | mmioAddr << 8, INSTALLER_BASE_ADDRESS + h); } } @@ -107,11 +108,11 @@ static bool InstallCodeHandler() u32 codelist_end_address = INSTALLER_END_ADDRESS; // Write a magic value to 'gameid' (codehandleronly does not actually read this). - Memory::Write_U32(0xd01f1bad, INSTALLER_BASE_ADDRESS); + PowerPC::HostWrite_U32(0xd01f1bad, INSTALLER_BASE_ADDRESS); // Create GCT in memory - Memory::Write_U32(0x00d0c0de, codelist_base_address); - Memory::Write_U32(0x00d0c0de, codelist_base_address + 4); + PowerPC::HostWrite_U32(0x00d0c0de, codelist_base_address); + PowerPC::HostWrite_U32(0x00d0c0de, codelist_base_address + 4); std::lock_guard lk(active_codes_lock); @@ -126,19 +127,19 @@ static bool InstallCodeHandler() // Make sure we have enough memory to hold the code list if ((codelist_base_address + 24 + i) < codelist_end_address) { - Memory::Write_U32(code.address, codelist_base_address + 8 + i); - Memory::Write_U32(code.data, codelist_base_address + 12 + i); + PowerPC::HostWrite_U32(code.address, codelist_base_address + 8 + i); + PowerPC::HostWrite_U32(code.data, codelist_base_address + 12 + i); i += 8; } } } } - Memory::Write_U32(0xff000000, codelist_base_address + 8 + i); - Memory::Write_U32(0x00000000, codelist_base_address + 12 + i); + PowerPC::HostWrite_U32(0xff000000, codelist_base_address + 8 + i); + PowerPC::HostWrite_U32(0x00000000, codelist_base_address + 12 + i); // Turn on codes - Memory::Write_U8(1, INSTALLER_BASE_ADDRESS + 7); + PowerPC::HostWrite_U8(1, INSTALLER_BASE_ADDRESS + 7); // Invalidate the icache and any asm codes for (unsigned int j = 0; j < (INSTALLER_END_ADDRESS - INSTALLER_BASE_ADDRESS); j += 32) @@ -156,7 +157,7 @@ void RunCodeHandler() { if (SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableCheats && active_codes.size() > 0) { - if (!code_handler_installed || Memory::Read_U32(INSTALLER_BASE_ADDRESS) - 0xd01f1bad > 5) + if (!code_handler_installed || PowerPC::HostRead_U32(INSTALLER_BASE_ADDRESS) - 0xd01f1bad > 5) code_handler_installed = InstallCodeHandler(); if (!code_handler_installed) diff --git a/Source/Core/Core/HLE/HLE_Misc.cpp b/Source/Core/Core/HLE/HLE_Misc.cpp index b3b18fb437..2b480f76b7 100644 --- a/Source/Core/Core/HLE/HLE_Misc.cpp +++ b/Source/Core/Core/HLE/HLE_Misc.cpp @@ -63,7 +63,7 @@ void HLEGeckoCodehandler() // robust alternative would be to actually detect memory writes, but that // would be even uglier.) u32 magic = 0xd01f1bad; - u32 existing = Memory::Read_U32(0x80001800); + u32 existing = PowerPC::HostRead_U32(0x80001800); if (existing - magic == 5) { return; @@ -72,7 +72,7 @@ void HLEGeckoCodehandler() { existing = magic; } - Memory::Write_U32(existing + 1, 0x80001800); + PowerPC::HostWrite_U32(existing + 1, 0x80001800); PowerPC::ppcState.iCache.Reset(); } diff --git a/Source/Core/Core/HLE/HLE_OS.cpp b/Source/Core/Core/HLE/HLE_OS.cpp index 08d1315391..ff8ab56da5 100644 --- a/Source/Core/Core/HLE/HLE_OS.cpp +++ b/Source/Core/Core/HLE/HLE_OS.cpp @@ -32,7 +32,7 @@ void HLE_OSPanic() void HLE_GeneralDebugPrint() { std::string ReportMessage; - if (Memory::Read_U32(GPR(3)) > 0x80000000) + if (PowerPC::HostRead_U32(GPR(3)) > 0x80000000) { GetStringVA(ReportMessage, 4); } @@ -63,7 +63,7 @@ void GetStringVA(std::string& _rOutBuffer, u32 strReg) std::string ArgumentBuffer = ""; u32 ParameterCounter = strReg+1; u32 FloatingParameterCounter = 1; - std::string string = Memory::GetString(GPR(strReg)); + std::string string = PowerPC::HostGetString(GPR(strReg)); for(u32 i = 0; i < string.size(); i++) { @@ -84,7 +84,7 @@ void GetStringVA(std::string& _rOutBuffer, u32 strReg) u64 Parameter; if (ParameterCounter > 10) { - Parameter = Memory::Read_U32(GPR(1) + 0x8 + ((ParameterCounter - 11) * 4)); + Parameter = PowerPC::HostRead_U32(GPR(1) + 0x8 + ((ParameterCounter - 11) * 4)); } else { @@ -101,7 +101,7 @@ void GetStringVA(std::string& _rOutBuffer, u32 strReg) switch (string[i]) { case 's': - _rOutBuffer += StringFromFormat(ArgumentBuffer.c_str(), Memory::GetString((u32)Parameter).c_str()); + _rOutBuffer += StringFromFormat(ArgumentBuffer.c_str(), PowerPC::HostGetString((u32)Parameter).c_str()); break; case 'd': @@ -135,7 +135,7 @@ void GetStringVA(std::string& _rOutBuffer, u32 strReg) _rOutBuffer += string[i]; } } - if (_rOutBuffer[_rOutBuffer.length() - 1] == '\n') + if (!_rOutBuffer.empty() && _rOutBuffer[_rOutBuffer.length() - 1] == '\n') _rOutBuffer.resize(_rOutBuffer.length() - 1); } diff --git a/Source/Core/Core/HW/DSPLLE/DSPDebugInterface.cpp b/Source/Core/Core/HW/DSPLLE/DSPDebugInterface.cpp index 3ccd46a589..6da9abec20 100644 --- a/Source/Core/Core/HW/DSPLLE/DSPDebugInterface.cpp +++ b/Source/Core/Core/HW/DSPLLE/DSPDebugInterface.cpp @@ -58,12 +58,12 @@ void DSPDebugInterface::GetRawMemoryString(int memory, unsigned int address, cha unsigned int DSPDebugInterface::ReadMemory(unsigned int address) { - return 0; //Memory::ReadUnchecked_U32(address); + return 0; } unsigned int DSPDebugInterface::ReadInstruction(unsigned int address) { - return 0; //Memory::Read_Instruction(address); + return 0; } bool DSPDebugInterface::IsAlive() diff --git a/Source/Core/Core/HW/DSPLLE/DSPLLE.cpp b/Source/Core/Core/HW/DSPLLE/DSPLLE.cpp index adbcc2475f..f809b0488f 100644 --- a/Source/Core/Core/HW/DSPLLE/DSPLLE.cpp +++ b/Source/Core/Core/HW/DSPLLE/DSPLLE.cpp @@ -185,7 +185,9 @@ bool DSPLLE::Initialize(bool bWii, bool bDSPThread) return false; // DSPLLE directly accesses the fastmem arena. - g_dsp.cpu_ram = Memory::base; + // TODO: The fastmem arena is only supposed to be used by the JIT: + // among other issues, its size is only 1GB on 32-bit targets. + g_dsp.cpu_ram = Memory::physical_base; DSPCore_Reset(); InitInstructionTable(); diff --git a/Source/Core/Core/HW/DVDInterface.cpp b/Source/Core/Core/HW/DVDInterface.cpp index bd6c3e2038..cbf2307da5 100644 --- a/Source/Core/Core/HW/DVDInterface.cpp +++ b/Source/Core/Core/HW/DVDInterface.cpp @@ -470,7 +470,7 @@ void SetLidOpen(bool _bOpen) bool DVDRead(u64 _iDVDOffset, u32 _iRamAddress, u32 _iLength, bool decrypt) { - return VolumeHandler::ReadToPtr(Memory::GetPointer(_iRamAddress), _iDVDOffset, _iLength, decrypt); + return VolumeHandler::ReadToPtr(Memory::GetPointer(_iRamAddress), _iDVDOffset, _iLength, decrypt); } void RegisterMMIO(MMIO::Mapping* mmio, u32 base) diff --git a/Source/Core/Core/HW/Memmap.cpp b/Source/Core/Core/HW/Memmap.cpp index adc04468d0..b781108592 100644 --- a/Source/Core/Core/HW/Memmap.cpp +++ b/Source/Core/Core/HW/Memmap.cpp @@ -53,7 +53,8 @@ static bool bMMU = false; // Init() declarations // ---------------- // Store the MemArena here -u8* base = nullptr; +u8* physical_base = nullptr; +u8* logical_base = nullptr; // The MemArena class static MemArena g_arena; @@ -106,13 +107,14 @@ bool IsInitialized() static MemoryView views[] = { {&m_pRAM, 0x00000000, RAM_SIZE, 0}, - {nullptr, 0x80000000, RAM_SIZE, MV_MIRROR_PREVIOUS}, - {nullptr, 0xC0000000, RAM_SIZE, MV_MIRROR_PREVIOUS}, - {&m_pL1Cache, 0xE0000000, L1_CACHE_SIZE, 0}, - {&m_pFakeVMEM, 0x7E000000, FAKEVMEM_SIZE, MV_FAKE_VMEM}, + {nullptr, 0x200000000, RAM_SIZE, MV_MIRROR_PREVIOUS}, + {nullptr, 0x280000000, RAM_SIZE, MV_MIRROR_PREVIOUS}, + {nullptr, 0x2C0000000, RAM_SIZE, MV_MIRROR_PREVIOUS}, + {&m_pL1Cache, 0x2E0000000, L1_CACHE_SIZE, 0}, + {&m_pFakeVMEM, 0x27E000000, FAKEVMEM_SIZE, MV_FAKE_VMEM}, {&m_pEXRAM, 0x10000000, EXRAM_SIZE, MV_WII_ONLY}, - {nullptr, 0x90000000, EXRAM_SIZE, MV_WII_ONLY | MV_MIRROR_PREVIOUS}, - {nullptr, 0xD0000000, EXRAM_SIZE, MV_WII_ONLY | MV_MIRROR_PREVIOUS}, + {nullptr, 0x290000000, EXRAM_SIZE, MV_WII_ONLY | MV_MIRROR_PREVIOUS}, + {nullptr, 0x2D0000000, EXRAM_SIZE, MV_WII_ONLY | MV_MIRROR_PREVIOUS}, }; static const int num_views = sizeof(views) / sizeof(MemoryView); @@ -129,7 +131,10 @@ void Init() u32 flags = 0; if (wii) flags |= MV_WII_ONLY; if (bFakeVMEM) flags |= MV_FAKE_VMEM; - base = MemoryMap_Setup(views, num_views, flags, &g_arena); + physical_base = MemoryMap_Setup(views, num_views, flags, &g_arena); +#ifndef _ARCH_32 + logical_base = physical_base + 0x200000000; +#endif mmio_mapping = new MMIO::Mapping(); @@ -164,7 +169,8 @@ void Shutdown() if (bFakeVMEM) flags |= MV_FAKE_VMEM; MemoryMap_Shutdown(views, num_views, flags, &g_arena); g_arena.ReleaseSHMSegment(); - base = nullptr; + physical_base = nullptr; + logical_base = nullptr; delete mmio_mapping; INFO_LOG(MEMMAP, "Memory system shut down."); } @@ -188,12 +194,6 @@ bool AreMemoryBreakpointsActivated() #endif } -u32 Read_Instruction(const u32 address) -{ - UGeckoInstruction inst = ReadUnchecked_U32(address); - return inst.hex; -} - static inline bool ValidCopyRange(u32 address, size_t size) { return (GetPointer(address) != nullptr && @@ -228,19 +228,6 @@ void Memset(const u32 _Address, const u8 _iValue, const u32 _iLength) { memset(ptr,_iValue,_iLength); } - else - { - for (u32 i = 0; i < _iLength; i++) - Write_U8(_iValue, _Address + i); - } -} - -void ClearCacheLine(const u32 address) -{ - // FIXME: does this do the right thing if dcbz is run on hardware memory, e.g. - // the FIFO? Do games even do that? Probably not, but we should try to be correct... - for (u32 i = 0; i < 32; i += 8) - Write_U64(0, address + i); } std::string GetString(u32 em_address, size_t size) @@ -260,93 +247,73 @@ std::string GetString(u32 em_address, size_t size) } } -// GetPointer must always return an address in the bottom 32 bits of address space, so that 64-bit -// programs don't have problems directly addressing any part of memory. -// TODO re-think with respect to other BAT setups... -u8* GetPointer(const u32 address) +u8* GetPointer(u32 address) { - switch (address >> 28) + // TODO: Should we be masking off more bits here? Can all devices access + // EXRAM? + address &= 0x3FFFFFFF; + if (address < REALRAM_SIZE) + return m_pRAM + address; + + if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii) { - case 0x0: - case 0x8: - if ((address & 0xfffffff) < REALRAM_SIZE) - return m_pRAM + (address & RAM_MASK); - break; - case 0xc: - switch (address >> 24) - { - case 0xcc: - case 0xcd: - _dbg_assert_msg_(MEMMAP, 0, "GetPointer from IO Bridge doesnt work"); - break; - case 0xc8: - // EFB. We don't want to return a pointer here since we have no memory mapped for it. - break; - - default: - if ((address & 0xfffffff) < REALRAM_SIZE) - return m_pRAM + (address & RAM_MASK); - } - break; - - case 0x1: - case 0x9: - case 0xd: - if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii) - { - if ((address & 0xfffffff) < EXRAM_SIZE) - return m_pEXRAM + (address & EXRAM_MASK); - } - break; - - case 0xe: - if (address < (0xE0000000 + L1_CACHE_SIZE)) - return m_pL1Cache + (address & L1_CACHE_MASK); - else - break; - - default: - if (bFakeVMEM) - return m_pFakeVMEM + (address & FAKEVMEM_MASK); - break; + if ((address >> 28) == 0x1 && (address & 0x0fffffff) < EXRAM_SIZE) + return m_pEXRAM + (address & EXRAM_MASK); } - ERROR_LOG(MEMMAP, "Unknown Pointer %#8x PC %#8x LR %#8x", address, PC, LR); + PanicAlert("Unknown Pointer 0x%08x PC 0x%08x LR 0x%08x", address, PC, LR); return nullptr; } -bool IsRAMAddress(const u32 address, bool allow_locked_cache, bool allow_fake_vmem) +u8 Read_U8(u32 address) { - switch ((address >> 24) & 0xFC) - { - case 0x00: - case 0x80: - case 0xC0: - if ((address & 0x1FFFFFFF) < RAM_SIZE) - return true; - else - return false; - case 0x10: - case 0x90: - case 0xD0: - if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && (address & 0x0FFFFFFF) < EXRAM_SIZE) - return true; - else - return false; - case 0xE0: - if (allow_locked_cache && address - 0xE0000000 < L1_CACHE_SIZE) - return true; - else - return false; - case 0x7C: - if (allow_fake_vmem && bFakeVMEM && address >= 0x7E000000) - return true; - else - return false; - default: - return false; - } + return *GetPointer(address); +} + +u16 Read_U16(u32 address) +{ + return Common::swap16(GetPointer(address)); +} + +u32 Read_U32(u32 address) +{ + return Common::swap32(GetPointer(address)); +} + +u64 Read_U64(u32 address) +{ + return Common::swap64(GetPointer(address)); +} + +void Write_U8(u8 value, u32 address) +{ + *GetPointer(address) = value; +} + +void Write_U16(u16 value, u32 address) +{ + *(u16*)GetPointer(address) = Common::swap16(value); +} + +void Write_U32(u32 value, u32 address) +{ + *(u32*)GetPointer(address) = Common::swap32(value); +} + +void Write_U64(u64 value, u32 address) +{ + *(u64*)GetPointer(address) = Common::swap64(value); +} + +void Write_U32_Swap(u32 value, u32 address) +{ + *(u32*)GetPointer(address) = value; +} + +void Write_U64_Swap(u64 value, u32 address) +{ + *(u64*)GetPointer(address) = value; } } // namespace diff --git a/Source/Core/Core/HW/Memmap.h b/Source/Core/Core/HW/Memmap.h index f7915367cf..1cbb56f169 100644 --- a/Source/Core/Core/HW/Memmap.h +++ b/Source/Core/Core/HW/Memmap.h @@ -27,7 +27,8 @@ namespace Memory // In 64-bit, this might point to "high memory" (above the 32-bit limit), // so be sure to load it into a 64-bit register. -extern u8* base; +extern u8* physical_base; +extern u8* logical_base; // These are guaranteed to point to "low memory" addresses (sub-32-bit). extern u8* m_pRAM; @@ -73,70 +74,22 @@ void DoState(PointerWrap &p); void Clear(); bool AreMemoryBreakpointsActivated(); -// ONLY for use by GUI -u8 ReadUnchecked_U8(const u32 address); -u32 ReadUnchecked_U32(const u32 address); - -void WriteUnchecked_U8(const u8 var, const u32 address); -void WriteUnchecked_U32(const u32 var, const u32 address); - -bool IsRAMAddress(const u32 address, bool allow_locked_cache = false, bool allow_fake_vmem = false); - -// used by interpreter to read instructions, uses iCache -u32 Read_Opcode(const u32 address); -// this is used by Debugger a lot. -// For now, just reads from memory! -u32 Read_Instruction(const u32 address); - - -// For use by emulator - +// Routines to access physically addressed memory, designed for use by +// emulated hardware outside the CPU. Use "Device_" prefix. +std::string GetString(u32 em_address, size_t size = 0); +u8* GetPointer(const u32 address); +void CopyFromEmu(void* data, u32 address, size_t size); +void CopyToEmu(u32 address, const void* data, size_t size); +void Memset(const u32 address, const u8 var, const u32 length); u8 Read_U8(const u32 address); u16 Read_U16(const u32 address); u32 Read_U32(const u32 address); u64 Read_U64(const u32 address); - -// Useful helper functions, used by ARM JIT -float Read_F32(const u32 address); -double Read_F64(const u32 address); - -// used by JIT. Return zero-extended 32bit values -u32 Read_U8_ZX(const u32 address); -u32 Read_U16_ZX(const u32 address); - void Write_U8(const u8 var, const u32 address); void Write_U16(const u16 var, const u32 address); void Write_U32(const u32 var, const u32 address); void Write_U64(const u64 var, const u32 address); - -void Write_U16_Swap(const u16 var, const u32 address); void Write_U32_Swap(const u32 var, const u32 address); void Write_U64_Swap(const u64 var, const u32 address); -// Useful helper functions, used by ARM JIT -void Write_F64(const double var, const u32 address); - -std::string GetString(u32 em_address, size_t size = 0); - -u8* GetPointer(const u32 address); -void DMA_LCToMemory(const u32 memAddr, const u32 cacheAddr, const u32 numBlocks); -void DMA_MemoryToLC(const u32 cacheAddr, const u32 memAddr, const u32 numBlocks); -void CopyFromEmu(void* data, u32 address, size_t size); -void CopyToEmu(u32 address, const void* data, size_t size); -void Memset(const u32 address, const u8 var, const u32 length); -void ClearCacheLine(const u32 address); // Zeroes 32 bytes; address should be 32-byte-aligned - -// TLB functions -void SDRUpdated(); -enum XCheckTLBFlag -{ - FLAG_NO_EXCEPTION, - FLAG_READ, - FLAG_WRITE, - FLAG_OPCODE, -}; -template u32 TranslateAddress(const u32 address); -void InvalidateTLBEntry(u32 address); -extern u32 pagetable_base; -extern u32 pagetable_hashmask; } diff --git a/Source/Core/Core/HW/SystemTimers.cpp b/Source/Core/Core/HW/SystemTimers.cpp index d735c1a2fa..72d1dc8715 100644 --- a/Source/Core/Core/HW/SystemTimers.cpp +++ b/Source/Core/Core/HW/SystemTimers.cpp @@ -194,7 +194,6 @@ static void PatchEngineCallback(u64 userdata, int cyclesLate) { // Patch mem and run the Action Replay PatchEngine::ApplyFramePatches(); - PatchEngine::ApplyARPatches(); CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame() - cyclesLate, et_PatchEngine); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp index af4efbbdc2..7c53f8fafd 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp @@ -925,7 +925,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) pDolLoader = std::make_unique(pContent->m_Filename); } pDolLoader->Load(); // TODO: Check why sysmenu does not load the DOL correctly - PC = pDolLoader->GetEntryPoint() | 0x80000000; + PC = pDolLoader->GetEntryPoint(); IOSv = ContentLoader.GetIosVersion(); bSuccess = true; } diff --git a/Source/Core/Core/PatchEngine.cpp b/Source/Core/Core/PatchEngine.cpp index e66e7ae2f1..0ac3787d76 100644 --- a/Source/Core/Core/PatchEngine.cpp +++ b/Source/Core/Core/PatchEngine.cpp @@ -30,7 +30,7 @@ #include "Core/GeckoCode.h" #include "Core/GeckoCodeConfig.h" #include "Core/PatchEngine.h" -#include "Core/HW/Memmap.h" +#include "Core/PowerPC/PowerPC.h" using namespace Common; @@ -188,13 +188,13 @@ static void ApplyPatches(const std::vector &patches) switch (entry.type) { case PATCH_8BIT: - Memory::Write_U8((u8)value, addr); + PowerPC::HostWrite_U8((u8)value, addr); break; case PATCH_16BIT: - Memory::Write_U16((u16)value, addr); + PowerPC::HostWrite_U16((u16)value, addr); break; case PATCH_32BIT: - Memory::Write_U32(value, addr); + PowerPC::HostWrite_U32(value, addr); break; default: //unknown patchtype @@ -207,15 +207,20 @@ static void ApplyPatches(const std::vector &patches) void ApplyFramePatches() { + // TODO: Messing with MSR this way is really, really, evil; we should + // probably be using some sort of Gecko OS-style hooking mechanism + // so the emulated CPU is in a predictable state when we process cheats. + u32 oldMSR = MSR; + UReg_MSR newMSR = oldMSR; + newMSR.IR = 1; + newMSR.DR = 1; + MSR = newMSR.Hex; ApplyPatches(onFrame); // Run the Gecko code handler Gecko::RunCodeHandler(); -} - -void ApplyARPatches() -{ ActionReplay::RunAllActive(); + MSR = oldMSR; } void Shutdown() diff --git a/Source/Core/Core/PatchEngine.h b/Source/Core/Core/PatchEngine.h index 8b35db8736..73039eb8b1 100644 --- a/Source/Core/Core/PatchEngine.h +++ b/Source/Core/Core/PatchEngine.h @@ -45,7 +45,6 @@ void LoadPatchSection(const std::string& section, std::vector &patches, IniFile &globalIni, IniFile &localIni); void LoadPatches(); void ApplyFramePatches(); -void ApplyARPatches(); void Shutdown(); inline int GetPatchTypeCharLength(PatchType type) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp index d8f7c86caa..0f549a74b9 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp @@ -107,7 +107,7 @@ int Interpreter::SingleStepInner() #endif NPC = PC + sizeof(UGeckoInstruction); - instCode.hex = Memory::Read_Opcode(PC); + instCode.hex = PowerPC::Read_Opcode(PC); // Uncomment to trace the interpreter //if ((PC & 0xffffff)>=0x0ab54c && (PC & 0xffffff)<=0x0ab624) @@ -283,7 +283,7 @@ void Interpreter::unknown_instruction(UGeckoInstruction _inst) { if (_inst.hex != 0) { - std::string disasm = GekkoDisassembler::Disassemble(Memory::ReadUnchecked_U32(last_pc), last_pc); + std::string disasm = GekkoDisassembler::Disassemble(PowerPC::HostRead_U32(last_pc), last_pc); NOTICE_LOG(POWERPC, "Last PC = %08x : %s", last_pc, disasm.c_str()); Dolphin_Debugger::PrintCallstack(); _assert_msg_(POWERPC, 0, "\nIntCPU: Unknown instruction %08x at PC = %08x last_PC = %08x LR = %08x\n", _inst.hex, PC, last_pc, LR); diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp index 1af0a6427a..823b5e716c 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp @@ -36,7 +36,7 @@ u32 Interpreter::Helper_Get_EA_UX(const UGeckoInstruction _inst) void Interpreter::lbz(UGeckoInstruction _inst) { - u32 temp = (u32)Memory::Read_U8(Helper_Get_EA(_inst)); + u32 temp = (u32)PowerPC::Read_U8(Helper_Get_EA(_inst)); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) rGPR[_inst.RD] = temp; } @@ -44,7 +44,7 @@ void Interpreter::lbz(UGeckoInstruction _inst) void Interpreter::lbzu(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_U(_inst); - u32 temp = (u32)Memory::Read_U8(uAddress); + u32 temp = (u32)PowerPC::Read_U8(uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RD] = temp; @@ -54,7 +54,7 @@ void Interpreter::lbzu(UGeckoInstruction _inst) void Interpreter::lfd(UGeckoInstruction _inst) { - u64 temp = Memory::Read_U64(Helper_Get_EA(_inst)); + u64 temp = PowerPC::Read_U64(Helper_Get_EA(_inst)); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) riPS0(_inst.FD) = temp; } @@ -62,7 +62,7 @@ void Interpreter::lfd(UGeckoInstruction _inst) void Interpreter::lfdu(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_U(_inst); - u64 temp = Memory::Read_U64(uAddress); + u64 temp = PowerPC::Read_U64(uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { riPS0(_inst.FD) = temp; @@ -73,7 +73,7 @@ void Interpreter::lfdu(UGeckoInstruction _inst) void Interpreter::lfdux(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_UX(_inst); - u64 temp = Memory::Read_U64(uAddress); + u64 temp = PowerPC::Read_U64(uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { riPS0(_inst.FD) = temp; @@ -83,14 +83,14 @@ void Interpreter::lfdux(UGeckoInstruction _inst) void Interpreter::lfdx(UGeckoInstruction _inst) { - u64 temp = Memory::Read_U64(Helper_Get_EA_X(_inst)); + u64 temp = PowerPC::Read_U64(Helper_Get_EA_X(_inst)); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) riPS0(_inst.FD) = temp; } void Interpreter::lfs(UGeckoInstruction _inst) { - u32 uTemp = Memory::Read_U32(Helper_Get_EA(_inst)); + u32 uTemp = PowerPC::Read_U32(Helper_Get_EA(_inst)); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { u64 value = ConvertToDouble(uTemp); @@ -102,7 +102,7 @@ void Interpreter::lfs(UGeckoInstruction _inst) void Interpreter::lfsu(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_U(_inst); - u32 uTemp = Memory::Read_U32(uAddress); + u32 uTemp = PowerPC::Read_U32(uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { u64 value = ConvertToDouble(uTemp); @@ -116,7 +116,7 @@ void Interpreter::lfsu(UGeckoInstruction _inst) void Interpreter::lfsux(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_UX(_inst); - u32 uTemp = Memory::Read_U32(uAddress); + u32 uTemp = PowerPC::Read_U32(uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { u64 value = ConvertToDouble(uTemp); @@ -128,7 +128,7 @@ void Interpreter::lfsux(UGeckoInstruction _inst) void Interpreter::lfsx(UGeckoInstruction _inst) { - u32 uTemp = Memory::Read_U32(Helper_Get_EA_X(_inst)); + u32 uTemp = PowerPC::Read_U32(Helper_Get_EA_X(_inst)); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { u64 value = ConvertToDouble(uTemp); @@ -139,7 +139,7 @@ void Interpreter::lfsx(UGeckoInstruction _inst) void Interpreter::lha(UGeckoInstruction _inst) { - u32 temp = (u32)(s32)(s16)Memory::Read_U16(Helper_Get_EA(_inst)); + u32 temp = (u32)(s32)(s16)PowerPC::Read_U16(Helper_Get_EA(_inst)); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RD] = temp; @@ -149,7 +149,7 @@ void Interpreter::lha(UGeckoInstruction _inst) void Interpreter::lhau(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_U(_inst); - u32 temp = (u32)(s32)(s16)Memory::Read_U16(uAddress); + u32 temp = (u32)(s32)(s16)PowerPC::Read_U16(uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RD] = temp; @@ -159,7 +159,7 @@ void Interpreter::lhau(UGeckoInstruction _inst) void Interpreter::lhz(UGeckoInstruction _inst) { - u32 temp = (u32)(u16)Memory::Read_U16(Helper_Get_EA(_inst)); + u32 temp = (u32)(u16)PowerPC::Read_U16(Helper_Get_EA(_inst)); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RD] = temp; @@ -169,7 +169,7 @@ void Interpreter::lhz(UGeckoInstruction _inst) void Interpreter::lhzu(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_U(_inst); - u32 temp = (u32)(u16)Memory::Read_U16(uAddress); + u32 temp = (u32)(u16)PowerPC::Read_U16(uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RD] = temp; @@ -183,7 +183,7 @@ void Interpreter::lmw(UGeckoInstruction _inst) u32 uAddress = Helper_Get_EA(_inst); for (int iReg = _inst.RD; iReg <= 31; iReg++, uAddress += 4) { - u32 TempReg = Memory::Read_U32(uAddress); + u32 TempReg = PowerPC::Read_U32(uAddress); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { PanicAlert("DSI exception in lmw"); @@ -203,7 +203,7 @@ void Interpreter::stmw(UGeckoInstruction _inst) u32 uAddress = Helper_Get_EA(_inst); for (int iReg = _inst.RS; iReg <= 31; iReg++, uAddress+=4) { - Memory::Write_U32(rGPR[iReg], uAddress); + PowerPC::Write_U32(rGPR[iReg], uAddress); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { PanicAlert("DSI exception in stmw"); @@ -216,7 +216,7 @@ void Interpreter::stmw(UGeckoInstruction _inst) void Interpreter::lwz(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA(_inst); - u32 temp = Memory::Read_U32(uAddress); + u32 temp = PowerPC::Read_U32(uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RD] = temp; @@ -226,7 +226,7 @@ void Interpreter::lwz(UGeckoInstruction _inst) void Interpreter::lwzu(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_U(_inst); - u32 temp = Memory::Read_U32(uAddress); + u32 temp = PowerPC::Read_U32(uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RD] = temp; @@ -236,13 +236,13 @@ void Interpreter::lwzu(UGeckoInstruction _inst) void Interpreter::stb(UGeckoInstruction _inst) { - Memory::Write_U8((u8)rGPR[_inst.RS], Helper_Get_EA(_inst)); + PowerPC::Write_U8((u8)rGPR[_inst.RS], Helper_Get_EA(_inst)); } void Interpreter::stbu(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_U(_inst); - Memory::Write_U8((u8)rGPR[_inst.RS], uAddress); + PowerPC::Write_U8((u8)rGPR[_inst.RS], uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RA] = uAddress; @@ -251,13 +251,13 @@ void Interpreter::stbu(UGeckoInstruction _inst) void Interpreter::stfd(UGeckoInstruction _inst) { - Memory::Write_U64(riPS0(_inst.FS), Helper_Get_EA(_inst)); + PowerPC::Write_U64(riPS0(_inst.FS), Helper_Get_EA(_inst)); } void Interpreter::stfdu(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_U(_inst); - Memory::Write_U64(riPS0(_inst.FS), uAddress); + PowerPC::Write_U64(riPS0(_inst.FS), uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RA] = uAddress; @@ -266,13 +266,13 @@ void Interpreter::stfdu(UGeckoInstruction _inst) void Interpreter::stfs(UGeckoInstruction _inst) { - Memory::Write_U32(ConvertToSingle(riPS0(_inst.FS)), Helper_Get_EA(_inst)); + PowerPC::Write_U32(ConvertToSingle(riPS0(_inst.FS)), Helper_Get_EA(_inst)); } void Interpreter::stfsu(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_U(_inst); - Memory::Write_U32(ConvertToSingle(riPS0(_inst.FS)), uAddress); + PowerPC::Write_U32(ConvertToSingle(riPS0(_inst.FS)), uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RA] = uAddress; @@ -281,13 +281,13 @@ void Interpreter::stfsu(UGeckoInstruction _inst) void Interpreter::sth(UGeckoInstruction _inst) { - Memory::Write_U16((u16)rGPR[_inst.RS], Helper_Get_EA(_inst)); + PowerPC::Write_U16((u16)rGPR[_inst.RS], Helper_Get_EA(_inst)); } void Interpreter::sthu(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_U(_inst); - Memory::Write_U16((u16)rGPR[_inst.RS], uAddress); + PowerPC::Write_U16((u16)rGPR[_inst.RS], uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RA] = uAddress; @@ -296,13 +296,13 @@ void Interpreter::sthu(UGeckoInstruction _inst) void Interpreter::stw(UGeckoInstruction _inst) { - Memory::Write_U32(rGPR[_inst.RS], Helper_Get_EA(_inst)); + PowerPC::Write_U32(rGPR[_inst.RS], Helper_Get_EA(_inst)); } void Interpreter::stwu(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_U(_inst); - Memory::Write_U32(rGPR[_inst.RS], uAddress); + PowerPC::Write_U32(rGPR[_inst.RS], uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RA] = uAddress; @@ -318,8 +318,8 @@ void Interpreter::dcbf(UGeckoInstruction _inst) { //This should tell GFX backend to throw out any cached data here // !!! SPEEDUP HACK for OSProtectRange !!! -/* u32 tmp1 = Memory::Read_U32(PC+4); - u32 tmp2 = Memory::Read_U32(PC+8); +/* u32 tmp1 = PowerPC::HostRead_U32(PC+4); + u32 tmp2 = PowerPC::HostRead_U32(PC+8); if ((tmp1 == 0x38630020) && (tmp2 == 0x4200fff8)) @@ -377,7 +377,7 @@ void Interpreter::dcbz(UGeckoInstruction _inst) { // HACK but works... we think if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bDCBZOFF) - Memory::ClearCacheLine(Helper_Get_EA_X(_inst) & (~31)); + PowerPC::ClearCacheLine(Helper_Get_EA_X(_inst) & (~31)); if (!JitInterface::GetCore()) PowerPC::CheckExceptions(); } @@ -403,7 +403,7 @@ void Interpreter::eciwx(UGeckoInstruction _inst) // _assert_msg_(POWERPC,0,"eciwx - fill r%i with word @ %08x from device %02x", // _inst.RS, EA, PowerPC::ppcState.spr[SPR_EAR] & 0x1f); - rGPR[_inst.RS] = Memory::Read_U32(EA); + rGPR[_inst.RS] = PowerPC::Read_U32(EA); } void Interpreter::ecowx(UGeckoInstruction _inst) @@ -425,7 +425,7 @@ void Interpreter::ecowx(UGeckoInstruction _inst) // _assert_msg_(POWERPC,0,"ecowx - send stw request (%08x@%08x) to device %02x", // rGPR[_inst.RS], EA, PowerPC::ppcState.spr[SPR_EAR] & 0x1f); - Memory::Write_U32(rGPR[_inst.RS], EA); + PowerPC::Write_U32(rGPR[_inst.RS], EA); } void Interpreter::eieio(UGeckoInstruction _inst) @@ -445,7 +445,7 @@ void Interpreter::icbi(UGeckoInstruction _inst) void Interpreter::lbzux(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_UX(_inst); - u32 temp = (u32)Memory::Read_U8(uAddress); + u32 temp = (u32)PowerPC::Read_U8(uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RD] = temp; @@ -455,7 +455,7 @@ void Interpreter::lbzux(UGeckoInstruction _inst) void Interpreter::lbzx(UGeckoInstruction _inst) { - u32 temp = (u32)Memory::Read_U8(Helper_Get_EA_X(_inst)); + u32 temp = (u32)PowerPC::Read_U8(Helper_Get_EA_X(_inst)); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RD] = temp; @@ -465,7 +465,7 @@ void Interpreter::lbzx(UGeckoInstruction _inst) void Interpreter::lhaux(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_UX(_inst); - s32 temp = (s32)(s16)Memory::Read_U16(uAddress); + s32 temp = (s32)(s16)PowerPC::Read_U16(uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RD] = temp; @@ -475,7 +475,7 @@ void Interpreter::lhaux(UGeckoInstruction _inst) void Interpreter::lhax(UGeckoInstruction _inst) { - s32 temp = (s32)(s16)Memory::Read_U16(Helper_Get_EA_X(_inst)); + s32 temp = (s32)(s16)PowerPC::Read_U16(Helper_Get_EA_X(_inst)); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RD] = temp; @@ -484,7 +484,7 @@ void Interpreter::lhax(UGeckoInstruction _inst) void Interpreter::lhbrx(UGeckoInstruction _inst) { - u32 temp = (u32)Common::swap16(Memory::Read_U16(Helper_Get_EA_X(_inst))); + u32 temp = (u32)Common::swap16(PowerPC::Read_U16(Helper_Get_EA_X(_inst))); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RD] = temp; @@ -494,7 +494,7 @@ void Interpreter::lhbrx(UGeckoInstruction _inst) void Interpreter::lhzux(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_UX(_inst); - u32 temp = (u32)Memory::Read_U16(uAddress); + u32 temp = (u32)PowerPC::Read_U16(uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RD] = temp; @@ -504,7 +504,7 @@ void Interpreter::lhzux(UGeckoInstruction _inst) void Interpreter::lhzx(UGeckoInstruction _inst) { - u32 temp = (u32)Memory::Read_U16(Helper_Get_EA_X(_inst)); + u32 temp = (u32)PowerPC::Read_U16(Helper_Get_EA_X(_inst)); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RD] = temp; @@ -525,7 +525,7 @@ void Interpreter::lswx(UGeckoInstruction _inst) rGPR[r] = 0; do { - u32 TempValue = Memory::Read_U8(EA) << (24 - i); + u32 TempValue = PowerPC::Read_U8(EA) << (24 - i); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { PanicAlert("DSI exception in lswx."); @@ -549,7 +549,7 @@ void Interpreter::lswx(UGeckoInstruction _inst) void Interpreter::lwbrx(UGeckoInstruction _inst) { - u32 temp = Common::swap32(Memory::Read_U32(Helper_Get_EA_X(_inst))); + u32 temp = Common::swap32(PowerPC::Read_U32(Helper_Get_EA_X(_inst))); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RD] = temp; @@ -559,7 +559,7 @@ void Interpreter::lwbrx(UGeckoInstruction _inst) void Interpreter::lwzux(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_UX(_inst); - u32 temp = Memory::Read_U32(uAddress); + u32 temp = PowerPC::Read_U32(uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RD] = temp; @@ -570,7 +570,7 @@ void Interpreter::lwzux(UGeckoInstruction _inst) void Interpreter::lwzx(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_X(_inst); - u32 temp = Memory::Read_U32(uAddress); + u32 temp = PowerPC::Read_U32(uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RD] = temp; @@ -580,7 +580,7 @@ void Interpreter::lwzx(UGeckoInstruction _inst) void Interpreter::stbux(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_UX(_inst); - Memory::Write_U8((u8)rGPR[_inst.RS], uAddress); + PowerPC::Write_U8((u8)rGPR[_inst.RS], uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RA] = uAddress; @@ -589,13 +589,13 @@ void Interpreter::stbux(UGeckoInstruction _inst) void Interpreter::stbx(UGeckoInstruction _inst) { - Memory::Write_U8((u8)rGPR[_inst.RS], Helper_Get_EA_X(_inst)); + PowerPC::Write_U8((u8)rGPR[_inst.RS], Helper_Get_EA_X(_inst)); } void Interpreter::stfdux(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_UX(_inst); - Memory::Write_U64(riPS0(_inst.FS), uAddress); + PowerPC::Write_U64(riPS0(_inst.FS), uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RA] = uAddress; @@ -604,7 +604,7 @@ void Interpreter::stfdux(UGeckoInstruction _inst) void Interpreter::stfdx(UGeckoInstruction _inst) { - Memory::Write_U64(riPS0(_inst.FS), Helper_Get_EA_X(_inst)); + PowerPC::Write_U64(riPS0(_inst.FS), Helper_Get_EA_X(_inst)); } // Stores Floating points into Integers indeXed @@ -612,14 +612,14 @@ void Interpreter::stfiwx(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_X(_inst); - Memory::Write_U32((u32)riPS0(_inst.FS), uAddress); + PowerPC::Write_U32((u32)riPS0(_inst.FS), uAddress); } void Interpreter::stfsux(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_UX(_inst); - Memory::Write_U32(ConvertToSingle(riPS0(_inst.FS)), uAddress); + PowerPC::Write_U32(ConvertToSingle(riPS0(_inst.FS)), uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RA] = uAddress; @@ -628,18 +628,18 @@ void Interpreter::stfsux(UGeckoInstruction _inst) void Interpreter::stfsx(UGeckoInstruction _inst) { - Memory::Write_U32(ConvertToSingle(riPS0(_inst.FS)), Helper_Get_EA_X(_inst)); + PowerPC::Write_U32(ConvertToSingle(riPS0(_inst.FS)), Helper_Get_EA_X(_inst)); } void Interpreter::sthbrx(UGeckoInstruction _inst) { - Memory::Write_U16(Common::swap16((u16)rGPR[_inst.RS]), Helper_Get_EA_X(_inst)); + PowerPC::Write_U16(Common::swap16((u16)rGPR[_inst.RS]), Helper_Get_EA_X(_inst)); } void Interpreter::sthux(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_UX(_inst); - Memory::Write_U16((u16)rGPR[_inst.RS], uAddress); + PowerPC::Write_U16((u16)rGPR[_inst.RS], uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RA] = uAddress; @@ -648,7 +648,7 @@ void Interpreter::sthux(UGeckoInstruction _inst) void Interpreter::sthx(UGeckoInstruction _inst) { - Memory::Write_U16((u16)rGPR[_inst.RS], Helper_Get_EA_X(_inst)); + PowerPC::Write_U16((u16)rGPR[_inst.RS], Helper_Get_EA_X(_inst)); } // __________________________________________________________________________________________________ @@ -679,7 +679,7 @@ void Interpreter::lswi(UGeckoInstruction _inst) rGPR[r] = 0; } - u32 TempValue = Memory::Read_U8(EA) << (24 - i); + u32 TempValue = PowerPC::Read_U8(EA) << (24 - i); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { PanicAlert("DSI exception in lsw."); @@ -723,7 +723,7 @@ void Interpreter::stswi(UGeckoInstruction _inst) r++; r &= 31; } - Memory::Write_U8((rGPR[r] >> (24 - i)) & 0xFF, EA); + PowerPC::Write_U8((rGPR[r] >> (24 - i)) & 0xFF, EA); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { return; @@ -747,7 +747,7 @@ void Interpreter::stswx(UGeckoInstruction _inst) while (n > 0) { - Memory::Write_U8((rGPR[r] >> (24 - i)) & 0xFF, EA); + PowerPC::Write_U8((rGPR[r] >> (24 - i)) & 0xFF, EA); EA++; n--; @@ -763,7 +763,7 @@ void Interpreter::stswx(UGeckoInstruction _inst) void Interpreter::stwbrx(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_X(_inst); - Memory::Write_U32(Common::swap32(rGPR[_inst.RS]), uAddress); + PowerPC::Write_U32(Common::swap32(rGPR[_inst.RS]), uAddress); } @@ -773,7 +773,7 @@ void Interpreter::stwbrx(UGeckoInstruction _inst) void Interpreter::lwarx(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_X(_inst); - u32 temp = Memory::Read_U32(uAddress); + u32 temp = PowerPC::Read_U32(uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RD] = temp; @@ -792,7 +792,7 @@ void Interpreter::stwcxd(UGeckoInstruction _inst) if (uAddress == g_reserveAddr) { - Memory::Write_U32(rGPR[_inst.RS], uAddress); + PowerPC::Write_U32(rGPR[_inst.RS], uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { g_bReserve = false; @@ -808,7 +808,7 @@ void Interpreter::stwcxd(UGeckoInstruction _inst) void Interpreter::stwux(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_UX(_inst); - Memory::Write_U32(rGPR[_inst.RS], uAddress); + PowerPC::Write_U32(rGPR[_inst.RS], uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { rGPR[_inst.RA] = uAddress; @@ -818,7 +818,7 @@ void Interpreter::stwux(UGeckoInstruction _inst) void Interpreter::stwx(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_X(_inst); - Memory::Write_U32(rGPR[_inst.RS], uAddress); + PowerPC::Write_U32(rGPR[_inst.RS], uAddress); } void Interpreter::sync(UGeckoInstruction _inst) @@ -838,7 +838,7 @@ void Interpreter::tlbie(UGeckoInstruction _inst) { // Invalidate TLB entry u32 _Address = rGPR[_inst.RB]; - Memory::InvalidateTLBEntry(_Address); + PowerPC::InvalidateTLBEntry(_Address); } void Interpreter::tlbsync(UGeckoInstruction _inst) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp index a5c6ea9787..1382fb31b4 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp @@ -53,7 +53,7 @@ void Interpreter::Helper_Quantize(const u32 _Addr, const double _fValue, const E switch (_quantizeType) { case QUANTIZE_FLOAT: - Memory::Write_U32(ConvertToSingleFTZ(*(u64*)&_fValue), _Addr); + PowerPC::Write_U32(ConvertToSingleFTZ(*(u64*)&_fValue), _Addr); break; // used for THP player @@ -61,7 +61,7 @@ void Interpreter::Helper_Quantize(const u32 _Addr, const double _fValue, const E { float fResult = (float)_fValue * m_quantizeTable[_uScale]; MathUtil::Clamp(&fResult, 0.0f, 255.0f); - Memory::Write_U8((u8)fResult, _Addr); + PowerPC::Write_U8((u8)fResult, _Addr); } break; @@ -69,7 +69,7 @@ void Interpreter::Helper_Quantize(const u32 _Addr, const double _fValue, const E { float fResult = (float)_fValue * m_quantizeTable[_uScale]; MathUtil::Clamp(&fResult, 0.0f, 65535.0f); - Memory::Write_U16((u16)fResult, _Addr); + PowerPC::Write_U16((u16)fResult, _Addr); } break; @@ -77,7 +77,7 @@ void Interpreter::Helper_Quantize(const u32 _Addr, const double _fValue, const E { float fResult = (float)_fValue * m_quantizeTable[_uScale]; MathUtil::Clamp(&fResult, -128.0f, 127.0f); - Memory::Write_U8((u8)(s8)fResult, _Addr); + PowerPC::Write_U8((u8)(s8)fResult, _Addr); } break; @@ -85,7 +85,7 @@ void Interpreter::Helper_Quantize(const u32 _Addr, const double _fValue, const E { float fResult = (float)_fValue * m_quantizeTable[_uScale]; MathUtil::Clamp(&fResult, -32768.0f, 32767.0f); - Memory::Write_U16((u16)(s16)fResult, _Addr); + PowerPC::Write_U16((u16)(s16)fResult, _Addr); } break; @@ -103,26 +103,26 @@ float Interpreter::Helper_Dequantize(const u32 _Addr, const EQuantizeType _quant { case QUANTIZE_FLOAT: { - u32 dwValue = Memory::Read_U32(_Addr); + u32 dwValue = PowerPC::Read_U32(_Addr); fResult = *(float*)&dwValue; } break; case QUANTIZE_U8: - fResult = static_cast(Memory::Read_U8(_Addr)) * m_dequantizeTable[_uScale]; + fResult = static_cast(PowerPC::Read_U8(_Addr)) * m_dequantizeTable[_uScale]; break; case QUANTIZE_U16: - fResult = static_cast(Memory::Read_U16(_Addr)) * m_dequantizeTable[_uScale]; + fResult = static_cast(PowerPC::Read_U16(_Addr)) * m_dequantizeTable[_uScale]; break; case QUANTIZE_S8: - fResult = static_cast((s8)Memory::Read_U8(_Addr)) * m_dequantizeTable[_uScale]; + fResult = static_cast((s8)PowerPC::Read_U8(_Addr)) * m_dequantizeTable[_uScale]; break; // used for THP player case QUANTIZE_S16: - fResult = static_cast((s16)Memory::Read_U16(_Addr)) * m_dequantizeTable[_uScale]; + fResult = static_cast((s16)PowerPC::Read_U16(_Addr)) * m_dequantizeTable[_uScale]; break; default: diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp index 2803af0b0c..d67e54c632 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp @@ -425,5 +425,5 @@ void Interpreter::ps_cmpo1(UGeckoInstruction _inst) void Interpreter::dcbz_l(UGeckoInstruction _inst) { //FAKE: clear memory instead of clearing the cache block - Memory::Memset(Helper_Get_EA_X(_inst) & (~31), 0, 32); + PowerPC::ClearCacheLine(Helper_Get_EA_X(_inst) & (~31)); } diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp index 50aac47962..3cb45fbb68 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp @@ -329,9 +329,9 @@ void Interpreter::mtspr(UGeckoInstruction _inst) if (iLength == 0) iLength = 128; if (DMAL.DMA_LD) - Memory::DMA_MemoryToLC(dwCacheAddress, dwMemAddress, iLength); + PowerPC::DMA_MemoryToLC(dwCacheAddress, dwMemAddress, iLength); else - Memory::DMA_LCToMemory(dwMemAddress, dwCacheAddress, iLength); + PowerPC::DMA_LCToMemory(dwMemAddress, dwCacheAddress, iLength); } DMAL.DMA_T = 0; break; @@ -351,7 +351,7 @@ void Interpreter::mtspr(UGeckoInstruction _inst) // Page table base etc case SPR_SDR: - Memory::SDRUpdated(); + PowerPC::SDRUpdated(); break; case SPR_XER: diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp index 4e2824515f..7bfcb17002 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp @@ -180,6 +180,7 @@ void Jit64::Init() jo.accurateSinglePrecision = true; js.memcheck = SConfig::GetInstance().m_LocalCoreStartupParameter.bMMU; js.fastmemLoadStore = NULL; + js.compilerPC = 0; gpr.SetEmitter(this); fpr.SetEmitter(this); @@ -539,6 +540,7 @@ void Jit64::Jit(u32 em_address) NPC = nextPC; PowerPC::ppcState.Exceptions |= EXCEPTION_ISI; PowerPC::CheckExceptions(); + WARN_LOG(POWERPC, "ISI exception at 0x%08x", nextPC); return; } diff --git a/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp b/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp index b8d732bd87..f50aa15011 100644 --- a/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp +++ b/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp @@ -39,7 +39,7 @@ void Jit64AsmRoutineManager::Generate() MOV(64, MDisp(RSP, 8), Imm32((u32)-1)); // Two statically allocated registers. - MOV(64, R(RMEM), Imm64((u64)Memory::base)); + //MOV(64, R(RMEM), Imm64((u64)Memory::physical_base)); MOV(64, R(RPPCSTATE), Imm64((u64)&PowerPC::ppcState + 0x80)); const u8* outerLoop = GetCodePtr(); @@ -83,8 +83,26 @@ void Jit64AsmRoutineManager::Generate() SetJumpTarget(skipToRealDispatch); dispatcherNoCheck = GetCodePtr(); + + // Switch to the correct memory base, in case MSR.DR has changed. + // TODO: Is there a more efficient place to put this? We don't + // need to do this for indirect jumps, just exceptions etc. + TEST(32, PPCSTATE(msr), Imm32(1 << (31 - 27))); + FixupBranch physmem = J_CC(CC_NZ); + MOV(64, R(RMEM), Imm64((u64)Memory::physical_base)); + FixupBranch membaseend = J(); + SetJumpTarget(physmem); + MOV(64, R(RMEM), Imm64((u64)Memory::logical_base)); + SetJumpTarget(membaseend); + MOV(32, R(RSCRATCH), PPCSTATE(pc)); + // TODO: We need to handle code which executes the same PC with + // different values of MSR.IR. It probably makes sense to handle + // MSR.DR here too, to allow IsOptimizableRAMAddress-based + // optimizations safe, because IR and DR are usually set/cleared together. + // TODO: Branching based on the 20 most significant bits of instruction + // addresses without translating them is wrong. u64 icache = (u64)jit->GetBlockCache()->iCache.data(); u64 icacheVmem = (u64)jit->GetBlockCache()->iCacheVMEM.data(); u64 icacheEx = (u64)jit->GetBlockCache()->iCacheEx.data(); @@ -251,5 +269,5 @@ void Jit64AsmRoutineManager::GenerateCommon() ADD(32, 1, M(&m_gatherPipeCount)); RET(); SetJumpTarget(skip_fast_write); - CALL((void *)&Memory::Write_U8);*/ + CALL((void *)&PowerPC::Write_U8);*/ } diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp index 0260497f11..6c25c1f752 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp @@ -108,6 +108,8 @@ void Jit64::lXXx(UGeckoInstruction inst) // (mb2): I agree, // IMHO those Idles should always be skipped and replaced by a more controllable "native" Idle methode // ... maybe the throttle one already do that :p + // TODO: We shouldn't use a debug read here. It should be possible to get + // the following instructions out of the JIT state. if (SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle && PowerPC::GetState() != PowerPC::CPU_STEPPING && inst.OPCD == 32 && @@ -335,7 +337,7 @@ void Jit64::dcbz(UGeckoInstruction inst) MOV(32, M(&PC), Imm32(jit->js.compilerPC)); BitSet32 registersInUse = CallerSavedRegistersInUse(); ABI_PushRegistersAndAdjustStack(registersInUse, 0); - ABI_CallFunctionR((void *)&Memory::ClearCacheLine, RSCRATCH); + ABI_CallFunctionR((void *)&PowerPC::ClearCacheLine, RSCRATCH); ABI_PopRegistersAndAdjustStack(registersInUse, 0); FixupBranch exit = J(true); diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp index 46aaddb1f6..4c6aa6d3f7 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp @@ -380,9 +380,8 @@ void Jit64::mtmsr(UGeckoInstruction inst) SetJumpTarget(noExceptionsPending); SetJumpTarget(eeDisabled); - WriteExit(js.compilerPC + 4); - - js.firstFPInstructionFound = false; + MOV(32, R(RSCRATCH), Imm32(js.compilerPC + 4)); + WriteExitDestInRSCRATCH(); } void Jit64::mfmsr(UGeckoInstruction inst) diff --git a/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp b/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp index c9aae70d21..a9164b0bb8 100644 --- a/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp +++ b/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp @@ -500,7 +500,7 @@ static void regMarkMemAddress(RegInfo& RI, InstLoc I, InstLoc AI, unsigned OpNum if (isImm(*AI)) { unsigned addr = RI.Build->GetImmValue(AI); - if (Memory::IsRAMAddress(addr)) + if (PowerPC::IsOptimizableRAMAddress(addr)) return; } @@ -520,7 +520,7 @@ static std::pair regBuildMemAddress(RegInfo& RI, InstLoc I, InstLoc if (isImm(*AI)) { unsigned addr = RI.Build->GetImmValue(AI); - if (Memory::IsRAMAddress(addr)) + if (PowerPC::IsOptimizableRAMAddress(addr)) { if (dest) *dest = regFindFreeReg(RI); diff --git a/Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp b/Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp index c3dfafdc44..fcf45aec1b 100644 --- a/Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp +++ b/Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp @@ -521,6 +521,7 @@ void JitIL::Jit(u32 em_address) NPC = nextPC; PowerPC::ppcState.Exceptions |= EXCEPTION_ISI; PowerPC::CheckExceptions(); + WARN_LOG(POWERPC, "ISI exception at 0x%08x", nextPC); return; } diff --git a/Source/Core/Core/PowerPC/JitArm32/JitArm_BackPatch.cpp b/Source/Core/Core/PowerPC/JitArm32/JitArm_BackPatch.cpp index 607bb78960..3a87784fde 100644 --- a/Source/Core/Core/PowerPC/JitArm32/JitArm_BackPatch.cpp +++ b/Source/Core/Core/PowerPC/JitArm32/JitArm_BackPatch.cpp @@ -189,7 +189,7 @@ bool JitArm::DisasmLoadStore(const u8* ptr, u32* flags, ARMReg* rD, ARMReg* V1) bool JitArm::HandleFault(uintptr_t access_address, SContext* ctx) { - if (access_address < (uintptr_t)Memory::base) + if (access_address < (uintptr_t)Memory::physical_base) PanicAlertT("Exception handler - access below memory space. 0x%08x", access_address); return BackPatch(ctx); } @@ -323,12 +323,12 @@ u32 JitArm::EmitBackpatchRoutine(ARMXEmitter* emit, u32 flags, bool fastmem, boo emit->MOV(R1, addr); emit->VCVT(S0, RS, 0); emit->VMOV(R0, S0); - emit->MOVI2R(temp, (u32)&Memory::Write_U32); + emit->MOVI2R(temp, (u32)&PowerPC::Write_U32); emit->BL(temp); } else { - emit->MOVI2R(temp, (u32)&Memory::Write_F64); + emit->MOVI2R(temp, (u32)&PowerPC::Write_F64); #if !defined(__ARM_PCS_VFP) // SoftFP returns in R0 and R1 emit->VMOV(R0, RS); emit->MOV(R2, addr); @@ -347,7 +347,7 @@ u32 JitArm::EmitBackpatchRoutine(ARMXEmitter* emit, u32 flags, bool fastmem, boo emit->MOV(R0, addr); if (flags & BackPatchInfo::FLAG_SIZE_F32) { - emit->MOVI2R(temp, (u32)&Memory::Read_U32); + emit->MOVI2R(temp, (u32)&PowerPC::Read_U32); emit->BL(temp); emit->VMOV(S0, R0); emit->VCVT(RS, S0, 0); @@ -355,7 +355,7 @@ u32 JitArm::EmitBackpatchRoutine(ARMXEmitter* emit, u32 flags, bool fastmem, boo } else { - emit->MOVI2R(temp, (u32)&Memory::Read_F64); + emit->MOVI2R(temp, (u32)&PowerPC::Read_F64); emit->BL(temp); #if !defined(__ARM_PCS_VFP) // SoftFP returns in R0 and R1 @@ -373,11 +373,11 @@ u32 JitArm::EmitBackpatchRoutine(ARMXEmitter* emit, u32 flags, bool fastmem, boo emit->MOV(R1, addr); if (flags & BackPatchInfo::FLAG_SIZE_32) - emit->MOVI2R(temp, (u32)&Memory::Write_U32); + emit->MOVI2R(temp, (u32)&PowerPC::Write_U32); else if (flags & BackPatchInfo::FLAG_SIZE_16) - emit->MOVI2R(temp, (u32)&Memory::Write_U16); + emit->MOVI2R(temp, (u32)&PowerPC::Write_U16); else - emit->MOVI2R(temp, (u32)&Memory::Write_U8); + emit->MOVI2R(temp, (u32)&PowerPC::Write_U8); emit->BL(temp); emit->POP(4, R0, R1, R2, R3); @@ -388,11 +388,11 @@ u32 JitArm::EmitBackpatchRoutine(ARMXEmitter* emit, u32 flags, bool fastmem, boo emit->MOV(R0, addr); if (flags & BackPatchInfo::FLAG_SIZE_32) - emit->MOVI2R(temp, (u32)&Memory::Read_U32); + emit->MOVI2R(temp, (u32)&PowerPC::Read_U32); else if (flags & BackPatchInfo::FLAG_SIZE_16) - emit->MOVI2R(temp, (u32)&Memory::Read_U16); + emit->MOVI2R(temp, (u32)&PowerPC::Read_U16); else if (flags & BackPatchInfo::FLAG_SIZE_8) - emit->MOVI2R(temp, (u32)&Memory::Read_U8); + emit->MOVI2R(temp, (u32)&PowerPC::Read_U8); emit->BL(temp); emit->MOV(temp, R0); diff --git a/Source/Core/Core/PowerPC/JitArm32/JitArm_LoadStore.cpp b/Source/Core/Core/PowerPC/JitArm32/JitArm_LoadStore.cpp index 678223b7a6..353a560665 100644 --- a/Source/Core/Core/PowerPC/JitArm32/JitArm_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/JitArm32/JitArm_LoadStore.cpp @@ -145,7 +145,7 @@ void JitArm::SafeStoreFromReg(s32 dest, u32 value, s32 regOffset, int accessSize STR(R11, R14); jit->js.fifoBytesThisBlock += accessSize >> 3; } - else if (Memory::IsRAMAddress(imm_addr)) + else if (PowerPC::IsOptimizableRAMAddress(imm_addr)) { MOVI2R(rA, imm_addr); EmitBackpatchRoutine(this, flags, SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem, true, RS); @@ -450,9 +450,9 @@ void JitArm::lXX(UGeckoInstruction inst) if (SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle && inst.OPCD == 32 && (inst.hex & 0xFFFF0000) == 0x800D0000 && - (Memory::ReadUnchecked_U32(js.compilerPC + 4) == 0x28000000 || - (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && Memory::ReadUnchecked_U32(js.compilerPC + 4) == 0x2C000000)) && - Memory::ReadUnchecked_U32(js.compilerPC + 8) == 0x4182fff8) + (PowerPC::HostRead_U32(js.compilerPC + 4) == 0x28000000 || + (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && PowerPC::HostRead_U32(js.compilerPC + 4) == 0x2C000000)) && + PowerPC::HostRead_U32(js.compilerPC + 8) == 0x4182fff8) { // if it's still 0, we can wait until the next event TST(RD, RD); @@ -536,7 +536,7 @@ void JitArm::dcbst(UGeckoInstruction inst) // memory location. Do not invalidate the JIT cache in this case as the memory // will be the same. // dcbt = 0x7c00022c - FALLBACK_IF((Memory::ReadUnchecked_U32(js.compilerPC - 4) & 0x7c00022c) != 0x7c00022c); + FALLBACK_IF((PowerPC::HostRead_U32(js.compilerPC - 4) & 0x7c00022c) != 0x7c00022c); } void JitArm::icbi(UGeckoInstruction inst) diff --git a/Source/Core/Core/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp b/Source/Core/Core/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp index e0c95152c1..ec232915b7 100644 --- a/Source/Core/Core/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp +++ b/Source/Core/Core/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp @@ -183,7 +183,7 @@ void JitArm::lfXX(UGeckoInstruction inst) EmitBackpatchRoutine(this, flags, SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem, - !(is_immediate && Memory::IsRAMAddress(imm_addr)), v0, v1); + !(is_immediate && PowerPC::IsOptimizableRAMAddress(imm_addr)), v0, v1); SetJumpTarget(DoNotLoad); } @@ -384,7 +384,7 @@ void JitArm::stfXX(UGeckoInstruction inst) jit->js.fifoBytesThisBlock += accessSize >> 3; } - else if (Memory::IsRAMAddress(imm_addr)) + else if (PowerPC::IsOptimizableRAMAddress(imm_addr)) { MOVI2R(addr, imm_addr); EmitBackpatchRoutine(this, flags, SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem, false, v0); diff --git a/Source/Core/Core/PowerPC/JitArm32/JitAsm.cpp b/Source/Core/Core/PowerPC/JitArm32/JitAsm.cpp index ff65bf6393..a14db90245 100644 --- a/Source/Core/Core/PowerPC/JitArm32/JitAsm.cpp +++ b/Source/Core/Core/PowerPC/JitArm32/JitAsm.cpp @@ -29,20 +29,20 @@ JitArmAsmRoutineManager asm_routines; static void WriteDual32(u32 value1, u32 value2, u32 address) { - Memory::Write_U32(value1, address); - Memory::Write_U32(value2, address + 4); + PowerPC::Write_U32(value1, address); + PowerPC::Write_U32(value2, address + 4); } static void WriteDual16(u32 value1, u32 value2, u32 address) { - Memory::Write_U16(value1, address); - Memory::Write_U16(value2, address + 2); + PowerPC::Write_U16(value1, address); + PowerPC::Write_U16(value2, address + 2); } static void WriteDual8(u32 value1, u32 value2, u32 address) { - Memory::Write_U8(value1, address); - Memory::Write_U8(value2, address + 1); + PowerPC::Write_U8(value1, address); + PowerPC::Write_U8(value2, address + 1); } void JitArmAsmRoutineManager::Generate() @@ -56,7 +56,7 @@ void JitArmAsmRoutineManager::Generate() SUB(_SP, _SP, 4); MOVI2R(R9, (u32)&PowerPC::ppcState.spr[0]); - MOVI2R(R8, (u32)Memory::base); + MOVI2R(R8, (u32)Memory::physical_base); FixupBranch skipToRealDispatcher = B(); dispatcher = GetCodePtr(); @@ -465,7 +465,7 @@ void JitArmAsmRoutineManager::GenerateCommon() PUSH(5, R0, R1, R2, R3, _LR); VMOV(R0, S0); MOV(R1, R10); - MOVI2R(R10, (u32)&Memory::Write_U32); + MOVI2R(R10, (u32)&PowerPC::Write_U32); BL(R10); POP(5, R0, R1, R2, R3, _PC); @@ -493,7 +493,7 @@ void JitArmAsmRoutineManager::GenerateCommon() PUSH(5, R0, R1, R2, R3, _LR); VMOV(R0, S0); MOV(R1, R10); - MOVI2R(R10, (u32)&Memory::Write_U8); + MOVI2R(R10, (u32)&PowerPC::Write_U8); BL(R10); POP(5, R0, R1, R2, R3, _PC); } @@ -521,7 +521,7 @@ void JitArmAsmRoutineManager::GenerateCommon() PUSH(5, R0, R1, R2, R3, _LR); VMOV(R0, S0); MOV(R1, R10); - MOVI2R(R10, (u32)&Memory::Write_U16); + MOVI2R(R10, (u32)&PowerPC::Write_U16); BL(R10); POP(5, R0, R1, R2, R3, _PC); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp index 7075a3a81b..c057c88a6b 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp @@ -8,6 +8,7 @@ #include "Common/StringUtil.h" #include "Core/HW/Memmap.h" +#include "Core/PowerPC/PowerPC.h" #include "Core/PowerPC/JitArm64/Jit.h" #include "Core/PowerPC/JitArmCommon/BackPatch.h" @@ -127,7 +128,8 @@ u32 JitArm64::EmitBackpatchRoutine(ARM64XEmitter* emit, u32 flags, bool fastmem, if (fastmem) { - MOVK(addr, ((u64)Memory::base >> 32) & 0xFFFF, SHIFT_32); + u8* base = UReg_MSR(MSR).DR ? Memory::logical_base : Memory::physical_base; + MOVK(addr, ((u64)base >> 32) & 0xFFFF, SHIFT_32); if (flags & BackPatchInfo::FLAG_STORE && flags & (BackPatchInfo::FLAG_SIZE_F32 | BackPatchInfo::FLAG_SIZE_F64)) @@ -249,22 +251,22 @@ u32 JitArm64::EmitBackpatchRoutine(ARM64XEmitter* emit, u32 flags, bool fastmem, emit->MOV(W0, RS); if (flags & BackPatchInfo::FLAG_SIZE_32) - emit->MOVI2R(X30, (u64)&Memory::Write_U32); + emit->MOVI2R(X30, (u64)&PowerPC::Write_U32); else if (flags & BackPatchInfo::FLAG_SIZE_16) - emit->MOVI2R(X30, (u64)&Memory::Write_U16); + emit->MOVI2R(X30, (u64)&PowerPC::Write_U16); else - emit->MOVI2R(X30, (u64)&Memory::Write_U8); + emit->MOVI2R(X30, (u64)&PowerPC::Write_U8); emit->BLR(X30); } else { if (flags & BackPatchInfo::FLAG_SIZE_32) - emit->MOVI2R(X30, (u64)&Memory::Read_U32); + emit->MOVI2R(X30, (u64)&PowerPC::Read_U32); else if (flags & BackPatchInfo::FLAG_SIZE_16) - emit->MOVI2R(X30, (u64)&Memory::Read_U16); + emit->MOVI2R(X30, (u64)&PowerPC::Read_U16); else if (flags & BackPatchInfo::FLAG_SIZE_8) - emit->MOVI2R(X30, (u64)&Memory::Read_U8); + emit->MOVI2R(X30, (u64)&PowerPC::Read_U8); emit->BLR(X30); @@ -302,9 +304,10 @@ u32 JitArm64::EmitBackpatchRoutine(ARM64XEmitter* emit, u32 flags, bool fastmem, bool JitArm64::HandleFault(uintptr_t access_address, SContext* ctx) { - if (access_address < (uintptr_t)Memory::base) + if (!(access_address >= (uintptr_t)Memory::physical_base && access_address < (uintptr_t)Memory::physical_base + 0x100010000) && + !(access_address >= (uintptr_t)Memory::logical_base && access_address < (uintptr_t)Memory::logical_base + 0x100010000)) { - ERROR_LOG(DYNA_REC, "Exception handler - access below memory space. PC: 0x%016llx 0x%016lx < 0x%016lx", ctx->CTX_PC, access_address, (uintptr_t)Memory::base); + ERROR_LOG(DYNA_REC, "Exception handler - access below memory space. PC: 0x%016llx 0x%016lx < 0x%016lx", ctx->CTX_PC, access_address, (uintptr_t)Memory::physical_base); DoBacktrace(access_address, ctx); return false; diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp index 51b4f32fc5..e7f03e6037 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp @@ -147,7 +147,7 @@ void JitArm64::SafeLoadToReg(u32 dest, s32 addr, s32 offsetReg, u32 flags, s32 o if (update) MOV(gpr.R(addr), addr_reg); - if (is_immediate && Memory::IsRAMAddress(imm_addr)) + if (is_immediate && PowerPC::IsOptimizableRAMAddress(imm_addr)) { EmitBackpatchRoutine(this, flags, true, false, dest_reg, XA); } @@ -288,7 +288,7 @@ void JitArm64::SafeStoreFromReg(s32 dest, u32 value, s32 regOffset, u32 flags, s ARM64Reg XA = EncodeRegTo64(addr_reg); - if (is_immediate && Memory::IsRAMAddress(imm_addr)) + if (is_immediate && PowerPC::IsOptimizableRAMAddress(imm_addr)) { MOVI2R(XA, imm_addr); @@ -401,9 +401,9 @@ void JitArm64::lXX(UGeckoInstruction inst) if (SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle && inst.OPCD == 32 && (inst.hex & 0xFFFF0000) == 0x800D0000 && - (Memory::ReadUnchecked_U32(js.compilerPC + 4) == 0x28000000 || - (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && Memory::ReadUnchecked_U32(js.compilerPC + 4) == 0x2C000000)) && - Memory::ReadUnchecked_U32(js.compilerPC + 8) == 0x4182fff8) + (PowerPC::HostRead_U32(js.compilerPC + 4) == 0x28000000 || + (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && PowerPC::HostRead_U32(js.compilerPC + 4) == 0x2C000000)) && + PowerPC::HostRead_U32(js.compilerPC + 8) == 0x4182fff8) { // if it's still 0, we can wait until the next event FixupBranch noIdle = CBNZ(gpr.R(d)); diff --git a/Source/Core/Core/PowerPC/JitCommon/JitBackpatch.cpp b/Source/Core/Core/PowerPC/JitCommon/JitBackpatch.cpp index eac028922e..6f2ad2747e 100644 --- a/Source/Core/Core/PowerPC/JitCommon/JitBackpatch.cpp +++ b/Source/Core/Core/PowerPC/JitCommon/JitBackpatch.cpp @@ -30,8 +30,11 @@ static void BackPatchError(const std::string &text, u8 *codePtr, u32 emAddress) bool Jitx86Base::HandleFault(uintptr_t access_address, SContext* ctx) { // TODO: do we properly handle off-the-end? - if (access_address >= (uintptr_t)Memory::base && access_address < (uintptr_t)Memory::base + 0x100010000) - return BackPatch((u32)(access_address - (uintptr_t)Memory::base), ctx); + if (access_address >= (uintptr_t)Memory::physical_base && access_address < (uintptr_t)Memory::physical_base + 0x100010000) + return BackPatch((u32)(access_address - (uintptr_t)Memory::physical_base), ctx); + if (access_address >= (uintptr_t)Memory::logical_base && access_address < (uintptr_t)Memory::logical_base + 0x100010000) + return BackPatch((u32)(access_address - (uintptr_t)Memory::logical_base), ctx); + return false; } diff --git a/Source/Core/Core/PowerPC/JitCommon/Jit_Util.cpp b/Source/Core/Core/PowerPC/JitCommon/Jit_Util.cpp index 99ae32e017..f15f606d86 100644 --- a/Source/Core/Core/PowerPC/JitCommon/Jit_Util.cpp +++ b/Source/Core/Core/PowerPC/JitCommon/Jit_Util.cpp @@ -71,12 +71,12 @@ u8 *EmuCodeBlock::UnsafeLoadToReg(X64Reg reg_value, OpArg opAddress, int accessS opAddress = R(reg_value); offset = 0; } - memOperand = MComplex(RMEM, opAddress.GetSimpleReg(), SCALE_1, offset); } else if (opAddress.IsImm()) { - memOperand = MDisp(RMEM, (opAddress.offset + offset) & 0x3FFFFFFF); + MOV(32, R(reg_value), Imm32((u32)(opAddress.offset + offset))); + memOperand = MRegSum(RMEM, reg_value); } else { @@ -308,9 +308,9 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg & opAddress, // access the RAM buffer and load from there). // 2. If the address is in the MMIO range, find the appropriate // MMIO handler and generate the code to load using the handler. - // 3. Otherwise, just generate a call to Memory::Read_* with the + // 3. Otherwise, just generate a call to PowerPC::Read_* with the // address hardcoded. - if (Memory::IsRAMAddress(address)) + if (PowerPC::IsOptimizableRAMAddress(address)) { UnsafeLoadToReg(reg_value, opAddress, accessSize, offset, signExtend); } @@ -324,10 +324,10 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg & opAddress, ABI_PushRegistersAndAdjustStack(registersInUse, 0); switch (accessSize) { - case 64: ABI_CallFunctionC((void *)&Memory::Read_U64, address); break; - case 32: ABI_CallFunctionC((void *)&Memory::Read_U32, address); break; - case 16: ABI_CallFunctionC((void *)&Memory::Read_U16_ZX, address); break; - case 8: ABI_CallFunctionC((void *)&Memory::Read_U8_ZX, address); break; + case 64: ABI_CallFunctionC((void *)&PowerPC::Read_U64, address); break; + case 32: ABI_CallFunctionC((void *)&PowerPC::Read_U32, address); break; + case 16: ABI_CallFunctionC((void *)&PowerPC::Read_U16_ZX, address); break; + case 8: ABI_CallFunctionC((void *)&PowerPC::Read_U8_ZX, address); break; } ABI_PopRegistersAndAdjustStack(registersInUse, 0); @@ -366,16 +366,16 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg & opAddress, switch (accessSize) { case 64: - ABI_CallFunctionR((void *)&Memory::Read_U64, reg_addr); + ABI_CallFunctionR((void *)&PowerPC::Read_U64, reg_addr); break; case 32: - ABI_CallFunctionR((void *)&Memory::Read_U32, reg_addr); + ABI_CallFunctionR((void *)&PowerPC::Read_U32, reg_addr); break; case 16: - ABI_CallFunctionR((void *)&Memory::Read_U16_ZX, reg_addr); + ABI_CallFunctionR((void *)&PowerPC::Read_U16_ZX, reg_addr); break; case 8: - ABI_CallFunctionR((void *)&Memory::Read_U8_ZX, reg_addr); + ABI_CallFunctionR((void *)&PowerPC::Read_U8_ZX, reg_addr); break; } ABI_PopRegistersAndAdjustStack(registersInUse, rsp_alignment); @@ -490,7 +490,7 @@ bool EmuCodeBlock::WriteToConstAddress(int accessSize, OpArg arg, u32 address, B UnsafeWriteGatherPipe(accessSize); return false; } - else if (Memory::IsRAMAddress(address)) + else if (PowerPC::IsOptimizableRAMAddress(address)) { WriteToConstRamAddress(accessSize, arg, address); return false; @@ -504,16 +504,16 @@ bool EmuCodeBlock::WriteToConstAddress(int accessSize, OpArg arg, u32 address, B switch (accessSize) { case 64: - ABI_CallFunctionAC(64, (void *)&Memory::Write_U64, arg, address); + ABI_CallFunctionAC(64, (void *)&PowerPC::Write_U64, arg, address); break; case 32: - ABI_CallFunctionAC(32, (void *)&Memory::Write_U32, arg, address); + ABI_CallFunctionAC(32, (void *)&PowerPC::Write_U32, arg, address); break; case 16: - ABI_CallFunctionAC(16, (void *)&Memory::Write_U16, arg, address); + ABI_CallFunctionAC(16, (void *)&PowerPC::Write_U16, arg, address); break; case 8: - ABI_CallFunctionAC(8, (void *)&Memory::Write_U8, arg, address); + ABI_CallFunctionAC(8, (void *)&PowerPC::Write_U8, arg, address); break; } ABI_PopRegistersAndAdjustStack(registersInUse, 0); @@ -599,16 +599,16 @@ void EmuCodeBlock::SafeWriteRegToReg(OpArg reg_value, X64Reg reg_addr, int acces switch (accessSize) { case 64: - ABI_CallFunctionRR(swap ? ((void *)&Memory::Write_U64) : ((void *)&Memory::Write_U64_Swap), reg, reg_addr); + ABI_CallFunctionRR(swap ? ((void *)&PowerPC::Write_U64) : ((void *)&PowerPC::Write_U64_Swap), reg, reg_addr); break; case 32: - ABI_CallFunctionRR(swap ? ((void *)&Memory::Write_U32) : ((void *)&Memory::Write_U32_Swap), reg, reg_addr); + ABI_CallFunctionRR(swap ? ((void *)&PowerPC::Write_U32) : ((void *)&PowerPC::Write_U32_Swap), reg, reg_addr); break; case 16: - ABI_CallFunctionRR(swap ? ((void *)&Memory::Write_U16) : ((void *)&Memory::Write_U16_Swap), reg, reg_addr); + ABI_CallFunctionRR(swap ? ((void *)&PowerPC::Write_U16) : ((void *)&PowerPC::Write_U16_Swap), reg, reg_addr); break; case 8: - ABI_CallFunctionRR((void *)&Memory::Write_U8, reg, reg_addr); + ABI_CallFunctionRR((void *)&PowerPC::Write_U8, reg, reg_addr); break; } ABI_PopRegistersAndAdjustStack(registersInUse, rsp_alignment); @@ -626,7 +626,8 @@ void EmuCodeBlock::WriteToConstRamAddress(int accessSize, OpArg arg, u32 address if (arg.IsImm()) { arg = SwapImmediate(accessSize, arg); - MOV(accessSize, MDisp(RMEM, address & 0x3FFFFFFF), arg); + MOV(32, R(RSCRATCH), Imm32(address)); + MOV(accessSize, MRegSum(RMEM, RSCRATCH), arg); return; } @@ -640,10 +641,11 @@ void EmuCodeBlock::WriteToConstRamAddress(int accessSize, OpArg arg, u32 address reg = arg.GetSimpleReg(); } + MOV(32, R(RSCRATCH2), Imm32(address)); if (swap) - SwapAndStore(accessSize, MDisp(RMEM, address & 0x3FFFFFFF), reg); + SwapAndStore(accessSize, MRegSum(RMEM, RSCRATCH2), reg); else - MOV(accessSize, MDisp(RMEM, address & 0x3FFFFFFF), R(reg)); + MOV(accessSize, MRegSum(RMEM, RSCRATCH2), R(reg)); } void EmuCodeBlock::ForceSinglePrecisionS(X64Reg output, X64Reg input) diff --git a/Source/Core/Core/PowerPC/JitCommon/TrampolineCache.cpp b/Source/Core/Core/PowerPC/JitCommon/TrampolineCache.cpp index 89ebfdea96..783b3d7edf 100644 --- a/Source/Core/Core/PowerPC/JitCommon/TrampolineCache.cpp +++ b/Source/Core/Core/PowerPC/JitCommon/TrampolineCache.cpp @@ -66,16 +66,16 @@ const u8* TrampolineCache::GenerateReadTrampoline(const InstructionInfo &info, B switch (info.operandSize) { case 8: - CALL((void *)&Memory::Read_U64); + CALL((void*)&PowerPC::Read_U64); break; case 4: - CALL((void *)&Memory::Read_U32); + CALL((void*)&PowerPC::Read_U32); break; case 2: - CALL((void *)&Memory::Read_U16); + CALL((void*)&PowerPC::Read_U16); break; case 1: - CALL((void *)&Memory::Read_U8); + CALL((void*)&PowerPC::Read_U8); break; } @@ -154,16 +154,16 @@ const u8* TrampolineCache::GenerateWriteTrampoline(const InstructionInfo &info, switch (info.operandSize) { case 8: - CALL((void *)&Memory::Write_U64); + CALL((void *)&PowerPC::Write_U64); break; case 4: - CALL((void *)&Memory::Write_U32); + CALL((void *)&PowerPC::Write_U32); break; case 2: - CALL((void *)&Memory::Write_U16); + CALL((void *)&PowerPC::Write_U16); break; case 1: - CALL((void *)&Memory::Write_U8); + CALL((void *)&PowerPC::Write_U8); break; } diff --git a/Source/Core/Core/PowerPC/JitILCommon/JitILBase_Branch.cpp b/Source/Core/Core/PowerPC/JitILCommon/JitILBase_Branch.cpp index e694fc23c2..13a5710bbe 100644 --- a/Source/Core/Core/PowerPC/JitILCommon/JitILBase_Branch.cpp +++ b/Source/Core/Core/PowerPC/JitILCommon/JitILBase_Branch.cpp @@ -142,11 +142,12 @@ void JitILBase::bcx(UGeckoInstruction inst) // The main Idle skipping is done in the LoadStore code, but there is an optimization here. // If idle skipping is enabled, then this branch will only be reached when the branch is not // taken. + // TODO: We shouldn't use debug reads here. if (SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle && inst.hex == 0x4182fff8 && - (Memory::ReadUnchecked_U32(js.compilerPC - 8) & 0xFFFF0000) == 0x800D0000 && - (Memory::ReadUnchecked_U32(js.compilerPC - 4) == 0x28000000 || - (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && Memory::ReadUnchecked_U32(js.compilerPC - 4) == 0x2C000000)) + (PowerPC::HostRead_U32(js.compilerPC - 8) & 0xFFFF0000) == 0x800D0000 && + (PowerPC::HostRead_U32(js.compilerPC - 4) == 0x28000000 || + (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && PowerPC::HostRead_U32(js.compilerPC - 4) == 0x2C000000)) ) { // Uh, Do nothing. diff --git a/Source/Core/Core/PowerPC/JitILCommon/JitILBase_LoadStore.cpp b/Source/Core/Core/PowerPC/JitILCommon/JitILBase_LoadStore.cpp index 4dbc9aeda5..58e886bb9d 100644 --- a/Source/Core/Core/PowerPC/JitILCommon/JitILBase_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/JitILCommon/JitILBase_LoadStore.cpp @@ -34,15 +34,17 @@ void JitILBase::lXz(UGeckoInstruction inst) IREmitter::InstLoc val; - // Idle Skipping. This really should be done somewhere else. - // Either lower in the IR or higher in PPCAnalyist + // Idle Skipping. + // TODO: This really should be done somewhere else. Either lower in the IR + // or higher in PPCAnalyst + // TODO: We shouldn't use debug reads here. if (SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle && PowerPC::GetState() != PowerPC::CPU_STEPPING && inst.OPCD == 32 && // Lwx (inst.hex & 0xFFFF0000) == 0x800D0000 && - (Memory::ReadUnchecked_U32(js.compilerPC + 4) == 0x28000000 || - (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && Memory::ReadUnchecked_U32(js.compilerPC + 4) == 0x2C000000)) && - Memory::ReadUnchecked_U32(js.compilerPC + 8) == 0x4182fff8) + (PowerPC::HostRead_U32(js.compilerPC + 4) == 0x28000000 || + (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && PowerPC::HostRead_U32(js.compilerPC + 4) == 0x2C000000)) && + PowerPC::HostRead_U32(js.compilerPC + 8) == 0x4182fff8) { val = ibuild.EmitLoad32(addr); ibuild.EmitIdleBranch(val, ibuild.EmitIntConst(js.compilerPC)); @@ -138,7 +140,9 @@ void JitILBase::dcbst(UGeckoInstruction inst) // memory location. Do not invalidate the JIT cache in this case as the memory // will be the same. // dcbt = 0x7c00022c - FALLBACK_IF((Memory::ReadUnchecked_U32(js.compilerPC - 4) & 0x7c00022c) != 0x7c00022c); + // TODO: We shouldn't use a debug read here; it should be possible to get the + // previous instruction from the JIT state. + FALLBACK_IF((PowerPC::HostRead_U32(js.compilerPC - 4) & 0x7c00022c) != 0x7c00022c); } // Zero cache line. diff --git a/Source/Core/Core/PowerPC/JitInterface.cpp b/Source/Core/Core/PowerPC/JitInterface.cpp index 9d3a04f768..977907052a 100644 --- a/Source/Core/Core/PowerPC/JitInterface.cpp +++ b/Source/Core/Core/PowerPC/JitInterface.cpp @@ -207,27 +207,6 @@ namespace JitInterface jit->GetBlockCache()->InvalidateICache(address, size, forced); } - u32 ReadOpcodeJIT(u32 _Address) - { - if (bMMU && !bFakeVMEM && (_Address & Memory::ADDR_MASK_MEM1)) - { - _Address = Memory::TranslateAddress(_Address); - if (_Address == 0) - { - return 0; - } - } - - u32 inst; - // Bypass the icache for the external interrupt exception handler - // -- this is stupid, should respect HID0 - if ( (_Address & 0x0FFFFF00) == 0x00000500 ) - inst = Memory::ReadUnchecked_U32(_Address); - else - inst = PowerPC::ppcState.iCache.ReadInstruction(_Address); - return inst; - } - void CompileExceptionCheck(ExceptionType type) { if (!jit) @@ -250,7 +229,7 @@ namespace JitInterface if (type == ExceptionType::EXCEPTIONS_FIFO_WRITE) { // Check in case the code has been replaced since: do we need to do this? - int optype = GetOpInfo(Memory::ReadUnchecked_U32(PC))->type; + int optype = GetOpInfo(PowerPC::HostRead_U32(PC))->type; if (optype != OPTYPE_STORE && optype != OPTYPE_STOREFP && (optype != OPTYPE_STOREPS)) return; } diff --git a/Source/Core/Core/PowerPC/JitInterface.h b/Source/Core/Core/PowerPC/JitInterface.h index 3c56683af1..f87bfda92f 100644 --- a/Source/Core/Core/PowerPC/JitInterface.h +++ b/Source/Core/Core/PowerPC/JitInterface.h @@ -29,9 +29,6 @@ namespace JitInterface // Memory Utilities bool HandleFault(uintptr_t access_address, SContext* ctx); - // used by JIT to read instructions - u32 ReadOpcodeJIT(const u32 _Address); - // Clearing CodeCache void ClearCache(); diff --git a/Source/Core/Core/HW/MemmapFunctions.cpp b/Source/Core/Core/PowerPC/MMU.cpp similarity index 71% rename from Source/Core/Core/HW/MemmapFunctions.cpp rename to Source/Core/Core/PowerPC/MMU.cpp index 42d389a077..9e63845cbe 100644 --- a/Source/Core/Core/HW/MemmapFunctions.cpp +++ b/Source/Core/Core/PowerPC/MMU.cpp @@ -32,7 +32,7 @@ #include "Core/PowerPC/GDBStub.h" #endif -namespace Memory +namespace PowerPC { #define HW_PAGE_SIZE 4096 @@ -66,6 +66,14 @@ inline u32 bswap(u32 val) { return Common::swap32(val); } inline u64 bswap(u64 val) { return Common::swap64(val); } // ================= +enum XCheckTLBFlag +{ + FLAG_NO_EXCEPTION, + FLAG_READ, + FLAG_WRITE, + FLAG_OPCODE, +}; +template static u32 TranslateAddress(const u32 address); // Nasty but necessary. Super Mario Galaxy pointer relies on this stuff. static u32 EFB_Read(const u32 addr) @@ -111,39 +119,62 @@ static void EFB_Write(u32 data, u32 addr) static void GenerateDSIException(u32 _EffectiveAddress, bool _bWrite); template -__forceinline T ReadFromHardware(const u32 em_address) +__forceinline static T ReadFromHardware(const u32 em_address) { int segment = em_address >> 28; + bool performTranslation = UReg_MSR(MSR).DR; + // Quick check for an address that can't meet any of the following conditions, // to speed up the MMU path. - if (!BitSet32(0xCFC)[segment]) + if (!BitSet32(0xCFC)[segment] && performTranslation) { // TODO: Figure out the fastest order of tests for both read and write (they are probably different). - if ((em_address & 0xC8000000) == 0xC8000000) + if (flag == FLAG_READ && (em_address & 0xF8000000) == 0xC8000000) { if (em_address < 0xcc000000) return EFB_Read(em_address); else - return (T)mmio_mapping->Read::type>(em_address); + return (T)Memory::mmio_mapping->Read::type>(em_address); } - else if (segment == 0x8 || segment == 0xC || segment == 0x0) + if ((segment == 0x0 || segment == 0x8 || segment == 0xC) && (em_address & 0x0FFFFFFF) < Memory::REALRAM_SIZE) { - return bswap((*(const T*)&m_pRAM[em_address & RAM_MASK])); + return bswap((*(const T*)&Memory::m_pRAM[em_address & 0x0FFFFFFF])); } - else if (m_pEXRAM && (segment == 0x9 || segment == 0xD || segment == 0x1)) + if (Memory::m_pEXRAM && (segment == 0x9 || segment == 0xD) && (em_address & 0x0FFFFFFF) < Memory::EXRAM_SIZE) { - return bswap((*(const T*)&m_pEXRAM[em_address & EXRAM_MASK])); + return bswap((*(const T*)&Memory::m_pEXRAM[em_address & 0x0FFFFFFF])); } - else if (segment == 0xE && (em_address < (0xE0000000 + L1_CACHE_SIZE))) + if (segment == 0xE && (em_address < (0xE0000000 + Memory::L1_CACHE_SIZE))) { - return bswap((*(const T*)&m_pL1Cache[em_address & L1_CACHE_MASK])); + return bswap((*(const T*)&Memory::m_pL1Cache[em_address & 0x0FFFFFFF])); } } - if (bFakeVMEM && (segment == 0x7 || segment == 0x4)) + if (Memory::bFakeVMEM && performTranslation && (segment == 0x7 || segment == 0x4)) { // fake VMEM - return bswap((*(const T*)&m_pFakeVMEM[em_address & FAKEVMEM_MASK])); + return bswap((*(const T*)&Memory::m_pFakeVMEM[em_address & Memory::FAKEVMEM_MASK])); + } + + if (!performTranslation) + { + if (flag == FLAG_READ && (em_address & 0xF8000000) == 0x08000000) + { + if (em_address < 0x0c000000) + return EFB_Read(em_address); + else + return (T)Memory::mmio_mapping->Read::type>(em_address | 0xC0000000); + } + if (em_address < Memory::REALRAM_SIZE) + { + return bswap((*(const T*)&Memory::m_pRAM[em_address])); + } + if (Memory::m_pEXRAM && segment == 0x1 && (em_address & 0x0FFFFFFF) < Memory::EXRAM_SIZE) + { + return bswap((*(const T*)&Memory::m_pEXRAM[em_address & 0x0FFFFFFF])); + } + PanicAlert("Unable to resolve read address %x PC %x", em_address, PC); + return 0; } // MMU: Do page table translation @@ -177,27 +208,29 @@ __forceinline T ReadFromHardware(const u32 em_address) { if (addr == em_address_next_page) tlb_addr = tlb_addr_next_page; - var = (var << 8) | Memory::base[tlb_addr]; + var = (var << 8) | Memory::physical_base[tlb_addr]; } return var; } // The easy case! - return bswap(*(const T*)&Memory::base[tlb_addr]); + return bswap(*(const T*)&Memory::physical_base[tlb_addr]); } template -__forceinline void WriteToHardware(u32 em_address, const T data) +__forceinline static void WriteToHardware(u32 em_address, const T data) { int segment = em_address >> 28; // Quick check for an address that can't meet any of the following conditions, // to speed up the MMU path. - if (!BitSet32(0xCFC)[segment]) + bool performTranslation = UReg_MSR(MSR).DR; + + if (!BitSet32(0xCFC)[segment] && performTranslation) { // First, let's check for FIFO writes, since they are probably the most common // reason we end up in this function: - if ((em_address & 0xFFFFF000) == 0xCC008000) + if (flag == FLAG_WRITE && (em_address & 0xFFFFF000) == 0xCC008000) { switch (sizeof(T)) { @@ -207,7 +240,7 @@ __forceinline void WriteToHardware(u32 em_address, const T data) case 8: GPFifo::Write64((u64)data, em_address); return; } } - if ((em_address & 0xC8000000) == 0xC8000000) + if (flag == FLAG_WRITE && (em_address & 0xF8000000) == 0xC8000000) { if (em_address < 0xcc000000) { @@ -217,31 +250,71 @@ __forceinline void WriteToHardware(u32 em_address, const T data) } else { - mmio_mapping->Write(em_address, data); + Memory::mmio_mapping->Write(em_address, data); return; } } - else if (segment == 0x8 || segment == 0xC || segment == 0x0) + if ((segment == 0x8 || segment == 0xC) && (em_address & 0x0FFFFFFF) < Memory::REALRAM_SIZE) { - *(T*)&m_pRAM[em_address & RAM_MASK] = bswap(data); + *(T*)&Memory::m_pRAM[em_address & 0x0FFFFFFF] = bswap(data); return; } - else if (m_pEXRAM && (segment == 0x9 || segment == 0xD || segment == 0x1)) + if (Memory::m_pEXRAM && (segment == 0x9 || segment == 0xD) && (em_address & 0x0FFFFFFF) < Memory::EXRAM_SIZE) { - *(T*)&m_pEXRAM[em_address & EXRAM_MASK] = bswap(data); + *(T*)&Memory::m_pEXRAM[em_address & 0x0FFFFFFF] = bswap(data); return; } - else if (segment == 0xE && (em_address < (0xE0000000 + L1_CACHE_SIZE))) + if (segment == 0xE && (em_address < (0xE0000000 + Memory::L1_CACHE_SIZE))) { - *(T*)&m_pL1Cache[em_address & L1_CACHE_MASK] = bswap(data); + *(T*)&Memory::m_pL1Cache[em_address & 0x0FFFFFFF] = bswap(data); return; } } - if (bFakeVMEM && (segment == 0x7 || segment == 0x4)) + if (Memory::bFakeVMEM && performTranslation && (segment == 0x7 || segment == 0x4)) { // fake VMEM - *(T*)&m_pFakeVMEM[em_address & FAKEVMEM_MASK] = bswap(data); + *(T*)&Memory::m_pFakeVMEM[em_address & Memory::FAKEVMEM_MASK] = bswap(data); + return; + } + + if (!performTranslation) + { + if (flag == FLAG_WRITE && (em_address & 0xFFFFF000) == 0x0C008000) + { + switch (sizeof(T)) + { + case 1: GPFifo::Write8((u8)data, em_address); return; + case 2: GPFifo::Write16((u16)data, em_address); return; + case 4: GPFifo::Write32((u32)data, em_address); return; + case 8: GPFifo::Write64((u64)data, em_address); return; + } + } + if (flag == FLAG_WRITE && (em_address & 0xF8000000) == 0x08000000) + { + if (em_address < 0x0c000000) + { + // TODO: This only works correctly for 32-bit writes. + EFB_Write((u32)data, em_address); + return; + } + else + { + Memory::mmio_mapping->Write(em_address | 0xC0000000, data); + return; + } + } + if (em_address < Memory::REALRAM_SIZE) + { + *(T*)&Memory::m_pRAM[em_address] = bswap(data); + return; + } + if (Memory::m_pEXRAM && segment == 0x1 && (em_address & 0x0FFFFFFF) < Memory::EXRAM_SIZE) + { + *(T*)&Memory::m_pEXRAM[em_address & 0x0FFFFFFF] = bswap(data); + return; + } + PanicAlert("Unable to resolve write address %x PC %x", em_address, PC); return; } @@ -272,13 +345,13 @@ __forceinline void WriteToHardware(u32 em_address, const T data) { if (addr == em_address_next_page) tlb_addr = tlb_addr_next_page; - Memory::base[tlb_addr] = (u8)val; + Memory::physical_base[tlb_addr] = (u8)val; } return; } // The easy case! - *(T*)&Memory::base[tlb_addr] = bswap(data); + *(T*)&Memory::physical_base[tlb_addr] = bswap(data); } // ===================== @@ -292,30 +365,59 @@ static void GenerateISIException(u32 effective_address); u32 Read_Opcode(u32 address) { - if (address == 0x00000000) + TryReadInstResult result = TryReadInstruction(address); + if (!result.valid) { - // FIXME use assert? - PanicAlert("Program tried to read an opcode from [00000000]. It has crashed."); - return 0x00000000; + GenerateISIException(address); + return 0; } + return result.hex; +} - if (SConfig::GetInstance().m_LocalCoreStartupParameter.bMMU && - (address & ADDR_MASK_MEM1)) +TryReadInstResult TryReadInstruction(u32 address) +{ + bool from_bat = true; + if (UReg_MSR(MSR).IR) { - // TODO: Check for MSR instruction address translation flag before translating - u32 tlb_addr = TranslateAddress(address); - if (tlb_addr == 0) + // TODO: Use real translation. + if (SConfig::GetInstance().m_LocalCoreStartupParameter.bMMU && (address & Memory::ADDR_MASK_MEM1)) { - GenerateISIException(address); - return 0; + u32 tlb_addr = TranslateAddress(address); + if (tlb_addr == 0) + { + return TryReadInstResult{ false, false, 0 }; + } + else + { + address = tlb_addr; + from_bat = false; + } } else { - address = tlb_addr; + int segment = address >> 28; + if ((segment == 0x8 || segment == 0x0) && (address & 0x0FFFFFFF) < Memory::REALRAM_SIZE) + address = address & 0x3FFFFFFF; + else if (segment == 0x9 && (address & 0x0FFFFFFF) < Memory::EXRAM_SIZE) + address = address & 0x3FFFFFFF; + else + return TryReadInstResult{ false, false, 0 }; } } + else + { + if (address & 0xC0000000) + ERROR_LOG(MEMMAP, "Strange program counter with address translation off: 0x%08x", address); + } - return PowerPC::ppcState.iCache.ReadInstruction(address); + u32 hex = PowerPC::ppcState.iCache.ReadInstruction(address); + return TryReadInstResult{ true, from_bat, hex }; +} + +u32 HostRead_Instruction(const u32 address) +{ + UGeckoInstruction inst = HostRead_U32(address); + return inst.hex; } static __forceinline void Memcheck(u32 address, u32 var, bool write, int size) @@ -442,30 +544,103 @@ void Write_F64(const double var, const u32 address) cvt.d = var; Write_U64(cvt.i, address); } -u8 ReadUnchecked_U8(const u32 address) + +u8 HostRead_U8(const u32 address) { u8 var = ReadFromHardware(address); return var; } +u16 HostRead_U16(const u32 address) +{ + u16 var = ReadFromHardware(address); + return var; +} -u32 ReadUnchecked_U32(const u32 address) +u32 HostRead_U32(const u32 address) { u32 var = ReadFromHardware(address); return var; } -void WriteUnchecked_U8(const u8 var, const u32 address) +void HostWrite_U8(const u8 var, const u32 address) { WriteToHardware(address, var); } +void HostWrite_U16(const u16 var, const u32 address) +{ + WriteToHardware(address, var); +} -void WriteUnchecked_U32(const u32 var, const u32 address) +void HostWrite_U32(const u32 var, const u32 address) { WriteToHardware(address, var); } +void HostWrite_U64(const u64 var, const u32 address) +{ + WriteToHardware(address, var); +} + +std::string HostGetString(u32 address, size_t size) +{ + std::string s; + do + { + if (!HostIsRAMAddress(address)) + break; + u8 res = HostRead_U8(address); + if (!res) + break; + ++address; + } while (size == 0 || s.length() < size); + return s; +} + +bool IsOptimizableRAMAddress(const u32 address) +{ + if (!UReg_MSR(MSR).DR) + return false; + + int segment = address >> 28; + + return (((segment == 0x8 || segment == 0xC || segment == 0x0) && (address & 0x0FFFFFFF) < Memory::REALRAM_SIZE) || + (Memory::m_pEXRAM && (segment == 0x9 || segment == 0xD) && (address & 0x0FFFFFFF) < Memory::EXRAM_SIZE) || + (segment == 0xE && (address < (0xE0000000 + Memory::L1_CACHE_SIZE)))); +} + +bool HostIsRAMAddress(u32 address) +{ + // TODO: This needs to be rewritten; it makes incorrect assumptions + // about BATs and page tables. + bool performTranslation = UReg_MSR(MSR).DR; + int segment = address >> 28; + if (performTranslation) + { + if ((segment == 0x8 || segment == 0xC || segment == 0x0) && (address & 0x0FFFFFFF) < Memory::REALRAM_SIZE) + return true; + else if (Memory::m_pEXRAM && (segment == 0x9 || segment == 0xD) && (address & 0x0FFFFFFF) < Memory::EXRAM_SIZE) + return true; + else if (Memory::bFakeVMEM && (segment == 0x7 || segment == 0x4)) + return true; + else if (segment == 0xE && (address < (0xE0000000 + Memory::L1_CACHE_SIZE))) + return true; + + address = TranslateAddress(address); + if (!address) + return false; + } + + if (segment == 0x0 && (address & 0x0FFFFFFF) < Memory::REALRAM_SIZE) + return true; + else if (Memory::m_pEXRAM && segment == 0x1 && (address & 0x0FFFFFFF) < Memory::EXRAM_SIZE) + return true; + return false; + + +} + void DMA_LCToMemory(const u32 memAddr, const u32 cacheAddr, const u32 numBlocks) { // TODO: It's not completely clear this is the right spot for this code; @@ -475,7 +650,7 @@ void DMA_LCToMemory(const u32 memAddr, const u32 cacheAddr, const u32 numBlocks) // Avatar: The Last Airbender (GC) uses this for videos. if ((memAddr & 0x0F000000) == 0x08000000) { - for (u32 i = 0; i < 32 * numBlocks; i+=4) + for (u32 i = 0; i < 32 * numBlocks; i += 4) { u32 data = bswap(*(u32*)(Memory::m_pL1Cache + ((cacheAddr + i) & 0x3FFFF))); EFB_Write(data, memAddr + i); @@ -490,7 +665,7 @@ void DMA_LCToMemory(const u32 memAddr, const u32 cacheAddr, const u32 numBlocks) for (u32 i = 0; i < 32 * numBlocks; i += 4) { u32 data = bswap(*(u32*)(Memory::m_pL1Cache + ((cacheAddr + i) & 0x3FFFF))); - mmio_mapping->Write(memAddr + i, data); + Memory::mmio_mapping->Write(memAddr + i, data); } return; } @@ -526,7 +701,7 @@ void DMA_MemoryToLC(const u32 cacheAddr, const u32 memAddr, const u32 numBlocks) { for (u32 i = 0; i < 32 * numBlocks; i += 4) { - u32 data = mmio_mapping->Read(memAddr + i); + u32 data = Memory::mmio_mapping->Read(memAddr + i); *(u32*)(Memory::m_pL1Cache + ((cacheAddr + i) & 0x3FFFF)) = bswap(data); } return; @@ -538,6 +713,14 @@ void DMA_MemoryToLC(const u32 cacheAddr, const u32 memAddr, const u32 numBlocks) memcpy(dst, src, 32 * numBlocks); } +void ClearCacheLine(const u32 address) +{ + // FIXME: does this do the right thing if dcbz is run on hardware memory, e.g. + // the FIFO? Do games even do that? Probably not, but we should try to be correct... + for (u32 i = 0; i < 32; i += 8) + Write_U64(0, address + i); +} + // ********************************************************************************* // Warning: Test Area // @@ -785,10 +968,6 @@ static __forceinline u32 TranslatePageAddress(const u32 address, const XCheckTLB u32 VSID = SR_VSID(sr); // 24 bit u32 api = EA_API(address); // 6 bit (part of page_index) - // Direct access to the fastmem Arena - // FIXME: is this the best idea for clean code? - u8* base_mem = Memory::base; - // hash function no 1 "xor" .360 u32 hash = (VSID ^ page_index); u32 pte1 = bswap((VSID << 7) | api | PTE1_V); @@ -806,10 +985,10 @@ static __forceinline u32 TranslatePageAddress(const u32 address, const XCheckTLB for (int i = 0; i < 8; i++, pteg_addr += 8) { - if (pte1 == *(u32*)&base_mem[pteg_addr]) + if (pte1 == *(u32*)&Memory::physical_base[pteg_addr]) { UPTE2 PTE2; - PTE2.Hex = bswap((*(u32*)&base_mem[(pteg_addr + 4)])); + PTE2.Hex = bswap((*(u32*)&Memory::physical_base[pteg_addr + 4])); // set the access bits switch (flag) @@ -821,7 +1000,7 @@ static __forceinline u32 TranslatePageAddress(const u32 address, const XCheckTLB } if (flag != FLAG_NO_EXCEPTION) - *(u32*)&base_mem[(pteg_addr + 4)] = bswap(PTE2.Hex); + *(u32*)&Memory::physical_base[pteg_addr + 4] = bswap(PTE2.Hex); // We already updated the TLB entry if this was caused by a C bit. if (res != TLB_UPDATE_C) @@ -895,16 +1074,12 @@ static u32 TranslateBlockAddress(const u32 address, const XCheckTLBFlag flag) // Translate effective address using BAT or PAT. Returns 0 if the address cannot be translated. template -u32 TranslateAddress(const u32 address) +__forceinline u32 TranslateAddress(const u32 address) { - // Check MSR[IR] bit before translating instruction addresses. Rogue Leader clears IR and DR?? - //if ((_Flag == FLAG_OPCODE) && !(MSR & (1 << (31 - 26)))) return _Address; - - // Check MSR[DR] bit before translating data addresses - //if (((_Flag == FLAG_READ) || (_Flag == FLAG_WRITE)) && !(MSR & (1 << (31 - 27)))) return _Address; - - // Technically we should do this, but almost no games, even heavy MMU ones, use any custom BATs whatsoever, - // so only do it where it's really needed. + // TODO: bBAT in theory should allow dynamic changes to the BAT registers. + // In reality, the option is mostly useless at the moment because we don't + // always translate addresses when we should. ReadFromHardware/WriteFromHardware, + // fastmem, the JIT cache, and some misc code in the JIT assume default BATs. if (SConfig::GetInstance().m_LocalCoreStartupParameter.bBAT) { u32 tlb_addr = TranslateBlockAddress(address, flag); @@ -914,8 +1089,4 @@ u32 TranslateAddress(const u32 address) return TranslatePageAddress(address, flag); } -template u32 TranslateAddress(const u32 address); -template u32 TranslateAddress(const u32 address); -template u32 TranslateAddress(const u32 address); -template u32 TranslateAddress(const u32 address); } // namespace diff --git a/Source/Core/Core/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/PowerPC/PPCAnalyst.cpp index 2cd692572d..69c27ac314 100644 --- a/Source/Core/Core/PowerPC/PPCAnalyst.cpp +++ b/Source/Core/Core/PowerPC/PPCAnalyst.cpp @@ -96,7 +96,7 @@ bool AnalyzeFunction(u32 startAddr, Symbol &func, int max_size) if (func.size >= CODEBUFFER_SIZE * 4) //weird return false; - UGeckoInstruction instr = (UGeckoInstruction)Memory::ReadUnchecked_U32(addr); + UGeckoInstruction instr = (UGeckoInstruction)PowerPC::HostRead_U32(addr); if (max_size && func.size > max_size) { func.address = startAddr; @@ -275,7 +275,7 @@ static void FindFunctionsFromBranches(u32 startAddr, u32 endAddr, SymbolDB *func { for (u32 addr = startAddr; addr < endAddr; addr+=4) { - UGeckoInstruction instr = (UGeckoInstruction)Memory::ReadUnchecked_U32(addr); + UGeckoInstruction instr = (UGeckoInstruction)PowerPC::HostRead_U32(addr); if (PPCTables::IsValidInstruction(instr)) { @@ -288,7 +288,7 @@ static void FindFunctionsFromBranches(u32 startAddr, u32 endAddr, SymbolDB *func u32 target = SignExt26(instr.LI << 2); if (!instr.AA) target += addr; - if (Memory::IsRAMAddress(target)) + if (PowerPC::HostIsRAMAddress(target)) { func_db->AddFunction(target); } @@ -314,9 +314,9 @@ static void FindFunctionsAfterBLR(PPCSymbolDB *func_db) while (true) { // skip zeroes that sometimes pad function to 16 byte boundary (e.g. Donkey Kong Country Returns) - while (Memory::Read_Instruction(location) == 0 && ((location & 0xf) != 0)) + while (PowerPC::HostRead_Instruction(location) == 0 && ((location & 0xf) != 0)) location += 4; - if (PPCTables::IsValidInstruction(Memory::Read_Instruction(location))) + if (PPCTables::IsValidInstruction(PowerPC::HostRead_Instruction(location))) { //check if this function is already mapped Symbol *f = func_db->AddFunction(location); @@ -649,34 +649,24 @@ u32 PPCAnalyzer::Analyze(u32 address, CodeBlock *block, CodeBuffer *buffer, u32 block->m_num_instructions = 0; block->m_gqr_used = BitSet8(0); - if (address == 0) - { - // Memory exception occurred during instruction fetch - block->m_memory_exception = true; - return address; - } - - bool virtualAddr = SConfig::GetInstance().m_LocalCoreStartupParameter.bMMU && (address & JIT_ICACHE_VMEM_BIT); - if (virtualAddr) - { - if (!Memory::TranslateAddress(address)) - { - // Memory exception occurred during instruction fetch - block->m_memory_exception = true; - return address; - } - } - CodeOp *code = buffer->codebuffer; bool found_exit = false; u32 return_address = 0; u32 numFollows = 0; u32 num_inst = 0; + bool prev_inst_from_bat = true; for (u32 i = 0; i < blockSize; ++i) { - UGeckoInstruction inst = JitInterface::ReadOpcodeJIT(address); + auto result = PowerPC::TryReadInstruction(address); + if (!result.valid) + { + if (i == 0) + block->m_memory_exception = true; + break; + } + UGeckoInstruction inst = result.hex; if (inst.hex != 0) { @@ -684,10 +674,11 @@ u32 PPCAnalyzer::Analyze(u32 address, CodeBlock *block, CodeBuffer *buffer, u32 // but broken blocks due to page faults break this assumption. Avoid this by just ending // all virtual memory instruction blocks at page boundaries. // FIXME: improve the JIT block cache so we don't need to do this. - if (virtualAddr && i > 0 && (address & 0xfff) == 0) + if ((!result.from_bat || !prev_inst_from_bat) && i > 0 && (address & 0xfff) == 0) { break; } + prev_inst_from_bat = result.from_bat; num_inst++; memset(&code[i], 0, sizeof(CodeOp)); @@ -813,10 +804,7 @@ u32 PPCAnalyzer::Analyze(u32 address, CodeBlock *block, CodeBuffer *buffer, u32 } else { - // ISI exception or other critical memory exception occured (game over) - // We can continue on in MMU mode though, so don't spam this error in that case. - if (!virtualAddr) - ERROR_LOG(DYNA_REC, "Instruction hex was 0!"); + ERROR_LOG(DYNA_REC, "Instruction hex was 0!"); break; } } diff --git a/Source/Core/Core/PowerPC/PPCCache.cpp b/Source/Core/Core/PowerPC/PPCCache.cpp index 28e006f7bc..313bb26bc5 100644 --- a/Source/Core/Core/PowerPC/PPCCache.cpp +++ b/Source/Core/Core/PowerPC/PPCCache.cpp @@ -100,7 +100,7 @@ namespace PowerPC u32 InstructionCache::ReadInstruction(u32 addr) { if (!HID0.ICE) // instruction cache is disabled - return Memory::ReadUnchecked_U32(addr); + return Memory::Read_U32(addr); u32 set = (addr >> 5) & 0x7f; u32 tag = addr >> 12; @@ -121,7 +121,7 @@ namespace PowerPC if (t == 0xff) // load to the cache { if (HID0.ILOCK) // instruction cache is locked - return Memory::ReadUnchecked_U32(addr); + return Memory::Read_U32(addr); // select a way if (valid[set] != 0xff) t = way_from_valid[valid[set]]; diff --git a/Source/Core/Core/PowerPC/PPCSymbolDB.cpp b/Source/Core/Core/PowerPC/PPCSymbolDB.cpp index 55d9cb1e59..9e779d8e30 100644 --- a/Source/Core/Core/PowerPC/PPCSymbolDB.cpp +++ b/Source/Core/Core/PowerPC/PPCSymbolDB.cpp @@ -86,7 +86,7 @@ void PPCSymbolDB::AddKnownSymbol(u32 startAddr, u32 size, const std::string& nam Symbol *PPCSymbolDB::GetSymbolFromAddr(u32 addr) { - if (!Memory::IsRAMAddress(addr)) + if (!PowerPC::HostIsRAMAddress(addr)) return nullptr; XFuncMap::iterator it = functions.find(addr); @@ -333,11 +333,11 @@ bool PPCSymbolDB::LoadMap(const std::string& filename, bool bad) if (!good) { // check for BLR before function - u32 opcode = Memory::Read_Instruction(vaddress - 4); + u32 opcode = PowerPC::HostRead_Instruction(vaddress - 4); if (opcode == 0x4e800020) { // check for BLR at end of function - opcode = Memory::Read_Instruction(vaddress + size - 4); + opcode = PowerPC::HostRead_Instruction(vaddress + size - 4); if (opcode == 0x4e800020) good = true; } diff --git a/Source/Core/Core/PowerPC/PowerPC.h b/Source/Core/Core/PowerPC/PowerPC.h index 6dce03a55b..a536b60ca5 100644 --- a/Source/Core/Core/PowerPC/PowerPC.h +++ b/Source/Core/Core/PowerPC/PowerPC.h @@ -192,6 +192,75 @@ void UpdatePerformanceMonitor(u32 cycles, u32 num_load_stores, u32 num_fp_inst); #define riPS0(i) (*(u64*)(&PowerPC::ppcState.ps[i][0])) #define riPS1(i) (*(u64*)(&PowerPC::ppcState.ps[i][1])) +// Routines for debugger UI, cheats, etc. to access emulated memory from the +// perspective of the CPU. Not for use by core emulation routines. +// Use "Host_" prefix. +u8 HostRead_U8(const u32 address); +u16 HostRead_U16(const u32 address); +u32 HostRead_U32(const u32 address); +u32 HostRead_Instruction(const u32 address); + +void HostWrite_U8(const u8 var, const u32 address); +void HostWrite_U16(const u16 var, const u32 address); +void HostWrite_U32(const u32 var, const u32 address); +void HostWrite_U64(const u64 var, const u32 address); + +// Returns whether a read or write to the given address will resolve to a RAM +// access given the current CPU state. +bool HostIsRAMAddress(const u32 address); + +std::string HostGetString(u32 em_address, size_t size = 0); + +// Routines for the CPU core to access memory. + +// Used by interpreter to read instructions, uses iCache +u32 Read_Opcode(const u32 address); +struct TryReadInstResult +{ + bool valid; + bool from_bat; + u32 hex; +}; +TryReadInstResult TryReadInstruction(const u32 address); + +u8 Read_U8(const u32 address); +u16 Read_U16(const u32 address); +u32 Read_U32(const u32 address); +u64 Read_U64(const u32 address); + +// Useful helper functions, used by ARM JIT +float Read_F32(const u32 address); +double Read_F64(const u32 address); + +// used by JIT. Return zero-extended 32bit values +u32 Read_U8_ZX(const u32 address); +u32 Read_U16_ZX(const u32 address); + +void Write_U8(const u8 var, const u32 address); +void Write_U16(const u16 var, const u32 address); +void Write_U32(const u32 var, const u32 address); +void Write_U64(const u64 var, const u32 address); + +void Write_U16_Swap(const u16 var, const u32 address); +void Write_U32_Swap(const u32 var, const u32 address); +void Write_U64_Swap(const u64 var, const u32 address); + +// Useful helper functions, used by ARM JIT +void Write_F64(const double var, const u32 address); + +void DMA_LCToMemory(const u32 memAddr, const u32 cacheAddr, const u32 numBlocks); +void DMA_MemoryToLC(const u32 cacheAddr, const u32 memAddr, const u32 numBlocks); +void ClearCacheLine(const u32 address); // Zeroes 32 bytes; address should be 32-byte-aligned + +// TLB functions +void SDRUpdated(); +void InvalidateTLBEntry(u32 address); + +// Result changes based on the BAT registers and MSR.DR. Returns whether +// it's safe to optimize a read or write to this address to an unguarded +// memory access. Does not consider page tables. +bool IsOptimizableRAMAddress(const u32 address); + } // namespace enum CRBits diff --git a/Source/Core/Core/PowerPC/SignatureDB.cpp b/Source/Core/Core/PowerPC/SignatureDB.cpp index d20a041e58..1a960e3749 100644 --- a/Source/Core/Core/PowerPC/SignatureDB.cpp +++ b/Source/Core/Core/PowerPC/SignatureDB.cpp @@ -150,7 +150,7 @@ void SignatureDB::Initialize(PPCSymbolDB *symbol_db, const std::string& prefix) u32 sum = 0; for (u32 offset = offsetStart; offset <= offsetEnd; offset += 4) { - u32 opcode = Memory::Read_Instruction(offset); + u32 opcode = PowerPC::HostRead_Instruction(offset); u32 op = opcode & 0xFC000000; u32 op2 = 0; u32 op3 = 0; diff --git a/Source/Core/DolphinWX/Debugger/CodeWindow.cpp b/Source/Core/DolphinWX/Debugger/CodeWindow.cpp index 8d5137430e..fcf42756ca 100644 --- a/Source/Core/DolphinWX/Debugger/CodeWindow.cpp +++ b/Source/Core/DolphinWX/Debugger/CodeWindow.cpp @@ -298,7 +298,7 @@ void CCodeWindow::StepOver() { if (CCPU::IsStepping()) { - UGeckoInstruction inst = Memory::Read_Instruction(PC); + UGeckoInstruction inst = PowerPC::HostRead_Instruction(PC); if (inst.LK) { PowerPC::breakpoints.ClearAllTemporary(); @@ -329,7 +329,7 @@ void CCodeWindow::StepOut() u64 steps = 0; PowerPC::CoreMode oldMode = PowerPC::GetMode(); PowerPC::SetMode(PowerPC::MODE_INTERPRETER); - UGeckoInstruction inst = Memory::Read_Instruction(PC); + UGeckoInstruction inst = PowerPC::HostRead_Instruction(PC); while (inst.hex != 0x4e800020 && steps < timeout) // check for blr { if (inst.LK) @@ -347,7 +347,7 @@ void CCodeWindow::StepOut() PowerPC::SingleStep(); ++steps; } - inst = Memory::Read_Instruction(PC); + inst = PowerPC::HostRead_Instruction(PC); } PowerPC::SingleStep(); @@ -604,7 +604,7 @@ void CCodeWindow::OnJitMenu(wxCommandEvent& event) bool found = false; for (u32 addr = 0x80000000; addr < 0x80180000; addr += 4) { - const char *name = PPCTables::GetInstructionName(Memory::ReadUnchecked_U32(addr)); + const char *name = PPCTables::GetInstructionName(PowerPC::HostRead_U32(addr)); if (name && (wx_name == name)) { NOTICE_LOG(POWERPC, "Found %s at %08x", wx_name.c_str(), addr); diff --git a/Source/Core/DolphinWX/Debugger/MemoryView.cpp b/Source/Core/DolphinWX/Debugger/MemoryView.cpp index 8595883949..c00bdda9b5 100644 --- a/Source/Core/DolphinWX/Debugger/MemoryView.cpp +++ b/Source/Core/DolphinWX/Debugger/MemoryView.cpp @@ -24,7 +24,7 @@ #include "Common/CommonTypes.h" #include "Common/DebugInterface.h" #include "Common/StringUtil.h" -#include "Core/HW/Memmap.h" +#include "Core/PowerPC/PowerPC.h" #include "DolphinWX/Frame.h" #include "DolphinWX/Globals.h" #include "DolphinWX/WxUtils.h" @@ -324,7 +324,7 @@ void CMemoryView::OnPaint(wxPaintEvent& event) dc.SetTextForeground(*wxBLACK); } - if (!Memory::IsRAMAddress(address)) + if (!PowerPC::HostIsRAMAddress(address)) continue; if (debugger->IsAlive()) diff --git a/Source/Core/DolphinWX/Debugger/MemoryWindow.cpp b/Source/Core/DolphinWX/Debugger/MemoryWindow.cpp index 1e129d5770..ec6ff6c295 100644 --- a/Source/Core/DolphinWX/Debugger/MemoryWindow.cpp +++ b/Source/Core/DolphinWX/Debugger/MemoryWindow.cpp @@ -181,7 +181,7 @@ void CMemoryWindow::SetMemoryValue(wxCommandEvent& event) return; } - Memory::Write_U32(val, addr); + PowerPC::HostWrite_U32(val, addr); memview->Refresh(); } diff --git a/Source/Core/DolphinWX/Debugger/WatchView.cpp b/Source/Core/DolphinWX/Debugger/WatchView.cpp index 13baf3660a..0ede80bb34 100644 --- a/Source/Core/DolphinWX/Debugger/WatchView.cpp +++ b/Source/Core/DolphinWX/Debugger/WatchView.cpp @@ -43,7 +43,7 @@ static u32 GetWatchAddr(int count) static u32 GetWatchValue(int count) { - return Memory::ReadUnchecked_U32(GetWatchAddr(count)); + return PowerPC::HostRead_U32(GetWatchAddr(count)); } static void AddWatchAddr(int count, u32 value) @@ -71,7 +71,7 @@ static void SetWatchName(int count, const std::string& value) static void SetWatchValue(int count, u32 value) { - Memory::WriteUnchecked_U32(value, GetWatchAddr(count)); + PowerPC::HostWrite_U32(value, GetWatchAddr(count)); } static wxString GetValueByRowCol(int row, int col) @@ -102,8 +102,8 @@ static wxString GetValueByRowCol(int row, int col) case 4: { u32 addr = GetWatchAddr(row); - if (Memory::IsRAMAddress(addr)) - return Memory::GetString(addr, 32).c_str(); + if (PowerPC::HostIsRAMAddress(addr)) + return PowerPC::HostGetString(addr, 32).c_str(); else return wxEmptyString; }