Example #1
0
 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;
 }
Example #2
0
 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());
 }
Example #3
0
 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();
 }
Example #4
0
        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);
            }
        }
Example #5
0
        /// <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;
            }
        }
Example #6
0
 private bool ContainsEntry(VirtualPageNumber2 vpn2)
 {
     return(m_VPN2Dictionary.ContainsKey(vpn2));
 }
Example #7
0
 public bool Equals(VirtualPageNumber2 other)
 {
     return
         (IsGlobal ? true : VPN2.Asid == other.Asid &&
          VPN2.Vpn2 == other.Vpn2);
 }