HW/Memmap: Refactor Memory to class, move to Core::System.

This commit is contained in:
Admiral H. Curtiss
2022-12-02 20:07:30 +01:00
parent 7cd9a78ebf
commit 839db591d9
83 changed files with 2222 additions and 1361 deletions

View File

@ -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)