start implementing Supervisor accesses I guess
This commit is contained in:
@@ -463,9 +463,8 @@ void Cop0::decode(const Instruction instr) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
bool Cop0::MapVirtualAddress<u32, true>(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
|
||||
bool Cop0::MapVirtualAddress<u32, Cop0::User>(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
|
||||
if (ircolib::is_inside_range(vaddr, START_VREGION_KUSEG, END_VREGION_KUSEG))
|
||||
return ProbeTLB(accessType, s64(s32(vaddr)), paddr);
|
||||
|
||||
@@ -474,26 +473,52 @@ bool Cop0::MapVirtualAddress<u32, true>(const TLBAccessType accessType, const u6
|
||||
}
|
||||
|
||||
template <>
|
||||
bool Cop0::MapVirtualAddress<u32, false>(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
|
||||
bool Cop0::MapVirtualAddress<u32, Cop0::Supervisor>(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
|
||||
u8 segment = static_cast<u32>(vaddr) >> 29 & 7;
|
||||
if (ircolib::is_inside_range(segment, 0, 3) || segment == 7)
|
||||
if (ircolib::is_inside_range(segment, 0, 3) || segment == 6)
|
||||
return ProbeTLB(accessType, static_cast<s32>(vaddr), paddr);
|
||||
|
||||
if (ircolib::is_inside_range(segment, 4, 5)) {
|
||||
paddr = vaddr & 0x1FFFFFFF;
|
||||
return true;
|
||||
if (ircolib::is_inside_range(segment, 4, 5) || segment == 7) {
|
||||
tlbError = DISALLOWED_ADDRESS;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (segment == 6)
|
||||
ircolib::panic("Unimplemented virtual mapping in KSSEG! ({:08X})", vaddr);
|
||||
|
||||
ircolib::panic("Should never end up in base case in MapVirtualAddress! ({:08X})", vaddr);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool Cop0::MapVirtualAddress<u64, true>(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
|
||||
bool Cop0::MapVirtualAddress<u32, Cop0::Kernel>(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
|
||||
u8 segment = static_cast<u32>(vaddr) >> 29 & 7;
|
||||
if (ircolib::is_inside_range(segment, 0, 3) || segment == 7 || segment == 6)
|
||||
return ProbeTLB(accessType, static_cast<s32>(vaddr), paddr);
|
||||
|
||||
if (ircolib::is_inside_range(segment, 4, 5)) {
|
||||
paddr = vaddr & 0x1FFFFFFF;
|
||||
return true;
|
||||
}
|
||||
|
||||
ircolib::panic("Should never end up in base case in MapVirtualAddress! ({:08X})", vaddr);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool Cop0::MapVirtualAddress<u64, Cop0::Supervisor>(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
|
||||
bool unused1 = ircolib::is_inside_range(vaddr, 0x0000'0100'0000'0000ull, 0x3fff'ffff'ffff'ffffull);
|
||||
bool unused2 = ircolib::is_inside_range(vaddr, 0x4000'0100'0000'0000ull, 0xffff'ffff'bfff'ffffull);
|
||||
bool unused3 = ircolib::is_inside_range(vaddr, 0xffff'ffff'e000'0000ull, 0xffff'ffff'ffff'ffffull);
|
||||
if (unused1 || unused2 || unused3) {
|
||||
tlbError = DISALLOWED_ADDRESS;
|
||||
return false;
|
||||
}
|
||||
|
||||
return ProbeTLB(accessType, static_cast<s32>(vaddr), paddr);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool Cop0::MapVirtualAddress<u64, Cop0::User>(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
|
||||
if (ircolib::is_inside_range(vaddr, 0x0000000000000000, 0x000000FFFFFFFFFF))
|
||||
return ProbeTLB(accessType, vaddr, paddr);
|
||||
|
||||
@@ -502,7 +527,7 @@ bool Cop0::MapVirtualAddress<u64, true>(const TLBAccessType accessType, const u6
|
||||
}
|
||||
|
||||
template <>
|
||||
bool Cop0::MapVirtualAddress<u64, false>(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
|
||||
bool Cop0::MapVirtualAddress<u64, Cop0::Kernel>(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
|
||||
if (ircolib::is_inside_range(vaddr, 0x0000000000000000, 0x000000FFFFFFFFFF) || // VREGION_XKUSEG
|
||||
ircolib::is_inside_range(vaddr, 0x4000000000000000, 0x400000FFFFFFFFFF) || // VREGION_XKSSEG
|
||||
ircolib::is_inside_range(vaddr, 0xC000000000000000, 0xC00000FF7FFFFFFF) || // VREGION_XKSEG
|
||||
@@ -553,23 +578,29 @@ bool Cop0::MapVirtualAddress<u64, false>(const TLBAccessType accessType, const u
|
||||
}
|
||||
|
||||
bool Cop0::MapVAddr(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
|
||||
if (supervisorMode)
|
||||
ircolib::panic("Supervisor mode memory access");
|
||||
|
||||
if (is64BitAddressing) [[unlikely]] {
|
||||
if (kernelMode) [[likely]]
|
||||
return MapVirtualAddress<u64, false>(accessType, vaddr, paddr);
|
||||
return MapVirtualAddress<u64, Cop0::Kernel>(accessType, vaddr, paddr);
|
||||
|
||||
if (supervisorMode)
|
||||
return MapVirtualAddress<u64, Cop0::Supervisor>(accessType, vaddr, paddr);
|
||||
|
||||
if (userMode)
|
||||
return MapVirtualAddress<u64, true>(accessType, vaddr, paddr);
|
||||
return MapVirtualAddress<u64, Cop0::User>(accessType, vaddr, paddr);
|
||||
|
||||
ircolib::panic("Unknown mode! This should never happen!");
|
||||
}
|
||||
|
||||
if (kernelMode) [[likely]]
|
||||
return MapVirtualAddress<u32, false>(accessType, vaddr, paddr);
|
||||
return MapVirtualAddress<u32, Cop0::Kernel>(accessType, vaddr, paddr);
|
||||
|
||||
if (supervisorMode)
|
||||
return MapVirtualAddress<u32, Cop0::Supervisor>(accessType, vaddr, paddr);
|
||||
|
||||
if (userMode)
|
||||
return MapVirtualAddress<u32, true>(accessType, vaddr, paddr);
|
||||
return MapVirtualAddress<u32, Cop0::User>(accessType, vaddr, paddr);
|
||||
|
||||
ircolib::panic("Unknown mode! This should never happen!");
|
||||
return false;
|
||||
}
|
||||
} // namespace n64
|
||||
|
||||
Reference in New Issue
Block a user