pagetable_walker.hh revision 7087
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/mem_object.hh"
495245Sgblack@eecs.umich.edu#include "mem/packet.hh"
505245Sgblack@eecs.umich.edu#include "params/X86PagetableWalker.hh"
515245Sgblack@eecs.umich.edu
525245Sgblack@eecs.umich.educlass ThreadContext;
535245Sgblack@eecs.umich.edu
545245Sgblack@eecs.umich.edunamespace X86ISA
555245Sgblack@eecs.umich.edu{
565245Sgblack@eecs.umich.edu    class Walker : public MemObject
575245Sgblack@eecs.umich.edu    {
585245Sgblack@eecs.umich.edu      public:
595245Sgblack@eecs.umich.edu        enum State {
605245Sgblack@eecs.umich.edu            Ready,
615245Sgblack@eecs.umich.edu            Waiting,
625245Sgblack@eecs.umich.edu            // Long mode
635245Sgblack@eecs.umich.edu            LongPML4, LongPDP, LongPD, LongPTE,
645245Sgblack@eecs.umich.edu            // PAE legacy mode
655245Sgblack@eecs.umich.edu            PAEPDP, PAEPD, PAEPTE,
665245Sgblack@eecs.umich.edu            // Non PAE legacy mode with and without PSE
675245Sgblack@eecs.umich.edu            PSEPD, PD, PTE
685245Sgblack@eecs.umich.edu        };
695245Sgblack@eecs.umich.edu
705897Sgblack@eecs.umich.edu        // Act on the current state and determine what to do next. The global
715897Sgblack@eecs.umich.edu        // read should be the packet that just came back from a read and write
725245Sgblack@eecs.umich.edu        // should be NULL. When the function returns, read is either NULL
735245Sgblack@eecs.umich.edu        // if the machine is finished, or points to a packet to initiate
745245Sgblack@eecs.umich.edu        // the next read. If any write is required to update an "accessed"
755245Sgblack@eecs.umich.edu        // bit, write will point to a packet to do the write. Otherwise it
765895Sgblack@eecs.umich.edu        // will be NULL. The return value is whatever fault was incurred
775895Sgblack@eecs.umich.edu        // during this stage of the lookup.
785897Sgblack@eecs.umich.edu        Fault doNext(PacketPtr &write);
795245Sgblack@eecs.umich.edu
805245Sgblack@eecs.umich.edu        // Kick off the state machine.
815895Sgblack@eecs.umich.edu        Fault start(ThreadContext * _tc, BaseTLB::Translation *translation,
826023Snate@binkert.org                RequestPtr req, BaseTLB::Mode mode);
835895Sgblack@eecs.umich.edu        // Clean up after the state machine.
845895Sgblack@eecs.umich.edu        void
855895Sgblack@eecs.umich.edu        stop()
865895Sgblack@eecs.umich.edu        {
875895Sgblack@eecs.umich.edu            nextState = Ready;
885895Sgblack@eecs.umich.edu            delete read->req;
895895Sgblack@eecs.umich.edu            delete read;
905895Sgblack@eecs.umich.edu            read = NULL;
915895Sgblack@eecs.umich.edu        }
925245Sgblack@eecs.umich.edu
935245Sgblack@eecs.umich.edu      protected:
945245Sgblack@eecs.umich.edu
955245Sgblack@eecs.umich.edu        /*
965245Sgblack@eecs.umich.edu         * State having to do with sending packets.
975245Sgblack@eecs.umich.edu         */
985245Sgblack@eecs.umich.edu        PacketPtr read;
995245Sgblack@eecs.umich.edu        std::vector<PacketPtr> writes;
1005245Sgblack@eecs.umich.edu
1015245Sgblack@eecs.umich.edu        // How many memory operations are in flight.
1025245Sgblack@eecs.umich.edu        unsigned inflight;
1035245Sgblack@eecs.umich.edu
1045245Sgblack@eecs.umich.edu        bool retrying;
1055245Sgblack@eecs.umich.edu
1065245Sgblack@eecs.umich.edu        /*
1075895Sgblack@eecs.umich.edu         * The fault, if any, that's waiting to be delivered in timing mode.
1085895Sgblack@eecs.umich.edu         */
1095895Sgblack@eecs.umich.edu        Fault timingFault;
1105895Sgblack@eecs.umich.edu
1115895Sgblack@eecs.umich.edu        /*
1125245Sgblack@eecs.umich.edu         * Functions for dealing with packets.
1135245Sgblack@eecs.umich.edu         */
1145245Sgblack@eecs.umich.edu        bool recvTiming(PacketPtr pkt);
1155245Sgblack@eecs.umich.edu        void recvRetry();
1165245Sgblack@eecs.umich.edu
1175245Sgblack@eecs.umich.edu        void sendPackets();
1185245Sgblack@eecs.umich.edu
1195245Sgblack@eecs.umich.edu        /*
1205245Sgblack@eecs.umich.edu         * Port for accessing memory
1215245Sgblack@eecs.umich.edu         */
1225245Sgblack@eecs.umich.edu        class WalkerPort : public Port
1235245Sgblack@eecs.umich.edu        {
1245245Sgblack@eecs.umich.edu          public:
1255245Sgblack@eecs.umich.edu            WalkerPort(const std::string &_name, Walker * _walker) :
1265245Sgblack@eecs.umich.edu                  Port(_name, _walker), walker(_walker),
1275245Sgblack@eecs.umich.edu                  snoopRangeSent(false)
1285245Sgblack@eecs.umich.edu            {}
1295245Sgblack@eecs.umich.edu
1305245Sgblack@eecs.umich.edu          protected:
1315245Sgblack@eecs.umich.edu            Walker * walker;
1325245Sgblack@eecs.umich.edu
1335245Sgblack@eecs.umich.edu            bool snoopRangeSent;
1345245Sgblack@eecs.umich.edu
1355245Sgblack@eecs.umich.edu            bool recvTiming(PacketPtr pkt);
1365245Sgblack@eecs.umich.edu            Tick recvAtomic(PacketPtr pkt);
1375245Sgblack@eecs.umich.edu            void recvFunctional(PacketPtr pkt);
1385245Sgblack@eecs.umich.edu            void recvStatusChange(Status status);
1395245Sgblack@eecs.umich.edu            void recvRetry();
1405245Sgblack@eecs.umich.edu            void getDeviceAddressRanges(AddrRangeList &resp,
1415245Sgblack@eecs.umich.edu                    bool &snoop)
1425245Sgblack@eecs.umich.edu            {
1435245Sgblack@eecs.umich.edu                resp.clear();
1445245Sgblack@eecs.umich.edu                snoop = true;
1455245Sgblack@eecs.umich.edu            }
1465245Sgblack@eecs.umich.edu        };
1475245Sgblack@eecs.umich.edu
1485245Sgblack@eecs.umich.edu        Port *getPort(const std::string &if_name, int idx = -1);
1495245Sgblack@eecs.umich.edu
1505245Sgblack@eecs.umich.edu        friend class WalkerPort;
1515245Sgblack@eecs.umich.edu
1525245Sgblack@eecs.umich.edu        WalkerPort port;
1535245Sgblack@eecs.umich.edu
1545245Sgblack@eecs.umich.edu        // The TLB we're supposed to load.
1555245Sgblack@eecs.umich.edu        TLB * tlb;
1565245Sgblack@eecs.umich.edu        System * sys;
1575895Sgblack@eecs.umich.edu        BaseTLB::Translation * translation;
1585245Sgblack@eecs.umich.edu
1595245Sgblack@eecs.umich.edu        /*
1605245Sgblack@eecs.umich.edu         * State machine state.
1615245Sgblack@eecs.umich.edu         */
1625245Sgblack@eecs.umich.edu        ThreadContext * tc;
1635895Sgblack@eecs.umich.edu        RequestPtr req;
1645245Sgblack@eecs.umich.edu        State state;
1655245Sgblack@eecs.umich.edu        State nextState;
1665245Sgblack@eecs.umich.edu        int size;
1675245Sgblack@eecs.umich.edu        bool enableNX;
1686023Snate@binkert.org        BaseTLB::Mode mode;
1696023Snate@binkert.org        bool user;
1705245Sgblack@eecs.umich.edu        TlbEntry entry;
1715881Sgblack@eecs.umich.edu
1725881Sgblack@eecs.umich.edu        Fault pageFault(bool present);
1735245Sgblack@eecs.umich.edu
1745245Sgblack@eecs.umich.edu      public:
1755245Sgblack@eecs.umich.edu
1765245Sgblack@eecs.umich.edu        void setTLB(TLB * _tlb)
1775245Sgblack@eecs.umich.edu        {
1785245Sgblack@eecs.umich.edu            tlb = _tlb;
1795245Sgblack@eecs.umich.edu        }
1805245Sgblack@eecs.umich.edu
1815245Sgblack@eecs.umich.edu        typedef X86PagetableWalkerParams Params;
1825245Sgblack@eecs.umich.edu
1835245Sgblack@eecs.umich.edu        Walker(const Params *params) :
1845245Sgblack@eecs.umich.edu            MemObject(params),
1855245Sgblack@eecs.umich.edu            read(NULL), inflight(0), retrying(false),
1865245Sgblack@eecs.umich.edu            port(name() + ".port", this),
1875245Sgblack@eecs.umich.edu            tlb(NULL), sys(params->system),
1885245Sgblack@eecs.umich.edu            tc(NULL), state(Ready), nextState(Ready)
1895245Sgblack@eecs.umich.edu        {
1905245Sgblack@eecs.umich.edu        }
1915245Sgblack@eecs.umich.edu    };
1925245Sgblack@eecs.umich.edu}
1935245Sgblack@eecs.umich.edu#endif // __ARCH_X86_PAGE_TABLE_WALKER_HH__
194