Merge pull request #1856 from magumagu/correct-translation-disable-2

Make address translation respect the CPU translation mode
This commit is contained in:
magumagu
2015-02-11 17:04:12 -08:00
61 changed files with 1021 additions and 788 deletions
+3 -3
View File
@@ -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))
+3 -3
View File
@@ -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;
+26 -26
View File
@@ -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:
+27 -8
View File
@@ -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
+45 -39
View File
@@ -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();
+1
View File
@@ -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)
+1 -1
View File
@@ -107,7 +107,7 @@ bool CBoot::Boot_WiiWAD(const std::string& _pFilename)
pDolLoader = std::make_unique<CDolLoader>(pContent->m_Filename);
}
pDolLoader->Load();
PC = pDolLoader->GetEntryPoint() | 0x80000000;
PC = pDolLoader->GetEntryPoint();
// Pass the "#002 check"
// Apploader should write the IOS version and revision to 0x3140, and compare it
+1 -1
View File
@@ -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
+1 -1
View File
@@ -140,7 +140,6 @@
<ClCompile Include="HW\GPFifo.cpp" />
<ClCompile Include="HW\HW.cpp" />
<ClCompile Include="HW\Memmap.cpp" />
<ClCompile Include="HW\MemmapFunctions.cpp" />
<ClCompile Include="HW\MemoryInterface.cpp" />
<ClCompile Include="HW\MMIO.cpp" />
<ClCompile Include="HW\ProcessorInterface.cpp" />
@@ -245,6 +244,7 @@
<ClCompile Include="PowerPC\JitCommon\Jit_Util.cpp" />
<ClCompile Include="PowerPC\JitCommon\TrampolineCache.cpp" />
<ClCompile Include="PowerPC\JitInterface.cpp" />
<ClCompile Include="PowerPC\MMU.cpp" />
<ClCompile Include="PowerPC\PowerPC.cpp" />
<ClCompile Include="PowerPC\PPCAnalyst.cpp" />
<ClCompile Include="PowerPC\PPCCache.cpp" />
+2 -3
View File
@@ -512,9 +512,6 @@
<ClCompile Include="HW\Memmap.cpp">
<Filter>HW %28Flipper/Hollywood%29</Filter>
</ClCompile>
<ClCompile Include="HW\MemmapFunctions.cpp">
<Filter>HW %28Flipper/Hollywood%29</Filter>
</ClCompile>
<ClCompile Include="HW\MMIO.cpp">
<Filter>HW %28Flipper/Hollywood%29</Filter>
</ClCompile>
@@ -726,6 +723,8 @@
</ClCompile>
<ClCompile Include="HW\GCKeyboard.cpp">
<Filter>HW %28Flipper/Hollywood%29\GCKeyboard</Filter>
<ClCompile Include="PowerPC\MMU.cpp">
<Filter>PowerPC</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
@@ -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<void(u32)>& 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<void(u32)>& stack_step)
// instead of "pointing ahead"
bool GetCallstack(std::vector<CallstackEntry> &output)
{
if (!Core::IsRunning() || !Memory::IsRAMAddress(PowerPC::ppcState.gpr[1]))
if (!Core::IsRunning() || !PowerPC::HostIsRAMAddress(PowerPC::ppcState.gpr[1]))
return false;
if (LR == 0)
+14 -16
View File
@@ -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<Memory::FLAG_NO_EXCEPTION>(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] =
{
+13 -2
View File
@@ -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()
+13 -12
View File
@@ -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<std::mutex> 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)
+2 -2
View File
@@ -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();
}
+5 -5
View File
@@ -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);
}
@@ -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()
+3 -1
View File
@@ -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();
+1 -1
View File
@@ -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)
+116 -107
View File
@@ -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;
@@ -102,17 +103,60 @@ bool IsInitialized()
}
// We don't declare the IO region in here since its handled by other means.
// Dolphin allocates memory to represent four regions:
// - 24MB RAM, available on Gamecube and Wii
// - 64MB "EXRAM", RAM only available on Wii
// - 64MB FakeVMem, allocated when MMU support is turned off. This is used
// to approximate the behavior of a common library which pages memory to
// and from the DSP's dedicated RAM, which isn't directly addressable on
// GameCube.
// - 256KB Locked L1, to represent cache lines allocated out of the L1 data cache
// cache in Locked L1 mode. Dolphin does not emulate this hardware feature
// accurately; it just pretends there is extra memory at 0xE0000000.
//
// The 4GB starting at physical_base represents access from the CPU
// with address translation turned off. (This is only used by the CPU;
// other devices, like the GPU, use other rules, approximated by
// Memory::GetPointer.) This memory is laid out as follows:
// [0x00000000, 0x01800000) - 24MB RAM
// [0x08000000, 0x0C000000) - EFB "mapping" (not handled here)
// [0x0C000000, 0x0E000000) - MMIO etc. (not handled here)
// [0x10000000, 0x14000000) - 64MB RAM (Wii-only; slightly slower)
//
// The 4GB starting at logical_base represents access from the CPU
// with address translation turned on. Instead of changing the mapping
// based on the BAT registers, we approximate the common BAT configuration
// used by games:
// [0x00000000, 0x01800000) - 24MB RAM, cached access, normally only mapped
// during startup by Wii WADs
// [0x40000000, 0x50000000) - FakeVMEM
// [0x70000000, 0x80000000) - FakeVMEM
// [0x80000000, 0x81800000) - 24MB RAM, cached access
// [0x90000000, 0x94000000) - 64MB RAM, Wii-only, cached access
// [0xC0000000, 0xC1800000) - 24MB RAM, uncached access
// [0xC8000000, 0xCC000000) - EFB "mapping" (not handled here)
// [0xCC000000, 0xCE000000) - MMIO etc. (not handled here)
// [0xD0000000, 0xD4000000) - 64MB RAM, Wii-only, uncached access
// [0xE0000000, 0xE0040000) - 256KB locked L1
//
// TODO: We shouldn't hardcode this mapping; we can generate it dynamically
// based on the BAT registers.
//
// Each of these 4GB regions is followed by 4GB of empty space so overflows
// in address computation in the JIT don't access the wrong memory.
//
// Dolphin doesn't emulate the difference between cached and uncached access.
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 +173,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 +211,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 +236,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 +270,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 +289,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

Some files were not shown because too many files have changed in this diff Show More