From f8f14c83a393b6fac61d2420b56f9ce65ea8f034 Mon Sep 17 00:00:00 2001 From: Pierre Bourdon Date: Tue, 4 Feb 2014 01:09:57 +0100 Subject: [PATCH] MMIO: Port the SW CP/PE MMIOs to the new interface. Migration is now complete. --- .../Software/SWCommandProcessor.cpp | 173 ++++++------------ .../Software/SWCommandProcessor.h | 3 + .../VideoBackends/Software/SWPixelEngine.cpp | 65 ++++--- .../VideoBackends/Software/SWPixelEngine.h | 3 + Source/Core/VideoBackends/Software/SWmain.cpp | 4 +- 5 files changed, 95 insertions(+), 153 deletions(-) diff --git a/Source/Core/VideoBackends/Software/SWCommandProcessor.cpp b/Source/Core/VideoBackends/Software/SWCommandProcessor.cpp index 06876a2035..e2f402a040 100644 --- a/Source/Core/VideoBackends/Software/SWCommandProcessor.cpp +++ b/Source/Core/VideoBackends/Software/SWCommandProcessor.cpp @@ -9,6 +9,7 @@ #include "Core.h" #include "CoreTiming.h" #include "HW/Memmap.h" +#include "HW/MMIO.h" #include "HW/ProcessorInterface.h" #include "VideoBackend.h" @@ -124,147 +125,77 @@ void RunGpu() } } -void Read16(u16& _rReturnValue, const u32 _Address) +void RegisterMMIO(MMIO::Mapping* mmio, u32 base) { - u32 regAddr = (_Address & 0xFFF) >> 1; - - DEBUG_LOG(COMMANDPROCESSOR, "(r): 0x%08x : 0x%08x", _Address, ((u16*)&cpreg)[regAddr]); - - if (regAddr < 0x20) - _rReturnValue = ((u16*)&cpreg)[regAddr]; - else - _rReturnValue = 0; -} - -void Write16(const u16 _Value, const u32 _Address) -{ - INFO_LOG(COMMANDPROCESSOR, "(write16): 0x%04x @ 0x%08x",_Value,_Address); - - switch (_Address & 0xFFF) + // Directly map reads and writes to the cpreg structure. + for (size_t i = 0; i < sizeof (cpreg) / sizeof (u16); ++i) { - case STATUS_REGISTER: - { - ERROR_LOG(COMMANDPROCESSOR,"\t write to STATUS_REGISTER : %04x", _Value); - } - break; + u16* ptr = ((u16*)&cpreg) + i; + mmio->Register(base | (i * 2), + MMIO::DirectRead(ptr), + MMIO::DirectWrite(ptr) + ); + } - case CTRL_REGISTER: - { - cpreg.ctrl.Hex = _Value; + // Bleh. Apparently SWCommandProcessor does not know about regs 0x40 to + // 0x64... + for (size_t i = 0x40; i < 0x64; ++i) + { + mmio->Register(base | i, + MMIO::Constant(0), + MMIO::Nop() + ); + } - DEBUG_LOG(COMMANDPROCESSOR,"\t write to CTRL_REGISTER : %04x", _Value); - DEBUG_LOG(COMMANDPROCESSOR, "\t GPREAD %s | CPULINK %s | BP %s || BPIntEnable %s | OvF %s | UndF %s" - , cpreg.ctrl.GPReadEnable ? "ON" : "OFF" - , cpreg.ctrl.GPLinkEnable ? "ON" : "OFF" - , cpreg.ctrl.BPEnable ? "ON" : "OFF" - , cpreg.ctrl.BreakPointIntEnable ? "ON" : "OFF" - , cpreg.ctrl.FifoOverflowIntEnable ? "ON" : "OFF" - , cpreg.ctrl.FifoUnderflowIntEnable ? "ON" : "OFF" - ); - } - break; + // The low part of MMIO regs for FIFO addresses needs to be aligned to 32 + // bytes. + u32 fifo_addr_lo_regs[] = { + FIFO_BASE_LO, FIFO_END_LO, FIFO_WRITE_POINTER_LO, + FIFO_READ_POINTER_LO, FIFO_BP_LO, FIFO_RW_DISTANCE_LO, + }; + for (u32 reg : fifo_addr_lo_regs) + { + mmio->RegisterWrite(base | reg, + MMIO::DirectWrite(((u16*)&cpreg) + (reg / 2), 0xFFE0) + ); + } - case CLEAR_REGISTER: - { - UCPClearReg tmpClear(_Value); + // The clear register needs to perform some more complicated operations on + // writes. + mmio->RegisterWrite(base | CLEAR_REGISTER, + MMIO::ComplexWrite([](u32, u16 val) { + UCPClearReg tmpClear(val); if (tmpClear.ClearFifoOverflow) cpreg.status.OverflowHiWatermark = 0; if (tmpClear.ClearFifoUnderflow) cpreg.status.UnderflowLoWatermark = 0; + }) + ); +} - INFO_LOG(COMMANDPROCESSOR,"\t write to CLEAR_REGISTER : %04x",_Value); - } - break; +void Read16(u16& _rReturnValue, const u32 _Address) +{ + // HACK: Remove this function when the new MMIO interface is used. + Memory::mmio_mapping->Read(_Address, _rReturnValue); +} - // Fifo Registers - case FIFO_TOKEN_REGISTER: - cpreg.token = _Value; - DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_TOKEN_REGISTER : %04x", _Value); - break; - - case FIFO_BASE_LO: - WriteLow ((u32 &)cpreg.fifobase, _Value & 0xFFE0); - DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_BASE_LO. FIFO base is : %08x", cpreg.fifobase); - break; - case FIFO_BASE_HI: - WriteHigh((u32 &)cpreg.fifobase, _Value); - DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_BASE_HI. FIFO base is : %08x", cpreg.fifobase); - break; - case FIFO_END_LO: - WriteLow ((u32 &)cpreg.fifoend, _Value & 0xFFE0); - DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_END_LO. FIFO end is : %08x", cpreg.fifoend); - break; - case FIFO_END_HI: - WriteHigh((u32 &)cpreg.fifoend, _Value); - DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_END_HI. FIFO end is : %08x", cpreg.fifoend); - break; - - case FIFO_WRITE_POINTER_LO: - WriteLow ((u32 &)cpreg.writeptr, _Value & 0xFFE0); - DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_WRITE_POINTER_LO. write ptr is : %08x", cpreg.writeptr); - break; - case FIFO_WRITE_POINTER_HI: - WriteHigh ((u32 &)cpreg.writeptr, _Value); - DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_WRITE_POINTER_HI. write ptr is : %08x", cpreg.writeptr); - break; - case FIFO_READ_POINTER_LO: - WriteLow ((u32 &)cpreg.readptr, _Value & 0xFFE0); - DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_READ_POINTER_LO. read ptr is : %08x", cpreg.readptr); - break; - case FIFO_READ_POINTER_HI: - WriteHigh ((u32 &)cpreg.readptr, _Value); - DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_READ_POINTER_HI. read ptr is : %08x", cpreg.readptr); - break; - - case FIFO_HI_WATERMARK_LO: - WriteLow ((u32 &)cpreg.hiwatermark, _Value); - DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_HI_WATERMARK_LO. hiwatermark is : %08x", cpreg.hiwatermark); - break; - case FIFO_HI_WATERMARK_HI: - WriteHigh ((u32 &)cpreg.hiwatermark, _Value); - DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_HI_WATERMARK_HI. hiwatermark is : %08x", cpreg.hiwatermark); - break; - case FIFO_LO_WATERMARK_LO: - WriteLow ((u32 &)cpreg.lowatermark, _Value); - DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_LO_WATERMARK_LO. lowatermark is : %08x", cpreg.lowatermark); - break; - case FIFO_LO_WATERMARK_HI: - WriteHigh ((u32 &)cpreg.lowatermark, _Value); - DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_LO_WATERMARK_HI. lowatermark is : %08x", cpreg.lowatermark); - break; - - case FIFO_BP_LO: - WriteLow ((u32 &)cpreg.breakpt, _Value & 0xFFE0); - DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_BP_LO. breakpoint is : %08x", cpreg.breakpt); - break; - case FIFO_BP_HI: - WriteHigh ((u32 &)cpreg.breakpt, _Value); - DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_BP_HI. breakpoint is : %08x", cpreg.breakpt); - break; - - case FIFO_RW_DISTANCE_LO: - WriteLow ((u32 &)cpreg.rwdistance, _Value & 0xFFE0); - DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_RW_DISTANCE_LO. rwdistance is : %08x", cpreg.rwdistance); - break; - case FIFO_RW_DISTANCE_HI: - WriteHigh ((u32 &)cpreg.rwdistance, _Value); - DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_RW_DISTANCE_HI. rwdistance is : %08x", cpreg.rwdistance); - break; - } - - RunGpu(); +void Write16(const u16 _Value, const u32 _Address) +{ + // HACK: Remove this function when the new MMIO interface is used. + Memory::mmio_mapping->Write(_Address, _Value); } void Read32(u32& _rReturnValue, const u32 _Address) { - _rReturnValue = 0; - _dbg_assert_msg_(COMMANDPROCESSOR, 0, "Read32 from CommandProcessor at 0x%08x", _Address); + // HACK: Remove this function when the new MMIO interface is used. + Memory::mmio_mapping->Read(_Address, _rReturnValue); } void Write32(const u32 _Data, const u32 _Address) { - _dbg_assert_msg_(COMMANDPROCESSOR, 0, "Write32 at CommandProcessor at 0x%08x", _Address); + // HACK: Remove this function when the new MMIO interface is used. + Memory::mmio_mapping->Write(_Address, _Data); } void STACKALIGN GatherPipeBursted() diff --git a/Source/Core/VideoBackends/Software/SWCommandProcessor.h b/Source/Core/VideoBackends/Software/SWCommandProcessor.h index 043ff85d0e..1144b66b67 100644 --- a/Source/Core/VideoBackends/Software/SWCommandProcessor.h +++ b/Source/Core/VideoBackends/Software/SWCommandProcessor.h @@ -7,6 +7,7 @@ #include "Common.h" class PointerWrap; +namespace MMIO { class Mapping; } extern volatile bool g_bSkipCurrentFrame; extern u8* g_pVideoData; @@ -123,6 +124,8 @@ namespace SWCommandProcessor void Shutdown(); void DoState(PointerWrap &p); + void RegisterMMIO(MMIO::Mapping* mmio, u32 base); + bool RunBuffer(); void RunGpu(); diff --git a/Source/Core/VideoBackends/Software/SWPixelEngine.cpp b/Source/Core/VideoBackends/Software/SWPixelEngine.cpp index 4d2f44f96f..fafa87e015 100644 --- a/Source/Core/VideoBackends/Software/SWPixelEngine.cpp +++ b/Source/Core/VideoBackends/Software/SWPixelEngine.cpp @@ -11,6 +11,7 @@ #include "ChunkFile.h" #include "CoreTiming.h" #include "ConfigManager.h" +#include "HW/MMIO.h" #include "HW/ProcessorInterface.h" #include "SWPixelEngine.h" @@ -60,30 +61,22 @@ void Init() et_SetFinishOnMainThread = CoreTiming::RegisterEvent("SetFinish", SetFinish_OnMainThread); } -void Read16(u16& _uReturnValue, const u32 _iAddress) +void RegisterMMIO(MMIO::Mapping* mmio, u32 base) { - DEBUG_LOG(PIXELENGINE, "(r16): 0x%08x", _iAddress); - - u16 address = _iAddress & 0xFFF; - - if (address <= 0x2e) - _uReturnValue = ((u16*)&pereg)[address >> 1]; -} - -void Write32(const u32 _iValue, const u32 _iAddress) -{ - WARN_LOG(PIXELENGINE, "(w32): 0x%08x @ 0x%08x",_iValue,_iAddress); -} - -void Write16(const u16 _iValue, const u32 _iAddress) -{ - u16 address = _iAddress & 0xFFF; - - switch (address) + // Directly map reads and writes to the pereg structure. + for (size_t i = 0; i < sizeof (pereg) / sizeof (u16); ++i) { - case PE_CTRL_REGISTER: - { - UPECtrlReg tmpCtrl(_iValue); + u16* ptr = (u16*)&pereg + i; + mmio->Register(base | (i * 2), + MMIO::DirectRead(ptr), + MMIO::DirectWrite(ptr) + ); + } + + // The control register has some more complex logic to perform on writes. + mmio->RegisterWrite(base | PE_CTRL_REGISTER, + MMIO::ComplexWrite([](u32, u16 val) { + UPECtrlReg tmpCtrl(val); if (tmpCtrl.PEToken) g_bSignalTokenInterrupt = false; if (tmpCtrl.PEFinish) g_bSignalFinishInterrupt = false; @@ -93,15 +86,27 @@ void Write16(const u16 _iValue, const u32 _iAddress) pereg.ctrl.PEToken = 0; // this flag is write only pereg.ctrl.PEFinish = 0; // this flag is write only - DEBUG_LOG(PIXELENGINE, "(w16): PE_CTRL_REGISTER: 0x%04x", _iValue); UpdateInterrupts(); - } - break; - default: - if (address <= 0x2e) - ((u16*)&pereg)[address >> 1] = _iValue; - break; - } + }) + ); +} + +void Read16(u16& _uReturnValue, const u32 _iAddress) +{ + // HACK: Remove this function when the new MMIO interface is used. + Memory::mmio_mapping->Read(_iAddress, _uReturnValue); +} + +void Write32(const u32 _iValue, const u32 _iAddress) +{ + // HACK: Remove this function when the new MMIO interface is used. + Memory::mmio_mapping->Write(_iAddress, _iValue); +} + +void Write16(const u16 _iValue, const u32 _iAddress) +{ + // HACK: Remove this function when the new MMIO interface is used. + Memory::mmio_mapping->Write(_iAddress, _iValue); } bool AllowIdleSkipping() diff --git a/Source/Core/VideoBackends/Software/SWPixelEngine.h b/Source/Core/VideoBackends/Software/SWPixelEngine.h index 5e4018a03c..e8d0a3d6c0 100644 --- a/Source/Core/VideoBackends/Software/SWPixelEngine.h +++ b/Source/Core/VideoBackends/Software/SWPixelEngine.h @@ -8,6 +8,7 @@ #include "VideoCommon.h" class PointerWrap; +namespace MMIO { class Mapping; } namespace SWPixelEngine { @@ -200,6 +201,8 @@ namespace SWPixelEngine void Init(); void DoState(PointerWrap &p); + void RegisterMMIO(MMIO::Mapping* mmio, u32 base); + // Read void Read16(u16& _uReturnValue, const u32 _iAddress); diff --git a/Source/Core/VideoBackends/Software/SWmain.cpp b/Source/Core/VideoBackends/Software/SWmain.cpp index f7c4856b61..4886d2b221 100644 --- a/Source/Core/VideoBackends/Software/SWmain.cpp +++ b/Source/Core/VideoBackends/Software/SWmain.cpp @@ -362,12 +362,12 @@ void VideoSoftware::Video_AbortFrame(void) void VideoSoftware::RegisterCPMMIO(MMIO::Mapping* mmio, u32 base) { - // TODO + SWCommandProcessor::RegisterMMIO(mmio, base); } void VideoSoftware::RegisterPEMMIO(MMIO::Mapping* mmio, u32 base) { - // TODO + SWPixelEngine::RegisterMMIO(mmio, base); } readFn16 VideoSoftware::Video_CPRead16()