From 7de697ab64606c1b755a4aaf08a99259ed33e961 Mon Sep 17 00:00:00 2001 From: irisz64 Date: Wed, 3 Sep 2025 11:48:14 +0200 Subject: [PATCH] Clean this up too --- src/backend/core/registers/Cop0.cpp | 81 +++++++++++++++++------------ src/backend/core/registers/Cop0.hpp | 8 ++- 2 files changed, 50 insertions(+), 39 deletions(-) diff --git a/src/backend/core/registers/Cop0.cpp b/src/backend/core/registers/Cop0.cpp index 0c7f5516..e287a575 100644 --- a/src/backend/core/registers/Cop0.cpp +++ b/src/backend/core/registers/Cop0.cpp @@ -443,24 +443,9 @@ void Cop0::decode(const Instruction instr) { } } -bool Cop0::MapVAddr(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) { - if(supervisorMode) - panic("Supervisor mode memory access, 64 bit mode"); - if (is64BitAddressing) [[unlikely]] { - if (kernelMode) [[likely]] return MapVAddr64(accessType, vaddr, paddr); - if (userMode) return UserMapVAddr64(accessType, vaddr, paddr); - - panic("Unknown mode! This should never happen!"); - } - - if (kernelMode) [[likely]] return MapVAddr32(accessType, vaddr, paddr); - if (userMode) return UserMapVAddr32(accessType, vaddr, paddr); - - panic("Unknown mode! This should never happen!"); -} - -bool Cop0::UserMapVAddr32(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) { +template <> +bool Cop0::MapVirtualAddress(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) { if(Util::IsInsideRange(vaddr, START_VREGION_KUSEG, END_VREGION_KUSEG)) return ProbeTLB(accessType, s64(s32(vaddr)), paddr); @@ -468,7 +453,8 @@ bool Cop0::UserMapVAddr32(const TLBAccessType accessType, const u64 vaddr, u32 & return false; } -bool Cop0::MapVAddr32(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) { +template <> +bool Cop0::MapVirtualAddress(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) { u8 segment = static_cast(vaddr) >> 29 & 7; if(Util::IsInsideRange(segment, 0, 3) || segment == 7) return ProbeTLB(accessType, static_cast(vaddr), paddr); @@ -481,10 +467,13 @@ bool Cop0::MapVAddr32(const TLBAccessType accessType, const u64 vaddr, u32 &padd if(segment == 6) panic("Unimplemented virtual mapping in KSSEG! ({:08X})", vaddr); + panic("Should never end up in base case in MapVirtualAddress! ({:08X})", vaddr); + return false; } -bool Cop0::UserMapVAddr64(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) { +template <> +bool Cop0::MapVirtualAddress(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) { if(Util::IsInsideRange(vaddr, 0x0000000000000000, 0x000000FFFFFFFFFF)) return ProbeTLB(accessType, vaddr, paddr); @@ -492,30 +481,37 @@ bool Cop0::UserMapVAddr64(const TLBAccessType accessType, const u64 vaddr, u32 & return false; } -bool Cop0::MapVAddr64(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) { - if(Util::IsInsideRange(vaddr, 0x0000000000000000, 0x000000FFFFFFFFFF) || - Util::IsInsideRange(vaddr, 0x4000000000000000, 0x400000FFFFFFFFFF) || - Util::IsInsideRange(vaddr, 0xC000000000000000, 0xC00000FF7FFFFFFF) || - Util::IsInsideRange(vaddr, 0xFFFFFFFFE0000000, 0xFFFFFFFFFFFFFFFF)) +template <> +bool Cop0::MapVirtualAddress(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) { + if(Util::IsInsideRange(vaddr, 0x0000000000000000, 0x000000FFFFFFFFFF) || // VREGION_XKUSEG + Util::IsInsideRange(vaddr, 0x4000000000000000, 0x400000FFFFFFFFFF) || // VREGION_XKSSEG + Util::IsInsideRange(vaddr, 0xC000000000000000, 0xC00000FF7FFFFFFF) || // VREGION_XKSEG + Util::IsInsideRange(vaddr, 0xFFFFFFFFE0000000, 0xFFFFFFFFFFFFFFFF)) // VREGION_CKSEG3 return ProbeTLB(accessType, vaddr, paddr); - if(Util::IsInsideRange(vaddr, 0x8000000000000000, 0xBFFFFFFFFFFFFFFF)) { - if (!kernelMode) panic("Access to XKPHYS address 0x{:016X} when outside kernel mode!", vaddr); - if (((vaddr >> 62) & 0b11) != 0b10) panic("Access to XKPHYS address 0x{:016X} with high two bits != 0b10!", vaddr); + if(Util::IsInsideRange(vaddr, 0x8000000000000000, 0xBFFFFFFFFFFFFFFF)) { // VREGION_XKPHYS + if (!kernelMode) + panic("Access to XKPHYS address 0x{:016X} when outside kernel mode!", vaddr); + + const u8 high_two_bits = (vaddr >> 62) & 0b11; + if (high_two_bits != 0b10) + panic("Access to XKPHYS address 0x{:016X} with high two bits != 0b10!", vaddr); const u8 subsegment = (vaddr >> 59) & 0b11; bool cached = subsegment != 2; // do something with this eventually // If any bits in the range of 58:32 are set, the address is invalid. - if ((vaddr & 0x07FFFFFF00000000) != 0) { + const bool valid = (vaddr & 0x07FFFFFF00000000) == 0; + if (!valid) { tlbError = DISALLOWED_ADDRESS; return false; } + paddr = vaddr & 0xFFFFFFFF; return true; } - if(Util::IsInsideRange(vaddr, 0xFFFFFFFF80000000, 0xFFFFFFFF9FFFFFFF) || - Util::IsInsideRange(vaddr, 0xFFFFFFFFA0000000, 0xFFFFFFFFBFFFFFFF)) { + if(Util::IsInsideRange(vaddr, 0xFFFFFFFF80000000, 0xFFFFFFFF9FFFFFFF) || // VREGION_CKSEG0 + Util::IsInsideRange(vaddr, 0xFFFFFFFFA0000000, 0xFFFFFFFFBFFFFFFF)) { // VREGION_CKSEG1 u32 cut = u32(vaddr) >> 28; u32 num = cut == 0xA; // Identical to ksegX in 32 bit mode. @@ -525,14 +521,31 @@ bool Cop0::MapVAddr64(const TLBAccessType accessType, const u64 vaddr, u32 &padd return true; } - if(Util::IsInsideRange(vaddr, 0x0000010000000000, 0x3FFFFFFFFFFFFFFF) || - Util::IsInsideRange(vaddr, 0x4000010000000000, 0x7FFFFFFFFFFFFFFF) || - Util::IsInsideRange(vaddr, 0xC00000FF80000000, 0xFFFFFFFF7FFFFFFF)) { + if(Util::IsInsideRange(vaddr, 0x0000010000000000, 0x3FFFFFFFFFFFFFFF) || // VREGION_XBAD1 + Util::IsInsideRange(vaddr, 0x4000010000000000, 0x7FFFFFFFFFFFFFFF) || // VREGION_XBAD2 + Util::IsInsideRange(vaddr, 0xC00000FF80000000, 0xFFFFFFFF7FFFFFFF)) { // VREGION_XBAD3 tlbError = DISALLOWED_ADDRESS; return false; } panic("Resolving virtual address 0x{:016X} in 64 bit mode", vaddr); - return false; + return false; // just to silence warning +} + +bool Cop0::MapVAddr(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) { + if(supervisorMode) + panic("Supervisor mode memory access"); + + if (is64BitAddressing) [[unlikely]] { + if (kernelMode) [[likely]] return MapVirtualAddress(accessType, vaddr, paddr); + if (userMode) return MapVirtualAddress(accessType, vaddr, paddr); + + panic("Unknown mode! This should never happen!"); + } + + if (kernelMode) [[likely]] return MapVirtualAddress(accessType, vaddr, paddr); + if (userMode) return MapVirtualAddress(accessType, vaddr, paddr); + + panic("Unknown mode! This should never happen!"); } } // namespace n64 diff --git a/src/backend/core/registers/Cop0.hpp b/src/backend/core/registers/Cop0.hpp index ab6a23f6..43f228f0 100644 --- a/src/backend/core/registers/Cop0.hpp +++ b/src/backend/core/registers/Cop0.hpp @@ -276,10 +276,8 @@ private: void tlbr(); void tlbw(int); void tlbp(); - - bool UserMapVAddr32(TLBAccessType accessType, u64 vaddr, u32 &paddr); - bool MapVAddr32(TLBAccessType accessType, u64 vaddr, u32 &paddr); - bool UserMapVAddr64(TLBAccessType accessType, u64 vaddr, u32 &paddr); - bool MapVAddr64(TLBAccessType accessType, u64 vaddr, u32 &paddr); + + template + bool MapVirtualAddress(TLBAccessType accessType, u64 vaddr, u32 &paddr); }; } // namespace n64