tlb.cc

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· CC 代码 · 共 633 行 · 第 1/2 页

CC
633
字号
/* * Copyright (c) 2001, 2002, 2003, 2004, 2005 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. * * Authors: Nathan L. Binkert *          Steven K. Reinhardt *          Andrew L. Schultz */#include <string>#include <vector>#include "arch/alpha/pagetable.hh"#include "arch/alpha/tlb.hh"#include "arch/alpha/faults.hh"#include "base/inifile.hh"#include "base/str.hh"#include "base/trace.hh"#include "config/alpha_tlaser.hh"#include "cpu/thread_context.hh"using namespace std;using namespace EV5;namespace AlphaISA {///////////////////////////////////////////////////////////////////////////  Alpha TLB//#ifdef DEBUGbool uncacheBit39 = false;bool uncacheBit40 = false;#endif#define MODE2MASK(X)			(1 << (X))TLB::TLB(const Params *p)    : BaseTLB(p), size(p->size), nlu(0){    table = new TlbEntry[size];    memset(table, 0, sizeof(TlbEntry[size]));    flushCache();}TLB::~TLB(){    if (table)        delete [] table;}// look up an entry in the TLBTlbEntry *TLB::lookup(Addr vpn, uint8_t asn){    // assume not found...    TlbEntry *retval = NULL;    if (EntryCache[0]) {        if (vpn == EntryCache[0]->tag &&            (EntryCache[0]->asma || EntryCache[0]->asn == asn))            retval = EntryCache[0];        else if (EntryCache[1]) {            if (vpn == EntryCache[1]->tag &&                (EntryCache[1]->asma || EntryCache[1]->asn == asn))                retval = EntryCache[1];            else if (EntryCache[2] && vpn == EntryCache[2]->tag &&                     (EntryCache[2]->asma || EntryCache[2]->asn == asn))                retval = EntryCache[2];        }    }    if (retval == NULL) {        PageTable::const_iterator i = lookupTable.find(vpn);        if (i != lookupTable.end()) {            while (i->first == vpn) {                int index = i->second;                TlbEntry *entry = &table[index];                assert(entry->valid);                if (vpn == entry->tag && (entry->asma || entry->asn == asn)) {                    retval = updateCache(entry);                    break;                }                ++i;            }        }    }    DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn,            retval ? "hit" : "miss", retval ? retval->ppn : 0);    return retval;}FaultTLB::checkCacheability(RequestPtr &req){// in Alpha, cacheability is controlled by upper-level bits of the// physical address/* * We support having the uncacheable bit in either bit 39 or bit 40. * The Turbolaser platform (and EV5) support having the bit in 39, but * Tsunami (which Linux assumes uses an EV6) generates accesses with * the bit in 40.  So we must check for both, but we have debug flags * to catch a weird case where both are used, which shouldn't happen. */#if ALPHA_TLASER    if (req->getPaddr() & PAddrUncachedBit39)#else    if (req->getPaddr() & PAddrUncachedBit43)#endif    {        // IPR memory space not implemented        if (PAddrIprSpace(req->getPaddr())) {            return new UnimpFault("IPR memory space not implemented!");        } else {            // mark request as uncacheable            req->setFlags(req->getFlags() | UNCACHEABLE);#if !ALPHA_TLASER            // Clear bits 42:35 of the physical address (10-2 in Tsunami manual)            req->setPaddr(req->getPaddr() & PAddrUncachedMask);#endif        }    }    return NoFault;}// insert a new TLB entryvoidTLB::insert(Addr addr, TlbEntry &entry){    flushCache();    VAddr vaddr = addr;    if (table[nlu].valid) {        Addr oldvpn = table[nlu].tag;        PageTable::iterator i = lookupTable.find(oldvpn);        if (i == lookupTable.end())            panic("TLB entry not found in lookupTable");        int index;        while ((index = i->second) != nlu) {            if (table[index].tag != oldvpn)                panic("TLB entry not found in lookupTable");            ++i;        }        DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn);        lookupTable.erase(i);    }    DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), entry.ppn);    table[nlu] = entry;    table[nlu].tag = vaddr.vpn();    table[nlu].valid = true;    lookupTable.insert(make_pair(vaddr.vpn(), nlu));    nextnlu();}voidTLB::flushAll(){    DPRINTF(TLB, "flushAll\n");    memset(table, 0, sizeof(TlbEntry[size]));    flushCache();    lookupTable.clear();    nlu = 0;}voidTLB::flushProcesses(){    flushCache();    PageTable::iterator i = lookupTable.begin();    PageTable::iterator end = lookupTable.end();    while (i != end) {        int index = i->second;        TlbEntry *entry = &table[index];        assert(entry->valid);        // we can't increment i after we erase it, so save a copy and        // increment it to get the next entry now        PageTable::iterator cur = i;        ++i;        if (!entry->asma) {            DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, entry->tag, entry->ppn);            entry->valid = false;            lookupTable.erase(cur);        }    }}voidTLB::flushAddr(Addr addr, uint8_t asn){    flushCache();    VAddr vaddr = addr;    PageTable::iterator i = lookupTable.find(vaddr.vpn());    if (i == lookupTable.end())        return;    while (i != lookupTable.end() && i->first == vaddr.vpn()) {        int index = i->second;        TlbEntry *entry = &table[index];        assert(entry->valid);        if (vaddr.vpn() == entry->tag && (entry->asma || entry->asn == asn)) {            DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vaddr.vpn(),                    entry->ppn);            // invalidate this entry            entry->valid = false;            lookupTable.erase(i++);        } else {            ++i;        }    }}voidTLB::serialize(ostream &os){    SERIALIZE_SCALAR(size);    SERIALIZE_SCALAR(nlu);    for (int i = 0; i < size; i++) {        nameOut(os, csprintf("%s.Entry%d", name(), i));        table[i].serialize(os);    }}voidTLB::unserialize(Checkpoint *cp, const string &section){    UNSERIALIZE_SCALAR(size);    UNSERIALIZE_SCALAR(nlu);    for (int i = 0; i < size; i++) {        table[i].unserialize(cp, csprintf("%s.Entry%d", section, i));        if (table[i].valid) {            lookupTable.insert(make_pair(table[i].tag, i));        }    }}///////////////////////////////////////////////////////////////////////////  Alpha ITB//ITB::ITB(const Params *p)    : TLB(p){}voidITB::regStats(){    hits        .name(name() + ".hits")        .desc("ITB hits");    misses        .name(name() + ".misses")        .desc("ITB misses");    acv        .name(name() + ".acv")        .desc("ITB acv");    accesses        .name(name() + ".accesses")        .desc("ITB accesses");    accesses = hits + misses;}FaultITB::translate(RequestPtr &req, ThreadContext *tc){    //If this is a pal pc, then set PHYSICAL    if(FULL_SYSTEM && PcPAL(req->getPC()))        req->setFlags(req->getFlags() | PHYSICAL);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?