Clean this up too
This commit is contained in:
@@ -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]] {
|
template <>
|
||||||
if (kernelMode) [[likely]] return MapVAddr64(accessType, vaddr, paddr);
|
bool Cop0::MapVirtualAddress<u32, true>(const TLBAccessType accessType, const u64 vaddr, u32 &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) {
|
|
||||||
if(Util::IsInsideRange(vaddr, START_VREGION_KUSEG, END_VREGION_KUSEG))
|
if(Util::IsInsideRange(vaddr, START_VREGION_KUSEG, END_VREGION_KUSEG))
|
||||||
return ProbeTLB(accessType, s64(s32(vaddr)), paddr);
|
return ProbeTLB(accessType, s64(s32(vaddr)), paddr);
|
||||||
|
|
||||||
@@ -468,7 +453,8 @@ bool Cop0::UserMapVAddr32(const TLBAccessType accessType, const u64 vaddr, u32 &
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Cop0::MapVAddr32(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
|
template <>
|
||||||
|
bool Cop0::MapVirtualAddress<u32, false>(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
|
||||||
u8 segment = static_cast<u32>(vaddr) >> 29 & 7;
|
u8 segment = static_cast<u32>(vaddr) >> 29 & 7;
|
||||||
if(Util::IsInsideRange(segment, 0, 3) || segment == 7)
|
if(Util::IsInsideRange(segment, 0, 3) || segment == 7)
|
||||||
return ProbeTLB(accessType, static_cast<s32>(vaddr), paddr);
|
return ProbeTLB(accessType, static_cast<s32>(vaddr), paddr);
|
||||||
@@ -481,10 +467,13 @@ bool Cop0::MapVAddr32(const TLBAccessType accessType, const u64 vaddr, u32 &padd
|
|||||||
if(segment == 6)
|
if(segment == 6)
|
||||||
panic("Unimplemented virtual mapping in KSSEG! ({:08X})", vaddr);
|
panic("Unimplemented virtual mapping in KSSEG! ({:08X})", vaddr);
|
||||||
|
|
||||||
|
panic("Should never end up in base case in MapVirtualAddress! ({:08X})", vaddr);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Cop0::UserMapVAddr64(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
|
template <>
|
||||||
|
bool Cop0::MapVirtualAddress<u64, true>(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
|
||||||
if(Util::IsInsideRange(vaddr, 0x0000000000000000, 0x000000FFFFFFFFFF))
|
if(Util::IsInsideRange(vaddr, 0x0000000000000000, 0x000000FFFFFFFFFF))
|
||||||
return ProbeTLB(accessType, vaddr, paddr);
|
return ProbeTLB(accessType, vaddr, paddr);
|
||||||
|
|
||||||
@@ -492,30 +481,37 @@ bool Cop0::UserMapVAddr64(const TLBAccessType accessType, const u64 vaddr, u32 &
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Cop0::MapVAddr64(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
|
template <>
|
||||||
if(Util::IsInsideRange(vaddr, 0x0000000000000000, 0x000000FFFFFFFFFF) ||
|
bool Cop0::MapVirtualAddress<u64, false>(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
|
||||||
Util::IsInsideRange(vaddr, 0x4000000000000000, 0x400000FFFFFFFFFF) ||
|
if(Util::IsInsideRange(vaddr, 0x0000000000000000, 0x000000FFFFFFFFFF) || // VREGION_XKUSEG
|
||||||
Util::IsInsideRange(vaddr, 0xC000000000000000, 0xC00000FF7FFFFFFF) ||
|
Util::IsInsideRange(vaddr, 0x4000000000000000, 0x400000FFFFFFFFFF) || // VREGION_XKSSEG
|
||||||
Util::IsInsideRange(vaddr, 0xFFFFFFFFE0000000, 0xFFFFFFFFFFFFFFFF))
|
Util::IsInsideRange(vaddr, 0xC000000000000000, 0xC00000FF7FFFFFFF) || // VREGION_XKSEG
|
||||||
|
Util::IsInsideRange(vaddr, 0xFFFFFFFFE0000000, 0xFFFFFFFFFFFFFFFF)) // VREGION_CKSEG3
|
||||||
return ProbeTLB(accessType, vaddr, paddr);
|
return ProbeTLB(accessType, vaddr, paddr);
|
||||||
|
|
||||||
if(Util::IsInsideRange(vaddr, 0x8000000000000000, 0xBFFFFFFFFFFFFFFF)) {
|
if(Util::IsInsideRange(vaddr, 0x8000000000000000, 0xBFFFFFFFFFFFFFFF)) { // VREGION_XKPHYS
|
||||||
if (!kernelMode) panic("Access to XKPHYS address 0x{:016X} when outside kernel mode!", vaddr);
|
if (!kernelMode)
|
||||||
if (((vaddr >> 62) & 0b11) != 0b10) panic("Access to XKPHYS address 0x{:016X} with high two bits != 0b10!", vaddr);
|
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;
|
const u8 subsegment = (vaddr >> 59) & 0b11;
|
||||||
bool cached = subsegment != 2; // do something with this eventually
|
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 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;
|
tlbError = DISALLOWED_ADDRESS;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
paddr = vaddr & 0xFFFFFFFF;
|
paddr = vaddr & 0xFFFFFFFF;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Util::IsInsideRange(vaddr, 0xFFFFFFFF80000000, 0xFFFFFFFF9FFFFFFF) ||
|
if(Util::IsInsideRange(vaddr, 0xFFFFFFFF80000000, 0xFFFFFFFF9FFFFFFF) || // VREGION_CKSEG0
|
||||||
Util::IsInsideRange(vaddr, 0xFFFFFFFFA0000000, 0xFFFFFFFFBFFFFFFF)) {
|
Util::IsInsideRange(vaddr, 0xFFFFFFFFA0000000, 0xFFFFFFFFBFFFFFFF)) { // VREGION_CKSEG1
|
||||||
u32 cut = u32(vaddr) >> 28;
|
u32 cut = u32(vaddr) >> 28;
|
||||||
u32 num = cut == 0xA;
|
u32 num = cut == 0xA;
|
||||||
// Identical to ksegX in 32 bit mode.
|
// Identical to ksegX in 32 bit mode.
|
||||||
@@ -525,14 +521,31 @@ bool Cop0::MapVAddr64(const TLBAccessType accessType, const u64 vaddr, u32 &padd
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Util::IsInsideRange(vaddr, 0x0000010000000000, 0x3FFFFFFFFFFFFFFF) ||
|
if(Util::IsInsideRange(vaddr, 0x0000010000000000, 0x3FFFFFFFFFFFFFFF) || // VREGION_XBAD1
|
||||||
Util::IsInsideRange(vaddr, 0x4000010000000000, 0x7FFFFFFFFFFFFFFF) ||
|
Util::IsInsideRange(vaddr, 0x4000010000000000, 0x7FFFFFFFFFFFFFFF) || // VREGION_XBAD2
|
||||||
Util::IsInsideRange(vaddr, 0xC00000FF80000000, 0xFFFFFFFF7FFFFFFF)) {
|
Util::IsInsideRange(vaddr, 0xC00000FF80000000, 0xFFFFFFFF7FFFFFFF)) { // VREGION_XBAD3
|
||||||
tlbError = DISALLOWED_ADDRESS;
|
tlbError = DISALLOWED_ADDRESS;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
panic("Resolving virtual address 0x{:016X} in 64 bit mode", vaddr);
|
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<u64, false>(accessType, vaddr, paddr);
|
||||||
|
if (userMode) return MapVirtualAddress<u64, true>(accessType, vaddr, paddr);
|
||||||
|
|
||||||
|
panic("Unknown mode! This should never happen!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kernelMode) [[likely]] return MapVirtualAddress<u32, false>(accessType, vaddr, paddr);
|
||||||
|
if (userMode) return MapVirtualAddress<u32, true>(accessType, vaddr, paddr);
|
||||||
|
|
||||||
|
panic("Unknown mode! This should never happen!");
|
||||||
}
|
}
|
||||||
} // namespace n64
|
} // namespace n64
|
||||||
|
|||||||
@@ -276,10 +276,8 @@ private:
|
|||||||
void tlbr();
|
void tlbr();
|
||||||
void tlbw(int);
|
void tlbw(int);
|
||||||
void tlbp();
|
void tlbp();
|
||||||
|
|
||||||
bool UserMapVAddr32(TLBAccessType accessType, u64 vaddr, u32 &paddr);
|
template <typename T, bool User>
|
||||||
bool MapVAddr32(TLBAccessType accessType, u64 vaddr, u32 &paddr);
|
bool MapVirtualAddress(TLBAccessType accessType, u64 vaddr, u32 &paddr);
|
||||||
bool UserMapVAddr64(TLBAccessType accessType, u64 vaddr, u32 &paddr);
|
|
||||||
bool MapVAddr64(TLBAccessType accessType, u64 vaddr, u32 &paddr);
|
|
||||||
};
|
};
|
||||||
} // namespace n64
|
} // namespace n64
|
||||||
|
|||||||
Reference in New Issue
Block a user