tlb.cc revision 11523
14997Sgblack@eecs.umich.edu/*
25268Sksewell@umich.edu * Copyright (c) 2001-2005 The Regents of The University of Michigan
35254Sksewell@umich.edu * Copyright (c) 2007 MIPS Technologies, Inc.
45254Sksewell@umich.edu * All rights reserved.
54997Sgblack@eecs.umich.edu *
65254Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without
75254Sksewell@umich.edu * modification, are permitted provided that the following conditions are
85254Sksewell@umich.edu * met: redistributions of source code must retain the above copyright
95254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer;
105254Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright
115254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the
125254Sksewell@umich.edu * documentation and/or other materials provided with the distribution;
135254Sksewell@umich.edu * neither the name of the copyright holders nor the names of its
145254Sksewell@umich.edu * contributors may be used to endorse or promote products derived from
155254Sksewell@umich.edu * this software without specific prior written permission.
164997Sgblack@eecs.umich.edu *
175254Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
185254Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
195254Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
205254Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
215254Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
225254Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
235254Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
245254Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
255254Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
265254Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
275254Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
284997Sgblack@eecs.umich.edu *
295268Sksewell@umich.edu * Authors: Nathan Binkert
305268Sksewell@umich.edu *          Steve Reinhardt
315268Sksewell@umich.edu *          Jaidev Patwardhan
328696Sguodeyuan@tsinghua.org.cn *          Zhengxing Li
338696Sguodeyuan@tsinghua.org.cn *          Deyuan Guo
344997Sgblack@eecs.umich.edu */
354997Sgblack@eecs.umich.edu
365222Sksewell@umich.edu#include <string>
375222Sksewell@umich.edu#include <vector>
384997Sgblack@eecs.umich.edu
398229Snate@binkert.org#include "arch/mips/faults.hh"
408229Snate@binkert.org#include "arch/mips/pagetable.hh"
415222Sksewell@umich.edu#include "arch/mips/pra_constants.hh"
424997Sgblack@eecs.umich.edu#include "arch/mips/tlb.hh"
435222Sksewell@umich.edu#include "arch/mips/utility.hh"
445222Sksewell@umich.edu#include "base/inifile.hh"
455222Sksewell@umich.edu#include "base/str.hh"
465222Sksewell@umich.edu#include "base/trace.hh"
475222Sksewell@umich.edu#include "cpu/thread_context.hh"
488232Snate@binkert.org#include "debug/MipsPRA.hh"
498232Snate@binkert.org#include "debug/TLB.hh"
505224Sksewell@umich.edu#include "mem/page_table.hh"
515222Sksewell@umich.edu#include "params/MipsTLB.hh"
528229Snate@binkert.org#include "sim/process.hh"
534997Sgblack@eecs.umich.edu
545222Sksewell@umich.eduusing namespace std;
555222Sksewell@umich.eduusing namespace MipsISA;
565019Sgblack@eecs.umich.edu
575222Sksewell@umich.edu///////////////////////////////////////////////////////////////////////
585222Sksewell@umich.edu//
595222Sksewell@umich.edu//  MIPS TLB
605222Sksewell@umich.edu//
615019Sgblack@eecs.umich.edu
625222Sksewell@umich.eduTLB::TLB(const Params *p)
635358Sgblack@eecs.umich.edu    : BaseTLB(p), size(p->size), nlu(0)
645222Sksewell@umich.edu{
656378Sgblack@eecs.umich.edu    table = new PTE[size];
666378Sgblack@eecs.umich.edu    memset(table, 0, sizeof(PTE[size]));
676378Sgblack@eecs.umich.edu    smallPages = 0;
685222Sksewell@umich.edu}
695222Sksewell@umich.edu
705222Sksewell@umich.eduTLB::~TLB()
715222Sksewell@umich.edu{
725222Sksewell@umich.edu    if (table)
735222Sksewell@umich.edu        delete [] table;
745222Sksewell@umich.edu}
755222Sksewell@umich.edu
765222Sksewell@umich.edu// look up an entry in the TLB
775222Sksewell@umich.eduMipsISA::PTE *
785222Sksewell@umich.eduTLB::lookup(Addr vpn, uint8_t asn) const
795222Sksewell@umich.edu{
805222Sksewell@umich.edu    // assume not found...
816378Sgblack@eecs.umich.edu    PTE *retval = NULL;
825222Sksewell@umich.edu    PageTable::const_iterator i = lookupTable.find(vpn);
835222Sksewell@umich.edu    if (i != lookupTable.end()) {
845222Sksewell@umich.edu        while (i->first == vpn) {
855222Sksewell@umich.edu            int index = i->second;
866378Sgblack@eecs.umich.edu            PTE *pte = &table[index];
875222Sksewell@umich.edu
885222Sksewell@umich.edu            /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */
895222Sksewell@umich.edu            Addr Mask = pte->Mask;
905222Sksewell@umich.edu            Addr InvMask = ~Mask;
915222Sksewell@umich.edu            Addr VPN  = pte->VPN;
926378Sgblack@eecs.umich.edu            if (((vpn & InvMask) == (VPN & InvMask)) &&
936378Sgblack@eecs.umich.edu                    (pte->G  || (asn == pte->asid))) {
946378Sgblack@eecs.umich.edu                // We have a VPN + ASID Match
955222Sksewell@umich.edu                retval = pte;
965222Sksewell@umich.edu                break;
976378Sgblack@eecs.umich.edu            }
985222Sksewell@umich.edu            ++i;
995222Sksewell@umich.edu        }
1005019Sgblack@eecs.umich.edu    }
1015019Sgblack@eecs.umich.edu
1025222Sksewell@umich.edu    DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn,
1035222Sksewell@umich.edu            retval ? "hit" : "miss", retval ? retval->PFN1 : 0);
1045222Sksewell@umich.edu    return retval;
1055222Sksewell@umich.edu}
1065222Sksewell@umich.edu
1076378Sgblack@eecs.umich.eduMipsISA::PTE*
1086378Sgblack@eecs.umich.eduTLB::getEntry(unsigned Index) const
1095222Sksewell@umich.edu{
1105222Sksewell@umich.edu    // Make sure that Index is valid
1115222Sksewell@umich.edu    assert(Index<size);
1125222Sksewell@umich.edu    return &table[Index];
1135222Sksewell@umich.edu}
1145222Sksewell@umich.edu
1156378Sgblack@eecs.umich.eduint
1166378Sgblack@eecs.umich.eduTLB::probeEntry(Addr vpn, uint8_t asn) const
1175222Sksewell@umich.edu{
1185222Sksewell@umich.edu    // assume not found...
1196378Sgblack@eecs.umich.edu    int Ind = -1;
1205222Sksewell@umich.edu    PageTable::const_iterator i = lookupTable.find(vpn);
1215222Sksewell@umich.edu    if (i != lookupTable.end()) {
1225222Sksewell@umich.edu        while (i->first == vpn) {
1235222Sksewell@umich.edu            int index = i->second;
1246378Sgblack@eecs.umich.edu            PTE *pte = &table[index];
1255222Sksewell@umich.edu
1265222Sksewell@umich.edu            /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */
1275222Sksewell@umich.edu            Addr Mask = pte->Mask;
1285222Sksewell@umich.edu            Addr InvMask = ~Mask;
1296378Sgblack@eecs.umich.edu            Addr VPN = pte->VPN;
1306378Sgblack@eecs.umich.edu            if (((vpn & InvMask) == (VPN & InvMask)) &&
1316378Sgblack@eecs.umich.edu                    (pte->G  || (asn == pte->asid))) {
1326378Sgblack@eecs.umich.edu                // We have a VPN + ASID Match
1335222Sksewell@umich.edu                Ind = index;
1345222Sksewell@umich.edu                break;
1356378Sgblack@eecs.umich.edu            }
1365222Sksewell@umich.edu            ++i;
1375222Sksewell@umich.edu        }
1385222Sksewell@umich.edu    }
1395222Sksewell@umich.edu    DPRINTF(MipsPRA,"VPN: %x, asid: %d, Result of TLBP: %d\n",vpn,asn,Ind);
1405222Sksewell@umich.edu    return Ind;
1415222Sksewell@umich.edu}
1426378Sgblack@eecs.umich.edu
1436378Sgblack@eecs.umich.eduinline Fault
1445222Sksewell@umich.eduTLB::checkCacheability(RequestPtr &req)
1455222Sksewell@umich.edu{
1466378Sgblack@eecs.umich.edu    Addr VAddrUncacheable = 0xA0000000;
1476378Sgblack@eecs.umich.edu    // In MIPS, cacheability is controlled by certain bits of the virtual
1486378Sgblack@eecs.umich.edu    // address or by the TLB entry
1496378Sgblack@eecs.umich.edu    if ((req->getVaddr() & VAddrUncacheable) == VAddrUncacheable) {
1506378Sgblack@eecs.umich.edu        // mark request as uncacheable
15110824SAndreas.Sandberg@ARM.com        req->setFlags(Request::UNCACHEABLE | Request::STRICT_ORDER);
1526378Sgblack@eecs.umich.edu    }
1536378Sgblack@eecs.umich.edu    return NoFault;
1545222Sksewell@umich.edu}
1556378Sgblack@eecs.umich.edu
1566378Sgblack@eecs.umich.eduvoid
1576378Sgblack@eecs.umich.eduTLB::insertAt(PTE &pte, unsigned Index, int _smallPages)
1585222Sksewell@umich.edu{
1596378Sgblack@eecs.umich.edu    smallPages = _smallPages;
1606378Sgblack@eecs.umich.edu    if (Index > size) {
1616378Sgblack@eecs.umich.edu        warn("Attempted to write at index (%d) beyond TLB size (%d)",
1626378Sgblack@eecs.umich.edu                Index, size);
1636378Sgblack@eecs.umich.edu    } else {
1646378Sgblack@eecs.umich.edu        // Update TLB
1656378Sgblack@eecs.umich.edu        DPRINTF(TLB, "TLB[%d]: %x %x %x %x\n",
1666378Sgblack@eecs.umich.edu                Index, pte.Mask << 11,
1676378Sgblack@eecs.umich.edu                ((pte.VPN << 11) | pte.asid),
1686378Sgblack@eecs.umich.edu                ((pte.PFN0 << 6) | (pte.C0 << 3) |
1696378Sgblack@eecs.umich.edu                 (pte.D0 << 2) | (pte.V0 <<1) | pte.G),
1706378Sgblack@eecs.umich.edu                ((pte.PFN1 <<6) | (pte.C1 << 3) |
1716378Sgblack@eecs.umich.edu                 (pte.D1 << 2) | (pte.V1 <<1) | pte.G));
17210231Ssteve.reinhardt@amd.com        if (table[Index].V0 || table[Index].V1) {
1736378Sgblack@eecs.umich.edu            // Previous entry is valid
1746378Sgblack@eecs.umich.edu            PageTable::iterator i = lookupTable.find(table[Index].VPN);
1756378Sgblack@eecs.umich.edu            lookupTable.erase(i);
1766378Sgblack@eecs.umich.edu        }
1776378Sgblack@eecs.umich.edu        table[Index]=pte;
1786378Sgblack@eecs.umich.edu        // Update fast lookup table
1796378Sgblack@eecs.umich.edu        lookupTable.insert(make_pair(table[Index].VPN, Index));
1805222Sksewell@umich.edu    }
1815222Sksewell@umich.edu}
1825222Sksewell@umich.edu
1835222Sksewell@umich.edu// insert a new TLB entry
1845222Sksewell@umich.eduvoid
1856378Sgblack@eecs.umich.eduTLB::insert(Addr addr, PTE &pte)
1865222Sksewell@umich.edu{
1876378Sgblack@eecs.umich.edu    fatal("TLB Insert not yet implemented\n");
1885222Sksewell@umich.edu}
1895222Sksewell@umich.edu
1905222Sksewell@umich.eduvoid
1915222Sksewell@umich.eduTLB::flushAll()
1925222Sksewell@umich.edu{
1935222Sksewell@umich.edu    DPRINTF(TLB, "flushAll\n");
1946378Sgblack@eecs.umich.edu    memset(table, 0, sizeof(PTE[size]));
1955222Sksewell@umich.edu    lookupTable.clear();
1965222Sksewell@umich.edu    nlu = 0;
1975222Sksewell@umich.edu}
1985222Sksewell@umich.edu
1995222Sksewell@umich.eduvoid
20010905Sandreas.sandberg@arm.comTLB::serialize(CheckpointOut &cp) const
2015222Sksewell@umich.edu{
2025222Sksewell@umich.edu    SERIALIZE_SCALAR(size);
2035222Sksewell@umich.edu    SERIALIZE_SCALAR(nlu);
2045222Sksewell@umich.edu
2055222Sksewell@umich.edu    for (int i = 0; i < size; i++) {
20610905Sandreas.sandberg@arm.com        ScopedCheckpointSection sec(cp, csprintf("PTE%d", i));
20710905Sandreas.sandberg@arm.com        table[i].serialize(cp);
2085222Sksewell@umich.edu    }
2095222Sksewell@umich.edu}
2105222Sksewell@umich.edu
2115222Sksewell@umich.eduvoid
21210905Sandreas.sandberg@arm.comTLB::unserialize(CheckpointIn &cp)
2135222Sksewell@umich.edu{
2145222Sksewell@umich.edu    UNSERIALIZE_SCALAR(size);
2155222Sksewell@umich.edu    UNSERIALIZE_SCALAR(nlu);
2165222Sksewell@umich.edu
2175222Sksewell@umich.edu    for (int i = 0; i < size; i++) {
21810905Sandreas.sandberg@arm.com        ScopedCheckpointSection sec(cp, csprintf("PTE%d", i));
21910905Sandreas.sandberg@arm.com        table[i].unserialize(cp);
2205222Sksewell@umich.edu        if (table[i].V0 || table[i].V1) {
2215222Sksewell@umich.edu            lookupTable.insert(make_pair(table[i].VPN, i));
2225222Sksewell@umich.edu        }
2235222Sksewell@umich.edu    }
2245222Sksewell@umich.edu}
2255222Sksewell@umich.edu
2265222Sksewell@umich.eduvoid
2275222Sksewell@umich.eduTLB::regStats()
2285222Sksewell@umich.edu{
22911523Sdavid.guillen@arm.com    BaseTLB::regStats();
23011523Sdavid.guillen@arm.com
2315222Sksewell@umich.edu    read_hits
2325222Sksewell@umich.edu        .name(name() + ".read_hits")
2335222Sksewell@umich.edu        .desc("DTB read hits")
2345222Sksewell@umich.edu        ;
2355222Sksewell@umich.edu
2365222Sksewell@umich.edu    read_misses
2375222Sksewell@umich.edu        .name(name() + ".read_misses")
2385222Sksewell@umich.edu        .desc("DTB read misses")
2395222Sksewell@umich.edu        ;
2405222Sksewell@umich.edu
2415222Sksewell@umich.edu
2425222Sksewell@umich.edu    read_accesses
2435222Sksewell@umich.edu        .name(name() + ".read_accesses")
2445222Sksewell@umich.edu        .desc("DTB read accesses")
2455222Sksewell@umich.edu        ;
2465222Sksewell@umich.edu
2475222Sksewell@umich.edu    write_hits
2485222Sksewell@umich.edu        .name(name() + ".write_hits")
2495222Sksewell@umich.edu        .desc("DTB write hits")
2505222Sksewell@umich.edu        ;
2515222Sksewell@umich.edu
2525222Sksewell@umich.edu    write_misses
2535222Sksewell@umich.edu        .name(name() + ".write_misses")
2545222Sksewell@umich.edu        .desc("DTB write misses")
2555222Sksewell@umich.edu        ;
2565222Sksewell@umich.edu
2575222Sksewell@umich.edu
2585222Sksewell@umich.edu    write_accesses
2595222Sksewell@umich.edu        .name(name() + ".write_accesses")
2605222Sksewell@umich.edu        .desc("DTB write accesses")
2615222Sksewell@umich.edu        ;
2625222Sksewell@umich.edu
2635222Sksewell@umich.edu    hits
2645222Sksewell@umich.edu        .name(name() + ".hits")
2655222Sksewell@umich.edu        .desc("DTB hits")
2665222Sksewell@umich.edu        ;
2675222Sksewell@umich.edu
2685222Sksewell@umich.edu    misses
2695222Sksewell@umich.edu        .name(name() + ".misses")
2705222Sksewell@umich.edu        .desc("DTB misses")
2715222Sksewell@umich.edu        ;
2725222Sksewell@umich.edu
2735222Sksewell@umich.edu    accesses
2745222Sksewell@umich.edu        .name(name() + ".accesses")
2755222Sksewell@umich.edu        .desc("DTB accesses")
2765222Sksewell@umich.edu        ;
2775222Sksewell@umich.edu
2785222Sksewell@umich.edu    hits = read_hits + write_hits;
2795222Sksewell@umich.edu    misses = read_misses + write_misses;
2805222Sksewell@umich.edu    accesses = read_accesses + write_accesses;
2815222Sksewell@umich.edu}
2825222Sksewell@umich.edu
2835222Sksewell@umich.eduFault
2846022Sgblack@eecs.umich.eduTLB::translateInst(RequestPtr req, ThreadContext *tc)
2855222Sksewell@umich.edu{
2868806Sgblack@eecs.umich.edu    if (FullSystem)
2878806Sgblack@eecs.umich.edu        panic("translateInst not implemented in MIPS.\n");
2885224Sksewell@umich.edu
2898806Sgblack@eecs.umich.edu    Process * p = tc->getProcessPtr();
2905224Sksewell@umich.edu
2918806Sgblack@eecs.umich.edu    Fault fault = p->pTable->translate(req);
2928806Sgblack@eecs.umich.edu    if (fault != NoFault)
2938806Sgblack@eecs.umich.edu        return fault;
2948806Sgblack@eecs.umich.edu
2958806Sgblack@eecs.umich.edu    return NoFault;
2965222Sksewell@umich.edu}
2975222Sksewell@umich.edu
2985222Sksewell@umich.eduFault
2996022Sgblack@eecs.umich.eduTLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
3005222Sksewell@umich.edu{
3018806Sgblack@eecs.umich.edu    if (FullSystem)
3028806Sgblack@eecs.umich.edu        panic("translateData not implemented in MIPS.\n");
3038767Sgblack@eecs.umich.edu
3048806Sgblack@eecs.umich.edu    Process * p = tc->getProcessPtr();
3058767Sgblack@eecs.umich.edu
3068806Sgblack@eecs.umich.edu    Fault fault = p->pTable->translate(req);
3078806Sgblack@eecs.umich.edu    if (fault != NoFault)
3088806Sgblack@eecs.umich.edu        return fault;
3098806Sgblack@eecs.umich.edu
3108806Sgblack@eecs.umich.edu    return NoFault;
3115222Sksewell@umich.edu}
3125222Sksewell@umich.edu
3136022Sgblack@eecs.umich.eduFault
3146023Snate@binkert.orgTLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
3156022Sgblack@eecs.umich.edu{
3166023Snate@binkert.org    if (mode == Execute)
3176022Sgblack@eecs.umich.edu        return translateInst(req, tc);
3186022Sgblack@eecs.umich.edu    else
3196023Snate@binkert.org        return translateData(req, tc, mode == Write);
3206022Sgblack@eecs.umich.edu}
3216022Sgblack@eecs.umich.edu
3225894Sgblack@eecs.umich.eduvoid
3236022Sgblack@eecs.umich.eduTLB::translateTiming(RequestPtr req, ThreadContext *tc,
3246023Snate@binkert.org        Translation *translation, Mode mode)
3255894Sgblack@eecs.umich.edu{
3265894Sgblack@eecs.umich.edu    assert(translation);
3276023Snate@binkert.org    translation->finish(translateAtomic(req, tc, mode), req, tc, mode);
3285894Sgblack@eecs.umich.edu}
3295894Sgblack@eecs.umich.edu
3308888Sgeoffrey.blake@arm.comFault
3318888Sgeoffrey.blake@arm.comTLB::translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode)
3328888Sgeoffrey.blake@arm.com{
3338888Sgeoffrey.blake@arm.com    panic("Not implemented\n");
3348888Sgeoffrey.blake@arm.com    return NoFault;
3358888Sgeoffrey.blake@arm.com}
3368888Sgeoffrey.blake@arm.com
3379738Sandreas@sandberg.pp.seFault
3389738Sandreas@sandberg.pp.seTLB::finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const
3399738Sandreas@sandberg.pp.se{
3409738Sandreas@sandberg.pp.se    return NoFault;
3419738Sandreas@sandberg.pp.se}
3429738Sandreas@sandberg.pp.se
3435222Sksewell@umich.edu
3445222Sksewell@umich.eduMipsISA::PTE &
3455222Sksewell@umich.eduTLB::index(bool advance)
3465222Sksewell@umich.edu{
3476378Sgblack@eecs.umich.edu    PTE *pte = &table[nlu];
3485222Sksewell@umich.edu
3495222Sksewell@umich.edu    if (advance)
3505222Sksewell@umich.edu        nextnlu();
3515222Sksewell@umich.edu
3525222Sksewell@umich.edu    return *pte;
3535222Sksewell@umich.edu}
3544997Sgblack@eecs.umich.edu
3556022Sgblack@eecs.umich.eduMipsISA::TLB *
3566022Sgblack@eecs.umich.eduMipsTLBParams::create()
3574997Sgblack@eecs.umich.edu{
3586378Sgblack@eecs.umich.edu    return new TLB(this);
3594997Sgblack@eecs.umich.edu}
360