diff options
author | Joel Hestness <hestness@cs.utexas.edu> | 2011-02-06 22:14:18 -0800 |
---|---|---|
committer | Joel Hestness <hestness@cs.utexas.edu> | 2011-02-06 22:14:18 -0800 |
commit | 3a2d2223e1debf932a0cec3244e4ce63e5d748af (patch) | |
tree | d0f33e52ede665c3d5c48d89e14273e7da8cc6fa /src/arch/x86/pagetable_walker.hh | |
parent | 52b611922849d8e3ca6fb3aa0176a8d85e91e922 (diff) | |
download | gem5-3a2d2223e1debf932a0cec3244e4ce63e5d748af.tar.xz |
x86: Timing support for pagetable walker
Move page table walker state to its own object type, and make the
walker instantiate state for each outstanding walk. By storing the
states in a queue, the walker is able to handle multiple outstanding
timing requests. Note that functional walks use separate state
elements.
Diffstat (limited to 'src/arch/x86/pagetable_walker.hh')
-rw-r--r-- | src/arch/x86/pagetable_walker.hh | 183 |
1 files changed, 97 insertions, 86 deletions
diff --git a/src/arch/x86/pagetable_walker.hh b/src/arch/x86/pagetable_walker.hh index 68f85be93..007c577ae 100644 --- a/src/arch/x86/pagetable_walker.hh +++ b/src/arch/x86/pagetable_walker.hh @@ -45,6 +45,7 @@ #include "arch/x86/pagetable.hh" #include "arch/x86/tlb.hh" #include "base/types.hh" +#include "base/fast_alloc.hh" #include "mem/mem_object.hh" #include "mem/packet.hh" #include "params/X86PagetableWalker.hh" @@ -56,70 +57,8 @@ namespace X86ISA { class Walker : public MemObject { - public: - enum State { - Ready, - Waiting, - // Long mode - LongPML4, LongPDP, LongPD, LongPTE, - // PAE legacy mode - PAEPDP, PAEPD, PAEPTE, - // Non PAE legacy mode with and without PSE - PSEPD, PD, PTE - }; - - // Act on the current state and determine what to do next. The global - // read should be the packet that just came back from a read and write - // should be NULL. When the function returns, read is either NULL - // if the machine is finished, or points to a packet to initiate - // the next read. If any write is required to update an "accessed" - // bit, write will point to a packet to do the write. Otherwise it - // will be NULL. The return value is whatever fault was incurred - // during this stage of the lookup. - Fault doNext(PacketPtr &write); - - // Kick off the state machine. - Fault start(ThreadContext * _tc, BaseTLB::Translation *translation, - RequestPtr req, BaseTLB::Mode mode); - // Clean up after the state machine. - void - stop() - { - nextState = Ready; - delete read->req; - delete read; - read = NULL; - } - protected: - - /* - * State having to do with sending packets. - */ - PacketPtr read; - std::vector<PacketPtr> writes; - - // How many memory operations are in flight. - unsigned inflight; - - bool retrying; - - /* - * The fault, if any, that's waiting to be delivered in timing mode. - */ - Fault timingFault; - - /* - * Functions for dealing with packets. - */ - bool recvTiming(PacketPtr pkt); - void recvRetry(); - - void sendPackets(); - - /* - * Port for accessing memory - */ + // Port for accessing memory class WalkerPort : public Port { public: @@ -146,31 +85,106 @@ namespace X86ISA } }; + friend class WalkerPort; + WalkerPort port; Port *getPort(const std::string &if_name, int idx = -1); - friend class WalkerPort; + // State to track each walk of the page table + class WalkerState : public FastAlloc + { + private: + enum State { + Ready, + Waiting, + // Long mode + LongPML4, LongPDP, LongPD, LongPTE, + // PAE legacy mode + PAEPDP, PAEPD, PAEPTE, + // Non PAE legacy mode with and without PSE + PSEPD, PD, PTE + }; - WalkerPort port; + protected: + Walker * walker; + ThreadContext *tc; + RequestPtr req; + State state; + State nextState; + int dataSize; + bool enableNX; + unsigned inflight; + TlbEntry entry; + PacketPtr read; + std::vector<PacketPtr> writes; + Fault timingFault; + TLB::Translation * translation; + BaseTLB::Mode mode; + bool functional; + bool timing; + bool retrying; + bool started; + + public: + WalkerState(Walker * _walker, BaseTLB::Translation *_translation, + RequestPtr _req, bool _isFunctional = false) : + walker(_walker), req(_req), state(Ready), + nextState(Ready), inflight(0), + translation(_translation), + functional(_isFunctional), timing(false), + retrying(false), started(false) + { + } + void initState(ThreadContext * _tc, BaseTLB::Mode _mode, + bool _isTiming = false); + Fault startWalk(); + Fault startFunctional(Addr &addr, Addr &pageSize); + bool recvPacket(PacketPtr pkt); + bool isRetrying(); + bool wasStarted(); + bool isTiming(); + void retry(); + std::string name() const {return walker->name();} + + private: + void setupWalk(Addr vaddr); + Fault stepWalk(PacketPtr &write); + void sendPackets(); + void endWalk(); + Fault pageFault(bool present); + }; + + friend class WalkerState; + // State for timing and atomic accesses (need multiple per walker in + // the case of multiple outstanding requests in timing mode) + std::list<WalkerState *> currStates; + // State for functional accesses (only need one of these per walker) + WalkerState funcState; + + struct WalkerSenderState : public Packet::SenderState + { + WalkerState * senderWalk; + Packet::SenderState * saved; + WalkerSenderState(WalkerState * _senderWalk, + Packet::SenderState * _saved) : + senderWalk(_senderWalk), saved(_saved) {} + }; + public: + // Kick off the state machine. + Fault start(ThreadContext * _tc, BaseTLB::Translation *translation, + RequestPtr req, BaseTLB::Mode mode); + Fault startFunctional(ThreadContext * _tc, Addr &addr, + Addr &pageSize, BaseTLB::Mode mode); + + protected: // The TLB we're supposed to load. TLB * tlb; System * sys; - BaseTLB::Translation * translation; - - /* - * State machine state. - */ - ThreadContext * tc; - RequestPtr req; - State state; - State nextState; - int size; - bool enableNX; - BaseTLB::Mode mode; - bool user; - TlbEntry entry; - - Fault pageFault(bool present); + + // Functions for dealing with packets. + bool recvTiming(PacketPtr pkt); + void recvRetry(); + bool sendTiming(WalkerState * sendingState, PacketPtr pkt); public: @@ -182,11 +196,8 @@ namespace X86ISA typedef X86PagetableWalkerParams Params; Walker(const Params *params) : - MemObject(params), - read(NULL), inflight(0), retrying(false), - port(name() + ".port", this), - tlb(NULL), sys(params->system), - tc(NULL), state(Ready), nextState(Ready) + MemObject(params), port(name() + ".port", this), + funcState(this, NULL, NULL, true), tlb(NULL), sys(params->system) { } }; |