pagetable_walker.hh revision 12088
12036SN/A/* 22036SN/A * Copyright (c) 2007 The Hewlett-Packard Development Company 32036SN/A * All rights reserved. 42036SN/A * 52036SN/A * The license below extends only to copyright in the software and shall 62036SN/A * not be construed as granting a license to any other intellectual 72036SN/A * property including but not limited to intellectual property relating 82036SN/A * to a hardware implementation of the functionality of the software 92036SN/A * licensed hereunder. You may use the software subject to the license 102036SN/A * terms below provided that you ensure that this notice is replicated 112036SN/A * unmodified and in its entirety in all distributions of the software, 122036SN/A * modified or unmodified, in source code or in binary form. 132036SN/A * 142036SN/A * Redistribution and use in source and binary forms, with or without 152036SN/A * modification, are permitted provided that the following conditions are 162036SN/A * met: redistributions of source code must retain the above copyright 172036SN/A * notice, this list of conditions and the following disclaimer; 182036SN/A * redistributions in binary form must reproduce the above copyright 192036SN/A * notice, this list of conditions and the following disclaimer in the 202036SN/A * documentation and/or other materials provided with the distribution; 212036SN/A * neither the name of the copyright holders nor the names of its 222036SN/A * contributors may be used to endorse or promote products derived from 232036SN/A * this software without specific prior written permission. 242036SN/A * 252036SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 262036SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 272665Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 282956Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 292956Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 302772Ssaidi@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 312036SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 322036SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 332036SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 342036SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 352036SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 362036SN/A * 372036SN/A * Authors: Gabe Black 382036SN/A */ 392036SN/A 404176Sgblack@eecs.umich.edu#ifndef __ARCH_X86_PAGE_TABLE_WALKER_HH__ 412779Sbinkertn@umich.edu#define __ARCH_X86_PAGE_TABLE_WALKER_HH__ 422036SN/A 432036SN/A#include <vector> 442036SN/A 452036SN/A#include "arch/x86/pagetable.hh" 462036SN/A#include "arch/x86/tlb.hh" 472565SN/A#include "base/types.hh" 482565SN/A#include "mem/mem_object.hh" 492565SN/A#include "mem/packet.hh" 502565SN/A#include "params/X86PagetableWalker.hh" 513918Ssaidi@eecs.umich.edu#include "sim/faults.hh" 523483Ssaidi@eecs.umich.edu#include "sim/system.hh" 532036SN/A 542036SN/Aclass ThreadContext; 552036SN/A 562036SN/Anamespace X86ISA 572778Ssaidi@eecs.umich.edu{ 582778Ssaidi@eecs.umich.edu class Walker : public MemObject 592778Ssaidi@eecs.umich.edu { 602778Ssaidi@eecs.umich.edu protected: 613799Sgblack@eecs.umich.edu // Port for accessing memory 623799Sgblack@eecs.umich.edu class WalkerPort : public MasterPort 632036SN/A { 642036SN/A public: 655549Snate@binkert.org WalkerPort(const std::string &_name, Walker * _walker) : 662036SN/A MasterPort(_name, _walker), walker(_walker) 672036SN/A {} 682565SN/A 692565SN/A protected: 702778Ssaidi@eecs.umich.edu Walker *walker; 712778Ssaidi@eecs.umich.edu 722565SN/A bool recvTimingResp(PacketPtr pkt); 732036SN/A void recvReqRetry(); 742036SN/A }; 752036SN/A 762036SN/A friend class WalkerPort; 772036SN/A WalkerPort port; 782036SN/A 792036SN/A // State to track each walk of the page table 802036SN/A class WalkerState 812565SN/A { 822036SN/A friend class Walker; 832036SN/A private: 845549Snate@binkert.org enum State { 852036SN/A Ready, 862036SN/A Waiting, 872565SN/A // Long mode 882565SN/A LongPML4, LongPDP, LongPD, LongPTE, 892778Ssaidi@eecs.umich.edu // PAE legacy mode 902778Ssaidi@eecs.umich.edu PAEPDP, PAEPD, PAEPTE, 912565SN/A // Non PAE legacy mode with and without PSE 922036SN/A PSEPD, PD, PTE 932036SN/A }; 942036SN/A 952565SN/A protected: 962036SN/A Walker *walker; 972036SN/A ThreadContext *tc; 985549Snate@binkert.org RequestPtr req; 992036SN/A State state; 1002036SN/A State nextState; 1012565SN/A int dataSize; 1022565SN/A bool enableNX; 1032778Ssaidi@eecs.umich.edu unsigned inflight; 1042778Ssaidi@eecs.umich.edu TlbEntry entry; 1052565SN/A PacketPtr read; 1062036SN/A std::vector<PacketPtr> writes; 1072036SN/A Fault timingFault; 1082565SN/A TLB::Translation * translation; 1092036SN/A BaseTLB::Mode mode; 1102036SN/A bool functional; 1112764Sstever@eecs.umich.edu bool timing; 1122764Sstever@eecs.umich.edu bool retrying; 1134176Sgblack@eecs.umich.edu bool started; 1142764Sstever@eecs.umich.edu public: 1152764Sstever@eecs.umich.edu WalkerState(Walker * _walker, BaseTLB::Translation *_translation, 1165549Snate@binkert.org RequestPtr _req, bool _isFunctional = false) : 1172764Sstever@eecs.umich.edu walker(_walker), req(_req), state(Ready), 1182764Sstever@eecs.umich.edu nextState(Ready), inflight(0), 1192764Sstever@eecs.umich.edu translation(_translation), 1202764Sstever@eecs.umich.edu functional(_isFunctional), timing(false), 1212764Sstever@eecs.umich.edu retrying(false), started(false) 1222764Sstever@eecs.umich.edu { 1232764Sstever@eecs.umich.edu } 1242764Sstever@eecs.umich.edu void initState(ThreadContext * _tc, BaseTLB::Mode _mode, 1252764Sstever@eecs.umich.edu bool _isTiming = false); 1262764Sstever@eecs.umich.edu Fault startWalk(); 1272764Sstever@eecs.umich.edu Fault startFunctional(Addr &addr, unsigned &logBytes); 1282036SN/A bool recvPacket(PacketPtr pkt); 1294176Sgblack@eecs.umich.edu bool isRetrying(); 1305549Snate@binkert.org bool wasStarted(); 1314176Sgblack@eecs.umich.edu bool isTiming(); 1324176Sgblack@eecs.umich.edu void retry(); 1334176Sgblack@eecs.umich.edu std::string name() const {return walker->name();} 1344176Sgblack@eecs.umich.edu 1354176Sgblack@eecs.umich.edu private: 1364176Sgblack@eecs.umich.edu void setupWalk(Addr vaddr); 1374176Sgblack@eecs.umich.edu Fault stepWalk(PacketPtr &write); 1385549Snate@binkert.org void sendPackets(); 1394176Sgblack@eecs.umich.edu void endWalk(); 1404176Sgblack@eecs.umich.edu Fault pageFault(bool present); 1414176Sgblack@eecs.umich.edu }; 1424176Sgblack@eecs.umich.edu 1434176Sgblack@eecs.umich.edu friend class WalkerState; 1444176Sgblack@eecs.umich.edu // State for timing and atomic accesses (need multiple per walker in 1452036SN/A // the case of multiple outstanding requests in timing mode) 1462036SN/A std::list<WalkerState *> currStates; 1475549Snate@binkert.org // State for functional accesses (only need one of these per walker) 1485549Snate@binkert.org WalkerState funcState; 1492036SN/A 1502036SN/A struct WalkerSenderState : public Packet::SenderState 1512036SN/A { 1523927Ssaidi@eecs.umich.edu WalkerState * senderWalk; 1533799Sgblack@eecs.umich.edu WalkerSenderState(WalkerState * _senderWalk) : 1545549Snate@binkert.org senderWalk(_senderWalk) {} 1555549Snate@binkert.org }; 1565549Snate@binkert.org 1575549Snate@binkert.org public: 1583483Ssaidi@eecs.umich.edu // Kick off the state machine. 1593799Sgblack@eecs.umich.edu Fault start(ThreadContext * _tc, BaseTLB::Translation *translation, 1605549Snate@binkert.org RequestPtr req, BaseTLB::Mode mode); 1615549Snate@binkert.org Fault startFunctional(ThreadContext * _tc, Addr &addr, 1625549Snate@binkert.org unsigned &logBytes, BaseTLB::Mode mode); 1635549Snate@binkert.org BaseMasterPort &getMasterPort(const std::string &if_name, 1642036SN/A PortID idx = InvalidPortID); 1652036SN/A 1662036SN/A protected: 1672036SN/A // The TLB we're supposed to load. 1682036SN/A TLB * tlb; 1692036SN/A System * sys; 1703799Sgblack@eecs.umich.edu MasterID masterId; 1713799Sgblack@eecs.umich.edu 1725549Snate@binkert.org // The number of outstanding walks that can be squashed per cycle. 1733799Sgblack@eecs.umich.edu unsigned numSquashable; 1745549Snate@binkert.org 1753799Sgblack@eecs.umich.edu // Wrapper for checking for squashes before starting a translation. 1765549Snate@binkert.org void startWalkWrapper(); 1773799Sgblack@eecs.umich.edu 1785549Snate@binkert.org /** 1793799Sgblack@eecs.umich.edu * Event used to call startWalkWrapper. 1805549Snate@binkert.org **/ 1813799Sgblack@eecs.umich.edu EventFunctionWrapper startWalkWrapperEvent; 1825549Snate@binkert.org 1832036SN/A // Functions for dealing with packets. 1842036SN/A bool recvTimingResp(PacketPtr pkt); 1852036SN/A void recvReqRetry(); 1862036SN/A bool sendTiming(WalkerState * sendingState, PacketPtr pkt); 1873799Sgblack@eecs.umich.edu 1883799Sgblack@eecs.umich.edu public: 1895549Snate@binkert.org 1903799Sgblack@eecs.umich.edu void setTLB(TLB * _tlb) 1915549Snate@binkert.org { 1923799Sgblack@eecs.umich.edu tlb = _tlb; 1935549Snate@binkert.org } 1943799Sgblack@eecs.umich.edu 1955549Snate@binkert.org typedef X86PagetableWalkerParams Params; 1963799Sgblack@eecs.umich.edu 1975549Snate@binkert.org const Params * 1983799Sgblack@eecs.umich.edu params() const 1995549Snate@binkert.org { 2002036SN/A return static_cast<const Params *>(_params); 2012036SN/A } 202 203 Walker(const Params *params) : 204 MemObject(params), port(name() + ".port", this), 205 funcState(this, NULL, NULL, true), tlb(NULL), sys(params->system), 206 masterId(sys->getMasterId(name())), 207 numSquashable(params->num_squash_per_cycle), 208 startWalkWrapperEvent([this]{ startWalkWrapper(); }, name()) 209 { 210 } 211 }; 212} 213#endif // __ARCH_X86_PAGE_TABLE_WALKER_HH__ 214