tlb.cc revision 828
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/A
481388SN/A#ifdef DEBUG
498229Snate@binkert.org    bool uncacheBit39 = false;
502SN/A    bool uncacheBit40 = false;
512SN/A#endif
527781SAli.Saidi@ARM.com
538229Snate@binkert.orgAlphaTlb::AlphaTlb(const string &name, int s)
541191SN/A    : SimObject(name), size(s), nlu(0)
551191SN/A{
561388SN/A    table = new AlphaISA::PTE[size];
575529Snate@binkert.org    memset(table, 0, sizeof(AlphaISA::PTE[size]));
5810529Smorr@cs.wisc.edu}
591717SN/A
602651Ssaidi@eecs.umich.eduAlphaTlb::~AlphaTlb()
618229Snate@binkert.org{
622680Sktlim@umich.edu    if (table)
6310529Smorr@cs.wisc.edu        delete [] table;
648232Snate@binkert.org}
6510529Smorr@cs.wisc.edu
665529Snate@binkert.org// look up an entry in the TLB
678779Sgblack@eecs.umich.eduAlphaISA::PTE *
682190SN/AAlphaTlb::lookup(Addr vpn, uint8_t asn) const
6956SN/A{
708229Snate@binkert.org    DPRINTF(TLB, "lookup %#x\n", vpn);
712190SN/A
722SN/A    PageTable::const_iterator i = lookupTable.find(vpn);
732359SN/A    if (i == lookupTable.end())
742359SN/A        return NULL;
752359SN/A
762SN/A    while (i->first == vpn) {
772SN/A        int index = i->second;
782SN/A        AlphaISA::PTE *pte = &table[index];
792SN/A        assert(pte->valid);
802SN/A        if (vpn == pte->tag && (pte->asma || pte->asn == asn))
812SN/A            return pte;
822SN/A
832SN/A        ++i;
842SN/A    }
855606Snate@binkert.org
866144Sksewell@umich.edu    // not found...
876144Sksewell@umich.edu    return NULL;
883126Sktlim@umich.edu}
896144Sksewell@umich.edu
907823Ssteve.reinhardt@amd.com
913126Sktlim@umich.eduvoid
923126Sktlim@umich.eduAlphaTlb::checkCacheability(MemReqPtr &req)
932356SN/A{
942356SN/A    // in Alpha, cacheability is controlled by upper-level bits of the
952356SN/A    // physical address
968834Satgutier@umich.edu
9710786Smalek.musleh@gmail.com    /*
9810786Smalek.musleh@gmail.com     * We support having the uncacheable bit in either bit 39 or bit 40.
9910786Smalek.musleh@gmail.com     * The Turbolaser platform (and EV5) support having the bit in 39, but
10010786Smalek.musleh@gmail.com     * Tsunami (which Linux assumes uses an EV6) generates accesses with
10110786Smalek.musleh@gmail.com     * the bit in 40.  So we must check for both, but we have debug flags
10210786Smalek.musleh@gmail.com     * to catch a weird case where both are used, which shouldn't happen.
10310786Smalek.musleh@gmail.com     */
10410786Smalek.musleh@gmail.com
1052356SN/A    if (req->paddr & PA_UNCACHED_BIT_40 ||
1069179Sandreas.hansson@arm.com        req->paddr & PA_UNCACHED_BIT_39) {
1072367SN/A
1086144Sksewell@umich.edu#ifdef DEBUG
1096144Sksewell@umich.edu        if (req->paddr & PA_UNCACHED_BIT_40) {
1106144Sksewell@umich.edu            if(uncacheBit39)
1112356SN/A                panic("Bit 40 access follows bit 39 access, PA=%x\n",
1122367SN/A                      req->paddr);
1136144Sksewell@umich.edu
1147823Ssteve.reinhardt@amd.com            uncacheBit40 = true;
1156144Sksewell@umich.edu        } else if (req->paddr & PA_UNCACHED_BIT_39) {
1162367SN/A            if(uncacheBit40)
1172356SN/A                panic("Bit 39 acceess follows bit 40 access, PA=%x\n",
1182356SN/A                      req->paddr);
1192356SN/A
1202356SN/A            uncacheBit39 = true;
1215336Shines@cs.fsu.edu        }
1222356SN/A#endif
1234873Sstever@eecs.umich.edu
1242356SN/A        // IPR memory space not implemented
1252356SN/A        if (PA_IPR_SPACE(req->paddr))
1268876Sandreas.hansson@arm.com            if (!req->xc->misspeculating())
12710190Sakash.bagdia@arm.com                panic("IPR memory space not implemented! PA=%x\n",
1288832SAli.Saidi@ARM.com                      req->paddr);
1298832SAli.Saidi@ARM.com
1309332Sdam.sunwoo@arm.com        // mark request as uncacheable
1319814Sandreas.hansson@arm.com        req->flags |= UNCACHEABLE;
1329220Shestness@cs.wisc.edu    }
13310529Smorr@cs.wisc.edu}
13410537Sandreas.hansson@arm.com
13510537Sandreas.hansson@arm.com
13610529Smorr@cs.wisc.edu// insert a new TLB entry
1372SN/Avoid
1385712Shsul@eecs.umich.eduAlphaTlb::insert(Addr vaddr, AlphaISA::PTE &pte)
1395712Shsul@eecs.umich.edu{
1405712Shsul@eecs.umich.edu    if (table[nlu].valid) {
1415712Shsul@eecs.umich.edu        Addr oldvpn = table[nlu].tag;
1425712Shsul@eecs.umich.edu        PageTable::iterator i = lookupTable.find(oldvpn);
1432SN/A
1442SN/A        if (i == lookupTable.end())
1452SN/A            panic("TLB entry not found in lookupTable");
14610190Sakash.bagdia@arm.com
14710190Sakash.bagdia@arm.com        int index;
1485712Shsul@eecs.umich.edu        while ((index = i->second) != nlu) {
1496221Snate@binkert.org            if (table[index].tag != oldvpn)
1506221Snate@binkert.org                panic("TLB entry not found in lookupTable");
1512SN/A
1522SN/A            ++i;
1536221Snate@binkert.org        }
1546221Snate@binkert.org
1556221Snate@binkert.org        DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn);
1566221Snate@binkert.org
1572SN/A        lookupTable.erase(i);
1582SN/A    }
1592SN/A
1602SN/A    Addr vpn = VA_VPN(vaddr);
1615606Snate@binkert.org    DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vpn, pte.ppn);
1625606Snate@binkert.org
1639749Sandreas@sandberg.pp.se    table[nlu] = pte;
1649749Sandreas@sandberg.pp.se    table[nlu].tag = vpn;
1655606Snate@binkert.org    table[nlu].valid = true;
1662SN/A
1679647Sdam.sunwoo@arm.com    lookupTable.insert(make_pair(vpn, nlu));
1689647Sdam.sunwoo@arm.com    nextnlu();
1699647Sdam.sunwoo@arm.com}
1709647Sdam.sunwoo@arm.com
1719647Sdam.sunwoo@arm.comvoid
1729647Sdam.sunwoo@arm.comAlphaTlb::flushAll()
1739749Sandreas@sandberg.pp.se{
1749749Sandreas@sandberg.pp.se    memset(table, 0, sizeof(AlphaISA::PTE[size]));
1759647Sdam.sunwoo@arm.com    lookupTable.clear();
1769647Sdam.sunwoo@arm.com    nlu = 0;
1771400SN/A}
1785606Snate@binkert.org
1795606Snate@binkert.orgvoid
1802SN/AAlphaTlb::flushProcesses()
1812SN/A{
1822SN/A    PageTable::iterator i = lookupTable.begin();
1832SN/A    PageTable::iterator end = lookupTable.end();
1846221Snate@binkert.org    while (i != end) {
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 (!pte->asma) {
1902SN/A            DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn);
191124SN/A            pte->valid = false;
1926221Snate@binkert.org            lookupTable.erase(i);
1936221Snate@binkert.org        }
1946221Snate@binkert.org
195124SN/A        ++i;
196124SN/A    }
197124SN/A}
198124SN/A
1995606Snate@binkert.orgvoid
2005606Snate@binkert.orgAlphaTlb::flushAddr(Addr vaddr, uint8_t asn)
2019749Sandreas@sandberg.pp.se{
2029749Sandreas@sandberg.pp.se    Addr vpn = VA_VPN(vaddr);
2035606Snate@binkert.org
204124SN/A    PageTable::iterator i = lookupTable.find(vpn);
2051400SN/A    if (i == lookupTable.end())
2065606Snate@binkert.org        return;
207124SN/A
208124SN/A    while (i->first == vpn) {
209124SN/A        int index = i->second;
210124SN/A        AlphaISA::PTE *pte = &table[index];
2116221Snate@binkert.org        assert(pte->valid);
2126221Snate@binkert.org
2135606Snate@binkert.org        if (vpn == pte->tag && (pte->asma || pte->asn == asn)) {
2146221Snate@binkert.org            DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vpn, pte->ppn);
2155606Snate@binkert.org
216124SN/A            // invalidate this entry
217124SN/A            pte->valid = false;
2181191SN/A
2195529Snate@binkert.org            lookupTable.erase(i);
2208634Schris.emmons@arm.com        }
2218634Schris.emmons@arm.com
2228634Schris.emmons@arm.com        ++i;
2238634Schris.emmons@arm.com    }
2248634Schris.emmons@arm.com}
2251191SN/A
2265529Snate@binkert.org
2271191SN/Avoid
2285529Snate@binkert.orgAlphaTlb::serialize(ostream &os)
2291191SN/A{
2301191SN/A    SERIALIZE_SCALAR(size);
2315606Snate@binkert.org    SERIALIZE_SCALAR(nlu);
2325606Snate@binkert.org
2335606Snate@binkert.org    for (int i = 0; i < size; i++) {
2341191SN/A        nameOut(os, csprintf("%s.PTE%d", name(), i));
2351191SN/A        table[i].serialize(os);
2368876Sandreas.hansson@arm.com    }
2378876Sandreas.hansson@arm.com}
2388876Sandreas.hansson@arm.com
2399433SAndreas.Sandberg@ARM.comvoid
2408876Sandreas.hansson@arm.comAlphaTlb::unserialize(Checkpoint *cp, const string &section)
2418876Sandreas.hansson@arm.com{
2428876Sandreas.hansson@arm.com    UNSERIALIZE_SCALAR(size);
2438876Sandreas.hansson@arm.com    UNSERIALIZE_SCALAR(nlu);
2448876Sandreas.hansson@arm.com
2458876Sandreas.hansson@arm.com    for (int i = 0; i < size; i++) {
2468876Sandreas.hansson@arm.com        table[i].unserialize(cp, csprintf("%s.PTE%d", section, i));
2475810Sgblack@eecs.umich.edu        if (table[i].valid) {
2488779Sgblack@eecs.umich.edu            lookupTable.insert(make_pair(table[i].tag, i));
2498779Sgblack@eecs.umich.edu        }
2508779Sgblack@eecs.umich.edu    }
2518779Sgblack@eecs.umich.edu}
2525529Snate@binkert.org
2539384SAndreas.Sandberg@arm.com
2549384SAndreas.Sandberg@arm.com///////////////////////////////////////////////////////////////////////
2559384SAndreas.Sandberg@arm.com//
2569384SAndreas.Sandberg@arm.com//  Alpha ITB
2579384SAndreas.Sandberg@arm.com//
2581917SN/AAlphaItb::AlphaItb(const std::string &name, int size)
2591191SN/A    : AlphaTlb(name, size)
2601191SN/A{}
2611191SN/A
2621191SN/A
2631191SN/Avoid
2641191SN/AAlphaItb::regStats()
2651191SN/A{
2661191SN/A    hits
2671191SN/A        .name(name() + ".hits")
2689086Sandreas.hansson@arm.com        .desc("ITB hits");
2699086Sandreas.hansson@arm.com    misses
2709086Sandreas.hansson@arm.com        .name(name() + ".misses")
2711191SN/A        .desc("ITB misses");
2721191SN/A    acv
2731129SN/A        .name(name() + ".acv")
27410529Smorr@cs.wisc.edu        .desc("ITB acv");
27510529Smorr@cs.wisc.edu    accesses
27610529Smorr@cs.wisc.edu        .name(name() + ".accesses")
27710529Smorr@cs.wisc.edu        .desc("ITB accesses");
27810529Smorr@cs.wisc.edu
27910529Smorr@cs.wisc.edu    accesses = hits + misses;
28010529Smorr@cs.wisc.edu}
28110529Smorr@cs.wisc.edu
28210529Smorr@cs.wisc.eduvoid
28310529Smorr@cs.wisc.eduAlphaItb::fault(Addr pc, ExecContext *xc) const
28410529Smorr@cs.wisc.edu{
28510529Smorr@cs.wisc.edu    uint64_t *ipr = xc->regs.ipr;
28610529Smorr@cs.wisc.edu
28710529Smorr@cs.wisc.edu    if (!xc->misspeculating()) {
28810529Smorr@cs.wisc.edu        ipr[AlphaISA::IPR_ITB_TAG] = pc;
28910529Smorr@cs.wisc.edu        ipr[AlphaISA::IPR_IFAULT_VA_FORM] =
29010529Smorr@cs.wisc.edu            ipr[AlphaISA::IPR_IVPTBR] | (VA_VPN(pc) << 3);
29110529Smorr@cs.wisc.edu    }
29210529Smorr@cs.wisc.edu}
29310529Smorr@cs.wisc.edu
29410529Smorr@cs.wisc.edu
29510529Smorr@cs.wisc.eduFault
29610529Smorr@cs.wisc.eduAlphaItb::translate(MemReqPtr &req) const
29710529Smorr@cs.wisc.edu{
29810529Smorr@cs.wisc.edu    InternalProcReg *ipr = req->xc->regs.ipr;
29910529Smorr@cs.wisc.edu
30010529Smorr@cs.wisc.edu    if (PC_PAL(req->vaddr)) {
30110529Smorr@cs.wisc.edu        // strip off PAL PC marker (lsb is 1)
30210529Smorr@cs.wisc.edu        req->paddr = (req->vaddr & ~3) & PA_IMPL_MASK;
30310529Smorr@cs.wisc.edu        hits++;
30410529Smorr@cs.wisc.edu        return No_Fault;
30510529Smorr@cs.wisc.edu    }
30610529Smorr@cs.wisc.edu
30710529Smorr@cs.wisc.edu    if (req->flags & PHYSICAL) {
30810529Smorr@cs.wisc.edu        req->paddr = req->vaddr;
30910529Smorr@cs.wisc.edu    } else {
31010529Smorr@cs.wisc.edu        // verify that this is a good virtual address
31110529Smorr@cs.wisc.edu        if (!validVirtualAddress(req->vaddr)) {
31210529Smorr@cs.wisc.edu            fault(req->vaddr, req->xc);
31310529Smorr@cs.wisc.edu            acv++;
31410529Smorr@cs.wisc.edu            return Itb_Acv_Fault;
31510529Smorr@cs.wisc.edu        }
31610529Smorr@cs.wisc.edu
31710529Smorr@cs.wisc.edu        // Check for "superpage" mapping: when SP<1> is set, and
31810529Smorr@cs.wisc.edu        // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>.
31910529Smorr@cs.wisc.edu        if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) &&
32010529Smorr@cs.wisc.edu               VA_SPACE(req->vaddr) == 2) {
32110529Smorr@cs.wisc.edu
32210529Smorr@cs.wisc.edu            // only valid in kernel mode
32310529Smorr@cs.wisc.edu            if (ICM_CM(ipr[AlphaISA::IPR_ICM]) != AlphaISA::mode_kernel) {
32410529Smorr@cs.wisc.edu                fault(req->vaddr, req->xc);
32510529Smorr@cs.wisc.edu                acv++;
32610529Smorr@cs.wisc.edu                return Itb_Acv_Fault;
32710529Smorr@cs.wisc.edu            }
32810529Smorr@cs.wisc.edu
32910529Smorr@cs.wisc.edu            req->paddr = req->vaddr & PA_IMPL_MASK;
33010529Smorr@cs.wisc.edu
3311129SN/A            // sign extend the physical address properly
3321129SN/A            if (req->paddr & PA_UNCACHED_BIT_39 ||
3339523SAndreas.Sandberg@ARM.com                req->paddr & PA_UNCACHED_BIT_40)
3342680Sktlim@umich.edu                req->paddr |= 0xf0000000000;
3359523SAndreas.Sandberg@ARM.com            else
3369523SAndreas.Sandberg@ARM.com                req->paddr &= 0xffffffffff;
3379523SAndreas.Sandberg@ARM.com
3381129SN/A        } else {
339180SN/A            // not a physical address: need to look up pte
3402SN/A            AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr),
3411917SN/A                                 DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]));
3421917SN/A
3438779Sgblack@eecs.umich.edu            if (!pte) {
3449433SAndreas.Sandberg@ARM.com                fault(req->vaddr, req->xc);
3458779Sgblack@eecs.umich.edu                misses++;
3468779Sgblack@eecs.umich.edu                return Itb_Fault_Fault;
3472356SN/A            }
3485529Snate@binkert.org
3499179Sandreas.hansson@arm.com            req->paddr = PA_PFN2PA(pte->ppn) + VA_POFS(req->vaddr & ~3);
3502356SN/A
3511917SN/A            // check permissions for this access
3521917SN/A            if (!(pte->xre & (1 << ICM_CM(ipr[AlphaISA::IPR_ICM])))) {
35310464SAndreas.Sandberg@ARM.com                // instruction access fault
35410464SAndreas.Sandberg@ARM.com                fault(req->vaddr, req->xc);
35510464SAndreas.Sandberg@ARM.com                acv++;
35610464SAndreas.Sandberg@ARM.com                return Itb_Acv_Fault;
35710464SAndreas.Sandberg@ARM.com            }
35810464SAndreas.Sandberg@ARM.com
35910464SAndreas.Sandberg@ARM.com            hits++;
36010464SAndreas.Sandberg@ARM.com        }
36110464SAndreas.Sandberg@ARM.com    }
36210464SAndreas.Sandberg@ARM.com
36310464SAndreas.Sandberg@ARM.com    // check that the physical address is ok (catch bad physical addresses)
36410464SAndreas.Sandberg@ARM.com    if (req->paddr & ~PA_IMPL_MASK)
36510464SAndreas.Sandberg@ARM.com        return Machine_Check_Fault;
36610464SAndreas.Sandberg@ARM.com
36710464SAndreas.Sandberg@ARM.com    checkCacheability(req);
36810464SAndreas.Sandberg@ARM.com
36910464SAndreas.Sandberg@ARM.com    return No_Fault;
37010464SAndreas.Sandberg@ARM.com}
37110464SAndreas.Sandberg@ARM.com
37210464SAndreas.Sandberg@ARM.com///////////////////////////////////////////////////////////////////////
37310464SAndreas.Sandberg@ARM.com//
37410464SAndreas.Sandberg@ARM.com//  Alpha DTB
37510464SAndreas.Sandberg@ARM.com//
37610464SAndreas.Sandberg@ARM.comAlphaDtb::AlphaDtb(const std::string &name, int size)
37710464SAndreas.Sandberg@ARM.com    : AlphaTlb(name, size)
37810464SAndreas.Sandberg@ARM.com{}
37910464SAndreas.Sandberg@ARM.com
38010464SAndreas.Sandberg@ARM.comvoid
38110464SAndreas.Sandberg@ARM.comAlphaDtb::regStats()
38210464SAndreas.Sandberg@ARM.com{
38310464SAndreas.Sandberg@ARM.com    read_hits
38410643Snikos.nikoleris@gmail.com        .name(name() + ".read_hits")
38510464SAndreas.Sandberg@ARM.com        .desc("DTB read hits")
38610464SAndreas.Sandberg@ARM.com        ;
38710464SAndreas.Sandberg@ARM.com
38810464SAndreas.Sandberg@ARM.com    read_misses
3891917SN/A        .name(name() + ".read_misses")
3901917SN/A        .desc("DTB read misses")
3912SN/A        ;
3922SN/A
393729SN/A    read_acv
394707SN/A        .name(name() + ".read_acv")
395707SN/A        .desc("DTB read access violations")
396707SN/A        ;
397707SN/A
398707SN/A    read_accesses
399707SN/A        .name(name() + ".read_accesses")
4007914SBrad.Beckmann@amd.com        .desc("DTB read accesses")
4017914SBrad.Beckmann@amd.com        ;
4027914SBrad.Beckmann@amd.com
4037914SBrad.Beckmann@amd.com    write_hits
4047914SBrad.Beckmann@amd.com        .name(name() + ".write_hits")
4057914SBrad.Beckmann@amd.com        .desc("DTB write hits")
4067914SBrad.Beckmann@amd.com        ;
4077914SBrad.Beckmann@amd.com
4087914SBrad.Beckmann@amd.com    write_misses
4097914SBrad.Beckmann@amd.com        .name(name() + ".write_misses")
4102680Sktlim@umich.edu        .desc("DTB write misses")
4112SN/A        ;
4122SN/A
4132SN/A    write_acv
4142SN/A        .name(name() + ".write_acv")
4152680Sktlim@umich.edu        .desc("DTB write access violations")
4162SN/A        ;
4172SN/A
4182680Sktlim@umich.edu    write_accesses
4192SN/A        .name(name() + ".write_accesses")
4202SN/A        .desc("DTB write accesses")
4219294Sandreas.hansson@arm.com        ;
4229294Sandreas.hansson@arm.com
4238850Sandreas.hansson@arm.com    hits
4248850Sandreas.hansson@arm.com        .name(name() + ".hits")
4258850Sandreas.hansson@arm.com        .desc("DTB hits")
4268850Sandreas.hansson@arm.com        ;
4279608Sandreas.hansson@arm.com
4288850Sandreas.hansson@arm.com    misses
4298922Swilliam.wang@arm.com        .name(name() + ".misses")
4308850Sandreas.hansson@arm.com        .desc("DTB misses")
4318922Swilliam.wang@arm.com        ;
4328850Sandreas.hansson@arm.com
4338922Swilliam.wang@arm.com    acv
4348850Sandreas.hansson@arm.com        .name(name() + ".acv")
4358850Sandreas.hansson@arm.com        .desc("DTB access violations")
436180SN/A        ;
4372680Sktlim@umich.edu
438180SN/A    accesses
4396221Snate@binkert.org        .name(name() + ".accesses")
4406221Snate@binkert.org        .desc("DTB accesses")
4416221Snate@binkert.org        ;
4422378SN/A
4435718Shsul@eecs.umich.edu    hits = read_hits + write_hits;
4445718Shsul@eecs.umich.edu    misses = read_misses + write_misses;
4455718Shsul@eecs.umich.edu    acv = read_acv + write_acv;
4465718Shsul@eecs.umich.edu    accesses = read_accesses + write_accesses;
4475718Shsul@eecs.umich.edu}
4485718Shsul@eecs.umich.edu
4495718Shsul@eecs.umich.eduvoid
4506221Snate@binkert.orgAlphaDtb::fault(Addr vaddr, uint64_t flags, ExecContext *xc) const
4515718Shsul@eecs.umich.edu{
4525718Shsul@eecs.umich.edu    uint64_t *ipr = xc->regs.ipr;
4535718Shsul@eecs.umich.edu
4548779Sgblack@eecs.umich.edu    // set fault address and flags
4558779Sgblack@eecs.umich.edu    if (!xc->misspeculating() && !xc->regs.intrlock) {
4568779Sgblack@eecs.umich.edu        // set VA register with faulting address
457180SN/A        ipr[AlphaISA::IPR_VA] = vaddr;
458180SN/A
459180SN/A        // set MM_STAT register flags
460180SN/A        ipr[AlphaISA::IPR_MM_STAT] = (((xc->regs.opcode & 0x3f) << 11)
4614000Ssaidi@eecs.umich.edu                               | ((xc->regs.ra & 0x1f) << 6)
4624000Ssaidi@eecs.umich.edu                               | (flags & 0x3f));
4634000Ssaidi@eecs.umich.edu
4646221Snate@binkert.org        // set VA_FORM register with faulting formatted address
4656221Snate@binkert.org        ipr[AlphaISA::IPR_VA_FORM] =
4666221Snate@binkert.org            ipr[AlphaISA::IPR_MVPTBR] | (VA_VPN(vaddr) << 3);
4676221Snate@binkert.org
4684000Ssaidi@eecs.umich.edu        // lock these registers until the VA register is read
4694000Ssaidi@eecs.umich.edu        xc->regs.intrlock = true;
4704000Ssaidi@eecs.umich.edu    }
4714000Ssaidi@eecs.umich.edu}
472180SN/A
4732798Sktlim@umich.eduFault
474180SN/AAlphaDtb::translate(MemReqPtr &req, bool write) const
4759430SAndreas.Sandberg@ARM.com{
4769430SAndreas.Sandberg@ARM.com    RegFile *regs = &req->xc->regs;
4772359SN/A    Addr pc = regs->pc;
4785606Snate@binkert.org    InternalProcReg *ipr = regs->ipr;
4799446SAndreas.Sandberg@ARM.com
4809446SAndreas.Sandberg@ARM.com    AlphaISA::mode_type mode =
4819446SAndreas.Sandberg@ARM.com        (AlphaISA::mode_type)DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]);
4829446SAndreas.Sandberg@ARM.com
483180SN/A    if (PC_PAL(pc)) {
484180SN/A        mode = (req->flags & ALTMODE) ?
485180SN/A            (AlphaISA::mode_type)ALT_MODE_AM(ipr[AlphaISA::IPR_ALT_MODE])
4868737Skoansin.tan@gmail.com            : AlphaISA::mode_kernel;
487180SN/A    }
4882680Sktlim@umich.edu
4899152Satgutier@umich.edu    if (req->flags & PHYSICAL) {
4909430SAndreas.Sandberg@ARM.com        req->paddr = req->vaddr;
4919430SAndreas.Sandberg@ARM.com    } else {
4929332Sdam.sunwoo@arm.com        // verify that this is a good virtual address
4939332Sdam.sunwoo@arm.com        if (!validVirtualAddress(req->vaddr)) {
4949430SAndreas.Sandberg@ARM.com            fault(req->vaddr,
4955712Shsul@eecs.umich.edu                  ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_BAD_VA_MASK |
4966221Snate@binkert.org                   MM_STAT_ACV_MASK),
4976221Snate@binkert.org                  req->xc);
4982680Sktlim@umich.edu
4992680Sktlim@umich.edu            if (write) { write_acv++; } else { read_acv++; }
500180SN/A            return Dtb_Fault_Fault;
5012680Sktlim@umich.edu        }
5022651Ssaidi@eecs.umich.edu
5032680Sktlim@umich.edu        // Check for "superpage" mapping: when SP<1> is set, and
5042651Ssaidi@eecs.umich.edu        // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>.
5055714Shsul@eecs.umich.edu        if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) &&
5065715Shsul@eecs.umich.edu            VA_SPACE(req->vaddr) == 2) {
5075714Shsul@eecs.umich.edu
5082359SN/A            // only valid in kernel mode
5095875Ssteve.reinhardt@amd.com            if (DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]) !=
5105875Ssteve.reinhardt@amd.com                AlphaISA::mode_kernel) {
5115875Ssteve.reinhardt@amd.com                fault(req->vaddr,
5125875Ssteve.reinhardt@amd.com                      ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK),
5135217Ssaidi@eecs.umich.edu                      req->xc);
5145875Ssteve.reinhardt@amd.com                if (write) { write_acv++; } else { read_acv++; }
5157781SAli.Saidi@ARM.com                return Dtb_Acv_Fault;
5169294Sandreas.hansson@arm.com            }
5179294Sandreas.hansson@arm.com
5189294Sandreas.hansson@arm.com            req->paddr = req->vaddr & PA_IMPL_MASK;
5199294Sandreas.hansson@arm.com
5207781SAli.Saidi@ARM.com            // sign extend the physical address properly
5217781SAli.Saidi@ARM.com            if (req->paddr & PA_UNCACHED_BIT_39 ||
5229178Sandreas.hansson@arm.com                req->paddr & PA_UNCACHED_BIT_40)
5239178Sandreas.hansson@arm.com                req->paddr |= 0xf0000000000;
5247781SAli.Saidi@ARM.com            else
5259178Sandreas.hansson@arm.com                req->paddr &= 0xffffffffff;
5269294Sandreas.hansson@arm.com
5279178Sandreas.hansson@arm.com        } else {
5288922Swilliam.wang@arm.com            if (write)
5297781SAli.Saidi@ARM.com                write_accesses++;
5309178Sandreas.hansson@arm.com            else
5319178Sandreas.hansson@arm.com                read_accesses++;
5327781SAli.Saidi@ARM.com
5339178Sandreas.hansson@arm.com            // not a physical address: need to look up pte
5349294Sandreas.hansson@arm.com            AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr),
5359178Sandreas.hansson@arm.com                                 DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]));
5368922Swilliam.wang@arm.com
5377781SAli.Saidi@ARM.com            if (!pte) {
53810194SGeoffrey.Blake@arm.com                // page fault
53910194SGeoffrey.Blake@arm.com                fault(req->vaddr,
5408733Sgeoffrey.blake@arm.com                      ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_DTB_MISS_MASK),
5418887Sgeoffrey.blake@arm.com                      req->xc);
5428887Sgeoffrey.blake@arm.com                if (write) { write_misses++; } else { read_misses++; }
5438887Sgeoffrey.blake@arm.com                return (req->flags & VPTE) ? Pdtb_Miss_Fault : Ndtb_Miss_Fault;
5448887Sgeoffrey.blake@arm.com            }
5458887Sgeoffrey.blake@arm.com
5469294Sandreas.hansson@arm.com            req->paddr = PA_PFN2PA(pte->ppn) | VA_POFS(req->vaddr);
5478922Swilliam.wang@arm.com
5489294Sandreas.hansson@arm.com            if (write) {
5498922Swilliam.wang@arm.com                if (!(pte->xwe & MODE2MASK(mode))) {
5509294Sandreas.hansson@arm.com                    // declare the instruction access fault
5518922Swilliam.wang@arm.com                    fault(req->vaddr, MM_STAT_WR_MASK | MM_STAT_ACV_MASK |
5529294Sandreas.hansson@arm.com                          (pte->fonw ? MM_STAT_FONW_MASK : 0),
5538922Swilliam.wang@arm.com                          req->xc);
5548733Sgeoffrey.blake@arm.com                    write_acv++;
55510194SGeoffrey.Blake@arm.com                    return Dtb_Fault_Fault;
55610194SGeoffrey.Blake@arm.com                }
55710194SGeoffrey.Blake@arm.com                if (pte->fonw) {
5588887Sgeoffrey.blake@arm.com                    fault(req->vaddr, MM_STAT_WR_MASK | MM_STAT_FONW_MASK,
5599178Sandreas.hansson@arm.com                          req->xc);
5609178Sandreas.hansson@arm.com                    write_acv++;
5618887Sgeoffrey.blake@arm.com                    return Dtb_Fault_Fault;
5629178Sandreas.hansson@arm.com                }
5639294Sandreas.hansson@arm.com            } else {
5649294Sandreas.hansson@arm.com                if (!(pte->xre & MODE2MASK(mode))) {
5659178Sandreas.hansson@arm.com                    fault(req->vaddr,
5668922Swilliam.wang@arm.com                          MM_STAT_ACV_MASK |
5678887Sgeoffrey.blake@arm.com                          (pte->fonr ? MM_STAT_FONR_MASK : 0),
5689178Sandreas.hansson@arm.com                          req->xc);
5699178Sandreas.hansson@arm.com                    read_acv++;
5708887Sgeoffrey.blake@arm.com                    return Dtb_Acv_Fault;
5719178Sandreas.hansson@arm.com                }
5729294Sandreas.hansson@arm.com                if (pte->fonr) {
5739294Sandreas.hansson@arm.com                    fault(req->vaddr, MM_STAT_FONR_MASK, req->xc);
5749178Sandreas.hansson@arm.com                    read_acv++;
5758922Swilliam.wang@arm.com                    return Dtb_Fault_Fault;
5768887Sgeoffrey.blake@arm.com                }
5778733Sgeoffrey.blake@arm.com            }
578180SN/A        }
579605SN/A
5803520Sgblack@eecs.umich.edu        if (write)
5815810Sgblack@eecs.umich.edu            write_hits++;
5829152Satgutier@umich.edu        else
5832254SN/A            read_hits++;
5848779Sgblack@eecs.umich.edu    }
5858779Sgblack@eecs.umich.edu
5868779Sgblack@eecs.umich.edu    // check that the physical address is ok (catch bad physical addresses)
5872254SN/A    if (req->paddr & ~PA_IMPL_MASK)
5888779Sgblack@eecs.umich.edu        return Machine_Check_Fault;
5898779Sgblack@eecs.umich.edu
5908779Sgblack@eecs.umich.edu    checkCacheability(req);
5914192Sktlim@umich.edu
5929178Sandreas.hansson@arm.com    return No_Fault;
5939178Sandreas.hansson@arm.com}
5949178Sandreas.hansson@arm.com
5959178Sandreas.hansson@arm.comAlphaISA::PTE &
5969178Sandreas.hansson@arm.comAlphaTlb::index(bool advance)
5979178Sandreas.hansson@arm.com{
5989294Sandreas.hansson@arm.com    AlphaISA::PTE *pte = &table[nlu];
5999178Sandreas.hansson@arm.com
6009178Sandreas.hansson@arm.com    if (advance)
6014192Sktlim@umich.edu        nextnlu();
6029178Sandreas.hansson@arm.com
6039178Sandreas.hansson@arm.com    return *pte;
6049294Sandreas.hansson@arm.com}
6059178Sandreas.hansson@arm.com
6069178Sandreas.hansson@arm.comBEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaItb)
607180SN/A
608180SN/A    Param<int> size;
6099446SAndreas.Sandberg@ARM.com
6109446SAndreas.Sandberg@ARM.comEND_DECLARE_SIM_OBJECT_PARAMS(AlphaItb)
6119446SAndreas.Sandberg@ARM.com
6129446SAndreas.Sandberg@ARM.comBEGIN_INIT_SIM_OBJECT_PARAMS(AlphaItb)
6139446SAndreas.Sandberg@ARM.com
6149446SAndreas.Sandberg@ARM.com    INIT_PARAM_DFLT(size, "TLB size", 48)
6159446SAndreas.Sandberg@ARM.com
6169446SAndreas.Sandberg@ARM.comEND_INIT_SIM_OBJECT_PARAMS(AlphaItb)
6179446SAndreas.Sandberg@ARM.com
6189446SAndreas.Sandberg@ARM.com
6199446SAndreas.Sandberg@ARM.comCREATE_SIM_OBJECT(AlphaItb)
6209446SAndreas.Sandberg@ARM.com{
6219446SAndreas.Sandberg@ARM.com    return new AlphaItb(getInstanceName(), size);
6229446SAndreas.Sandberg@ARM.com}
6239446SAndreas.Sandberg@ARM.com
6249446SAndreas.Sandberg@ARM.comREGISTER_SIM_OBJECT("AlphaITB", AlphaItb)
625180SN/A
6265536Srstrong@hp.comBEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaDtb)
6275606Snate@binkert.org
6281917SN/A    Param<int> size;
6291917SN/A
6301917SN/AEND_DECLARE_SIM_OBJECT_PARAMS(AlphaDtb)
6311917SN/A
6321917SN/ABEGIN_INIT_SIM_OBJECT_PARAMS(AlphaDtb)
6336221Snate@binkert.org
6346221Snate@binkert.org    INIT_PARAM_DFLT(size, "TLB size", 64)
6352680Sktlim@umich.edu
6362680Sktlim@umich.eduEND_INIT_SIM_OBJECT_PARAMS(AlphaDtb)
6371917SN/A
6382254SN/A
6397823Ssteve.reinhardt@amd.comCREATE_SIM_OBJECT(AlphaDtb)
6401917SN/A{
6411917SN/A    return new AlphaDtb(getInstanceName(), size);
6422SN/A}
643921SN/A
644921SN/AREGISTER_SIM_OBJECT("AlphaDTB", AlphaDtb)
6454000Ssaidi@eecs.umich.edu
6469332Sdam.sunwoo@arm.com