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
3611793Sbrandon.potter@amd.com#include "arch/mips/tlb.hh"
3711793Sbrandon.potter@amd.com
385222Sksewell@umich.edu#include <string>
395222Sksewell@umich.edu#include <vector>
404997Sgblack@eecs.umich.edu
418229Snate@binkert.org#include "arch/mips/faults.hh"
428229Snate@binkert.org#include "arch/mips/pagetable.hh"
435222Sksewell@umich.edu#include "arch/mips/pra_constants.hh"
445222Sksewell@umich.edu#include "arch/mips/utility.hh"
455222Sksewell@umich.edu#include "base/inifile.hh"
465222Sksewell@umich.edu#include "base/str.hh"
475222Sksewell@umich.edu#include "base/trace.hh"
485222Sksewell@umich.edu#include "cpu/thread_context.hh"
498232Snate@binkert.org#include "debug/MipsPRA.hh"
508232Snate@binkert.org#include "debug/TLB.hh"
515224Sksewell@umich.edu#include "mem/page_table.hh"
525222Sksewell@umich.edu#include "params/MipsTLB.hh"
538229Snate@binkert.org#include "sim/process.hh"
544997Sgblack@eecs.umich.edu
555222Sksewell@umich.eduusing namespace std;
565222Sksewell@umich.eduusing namespace MipsISA;
575019Sgblack@eecs.umich.edu
585222Sksewell@umich.edu///////////////////////////////////////////////////////////////////////
595222Sksewell@umich.edu//
605222Sksewell@umich.edu//  MIPS TLB
615222Sksewell@umich.edu//
625019Sgblack@eecs.umich.edu
635222Sksewell@umich.eduTLB::TLB(const Params *p)
645358Sgblack@eecs.umich.edu    : BaseTLB(p), size(p->size), nlu(0)
655222Sksewell@umich.edu{
666378Sgblack@eecs.umich.edu    table = new PTE[size];
676378Sgblack@eecs.umich.edu    memset(table, 0, sizeof(PTE[size]));
686378Sgblack@eecs.umich.edu    smallPages = 0;
695222Sksewell@umich.edu}
705222Sksewell@umich.edu
715222Sksewell@umich.eduTLB::~TLB()
725222Sksewell@umich.edu{
735222Sksewell@umich.edu    if (table)
745222Sksewell@umich.edu        delete [] table;
755222Sksewell@umich.edu}
765222Sksewell@umich.edu
775222Sksewell@umich.edu// look up an entry in the TLB
785222Sksewell@umich.eduMipsISA::PTE *
795222Sksewell@umich.eduTLB::lookup(Addr vpn, uint8_t asn) const
805222Sksewell@umich.edu{
815222Sksewell@umich.edu    // assume not found...
826378Sgblack@eecs.umich.edu    PTE *retval = NULL;
835222Sksewell@umich.edu    PageTable::const_iterator i = lookupTable.find(vpn);
845222Sksewell@umich.edu    if (i != lookupTable.end()) {
855222Sksewell@umich.edu        while (i->first == vpn) {
865222Sksewell@umich.edu            int index = i->second;
876378Sgblack@eecs.umich.edu            PTE *pte = &table[index];
885222Sksewell@umich.edu
895222Sksewell@umich.edu            /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */
905222Sksewell@umich.edu            Addr Mask = pte->Mask;
915222Sksewell@umich.edu            Addr InvMask = ~Mask;
925222Sksewell@umich.edu            Addr VPN  = pte->VPN;
936378Sgblack@eecs.umich.edu            if (((vpn & InvMask) == (VPN & InvMask)) &&
946378Sgblack@eecs.umich.edu                    (pte->G  || (asn == pte->asid))) {
956378Sgblack@eecs.umich.edu                // We have a VPN + ASID Match
965222Sksewell@umich.edu                retval = pte;
975222Sksewell@umich.edu                break;
986378Sgblack@eecs.umich.edu            }
995222Sksewell@umich.edu            ++i;
1005222Sksewell@umich.edu        }
1015019Sgblack@eecs.umich.edu    }
1025019Sgblack@eecs.umich.edu
1035222Sksewell@umich.edu    DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn,
1045222Sksewell@umich.edu            retval ? "hit" : "miss", retval ? retval->PFN1 : 0);
1055222Sksewell@umich.edu    return retval;
1065222Sksewell@umich.edu}
1075222Sksewell@umich.edu
1086378Sgblack@eecs.umich.eduMipsISA::PTE*
1096378Sgblack@eecs.umich.eduTLB::getEntry(unsigned Index) const
1105222Sksewell@umich.edu{
1115222Sksewell@umich.edu    // Make sure that Index is valid
1125222Sksewell@umich.edu    assert(Index<size);
1135222Sksewell@umich.edu    return &table[Index];
1145222Sksewell@umich.edu}
1155222Sksewell@umich.edu
1166378Sgblack@eecs.umich.eduint
1176378Sgblack@eecs.umich.eduTLB::probeEntry(Addr vpn, uint8_t asn) const
1185222Sksewell@umich.edu{
1195222Sksewell@umich.edu    // assume not found...
1206378Sgblack@eecs.umich.edu    int Ind = -1;
1215222Sksewell@umich.edu    PageTable::const_iterator i = lookupTable.find(vpn);
1225222Sksewell@umich.edu    if (i != lookupTable.end()) {
1235222Sksewell@umich.edu        while (i->first == vpn) {
1245222Sksewell@umich.edu            int index = i->second;
1256378Sgblack@eecs.umich.edu            PTE *pte = &table[index];
1265222Sksewell@umich.edu
1275222Sksewell@umich.edu            /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */
1285222Sksewell@umich.edu            Addr Mask = pte->Mask;
1295222Sksewell@umich.edu            Addr InvMask = ~Mask;
1306378Sgblack@eecs.umich.edu            Addr VPN = pte->VPN;
1316378Sgblack@eecs.umich.edu            if (((vpn & InvMask) == (VPN & InvMask)) &&
1326378Sgblack@eecs.umich.edu                    (pte->G  || (asn == pte->asid))) {
1336378Sgblack@eecs.umich.edu                // We have a VPN + ASID Match
1345222Sksewell@umich.edu                Ind = index;
1355222Sksewell@umich.edu                break;
1366378Sgblack@eecs.umich.edu            }
1375222Sksewell@umich.edu            ++i;
1385222Sksewell@umich.edu        }
1395222Sksewell@umich.edu    }
1405222Sksewell@umich.edu    DPRINTF(MipsPRA,"VPN: %x, asid: %d, Result of TLBP: %d\n",vpn,asn,Ind);
1415222Sksewell@umich.edu    return Ind;
1425222Sksewell@umich.edu}
1436378Sgblack@eecs.umich.edu
1446378Sgblack@eecs.umich.eduinline Fault
14512749Sgiacomo.travaglini@arm.comTLB::checkCacheability(const RequestPtr &req)
1465222Sksewell@umich.edu{
1476378Sgblack@eecs.umich.edu    Addr VAddrUncacheable = 0xA0000000;
1486378Sgblack@eecs.umich.edu    // In MIPS, cacheability is controlled by certain bits of the virtual
1496378Sgblack@eecs.umich.edu    // address or by the TLB entry
1506378Sgblack@eecs.umich.edu    if ((req->getVaddr() & VAddrUncacheable) == VAddrUncacheable) {
1516378Sgblack@eecs.umich.edu        // mark request as uncacheable
15210824SAndreas.Sandberg@ARM.com        req->setFlags(Request::UNCACHEABLE | Request::STRICT_ORDER);
1536378Sgblack@eecs.umich.edu    }
1546378Sgblack@eecs.umich.edu    return NoFault;
1555222Sksewell@umich.edu}
1566378Sgblack@eecs.umich.edu
1576378Sgblack@eecs.umich.eduvoid
1586378Sgblack@eecs.umich.eduTLB::insertAt(PTE &pte, unsigned Index, int _smallPages)
1595222Sksewell@umich.edu{
1606378Sgblack@eecs.umich.edu    smallPages = _smallPages;
1616378Sgblack@eecs.umich.edu    if (Index > size) {
1626378Sgblack@eecs.umich.edu        warn("Attempted to write at index (%d) beyond TLB size (%d)",
1636378Sgblack@eecs.umich.edu                Index, size);
1646378Sgblack@eecs.umich.edu    } else {
1656378Sgblack@eecs.umich.edu        // Update TLB
1666378Sgblack@eecs.umich.edu        DPRINTF(TLB, "TLB[%d]: %x %x %x %x\n",
1676378Sgblack@eecs.umich.edu                Index, pte.Mask << 11,
1686378Sgblack@eecs.umich.edu                ((pte.VPN << 11) | pte.asid),
1696378Sgblack@eecs.umich.edu                ((pte.PFN0 << 6) | (pte.C0 << 3) |
1706378Sgblack@eecs.umich.edu                 (pte.D0 << 2) | (pte.V0 <<1) | pte.G),
1716378Sgblack@eecs.umich.edu                ((pte.PFN1 <<6) | (pte.C1 << 3) |
1726378Sgblack@eecs.umich.edu                 (pte.D1 << 2) | (pte.V1 <<1) | pte.G));
17310231Ssteve.reinhardt@amd.com        if (table[Index].V0 || table[Index].V1) {
1746378Sgblack@eecs.umich.edu            // Previous entry is valid
1756378Sgblack@eecs.umich.edu            PageTable::iterator i = lookupTable.find(table[Index].VPN);
1766378Sgblack@eecs.umich.edu            lookupTable.erase(i);
1776378Sgblack@eecs.umich.edu        }
1786378Sgblack@eecs.umich.edu        table[Index]=pte;
1796378Sgblack@eecs.umich.edu        // Update fast lookup table
1806378Sgblack@eecs.umich.edu        lookupTable.insert(make_pair(table[Index].VPN, Index));
1815222Sksewell@umich.edu    }
1825222Sksewell@umich.edu}
1835222Sksewell@umich.edu
1845222Sksewell@umich.edu// insert a new TLB entry
1855222Sksewell@umich.eduvoid
1866378Sgblack@eecs.umich.eduTLB::insert(Addr addr, PTE &pte)
1875222Sksewell@umich.edu{
1886378Sgblack@eecs.umich.edu    fatal("TLB Insert not yet implemented\n");
1895222Sksewell@umich.edu}
1905222Sksewell@umich.edu
1915222Sksewell@umich.eduvoid
1925222Sksewell@umich.eduTLB::flushAll()
1935222Sksewell@umich.edu{
1945222Sksewell@umich.edu    DPRINTF(TLB, "flushAll\n");
1956378Sgblack@eecs.umich.edu    memset(table, 0, sizeof(PTE[size]));
1965222Sksewell@umich.edu    lookupTable.clear();
1975222Sksewell@umich.edu    nlu = 0;
1985222Sksewell@umich.edu}
1995222Sksewell@umich.edu
2005222Sksewell@umich.eduvoid
20110905Sandreas.sandberg@arm.comTLB::serialize(CheckpointOut &cp) const
2025222Sksewell@umich.edu{
2035222Sksewell@umich.edu    SERIALIZE_SCALAR(size);
2045222Sksewell@umich.edu    SERIALIZE_SCALAR(nlu);
2055222Sksewell@umich.edu
2065222Sksewell@umich.edu    for (int i = 0; i < size; i++) {
20710905Sandreas.sandberg@arm.com        ScopedCheckpointSection sec(cp, csprintf("PTE%d", i));
20810905Sandreas.sandberg@arm.com        table[i].serialize(cp);
2095222Sksewell@umich.edu    }
2105222Sksewell@umich.edu}
2115222Sksewell@umich.edu
2125222Sksewell@umich.eduvoid
21310905Sandreas.sandberg@arm.comTLB::unserialize(CheckpointIn &cp)
2145222Sksewell@umich.edu{
2155222Sksewell@umich.edu    UNSERIALIZE_SCALAR(size);
2165222Sksewell@umich.edu    UNSERIALIZE_SCALAR(nlu);
2175222Sksewell@umich.edu
2185222Sksewell@umich.edu    for (int i = 0; i < size; i++) {
21910905Sandreas.sandberg@arm.com        ScopedCheckpointSection sec(cp, csprintf("PTE%d", i));
22010905Sandreas.sandberg@arm.com        table[i].unserialize(cp);
2215222Sksewell@umich.edu        if (table[i].V0 || table[i].V1) {
2225222Sksewell@umich.edu            lookupTable.insert(make_pair(table[i].VPN, i));
2235222Sksewell@umich.edu        }
2245222Sksewell@umich.edu    }
2255222Sksewell@umich.edu}
2265222Sksewell@umich.edu
2275222Sksewell@umich.eduvoid
2285222Sksewell@umich.eduTLB::regStats()
2295222Sksewell@umich.edu{
23011523Sdavid.guillen@arm.com    BaseTLB::regStats();
23111523Sdavid.guillen@arm.com
2325222Sksewell@umich.edu    read_hits
2335222Sksewell@umich.edu        .name(name() + ".read_hits")
2345222Sksewell@umich.edu        .desc("DTB read hits")
2355222Sksewell@umich.edu        ;
2365222Sksewell@umich.edu
2375222Sksewell@umich.edu    read_misses
2385222Sksewell@umich.edu        .name(name() + ".read_misses")
2395222Sksewell@umich.edu        .desc("DTB read misses")
2405222Sksewell@umich.edu        ;
2415222Sksewell@umich.edu
2425222Sksewell@umich.edu
2435222Sksewell@umich.edu    read_accesses
2445222Sksewell@umich.edu        .name(name() + ".read_accesses")
2455222Sksewell@umich.edu        .desc("DTB read accesses")
2465222Sksewell@umich.edu        ;
2475222Sksewell@umich.edu
2485222Sksewell@umich.edu    write_hits
2495222Sksewell@umich.edu        .name(name() + ".write_hits")
2505222Sksewell@umich.edu        .desc("DTB write hits")
2515222Sksewell@umich.edu        ;
2525222Sksewell@umich.edu
2535222Sksewell@umich.edu    write_misses
2545222Sksewell@umich.edu        .name(name() + ".write_misses")
2555222Sksewell@umich.edu        .desc("DTB write misses")
2565222Sksewell@umich.edu        ;
2575222Sksewell@umich.edu
2585222Sksewell@umich.edu
2595222Sksewell@umich.edu    write_accesses
2605222Sksewell@umich.edu        .name(name() + ".write_accesses")
2615222Sksewell@umich.edu        .desc("DTB write accesses")
2625222Sksewell@umich.edu        ;
2635222Sksewell@umich.edu
2645222Sksewell@umich.edu    hits
2655222Sksewell@umich.edu        .name(name() + ".hits")
2665222Sksewell@umich.edu        .desc("DTB hits")
2675222Sksewell@umich.edu        ;
2685222Sksewell@umich.edu
2695222Sksewell@umich.edu    misses
2705222Sksewell@umich.edu        .name(name() + ".misses")
2715222Sksewell@umich.edu        .desc("DTB misses")
2725222Sksewell@umich.edu        ;
2735222Sksewell@umich.edu
2745222Sksewell@umich.edu    accesses
2755222Sksewell@umich.edu        .name(name() + ".accesses")
2765222Sksewell@umich.edu        .desc("DTB accesses")
2775222Sksewell@umich.edu        ;
2785222Sksewell@umich.edu
2795222Sksewell@umich.edu    hits = read_hits + write_hits;
2805222Sksewell@umich.edu    misses = read_misses + write_misses;
2815222Sksewell@umich.edu    accesses = read_accesses + write_accesses;
2825222Sksewell@umich.edu}
2835222Sksewell@umich.edu
2845222Sksewell@umich.eduFault
28512749Sgiacomo.travaglini@arm.comTLB::translateInst(const RequestPtr &req, ThreadContext *tc)
2865222Sksewell@umich.edu{
2878806Sgblack@eecs.umich.edu    if (FullSystem)
2888806Sgblack@eecs.umich.edu        panic("translateInst not implemented in MIPS.\n");
2895224Sksewell@umich.edu
2908806Sgblack@eecs.umich.edu    Process * p = tc->getProcessPtr();
2915224Sksewell@umich.edu
2928806Sgblack@eecs.umich.edu    Fault fault = p->pTable->translate(req);
2938806Sgblack@eecs.umich.edu    if (fault != NoFault)
2948806Sgblack@eecs.umich.edu        return fault;
2958806Sgblack@eecs.umich.edu
2968806Sgblack@eecs.umich.edu    return NoFault;
2975222Sksewell@umich.edu}
2985222Sksewell@umich.edu
2995222Sksewell@umich.eduFault
30012749Sgiacomo.travaglini@arm.comTLB::translateData(const RequestPtr &req, ThreadContext *tc, bool write)
3015222Sksewell@umich.edu{
3028806Sgblack@eecs.umich.edu    if (FullSystem)
3038806Sgblack@eecs.umich.edu        panic("translateData not implemented in MIPS.\n");
3048767Sgblack@eecs.umich.edu
3058806Sgblack@eecs.umich.edu    Process * p = tc->getProcessPtr();
3068767Sgblack@eecs.umich.edu
3078806Sgblack@eecs.umich.edu    Fault fault = p->pTable->translate(req);
3088806Sgblack@eecs.umich.edu    if (fault != NoFault)
3098806Sgblack@eecs.umich.edu        return fault;
3108806Sgblack@eecs.umich.edu
3118806Sgblack@eecs.umich.edu    return NoFault;
3125222Sksewell@umich.edu}
3135222Sksewell@umich.edu
3146022Sgblack@eecs.umich.eduFault
31512749Sgiacomo.travaglini@arm.comTLB::translateAtomic(const RequestPtr &req, ThreadContext *tc, Mode mode)
3166022Sgblack@eecs.umich.edu{
3176023Snate@binkert.org    if (mode == Execute)
3186022Sgblack@eecs.umich.edu        return translateInst(req, tc);
3196022Sgblack@eecs.umich.edu    else
3206023Snate@binkert.org        return translateData(req, tc, mode == Write);
3216022Sgblack@eecs.umich.edu}
3226022Sgblack@eecs.umich.edu
3235894Sgblack@eecs.umich.eduvoid
32412749Sgiacomo.travaglini@arm.comTLB::translateTiming(const RequestPtr &req, ThreadContext *tc,
3256023Snate@binkert.org        Translation *translation, Mode mode)
3265894Sgblack@eecs.umich.edu{
3275894Sgblack@eecs.umich.edu    assert(translation);
3286023Snate@binkert.org    translation->finish(translateAtomic(req, tc, mode), req, tc, mode);
3295894Sgblack@eecs.umich.edu}
3305894Sgblack@eecs.umich.edu
3318888Sgeoffrey.blake@arm.comFault
33212749Sgiacomo.travaglini@arm.comTLB::finalizePhysical(const RequestPtr &req,
33312749Sgiacomo.travaglini@arm.com                      ThreadContext *tc, Mode mode) const
3349738Sandreas@sandberg.pp.se{
3359738Sandreas@sandberg.pp.se    return NoFault;
3369738Sandreas@sandberg.pp.se}
3379738Sandreas@sandberg.pp.se
3385222Sksewell@umich.edu
3395222Sksewell@umich.eduMipsISA::PTE &
3405222Sksewell@umich.eduTLB::index(bool advance)
3415222Sksewell@umich.edu{
3426378Sgblack@eecs.umich.edu    PTE *pte = &table[nlu];
3435222Sksewell@umich.edu
3445222Sksewell@umich.edu    if (advance)
3455222Sksewell@umich.edu        nextnlu();
3465222Sksewell@umich.edu
3475222Sksewell@umich.edu    return *pte;
3485222Sksewell@umich.edu}
3494997Sgblack@eecs.umich.edu
3506022Sgblack@eecs.umich.eduMipsISA::TLB *
3516022Sgblack@eecs.umich.eduMipsTLBParams::create()
3524997Sgblack@eecs.umich.edu{
3536378Sgblack@eecs.umich.edu    return new TLB(this);
3544997Sgblack@eecs.umich.edu}
355