pagetable_walker.hh revision 12088
12568SN/A/*
211600Sandreas.hansson@arm.com * Copyright (c) 2007 The Hewlett-Packard Development Company
38668Sgeoffrey.blake@arm.com * All rights reserved.
48668Sgeoffrey.blake@arm.com *
58668Sgeoffrey.blake@arm.com * The license below extends only to copyright in the software and shall
68668Sgeoffrey.blake@arm.com * not be construed as granting a license to any other intellectual
78668Sgeoffrey.blake@arm.com * property including but not limited to intellectual property relating
88668Sgeoffrey.blake@arm.com * to a hardware implementation of the functionality of the software
98668Sgeoffrey.blake@arm.com * licensed hereunder.  You may use the software subject to the license
108668Sgeoffrey.blake@arm.com * terms below provided that you ensure that this notice is replicated
118668Sgeoffrey.blake@arm.com * unmodified and in its entirety in all distributions of the software,
128668Sgeoffrey.blake@arm.com * modified or unmodified, in source code or in binary form.
138668Sgeoffrey.blake@arm.com *
142568SN/A * Redistribution and use in source and binary forms, with or without
1510975Sdavid.hashe@amd.com * modification, are permitted provided that the following conditions are
162568SN/A * met: redistributions of source code must retain the above copyright
172568SN/A * notice, this list of conditions and the following disclaimer;
182568SN/A * redistributions in binary form must reproduce the above copyright
192568SN/A * notice, this list of conditions and the following disclaimer in the
202568SN/A * documentation and/or other materials provided with the distribution;
212568SN/A * neither the name of the copyright holders nor the names of its
222568SN/A * contributors may be used to endorse or promote products derived from
232568SN/A * this software without specific prior written permission.
242568SN/A *
252568SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
262568SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
272568SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
282568SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
292568SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
302568SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
312568SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
322568SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
332568SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
342568SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
352568SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
362568SN/A *
372568SN/A * Authors: Gabe Black
382568SN/A */
392568SN/A
402665Ssaidi@eecs.umich.edu#ifndef __ARCH_X86_PAGE_TABLE_WALKER_HH__
412665Ssaidi@eecs.umich.edu#define __ARCH_X86_PAGE_TABLE_WALKER_HH__
422665Ssaidi@eecs.umich.edu
432568SN/A#include <vector>
442568SN/A
452568SN/A#include "arch/x86/pagetable.hh"
462568SN/A#include "arch/x86/tlb.hh"
472568SN/A#include "base/types.hh"
482568SN/A#include "mem/mem_object.hh"
492568SN/A#include "mem/packet.hh"
503260Ssaidi@eecs.umich.edu#include "params/X86PagetableWalker.hh"
5111793Sbrandon.potter@amd.com#include "sim/faults.hh"
5211793Sbrandon.potter@amd.com#include "sim/system.hh"
538229Snate@binkert.org
543260Ssaidi@eecs.umich.educlass ThreadContext;
558229Snate@binkert.org
565314Sstever@gmail.comnamespace X86ISA
572590SN/A{
583348Sbinkertn@umich.edu    class Walker : public MemObject
592568SN/A    {
605735Snate@binkert.org      protected:
615735Snate@binkert.org        // Port for accessing memory
624022Sstever@eecs.umich.edu        class WalkerPort : public MasterPort
634022Sstever@eecs.umich.edu        {
644022Sstever@eecs.umich.edu          public:
654022Sstever@eecs.umich.edu            WalkerPort(const std::string &_name, Walker * _walker) :
664022Sstever@eecs.umich.edu                  MasterPort(_name, _walker), walker(_walker)
674022Sstever@eecs.umich.edu            {}
684022Sstever@eecs.umich.edu
6911600Sandreas.hansson@arm.com          protected:
7011600Sandreas.hansson@arm.com            Walker *walker;
712641Sstever@eecs.umich.edu
724022Sstever@eecs.umich.edu            bool recvTimingResp(PacketPtr pkt);
734022Sstever@eecs.umich.edu            void recvReqRetry();
742641Sstever@eecs.umich.edu        };
754022Sstever@eecs.umich.edu
764022Sstever@eecs.umich.edu        friend class WalkerPort;
7710885Sandreas.hansson@arm.com        WalkerPort port;
7810885Sandreas.hansson@arm.com
794022Sstever@eecs.umich.edu        // State to track each walk of the page table
804473Sstever@eecs.umich.edu        class WalkerState
814473Sstever@eecs.umich.edu        {
825319Sstever@gmail.com          friend class Walker;
835319Sstever@gmail.com          private:
845319Sstever@gmail.com            enum State {
854022Sstever@eecs.umich.edu                Ready,
8611284Sandreas.hansson@arm.com                Waiting,
874022Sstever@eecs.umich.edu                // Long mode
884022Sstever@eecs.umich.edu                LongPML4, LongPDP, LongPD, LongPTE,
8911287Sandreas.hansson@arm.com                // PAE legacy mode
9011199Sandreas.hansson@arm.com                PAEPDP, PAEPD, PAEPTE,
9111600Sandreas.hansson@arm.com                // Non PAE legacy mode with and without PSE
9211199Sandreas.hansson@arm.com                PSEPD, PD, PTE
9311199Sandreas.hansson@arm.com            };
9411199Sandreas.hansson@arm.com
9511199Sandreas.hansson@arm.com          protected:
9611600Sandreas.hansson@arm.com            Walker *walker;
9711199Sandreas.hansson@arm.com            ThreadContext *tc;
9810883Sali.jafri@arm.com            RequestPtr req;
9911600Sandreas.hansson@arm.com            State state;
1004022Sstever@eecs.umich.edu            State nextState;
1014022Sstever@eecs.umich.edu            int dataSize;
1024022Sstever@eecs.umich.edu            bool enableNX;
1034022Sstever@eecs.umich.edu            unsigned inflight;
10411600Sandreas.hansson@arm.com            TlbEntry entry;
1054022Sstever@eecs.umich.edu            PacketPtr read;
1064022Sstever@eecs.umich.edu            std::vector<PacketPtr> writes;
1074022Sstever@eecs.umich.edu            Fault timingFault;
1084022Sstever@eecs.umich.edu            TLB::Translation * translation;
1094022Sstever@eecs.umich.edu            BaseTLB::Mode mode;
1104022Sstever@eecs.umich.edu            bool functional;
1114022Sstever@eecs.umich.edu            bool timing;
11210886Sandreas.hansson@arm.com            bool retrying;
11311284Sandreas.hansson@arm.com            bool started;
11410886Sandreas.hansson@arm.com          public:
1154022Sstever@eecs.umich.edu            WalkerState(Walker * _walker, BaseTLB::Translation *_translation,
11611600Sandreas.hansson@arm.com                    RequestPtr _req, bool _isFunctional = false) :
11711600Sandreas.hansson@arm.com                        walker(_walker), req(_req), state(Ready),
1184628Sstever@eecs.umich.edu                        nextState(Ready), inflight(0),
1197465Ssteve.reinhardt@amd.com                        translation(_translation),
12011600Sandreas.hansson@arm.com                        functional(_isFunctional), timing(false),
12111600Sandreas.hansson@arm.com                        retrying(false), started(false)
1227465Ssteve.reinhardt@amd.com            {
1234628Sstever@eecs.umich.edu            }
12411287Sandreas.hansson@arm.com            void initState(ThreadContext * _tc, BaseTLB::Mode _mode,
1257465Ssteve.reinhardt@amd.com                           bool _isTiming = false);
12610325Sgeoffrey.blake@arm.com            Fault startWalk();
12711600Sandreas.hansson@arm.com            Fault startFunctional(Addr &addr, unsigned &logBytes);
12811600Sandreas.hansson@arm.com            bool recvPacket(PacketPtr pkt);
1297465Ssteve.reinhardt@amd.com            bool isRetrying();
13010325Sgeoffrey.blake@arm.com            bool wasStarted();
13110325Sgeoffrey.blake@arm.com            bool isTiming();
13211287Sandreas.hansson@arm.com            void retry();
1337465Ssteve.reinhardt@amd.com            std::string name() const {return walker->name();}
13410885Sandreas.hansson@arm.com
13510885Sandreas.hansson@arm.com          private:
13610885Sandreas.hansson@arm.com            void setupWalk(Addr vaddr);
13711600Sandreas.hansson@arm.com            Fault stepWalk(PacketPtr &write);
13811600Sandreas.hansson@arm.com            void sendPackets();
1394022Sstever@eecs.umich.edu            void endWalk();
14010885Sandreas.hansson@arm.com            Fault pageFault(bool present);
14110885Sandreas.hansson@arm.com        };
14211287Sandreas.hansson@arm.com
1434040Ssaidi@eecs.umich.edu        friend class WalkerState;
14410885Sandreas.hansson@arm.com        // State for timing and atomic accesses (need multiple per walker in
14510885Sandreas.hansson@arm.com        // the case of multiple outstanding requests in timing mode)
14610885Sandreas.hansson@arm.com        std::list<WalkerState *> currStates;
14711600Sandreas.hansson@arm.com        // State for functional accesses (only need one of these per walker)
14811600Sandreas.hansson@arm.com        WalkerState funcState;
14910885Sandreas.hansson@arm.com
15010885Sandreas.hansson@arm.com        struct WalkerSenderState : public Packet::SenderState
15110885Sandreas.hansson@arm.com        {
15211600Sandreas.hansson@arm.com            WalkerState * senderWalk;
15311600Sandreas.hansson@arm.com            WalkerSenderState(WalkerState * _senderWalk) :
1545507Sstever@gmail.com                senderWalk(_senderWalk) {}
1555507Sstever@gmail.com        };
1566076Sgblack@eecs.umich.edu
1575507Sstever@gmail.com      public:
1584626Sstever@eecs.umich.edu        // Kick off the state machine.
15911284Sandreas.hansson@arm.com        Fault start(ThreadContext * _tc, BaseTLB::Translation *translation,
1604626Sstever@eecs.umich.edu                RequestPtr req, BaseTLB::Mode mode);
1614626Sstever@eecs.umich.edu        Fault startFunctional(ThreadContext * _tc, Addr &addr,
16210325Sgeoffrey.blake@arm.com                unsigned &logBytes, BaseTLB::Mode mode);
16311284Sandreas.hansson@arm.com        BaseMasterPort &getMasterPort(const std::string &if_name,
1647669Ssteve.reinhardt@amd.com                                      PortID idx = InvalidPortID);
1657669Ssteve.reinhardt@amd.com
1664626Sstever@eecs.umich.edu      protected:
16711287Sandreas.hansson@arm.com        // The TLB we're supposed to load.
1684626Sstever@eecs.umich.edu        TLB * tlb;
1694040Ssaidi@eecs.umich.edu        System * sys;
17011284Sandreas.hansson@arm.com        MasterID masterId;
1714040Ssaidi@eecs.umich.edu
1724040Ssaidi@eecs.umich.edu        // The number of outstanding walks that can be squashed per cycle.
17311287Sandreas.hansson@arm.com        unsigned numSquashable;
1744870Sstever@eecs.umich.edu
1755650Sgblack@eecs.umich.edu        // Wrapper for checking for squashes before starting a translation.
1765650Sgblack@eecs.umich.edu        void startWalkWrapper();
1776063Sgblack@eecs.umich.edu
1785650Sgblack@eecs.umich.edu        /**
1796063Sgblack@eecs.umich.edu         * Event used to call startWalkWrapper.
18011256Santhony.gutierrez@amd.com         **/
18111256Santhony.gutierrez@amd.com        EventFunctionWrapper startWalkWrapperEvent;
18211256Santhony.gutierrez@amd.com
18311256Santhony.gutierrez@amd.com        // Functions for dealing with packets.
1844870Sstever@eecs.umich.edu        bool recvTimingResp(PacketPtr pkt);
1854986Ssaidi@eecs.umich.edu        void recvReqRetry();
1864870Sstever@eecs.umich.edu        bool sendTiming(WalkerState * sendingState, PacketPtr pkt);
1875314Sstever@gmail.com
1888436SBrad.Beckmann@amd.com      public:
1898436SBrad.Beckmann@amd.com
1908436SBrad.Beckmann@amd.com        void setTLB(TLB * _tlb)
1918436SBrad.Beckmann@amd.com        {
1925314Sstever@gmail.com            tlb = _tlb;
1938184Ssomayeh@cs.wisc.edu        }
1948184Ssomayeh@cs.wisc.edu
19511284Sandreas.hansson@arm.com        typedef X86PagetableWalkerParams Params;
1968716Snilay@cs.wisc.edu
19711600Sandreas.hansson@arm.com        const Params *
19810886Sandreas.hansson@arm.com        params() const
19910886Sandreas.hansson@arm.com        {
20011287Sandreas.hansson@arm.com            return static_cast<const Params *>(_params);
20110886Sandreas.hansson@arm.com        }
2024022Sstever@eecs.umich.edu
2032592SN/A        Walker(const Params *params) :
2043607Srdreslin@umich.edu            MemObject(params), port(name() + ".port", this),
20510028SGiacomo.Gabrielli@arm.com            funcState(this, NULL, NULL, true), tlb(NULL), sys(params->system),
20610570Sandreas.hansson@arm.com            masterId(sys->getMasterId(name())),
2072641Sstever@eecs.umich.edu            numSquashable(params->num_squash_per_cycle),
2084626Sstever@eecs.umich.edu            startWalkWrapperEvent([this]{ startWalkWrapper(); }, name())
2094626Sstever@eecs.umich.edu        {
2104626Sstever@eecs.umich.edu        }
2114626Sstever@eecs.umich.edu    };
2123260Ssaidi@eecs.umich.edu}
21310028SGiacomo.Gabrielli@arm.com#endif // __ARCH_X86_PAGE_TABLE_WALKER_HH__
21410028SGiacomo.Gabrielli@arm.com