From f99487e50e3636b598b1d924e62a7b25952ab73f Mon Sep 17 00:00:00 2001 From: Giovanni Bajo Date: Sun, 3 Dec 2023 22:16:00 +0100 Subject: [PATCH] n64: add support to RDP DMA (and XBUS) to cache coherency checks --- ares/n64/rsp/debugger.cpp | 4 ++-- ares/n64/rsp/rsp.hpp | 4 ++-- ares/n64/vulkan/vulkan.cpp | 22 ++++++++++++++++------ 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/ares/n64/rsp/debugger.cpp b/ares/n64/rsp/debugger.cpp index edae695b5b..6e6437f60d 100644 --- a/ares/n64/rsp/debugger.cpp +++ b/ares/n64/rsp/debugger.cpp @@ -123,13 +123,13 @@ auto RSP::Debugger::dmaReadWord(u32 rdramAddress, u32 pbusRegion, u32 pbusAddres } } -auto RSP::Debugger::dmemReadWord(u12 address, int size) -> void { +auto RSP::Debugger::dmemReadWord(u12 address, int size, const char *peripheral) -> void { if (system.homebrewMode) { u8 readMask = ((1 << size) - 1) << (address & 0x7); auto& taintWord = taintMask.dmem[address >> 3]; if (taintWord.dirty & readMask) { u32 rdramAddress = taintWord.ctxDmaRdramAddress + (address & 0x7); - string msg = { "RSP reading from DMEM address 0x", hex(address), " which contains a value which is not cache coherent\n"}; + string msg = { peripheral, " reading from DMEM address 0x", hex(address), " which contains a value which is not cache coherent\n"}; msg.append(string{ "\tCurrent RSP PC: 0x", hex(rsp.ipu.pc, 3L), "\n" }); msg.append(string{ "\tThe value read was previously written by RSP DMA from RDRAM address 0x", hex(rdramAddress, 8L), "\n" }); if(taintWord.ctxDmaOriginCpu) { diff --git a/ares/n64/rsp/rsp.hpp b/ares/n64/rsp/rsp.hpp index 49b6da579e..a69721a028 100644 --- a/ares/n64/rsp/rsp.hpp +++ b/ares/n64/rsp/rsp.hpp @@ -10,7 +10,7 @@ struct RSP : Thread, Memory::RCP { template auto read(u32 address) -> u64 { if (system.homebrewMode) { - self.debugger.dmemReadWord(address, Size); + self.debugger.dmemReadWord(address, Size, "RSP"); } return Memory::Writable::read(address); } @@ -36,7 +36,7 @@ struct RSP : Thread, Memory::RCP { auto ioStatus(bool mode, u32 address, u32 data) -> void; auto dmaReadWord(u32 rdramAddress, u32 pbusRegion, u32 pbusAddress) -> void; - auto dmemReadWord(u12 address, int size) -> void; + auto dmemReadWord(u12 address, int size, const char *peripheral) -> void; auto dmemWriteWord(u12 address, int size, u64 value) -> void; struct TaintMask { diff --git a/ares/n64/vulkan/vulkan.cpp b/ares/n64/vulkan/vulkan.cpp index 1cfe6f08c6..d0d3167acd 100644 --- a/ares/n64/vulkan/vulkan.cpp +++ b/ares/n64/vulkan/vulkan.cpp @@ -82,7 +82,6 @@ auto Vulkan::render() -> bool { }; auto& command = rdp.command; - auto& memory = !command.source ? (Memory::Writable&)rdram.ram : (Memory::Writable&)rsp.dmem; u32 current = command.current & ~7; u32 end = command.end & ~7; @@ -94,11 +93,22 @@ auto Vulkan::render() -> bool { u32& queueOffset = implementation->queueOffset; if(queueSize + length >= 0x8000) return true; - do { - buffer[queueSize * 2 + 0] = memory.read(current); current += 4; - buffer[queueSize * 2 + 1] = memory.read(current); current += 4; - queueSize++; - } while(--length); + if(!command.source) { + do { + buffer[queueSize * 2 + 0] = rdram.ram.read(current, "RDP DMA"); current += 4; + buffer[queueSize * 2 + 1] = rdram.ram.read(current, "RDP DMA"); current += 4; + queueSize++; + } while(--length); + } else { + do { + buffer[queueSize * 2 + 0] = rsp.dmem.read(current); current += 4; + buffer[queueSize * 2 + 1] = rsp.dmem.read(current); current += 4; + if(system.homebrewMode) { + rsp.debugger.dmemReadWord(current - 8, 8, "RDP XBUS"); + } + queueSize++; + } while(--length); + } while(queueOffset < queueSize) { u32 op = buffer[queueOffset * 2];