HW/MemoryInterface: Refactor to class.

This commit is contained in:
Admiral H. Curtiss
2023-03-10 21:27:35 +01:00
parent bf95d4012f
commit 84542d915d
6 changed files with 135 additions and 144 deletions

View File

@ -48,7 +48,7 @@ void Init(const Sram* override_sram)
system.GetHSP().Init(); system.GetHSP().Init();
system.GetMemory().Init(); // Needs to be initialized before AddressSpace system.GetMemory().Init(); // Needs to be initialized before AddressSpace
AddressSpace::Init(); AddressSpace::Init();
MemoryInterface::Init(); system.GetMemoryInterface().Init();
system.GetDSP().Init(Config::Get(Config::MAIN_DSP_HLE)); system.GetDSP().Init(Config::Get(Config::MAIN_DSP_HLE));
system.GetDVDInterface().Init(); system.GetDVDInterface().Init();
system.GetGPFifo().Init(); system.GetGPFifo().Init();
@ -74,7 +74,7 @@ void Shutdown()
system.GetCPU().Shutdown(); system.GetCPU().Shutdown();
system.GetDVDInterface().Shutdown(); system.GetDVDInterface().Shutdown();
system.GetDSP().Shutdown(); system.GetDSP().Shutdown();
MemoryInterface::Shutdown(); system.GetMemoryInterface().Shutdown();
AddressSpace::Shutdown(); AddressSpace::Shutdown();
system.GetMemory().Shutdown(); system.GetMemory().Shutdown();
system.GetHSP().Shutdown(); system.GetHSP().Shutdown();
@ -91,7 +91,7 @@ void DoState(PointerWrap& p)
auto& system = Core::System::GetInstance(); auto& system = Core::System::GetInstance();
system.GetMemory().DoState(p); system.GetMemory().DoState(p);
p.DoMarker("Memory"); p.DoMarker("Memory");
MemoryInterface::DoState(p); system.GetMemoryInterface().DoState(p);
p.DoMarker("MemoryInterface"); p.DoMarker("MemoryInterface");
VideoInterface::DoState(p); VideoInterface::DoState(p);
p.DoMarker("VideoInterface"); p.DoMarker("VideoInterface");

View File

@ -53,7 +53,7 @@ void MemoryManager::InitMMIO(bool is_wii)
system.GetPixelEngine().RegisterMMIO(m_mmio_mapping.get(), 0x0C001000); system.GetPixelEngine().RegisterMMIO(m_mmio_mapping.get(), 0x0C001000);
VideoInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C002000); VideoInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C002000);
system.GetProcessorInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C003000); system.GetProcessorInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C003000);
MemoryInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C004000); system.GetMemoryInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C004000);
system.GetDSP().RegisterMMIO(m_mmio_mapping.get(), 0x0C005000); system.GetDSP().RegisterMMIO(m_mmio_mapping.get(), 0x0C005000);
system.GetDVDInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C006000, false); system.GetDVDInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C006000, false);
SerialInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C006400); SerialInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C006400);

View File

