diff --git a/Source/Core/Core/HW/EXI/EXI_Channel.cpp b/Source/Core/Core/HW/EXI/EXI_Channel.cpp index 11f4814fd2..ca2d8f49cd 100644 --- a/Source/Core/Core/HW/EXI/EXI_Channel.cpp +++ b/Source/Core/Core/HW/EXI/EXI_Channel.cpp @@ -15,6 +15,7 @@ #include "Core/HW/EXI/EXI_Device.h" #include "Core/HW/MMIO.h" #include "Core/Movie.h" +#include "Core/System.h" namespace ExpansionInterface { diff --git a/Source/Core/Core/HW/MMIO.h b/Source/Core/Core/HW/MMIO.h index e25c9ace77..6458d0afaf 100644 --- a/Source/Core/Core/HW/MMIO.h +++ b/Source/Core/Core/HW/MMIO.h @@ -15,7 +15,11 @@ #include "Core/ConfigManager.h" #include "Core/HW/GPFifo.h" #include "Core/HW/MMIOHandlers.h" -#include "Core/System.h" + +namespace Core +{ +class System; +} namespace MMIO { @@ -131,15 +135,15 @@ public: // called in interpreter mode, from Dolphin's own code, or from JIT'd code // where the access address could not be predicted. template - Unit Read(u32 addr) + Unit Read(Core::System& system, u32 addr) { - return GetHandlerForRead(addr).Read(Core::System::GetInstance(), addr); + return GetHandlerForRead(addr).Read(system, addr); } template - void Write(u32 addr, Unit val) + void Write(Core::System& system, u32 addr, Unit val) { - GetHandlerForWrite(addr).Write(Core::System::GetInstance(), addr, val); + GetHandlerForWrite(addr).Write(system, addr, val); } // Handlers access interface. @@ -214,14 +218,14 @@ private: // Dummy 64 bits variants of these functions. While 64 bits MMIO access is // not supported, we need these in order to make the code compile. template <> -inline u64 Mapping::Read(u32 addr) +inline u64 Mapping::Read(Core::System& system, u32 addr) { DEBUG_ASSERT(false); return 0; } template <> -inline void Mapping::Write(u32 addr, u64 val) +inline void Mapping::Write(Core::System& system, u32 addr, u64 val) { DEBUG_ASSERT(false); } diff --git a/Source/Core/Core/IOS/DI/DI.cpp b/Source/Core/Core/IOS/DI/DI.cpp index f3b9744da8..3d8f228b02 100644 --- a/Source/Core/Core/IOS/DI/DI.cpp +++ b/Source/Core/Core/IOS/DI/DI.cpp @@ -162,14 +162,14 @@ std::optional DIDevice::StartIOCtl(const IOCtlRequest& reque { case DIIoctl::DVDLowInquiry: INFO_LOG_FMT(IOS_DI, "DVDLowInquiry"); - mmio->Write(ADDRESS_DICMDBUF0, 0x12000000); - mmio->Write(ADDRESS_DICMDBUF1, 0); + mmio->Write(system, ADDRESS_DICMDBUF0, 0x12000000); + mmio->Write(system, ADDRESS_DICMDBUF1, 0); return StartDMATransfer(0x20, request); case DIIoctl::DVDLowReadDiskID: INFO_LOG_FMT(IOS_DI, "DVDLowReadDiskID"); - mmio->Write(ADDRESS_DICMDBUF0, 0xA8000040); - mmio->Write(ADDRESS_DICMDBUF1, 0); - mmio->Write(ADDRESS_DICMDBUF2, 0x20); + mmio->Write(system, ADDRESS_DICMDBUF0, 0xA8000040); + mmio->Write(system, ADDRESS_DICMDBUF1, 0); + mmio->Write(system, ADDRESS_DICMDBUF2, 0x20); return StartDMATransfer(0x20, request); // TODO: Include an additional read that happens on Wii discs, or at least // emulate its side effect of disabling DTK configuration @@ -211,7 +211,7 @@ std::optional DIDevice::StartIOCtl(const IOCtlRequest& reque return DIResult::CoverClosed; case DIIoctl::DVDLowGetCoverRegister: { - const u32 dicvr = mmio->Read(ADDRESS_DICVR); + const u32 dicvr = mmio->Read(system, ADDRESS_DICVR); DEBUG_LOG_FMT(IOS_DI, "DVDLowGetCoverRegister {:#010x}", dicvr); return WriteIfFits(request, dicvr); } @@ -226,27 +226,27 @@ std::optional DIDevice::StartIOCtl(const IOCtlRequest& reque { const u8 position = memory.Read_U8(request.buffer_in + 7); INFO_LOG_FMT(IOS_DI, "DVDLowReadDvdPhysical: position {:#04x}", position); - mmio->Write(ADDRESS_DICMDBUF0, 0xAD000000 | (position << 8)); - mmio->Write(ADDRESS_DICMDBUF1, 0); - mmio->Write(ADDRESS_DICMDBUF2, 0); + mmio->Write(system, ADDRESS_DICMDBUF0, 0xAD000000 | (position << 8)); + mmio->Write(system, ADDRESS_DICMDBUF1, 0); + mmio->Write(system, ADDRESS_DICMDBUF2, 0); return StartDMATransfer(0x800, request); } case DIIoctl::DVDLowReadDvdCopyright: { const u8 position = memory.Read_U8(request.buffer_in + 7); INFO_LOG_FMT(IOS_DI, "DVDLowReadDvdCopyright: position {:#04x}", position); - mmio->Write(ADDRESS_DICMDBUF0, 0xAD010000 | (position << 8)); - mmio->Write(ADDRESS_DICMDBUF1, 0); - mmio->Write(ADDRESS_DICMDBUF2, 0); + mmio->Write(system, ADDRESS_DICMDBUF0, 0xAD010000 | (position << 8)); + mmio->Write(system, ADDRESS_DICMDBUF1, 0); + mmio->Write(system, ADDRESS_DICMDBUF2, 0); return StartImmediateTransfer(request); } case DIIoctl::DVDLowReadDvdDiscKey: { const u8 position = memory.Read_U8(request.buffer_in + 7); INFO_LOG_FMT(IOS_DI, "DVDLowReadDvdDiscKey: position {:#04x}", position); - mmio->Write(ADDRESS_DICMDBUF0, 0xAD020000 | (position << 8)); - mmio->Write(ADDRESS_DICMDBUF1, 0); - mmio->Write(ADDRESS_DICMDBUF2, 0); + mmio->Write(system, ADDRESS_DICMDBUF0, 0xAD020000 | (position << 8)); + mmio->Write(system, ADDRESS_DICMDBUF1, 0); + mmio->Write(system, ADDRESS_DICMDBUF2, 0); return StartDMATransfer(0x800, request); } case DIIoctl::DVDLowGetLength: @@ -254,7 +254,7 @@ std::optional DIDevice::StartIOCtl(const IOCtlRequest& reque return WriteIfFits(request, m_last_length); case DIIoctl::DVDLowGetImmBuf: { - const u32 diimmbuf = mmio->Read(ADDRESS_DIIMMBUF); + const u32 diimmbuf = mmio->Read(system, ADDRESS_DIIMMBUF); INFO_LOG_FMT(IOS_DI, "DVDLowGetImmBuf {:#010x}", diimmbuf); return WriteIfFits(request, diimmbuf); } @@ -289,27 +289,30 @@ std::optional DIDevice::StartIOCtl(const IOCtlRequest& reque const bool spinup = memory.Read_U32(request.buffer_in + 4); // The GPIO *disables* spinning up the drive. Normally handled via syscall 0x4e. - const u32 old_gpio = mmio->Read(ADDRESS_HW_GPIO_OUT); + const u32 old_gpio = mmio->Read(system, ADDRESS_HW_GPIO_OUT); if (spinup) - mmio->Write(ADDRESS_HW_GPIO_OUT, old_gpio & ~static_cast(GPIO::DI_SPIN)); + mmio->Write(system, ADDRESS_HW_GPIO_OUT, old_gpio & ~static_cast(GPIO::DI_SPIN)); else - mmio->Write(ADDRESS_HW_GPIO_OUT, old_gpio | static_cast(GPIO::DI_SPIN)); + mmio->Write(system, ADDRESS_HW_GPIO_OUT, old_gpio | static_cast(GPIO::DI_SPIN)); // Syscall 0x46 check_di_reset - const bool was_resetting = (mmio->Read(ADDRESS_HW_RESETS) & (1 << 10)) == 0; + const bool was_resetting = (mmio->Read(system, ADDRESS_HW_RESETS) & (1 << 10)) == 0; if (was_resetting) { // This route will not generally be taken in Dolphin but is included for completeness // Syscall 0x45 deassert_di_reset - mmio->Write(ADDRESS_HW_RESETS, mmio->Read(ADDRESS_HW_RESETS) | (1 << 10)); + mmio->Write(system, ADDRESS_HW_RESETS, + mmio->Read(system, ADDRESS_HW_RESETS) | (1 << 10)); } else { // Syscall 0x44 assert_di_reset - mmio->Write(ADDRESS_HW_RESETS, mmio->Read(ADDRESS_HW_RESETS) & ~(1 << 10)); + mmio->Write(system, ADDRESS_HW_RESETS, + mmio->Read(system, ADDRESS_HW_RESETS) & ~(1 << 10)); // Normally IOS sleeps for 12 microseconds here, but we can't easily emulate that // Syscall 0x45 deassert_di_reset - mmio->Write(ADDRESS_HW_RESETS, mmio->Read(ADDRESS_HW_RESETS) | (1 << 10)); + mmio->Write(system, ADDRESS_HW_RESETS, + mmio->Read(system, ADDRESS_HW_RESETS) | (1 << 10)); } ResetDIRegisters(); return DIResult::Success; @@ -342,14 +345,14 @@ std::optional DIDevice::StartIOCtl(const IOCtlRequest& reque if (range.start <= position && position <= range.end && range.start <= end && end <= range.end) { - mmio->Write(ADDRESS_DICMDBUF0, 0xA8000000); - mmio->Write(ADDRESS_DICMDBUF1, position); - mmio->Write(ADDRESS_DICMDBUF2, length); + mmio->Write(system, ADDRESS_DICMDBUF0, 0xA8000000); + mmio->Write(system, ADDRESS_DICMDBUF1, position); + mmio->Write(system, ADDRESS_DICMDBUF2, length); if (range.is_error_001_range && Config::Get(Config::SESSION_SHOULD_FAKE_ERROR_001)) { - mmio->Write(ADDRESS_DIMAR, request.buffer_out); + mmio->Write(system, ADDRESS_DIMAR, request.buffer_out); m_last_length = length; - mmio->Write(ADDRESS_DILENGTH, length); + mmio->Write(system, ADDRESS_DILENGTH, length); system.GetDVDInterface().ForceOutOfBoundsRead(DVD::ReplyType::IOS); return {}; } @@ -389,13 +392,13 @@ std::optional DIDevice::StartIOCtl(const IOCtlRequest& reque return DIResult::SecurityError; case DIIoctl::DVDLowGetStatusRegister: { - const u32 disr = mmio->Read(ADDRESS_DISR); + const u32 disr = mmio->Read(system, ADDRESS_DISR); INFO_LOG_FMT(IOS_DI, "DVDLowGetStatusRegister: {:#010x}", disr); return WriteIfFits(request, disr); } case DIIoctl::DVDLowGetControlRegister: { - const u32 dicr = mmio->Read(ADDRESS_DICR); + const u32 dicr = mmio->Read(system, ADDRESS_DICR); INFO_LOG_FMT(IOS_DI, "DVDLowGetControlRegister: {:#010x}", dicr); return WriteIfFits(request, dicr); } @@ -404,9 +407,9 @@ std::optional DIDevice::StartIOCtl(const IOCtlRequest& reque const u8 param1 = memory.Read_U8(request.buffer_in + 7); const u32 param2 = memory.Read_U32(request.buffer_in + 8); INFO_LOG_FMT(IOS_DI, "DVDLowReportKey: param1 {:#04x}, param2 {:#08x}", param1, param2); - mmio->Write(ADDRESS_DICMDBUF0, 0xA4000000 | (param1 << 16)); - mmio->Write(ADDRESS_DICMDBUF1, param2 & 0xFFFFFF); - mmio->Write(ADDRESS_DICMDBUF2, 0); + mmio->Write(system, ADDRESS_DICMDBUF0, 0xA4000000 | (param1 << 16)); + mmio->Write(system, ADDRESS_DICMDBUF1, param2 & 0xFFFFFF); + mmio->Write(system, ADDRESS_DICMDBUF2, 0); return StartDMATransfer(0x20, request); } case DIIoctl::DVDLowSeek: @@ -414,8 +417,8 @@ std::optional DIDevice::StartIOCtl(const IOCtlRequest& reque const u32 position = memory.Read_U32(request.buffer_in + 4); // 32-bit offset INFO_LOG_FMT(IOS_DI, "DVDLowSeek: position {:#010x}, translated to {:#010x}", position, position); // TODO: do partition translation! - mmio->Write(ADDRESS_DICMDBUF0, 0xAB000000); - mmio->Write(ADDRESS_DICMDBUF1, position); + mmio->Write(system, ADDRESS_DICMDBUF0, 0xAB000000); + mmio->Write(system, ADDRESS_DICMDBUF1, position); return StartImmediateTransfer(request, false); } case DIIoctl::DVDLowReadDvd: @@ -426,9 +429,10 @@ std::optional DIDevice::StartIOCtl(const IOCtlRequest& reque const u32 position = memory.Read_U32(request.buffer_in + 16); INFO_LOG_FMT(IOS_DI, "DVDLowReadDvd({}, {}): position {:#08x}, length {:#08x}", flag1, flag2, position, length); - mmio->Write(ADDRESS_DICMDBUF0, 0xD0000000 | ((flag1 & 1) << 7) | ((flag2 & 1) << 6)); - mmio->Write(ADDRESS_DICMDBUF1, position & 0xFFFFFF); - mmio->Write(ADDRESS_DICMDBUF2, length & 0xFFFFFF); + mmio->Write(system, ADDRESS_DICMDBUF0, + 0xD0000000 | ((flag1 & 1) << 7) | ((flag2 & 1) << 6)); + mmio->Write(system, ADDRESS_DICMDBUF1, position & 0xFFFFFF); + mmio->Write(system, ADDRESS_DICMDBUF2, length & 0xFFFFFF); return StartDMATransfer(0x800 * length, request); } case DIIoctl::DVDLowReadDvdConfig: @@ -437,41 +441,41 @@ std::optional DIDevice::StartIOCtl(const IOCtlRequest& reque const u8 param2 = memory.Read_U8(request.buffer_in + 11); const u32 position = memory.Read_U32(request.buffer_in + 12); INFO_LOG_FMT(IOS_DI, "DVDLowReadDvdConfig({}, {}): position {:#08x}", flag1, param2, position); - mmio->Write(ADDRESS_DICMDBUF0, 0xD1000000 | ((flag1 & 1) << 16) | param2); - mmio->Write(ADDRESS_DICMDBUF1, position & 0xFFFFFF); - mmio->Write(ADDRESS_DICMDBUF2, 0); + mmio->Write(system, ADDRESS_DICMDBUF0, 0xD1000000 | ((flag1 & 1) << 16) | param2); + mmio->Write(system, ADDRESS_DICMDBUF1, position & 0xFFFFFF); + mmio->Write(system, ADDRESS_DICMDBUF2, 0); return StartImmediateTransfer(request); } case DIIoctl::DVDLowStopLaser: INFO_LOG_FMT(IOS_DI, "DVDLowStopLaser"); - mmio->Write(ADDRESS_DICMDBUF0, 0xD2000000); + mmio->Write(system, ADDRESS_DICMDBUF0, 0xD2000000); return StartImmediateTransfer(request); case DIIoctl::DVDLowOffset: { const u8 flag = memory.Read_U8(request.buffer_in + 7); const u32 offset = memory.Read_U32(request.buffer_in + 8); INFO_LOG_FMT(IOS_DI, "DVDLowOffset({}): offset {:#010x}", flag, offset); - mmio->Write(ADDRESS_DICMDBUF0, 0xD9000000 | ((flag & 1) << 16)); - mmio->Write(ADDRESS_DICMDBUF1, offset); + mmio->Write(system, ADDRESS_DICMDBUF0, 0xD9000000 | ((flag & 1) << 16)); + mmio->Write(system, ADDRESS_DICMDBUF1, offset); return StartImmediateTransfer(request); } case DIIoctl::DVDLowReadDiskBca: INFO_LOG_FMT(IOS_DI, "DVDLowReadDiskBca"); - mmio->Write(ADDRESS_DICMDBUF0, 0xDA000000); + mmio->Write(system, ADDRESS_DICMDBUF0, 0xDA000000); return StartDMATransfer(0x40, request); case DIIoctl::DVDLowRequestDiscStatus: INFO_LOG_FMT(IOS_DI, "DVDLowRequestDiscStatus"); - mmio->Write(ADDRESS_DICMDBUF0, 0xDB000000); + mmio->Write(system, ADDRESS_DICMDBUF0, 0xDB000000); return StartImmediateTransfer(request); case DIIoctl::DVDLowRequestRetryNumber: INFO_LOG_FMT(IOS_DI, "DVDLowRequestRetryNumber"); - mmio->Write(ADDRESS_DICMDBUF0, 0xDC000000); + mmio->Write(system, ADDRESS_DICMDBUF0, 0xDC000000); return StartImmediateTransfer(request); case DIIoctl::DVDLowSetMaximumRotation: { const u8 speed = memory.Read_U8(request.buffer_in + 7); INFO_LOG_FMT(IOS_DI, "DVDLowSetMaximumRotation: speed {}", speed); - mmio->Write(ADDRESS_DICMDBUF0, 0xDD000000 | ((speed & 3) << 16)); + mmio->Write(system, ADDRESS_DICMDBUF0, 0xDD000000 | ((speed & 3) << 16)); return StartImmediateTransfer(request, false); } case DIIoctl::DVDLowSerMeasControl: @@ -479,12 +483,13 @@ std::optional DIDevice::StartIOCtl(const IOCtlRequest& reque const u8 flag1 = memory.Read_U8(request.buffer_in + 7); const u8 flag2 = memory.Read_U8(request.buffer_in + 11); INFO_LOG_FMT(IOS_DI, "DVDLowSerMeasControl({}, {})", flag1, flag2); - mmio->Write(ADDRESS_DICMDBUF0, 0xDF000000 | ((flag1 & 1) << 17) | ((flag2 & 1) << 16)); + mmio->Write(system, ADDRESS_DICMDBUF0, + 0xDF000000 | ((flag1 & 1) << 17) | ((flag2 & 1) << 16)); return StartDMATransfer(0x20, request); } case DIIoctl::DVDLowRequestError: INFO_LOG_FMT(IOS_DI, "DVDLowRequestError"); - mmio->Write(ADDRESS_DICMDBUF0, 0xE0000000); + mmio->Write(system, ADDRESS_DICMDBUF0, 0xE0000000); return StartImmediateTransfer(request); case DIIoctl::DVDLowAudioStream: { @@ -493,17 +498,17 @@ std::optional DIDevice::StartIOCtl(const IOCtlRequest& reque const u32 position = memory.Read_U32(request.buffer_in + 12); INFO_LOG_FMT(IOS_DI, "DVDLowAudioStream({}): offset {:#010x} (byte {:#011x}), length {:#x}", mode, position, static_cast(position) << 2, length); - mmio->Write(ADDRESS_DICMDBUF0, 0xE1000000 | ((mode & 3) << 16)); - mmio->Write(ADDRESS_DICMDBUF1, position); - mmio->Write(ADDRESS_DICMDBUF2, length); + mmio->Write(system, ADDRESS_DICMDBUF0, 0xE1000000 | ((mode & 3) << 16)); + mmio->Write(system, ADDRESS_DICMDBUF1, position); + mmio->Write(system, ADDRESS_DICMDBUF2, length); return StartImmediateTransfer(request, false); } case DIIoctl::DVDLowRequestAudioStatus: { const u8 mode = memory.Read_U8(request.buffer_in + 7); INFO_LOG_FMT(IOS_DI, "DVDLowRequestAudioStatus({})", mode); - mmio->Write(ADDRESS_DICMDBUF0, 0xE2000000 | ((mode & 3) << 16)); - mmio->Write(ADDRESS_DICMDBUF1, 0); + mmio->Write(system, ADDRESS_DICMDBUF0, 0xE2000000 | ((mode & 3) << 16)); + mmio->Write(system, ADDRESS_DICMDBUF1, 0); // Note that this command does not copy the value written to DIIMMBUF, which makes it rather // useless (to actually use it, DVDLowGetImmBuf would need to be used afterwards) return StartImmediateTransfer(request, false); @@ -513,8 +518,9 @@ std::optional DIDevice::StartIOCtl(const IOCtlRequest& reque const u8 eject = memory.Read_U8(request.buffer_in + 7); const u8 kill = memory.Read_U8(request.buffer_in + 11); INFO_LOG_FMT(IOS_DI, "DVDLowStopMotor({}, {})", eject, kill); - mmio->Write(ADDRESS_DICMDBUF0, 0xE3000000 | ((eject & 1) << 17) | ((kill & 1) << 20)); - mmio->Write(ADDRESS_DICMDBUF1, 0); + mmio->Write(system, ADDRESS_DICMDBUF0, + 0xE3000000 | ((eject & 1) << 17) | ((kill & 1) << 20)); + mmio->Write(system, ADDRESS_DICMDBUF1, 0); return StartImmediateTransfer(request); } case DIIoctl::DVDLowAudioBufferConfig: @@ -523,8 +529,9 @@ std::optional DIDevice::StartIOCtl(const IOCtlRequest& reque const u8 buffer_size = memory.Read_U8(request.buffer_in + 11); INFO_LOG_FMT(IOS_DI, "DVDLowAudioBufferConfig: {}, buffer size {}", enable ? "enabled" : "disabled", buffer_size); - mmio->Write(ADDRESS_DICMDBUF0, 0xE4000000 | ((enable & 1) << 16) | (buffer_size & 0xf)); - mmio->Write(ADDRESS_DICMDBUF1, 0); + mmio->Write(system, ADDRESS_DICMDBUF0, + 0xE4000000 | ((enable & 1) << 16) | (buffer_size & 0xf)); + mmio->Write(system, ADDRESS_DICMDBUF1, 0); // On the other hand, this command *does* copy DIIMMBUF, but the actual code in the drive never // writes anything to it, so it just copies over a stale value (e.g. from DVDLowRequestError). return StartImmediateTransfer(request); @@ -565,9 +572,9 @@ std::optional DIDevice::StartDMATransfer(u32 command_length, auto& system = GetSystem(); auto* mmio = system.GetMemory().GetMMIOMapping(); - mmio->Write(ADDRESS_DIMAR, request.buffer_out); + mmio->Write(system, ADDRESS_DIMAR, request.buffer_out); m_last_length = command_length; - mmio->Write(ADDRESS_DILENGTH, command_length); + mmio->Write(system, ADDRESS_DILENGTH, command_length); system.GetDVDInterface().ExecuteCommand(DVD::ReplyType::IOS); // Reply will be posted when done by FinishIOCtl. @@ -658,7 +665,7 @@ void DIDevice::FinishDICommand(DIResult result) IOCtlRequest request{system, m_executing_command->m_request_address}; if (m_executing_command->m_copy_diimmbuf) - memory.Write_U32(mmio->Read(ADDRESS_DIIMMBUF), request.buffer_out); + memory.Write_U32(mmio->Read(system, ADDRESS_DIIMMBUF), request.buffer_out); GetEmulationKernel().EnqueueIPCReply(request, static_cast(result)); diff --git a/Source/Core/Core/PowerPC/MMU.cpp b/Source/Core/Core/PowerPC/MMU.cpp index 49a85a3337..805eac1cc1 100644 --- a/Source/Core/Core/PowerPC/MMU.cpp +++ b/Source/Core/Core/PowerPC/MMU.cpp @@ -189,9 +189,14 @@ T MMU::ReadFromHardware(u32 em_address) if (flag == XCheckTLBFlag::Read && (em_address & 0xF8000000) == 0x08000000) { if (em_address < 0x0c000000) + { return EFB_Read(em_address); + } else - return static_cast(m_memory.GetMMIOMapping()->Read>(em_address)); + { + return static_cast( + m_memory.GetMMIOMapping()->Read>(m_system, em_address)); + } } // Locked L1 technically doesn't have a fixed address, but games all use 0xE0000000. @@ -346,20 +351,20 @@ void MMU::WriteToHardware(u32 em_address, const u32 data, const u32 size) switch (size) { case 1: - m_memory.GetMMIOMapping()->Write(em_address, static_cast(data)); + m_memory.GetMMIOMapping()->Write(m_system, em_address, static_cast(data)); return; case 2: - m_memory.GetMMIOMapping()->Write(em_address, static_cast(data)); + m_memory.GetMMIOMapping()->Write(m_system, em_address, static_cast(data)); return; case 4: - m_memory.GetMMIOMapping()->Write(em_address, data); + m_memory.GetMMIOMapping()->Write(m_system, em_address, data); return; default: // Some kind of misaligned write. TODO: Does this match how the actual hardware handles it? for (size_t i = size * 8; i > 0; em_address++) { i -= 8; - m_memory.GetMMIOMapping()->Write(em_address, static_cast(data >> i)); + m_memory.GetMMIOMapping()->Write(m_system, em_address, static_cast(data >> i)); } return; } @@ -1035,7 +1040,7 @@ void MMU::DMA_LCToMemory(const u32 mem_address, const u32 cache_address, const u for (u32 i = 0; i < 32 * num_blocks; i += 4) { const u32 data = Common::swap32(m_memory.GetL1Cache() + ((cache_address + i) & 0x3FFFF)); - m_memory.GetMMIOMapping()->Write(mem_address + i, data); + m_memory.GetMMIOMapping()->Write(m_system, mem_address + i, data); } return; } @@ -1071,7 +1076,8 @@ void MMU::DMA_MemoryToLC(const u32 cache_address, const u32 mem_address, const u { for (u32 i = 0; i < 32 * num_blocks; i += 4) { - const u32 data = Common::swap32(m_memory.GetMMIOMapping()->Read(mem_address + i)); + const u32 data = + Common::swap32(m_memory.GetMMIOMapping()->Read(m_system, mem_address + i)); std::memcpy(m_memory.GetL1Cache() + ((cache_address + i) & 0x3FFFF), &data, sizeof(u32)); } return; diff --git a/Source/UnitTests/Core/MMIOTest.cpp b/Source/UnitTests/Core/MMIOTest.cpp index a92cdcbc4e..428621cc99 100644 --- a/Source/UnitTests/Core/MMIOTest.cpp +++ b/Source/UnitTests/Core/MMIOTest.cpp @@ -2,6 +2,8 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include + +#include #include #include @@ -10,6 +12,7 @@ #include "Common/FileUtil.h" #include "Core/HW/GPFifo.h" #include "Core/HW/MMIO.h" +#include "Core/System.h" #include "UICommon/UICommon.h" // Tests that the UniqueID function returns a "unique enough" identifier @@ -66,9 +69,18 @@ TEST(IsMMIOAddress, SpecialAddresses) class MappingTest : public testing::Test { protected: - virtual void SetUp() override { m_mapping = new MMIO::Mapping(); } - virtual void TearDown() override { delete m_mapping; } - MMIO::Mapping* m_mapping = nullptr; + virtual void SetUp() override + { + m_system = &Core::System::GetInstance(); + m_mapping = std::make_unique(); + } + virtual void TearDown() override + { + m_system = nullptr; + m_mapping.reset(); + } + Core::System* m_system = nullptr; + std::unique_ptr m_mapping; }; TEST_F(MappingTest, ReadConstant) @@ -77,9 +89,9 @@ TEST_F(MappingTest, ReadConstant) m_mapping->Register(0x0C001234, MMIO::Constant(0x1234), MMIO::Nop()); m_mapping->Register(0x0C001234, MMIO::Constant(0xdeadbeef), MMIO::Nop()); - u8 val8 = m_mapping->Read(0x0C001234); - u16 val16 = m_mapping->Read(0x0C001234); - u32 val32 = m_mapping->Read(0x0C001234); + u8 val8 = m_mapping->Read(*m_system, 0x0C001234); + u16 val16 = m_mapping->Read(*m_system, 0x0C001234); + u32 val32 = m_mapping->Read(*m_system, 0x0C001234); EXPECT_EQ(0x42, val8); EXPECT_EQ(0x1234, val16); @@ -101,19 +113,19 @@ TEST_F(MappingTest, ReadWriteDirect) for (u32 i = 0; i < 100; ++i) { - u8 val8 = m_mapping->Read(0x0C001234); + u8 val8 = m_mapping->Read(*m_system, 0x0C001234); EXPECT_EQ(i, val8); - u16 val16 = m_mapping->Read(0x0C001234); + u16 val16 = m_mapping->Read(*m_system, 0x0C001234); EXPECT_EQ(i, val16); - u32 val32 = m_mapping->Read(0x0C001234); + u32 val32 = m_mapping->Read(*m_system, 0x0C001234); EXPECT_EQ(i, val32); val8 += 1; - m_mapping->Write(0x0C001234, val8); + m_mapping->Write(*m_system, 0x0C001234, val8); val16 += 1; - m_mapping->Write(0x0C001234, val16); + m_mapping->Write(*m_system, 0x0C001234, val16); val32 += 1; - m_mapping->Write(0x0C001234, val32); + m_mapping->Write(*m_system, 0x0C001234, val32); } } @@ -132,9 +144,9 @@ TEST_F(MappingTest, ReadWriteComplex) write_called = true; })); - u8 val = m_mapping->Read(0x0C001234); + u8 val = m_mapping->Read(*m_system, 0x0C001234); EXPECT_EQ(0x12, val); - m_mapping->Write(0x0C001234, (u8)0x34); + m_mapping->Write(*m_system, 0x0C001234, (u8)0x34); EXPECT_TRUE(read_called); EXPECT_TRUE(write_called);