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"
476216Snate@binkert.org#include "base/types.hh"
485245Sgblack@eecs.umich.edu#include "mem/packet.hh"
495245Sgblack@eecs.umich.edu#include "params/X86PagetableWalker.hh"
5013892Sgabeblack@google.com#include "sim/clocked_object.hh"
517901Shestness@cs.utexas.edu#include "sim/faults.hh"
528832SAli.Saidi@ARM.com#include "sim/system.hh"
535245Sgblack@eecs.umich.edu
545245Sgblack@eecs.umich.educlass ThreadContext;
555245Sgblack@eecs.umich.edu
565245Sgblack@eecs.umich.edunamespace X86ISA
575245Sgblack@eecs.umich.edu{
5813892Sgabeblack@google.com    class Walker : public ClockedObject
595245Sgblack@eecs.umich.edu    {
605245Sgblack@eecs.umich.edu      protected:
617912Shestness@cs.utexas.edu        // Port for accessing memory
628922Swilliam.wang@arm.com        class WalkerPort : public MasterPort
635245Sgblack@eecs.umich.edu        {
645245Sgblack@eecs.umich.edu          public:
655245Sgblack@eecs.umich.edu            WalkerPort(const std::string &_name, Walker * _walker) :
668922Swilliam.wang@arm.com                  MasterPort(_name, _walker), walker(_walker)
675245Sgblack@eecs.umich.edu            {}
685245Sgblack@eecs.umich.edu
695245Sgblack@eecs.umich.edu          protected:
708832SAli.Saidi@ARM.com            Walker *walker;
715245Sgblack@eecs.umich.edu
728975Sandreas.hansson@arm.com            bool recvTimingResp(PacketPtr pkt);
7310713Sandreas.hansson@arm.com            void recvReqRetry();
745245Sgblack@eecs.umich.edu        };
755245Sgblack@eecs.umich.edu
767912Shestness@cs.utexas.edu        friend class WalkerPort;
777912Shestness@cs.utexas.edu        WalkerPort port;
785245Sgblack@eecs.umich.edu
797912Shestness@cs.utexas.edu        // State to track each walk of the page table
809044SAli.Saidi@ARM.com        class WalkerState
817912Shestness@cs.utexas.edu        {
829701Sgedare@rtems.org          friend class Walker;
837912Shestness@cs.utexas.edu          private:
847912Shestness@cs.utexas.edu            enum State {
857912Shestness@cs.utexas.edu                Ready,
867912Shestness@cs.utexas.edu                Waiting,
877912Shestness@cs.utexas.edu                // Long mode
887912Shestness@cs.utexas.edu                LongPML4, LongPDP, LongPD, LongPTE,
897912Shestness@cs.utexas.edu                // PAE legacy mode
907912Shestness@cs.utexas.edu                PAEPDP, PAEPD, PAEPTE,
917912Shestness@cs.utexas.edu                // Non PAE legacy mode with and without PSE
927912Shestness@cs.utexas.edu                PSEPD, PD, PTE
937912Shestness@cs.utexas.edu            };
945245Sgblack@eecs.umich.edu
957912Shestness@cs.utexas.edu          protected:
968832SAli.Saidi@ARM.com            Walker *walker;
977912Shestness@cs.utexas.edu            ThreadContext *tc;
987912Shestness@cs.utexas.edu            RequestPtr req;
997912Shestness@cs.utexas.edu            State state;
1007912Shestness@cs.utexas.edu            State nextState;
1017912Shestness@cs.utexas.edu            int dataSize;
1027912Shestness@cs.utexas.edu            bool enableNX;
1037912Shestness@cs.utexas.edu            unsigned inflight;
1047912Shestness@cs.utexas.edu            TlbEntry entry;
1057912Shestness@cs.utexas.edu            PacketPtr read;
1067912Shestness@cs.utexas.edu            std::vector<PacketPtr> writes;
1077912Shestness@cs.utexas.edu            Fault timingFault;
1087912Shestness@cs.utexas.edu            TLB::Translation * translation;
1097912Shestness@cs.utexas.edu            BaseTLB::Mode mode;
1107912Shestness@cs.utexas.edu            bool functional;
1117912Shestness@cs.utexas.edu            bool timing;
1127912Shestness@cs.utexas.edu            bool retrying;
1137912Shestness@cs.utexas.edu            bool started;
11414096Smatthew.poremba@amd.com            bool squashed;
1157912Shestness@cs.utexas.edu          public:
1167912Shestness@cs.utexas.edu            WalkerState(Walker * _walker, BaseTLB::Translation *_translation,
11712749Sgiacomo.travaglini@arm.com                        const RequestPtr &_req, bool _isFunctional = false) :
11812749Sgiacomo.travaglini@arm.com                walker(_walker), req(_req), state(Ready),
11912749Sgiacomo.travaglini@arm.com                nextState(Ready), inflight(0),
12012749Sgiacomo.travaglini@arm.com                translation(_translation),
12112749Sgiacomo.travaglini@arm.com                functional(_isFunctional), timing(false),
12214096Smatthew.poremba@amd.com                retrying(false), started(false), squashed(false)
1237912Shestness@cs.utexas.edu            {
1247912Shestness@cs.utexas.edu            }
1257912Shestness@cs.utexas.edu            void initState(ThreadContext * _tc, BaseTLB::Mode _mode,
1267912Shestness@cs.utexas.edu                           bool _isTiming = false);
1277912Shestness@cs.utexas.edu            Fault startWalk();
1288953Sgblack@eecs.umich.edu            Fault startFunctional(Addr &addr, unsigned &logBytes);
1297912Shestness@cs.utexas.edu            bool recvPacket(PacketPtr pkt);
13014096Smatthew.poremba@amd.com            unsigned numInflight() const;
1317912Shestness@cs.utexas.edu            bool isRetrying();
1327912Shestness@cs.utexas.edu            bool wasStarted();
1337912Shestness@cs.utexas.edu            bool isTiming();
1347912Shestness@cs.utexas.edu            void retry();
13514096Smatthew.poremba@amd.com            void squash();
1367912Shestness@cs.utexas.edu            std::string name() const {return walker->name();}
1377912Shestness@cs.utexas.edu
1387912Shestness@cs.utexas.edu          private:
1397912Shestness@cs.utexas.edu            void setupWalk(Addr vaddr);
1407912Shestness@cs.utexas.edu            Fault stepWalk(PacketPtr &write);
1417912Shestness@cs.utexas.edu            void sendPackets();
1427912Shestness@cs.utexas.edu            void endWalk();
1437912Shestness@cs.utexas.edu            Fault pageFault(bool present);
1447912Shestness@cs.utexas.edu        };
1457912Shestness@cs.utexas.edu
1467912Shestness@cs.utexas.edu        friend class WalkerState;
1477912Shestness@cs.utexas.edu        // State for timing and atomic accesses (need multiple per walker in
1487912Shestness@cs.utexas.edu        // the case of multiple outstanding requests in timing mode)
1497912Shestness@cs.utexas.edu        std::list<WalkerState *> currStates;
1507912Shestness@cs.utexas.edu        // State for functional accesses (only need one of these per walker)
1517912Shestness@cs.utexas.edu        WalkerState funcState;
1527912Shestness@cs.utexas.edu
1537912Shestness@cs.utexas.edu        struct WalkerSenderState : public Packet::SenderState
1547912Shestness@cs.utexas.edu        {
1557912Shestness@cs.utexas.edu            WalkerState * senderWalk;
1569542Sandreas.hansson@arm.com            WalkerSenderState(WalkerState * _senderWalk) :
1579542Sandreas.hansson@arm.com                senderWalk(_senderWalk) {}
1587912Shestness@cs.utexas.edu        };
1597912Shestness@cs.utexas.edu
1607912Shestness@cs.utexas.edu      public:
1617912Shestness@cs.utexas.edu        // Kick off the state machine.
1627912Shestness@cs.utexas.edu        Fault start(ThreadContext * _tc, BaseTLB::Translation *translation,
16312749Sgiacomo.travaglini@arm.com                const RequestPtr &req, BaseTLB::Mode mode);
1647912Shestness@cs.utexas.edu        Fault startFunctional(ThreadContext * _tc, Addr &addr,
1658953Sgblack@eecs.umich.edu                unsigned &logBytes, BaseTLB::Mode mode);
16613784Sgabeblack@google.com        Port &getPort(const std::string &if_name,
16713784Sgabeblack@google.com                      PortID idx=InvalidPortID) override;
1687912Shestness@cs.utexas.edu
1697912Shestness@cs.utexas.edu      protected:
1705245Sgblack@eecs.umich.edu        // The TLB we're supposed to load.
1715245Sgblack@eecs.umich.edu        TLB * tlb;
1725245Sgblack@eecs.umich.edu        System * sys;
1738832SAli.Saidi@ARM.com        MasterID masterId;
1745245Sgblack@eecs.umich.edu
1759701Sgedare@rtems.org        // The number of outstanding walks that can be squashed per cycle.
1769701Sgedare@rtems.org        unsigned numSquashable;
1779701Sgedare@rtems.org
1789701Sgedare@rtems.org        // Wrapper for checking for squashes before starting a translation.
1799701Sgedare@rtems.org        void startWalkWrapper();
1809701Sgedare@rtems.org
18110654Sandreas.hansson@arm.com        /**
18210654Sandreas.hansson@arm.com         * Event used to call startWalkWrapper.
18310654Sandreas.hansson@arm.com         **/
18412088Sspwilson2@wisc.edu        EventFunctionWrapper startWalkWrapperEvent;
18510654Sandreas.hansson@arm.com
1867912Shestness@cs.utexas.edu        // Functions for dealing with packets.
1878975Sandreas.hansson@arm.com        bool recvTimingResp(PacketPtr pkt);
18810713Sandreas.hansson@arm.com        void recvReqRetry();
1897912Shestness@cs.utexas.edu        bool sendTiming(WalkerState * sendingState, PacketPtr pkt);
1905245Sgblack@eecs.umich.edu
1915245Sgblack@eecs.umich.edu      public:
1925245Sgblack@eecs.umich.edu
1935245Sgblack@eecs.umich.edu        void setTLB(TLB * _tlb)
1945245Sgblack@eecs.umich.edu        {
1955245Sgblack@eecs.umich.edu            tlb = _tlb;
1965245Sgblack@eecs.umich.edu        }
1975245Sgblack@eecs.umich.edu
1985245Sgblack@eecs.umich.edu        typedef X86PagetableWalkerParams Params;
1995245Sgblack@eecs.umich.edu
2008832SAli.Saidi@ARM.com        const Params *
2018832SAli.Saidi@ARM.com        params() const
2028832SAli.Saidi@ARM.com        {
2038832SAli.Saidi@ARM.com            return static_cast<const Params *>(_params);
2048832SAli.Saidi@ARM.com        }
2058832SAli.Saidi@ARM.com
2065245Sgblack@eecs.umich.edu        Walker(const Params *params) :
20713892Sgabeblack@google.com            ClockedObject(params), port(name() + ".port", this),
2088832SAli.Saidi@ARM.com            funcState(this, NULL, NULL, true), tlb(NULL), sys(params->system),
20912680Sgiacomo.travaglini@arm.com            masterId(sys->getMasterId(this)),
21010654Sandreas.hansson@arm.com            numSquashable(params->num_squash_per_cycle),
21112088Sspwilson2@wisc.edu            startWalkWrapperEvent([this]{ startWalkWrapper(); }, name())
2125245Sgblack@eecs.umich.edu        {
2135245Sgblack@eecs.umich.edu        }
2145245Sgblack@eecs.umich.edu    };
2155245Sgblack@eecs.umich.edu}
2165245Sgblack@eecs.umich.edu#endif // __ARCH_X86_PAGE_TABLE_WALKER_HH__
217