pagetable_walker.cc revision 8232
15245Sgblack@eecs.umich.edu/*
25245Sgblack@eecs.umich.edu * Copyright (c) 2007 The Hewlett-Packard Development Company
35245Sgblack@eecs.umich.edu * All rights reserved.
45245Sgblack@eecs.umich.edu *
57087Snate@binkert.org * The license below extends only to copyright in the software and shall
67087Snate@binkert.org * not be construed as granting a license to any other intellectual
77087Snate@binkert.org * property including but not limited to intellectual property relating
87087Snate@binkert.org * to a hardware implementation of the functionality of the software
97087Snate@binkert.org * licensed hereunder.  You may use the software subject to the license
107087Snate@binkert.org * terms below provided that you ensure that this notice is replicated
117087Snate@binkert.org * unmodified and in its entirety in all distributions of the software,
127087Snate@binkert.org * modified or unmodified, in source code or in binary form.
135245Sgblack@eecs.umich.edu *
147087Snate@binkert.org * Redistribution and use in source and binary forms, with or without
157087Snate@binkert.org * modification, are permitted provided that the following conditions are
167087Snate@binkert.org * met: redistributions of source code must retain the above copyright
177087Snate@binkert.org * notice, this list of conditions and the following disclaimer;
187087Snate@binkert.org * redistributions in binary form must reproduce the above copyright
197087Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
207087Snate@binkert.org * documentation and/or other materials provided with the distribution;
217087Snate@binkert.org * neither the name of the copyright holders nor the names of its
225245Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
237087Snate@binkert.org * this software without specific prior written permission.
245245Sgblack@eecs.umich.edu *
255245Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
265245Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
275245Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
285245Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
295245Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
305245Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
315245Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
325245Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
335245Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
345245Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
355245Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
365245Sgblack@eecs.umich.edu *
375245Sgblack@eecs.umich.edu * Authors: Gabe Black
385245Sgblack@eecs.umich.edu */
395245Sgblack@eecs.umich.edu
405245Sgblack@eecs.umich.edu#include "arch/x86/pagetable.hh"
415245Sgblack@eecs.umich.edu#include "arch/x86/pagetable_walker.hh"
425245Sgblack@eecs.umich.edu#include "arch/x86/tlb.hh"
437912Shestness@cs.utexas.edu#include "arch/x86/vtophys.hh"
445245Sgblack@eecs.umich.edu#include "base/bitfield.hh"
458229Snate@binkert.org#include "cpu/base.hh"
465245Sgblack@eecs.umich.edu#include "cpu/thread_context.hh"
478232Snate@binkert.org#include "debug/PageTableWalker.hh"
485245Sgblack@eecs.umich.edu#include "mem/packet_access.hh"
495245Sgblack@eecs.umich.edu#include "mem/request.hh"
505245Sgblack@eecs.umich.edu#include "sim/system.hh"
515245Sgblack@eecs.umich.edu
525245Sgblack@eecs.umich.edunamespace X86ISA {
535245Sgblack@eecs.umich.edu
545245Sgblack@eecs.umich.edu// Unfortunately, the placement of the base field in a page table entry is
555245Sgblack@eecs.umich.edu// very erratic and would make a mess here. It might be moved here at some
565245Sgblack@eecs.umich.edu// point in the future.
575245Sgblack@eecs.umich.eduBitUnion64(PageTableEntry)
585245Sgblack@eecs.umich.edu    Bitfield<63> nx;
595245Sgblack@eecs.umich.edu    Bitfield<11, 9> avl;
605245Sgblack@eecs.umich.edu    Bitfield<8> g;
615245Sgblack@eecs.umich.edu    Bitfield<7> ps;
625245Sgblack@eecs.umich.edu    Bitfield<6> d;
635245Sgblack@eecs.umich.edu    Bitfield<5> a;
645245Sgblack@eecs.umich.edu    Bitfield<4> pcd;
655245Sgblack@eecs.umich.edu    Bitfield<3> pwt;
665245Sgblack@eecs.umich.edu    Bitfield<2> u;
675245Sgblack@eecs.umich.edu    Bitfield<1> w;
685245Sgblack@eecs.umich.edu    Bitfield<0> p;
695245Sgblack@eecs.umich.eduEndBitUnion(PageTableEntry)
705245Sgblack@eecs.umich.edu
715895Sgblack@eecs.umich.eduFault
727912Shestness@cs.utexas.eduWalker::start(ThreadContext * _tc, BaseTLB::Translation *_translation,
737912Shestness@cs.utexas.edu              RequestPtr _req, BaseTLB::Mode _mode)
745245Sgblack@eecs.umich.edu{
757912Shestness@cs.utexas.edu    // TODO: in timing mode, instead of blocking when there are other
767912Shestness@cs.utexas.edu    // outstanding requests, see if this request can be coalesced with
777912Shestness@cs.utexas.edu    // another one (i.e. either coalesce or start walk)
787912Shestness@cs.utexas.edu    WalkerState * newState = new WalkerState(this, _translation, _req);
797912Shestness@cs.utexas.edu    newState->initState(_tc, _mode, sys->getMemoryMode() == Enums::timing);
807912Shestness@cs.utexas.edu    if (currStates.size()) {
817912Shestness@cs.utexas.edu        assert(newState->isTiming());
827912Shestness@cs.utexas.edu        DPRINTF(PageTableWalker, "Walks in progress: %d\n", currStates.size());
837912Shestness@cs.utexas.edu        currStates.push_back(newState);
847912Shestness@cs.utexas.edu        return NoFault;
857912Shestness@cs.utexas.edu    } else {
867912Shestness@cs.utexas.edu        currStates.push_back(newState);
877912Shestness@cs.utexas.edu        Fault fault = newState->startWalk();
887912Shestness@cs.utexas.edu        if (!newState->isTiming()) {
897912Shestness@cs.utexas.edu            currStates.pop_front();
907912Shestness@cs.utexas.edu            delete newState;
915895Sgblack@eecs.umich.edu        }
927912Shestness@cs.utexas.edu        return fault;
935245Sgblack@eecs.umich.edu    }
945245Sgblack@eecs.umich.edu}
955245Sgblack@eecs.umich.edu
965895Sgblack@eecs.umich.eduFault
977912Shestness@cs.utexas.eduWalker::startFunctional(ThreadContext * _tc, Addr &addr, Addr &pageSize,
987912Shestness@cs.utexas.edu              BaseTLB::Mode _mode)
995245Sgblack@eecs.umich.edu{
1007912Shestness@cs.utexas.edu    funcState.initState(_tc, _mode);
1017912Shestness@cs.utexas.edu    return funcState.startFunctional(addr, pageSize);
1025245Sgblack@eecs.umich.edu}
1035245Sgblack@eecs.umich.edu
1045245Sgblack@eecs.umich.edubool
1055245Sgblack@eecs.umich.eduWalker::WalkerPort::recvTiming(PacketPtr pkt)
1065245Sgblack@eecs.umich.edu{
1075245Sgblack@eecs.umich.edu    return walker->recvTiming(pkt);
1085245Sgblack@eecs.umich.edu}
1095245Sgblack@eecs.umich.edu
1105245Sgblack@eecs.umich.edubool
1115245Sgblack@eecs.umich.eduWalker::recvTiming(PacketPtr pkt)
1125245Sgblack@eecs.umich.edu{
1137912Shestness@cs.utexas.edu    if (pkt->isResponse() || pkt->wasNacked()) {
1147912Shestness@cs.utexas.edu        WalkerSenderState * senderState =
1157912Shestness@cs.utexas.edu                dynamic_cast<WalkerSenderState *>(pkt->senderState);
1167912Shestness@cs.utexas.edu        pkt->senderState = senderState->saved;
1177912Shestness@cs.utexas.edu        WalkerState * senderWalk = senderState->senderWalk;
1187912Shestness@cs.utexas.edu        bool walkComplete = senderWalk->recvPacket(pkt);
1197912Shestness@cs.utexas.edu        delete senderState;
1207912Shestness@cs.utexas.edu        if (walkComplete) {
1217912Shestness@cs.utexas.edu            std::list<WalkerState *>::iterator iter;
1227912Shestness@cs.utexas.edu            for (iter = currStates.begin(); iter != currStates.end(); iter++) {
1237912Shestness@cs.utexas.edu                WalkerState * walkerState = *(iter);
1247912Shestness@cs.utexas.edu                if (walkerState == senderWalk) {
1257912Shestness@cs.utexas.edu                    iter = currStates.erase(iter);
1267912Shestness@cs.utexas.edu                    break;
1277912Shestness@cs.utexas.edu                }
1285245Sgblack@eecs.umich.edu            }
1297912Shestness@cs.utexas.edu            delete senderWalk;
1307912Shestness@cs.utexas.edu            // Since we block requests when another is outstanding, we
1317912Shestness@cs.utexas.edu            // need to check if there is a waiting request to be serviced
1327912Shestness@cs.utexas.edu            if (currStates.size()) {
1337912Shestness@cs.utexas.edu                WalkerState * newState = currStates.front();
1347912Shestness@cs.utexas.edu                if (!newState->wasStarted())
1357912Shestness@cs.utexas.edu                    newState->startWalk();
1365895Sgblack@eecs.umich.edu            }
1375245Sgblack@eecs.umich.edu        }
1387912Shestness@cs.utexas.edu    } else {
1397912Shestness@cs.utexas.edu        DPRINTF(PageTableWalker, "Received strange packet\n");
1405245Sgblack@eecs.umich.edu    }
1415245Sgblack@eecs.umich.edu    return true;
1425245Sgblack@eecs.umich.edu}
1435245Sgblack@eecs.umich.edu
1445245Sgblack@eecs.umich.eduTick
1455245Sgblack@eecs.umich.eduWalker::WalkerPort::recvAtomic(PacketPtr pkt)
1465245Sgblack@eecs.umich.edu{
1475245Sgblack@eecs.umich.edu    return 0;
1485245Sgblack@eecs.umich.edu}
1495245Sgblack@eecs.umich.edu
1505245Sgblack@eecs.umich.eduvoid
1515245Sgblack@eecs.umich.eduWalker::WalkerPort::recvFunctional(PacketPtr pkt)
1525245Sgblack@eecs.umich.edu{
1535245Sgblack@eecs.umich.edu    return;
1545245Sgblack@eecs.umich.edu}
1555245Sgblack@eecs.umich.edu
1565245Sgblack@eecs.umich.eduvoid
1575245Sgblack@eecs.umich.eduWalker::WalkerPort::recvStatusChange(Status status)
1585245Sgblack@eecs.umich.edu{
1595245Sgblack@eecs.umich.edu    if (status == RangeChange) {
1605245Sgblack@eecs.umich.edu        if (!snoopRangeSent) {
1615245Sgblack@eecs.umich.edu            snoopRangeSent = true;
1625245Sgblack@eecs.umich.edu            sendStatusChange(Port::RangeChange);
1635245Sgblack@eecs.umich.edu        }
1645245Sgblack@eecs.umich.edu        return;
1655245Sgblack@eecs.umich.edu    }
1665245Sgblack@eecs.umich.edu
1675245Sgblack@eecs.umich.edu    panic("Unexpected recvStatusChange.\n");
1685245Sgblack@eecs.umich.edu}
1695245Sgblack@eecs.umich.edu
1705245Sgblack@eecs.umich.eduvoid
1715245Sgblack@eecs.umich.eduWalker::WalkerPort::recvRetry()
1725245Sgblack@eecs.umich.edu{
1735245Sgblack@eecs.umich.edu    walker->recvRetry();
1745245Sgblack@eecs.umich.edu}
1755245Sgblack@eecs.umich.edu
1765245Sgblack@eecs.umich.eduvoid
1775245Sgblack@eecs.umich.eduWalker::recvRetry()
1785245Sgblack@eecs.umich.edu{
1797912Shestness@cs.utexas.edu    std::list<WalkerState *>::iterator iter;
1807912Shestness@cs.utexas.edu    for (iter = currStates.begin(); iter != currStates.end(); iter++) {
1817912Shestness@cs.utexas.edu        WalkerState * walkerState = *(iter);
1827912Shestness@cs.utexas.edu        if (walkerState->isRetrying()) {
1837912Shestness@cs.utexas.edu            walkerState->retry();
1847912Shestness@cs.utexas.edu        }
1857912Shestness@cs.utexas.edu    }
1867912Shestness@cs.utexas.edu}
1877912Shestness@cs.utexas.edu
1887912Shestness@cs.utexas.edubool Walker::sendTiming(WalkerState* sendingState, PacketPtr pkt)
1897912Shestness@cs.utexas.edu{
1907912Shestness@cs.utexas.edu    pkt->senderState = new WalkerSenderState(sendingState, pkt->senderState);
1917912Shestness@cs.utexas.edu    return port.sendTiming(pkt);
1927912Shestness@cs.utexas.edu}
1937912Shestness@cs.utexas.edu
1947912Shestness@cs.utexas.eduPort *
1957912Shestness@cs.utexas.eduWalker::getPort(const std::string &if_name, int idx)
1967912Shestness@cs.utexas.edu{
1977912Shestness@cs.utexas.edu    if (if_name == "port")
1987912Shestness@cs.utexas.edu        return &port;
1997912Shestness@cs.utexas.edu    else
2007912Shestness@cs.utexas.edu        panic("No page table walker port named %s!\n", if_name);
2015245Sgblack@eecs.umich.edu}
2025245Sgblack@eecs.umich.edu
2035245Sgblack@eecs.umich.eduvoid
2047912Shestness@cs.utexas.eduWalker::WalkerState::initState(ThreadContext * _tc,
2057912Shestness@cs.utexas.edu        BaseTLB::Mode _mode, bool _isTiming)
2067912Shestness@cs.utexas.edu{
2077912Shestness@cs.utexas.edu    assert(state == Ready);
2087912Shestness@cs.utexas.edu    started = false;
2097912Shestness@cs.utexas.edu    tc = _tc;
2107912Shestness@cs.utexas.edu    mode = _mode;
2117912Shestness@cs.utexas.edu    timing = _isTiming;
2127912Shestness@cs.utexas.edu}
2137912Shestness@cs.utexas.edu
2147912Shestness@cs.utexas.eduFault
2157912Shestness@cs.utexas.eduWalker::WalkerState::startWalk()
2167912Shestness@cs.utexas.edu{
2177912Shestness@cs.utexas.edu    Fault fault = NoFault;
2187912Shestness@cs.utexas.edu    assert(started == false);
2197912Shestness@cs.utexas.edu    started = true;
2207912Shestness@cs.utexas.edu    setupWalk(req->getVaddr());
2217912Shestness@cs.utexas.edu    if (timing) {
2227912Shestness@cs.utexas.edu        nextState = state;
2237912Shestness@cs.utexas.edu        state = Waiting;
2247912Shestness@cs.utexas.edu        timingFault = NoFault;
2257912Shestness@cs.utexas.edu        sendPackets();
2267912Shestness@cs.utexas.edu    } else {
2277912Shestness@cs.utexas.edu        do {
2287912Shestness@cs.utexas.edu            walker->port.sendAtomic(read);
2297912Shestness@cs.utexas.edu            PacketPtr write = NULL;
2307912Shestness@cs.utexas.edu            fault = stepWalk(write);
2317912Shestness@cs.utexas.edu            assert(fault == NoFault || read == NULL);
2327912Shestness@cs.utexas.edu            state = nextState;
2337912Shestness@cs.utexas.edu            nextState = Ready;
2347912Shestness@cs.utexas.edu            if (write)
2357912Shestness@cs.utexas.edu                walker->port.sendAtomic(write);
2367912Shestness@cs.utexas.edu        } while(read);
2377912Shestness@cs.utexas.edu        state = Ready;
2387912Shestness@cs.utexas.edu        nextState = Waiting;
2397912Shestness@cs.utexas.edu    }
2407912Shestness@cs.utexas.edu    return fault;
2417912Shestness@cs.utexas.edu}
2427912Shestness@cs.utexas.edu
2437912Shestness@cs.utexas.eduFault
2447912Shestness@cs.utexas.eduWalker::WalkerState::startFunctional(Addr &addr, Addr &pageSize)
2457912Shestness@cs.utexas.edu{
2467912Shestness@cs.utexas.edu    Fault fault = NoFault;
2477912Shestness@cs.utexas.edu    assert(started == false);
2487912Shestness@cs.utexas.edu    started = true;
2497912Shestness@cs.utexas.edu    setupWalk(addr);
2507912Shestness@cs.utexas.edu
2517912Shestness@cs.utexas.edu    do {
2527912Shestness@cs.utexas.edu        walker->port.sendFunctional(read);
2537912Shestness@cs.utexas.edu        // On a functional access (page table lookup), writes should
2547912Shestness@cs.utexas.edu        // not happen so this pointer is ignored after stepWalk
2557912Shestness@cs.utexas.edu        PacketPtr write = NULL;
2567912Shestness@cs.utexas.edu        fault = stepWalk(write);
2577912Shestness@cs.utexas.edu        assert(fault == NoFault || read == NULL);
2587912Shestness@cs.utexas.edu        state = nextState;
2597912Shestness@cs.utexas.edu        nextState = Ready;
2607912Shestness@cs.utexas.edu    } while(read);
2617912Shestness@cs.utexas.edu    pageSize = entry.size;
2627912Shestness@cs.utexas.edu    addr = entry.paddr;
2637912Shestness@cs.utexas.edu
2647912Shestness@cs.utexas.edu    return fault;
2657912Shestness@cs.utexas.edu}
2667912Shestness@cs.utexas.edu
2677912Shestness@cs.utexas.eduFault
2687912Shestness@cs.utexas.eduWalker::WalkerState::stepWalk(PacketPtr &write)
2697912Shestness@cs.utexas.edu{
2707912Shestness@cs.utexas.edu    assert(state != Ready && state != Waiting);
2717912Shestness@cs.utexas.edu    Fault fault = NoFault;
2727912Shestness@cs.utexas.edu    write = NULL;
2737912Shestness@cs.utexas.edu    PageTableEntry pte;
2747912Shestness@cs.utexas.edu    if (dataSize == 8)
2757912Shestness@cs.utexas.edu        pte = read->get<uint64_t>();
2767912Shestness@cs.utexas.edu    else
2777912Shestness@cs.utexas.edu        pte = read->get<uint32_t>();
2787912Shestness@cs.utexas.edu    VAddr vaddr = entry.vaddr;
2797912Shestness@cs.utexas.edu    bool uncacheable = pte.pcd;
2807912Shestness@cs.utexas.edu    Addr nextRead = 0;
2817912Shestness@cs.utexas.edu    bool doWrite = false;
2827912Shestness@cs.utexas.edu    bool doTLBInsert = false;
2837912Shestness@cs.utexas.edu    bool doEndWalk = false;
2847912Shestness@cs.utexas.edu    bool badNX = pte.nx && mode == BaseTLB::Execute && enableNX;
2857912Shestness@cs.utexas.edu    switch(state) {
2867912Shestness@cs.utexas.edu      case LongPML4:
2877912Shestness@cs.utexas.edu        DPRINTF(PageTableWalker,
2887912Shestness@cs.utexas.edu                "Got long mode PML4 entry %#016x.\n", (uint64_t)pte);
2897912Shestness@cs.utexas.edu        nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.longl3 * dataSize;
2907912Shestness@cs.utexas.edu        doWrite = !pte.a;
2917912Shestness@cs.utexas.edu        pte.a = 1;
2927912Shestness@cs.utexas.edu        entry.writable = pte.w;
2937912Shestness@cs.utexas.edu        entry.user = pte.u;
2947912Shestness@cs.utexas.edu        if (badNX || !pte.p) {
2957912Shestness@cs.utexas.edu            doEndWalk = true;
2967912Shestness@cs.utexas.edu            fault = pageFault(pte.p);
2977912Shestness@cs.utexas.edu            break;
2987912Shestness@cs.utexas.edu        }
2997912Shestness@cs.utexas.edu        entry.noExec = pte.nx;
3007912Shestness@cs.utexas.edu        nextState = LongPDP;
3017912Shestness@cs.utexas.edu        break;
3027912Shestness@cs.utexas.edu      case LongPDP:
3037912Shestness@cs.utexas.edu        DPRINTF(PageTableWalker,
3047912Shestness@cs.utexas.edu                "Got long mode PDP entry %#016x.\n", (uint64_t)pte);
3057912Shestness@cs.utexas.edu        nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.longl2 * dataSize;
3067912Shestness@cs.utexas.edu        doWrite = !pte.a;
3077912Shestness@cs.utexas.edu        pte.a = 1;
3087912Shestness@cs.utexas.edu        entry.writable = entry.writable && pte.w;
3097912Shestness@cs.utexas.edu        entry.user = entry.user && pte.u;
3107912Shestness@cs.utexas.edu        if (badNX || !pte.p) {
3117912Shestness@cs.utexas.edu            doEndWalk = true;
3127912Shestness@cs.utexas.edu            fault = pageFault(pte.p);
3137912Shestness@cs.utexas.edu            break;
3147912Shestness@cs.utexas.edu        }
3157912Shestness@cs.utexas.edu        nextState = LongPD;
3167912Shestness@cs.utexas.edu        break;
3177912Shestness@cs.utexas.edu      case LongPD:
3187912Shestness@cs.utexas.edu        DPRINTF(PageTableWalker,
3197912Shestness@cs.utexas.edu                "Got long mode PD entry %#016x.\n", (uint64_t)pte);
3207912Shestness@cs.utexas.edu        doWrite = !pte.a;
3217912Shestness@cs.utexas.edu        pte.a = 1;
3227912Shestness@cs.utexas.edu        entry.writable = entry.writable && pte.w;
3237912Shestness@cs.utexas.edu        entry.user = entry.user && pte.u;
3247912Shestness@cs.utexas.edu        if (badNX || !pte.p) {
3257912Shestness@cs.utexas.edu            doEndWalk = true;
3267912Shestness@cs.utexas.edu            fault = pageFault(pte.p);
3277912Shestness@cs.utexas.edu            break;
3287912Shestness@cs.utexas.edu        }
3297912Shestness@cs.utexas.edu        if (!pte.ps) {
3307912Shestness@cs.utexas.edu            // 4 KB page
3317912Shestness@cs.utexas.edu            entry.size = 4 * (1 << 10);
3327912Shestness@cs.utexas.edu            nextRead =
3337912Shestness@cs.utexas.edu                ((uint64_t)pte & (mask(40) << 12)) + vaddr.longl1 * dataSize;
3347912Shestness@cs.utexas.edu            nextState = LongPTE;
3357912Shestness@cs.utexas.edu            break;
3367912Shestness@cs.utexas.edu        } else {
3377912Shestness@cs.utexas.edu            // 2 MB page
3387912Shestness@cs.utexas.edu            entry.size = 2 * (1 << 20);
3397912Shestness@cs.utexas.edu            entry.paddr = (uint64_t)pte & (mask(31) << 21);
3407912Shestness@cs.utexas.edu            entry.uncacheable = uncacheable;
3417912Shestness@cs.utexas.edu            entry.global = pte.g;
3427912Shestness@cs.utexas.edu            entry.patBit = bits(pte, 12);
3437912Shestness@cs.utexas.edu            entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1);
3447912Shestness@cs.utexas.edu            doTLBInsert = true;
3457912Shestness@cs.utexas.edu            doEndWalk = true;
3467912Shestness@cs.utexas.edu            break;
3477912Shestness@cs.utexas.edu        }
3487912Shestness@cs.utexas.edu      case LongPTE:
3497912Shestness@cs.utexas.edu        DPRINTF(PageTableWalker,
3507912Shestness@cs.utexas.edu                "Got long mode PTE entry %#016x.\n", (uint64_t)pte);
3517912Shestness@cs.utexas.edu        doWrite = !pte.a;
3527912Shestness@cs.utexas.edu        pte.a = 1;
3537912Shestness@cs.utexas.edu        entry.writable = entry.writable && pte.w;
3547912Shestness@cs.utexas.edu        entry.user = entry.user && pte.u;
3557912Shestness@cs.utexas.edu        if (badNX || !pte.p) {
3567912Shestness@cs.utexas.edu            doEndWalk = true;
3577912Shestness@cs.utexas.edu            fault = pageFault(pte.p);
3587912Shestness@cs.utexas.edu            break;
3597912Shestness@cs.utexas.edu        }
3607912Shestness@cs.utexas.edu        entry.paddr = (uint64_t)pte & (mask(40) << 12);
3617912Shestness@cs.utexas.edu        entry.uncacheable = uncacheable;
3627912Shestness@cs.utexas.edu        entry.global = pte.g;
3637912Shestness@cs.utexas.edu        entry.patBit = bits(pte, 12);
3647912Shestness@cs.utexas.edu        entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
3657912Shestness@cs.utexas.edu        doTLBInsert = true;
3667912Shestness@cs.utexas.edu        doEndWalk = true;
3677912Shestness@cs.utexas.edu        break;
3687912Shestness@cs.utexas.edu      case PAEPDP:
3697912Shestness@cs.utexas.edu        DPRINTF(PageTableWalker,
3707912Shestness@cs.utexas.edu                "Got legacy mode PAE PDP entry %#08x.\n", (uint32_t)pte);
3717912Shestness@cs.utexas.edu        nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.pael2 * dataSize;
3727912Shestness@cs.utexas.edu        if (!pte.p) {
3737912Shestness@cs.utexas.edu            doEndWalk = true;
3747912Shestness@cs.utexas.edu            fault = pageFault(pte.p);
3757912Shestness@cs.utexas.edu            break;
3767912Shestness@cs.utexas.edu        }
3777912Shestness@cs.utexas.edu        nextState = PAEPD;
3787912Shestness@cs.utexas.edu        break;
3797912Shestness@cs.utexas.edu      case PAEPD:
3807912Shestness@cs.utexas.edu        DPRINTF(PageTableWalker,
3817912Shestness@cs.utexas.edu                "Got legacy mode PAE PD entry %#08x.\n", (uint32_t)pte);
3827912Shestness@cs.utexas.edu        doWrite = !pte.a;
3837912Shestness@cs.utexas.edu        pte.a = 1;
3847912Shestness@cs.utexas.edu        entry.writable = pte.w;
3857912Shestness@cs.utexas.edu        entry.user = pte.u;
3867912Shestness@cs.utexas.edu        if (badNX || !pte.p) {
3877912Shestness@cs.utexas.edu            doEndWalk = true;
3887912Shestness@cs.utexas.edu            fault = pageFault(pte.p);
3897912Shestness@cs.utexas.edu            break;
3907912Shestness@cs.utexas.edu        }
3917912Shestness@cs.utexas.edu        if (!pte.ps) {
3927912Shestness@cs.utexas.edu            // 4 KB page
3937912Shestness@cs.utexas.edu            entry.size = 4 * (1 << 10);
3947912Shestness@cs.utexas.edu            nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.pael1 * dataSize;
3957912Shestness@cs.utexas.edu            nextState = PAEPTE;
3967912Shestness@cs.utexas.edu            break;
3977912Shestness@cs.utexas.edu        } else {
3987912Shestness@cs.utexas.edu            // 2 MB page
3997912Shestness@cs.utexas.edu            entry.size = 2 * (1 << 20);
4007912Shestness@cs.utexas.edu            entry.paddr = (uint64_t)pte & (mask(31) << 21);
4017912Shestness@cs.utexas.edu            entry.uncacheable = uncacheable;
4027912Shestness@cs.utexas.edu            entry.global = pte.g;
4037912Shestness@cs.utexas.edu            entry.patBit = bits(pte, 12);
4047912Shestness@cs.utexas.edu            entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1);
4057912Shestness@cs.utexas.edu            doTLBInsert = true;
4067912Shestness@cs.utexas.edu            doEndWalk = true;
4077912Shestness@cs.utexas.edu            break;
4087912Shestness@cs.utexas.edu        }
4097912Shestness@cs.utexas.edu      case PAEPTE:
4107912Shestness@cs.utexas.edu        DPRINTF(PageTableWalker,
4117912Shestness@cs.utexas.edu                "Got legacy mode PAE PTE entry %#08x.\n", (uint32_t)pte);
4127912Shestness@cs.utexas.edu        doWrite = !pte.a;
4137912Shestness@cs.utexas.edu        pte.a = 1;
4147912Shestness@cs.utexas.edu        entry.writable = entry.writable && pte.w;
4157912Shestness@cs.utexas.edu        entry.user = entry.user && pte.u;
4167912Shestness@cs.utexas.edu        if (badNX || !pte.p) {
4177912Shestness@cs.utexas.edu            doEndWalk = true;
4187912Shestness@cs.utexas.edu            fault = pageFault(pte.p);
4197912Shestness@cs.utexas.edu            break;
4207912Shestness@cs.utexas.edu        }
4217912Shestness@cs.utexas.edu        entry.paddr = (uint64_t)pte & (mask(40) << 12);
4227912Shestness@cs.utexas.edu        entry.uncacheable = uncacheable;
4237912Shestness@cs.utexas.edu        entry.global = pte.g;
4247912Shestness@cs.utexas.edu        entry.patBit = bits(pte, 7);
4257912Shestness@cs.utexas.edu        entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
4267912Shestness@cs.utexas.edu        doTLBInsert = true;
4277912Shestness@cs.utexas.edu        doEndWalk = true;
4287912Shestness@cs.utexas.edu        break;
4297912Shestness@cs.utexas.edu      case PSEPD:
4307912Shestness@cs.utexas.edu        DPRINTF(PageTableWalker,
4317912Shestness@cs.utexas.edu                "Got legacy mode PSE PD entry %#08x.\n", (uint32_t)pte);
4327912Shestness@cs.utexas.edu        doWrite = !pte.a;
4337912Shestness@cs.utexas.edu        pte.a = 1;
4347912Shestness@cs.utexas.edu        entry.writable = pte.w;
4357912Shestness@cs.utexas.edu        entry.user = pte.u;
4367912Shestness@cs.utexas.edu        if (!pte.p) {
4377912Shestness@cs.utexas.edu            doEndWalk = true;
4387912Shestness@cs.utexas.edu            fault = pageFault(pte.p);
4397912Shestness@cs.utexas.edu            break;
4407912Shestness@cs.utexas.edu        }
4417912Shestness@cs.utexas.edu        if (!pte.ps) {
4427912Shestness@cs.utexas.edu            // 4 KB page
4437912Shestness@cs.utexas.edu            entry.size = 4 * (1 << 10);
4447912Shestness@cs.utexas.edu            nextRead =
4457912Shestness@cs.utexas.edu                ((uint64_t)pte & (mask(20) << 12)) + vaddr.norml2 * dataSize;
4467912Shestness@cs.utexas.edu            nextState = PTE;
4477912Shestness@cs.utexas.edu            break;
4487912Shestness@cs.utexas.edu        } else {
4497912Shestness@cs.utexas.edu            // 4 MB page
4507912Shestness@cs.utexas.edu            entry.size = 4 * (1 << 20);
4517912Shestness@cs.utexas.edu            entry.paddr = bits(pte, 20, 13) << 32 | bits(pte, 31, 22) << 22;
4527912Shestness@cs.utexas.edu            entry.uncacheable = uncacheable;
4537912Shestness@cs.utexas.edu            entry.global = pte.g;
4547912Shestness@cs.utexas.edu            entry.patBit = bits(pte, 12);
4557912Shestness@cs.utexas.edu            entry.vaddr = entry.vaddr & ~((4 * (1 << 20)) - 1);
4567912Shestness@cs.utexas.edu            doTLBInsert = true;
4577912Shestness@cs.utexas.edu            doEndWalk = true;
4587912Shestness@cs.utexas.edu            break;
4597912Shestness@cs.utexas.edu        }
4607912Shestness@cs.utexas.edu      case PD:
4617912Shestness@cs.utexas.edu        DPRINTF(PageTableWalker,
4627912Shestness@cs.utexas.edu                "Got legacy mode PD entry %#08x.\n", (uint32_t)pte);
4637912Shestness@cs.utexas.edu        doWrite = !pte.a;
4647912Shestness@cs.utexas.edu        pte.a = 1;
4657912Shestness@cs.utexas.edu        entry.writable = pte.w;
4667912Shestness@cs.utexas.edu        entry.user = pte.u;
4677912Shestness@cs.utexas.edu        if (!pte.p) {
4687912Shestness@cs.utexas.edu            doEndWalk = true;
4697912Shestness@cs.utexas.edu            fault = pageFault(pte.p);
4707912Shestness@cs.utexas.edu            break;
4717912Shestness@cs.utexas.edu        }
4727912Shestness@cs.utexas.edu        // 4 KB page
4737912Shestness@cs.utexas.edu        entry.size = 4 * (1 << 10);
4747912Shestness@cs.utexas.edu        nextRead = ((uint64_t)pte & (mask(20) << 12)) + vaddr.norml2 * dataSize;
4757912Shestness@cs.utexas.edu        nextState = PTE;
4767912Shestness@cs.utexas.edu        break;
4777912Shestness@cs.utexas.edu      case PTE:
4787912Shestness@cs.utexas.edu        DPRINTF(PageTableWalker,
4797912Shestness@cs.utexas.edu                "Got legacy mode PTE entry %#08x.\n", (uint32_t)pte);
4807912Shestness@cs.utexas.edu        doWrite = !pte.a;
4817912Shestness@cs.utexas.edu        pte.a = 1;
4827912Shestness@cs.utexas.edu        entry.writable = pte.w;
4837912Shestness@cs.utexas.edu        entry.user = pte.u;
4847912Shestness@cs.utexas.edu        if (!pte.p) {
4857912Shestness@cs.utexas.edu            doEndWalk = true;
4867912Shestness@cs.utexas.edu            fault = pageFault(pte.p);
4877912Shestness@cs.utexas.edu            break;
4887912Shestness@cs.utexas.edu        }
4897912Shestness@cs.utexas.edu        entry.paddr = (uint64_t)pte & (mask(20) << 12);
4907912Shestness@cs.utexas.edu        entry.uncacheable = uncacheable;
4917912Shestness@cs.utexas.edu        entry.global = pte.g;
4927912Shestness@cs.utexas.edu        entry.patBit = bits(pte, 7);
4937912Shestness@cs.utexas.edu        entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
4947912Shestness@cs.utexas.edu        doTLBInsert = true;
4957912Shestness@cs.utexas.edu        doEndWalk = true;
4967912Shestness@cs.utexas.edu        break;
4977912Shestness@cs.utexas.edu      default:
4987912Shestness@cs.utexas.edu        panic("Unknown page table walker state %d!\n");
4997912Shestness@cs.utexas.edu    }
5007912Shestness@cs.utexas.edu    if (doEndWalk) {
5017912Shestness@cs.utexas.edu        if (doTLBInsert)
5027912Shestness@cs.utexas.edu            if (!functional)
5037912Shestness@cs.utexas.edu                walker->tlb->insert(entry.vaddr, entry);
5047912Shestness@cs.utexas.edu        endWalk();
5057912Shestness@cs.utexas.edu    } else {
5067912Shestness@cs.utexas.edu        PacketPtr oldRead = read;
5077912Shestness@cs.utexas.edu        //If we didn't return, we're setting up another read.
5087912Shestness@cs.utexas.edu        Request::Flags flags = oldRead->req->getFlags();
5097912Shestness@cs.utexas.edu        flags.set(Request::UNCACHEABLE, uncacheable);
5107912Shestness@cs.utexas.edu        RequestPtr request =
5117912Shestness@cs.utexas.edu            new Request(nextRead, oldRead->getSize(), flags);
5128096Sgblack@eecs.umich.edu        read = new Packet(request, MemCmd::ReadReq, Packet::Broadcast);
5137912Shestness@cs.utexas.edu        read->allocate();
5147912Shestness@cs.utexas.edu        // If we need to write, adjust the read packet to write the modified
5157912Shestness@cs.utexas.edu        // value back to memory.
5167912Shestness@cs.utexas.edu        if (doWrite) {
5177912Shestness@cs.utexas.edu            write = oldRead;
5187912Shestness@cs.utexas.edu            write->set<uint64_t>(pte);
5197912Shestness@cs.utexas.edu            write->cmd = MemCmd::WriteReq;
5207912Shestness@cs.utexas.edu            write->setDest(Packet::Broadcast);
5217912Shestness@cs.utexas.edu        } else {
5227912Shestness@cs.utexas.edu            write = NULL;
5237912Shestness@cs.utexas.edu            delete oldRead->req;
5247912Shestness@cs.utexas.edu            delete oldRead;
5257912Shestness@cs.utexas.edu        }
5267912Shestness@cs.utexas.edu    }
5277912Shestness@cs.utexas.edu    return fault;
5287912Shestness@cs.utexas.edu}
5297912Shestness@cs.utexas.edu
5307912Shestness@cs.utexas.eduvoid
5317912Shestness@cs.utexas.eduWalker::WalkerState::endWalk()
5327912Shestness@cs.utexas.edu{
5337912Shestness@cs.utexas.edu    nextState = Ready;
5347912Shestness@cs.utexas.edu    delete read->req;
5357912Shestness@cs.utexas.edu    delete read;
5367912Shestness@cs.utexas.edu    read = NULL;
5377912Shestness@cs.utexas.edu}
5387912Shestness@cs.utexas.edu
5397912Shestness@cs.utexas.eduvoid
5407912Shestness@cs.utexas.eduWalker::WalkerState::setupWalk(Addr vaddr)
5417912Shestness@cs.utexas.edu{
5427912Shestness@cs.utexas.edu    VAddr addr = vaddr;
5437912Shestness@cs.utexas.edu    CR3 cr3 = tc->readMiscRegNoEffect(MISCREG_CR3);
5447912Shestness@cs.utexas.edu    // Check if we're in long mode or not
5457912Shestness@cs.utexas.edu    Efer efer = tc->readMiscRegNoEffect(MISCREG_EFER);
5467912Shestness@cs.utexas.edu    dataSize = 8;
5477912Shestness@cs.utexas.edu    Addr topAddr;
5487912Shestness@cs.utexas.edu    if (efer.lma) {
5497912Shestness@cs.utexas.edu        // Do long mode.
5507912Shestness@cs.utexas.edu        state = LongPML4;
5517912Shestness@cs.utexas.edu        topAddr = (cr3.longPdtb << 12) + addr.longl4 * dataSize;
5527912Shestness@cs.utexas.edu        enableNX = efer.nxe;
5537912Shestness@cs.utexas.edu    } else {
5547912Shestness@cs.utexas.edu        // We're in some flavor of legacy mode.
5557912Shestness@cs.utexas.edu        CR4 cr4 = tc->readMiscRegNoEffect(MISCREG_CR4);
5567912Shestness@cs.utexas.edu        if (cr4.pae) {
5577912Shestness@cs.utexas.edu            // Do legacy PAE.
5587912Shestness@cs.utexas.edu            state = PAEPDP;
5597912Shestness@cs.utexas.edu            topAddr = (cr3.paePdtb << 5) + addr.pael3 * dataSize;
5607912Shestness@cs.utexas.edu            enableNX = efer.nxe;
5617912Shestness@cs.utexas.edu        } else {
5627912Shestness@cs.utexas.edu            dataSize = 4;
5637912Shestness@cs.utexas.edu            topAddr = (cr3.pdtb << 12) + addr.norml2 * dataSize;
5647912Shestness@cs.utexas.edu            if (cr4.pse) {
5657912Shestness@cs.utexas.edu                // Do legacy PSE.
5667912Shestness@cs.utexas.edu                state = PSEPD;
5677912Shestness@cs.utexas.edu            } else {
5687912Shestness@cs.utexas.edu                // Do legacy non PSE.
5697912Shestness@cs.utexas.edu                state = PD;
5707912Shestness@cs.utexas.edu            }
5717912Shestness@cs.utexas.edu            enableNX = false;
5727912Shestness@cs.utexas.edu        }
5737912Shestness@cs.utexas.edu    }
5747912Shestness@cs.utexas.edu
5757912Shestness@cs.utexas.edu    nextState = Ready;
5767912Shestness@cs.utexas.edu    entry.vaddr = vaddr;
5777912Shestness@cs.utexas.edu
5787912Shestness@cs.utexas.edu    Request::Flags flags = Request::PHYSICAL;
5797912Shestness@cs.utexas.edu    if (cr3.pcd)
5807912Shestness@cs.utexas.edu        flags.set(Request::UNCACHEABLE);
5817912Shestness@cs.utexas.edu    RequestPtr request = new Request(topAddr, dataSize, flags);
5828096Sgblack@eecs.umich.edu    read = new Packet(request, MemCmd::ReadReq, Packet::Broadcast);
5837912Shestness@cs.utexas.edu    read->allocate();
5847912Shestness@cs.utexas.edu}
5857912Shestness@cs.utexas.edu
5867912Shestness@cs.utexas.edubool
5877912Shestness@cs.utexas.eduWalker::WalkerState::recvPacket(PacketPtr pkt)
5887912Shestness@cs.utexas.edu{
5897912Shestness@cs.utexas.edu    if (pkt->isResponse() && !pkt->wasNacked()) {
5907912Shestness@cs.utexas.edu        assert(inflight);
5917912Shestness@cs.utexas.edu        assert(state == Waiting);
5927912Shestness@cs.utexas.edu        assert(!read);
5937912Shestness@cs.utexas.edu        inflight--;
5947912Shestness@cs.utexas.edu        if (pkt->isRead()) {
5957912Shestness@cs.utexas.edu            state = nextState;
5967912Shestness@cs.utexas.edu            nextState = Ready;
5977912Shestness@cs.utexas.edu            PacketPtr write = NULL;
5987912Shestness@cs.utexas.edu            read = pkt;
5997912Shestness@cs.utexas.edu            timingFault = stepWalk(write);
6007912Shestness@cs.utexas.edu            state = Waiting;
6017912Shestness@cs.utexas.edu            assert(timingFault == NoFault || read == NULL);
6027912Shestness@cs.utexas.edu            if (write) {
6037912Shestness@cs.utexas.edu                writes.push_back(write);
6047912Shestness@cs.utexas.edu            }
6057912Shestness@cs.utexas.edu            sendPackets();
6067912Shestness@cs.utexas.edu        } else {
6077912Shestness@cs.utexas.edu            sendPackets();
6087912Shestness@cs.utexas.edu        }
6097912Shestness@cs.utexas.edu        if (inflight == 0 && read == NULL && writes.size() == 0) {
6107912Shestness@cs.utexas.edu            state = Ready;
6117912Shestness@cs.utexas.edu            nextState = Waiting;
6127912Shestness@cs.utexas.edu            if (timingFault == NoFault) {
6137912Shestness@cs.utexas.edu                /*
6147912Shestness@cs.utexas.edu                 * Finish the translation. Now that we now the right entry is
6157912Shestness@cs.utexas.edu                 * in the TLB, this should work with no memory accesses.
6167912Shestness@cs.utexas.edu                 * There could be new faults unrelated to the table walk like
6177912Shestness@cs.utexas.edu                 * permissions violations, so we'll need the return value as
6187912Shestness@cs.utexas.edu                 * well.
6197912Shestness@cs.utexas.edu                 */
6207912Shestness@cs.utexas.edu                bool delayedResponse;
6217912Shestness@cs.utexas.edu                Fault fault = walker->tlb->translate(req, tc, NULL, mode,
6227912Shestness@cs.utexas.edu                        delayedResponse, true);
6237912Shestness@cs.utexas.edu                assert(!delayedResponse);
6247912Shestness@cs.utexas.edu                // Let the CPU continue.
6257912Shestness@cs.utexas.edu                translation->finish(fault, req, tc, mode);
6267912Shestness@cs.utexas.edu            } else {
6277912Shestness@cs.utexas.edu                // There was a fault during the walk. Let the CPU know.
6287912Shestness@cs.utexas.edu                translation->finish(timingFault, req, tc, mode);
6297912Shestness@cs.utexas.edu            }
6307912Shestness@cs.utexas.edu            return true;
6317912Shestness@cs.utexas.edu        }
6327912Shestness@cs.utexas.edu    } else if (pkt->wasNacked()) {
6337912Shestness@cs.utexas.edu        DPRINTF(PageTableWalker, "Request was nacked. Entering retry state\n");
6347912Shestness@cs.utexas.edu        pkt->reinitNacked();
6357912Shestness@cs.utexas.edu        if (!walker->sendTiming(this, pkt)) {
6367912Shestness@cs.utexas.edu            inflight--;
6377912Shestness@cs.utexas.edu            retrying = true;
6387912Shestness@cs.utexas.edu            if (pkt->isWrite()) {
6397912Shestness@cs.utexas.edu                writes.push_back(pkt);
6407912Shestness@cs.utexas.edu            } else {
6417912Shestness@cs.utexas.edu                assert(!read);
6427912Shestness@cs.utexas.edu                read = pkt;
6437912Shestness@cs.utexas.edu            }
6447912Shestness@cs.utexas.edu        }
6457912Shestness@cs.utexas.edu    }
6467912Shestness@cs.utexas.edu    return false;
6477912Shestness@cs.utexas.edu}
6487912Shestness@cs.utexas.edu
6497912Shestness@cs.utexas.eduvoid
6507912Shestness@cs.utexas.eduWalker::WalkerState::sendPackets()
6515245Sgblack@eecs.umich.edu{
6525245Sgblack@eecs.umich.edu    //If we're already waiting for the port to become available, just return.
6535245Sgblack@eecs.umich.edu    if (retrying)
6545245Sgblack@eecs.umich.edu        return;
6555245Sgblack@eecs.umich.edu
6565245Sgblack@eecs.umich.edu    //Reads always have priority
6575245Sgblack@eecs.umich.edu    if (read) {
6585897Sgblack@eecs.umich.edu        PacketPtr pkt = read;
6595897Sgblack@eecs.umich.edu        read = NULL;
6605897Sgblack@eecs.umich.edu        inflight++;
6617912Shestness@cs.utexas.edu        if (!walker->sendTiming(this, pkt)) {
6625245Sgblack@eecs.umich.edu            retrying = true;
6635897Sgblack@eecs.umich.edu            read = pkt;
6645897Sgblack@eecs.umich.edu            inflight--;
6655245Sgblack@eecs.umich.edu            return;
6665245Sgblack@eecs.umich.edu        }
6675245Sgblack@eecs.umich.edu    }
6685245Sgblack@eecs.umich.edu    //Send off as many of the writes as we can.
6695245Sgblack@eecs.umich.edu    while (writes.size()) {
6705245Sgblack@eecs.umich.edu        PacketPtr write = writes.back();
6715897Sgblack@eecs.umich.edu        writes.pop_back();
6725897Sgblack@eecs.umich.edu        inflight++;
6737912Shestness@cs.utexas.edu        if (!walker->sendTiming(this, write)) {
6745245Sgblack@eecs.umich.edu            retrying = true;
6755897Sgblack@eecs.umich.edu            writes.push_back(write);
6765897Sgblack@eecs.umich.edu            inflight--;
6775245Sgblack@eecs.umich.edu            return;
6785245Sgblack@eecs.umich.edu        }
6795245Sgblack@eecs.umich.edu    }
6805245Sgblack@eecs.umich.edu}
6815245Sgblack@eecs.umich.edu
6827912Shestness@cs.utexas.edubool
6837912Shestness@cs.utexas.eduWalker::WalkerState::isRetrying()
6845245Sgblack@eecs.umich.edu{
6857912Shestness@cs.utexas.edu    return retrying;
6867912Shestness@cs.utexas.edu}
6877912Shestness@cs.utexas.edu
6887912Shestness@cs.utexas.edubool
6897912Shestness@cs.utexas.eduWalker::WalkerState::isTiming()
6907912Shestness@cs.utexas.edu{
6917912Shestness@cs.utexas.edu    return timing;
6927912Shestness@cs.utexas.edu}
6937912Shestness@cs.utexas.edu
6947912Shestness@cs.utexas.edubool
6957912Shestness@cs.utexas.eduWalker::WalkerState::wasStarted()
6967912Shestness@cs.utexas.edu{
6977912Shestness@cs.utexas.edu    return started;
6987912Shestness@cs.utexas.edu}
6997912Shestness@cs.utexas.edu
7007912Shestness@cs.utexas.eduvoid
7017912Shestness@cs.utexas.eduWalker::WalkerState::retry()
7027912Shestness@cs.utexas.edu{
7037912Shestness@cs.utexas.edu    retrying = false;
7047912Shestness@cs.utexas.edu    sendPackets();
7055245Sgblack@eecs.umich.edu}
7065245Sgblack@eecs.umich.edu
7075895Sgblack@eecs.umich.eduFault
7087912Shestness@cs.utexas.eduWalker::WalkerState::pageFault(bool present)
7095895Sgblack@eecs.umich.edu{
7105904Sgblack@eecs.umich.edu    DPRINTF(PageTableWalker, "Raising page fault.\n");
7115895Sgblack@eecs.umich.edu    HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
7126023Snate@binkert.org    if (mode == BaseTLB::Execute && !enableNX)
7136023Snate@binkert.org        mode = BaseTLB::Read;
7146023Snate@binkert.org    return new PageFault(entry.vaddr, present, mode, 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