pagetable_walker.cc revision 12749
15245Sgblack@eecs.umich.edu/* 28948Sandreas.hansson@arm.com * Copyright (c) 2012 ARM Limited 38948Sandreas.hansson@arm.com * All rights reserved. 48948Sandreas.hansson@arm.com * 58948Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall 68948Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual 78948Sandreas.hansson@arm.com * property including but not limited to intellectual property relating 88948Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software 98948Sandreas.hansson@arm.com * licensed hereunder. You may use the software subject to the license 108948Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated 118948Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software, 128948Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form. 138948Sandreas.hansson@arm.com * 145245Sgblack@eecs.umich.edu * Copyright (c) 2007 The Hewlett-Packard Development Company 155245Sgblack@eecs.umich.edu * All rights reserved. 165245Sgblack@eecs.umich.edu * 177087Snate@binkert.org * The license below extends only to copyright in the software and shall 187087Snate@binkert.org * not be construed as granting a license to any other intellectual 197087Snate@binkert.org * property including but not limited to intellectual property relating 207087Snate@binkert.org * to a hardware implementation of the functionality of the software 217087Snate@binkert.org * licensed hereunder. You may use the software subject to the license 227087Snate@binkert.org * terms below provided that you ensure that this notice is replicated 237087Snate@binkert.org * unmodified and in its entirety in all distributions of the software, 247087Snate@binkert.org * modified or unmodified, in source code or in binary form. 255245Sgblack@eecs.umich.edu * 267087Snate@binkert.org * Redistribution and use in source and binary forms, with or without 277087Snate@binkert.org * modification, are permitted provided that the following conditions are 287087Snate@binkert.org * met: redistributions of source code must retain the above copyright 297087Snate@binkert.org * notice, this list of conditions and the following disclaimer; 307087Snate@binkert.org * redistributions in binary form must reproduce the above copyright 317087Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 327087Snate@binkert.org * documentation and/or other materials provided with the distribution; 337087Snate@binkert.org * neither the name of the copyright holders nor the names of its 345245Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 357087Snate@binkert.org * this software without specific prior written permission. 365245Sgblack@eecs.umich.edu * 375245Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 385245Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 395245Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 405245Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 415245Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 425245Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 435245Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 445245Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 455245Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 465245Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 475245Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 485245Sgblack@eecs.umich.edu * 495245Sgblack@eecs.umich.edu * Authors: Gabe Black 505245Sgblack@eecs.umich.edu */ 515245Sgblack@eecs.umich.edu 5211793Sbrandon.potter@amd.com#include "arch/x86/pagetable_walker.hh" 5311793Sbrandon.potter@amd.com 5410474Sandreas.hansson@arm.com#include <memory> 5510474Sandreas.hansson@arm.com 565245Sgblack@eecs.umich.edu#include "arch/x86/pagetable.hh" 575245Sgblack@eecs.umich.edu#include "arch/x86/tlb.hh" 587912Shestness@cs.utexas.edu#include "arch/x86/vtophys.hh" 595245Sgblack@eecs.umich.edu#include "base/bitfield.hh" 608953Sgblack@eecs.umich.edu#include "base/trie.hh" 618229Snate@binkert.org#include "cpu/base.hh" 625245Sgblack@eecs.umich.edu#include "cpu/thread_context.hh" 638232Snate@binkert.org#include "debug/PageTableWalker.hh" 645245Sgblack@eecs.umich.edu#include "mem/packet_access.hh" 655245Sgblack@eecs.umich.edu#include "mem/request.hh" 665245Sgblack@eecs.umich.edu 675245Sgblack@eecs.umich.edunamespace X86ISA { 685245Sgblack@eecs.umich.edu 695895Sgblack@eecs.umich.eduFault 707912Shestness@cs.utexas.eduWalker::start(ThreadContext * _tc, BaseTLB::Translation *_translation, 7112749Sgiacomo.travaglini@arm.com const RequestPtr &_req, BaseTLB::Mode _mode) 725245Sgblack@eecs.umich.edu{ 737912Shestness@cs.utexas.edu // TODO: in timing mode, instead of blocking when there are other 747912Shestness@cs.utexas.edu // outstanding requests, see if this request can be coalesced with 757912Shestness@cs.utexas.edu // another one (i.e. either coalesce or start walk) 767912Shestness@cs.utexas.edu WalkerState * newState = new WalkerState(this, _translation, _req); 779524SAndreas.Sandberg@ARM.com newState->initState(_tc, _mode, sys->isTimingMode()); 787912Shestness@cs.utexas.edu if (currStates.size()) { 797912Shestness@cs.utexas.edu assert(newState->isTiming()); 807912Shestness@cs.utexas.edu DPRINTF(PageTableWalker, "Walks in progress: %d\n", currStates.size()); 817912Shestness@cs.utexas.edu currStates.push_back(newState); 827912Shestness@cs.utexas.edu return NoFault; 837912Shestness@cs.utexas.edu } else { 847912Shestness@cs.utexas.edu currStates.push_back(newState); 857912Shestness@cs.utexas.edu Fault fault = newState->startWalk(); 867912Shestness@cs.utexas.edu if (!newState->isTiming()) { 877912Shestness@cs.utexas.edu currStates.pop_front(); 887912Shestness@cs.utexas.edu delete newState; 895895Sgblack@eecs.umich.edu } 907912Shestness@cs.utexas.edu return fault; 915245Sgblack@eecs.umich.edu } 925245Sgblack@eecs.umich.edu} 935245Sgblack@eecs.umich.edu 945895Sgblack@eecs.umich.eduFault 958953Sgblack@eecs.umich.eduWalker::startFunctional(ThreadContext * _tc, Addr &addr, unsigned &logBytes, 967912Shestness@cs.utexas.edu BaseTLB::Mode _mode) 975245Sgblack@eecs.umich.edu{ 987912Shestness@cs.utexas.edu funcState.initState(_tc, _mode); 998953Sgblack@eecs.umich.edu return funcState.startFunctional(addr, logBytes); 1005245Sgblack@eecs.umich.edu} 1015245Sgblack@eecs.umich.edu 1025245Sgblack@eecs.umich.edubool 1038975Sandreas.hansson@arm.comWalker::WalkerPort::recvTimingResp(PacketPtr pkt) 1045245Sgblack@eecs.umich.edu{ 1058975Sandreas.hansson@arm.com return walker->recvTimingResp(pkt); 1065245Sgblack@eecs.umich.edu} 1075245Sgblack@eecs.umich.edu 1085245Sgblack@eecs.umich.edubool 1098975Sandreas.hansson@arm.comWalker::recvTimingResp(PacketPtr pkt) 1105245Sgblack@eecs.umich.edu{ 1118948Sandreas.hansson@arm.com WalkerSenderState * senderState = 1129542Sandreas.hansson@arm.com dynamic_cast<WalkerSenderState *>(pkt->popSenderState()); 1138948Sandreas.hansson@arm.com WalkerState * senderWalk = senderState->senderWalk; 1148948Sandreas.hansson@arm.com bool walkComplete = senderWalk->recvPacket(pkt); 1158948Sandreas.hansson@arm.com delete senderState; 1168948Sandreas.hansson@arm.com if (walkComplete) { 1178948Sandreas.hansson@arm.com std::list<WalkerState *>::iterator iter; 1188948Sandreas.hansson@arm.com for (iter = currStates.begin(); iter != currStates.end(); iter++) { 1198948Sandreas.hansson@arm.com WalkerState * walkerState = *(iter); 1208948Sandreas.hansson@arm.com if (walkerState == senderWalk) { 1218948Sandreas.hansson@arm.com iter = currStates.erase(iter); 1228948Sandreas.hansson@arm.com break; 1235895Sgblack@eecs.umich.edu } 1245245Sgblack@eecs.umich.edu } 1258948Sandreas.hansson@arm.com delete senderWalk; 1268948Sandreas.hansson@arm.com // Since we block requests when another is outstanding, we 1278948Sandreas.hansson@arm.com // need to check if there is a waiting request to be serviced 12810654Sandreas.hansson@arm.com if (currStates.size() && !startWalkWrapperEvent.scheduled()) 12910654Sandreas.hansson@arm.com // delay sending any new requests until we are finished 13010654Sandreas.hansson@arm.com // with the responses 13110654Sandreas.hansson@arm.com schedule(startWalkWrapperEvent, clockEdge()); 1325245Sgblack@eecs.umich.edu } 1335245Sgblack@eecs.umich.edu return true; 1345245Sgblack@eecs.umich.edu} 1355245Sgblack@eecs.umich.edu 1365245Sgblack@eecs.umich.eduvoid 13710713Sandreas.hansson@arm.comWalker::WalkerPort::recvReqRetry() 1385245Sgblack@eecs.umich.edu{ 13910713Sandreas.hansson@arm.com walker->recvReqRetry(); 1405245Sgblack@eecs.umich.edu} 1415245Sgblack@eecs.umich.edu 1425245Sgblack@eecs.umich.eduvoid 14310713Sandreas.hansson@arm.comWalker::recvReqRetry() 1445245Sgblack@eecs.umich.edu{ 1457912Shestness@cs.utexas.edu std::list<WalkerState *>::iterator iter; 1467912Shestness@cs.utexas.edu for (iter = currStates.begin(); iter != currStates.end(); iter++) { 1477912Shestness@cs.utexas.edu WalkerState * walkerState = *(iter); 1487912Shestness@cs.utexas.edu if (walkerState->isRetrying()) { 1497912Shestness@cs.utexas.edu walkerState->retry(); 1507912Shestness@cs.utexas.edu } 1517912Shestness@cs.utexas.edu } 1527912Shestness@cs.utexas.edu} 1537912Shestness@cs.utexas.edu 1547912Shestness@cs.utexas.edubool Walker::sendTiming(WalkerState* sendingState, PacketPtr pkt) 1557912Shestness@cs.utexas.edu{ 15610018Sandreas.hansson@arm.com WalkerSenderState* walker_state = new WalkerSenderState(sendingState); 15710018Sandreas.hansson@arm.com pkt->pushSenderState(walker_state); 15810018Sandreas.hansson@arm.com if (port.sendTimingReq(pkt)) { 15910018Sandreas.hansson@arm.com return true; 16010018Sandreas.hansson@arm.com } else { 16110018Sandreas.hansson@arm.com // undo the adding of the sender state and delete it, as we 16210018Sandreas.hansson@arm.com // will do it again the next time we attempt to send it 16310018Sandreas.hansson@arm.com pkt->popSenderState(); 16410018Sandreas.hansson@arm.com delete walker_state; 16510018Sandreas.hansson@arm.com return false; 16610018Sandreas.hansson@arm.com } 16710018Sandreas.hansson@arm.com 1687912Shestness@cs.utexas.edu} 1697912Shestness@cs.utexas.edu 1709294Sandreas.hansson@arm.comBaseMasterPort & 1719294Sandreas.hansson@arm.comWalker::getMasterPort(const std::string &if_name, PortID idx) 1727912Shestness@cs.utexas.edu{ 1737912Shestness@cs.utexas.edu if (if_name == "port") 1748922Swilliam.wang@arm.com return port; 1757912Shestness@cs.utexas.edu else 1768922Swilliam.wang@arm.com return MemObject::getMasterPort(if_name, idx); 1775245Sgblack@eecs.umich.edu} 1785245Sgblack@eecs.umich.edu 1795245Sgblack@eecs.umich.eduvoid 1807912Shestness@cs.utexas.eduWalker::WalkerState::initState(ThreadContext * _tc, 1817912Shestness@cs.utexas.edu BaseTLB::Mode _mode, bool _isTiming) 1827912Shestness@cs.utexas.edu{ 1837912Shestness@cs.utexas.edu assert(state == Ready); 1847912Shestness@cs.utexas.edu started = false; 1857912Shestness@cs.utexas.edu tc = _tc; 1867912Shestness@cs.utexas.edu mode = _mode; 1877912Shestness@cs.utexas.edu timing = _isTiming; 1887912Shestness@cs.utexas.edu} 1897912Shestness@cs.utexas.edu 1909701Sgedare@rtems.orgvoid 1919701Sgedare@rtems.orgWalker::startWalkWrapper() 1929701Sgedare@rtems.org{ 1939701Sgedare@rtems.org unsigned num_squashed = 0; 1949701Sgedare@rtems.org WalkerState *currState = currStates.front(); 1959701Sgedare@rtems.org while ((num_squashed < numSquashable) && currState && 1969701Sgedare@rtems.org currState->translation->squashed()) { 1979701Sgedare@rtems.org currStates.pop_front(); 1989701Sgedare@rtems.org num_squashed++; 1999701Sgedare@rtems.org 2009701Sgedare@rtems.org DPRINTF(PageTableWalker, "Squashing table walk for address %#x\n", 2019701Sgedare@rtems.org currState->req->getVaddr()); 2029701Sgedare@rtems.org 2039701Sgedare@rtems.org // finish the translation which will delete the translation object 20410474Sandreas.hansson@arm.com currState->translation->finish( 20510474Sandreas.hansson@arm.com std::make_shared<UnimpFault>("Squashed Inst"), 20610474Sandreas.hansson@arm.com currState->req, currState->tc, currState->mode); 2079701Sgedare@rtems.org 2089701Sgedare@rtems.org // delete the current request 2099701Sgedare@rtems.org delete currState; 2109701Sgedare@rtems.org 2119701Sgedare@rtems.org // check the next translation request, if it exists 2129701Sgedare@rtems.org if (currStates.size()) 2139701Sgedare@rtems.org currState = currStates.front(); 2149701Sgedare@rtems.org else 2159701Sgedare@rtems.org currState = NULL; 2169701Sgedare@rtems.org } 2179701Sgedare@rtems.org if (currState && !currState->wasStarted()) 2189701Sgedare@rtems.org currState->startWalk(); 2199701Sgedare@rtems.org} 2209701Sgedare@rtems.org 2217912Shestness@cs.utexas.eduFault 2227912Shestness@cs.utexas.eduWalker::WalkerState::startWalk() 2237912Shestness@cs.utexas.edu{ 2247912Shestness@cs.utexas.edu Fault fault = NoFault; 22510231Ssteve.reinhardt@amd.com assert(!started); 2267912Shestness@cs.utexas.edu started = true; 2277912Shestness@cs.utexas.edu setupWalk(req->getVaddr()); 2287912Shestness@cs.utexas.edu if (timing) { 2297912Shestness@cs.utexas.edu nextState = state; 2307912Shestness@cs.utexas.edu state = Waiting; 2317912Shestness@cs.utexas.edu timingFault = NoFault; 2327912Shestness@cs.utexas.edu sendPackets(); 2337912Shestness@cs.utexas.edu } else { 2347912Shestness@cs.utexas.edu do { 2357912Shestness@cs.utexas.edu walker->port.sendAtomic(read); 2367912Shestness@cs.utexas.edu PacketPtr write = NULL; 2377912Shestness@cs.utexas.edu fault = stepWalk(write); 2387912Shestness@cs.utexas.edu assert(fault == NoFault || read == NULL); 2397912Shestness@cs.utexas.edu state = nextState; 2407912Shestness@cs.utexas.edu nextState = Ready; 2417912Shestness@cs.utexas.edu if (write) 2427912Shestness@cs.utexas.edu walker->port.sendAtomic(write); 24311321Ssteve.reinhardt@amd.com } while (read); 2447912Shestness@cs.utexas.edu state = Ready; 2457912Shestness@cs.utexas.edu nextState = Waiting; 2467912Shestness@cs.utexas.edu } 2477912Shestness@cs.utexas.edu return fault; 2487912Shestness@cs.utexas.edu} 2497912Shestness@cs.utexas.edu 2507912Shestness@cs.utexas.eduFault 2518953Sgblack@eecs.umich.eduWalker::WalkerState::startFunctional(Addr &addr, unsigned &logBytes) 2527912Shestness@cs.utexas.edu{ 2537912Shestness@cs.utexas.edu Fault fault = NoFault; 25410231Ssteve.reinhardt@amd.com assert(!started); 2557912Shestness@cs.utexas.edu started = true; 2567912Shestness@cs.utexas.edu setupWalk(addr); 2577912Shestness@cs.utexas.edu 2587912Shestness@cs.utexas.edu do { 2597912Shestness@cs.utexas.edu walker->port.sendFunctional(read); 2607912Shestness@cs.utexas.edu // On a functional access (page table lookup), writes should 2617912Shestness@cs.utexas.edu // not happen so this pointer is ignored after stepWalk 2627912Shestness@cs.utexas.edu PacketPtr write = NULL; 2637912Shestness@cs.utexas.edu fault = stepWalk(write); 2647912Shestness@cs.utexas.edu assert(fault == NoFault || read == NULL); 2657912Shestness@cs.utexas.edu state = nextState; 2667912Shestness@cs.utexas.edu nextState = Ready; 26711321Ssteve.reinhardt@amd.com } while (read); 2688953Sgblack@eecs.umich.edu logBytes = entry.logBytes; 2697912Shestness@cs.utexas.edu addr = entry.paddr; 2707912Shestness@cs.utexas.edu 2717912Shestness@cs.utexas.edu return fault; 2727912Shestness@cs.utexas.edu} 2737912Shestness@cs.utexas.edu 2747912Shestness@cs.utexas.eduFault 2757912Shestness@cs.utexas.eduWalker::WalkerState::stepWalk(PacketPtr &write) 2767912Shestness@cs.utexas.edu{ 2777912Shestness@cs.utexas.edu assert(state != Ready && state != Waiting); 2787912Shestness@cs.utexas.edu Fault fault = NoFault; 2797912Shestness@cs.utexas.edu write = NULL; 2807912Shestness@cs.utexas.edu PageTableEntry pte; 2817912Shestness@cs.utexas.edu if (dataSize == 8) 2827912Shestness@cs.utexas.edu pte = read->get<uint64_t>(); 2837912Shestness@cs.utexas.edu else 2847912Shestness@cs.utexas.edu pte = read->get<uint32_t>(); 2857912Shestness@cs.utexas.edu VAddr vaddr = entry.vaddr; 2867912Shestness@cs.utexas.edu bool uncacheable = pte.pcd; 2877912Shestness@cs.utexas.edu Addr nextRead = 0; 2887912Shestness@cs.utexas.edu bool doWrite = false; 2897912Shestness@cs.utexas.edu bool doTLBInsert = false; 2907912Shestness@cs.utexas.edu bool doEndWalk = false; 2917912Shestness@cs.utexas.edu bool badNX = pte.nx && mode == BaseTLB::Execute && enableNX; 2927912Shestness@cs.utexas.edu switch(state) { 2937912Shestness@cs.utexas.edu case LongPML4: 2947912Shestness@cs.utexas.edu DPRINTF(PageTableWalker, 2957912Shestness@cs.utexas.edu "Got long mode PML4 entry %#016x.\n", (uint64_t)pte); 2967912Shestness@cs.utexas.edu nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.longl3 * dataSize; 2977912Shestness@cs.utexas.edu doWrite = !pte.a; 2987912Shestness@cs.utexas.edu pte.a = 1; 2997912Shestness@cs.utexas.edu entry.writable = pte.w; 3007912Shestness@cs.utexas.edu entry.user = pte.u; 3017912Shestness@cs.utexas.edu if (badNX || !pte.p) { 3027912Shestness@cs.utexas.edu doEndWalk = true; 3037912Shestness@cs.utexas.edu fault = pageFault(pte.p); 3047912Shestness@cs.utexas.edu break; 3057912Shestness@cs.utexas.edu } 3067912Shestness@cs.utexas.edu entry.noExec = pte.nx; 3077912Shestness@cs.utexas.edu nextState = LongPDP; 3087912Shestness@cs.utexas.edu break; 3097912Shestness@cs.utexas.edu case LongPDP: 3107912Shestness@cs.utexas.edu DPRINTF(PageTableWalker, 3117912Shestness@cs.utexas.edu "Got long mode PDP entry %#016x.\n", (uint64_t)pte); 3127912Shestness@cs.utexas.edu nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.longl2 * dataSize; 3137912Shestness@cs.utexas.edu doWrite = !pte.a; 3147912Shestness@cs.utexas.edu pte.a = 1; 3157912Shestness@cs.utexas.edu entry.writable = entry.writable && pte.w; 3167912Shestness@cs.utexas.edu entry.user = entry.user && pte.u; 3177912Shestness@cs.utexas.edu if (badNX || !pte.p) { 3187912Shestness@cs.utexas.edu doEndWalk = true; 3197912Shestness@cs.utexas.edu fault = pageFault(pte.p); 3207912Shestness@cs.utexas.edu break; 3217912Shestness@cs.utexas.edu } 3227912Shestness@cs.utexas.edu nextState = LongPD; 3237912Shestness@cs.utexas.edu break; 3247912Shestness@cs.utexas.edu case LongPD: 3257912Shestness@cs.utexas.edu DPRINTF(PageTableWalker, 3267912Shestness@cs.utexas.edu "Got long mode PD entry %#016x.\n", (uint64_t)pte); 3277912Shestness@cs.utexas.edu doWrite = !pte.a; 3287912Shestness@cs.utexas.edu pte.a = 1; 3297912Shestness@cs.utexas.edu entry.writable = entry.writable && pte.w; 3307912Shestness@cs.utexas.edu entry.user = entry.user && pte.u; 3317912Shestness@cs.utexas.edu if (badNX || !pte.p) { 3327912Shestness@cs.utexas.edu doEndWalk = true; 3337912Shestness@cs.utexas.edu fault = pageFault(pte.p); 3347912Shestness@cs.utexas.edu break; 3357912Shestness@cs.utexas.edu } 3367912Shestness@cs.utexas.edu if (!pte.ps) { 3377912Shestness@cs.utexas.edu // 4 KB page 3388953Sgblack@eecs.umich.edu entry.logBytes = 12; 3397912Shestness@cs.utexas.edu nextRead = 3407912Shestness@cs.utexas.edu ((uint64_t)pte & (mask(40) << 12)) + vaddr.longl1 * dataSize; 3417912Shestness@cs.utexas.edu nextState = LongPTE; 3427912Shestness@cs.utexas.edu break; 3437912Shestness@cs.utexas.edu } else { 3447912Shestness@cs.utexas.edu // 2 MB page 3458953Sgblack@eecs.umich.edu entry.logBytes = 21; 3467912Shestness@cs.utexas.edu entry.paddr = (uint64_t)pte & (mask(31) << 21); 3477912Shestness@cs.utexas.edu entry.uncacheable = uncacheable; 3487912Shestness@cs.utexas.edu entry.global = pte.g; 3497912Shestness@cs.utexas.edu entry.patBit = bits(pte, 12); 3507912Shestness@cs.utexas.edu entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1); 3517912Shestness@cs.utexas.edu doTLBInsert = true; 3527912Shestness@cs.utexas.edu doEndWalk = true; 3537912Shestness@cs.utexas.edu break; 3547912Shestness@cs.utexas.edu } 3557912Shestness@cs.utexas.edu case LongPTE: 3567912Shestness@cs.utexas.edu DPRINTF(PageTableWalker, 3577912Shestness@cs.utexas.edu "Got long mode PTE entry %#016x.\n", (uint64_t)pte); 3587912Shestness@cs.utexas.edu doWrite = !pte.a; 3597912Shestness@cs.utexas.edu pte.a = 1; 3607912Shestness@cs.utexas.edu entry.writable = entry.writable && pte.w; 3617912Shestness@cs.utexas.edu entry.user = entry.user && pte.u; 3627912Shestness@cs.utexas.edu if (badNX || !pte.p) { 3637912Shestness@cs.utexas.edu doEndWalk = true; 3647912Shestness@cs.utexas.edu fault = pageFault(pte.p); 3657912Shestness@cs.utexas.edu break; 3667912Shestness@cs.utexas.edu } 3677912Shestness@cs.utexas.edu entry.paddr = (uint64_t)pte & (mask(40) << 12); 3687912Shestness@cs.utexas.edu entry.uncacheable = uncacheable; 3697912Shestness@cs.utexas.edu entry.global = pte.g; 3707912Shestness@cs.utexas.edu entry.patBit = bits(pte, 12); 3717912Shestness@cs.utexas.edu entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1); 3727912Shestness@cs.utexas.edu doTLBInsert = true; 3737912Shestness@cs.utexas.edu doEndWalk = true; 3747912Shestness@cs.utexas.edu break; 3757912Shestness@cs.utexas.edu case PAEPDP: 3767912Shestness@cs.utexas.edu DPRINTF(PageTableWalker, 3777912Shestness@cs.utexas.edu "Got legacy mode PAE PDP entry %#08x.\n", (uint32_t)pte); 3787912Shestness@cs.utexas.edu nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.pael2 * dataSize; 3797912Shestness@cs.utexas.edu if (!pte.p) { 3807912Shestness@cs.utexas.edu doEndWalk = true; 3817912Shestness@cs.utexas.edu fault = pageFault(pte.p); 3827912Shestness@cs.utexas.edu break; 3837912Shestness@cs.utexas.edu } 3847912Shestness@cs.utexas.edu nextState = PAEPD; 3857912Shestness@cs.utexas.edu break; 3867912Shestness@cs.utexas.edu case PAEPD: 3877912Shestness@cs.utexas.edu DPRINTF(PageTableWalker, 3887912Shestness@cs.utexas.edu "Got legacy mode PAE PD entry %#08x.\n", (uint32_t)pte); 3897912Shestness@cs.utexas.edu doWrite = !pte.a; 3907912Shestness@cs.utexas.edu pte.a = 1; 3917912Shestness@cs.utexas.edu entry.writable = pte.w; 3927912Shestness@cs.utexas.edu entry.user = pte.u; 3937912Shestness@cs.utexas.edu if (badNX || !pte.p) { 3947912Shestness@cs.utexas.edu doEndWalk = true; 3957912Shestness@cs.utexas.edu fault = pageFault(pte.p); 3967912Shestness@cs.utexas.edu break; 3977912Shestness@cs.utexas.edu } 3987912Shestness@cs.utexas.edu if (!pte.ps) { 3997912Shestness@cs.utexas.edu // 4 KB page 4008953Sgblack@eecs.umich.edu entry.logBytes = 12; 4017912Shestness@cs.utexas.edu nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.pael1 * dataSize; 4027912Shestness@cs.utexas.edu nextState = PAEPTE; 4037912Shestness@cs.utexas.edu break; 4047912Shestness@cs.utexas.edu } else { 4057912Shestness@cs.utexas.edu // 2 MB page 4068953Sgblack@eecs.umich.edu entry.logBytes = 21; 4077912Shestness@cs.utexas.edu entry.paddr = (uint64_t)pte & (mask(31) << 21); 4087912Shestness@cs.utexas.edu entry.uncacheable = uncacheable; 4097912Shestness@cs.utexas.edu entry.global = pte.g; 4107912Shestness@cs.utexas.edu entry.patBit = bits(pte, 12); 4117912Shestness@cs.utexas.edu entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1); 4127912Shestness@cs.utexas.edu doTLBInsert = true; 4137912Shestness@cs.utexas.edu doEndWalk = true; 4147912Shestness@cs.utexas.edu break; 4157912Shestness@cs.utexas.edu } 4167912Shestness@cs.utexas.edu case PAEPTE: 4177912Shestness@cs.utexas.edu DPRINTF(PageTableWalker, 4187912Shestness@cs.utexas.edu "Got legacy mode PAE PTE entry %#08x.\n", (uint32_t)pte); 4197912Shestness@cs.utexas.edu doWrite = !pte.a; 4207912Shestness@cs.utexas.edu pte.a = 1; 4217912Shestness@cs.utexas.edu entry.writable = entry.writable && pte.w; 4227912Shestness@cs.utexas.edu entry.user = entry.user && pte.u; 4237912Shestness@cs.utexas.edu if (badNX || !pte.p) { 4247912Shestness@cs.utexas.edu doEndWalk = true; 4257912Shestness@cs.utexas.edu fault = pageFault(pte.p); 4267912Shestness@cs.utexas.edu break; 4277912Shestness@cs.utexas.edu } 4287912Shestness@cs.utexas.edu entry.paddr = (uint64_t)pte & (mask(40) << 12); 4297912Shestness@cs.utexas.edu entry.uncacheable = uncacheable; 4307912Shestness@cs.utexas.edu entry.global = pte.g; 4317912Shestness@cs.utexas.edu entry.patBit = bits(pte, 7); 4327912Shestness@cs.utexas.edu entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1); 4337912Shestness@cs.utexas.edu doTLBInsert = true; 4347912Shestness@cs.utexas.edu doEndWalk = true; 4357912Shestness@cs.utexas.edu break; 4367912Shestness@cs.utexas.edu case PSEPD: 4377912Shestness@cs.utexas.edu DPRINTF(PageTableWalker, 4387912Shestness@cs.utexas.edu "Got legacy mode PSE PD entry %#08x.\n", (uint32_t)pte); 4397912Shestness@cs.utexas.edu doWrite = !pte.a; 4407912Shestness@cs.utexas.edu pte.a = 1; 4417912Shestness@cs.utexas.edu entry.writable = pte.w; 4427912Shestness@cs.utexas.edu entry.user = pte.u; 4437912Shestness@cs.utexas.edu if (!pte.p) { 4447912Shestness@cs.utexas.edu doEndWalk = true; 4457912Shestness@cs.utexas.edu fault = pageFault(pte.p); 4467912Shestness@cs.utexas.edu break; 4477912Shestness@cs.utexas.edu } 4487912Shestness@cs.utexas.edu if (!pte.ps) { 4497912Shestness@cs.utexas.edu // 4 KB page 4508953Sgblack@eecs.umich.edu entry.logBytes = 12; 4517912Shestness@cs.utexas.edu nextRead = 4527912Shestness@cs.utexas.edu ((uint64_t)pte & (mask(20) << 12)) + vaddr.norml2 * dataSize; 4537912Shestness@cs.utexas.edu nextState = PTE; 4547912Shestness@cs.utexas.edu break; 4557912Shestness@cs.utexas.edu } else { 4567912Shestness@cs.utexas.edu // 4 MB page 4578953Sgblack@eecs.umich.edu entry.logBytes = 21; 4587912Shestness@cs.utexas.edu entry.paddr = bits(pte, 20, 13) << 32 | bits(pte, 31, 22) << 22; 4597912Shestness@cs.utexas.edu entry.uncacheable = uncacheable; 4607912Shestness@cs.utexas.edu entry.global = pte.g; 4617912Shestness@cs.utexas.edu entry.patBit = bits(pte, 12); 4627912Shestness@cs.utexas.edu entry.vaddr = entry.vaddr & ~((4 * (1 << 20)) - 1); 4637912Shestness@cs.utexas.edu doTLBInsert = true; 4647912Shestness@cs.utexas.edu doEndWalk = true; 4657912Shestness@cs.utexas.edu break; 4667912Shestness@cs.utexas.edu } 4677912Shestness@cs.utexas.edu case PD: 4687912Shestness@cs.utexas.edu DPRINTF(PageTableWalker, 4697912Shestness@cs.utexas.edu "Got legacy mode PD entry %#08x.\n", (uint32_t)pte); 4707912Shestness@cs.utexas.edu doWrite = !pte.a; 4717912Shestness@cs.utexas.edu pte.a = 1; 4727912Shestness@cs.utexas.edu entry.writable = pte.w; 4737912Shestness@cs.utexas.edu entry.user = pte.u; 4747912Shestness@cs.utexas.edu if (!pte.p) { 4757912Shestness@cs.utexas.edu doEndWalk = true; 4767912Shestness@cs.utexas.edu fault = pageFault(pte.p); 4777912Shestness@cs.utexas.edu break; 4787912Shestness@cs.utexas.edu } 4797912Shestness@cs.utexas.edu // 4 KB page 4808953Sgblack@eecs.umich.edu entry.logBytes = 12; 4817912Shestness@cs.utexas.edu nextRead = ((uint64_t)pte & (mask(20) << 12)) + vaddr.norml2 * dataSize; 4827912Shestness@cs.utexas.edu nextState = PTE; 4837912Shestness@cs.utexas.edu break; 4847912Shestness@cs.utexas.edu case PTE: 4857912Shestness@cs.utexas.edu DPRINTF(PageTableWalker, 4867912Shestness@cs.utexas.edu "Got legacy mode PTE entry %#08x.\n", (uint32_t)pte); 4877912Shestness@cs.utexas.edu doWrite = !pte.a; 4887912Shestness@cs.utexas.edu pte.a = 1; 4897912Shestness@cs.utexas.edu entry.writable = pte.w; 4907912Shestness@cs.utexas.edu entry.user = pte.u; 4917912Shestness@cs.utexas.edu if (!pte.p) { 4927912Shestness@cs.utexas.edu doEndWalk = true; 4937912Shestness@cs.utexas.edu fault = pageFault(pte.p); 4947912Shestness@cs.utexas.edu break; 4957912Shestness@cs.utexas.edu } 4967912Shestness@cs.utexas.edu entry.paddr = (uint64_t)pte & (mask(20) << 12); 4977912Shestness@cs.utexas.edu entry.uncacheable = uncacheable; 4987912Shestness@cs.utexas.edu entry.global = pte.g; 4997912Shestness@cs.utexas.edu entry.patBit = bits(pte, 7); 5007912Shestness@cs.utexas.edu entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1); 5017912Shestness@cs.utexas.edu doTLBInsert = true; 5027912Shestness@cs.utexas.edu doEndWalk = true; 5037912Shestness@cs.utexas.edu break; 5047912Shestness@cs.utexas.edu default: 5057912Shestness@cs.utexas.edu panic("Unknown page table walker state %d!\n"); 5067912Shestness@cs.utexas.edu } 5077912Shestness@cs.utexas.edu if (doEndWalk) { 5087912Shestness@cs.utexas.edu if (doTLBInsert) 5097912Shestness@cs.utexas.edu if (!functional) 5107912Shestness@cs.utexas.edu walker->tlb->insert(entry.vaddr, entry); 5117912Shestness@cs.utexas.edu endWalk(); 5127912Shestness@cs.utexas.edu } else { 5137912Shestness@cs.utexas.edu PacketPtr oldRead = read; 5147912Shestness@cs.utexas.edu //If we didn't return, we're setting up another read. 5157912Shestness@cs.utexas.edu Request::Flags flags = oldRead->req->getFlags(); 5167912Shestness@cs.utexas.edu flags.set(Request::UNCACHEABLE, uncacheable); 51712749Sgiacomo.travaglini@arm.com RequestPtr request = std::make_shared<Request>( 51812749Sgiacomo.travaglini@arm.com nextRead, oldRead->getSize(), flags, walker->masterId); 5198949Sandreas.hansson@arm.com read = new Packet(request, MemCmd::ReadReq); 5207912Shestness@cs.utexas.edu read->allocate(); 5217912Shestness@cs.utexas.edu // If we need to write, adjust the read packet to write the modified 5227912Shestness@cs.utexas.edu // value back to memory. 5237912Shestness@cs.utexas.edu if (doWrite) { 5247912Shestness@cs.utexas.edu write = oldRead; 5257912Shestness@cs.utexas.edu write->set<uint64_t>(pte); 5267912Shestness@cs.utexas.edu write->cmd = MemCmd::WriteReq; 5277912Shestness@cs.utexas.edu } else { 5287912Shestness@cs.utexas.edu write = NULL; 5297912Shestness@cs.utexas.edu delete oldRead; 5307912Shestness@cs.utexas.edu } 5317912Shestness@cs.utexas.edu } 5327912Shestness@cs.utexas.edu return fault; 5337912Shestness@cs.utexas.edu} 5347912Shestness@cs.utexas.edu 5357912Shestness@cs.utexas.eduvoid 5367912Shestness@cs.utexas.eduWalker::WalkerState::endWalk() 5377912Shestness@cs.utexas.edu{ 5387912Shestness@cs.utexas.edu nextState = Ready; 5397912Shestness@cs.utexas.edu delete read; 5407912Shestness@cs.utexas.edu read = NULL; 5417912Shestness@cs.utexas.edu} 5427912Shestness@cs.utexas.edu 5437912Shestness@cs.utexas.eduvoid 5447912Shestness@cs.utexas.eduWalker::WalkerState::setupWalk(Addr vaddr) 5457912Shestness@cs.utexas.edu{ 5467912Shestness@cs.utexas.edu VAddr addr = vaddr; 5477912Shestness@cs.utexas.edu CR3 cr3 = tc->readMiscRegNoEffect(MISCREG_CR3); 5487912Shestness@cs.utexas.edu // Check if we're in long mode or not 5497912Shestness@cs.utexas.edu Efer efer = tc->readMiscRegNoEffect(MISCREG_EFER); 5507912Shestness@cs.utexas.edu dataSize = 8; 5517912Shestness@cs.utexas.edu Addr topAddr; 5527912Shestness@cs.utexas.edu if (efer.lma) { 5537912Shestness@cs.utexas.edu // Do long mode. 5547912Shestness@cs.utexas.edu state = LongPML4; 5557912Shestness@cs.utexas.edu topAddr = (cr3.longPdtb << 12) + addr.longl4 * dataSize; 5567912Shestness@cs.utexas.edu enableNX = efer.nxe; 5577912Shestness@cs.utexas.edu } else { 5587912Shestness@cs.utexas.edu // We're in some flavor of legacy mode. 5597912Shestness@cs.utexas.edu CR4 cr4 = tc->readMiscRegNoEffect(MISCREG_CR4); 5607912Shestness@cs.utexas.edu if (cr4.pae) { 5617912Shestness@cs.utexas.edu // Do legacy PAE. 5627912Shestness@cs.utexas.edu state = PAEPDP; 5637912Shestness@cs.utexas.edu topAddr = (cr3.paePdtb << 5) + addr.pael3 * dataSize; 5647912Shestness@cs.utexas.edu enableNX = efer.nxe; 5657912Shestness@cs.utexas.edu } else { 5667912Shestness@cs.utexas.edu dataSize = 4; 5677912Shestness@cs.utexas.edu topAddr = (cr3.pdtb << 12) + addr.norml2 * dataSize; 5687912Shestness@cs.utexas.edu if (cr4.pse) { 5697912Shestness@cs.utexas.edu // Do legacy PSE. 5707912Shestness@cs.utexas.edu state = PSEPD; 5717912Shestness@cs.utexas.edu } else { 5727912Shestness@cs.utexas.edu // Do legacy non PSE. 5737912Shestness@cs.utexas.edu state = PD; 5747912Shestness@cs.utexas.edu } 5757912Shestness@cs.utexas.edu enableNX = false; 5767912Shestness@cs.utexas.edu } 5777912Shestness@cs.utexas.edu } 5787912Shestness@cs.utexas.edu 5797912Shestness@cs.utexas.edu nextState = Ready; 5807912Shestness@cs.utexas.edu entry.vaddr = vaddr; 5817912Shestness@cs.utexas.edu 5827912Shestness@cs.utexas.edu Request::Flags flags = Request::PHYSICAL; 5837912Shestness@cs.utexas.edu if (cr3.pcd) 5847912Shestness@cs.utexas.edu flags.set(Request::UNCACHEABLE); 58512749Sgiacomo.travaglini@arm.com 58612749Sgiacomo.travaglini@arm.com RequestPtr request = std::make_shared<Request>( 58712749Sgiacomo.travaglini@arm.com topAddr, dataSize, flags, walker->masterId); 58812749Sgiacomo.travaglini@arm.com 5898949Sandreas.hansson@arm.com read = new Packet(request, MemCmd::ReadReq); 5907912Shestness@cs.utexas.edu read->allocate(); 5917912Shestness@cs.utexas.edu} 5927912Shestness@cs.utexas.edu 5937912Shestness@cs.utexas.edubool 5947912Shestness@cs.utexas.eduWalker::WalkerState::recvPacket(PacketPtr pkt) 5957912Shestness@cs.utexas.edu{ 5968948Sandreas.hansson@arm.com assert(pkt->isResponse()); 5979165Sandreas.hansson@arm.com assert(inflight); 5989165Sandreas.hansson@arm.com assert(state == Waiting); 5999165Sandreas.hansson@arm.com inflight--; 6009165Sandreas.hansson@arm.com if (pkt->isRead()) { 60110241Sbinhpham@cs.rutgers.edu // should not have a pending read it we also had one outstanding 60210241Sbinhpham@cs.rutgers.edu assert(!read); 60310241Sbinhpham@cs.rutgers.edu 6049579Sandreas.hansson@arm.com // @todo someone should pay for this 60510694SMarco.Balboni@ARM.com pkt->headerDelay = pkt->payloadDelay = 0; 6069579Sandreas.hansson@arm.com 6079165Sandreas.hansson@arm.com state = nextState; 6089165Sandreas.hansson@arm.com nextState = Ready; 6099165Sandreas.hansson@arm.com PacketPtr write = NULL; 6109165Sandreas.hansson@arm.com read = pkt; 6119165Sandreas.hansson@arm.com timingFault = stepWalk(write); 6129165Sandreas.hansson@arm.com state = Waiting; 6139165Sandreas.hansson@arm.com assert(timingFault == NoFault || read == NULL); 6149165Sandreas.hansson@arm.com if (write) { 6159165Sandreas.hansson@arm.com writes.push_back(write); 6169165Sandreas.hansson@arm.com } 6179165Sandreas.hansson@arm.com sendPackets(); 6189165Sandreas.hansson@arm.com } else { 6199165Sandreas.hansson@arm.com sendPackets(); 6209165Sandreas.hansson@arm.com } 6219165Sandreas.hansson@arm.com if (inflight == 0 && read == NULL && writes.size() == 0) { 6229165Sandreas.hansson@arm.com state = Ready; 6239165Sandreas.hansson@arm.com nextState = Waiting; 6249165Sandreas.hansson@arm.com if (timingFault == NoFault) { 6259165Sandreas.hansson@arm.com /* 62611216Sbaz21@cam.ac.uk * Finish the translation. Now that we know the right entry is 6279165Sandreas.hansson@arm.com * in the TLB, this should work with no memory accesses. 6289165Sandreas.hansson@arm.com * There could be new faults unrelated to the table walk like 6299165Sandreas.hansson@arm.com * permissions violations, so we'll need the return value as 6309165Sandreas.hansson@arm.com * well. 6319165Sandreas.hansson@arm.com */ 6329165Sandreas.hansson@arm.com bool delayedResponse; 6339165Sandreas.hansson@arm.com Fault fault = walker->tlb->translate(req, tc, NULL, mode, 6349165Sandreas.hansson@arm.com delayedResponse, true); 6359165Sandreas.hansson@arm.com assert(!delayedResponse); 6369165Sandreas.hansson@arm.com // Let the CPU continue. 6379165Sandreas.hansson@arm.com translation->finish(fault, req, tc, mode); 6387912Shestness@cs.utexas.edu } else { 6399165Sandreas.hansson@arm.com // There was a fault during the walk. Let the CPU know. 6409165Sandreas.hansson@arm.com translation->finish(timingFault, req, tc, mode); 6417912Shestness@cs.utexas.edu } 6429165Sandreas.hansson@arm.com return true; 6437912Shestness@cs.utexas.edu } 6449165Sandreas.hansson@arm.com 6457912Shestness@cs.utexas.edu return false; 6467912Shestness@cs.utexas.edu} 6477912Shestness@cs.utexas.edu 6487912Shestness@cs.utexas.eduvoid 6497912Shestness@cs.utexas.eduWalker::WalkerState::sendPackets() 6505245Sgblack@eecs.umich.edu{ 6515245Sgblack@eecs.umich.edu //If we're already waiting for the port to become available, just return. 6525245Sgblack@eecs.umich.edu if (retrying) 6535245Sgblack@eecs.umich.edu return; 6545245Sgblack@eecs.umich.edu 6555245Sgblack@eecs.umich.edu //Reads always have priority 6565245Sgblack@eecs.umich.edu if (read) { 6575897Sgblack@eecs.umich.edu PacketPtr pkt = read; 6585897Sgblack@eecs.umich.edu read = NULL; 6595897Sgblack@eecs.umich.edu inflight++; 6607912Shestness@cs.utexas.edu if (!walker->sendTiming(this, pkt)) { 6615245Sgblack@eecs.umich.edu retrying = true; 6625897Sgblack@eecs.umich.edu read = pkt; 6635897Sgblack@eecs.umich.edu inflight--; 6645245Sgblack@eecs.umich.edu return; 6655245Sgblack@eecs.umich.edu } 6665245Sgblack@eecs.umich.edu } 6675245Sgblack@eecs.umich.edu //Send off as many of the writes as we can. 6685245Sgblack@eecs.umich.edu while (writes.size()) { 6695245Sgblack@eecs.umich.edu PacketPtr write = writes.back(); 6705897Sgblack@eecs.umich.edu writes.pop_back(); 6715897Sgblack@eecs.umich.edu inflight++; 6727912Shestness@cs.utexas.edu if (!walker->sendTiming(this, write)) { 6735245Sgblack@eecs.umich.edu retrying = true; 6745897Sgblack@eecs.umich.edu writes.push_back(write); 6755897Sgblack@eecs.umich.edu inflight--; 6765245Sgblack@eecs.umich.edu return; 6775245Sgblack@eecs.umich.edu } 6785245Sgblack@eecs.umich.edu } 6795245Sgblack@eecs.umich.edu} 6805245Sgblack@eecs.umich.edu 6817912Shestness@cs.utexas.edubool 6827912Shestness@cs.utexas.eduWalker::WalkerState::isRetrying() 6835245Sgblack@eecs.umich.edu{ 6847912Shestness@cs.utexas.edu return retrying; 6857912Shestness@cs.utexas.edu} 6867912Shestness@cs.utexas.edu 6877912Shestness@cs.utexas.edubool 6887912Shestness@cs.utexas.eduWalker::WalkerState::isTiming() 6897912Shestness@cs.utexas.edu{ 6907912Shestness@cs.utexas.edu return timing; 6917912Shestness@cs.utexas.edu} 6927912Shestness@cs.utexas.edu 6937912Shestness@cs.utexas.edubool 6947912Shestness@cs.utexas.eduWalker::WalkerState::wasStarted() 6957912Shestness@cs.utexas.edu{ 6967912Shestness@cs.utexas.edu return started; 6977912Shestness@cs.utexas.edu} 6987912Shestness@cs.utexas.edu 6997912Shestness@cs.utexas.eduvoid 7007912Shestness@cs.utexas.eduWalker::WalkerState::retry() 7017912Shestness@cs.utexas.edu{ 7027912Shestness@cs.utexas.edu retrying = false; 7037912Shestness@cs.utexas.edu sendPackets(); 7045245Sgblack@eecs.umich.edu} 7055245Sgblack@eecs.umich.edu 7065895Sgblack@eecs.umich.eduFault 7077912Shestness@cs.utexas.eduWalker::WalkerState::pageFault(bool present) 7085895Sgblack@eecs.umich.edu{ 7095904Sgblack@eecs.umich.edu DPRINTF(PageTableWalker, "Raising page fault.\n"); 7105895Sgblack@eecs.umich.edu HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG); 7116023Snate@binkert.org if (mode == BaseTLB::Execute && !enableNX) 7126023Snate@binkert.org mode = BaseTLB::Read; 71310474Sandreas.hansson@arm.com return std::make_shared<PageFault>(entry.vaddr, present, mode, 71410474Sandreas.hansson@arm.com m5reg.cpl == 3, false); 7155895Sgblack@eecs.umich.edu} 7165895Sgblack@eecs.umich.edu 7177912Shestness@cs.utexas.edu/* end namespace X86ISA */ } 7185245Sgblack@eecs.umich.edu 7195245Sgblack@eecs.umich.eduX86ISA::Walker * 7205245Sgblack@eecs.umich.eduX86PagetableWalkerParams::create() 7215245Sgblack@eecs.umich.edu{ 7225245Sgblack@eecs.umich.edu return new X86ISA::Walker(this); 7235245Sgblack@eecs.umich.edu} 724