mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-21 05:09:34 -06:00
HW/Memmap: Refactor Memory to class, move to Core::System.
This commit is contained in:
@ -104,6 +104,9 @@ constexpr u32 PLACEHOLDER = 0xDEADBEEF;
|
||||
|
||||
static bool SetupMemory(u64 ios_title_id, MemorySetupType setup_type)
|
||||
{
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
auto target_imv = std::find_if(
|
||||
GetMemoryValues().begin(), GetMemoryValues().end(),
|
||||
[&](const MemoryValues& imv) { return imv.ios_number == (ios_title_id & 0xffff); });
|
||||
@ -116,7 +119,7 @@ static bool SetupMemory(u64 ios_title_id, MemorySetupType setup_type)
|
||||
|
||||
if (setup_type == MemorySetupType::IOSReload)
|
||||
{
|
||||
Memory::Write_U32(target_imv->ios_version, ADDR_IOS_VERSION);
|
||||
memory.Write_U32(target_imv->ios_version, ADDR_IOS_VERSION);
|
||||
|
||||
// These values are written by the IOS kernel as part of its boot process (for IOS28 and newer).
|
||||
//
|
||||
@ -127,15 +130,15 @@ static bool SetupMemory(u64 ios_title_id, MemorySetupType setup_type)
|
||||
// the new IOS either updates the range (>= IOS28) or inherits it (< IOS28).
|
||||
//
|
||||
// We can skip this convoluted process and just write the correct range directly.
|
||||
Memory::Write_U32(target_imv->mem2_physical_size, ADDR_MEM2_SIZE);
|
||||
Memory::Write_U32(target_imv->mem2_simulated_size, ADDR_MEM2_SIM_SIZE);
|
||||
Memory::Write_U32(target_imv->mem2_end, ADDR_MEM2_END);
|
||||
Memory::Write_U32(target_imv->mem2_arena_begin, ADDR_MEM2_ARENA_BEGIN);
|
||||
Memory::Write_U32(target_imv->mem2_arena_end, ADDR_MEM2_ARENA_END);
|
||||
Memory::Write_U32(target_imv->ipc_buffer_begin, ADDR_IPC_BUFFER_BEGIN);
|
||||
Memory::Write_U32(target_imv->ipc_buffer_end, ADDR_IPC_BUFFER_END);
|
||||
Memory::Write_U32(target_imv->ios_reserved_begin, ADDR_IOS_RESERVED_BEGIN);
|
||||
Memory::Write_U32(target_imv->ios_reserved_end, ADDR_IOS_RESERVED_END);
|
||||
memory.Write_U32(target_imv->mem2_physical_size, ADDR_MEM2_SIZE);
|
||||
memory.Write_U32(target_imv->mem2_simulated_size, ADDR_MEM2_SIM_SIZE);
|
||||
memory.Write_U32(target_imv->mem2_end, ADDR_MEM2_END);
|
||||
memory.Write_U32(target_imv->mem2_arena_begin, ADDR_MEM2_ARENA_BEGIN);
|
||||
memory.Write_U32(target_imv->mem2_arena_end, ADDR_MEM2_ARENA_END);
|
||||
memory.Write_U32(target_imv->ipc_buffer_begin, ADDR_IPC_BUFFER_BEGIN);
|
||||
memory.Write_U32(target_imv->ipc_buffer_end, ADDR_IPC_BUFFER_END);
|
||||
memory.Write_U32(target_imv->ios_reserved_begin, ADDR_IOS_RESERVED_BEGIN);
|
||||
memory.Write_U32(target_imv->ios_reserved_end, ADDR_IOS_RESERVED_END);
|
||||
|
||||
RAMOverrideForIOSMemoryValues(setup_type);
|
||||
|
||||
@ -146,40 +149,40 @@ static bool SetupMemory(u64 ios_title_id, MemorySetupType setup_type)
|
||||
// and system information (see below).
|
||||
constexpr u32 LOW_MEM1_REGION_START = 0;
|
||||
constexpr u32 LOW_MEM1_REGION_SIZE = 0x3fff;
|
||||
Memory::Memset(LOW_MEM1_REGION_START, 0, LOW_MEM1_REGION_SIZE);
|
||||
memory.Memset(LOW_MEM1_REGION_START, 0, LOW_MEM1_REGION_SIZE);
|
||||
|
||||
Memory::Write_U32(target_imv->mem1_physical_size, ADDR_MEM1_SIZE);
|
||||
Memory::Write_U32(target_imv->mem1_simulated_size, ADDR_MEM1_SIM_SIZE);
|
||||
Memory::Write_U32(target_imv->mem1_end, ADDR_MEM1_END);
|
||||
Memory::Write_U32(target_imv->mem1_arena_begin, ADDR_MEM1_ARENA_BEGIN);
|
||||
Memory::Write_U32(target_imv->mem1_arena_end, ADDR_MEM1_ARENA_END);
|
||||
Memory::Write_U32(PLACEHOLDER, ADDR_PH1);
|
||||
Memory::Write_U32(target_imv->mem2_physical_size, ADDR_MEM2_SIZE);
|
||||
Memory::Write_U32(target_imv->mem2_simulated_size, ADDR_MEM2_SIM_SIZE);
|
||||
Memory::Write_U32(target_imv->mem2_end, ADDR_MEM2_END);
|
||||
Memory::Write_U32(target_imv->mem2_arena_begin, ADDR_MEM2_ARENA_BEGIN);
|
||||
Memory::Write_U32(target_imv->mem2_arena_end, ADDR_MEM2_ARENA_END);
|
||||
Memory::Write_U32(PLACEHOLDER, ADDR_PH2);
|
||||
Memory::Write_U32(target_imv->ipc_buffer_begin, ADDR_IPC_BUFFER_BEGIN);
|
||||
Memory::Write_U32(target_imv->ipc_buffer_end, ADDR_IPC_BUFFER_END);
|
||||
Memory::Write_U32(target_imv->hollywood_revision, ADDR_HOLLYWOOD_REVISION);
|
||||
Memory::Write_U32(PLACEHOLDER, ADDR_PH3);
|
||||
Memory::Write_U32(target_imv->ios_version, ADDR_IOS_VERSION);
|
||||
Memory::Write_U32(target_imv->ios_date, ADDR_IOS_DATE);
|
||||
Memory::Write_U32(target_imv->ios_reserved_begin, ADDR_IOS_RESERVED_BEGIN);
|
||||
Memory::Write_U32(target_imv->ios_reserved_end, ADDR_IOS_RESERVED_END);
|
||||
Memory::Write_U32(PLACEHOLDER, ADDR_PH4);
|
||||
Memory::Write_U32(PLACEHOLDER, ADDR_PH5);
|
||||
Memory::Write_U32(target_imv->ram_vendor, ADDR_RAM_VENDOR);
|
||||
Memory::Write_U8(0xDE, ADDR_BOOT_FLAG);
|
||||
Memory::Write_U8(0xAD, ADDR_APPLOADER_FLAG);
|
||||
Memory::Write_U16(0xBEEF, ADDR_DEVKIT_BOOT_PROGRAM_VERSION);
|
||||
Memory::Write_U32(target_imv->sysmenu_sync, ADDR_SYSMENU_SYNC);
|
||||
memory.Write_U32(target_imv->mem1_physical_size, ADDR_MEM1_SIZE);
|
||||
memory.Write_U32(target_imv->mem1_simulated_size, ADDR_MEM1_SIM_SIZE);
|
||||
memory.Write_U32(target_imv->mem1_end, ADDR_MEM1_END);
|
||||
memory.Write_U32(target_imv->mem1_arena_begin, ADDR_MEM1_ARENA_BEGIN);
|
||||
memory.Write_U32(target_imv->mem1_arena_end, ADDR_MEM1_ARENA_END);
|
||||
memory.Write_U32(PLACEHOLDER, ADDR_PH1);
|
||||
memory.Write_U32(target_imv->mem2_physical_size, ADDR_MEM2_SIZE);
|
||||
memory.Write_U32(target_imv->mem2_simulated_size, ADDR_MEM2_SIM_SIZE);
|
||||
memory.Write_U32(target_imv->mem2_end, ADDR_MEM2_END);
|
||||
memory.Write_U32(target_imv->mem2_arena_begin, ADDR_MEM2_ARENA_BEGIN);
|
||||
memory.Write_U32(target_imv->mem2_arena_end, ADDR_MEM2_ARENA_END);
|
||||
memory.Write_U32(PLACEHOLDER, ADDR_PH2);
|
||||
memory.Write_U32(target_imv->ipc_buffer_begin, ADDR_IPC_BUFFER_BEGIN);
|
||||
memory.Write_U32(target_imv->ipc_buffer_end, ADDR_IPC_BUFFER_END);
|
||||
memory.Write_U32(target_imv->hollywood_revision, ADDR_HOLLYWOOD_REVISION);
|
||||
memory.Write_U32(PLACEHOLDER, ADDR_PH3);
|
||||
memory.Write_U32(target_imv->ios_version, ADDR_IOS_VERSION);
|
||||
memory.Write_U32(target_imv->ios_date, ADDR_IOS_DATE);
|
||||
memory.Write_U32(target_imv->ios_reserved_begin, ADDR_IOS_RESERVED_BEGIN);
|
||||
memory.Write_U32(target_imv->ios_reserved_end, ADDR_IOS_RESERVED_END);
|
||||
memory.Write_U32(PLACEHOLDER, ADDR_PH4);
|
||||
memory.Write_U32(PLACEHOLDER, ADDR_PH5);
|
||||
memory.Write_U32(target_imv->ram_vendor, ADDR_RAM_VENDOR);
|
||||
memory.Write_U8(0xDE, ADDR_BOOT_FLAG);
|
||||
memory.Write_U8(0xAD, ADDR_APPLOADER_FLAG);
|
||||
memory.Write_U16(0xBEEF, ADDR_DEVKIT_BOOT_PROGRAM_VERSION);
|
||||
memory.Write_U32(target_imv->sysmenu_sync, ADDR_SYSMENU_SYNC);
|
||||
|
||||
Memory::Write_U32(target_imv->mem1_physical_size, ADDR_LEGACY_MEM_SIZE);
|
||||
Memory::Write_U32(target_imv->mem1_arena_begin, ADDR_LEGACY_ARENA_LOW);
|
||||
Memory::Write_U32(target_imv->mem1_arena_end, ADDR_LEGACY_ARENA_HIGH);
|
||||
Memory::Write_U32(target_imv->mem1_simulated_size, ADDR_LEGACY_MEM_SIM_SIZE);
|
||||
memory.Write_U32(target_imv->mem1_physical_size, ADDR_LEGACY_MEM_SIZE);
|
||||
memory.Write_U32(target_imv->mem1_arena_begin, ADDR_LEGACY_ARENA_LOW);
|
||||
memory.Write_U32(target_imv->mem1_arena_end, ADDR_LEGACY_ARENA_HIGH);
|
||||
memory.Write_U32(target_imv->mem1_simulated_size, ADDR_LEGACY_MEM_SIM_SIZE);
|
||||
|
||||
RAMOverrideForIOSMemoryValues(setup_type);
|
||||
|
||||
@ -193,14 +196,18 @@ static bool SetupMemory(u64 ios_title_id, MemorySetupType setup_type)
|
||||
static void ResetAndPausePPC()
|
||||
{
|
||||
// This should be cleared when the PPC is released so that the write is not observable.
|
||||
Memory::Write_U32(0x48000000, 0x00000000); // b 0x0
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& memory = system.GetMemory();
|
||||
memory.Write_U32(0x48000000, 0x00000000); // b 0x0
|
||||
PowerPC::Reset();
|
||||
PC = 0;
|
||||
}
|
||||
|
||||
static void ReleasePPC()
|
||||
{
|
||||
Memory::Write_U32(0, 0);
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& memory = system.GetMemory();
|
||||
memory.Write_U32(0, 0);
|
||||
// HLE the bootstub that jumps to 0x3400.
|
||||
// NAND titles start with address translation off at 0x3400 (via the PPC bootstub)
|
||||
// The state of other CPU registers (like the BAT registers) doesn't matter much
|
||||
@ -210,7 +217,9 @@ static void ReleasePPC()
|
||||
|
||||
static void ReleasePPCAncast()
|
||||
{
|
||||
Memory::Write_U32(0, 0);
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& memory = system.GetMemory();
|
||||
memory.Write_U32(0, 0);
|
||||
// On a real console the Espresso verifies and decrypts the Ancast image,
|
||||
// then jumps to the decrypted ancast body.
|
||||
// The Ancast loader already did this, so just jump to the decrypted body.
|
||||
@ -223,19 +232,22 @@ void RAMOverrideForIOSMemoryValues(MemorySetupType setup_type)
|
||||
if (!Config::Get(Config::MAIN_RAM_OVERRIDE_ENABLE))
|
||||
return;
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
// Some unstated constants that can be inferred.
|
||||
const u32 ipc_buffer_size =
|
||||
Memory::Read_U32(ADDR_IPC_BUFFER_END) - Memory::Read_U32(ADDR_IPC_BUFFER_BEGIN);
|
||||
memory.Read_U32(ADDR_IPC_BUFFER_END) - memory.Read_U32(ADDR_IPC_BUFFER_BEGIN);
|
||||
const u32 ios_reserved_size =
|
||||
Memory::Read_U32(ADDR_IOS_RESERVED_END) - Memory::Read_U32(ADDR_IOS_RESERVED_BEGIN);
|
||||
memory.Read_U32(ADDR_IOS_RESERVED_END) - memory.Read_U32(ADDR_IOS_RESERVED_BEGIN);
|
||||
|
||||
const u32 mem1_physical_size = Memory::GetRamSizeReal();
|
||||
const u32 mem1_simulated_size = Memory::GetRamSizeReal();
|
||||
const u32 mem1_physical_size = memory.GetRamSizeReal();
|
||||
const u32 mem1_simulated_size = memory.GetRamSizeReal();
|
||||
const u32 mem1_end = Memory::MEM1_BASE_ADDR + mem1_simulated_size;
|
||||
const u32 mem1_arena_begin = 0;
|
||||
const u32 mem1_arena_end = mem1_end;
|
||||
const u32 mem2_physical_size = Memory::GetExRamSizeReal();
|
||||
const u32 mem2_simulated_size = Memory::GetExRamSizeReal();
|
||||
const u32 mem2_physical_size = memory.GetExRamSizeReal();
|
||||
const u32 mem2_simulated_size = memory.GetExRamSizeReal();
|
||||
const u32 mem2_end = Memory::MEM2_BASE_ADDR + mem2_simulated_size - ios_reserved_size;
|
||||
const u32 mem2_arena_begin = Memory::MEM2_BASE_ADDR + 0x800U;
|
||||
const u32 mem2_arena_end = mem2_end - ipc_buffer_size;
|
||||
@ -247,31 +259,33 @@ void RAMOverrideForIOSMemoryValues(MemorySetupType setup_type)
|
||||
if (setup_type == MemorySetupType::Full)
|
||||
{
|
||||
// Overwriting these after the game's apploader sets them would be bad
|
||||
Memory::Write_U32(mem1_physical_size, ADDR_MEM1_SIZE);
|
||||
Memory::Write_U32(mem1_simulated_size, ADDR_MEM1_SIM_SIZE);
|
||||
Memory::Write_U32(mem1_end, ADDR_MEM1_END);
|
||||
Memory::Write_U32(mem1_arena_begin, ADDR_MEM1_ARENA_BEGIN);
|
||||
Memory::Write_U32(mem1_arena_end, ADDR_MEM1_ARENA_END);
|
||||
memory.Write_U32(mem1_physical_size, ADDR_MEM1_SIZE);
|
||||
memory.Write_U32(mem1_simulated_size, ADDR_MEM1_SIM_SIZE);
|
||||
memory.Write_U32(mem1_end, ADDR_MEM1_END);
|
||||
memory.Write_U32(mem1_arena_begin, ADDR_MEM1_ARENA_BEGIN);
|
||||
memory.Write_U32(mem1_arena_end, ADDR_MEM1_ARENA_END);
|
||||
|
||||
Memory::Write_U32(mem1_physical_size, ADDR_LEGACY_MEM_SIZE);
|
||||
Memory::Write_U32(mem1_arena_begin, ADDR_LEGACY_ARENA_LOW);
|
||||
Memory::Write_U32(mem1_arena_end, ADDR_LEGACY_ARENA_HIGH);
|
||||
Memory::Write_U32(mem1_simulated_size, ADDR_LEGACY_MEM_SIM_SIZE);
|
||||
memory.Write_U32(mem1_physical_size, ADDR_LEGACY_MEM_SIZE);
|
||||
memory.Write_U32(mem1_arena_begin, ADDR_LEGACY_ARENA_LOW);
|
||||
memory.Write_U32(mem1_arena_end, ADDR_LEGACY_ARENA_HIGH);
|
||||
memory.Write_U32(mem1_simulated_size, ADDR_LEGACY_MEM_SIM_SIZE);
|
||||
}
|
||||
Memory::Write_U32(mem2_physical_size, ADDR_MEM2_SIZE);
|
||||
Memory::Write_U32(mem2_simulated_size, ADDR_MEM2_SIM_SIZE);
|
||||
Memory::Write_U32(mem2_end, ADDR_MEM2_END);
|
||||
Memory::Write_U32(mem2_arena_begin, ADDR_MEM2_ARENA_BEGIN);
|
||||
Memory::Write_U32(mem2_arena_end, ADDR_MEM2_ARENA_END);
|
||||
Memory::Write_U32(ipc_buffer_begin, ADDR_IPC_BUFFER_BEGIN);
|
||||
Memory::Write_U32(ipc_buffer_end, ADDR_IPC_BUFFER_END);
|
||||
Memory::Write_U32(ios_reserved_begin, ADDR_IOS_RESERVED_BEGIN);
|
||||
Memory::Write_U32(ios_reserved_end, ADDR_IOS_RESERVED_END);
|
||||
memory.Write_U32(mem2_physical_size, ADDR_MEM2_SIZE);
|
||||
memory.Write_U32(mem2_simulated_size, ADDR_MEM2_SIM_SIZE);
|
||||
memory.Write_U32(mem2_end, ADDR_MEM2_END);
|
||||
memory.Write_U32(mem2_arena_begin, ADDR_MEM2_ARENA_BEGIN);
|
||||
memory.Write_U32(mem2_arena_end, ADDR_MEM2_ARENA_END);
|
||||
memory.Write_U32(ipc_buffer_begin, ADDR_IPC_BUFFER_BEGIN);
|
||||
memory.Write_U32(ipc_buffer_end, ADDR_IPC_BUFFER_END);
|
||||
memory.Write_U32(ios_reserved_begin, ADDR_IOS_RESERVED_BEGIN);
|
||||
memory.Write_U32(ios_reserved_end, ADDR_IOS_RESERVED_END);
|
||||
}
|
||||
|
||||
void WriteReturnValue(s32 value, u32 address)
|
||||
{
|
||||
Memory::Write_U32(static_cast<u32>(value), address);
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& memory = system.GetMemory();
|
||||
memory.Write_U32(static_cast<u32>(value), address);
|
||||
}
|
||||
|
||||
Kernel::Kernel(IOSC::ConsoleType console_type) : m_iosc(console_type)
|
||||
@ -751,13 +765,14 @@ void Kernel::EnqueueIPCRequest(u32 address)
|
||||
void Kernel::EnqueueIPCReply(const Request& request, const s32 return_value, s64 cycles_in_future,
|
||||
CoreTiming::FromThread from)
|
||||
{
|
||||
Memory::Write_U32(static_cast<u32>(return_value), request.address + 4);
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& memory = system.GetMemory();
|
||||
memory.Write_U32(static_cast<u32>(return_value), request.address + 4);
|
||||
// IOS writes back the command that was responded to in the FD field.
|
||||
Memory::Write_U32(request.command, request.address + 8);
|
||||
memory.Write_U32(request.command, request.address + 8);
|
||||
// IOS also overwrites the command type with the reply type.
|
||||
Memory::Write_U32(IPC_REPLY, request.address);
|
||||
Core::System::GetInstance().GetCoreTiming().ScheduleEvent(cycles_in_future, s_event_enqueue,
|
||||
request.address, from);
|
||||
memory.Write_U32(IPC_REPLY, request.address);
|
||||
system.GetCoreTiming().ScheduleEvent(cycles_in_future, s_event_enqueue, request.address, from);
|
||||
}
|
||||
|
||||
void Kernel::HandleIPCEvent(u64 userdata)
|
||||
|
Reference in New Issue
Block a user