97 lines
2.8 KiB
C++
97 lines
2.8 KiB
C++
#include <Core.hpp>
|
|
|
|
namespace n64 {
|
|
void InstructionCache::FillLine(u64 vaddr, u32 paddr) {
|
|
int index = GetICacheLineIndex(vaddr);
|
|
auto &line = lines[index];
|
|
line.valid = true;
|
|
line.ptag = paddr & ~0x00000fff;
|
|
auto &mmio = Core::GetMem().mmio;
|
|
|
|
for (int i = 0; i < 8; i++) {
|
|
line.data[i] = mmio.rdp.ReadRDRAM<u32>(line.ptag | index);
|
|
}
|
|
}
|
|
|
|
void InstructionCache::StoreTag(u64 vaddr, u32 ptag, Cop0 &cop0) {
|
|
auto &line = lines[GetICacheLineIndex(vaddr)];
|
|
|
|
line.valid = (cop0.tagLo.pstate >> 1) & 1;
|
|
line.ptag = ptag;
|
|
}
|
|
|
|
void DataCache::StoreTag(u64 vaddr, u32 ptag, Cop0 &cop0) {
|
|
auto &line = lines[GetDCacheLineIndex(vaddr)];
|
|
|
|
line.valid = (cop0.tagLo.pstate >> 1) & 1;
|
|
line.dirty = (cop0.tagLo.pstate >> 0) & 1;
|
|
line.ptag = ptag;
|
|
}
|
|
|
|
void InstructionCache::LoadTag(u64 vaddr) {
|
|
auto &cop0 = Core::GetRegs().cop0;
|
|
auto &line = lines[GetICacheLineIndex(vaddr)];
|
|
cop0.tagLo.pstate = line.valid << 1;
|
|
cop0.tagLo.ptaglo = line.ptag;
|
|
}
|
|
|
|
void DataCache::LoadTag(u64 vaddr) {
|
|
auto &cop0 = Core::GetRegs().cop0;
|
|
auto &line = lines[GetDCacheLineIndex(vaddr)];
|
|
cop0.tagLo.pstate = (line.valid << 1) | line.dirty;
|
|
cop0.tagLo.ptaglo = line.ptag;
|
|
}
|
|
|
|
template <>
|
|
void DataCache::WriteBack<false>(u64 vaddr, u32 paddr) {
|
|
auto &mmio = Core::GetMem().mmio;
|
|
|
|
DCacheLine &line = lines[GetDCacheLineIndex(vaddr)];
|
|
if (!line.valid)
|
|
return;
|
|
|
|
u32 origPhysAddr = (line.ptag << 12) | (paddr & 0xfff);
|
|
u32 lineStart = GetDCacheLineStart(origPhysAddr);
|
|
Core::GetInstance().interpreter.EvictCachedBlock(vaddr);
|
|
for (int i = 0; i < 16; i++) {
|
|
mmio.rdp.WriteRDRAM(lineStart + i, line.data[i]);
|
|
}
|
|
|
|
line.dirty = false;
|
|
}
|
|
|
|
template <>
|
|
void DataCache::WriteBack<true>(u64 vaddr, u32 paddr) {
|
|
WriteBack<false>(vaddr, paddr);
|
|
lines[GetDCacheLineIndex(vaddr)].valid = false;
|
|
}
|
|
|
|
template <>
|
|
void DataCache::WriteBack<false>(u64 vaddr, u32 paddr, u32 ptag) {
|
|
DCacheLine &line = lines[GetDCacheLineIndex(vaddr)];
|
|
if (line.ptag == ptag)
|
|
WriteBack(vaddr, paddr);
|
|
}
|
|
|
|
template <>
|
|
void DataCache::WriteBack<true>(u64 vaddr, u32 paddr, u32 ptag) {
|
|
DCacheLine &line = lines[GetDCacheLineIndex(vaddr)];
|
|
if (line.ptag == ptag)
|
|
WriteBack<true>(vaddr, paddr);
|
|
}
|
|
|
|
void InstructionCache::WriteBack(u64 vaddr, u32 paddr, u32 ptag) {
|
|
auto &mmio = Core::GetMem().mmio;
|
|
ICacheLine &line = lines[GetICacheLineIndex(vaddr)];
|
|
|
|
if (line.ptag == ptag && line.valid) {
|
|
u32 origPhysAddr = (line.ptag << 12) | (paddr & 0xfff);
|
|
u32 lineStart = GetICacheLineStart(origPhysAddr);
|
|
Core::GetInstance().interpreter.EvictCachedBlock(vaddr);
|
|
for (int i = 0; i < 16; i++) {
|
|
mmio.rdp.WriteRDRAM(lineStart + i, line.data[i]);
|
|
}
|
|
}
|
|
}
|
|
} // namespace n64
|