tlb.cc revision 533
12SN/A/*
28922Swilliam.wang@arm.com * Copyright (c) 2003 The Regents of The University of Michigan
38707Sandreas.hansson@arm.com * All rights reserved.
48707Sandreas.hansson@arm.com *
58707Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
68707Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
78707Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
88707Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
98707Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
108707Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
118707Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
128707Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
138707Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
141762SN/A * this software without specific prior written permission.
157897Shestness@cs.utexas.edu *
169983Sstever@gmail.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
179983Sstever@gmail.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272SN/A */
282SN/A
292SN/A#include <sstream>
302SN/A#include <string>
312SN/A#include <vector>
322SN/A
332SN/A#include "base/inifile.hh"
342SN/A#include "base/str.hh"
352SN/A#include "base/trace.hh"
362SN/A#include "cpu/exec_context.hh"
372SN/A#include "sim/builder.hh"
382SN/A#include "targetarch/alpha_memory.hh"
392SN/A#include "targetarch/ev5.hh"
402SN/A
412SN/Ausing namespace std;
422665Ssaidi@eecs.umich.edu
432665Ssaidi@eecs.umich.edu///////////////////////////////////////////////////////////////////////
442665Ssaidi@eecs.umich.edu//
457897Shestness@cs.utexas.edu//  Alpha TLB
462SN/A//
472SN/AAlphaTlb::AlphaTlb(const string &name, int s)
481388SN/A    : SimObject(name), size(s), nlu(0)
498229Snate@binkert.org{
502SN/A    table = new AlphaISA::PTE[size];
512SN/A    memset(table, 0, sizeof(AlphaISA::PTE[size]));
527781SAli.Saidi@ARM.com}
538229Snate@binkert.org
541191SN/AAlphaTlb::~AlphaTlb()
551191SN/A{
561388SN/A    if (table)
575529Snate@binkert.org        delete [] table;
5810529Smorr@cs.wisc.edu}
591717SN/A
602651Ssaidi@eecs.umich.edu// look up an entry in the TLB
618229Snate@binkert.orgAlphaISA::PTE *
622680Sktlim@umich.eduAlphaTlb::lookup(Addr vpn, uint8_t asn) const
6310529Smorr@cs.wisc.edu{
648232Snate@binkert.org    DPRINTF(TLB, "lookup %#x\n", vpn);
6510529Smorr@cs.wisc.edu
665529Snate@binkert.org    PageTable::const_iterator i = lookupTable.find(vpn);
678779Sgblack@eecs.umich.edu    if (i == lookupTable.end())
682190SN/A        return NULL;
6956SN/A
708229Snate@binkert.org    while (i->first == vpn) {
712190SN/A        int index = i->second;
722SN/A        AlphaISA::PTE *pte = &table[index];
732359SN/A        assert(pte->valid);
742359SN/A        if (vpn == pte->tag && (pte->asma || pte->asn == asn))
752359SN/A            return pte;
762SN/A
772SN/A        ++i;
782SN/A    }
792SN/A
802SN/A    // not found...
812SN/A    return NULL;
822SN/A}
832SN/A
842SN/A
855606Snate@binkert.orgvoid
866144Sksewell@umich.eduAlphaTlb::checkCacheability(MemReqPtr &req)
876144Sksewell@umich.edu{
883126Sktlim@umich.edu    // in Alpha, cacheability is controlled by upper-level bits of the
896144Sksewell@umich.edu    // physical address
907823Ssteve.reinhardt@amd.com    if (req->paddr & PA_UNCACHED_BIT) {
913126Sktlim@umich.edu        if (PA_IPR_SPACE(req->paddr)) {
923126Sktlim@umich.edu            // IPR memory space not implemented
932356SN/A            if (!req->xc->misspeculating()) {
942356SN/A                switch (req->paddr) {
952356SN/A                  case 0xFFFFF00188:
968834Satgutier@umich.edu                    req->data = 0;
9710786Smalek.musleh@gmail.com                    break;
9810786Smalek.musleh@gmail.com
9910786Smalek.musleh@gmail.com                  default:
10010786Smalek.musleh@gmail.com                    panic("IPR memory space not implemented! PA=%x\n",
10110786Smalek.musleh@gmail.com                          req->paddr);
10210786Smalek.musleh@gmail.com                }
10310786Smalek.musleh@gmail.com            }
10410786Smalek.musleh@gmail.com        } else {
1052356SN/A            // mark request as uncacheable
1069179Sandreas.hansson@arm.com            req->flags |= UNCACHEABLE;
1072367SN/A        }
1086144Sksewell@umich.edu    }
1096144Sksewell@umich.edu}
1106144Sksewell@umich.edu
1112356SN/A
1122367SN/A// insert a new TLB entry
1136144Sksewell@umich.eduvoid
1147823Ssteve.reinhardt@amd.comAlphaTlb::insert(Addr vaddr, AlphaISA::PTE &pte)
1156144Sksewell@umich.edu{
1162367SN/A    if (table[nlu].valid) {
1172356SN/A        Addr oldvpn = table[nlu].tag;
1182356SN/A        PageTable::iterator i = lookupTable.find(oldvpn);
1192356SN/A
1202356SN/A        if (i == lookupTable.end())
1215336Shines@cs.fsu.edu            panic("TLB entry not found in lookupTable");
1222356SN/A
1234873Sstever@eecs.umich.edu        int index;
1242356SN/A        while ((index = i->second) != nlu) {
1252356SN/A            if (table[index].tag != oldvpn)
1268876Sandreas.hansson@arm.com                panic("TLB entry not found in lookupTable");
12710190Sakash.bagdia@arm.com
1288832SAli.Saidi@ARM.com            ++i;
1298832SAli.Saidi@ARM.com        }
1309332Sdam.sunwoo@arm.com
1319814Sandreas.hansson@arm.com        DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn);
1329220Shestness@cs.wisc.edu
13310529Smorr@cs.wisc.edu        lookupTable.erase(i);
13410537Sandreas.hansson@arm.com    }
13510537Sandreas.hansson@arm.com
13610529Smorr@cs.wisc.edu    Addr vpn = VA_VPN(vaddr);
1372SN/A    DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vpn, pte.ppn);
1385712Shsul@eecs.umich.edu
1395712Shsul@eecs.umich.edu    table[nlu] = pte;
1405712Shsul@eecs.umich.edu    table[nlu].tag = vpn;
1415712Shsul@eecs.umich.edu    table[nlu].valid = true;
1425712Shsul@eecs.umich.edu
1432SN/A    lookupTable.insert(make_pair(vpn, nlu));
1442SN/A    nextnlu();
1452SN/A}
14610190Sakash.bagdia@arm.com
14710190Sakash.bagdia@arm.comvoid
1485712Shsul@eecs.umich.eduAlphaTlb::flushAll()
1496221Snate@binkert.org{
1506221Snate@binkert.org    memset(table, 0, sizeof(AlphaISA::PTE[size]));
1512SN/A    lookupTable.clear();
1522SN/A    nlu = 0;
1536221Snate@binkert.org}
1546221Snate@binkert.org
1556221Snate@binkert.orgvoid
1566221Snate@binkert.orgAlphaTlb::flushProcesses()
1572SN/A{
1582SN/A    PageTable::iterator i = lookupTable.begin();
1592SN/A    PageTable::iterator end = lookupTable.end();
1602SN/A    while (i != end) {
1615606Snate@binkert.org        int index = i->second;
1625606Snate@binkert.org        AlphaISA::PTE *pte = &table[index];
1639749Sandreas@sandberg.pp.se        assert(pte->valid);
1649749Sandreas@sandberg.pp.se
1655606Snate@binkert.org        if (!pte->asma) {
1662SN/A            DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn);
1679647Sdam.sunwoo@arm.com            pte->valid = false;
1689647Sdam.sunwoo@arm.com            lookupTable.erase(i);
1699647Sdam.sunwoo@arm.com        }
1709647Sdam.sunwoo@arm.com
1719647Sdam.sunwoo@arm.com        ++i;
1729647Sdam.sunwoo@arm.com    }
1739749Sandreas@sandberg.pp.se}
1749749Sandreas@sandberg.pp.se
1759647Sdam.sunwoo@arm.comvoid
1769647Sdam.sunwoo@arm.comAlphaTlb::flushAddr(Addr vaddr, uint8_t asn)
1771400SN/A{
1785606Snate@binkert.org    Addr vpn = VA_VPN(vaddr);
1795606Snate@binkert.org
1802SN/A    PageTable::iterator i = lookupTable.find(vpn);
1812SN/A    if (i == lookupTable.end())
1822SN/A        return;
1832SN/A
1846221Snate@binkert.org    while (i->first == vpn) {
1856221Snate@binkert.org        int index = i->second;
1865606Snate@binkert.org        AlphaISA::PTE *pte = &table[index];
1876670Shsul@eecs.umich.edu        assert(pte->valid);
1885606Snate@binkert.org
1892SN/A        if (vpn == pte->tag && (pte->asma || pte->asn == asn)) {
1902SN/A            DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vpn, pte->ppn);
191124SN/A
1926221Snate@binkert.org            // invalidate this entry
1936221Snate@binkert.org            pte->valid = false;
1946221Snate@binkert.org
195124SN/A            lookupTable.erase(i);
196124SN/A        }
197124SN/A
198124SN/A        ++i;
1995606Snate@binkert.org    }
2005606Snate@binkert.org}
2019749Sandreas@sandberg.pp.se
2029749Sandreas@sandberg.pp.se
2035606Snate@binkert.orgvoid
204124SN/AAlphaTlb::serialize(ostream &os)
2051400SN/A{
2065606Snate@binkert.org    SERIALIZE_SCALAR(size);
207124SN/A    SERIALIZE_SCALAR(nlu);
208124SN/A
209124SN/A    for (int i = 0; i < size; i++) {
210124SN/A        nameOut(os, csprintf("%s.PTE%d", name(), i));
2116221Snate@binkert.org        table[i].serialize(os);
2126221Snate@binkert.org    }
2135606Snate@binkert.org}
2146221Snate@binkert.org
2155606Snate@binkert.orgvoid
216124SN/AAlphaTlb::unserialize(Checkpoint *cp, const string &section)
217124SN/A{
2181191SN/A    UNSERIALIZE_SCALAR(size);
2195529Snate@binkert.org    UNSERIALIZE_SCALAR(nlu);
2208634Schris.emmons@arm.com
2218634Schris.emmons@arm.com    for (int i = 0; i < size; i++) {
2228634Schris.emmons@arm.com        table[i].unserialize(cp, csprintf("%s.PTE%d", section, i));
2238634Schris.emmons@arm.com        if (table[i].valid) {
2248634Schris.emmons@arm.com            lookupTable.insert(make_pair(table[i].tag, i));
2251191SN/A        }
2265529Snate@binkert.org    }
2271191SN/A}
2285529Snate@binkert.org
2291191SN/A
2301191SN/A///////////////////////////////////////////////////////////////////////
2315606Snate@binkert.org//
2325606Snate@binkert.org//  Alpha ITB
2335606Snate@binkert.org//
2341191SN/AAlphaItb::AlphaItb(const std::string &name, int size)
2351191SN/A    : AlphaTlb(name, size)
2368876Sandreas.hansson@arm.com{}
2378876Sandreas.hansson@arm.com
2388876Sandreas.hansson@arm.com
2399433SAndreas.Sandberg@ARM.comvoid
2408876Sandreas.hansson@arm.comAlphaItb::regStats()
2418876Sandreas.hansson@arm.com{
2428876Sandreas.hansson@arm.com    hits
2438876Sandreas.hansson@arm.com        .name(name() + ".hits")
2448876Sandreas.hansson@arm.com        .desc("ITB hits");
2458876Sandreas.hansson@arm.com    misses
2468876Sandreas.hansson@arm.com        .name(name() + ".misses")
2475810Sgblack@eecs.umich.edu        .desc("ITB misses");
2488779Sgblack@eecs.umich.edu    acv
2498779Sgblack@eecs.umich.edu        .name(name() + ".acv")
2508779Sgblack@eecs.umich.edu        .desc("ITB acv");
2518779Sgblack@eecs.umich.edu    accesses
2525529Snate@binkert.org        .name(name() + ".accesses")
2539384SAndreas.Sandberg@arm.com        .desc("ITB accesses");
2549384SAndreas.Sandberg@arm.com
2559384SAndreas.Sandberg@arm.com    accesses = hits + misses;
2569384SAndreas.Sandberg@arm.com}
2579384SAndreas.Sandberg@arm.com
2581917SN/Avoid
2591191SN/AAlphaItb::fault(Addr pc, ExecContext *xc) const
2601191SN/A{
2611191SN/A    uint64_t *ipr = xc->regs.ipr;
2621191SN/A
2631191SN/A    if (!xc->misspeculating()) {
2641191SN/A        ipr[AlphaISA::IPR_ITB_TAG] = pc;
2651191SN/A        ipr[AlphaISA::IPR_IFAULT_VA_FORM] =
2661191SN/A            ipr[AlphaISA::IPR_IVPTBR] | (VA_VPN(pc) << 3);
2671191SN/A    }
2689086Sandreas.hansson@arm.com}
2699086Sandreas.hansson@arm.com
2709086Sandreas.hansson@arm.com
2711191SN/AFault
2721191SN/AAlphaItb::translate(MemReqPtr &req) const
2731129SN/A{
27410529Smorr@cs.wisc.edu    InternalProcReg *ipr = req->xc->regs.ipr;
27510529Smorr@cs.wisc.edu
27610529Smorr@cs.wisc.edu    if (PC_PAL(req->vaddr)) {
27710529Smorr@cs.wisc.edu        // strip off PAL PC marker (lsb is 1)
27810529Smorr@cs.wisc.edu        req->paddr = (req->vaddr & ~3) & PA_IMPL_MASK;
27910529Smorr@cs.wisc.edu        hits++;
28010529Smorr@cs.wisc.edu        return No_Fault;
28110529Smorr@cs.wisc.edu    }
28210529Smorr@cs.wisc.edu
28310529Smorr@cs.wisc.edu    // verify that this is a good virtual address
28410529Smorr@cs.wisc.edu    if (!validVirtualAddress(req->vaddr)) {
28510529Smorr@cs.wisc.edu        fault(req->vaddr, req->xc);
28610529Smorr@cs.wisc.edu        acv++;
28710529Smorr@cs.wisc.edu        return Itb_Acv_Fault;
28810529Smorr@cs.wisc.edu    }
28910529Smorr@cs.wisc.edu
29010529Smorr@cs.wisc.edu    // Check for "superpage" mapping: when SP<1> is set, and
29110529Smorr@cs.wisc.edu    // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>.
29210529Smorr@cs.wisc.edu    if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) &&
29310529Smorr@cs.wisc.edu        VA_SPACE(req->vaddr) == 2) {
29410529Smorr@cs.wisc.edu        // only valid in kernel mode
29510529Smorr@cs.wisc.edu        if (ICM_CM(ipr[AlphaISA::IPR_ICM]) != AlphaISA::mode_kernel) {
29610529Smorr@cs.wisc.edu            fault(req->vaddr, req->xc);
29710529Smorr@cs.wisc.edu            acv++;
29810529Smorr@cs.wisc.edu            return Itb_Acv_Fault;
29910529Smorr@cs.wisc.edu        }
30010529Smorr@cs.wisc.edu
30110529Smorr@cs.wisc.edu        req->flags |= PHYSICAL;
30210529Smorr@cs.wisc.edu    }
30310529Smorr@cs.wisc.edu
30410529Smorr@cs.wisc.edu    if (req->flags & PHYSICAL) {
30510529Smorr@cs.wisc.edu        req->paddr = req->vaddr & PA_IMPL_MASK;
30610529Smorr@cs.wisc.edu    } else {
30710529Smorr@cs.wisc.edu        // not a physical address: need to look up pte
30810529Smorr@cs.wisc.edu
30910529Smorr@cs.wisc.edu        AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr),
31010529Smorr@cs.wisc.edu                                DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]));
31110529Smorr@cs.wisc.edu
31210529Smorr@cs.wisc.edu        if (!pte) {
31310529Smorr@cs.wisc.edu            fault(req->vaddr, req->xc);
31410529Smorr@cs.wisc.edu            misses++;
31510529Smorr@cs.wisc.edu            return Itb_Fault_Fault;
31610529Smorr@cs.wisc.edu        }
31710529Smorr@cs.wisc.edu
31810529Smorr@cs.wisc.edu        req->paddr = PA_PFN2PA(pte->ppn) + VA_POFS(req->vaddr & ~3);
31910529Smorr@cs.wisc.edu
32010529Smorr@cs.wisc.edu        // check permissions for this access
32110529Smorr@cs.wisc.edu        if (!(pte->xre & (1 << ICM_CM(ipr[AlphaISA::IPR_ICM])))) {
32210529Smorr@cs.wisc.edu            // instruction access fault
32310529Smorr@cs.wisc.edu            fault(req->vaddr, req->xc);
32410529Smorr@cs.wisc.edu            acv++;
32510529Smorr@cs.wisc.edu            return Itb_Acv_Fault;
32610529Smorr@cs.wisc.edu        }
32710529Smorr@cs.wisc.edu    }
32810529Smorr@cs.wisc.edu
32910529Smorr@cs.wisc.edu    checkCacheability(req);
33010529Smorr@cs.wisc.edu
3311129SN/A    hits++;
3321129SN/A    return No_Fault;
3339523SAndreas.Sandberg@ARM.com}
3342680Sktlim@umich.edu
3359523SAndreas.Sandberg@ARM.com///////////////////////////////////////////////////////////////////////
3369523SAndreas.Sandberg@ARM.com//
3379523SAndreas.Sandberg@ARM.com//  Alpha DTB
3381129SN/A//
339180SN/AAlphaDtb::AlphaDtb(const std::string &name, int size)
3402SN/A    : AlphaTlb(name, size)
3411917SN/A{}
3421917SN/A
3438779Sgblack@eecs.umich.eduvoid
3449433SAndreas.Sandberg@ARM.comAlphaDtb::regStats()
3458779Sgblack@eecs.umich.edu{
3468779Sgblack@eecs.umich.edu    read_hits
3472356SN/A        .name(name() + ".read_hits")
3485529Snate@binkert.org        .desc("DTB read hits")
3499179Sandreas.hansson@arm.com        ;
3502356SN/A
3511917SN/A    read_misses
3521917SN/A        .name(name() + ".read_misses")
35310464SAndreas.Sandberg@ARM.com        .desc("DTB read misses")
35410464SAndreas.Sandberg@ARM.com        ;
35510464SAndreas.Sandberg@ARM.com
35610464SAndreas.Sandberg@ARM.com    read_acv
35710464SAndreas.Sandberg@ARM.com        .name(name() + ".read_acv")
35810464SAndreas.Sandberg@ARM.com        .desc("DTB read access violations")
35910464SAndreas.Sandberg@ARM.com        ;
36010464SAndreas.Sandberg@ARM.com
36110464SAndreas.Sandberg@ARM.com    read_accesses
36210464SAndreas.Sandberg@ARM.com        .name(name() + ".read_accesses")
36310464SAndreas.Sandberg@ARM.com        .desc("DTB read accesses")
36410464SAndreas.Sandberg@ARM.com        ;
36510464SAndreas.Sandberg@ARM.com
36610464SAndreas.Sandberg@ARM.com    write_hits
36710464SAndreas.Sandberg@ARM.com        .name(name() + ".write_hits")
36810464SAndreas.Sandberg@ARM.com        .desc("DTB write hits")
36910464SAndreas.Sandberg@ARM.com        ;
37010464SAndreas.Sandberg@ARM.com
37110464SAndreas.Sandberg@ARM.com    write_misses
37210464SAndreas.Sandberg@ARM.com        .name(name() + ".write_misses")
37310464SAndreas.Sandberg@ARM.com        .desc("DTB write misses")
37410464SAndreas.Sandberg@ARM.com        ;
37510464SAndreas.Sandberg@ARM.com
37610464SAndreas.Sandberg@ARM.com    write_acv
37710464SAndreas.Sandberg@ARM.com        .name(name() + ".write_acv")
37810464SAndreas.Sandberg@ARM.com        .desc("DTB write access violations")
37910464SAndreas.Sandberg@ARM.com        ;
38010464SAndreas.Sandberg@ARM.com
38110464SAndreas.Sandberg@ARM.com    write_accesses
38210464SAndreas.Sandberg@ARM.com        .name(name() + ".write_accesses")
38310464SAndreas.Sandberg@ARM.com        .desc("DTB write accesses")
38410643Snikos.nikoleris@gmail.com        ;
38510464SAndreas.Sandberg@ARM.com
38610464SAndreas.Sandberg@ARM.com    hits
38710464SAndreas.Sandberg@ARM.com        .name(name() + ".hits")
38810464SAndreas.Sandberg@ARM.com        .desc("DTB hits")
3891917SN/A        ;
3901917SN/A
3912SN/A    misses
3922SN/A        .name(name() + ".misses")
393729SN/A        .desc("DTB misses")
394707SN/A        ;
395707SN/A
396707SN/A    acv
397707SN/A        .name(name() + ".acv")
398707SN/A        .desc("DTB access violations")
399707SN/A        ;
4007914SBrad.Beckmann@amd.com
4017914SBrad.Beckmann@amd.com    accesses
4027914SBrad.Beckmann@amd.com        .name(name() + ".accesses")
4037914SBrad.Beckmann@amd.com        .desc("DTB accesses")
4047914SBrad.Beckmann@amd.com        ;
4057914SBrad.Beckmann@amd.com
4067914SBrad.Beckmann@amd.com    hits = read_hits + write_hits;
4077914SBrad.Beckmann@amd.com    misses = read_misses + write_misses;
4087914SBrad.Beckmann@amd.com    acv = read_acv + write_acv;
4097914SBrad.Beckmann@amd.com    accesses = read_accesses + write_accesses;
4102680Sktlim@umich.edu}
4112SN/A
4122SN/Avoid
4132SN/AAlphaDtb::fault(Addr vaddr, uint64_t flags, ExecContext *xc) const
4142SN/A{
4152680Sktlim@umich.edu    uint64_t *ipr = xc->regs.ipr;
4162SN/A
4172SN/A    // set fault address and flags
4182680Sktlim@umich.edu    if (!xc->misspeculating() && !xc->regs.intrlock) {
4192SN/A        // set VA register with faulting address
4202SN/A        ipr[AlphaISA::IPR_VA] = vaddr;
4219294Sandreas.hansson@arm.com
4229294Sandreas.hansson@arm.com        // set MM_STAT register flags
4238850Sandreas.hansson@arm.com        ipr[AlphaISA::IPR_MM_STAT] = (((xc->regs.opcode & 0x3f) << 11)
4248850Sandreas.hansson@arm.com                               | ((xc->regs.ra & 0x1f) << 6)
4258850Sandreas.hansson@arm.com                               | (flags & 0x3f));
4268850Sandreas.hansson@arm.com
4279608Sandreas.hansson@arm.com        // set VA_FORM register with faulting formatted address
4288850Sandreas.hansson@arm.com        ipr[AlphaISA::IPR_VA_FORM] =
4298922Swilliam.wang@arm.com            ipr[AlphaISA::IPR_MVPTBR] | (VA_VPN(vaddr) << 3);
4308850Sandreas.hansson@arm.com
4318922Swilliam.wang@arm.com        // lock these registers until the VA register is read
4328850Sandreas.hansson@arm.com        xc->regs.intrlock = true;
4338922Swilliam.wang@arm.com    }
4348850Sandreas.hansson@arm.com}
4358850Sandreas.hansson@arm.com
436180SN/AFault
4372680Sktlim@umich.eduAlphaDtb::translate(MemReqPtr &req, bool write) const
438180SN/A{
4396221Snate@binkert.org    RegFile *regs = &req->xc->regs;
4406221Snate@binkert.org    Addr pc = regs->pc;
4416221Snate@binkert.org    InternalProcReg *ipr = regs->ipr;
4422378SN/A
4435718Shsul@eecs.umich.edu    if (write)
4445718Shsul@eecs.umich.edu        write_accesses++;
4455718Shsul@eecs.umich.edu    else
4465718Shsul@eecs.umich.edu        read_accesses++;
4475718Shsul@eecs.umich.edu
4485718Shsul@eecs.umich.edu    AlphaISA::mode_type mode =
4495718Shsul@eecs.umich.edu        (AlphaISA::mode_type)DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]);
4506221Snate@binkert.org
4515718Shsul@eecs.umich.edu    if (PC_PAL(pc)) {
4525718Shsul@eecs.umich.edu        mode = (req->flags & ALTMODE) ?
4535718Shsul@eecs.umich.edu            (AlphaISA::mode_type)ALT_MODE_AM(ipr[AlphaISA::IPR_ALT_MODE])
4548779Sgblack@eecs.umich.edu            : AlphaISA::mode_kernel;
4558779Sgblack@eecs.umich.edu    }
4568779Sgblack@eecs.umich.edu
457180SN/A    // verify that this is a good virtual address
458180SN/A    if (!validVirtualAddress(req->vaddr)) {
459180SN/A        fault(req->vaddr,
460180SN/A              ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_BAD_VA_MASK |
4614000Ssaidi@eecs.umich.edu               MM_STAT_ACV_MASK),
4624000Ssaidi@eecs.umich.edu              req->xc);
4634000Ssaidi@eecs.umich.edu
4646221Snate@binkert.org        if (write) { write_acv++; } else { read_acv++; }
4656221Snate@binkert.org        return Dtb_Fault_Fault;
4666221Snate@binkert.org    }
4676221Snate@binkert.org
4684000Ssaidi@eecs.umich.edu    // Check for "superpage" mapping: when SP<1> is set, and
4694000Ssaidi@eecs.umich.edu    // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>.
4704000Ssaidi@eecs.umich.edu    if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && VA_SPACE(req->vaddr) == 2) {
4714000Ssaidi@eecs.umich.edu        // only valid in kernel mode
472180SN/A        if (DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]) != AlphaISA::mode_kernel) {
4732798Sktlim@umich.edu            fault(req->vaddr,
474180SN/A                  ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK),
4759430SAndreas.Sandberg@ARM.com                  req->xc);
4769430SAndreas.Sandberg@ARM.com            if (write) { write_acv++; } else { read_acv++; }
4772359SN/A            return Dtb_Acv_Fault;
4785606Snate@binkert.org        }
4799446SAndreas.Sandberg@ARM.com
4809446SAndreas.Sandberg@ARM.com        req->flags |= PHYSICAL;
4819446SAndreas.Sandberg@ARM.com    }
4829446SAndreas.Sandberg@ARM.com
483180SN/A    if (req->flags & PHYSICAL) {
484180SN/A        req->paddr = req->vaddr & PA_IMPL_MASK;
485180SN/A    } else {
4868737Skoansin.tan@gmail.com        // not a physical address: need to look up pte
487180SN/A
4882680Sktlim@umich.edu        AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr),
4899152Satgutier@umich.edu                                DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]));
4909430SAndreas.Sandberg@ARM.com
4919430SAndreas.Sandberg@ARM.com        if (!pte) {
4929332Sdam.sunwoo@arm.com            // page fault
4939332Sdam.sunwoo@arm.com            fault(req->vaddr,
4949430SAndreas.Sandberg@ARM.com                  ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_DTB_MISS_MASK),
4955712Shsul@eecs.umich.edu                  req->xc);
4966221Snate@binkert.org            if (write) { write_misses++; } else { read_misses++; }
4976221Snate@binkert.org            return (req->flags & VPTE) ? Pdtb_Miss_Fault : Ndtb_Miss_Fault;
4982680Sktlim@umich.edu        }
4992680Sktlim@umich.edu
500180SN/A        req->paddr = PA_PFN2PA(pte->ppn) | VA_POFS(req->vaddr);
5012680Sktlim@umich.edu
5022651Ssaidi@eecs.umich.edu        if (write) {
5032680Sktlim@umich.edu            if (!(pte->xwe & MODE2MASK(mode))) {
5042651Ssaidi@eecs.umich.edu                // declare the instruction access fault
5055714Shsul@eecs.umich.edu                fault(req->vaddr, MM_STAT_WR_MASK | MM_STAT_ACV_MASK |
5065715Shsul@eecs.umich.edu                      (pte->fonw ? MM_STAT_FONW_MASK : 0),
5075714Shsul@eecs.umich.edu                      req->xc);
5082359SN/A                write_acv++;
5095875Ssteve.reinhardt@amd.com                return Dtb_Fault_Fault;
5105875Ssteve.reinhardt@amd.com            }
5115875Ssteve.reinhardt@amd.com            if (pte->fonw) {
5125875Ssteve.reinhardt@amd.com                fault(req->vaddr, MM_STAT_WR_MASK | MM_STAT_FONW_MASK,
5135217Ssaidi@eecs.umich.edu                      req->xc);
5145875Ssteve.reinhardt@amd.com                write_acv++;
5157781SAli.Saidi@ARM.com                return Dtb_Fault_Fault;
5169294Sandreas.hansson@arm.com            }
5179294Sandreas.hansson@arm.com        } else {
5189294Sandreas.hansson@arm.com            if (!(pte->xre & MODE2MASK(mode))) {
5199294Sandreas.hansson@arm.com                fault(req->vaddr,
5207781SAli.Saidi@ARM.com                      MM_STAT_ACV_MASK | (pte->fonr ? MM_STAT_FONR_MASK : 0),
5217781SAli.Saidi@ARM.com                      req->xc);
5229178Sandreas.hansson@arm.com                read_acv++;
5239178Sandreas.hansson@arm.com                return Dtb_Acv_Fault;
5247781SAli.Saidi@ARM.com            }
5259178Sandreas.hansson@arm.com            if (pte->fonr) {
5269294Sandreas.hansson@arm.com                fault(req->vaddr, MM_STAT_FONR_MASK, req->xc);
5279178Sandreas.hansson@arm.com                read_acv++;
5288922Swilliam.wang@arm.com                return Dtb_Fault_Fault;
5297781SAli.Saidi@ARM.com            }
5309178Sandreas.hansson@arm.com        }
5319178Sandreas.hansson@arm.com    }
5327781SAli.Saidi@ARM.com
5339178Sandreas.hansson@arm.com    checkCacheability(req);
5349294Sandreas.hansson@arm.com
5359178Sandreas.hansson@arm.com    if (write)
5368922Swilliam.wang@arm.com        write_hits++;
5377781SAli.Saidi@ARM.com    else
53810194SGeoffrey.Blake@arm.com        read_hits++;
53910194SGeoffrey.Blake@arm.com
5408733Sgeoffrey.blake@arm.com    return No_Fault;
5418887Sgeoffrey.blake@arm.com}
5428887Sgeoffrey.blake@arm.com
5438887Sgeoffrey.blake@arm.comAlphaISA::PTE &
5448887Sgeoffrey.blake@arm.comAlphaTlb::index()
5458887Sgeoffrey.blake@arm.com{
5469294Sandreas.hansson@arm.com    AlphaISA::PTE *pte = &table[nlu];
5478922Swilliam.wang@arm.com    nextnlu();
5489294Sandreas.hansson@arm.com
5498922Swilliam.wang@arm.com    return *pte;
5509294Sandreas.hansson@arm.com}
5518922Swilliam.wang@arm.com
5529294Sandreas.hansson@arm.comBEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaItb)
5538922Swilliam.wang@arm.com
5548733Sgeoffrey.blake@arm.com    Param<int> size;
55510194SGeoffrey.Blake@arm.com
55610194SGeoffrey.Blake@arm.comEND_DECLARE_SIM_OBJECT_PARAMS(AlphaItb)
55710194SGeoffrey.Blake@arm.com
5588887Sgeoffrey.blake@arm.comBEGIN_INIT_SIM_OBJECT_PARAMS(AlphaItb)
5599178Sandreas.hansson@arm.com
5609178Sandreas.hansson@arm.com    INIT_PARAM_DFLT(size, "TLB size", 48)
5618887Sgeoffrey.blake@arm.com
5629178Sandreas.hansson@arm.comEND_INIT_SIM_OBJECT_PARAMS(AlphaItb)
5639294Sandreas.hansson@arm.com
5649294Sandreas.hansson@arm.com
5659178Sandreas.hansson@arm.comCREATE_SIM_OBJECT(AlphaItb)
5668922Swilliam.wang@arm.com{
5678887Sgeoffrey.blake@arm.com    return new AlphaItb(getInstanceName(), size);
5689178Sandreas.hansson@arm.com}
5699178Sandreas.hansson@arm.com
5708887Sgeoffrey.blake@arm.comREGISTER_SIM_OBJECT("AlphaITB", AlphaItb)
5719178Sandreas.hansson@arm.com
5729294Sandreas.hansson@arm.comBEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaDtb)
5739294Sandreas.hansson@arm.com
5749178Sandreas.hansson@arm.com    Param<int> size;
5758922Swilliam.wang@arm.com
5768887Sgeoffrey.blake@arm.comEND_DECLARE_SIM_OBJECT_PARAMS(AlphaDtb)
5778733Sgeoffrey.blake@arm.com
578180SN/ABEGIN_INIT_SIM_OBJECT_PARAMS(AlphaDtb)
579605SN/A
5803520Sgblack@eecs.umich.edu    INIT_PARAM_DFLT(size, "TLB size", 64)
5815810Sgblack@eecs.umich.edu
5829152Satgutier@umich.eduEND_INIT_SIM_OBJECT_PARAMS(AlphaDtb)
5832254SN/A
5848779Sgblack@eecs.umich.edu
5858779Sgblack@eecs.umich.eduCREATE_SIM_OBJECT(AlphaDtb)
5868779Sgblack@eecs.umich.edu{
5872254SN/A    return new AlphaDtb(getInstanceName(), size);
5888779Sgblack@eecs.umich.edu}
5898779Sgblack@eecs.umich.edu
5908779Sgblack@eecs.umich.eduREGISTER_SIM_OBJECT("AlphaDTB", AlphaDtb)
5914192Sktlim@umich.edu
5929178Sandreas.hansson@arm.com