tlb.cc revision 10280:5b67e1bdf6ad
1955SN/A/*
2955SN/A * Copyright (c) 2001-2005 The Regents of The University of Michigan
312230Sgiacomo.travaglini@arm.com * Copyright (c) 2007 MIPS Technologies, Inc.
49812Sandreas.hansson@arm.com * All rights reserved.
59812Sandreas.hansson@arm.com *
69812Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
79812Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
89812Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
99812Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
109812Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
119812Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
129812Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
139812Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
149812Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
157816Ssteve.reinhardt@amd.com * this software without specific prior written permission.
165871Snate@binkert.org *
171762SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18955SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19955SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20955SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21955SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22955SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23955SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24955SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25955SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26955SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27955SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28955SN/A *
29955SN/A * Authors: Nathan Binkert
30955SN/A *          Steve Reinhardt
31955SN/A *          Jaidev Patwardhan
32955SN/A *          Zhengxing Li
33955SN/A *          Deyuan Guo
34955SN/A */
35955SN/A
36955SN/A#include <string>
37955SN/A#include <vector>
38955SN/A
39955SN/A#include "arch/mips/faults.hh"
40955SN/A#include "arch/mips/pagetable.hh"
41955SN/A#include "arch/mips/pra_constants.hh"
422665Ssaidi@eecs.umich.edu#include "arch/mips/tlb.hh"
432665Ssaidi@eecs.umich.edu#include "arch/mips/utility.hh"
445863Snate@binkert.org#include "base/inifile.hh"
45955SN/A#include "base/str.hh"
46955SN/A#include "base/trace.hh"
47955SN/A#include "cpu/thread_context.hh"
48955SN/A#include "debug/MipsPRA.hh"
49955SN/A#include "debug/TLB.hh"
508878Ssteve.reinhardt@amd.com#include "mem/page_table.hh"
512632Sstever@eecs.umich.edu#include "params/MipsTLB.hh"
528878Ssteve.reinhardt@amd.com#include "sim/process.hh"
532632Sstever@eecs.umich.edu
54955SN/Ausing namespace std;
558878Ssteve.reinhardt@amd.comusing namespace MipsISA;
562632Sstever@eecs.umich.edu
572761Sstever@eecs.umich.edu///////////////////////////////////////////////////////////////////////
582632Sstever@eecs.umich.edu//
592632Sstever@eecs.umich.edu//  MIPS TLB
602632Sstever@eecs.umich.edu//
612761Sstever@eecs.umich.edu
622761Sstever@eecs.umich.eduTLB::TLB(const Params *p)
632761Sstever@eecs.umich.edu    : BaseTLB(p), size(p->size), nlu(0)
648878Ssteve.reinhardt@amd.com{
658878Ssteve.reinhardt@amd.com    table = new PTE[size];
662761Sstever@eecs.umich.edu    memset(table, 0, sizeof(PTE[size]));
672761Sstever@eecs.umich.edu    smallPages = 0;
682761Sstever@eecs.umich.edu}
692761Sstever@eecs.umich.edu
702761Sstever@eecs.umich.eduTLB::~TLB()
718878Ssteve.reinhardt@amd.com{
728878Ssteve.reinhardt@amd.com    if (table)
732632Sstever@eecs.umich.edu        delete [] table;
742632Sstever@eecs.umich.edu}
758878Ssteve.reinhardt@amd.com
768878Ssteve.reinhardt@amd.com// look up an entry in the TLB
772632Sstever@eecs.umich.eduMipsISA::PTE *
78955SN/ATLB::lookup(Addr vpn, uint8_t asn) const
79955SN/A{
80955SN/A    // assume not found...
8112563Sgabeblack@google.com    PTE *retval = NULL;
8212563Sgabeblack@google.com    PageTable::const_iterator i = lookupTable.find(vpn);
836654Snate@binkert.org    if (i != lookupTable.end()) {
8410196SCurtis.Dunham@arm.com        while (i->first == vpn) {
85955SN/A            int index = i->second;
865396Ssaidi@eecs.umich.edu            PTE *pte = &table[index];
8711401Sandreas.sandberg@arm.com
885863Snate@binkert.org            /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */
895863Snate@binkert.org            Addr Mask = pte->Mask;
904202Sbinkertn@umich.edu            Addr InvMask = ~Mask;
915863Snate@binkert.org            Addr VPN  = pte->VPN;
925863Snate@binkert.org            if (((vpn & InvMask) == (VPN & InvMask)) &&
935863Snate@binkert.org                    (pte->G  || (asn == pte->asid))) {
945863Snate@binkert.org                // We have a VPN + ASID Match
95955SN/A                retval = pte;
966654Snate@binkert.org                break;
975273Sstever@gmail.com            }
985871Snate@binkert.org            ++i;
995273Sstever@gmail.com        }
1006654Snate@binkert.org    }
1015396Ssaidi@eecs.umich.edu
1028120Sgblack@eecs.umich.edu    DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn,
1038120Sgblack@eecs.umich.edu            retval ? "hit" : "miss", retval ? retval->PFN1 : 0);
1048120Sgblack@eecs.umich.edu    return retval;
1058120Sgblack@eecs.umich.edu}
1068120Sgblack@eecs.umich.edu
1078120Sgblack@eecs.umich.eduMipsISA::PTE*
1088120Sgblack@eecs.umich.eduTLB::getEntry(unsigned Index) const
1098120Sgblack@eecs.umich.edu{
1108879Ssteve.reinhardt@amd.com    // Make sure that Index is valid
1118879Ssteve.reinhardt@amd.com    assert(Index<size);
1128879Ssteve.reinhardt@amd.com    return &table[Index];
1138879Ssteve.reinhardt@amd.com}
1148879Ssteve.reinhardt@amd.com
1158879Ssteve.reinhardt@amd.comint
1168879Ssteve.reinhardt@amd.comTLB::probeEntry(Addr vpn, uint8_t asn) const
1178879Ssteve.reinhardt@amd.com{
1188879Ssteve.reinhardt@amd.com    // assume not found...
1198879Ssteve.reinhardt@amd.com    int Ind = -1;
1208879Ssteve.reinhardt@amd.com    PageTable::const_iterator i = lookupTable.find(vpn);
1218879Ssteve.reinhardt@amd.com    if (i != lookupTable.end()) {
1228879Ssteve.reinhardt@amd.com        while (i->first == vpn) {
1238120Sgblack@eecs.umich.edu            int index = i->second;
1248120Sgblack@eecs.umich.edu            PTE *pte = &table[index];
1258120Sgblack@eecs.umich.edu
1268120Sgblack@eecs.umich.edu            /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */
1278120Sgblack@eecs.umich.edu            Addr Mask = pte->Mask;
1288120Sgblack@eecs.umich.edu            Addr InvMask = ~Mask;
1298120Sgblack@eecs.umich.edu            Addr VPN = pte->VPN;
1308120Sgblack@eecs.umich.edu            if (((vpn & InvMask) == (VPN & InvMask)) &&
1318120Sgblack@eecs.umich.edu                    (pte->G  || (asn == pte->asid))) {
1328120Sgblack@eecs.umich.edu                // We have a VPN + ASID Match
1338120Sgblack@eecs.umich.edu                Ind = index;
1348120Sgblack@eecs.umich.edu                break;
1358120Sgblack@eecs.umich.edu            }
1368120Sgblack@eecs.umich.edu            ++i;
1378879Ssteve.reinhardt@amd.com        }
1388879Ssteve.reinhardt@amd.com    }
1398879Ssteve.reinhardt@amd.com    DPRINTF(MipsPRA,"VPN: %x, asid: %d, Result of TLBP: %d\n",vpn,asn,Ind);
1408879Ssteve.reinhardt@amd.com    return Ind;
14110458Sandreas.hansson@arm.com}
14210458Sandreas.hansson@arm.com
14310458Sandreas.hansson@arm.cominline Fault
1448879Ssteve.reinhardt@amd.comTLB::checkCacheability(RequestPtr &req)
1458879Ssteve.reinhardt@amd.com{
1468879Ssteve.reinhardt@amd.com    Addr VAddrUncacheable = 0xA0000000;
1478879Ssteve.reinhardt@amd.com    // In MIPS, cacheability is controlled by certain bits of the virtual
1489227Sandreas.hansson@arm.com    // address or by the TLB entry
1499227Sandreas.hansson@arm.com    if ((req->getVaddr() & VAddrUncacheable) == VAddrUncacheable) {
15012063Sgabeblack@google.com        // mark request as uncacheable
15112063Sgabeblack@google.com        req->setFlags(Request::UNCACHEABLE);
15212063Sgabeblack@google.com    }
1538879Ssteve.reinhardt@amd.com    return NoFault;
1548879Ssteve.reinhardt@amd.com}
1558879Ssteve.reinhardt@amd.com
1568879Ssteve.reinhardt@amd.comvoid
15710453SAndrew.Bardsley@arm.comTLB::insertAt(PTE &pte, unsigned Index, int _smallPages)
15810453SAndrew.Bardsley@arm.com{
15910453SAndrew.Bardsley@arm.com    smallPages = _smallPages;
16010456SCurtis.Dunham@arm.com    if (Index > size) {
16110456SCurtis.Dunham@arm.com        warn("Attempted to write at index (%d) beyond TLB size (%d)",
16210456SCurtis.Dunham@arm.com                Index, size);
16310457Sandreas.hansson@arm.com    } else {
16410457Sandreas.hansson@arm.com        // Update TLB
16511342Sandreas.hansson@arm.com        DPRINTF(TLB, "TLB[%d]: %x %x %x %x\n",
16611342Sandreas.hansson@arm.com                Index, pte.Mask << 11,
1678120Sgblack@eecs.umich.edu                ((pte.VPN << 11) | pte.asid),
16812063Sgabeblack@google.com                ((pte.PFN0 << 6) | (pte.C0 << 3) |
16912563Sgabeblack@google.com                 (pte.D0 << 2) | (pte.V0 <<1) | pte.G),
17012063Sgabeblack@google.com                ((pte.PFN1 <<6) | (pte.C1 << 3) |
17112063Sgabeblack@google.com                 (pte.D1 << 2) | (pte.V1 <<1) | pte.G));
1725871Snate@binkert.org        if (table[Index].V0 || table[Index].V1) {
1735871Snate@binkert.org            // Previous entry is valid
1746121Snate@binkert.org            PageTable::iterator i = lookupTable.find(table[Index].VPN);
1755871Snate@binkert.org            lookupTable.erase(i);
1765871Snate@binkert.org        }
1779926Sstan.czerniawski@arm.com        table[Index]=pte;
17812243Sgabeblack@google.com        // Update fast lookup table
1791533SN/A        lookupTable.insert(make_pair(table[Index].VPN, Index));
18012246Sgabeblack@google.com    }
18112246Sgabeblack@google.com}
18212246Sgabeblack@google.com
18312246Sgabeblack@google.com// insert a new TLB entry
1849239Sandreas.hansson@arm.comvoid
1859239Sandreas.hansson@arm.comTLB::insert(Addr addr, PTE &pte)
1869239Sandreas.hansson@arm.com{
1879239Sandreas.hansson@arm.com    fatal("TLB Insert not yet implemented\n");
18812563Sgabeblack@google.com}
1899239Sandreas.hansson@arm.com
1909239Sandreas.hansson@arm.comvoid
191955SN/ATLB::flushAll()
192955SN/A{
1932632Sstever@eecs.umich.edu    DPRINTF(TLB, "flushAll\n");
1942632Sstever@eecs.umich.edu    memset(table, 0, sizeof(PTE[size]));
195955SN/A    lookupTable.clear();
196955SN/A    nlu = 0;
197955SN/A}
198955SN/A
1998878Ssteve.reinhardt@amd.comvoid
200955SN/ATLB::serialize(ostream &os)
2012632Sstever@eecs.umich.edu{
2022632Sstever@eecs.umich.edu    SERIALIZE_SCALAR(size);
2032632Sstever@eecs.umich.edu    SERIALIZE_SCALAR(nlu);
2042632Sstever@eecs.umich.edu
2052632Sstever@eecs.umich.edu    for (int i = 0; i < size; i++) {
2062632Sstever@eecs.umich.edu        nameOut(os, csprintf("%s.PTE%d", name(), i));
2072632Sstever@eecs.umich.edu        table[i].serialize(os);
2088268Ssteve.reinhardt@amd.com    }
2098268Ssteve.reinhardt@amd.com}
2108268Ssteve.reinhardt@amd.com
2118268Ssteve.reinhardt@amd.comvoid
2128268Ssteve.reinhardt@amd.comTLB::unserialize(Checkpoint *cp, const string &section)
2138268Ssteve.reinhardt@amd.com{
2148268Ssteve.reinhardt@amd.com    UNSERIALIZE_SCALAR(size);
2152632Sstever@eecs.umich.edu    UNSERIALIZE_SCALAR(nlu);
2162632Sstever@eecs.umich.edu
2172632Sstever@eecs.umich.edu    for (int i = 0; i < size; i++) {
2182632Sstever@eecs.umich.edu        table[i].unserialize(cp, csprintf("%s.PTE%d", section, i));
2198268Ssteve.reinhardt@amd.com        if (table[i].V0 || table[i].V1) {
2202632Sstever@eecs.umich.edu            lookupTable.insert(make_pair(table[i].VPN, i));
2218268Ssteve.reinhardt@amd.com        }
2228268Ssteve.reinhardt@amd.com    }
2238268Ssteve.reinhardt@amd.com}
2248268Ssteve.reinhardt@amd.com
2253718Sstever@eecs.umich.eduvoid
2262634Sstever@eecs.umich.eduTLB::regStats()
2272634Sstever@eecs.umich.edu{
2285863Snate@binkert.org    read_hits
2292638Sstever@eecs.umich.edu        .name(name() + ".read_hits")
2308268Ssteve.reinhardt@amd.com        .desc("DTB read hits")
2312632Sstever@eecs.umich.edu        ;
2322632Sstever@eecs.umich.edu
2332632Sstever@eecs.umich.edu    read_misses
2342632Sstever@eecs.umich.edu        .name(name() + ".read_misses")
23512563Sgabeblack@google.com        .desc("DTB read misses")
2361858SN/A        ;
2373716Sstever@eecs.umich.edu
2382638Sstever@eecs.umich.edu
2392638Sstever@eecs.umich.edu    read_accesses
2402638Sstever@eecs.umich.edu        .name(name() + ".read_accesses")
2412638Sstever@eecs.umich.edu        .desc("DTB read accesses")
24212563Sgabeblack@google.com        ;
24312563Sgabeblack@google.com
2442638Sstever@eecs.umich.edu    write_hits
2455863Snate@binkert.org        .name(name() + ".write_hits")
2465863Snate@binkert.org        .desc("DTB write hits")
2475863Snate@binkert.org        ;
248955SN/A
2495341Sstever@gmail.com    write_misses
2505341Sstever@gmail.com        .name(name() + ".write_misses")
2515863Snate@binkert.org        .desc("DTB write misses")
2527756SAli.Saidi@ARM.com        ;
2535341Sstever@gmail.com
2546121Snate@binkert.org
2554494Ssaidi@eecs.umich.edu    write_accesses
2566121Snate@binkert.org        .name(name() + ".write_accesses")
2571105SN/A        .desc("DTB write accesses")
2582667Sstever@eecs.umich.edu        ;
2592667Sstever@eecs.umich.edu
2602667Sstever@eecs.umich.edu    hits
2612667Sstever@eecs.umich.edu        .name(name() + ".hits")
2626121Snate@binkert.org        .desc("DTB hits")
2632667Sstever@eecs.umich.edu        ;
2645341Sstever@gmail.com
2655863Snate@binkert.org    misses
2665341Sstever@gmail.com        .name(name() + ".misses")
2675341Sstever@gmail.com        .desc("DTB misses")
2685341Sstever@gmail.com        ;
2698120Sgblack@eecs.umich.edu
2705341Sstever@gmail.com    accesses
2718120Sgblack@eecs.umich.edu        .name(name() + ".accesses")
2725341Sstever@gmail.com        .desc("DTB accesses")
2738120Sgblack@eecs.umich.edu        ;
2746121Snate@binkert.org
2756121Snate@binkert.org    hits = read_hits + write_hits;
2769396Sandreas.hansson@arm.com    misses = read_misses + write_misses;
2775397Ssaidi@eecs.umich.edu    accesses = read_accesses + write_accesses;
2785397Ssaidi@eecs.umich.edu}
2797727SAli.Saidi@ARM.com
2808268Ssteve.reinhardt@amd.comFault
2816168Snate@binkert.orgTLB::translateInst(RequestPtr req, ThreadContext *tc)
2825341Sstever@gmail.com{
2838120Sgblack@eecs.umich.edu    if (FullSystem)
2848120Sgblack@eecs.umich.edu        panic("translateInst not implemented in MIPS.\n");
2858120Sgblack@eecs.umich.edu
2866814Sgblack@eecs.umich.edu    Process * p = tc->getProcessPtr();
2875863Snate@binkert.org
2888120Sgblack@eecs.umich.edu    Fault fault = p->pTable->translate(req);
2895341Sstever@gmail.com    if (fault != NoFault)
2905863Snate@binkert.org        return fault;
2918268Ssteve.reinhardt@amd.com
2926121Snate@binkert.org    return NoFault;
2936121Snate@binkert.org}
2948268Ssteve.reinhardt@amd.com
2955742Snate@binkert.orgFault
2965742Snate@binkert.orgTLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
2975341Sstever@gmail.com{
2985742Snate@binkert.org    if (FullSystem)
2995742Snate@binkert.org        panic("translateData not implemented in MIPS.\n");
3005341Sstever@gmail.com
3016017Snate@binkert.org    Process * p = tc->getProcessPtr();
3026121Snate@binkert.org
3036017Snate@binkert.org    Fault fault = p->pTable->translate(req);
30412158Sandreas.sandberg@arm.com    if (fault != NoFault)
30512158Sandreas.sandberg@arm.com        return fault;
30612158Sandreas.sandberg@arm.com
3078120Sgblack@eecs.umich.edu    return NoFault;
3087756SAli.Saidi@ARM.com}
3097756SAli.Saidi@ARM.com
3107756SAli.Saidi@ARM.comFault
3117756SAli.Saidi@ARM.comTLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
3127816Ssteve.reinhardt@amd.com{
3137816Ssteve.reinhardt@amd.com    if (mode == Execute)
3147816Ssteve.reinhardt@amd.com        return translateInst(req, tc);
3157816Ssteve.reinhardt@amd.com    else
3167816Ssteve.reinhardt@amd.com        return translateData(req, tc, mode == Write);
31711979Sgabeblack@google.com}
3187816Ssteve.reinhardt@amd.com
3197816Ssteve.reinhardt@amd.comvoid
3207816Ssteve.reinhardt@amd.comTLB::translateTiming(RequestPtr req, ThreadContext *tc,
3217816Ssteve.reinhardt@amd.com        Translation *translation, Mode mode)
3227756SAli.Saidi@ARM.com{
3237756SAli.Saidi@ARM.com    assert(translation);
3249227Sandreas.hansson@arm.com    translation->finish(translateAtomic(req, tc, mode), req, tc, mode);
3259227Sandreas.hansson@arm.com}
3269227Sandreas.hansson@arm.com
3279227Sandreas.hansson@arm.comFault
3289590Sandreas@sandberg.pp.seTLB::translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode)
3299590Sandreas@sandberg.pp.se{
3309590Sandreas@sandberg.pp.se    panic("Not implemented\n");
3319590Sandreas@sandberg.pp.se    return NoFault;
3329590Sandreas@sandberg.pp.se}
3339590Sandreas@sandberg.pp.se
3346654Snate@binkert.orgFault
3356654Snate@binkert.orgTLB::finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const
3365871Snate@binkert.org{
3376121Snate@binkert.org    return NoFault;
3388946Sandreas.hansson@arm.com}
3399419Sandreas.hansson@arm.com
34012563Sgabeblack@google.com
3413918Ssaidi@eecs.umich.eduMipsISA::PTE &
3423918Ssaidi@eecs.umich.eduTLB::index(bool advance)
3431858SN/A{
3449556Sandreas.hansson@arm.com    PTE *pte = &table[nlu];
3459556Sandreas.hansson@arm.com
3469556Sandreas.hansson@arm.com    if (advance)
3479556Sandreas.hansson@arm.com        nextnlu();
34811294Sandreas.hansson@arm.com
34911294Sandreas.hansson@arm.com    return *pte;
35011294Sandreas.hansson@arm.com}
35111294Sandreas.hansson@arm.com
35210878Sandreas.hansson@arm.comMipsISA::TLB *
35310878Sandreas.hansson@arm.comMipsTLBParams::create()
35411811Sbaz21@cam.ac.uk{
35511811Sbaz21@cam.ac.uk    return new TLB(this);
35611811Sbaz21@cam.ac.uk}
35711982Sgabeblack@google.com