need to figure out why n64-systemtest loops indefinitely at some address that appears to be valid (i think it's me not invalidating the cache properly)

This commit is contained in:
2026-06-03 16:03:24 +02:00
parent 204f0e13b0
commit 12e81e73e8
37 changed files with 305 additions and 3355 deletions
+21 -59
View File
@@ -7,11 +7,7 @@
#include <Registers.hpp>
namespace n64 {
#ifdef KAIZEN_JIT_ENABLED
Mem::Mem(JIT &jit) : flash(saveData), jit(jit) {
#else
Mem::Mem() : flash(saveData) {
#endif
rom.cart.resize(CART_SIZE);
std::ranges::fill(rom.cart, 0);
isviewer_sink = std::ofstream("isviewer.log");
@@ -21,12 +17,10 @@ void Mem::Reset() {
std::ranges::fill(isviewer, 0);
flash.Reset();
if (saveData.is_mapped()) {
std::error_code error;
saveData.sync(error);
if (error) {
Util::Error::GetInstance().Throw({Util::Error::Severity::NON_FATAL},
{Util::Error::Type::COULD_NOT_SYNC_SAVE_DATA}, {}, {},
"[Mem]: Could not sync save data!");
std::error_code err;
saveData.sync(err);
if (err) {
error("[Mem]: Could not sync save data!");
return;
}
saveData.unmap();
@@ -36,18 +30,16 @@ void Mem::Reset() {
void Mem::LoadSRAM(SaveType save_type, fs::path path) {
if (save_type == SAVE_SRAM_256k) {
std::error_code error;
std::error_code err;
std::string savePath = Options::GetInstance().GetValue<std::string>("general", "savePath");
if (!savePath.empty()) {
path = savePath / path.filename();
}
sramPath = path.replace_extension(".sram").string();
if (saveData.is_mapped()) {
saveData.sync(error);
if (error) {
Util::Error::GetInstance().Throw({Util::Error::Severity::NON_FATAL},
{Util::Error::Type::COULD_NOT_SYNC_SAVE_DATA}, {}, {},
R"([Mem]: Could not sync save data stored @ "{}")", sramPath);
saveData.sync(err);
if (err) {
error(R"([Mem]: Could not sync save data stored @ "{}")", sramPath);
return;
}
saveData.unmap();
@@ -60,17 +52,13 @@ void Mem::LoadSRAM(SaveType save_type, fs::path path) {
}
if (sramVec.size() != SRAM_SIZE) {
Util::Error::GetInstance().Throw(
{Util::Error::Severity::NON_FATAL}, {Util::Error::Type::SAVE_DATA_IS_CORRUPT_OR_INVALID_SIZE}, {}, {},
"[Mem]: Save data is corrupt or has unexpected size! (it's {} KiB)", sramVec.size() / 1024);
error("[Mem]: Save data is corrupt or has unexpected size! (it's {} KiB)", sramVec.size() / 1024);
return;
}
saveData = mio::make_mmap_sink(sramPath, error);
if (error) {
Util::Error::GetInstance().Throw({Util::Error::Severity::NON_FATAL},
{Util::Error::Type::MMAP_MAKE_SINK_ERROR}, {}, {},
R"([Mem]: Could not create file sink for save data @ "{}")", sramPath);
saveData = mio::make_mmap_sink(sramPath, err);
if (err) {
error(R"([Mem]: Could not create file sink for save data @ "{}")", sramPath);
}
}
}
@@ -170,9 +158,7 @@ u8 Mem::Read(const u32 paddr) {
if (ircolib::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
ircolib::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) {
Util::Error::GetInstance().Throw(
{Util::Error::Severity::NON_FATAL}, {Util::Error::Type::MEM_INVALID_ACCESS}, regs.pc,
Util::Error::MemoryAccess{false, Util::Error::MemoryAccess::BYTE, paddr, 0}, "8-bit read access from MMIO");
panic("8-bit read access from MMIO addr 0x{:08X} @ pc 0x{:016X}", paddr, (u64)regs.pc);
return 0;
}
@@ -186,10 +172,7 @@ u8 Mem::Read(const u32 paddr) {
ircolib::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4))
return 0;
Util::Error::GetInstance().Throw({Util::Error::Severity::NON_FATAL}, {Util::Error::Type::MEM_UNHANDLED_ACCESS},
regs.pc,
Util::Error::MemoryAccess{false, Util::Error::MemoryAccess::BYTE, paddr, 0},
"8-bit read access in unhandled region");
panic("8-bit read access in unhandled addr 0x{:08X} @ pc 0x{:016X}", paddr, (u64)regs.pc);
return 0;
}
@@ -220,10 +203,7 @@ u16 Mem::Read(const u32 paddr) {
ircolib::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4))
return 0;
Util::Error::GetInstance().Throw({Util::Error::Severity::NON_FATAL}, {Util::Error::Type::MEM_UNHANDLED_ACCESS},
regs.pc,
Util::Error::MemoryAccess{false, Util::Error::MemoryAccess::SHORT, paddr, 0},
"16-bit read access in unhandled region");
panic("16-bit read access in unhandled addr 0x{:08X} @ pc 0x{:016X}", paddr, (u64)regs.pc);
return 0;
}
@@ -255,10 +235,7 @@ u32 Mem::Read(const u32 paddr) {
ircolib::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4))
return 0;
Util::Error::GetInstance().Throw({Util::Error::Severity::NON_FATAL}, {Util::Error::Type::MEM_UNHANDLED_ACCESS},
regs.pc,
Util::Error::MemoryAccess{false, Util::Error::MemoryAccess::WORD, paddr, 0},
"32-bit read access in unhandled region");
panic("32-bit read access in unhandled addr 0x{:08X} @ pc 0x{:016X}", paddr, (u64)regs.pc);
return 0;
}
@@ -290,10 +267,7 @@ u64 Mem::Read(const u32 paddr) {
ircolib::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4))
return 0;
Util::Error::GetInstance().Throw({Util::Error::Severity::NON_FATAL}, {Util::Error::Type::MEM_UNHANDLED_ACCESS},
regs.pc,
Util::Error::MemoryAccess{false, Util::Error::MemoryAccess::DWORD, paddr, 0},
"64-bit read access in unhandled region");
panic("64-bit read access in unhandled addr 0x{:08X} @ pc 0x{:016X}", paddr, (u64)regs.pc);
return 0;
}
@@ -302,12 +276,9 @@ void Mem::Write<u8>(u32 paddr, u32 val) {
n64::Registers &regs = n64::Core::GetRegs();
SI &si = mmio.si;
#ifdef KAIZEN_JIT_ENABLED
jit.InvalidateBlock(paddr);
#endif
if (ircolib::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) {
mmio.rdp.WriteRDRAM<u8>(paddr, val);
Core::GetInstance().interpreter.cachedState.EvictCachedBlock(paddr);
return;
}
if (ircolib::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
@@ -352,12 +323,9 @@ void Mem::Write<u16>(u32 paddr, u32 val) {
n64::Registers &regs = n64::Core::GetRegs();
SI &si = mmio.si;
#ifdef KAIZEN_JIT_ENABLED
jit.InvalidateBlock(paddr);
#endif
if (ircolib::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) {
mmio.rdp.WriteRDRAM<u16>(paddr, val);
Core::GetInstance().interpreter.cachedState.EvictCachedBlock(paddr);
return;
}
if (ircolib::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
@@ -402,12 +370,9 @@ void Mem::Write<u32>(const u32 paddr, const u32 val) {
n64::Registers &regs = n64::Core::GetRegs();
SI &si = mmio.si;
#ifdef KAIZEN_JIT_ENABLED
jit.InvalidateBlock(paddr);
#endif
if (ircolib::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) {
mmio.rdp.WriteRDRAM<u32>(paddr, val);
Core::GetInstance().interpreter.cachedState.EvictCachedBlock(paddr);
return;
}
if (ircolib::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
@@ -449,12 +414,9 @@ void Mem::Write(const u32 paddr, u64 val) {
n64::Registers &regs = n64::Core::GetRegs();
SI &si = mmio.si;
#ifdef KAIZEN_JIT_ENABLED
jit.InvalidateBlock(paddr);
#endif
if (ircolib::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) {
mmio.rdp.WriteRDRAM<u64>(paddr, val);
Core::GetInstance().interpreter.cachedState.EvictCachedBlock(paddr);
return;
}
if (ircolib::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {