pagetable_walker.hh revision 8832
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#ifndef __ARCH_X86_PAGE_TABLE_WALKER_HH__
415245Sgblack@eecs.umich.edu#define __ARCH_X86_PAGE_TABLE_WALKER_HH__
425245Sgblack@eecs.umich.edu
435245Sgblack@eecs.umich.edu#include <vector>
445245Sgblack@eecs.umich.edu
455245Sgblack@eecs.umich.edu#include "arch/x86/pagetable.hh"
465245Sgblack@eecs.umich.edu#include "arch/x86/tlb.hh"
478229Snate@binkert.org#include "base/fast_alloc.hh"
486216Snate@binkert.org#include "base/types.hh"
495245Sgblack@eecs.umich.edu#include "mem/mem_object.hh"
505245Sgblack@eecs.umich.edu#include "mem/packet.hh"
515245Sgblack@eecs.umich.edu#include "params/X86PagetableWalker.hh"
527901Shestness@cs.utexas.edu#include "sim/faults.hh"
538832SAli.Saidi@ARM.com#include "sim/system.hh"
545245Sgblack@eecs.umich.edu
555245Sgblack@eecs.umich.educlass ThreadContext;
565245Sgblack@eecs.umich.edu
575245Sgblack@eecs.umich.edunamespace X86ISA
585245Sgblack@eecs.umich.edu{
595245Sgblack@eecs.umich.edu    class Walker : public MemObject
605245Sgblack@eecs.umich.edu    {
615245Sgblack@eecs.umich.edu      protected:
627912Shestness@cs.utexas.edu        // Port for accessing memory
635245Sgblack@eecs.umich.edu        class WalkerPort : public Port
645245Sgblack@eecs.umich.edu        {
655245Sgblack@eecs.umich.edu          public:
665245Sgblack@eecs.umich.edu            WalkerPort(const std::string &_name, Walker * _walker) :
678711Sandreas.hansson@arm.com                  Port(_name, _walker), walker(_walker)
685245Sgblack@eecs.umich.edu            {}
695245Sgblack@eecs.umich.edu
705245Sgblack@eecs.umich.edu          protected:
718832SAli.Saidi@ARM.com            Walker *walker;
725245Sgblack@eecs.umich.edu
735245Sgblack@eecs.umich.edu            bool recvTiming(PacketPtr pkt);
745245Sgblack@eecs.umich.edu            Tick recvAtomic(PacketPtr pkt);
755245Sgblack@eecs.umich.edu            void recvFunctional(PacketPtr pkt);
768711Sandreas.hansson@arm.com            void recvRangeChange();
775245Sgblack@eecs.umich.edu            void recvRetry();
788711Sandreas.hansson@arm.com            bool isSnooping() { return true; }
795245Sgblack@eecs.umich.edu        };
805245Sgblack@eecs.umich.edu
817912Shestness@cs.utexas.edu        friend class WalkerPort;
827912Shestness@cs.utexas.edu        WalkerPort port;
835245Sgblack@eecs.umich.edu        Port *getPort(const std::string &if_name, int idx = -1);
845245Sgblack@eecs.umich.edu
857912Shestness@cs.utexas.edu        // State to track each walk of the page table
867912Shestness@cs.utexas.edu        class WalkerState : public FastAlloc
877912Shestness@cs.utexas.edu        {
887912Shestness@cs.utexas.edu          private:
897912Shestness@cs.utexas.edu            enum State {
907912Shestness@cs.utexas.edu                Ready,
917912Shestness@cs.utexas.edu                Waiting,
927912Shestness@cs.utexas.edu                // Long mode
937912Shestness@cs.utexas.edu                LongPML4, LongPDP, LongPD, LongPTE,
947912Shestness@cs.utexas.edu                // PAE legacy mode
957912Shestness@cs.utexas.edu                PAEPDP, PAEPD, PAEPTE,
967912Shestness@cs.utexas.edu                // Non PAE legacy mode with and without PSE
977912Shestness@cs.utexas.edu                PSEPD, PD, PTE
987912Shestness@cs.utexas.edu            };
995245Sgblack@eecs.umich.edu
1007912Shestness@cs.utexas.edu          protected:
1018832SAli.Saidi@ARM.com            Walker *walker;
1027912Shestness@cs.utexas.edu            ThreadContext *tc;
1037912Shestness@cs.utexas.edu            RequestPtr req;
1047912Shestness@cs.utexas.edu            State state;
1057912Shestness@cs.utexas.edu            State nextState;
1067912Shestness@cs.utexas.edu            int dataSize;
1077912Shestness@cs.utexas.edu            bool enableNX;
1087912Shestness@cs.utexas.edu            unsigned inflight;
1097912Shestness@cs.utexas.edu            TlbEntry entry;
1107912Shestness@cs.utexas.edu            PacketPtr read;
1117912Shestness@cs.utexas.edu            std::vector<PacketPtr> writes;
1127912Shestness@cs.utexas.edu            Fault timingFault;
1137912Shestness@cs.utexas.edu            TLB::Translation * translation;
1147912Shestness@cs.utexas.edu            BaseTLB::Mode mode;
1157912Shestness@cs.utexas.edu            bool functional;
1167912Shestness@cs.utexas.edu            bool timing;
1177912Shestness@cs.utexas.edu            bool retrying;
1187912Shestness@cs.utexas.edu            bool started;
1197912Shestness@cs.utexas.edu          public:
1207912Shestness@cs.utexas.edu            WalkerState(Walker * _walker, BaseTLB::Translation *_translation,
1217912Shestness@cs.utexas.edu                    RequestPtr _req, bool _isFunctional = false) :
1227912Shestness@cs.utexas.edu                        walker(_walker), req(_req), state(Ready),
1237912Shestness@cs.utexas.edu                        nextState(Ready), inflight(0),
1247912Shestness@cs.utexas.edu                        translation(_translation),
1257912Shestness@cs.utexas.edu                        functional(_isFunctional), timing(false),
1267912Shestness@cs.utexas.edu                        retrying(false), started(false)
1277912Shestness@cs.utexas.edu            {
1287912Shestness@cs.utexas.edu            }
1297912Shestness@cs.utexas.edu            void initState(ThreadContext * _tc, BaseTLB::Mode _mode,
1307912Shestness@cs.utexas.edu                           bool _isTiming = false);
1317912Shestness@cs.utexas.edu            Fault startWalk();
1327912Shestness@cs.utexas.edu            Fault startFunctional(Addr &addr, Addr &pageSize);
1337912Shestness@cs.utexas.edu            bool recvPacket(PacketPtr pkt);
1347912Shestness@cs.utexas.edu            bool isRetrying();
1357912Shestness@cs.utexas.edu            bool wasStarted();
1367912Shestness@cs.utexas.edu            bool isTiming();
1377912Shestness@cs.utexas.edu            void retry();
1387912Shestness@cs.utexas.edu            std::string name() const {return walker->name();}
1397912Shestness@cs.utexas.edu
1407912Shestness@cs.utexas.edu          private:
1417912Shestness@cs.utexas.edu            void setupWalk(Addr vaddr);
1427912Shestness@cs.utexas.edu            Fault stepWalk(PacketPtr &write);
1437912Shestness@cs.utexas.edu            void sendPackets();
1447912Shestness@cs.utexas.edu            void endWalk();
1457912Shestness@cs.utexas.edu            Fault pageFault(bool present);
1467912Shestness@cs.utexas.edu        };
1477912Shestness@cs.utexas.edu
1487912Shestness@cs.utexas.edu        friend class WalkerState;
1497912Shestness@cs.utexas.edu        // State for timing and atomic accesses (need multiple per walker in
1507912Shestness@cs.utexas.edu        // the case of multiple outstanding requests in timing mode)
1517912Shestness@cs.utexas.edu        std::list<WalkerState *> currStates;
1527912Shestness@cs.utexas.edu        // State for functional accesses (only need one of these per walker)
1537912Shestness@cs.utexas.edu        WalkerState funcState;
1547912Shestness@cs.utexas.edu
1557912Shestness@cs.utexas.edu        struct WalkerSenderState : public Packet::SenderState
1567912Shestness@cs.utexas.edu        {
1577912Shestness@cs.utexas.edu            WalkerState * senderWalk;
1587912Shestness@cs.utexas.edu            Packet::SenderState * saved;
1597912Shestness@cs.utexas.edu            WalkerSenderState(WalkerState * _senderWalk,
1607912Shestness@cs.utexas.edu                    Packet::SenderState * _saved) :
1617912Shestness@cs.utexas.edu                senderWalk(_senderWalk), saved(_saved) {}
1627912Shestness@cs.utexas.edu        };
1637912Shestness@cs.utexas.edu
1647912Shestness@cs.utexas.edu      public:
1657912Shestness@cs.utexas.edu        // Kick off the state machine.
1667912Shestness@cs.utexas.edu        Fault start(ThreadContext * _tc, BaseTLB::Translation *translation,
1677912Shestness@cs.utexas.edu                RequestPtr req, BaseTLB::Mode mode);
1687912Shestness@cs.utexas.edu        Fault startFunctional(ThreadContext * _tc, Addr &addr,
1697912Shestness@cs.utexas.edu                Addr &pageSize, BaseTLB::Mode mode);
1707912Shestness@cs.utexas.edu
1717912Shestness@cs.utexas.edu      protected:
1725245Sgblack@eecs.umich.edu        // The TLB we're supposed to load.
1735245Sgblack@eecs.umich.edu        TLB * tlb;
1745245Sgblack@eecs.umich.edu        System * sys;
1758832SAli.Saidi@ARM.com        MasterID masterId;
1765245Sgblack@eecs.umich.edu
1777912Shestness@cs.utexas.edu        // Functions for dealing with packets.
1787912Shestness@cs.utexas.edu        bool recvTiming(PacketPtr pkt);
1797912Shestness@cs.utexas.edu        void recvRetry();
1807912Shestness@cs.utexas.edu        bool sendTiming(WalkerState * sendingState, PacketPtr pkt);
1815245Sgblack@eecs.umich.edu
1825245Sgblack@eecs.umich.edu      public:
1835245Sgblack@eecs.umich.edu
1845245Sgblack@eecs.umich.edu        void setTLB(TLB * _tlb)
1855245Sgblack@eecs.umich.edu        {
1865245Sgblack@eecs.umich.edu            tlb = _tlb;
1875245Sgblack@eecs.umich.edu        }
1885245Sgblack@eecs.umich.edu
1895245Sgblack@eecs.umich.edu        typedef X86PagetableWalkerParams Params;
1905245Sgblack@eecs.umich.edu
1918832SAli.Saidi@ARM.com        const Params *
1928832SAli.Saidi@ARM.com        params() const
1938832SAli.Saidi@ARM.com        {
1948832SAli.Saidi@ARM.com            return static_cast<const Params *>(_params);
1958832SAli.Saidi@ARM.com        }
1968832SAli.Saidi@ARM.com
1975245Sgblack@eecs.umich.edu        Walker(const Params *params) :
1987912Shestness@cs.utexas.edu            MemObject(params), port(name() + ".port", this),
1998832SAli.Saidi@ARM.com            funcState(this, NULL, NULL, true), tlb(NULL), sys(params->system),
2008832SAli.Saidi@ARM.com            masterId(sys->getMasterId(name()))
2015245Sgblack@eecs.umich.edu        {
2025245Sgblack@eecs.umich.edu        }
2035245Sgblack@eecs.umich.edu    };
2045245Sgblack@eecs.umich.edu}
2055245Sgblack@eecs.umich.edu#endif // __ARCH_X86_PAGE_TABLE_WALKER_HH__
206