tlb.cc revision 7705:fd65f85fcc0c
15331Sgblack@eecs.umich.edu/*
25331Sgblack@eecs.umich.edu * Copyright (c) 2010 ARM Limited
35331Sgblack@eecs.umich.edu * All rights reserved
45331Sgblack@eecs.umich.edu *
55331Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall
65331Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual
75331Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating
85331Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software
95331Sgblack@eecs.umich.edu * licensed hereunder.  You may use the software subject to the license
105331Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated
115331Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software,
125331Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form.
135331Sgblack@eecs.umich.edu *
145331Sgblack@eecs.umich.edu * Copyright (c) 2001-2005 The Regents of The University of Michigan
155331Sgblack@eecs.umich.edu * All rights reserved.
165331Sgblack@eecs.umich.edu *
175331Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
185331Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
195331Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
205331Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
215331Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
225331Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
235331Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
245331Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
255331Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
265331Sgblack@eecs.umich.edu * this software without specific prior written permission.
275331Sgblack@eecs.umich.edu *
285331Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
295331Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
304276Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
314276Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
324276Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
334276Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
344276Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
354276Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
364276Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
374276Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
384276Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
394276Sgblack@eecs.umich.edu *
404276Sgblack@eecs.umich.edu * Authors: Ali Saidi
414276Sgblack@eecs.umich.edu *          Nathan Binkert
424276Sgblack@eecs.umich.edu *          Steve Reinhardt
434276Sgblack@eecs.umich.edu */
444276Sgblack@eecs.umich.edu
454276Sgblack@eecs.umich.edu#include <string>
464276Sgblack@eecs.umich.edu#include <vector>
474276Sgblack@eecs.umich.edu
484276Sgblack@eecs.umich.edu#include "arch/arm/faults.hh"
494276Sgblack@eecs.umich.edu#include "arch/arm/pagetable.hh"
504276Sgblack@eecs.umich.edu#include "arch/arm/tlb.hh"
514276Sgblack@eecs.umich.edu#include "arch/arm/utility.hh"
524276Sgblack@eecs.umich.edu#include "base/inifile.hh"
534276Sgblack@eecs.umich.edu#include "base/str.hh"
544276Sgblack@eecs.umich.edu#include "base/trace.hh"
554276Sgblack@eecs.umich.edu#include "cpu/thread_context.hh"
564276Sgblack@eecs.umich.edu#include "mem/page_table.hh"
574276Sgblack@eecs.umich.edu#include "params/ArmTLB.hh"
584276Sgblack@eecs.umich.edu#include "sim/process.hh"
594276Sgblack@eecs.umich.edu
604276Sgblack@eecs.umich.edu#if FULL_SYSTEM
614276Sgblack@eecs.umich.edu#include "arch/arm/table_walker.hh"
624276Sgblack@eecs.umich.edu#endif
634276Sgblack@eecs.umich.edu
644276Sgblack@eecs.umich.eduusing namespace std;
654276Sgblack@eecs.umich.eduusing namespace ArmISA;
664276Sgblack@eecs.umich.edu
674276Sgblack@eecs.umich.eduTLB::TLB(const Params *p)
684276Sgblack@eecs.umich.edu    : BaseTLB(p), size(p->size)
694276Sgblack@eecs.umich.edu#if FULL_SYSTEM
704276Sgblack@eecs.umich.edu      , tableWalker(p->walker)
714276Sgblack@eecs.umich.edu#endif
724276Sgblack@eecs.umich.edu    , rangeMRU(1)
734276Sgblack@eecs.umich.edu{
744276Sgblack@eecs.umich.edu    table = new TlbEntry[size];
754276Sgblack@eecs.umich.edu    memset(table, 0, sizeof(TlbEntry[size]));
764276Sgblack@eecs.umich.edu
774276Sgblack@eecs.umich.edu#if FULL_SYSTEM
784276Sgblack@eecs.umich.edu    tableWalker->setTlb(this);
794276Sgblack@eecs.umich.edu#endif
804276Sgblack@eecs.umich.edu}
814276Sgblack@eecs.umich.edu
824276Sgblack@eecs.umich.eduTLB::~TLB()
834276Sgblack@eecs.umich.edu{
844276Sgblack@eecs.umich.edu    if (table)
854276Sgblack@eecs.umich.edu        delete [] table;
864276Sgblack@eecs.umich.edu}
874276Sgblack@eecs.umich.edu
884276Sgblack@eecs.umich.edubool
894711Sgblack@eecs.umich.eduTLB::translateFunctional(ThreadContext *tc, Addr va, Addr &pa)
904276Sgblack@eecs.umich.edu{
914276Sgblack@eecs.umich.edu    uint32_t context_id = tc->readMiscReg(MISCREG_CONTEXTIDR);
925238Sgblack@eecs.umich.edu    TlbEntry *e = lookup(va, context_id, true);
935238Sgblack@eecs.umich.edu    if (!e)
945238Sgblack@eecs.umich.edu        return false;
955238Sgblack@eecs.umich.edu    pa = e->pAddr(va);
965937Sgblack@eecs.umich.edu    return true;
975902Sgblack@eecs.umich.edu}
985238Sgblack@eecs.umich.edu
995238Sgblack@eecs.umich.eduTlbEntry*
1005238Sgblack@eecs.umich.eduTLB::lookup(Addr va, uint8_t cid, bool functional)
1015238Sgblack@eecs.umich.edu{
1025238Sgblack@eecs.umich.edu
1035238Sgblack@eecs.umich.edu    TlbEntry *retval = NULL;
1045238Sgblack@eecs.umich.edu
1055238Sgblack@eecs.umich.edu    // Maitaining LRU array
1065238Sgblack@eecs.umich.edu
1075238Sgblack@eecs.umich.edu    int x = 0;
1085238Sgblack@eecs.umich.edu    while (retval == NULL && x < size) {
1095238Sgblack@eecs.umich.edu        if (table[x].match(va, cid)) {
1105238Sgblack@eecs.umich.edu
1115238Sgblack@eecs.umich.edu            // We only move the hit entry ahead when the position is higher than rangeMRU
1125238Sgblack@eecs.umich.edu            if (x > rangeMRU) {
1135238Sgblack@eecs.umich.edu                TlbEntry tmp_entry = table[x];
1145238Sgblack@eecs.umich.edu                for(int i = x; i > 0; i--)
1155238Sgblack@eecs.umich.edu                    table[i] = table[i-1];
1165238Sgblack@eecs.umich.edu                table[0] = tmp_entry;
1175238Sgblack@eecs.umich.edu                retval = &table[0];
1185238Sgblack@eecs.umich.edu            } else {
1195238Sgblack@eecs.umich.edu                retval = &table[x];
1205238Sgblack@eecs.umich.edu            }
1215238Sgblack@eecs.umich.edu            break;
1225238Sgblack@eecs.umich.edu        }
1235238Sgblack@eecs.umich.edu        x++;
1245238Sgblack@eecs.umich.edu    }
1255238Sgblack@eecs.umich.edu
1265238Sgblack@eecs.umich.edu    DPRINTF(TLBVerbose, "Lookup %#x, cid %#x -> %s ppn %#x size: %#x pa: %#x ap:%d\n",
1275238Sgblack@eecs.umich.edu            va, cid, retval ? "hit" : "miss", retval ? retval->pfn : 0,
1286055Sgblack@eecs.umich.edu            retval ? retval->size : 0, retval ? retval->pAddr(va) : 0,
1296054Sgblack@eecs.umich.edu            retval ? retval->ap : 0);
1305238Sgblack@eecs.umich.edu    ;
1315683Sgblack@eecs.umich.edu    return retval;
1325238Sgblack@eecs.umich.edu}
1335238Sgblack@eecs.umich.edu
1345238Sgblack@eecs.umich.edu// insert a new TLB entry
1355238Sgblack@eecs.umich.eduvoid
1365238Sgblack@eecs.umich.eduTLB::insert(Addr addr, TlbEntry &entry)
1375238Sgblack@eecs.umich.edu{
1385238Sgblack@eecs.umich.edu    DPRINTF(TLB, "Inserting entry into TLB with pfn:%#x size:%#x vpn: %#x"
1395238Sgblack@eecs.umich.edu            " asid:%d N:%d global:%d valid:%d nc:%d sNp:%d xn:%d ap:%#x"
1405291Sgblack@eecs.umich.edu            " domain:%#x\n", entry.pfn, entry.size, entry.vpn, entry.asid,
1415291Sgblack@eecs.umich.edu            entry.N, entry.global, entry.valid, entry.nonCacheable, entry.sNp,
1425291Sgblack@eecs.umich.edu            entry.xn, entry.ap, entry.domain);
1435291Sgblack@eecs.umich.edu
1445291Sgblack@eecs.umich.edu    if (table[size-1].valid)
1455291Sgblack@eecs.umich.edu        DPRINTF(TLB, " - Replacing Valid entry %#x, asn %d ppn %#x size: %#x ap:%d\n",
1465291Sgblack@eecs.umich.edu                table[size-1].vpn << table[size-1].N, table[size-1].asid,
1475291Sgblack@eecs.umich.edu                table[size-1].pfn << table[size-1].N, table[size-1].size,
1485291Sgblack@eecs.umich.edu                table[size-1].ap);
1495292Sgblack@eecs.umich.edu
1505292Sgblack@eecs.umich.edu    //inserting to MRU position and evicting the LRU one
1515292Sgblack@eecs.umich.edu
1525292Sgblack@eecs.umich.edu    for(int i = size-1; i > 0; i--)
1535292Sgblack@eecs.umich.edu      table[i] = table[i-1];
1545292Sgblack@eecs.umich.edu    table[0] = entry;
1555292Sgblack@eecs.umich.edu}
1565292Sgblack@eecs.umich.edu
1575292Sgblack@eecs.umich.eduvoid
1586055Sgblack@eecs.umich.eduTLB::printTlb()
1596054Sgblack@eecs.umich.edu{
1605359Sgblack@eecs.umich.edu    int x = 0;
1615238Sgblack@eecs.umich.edu    TlbEntry *te;
1625238Sgblack@eecs.umich.edu    DPRINTF(TLB, "Current TLB contents:\n");
1635238Sgblack@eecs.umich.edu    while (x < size) {
1644276Sgblack@eecs.umich.edu       te = &table[x];
1654276Sgblack@eecs.umich.edu       if (te->valid)
1665789Sgblack@eecs.umich.edu           DPRINTF(TLB, " *  %#x, asn %d ppn %#x size: %#x ap:%d\n",
1675789Sgblack@eecs.umich.edu                te->vpn << te->N, te->asid, te->pfn << te->N, te->size, te->ap);
1685789Sgblack@eecs.umich.edu       x++;
1695789Sgblack@eecs.umich.edu    }
1705789Sgblack@eecs.umich.edu}
1715789Sgblack@eecs.umich.edu
1725789Sgblack@eecs.umich.edu
1735789Sgblack@eecs.umich.eduvoid
1745789Sgblack@eecs.umich.eduTLB::flushAll()
1755789Sgblack@eecs.umich.edu{
1765789Sgblack@eecs.umich.edu    DPRINTF(TLB, "Flushing all TLB entries\n");
1775789Sgblack@eecs.umich.edu    int x = 0;
1785789Sgblack@eecs.umich.edu    TlbEntry *te;
1795789Sgblack@eecs.umich.edu    while (x < size) {
1805789Sgblack@eecs.umich.edu       te = &table[x];
1815789Sgblack@eecs.umich.edu       if (te->valid)
1825789Sgblack@eecs.umich.edu           DPRINTF(TLB, " -  %#x, asn %d ppn %#x size: %#x ap:%d\n",
1835789Sgblack@eecs.umich.edu                te->vpn << te->N, te->asid, te->pfn << te->N, te->size, te->ap);
1845789Sgblack@eecs.umich.edu       x++;
1855789Sgblack@eecs.umich.edu    }
1865789Sgblack@eecs.umich.edu
1875789Sgblack@eecs.umich.edu    memset(table, 0, sizeof(TlbEntry[size]));
1885789Sgblack@eecs.umich.edu}
1895789Sgblack@eecs.umich.edu
1905789Sgblack@eecs.umich.edu
1915789Sgblack@eecs.umich.eduvoid
1925789Sgblack@eecs.umich.eduTLB::flushMvaAsid(Addr mva, uint64_t asn)
1935789Sgblack@eecs.umich.edu{
1945789Sgblack@eecs.umich.edu    DPRINTF(TLB, "Flushing mva %#x asid: %#x\n", mva, asn);
1955789Sgblack@eecs.umich.edu    TlbEntry *te;
1965789Sgblack@eecs.umich.edu
1975789Sgblack@eecs.umich.edu    te = lookup(mva, asn);
1985789Sgblack@eecs.umich.edu    while (te != NULL) {
1995789Sgblack@eecs.umich.edu     DPRINTF(TLB, " -  %#x, asn %d ppn %#x size: %#x ap:%d\n",
2005789Sgblack@eecs.umich.edu            te->vpn << te->N, te->asid, te->pfn << te->N, te->size, te->ap);
2015789Sgblack@eecs.umich.edu        te->valid = false;
2025789Sgblack@eecs.umich.edu        te = lookup(mva,asn);
2035789Sgblack@eecs.umich.edu    }
2045789Sgblack@eecs.umich.edu}
2055789Sgblack@eecs.umich.edu
2065789Sgblack@eecs.umich.eduvoid
2075789Sgblack@eecs.umich.eduTLB::flushAsid(uint64_t asn)
2085789Sgblack@eecs.umich.edu{
2095789Sgblack@eecs.umich.edu    DPRINTF(TLB, "Flushing all entries with asid: %#x\n", asn);
2105789Sgblack@eecs.umich.edu
2115789Sgblack@eecs.umich.edu    int x = 0;
2125789Sgblack@eecs.umich.edu    TlbEntry *te;
2135789Sgblack@eecs.umich.edu
2145789Sgblack@eecs.umich.edu    while (x < size) {
2155789Sgblack@eecs.umich.edu        te = &table[x];
2165789Sgblack@eecs.umich.edu        if (te->asid == asn) {
2175789Sgblack@eecs.umich.edu            te->valid = false;
2185789Sgblack@eecs.umich.edu            DPRINTF(TLB, " -  %#x, asn %d ppn %#x size: %#x ap:%d\n",
2195789Sgblack@eecs.umich.edu                te->vpn << te->N, te->asid, te->pfn << te->N, te->size, te->ap);
2205789Sgblack@eecs.umich.edu        }
2215789Sgblack@eecs.umich.edu        x++;
2225789Sgblack@eecs.umich.edu    }
2235789Sgblack@eecs.umich.edu}
2245789Sgblack@eecs.umich.edu
2255789Sgblack@eecs.umich.eduvoid
2265789Sgblack@eecs.umich.eduTLB::flushMva(Addr mva)
2275789Sgblack@eecs.umich.edu{
2285789Sgblack@eecs.umich.edu    DPRINTF(TLB, "Flushing all entries with mva: %#x\n", mva);
2295789Sgblack@eecs.umich.edu
2305789Sgblack@eecs.umich.edu    int x = 0;
2315789Sgblack@eecs.umich.edu    TlbEntry *te;
2325789Sgblack@eecs.umich.edu
2335789Sgblack@eecs.umich.edu    while (x < size) {
2345789Sgblack@eecs.umich.edu        te = &table[x];
2355789Sgblack@eecs.umich.edu        Addr v = te->vpn << te->N;
2365789Sgblack@eecs.umich.edu        if (mva >= v && mva < v + te->size) {
2375789Sgblack@eecs.umich.edu            te->valid = false;
2385789Sgblack@eecs.umich.edu            DPRINTF(TLB, " -  %#x, asn %d ppn %#x size: %#x ap:%d\n",
2395789Sgblack@eecs.umich.edu                te->vpn << te->N, te->asid, te->pfn << te->N, te->size, te->ap);
2405789Sgblack@eecs.umich.edu        }
2415789Sgblack@eecs.umich.edu        x++;
2425789Sgblack@eecs.umich.edu    }
2435789Sgblack@eecs.umich.edu}
2445789Sgblack@eecs.umich.edu
2455789Sgblack@eecs.umich.eduvoid
2465789Sgblack@eecs.umich.eduTLB::serialize(ostream &os)
2475789Sgblack@eecs.umich.edu{
2485789Sgblack@eecs.umich.edu    panic("Implement Serialize\n");
2495789Sgblack@eecs.umich.edu}
2505789Sgblack@eecs.umich.edu
2515789Sgblack@eecs.umich.eduvoid
2525789Sgblack@eecs.umich.eduTLB::unserialize(Checkpoint *cp, const string &section)
2535789Sgblack@eecs.umich.edu{
2545789Sgblack@eecs.umich.edu
2555789Sgblack@eecs.umich.edu    panic("Need to properly unserialize TLB\n");
2564712Sgblack@eecs.umich.edu}
2575907Sgblack@eecs.umich.edu
2585907Sgblack@eecs.umich.eduvoid
2595907Sgblack@eecs.umich.eduTLB::regStats()
2605907Sgblack@eecs.umich.edu{
2615907Sgblack@eecs.umich.edu    read_hits
2625907Sgblack@eecs.umich.edu        .name(name() + ".read_hits")
2635907Sgblack@eecs.umich.edu        .desc("DTB read hits")
2644712Sgblack@eecs.umich.edu        ;
2655659Sgblack@eecs.umich.edu
2664712Sgblack@eecs.umich.edu    read_misses
2675933Sgblack@eecs.umich.edu        .name(name() + ".read_misses")
2685908Sgblack@eecs.umich.edu        .desc("DTB read misses")
2695908Sgblack@eecs.umich.edu        ;
2705908Sgblack@eecs.umich.edu
2715908Sgblack@eecs.umich.edu
2725908Sgblack@eecs.umich.edu    read_accesses
2735908Sgblack@eecs.umich.edu        .name(name() + ".read_accesses")
2745908Sgblack@eecs.umich.edu        .desc("DTB read accesses")
2755908Sgblack@eecs.umich.edu        ;
2765908Sgblack@eecs.umich.edu
2774276Sgblack@eecs.umich.edu    write_hits
2784276Sgblack@eecs.umich.edu        .name(name() + ".write_hits")
2794712Sgblack@eecs.umich.edu        .desc("DTB write hits")
2804712Sgblack@eecs.umich.edu        ;
2814730Sgblack@eecs.umich.edu
2824760Sgblack@eecs.umich.edu    write_misses
2834730Sgblack@eecs.umich.edu        .name(name() + ".write_misses")
2845920Sgblack@eecs.umich.edu        .desc("DTB write misses")
2855422Sgblack@eecs.umich.edu        ;
2865422Sgblack@eecs.umich.edu
2874276Sgblack@eecs.umich.edu
2886576Sgblack@eecs.umich.edu    write_accesses
2896576Sgblack@eecs.umich.edu        .name(name() + ".write_accesses")
2906576Sgblack@eecs.umich.edu        .desc("DTB write accesses")
2916576Sgblack@eecs.umich.edu        ;
2926576Sgblack@eecs.umich.edu
2936576Sgblack@eecs.umich.edu    hits
2946576Sgblack@eecs.umich.edu        .name(name() + ".hits")
2956576Sgblack@eecs.umich.edu        .desc("DTB hits")
2966576Sgblack@eecs.umich.edu        ;
2976576Sgblack@eecs.umich.edu
2986576Sgblack@eecs.umich.edu    misses
2996576Sgblack@eecs.umich.edu        .name(name() + ".misses")
3006576Sgblack@eecs.umich.edu        .desc("DTB misses")
3016576Sgblack@eecs.umich.edu        ;
3026576Sgblack@eecs.umich.edu
3036576Sgblack@eecs.umich.edu    accesses
3046576Sgblack@eecs.umich.edu        .name(name() + ".accesses")
3056576Sgblack@eecs.umich.edu        .desc("DTB accesses")
3065020Sgblack@eecs.umich.edu        ;
3076576Sgblack@eecs.umich.edu
3086576Sgblack@eecs.umich.edu    hits = read_hits + write_hits;
3096600Sgblack@eecs.umich.edu    misses = read_misses + write_misses;
3106600Sgblack@eecs.umich.edu    accesses = read_accesses + write_accesses;
3116576Sgblack@eecs.umich.edu}
3126576Sgblack@eecs.umich.edu
3136576Sgblack@eecs.umich.edu#if !FULL_SYSTEM
3145020Sgblack@eecs.umich.eduFault
3156576Sgblack@eecs.umich.eduTLB::translateSe(RequestPtr req, ThreadContext *tc, Mode mode,
3166576Sgblack@eecs.umich.edu        Translation *translation, bool &delay, bool timing)
3176576Sgblack@eecs.umich.edu{
3186576Sgblack@eecs.umich.edu    // XXX Cache misc registers and have miscreg write function inv cache
3196576Sgblack@eecs.umich.edu    Addr vaddr = req->getVaddr() & ~PcModeMask;
3206576Sgblack@eecs.umich.edu    SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
3216576Sgblack@eecs.umich.edu    uint32_t flags = req->getFlags();
3226576Sgblack@eecs.umich.edu
3236576Sgblack@eecs.umich.edu    bool is_fetch = (mode == Execute);
3246576Sgblack@eecs.umich.edu    bool is_write = (mode == Write);
3256576Sgblack@eecs.umich.edu
3266576Sgblack@eecs.umich.edu    if (!is_fetch) {
3276576Sgblack@eecs.umich.edu        assert(flags & MustBeOne);
3286576Sgblack@eecs.umich.edu        if (sctlr.a || !(flags & AllowUnaligned)) {
3296576Sgblack@eecs.umich.edu            if (vaddr & flags & AlignmentMask) {
3306576Sgblack@eecs.umich.edu                return new DataAbort(vaddr, 0, is_write, ArmFault::AlignmentFault);
3316576Sgblack@eecs.umich.edu            }
3326576Sgblack@eecs.umich.edu        }
3336576Sgblack@eecs.umich.edu    }
3344760Sgblack@eecs.umich.edu
3356576Sgblack@eecs.umich.edu    Addr paddr;
3366576Sgblack@eecs.umich.edu    Process *p = tc->getProcessPtr();
3376576Sgblack@eecs.umich.edu
3386576Sgblack@eecs.umich.edu    if (!p->pTable->translate(vaddr, paddr))
3396576Sgblack@eecs.umich.edu        return Fault(new GenericPageTableFault(vaddr));
3406576Sgblack@eecs.umich.edu    req->setPaddr(paddr);
3416576Sgblack@eecs.umich.edu
3426576Sgblack@eecs.umich.edu    return NoFault;
3436576Sgblack@eecs.umich.edu}
3446576Sgblack@eecs.umich.edu
3456576Sgblack@eecs.umich.edu#else // FULL_SYSTEM
3466576Sgblack@eecs.umich.edu
3476576Sgblack@eecs.umich.eduFault
3486576Sgblack@eecs.umich.eduTLB::trickBoxCheck(RequestPtr req, Mode mode, uint8_t domain, bool sNp)
3496576Sgblack@eecs.umich.edu{
3506576Sgblack@eecs.umich.edu    return NoFault;
3514760Sgblack@eecs.umich.edu}
3526576Sgblack@eecs.umich.edu
3536576Sgblack@eecs.umich.eduFault
3546576Sgblack@eecs.umich.eduTLB::walkTrickBoxCheck(Addr pa, Addr va, Addr sz, bool is_exec,
3556576Sgblack@eecs.umich.edu        bool is_write, uint8_t domain, bool sNp)
3566576Sgblack@eecs.umich.edu{
3576576Sgblack@eecs.umich.edu    return NoFault;
3586576Sgblack@eecs.umich.edu}
3596576Sgblack@eecs.umich.edu
3606576Sgblack@eecs.umich.eduFault
3616576Sgblack@eecs.umich.eduTLB::translateFs(RequestPtr req, ThreadContext *tc, Mode mode,
3626576Sgblack@eecs.umich.edu        Translation *translation, bool &delay, bool timing)
3636576Sgblack@eecs.umich.edu{
3646576Sgblack@eecs.umich.edu    // XXX Cache misc registers and have miscreg write function inv cache
3656576Sgblack@eecs.umich.edu    Addr vaddr = req->getVaddr() & ~PcModeMask;
3666576Sgblack@eecs.umich.edu    SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
3676576Sgblack@eecs.umich.edu    CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
3686576Sgblack@eecs.umich.edu    uint32_t flags = req->getFlags();
3694760Sgblack@eecs.umich.edu
3704276Sgblack@eecs.umich.edu    bool is_fetch = (mode == Execute);
3715020Sgblack@eecs.umich.edu    bool is_write = (mode == Write);
3725020Sgblack@eecs.umich.edu    bool is_priv = (cpsr.mode != MODE_USER) && !(flags & UserMode);
3735020Sgblack@eecs.umich.edu
3745031Sgblack@eecs.umich.edu    DPRINTF(TLBVerbose, "CPSR is user:%d UserMode:%d\n", cpsr.mode == MODE_USER, flags
3755031Sgblack@eecs.umich.edu            & UserMode);
3765031Sgblack@eecs.umich.edu    // If this is a clrex instruction, provide a PA of 0 with no fault
3775031Sgblack@eecs.umich.edu    // This will force the monitor to set the tracked address to 0
3786563Sgblack@eecs.umich.edu    // a bit of a hack but this effectively clrears this processors monitor
3795020Sgblack@eecs.umich.edu    if (flags & Request::CLEAR_LL){
3806606Sgblack@eecs.umich.edu       req->setPaddr(0);
3816606Sgblack@eecs.umich.edu       req->setFlags(Request::UNCACHEABLE);
3826602Sgblack@eecs.umich.edu       req->setFlags(Request::CLEAR_LL);
3836602Sgblack@eecs.umich.edu       return NoFault;
3845020Sgblack@eecs.umich.edu    }
3855020Sgblack@eecs.umich.edu    if ((req->isInstFetch() && (!sctlr.i)) ||
3865020Sgblack@eecs.umich.edu        ((!req->isInstFetch()) && (!sctlr.c))){
3876563Sgblack@eecs.umich.edu       req->setFlags(Request::UNCACHEABLE);
3886606Sgblack@eecs.umich.edu    }
3896606Sgblack@eecs.umich.edu    if (!is_fetch) {
3905020Sgblack@eecs.umich.edu        assert(flags & MustBeOne);
3915020Sgblack@eecs.umich.edu        if (sctlr.a || !(flags & AllowUnaligned)) {
3925020Sgblack@eecs.umich.edu            if (vaddr & flags & AlignmentMask) {
3935020Sgblack@eecs.umich.edu                return new DataAbort(vaddr, 0, is_write, ArmFault::AlignmentFault);
3946564Sgblack@eecs.umich.edu            }
3956564Sgblack@eecs.umich.edu        }
3966563Sgblack@eecs.umich.edu    }
3975020Sgblack@eecs.umich.edu
3986606Sgblack@eecs.umich.edu    uint32_t context_id = tc->readMiscReg(MISCREG_CONTEXTIDR);
3996606Sgblack@eecs.umich.edu    Fault fault;
4005058Sgblack@eecs.umich.edu
4016602Sgblack@eecs.umich.edu
4025020Sgblack@eecs.umich.edu    if (!sctlr.m) {
4035020Sgblack@eecs.umich.edu        req->setPaddr(vaddr);
4045020Sgblack@eecs.umich.edu        if (sctlr.tre == 0) {
4055046Sgblack@eecs.umich.edu            req->setFlags(Request::UNCACHEABLE);
4065046Sgblack@eecs.umich.edu        } else {
4075046Sgblack@eecs.umich.edu            PRRR prrr = tc->readMiscReg(MISCREG_PRRR);
4085046Sgblack@eecs.umich.edu            NMRR nmrr = tc->readMiscReg(MISCREG_NMRR);
4096606Sgblack@eecs.umich.edu
4105020Sgblack@eecs.umich.edu            if (nmrr.ir0 == 0 || nmrr.or0 == 0 || prrr.tr0 != 0x2)
4115020Sgblack@eecs.umich.edu               req->setFlags(Request::UNCACHEABLE);
4125020Sgblack@eecs.umich.edu        }
4134276Sgblack@eecs.umich.edu
4144276Sgblack@eecs.umich.edu        // Set memory attributes
4155149Sgblack@eecs.umich.edu        TlbEntry temp_te;
4165409Sgblack@eecs.umich.edu        tableWalker->memAttrs(tc, temp_te, sctlr, 0, 1);
4175149Sgblack@eecs.umich.edu        temp_te.shareable = true;
4184712Sgblack@eecs.umich.edu        DPRINTF(TLBVerbose, "(No MMU) setting memory attributes: shareable:\
4195972Sgblack@eecs.umich.edu                %d, innerAttrs: %d, outerAttrs: %d\n", temp_te.shareable,
4204712Sgblack@eecs.umich.edu                temp_te.innerAttrs, temp_te.outerAttrs);
4215972Sgblack@eecs.umich.edu        setAttr(temp_te.attributes);
4225972Sgblack@eecs.umich.edu
4235972Sgblack@eecs.umich.edu        return trickBoxCheck(req, mode, 0, false);
4244712Sgblack@eecs.umich.edu    }
4254730Sgblack@eecs.umich.edu
4264712Sgblack@eecs.umich.edu    DPRINTF(TLBVerbose, "Translating vaddr=%#x context=%d\n", vaddr, context_id);
4274276Sgblack@eecs.umich.edu    // Translation enabled
4284276Sgblack@eecs.umich.edu
4294712Sgblack@eecs.umich.edu    TlbEntry *te = lookup(vaddr, context_id);
4304712Sgblack@eecs.umich.edu    if (te == NULL) {
4314712Sgblack@eecs.umich.edu        if (req->isPrefetch()){
4324712Sgblack@eecs.umich.edu           //if the request is a prefetch don't attempt to fill the TLB
4334712Sgblack@eecs.umich.edu           //or go any further with the memory access
4344712Sgblack@eecs.umich.edu           return new PrefetchAbort(vaddr, ArmFault::PrefetchTLBMiss);
4354712Sgblack@eecs.umich.edu        }
4364712Sgblack@eecs.umich.edu        // start translation table walk, pass variables rather than
4374276Sgblack@eecs.umich.edu        // re-retreaving in table walker for speed
4384760Sgblack@eecs.umich.edu        DPRINTF(TLB, "TLB Miss: Starting hardware table walker for %#x(%d)\n",
4394760Sgblack@eecs.umich.edu                vaddr, context_id);
4404760Sgblack@eecs.umich.edu        fault = tableWalker->walk(req, tc, context_id, mode, translation,
4414760Sgblack@eecs.umich.edu                timing);
4424760Sgblack@eecs.umich.edu        if (timing) {
4434760Sgblack@eecs.umich.edu            delay = true;
4444760Sgblack@eecs.umich.edu            // for timing mode, return and wait for table walk
4454760Sgblack@eecs.umich.edu            return fault;
4464760Sgblack@eecs.umich.edu        }
4474760Sgblack@eecs.umich.edu        if (fault)
4484760Sgblack@eecs.umich.edu            return fault;
4494760Sgblack@eecs.umich.edu
4504760Sgblack@eecs.umich.edu        te = lookup(vaddr, context_id);
4514760Sgblack@eecs.umich.edu        if (!te)
4524760Sgblack@eecs.umich.edu            printTlb();
4534760Sgblack@eecs.umich.edu        assert(te);
4544760Sgblack@eecs.umich.edu    }
4554760Sgblack@eecs.umich.edu
4564760Sgblack@eecs.umich.edu    // Set memory attributes
4574760Sgblack@eecs.umich.edu    DPRINTF(TLBVerbose,
4584760Sgblack@eecs.umich.edu            "Setting memory attributes: shareable: %d, innerAttrs: %d, \
4596576Sgblack@eecs.umich.edu            outerAttrs: %d\n",
4606576Sgblack@eecs.umich.edu            te->shareable, te->innerAttrs, te->outerAttrs);
4616576Sgblack@eecs.umich.edu    setAttr(te->attributes);
4626593Sgblack@eecs.umich.edu    if (te->nonCacheable)
4636576Sgblack@eecs.umich.edu        req->setFlags(Request::UNCACHEABLE);
4646576Sgblack@eecs.umich.edu    uint32_t dacr = tc->readMiscReg(MISCREG_DACR);
4656576Sgblack@eecs.umich.edu    switch ( (dacr >> (te->domain * 2)) & 0x3) {
4666576Sgblack@eecs.umich.edu      case 0:
4676576Sgblack@eecs.umich.edu        DPRINTF(TLB, "TLB Fault: Data abort on domain. DACR: %#x domain: %#x"
4686576Sgblack@eecs.umich.edu               " write:%d sNp:%d\n", dacr, te->domain, is_write, te->sNp);
4696576Sgblack@eecs.umich.edu        if (is_fetch)
4706576Sgblack@eecs.umich.edu            return new PrefetchAbort(vaddr,
4716576Sgblack@eecs.umich.edu                (te->sNp ? ArmFault::Domain0 : ArmFault::Domain1));
4726576Sgblack@eecs.umich.edu        else
4736576Sgblack@eecs.umich.edu            return new DataAbort(vaddr, te->domain, is_write,
4746576Sgblack@eecs.umich.edu                (te->sNp ? ArmFault::Domain0 : ArmFault::Domain1));
4756576Sgblack@eecs.umich.edu      case 1:
4766576Sgblack@eecs.umich.edu        // Continue with permissions check
4776576Sgblack@eecs.umich.edu        break;
4786576Sgblack@eecs.umich.edu      case 2:
4796576Sgblack@eecs.umich.edu        panic("UNPRED domain\n");
4806593Sgblack@eecs.umich.edu      case 3:
4816576Sgblack@eecs.umich.edu        req->setPaddr(te->pAddr(vaddr));
4826576Sgblack@eecs.umich.edu        fault = trickBoxCheck(req, mode, te->domain, te->sNp);
4836576Sgblack@eecs.umich.edu        if (fault)
4846576Sgblack@eecs.umich.edu            return fault;
4856576Sgblack@eecs.umich.edu        return NoFault;
4866576Sgblack@eecs.umich.edu    }
4876576Sgblack@eecs.umich.edu
4886576Sgblack@eecs.umich.edu    uint8_t ap = te->ap;
4896576Sgblack@eecs.umich.edu
4905059Sgblack@eecs.umich.edu    if (sctlr.afe == 1)
4915059Sgblack@eecs.umich.edu        ap |= 1;
4926576Sgblack@eecs.umich.edu
4935059Sgblack@eecs.umich.edu    bool abt;
4945059Sgblack@eecs.umich.edu
4955059Sgblack@eecs.umich.edu   /* if (!sctlr.xp)
4965020Sgblack@eecs.umich.edu        ap &= 0x3;
4976576Sgblack@eecs.umich.edu*/
4986576Sgblack@eecs.umich.edu    switch (ap) {
4996576Sgblack@eecs.umich.edu      case 0:
5006576Sgblack@eecs.umich.edu        DPRINTF(TLB, "Access permissions 0, checking rs:%#x\n", (int)sctlr.rs);
5016576Sgblack@eecs.umich.edu        if (!sctlr.xp) {
5026576Sgblack@eecs.umich.edu            switch ((int)sctlr.rs) {
5036576Sgblack@eecs.umich.edu              case 2:
5046576Sgblack@eecs.umich.edu                abt = is_write;
5056576Sgblack@eecs.umich.edu                break;
5066576Sgblack@eecs.umich.edu              case 1:
5076576Sgblack@eecs.umich.edu                abt = is_write || !is_priv;
5086576Sgblack@eecs.umich.edu                break;
5096576Sgblack@eecs.umich.edu              case 0:
5106576Sgblack@eecs.umich.edu              case 3:
5116576Sgblack@eecs.umich.edu              default:
5126576Sgblack@eecs.umich.edu                abt = true;
5136576Sgblack@eecs.umich.edu                break;
5146606Sgblack@eecs.umich.edu            }
5156576Sgblack@eecs.umich.edu        } else {
5166576Sgblack@eecs.umich.edu            abt = true;
5176576Sgblack@eecs.umich.edu        }
5186576Sgblack@eecs.umich.edu        break;
5196576Sgblack@eecs.umich.edu      case 1:
5206576Sgblack@eecs.umich.edu        abt = !is_priv;
5216576Sgblack@eecs.umich.edu        break;
5226576Sgblack@eecs.umich.edu      case 2:
5236576Sgblack@eecs.umich.edu        abt = !is_priv && is_write;
5246576Sgblack@eecs.umich.edu        break;
5256606Sgblack@eecs.umich.edu      case 3:
5266576Sgblack@eecs.umich.edu        abt = false;
5276576Sgblack@eecs.umich.edu        break;
5286576Sgblack@eecs.umich.edu      case 4:
5296576Sgblack@eecs.umich.edu        panic("UNPRED premissions\n");
5306576Sgblack@eecs.umich.edu      case 5:
5316576Sgblack@eecs.umich.edu        abt = !is_priv || is_write;
5326576Sgblack@eecs.umich.edu        break;
5336576Sgblack@eecs.umich.edu      case 6:
5346576Sgblack@eecs.umich.edu      case 7:
5356576Sgblack@eecs.umich.edu        abt = is_write;
5366576Sgblack@eecs.umich.edu        break;
5376576Sgblack@eecs.umich.edu      default:
5386576Sgblack@eecs.umich.edu        panic("Unknown permissions\n");
5396576Sgblack@eecs.umich.edu    }
5406576Sgblack@eecs.umich.edu    if ((is_fetch) && (abt || te->xn)) {
5416576Sgblack@eecs.umich.edu        DPRINTF(TLB, "TLB Fault: Prefetch abort on permission check. AP:%d priv:%d"
5426576Sgblack@eecs.umich.edu               " write:%d sNp:%d\n", ap, is_priv, is_write, te->sNp);
5435020Sgblack@eecs.umich.edu        return new PrefetchAbort(vaddr,
5446576Sgblack@eecs.umich.edu                (te->sNp ? ArmFault::Permission0 :
5456576Sgblack@eecs.umich.edu                 ArmFault::Permission1));
5466576Sgblack@eecs.umich.edu    } else if (abt) {
5476576Sgblack@eecs.umich.edu        DPRINTF(TLB, "TLB Fault: Data abort on permission check. AP:%d priv:%d"
5486576Sgblack@eecs.umich.edu               " write:%d sNp:%d\n", ap, is_priv, is_write, te->sNp);
5496576Sgblack@eecs.umich.edu        return new DataAbort(vaddr, te->domain, is_write,
5506576Sgblack@eecs.umich.edu                (te->sNp ? ArmFault::Permission0 :
5516576Sgblack@eecs.umich.edu                 ArmFault::Permission1));
5526576Sgblack@eecs.umich.edu    }
5536576Sgblack@eecs.umich.edu
5546576Sgblack@eecs.umich.edu    req->setPaddr(te->pAddr(vaddr));
5556576Sgblack@eecs.umich.edu    // Check for a trickbox generated address fault
5566576Sgblack@eecs.umich.edu    fault = trickBoxCheck(req, mode, te->domain, te->sNp);
5576576Sgblack@eecs.umich.edu    if (fault)
5586576Sgblack@eecs.umich.edu        return fault;
5596576Sgblack@eecs.umich.edu
5606576Sgblack@eecs.umich.edu    return NoFault;
5616576Sgblack@eecs.umich.edu}
5626576Sgblack@eecs.umich.edu
5636576Sgblack@eecs.umich.edu#endif
5646576Sgblack@eecs.umich.edu
5656576Sgblack@eecs.umich.eduFault
5666576Sgblack@eecs.umich.eduTLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
5676576Sgblack@eecs.umich.edu{
5685020Sgblack@eecs.umich.edu    bool delay = false;
5696576Sgblack@eecs.umich.edu    Fault fault;
5706576Sgblack@eecs.umich.edu#if FULL_SYSTEM
5716576Sgblack@eecs.umich.edu    fault = translateFs(req, tc, mode, NULL, delay, false);
5726576Sgblack@eecs.umich.edu#else
5736576Sgblack@eecs.umich.edu    fault = translateSe(req, tc, mode, NULL, delay, false);
5746576Sgblack@eecs.umich.edu#endif
5756576Sgblack@eecs.umich.edu    assert(!delay);
5766576Sgblack@eecs.umich.edu    return fault;
5776576Sgblack@eecs.umich.edu}
5786576Sgblack@eecs.umich.edu
5796576Sgblack@eecs.umich.eduFault
5806576Sgblack@eecs.umich.eduTLB::translateTiming(RequestPtr req, ThreadContext *tc,
5816576Sgblack@eecs.umich.edu        Translation *translation, Mode mode)
5826576Sgblack@eecs.umich.edu{
5836576Sgblack@eecs.umich.edu    assert(translation);
5846576Sgblack@eecs.umich.edu    bool delay = false;
5856576Sgblack@eecs.umich.edu    Fault fault;
5866576Sgblack@eecs.umich.edu#if FULL_SYSTEM
5876576Sgblack@eecs.umich.edu    fault = translateFs(req, tc, mode, translation, delay, true);
5886576Sgblack@eecs.umich.edu#else
5896576Sgblack@eecs.umich.edu    fault = translateSe(req, tc, mode, translation, delay, true);
5906576Sgblack@eecs.umich.edu#endif
5916576Sgblack@eecs.umich.edu    if (!delay)
5926576Sgblack@eecs.umich.edu        translation->finish(fault, req, tc, mode);
5936576Sgblack@eecs.umich.edu    return fault;
5946576Sgblack@eecs.umich.edu}
5956576Sgblack@eecs.umich.edu
5966576Sgblack@eecs.umich.eduArmISA::TLB *
5975020Sgblack@eecs.umich.eduArmTLBParams::create()
5986584Sgblack@eecs.umich.edu{
5996584Sgblack@eecs.umich.edu    return new ArmISA::TLB(this);
6006584Sgblack@eecs.umich.edu}
6016597Sgblack@eecs.umich.edu