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 §ion) 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