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
17013784Sgabeblack@google.comPort &
17113784Sgabeblack@google.comWalker::getPort(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
17613892Sgabeblack@google.com        return ClockedObject::getPort(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
20814096Smatthew.poremba@amd.com        // delete the current request if there are no inflight packets.
20914096Smatthew.poremba@amd.com        // if there is something in flight, delete when the packets are
21014096Smatthew.poremba@amd.com        // received and inflight is zero.
21114096Smatthew.poremba@amd.com        if (currState->numInflight() == 0) {
21214096Smatthew.poremba@amd.com            delete currState;
21314096Smatthew.poremba@amd.com        } else {
21414096Smatthew.poremba@amd.com            currState->squash();
21514096Smatthew.poremba@amd.com        }
2169701Sgedare@rtems.org
2179701Sgedare@rtems.org        // check the next translation request, if it exists
2189701Sgedare@rtems.org        if (currStates.size())
2199701Sgedare@rtems.org            currState = currStates.front();
2209701Sgedare@rtems.org        else
2219701Sgedare@rtems.org            currState = NULL;
2229701Sgedare@rtems.org    }
2239701Sgedare@rtems.org    if (currState && !currState->wasStarted())
2249701Sgedare@rtems.org        currState->startWalk();
2259701Sgedare@rtems.org}
2269701Sgedare@rtems.org
2277912Shestness@cs.utexas.eduFault
2287912Shestness@cs.utexas.eduWalker::WalkerState::startWalk()
2297912Shestness@cs.utexas.edu{
2307912Shestness@cs.utexas.edu    Fault fault = NoFault;
23110231Ssteve.reinhardt@amd.com    assert(!started);
2327912Shestness@cs.utexas.edu    started = true;
2337912Shestness@cs.utexas.edu    setupWalk(req->getVaddr());
2347912Shestness@cs.utexas.edu    if (timing) {
2357912Shestness@cs.utexas.edu        nextState = state;
2367912Shestness@cs.utexas.edu        state = Waiting;
2377912Shestness@cs.utexas.edu        timingFault = NoFault;
2387912Shestness@cs.utexas.edu        sendPackets();
2397912Shestness@cs.utexas.edu    } else {
2407912Shestness@cs.utexas.edu        do {
2417912Shestness@cs.utexas.edu            walker->port.sendAtomic(read);
2427912Shestness@cs.utexas.edu            PacketPtr write = NULL;
2437912Shestness@cs.utexas.edu            fault = stepWalk(write);
2447912Shestness@cs.utexas.edu            assert(fault == NoFault || read == NULL);
2457912Shestness@cs.utexas.edu            state = nextState;
2467912Shestness@cs.utexas.edu            nextState = Ready;
2477912Shestness@cs.utexas.edu            if (write)
2487912Shestness@cs.utexas.edu                walker->port.sendAtomic(write);
24911321Ssteve.reinhardt@amd.com        } while (read);
2507912Shestness@cs.utexas.edu        state = Ready;
2517912Shestness@cs.utexas.edu        nextState = Waiting;
2527912Shestness@cs.utexas.edu    }
2537912Shestness@cs.utexas.edu    return fault;
2547912Shestness@cs.utexas.edu}
2557912Shestness@cs.utexas.edu
2567912Shestness@cs.utexas.eduFault
2578953Sgblack@eecs.umich.eduWalker::WalkerState::startFunctional(Addr &addr, unsigned &logBytes)
2587912Shestness@cs.utexas.edu{
2597912Shestness@cs.utexas.edu    Fault fault = NoFault;
26010231Ssteve.reinhardt@amd.com    assert(!started);
2617912Shestness@cs.utexas.edu    started = true;
2627912Shestness@cs.utexas.edu    setupWalk(addr);
2637912Shestness@cs.utexas.edu
2647912Shestness@cs.utexas.edu    do {
2657912Shestness@cs.utexas.edu        walker->port.sendFunctional(read);
2667912Shestness@cs.utexas.edu        // On a functional access (page table lookup), writes should
2677912Shestness@cs.utexas.edu        // not happen so this pointer is ignored after stepWalk
2687912Shestness@cs.utexas.edu        PacketPtr write = NULL;
2697912Shestness@cs.utexas.edu        fault = stepWalk(write);
2707912Shestness@cs.utexas.edu        assert(fault == NoFault || read == NULL);
2717912Shestness@cs.utexas.edu        state = nextState;
2727912Shestness@cs.utexas.edu        nextState = Ready;
27311321Ssteve.reinhardt@amd.com    } while (read);
2748953Sgblack@eecs.umich.edu    logBytes = entry.logBytes;
2757912Shestness@cs.utexas.edu    addr = entry.paddr;
2767912Shestness@cs.utexas.edu
2777912Shestness@cs.utexas.edu    return fault;
2787912Shestness@cs.utexas.edu}
2797912Shestness@cs.utexas.edu
2807912Shestness@cs.utexas.eduFault
2817912Shestness@cs.utexas.eduWalker::WalkerState::stepWalk(PacketPtr &write)
2827912Shestness@cs.utexas.edu{
2837912Shestness@cs.utexas.edu    assert(state != Ready && state != Waiting);
2847912Shestness@cs.utexas.edu    Fault fault = NoFault;
2857912Shestness@cs.utexas.edu    write = NULL;
2867912Shestness@cs.utexas.edu    PageTableEntry pte;
2877912Shestness@cs.utexas.edu    if (dataSize == 8)
28813229Sgabeblack@google.com        pte = read->getLE<uint64_t>();
2897912Shestness@cs.utexas.edu    else
29013229Sgabeblack@google.com        pte = read->getLE<uint32_t>();
2917912Shestness@cs.utexas.edu    VAddr vaddr = entry.vaddr;
2927912Shestness@cs.utexas.edu    bool uncacheable = pte.pcd;
2937912Shestness@cs.utexas.edu    Addr nextRead = 0;
2947912Shestness@cs.utexas.edu    bool doWrite = false;
2957912Shestness@cs.utexas.edu    bool doTLBInsert = false;
2967912Shestness@cs.utexas.edu    bool doEndWalk = false;
2977912Shestness@cs.utexas.edu    bool badNX = pte.nx && mode == BaseTLB::Execute && enableNX;
2987912Shestness@cs.utexas.edu    switch(state) {
2997912Shestness@cs.utexas.edu      case LongPML4:
3007912Shestness@cs.utexas.edu        DPRINTF(PageTableWalker,
3017912Shestness@cs.utexas.edu                "Got long mode PML4 entry %#016x.\n", (uint64_t)pte);
3027912Shestness@cs.utexas.edu        nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.longl3 * dataSize;
3037912Shestness@cs.utexas.edu        doWrite = !pte.a;
3047912Shestness@cs.utexas.edu        pte.a = 1;
3057912Shestness@cs.utexas.edu        entry.writable = pte.w;
3067912Shestness@cs.utexas.edu        entry.user = pte.u;
3077912Shestness@cs.utexas.edu        if (badNX || !pte.p) {
3087912Shestness@cs.utexas.edu            doEndWalk = true;
3097912Shestness@cs.utexas.edu            fault = pageFault(pte.p);
3107912Shestness@cs.utexas.edu            break;
3117912Shestness@cs.utexas.edu        }
3127912Shestness@cs.utexas.edu        entry.noExec = pte.nx;
3137912Shestness@cs.utexas.edu        nextState = LongPDP;
3147912Shestness@cs.utexas.edu        break;
3157912Shestness@cs.utexas.edu      case LongPDP:
3167912Shestness@cs.utexas.edu        DPRINTF(PageTableWalker,
3177912Shestness@cs.utexas.edu                "Got long mode PDP entry %#016x.\n", (uint64_t)pte);
3187912Shestness@cs.utexas.edu        nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.longl2 * dataSize;
3197912Shestness@cs.utexas.edu        doWrite = !pte.a;
3207912Shestness@cs.utexas.edu        pte.a = 1;
3217912Shestness@cs.utexas.edu        entry.writable = entry.writable && pte.w;
3227912Shestness@cs.utexas.edu        entry.user = entry.user && pte.u;
3237912Shestness@cs.utexas.edu        if (badNX || !pte.p) {
3247912Shestness@cs.utexas.edu            doEndWalk = true;
3257912Shestness@cs.utexas.edu            fault = pageFault(pte.p);
3267912Shestness@cs.utexas.edu            break;
3277912Shestness@cs.utexas.edu        }
3287912Shestness@cs.utexas.edu        nextState = LongPD;
3297912Shestness@cs.utexas.edu        break;
3307912Shestness@cs.utexas.edu      case LongPD:
3317912Shestness@cs.utexas.edu        DPRINTF(PageTableWalker,
3327912Shestness@cs.utexas.edu                "Got long mode PD entry %#016x.\n", (uint64_t)pte);
3337912Shestness@cs.utexas.edu        doWrite = !pte.a;
3347912Shestness@cs.utexas.edu        pte.a = 1;
3357912Shestness@cs.utexas.edu        entry.writable = entry.writable && pte.w;
3367912Shestness@cs.utexas.edu        entry.user = entry.user && pte.u;
3377912Shestness@cs.utexas.edu        if (badNX || !pte.p) {
3387912Shestness@cs.utexas.edu            doEndWalk = true;
3397912Shestness@cs.utexas.edu            fault = pageFault(pte.p);
3407912Shestness@cs.utexas.edu            break;
3417912Shestness@cs.utexas.edu        }
3427912Shestness@cs.utexas.edu        if (!pte.ps) {
3437912Shestness@cs.utexas.edu            // 4 KB page
3448953Sgblack@eecs.umich.edu            entry.logBytes = 12;
3457912Shestness@cs.utexas.edu            nextRead =
3467912Shestness@cs.utexas.edu                ((uint64_t)pte & (mask(40) << 12)) + vaddr.longl1 * dataSize;
3477912Shestness@cs.utexas.edu            nextState = LongPTE;
3487912Shestness@cs.utexas.edu            break;
3497912Shestness@cs.utexas.edu        } else {
3507912Shestness@cs.utexas.edu            // 2 MB page
3518953Sgblack@eecs.umich.edu            entry.logBytes = 21;
3527912Shestness@cs.utexas.edu            entry.paddr = (uint64_t)pte & (mask(31) << 21);
3537912Shestness@cs.utexas.edu            entry.uncacheable = uncacheable;
3547912Shestness@cs.utexas.edu            entry.global = pte.g;
3557912Shestness@cs.utexas.edu            entry.patBit = bits(pte, 12);
3567912Shestness@cs.utexas.edu            entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1);
3577912Shestness@cs.utexas.edu            doTLBInsert = true;
3587912Shestness@cs.utexas.edu            doEndWalk = true;
3597912Shestness@cs.utexas.edu            break;
3607912Shestness@cs.utexas.edu        }
3617912Shestness@cs.utexas.edu      case LongPTE:
3627912Shestness@cs.utexas.edu        DPRINTF(PageTableWalker,
3637912Shestness@cs.utexas.edu                "Got long mode PTE entry %#016x.\n", (uint64_t)pte);
3647912Shestness@cs.utexas.edu        doWrite = !pte.a;
3657912Shestness@cs.utexas.edu        pte.a = 1;
3667912Shestness@cs.utexas.edu        entry.writable = entry.writable && pte.w;
3677912Shestness@cs.utexas.edu        entry.user = entry.user && pte.u;
3687912Shestness@cs.utexas.edu        if (badNX || !pte.p) {
3697912Shestness@cs.utexas.edu            doEndWalk = true;
3707912Shestness@cs.utexas.edu            fault = pageFault(pte.p);
3717912Shestness@cs.utexas.edu            break;
3727912Shestness@cs.utexas.edu        }
3737912Shestness@cs.utexas.edu        entry.paddr = (uint64_t)pte & (mask(40) << 12);
3747912Shestness@cs.utexas.edu        entry.uncacheable = uncacheable;
3757912Shestness@cs.utexas.edu        entry.global = pte.g;
3767912Shestness@cs.utexas.edu        entry.patBit = bits(pte, 12);
3777912Shestness@cs.utexas.edu        entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
3787912Shestness@cs.utexas.edu        doTLBInsert = true;
3797912Shestness@cs.utexas.edu        doEndWalk = true;
3807912Shestness@cs.utexas.edu        break;
3817912Shestness@cs.utexas.edu      case PAEPDP:
3827912Shestness@cs.utexas.edu        DPRINTF(PageTableWalker,
3837912Shestness@cs.utexas.edu                "Got legacy mode PAE PDP entry %#08x.\n", (uint32_t)pte);
3847912Shestness@cs.utexas.edu        nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.pael2 * dataSize;
3857912Shestness@cs.utexas.edu        if (!pte.p) {
3867912Shestness@cs.utexas.edu            doEndWalk = true;
3877912Shestness@cs.utexas.edu            fault = pageFault(pte.p);
3887912Shestness@cs.utexas.edu            break;
3897912Shestness@cs.utexas.edu        }
3907912Shestness@cs.utexas.edu        nextState = PAEPD;
3917912Shestness@cs.utexas.edu        break;
3927912Shestness@cs.utexas.edu      case PAEPD:
3937912Shestness@cs.utexas.edu        DPRINTF(PageTableWalker,
3947912Shestness@cs.utexas.edu                "Got legacy mode PAE PD entry %#08x.\n", (uint32_t)pte);
3957912Shestness@cs.utexas.edu        doWrite = !pte.a;
3967912Shestness@cs.utexas.edu        pte.a = 1;
3977912Shestness@cs.utexas.edu        entry.writable = pte.w;
3987912Shestness@cs.utexas.edu        entry.user = pte.u;
3997912Shestness@cs.utexas.edu        if (badNX || !pte.p) {
4007912Shestness@cs.utexas.edu            doEndWalk = true;
4017912Shestness@cs.utexas.edu            fault = pageFault(pte.p);
4027912Shestness@cs.utexas.edu            break;
4037912Shestness@cs.utexas.edu        }
4047912Shestness@cs.utexas.edu        if (!pte.ps) {
4057912Shestness@cs.utexas.edu            // 4 KB page
4068953Sgblack@eecs.umich.edu            entry.logBytes = 12;
4077912Shestness@cs.utexas.edu            nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.pael1 * dataSize;
4087912Shestness@cs.utexas.edu            nextState = PAEPTE;
4097912Shestness@cs.utexas.edu            break;
4107912Shestness@cs.utexas.edu        } else {
4117912Shestness@cs.utexas.edu            // 2 MB page
4128953Sgblack@eecs.umich.edu            entry.logBytes = 21;
4137912Shestness@cs.utexas.edu            entry.paddr = (uint64_t)pte & (mask(31) << 21);
4147912Shestness@cs.utexas.edu            entry.uncacheable = uncacheable;
4157912Shestness@cs.utexas.edu            entry.global = pte.g;
4167912Shestness@cs.utexas.edu            entry.patBit = bits(pte, 12);
4177912Shestness@cs.utexas.edu            entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1);
4187912Shestness@cs.utexas.edu            doTLBInsert = true;
4197912Shestness@cs.utexas.edu            doEndWalk = true;
4207912Shestness@cs.utexas.edu            break;
4217912Shestness@cs.utexas.edu        }
4227912Shestness@cs.utexas.edu      case PAEPTE:
4237912Shestness@cs.utexas.edu        DPRINTF(PageTableWalker,
4247912Shestness@cs.utexas.edu                "Got legacy mode PAE PTE entry %#08x.\n", (uint32_t)pte);
4257912Shestness@cs.utexas.edu        doWrite = !pte.a;
4267912Shestness@cs.utexas.edu        pte.a = 1;
4277912Shestness@cs.utexas.edu        entry.writable = entry.writable && pte.w;
4287912Shestness@cs.utexas.edu        entry.user = entry.user && pte.u;
4297912Shestness@cs.utexas.edu        if (badNX || !pte.p) {
4307912Shestness@cs.utexas.edu            doEndWalk = true;
4317912Shestness@cs.utexas.edu            fault = pageFault(pte.p);
4327912Shestness@cs.utexas.edu            break;
4337912Shestness@cs.utexas.edu        }
4347912Shestness@cs.utexas.edu        entry.paddr = (uint64_t)pte & (mask(40) << 12);
4357912Shestness@cs.utexas.edu        entry.uncacheable = uncacheable;
4367912Shestness@cs.utexas.edu        entry.global = pte.g;
4377912Shestness@cs.utexas.edu        entry.patBit = bits(pte, 7);
4387912Shestness@cs.utexas.edu        entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
4397912Shestness@cs.utexas.edu        doTLBInsert = true;
4407912Shestness@cs.utexas.edu        doEndWalk = true;
4417912Shestness@cs.utexas.edu        break;
4427912Shestness@cs.utexas.edu      case PSEPD:
4437912Shestness@cs.utexas.edu        DPRINTF(PageTableWalker,
4447912Shestness@cs.utexas.edu                "Got legacy mode PSE PD entry %#08x.\n", (uint32_t)pte);
4457912Shestness@cs.utexas.edu        doWrite = !pte.a;
4467912Shestness@cs.utexas.edu        pte.a = 1;
4477912Shestness@cs.utexas.edu        entry.writable = pte.w;
4487912Shestness@cs.utexas.edu        entry.user = pte.u;
4497912Shestness@cs.utexas.edu        if (!pte.p) {
4507912Shestness@cs.utexas.edu            doEndWalk = true;
4517912Shestness@cs.utexas.edu            fault = pageFault(pte.p);
4527912Shestness@cs.utexas.edu            break;
4537912Shestness@cs.utexas.edu        }
4547912Shestness@cs.utexas.edu        if (!pte.ps) {
4557912Shestness@cs.utexas.edu            // 4 KB page
4568953Sgblack@eecs.umich.edu            entry.logBytes = 12;
4577912Shestness@cs.utexas.edu            nextRead =
4587912Shestness@cs.utexas.edu                ((uint64_t)pte & (mask(20) << 12)) + vaddr.norml2 * dataSize;
4597912Shestness@cs.utexas.edu            nextState = PTE;
4607912Shestness@cs.utexas.edu            break;
4617912Shestness@cs.utexas.edu        } else {
4627912Shestness@cs.utexas.edu            // 4 MB page
4638953Sgblack@eecs.umich.edu            entry.logBytes = 21;
4647912Shestness@cs.utexas.edu            entry.paddr = bits(pte, 20, 13) << 32 | bits(pte, 31, 22) << 22;
4657912Shestness@cs.utexas.edu            entry.uncacheable = uncacheable;
4667912Shestness@cs.utexas.edu            entry.global = pte.g;
4677912Shestness@cs.utexas.edu            entry.patBit = bits(pte, 12);
4687912Shestness@cs.utexas.edu            entry.vaddr = entry.vaddr & ~((4 * (1 << 20)) - 1);
4697912Shestness@cs.utexas.edu            doTLBInsert = true;
4707912Shestness@cs.utexas.edu            doEndWalk = true;
4717912Shestness@cs.utexas.edu            break;
4727912Shestness@cs.utexas.edu        }
4737912Shestness@cs.utexas.edu      case PD:
4747912Shestness@cs.utexas.edu        DPRINTF(PageTableWalker,
4757912Shestness@cs.utexas.edu                "Got legacy mode PD entry %#08x.\n", (uint32_t)pte);
4767912Shestness@cs.utexas.edu        doWrite = !pte.a;
4777912Shestness@cs.utexas.edu        pte.a = 1;
4787912Shestness@cs.utexas.edu        entry.writable = pte.w;
4797912Shestness@cs.utexas.edu        entry.user = pte.u;
4807912Shestness@cs.utexas.edu        if (!pte.p) {
4817912Shestness@cs.utexas.edu            doEndWalk = true;
4827912Shestness@cs.utexas.edu            fault = pageFault(pte.p);
4837912Shestness@cs.utexas.edu            break;
4847912Shestness@cs.utexas.edu        }
4857912Shestness@cs.utexas.edu        // 4 KB page
4868953Sgblack@eecs.umich.edu        entry.logBytes = 12;
4877912Shestness@cs.utexas.edu        nextRead = ((uint64_t)pte & (mask(20) << 12)) + vaddr.norml2 * dataSize;
4887912Shestness@cs.utexas.edu        nextState = PTE;
4897912Shestness@cs.utexas.edu        break;
4907912Shestness@cs.utexas.edu      case PTE:
4917912Shestness@cs.utexas.edu        DPRINTF(PageTableWalker,
4927912Shestness@cs.utexas.edu                "Got legacy mode PTE entry %#08x.\n", (uint32_t)pte);
4937912Shestness@cs.utexas.edu        doWrite = !pte.a;
4947912Shestness@cs.utexas.edu        pte.a = 1;
4957912Shestness@cs.utexas.edu        entry.writable = pte.w;
4967912Shestness@cs.utexas.edu        entry.user = pte.u;
4977912Shestness@cs.utexas.edu        if (!pte.p) {
4987912Shestness@cs.utexas.edu            doEndWalk = true;
4997912Shestness@cs.utexas.edu            fault = pageFault(pte.p);
5007912Shestness@cs.utexas.edu            break;
5017912Shestness@cs.utexas.edu        }
5027912Shestness@cs.utexas.edu        entry.paddr = (uint64_t)pte & (mask(20) << 12);
5037912Shestness@cs.utexas.edu        entry.uncacheable = uncacheable;
5047912Shestness@cs.utexas.edu        entry.global = pte.g;
5057912Shestness@cs.utexas.edu        entry.patBit = bits(pte, 7);
5067912Shestness@cs.utexas.edu        entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
5077912Shestness@cs.utexas.edu        doTLBInsert = true;
5087912Shestness@cs.utexas.edu        doEndWalk = true;
5097912Shestness@cs.utexas.edu        break;
5107912Shestness@cs.utexas.edu      default:
5117912Shestness@cs.utexas.edu        panic("Unknown page table walker state %d!\n");
5127912Shestness@cs.utexas.edu    }
5137912Shestness@cs.utexas.edu    if (doEndWalk) {
5147912Shestness@cs.utexas.edu        if (doTLBInsert)
5157912Shestness@cs.utexas.edu            if (!functional)
5167912Shestness@cs.utexas.edu                walker->tlb->insert(entry.vaddr, entry);
5177912Shestness@cs.utexas.edu        endWalk();
5187912Shestness@cs.utexas.edu    } else {
5197912Shestness@cs.utexas.edu        PacketPtr oldRead = read;
5207912Shestness@cs.utexas.edu        //If we didn't return, we're setting up another read.
5217912Shestness@cs.utexas.edu        Request::Flags flags = oldRead->req->getFlags();
5227912Shestness@cs.utexas.edu        flags.set(Request::UNCACHEABLE, uncacheable);
52312749Sgiacomo.travaglini@arm.com        RequestPtr request = std::make_shared<Request>(
52412749Sgiacomo.travaglini@arm.com            nextRead, oldRead->getSize(), flags, walker->masterId);
5258949Sandreas.hansson@arm.com        read = new Packet(request, MemCmd::ReadReq);
5267912Shestness@cs.utexas.edu        read->allocate();
5277912Shestness@cs.utexas.edu        // If we need to write, adjust the read packet to write the modified
5287912Shestness@cs.utexas.edu        // value back to memory.
5297912Shestness@cs.utexas.edu        if (doWrite) {
5307912Shestness@cs.utexas.edu            write = oldRead;
53113229Sgabeblack@google.com            write->setLE<uint64_t>(pte);
5327912Shestness@cs.utexas.edu            write->cmd = MemCmd::WriteReq;
5337912Shestness@cs.utexas.edu        } else {
5347912Shestness@cs.utexas.edu            write = NULL;
5357912Shestness@cs.utexas.edu            delete oldRead;
5367912Shestness@cs.utexas.edu        }
5377912Shestness@cs.utexas.edu    }
5387912Shestness@cs.utexas.edu    return fault;
5397912Shestness@cs.utexas.edu}
5407912Shestness@cs.utexas.edu
5417912Shestness@cs.utexas.eduvoid
5427912Shestness@cs.utexas.eduWalker::WalkerState::endWalk()
5437912Shestness@cs.utexas.edu{
5447912Shestness@cs.utexas.edu    nextState = Ready;
5457912Shestness@cs.utexas.edu    delete read;
5467912Shestness@cs.utexas.edu    read = NULL;
5477912Shestness@cs.utexas.edu}
5487912Shestness@cs.utexas.edu
5497912Shestness@cs.utexas.eduvoid
5507912Shestness@cs.utexas.eduWalker::WalkerState::setupWalk(Addr vaddr)
5517912Shestness@cs.utexas.edu{
5527912Shestness@cs.utexas.edu    VAddr addr = vaddr;
5537912Shestness@cs.utexas.edu    CR3 cr3 = tc->readMiscRegNoEffect(MISCREG_CR3);
5547912Shestness@cs.utexas.edu    // Check if we're in long mode or not
5557912Shestness@cs.utexas.edu    Efer efer = tc->readMiscRegNoEffect(MISCREG_EFER);
5567912Shestness@cs.utexas.edu    dataSize = 8;
5577912Shestness@cs.utexas.edu    Addr topAddr;
5587912Shestness@cs.utexas.edu    if (efer.lma) {
5597912Shestness@cs.utexas.edu        // Do long mode.
5607912Shestness@cs.utexas.edu        state = LongPML4;
5617912Shestness@cs.utexas.edu        topAddr = (cr3.longPdtb << 12) + addr.longl4 * dataSize;
5627912Shestness@cs.utexas.edu        enableNX = efer.nxe;
5637912Shestness@cs.utexas.edu    } else {
5647912Shestness@cs.utexas.edu        // We're in some flavor of legacy mode.
5657912Shestness@cs.utexas.edu        CR4 cr4 = tc->readMiscRegNoEffect(MISCREG_CR4);
5667912Shestness@cs.utexas.edu        if (cr4.pae) {
5677912Shestness@cs.utexas.edu            // Do legacy PAE.
5687912Shestness@cs.utexas.edu            state = PAEPDP;
5697912Shestness@cs.utexas.edu            topAddr = (cr3.paePdtb << 5) + addr.pael3 * dataSize;
5707912Shestness@cs.utexas.edu            enableNX = efer.nxe;
5717912Shestness@cs.utexas.edu        } else {
5727912Shestness@cs.utexas.edu            dataSize = 4;
5737912Shestness@cs.utexas.edu            topAddr = (cr3.pdtb << 12) + addr.norml2 * dataSize;
5747912Shestness@cs.utexas.edu            if (cr4.pse) {
5757912Shestness@cs.utexas.edu                // Do legacy PSE.
5767912Shestness@cs.utexas.edu                state = PSEPD;
5777912Shestness@cs.utexas.edu            } else {
5787912Shestness@cs.utexas.edu                // Do legacy non PSE.
5797912Shestness@cs.utexas.edu                state = PD;
5807912Shestness@cs.utexas.edu            }
5817912Shestness@cs.utexas.edu            enableNX = false;
5827912Shestness@cs.utexas.edu        }
5837912Shestness@cs.utexas.edu    }
5847912Shestness@cs.utexas.edu
5857912Shestness@cs.utexas.edu    nextState = Ready;
5867912Shestness@cs.utexas.edu    entry.vaddr = vaddr;
5877912Shestness@cs.utexas.edu
5887912Shestness@cs.utexas.edu    Request::Flags flags = Request::PHYSICAL;
5897912Shestness@cs.utexas.edu    if (cr3.pcd)
5907912Shestness@cs.utexas.edu        flags.set(Request::UNCACHEABLE);
59112749Sgiacomo.travaglini@arm.com
59212749Sgiacomo.travaglini@arm.com    RequestPtr request = std::make_shared<Request>(
59312749Sgiacomo.travaglini@arm.com        topAddr, dataSize, flags, walker->masterId);
59412749Sgiacomo.travaglini@arm.com
5958949Sandreas.hansson@arm.com    read = new Packet(request, MemCmd::ReadReq);
5967912Shestness@cs.utexas.edu    read->allocate();
5977912Shestness@cs.utexas.edu}
5987912Shestness@cs.utexas.edu
5997912Shestness@cs.utexas.edubool
6007912Shestness@cs.utexas.eduWalker::WalkerState::recvPacket(PacketPtr pkt)
6017912Shestness@cs.utexas.edu{
6028948Sandreas.hansson@arm.com    assert(pkt->isResponse());
6039165Sandreas.hansson@arm.com    assert(inflight);
6049165Sandreas.hansson@arm.com    assert(state == Waiting);
6059165Sandreas.hansson@arm.com    inflight--;
60614096Smatthew.poremba@amd.com    if (squashed) {
60714096Smatthew.poremba@amd.com        // if were were squashed, return true once inflight is zero and
60814096Smatthew.poremba@amd.com        // this WalkerState will be freed there.
60914096Smatthew.poremba@amd.com        return (inflight == 0);
61014096Smatthew.poremba@amd.com    }
6119165Sandreas.hansson@arm.com    if (pkt->isRead()) {
61210241Sbinhpham@cs.rutgers.edu        // should not have a pending read it we also had one outstanding
61310241Sbinhpham@cs.rutgers.edu        assert(!read);
61410241Sbinhpham@cs.rutgers.edu
6159579Sandreas.hansson@arm.com        // @todo someone should pay for this
61610694SMarco.Balboni@ARM.com        pkt->headerDelay = pkt->payloadDelay = 0;
6179579Sandreas.hansson@arm.com
6189165Sandreas.hansson@arm.com        state = nextState;
6199165Sandreas.hansson@arm.com        nextState = Ready;
6209165Sandreas.hansson@arm.com        PacketPtr write = NULL;
6219165Sandreas.hansson@arm.com        read = pkt;
6229165Sandreas.hansson@arm.com        timingFault = stepWalk(write);
6239165Sandreas.hansson@arm.com        state = Waiting;
6249165Sandreas.hansson@arm.com        assert(timingFault == NoFault || read == NULL);
6259165Sandreas.hansson@arm.com        if (write) {
6269165Sandreas.hansson@arm.com            writes.push_back(write);
6279165Sandreas.hansson@arm.com        }
6289165Sandreas.hansson@arm.com        sendPackets();
6299165Sandreas.hansson@arm.com    } else {
6309165Sandreas.hansson@arm.com        sendPackets();
6319165Sandreas.hansson@arm.com    }
6329165Sandreas.hansson@arm.com    if (inflight == 0 && read == NULL && writes.size() == 0) {
6339165Sandreas.hansson@arm.com        state = Ready;
6349165Sandreas.hansson@arm.com        nextState = Waiting;
6359165Sandreas.hansson@arm.com        if (timingFault == NoFault) {
6369165Sandreas.hansson@arm.com            /*
63711216Sbaz21@cam.ac.uk             * Finish the translation. Now that we know the right entry is
6389165Sandreas.hansson@arm.com             * in the TLB, this should work with no memory accesses.
6399165Sandreas.hansson@arm.com             * There could be new faults unrelated to the table walk like
6409165Sandreas.hansson@arm.com             * permissions violations, so we'll need the return value as
6419165Sandreas.hansson@arm.com             * well.
6429165Sandreas.hansson@arm.com             */
6439165Sandreas.hansson@arm.com            bool delayedResponse;
6449165Sandreas.hansson@arm.com            Fault fault = walker->tlb->translate(req, tc, NULL, mode,
6459165Sandreas.hansson@arm.com                                                 delayedResponse, true);
6469165Sandreas.hansson@arm.com            assert(!delayedResponse);
6479165Sandreas.hansson@arm.com            // Let the CPU continue.
6489165Sandreas.hansson@arm.com            translation->finish(fault, req, tc, mode);
6497912Shestness@cs.utexas.edu        } else {
6509165Sandreas.hansson@arm.com            // There was a fault during the walk. Let the CPU know.
6519165Sandreas.hansson@arm.com            translation->finish(timingFault, req, tc, mode);
6527912Shestness@cs.utexas.edu        }
6539165Sandreas.hansson@arm.com        return true;
6547912Shestness@cs.utexas.edu    }
6559165Sandreas.hansson@arm.com
6567912Shestness@cs.utexas.edu    return false;
6577912Shestness@cs.utexas.edu}
6587912Shestness@cs.utexas.edu
6597912Shestness@cs.utexas.eduvoid
6607912Shestness@cs.utexas.eduWalker::WalkerState::sendPackets()
6615245Sgblack@eecs.umich.edu{
6625245Sgblack@eecs.umich.edu    //If we're already waiting for the port to become available, just return.
6635245Sgblack@eecs.umich.edu    if (retrying)
6645245Sgblack@eecs.umich.edu        return;
6655245Sgblack@eecs.umich.edu
6665245Sgblack@eecs.umich.edu    //Reads always have priority
6675245Sgblack@eecs.umich.edu    if (read) {
6685897Sgblack@eecs.umich.edu        PacketPtr pkt = read;
6695897Sgblack@eecs.umich.edu        read = NULL;
6705897Sgblack@eecs.umich.edu        inflight++;
6717912Shestness@cs.utexas.edu        if (!walker->sendTiming(this, pkt)) {
6725245Sgblack@eecs.umich.edu            retrying = true;
6735897Sgblack@eecs.umich.edu            read = pkt;
6745897Sgblack@eecs.umich.edu            inflight--;
6755245Sgblack@eecs.umich.edu            return;
6765245Sgblack@eecs.umich.edu        }
6775245Sgblack@eecs.umich.edu    }
6785245Sgblack@eecs.umich.edu    //Send off as many of the writes as we can.
6795245Sgblack@eecs.umich.edu    while (writes.size()) {
6805245Sgblack@eecs.umich.edu        PacketPtr write = writes.back();
6815897Sgblack@eecs.umich.edu        writes.pop_back();
6825897Sgblack@eecs.umich.edu        inflight++;
6837912Shestness@cs.utexas.edu        if (!walker->sendTiming(this, write)) {
6845245Sgblack@eecs.umich.edu            retrying = true;
6855897Sgblack@eecs.umich.edu            writes.push_back(write);
6865897Sgblack@eecs.umich.edu            inflight--;
6875245Sgblack@eecs.umich.edu            return;
6885245Sgblack@eecs.umich.edu        }
6895245Sgblack@eecs.umich.edu    }
6905245Sgblack@eecs.umich.edu}
6915245Sgblack@eecs.umich.edu
69214096Smatthew.poremba@amd.comunsigned
69314096Smatthew.poremba@amd.comWalker::WalkerState::numInflight() const
69414096Smatthew.poremba@amd.com{
69514096Smatthew.poremba@amd.com    return inflight;
69614096Smatthew.poremba@amd.com}
69714096Smatthew.poremba@amd.com
6987912Shestness@cs.utexas.edubool
6997912Shestness@cs.utexas.eduWalker::WalkerState::isRetrying()
7005245Sgblack@eecs.umich.edu{
7017912Shestness@cs.utexas.edu    return retrying;
7027912Shestness@cs.utexas.edu}
7037912Shestness@cs.utexas.edu
7047912Shestness@cs.utexas.edubool
7057912Shestness@cs.utexas.eduWalker::WalkerState::isTiming()
7067912Shestness@cs.utexas.edu{
7077912Shestness@cs.utexas.edu    return timing;
7087912Shestness@cs.utexas.edu}
7097912Shestness@cs.utexas.edu
7107912Shestness@cs.utexas.edubool
7117912Shestness@cs.utexas.eduWalker::WalkerState::wasStarted()
7127912Shestness@cs.utexas.edu{
7137912Shestness@cs.utexas.edu    return started;
7147912Shestness@cs.utexas.edu}
7157912Shestness@cs.utexas.edu
7167912Shestness@cs.utexas.eduvoid
71714096Smatthew.poremba@amd.comWalker::WalkerState::squash()
71814096Smatthew.poremba@amd.com{
71914096Smatthew.poremba@amd.com    squashed = true;
72014096Smatthew.poremba@amd.com}
72114096Smatthew.poremba@amd.com
72214096Smatthew.poremba@amd.comvoid
7237912Shestness@cs.utexas.eduWalker::WalkerState::retry()
7247912Shestness@cs.utexas.edu{
7257912Shestness@cs.utexas.edu    retrying = false;
7267912Shestness@cs.utexas.edu    sendPackets();
7275245Sgblack@eecs.umich.edu}
7285245Sgblack@eecs.umich.edu
7295895Sgblack@eecs.umich.eduFault
7307912Shestness@cs.utexas.eduWalker::WalkerState::pageFault(bool present)
7315895Sgblack@eecs.umich.edu{
7325904Sgblack@eecs.umich.edu    DPRINTF(PageTableWalker, "Raising page fault.\n");
7335895Sgblack@eecs.umich.edu    HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
7346023Snate@binkert.org    if (mode == BaseTLB::Execute && !enableNX)
7356023Snate@binkert.org        mode = BaseTLB::Read;
73610474Sandreas.hansson@arm.com    return std::make_shared<PageFault>(entry.vaddr, present, mode,
73710474Sandreas.hansson@arm.com                                       m5reg.cpl == 3, false);
7385895Sgblack@eecs.umich.edu}
7395895Sgblack@eecs.umich.edu
7407912Shestness@cs.utexas.edu/* end namespace X86ISA */ }
7415245Sgblack@eecs.umich.edu
7425245Sgblack@eecs.umich.eduX86ISA::Walker *
7435245Sgblack@eecs.umich.eduX86PagetableWalkerParams::create()
7445245Sgblack@eecs.umich.edu{
7455245Sgblack@eecs.umich.edu    return new X86ISA::Walker(this);
7465245Sgblack@eecs.umich.edu}
747