Core: Have load/store ops be able to use 64bit addresses
This commit is contained in:
parent
9f07fe2aac
commit
e74e8f6a23
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue