public TLBEntry(Boolean addressMode, Byte asid, Int64 virtualAddress, PageSize size) : this(addressMode) { /* This is a hack to create entries without using the TLB regs */ m_Vpn2 = new VirtualPageNumber2(asid, (UInt64)virtualAddress & size.AddressBaseMask); m_PageSize = size; }
public byte GetIndex(VirtualPageNumber2 vpn2) { return((Byte) (from index in Enumerable.Range(0, m_Entries.Length) let entry = m_Entries[index] where entry != null && entry.Equals(vpn2) select index).First()); }
public TLBEntry(Boolean addressMode = false) { m_AddressingMode = addressMode; m_PageSize = new PageSize(NamedPageSize.Size4KB); m_Vpn2 = new VirtualPageNumber2(); m_EntryEven = new PageFrameNumber(); m_EntryOdd = new PageFrameNumber(); }
public long TranslateVirtualAddress(long virtualAddress) { VirtualPageNumber2 vpn2 = new VirtualPageNumber2(m_Cp0Regs.EntryHi); PageSize pageSize = new PageSize(m_Cp0Regs.PageMask); TLBEntry entry = null; /* Note: * We are assuming the software set ASID and VPN in the EntryHi when comparing * the virtual address with the TLB cache. Without a real test of this, * we don't know truly know if we rely on EntryHi every time there is a translation * to be performed. I do not understand how the TLB is really even used on the N64 * system, virtual memory is useless without having some kind of pagefile. */ if (m_DuplicateEntryError) { // TODO: Set the TS bit in the status register m_DisableTLB = true; return(-1); } /* Access the global entries first */ if (!m_GlobalVPN2Dictionary.TryGetValue(vpn2, out entry)) { /* If nothing is in global table, then access the entries grouped by an ASID */ if (!m_VPN2Dictionary.TryGetValue(vpn2, out entry)) { throw new TLBException(TLBExceptionType.Refill); } } Boolean isOddPage = ((virtualAddress & pageSize.Size) > 0) ? false : true; PageFrameNumber pfn = isOddPage ? entry.PfnOdd : entry.PfnEven; if (pfn.IsValid) { return(pfn.MapPhysical(pageSize, (UInt64)virtualAddress)); } else { throw new TLBException(TLBExceptionType.Refill); } }
/// <summary> /// If successful, the probe returns the entry index matching the VPN2 / ASID values in EntryHi. /// </summary> /// <remarks> /// Ref: MIPS R4300I Manual Page 637 /// Ref: MIPS R4300I Manual Page 115 /// </remarks> public virtual void Probe() { if (m_DisableTLB) { return; } UpdateRandom(); VirtualPageNumber2 vpn2 = new VirtualPageNumber2(m_Cp0Regs.EntryHi); if (ContainsEntry(vpn2)) { /* Get the entry index */ m_Cp0Regs.Index = GetIndex(vpn2); } else { /* Set P bit to 1 indicating the probe has failed */ m_Cp0Regs.Index = 0x80000000; } }
private bool ContainsEntry(VirtualPageNumber2 vpn2) { return(m_VPN2Dictionary.ContainsKey(vpn2)); }
public bool Equals(VirtualPageNumber2 other) { return (IsGlobal ? true : VPN2.Asid == other.Asid && VPN2.Vpn2 == other.Vpn2); }