table_walker.hh revision 7437:5853fbdfba9b
13062Sgblack@eecs.umich.edu/*
23062Sgblack@eecs.umich.edu * Copyright (c) 2010 ARM Limited
33062Sgblack@eecs.umich.edu * All rights reserved
43062Sgblack@eecs.umich.edu *
53062Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall
63062Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual
73062Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating
83062Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software
93062Sgblack@eecs.umich.edu * licensed hereunder.  You may use the software subject to the license
103062Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated
113062Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software,
123062Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form.
133062Sgblack@eecs.umich.edu *
143062Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
153062Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
163062Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
173062Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
183062Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
193062Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
203062Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
213062Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
223062Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
233062Sgblack@eecs.umich.edu * this software without specific prior written permission.
243062Sgblack@eecs.umich.edu *
253062Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
263062Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
273062Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
283062Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
293804Ssaidi@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
303062Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
313062Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
323062Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
333062Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
343062Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
353062Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
363062Sgblack@eecs.umich.edu *
373062Sgblack@eecs.umich.edu * Authors: Ali Saidi
383062Sgblack@eecs.umich.edu */
393062Sgblack@eecs.umich.edu
403062Sgblack@eecs.umich.edu#ifndef __ARCH_ARM_TABLE_WALKER_HH__
413062Sgblack@eecs.umich.edu#define __ARCH_ARM_TABLE_WALKER_HH__
423062Sgblack@eecs.umich.edu
433062Sgblack@eecs.umich.edu#include "arch/arm/miscregs.hh"
443062Sgblack@eecs.umich.edu#include "arch/arm/tlb.hh"
453062Sgblack@eecs.umich.edu#include "mem/mem_object.hh"
463062Sgblack@eecs.umich.edu#include "mem/request.hh"
473062Sgblack@eecs.umich.edu#include "mem/request.hh"
483062Sgblack@eecs.umich.edu#include "params/ArmTableWalker.hh"
493062Sgblack@eecs.umich.edu#include "sim/faults.hh"
503062Sgblack@eecs.umich.edu#include "sim/eventq.hh"
513062Sgblack@eecs.umich.edu
523062Sgblack@eecs.umich.educlass DmaPort;
533062Sgblack@eecs.umich.educlass ThreadContext;
543062Sgblack@eecs.umich.edu
553062Sgblack@eecs.umich.edunamespace ArmISA {
563062Sgblack@eecs.umich.educlass Translation;
573804Ssaidi@eecs.umich.educlass TLB;
583804Ssaidi@eecs.umich.edu
593804Ssaidi@eecs.umich.educlass TableWalker : public MemObject
603804Ssaidi@eecs.umich.edu{
613062Sgblack@eecs.umich.edu  protected:
623062Sgblack@eecs.umich.edu    struct L1Descriptor {
633062Sgblack@eecs.umich.edu        /** Type of page table entry ARM DDI 0406B: B3-8*/
643062Sgblack@eecs.umich.edu        enum EntryType {
653062Sgblack@eecs.umich.edu            Ignore,
663804Ssaidi@eecs.umich.edu            PageTable,
673804Ssaidi@eecs.umich.edu            Section,
683804Ssaidi@eecs.umich.edu            Reserved
693804Ssaidi@eecs.umich.edu        };
703062Sgblack@eecs.umich.edu
713804Ssaidi@eecs.umich.edu        /** The raw bits of the entry */
723062Sgblack@eecs.umich.edu        uint32_t data;
733062Sgblack@eecs.umich.edu
743062Sgblack@eecs.umich.edu        /** This entry has been modified (access flag set) and needs to be
753062Sgblack@eecs.umich.edu         * written back to memory */
763804Ssaidi@eecs.umich.edu        bool _dirty;
773062Sgblack@eecs.umich.edu
783804Ssaidi@eecs.umich.edu        EntryType type() const
793804Ssaidi@eecs.umich.edu        {
803062Sgblack@eecs.umich.edu            return (EntryType)(data & 0x3);
813062Sgblack@eecs.umich.edu        }
823804Ssaidi@eecs.umich.edu
833804Ssaidi@eecs.umich.edu        /** Is the page a Supersection (16MB)?*/
843062Sgblack@eecs.umich.edu        bool supersection() const
853804Ssaidi@eecs.umich.edu        {
863804Ssaidi@eecs.umich.edu            return bits(data, 18);
873804Ssaidi@eecs.umich.edu        }
883804Ssaidi@eecs.umich.edu
893804Ssaidi@eecs.umich.edu        /** Return the physcal address of the entry, bits in position*/
903804Ssaidi@eecs.umich.edu        Addr paddr() const
913804Ssaidi@eecs.umich.edu        {
923804Ssaidi@eecs.umich.edu            if (supersection())
933804Ssaidi@eecs.umich.edu                panic("Super sections not implemented\n");
943804Ssaidi@eecs.umich.edu            return mbits(data, 31,20);
953804Ssaidi@eecs.umich.edu        }
963062Sgblack@eecs.umich.edu
973062Sgblack@eecs.umich.edu        /** Return the physical frame, bits shifted right */
983062Sgblack@eecs.umich.edu        Addr pfn() const
993062Sgblack@eecs.umich.edu        {
1003804Ssaidi@eecs.umich.edu            if (supersection())
1013804Ssaidi@eecs.umich.edu                panic("Super sections not implemented\n");
1023804Ssaidi@eecs.umich.edu            return bits(data, 31,20);
1033804Ssaidi@eecs.umich.edu        }
1043804Ssaidi@eecs.umich.edu
1053804Ssaidi@eecs.umich.edu        /** Is the translation global (no asid used)? */
1063804Ssaidi@eecs.umich.edu        bool global() const
1073804Ssaidi@eecs.umich.edu        {
1083804Ssaidi@eecs.umich.edu            return bits(data, 4);
1093804Ssaidi@eecs.umich.edu        }
1103804Ssaidi@eecs.umich.edu
1113804Ssaidi@eecs.umich.edu        /** Is the translation not allow execution? */
1123804Ssaidi@eecs.umich.edu        bool xn() const
1133804Ssaidi@eecs.umich.edu        {
1143804Ssaidi@eecs.umich.edu            return bits(data, 17);
1153804Ssaidi@eecs.umich.edu        }
1163804Ssaidi@eecs.umich.edu
1173804Ssaidi@eecs.umich.edu        /** Three bit access protection flags */
1183804Ssaidi@eecs.umich.edu        uint8_t ap() const
1193804Ssaidi@eecs.umich.edu        {
1203804Ssaidi@eecs.umich.edu            return (bits(data, 15) << 2) | bits(data,11,10);
1213804Ssaidi@eecs.umich.edu        }
1223804Ssaidi@eecs.umich.edu
1233804Ssaidi@eecs.umich.edu        /** Domain Client/Manager: ARM DDI 0406B: B3-31 */
1243804Ssaidi@eecs.umich.edu        uint8_t domain() const
1253804Ssaidi@eecs.umich.edu        {
1263804Ssaidi@eecs.umich.edu            return bits(data,8,5);
1273804Ssaidi@eecs.umich.edu        }
1283804Ssaidi@eecs.umich.edu
1293804Ssaidi@eecs.umich.edu        /** Address of L2 descriptor if it exists */
1303804Ssaidi@eecs.umich.edu        Addr l2Addr() const
1313804Ssaidi@eecs.umich.edu        {
1323804Ssaidi@eecs.umich.edu            return mbits(data, 31,10);
1333062Sgblack@eecs.umich.edu        }
1343062Sgblack@eecs.umich.edu
1353804Ssaidi@eecs.umich.edu        /** Memory region attributes: ARM DDI 0406B: B3-32.
1363804Ssaidi@eecs.umich.edu         * These bits are largly ignored by M5 and only used to
1373062Sgblack@eecs.umich.edu         * provide the illusion that the memory system cares about
1383804Ssaidi@eecs.umich.edu         * anything but cachable vs. uncachable.
1393062Sgblack@eecs.umich.edu         */
1403062Sgblack@eecs.umich.edu        uint8_t texcb() const
1413062Sgblack@eecs.umich.edu        {
1423062Sgblack@eecs.umich.edu            return bits(data, 2) | bits(data,3) << 1 | bits(data, 14, 12) << 2;
1433804Ssaidi@eecs.umich.edu        }
1443804Ssaidi@eecs.umich.edu
1453804Ssaidi@eecs.umich.edu        /** If the section is shareable. See texcb() comment. */
1463062Sgblack@eecs.umich.edu        bool shareable() const
1473062Sgblack@eecs.umich.edu        {
1483062Sgblack@eecs.umich.edu            return bits(data, 16);
1493062Sgblack@eecs.umich.edu        }
1503804Ssaidi@eecs.umich.edu
1513804Ssaidi@eecs.umich.edu        /** Set access flag that this entry has been touched. Mark
1523062Sgblack@eecs.umich.edu         * the entry as requiring a writeback, in the future.
1533804Ssaidi@eecs.umich.edu         */
1543804Ssaidi@eecs.umich.edu        void setAp0()
1553804Ssaidi@eecs.umich.edu        {
1563804Ssaidi@eecs.umich.edu            data |= 1 << 10;
1573804Ssaidi@eecs.umich.edu            _dirty = true;
1583804Ssaidi@eecs.umich.edu        }
1593804Ssaidi@eecs.umich.edu
1603804Ssaidi@eecs.umich.edu        /** This entry needs to be written back to memory */
1613062Sgblack@eecs.umich.edu        bool dirty() const
1623062Sgblack@eecs.umich.edu        {
1633062Sgblack@eecs.umich.edu            return _dirty;
1643062Sgblack@eecs.umich.edu        }
1653062Sgblack@eecs.umich.edu    };
1663062Sgblack@eecs.umich.edu
1673062Sgblack@eecs.umich.edu    /** Level 2 page table descriptor */
1683062Sgblack@eecs.umich.edu    struct L2Descriptor {
1693062Sgblack@eecs.umich.edu
1703062Sgblack@eecs.umich.edu        /** The raw bits of the entry. */
1713062Sgblack@eecs.umich.edu        uint32_t data;
1723062Sgblack@eecs.umich.edu
1733062Sgblack@eecs.umich.edu        /** This entry has been modified (access flag set) and needs to be
1743062Sgblack@eecs.umich.edu         * written back to memory */
1753062Sgblack@eecs.umich.edu        bool _dirty;
1763062Sgblack@eecs.umich.edu
1773062Sgblack@eecs.umich.edu        /** Is the entry invalid */
1783062Sgblack@eecs.umich.edu        bool invalid() const
1793062Sgblack@eecs.umich.edu        {
1803062Sgblack@eecs.umich.edu            return bits(data, 1,0) == 0;;
1813062Sgblack@eecs.umich.edu        }
1823062Sgblack@eecs.umich.edu
1833062Sgblack@eecs.umich.edu        /** What is the size of the mapping? */
1843062Sgblack@eecs.umich.edu        bool large() const
1853062Sgblack@eecs.umich.edu        {
1863062Sgblack@eecs.umich.edu            return bits(data, 1) == 0;
1873062Sgblack@eecs.umich.edu        }
1883062Sgblack@eecs.umich.edu
1893062Sgblack@eecs.umich.edu        /** Is execution allowed on this mapping? */
1903063Sgblack@eecs.umich.edu        bool xn() const
1913062Sgblack@eecs.umich.edu        {
1923062Sgblack@eecs.umich.edu            return large() ? bits(data, 15) : bits(data, 0);
1933063Sgblack@eecs.umich.edu        }
1943062Sgblack@eecs.umich.edu
1953062Sgblack@eecs.umich.edu        /** Is the translation global (no asid used)? */
1963062Sgblack@eecs.umich.edu        bool global() const
1973062Sgblack@eecs.umich.edu        {
1983062Sgblack@eecs.umich.edu            return !bits(data, 11);
1993062Sgblack@eecs.umich.edu        }
2003062Sgblack@eecs.umich.edu
2013062Sgblack@eecs.umich.edu        /** Three bit access protection flags */
2023062Sgblack@eecs.umich.edu        uint8_t ap() const
2033062Sgblack@eecs.umich.edu        {
2043062Sgblack@eecs.umich.edu           return bits(data, 5, 4) | (bits(data, 9) << 2);
2053062Sgblack@eecs.umich.edu        }
2063123Sgblack@eecs.umich.edu
2073123Sgblack@eecs.umich.edu        /** Memory region attributes: ARM DDI 0406B: B3-32 */
2083123Sgblack@eecs.umich.edu        uint8_t texcb() const
2093123Sgblack@eecs.umich.edu        {
2103123Sgblack@eecs.umich.edu            return large() ?
2113123Sgblack@eecs.umich.edu                (bits(data, 2) | (bits(data,3) << 1) | (bits(data, 14, 12) << 2)) :
2123123Sgblack@eecs.umich.edu                (bits(data, 2) | (bits(data,3) << 1) | (bits(data, 8, 6) << 2));
2133123Sgblack@eecs.umich.edu        }
2143062Sgblack@eecs.umich.edu
2153123Sgblack@eecs.umich.edu        /** Return the physical frame, bits shifted right */
2163123Sgblack@eecs.umich.edu        Addr pfn() const
2173123Sgblack@eecs.umich.edu        {
2183123Sgblack@eecs.umich.edu            return large() ? bits(data, 31, 16) : bits(data, 31, 12);
2193123Sgblack@eecs.umich.edu        }
2203123Sgblack@eecs.umich.edu
2213123Sgblack@eecs.umich.edu        /** If the section is shareable. See texcb() comment. */
2223123Sgblack@eecs.umich.edu        bool shareable() const
2233062Sgblack@eecs.umich.edu        {
2243062Sgblack@eecs.umich.edu            return bits(data, 10);
2253062Sgblack@eecs.umich.edu        }
2263062Sgblack@eecs.umich.edu
2273062Sgblack@eecs.umich.edu        /** Set access flag that this entry has been touched. Mark
2283062Sgblack@eecs.umich.edu         * the entry as requiring a writeback, in the future.
2293062Sgblack@eecs.umich.edu         */
2303062Sgblack@eecs.umich.edu        void setAp0()
2313062Sgblack@eecs.umich.edu        {
2323062Sgblack@eecs.umich.edu            data |= 1 << 4;
2333062Sgblack@eecs.umich.edu            _dirty = true;
2343062Sgblack@eecs.umich.edu        }
2353062Sgblack@eecs.umich.edu
2363062Sgblack@eecs.umich.edu        /** This entry needs to be written back to memory */
2373062Sgblack@eecs.umich.edu        bool dirty() const
2383062Sgblack@eecs.umich.edu        {
2393062Sgblack@eecs.umich.edu            return _dirty;
2403062Sgblack@eecs.umich.edu        }
2413062Sgblack@eecs.umich.edu
2423062Sgblack@eecs.umich.edu    };
2433123Sgblack@eecs.umich.edu
2443062Sgblack@eecs.umich.edu    /** Port to issue translation requests from */
2453804Ssaidi@eecs.umich.edu    DmaPort *port;
2463123Sgblack@eecs.umich.edu
2473062Sgblack@eecs.umich.edu    /** TLB that is initiating these table walks */
2483123Sgblack@eecs.umich.edu    TLB *tlb;
2493123Sgblack@eecs.umich.edu
2503123Sgblack@eecs.umich.edu    /** Thread context that we're doing the walk for */
2513123Sgblack@eecs.umich.edu    ThreadContext *tc;
2523123Sgblack@eecs.umich.edu
2533123Sgblack@eecs.umich.edu    /** Request that is currently being serviced */
2543123Sgblack@eecs.umich.edu    RequestPtr req;
2553123Sgblack@eecs.umich.edu
2563123Sgblack@eecs.umich.edu    /** Context ID that we're servicing the request under */
2573123Sgblack@eecs.umich.edu    uint8_t contextId;
2583123Sgblack@eecs.umich.edu
2593123Sgblack@eecs.umich.edu    /** Translation state for delayed requests */
2603123Sgblack@eecs.umich.edu    TLB::Translation *transState;
2613123Sgblack@eecs.umich.edu
2623123Sgblack@eecs.umich.edu    /** The fault that we are going to return */
2633123Sgblack@eecs.umich.edu    Fault fault;
2643123Sgblack@eecs.umich.edu
2653123Sgblack@eecs.umich.edu    /** The virtual address that is being translated */
2663123Sgblack@eecs.umich.edu    Addr vaddr;
2673804Ssaidi@eecs.umich.edu
2683804Ssaidi@eecs.umich.edu    /** Cached copy of the sctlr as it existed when translation began */
2693804Ssaidi@eecs.umich.edu    SCTLR sctlr;
2703804Ssaidi@eecs.umich.edu
2713123Sgblack@eecs.umich.edu    /** Cached copy of the cpsr as it existed when the translation began */
2723062Sgblack@eecs.umich.edu    CPSR cpsr;
2733062Sgblack@eecs.umich.edu
2743519Sgblack@eecs.umich.edu    /** Width of the base address held in TTRB0 */
275    uint32_t N;
276
277    /** If the access is a write */
278    bool isWrite;
279
280    /** If the access is not from user mode */
281    bool isPriv;
282
283    /** If the access is a fetch (for execution, and no-exec) must be checked?*/
284    bool isFetch;
285
286    /** If the mode is timing or atomic */
287    bool timing;
288
289    L1Descriptor l1Desc;
290    L2Descriptor l2Desc;
291
292    /** Save mode for use in delayed response */
293    BaseTLB::Mode mode;
294
295    /** Whether L1/L2 descriptor response is delayed in timing mode */
296    bool delayed;
297
298  public:
299    typedef ArmTableWalkerParams Params;
300    TableWalker(const Params *p);
301    virtual ~TableWalker();
302
303    const Params *
304    params() const
305    {
306        return dynamic_cast<const Params *>(_params);
307    }
308
309    virtual unsigned int drain(Event *de) { panic("write me\n"); }
310    virtual Port *getPort(const std::string &if_name, int idx = -1);
311
312    Fault walk(RequestPtr req, ThreadContext *tc, uint8_t cid, TLB::Mode mode,
313            TLB::Translation *_trans, bool timing);
314
315    void setTlb(TLB *_tlb) { tlb = _tlb; }
316    void memAttrs(TlbEntry &te, uint8_t texcb, bool s);
317
318  private:
319
320    void doL1Descriptor();
321    void doL1DescriptorWrapper();
322    EventWrapper<TableWalker, &TableWalker::doL1DescriptorWrapper> doL1DescEvent;
323
324    void doL2Descriptor();
325    void doL2DescriptorWrapper();
326    EventWrapper<TableWalker, &TableWalker::doL2DescriptorWrapper> doL2DescEvent;
327
328
329};
330
331
332} // namespace ArmISA
333
334#endif //__ARCH_ARM_TABLE_WALKER_HH__
335
336