table_walker.hh revision 7404
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
717404SAli.Saidi@ARM.com        uint32_t data;
727404SAli.Saidi@ARM.com
737404SAli.Saidi@ARM.com        EntryType type() const
747404SAli.Saidi@ARM.com        {
757404SAli.Saidi@ARM.com            return (EntryType)(data & 0x3);
767404SAli.Saidi@ARM.com        }
777404SAli.Saidi@ARM.com
787404SAli.Saidi@ARM.com        /** Is the page a Supersection (16MB)?*/
797404SAli.Saidi@ARM.com        bool supersection() const
807404SAli.Saidi@ARM.com        {
817404SAli.Saidi@ARM.com            return bits(data, 18);
827404SAli.Saidi@ARM.com        }
837404SAli.Saidi@ARM.com
847404SAli.Saidi@ARM.com        /** Return the physcal address of the entry, bits in position*/
857404SAli.Saidi@ARM.com        Addr paddr() const
867404SAli.Saidi@ARM.com        {
877404SAli.Saidi@ARM.com            if (supersection())
887404SAli.Saidi@ARM.com                panic("Super sections not implemented\n");
897404SAli.Saidi@ARM.com            return mbits(data, 31,20);
907404SAli.Saidi@ARM.com        }
917404SAli.Saidi@ARM.com
927404SAli.Saidi@ARM.com        /** Return the physical frame, bits shifted right */
937404SAli.Saidi@ARM.com        Addr pfn() const
947404SAli.Saidi@ARM.com        {
957404SAli.Saidi@ARM.com            if (supersection())
967404SAli.Saidi@ARM.com                panic("Super sections not implemented\n");
977404SAli.Saidi@ARM.com            return bits(data, 31,20);
987404SAli.Saidi@ARM.com        }
997404SAli.Saidi@ARM.com
1007404SAli.Saidi@ARM.com        /** Is the translation global (no asid used)? */
1017404SAli.Saidi@ARM.com        bool global() const
1027404SAli.Saidi@ARM.com        {
1037404SAli.Saidi@ARM.com            return bits(data, 17);
1047404SAli.Saidi@ARM.com        }
1057404SAli.Saidi@ARM.com
1067404SAli.Saidi@ARM.com        /** Is the translation not allow execution? */
1077404SAli.Saidi@ARM.com        bool xn() const
1087404SAli.Saidi@ARM.com        {
1097404SAli.Saidi@ARM.com            return bits(data, 17);
1107404SAli.Saidi@ARM.com        }
1117404SAli.Saidi@ARM.com
1127404SAli.Saidi@ARM.com        /** Three bit access protection flags */
1137404SAli.Saidi@ARM.com        uint8_t ap() const
1147404SAli.Saidi@ARM.com        {
1157404SAli.Saidi@ARM.com            return (bits(data, 15) << 2) | bits(data,11,10);
1167404SAli.Saidi@ARM.com        }
1177404SAli.Saidi@ARM.com
1187404SAli.Saidi@ARM.com        /** Domain Client/Manager: ARM DDI 0406B: B3-31 */
1197404SAli.Saidi@ARM.com        uint8_t domain() const
1207404SAli.Saidi@ARM.com        {
1217404SAli.Saidi@ARM.com            return bits(data,8,5);
1227404SAli.Saidi@ARM.com        }
1237404SAli.Saidi@ARM.com
1247404SAli.Saidi@ARM.com        /** Address of L2 descriptor if it exists */
1257404SAli.Saidi@ARM.com        Addr l2Addr() const
1267404SAli.Saidi@ARM.com        {
1277404SAli.Saidi@ARM.com            return mbits(data, 31,10);
1287404SAli.Saidi@ARM.com        }
1297404SAli.Saidi@ARM.com
1307404SAli.Saidi@ARM.com        /** Memory region attributes: ARM DDI 0406B: B3-32 */
1317404SAli.Saidi@ARM.com        uint8_t texcb() const
1327404SAli.Saidi@ARM.com        {
1337404SAli.Saidi@ARM.com            return bits(data, 2) | bits(data,3) << 1 | bits(data, 12, 14) << 2;
1347404SAli.Saidi@ARM.com        }
1357404SAli.Saidi@ARM.com
1367404SAli.Saidi@ARM.com    };
1377404SAli.Saidi@ARM.com
1387404SAli.Saidi@ARM.com    /** Level 2 page table descriptor */
1397404SAli.Saidi@ARM.com    struct L2Descriptor {
1407404SAli.Saidi@ARM.com
1417404SAli.Saidi@ARM.com        uint32_t data;
1427404SAli.Saidi@ARM.com
1437404SAli.Saidi@ARM.com        /** Is the entry invalid */
1447404SAli.Saidi@ARM.com        bool invalid() const
1457404SAli.Saidi@ARM.com        {
1467404SAli.Saidi@ARM.com            return bits(data, 1,0) == 0;;
1477404SAli.Saidi@ARM.com        }
1487404SAli.Saidi@ARM.com
1497404SAli.Saidi@ARM.com        /** What is the size of the mapping? */
1507404SAli.Saidi@ARM.com        bool large() const
1517404SAli.Saidi@ARM.com        {
1527404SAli.Saidi@ARM.com            return bits(data, 1) == 0;
1537404SAli.Saidi@ARM.com        }
1547404SAli.Saidi@ARM.com
1557404SAli.Saidi@ARM.com        /** Is execution allowed on this mapping? */
1567404SAli.Saidi@ARM.com        bool xn() const
1577404SAli.Saidi@ARM.com        {
1587404SAli.Saidi@ARM.com            return large() ? bits(data, 15) : bits(data, 0);
1597404SAli.Saidi@ARM.com        }
1607404SAli.Saidi@ARM.com
1617404SAli.Saidi@ARM.com        /** Is the translation global (no asid used)? */
1627404SAli.Saidi@ARM.com        bool global() const
1637404SAli.Saidi@ARM.com        {
1647404SAli.Saidi@ARM.com            return !bits(data, 11);
1657404SAli.Saidi@ARM.com        }
1667404SAli.Saidi@ARM.com
1677404SAli.Saidi@ARM.com        /** Three bit access protection flags */
1687404SAli.Saidi@ARM.com        uint8_t ap() const
1697404SAli.Saidi@ARM.com        {
1707404SAli.Saidi@ARM.com           return bits(data, 5, 4) | (bits(data, 9) << 2);
1717404SAli.Saidi@ARM.com        }
1727404SAli.Saidi@ARM.com
1737404SAli.Saidi@ARM.com        /** Memory region attributes: ARM DDI 0406B: B3-32 */
1747404SAli.Saidi@ARM.com        uint8_t texcb() const
1757404SAli.Saidi@ARM.com        {
1767404SAli.Saidi@ARM.com            return large() ?
1777404SAli.Saidi@ARM.com                (bits(data, 2) | (bits(data,3) << 1) | (bits(data, 12, 14) << 2)) :
1787404SAli.Saidi@ARM.com                (bits(data, 2) | (bits(data,3) << 1) | (bits(data, 6, 8) << 2));
1797404SAli.Saidi@ARM.com        }
1807404SAli.Saidi@ARM.com
1817404SAli.Saidi@ARM.com        /** Return the physical frame, bits shifted right */
1827404SAli.Saidi@ARM.com        Addr pfn() const
1837404SAli.Saidi@ARM.com        {
1847404SAli.Saidi@ARM.com            return large() ? bits(data, 31, 16) : bits(data, 31, 12);
1857404SAli.Saidi@ARM.com        }
1867404SAli.Saidi@ARM.com
1877404SAli.Saidi@ARM.com    };
1887404SAli.Saidi@ARM.com
1897404SAli.Saidi@ARM.com    /** Port to issue translation requests from */
1907404SAli.Saidi@ARM.com    DmaPort *port;
1917404SAli.Saidi@ARM.com
1927404SAli.Saidi@ARM.com    /** TLB that is initiating these table walks */
1937404SAli.Saidi@ARM.com    TLB *tlb;
1947404SAli.Saidi@ARM.com
1957404SAli.Saidi@ARM.com    /** Thread context that we're doing the walk for */
1967404SAli.Saidi@ARM.com    ThreadContext *tc;
1977404SAli.Saidi@ARM.com
1987404SAli.Saidi@ARM.com    /** Request that is currently being serviced */
1997404SAli.Saidi@ARM.com    RequestPtr req;
2007404SAli.Saidi@ARM.com
2017404SAli.Saidi@ARM.com    /** Context ID that we're servicing the request under */
2027404SAli.Saidi@ARM.com    uint8_t contextId;
2037404SAli.Saidi@ARM.com
2047404SAli.Saidi@ARM.com    /** Translation state for delayed requests */
2057404SAli.Saidi@ARM.com    TLB::Translation *transState;
2067404SAli.Saidi@ARM.com
2077404SAli.Saidi@ARM.com    /** The fault that we are going to return */
2087404SAli.Saidi@ARM.com    Fault fault;
2097404SAli.Saidi@ARM.com
2107404SAli.Saidi@ARM.com    /** The virtual address that is being translated */
2117404SAli.Saidi@ARM.com    Addr vaddr;
2127404SAli.Saidi@ARM.com
2137404SAli.Saidi@ARM.com    /** Cached copy of the sctlr as it existed when translation began */
2147404SAli.Saidi@ARM.com    SCTLR sctlr;
2157404SAli.Saidi@ARM.com
2167404SAli.Saidi@ARM.com    /** Cached copy of the cpsr as it existed when the translation began */
2177404SAli.Saidi@ARM.com    CPSR cpsr;
2187404SAli.Saidi@ARM.com
2197404SAli.Saidi@ARM.com    /** Width of the base address held in TTRB0 */
2207404SAli.Saidi@ARM.com    uint32_t N;
2217404SAli.Saidi@ARM.com
2227404SAli.Saidi@ARM.com    /** If the access is a write */
2237404SAli.Saidi@ARM.com    bool isWrite;
2247404SAli.Saidi@ARM.com
2257404SAli.Saidi@ARM.com    /** If the access is not from user mode */
2267404SAli.Saidi@ARM.com    bool isPriv;
2277404SAli.Saidi@ARM.com
2287404SAli.Saidi@ARM.com    /** If the access is a fetch (for execution, and no-exec) must be checked?*/
2297404SAli.Saidi@ARM.com    bool isFetch;
2307404SAli.Saidi@ARM.com
2317404SAli.Saidi@ARM.com    /** If the mode is timing or atomic */
2327404SAli.Saidi@ARM.com    bool timing;
2337404SAli.Saidi@ARM.com
2347404SAli.Saidi@ARM.com    L1Descriptor l1Desc;
2357404SAli.Saidi@ARM.com    L2Descriptor l2Desc;
2367404SAli.Saidi@ARM.com
2377404SAli.Saidi@ARM.com  public:
2387404SAli.Saidi@ARM.com    typedef ArmTableWalkerParams Params;
2397404SAli.Saidi@ARM.com    TableWalker(const Params *p);
2407404SAli.Saidi@ARM.com    virtual ~TableWalker();
2417404SAli.Saidi@ARM.com
2427404SAli.Saidi@ARM.com    const Params *
2437404SAli.Saidi@ARM.com    params() const
2447404SAli.Saidi@ARM.com    {
2457404SAli.Saidi@ARM.com        return dynamic_cast<const Params *>(_params);
2467404SAli.Saidi@ARM.com    }
2477404SAli.Saidi@ARM.com
2487404SAli.Saidi@ARM.com    virtual unsigned int drain(Event *de) { panic("write me\n"); }
2497404SAli.Saidi@ARM.com    virtual Port *getPort(const std::string &if_name, int idx = -1);
2507404SAli.Saidi@ARM.com
2517404SAli.Saidi@ARM.com    Fault walk(RequestPtr req, ThreadContext *tc, uint8_t cid, TLB::Mode mode,
2527404SAli.Saidi@ARM.com            TLB::Translation *_trans, bool timing);
2537404SAli.Saidi@ARM.com
2547404SAli.Saidi@ARM.com    void setTlb(TLB *_tlb) { tlb = _tlb; }
2557404SAli.Saidi@ARM.com
2567404SAli.Saidi@ARM.com  private:
2577404SAli.Saidi@ARM.com    void memAttrs(TlbEntry &te, uint8_t texcb);
2587404SAli.Saidi@ARM.com
2597404SAli.Saidi@ARM.com    void doL1Descriptor();
2607404SAli.Saidi@ARM.com    EventWrapper<TableWalker, &TableWalker::doL1Descriptor> doL1DescEvent;
2617404SAli.Saidi@ARM.com
2627404SAli.Saidi@ARM.com    void doL2Descriptor();
2637404SAli.Saidi@ARM.com    EventWrapper<TableWalker, &TableWalker::doL2Descriptor> doL2DescEvent;
2647404SAli.Saidi@ARM.com
2657404SAli.Saidi@ARM.com
2667404SAli.Saidi@ARM.com};
2677404SAli.Saidi@ARM.com
2687404SAli.Saidi@ARM.com
2697404SAli.Saidi@ARM.com} // namespace ArmISA
2707404SAli.Saidi@ARM.com
2717404SAli.Saidi@ARM.com#endif //__ARCH_ARM_TABLE_WALKER_HH__
2727404SAli.Saidi@ARM.com
273