tlb.cc revision 828
15409Sgblack@eecs.umich.edu/*
24519Sgblack@eecs.umich.edu * Copyright (c) 2003 The Regents of The University of Michigan
34519Sgblack@eecs.umich.edu * All rights reserved.
44519Sgblack@eecs.umich.edu *
54519Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
64519Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
74519Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
84519Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
94519Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
104519Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
114519Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
124519Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
134519Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
144519Sgblack@eecs.umich.edu * this software without specific prior written permission.
154519Sgblack@eecs.umich.edu *
164519Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
174519Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
184519Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
194519Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
204519Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
214519Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
224519Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
234519Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
244519Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
254519Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
264519Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
274519Sgblack@eecs.umich.edu */
284519Sgblack@eecs.umich.edu
294519Sgblack@eecs.umich.edu#include <sstream>
304519Sgblack@eecs.umich.edu#include <string>
314519Sgblack@eecs.umich.edu#include <vector>
324519Sgblack@eecs.umich.edu
334519Sgblack@eecs.umich.edu#include "base/inifile.hh"
344519Sgblack@eecs.umich.edu#include "base/str.hh"
354519Sgblack@eecs.umich.edu#include "base/trace.hh"
364519Sgblack@eecs.umich.edu#include "cpu/exec_context.hh"
374519Sgblack@eecs.umich.edu#include "sim/builder.hh"
384519Sgblack@eecs.umich.edu#include "targetarch/alpha_memory.hh"
394519Sgblack@eecs.umich.edu#include "targetarch/ev5.hh"
404519Sgblack@eecs.umich.edu
414519Sgblack@eecs.umich.eduusing namespace std;
424519Sgblack@eecs.umich.edu
434519Sgblack@eecs.umich.edu///////////////////////////////////////////////////////////////////////
444519Sgblack@eecs.umich.edu//
454519Sgblack@eecs.umich.edu//  Alpha TLB
464519Sgblack@eecs.umich.edu//
474519Sgblack@eecs.umich.edu
484519Sgblack@eecs.umich.edu#ifdef DEBUG
494519Sgblack@eecs.umich.edu    bool uncacheBit39 = false;
504519Sgblack@eecs.umich.edu    bool uncacheBit40 = false;
514519Sgblack@eecs.umich.edu#endif
524519Sgblack@eecs.umich.edu
534519Sgblack@eecs.umich.eduAlphaTlb::AlphaTlb(const string &name, int s)
544519Sgblack@eecs.umich.edu    : SimObject(name), size(s), nlu(0)
554519Sgblack@eecs.umich.edu{
564519Sgblack@eecs.umich.edu    table = new AlphaISA::PTE[size];
574519Sgblack@eecs.umich.edu    memset(table, 0, sizeof(AlphaISA::PTE[size]));
584519Sgblack@eecs.umich.edu}
594519Sgblack@eecs.umich.edu
604519Sgblack@eecs.umich.eduAlphaTlb::~AlphaTlb()
614519Sgblack@eecs.umich.edu{
624519Sgblack@eecs.umich.edu    if (table)
634519Sgblack@eecs.umich.edu        delete [] table;
644519Sgblack@eecs.umich.edu}
654519Sgblack@eecs.umich.edu
664519Sgblack@eecs.umich.edu// look up an entry in the TLB
674519Sgblack@eecs.umich.eduAlphaISA::PTE *
684809Sgblack@eecs.umich.eduAlphaTlb::lookup(Addr vpn, uint8_t asn) const
694519Sgblack@eecs.umich.edu{
704519Sgblack@eecs.umich.edu    DPRINTF(TLB, "lookup %#x\n", vpn);
714688Sgblack@eecs.umich.edu
724688Sgblack@eecs.umich.edu    PageTable::const_iterator i = lookupTable.find(vpn);
734688Sgblack@eecs.umich.edu    if (i == lookupTable.end())
744688Sgblack@eecs.umich.edu        return NULL;
754688Sgblack@eecs.umich.edu
764688Sgblack@eecs.umich.edu    while (i->first == vpn) {
774708Sgblack@eecs.umich.edu        int index = i->second;
784708Sgblack@eecs.umich.edu        AlphaISA::PTE *pte = &table[index];
794708Sgblack@eecs.umich.edu        assert(pte->valid);
804708Sgblack@eecs.umich.edu        if (vpn == pte->tag && (pte->asma || pte->asn == asn))
814519Sgblack@eecs.umich.edu            return pte;
824519Sgblack@eecs.umich.edu
834519Sgblack@eecs.umich.edu        ++i;
844519Sgblack@eecs.umich.edu    }
854519Sgblack@eecs.umich.edu
864519Sgblack@eecs.umich.edu    // not found...
874519Sgblack@eecs.umich.edu    return NULL;
884519Sgblack@eecs.umich.edu}
894519Sgblack@eecs.umich.edu
904519Sgblack@eecs.umich.edu
914519Sgblack@eecs.umich.eduvoid
924951Sgblack@eecs.umich.eduAlphaTlb::checkCacheability(MemReqPtr &req)
934519Sgblack@eecs.umich.edu{
944519Sgblack@eecs.umich.edu    // in Alpha, cacheability is controlled by upper-level bits of the
954519Sgblack@eecs.umich.edu    // physical address
964519Sgblack@eecs.umich.edu
974519Sgblack@eecs.umich.edu    /*
984519Sgblack@eecs.umich.edu     * We support having the uncacheable bit in either bit 39 or bit 40.
994688Sgblack@eecs.umich.edu     * The Turbolaser platform (and EV5) support having the bit in 39, but
1004688Sgblack@eecs.umich.edu     * Tsunami (which Linux assumes uses an EV6) generates accesses with
1014688Sgblack@eecs.umich.edu     * the bit in 40.  So we must check for both, but we have debug flags
1024688Sgblack@eecs.umich.edu     * to catch a weird case where both are used, which shouldn't happen.
1034688Sgblack@eecs.umich.edu     */
1044688Sgblack@eecs.umich.edu
1054708Sgblack@eecs.umich.edu    if (req->paddr & PA_UNCACHED_BIT_40 ||
1064708Sgblack@eecs.umich.edu        req->paddr & PA_UNCACHED_BIT_39) {
1074708Sgblack@eecs.umich.edu
1084708Sgblack@eecs.umich.edu#ifdef DEBUG
1094519Sgblack@eecs.umich.edu        if (req->paddr & PA_UNCACHED_BIT_40) {
1104519Sgblack@eecs.umich.edu            if(uncacheBit39)
1114519Sgblack@eecs.umich.edu                panic("Bit 40 access follows bit 39 access, PA=%x\n",
1124519Sgblack@eecs.umich.edu                      req->paddr);
1134519Sgblack@eecs.umich.edu
1144519Sgblack@eecs.umich.edu            uncacheBit40 = true;
1154519Sgblack@eecs.umich.edu        } else if (req->paddr & PA_UNCACHED_BIT_39) {
1164519Sgblack@eecs.umich.edu            if(uncacheBit40)
1174519Sgblack@eecs.umich.edu                panic("Bit 39 acceess follows bit 40 access, PA=%x\n",
1184519Sgblack@eecs.umich.edu                      req->paddr);
1194519Sgblack@eecs.umich.edu
1204519Sgblack@eecs.umich.edu            uncacheBit39 = true;
1214519Sgblack@eecs.umich.edu        }
1224519Sgblack@eecs.umich.edu#endif
1234519Sgblack@eecs.umich.edu
1244519Sgblack@eecs.umich.edu        // IPR memory space not implemented
1254519Sgblack@eecs.umich.edu        if (PA_IPR_SPACE(req->paddr))
1264519Sgblack@eecs.umich.edu            if (!req->xc->misspeculating())
1274519Sgblack@eecs.umich.edu                panic("IPR memory space not implemented! PA=%x\n",
1284519Sgblack@eecs.umich.edu                      req->paddr);
1294519Sgblack@eecs.umich.edu
1304712Sgblack@eecs.umich.edu        // mark request as uncacheable
1314519Sgblack@eecs.umich.edu        req->flags |= UNCACHEABLE;
1324519Sgblack@eecs.umich.edu    }
1334519Sgblack@eecs.umich.edu}
1344519Sgblack@eecs.umich.edu
1354712Sgblack@eecs.umich.edu
1364519Sgblack@eecs.umich.edu// insert a new TLB entry
1374519Sgblack@eecs.umich.eduvoid
1384519Sgblack@eecs.umich.eduAlphaTlb::insert(Addr vaddr, AlphaISA::PTE &pte)
1394519Sgblack@eecs.umich.edu{
1404519Sgblack@eecs.umich.edu    if (table[nlu].valid) {
1414519Sgblack@eecs.umich.edu        Addr oldvpn = table[nlu].tag;
1424519Sgblack@eecs.umich.edu        PageTable::iterator i = lookupTable.find(oldvpn);
1434951Sgblack@eecs.umich.edu
1444519Sgblack@eecs.umich.edu        if (i == lookupTable.end())
1454519Sgblack@eecs.umich.edu            panic("TLB entry not found in lookupTable");
1464519Sgblack@eecs.umich.edu
1474519Sgblack@eecs.umich.edu        int index;
1484519Sgblack@eecs.umich.edu        while ((index = i->second) != nlu) {
1494951Sgblack@eecs.umich.edu            if (table[index].tag != oldvpn)
1504519Sgblack@eecs.umich.edu                panic("TLB entry not found in lookupTable");
1514519Sgblack@eecs.umich.edu
1524951Sgblack@eecs.umich.edu            ++i;
1534712Sgblack@eecs.umich.edu        }
1544519Sgblack@eecs.umich.edu
1554951Sgblack@eecs.umich.edu        DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn);
1564519Sgblack@eecs.umich.edu
1574951Sgblack@eecs.umich.edu        lookupTable.erase(i);
1584712Sgblack@eecs.umich.edu    }
1594519Sgblack@eecs.umich.edu
1604519Sgblack@eecs.umich.edu    Addr vpn = VA_VPN(vaddr);
1614519Sgblack@eecs.umich.edu    DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vpn, pte.ppn);
1624519Sgblack@eecs.umich.edu
1634519Sgblack@eecs.umich.edu    table[nlu] = pte;
1644519Sgblack@eecs.umich.edu    table[nlu].tag = vpn;
1654519Sgblack@eecs.umich.edu    table[nlu].valid = true;
1664519Sgblack@eecs.umich.edu
1674519Sgblack@eecs.umich.edu    lookupTable.insert(make_pair(vpn, nlu));
1684519Sgblack@eecs.umich.edu    nextnlu();
1694519Sgblack@eecs.umich.edu}
1704519Sgblack@eecs.umich.edu
1714519Sgblack@eecs.umich.eduvoid
1724519Sgblack@eecs.umich.eduAlphaTlb::flushAll()
1734519Sgblack@eecs.umich.edu{
1744712Sgblack@eecs.umich.edu    memset(table, 0, sizeof(AlphaISA::PTE[size]));
1754519Sgblack@eecs.umich.edu    lookupTable.clear();
1764581Sgblack@eecs.umich.edu    nlu = 0;
1774688Sgblack@eecs.umich.edu}
1784581Sgblack@eecs.umich.edu
1794519Sgblack@eecs.umich.eduvoid
1804519Sgblack@eecs.umich.eduAlphaTlb::flushProcesses()
1814519Sgblack@eecs.umich.edu{
1824519Sgblack@eecs.umich.edu    PageTable::iterator i = lookupTable.begin();
1834519Sgblack@eecs.umich.edu    PageTable::iterator end = lookupTable.end();
1844519Sgblack@eecs.umich.edu    while (i != end) {
1854519Sgblack@eecs.umich.edu        int index = i->second;
1864519Sgblack@eecs.umich.edu        AlphaISA::PTE *pte = &table[index];
1874712Sgblack@eecs.umich.edu        assert(pte->valid);
1884519Sgblack@eecs.umich.edu
1894581Sgblack@eecs.umich.edu        if (!pte->asma) {
1904688Sgblack@eecs.umich.edu            DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn);
1914581Sgblack@eecs.umich.edu            pte->valid = false;
1924519Sgblack@eecs.umich.edu            lookupTable.erase(i);
1934519Sgblack@eecs.umich.edu        }
1944519Sgblack@eecs.umich.edu
1954519Sgblack@eecs.umich.edu        ++i;
1964519Sgblack@eecs.umich.edu    }
1974519Sgblack@eecs.umich.edu}
1984519Sgblack@eecs.umich.edu
1994951Sgblack@eecs.umich.eduvoid
2004519Sgblack@eecs.umich.eduAlphaTlb::flushAddr(Addr vaddr, uint8_t asn)
2014519Sgblack@eecs.umich.edu{
2024519Sgblack@eecs.umich.edu    Addr vpn = VA_VPN(vaddr);
2034519Sgblack@eecs.umich.edu
2044951Sgblack@eecs.umich.edu    PageTable::iterator i = lookupTable.find(vpn);
2054519Sgblack@eecs.umich.edu    if (i == lookupTable.end())
2064951Sgblack@eecs.umich.edu        return;
2074712Sgblack@eecs.umich.edu
2084519Sgblack@eecs.umich.edu    while (i->first == vpn) {
2094581Sgblack@eecs.umich.edu        int index = i->second;
2104688Sgblack@eecs.umich.edu        AlphaISA::PTE *pte = &table[index];
2114581Sgblack@eecs.umich.edu        assert(pte->valid);
2124519Sgblack@eecs.umich.edu
2134519Sgblack@eecs.umich.edu        if (vpn == pte->tag && (pte->asma || pte->asn == asn)) {
2144519Sgblack@eecs.umich.edu            DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vpn, pte->ppn);
2154519Sgblack@eecs.umich.edu
2164951Sgblack@eecs.umich.edu            // invalidate this entry
2174519Sgblack@eecs.umich.edu            pte->valid = false;
2184519Sgblack@eecs.umich.edu
2194951Sgblack@eecs.umich.edu            lookupTable.erase(i);
2204712Sgblack@eecs.umich.edu        }
2214519Sgblack@eecs.umich.edu
2224581Sgblack@eecs.umich.edu        ++i;
2234688Sgblack@eecs.umich.edu    }
2244581Sgblack@eecs.umich.edu}
2254519Sgblack@eecs.umich.edu
2264519Sgblack@eecs.umich.edu
2274519Sgblack@eecs.umich.eduvoid
2284519Sgblack@eecs.umich.eduAlphaTlb::serialize(ostream &os)
2294519Sgblack@eecs.umich.edu{
2305075Sgblack@eecs.umich.edu    SERIALIZE_SCALAR(size);
2315075Sgblack@eecs.umich.edu    SERIALIZE_SCALAR(nlu);
2325075Sgblack@eecs.umich.edu
2335075Sgblack@eecs.umich.edu    for (int i = 0; i < size; i++) {
2345428Sgblack@eecs.umich.edu        nameOut(os, csprintf("%s.PTE%d", name(), i));
2355428Sgblack@eecs.umich.edu        table[i].serialize(os);
2365674Sgblack@eecs.umich.edu    }
2375899Sgblack@eecs.umich.edu}
2385936Sgblack@eecs.umich.edu
2395428Sgblack@eecs.umich.eduvoid
2405678Sgblack@eecs.umich.eduAlphaTlb::unserialize(Checkpoint *cp, const string &section)
2415678Sgblack@eecs.umich.edu{
2425678Sgblack@eecs.umich.edu    UNSERIALIZE_SCALAR(size);
2435678Sgblack@eecs.umich.edu    UNSERIALIZE_SCALAR(nlu);
2445678Sgblack@eecs.umich.edu
2455678Sgblack@eecs.umich.edu    for (int i = 0; i < size; i++) {
2465678Sgblack@eecs.umich.edu        table[i].unserialize(cp, csprintf("%s.PTE%d", section, i));
2475678Sgblack@eecs.umich.edu        if (table[i].valid) {
2485678Sgblack@eecs.umich.edu            lookupTable.insert(make_pair(table[i].tag, i));
2495075Sgblack@eecs.umich.edu        }
2505075Sgblack@eecs.umich.edu    }
2515075Sgblack@eecs.umich.edu}
2525075Sgblack@eecs.umich.edu
2535075Sgblack@eecs.umich.edu
2545075Sgblack@eecs.umich.edu///////////////////////////////////////////////////////////////////////
2555075Sgblack@eecs.umich.edu//
2565075Sgblack@eecs.umich.edu//  Alpha ITB
2575075Sgblack@eecs.umich.edu//
2585075Sgblack@eecs.umich.eduAlphaItb::AlphaItb(const std::string &name, int size)
2595075Sgblack@eecs.umich.edu    : AlphaTlb(name, size)
2605075Sgblack@eecs.umich.edu{}
2615075Sgblack@eecs.umich.edu
2625075Sgblack@eecs.umich.edu
2635075Sgblack@eecs.umich.eduvoid
2645075Sgblack@eecs.umich.eduAlphaItb::regStats()
2655075Sgblack@eecs.umich.edu{
2665075Sgblack@eecs.umich.edu    hits
2675075Sgblack@eecs.umich.edu        .name(name() + ".hits")
2685075Sgblack@eecs.umich.edu        .desc("ITB hits");
2695075Sgblack@eecs.umich.edu    misses
2705075Sgblack@eecs.umich.edu        .name(name() + ".misses")
2715075Sgblack@eecs.umich.edu        .desc("ITB misses");
2725075Sgblack@eecs.umich.edu    acv
2735075Sgblack@eecs.umich.edu        .name(name() + ".acv")
2745075Sgblack@eecs.umich.edu        .desc("ITB acv");
2755075Sgblack@eecs.umich.edu    accesses
2765075Sgblack@eecs.umich.edu        .name(name() + ".accesses")
2775075Sgblack@eecs.umich.edu        .desc("ITB accesses");
2785075Sgblack@eecs.umich.edu
2795075Sgblack@eecs.umich.edu    accesses = hits + misses;
2805075Sgblack@eecs.umich.edu}
2815075Sgblack@eecs.umich.edu
2825075Sgblack@eecs.umich.eduvoid
2835075Sgblack@eecs.umich.eduAlphaItb::fault(Addr pc, ExecContext *xc) const
2844519Sgblack@eecs.umich.edu{
2855040Sgblack@eecs.umich.edu    uint64_t *ipr = xc->regs.ipr;
2865040Sgblack@eecs.umich.edu
2875040Sgblack@eecs.umich.edu    if (!xc->misspeculating()) {
2885040Sgblack@eecs.umich.edu        ipr[AlphaISA::IPR_ITB_TAG] = pc;
2895040Sgblack@eecs.umich.edu        ipr[AlphaISA::IPR_IFAULT_VA_FORM] =
2905040Sgblack@eecs.umich.edu            ipr[AlphaISA::IPR_IVPTBR] | (VA_VPN(pc) << 3);
2915040Sgblack@eecs.umich.edu    }
2925040Sgblack@eecs.umich.edu}
2935040Sgblack@eecs.umich.edu
2945040Sgblack@eecs.umich.edu
2955040Sgblack@eecs.umich.eduFault
2965040Sgblack@eecs.umich.eduAlphaItb::translate(MemReqPtr &req) const
2975040Sgblack@eecs.umich.edu{
2985040Sgblack@eecs.umich.edu    InternalProcReg *ipr = req->xc->regs.ipr;
2995040Sgblack@eecs.umich.edu
3005040Sgblack@eecs.umich.edu    if (PC_PAL(req->vaddr)) {
3015040Sgblack@eecs.umich.edu        // strip off PAL PC marker (lsb is 1)
3025040Sgblack@eecs.umich.edu        req->paddr = (req->vaddr & ~3) & PA_IMPL_MASK;
3035040Sgblack@eecs.umich.edu        hits++;
3045040Sgblack@eecs.umich.edu        return No_Fault;
3055040Sgblack@eecs.umich.edu    }
3065040Sgblack@eecs.umich.edu
3075040Sgblack@eecs.umich.edu    if (req->flags & PHYSICAL) {
3085040Sgblack@eecs.umich.edu        req->paddr = req->vaddr;
3095040Sgblack@eecs.umich.edu    } else {
3105040Sgblack@eecs.umich.edu        // verify that this is a good virtual address
3115040Sgblack@eecs.umich.edu        if (!validVirtualAddress(req->vaddr)) {
3125040Sgblack@eecs.umich.edu            fault(req->vaddr, req->xc);
3135040Sgblack@eecs.umich.edu            acv++;
3145040Sgblack@eecs.umich.edu            return Itb_Acv_Fault;
3155062Sgblack@eecs.umich.edu        }
3165062Sgblack@eecs.umich.edu
3175062Sgblack@eecs.umich.edu        // Check for "superpage" mapping: when SP<1> is set, and
3185062Sgblack@eecs.umich.edu        // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>.
3195062Sgblack@eecs.umich.edu        if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) &&
3205062Sgblack@eecs.umich.edu               VA_SPACE(req->vaddr) == 2) {
3215062Sgblack@eecs.umich.edu
3225040Sgblack@eecs.umich.edu            // only valid in kernel mode
3235062Sgblack@eecs.umich.edu            if (ICM_CM(ipr[AlphaISA::IPR_ICM]) != AlphaISA::mode_kernel) {
3245062Sgblack@eecs.umich.edu                fault(req->vaddr, req->xc);
3255062Sgblack@eecs.umich.edu                acv++;
3265062Sgblack@eecs.umich.edu                return Itb_Acv_Fault;
3275040Sgblack@eecs.umich.edu            }
3285040Sgblack@eecs.umich.edu
3295040Sgblack@eecs.umich.edu            req->paddr = req->vaddr & PA_IMPL_MASK;
3305040Sgblack@eecs.umich.edu
3315040Sgblack@eecs.umich.edu            // sign extend the physical address properly
3325040Sgblack@eecs.umich.edu            if (req->paddr & PA_UNCACHED_BIT_39 ||
3335040Sgblack@eecs.umich.edu                req->paddr & PA_UNCACHED_BIT_40)
3345040Sgblack@eecs.umich.edu                req->paddr |= 0xf0000000000;
3355040Sgblack@eecs.umich.edu            else
3365239Sgblack@eecs.umich.edu                req->paddr &= 0xffffffffff;
3375040Sgblack@eecs.umich.edu
3385040Sgblack@eecs.umich.edu        } else {
3395040Sgblack@eecs.umich.edu            // not a physical address: need to look up pte
3405040Sgblack@eecs.umich.edu            AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr),
3415040Sgblack@eecs.umich.edu                                 DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]));
3425040Sgblack@eecs.umich.edu
3435040Sgblack@eecs.umich.edu            if (!pte) {
3445040Sgblack@eecs.umich.edu                fault(req->vaddr, req->xc);
3455061Sgblack@eecs.umich.edu                misses++;
3465040Sgblack@eecs.umich.edu                return Itb_Fault_Fault;
3475040Sgblack@eecs.umich.edu            }
3485061Sgblack@eecs.umich.edu
3495061Sgblack@eecs.umich.edu            req->paddr = PA_PFN2PA(pte->ppn) + VA_POFS(req->vaddr & ~3);
3505061Sgblack@eecs.umich.edu
3515061Sgblack@eecs.umich.edu            // check permissions for this access
3525061Sgblack@eecs.umich.edu            if (!(pte->xre & (1 << ICM_CM(ipr[AlphaISA::IPR_ICM])))) {
3535061Sgblack@eecs.umich.edu                // instruction access fault
3545061Sgblack@eecs.umich.edu                fault(req->vaddr, req->xc);
3555061Sgblack@eecs.umich.edu                acv++;
3565040Sgblack@eecs.umich.edu                return Itb_Acv_Fault;
3575040Sgblack@eecs.umich.edu            }
3585040Sgblack@eecs.umich.edu
3595040Sgblack@eecs.umich.edu            hits++;
3605040Sgblack@eecs.umich.edu        }
3615040Sgblack@eecs.umich.edu    }
3625040Sgblack@eecs.umich.edu
3635040Sgblack@eecs.umich.edu    // check that the physical address is ok (catch bad physical addresses)
3645040Sgblack@eecs.umich.edu    if (req->paddr & ~PA_IMPL_MASK)
3655040Sgblack@eecs.umich.edu        return Machine_Check_Fault;
3665040Sgblack@eecs.umich.edu
3675040Sgblack@eecs.umich.edu    checkCacheability(req);
3685040Sgblack@eecs.umich.edu
3695040Sgblack@eecs.umich.edu    return No_Fault;
3705040Sgblack@eecs.umich.edu}
3715040Sgblack@eecs.umich.edu
3725040Sgblack@eecs.umich.edu///////////////////////////////////////////////////////////////////////
3735040Sgblack@eecs.umich.edu//
3745040Sgblack@eecs.umich.edu//  Alpha DTB
3755040Sgblack@eecs.umich.edu//
3765040Sgblack@eecs.umich.eduAlphaDtb::AlphaDtb(const std::string &name, int size)
3775040Sgblack@eecs.umich.edu    : AlphaTlb(name, size)
3785040Sgblack@eecs.umich.edu{}
3795040Sgblack@eecs.umich.edu
3805040Sgblack@eecs.umich.eduvoid
3814688Sgblack@eecs.umich.eduAlphaDtb::regStats()
3825040Sgblack@eecs.umich.edu{
3834688Sgblack@eecs.umich.edu    read_hits
3844688Sgblack@eecs.umich.edu        .name(name() + ".read_hits")
3854688Sgblack@eecs.umich.edu        .desc("DTB read hits")
3864688Sgblack@eecs.umich.edu        ;
3875040Sgblack@eecs.umich.edu
3884688Sgblack@eecs.umich.edu    read_misses
3895040Sgblack@eecs.umich.edu        .name(name() + ".read_misses")
3905040Sgblack@eecs.umich.edu        .desc("DTB read misses")
3915040Sgblack@eecs.umich.edu        ;
3925040Sgblack@eecs.umich.edu
3935040Sgblack@eecs.umich.edu    read_acv
3945040Sgblack@eecs.umich.edu        .name(name() + ".read_acv")
3955040Sgblack@eecs.umich.edu        .desc("DTB read access violations")
3965040Sgblack@eecs.umich.edu        ;
3975040Sgblack@eecs.umich.edu
3985040Sgblack@eecs.umich.edu    read_accesses
3995040Sgblack@eecs.umich.edu        .name(name() + ".read_accesses")
4005040Sgblack@eecs.umich.edu        .desc("DTB read accesses")
4015040Sgblack@eecs.umich.edu        ;
4025040Sgblack@eecs.umich.edu
4035040Sgblack@eecs.umich.edu    write_hits
4045040Sgblack@eecs.umich.edu        .name(name() + ".write_hits")
4055040Sgblack@eecs.umich.edu        .desc("DTB write hits")
4065040Sgblack@eecs.umich.edu        ;
4075040Sgblack@eecs.umich.edu
4085040Sgblack@eecs.umich.edu    write_misses
4095040Sgblack@eecs.umich.edu        .name(name() + ".write_misses")
4105040Sgblack@eecs.umich.edu        .desc("DTB write misses")
4114688Sgblack@eecs.umich.edu        ;
4124688Sgblack@eecs.umich.edu
4135040Sgblack@eecs.umich.edu    write_acv
4145040Sgblack@eecs.umich.edu        .name(name() + ".write_acv")
4155040Sgblack@eecs.umich.edu        .desc("DTB write access violations")
4165040Sgblack@eecs.umich.edu        ;
4174688Sgblack@eecs.umich.edu
4184688Sgblack@eecs.umich.edu    write_accesses
4195040Sgblack@eecs.umich.edu        .name(name() + ".write_accesses")
4205040Sgblack@eecs.umich.edu        .desc("DTB write accesses")
4215040Sgblack@eecs.umich.edu        ;
4225040Sgblack@eecs.umich.edu
4235040Sgblack@eecs.umich.edu    hits
4245040Sgblack@eecs.umich.edu        .name(name() + ".hits")
4254519Sgblack@eecs.umich.edu        .desc("DTB hits")
4264519Sgblack@eecs.umich.edu        ;
4275040Sgblack@eecs.umich.edu
4284688Sgblack@eecs.umich.edu    misses
4294701Sgblack@eecs.umich.edu        .name(name() + ".misses")
4304688Sgblack@eecs.umich.edu        .desc("DTB misses")
4314688Sgblack@eecs.umich.edu        ;
4324688Sgblack@eecs.umich.edu
4334688Sgblack@eecs.umich.edu    acv
4344688Sgblack@eecs.umich.edu        .name(name() + ".acv")
4354688Sgblack@eecs.umich.edu        .desc("DTB access violations")
4364688Sgblack@eecs.umich.edu        ;
4374519Sgblack@eecs.umich.edu
4384519Sgblack@eecs.umich.edu    accesses
4395040Sgblack@eecs.umich.edu        .name(name() + ".accesses")
4405040Sgblack@eecs.umich.edu        .desc("DTB accesses")
4415040Sgblack@eecs.umich.edu        ;
4425788Sgblack@eecs.umich.edu
4435040Sgblack@eecs.umich.edu    hits = read_hits + write_hits;
4444688Sgblack@eecs.umich.edu    misses = read_misses + write_misses;
4455040Sgblack@eecs.umich.edu    acv = read_acv + write_acv;
4464519Sgblack@eecs.umich.edu    accesses = read_accesses + write_accesses;
4475040Sgblack@eecs.umich.edu}
4484519Sgblack@eecs.umich.edu
4494519Sgblack@eecs.umich.eduvoid
4504519Sgblack@eecs.umich.eduAlphaDtb::fault(Addr vaddr, uint64_t flags, ExecContext *xc) const
4514539Sgblack@eecs.umich.edu{
4524519Sgblack@eecs.umich.edu    uint64_t *ipr = xc->regs.ipr;
4535040Sgblack@eecs.umich.edu
4544688Sgblack@eecs.umich.edu    // set fault address and flags
4555040Sgblack@eecs.umich.edu    if (!xc->misspeculating() && !xc->regs.intrlock) {
4565040Sgblack@eecs.umich.edu        // set VA register with faulting address
4575115Sgblack@eecs.umich.edu        ipr[AlphaISA::IPR_VA] = vaddr;
4585040Sgblack@eecs.umich.edu
4595040Sgblack@eecs.umich.edu        // set MM_STAT register flags
4605040Sgblack@eecs.umich.edu        ipr[AlphaISA::IPR_MM_STAT] = (((xc->regs.opcode & 0x3f) << 11)
4615115Sgblack@eecs.umich.edu                               | ((xc->regs.ra & 0x1f) << 6)
4625040Sgblack@eecs.umich.edu                               | (flags & 0x3f));
4635040Sgblack@eecs.umich.edu
4644519Sgblack@eecs.umich.edu        // set VA_FORM register with faulting formatted address
4655040Sgblack@eecs.umich.edu        ipr[AlphaISA::IPR_VA_FORM] =
4665040Sgblack@eecs.umich.edu            ipr[AlphaISA::IPR_MVPTBR] | (VA_VPN(vaddr) << 3);
4675040Sgblack@eecs.umich.edu
4685040Sgblack@eecs.umich.edu        // lock these registers until the VA register is read
4694519Sgblack@eecs.umich.edu        xc->regs.intrlock = true;
4705040Sgblack@eecs.umich.edu    }
4715040Sgblack@eecs.umich.edu}
4725040Sgblack@eecs.umich.edu
4735040Sgblack@eecs.umich.eduFault
4744519Sgblack@eecs.umich.eduAlphaDtb::translate(MemReqPtr &req, bool write) const
4755040Sgblack@eecs.umich.edu{
4765040Sgblack@eecs.umich.edu    RegFile *regs = &req->xc->regs;
4775083Sgblack@eecs.umich.edu    Addr pc = regs->pc;
4784519Sgblack@eecs.umich.edu    InternalProcReg *ipr = regs->ipr;
4795063Sgblack@eecs.umich.edu
4805063Sgblack@eecs.umich.edu    AlphaISA::mode_type mode =
4815063Sgblack@eecs.umich.edu        (AlphaISA::mode_type)DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]);
4825063Sgblack@eecs.umich.edu
4835063Sgblack@eecs.umich.edu    if (PC_PAL(pc)) {
4845063Sgblack@eecs.umich.edu        mode = (req->flags & ALTMODE) ?
4855063Sgblack@eecs.umich.edu            (AlphaISA::mode_type)ALT_MODE_AM(ipr[AlphaISA::IPR_ALT_MODE])
4865063Sgblack@eecs.umich.edu            : AlphaISA::mode_kernel;
4875063Sgblack@eecs.umich.edu    }
4885063Sgblack@eecs.umich.edu
4895063Sgblack@eecs.umich.edu    if (req->flags & PHYSICAL) {
4905063Sgblack@eecs.umich.edu        req->paddr = req->vaddr;
4915040Sgblack@eecs.umich.edu    } else {
4925040Sgblack@eecs.umich.edu        // verify that this is a good virtual address
4934595Sgblack@eecs.umich.edu        if (!validVirtualAddress(req->vaddr)) {
4945040Sgblack@eecs.umich.edu            fault(req->vaddr,
4955040Sgblack@eecs.umich.edu                  ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_BAD_VA_MASK |
4964595Sgblack@eecs.umich.edu                   MM_STAT_ACV_MASK),
4975040Sgblack@eecs.umich.edu                  req->xc);
4985040Sgblack@eecs.umich.edu
4994732Sgblack@eecs.umich.edu            if (write) { write_acv++; } else { read_acv++; }
5005138Sgblack@eecs.umich.edu            return Dtb_Fault_Fault;
5015040Sgblack@eecs.umich.edu        }
5025040Sgblack@eecs.umich.edu
5035040Sgblack@eecs.umich.edu        // Check for "superpage" mapping: when SP<1> is set, and
5045040Sgblack@eecs.umich.edu        // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>.
5054732Sgblack@eecs.umich.edu        if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) &&
5065138Sgblack@eecs.umich.edu            VA_SPACE(req->vaddr) == 2) {
5075040Sgblack@eecs.umich.edu
5085040Sgblack@eecs.umich.edu            // only valid in kernel mode
5095040Sgblack@eecs.umich.edu            if (DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]) !=
5105040Sgblack@eecs.umich.edu                AlphaISA::mode_kernel) {
5115040Sgblack@eecs.umich.edu                fault(req->vaddr,
5125040Sgblack@eecs.umich.edu                      ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK),
5135040Sgblack@eecs.umich.edu                      req->xc);
5145040Sgblack@eecs.umich.edu                if (write) { write_acv++; } else { read_acv++; }
5155040Sgblack@eecs.umich.edu                return Dtb_Acv_Fault;
5165040Sgblack@eecs.umich.edu            }
5175040Sgblack@eecs.umich.edu
5185065Sgblack@eecs.umich.edu            req->paddr = req->vaddr & PA_IMPL_MASK;
5195065Sgblack@eecs.umich.edu
5205065Sgblack@eecs.umich.edu            // sign extend the physical address properly
5215065Sgblack@eecs.umich.edu            if (req->paddr & PA_UNCACHED_BIT_39 ||
5225065Sgblack@eecs.umich.edu                req->paddr & PA_UNCACHED_BIT_40)
5235063Sgblack@eecs.umich.edu                req->paddr |= 0xf0000000000;
5245040Sgblack@eecs.umich.edu            else
5255063Sgblack@eecs.umich.edu                req->paddr &= 0xffffffffff;
5265063Sgblack@eecs.umich.edu
5275063Sgblack@eecs.umich.edu        } else {
5285063Sgblack@eecs.umich.edu            if (write)
5295063Sgblack@eecs.umich.edu                write_accesses++;
5305063Sgblack@eecs.umich.edu            else
5315063Sgblack@eecs.umich.edu                read_accesses++;
5325063Sgblack@eecs.umich.edu
5335063Sgblack@eecs.umich.edu            // not a physical address: need to look up pte
5345040Sgblack@eecs.umich.edu            AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr),
5355040Sgblack@eecs.umich.edu                                 DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]));
5365063Sgblack@eecs.umich.edu
5375040Sgblack@eecs.umich.edu            if (!pte) {
5385063Sgblack@eecs.umich.edu                // page fault
5394809Sgblack@eecs.umich.edu                fault(req->vaddr,
5405063Sgblack@eecs.umich.edu                      ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_DTB_MISS_MASK),
5415063Sgblack@eecs.umich.edu                      req->xc);
5425063Sgblack@eecs.umich.edu                if (write) { write_misses++; } else { read_misses++; }
5435063Sgblack@eecs.umich.edu                return (req->flags & VPTE) ? Pdtb_Miss_Fault : Ndtb_Miss_Fault;
5445063Sgblack@eecs.umich.edu            }
5455063Sgblack@eecs.umich.edu
5465063Sgblack@eecs.umich.edu            req->paddr = PA_PFN2PA(pte->ppn) | VA_POFS(req->vaddr);
5475040Sgblack@eecs.umich.edu
5485040Sgblack@eecs.umich.edu            if (write) {
5495063Sgblack@eecs.umich.edu                if (!(pte->xwe & MODE2MASK(mode))) {
5505063Sgblack@eecs.umich.edu                    // declare the instruction access fault
5515040Sgblack@eecs.umich.edu                    fault(req->vaddr, MM_STAT_WR_MASK | MM_STAT_ACV_MASK |
5525063Sgblack@eecs.umich.edu                          (pte->fonw ? MM_STAT_FONW_MASK : 0),
5535063Sgblack@eecs.umich.edu                          req->xc);
5545063Sgblack@eecs.umich.edu                    write_acv++;
5555063Sgblack@eecs.umich.edu                    return Dtb_Fault_Fault;
5565063Sgblack@eecs.umich.edu                }
5575063Sgblack@eecs.umich.edu                if (pte->fonw) {
5585063Sgblack@eecs.umich.edu                    fault(req->vaddr, MM_STAT_WR_MASK | MM_STAT_FONW_MASK,
5595063Sgblack@eecs.umich.edu                          req->xc);
5605063Sgblack@eecs.umich.edu                    write_acv++;
5615063Sgblack@eecs.umich.edu                    return Dtb_Fault_Fault;
5625063Sgblack@eecs.umich.edu                }
5635063Sgblack@eecs.umich.edu            } else {
5645062Sgblack@eecs.umich.edu                if (!(pte->xre & MODE2MASK(mode))) {
5655075Sgblack@eecs.umich.edu                    fault(req->vaddr,
5665075Sgblack@eecs.umich.edu                          MM_STAT_ACV_MASK |
5675040Sgblack@eecs.umich.edu                          (pte->fonr ? MM_STAT_FONR_MASK : 0),
5685075Sgblack@eecs.umich.edu                          req->xc);
5695075Sgblack@eecs.umich.edu                    read_acv++;
5705075Sgblack@eecs.umich.edu                    return Dtb_Acv_Fault;
5715075Sgblack@eecs.umich.edu                }
5725075Sgblack@eecs.umich.edu                if (pte->fonr) {
5735075Sgblack@eecs.umich.edu                    fault(req->vaddr, MM_STAT_FONR_MASK, req->xc);
5745075Sgblack@eecs.umich.edu                    read_acv++;
5755075Sgblack@eecs.umich.edu                    return Dtb_Fault_Fault;
5765075Sgblack@eecs.umich.edu                }
5775075Sgblack@eecs.umich.edu            }
5785075Sgblack@eecs.umich.edu        }
5795075Sgblack@eecs.umich.edu
5805075Sgblack@eecs.umich.edu        if (write)
5815075Sgblack@eecs.umich.edu            write_hits++;
5825075Sgblack@eecs.umich.edu        else
5835040Sgblack@eecs.umich.edu            read_hits++;
5844823Sgblack@eecs.umich.edu    }
5855075Sgblack@eecs.umich.edu
5865075Sgblack@eecs.umich.edu    // check that the physical address is ok (catch bad physical addresses)
5875075Sgblack@eecs.umich.edu    if (req->paddr & ~PA_IMPL_MASK)
5885075Sgblack@eecs.umich.edu        return Machine_Check_Fault;
5895075Sgblack@eecs.umich.edu
5905075Sgblack@eecs.umich.edu    checkCacheability(req);
5915075Sgblack@eecs.umich.edu
5925075Sgblack@eecs.umich.edu    return No_Fault;
5935075Sgblack@eecs.umich.edu}
5945075Sgblack@eecs.umich.edu
5955075Sgblack@eecs.umich.eduAlphaISA::PTE &
5965075Sgblack@eecs.umich.eduAlphaTlb::index(bool advance)
5975075Sgblack@eecs.umich.edu{
5985075Sgblack@eecs.umich.edu    AlphaISA::PTE *pte = &table[nlu];
5995075Sgblack@eecs.umich.edu
6005075Sgblack@eecs.umich.edu    if (advance)
6015075Sgblack@eecs.umich.edu        nextnlu();
6025075Sgblack@eecs.umich.edu
6035075Sgblack@eecs.umich.edu    return *pte;
6045075Sgblack@eecs.umich.edu}
6055075Sgblack@eecs.umich.edu
6065075Sgblack@eecs.umich.eduBEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaItb)
6075075Sgblack@eecs.umich.edu
6085075Sgblack@eecs.umich.edu    Param<int> size;
6095075Sgblack@eecs.umich.edu
6105075Sgblack@eecs.umich.eduEND_DECLARE_SIM_OBJECT_PARAMS(AlphaItb)
6115075Sgblack@eecs.umich.edu
6125075Sgblack@eecs.umich.eduBEGIN_INIT_SIM_OBJECT_PARAMS(AlphaItb)
6135075Sgblack@eecs.umich.edu
6145075Sgblack@eecs.umich.edu    INIT_PARAM_DFLT(size, "TLB size", 48)
6155075Sgblack@eecs.umich.edu
6165075Sgblack@eecs.umich.eduEND_INIT_SIM_OBJECT_PARAMS(AlphaItb)
6175075Sgblack@eecs.umich.edu
6184732Sgblack@eecs.umich.edu
6195075Sgblack@eecs.umich.eduCREATE_SIM_OBJECT(AlphaItb)
6205075Sgblack@eecs.umich.edu{
6215075Sgblack@eecs.umich.edu    return new AlphaItb(getInstanceName(), size);
6225075Sgblack@eecs.umich.edu}
6235075Sgblack@eecs.umich.edu
6245040Sgblack@eecs.umich.eduREGISTER_SIM_OBJECT("AlphaITB", AlphaItb)
6255040Sgblack@eecs.umich.edu
6265040Sgblack@eecs.umich.eduBEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaDtb)
6275040Sgblack@eecs.umich.edu
6285040Sgblack@eecs.umich.edu    Param<int> size;
6294732Sgblack@eecs.umich.edu
6305040Sgblack@eecs.umich.eduEND_DECLARE_SIM_OBJECT_PARAMS(AlphaDtb)
6315076Sgblack@eecs.umich.edu
6325040Sgblack@eecs.umich.eduBEGIN_INIT_SIM_OBJECT_PARAMS(AlphaDtb)
6334756Sgblack@eecs.umich.edu
6344823Sgblack@eecs.umich.edu    INIT_PARAM_DFLT(size, "TLB size", 64)
6355040Sgblack@eecs.umich.edu
6365076Sgblack@eecs.umich.eduEND_INIT_SIM_OBJECT_PARAMS(AlphaDtb)
6375076Sgblack@eecs.umich.edu
6385076Sgblack@eecs.umich.edu
6395076Sgblack@eecs.umich.eduCREATE_SIM_OBJECT(AlphaDtb)
6405076Sgblack@eecs.umich.edu{
6415076Sgblack@eecs.umich.edu    return new AlphaDtb(getInstanceName(), size);
6425076Sgblack@eecs.umich.edu}
6435076Sgblack@eecs.umich.edu
6445076Sgblack@eecs.umich.eduREGISTER_SIM_OBJECT("AlphaDTB", AlphaDtb)
6455076Sgblack@eecs.umich.edu
6465076Sgblack@eecs.umich.edu