Core: Have load/store ops be able to use 64bit addresses

This commit is contained in:
zilmar 2023-10-05 14:28:32 +10:30
parent 9f07fe2aac
commit e74e8f6a23
4 changed files with 408 additions and 70 deletions

View File

@ -364,10 +364,16 @@ bool CMipsMemoryVM::UpdateMemoryValue32(uint32_t VAddr, uint32_t Value)
bool CMipsMemoryVM::LB_Memory(uint64_t VAddr, uint8_t & Value)
{
if (!b32BitCore() && (uint64_t)((int32_t)VAddr) != VAddr)
if ((uint64_t)((int32_t)VAddr) != VAddr)
{
m_Reg.DoAddressError(VAddr, true);
return false;
uint32_t PAddr;
bool MemoryUnused;
if (!g_TLB->VAddrToPAddr(VAddr, PAddr, MemoryUnused))
{
m_Reg.TriggerAddressException(VAddr, MemoryUnused ? EXC_RADE : EXC_RMISS);
return false;
}
return LB_PhysicalAddress(PAddr, Value);
}
uint32_t VAddr32 = (uint32_t)VAddr;
if (HaveReadBP() && g_Debugger->ReadBP8(VAddr32) && MemoryBreakpoint())
@ -385,17 +391,23 @@ bool CMipsMemoryVM::LB_Memory(uint64_t VAddr, uint8_t & Value)
bool CMipsMemoryVM::LH_Memory(uint64_t VAddr, uint16_t & Value)
{
if (!b32BitCore() && (uint64_t)((int32_t)VAddr) != VAddr)
if ((VAddr & 1) != 0)
{
m_Reg.DoAddressError(VAddr, true);
m_Reg.TriggerAddressException(VAddr, EXC_RADE);
return false;
}
if ((uint64_t)((int32_t)VAddr) != VAddr)
{
uint32_t PAddr;
bool MemoryUnused;
if (!g_TLB->VAddrToPAddr(VAddr, PAddr, MemoryUnused))
{
m_Reg.TriggerAddressException(VAddr, MemoryUnused ? EXC_RADE : EXC_RMISS);
return false;
}
return LH_PhysicalAddress(PAddr, Value);
}
uint32_t VAddr32 = (uint32_t)VAddr;
if ((VAddr32 & 1) != 0)
{
m_Reg.DoAddressError(VAddr, true);
return false;
}
if (HaveReadBP() && g_Debugger->ReadBP16(VAddr32) && MemoryBreakpoint())
{
return false;
@ -411,17 +423,23 @@ bool CMipsMemoryVM::LH_Memory(uint64_t VAddr, uint16_t & Value)
bool CMipsMemoryVM::LW_Memory(uint64_t VAddr, uint32_t & Value)
{
if (!b32BitCore() && (uint64_t)((int32_t)VAddr) != VAddr)
if ((VAddr & 3) != 0)
{
m_Reg.DoAddressError(VAddr, true);
m_Reg.TriggerAddressException(VAddr, EXC_RADE);
return false;
}
if ((uint64_t)((int32_t)VAddr) != VAddr)
{
uint32_t PAddr;
bool MemoryUnused;
if (!g_TLB->VAddrToPAddr(VAddr, PAddr, MemoryUnused))
{
m_Reg.TriggerAddressException(VAddr, MemoryUnused ? EXC_RADE : EXC_RMISS);
return false;
}
return LW_PhysicalAddress(PAddr, Value);
}
uint32_t VAddr32 = (uint32_t)VAddr;
if ((VAddr32 & 3) != 0)
{
m_Reg.DoAddressError(VAddr, true);
return false;
}
if (HaveReadBP() && g_Debugger->ReadBP32(VAddr32) && MemoryBreakpoint())
{
return false;
@ -437,18 +455,23 @@ bool CMipsMemoryVM::LW_Memory(uint64_t VAddr, uint32_t & Value)
bool CMipsMemoryVM::LD_Memory(uint64_t VAddr, uint64_t & Value)
{
if (!b32BitCore() && (uint64_t)((int32_t)VAddr) != VAddr)
if ((VAddr & 7) != 0)
{
m_Reg.DoAddressError(VAddr, true);
m_Reg.TriggerAddressException(VAddr, EXC_RADE);
return false;
}
if ((uint64_t)((int32_t)VAddr) != VAddr)
{
uint32_t PAddr;
bool MemoryUnused;
if (!g_TLB->VAddrToPAddr(VAddr, PAddr, MemoryUnused))
{
m_Reg.TriggerAddressException(VAddr, MemoryUnused ? EXC_RADE : EXC_RMISS);
return false;
}
return LD_PhysicalAddress(PAddr, Value);
}
uint32_t VAddr32 = (uint32_t)VAddr;
if ((VAddr32 & 7) != 0)
{
m_Reg.DoAddressError(VAddr, true);
return false;
}
if (HaveReadBP() && g_Debugger->ReadBP64(VAddr32) && MemoryBreakpoint())
{
return false;
@ -465,13 +488,18 @@ bool CMipsMemoryVM::LD_Memory(uint64_t VAddr, uint64_t & Value)
bool CMipsMemoryVM::SB_Memory(uint64_t VAddr, uint32_t Value)
{
if (!b32BitCore() && (uint64_t)((int32_t)VAddr) != VAddr)
if ((uint64_t)((int32_t)VAddr) != VAddr)
{
m_Reg.DoAddressError(VAddr, false);
return false;
uint32_t PAddr;
bool MemoryUnused;
if (!g_TLB->VAddrToPAddr(VAddr, PAddr, MemoryUnused))
{
m_Reg.TriggerAddressException(VAddr, MemoryUnused ? EXC_WADE : EXC_WMISS);
return false;
}
return SB_PhysicalAddress(PAddr, Value);
}
uint32_t VAddr32 = (uint32_t)VAddr;
if (HaveWriteBP() && g_Debugger->WriteBP8(VAddr32) && MemoryBreakpoint())
{
return false;
@ -487,18 +515,23 @@ bool CMipsMemoryVM::SB_Memory(uint64_t VAddr, uint32_t Value)
bool CMipsMemoryVM::SH_Memory(uint64_t VAddr, uint32_t Value)
{
if (!b32BitCore() && (uint64_t)((int32_t)VAddr) != VAddr)
if ((VAddr & 1) != 0)
{
m_Reg.DoAddressError(VAddr, false);
m_Reg.TriggerAddressException(VAddr, EXC_WADE);
return false;
}
if ((uint64_t)((int32_t)VAddr) != VAddr)
{
uint32_t PAddr;
bool MemoryUnused;
if (!g_TLB->VAddrToPAddr(VAddr, PAddr, MemoryUnused))
{
m_Reg.TriggerAddressException(VAddr, MemoryUnused ? EXC_WADE : EXC_WMISS);
return false;
}
return SH_PhysicalAddress(PAddr, Value);
}
uint32_t VAddr32 = (uint32_t)VAddr;
if ((VAddr32 & 1) != 0)
{
m_Reg.DoAddressError(VAddr, false);
return false;
}
if (HaveWriteBP() && g_Debugger->WriteBP16(VAddr32) && MemoryBreakpoint())
{
return false;
@ -514,18 +547,23 @@ bool CMipsMemoryVM::SH_Memory(uint64_t VAddr, uint32_t Value)
bool CMipsMemoryVM::SW_Memory(uint64_t VAddr, uint32_t Value)
{
if (!b32BitCore() && (uint64_t)((int32_t)VAddr) != VAddr)
if ((VAddr & 3) != 0)
{
m_Reg.DoAddressError(VAddr, false);
m_Reg.TriggerAddressException(VAddr, EXC_WADE);
return false;
}
if ((uint64_t)((int32_t)VAddr) != VAddr)
{
uint32_t PAddr;
bool MemoryUnused;
if (!g_TLB->VAddrToPAddr(VAddr, PAddr, MemoryUnused))
{
m_Reg.TriggerAddressException(VAddr, MemoryUnused ? EXC_WADE : EXC_WMISS);
return false;
}
return SW_PhysicalAddress(PAddr, Value);
}
uint32_t VAddr32 = (uint32_t)VAddr;
if ((VAddr32 & 3) != 0)
{
m_Reg.DoAddressError(VAddr, false);
return false;
}
if (HaveWriteBP() && g_Debugger->WriteBP32(VAddr32) && MemoryBreakpoint())
{
return false;
@ -541,23 +579,27 @@ bool CMipsMemoryVM::SW_Memory(uint64_t VAddr, uint32_t Value)
bool CMipsMemoryVM::SD_Memory(uint64_t VAddr, uint64_t Value)
{
if (!b32BitCore() && (uint64_t)((int32_t)VAddr) != VAddr)
{
m_Reg.DoAddressError(VAddr, false);
return false;
}
uint32_t VAddr32 = (uint32_t)VAddr;
if ((VAddr & 7) != 0)
{
m_Reg.DoAddressError(VAddr, false);
m_Reg.TriggerAddressException(VAddr, EXC_WADE);
return false;
}
if ((uint64_t)((int32_t)VAddr) != VAddr)
{
uint32_t PAddr;
bool MemoryUnused;
if (!g_TLB->VAddrToPAddr(VAddr, PAddr, MemoryUnused))
{
m_Reg.TriggerAddressException(VAddr, MemoryUnused ? EXC_WADE : EXC_WMISS);
return false;
}
return SD_PhysicalAddress(PAddr, Value);
}
uint32_t VAddr32 = (uint32_t)VAddr;
if (HaveWriteBP() && g_Debugger->WriteBP64(VAddr32) && MemoryBreakpoint())
{
return false;
}
uint8_t * MemoryPtr = (uint8_t *)m_MemoryWriteMap[VAddr32 >> 12];
if (MemoryPtr != (uint8_t *)-1)
{
@ -635,7 +677,12 @@ bool CMipsMemoryVM::LB_PhysicalAddress(uint32_t PAddr, uint8_t & Value)
{
case 0x1FC00000: m_PifRamHandler.Read32(ReadAddress, Value32); break;
default:
if (PAddr >= 0x10000000 && PAddr < 0x20000000)
if (PAddr < RdramSize())
{
Value = *(uint8_t *)(m_RDRAM + (PAddr ^ 3));
return true;
}
else if (PAddr >= 0x10000000 && PAddr < 0x20000000)
{
if (!m_RomMemoryHandler.Read32(PAddr, Value32))
{
@ -665,7 +712,12 @@ bool CMipsMemoryVM::LH_PhysicalAddress(uint32_t PAddr, uint16_t & Value)
{
case 0x1FC00000: m_PifRamHandler.Read32(ReadAddress, Value32); break;
default:
if (PAddr >= 0x10000000 && PAddr < 0x20000000)
if (PAddr < RdramSize())
{
Value = *(uint16_t *)(m_RDRAM + (PAddr ^ 2));
return true;
}
else if (PAddr >= 0x10000000 && PAddr < 0x20000000)
{
if (!m_RomMemoryHandler.Read32(PAddr, Value32))
{
@ -707,7 +759,11 @@ bool CMipsMemoryVM::LW_PhysicalAddress(uint32_t PAddr, uint32_t & Value)
case 0x1FC00000: m_PifRamHandler.Read32(PAddr, Value); break;
case 0x1FF00000: m_CartridgeDomain1Address3Handler.Read32(PAddr, Value); break;
default:
if (PAddr >= 0x10000000 && PAddr < 0x20000000)
if (PAddr < RdramSize())
{
Value = *(uint32_t *)(m_RDRAM + PAddr);
}
else if (PAddr >= 0x10000000 && PAddr < 0x20000000)
{
m_RomMemoryHandler.Read32(PAddr, Value);
}
@ -726,7 +782,13 @@ bool CMipsMemoryVM::LW_PhysicalAddress(uint32_t PAddr, uint32_t & Value)
bool CMipsMemoryVM::LD_PhysicalAddress(uint32_t PAddr, uint64_t & Value)
{
if (PAddr < 0x800000)
if (PAddr < RdramSize())
{
*((uint32_t *)(&Value) + 1) = *(uint32_t *)(m_RDRAM + PAddr);
*((uint32_t *)(&Value) + 0) = *(uint32_t *)(m_RDRAM + PAddr + 4);
return true;
}
else if (PAddr < 0x800000)
{
Value = 0;
return true;

View File

@ -526,6 +526,7 @@ void CRegisters::Reset(bool bPostPif, CMipsMemoryVM & MMU)
case CIC_NUS_6106: PIF_Ram[37] = 0x02; PIF_Ram[38] = 0x85; break;
}*/
}
m_System.m_TLB.COP0StatusChanged();
}
void CRegisters::SetAsCurrentSystem()
@ -630,6 +631,7 @@ void CRegisters::Cop0_MT(COP0Reg Reg, uint64_t Value)
{
FixFpuLocations();
}
m_System.m_TLB.COP0StatusChanged();
CheckInterrupts();
break;
}
@ -790,7 +792,7 @@ void CRegisters::TriggerAddressException(uint64_t Address, uint32_t ExceptionCod
}
BAD_VADDR_REGISTER = Address;
ENTRYHI_REGISTER.VPN2 = Address >> 13;
ENTRYHI_REGISTER.VPN2 = ((Address >> 13) & 0x7FFFFFF);
ENTRYHI_REGISTER.R = Address >> 62;
CONTEXT_REGISTER.BadVPN2 = Address >> 13;
XCONTEXT_REGISTER.BadVPN2 = Address >> 13;
@ -831,7 +833,7 @@ void CRegisters::TriggerException(uint32_t ExceptionCode, uint32_t Coprocessor)
CAUSE_REGISTER.ExceptionCode = ExceptionCode;
CAUSE_REGISTER.CoprocessorUnitNumber = Coprocessor;
CAUSE_REGISTER.BranchDelay = m_System.m_PipelineStage == PIPELINE_STAGE_JUMP;
CAUSE_REGISTER.BranchDelay = m_System.m_PipelineStage == PIPELINE_STAGE_JUMP || m_System.m_PipelineStage == PIPELINE_STAGE_PERMLOOP_DELAY_DONE;
EPC_REGISTER = (int64_t)((int32_t)m_PROGRAM_COUNTER - (CAUSE_REGISTER.BranchDelay ? 4 : 0));
STATUS_REGISTER.ExceptionLevel = 1;
m_System.m_PipelineStage = PIPELINE_STAGE_JUMP;

View File

@ -10,7 +10,9 @@
CTLB::CTLB(CMipsMemoryVM & MMU, CRegisters & Reg, CRecompiler *& Recomp) :
m_MMU(MMU),
m_Reg(Reg),
m_Recomp(Recomp)
m_Recomp(Recomp),
m_PrivilegeMode(PrivilegeMode_Kernel),
m_AddressSize32bit(true)
{
WriteTrace(TraceTLB, TraceDebug, "Start");
memset(m_tlb, 0, sizeof(m_tlb));
@ -48,6 +50,7 @@ void CTLB::Reset(bool InvalidateTLB)
SetupTLB_Entry(count, false);
}
}
COP0StatusChanged();
}
bool CTLB::AddressDefined(uint64_t VAddr)
@ -188,6 +191,23 @@ void CTLB::WriteEntry(uint32_t Index, bool Random)
}
}
void CTLB::COP0StatusChanged(void)
{
m_PrivilegeMode = m_Reg.STATUS_REGISTER.PrivilegeMode;
switch (m_PrivilegeMode)
{
case PrivilegeMode_Kernel:
m_AddressSize32bit = m_Reg.STATUS_REGISTER.KernelExtendedAddressing == 0;
break;
case PrivilegeMode_Supervisor:
m_AddressSize32bit = m_Reg.STATUS_REGISTER.SupervisorExtendedAddressing == 0;
break;
case PrivilegeMode_User:
m_AddressSize32bit = m_Reg.STATUS_REGISTER.UserExtendedAddressing == 0;
break;
}
}
void CTLB::SetupTLB_Entry(uint32_t Index, bool Random)
{
// Fix up fast TLB entries
@ -201,10 +221,10 @@ void CTLB::SetupTLB_Entry(uint32_t Index, bool Random)
{
TLB_Unmaped(m_FastTlb[FastIndx].VSTART, m_FastTlb[FastIndx].Length);
}
m_FastTlb[FastIndx].Length = (m_tlb[Index].PageMask.Mask << 12) + 0xFFF;
m_FastTlb[FastIndx].Length = (uint32_t)((m_tlb[Index].PageMask.Mask << 12) + 0xFFF);
m_FastTlb[FastIndx].VSTART = m_tlb[Index].EntryHi.R << 62 | m_tlb[Index].EntryHi.VPN2 << 13;
m_FastTlb[FastIndx].VEND = m_FastTlb[FastIndx].VSTART + m_FastTlb[FastIndx].Length;
m_FastTlb[FastIndx].PHYSSTART = m_tlb[Index].EntryLo0.PFN << 12;
m_FastTlb[FastIndx].PHYSSTART = (uint32_t)(m_tlb[Index].EntryLo0.PFN << 12);
m_FastTlb[FastIndx].PHYSEND = m_FastTlb[FastIndx].PHYSSTART + m_FastTlb[FastIndx].Length;
m_FastTlb[FastIndx].VALID = m_tlb[Index].EntryLo0.V;
m_FastTlb[FastIndx].DIRTY = m_tlb[Index].EntryLo0.D;
@ -218,10 +238,10 @@ void CTLB::SetupTLB_Entry(uint32_t Index, bool Random)
{
TLB_Unmaped(m_FastTlb[FastIndx].VSTART, m_FastTlb[FastIndx].Length);
}
m_FastTlb[FastIndx].Length = (m_tlb[Index].PageMask.Mask << 12) + 0xFFF;
m_FastTlb[FastIndx].Length = (uint32_t)((m_tlb[Index].PageMask.Mask << 12) + 0xFFF);
m_FastTlb[FastIndx].VSTART = (m_tlb[Index].EntryHi.R << 62 | (m_tlb[Index].EntryHi.VPN2 << 13)) + (m_FastTlb[FastIndx].Length + 1);
m_FastTlb[FastIndx].VEND = m_FastTlb[FastIndx].VSTART + m_FastTlb[FastIndx].Length;
m_FastTlb[FastIndx].PHYSSTART = m_tlb[Index].EntryLo1.PFN << 12;
m_FastTlb[FastIndx].PHYSSTART = (uint32_t)m_tlb[Index].EntryLo1.PFN << 12;
m_FastTlb[FastIndx].PHYSEND = m_FastTlb[FastIndx].PHYSSTART + m_FastTlb[FastIndx].Length;
m_FastTlb[FastIndx].VALID = m_tlb[Index].EntryLo1.V;
m_FastTlb[FastIndx].DIRTY = m_tlb[Index].EntryLo1.D;
@ -258,15 +278,254 @@ void CTLB::SetupTLB_Entry(uint32_t Index, bool Random)
}
}
void CTLB::TLB_Unmaped(uint32_t VAddr, uint32_t Len)
void CTLB::TLB_Unmaped(uint64_t VAddr, uint32_t Len)
{
m_MMU.TLB_Unmaped(VAddr, Len);
if (m_Recomp && bSMM_TLB())
if (m_Recomp && bSMM_TLB() && (uint64_t)((int32_t)VAddr) == VAddr)
{
m_Recomp->ClearRecompCode_Virt(VAddr, Len, CRecompiler::Remove_TLB);
m_Recomp->ClearRecompCode_Virt((uint32_t)VAddr, Len, CRecompiler::Remove_TLB);
}
}
bool CTLB::VAddrToPAddr(uint64_t VAddr, uint32_t & PAddr, bool & MemoryUnused)
{
MemoryUnused = false;
if (b32BitCore() && (uint64_t)((int32_t)VAddr) != VAddr)
{
MemoryUnused = true;
return false;
}
MemorySegment Segment = VAddrMemorySegment(VAddr);
if (Segment == MemorySegment_Mapped)
{
for (int i = 0; i < 64; i++)
{
if (m_FastTlb[i].ValidEntry == false)
{
continue;
}
if (VAddr >= m_FastTlb[i].VSTART && VAddr < m_FastTlb[i].VEND)
{
PAddr = (uint32_t)(m_FastTlb[i].PHYSSTART + (VAddr - m_FastTlb[i].VSTART));
return true;
}
}
return false;
}
if (Segment == MemorySegment_Unused)
{
MemoryUnused = true;
return false;
}
if (Segment == MemorySegment_Direct32 || Segment == MemorySegment_Cached32)
{
PAddr = VAddr & 0x1FFFFFFF;
return true;
}
return false;
}
MemorySegment CTLB::VAddrMemorySegment(uint64_t VAddr)
{
if (m_AddressSize32bit)
{
if ((uint64_t)((int32_t)VAddr) != VAddr)
{
return MemorySegment_Unused;
}
uint32_t VAddr32 = (uint32_t)VAddr;
if (m_PrivilegeMode == PrivilegeMode_Kernel)
{
if (VAddr32 <= 0x7fffffff) //kuseg
{
return MemorySegment_Mapped;
}
if (VAddr32 <= 0x9fffffff) //kseg0
{
return MemorySegment_Cached32;
}
if (VAddr32 <= 0xbfffffff) //kseg1
{
return MemorySegment_Direct32;
}
if (VAddr32 <= 0xdfffffff) //ksseg
{
return MemorySegment_Mapped;
}
if (VAddr32 <= 0xffffffff) //kseg3
{
return MemorySegment_Mapped;
}
}
else if (m_PrivilegeMode == PrivilegeMode_Supervisor)
{
if (VAddr32 <= 0x7fffffff) //suseg
{
return MemorySegment_Mapped;
}
if (VAddr32 <= 0xbfffffff)
{
return MemorySegment_Unused;
}
if (VAddr32 <= 0xdfffffff) //sseg
{
return MemorySegment_Mapped;
}
}
else if (m_PrivilegeMode == PrivilegeMode_User)
{
if (VAddr32 <= 0x7fffffff) //useg
{
return MemorySegment_Mapped;
}
}
return MemorySegment_Unused;
}
if (m_PrivilegeMode == PrivilegeMode_Kernel)
{
if (VAddr <= 0x000000ffffffffffull) //xkuseg
{
return MemorySegment_Mapped;
}
if (VAddr <= 0x3fffffffffffffffull)
{
return MemorySegment_Unused;
}
if (VAddr <= 0x400000ffffffffffull) //xksseg
{
return MemorySegment_Mapped;
}
if (VAddr <= 0x7fffffffffffffffull)
{
return MemorySegment_Unused;
}
if (VAddr <= 0x80000000ffffffffull) //xkphys*
{
return MemorySegment_Cached32;
}
if (VAddr <= 0x87ffffffffffffffull)
{
return MemorySegment_Unused;
}
if (VAddr <= 0x88000000ffffffffull)
{
return MemorySegment_Cached32; //xkphys*
}
if (VAddr <= 0x8fffffffffffffffull)
{
return MemorySegment_Unused;
}
if (VAddr <= 0x90000000ffffffffull) //xkphys*
{
return MemorySegment_Direct32;
}
if (VAddr <= 0x97ffffffffffffffull)
{
return MemorySegment_Unused;
}
if (VAddr <= 0x98000000ffffffffull) //xkphys*
{
return MemorySegment_Cached32;
}
if (VAddr <= 0x9fffffffffffffffull)
{
return MemorySegment_Unused;
}
if (VAddr <= 0xa0000000ffffffffull) //xkphys*
{
return MemorySegment_Cached32;
}
if (VAddr <= 0xa7ffffffffffffffull)
{
return MemorySegment_Unused;
}
if (VAddr <= 0xa8000000ffffffffull) //xkphys*
{
return MemorySegment_Cached32;
}
if (VAddr <= 0xafffffffffffffffull)
{
return MemorySegment_Unused;
}
if (VAddr <= 0xb0000000ffffffffull) //xkphys*
{
return MemorySegment_Cached32;
}
if (VAddr <= 0xb7ffffffffffffffull)
{
return MemorySegment_Unused;
}
if (VAddr <= 0xb8000000ffffffffull) //xkphys*
{
return MemorySegment_Cached32;
}
if (VAddr <= 0xbfffffffffffffffull)
{
return MemorySegment_Unused;
}
if (VAddr <= 0xc00000ff7fffffffull) //xkseg
{
return MemorySegment_Mapped;
}
if (VAddr <= 0xffffffff7fffffffull)
{
return MemorySegment_Unused;
}
if (VAddr <= 0xffffffff9fffffffull) //ckseg0
{
return MemorySegment_Cached32;
}
if (VAddr <= 0xffffffffbfffffffull) //ckseg1
{
return MemorySegment_Direct32;
}
if (VAddr <= 0xffffffffdfffffffull) //ckseg2
{
return MemorySegment_Mapped;
}
if (VAddr <= 0xffffffffffffffffull) //ckseg3
{
return MemorySegment_Mapped;
}
}
else if (m_PrivilegeMode == PrivilegeMode_Kernel)
{
if (VAddr <= 0x000000ffffffffffull) //xsuseg
{
return MemorySegment_Mapped;
}
if (VAddr <= 0x3fffffffffffffffull)
{
return MemorySegment_Unused;
}
if (VAddr <= 0x400000ffffffffffull) //xsseg
{
return MemorySegment_Mapped;
}
if (VAddr <= 0xffffffffbfffffffull)
{
return MemorySegment_Unused;
}
if (VAddr <= 0xffffffffdfffffffull) //csseg
{
return MemorySegment_Mapped;
}
if (VAddr <= 0xffffffffffffffffull)
{
return MemorySegment_Unused;
}
}
else if (m_PrivilegeMode == PrivilegeMode_User)
{
if (VAddr <= 0x000000ffffffffffull)
{
return MemorySegment_Mapped; //xuseg
}
}
return MemorySegment_Unused;
}
bool CTLB::PAddrToVAddr(uint32_t PAddr, uint32_t & VAddr, uint32_t & Index)
{
for (int i = Index; i < 64; i++)
@ -277,7 +536,7 @@ bool CTLB::PAddrToVAddr(uint32_t PAddr, uint32_t & VAddr, uint32_t & Index)
}
if (PAddr >= m_FastTlb[i].PHYSSTART && PAddr < m_FastTlb[i].PHYSEND)
{
VAddr = m_FastTlb[i].VSTART + (PAddr - m_FastTlb[i].PHYSSTART);
VAddr = (uint32_t)(m_FastTlb[i].VSTART + (PAddr - m_FastTlb[i].PHYSSTART));
Index = i + 1;
return true;
}

View File

@ -9,6 +9,16 @@ class CRecompiler;
#pragma warning(push)
#pragma warning(disable : 4201) // warning C4201: nonstandard extension used : nameless struct/union
enum MemorySegment
{
MemorySegment_Mapped,
MemorySegment_Cached,
MemorySegment_Cached32,
MemorySegment_Direct,
MemorySegment_Direct32,
MemorySegment_Unused,
};
struct TLB_ENTRY
{
bool EntryDefined;
@ -47,9 +57,11 @@ public:
void Probe();
void ReadEntry();
void WriteEntry(uint32_t Index, bool Random);
void COP0StatusChanged(void);
bool AddressDefined(uint64_t VAddr);
TLB_ENTRY & TlbEntry(int32_t Entry);
bool VAddrToPAddr(uint64_t VAddr, uint32_t & PAddr, bool & MemoryUnused);
bool PAddrToVAddr(uint32_t PAddr, uint32_t & VAddr, uint32_t & Index);
void RecordDifference(CLog & LogFile, const CTLB & rTLB);
@ -62,8 +74,11 @@ private:
CTLB & operator=(const CTLB &);
void SetupTLB_Entry(uint32_t Index, bool Random);
void TLB_Unmaped(uint32_t VAddr, uint32_t Len);
void TLB_Unmaped(uint64_t VAddr, uint32_t Len);
MemorySegment VAddrMemorySegment(uint64_t VAddr);
PRIVILEGE_MODE m_PrivilegeMode;
bool m_AddressSize32bit;
CMipsMemoryVM & m_MMU;
CRegisters & m_Reg;
CRecompiler *& m_Recomp;