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); } }