table_walker.hh revision 9258
17404SAli.Saidi@ARM.com/*
29015Sandreas.hansson@arm.com * Copyright (c) 2010-2012 ARM Limited
37404SAli.Saidi@ARM.com * All rights reserved
47404SAli.Saidi@ARM.com *
57404SAli.Saidi@ARM.com * The license below extends only to copyright in the software and shall
67404SAli.Saidi@ARM.com * not be construed as granting a license to any other intellectual
77404SAli.Saidi@ARM.com * property including but not limited to intellectual property relating
87404SAli.Saidi@ARM.com * to a hardware implementation of the functionality of the software
97404SAli.Saidi@ARM.com * licensed hereunder.  You may use the software subject to the license
107404SAli.Saidi@ARM.com * terms below provided that you ensure that this notice is replicated
117404SAli.Saidi@ARM.com * unmodified and in its entirety in all distributions of the software,
127404SAli.Saidi@ARM.com * modified or unmodified, in source code or in binary form.
137404SAli.Saidi@ARM.com *
147404SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without
157404SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are
167404SAli.Saidi@ARM.com * met: redistributions of source code must retain the above copyright
177404SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer;
187404SAli.Saidi@ARM.com * redistributions in binary form must reproduce the above copyright
197404SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer in the
207404SAli.Saidi@ARM.com * documentation and/or other materials provided with the distribution;
217404SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its
227404SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from
237404SAli.Saidi@ARM.com * this software without specific prior written permission.
247404SAli.Saidi@ARM.com *
257404SAli.Saidi@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
267404SAli.Saidi@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
277404SAli.Saidi@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
287404SAli.Saidi@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
297404SAli.Saidi@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
307404SAli.Saidi@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
317404SAli.Saidi@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
327404SAli.Saidi@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
337404SAli.Saidi@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
347404SAli.Saidi@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
357404SAli.Saidi@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
367404SAli.Saidi@ARM.com *
377404SAli.Saidi@ARM.com * Authors: Ali Saidi
387404SAli.Saidi@ARM.com */
397404SAli.Saidi@ARM.com
407404SAli.Saidi@ARM.com#ifndef __ARCH_ARM_TABLE_WALKER_HH__
417404SAli.Saidi@ARM.com#define __ARCH_ARM_TABLE_WALKER_HH__
427404SAli.Saidi@ARM.com
437578Sdam.sunwoo@arm.com#include <list>
447578Sdam.sunwoo@arm.com
457404SAli.Saidi@ARM.com#include "arch/arm/miscregs.hh"
467404SAli.Saidi@ARM.com#include "arch/arm/tlb.hh"
479016Sandreas.hansson@arm.com#include "dev/dma_device.hh"
487404SAli.Saidi@ARM.com#include "mem/mem_object.hh"
497404SAli.Saidi@ARM.com#include "mem/request.hh"
507404SAli.Saidi@ARM.com#include "params/ArmTableWalker.hh"
517404SAli.Saidi@ARM.com#include "sim/eventq.hh"
527878Sgblack@eecs.umich.edu#include "sim/fault_fwd.hh"
537404SAli.Saidi@ARM.com
547404SAli.Saidi@ARM.comclass ThreadContext;
557404SAli.Saidi@ARM.com
567404SAli.Saidi@ARM.comnamespace ArmISA {
577404SAli.Saidi@ARM.comclass Translation;
587404SAli.Saidi@ARM.comclass TLB;
597404SAli.Saidi@ARM.com
607404SAli.Saidi@ARM.comclass TableWalker : public MemObject
617404SAli.Saidi@ARM.com{
627694SAli.Saidi@ARM.com  public:
637404SAli.Saidi@ARM.com    struct L1Descriptor {
647404SAli.Saidi@ARM.com        /** Type of page table entry ARM DDI 0406B: B3-8*/
657404SAli.Saidi@ARM.com        enum EntryType {
667404SAli.Saidi@ARM.com            Ignore,
677404SAli.Saidi@ARM.com            PageTable,
687404SAli.Saidi@ARM.com            Section,
697404SAli.Saidi@ARM.com            Reserved
707404SAli.Saidi@ARM.com        };
717404SAli.Saidi@ARM.com
727436Sdam.sunwoo@arm.com        /** The raw bits of the entry */
737404SAli.Saidi@ARM.com        uint32_t data;
747404SAli.Saidi@ARM.com
757436Sdam.sunwoo@arm.com        /** This entry has been modified (access flag set) and needs to be
767436Sdam.sunwoo@arm.com         * written back to memory */
777436Sdam.sunwoo@arm.com        bool _dirty;
787436Sdam.sunwoo@arm.com
797404SAli.Saidi@ARM.com        EntryType type() const
807404SAli.Saidi@ARM.com        {
817404SAli.Saidi@ARM.com            return (EntryType)(data & 0x3);
827404SAli.Saidi@ARM.com        }
837404SAli.Saidi@ARM.com
847404SAli.Saidi@ARM.com        /** Is the page a Supersection (16MB)?*/
857404SAli.Saidi@ARM.com        bool supersection() const
867404SAli.Saidi@ARM.com        {
877404SAli.Saidi@ARM.com            return bits(data, 18);
887404SAli.Saidi@ARM.com        }
897404SAli.Saidi@ARM.com
907404SAli.Saidi@ARM.com        /** Return the physcal address of the entry, bits in position*/
917404SAli.Saidi@ARM.com        Addr paddr() const
927404SAli.Saidi@ARM.com        {
937404SAli.Saidi@ARM.com            if (supersection())
947404SAli.Saidi@ARM.com                panic("Super sections not implemented\n");
957946SGiacomo.Gabrielli@arm.com            return mbits(data, 31, 20);
967404SAli.Saidi@ARM.com        }
977694SAli.Saidi@ARM.com        /** Return the physcal address of the entry, bits in position*/
987694SAli.Saidi@ARM.com        Addr paddr(Addr va) const
997694SAli.Saidi@ARM.com        {
1007694SAli.Saidi@ARM.com            if (supersection())
1017694SAli.Saidi@ARM.com                panic("Super sections not implemented\n");
1027946SGiacomo.Gabrielli@arm.com            return mbits(data, 31, 20) | mbits(va, 19, 0);
1037694SAli.Saidi@ARM.com        }
1047694SAli.Saidi@ARM.com
1057404SAli.Saidi@ARM.com
1067404SAli.Saidi@ARM.com        /** Return the physical frame, bits shifted right */
1077404SAli.Saidi@ARM.com        Addr pfn() const
1087404SAli.Saidi@ARM.com        {
1097404SAli.Saidi@ARM.com            if (supersection())
1107404SAli.Saidi@ARM.com                panic("Super sections not implemented\n");
1117946SGiacomo.Gabrielli@arm.com            return bits(data, 31, 20);
1127404SAli.Saidi@ARM.com        }
1137404SAli.Saidi@ARM.com
1147404SAli.Saidi@ARM.com        /** Is the translation global (no asid used)? */
1157404SAli.Saidi@ARM.com        bool global() const
1167404SAli.Saidi@ARM.com        {
1177608SGene.Wu@arm.com            return bits(data, 17);
1187404SAli.Saidi@ARM.com        }
1197404SAli.Saidi@ARM.com
1207404SAli.Saidi@ARM.com        /** Is the translation not allow execution? */
1217404SAli.Saidi@ARM.com        bool xn() const
1227404SAli.Saidi@ARM.com        {
1237608SGene.Wu@arm.com            return bits(data, 4);
1247404SAli.Saidi@ARM.com        }
1257404SAli.Saidi@ARM.com
1267404SAli.Saidi@ARM.com        /** Three bit access protection flags */
1277404SAli.Saidi@ARM.com        uint8_t ap() const
1287404SAli.Saidi@ARM.com        {
1297946SGiacomo.Gabrielli@arm.com            return (bits(data, 15) << 2) | bits(data, 11, 10);
1307404SAli.Saidi@ARM.com        }
1317404SAli.Saidi@ARM.com
1327404SAli.Saidi@ARM.com        /** Domain Client/Manager: ARM DDI 0406B: B3-31 */
1337404SAli.Saidi@ARM.com        uint8_t domain() const
1347404SAli.Saidi@ARM.com        {
1357946SGiacomo.Gabrielli@arm.com            return bits(data, 8, 5);
1367404SAli.Saidi@ARM.com        }
1377404SAli.Saidi@ARM.com
1387404SAli.Saidi@ARM.com        /** Address of L2 descriptor if it exists */
1397404SAli.Saidi@ARM.com        Addr l2Addr() const
1407404SAli.Saidi@ARM.com        {
1417946SGiacomo.Gabrielli@arm.com            return mbits(data, 31, 10);
1427404SAli.Saidi@ARM.com        }
1437404SAli.Saidi@ARM.com
1447436Sdam.sunwoo@arm.com        /** Memory region attributes: ARM DDI 0406B: B3-32.
1457436Sdam.sunwoo@arm.com         * These bits are largly ignored by M5 and only used to
1467436Sdam.sunwoo@arm.com         * provide the illusion that the memory system cares about
1477436Sdam.sunwoo@arm.com         * anything but cachable vs. uncachable.
1487436Sdam.sunwoo@arm.com         */
1497404SAli.Saidi@ARM.com        uint8_t texcb() const
1507404SAli.Saidi@ARM.com        {
1517946SGiacomo.Gabrielli@arm.com            return bits(data, 2) | bits(data, 3) << 1 | bits(data, 14, 12) << 2;
1527404SAli.Saidi@ARM.com        }
1537404SAli.Saidi@ARM.com
1547436Sdam.sunwoo@arm.com        /** If the section is shareable. See texcb() comment. */
1557436Sdam.sunwoo@arm.com        bool shareable() const
1567436Sdam.sunwoo@arm.com        {
1577436Sdam.sunwoo@arm.com            return bits(data, 16);
1587436Sdam.sunwoo@arm.com        }
1597436Sdam.sunwoo@arm.com
1607436Sdam.sunwoo@arm.com        /** Set access flag that this entry has been touched. Mark
1617436Sdam.sunwoo@arm.com         * the entry as requiring a writeback, in the future.
1627436Sdam.sunwoo@arm.com         */
1637436Sdam.sunwoo@arm.com        void setAp0()
1647436Sdam.sunwoo@arm.com        {
1657436Sdam.sunwoo@arm.com            data |= 1 << 10;
1667436Sdam.sunwoo@arm.com            _dirty = true;
1677436Sdam.sunwoo@arm.com        }
1687436Sdam.sunwoo@arm.com
1697436Sdam.sunwoo@arm.com        /** This entry needs to be written back to memory */
1707436Sdam.sunwoo@arm.com        bool dirty() const
1717436Sdam.sunwoo@arm.com        {
1727436Sdam.sunwoo@arm.com            return _dirty;
1737436Sdam.sunwoo@arm.com        }
1747404SAli.Saidi@ARM.com    };
1757404SAli.Saidi@ARM.com
1767404SAli.Saidi@ARM.com    /** Level 2 page table descriptor */
1777404SAli.Saidi@ARM.com    struct L2Descriptor {
1787404SAli.Saidi@ARM.com
1797436Sdam.sunwoo@arm.com        /** The raw bits of the entry. */
1807404SAli.Saidi@ARM.com        uint32_t data;
1817404SAli.Saidi@ARM.com
1827436Sdam.sunwoo@arm.com        /** This entry has been modified (access flag set) and needs to be
1837436Sdam.sunwoo@arm.com         * written back to memory */
1847436Sdam.sunwoo@arm.com        bool _dirty;
1857436Sdam.sunwoo@arm.com
1867404SAli.Saidi@ARM.com        /** Is the entry invalid */
1877404SAli.Saidi@ARM.com        bool invalid() const
1887404SAli.Saidi@ARM.com        {
1897946SGiacomo.Gabrielli@arm.com            return bits(data, 1, 0) == 0;
1907404SAli.Saidi@ARM.com        }
1917404SAli.Saidi@ARM.com
1927404SAli.Saidi@ARM.com        /** What is the size of the mapping? */
1937404SAli.Saidi@ARM.com        bool large() const
1947404SAli.Saidi@ARM.com        {
1957404SAli.Saidi@ARM.com            return bits(data, 1) == 0;
1967404SAli.Saidi@ARM.com        }
1977404SAli.Saidi@ARM.com
1987404SAli.Saidi@ARM.com        /** Is execution allowed on this mapping? */
1997404SAli.Saidi@ARM.com        bool xn() const
2007404SAli.Saidi@ARM.com        {
2017404SAli.Saidi@ARM.com            return large() ? bits(data, 15) : bits(data, 0);
2027404SAli.Saidi@ARM.com        }
2037404SAli.Saidi@ARM.com
2047404SAli.Saidi@ARM.com        /** Is the translation global (no asid used)? */
2057404SAli.Saidi@ARM.com        bool global() const
2067404SAli.Saidi@ARM.com        {
2077404SAli.Saidi@ARM.com            return !bits(data, 11);
2087404SAli.Saidi@ARM.com        }
2097404SAli.Saidi@ARM.com
2107404SAli.Saidi@ARM.com        /** Three bit access protection flags */
2117404SAli.Saidi@ARM.com        uint8_t ap() const
2127404SAli.Saidi@ARM.com        {
2137404SAli.Saidi@ARM.com           return bits(data, 5, 4) | (bits(data, 9) << 2);
2147404SAli.Saidi@ARM.com        }
2157404SAli.Saidi@ARM.com
2167404SAli.Saidi@ARM.com        /** Memory region attributes: ARM DDI 0406B: B3-32 */
2177404SAli.Saidi@ARM.com        uint8_t texcb() const
2187404SAli.Saidi@ARM.com        {
2197404SAli.Saidi@ARM.com            return large() ?
2207946SGiacomo.Gabrielli@arm.com                (bits(data, 2) | (bits(data, 3) << 1) | (bits(data, 14, 12) << 2)) :
2217946SGiacomo.Gabrielli@arm.com                (bits(data, 2) | (bits(data, 3) << 1) | (bits(data, 8, 6) << 2));
2227404SAli.Saidi@ARM.com        }
2237404SAli.Saidi@ARM.com
2247404SAli.Saidi@ARM.com        /** Return the physical frame, bits shifted right */
2257404SAli.Saidi@ARM.com        Addr pfn() const
2267404SAli.Saidi@ARM.com        {
2277404SAli.Saidi@ARM.com            return large() ? bits(data, 31, 16) : bits(data, 31, 12);
2287404SAli.Saidi@ARM.com        }
2297404SAli.Saidi@ARM.com
2307694SAli.Saidi@ARM.com        /** Return complete physical address given a VA */
2317694SAli.Saidi@ARM.com        Addr paddr(Addr va) const
2327694SAli.Saidi@ARM.com        {
2337694SAli.Saidi@ARM.com            if (large())
2347694SAli.Saidi@ARM.com                return mbits(data, 31, 16) | mbits(va, 15, 0);
2357694SAli.Saidi@ARM.com            else
2367694SAli.Saidi@ARM.com                return mbits(data, 31, 12) | mbits(va, 11, 0);
2377694SAli.Saidi@ARM.com        }
2387694SAli.Saidi@ARM.com
2397436Sdam.sunwoo@arm.com        /** If the section is shareable. See texcb() comment. */
2407436Sdam.sunwoo@arm.com        bool shareable() const
2417436Sdam.sunwoo@arm.com        {
2427436Sdam.sunwoo@arm.com            return bits(data, 10);
2437436Sdam.sunwoo@arm.com        }
2447436Sdam.sunwoo@arm.com
2457436Sdam.sunwoo@arm.com        /** Set access flag that this entry has been touched. Mark
2467436Sdam.sunwoo@arm.com         * the entry as requiring a writeback, in the future.
2477436Sdam.sunwoo@arm.com         */
2487436Sdam.sunwoo@arm.com        void setAp0()
2497436Sdam.sunwoo@arm.com        {
2507436Sdam.sunwoo@arm.com            data |= 1 << 4;
2517436Sdam.sunwoo@arm.com            _dirty = true;
2527436Sdam.sunwoo@arm.com        }
2537436Sdam.sunwoo@arm.com
2547436Sdam.sunwoo@arm.com        /** This entry needs to be written back to memory */
2557436Sdam.sunwoo@arm.com        bool dirty() const
2567436Sdam.sunwoo@arm.com        {
2577436Sdam.sunwoo@arm.com            return _dirty;
2587436Sdam.sunwoo@arm.com        }
2597436Sdam.sunwoo@arm.com
2607404SAli.Saidi@ARM.com    };
2617404SAli.Saidi@ARM.com
2629015Sandreas.hansson@arm.com  protected:
2639015Sandreas.hansson@arm.com
2649015Sandreas.hansson@arm.com    /**
2659015Sandreas.hansson@arm.com     * A snooping DMA port that currently does nothing besides
2669015Sandreas.hansson@arm.com     * extending the DMA port to accept snoops without complaining.
2679015Sandreas.hansson@arm.com     */
2689015Sandreas.hansson@arm.com    class SnoopingDmaPort : public DmaPort
2699015Sandreas.hansson@arm.com    {
2709015Sandreas.hansson@arm.com
2719015Sandreas.hansson@arm.com      protected:
2729015Sandreas.hansson@arm.com
2739015Sandreas.hansson@arm.com        virtual void recvTimingSnoopReq(PacketPtr pkt)
2749015Sandreas.hansson@arm.com        { }
2759015Sandreas.hansson@arm.com
2769015Sandreas.hansson@arm.com        virtual Tick recvAtomicSnoop(PacketPtr pkt)
2779015Sandreas.hansson@arm.com        { return 0; }
2789015Sandreas.hansson@arm.com
2799015Sandreas.hansson@arm.com        virtual void recvFunctionalSnoop(PacketPtr pkt)
2809015Sandreas.hansson@arm.com        { }
2819015Sandreas.hansson@arm.com
2829015Sandreas.hansson@arm.com        virtual bool isSnooping() const { return true; }
2839015Sandreas.hansson@arm.com
2849015Sandreas.hansson@arm.com      public:
2859015Sandreas.hansson@arm.com
2869015Sandreas.hansson@arm.com        /**
2879015Sandreas.hansson@arm.com         * A snooping DMA port merely calls the construtor of the DMA
2889015Sandreas.hansson@arm.com         * port.
2899015Sandreas.hansson@arm.com         */
2909165Sandreas.hansson@arm.com        SnoopingDmaPort(MemObject *dev, System *s) :
2919165Sandreas.hansson@arm.com            DmaPort(dev, s)
2929015Sandreas.hansson@arm.com        { }
2939015Sandreas.hansson@arm.com    };
2949015Sandreas.hansson@arm.com
2957439Sdam.sunwoo@arm.com    struct WalkerState //: public SimObject
2967439Sdam.sunwoo@arm.com    {
2977439Sdam.sunwoo@arm.com        /** Thread context that we're doing the walk for */
2987439Sdam.sunwoo@arm.com        ThreadContext *tc;
2997439Sdam.sunwoo@arm.com
3007439Sdam.sunwoo@arm.com        /** Request that is currently being serviced */
3017439Sdam.sunwoo@arm.com        RequestPtr req;
3027439Sdam.sunwoo@arm.com
3037439Sdam.sunwoo@arm.com        /** Context ID that we're servicing the request under */
3047439Sdam.sunwoo@arm.com        uint8_t contextId;
3057439Sdam.sunwoo@arm.com
3067439Sdam.sunwoo@arm.com        /** Translation state for delayed requests */
3077439Sdam.sunwoo@arm.com        TLB::Translation *transState;
3087439Sdam.sunwoo@arm.com
3097439Sdam.sunwoo@arm.com        /** The fault that we are going to return */
3107439Sdam.sunwoo@arm.com        Fault fault;
3117439Sdam.sunwoo@arm.com
3127439Sdam.sunwoo@arm.com        /** The virtual address that is being translated */
3137439Sdam.sunwoo@arm.com        Addr vaddr;
3147439Sdam.sunwoo@arm.com
3157439Sdam.sunwoo@arm.com        /** Cached copy of the sctlr as it existed when translation began */
3167439Sdam.sunwoo@arm.com        SCTLR sctlr;
3177439Sdam.sunwoo@arm.com
3187439Sdam.sunwoo@arm.com        /** Width of the base address held in TTRB0 */
3197439Sdam.sunwoo@arm.com        uint32_t N;
3207439Sdam.sunwoo@arm.com
3217439Sdam.sunwoo@arm.com        /** If the access is a write */
3227439Sdam.sunwoo@arm.com        bool isWrite;
3237439Sdam.sunwoo@arm.com
3247439Sdam.sunwoo@arm.com        /** If the access is a fetch (for execution, and no-exec) must be checked?*/
3257439Sdam.sunwoo@arm.com        bool isFetch;
3267439Sdam.sunwoo@arm.com
3277439Sdam.sunwoo@arm.com        /** If the mode is timing or atomic */
3287439Sdam.sunwoo@arm.com        bool timing;
3297439Sdam.sunwoo@arm.com
3308733Sgeoffrey.blake@arm.com        /** If the atomic mode should be functional */
3318733Sgeoffrey.blake@arm.com        bool functional;
3328733Sgeoffrey.blake@arm.com
3337439Sdam.sunwoo@arm.com        /** Save mode for use in delayed response */
3347439Sdam.sunwoo@arm.com        BaseTLB::Mode mode;
3357439Sdam.sunwoo@arm.com
3367439Sdam.sunwoo@arm.com        L1Descriptor l1Desc;
3377439Sdam.sunwoo@arm.com        L2Descriptor l2Desc;
3387439Sdam.sunwoo@arm.com
3397439Sdam.sunwoo@arm.com        /** Whether L1/L2 descriptor response is delayed in timing mode */
3407439Sdam.sunwoo@arm.com        bool delayed;
3417439Sdam.sunwoo@arm.com
3427439Sdam.sunwoo@arm.com        TableWalker *tableWalker;
3437439Sdam.sunwoo@arm.com
3447439Sdam.sunwoo@arm.com        void doL1Descriptor();
3457439Sdam.sunwoo@arm.com        void doL2Descriptor();
3467439Sdam.sunwoo@arm.com
3477439Sdam.sunwoo@arm.com        std::string name() const {return tableWalker->name();}
3487439Sdam.sunwoo@arm.com    };
3497439Sdam.sunwoo@arm.com
3507439Sdam.sunwoo@arm.com
3517653Sgene.wu@arm.com    /** Queue of requests that need processing first level translation */
3527653Sgene.wu@arm.com    std::list<WalkerState *> stateQueueL1;
3537653Sgene.wu@arm.com
3547653Sgene.wu@arm.com    /** Queue of requests that have passed first level translation and
3557653Sgene.wu@arm.com     * require an additional level. */
3567653Sgene.wu@arm.com    std::list<WalkerState *> stateQueueL2;
3577439Sdam.sunwoo@arm.com
3587728SAli.Saidi@ARM.com    /** Queue of requests that have passed are waiting because the walker is
3597728SAli.Saidi@ARM.com     * currently busy. */
3608902Sandreas.hansson@arm.com    std::list<WalkerState *> pendingQueue;
3617728SAli.Saidi@ARM.com
3627728SAli.Saidi@ARM.com
3637404SAli.Saidi@ARM.com    /** Port to issue translation requests from */
3649015Sandreas.hansson@arm.com    SnoopingDmaPort port;
3657404SAli.Saidi@ARM.com
3669152Satgutier@umich.edu    /** If we're draining keep the drain event around until we're drained */
3679152Satgutier@umich.edu    Event *drainEvent;
3689152Satgutier@umich.edu
3697404SAli.Saidi@ARM.com    /** TLB that is initiating these table walks */
3707404SAli.Saidi@ARM.com    TLB *tlb;
3717404SAli.Saidi@ARM.com
3727404SAli.Saidi@ARM.com    /** Cached copy of the sctlr as it existed when translation began */
3737404SAli.Saidi@ARM.com    SCTLR sctlr;
3747404SAli.Saidi@ARM.com
3757439Sdam.sunwoo@arm.com    WalkerState *currState;
3767437Sdam.sunwoo@arm.com
3777728SAli.Saidi@ARM.com    /** If a timing translation is currently in progress */
3787728SAli.Saidi@ARM.com    bool pending;
3797728SAli.Saidi@ARM.com
3808832SAli.Saidi@ARM.com    /** Request id for requests generated by this walker */
3818832SAli.Saidi@ARM.com    MasterID masterId;
3828832SAli.Saidi@ARM.com
3839258SAli.Saidi@ARM.com    /** The number of walks belonging to squashed instructions that can be
3849258SAli.Saidi@ARM.com     * removed from the pendingQueue per cycle. */
3859258SAli.Saidi@ARM.com    unsigned numSquashable;
3869258SAli.Saidi@ARM.com
3877404SAli.Saidi@ARM.com  public:
3887404SAli.Saidi@ARM.com    typedef ArmTableWalkerParams Params;
3897404SAli.Saidi@ARM.com    TableWalker(const Params *p);
3907404SAli.Saidi@ARM.com    virtual ~TableWalker();
3917404SAli.Saidi@ARM.com
3927404SAli.Saidi@ARM.com    const Params *
3937404SAli.Saidi@ARM.com    params() const
3947404SAli.Saidi@ARM.com    {
3957404SAli.Saidi@ARM.com        return dynamic_cast<const Params *>(_params);
3967404SAli.Saidi@ARM.com    }
3977404SAli.Saidi@ARM.com
3989152Satgutier@umich.edu    /** Checks if all state is cleared and if so, completes drain */
3999152Satgutier@umich.edu    void completeDrain();
4007733SAli.Saidi@ARM.com    virtual unsigned int drain(Event *de);
4017748SAli.Saidi@ARM.com    virtual void resume();
4028922Swilliam.wang@arm.com    virtual MasterPort& getMasterPort(const std::string &if_name,
4038922Swilliam.wang@arm.com                                      int idx = -1);
4047404SAli.Saidi@ARM.com
4057404SAli.Saidi@ARM.com    Fault walk(RequestPtr req, ThreadContext *tc, uint8_t cid, TLB::Mode mode,
4068733Sgeoffrey.blake@arm.com            TLB::Translation *_trans, bool timing, bool functional = false);
4077404SAli.Saidi@ARM.com
4087404SAli.Saidi@ARM.com    void setTlb(TLB *_tlb) { tlb = _tlb; }
4097439Sdam.sunwoo@arm.com    void memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr,
4107439Sdam.sunwoo@arm.com                  uint8_t texcb, bool s);
4117404SAli.Saidi@ARM.com
4127404SAli.Saidi@ARM.com  private:
4137404SAli.Saidi@ARM.com
4147404SAli.Saidi@ARM.com    void doL1Descriptor();
4157437Sdam.sunwoo@arm.com    void doL1DescriptorWrapper();
4167437Sdam.sunwoo@arm.com    EventWrapper<TableWalker, &TableWalker::doL1DescriptorWrapper> doL1DescEvent;
4177404SAli.Saidi@ARM.com
4187404SAli.Saidi@ARM.com    void doL2Descriptor();
4197437Sdam.sunwoo@arm.com    void doL2DescriptorWrapper();
4207437Sdam.sunwoo@arm.com    EventWrapper<TableWalker, &TableWalker::doL2DescriptorWrapper> doL2DescEvent;
4217404SAli.Saidi@ARM.com
4227728SAli.Saidi@ARM.com    Fault processWalk();
4237728SAli.Saidi@ARM.com    void processWalkWrapper();
4247728SAli.Saidi@ARM.com    EventWrapper<TableWalker, &TableWalker::processWalkWrapper> doProcessEvent;
4257404SAli.Saidi@ARM.com
4267728SAli.Saidi@ARM.com    void nextWalk(ThreadContext *tc);
4277404SAli.Saidi@ARM.com};
4287404SAli.Saidi@ARM.com
4297404SAli.Saidi@ARM.com
4307404SAli.Saidi@ARM.com} // namespace ArmISA
4317404SAli.Saidi@ARM.com
4327404SAli.Saidi@ARM.com#endif //__ARCH_ARM_TABLE_WALKER_HH__
4337404SAli.Saidi@ARM.com
434