@ -11,7 +11,6 @@
#include "Common/ChunkFile.h" #include "Common/ChunkFile.h"
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Core/HW/MMIO.h" #include "Core/HW/MMIO.h"
#include "Core/System.h"
namespace MemoryInterface namespace MemoryInterface
{ {
@ -55,166 +54,75 @@ enum
MI_UNKNOWN2 = 0x05A, MI_UNKNOWN2 = 0x05A,
}; };
union MIRegion MemoryInterfaceManager::MemoryInterfaceManager() = default;
MemoryInterfaceManager::~MemoryInterfaceManager() = default;
void MemoryInterfaceManager::Init()
{ {
u32 hex = 0;
struct
{
u16 first_page;
u16 last_page;
};
};
union MIProtType
{
u16 hex = 0;
BitField<0, 2, u16> reg0;
BitField<2, 2, u16> reg1;
BitField<4, 2, u16> reg2;
BitField<6, 2, u16> reg3;
BitField<8, 8, u16> reserved;
};
union MIIRQMask
{
u16 hex = 0;
BitField<0, 1, u16> reg0;
BitField<1, 1, u16> reg1;
BitField<2, 1, u16> reg2;
BitField<3, 1, u16> reg3;
BitField<4, 1, u16> all_regs;
BitField<5, 11, u16> reserved;
};
union MIIRQFlag
{
u16 hex = 0;
BitField<0, 1, u16> reg0;
BitField<1, 1, u16> reg1;
BitField<2, 1, u16> reg2;
BitField<3, 1, u16> reg3;
BitField<4, 1, u16> all_regs;
BitField<5, 11, u16> reserved;
};
union MIProtAddr
{
u32 hex = 0;
struct
{
u16 lo;
u16 hi;
};
BitField<0, 5, u32> reserved_1;
BitField<5, 25, u32> addr;
BitField<30, 2, u32> reserved_2;
};
union MITimer
{
u32 hex = 0;
struct
{
u16 lo;
u16 hi;
};
};
struct MIMemStruct
{
std::array<MIRegion, 4> regions;
MIProtType prot_type;
MIIRQMask irq_mask;
MIIRQFlag irq_flag;
u16 unknown1 = 0;
MIProtAddr prot_addr;
std::array<MITimer, 10> timers;
u16 unknown2 = 0;
};
struct MemoryInterfaceState::Data
{
MIMemStruct mi_mem;
};
MemoryInterfaceState::MemoryInterfaceState() : m_data(std::make_unique<Data>())
{
}
MemoryInterfaceState::~MemoryInterfaceState() = default;
void Init()
{
auto& state = Core::System::GetInstance().GetMemoryInterfaceState().GetData();
static_assert(std::is_trivially_copyable_v<MIMemStruct>); static_assert(std::is_trivially_copyable_v<MIMemStruct>);
#ifdef __GNUC__ #ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wclass-memaccess" #pragma GCC diagnostic ignored "-Wclass-memaccess"
#endif #endif
std::memset(&state.mi_mem, 0, sizeof(MIMemStruct)); std::memset(&m_mi_mem, 0, sizeof(MIMemStruct));
#ifdef __GNUC__ #ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
} }
void Shutdown() void MemoryInterfaceManager::Shutdown()
{ {
Init(); Init();
} }
void DoState(PointerWrap& p) void MemoryInterfaceManager::DoState(PointerWrap& p)
{ {
auto& state = Core::System::GetInstance().GetMemoryInterfaceState().GetData(); p.Do(m_mi_mem);
p.Do(state.mi_mem);
} }
void RegisterMMIO(MMIO::Mapping* mmio, u32 base) void MemoryInterfaceManager::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
{ {
auto& state = Core::System::GetInstance().GetMemoryInterfaceState().GetData();
for (u32 i = MI_REGION0_FIRST; i <= MI_REGION3_LAST; i += 4) for (u32 i = MI_REGION0_FIRST; i <= MI_REGION3_LAST; i += 4)
{ {
auto& region = state.mi_mem.regions[i / 4]; auto& region = m_mi_mem.regions[i / 4];
mmio->Register(base | i, MMIO::DirectRead<u16>(&region.first_page), mmio->Register(base | i, MMIO::DirectRead<u16>(&region.first_page),
MMIO::DirectWrite<u16>(&region.first_page)); MMIO::DirectWrite<u16>(&region.first_page));
mmio->Register(base | (i + 2), MMIO::DirectRead<u16>(&region.last_page), mmio->Register(base | (i + 2), MMIO::DirectRead<u16>(&region.last_page),
MMIO::DirectWrite<u16>(&region.last_page)); MMIO::DirectWrite<u16>(&region.last_page));
} }
mmio->Register(base | MI_PROT_TYPE, MMIO::DirectRead<u16>(&state.mi_mem.prot_type.hex), mmio->Register(base | MI_PROT_TYPE, MMIO::DirectRead<u16>(&m_mi_mem.prot_type.hex),
MMIO::DirectWrite<u16>(&state.mi_mem.prot_type.hex)); MMIO::DirectWrite<u16>(&m_mi_mem.prot_type.hex));
mmio->Register(base | MI_IRQMASK, MMIO::DirectRead<u16>(&state.mi_mem.irq_mask.hex), mmio->Register(base | MI_IRQMASK, MMIO::DirectRead<u16>(&m_mi_mem.irq_mask.hex),
MMIO::DirectWrite<u16>(&state.mi_mem.irq_mask.hex)); MMIO::DirectWrite<u16>(&m_mi_mem.irq_mask.hex));
mmio->Register(base | MI_IRQFLAG, MMIO::DirectRead<u16>(&state.mi_mem.irq_flag.hex), mmio->Register(base | MI_IRQFLAG, MMIO::DirectRead<u16>(&m_mi_mem.irq_flag.hex),
MMIO::DirectWrite<u16>(&state.mi_mem.irq_flag.hex)); MMIO::DirectWrite<u16>(&m_mi_mem.irq_flag.hex));
mmio->Register(base | MI_UNKNOWN1, MMIO::DirectRead<u16>(&state.mi_mem.unknown1), mmio->Register(base | MI_UNKNOWN1, MMIO::DirectRead<u16>(&m_mi_mem.unknown1),
MMIO::DirectWrite<u16>(&state.mi_mem.unknown1)); MMIO::DirectWrite<u16>(&m_mi_mem.unknown1));
// The naming is confusing here: the register contains the lower part of // The naming is confusing here: the register contains the lower part of
// the address (hence MI_..._LO but this is still the high part of the // the address (hence MI_..._LO but this is still the high part of the
// overall register. // overall register.
mmio->Register(base | MI_PROT_ADDR_LO, MMIO::DirectRead<u16>(&state.mi_mem.prot_addr.hi), mmio->Register(base | MI_PROT_ADDR_LO, MMIO::DirectRead<u16>(&m_mi_mem.prot_addr.hi),
MMIO::DirectWrite<u16>(&state.mi_mem.prot_addr.hi)); MMIO::DirectWrite<u16>(&m_mi_mem.prot_addr.hi));
mmio->Register(base | MI_PROT_ADDR_HI, MMIO::DirectRead<u16>(&state.mi_mem.prot_addr.lo), mmio->Register(base | MI_PROT_ADDR_HI, MMIO::DirectRead<u16>(&m_mi_mem.prot_addr.lo),
MMIO::DirectWrite<u16>(&state.mi_mem.prot_addr.lo)); MMIO::DirectWrite<u16>(&m_mi_mem.prot_addr.lo));
for (u32 i = 0; i < state.mi_mem.timers.size(); ++i) for (u32 i = 0; i < m_mi_mem.timers.size(); ++i)
{ {
auto& timer = state.mi_mem.timers[i]; auto& timer = m_mi_mem.timers[i];
mmio->Register(base | (MI_TIMER0_HI + 4 * i), MMIO::DirectRead<u16>(&timer.hi), mmio->Register(base | (MI_TIMER0_HI + 4 * i), MMIO::DirectRead<u16>(&timer.hi),
MMIO::DirectWrite<u16>(&timer.hi)); MMIO::DirectWrite<u16>(&timer.hi));
mmio->Register(base | (MI_TIMER0_LO + 4 * i), MMIO::DirectRead<u16>(&timer.lo), mmio->Register(base | (MI_TIMER0_LO + 4 * i), MMIO::DirectRead<u16>(&timer.lo),
MMIO::DirectWrite<u16>(&timer.lo)); MMIO::DirectWrite<u16>(&timer.lo));
} }
mmio->Register(base | MI_UNKNOWN2, MMIO::DirectRead<u16>(&state.mi_mem.unknown2), mmio->Register(base | MI_UNKNOWN2, MMIO::DirectRead<u16>(&m_mi_mem.unknown2),
MMIO::DirectWrite<u16>(&state.mi_mem.unknown2)); MMIO::DirectWrite<u16>(&m_mi_mem.unknown2));
for (u32 i = 0; i < 0x1000; i += 4) for (u32 i = 0; i < 0x1000; i += 4)
{ {

View File

@ -3,10 +3,16 @@
#pragma once #pragma once
#include <array>
#include <memory> #include <memory>
#include "Common/BitField.h"
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
namespace Core
{
class System;
}
namespace MMIO namespace MMIO
{ {
class Mapping; class Mapping;
@ -15,26 +21,103 @@ class PointerWrap;
namespace MemoryInterface namespace MemoryInterface
{ {
class MemoryInterfaceState class MemoryInterfaceManager
{ {
public: public:
MemoryInterfaceState(); MemoryInterfaceManager();
MemoryInterfaceState(const MemoryInterfaceState&) = delete; MemoryInterfaceManager(const MemoryInterfaceManager&) = delete;
MemoryInterfaceState(MemoryInterfaceState&&) = delete; MemoryInterfaceManager(MemoryInterfaceManager&&) = delete;
MemoryInterfaceState& operator=(const MemoryInterfaceState&) = delete; MemoryInterfaceManager& operator=(const MemoryInterfaceManager&) = delete;
MemoryInterfaceState& operator=(MemoryInterfaceState&&) = delete; MemoryInterfaceManager& operator=(MemoryInterfaceManager&&) = delete;
~MemoryInterfaceState(); ~MemoryInterfaceManager();
struct Data; void Init();
Data& GetData() { return *m_data; } void Shutdown();
void DoState(PointerWrap& p);
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
private: private:
std::unique_ptr<Data> m_data; union MIRegion
{
u32 hex = 0;
struct
{
u16 first_page;
u16 last_page;
};
};
union MIProtType
{
u16 hex = 0;
BitField<0, 2, u16> reg0;
BitField<2, 2, u16> reg1;
BitField<4, 2, u16> reg2;
BitField<6, 2, u16> reg3;
BitField<8, 8, u16> reserved;
};
union MIIRQMask
{
u16 hex = 0;
BitField<0, 1, u16> reg0;
BitField<1, 1, u16> reg1;
BitField<2, 1, u16> reg2;
BitField<3, 1, u16> reg3;
BitField<4, 1, u16> all_regs;
BitField<5, 11, u16> reserved;
};
union MIIRQFlag
{
u16 hex = 0;
BitField<0, 1, u16> reg0;
BitField<1, 1, u16> reg1;
BitField<2, 1, u16> reg2;
BitField<3, 1, u16> reg3;
BitField<4, 1, u16> all_regs;
BitField<5, 11, u16> reserved;
};
union MIProtAddr
{
u32 hex = 0;
struct
{
u16 lo;
u16 hi;
};
BitField<0, 5, u32> reserved_1;
BitField<5, 25, u32> addr;
BitField<30, 2, u32> reserved_2;
};
union MITimer
{
u32 hex = 0;
struct
{
u16 lo;
u16 hi;
};
};
struct MIMemStruct
{
std::array<MIRegion, 4> regions;
MIProtType prot_type;
MIIRQMask irq_mask;
MIIRQFlag irq_flag;
u16 unknown1 = 0;
MIProtAddr prot_addr;
std::array<MITimer, 10> timers;
u16 unknown2 = 0;
};
MIMemStruct m_mi_mem;
}; };
void Init();
void Shutdown();
void DoState(PointerWrap& p);
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
} // namespace MemoryInterface } // namespace MemoryInterface

View File

@ -60,7 +60,7 @@ struct System::Impl
HSP::HSPManager m_hsp; HSP::HSPManager m_hsp;
IOS::HLE::USB::SkylanderPortal m_skylander_portal; IOS::HLE::USB::SkylanderPortal m_skylander_portal;
Memory::MemoryManager m_memory; Memory::MemoryManager m_memory;
MemoryInterface::MemoryInterfaceState m_memory_interface_state; MemoryInterface::MemoryInterfaceManager m_memory_interface;
PixelEngine::PixelEngineManager m_pixel_engine; PixelEngine::PixelEngineManager m_pixel_engine;
PixelShaderManager m_pixel_shader_manager; PixelShaderManager m_pixel_shader_manager;
PowerPC::PowerPCState& m_ppc_state; PowerPC::PowerPCState& m_ppc_state;
@ -184,9 +184,9 @@ Memory::MemoryManager& System::GetMemory() const
return m_impl->m_memory; return m_impl->m_memory;
} }
MemoryInterface::MemoryInterfaceState& System::GetMemoryInterfaceState() const MemoryInterface::MemoryInterfaceManager& System::GetMemoryInterface() const
{ {
return m_impl->m_memory_interface_state; return m_impl->m_memory_interface;
} }
PixelEngine::PixelEngineManager& System::GetPixelEngine() const PixelEngine::PixelEngineManager& System::GetPixelEngine() const

View File

@ -62,7 +62,7 @@ class MemoryManager;
}; };
namespace MemoryInterface namespace MemoryInterface
{ {
class MemoryInterfaceState; class MemoryInterfaceManager;
}; };
namespace PixelEngine namespace PixelEngine
{ {
@ -133,7 +133,7 @@ public:
HSP::HSPManager& GetHSP() const; HSP::HSPManager& GetHSP() const;
IOS::HLE::USB::SkylanderPortal& GetSkylanderPortal() const; IOS::HLE::USB::SkylanderPortal& GetSkylanderPortal() const;
Memory::MemoryManager& GetMemory() const; Memory::MemoryManager& GetMemory() const;
MemoryInterface::MemoryInterfaceState& GetMemoryInterfaceState() const; MemoryInterface::MemoryInterfaceManager& GetMemoryInterface() const;
PixelEngine::PixelEngineManager& GetPixelEngine() const; PixelEngine::PixelEngineManager& GetPixelEngine() const;
PixelShaderManager& GetPixelShaderManager() const; PixelShaderManager& GetPixelShaderManager() const;
PowerPC::PowerPCState& GetPPCState() const; PowerPC::PowerPCState& GetPPCState() const;