tlb.cc revision 2984:797622d7b311
18706Sandreas.hansson@arm.com/*
27586SAli.Saidi@arm.com * Copyright (c) 2001-2005 The Regents of The University of Michigan
37586SAli.Saidi@arm.com * All rights reserved.
47586SAli.Saidi@arm.com *
57586SAli.Saidi@arm.com * Redistribution and use in source and binary forms, with or without
67586SAli.Saidi@arm.com * modification, are permitted provided that the following conditions are
77586SAli.Saidi@arm.com * met: redistributions of source code must retain the above copyright
87586SAli.Saidi@arm.com * notice, this list of conditions and the following disclaimer;
97586SAli.Saidi@arm.com * redistributions in binary form must reproduce the above copyright
107586SAli.Saidi@arm.com * notice, this list of conditions and the following disclaimer in the
117586SAli.Saidi@arm.com * documentation and/or other materials provided with the distribution;
127586SAli.Saidi@arm.com * neither the name of the copyright holders nor the names of its
137905SBrad.Beckmann@amd.com * contributors may be used to endorse or promote products derived from
145323Sgblack@eecs.umich.edu * this software without specific prior written permission.
152934Sktlim@umich.edu *
162934Sktlim@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172934Sktlim@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182934Sktlim@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192934Sktlim@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202934Sktlim@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212934Sktlim@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222934Sktlim@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232934Sktlim@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242934Sktlim@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252934Sktlim@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262934Sktlim@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272934Sktlim@umich.edu *
282934Sktlim@umich.edu * Authors: Nathan Binkert
292934Sktlim@umich.edu *          Steve Reinhardt
302934Sktlim@umich.edu *          Andrew Schultz
312934Sktlim@umich.edu */
322934Sktlim@umich.edu
332934Sktlim@umich.edu#include <string>
342934Sktlim@umich.edu#include <vector>
352934Sktlim@umich.edu
362934Sktlim@umich.edu#include "arch/alpha/pagetable.hh"
372934Sktlim@umich.edu#include "arch/alpha/tlb.hh"
382934Sktlim@umich.edu#include "arch/alpha/faults.hh"
392934Sktlim@umich.edu#include "base/inifile.hh"
402934Sktlim@umich.edu#include "base/str.hh"
412934Sktlim@umich.edu#include "base/trace.hh"
422934Sktlim@umich.edu#include "config/alpha_tlaser.hh"
432995Ssaidi@eecs.umich.edu#include "cpu/thread_context.hh"
4410046Snilay@cs.wisc.edu#include "sim/builder.hh"
452934Sktlim@umich.edu
462934Sktlim@umich.eduusing namespace std;
472934Sktlim@umich.eduusing namespace EV5;
482934Sktlim@umich.edu
492934Sktlim@umich.edu///////////////////////////////////////////////////////////////////////
502934Sktlim@umich.edu//
512934Sktlim@umich.edu//  Alpha TLB
522934Sktlim@umich.edu//
5310720Sandreas.hansson@arm.com#ifdef DEBUG
546122SSteve.Reinhardt@amd.combool uncacheBit39 = false;
556122SSteve.Reinhardt@amd.combool uncacheBit40 = false;
566122SSteve.Reinhardt@amd.com#endif
576122SSteve.Reinhardt@amd.com
5810594Sgabeblack@google.com#define MODE2MASK(X)			(1 << (X))
5910594Sgabeblack@google.com
6010697SCurtis.Dunham@arm.comAlphaTLB::AlphaTLB(const string &name, int s)
6110594Sgabeblack@google.com    : SimObject(name), size(s), nlu(0)
6210594Sgabeblack@google.com{
6310594Sgabeblack@google.com    table = new AlphaISA::PTE[size];
6410594Sgabeblack@google.com    memset(table, 0, sizeof(AlphaISA::PTE[size]));
6510594Sgabeblack@google.com}
6610118Snilay@cs.wisc.edu
674520Ssaidi@eecs.umich.eduAlphaTLB::~AlphaTLB()
684982Ssaidi@eecs.umich.edu{
694520Ssaidi@eecs.umich.edu    if (table)
704520Ssaidi@eecs.umich.edu        delete [] table;
712934Sktlim@umich.edu}
722934Sktlim@umich.edu
733005Sstever@eecs.umich.edu// look up an entry in the TLB
743005Sstever@eecs.umich.eduAlphaISA::PTE *
753304Sstever@eecs.umich.eduAlphaTLB::lookup(Addr vpn, uint8_t asn) const
762995Ssaidi@eecs.umich.edu{
7710118Snilay@cs.wisc.edu    // assume not found...
7810118Snilay@cs.wisc.edu    AlphaISA::PTE *retval = NULL;
7910118Snilay@cs.wisc.edu
8010118Snilay@cs.wisc.edu    PageTable::const_iterator i = lookupTable.find(vpn);
8110720Sandreas.hansson@arm.com    if (i != lookupTable.end()) {
8210118Snilay@cs.wisc.edu        while (i->first == vpn) {
8310118Snilay@cs.wisc.edu            int index = i->second;
8410118Snilay@cs.wisc.edu            AlphaISA::PTE *pte = &table[index];
8510118Snilay@cs.wisc.edu            assert(pte->valid);
8610118Snilay@cs.wisc.edu            if (vpn == pte->tag && (pte->asma || pte->asn == asn)) {
8710118Snilay@cs.wisc.edu                retval = pte;
8810118Snilay@cs.wisc.edu                break;
8910118Snilay@cs.wisc.edu            }
9010118Snilay@cs.wisc.edu
9110118Snilay@cs.wisc.edu            ++i;
9210118Snilay@cs.wisc.edu        }
9310118Snilay@cs.wisc.edu    }
9410118Snilay@cs.wisc.edu
9510118Snilay@cs.wisc.edu    DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn,
9610118Snilay@cs.wisc.edu            retval ? "hit" : "miss", retval ? retval->ppn : 0);
9710118Snilay@cs.wisc.edu    return retval;
9810118Snilay@cs.wisc.edu}
9910118Snilay@cs.wisc.edu
10010118Snilay@cs.wisc.edu
1018713Sandreas.hansson@arm.comFault
10210118Snilay@cs.wisc.eduAlphaTLB::checkCacheability(RequestPtr &req)
10310118Snilay@cs.wisc.edu{
10410118Snilay@cs.wisc.edu    // in Alpha, cacheability is controlled by upper-level bits of the
10510118Snilay@cs.wisc.edu    // physical address
10610118Snilay@cs.wisc.edu
10710118Snilay@cs.wisc.edu    /*
10810118Snilay@cs.wisc.edu     * We support having the uncacheable bit in either bit 39 or bit 40.
10910118Snilay@cs.wisc.edu     * The Turbolaser platform (and EV5) support having the bit in 39, but
1109826Sandreas.hansson@arm.com     * Tsunami (which Linux assumes uses an EV6) generates accesses with
1112934Sktlim@umich.edu     * the bit in 40.  So we must check for both, but we have debug flags
1122934Sktlim@umich.edu     * to catch a weird case where both are used, which shouldn't happen.
1132995Ssaidi@eecs.umich.edu     */
1142934Sktlim@umich.edu
1156765SBrad.Beckmann@amd.com
1166765SBrad.Beckmann@amd.com#if ALPHA_TLASER
1176765SBrad.Beckmann@amd.com    if (req->getPaddr() & PAddrUncachedBit39) {
1186765SBrad.Beckmann@amd.com#else
1196765SBrad.Beckmann@amd.com    if (req->getPaddr() & PAddrUncachedBit43) {
1206765SBrad.Beckmann@amd.com#endif
1216765SBrad.Beckmann@amd.com        // IPR memory space not implemented
1226765SBrad.Beckmann@amd.com        if (PAddrIprSpace(req->getPaddr())) {
12310594Sgabeblack@google.com            return new UnimpFault("IPR memory space not implemented!");
12410594Sgabeblack@google.com        } else {
12510594Sgabeblack@google.com            // mark request as uncacheable
1266765SBrad.Beckmann@amd.com            req->setFlags(req->getFlags() | UNCACHEABLE);
1276765SBrad.Beckmann@amd.com
1286765SBrad.Beckmann@amd.com#if !ALPHA_TLASER
12910588Sgabeblack@google.com            // Clear bits 42:35 of the physical address (10-2 in Tsunami manual)
1308713Sandreas.hansson@arm.com            req->setPaddr(req->getPaddr() & PAddrUncachedMask);
1318713Sandreas.hansson@arm.com#endif
1328713Sandreas.hansson@arm.com        }
1338713Sandreas.hansson@arm.com    }
1344486Sbinkertn@umich.edu    return NoFault;
1354486Sbinkertn@umich.edu}
1364486Sbinkertn@umich.edu
1374486Sbinkertn@umich.edu
1384486Sbinkertn@umich.edu// insert a new TLB entry
1394486Sbinkertn@umich.eduvoid
1404486Sbinkertn@umich.eduAlphaTLB::insert(Addr addr, AlphaISA::PTE &pte)
1413584Ssaidi@eecs.umich.edu{
1423584Ssaidi@eecs.umich.edu    AlphaISA::VAddr vaddr = addr;
1433584Ssaidi@eecs.umich.edu    if (table[nlu].valid) {
1443584Ssaidi@eecs.umich.edu        Addr oldvpn = table[nlu].tag;
1453584Ssaidi@eecs.umich.edu        PageTable::iterator i = lookupTable.find(oldvpn);
14610720Sandreas.hansson@arm.com
1479036Sandreas.hansson@arm.com        if (i == lookupTable.end())
1489164Sandreas.hansson@arm.com            panic("TLB entry not found in lookupTable");
1493743Sgblack@eecs.umich.edu
1504104Ssaidi@eecs.umich.edu        int index;
1513743Sgblack@eecs.umich.edu        while ((index = i->second) != nlu) {
1529826Sandreas.hansson@arm.com            if (table[index].tag != oldvpn)
1539826Sandreas.hansson@arm.com                panic("TLB entry not found in lookupTable");
1548839Sandreas.hansson@arm.com
1558839Sandreas.hansson@arm.com            ++i;
1568839Sandreas.hansson@arm.com        }
1578839Sandreas.hansson@arm.com
1588839Sandreas.hansson@arm.com        DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn);
1598839Sandreas.hansson@arm.com
1603584Ssaidi@eecs.umich.edu        lookupTable.erase(i);
1613898Ssaidi@eecs.umich.edu    }
1623898Ssaidi@eecs.umich.edu
1638839Sandreas.hansson@arm.com    DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), pte.ppn);
1648713Sandreas.hansson@arm.com
1658713Sandreas.hansson@arm.com    table[nlu] = pte;
1668713Sandreas.hansson@arm.com    table[nlu].tag = vaddr.vpn();
1678713Sandreas.hansson@arm.com    table[nlu].valid = true;
1688713Sandreas.hansson@arm.com
1698713Sandreas.hansson@arm.com    lookupTable.insert(make_pair(vaddr.vpn(), nlu));
1708713Sandreas.hansson@arm.com    nextnlu();
1718713Sandreas.hansson@arm.com}
1728713Sandreas.hansson@arm.com
1738713Sandreas.hansson@arm.comvoid
1748713Sandreas.hansson@arm.comAlphaTLB::flushAll()
1758713Sandreas.hansson@arm.com{
1768713Sandreas.hansson@arm.com    DPRINTF(TLB, "flushAll\n");
1778713Sandreas.hansson@arm.com    memset(table, 0, sizeof(AlphaISA::PTE[size]));
1788713Sandreas.hansson@arm.com    lookupTable.clear();
1798713Sandreas.hansson@arm.com    nlu = 0;
1808713Sandreas.hansson@arm.com}
1818713Sandreas.hansson@arm.com
1828713Sandreas.hansson@arm.comvoid
1834103Ssaidi@eecs.umich.eduAlphaTLB::flushProcesses()
1844103Ssaidi@eecs.umich.edu{
1854103Ssaidi@eecs.umich.edu    PageTable::iterator i = lookupTable.begin();
1863745Sgblack@eecs.umich.edu    PageTable::iterator end = lookupTable.end();
1873745Sgblack@eecs.umich.edu    while (i != end) {
1883745Sgblack@eecs.umich.edu        int index = i->second;
1893584Ssaidi@eecs.umich.edu        AlphaISA::PTE *pte = &table[index];
1908839Sandreas.hansson@arm.com        assert(pte->valid);
1918706Sandreas.hansson@arm.com
1923584Ssaidi@eecs.umich.edu        // we can't increment i after we erase it, so save a copy and
1933584Ssaidi@eecs.umich.edu        // increment it to get the next entry now
19410588Sgabeblack@google.com        PageTable::iterator cur = i;
19510594Sgabeblack@google.com        ++i;
1968061SAli.Saidi@ARM.com
1978061SAli.Saidi@ARM.com        if (!pte->asma) {
1987586SAli.Saidi@arm.com            DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn);
1997586SAli.Saidi@arm.com            pte->valid = false;
2007586SAli.Saidi@arm.com            lookupTable.erase(cur);
2017586SAli.Saidi@arm.com        }
2027586SAli.Saidi@arm.com    }
2037586SAli.Saidi@arm.com}
2047586SAli.Saidi@arm.com
2057586SAli.Saidi@arm.comvoid
2067586SAli.Saidi@arm.comAlphaTLB::flushAddr(Addr addr, uint8_t asn)
2077586SAli.Saidi@arm.com{
20810720Sandreas.hansson@arm.com    AlphaISA::VAddr vaddr = addr;
2099036Sandreas.hansson@arm.com
2107586SAli.Saidi@arm.com    PageTable::iterator i = lookupTable.find(vaddr.vpn());
2119164Sandreas.hansson@arm.com    if (i == lookupTable.end())
2128839Sandreas.hansson@arm.com        return;
2138839Sandreas.hansson@arm.com
2147586SAli.Saidi@arm.com    while (i->first == vaddr.vpn()) {
2157586SAli.Saidi@arm.com        int index = i->second;
2167586SAli.Saidi@arm.com        AlphaISA::PTE *pte = &table[index];
2177586SAli.Saidi@arm.com        assert(pte->valid);
2187586SAli.Saidi@arm.com
2197586SAli.Saidi@arm.com        if (vaddr.vpn() == pte->tag && (pte->asma || pte->asn == asn)) {
2207586SAli.Saidi@arm.com            DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vaddr.vpn(),
2218870SAli.Saidi@ARM.com                    pte->ppn);
2228870SAli.Saidi@ARM.com
22310512SAli.Saidi@ARM.com            // invalidate this entry
22410512SAli.Saidi@ARM.com            pte->valid = false;
22510037SARM gem5 Developers
22610037SARM gem5 Developers            lookupTable.erase(i);
22710512SAli.Saidi@ARM.com        }
22810512SAli.Saidi@ARM.com
22910512SAli.Saidi@ARM.com        ++i;
23010512SAli.Saidi@ARM.com    }
23110512SAli.Saidi@ARM.com}
2327586SAli.Saidi@arm.com
2337586SAli.Saidi@arm.com
2347586SAli.Saidi@arm.comvoid
2357586SAli.Saidi@arm.comAlphaTLB::serialize(ostream &os)
2368528SAli.Saidi@ARM.com{
2378528SAli.Saidi@ARM.com    SERIALIZE_SCALAR(size);
23810353SGeoffrey.Blake@arm.com    SERIALIZE_SCALAR(nlu);
23910353SGeoffrey.Blake@arm.com
24010353SGeoffrey.Blake@arm.com    for (int i = 0; i < size; i++) {
2418528SAli.Saidi@ARM.com        nameOut(os, csprintf("%s.PTE%d", name(), i));
24210357SAli.Saidi@ARM.com        table[i].serialize(os);
24310357SAli.Saidi@ARM.com    }
24410357SAli.Saidi@ARM.com}
2458528SAli.Saidi@ARM.com
2468528SAli.Saidi@ARM.comvoid
24710507SAli.Saidi@ARM.comAlphaTLB::unserialize(Checkpoint *cp, const string &section)
24810507SAli.Saidi@ARM.com{
24910507SAli.Saidi@ARM.com    UNSERIALIZE_SCALAR(size);
25010507SAli.Saidi@ARM.com    UNSERIALIZE_SCALAR(nlu);
25110507SAli.Saidi@ARM.com
25210507SAli.Saidi@ARM.com    for (int i = 0; i < size; i++) {
25310507SAli.Saidi@ARM.com        table[i].unserialize(cp, csprintf("%s.PTE%d", section, i));
25410507SAli.Saidi@ARM.com        if (table[i].valid) {
25510507SAli.Saidi@ARM.com            lookupTable.insert(make_pair(table[i].tag, i));
25610507SAli.Saidi@ARM.com        }
25710507SAli.Saidi@ARM.com    }
25810507SAli.Saidi@ARM.com}
25910507SAli.Saidi@ARM.com
26010507SAli.Saidi@ARM.com
26110507SAli.Saidi@ARM.com///////////////////////////////////////////////////////////////////////
26210507SAli.Saidi@ARM.com//
26310507SAli.Saidi@ARM.com//  Alpha ITB
26410507SAli.Saidi@ARM.com//
2658061SAli.Saidi@ARM.comAlphaITB::AlphaITB(const std::string &name, int size)
2668061SAli.Saidi@ARM.com    : AlphaTLB(name, size)
2678061SAli.Saidi@ARM.com{}
2688061SAli.Saidi@ARM.com
26910161Satgutier@umich.edu
27010512SAli.Saidi@ARM.comvoid
27110161Satgutier@umich.eduAlphaITB::regStats()
27210512SAli.Saidi@ARM.com{
27310161Satgutier@umich.edu    hits
27410161Satgutier@umich.edu        .name(name() + ".hits")
27510161Satgutier@umich.edu        .desc("ITB hits");
2769929SAli.Saidi@ARM.com    misses
2779929SAli.Saidi@ARM.com        .name(name() + ".misses")
2787586SAli.Saidi@arm.com        .desc("ITB misses");
27910071Satgutier@umich.edu    acv
28010594Sgabeblack@google.com        .name(name() + ".acv")
28110594Sgabeblack@google.com        .desc("ITB acv");
28210594Sgabeblack@google.com    accesses
28310697SCurtis.Dunham@arm.com        .name(name() + ".accesses")
28410071Satgutier@umich.edu        .desc("ITB accesses");
2858870SAli.Saidi@ARM.com
2868528SAli.Saidi@ARM.com    accesses = hits + misses;
2878528SAli.Saidi@ARM.com}
2888287SAli.Saidi@ARM.com
28910735Srb639@drexel.edu
29010735Srb639@drexel.eduFault
29110735Srb639@drexel.eduAlphaITB::translate(RequestPtr &req, ThreadContext *tc) const
29210667Smalek.musleh@gmail.com{
29310594Sgabeblack@google.com    if (AlphaISA::PcPAL(req->getVaddr())) {
2948713Sandreas.hansson@arm.com        // strip off PAL PC marker (lsb is 1)
2957586SAli.Saidi@arm.com        req->setPaddr((req->getVaddr() & ~3) & PAddrImplMask);
2967586SAli.Saidi@arm.com        hits++;
2977586SAli.Saidi@arm.com        return NoFault;
2987949SAli.Saidi@ARM.com    }
2997586SAli.Saidi@arm.com
3008839Sandreas.hansson@arm.com    if (req->getFlags() & PHYSICAL) {
3018706Sandreas.hansson@arm.com        req->setPaddr(req->getVaddr());
3027586SAli.Saidi@arm.com    } else {
3037586SAli.Saidi@arm.com        // verify that this is a good virtual address
3047586SAli.Saidi@arm.com        if (!validVirtualAddress(req->getVaddr())) {
30510594Sgabeblack@google.com            acv++;
3065222Sksewell@umich.edu            return new ItbAcvFault(req->getVaddr());
3075222Sksewell@umich.edu        }
3085222Sksewell@umich.edu
3095222Sksewell@umich.edu
3105222Sksewell@umich.edu        // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13> for EV5
3115222Sksewell@umich.edu        // VA<47:41> == 0x7e, VA<40:13> maps directly to PA<40:13> for EV6
3125222Sksewell@umich.edu#if ALPHA_TLASER
3135222Sksewell@umich.edu        if ((MCSR_SP(tc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) &&
3145222Sksewell@umich.edu            VAddrSpaceEV5(req->getVaddr()) == 2) {
3155222Sksewell@umich.edu#else
31610720Sandreas.hansson@arm.com        if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) {
3179036Sandreas.hansson@arm.com#endif
3189164Sandreas.hansson@arm.com            // only valid in kernel mode
3199826Sandreas.hansson@arm.com            if (ICM_CM(tc->readMiscReg(AlphaISA::IPR_ICM)) !=
3208839Sandreas.hansson@arm.com                AlphaISA::mode_kernel) {
3218839Sandreas.hansson@arm.com                acv++;
3225222Sksewell@umich.edu                return new ItbAcvFault(req->getVaddr());
3235222Sksewell@umich.edu            }
3245222Sksewell@umich.edu
3255222Sksewell@umich.edu            req->setPaddr(req->getVaddr() & PAddrImplMask);
3265222Sksewell@umich.edu
3275222Sksewell@umich.edu#if !ALPHA_TLASER
3288839Sandreas.hansson@arm.com            // sign extend the physical address properly
3298839Sandreas.hansson@arm.com            if (req->getPaddr() & PAddrUncachedBit40)
3308839Sandreas.hansson@arm.com                req->setPaddr(req->getPaddr() | ULL(0xf0000000000));
3318839Sandreas.hansson@arm.com            else
3328839Sandreas.hansson@arm.com                req->setPaddr(req->getPaddr() & ULL(0xffffffffff));
3338839Sandreas.hansson@arm.com#endif
3345222Sksewell@umich.edu
3355222Sksewell@umich.edu        } else {
3365222Sksewell@umich.edu            // not a physical address: need to look up pte
3375222Sksewell@umich.edu            int asn = DTB_ASN_ASN(tc->readMiscReg(AlphaISA::IPR_DTB_ASN));
3385478Snate@binkert.org            AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->getVaddr()).vpn(),
3395222Sksewell@umich.edu                                        asn);
3405222Sksewell@umich.edu
34110594Sgabeblack@google.com            if (!pte) {
34210594Sgabeblack@google.com                misses++;
34310594Sgabeblack@google.com                return new ItbPageFault(req->getVaddr());
3445222Sksewell@umich.edu            }
3458839Sandreas.hansson@arm.com
3468706Sandreas.hansson@arm.com            req->setPaddr((pte->ppn << AlphaISA::PageShift) +
3475222Sksewell@umich.edu                          (AlphaISA::VAddr(req->getVaddr()).offset()
3485222Sksewell@umich.edu                           & ~3));
3495323Sgblack@eecs.umich.edu
3505357Sgblack@eecs.umich.edu            // check permissions for this access
3518323Ssteve.reinhardt@amd.com            if (!(pte->xre &
3525323Sgblack@eecs.umich.edu                  (1 << ICM_CM(tc->readMiscReg(AlphaISA::IPR_ICM))))) {
3538858Sgblack@eecs.umich.edu                // instruction access fault
3548713Sandreas.hansson@arm.com                acv++;
3558713Sandreas.hansson@arm.com                return new ItbAcvFault(req->getVaddr());
3568713Sandreas.hansson@arm.com            }
3578713Sandreas.hansson@arm.com
3588713Sandreas.hansson@arm.com            hits++;
3598713Sandreas.hansson@arm.com        }
3609036Sandreas.hansson@arm.com    }
3617905SBrad.Beckmann@amd.com
3627905SBrad.Beckmann@amd.com    // check that the physical address is ok (catch bad physical addresses)
36310720Sandreas.hansson@arm.com    if (req->getPaddr() & ~PAddrImplMask)
3649164Sandreas.hansson@arm.com        return genMachineCheckFault();
3658839Sandreas.hansson@arm.com
3668839Sandreas.hansson@arm.com    return checkCacheability(req);
36710438Smajiuyue@ncic.ac.cn
36810438Smajiuyue@ncic.ac.cn}
36910438Smajiuyue@ncic.ac.cn
37010438Smajiuyue@ncic.ac.cn///////////////////////////////////////////////////////////////////////
37110438Smajiuyue@ncic.ac.cn//
37210438Smajiuyue@ncic.ac.cn//  Alpha DTB
3738713Sandreas.hansson@arm.com//
3748713Sandreas.hansson@arm.comAlphaDTB::AlphaDTB(const std::string &name, int size)
37510438Smajiuyue@ncic.ac.cn    : AlphaTLB(name, size)
3768713Sandreas.hansson@arm.com{}
3778713Sandreas.hansson@arm.com
3788713Sandreas.hansson@arm.comvoid
3798713Sandreas.hansson@arm.comAlphaDTB::regStats()
3808713Sandreas.hansson@arm.com{
3818713Sandreas.hansson@arm.com    read_hits
3828713Sandreas.hansson@arm.com        .name(name() + ".read_hits")
3838713Sandreas.hansson@arm.com        .desc("DTB read hits")
3849164Sandreas.hansson@arm.com        ;
3858839Sandreas.hansson@arm.com
3868839Sandreas.hansson@arm.com    read_misses
3878815Sgblack@eecs.umich.edu        .name(name() + ".read_misses")
3888815Sgblack@eecs.umich.edu        .desc("DTB read misses")
3898858Sgblack@eecs.umich.edu        ;
3908858Sgblack@eecs.umich.edu
3917905SBrad.Beckmann@amd.com    read_acv
3927905SBrad.Beckmann@amd.com        .name(name() + ".read_acv")
3937905SBrad.Beckmann@amd.com        .desc("DTB read access violations")
3947905SBrad.Beckmann@amd.com        ;
3958839Sandreas.hansson@arm.com
3968706Sandreas.hansson@arm.com    read_accesses
3977905SBrad.Beckmann@amd.com        .name(name() + ".read_accesses")
3987905SBrad.Beckmann@amd.com        .desc("DTB read accesses")
39910720Sandreas.hansson@arm.com        ;
4007905SBrad.Beckmann@amd.com
4018929Snilay@cs.wisc.edu    write_hits
4028929Snilay@cs.wisc.edu        .name(name() + ".write_hits")
4038929Snilay@cs.wisc.edu        .desc("DTB write hits")
40410118Snilay@cs.wisc.edu        ;
4057905SBrad.Beckmann@amd.com
4067905SBrad.Beckmann@amd.com    write_misses
40710588Sgabeblack@google.com        .name(name() + ".write_misses")
4085613Sgblack@eecs.umich.edu        .desc("DTB write misses")
4095613Sgblack@eecs.umich.edu        ;
4105613Sgblack@eecs.umich.edu
4115133Sgblack@eecs.umich.edu    write_acv
4125133Sgblack@eecs.umich.edu        .name(name() + ".write_acv")
4135133Sgblack@eecs.umich.edu        .desc("DTB write access violations")
4145133Sgblack@eecs.umich.edu        ;
4155133Sgblack@eecs.umich.edu
4166802Sgblack@eecs.umich.edu    write_accesses
4176802Sgblack@eecs.umich.edu        .name(name() + ".write_accesses")
4185133Sgblack@eecs.umich.edu        .desc("DTB write accesses")
41910041Snilay@cs.wisc.edu        ;
42010041Snilay@cs.wisc.edu
42110041Snilay@cs.wisc.edu    hits
42210041Snilay@cs.wisc.edu        .name(name() + ".hits")
42310041Snilay@cs.wisc.edu        .desc("DTB hits")
42410041Snilay@cs.wisc.edu        ;
42510041Snilay@cs.wisc.edu
42610041Snilay@cs.wisc.edu    misses
42710046Snilay@cs.wisc.edu        .name(name() + ".misses")
42810046Snilay@cs.wisc.edu        .desc("DTB misses")
42910046Snilay@cs.wisc.edu        ;
43010046Snilay@cs.wisc.edu
43110041Snilay@cs.wisc.edu    acv
43210041Snilay@cs.wisc.edu        .name(name() + ".acv")
4335613Sgblack@eecs.umich.edu        .desc("DTB access violations")
4345613Sgblack@eecs.umich.edu        ;
4355638Sgblack@eecs.umich.edu
4367905SBrad.Beckmann@amd.com    accesses
4377905SBrad.Beckmann@amd.com        .name(name() + ".accesses")
4387905SBrad.Beckmann@amd.com        .desc("DTB accesses")
4397905SBrad.Beckmann@amd.com        ;
4407905SBrad.Beckmann@amd.com
4418858Sgblack@eecs.umich.edu    hits = read_hits + write_hits;
4425613Sgblack@eecs.umich.edu    misses = read_misses + write_misses;
4435613Sgblack@eecs.umich.edu    acv = read_acv + write_acv;
4445613Sgblack@eecs.umich.edu    accesses = read_accesses + write_accesses;
4455841Sgblack@eecs.umich.edu}
4465841Sgblack@eecs.umich.edu
4475841Sgblack@eecs.umich.eduFault
4485841Sgblack@eecs.umich.eduAlphaDTB::translate(RequestPtr &req, ThreadContext *tc, bool write) const
4495841Sgblack@eecs.umich.edu{
4505841Sgblack@eecs.umich.edu    Addr pc = tc->readPC();
4515841Sgblack@eecs.umich.edu
4525615Sgblack@eecs.umich.edu    AlphaISA::mode_type mode =
4535615Sgblack@eecs.umich.edu        (AlphaISA::mode_type)DTB_CM_CM(tc->readMiscReg(AlphaISA::IPR_DTB_CM));
4545615Sgblack@eecs.umich.edu
4555615Sgblack@eecs.umich.edu
4565641Sgblack@eecs.umich.edu    /**
4578323Ssteve.reinhardt@amd.com     * Check for alignment faults
4588323Ssteve.reinhardt@amd.com     */
4596135Sgblack@eecs.umich.edu    if (req->getVaddr() & (req->getSize() - 1)) {
4606135Sgblack@eecs.umich.edu        DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(),
4616135Sgblack@eecs.umich.edu                req->getSize());
4626135Sgblack@eecs.umich.edu        uint64_t flags = write ? MM_STAT_WR_MASK : 0;
4636135Sgblack@eecs.umich.edu        return new DtbAlignmentFault(req->getVaddr(), req->getFlags(), flags);
4646135Sgblack@eecs.umich.edu    }
4658323Ssteve.reinhardt@amd.com
4665644Sgblack@eecs.umich.edu    if (pc & 0x1) {
4676135Sgblack@eecs.umich.edu        mode = (req->getFlags() & ALTMODE) ?
4685644Sgblack@eecs.umich.edu            (AlphaISA::mode_type)ALT_MODE_AM(
4695644Sgblack@eecs.umich.edu                tc->readMiscReg(AlphaISA::IPR_ALT_MODE))
4705644Sgblack@eecs.umich.edu            : AlphaISA::mode_kernel;
4716135Sgblack@eecs.umich.edu    }
4728323Ssteve.reinhardt@amd.com
47310437Smajiuyue@ncic.ac.cn    if (req->getFlags() & PHYSICAL) {
47410437Smajiuyue@ncic.ac.cn        req->setPaddr(req->getVaddr());
47510437Smajiuyue@ncic.ac.cn    } else {
47610437Smajiuyue@ncic.ac.cn        // verify that this is a good virtual address
47710437Smajiuyue@ncic.ac.cn        if (!validVirtualAddress(req->getVaddr())) {
47810437Smajiuyue@ncic.ac.cn            if (write) { write_acv++; } else { read_acv++; }
4798323Ssteve.reinhardt@amd.com            uint64_t flags = (write ? MM_STAT_WR_MASK : 0) |
48010437Smajiuyue@ncic.ac.cn                MM_STAT_BAD_VA_MASK |
48110437Smajiuyue@ncic.ac.cn                MM_STAT_ACV_MASK;
4828323Ssteve.reinhardt@amd.com            return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
4835843Sgblack@eecs.umich.edu        }
4845843Sgblack@eecs.umich.edu
4855843Sgblack@eecs.umich.edu        // Check for "superpage" mapping
4865843Sgblack@eecs.umich.edu#if ALPHA_TLASER
48710437Smajiuyue@ncic.ac.cn        if ((MCSR_SP(tc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) &&
4885843Sgblack@eecs.umich.edu            VAddrSpaceEV5(req->getVaddr()) == 2) {
4896044Sgblack@eecs.umich.edu#else
4905843Sgblack@eecs.umich.edu        if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) {
4918323Ssteve.reinhardt@amd.com#endif
4926135Sgblack@eecs.umich.edu
4936135Sgblack@eecs.umich.edu            // only valid in kernel mode
4946135Sgblack@eecs.umich.edu            if (DTB_CM_CM(tc->readMiscReg(AlphaISA::IPR_DTB_CM)) !=
4956135Sgblack@eecs.umich.edu                AlphaISA::mode_kernel) {
4966135Sgblack@eecs.umich.edu                if (write) { write_acv++; } else { read_acv++; }
49710437Smajiuyue@ncic.ac.cn                uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) |
4986135Sgblack@eecs.umich.edu                                  MM_STAT_ACV_MASK);
4996135Sgblack@eecs.umich.edu                return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags);
5006135Sgblack@eecs.umich.edu            }
5018323Ssteve.reinhardt@amd.com
5026135Sgblack@eecs.umich.edu            req->setPaddr(req->getVaddr() & PAddrImplMask);
5036135Sgblack@eecs.umich.edu
5046135Sgblack@eecs.umich.edu#if !ALPHA_TLASER
5056135Sgblack@eecs.umich.edu            // sign extend the physical address properly
50610437Smajiuyue@ncic.ac.cn            if (req->getPaddr() & PAddrUncachedBit40)
5076135Sgblack@eecs.umich.edu                req->setPaddr(req->getPaddr() | ULL(0xf0000000000));
5086135Sgblack@eecs.umich.edu            else
5096135Sgblack@eecs.umich.edu                req->setPaddr(req->getPaddr() & ULL(0xffffffffff));
5108323Ssteve.reinhardt@amd.com#endif
5116135Sgblack@eecs.umich.edu
5126135Sgblack@eecs.umich.edu        } else {
5136135Sgblack@eecs.umich.edu            if (write)
5146135Sgblack@eecs.umich.edu                write_accesses++;
5158323Ssteve.reinhardt@amd.com            else
5168323Ssteve.reinhardt@amd.com                read_accesses++;
5175641Sgblack@eecs.umich.edu
51810594Sgabeblack@google.com            int asn = DTB_ASN_ASN(tc->readMiscReg(AlphaISA::IPR_DTB_ASN));
51910594Sgabeblack@google.com
5205613Sgblack@eecs.umich.edu            // not a physical address: need to look up pte
5215613Sgblack@eecs.umich.edu            AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->getVaddr()).vpn(),
5227905SBrad.Beckmann@amd.com                                        asn);
5239826Sandreas.hansson@arm.com
5245613Sgblack@eecs.umich.edu            if (!pte) {
5255450Sgblack@eecs.umich.edu                // page fault
5265450Sgblack@eecs.umich.edu                if (write) { write_misses++; } else { read_misses++; }
5279826Sandreas.hansson@arm.com                uint64_t flags = (write ? MM_STAT_WR_MASK : 0) |
5289232Sandreas.hansson@arm.com                    MM_STAT_DTB_MISS_MASK;
52910041Snilay@cs.wisc.edu                return (req->getFlags() & VPTE) ?
5305450Sgblack@eecs.umich.edu                    (Fault)(new PDtbMissFault(req->getVaddr(), req->getFlags(),
53110041Snilay@cs.wisc.edu                                              flags)) :
5328323Ssteve.reinhardt@amd.com                    (Fault)(new NDtbMissFault(req->getVaddr(), req->getFlags(),
5338323Ssteve.reinhardt@amd.com                                              flags));
5349622Snilay@cs.wisc.edu            }
5359622Snilay@cs.wisc.edu
53610041Snilay@cs.wisc.edu            req->setPaddr((pte->ppn << AlphaISA::PageShift) +
5378323Ssteve.reinhardt@amd.com                AlphaISA::VAddr(req->getVaddr()).offset());
53810041Snilay@cs.wisc.edu
5399898Sandreas@sandberg.pp.se            if (write) {
5408323Ssteve.reinhardt@amd.com                if (!(pte->xwe & MODE2MASK(mode))) {
5415450Sgblack@eecs.umich.edu                    // declare the instruction access fault
54210438Smajiuyue@ncic.ac.cn                    write_acv++;
54310438Smajiuyue@ncic.ac.cn                    uint64_t flags = MM_STAT_WR_MASK |
54410438Smajiuyue@ncic.ac.cn                        MM_STAT_ACV_MASK |
54510438Smajiuyue@ncic.ac.cn                        (pte->fonw ? MM_STAT_FONW_MASK : 0);
54610438Smajiuyue@ncic.ac.cn                    return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
54710438Smajiuyue@ncic.ac.cn                }
54810438Smajiuyue@ncic.ac.cn                if (pte->fonw) {
54910438Smajiuyue@ncic.ac.cn                    write_acv++;
55010438Smajiuyue@ncic.ac.cn                    uint64_t flags = MM_STAT_WR_MASK |
55110438Smajiuyue@ncic.ac.cn                        MM_STAT_FONW_MASK;
55210438Smajiuyue@ncic.ac.cn                    return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
55310041Snilay@cs.wisc.edu                }
55410041Snilay@cs.wisc.edu            } else {
55510041Snilay@cs.wisc.edu                if (!(pte->xre & MODE2MASK(mode))) {
55610041Snilay@cs.wisc.edu                    read_acv++;
55710041Snilay@cs.wisc.edu                    uint64_t flags = MM_STAT_ACV_MASK |
55810041Snilay@cs.wisc.edu                        (pte->fonr ? MM_STAT_FONR_MASK : 0);
55910041Snilay@cs.wisc.edu                    return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags);
56010041Snilay@cs.wisc.edu                }
56110041Snilay@cs.wisc.edu                if (pte->fonr) {
56210041Snilay@cs.wisc.edu                    read_acv++;
5635330Sgblack@eecs.umich.edu                    uint64_t flags = MM_STAT_FONR_MASK;
56410594Sgabeblack@google.com                    return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
56510594Sgabeblack@google.com                }
56610594Sgabeblack@google.com            }
56710003Ssteve.reinhardt@amd.com        }
5685133Sgblack@eecs.umich.edu
5695133Sgblack@eecs.umich.edu        if (write)
5703584Ssaidi@eecs.umich.edu            write_hits++;
5718801Sgblack@eecs.umich.edu        else
5728801Sgblack@eecs.umich.edu            read_hits++;
5732995Ssaidi@eecs.umich.edu    }
5742995Ssaidi@eecs.umich.edu
5754981Ssaidi@eecs.umich.edu    // check that the physical address is ok (catch bad physical addresses)
5764981Ssaidi@eecs.umich.edu    if (req->getPaddr() & ~PAddrImplMask)
5778661SAli.Saidi@ARM.com        return genMachineCheckFault();
5788661SAli.Saidi@ARM.com
5798661SAli.Saidi@ARM.com    return checkCacheability(req);
5808661SAli.Saidi@ARM.com}
5818661SAli.Saidi@ARM.com
5828661SAli.Saidi@ARM.comAlphaISA::PTE &
5838661SAli.Saidi@ARM.comAlphaTLB::index(bool advance)
5848661SAli.Saidi@ARM.com{
5858661SAli.Saidi@ARM.com    AlphaISA::PTE *pte = &table[nlu];
5863025Ssaidi@eecs.umich.edu
5873025Ssaidi@eecs.umich.edu    if (advance)
5883025Ssaidi@eecs.umich.edu        nextnlu();
5892934Sktlim@umich.edu
5902934Sktlim@umich.edu    return *pte;
591}
592
593DEFINE_SIM_OBJECT_CLASS_NAME("AlphaTLB", AlphaTLB)
594
595BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaITB)
596
597    Param<int> size;
598
599END_DECLARE_SIM_OBJECT_PARAMS(AlphaITB)
600
601BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaITB)
602
603    INIT_PARAM_DFLT(size, "TLB size", 48)
604
605END_INIT_SIM_OBJECT_PARAMS(AlphaITB)
606
607
608CREATE_SIM_OBJECT(AlphaITB)
609{
610    return new AlphaITB(getInstanceName(), size);
611}
612
613REGISTER_SIM_OBJECT("AlphaITB", AlphaITB)
614
615BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaDTB)
616
617    Param<int> size;
618
619END_DECLARE_SIM_OBJECT_PARAMS(AlphaDTB)
620
621BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaDTB)
622
623    INIT_PARAM_DFLT(size, "TLB size", 64)
624
625END_INIT_SIM_OBJECT_PARAMS(AlphaDTB)
626
627
628CREATE_SIM_OBJECT(AlphaDTB)
629{
630    return new AlphaDTB(getInstanceName(), size);
631}
632
633REGISTER_SIM_OBJECT("AlphaDTB", AlphaDTB)
634
635