table_walker.hh revision 7437
17404SAli.Saidi@ARM.com/*
27404SAli.Saidi@ARM.com * Copyright (c) 2010 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
437404SAli.Saidi@ARM.com#include "arch/arm/miscregs.hh"
447404SAli.Saidi@ARM.com#include "arch/arm/tlb.hh"
457404SAli.Saidi@ARM.com#include "mem/mem_object.hh"
467404SAli.Saidi@ARM.com#include "mem/request.hh"
477404SAli.Saidi@ARM.com#include "mem/request.hh"
487404SAli.Saidi@ARM.com#include "params/ArmTableWalker.hh"
497404SAli.Saidi@ARM.com#include "sim/faults.hh"
507404SAli.Saidi@ARM.com#include "sim/eventq.hh"
517404SAli.Saidi@ARM.com
527404SAli.Saidi@ARM.comclass DmaPort;
537404SAli.Saidi@ARM.comclass ThreadContext;
547404SAli.Saidi@ARM.com
557404SAli.Saidi@ARM.comnamespace ArmISA {
567404SAli.Saidi@ARM.comclass Translation;
577404SAli.Saidi@ARM.comclass TLB;
587404SAli.Saidi@ARM.com
597404SAli.Saidi@ARM.comclass TableWalker : public MemObject
607404SAli.Saidi@ARM.com{
617404SAli.Saidi@ARM.com  protected:
627404SAli.Saidi@ARM.com    struct L1Descriptor {
637404SAli.Saidi@ARM.com        /** Type of page table entry ARM DDI 0406B: B3-8*/
647404SAli.Saidi@ARM.com        enum EntryType {
657404SAli.Saidi@ARM.com            Ignore,
667404SAli.Saidi@ARM.com            PageTable,
677404SAli.Saidi@ARM.com            Section,
687404SAli.Saidi@ARM.com            Reserved
697404SAli.Saidi@ARM.com        };
707404SAli.Saidi@ARM.com
717436Sdam.sunwoo@arm.com        /** The raw bits of the entry */
727404SAli.Saidi@ARM.com        uint32_t data;
737404SAli.Saidi@ARM.com
747436Sdam.sunwoo@arm.com        /** This entry has been modified (access flag set) and needs to be
757436Sdam.sunwoo@arm.com         * written back to memory */
767436Sdam.sunwoo@arm.com        bool _dirty;
777436Sdam.sunwoo@arm.com
787404SAli.Saidi@ARM.com        EntryType type() const
797404SAli.Saidi@ARM.com        {
807404SAli.Saidi@ARM.com            return (EntryType)(data & 0x3);
817404SAli.Saidi@ARM.com        }
827404SAli.Saidi@ARM.com
837404SAli.Saidi@ARM.com        /** Is the page a Supersection (16MB)?*/
847404SAli.Saidi@ARM.com        bool supersection() const
857404SAli.Saidi@ARM.com        {
867404SAli.Saidi@ARM.com            return bits(data, 18);
877404SAli.Saidi@ARM.com        }
887404SAli.Saidi@ARM.com
897404SAli.Saidi@ARM.com        /** Return the physcal address of the entry, bits in position*/
907404SAli.Saidi@ARM.com        Addr paddr() const
917404SAli.Saidi@ARM.com        {
927404SAli.Saidi@ARM.com            if (supersection())
937404SAli.Saidi@ARM.com                panic("Super sections not implemented\n");
947404SAli.Saidi@ARM.com            return mbits(data, 31,20);
957404SAli.Saidi@ARM.com        }
967404SAli.Saidi@ARM.com
977404SAli.Saidi@ARM.com        /** Return the physical frame, bits shifted right */
987404SAli.Saidi@ARM.com        Addr pfn() const
997404SAli.Saidi@ARM.com        {
1007404SAli.Saidi@ARM.com            if (supersection())
1017404SAli.Saidi@ARM.com                panic("Super sections not implemented\n");
1027404SAli.Saidi@ARM.com            return bits(data, 31,20);
1037404SAli.Saidi@ARM.com        }
1047404SAli.Saidi@ARM.com
1057404SAli.Saidi@ARM.com        /** Is the translation global (no asid used)? */
1067404SAli.Saidi@ARM.com        bool global() const
1077404SAli.Saidi@ARM.com        {
1087406SAli.Saidi@ARM.com            return bits(data, 4);
1097404SAli.Saidi@ARM.com        }
1107404SAli.Saidi@ARM.com
1117404SAli.Saidi@ARM.com        /** Is the translation not allow execution? */
1127404SAli.Saidi@ARM.com        bool xn() const
1137404SAli.Saidi@ARM.com        {
1147404SAli.Saidi@ARM.com            return bits(data, 17);
1157404SAli.Saidi@ARM.com        }
1167404SAli.Saidi@ARM.com
1177404SAli.Saidi@ARM.com        /** Three bit access protection flags */
1187404SAli.Saidi@ARM.com        uint8_t ap() const
1197404SAli.Saidi@ARM.com        {
1207404SAli.Saidi@ARM.com            return (bits(data, 15) << 2) | bits(data,11,10);
1217404SAli.Saidi@ARM.com        }
1227404SAli.Saidi@ARM.com
1237404SAli.Saidi@ARM.com        /** Domain Client/Manager: ARM DDI 0406B: B3-31 */
1247404SAli.Saidi@ARM.com        uint8_t domain() const
1257404SAli.Saidi@ARM.com        {
1267404SAli.Saidi@ARM.com            return bits(data,8,5);
1277404SAli.Saidi@ARM.com        }
1287404SAli.Saidi@ARM.com
1297404SAli.Saidi@ARM.com        /** Address of L2 descriptor if it exists */
1307404SAli.Saidi@ARM.com        Addr l2Addr() const
1317404SAli.Saidi@ARM.com        {
1327404SAli.Saidi@ARM.com            return mbits(data, 31,10);
1337404SAli.Saidi@ARM.com        }
1347404SAli.Saidi@ARM.com
1357436Sdam.sunwoo@arm.com        /** Memory region attributes: ARM DDI 0406B: B3-32.
1367436Sdam.sunwoo@arm.com         * These bits are largly ignored by M5 and only used to
1377436Sdam.sunwoo@arm.com         * provide the illusion that the memory system cares about
1387436Sdam.sunwoo@arm.com         * anything but cachable vs. uncachable.
1397436Sdam.sunwoo@arm.com         */
1407404SAli.Saidi@ARM.com        uint8_t texcb() const
1417404SAli.Saidi@ARM.com        {
1427406SAli.Saidi@ARM.com            return bits(data, 2) | bits(data,3) << 1 | bits(data, 14, 12) << 2;
1437404SAli.Saidi@ARM.com        }
1447404SAli.Saidi@ARM.com
1457436Sdam.sunwoo@arm.com        /** If the section is shareable. See texcb() comment. */
1467436Sdam.sunwoo@arm.com        bool shareable() const
1477436Sdam.sunwoo@arm.com        {
1487436Sdam.sunwoo@arm.com            return bits(data, 16);
1497436Sdam.sunwoo@arm.com        }
1507436Sdam.sunwoo@arm.com
1517436Sdam.sunwoo@arm.com        /** Set access flag that this entry has been touched. Mark
1527436Sdam.sunwoo@arm.com         * the entry as requiring a writeback, in the future.
1537436Sdam.sunwoo@arm.com         */
1547436Sdam.sunwoo@arm.com        void setAp0()
1557436Sdam.sunwoo@arm.com        {
1567436Sdam.sunwoo@arm.com            data |= 1 << 10;
1577436Sdam.sunwoo@arm.com            _dirty = true;
1587436Sdam.sunwoo@arm.com        }
1597436Sdam.sunwoo@arm.com
1607436Sdam.sunwoo@arm.com        /** This entry needs to be written back to memory */
1617436Sdam.sunwoo@arm.com        bool dirty() const
1627436Sdam.sunwoo@arm.com        {
1637436Sdam.sunwoo@arm.com            return _dirty;
1647436Sdam.sunwoo@arm.com        }
1657404SAli.Saidi@ARM.com    };
1667404SAli.Saidi@ARM.com
1677404SAli.Saidi@ARM.com    /** Level 2 page table descriptor */
1687404SAli.Saidi@ARM.com    struct L2Descriptor {
1697404SAli.Saidi@ARM.com
1707436Sdam.sunwoo@arm.com        /** The raw bits of the entry. */
1717404SAli.Saidi@ARM.com        uint32_t data;
1727404SAli.Saidi@ARM.com
1737436Sdam.sunwoo@arm.com        /** This entry has been modified (access flag set) and needs to be
1747436Sdam.sunwoo@arm.com         * written back to memory */
1757436Sdam.sunwoo@arm.com        bool _dirty;
1767436Sdam.sunwoo@arm.com
1777404SAli.Saidi@ARM.com        /** Is the entry invalid */
1787404SAli.Saidi@ARM.com        bool invalid() const
1797404SAli.Saidi@ARM.com        {
1807404SAli.Saidi@ARM.com            return bits(data, 1,0) == 0;;
1817404SAli.Saidi@ARM.com        }
1827404SAli.Saidi@ARM.com
1837404SAli.Saidi@ARM.com        /** What is the size of the mapping? */
1847404SAli.Saidi@ARM.com        bool large() const
1857404SAli.Saidi@ARM.com        {
1867404SAli.Saidi@ARM.com            return bits(data, 1) == 0;
1877404SAli.Saidi@ARM.com        }
1887404SAli.Saidi@ARM.com
1897404SAli.Saidi@ARM.com        /** Is execution allowed on this mapping? */
1907404SAli.Saidi@ARM.com        bool xn() const
1917404SAli.Saidi@ARM.com        {
1927404SAli.Saidi@ARM.com            return large() ? bits(data, 15) : bits(data, 0);
1937404SAli.Saidi@ARM.com        }
1947404SAli.Saidi@ARM.com
1957404SAli.Saidi@ARM.com        /** Is the translation global (no asid used)? */
1967404SAli.Saidi@ARM.com        bool global() const
1977404SAli.Saidi@ARM.com        {
1987404SAli.Saidi@ARM.com            return !bits(data, 11);
1997404SAli.Saidi@ARM.com        }
2007404SAli.Saidi@ARM.com
2017404SAli.Saidi@ARM.com        /** Three bit access protection flags */
2027404SAli.Saidi@ARM.com        uint8_t ap() const
2037404SAli.Saidi@ARM.com        {
2047404SAli.Saidi@ARM.com           return bits(data, 5, 4) | (bits(data, 9) << 2);
2057404SAli.Saidi@ARM.com        }
2067404SAli.Saidi@ARM.com
2077404SAli.Saidi@ARM.com        /** Memory region attributes: ARM DDI 0406B: B3-32 */
2087404SAli.Saidi@ARM.com        uint8_t texcb() const
2097404SAli.Saidi@ARM.com        {
2107404SAli.Saidi@ARM.com            return large() ?
2117406SAli.Saidi@ARM.com                (bits(data, 2) | (bits(data,3) << 1) | (bits(data, 14, 12) << 2)) :
2127406SAli.Saidi@ARM.com                (bits(data, 2) | (bits(data,3) << 1) | (bits(data, 8, 6) << 2));
2137404SAli.Saidi@ARM.com        }
2147404SAli.Saidi@ARM.com
2157404SAli.Saidi@ARM.com        /** Return the physical frame, bits shifted right */
2167404SAli.Saidi@ARM.com        Addr pfn() const
2177404SAli.Saidi@ARM.com        {
2187404SAli.Saidi@ARM.com            return large() ? bits(data, 31, 16) : bits(data, 31, 12);
2197404SAli.Saidi@ARM.com        }
2207404SAli.Saidi@ARM.com
2217436Sdam.sunwoo@arm.com        /** If the section is shareable. See texcb() comment. */
2227436Sdam.sunwoo@arm.com        bool shareable() const
2237436Sdam.sunwoo@arm.com        {
2247436Sdam.sunwoo@arm.com            return bits(data, 10);
2257436Sdam.sunwoo@arm.com        }
2267436Sdam.sunwoo@arm.com
2277436Sdam.sunwoo@arm.com        /** Set access flag that this entry has been touched. Mark
2287436Sdam.sunwoo@arm.com         * the entry as requiring a writeback, in the future.
2297436Sdam.sunwoo@arm.com         */
2307436Sdam.sunwoo@arm.com        void setAp0()
2317436Sdam.sunwoo@arm.com        {
2327436Sdam.sunwoo@arm.com            data |= 1 << 4;
2337436Sdam.sunwoo@arm.com            _dirty = true;
2347436Sdam.sunwoo@arm.com        }
2357436Sdam.sunwoo@arm.com
2367436Sdam.sunwoo@arm.com        /** This entry needs to be written back to memory */
2377436Sdam.sunwoo@arm.com        bool dirty() const
2387436Sdam.sunwoo@arm.com        {
2397436Sdam.sunwoo@arm.com            return _dirty;
2407436Sdam.sunwoo@arm.com        }
2417436Sdam.sunwoo@arm.com
2427404SAli.Saidi@ARM.com    };
2437404SAli.Saidi@ARM.com
2447404SAli.Saidi@ARM.com    /** Port to issue translation requests from */
2457404SAli.Saidi@ARM.com    DmaPort *port;
2467404SAli.Saidi@ARM.com
2477404SAli.Saidi@ARM.com    /** TLB that is initiating these table walks */
2487404SAli.Saidi@ARM.com    TLB *tlb;
2497404SAli.Saidi@ARM.com
2507404SAli.Saidi@ARM.com    /** Thread context that we're doing the walk for */
2517404SAli.Saidi@ARM.com    ThreadContext *tc;
2527404SAli.Saidi@ARM.com
2537404SAli.Saidi@ARM.com    /** Request that is currently being serviced */
2547404SAli.Saidi@ARM.com    RequestPtr req;
2557404SAli.Saidi@ARM.com
2567404SAli.Saidi@ARM.com    /** Context ID that we're servicing the request under */
2577404SAli.Saidi@ARM.com    uint8_t contextId;
2587404SAli.Saidi@ARM.com
2597404SAli.Saidi@ARM.com    /** Translation state for delayed requests */
2607404SAli.Saidi@ARM.com    TLB::Translation *transState;
2617404SAli.Saidi@ARM.com
2627404SAli.Saidi@ARM.com    /** The fault that we are going to return */
2637404SAli.Saidi@ARM.com    Fault fault;
2647404SAli.Saidi@ARM.com
2657404SAli.Saidi@ARM.com    /** The virtual address that is being translated */
2667404SAli.Saidi@ARM.com    Addr vaddr;
2677404SAli.Saidi@ARM.com
2687404SAli.Saidi@ARM.com    /** Cached copy of the sctlr as it existed when translation began */
2697404SAli.Saidi@ARM.com    SCTLR sctlr;
2707404SAli.Saidi@ARM.com
2717404SAli.Saidi@ARM.com    /** Cached copy of the cpsr as it existed when the translation began */
2727404SAli.Saidi@ARM.com    CPSR cpsr;
2737404SAli.Saidi@ARM.com
2747404SAli.Saidi@ARM.com    /** Width of the base address held in TTRB0 */
2757404SAli.Saidi@ARM.com    uint32_t N;
2767404SAli.Saidi@ARM.com
2777404SAli.Saidi@ARM.com    /** If the access is a write */
2787404SAli.Saidi@ARM.com    bool isWrite;
2797404SAli.Saidi@ARM.com
2807404SAli.Saidi@ARM.com    /** If the access is not from user mode */
2817404SAli.Saidi@ARM.com    bool isPriv;
2827404SAli.Saidi@ARM.com
2837404SAli.Saidi@ARM.com    /** If the access is a fetch (for execution, and no-exec) must be checked?*/
2847404SAli.Saidi@ARM.com    bool isFetch;
2857404SAli.Saidi@ARM.com
2867404SAli.Saidi@ARM.com    /** If the mode is timing or atomic */
2877404SAli.Saidi@ARM.com    bool timing;
2887404SAli.Saidi@ARM.com
2897404SAli.Saidi@ARM.com    L1Descriptor l1Desc;
2907404SAli.Saidi@ARM.com    L2Descriptor l2Desc;
2917404SAli.Saidi@ARM.com
2927437Sdam.sunwoo@arm.com    /** Save mode for use in delayed response */
2937437Sdam.sunwoo@arm.com    BaseTLB::Mode mode;
2947437Sdam.sunwoo@arm.com
2957437Sdam.sunwoo@arm.com    /** Whether L1/L2 descriptor response is delayed in timing mode */
2967437Sdam.sunwoo@arm.com    bool delayed;
2977437Sdam.sunwoo@arm.com
2987404SAli.Saidi@ARM.com  public:
2997404SAli.Saidi@ARM.com    typedef ArmTableWalkerParams Params;
3007404SAli.Saidi@ARM.com    TableWalker(const Params *p);
3017404SAli.Saidi@ARM.com    virtual ~TableWalker();
3027404SAli.Saidi@ARM.com
3037404SAli.Saidi@ARM.com    const Params *
3047404SAli.Saidi@ARM.com    params() const
3057404SAli.Saidi@ARM.com    {
3067404SAli.Saidi@ARM.com        return dynamic_cast<const Params *>(_params);
3077404SAli.Saidi@ARM.com    }
3087404SAli.Saidi@ARM.com
3097404SAli.Saidi@ARM.com    virtual unsigned int drain(Event *de) { panic("write me\n"); }
3107404SAli.Saidi@ARM.com    virtual Port *getPort(const std::string &if_name, int idx = -1);
3117404SAli.Saidi@ARM.com
3127404SAli.Saidi@ARM.com    Fault walk(RequestPtr req, ThreadContext *tc, uint8_t cid, TLB::Mode mode,
3137404SAli.Saidi@ARM.com            TLB::Translation *_trans, bool timing);
3147404SAli.Saidi@ARM.com
3157404SAli.Saidi@ARM.com    void setTlb(TLB *_tlb) { tlb = _tlb; }
3167436Sdam.sunwoo@arm.com    void memAttrs(TlbEntry &te, uint8_t texcb, bool s);
3177404SAli.Saidi@ARM.com
3187404SAli.Saidi@ARM.com  private:
3197404SAli.Saidi@ARM.com
3207404SAli.Saidi@ARM.com    void doL1Descriptor();
3217437Sdam.sunwoo@arm.com    void doL1DescriptorWrapper();
3227437Sdam.sunwoo@arm.com    EventWrapper<TableWalker, &TableWalker::doL1DescriptorWrapper> doL1DescEvent;
3237404SAli.Saidi@ARM.com
3247404SAli.Saidi@ARM.com    void doL2Descriptor();
3257437Sdam.sunwoo@arm.com    void doL2DescriptorWrapper();
3267437Sdam.sunwoo@arm.com    EventWrapper<TableWalker, &TableWalker::doL2DescriptorWrapper> doL2DescEvent;
3277404SAli.Saidi@ARM.com
3287404SAli.Saidi@ARM.com
3297404SAli.Saidi@ARM.com};
3307404SAli.Saidi@ARM.com
3317404SAli.Saidi@ARM.com
3327404SAli.Saidi@ARM.com} // namespace ArmISA
3337404SAli.Saidi@ARM.com
3347404SAli.Saidi@ARM.com#endif //__ARCH_ARM_TABLE_WALKER_HH__
3357404SAli.Saidi@ARM.com
336