tlb.hh revision 10822:d259f2bc2b31
12068SN/A/*
22068SN/A * Copyright (c) 2010-2013 ARM Limited
32188SN/A * All rights reserved
42068SN/A *
52068SN/A * The license below extends only to copyright in the software and shall
62068SN/A * not be construed as granting a license to any other intellectual
72068SN/A * property including but not limited to intellectual property relating
82068SN/A * to a hardware implementation of the functionality of the software
92068SN/A * licensed hereunder.  You may use the software subject to the license
102068SN/A * terms below provided that you ensure that this notice is replicated
112068SN/A * unmodified and in its entirety in all distributions of the software,
122068SN/A * modified or unmodified, in source code or in binary form.
132068SN/A *
142068SN/A * Copyright (c) 2001-2005 The Regents of The University of Michigan
152068SN/A * All rights reserved.
162068SN/A *
172068SN/A * Redistribution and use in source and binary forms, with or without
182068SN/A * modification, are permitted provided that the following conditions are
192068SN/A * met: redistributions of source code must retain the above copyright
202068SN/A * notice, this list of conditions and the following disclaimer;
212068SN/A * redistributions in binary form must reproduce the above copyright
222068SN/A * notice, this list of conditions and the following disclaimer in the
232068SN/A * documentation and/or other materials provided with the distribution;
242068SN/A * neither the name of the copyright holders nor the names of its
252068SN/A * contributors may be used to endorse or promote products derived from
262068SN/A * this software without specific prior written permission.
272068SN/A *
282665Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292665Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302068SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312649Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
322649Ssaidi@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332649Ssaidi@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342649Ssaidi@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352649Ssaidi@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
362068SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372068SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382068SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392068SN/A *
402068SN/A * Authors: Ali Saidi
412068SN/A */
422068SN/A
432068SN/A#ifndef __ARCH_ARM_TLB_HH__
442075SN/A#define __ARCH_ARM_TLB_HH__
452075SN/A
462075SN/A
472075SN/A#include "arch/arm/isa_traits.hh"
482075SN/A#include "arch/arm/pagetable.hh"
492075SN/A#include "arch/arm/utility.hh"
502735Sktlim@umich.edu#include "arch/arm/vtophys.hh"
512069SN/A#include "arch/generic/tlb.hh"
522069SN/A#include "base/statistics.hh"
532075SN/A#include "dev/dma_device.hh"
542735Sktlim@umich.edu#include "mem/request.hh"
552068SN/A#include "params/ArmTLB.hh"
562068SN/A#include "sim/probe/pmu.hh"
572068SN/A
582075SN/Aclass ThreadContext;
592075SN/A
602068SN/Anamespace ArmISA {
612068SN/A
622075SN/Aclass TableWalker;
632075SN/Aclass Stage2LookUp;
642068SN/Aclass Stage2MMU;
652068SN/A
662068SN/Aclass TLB : public BaseTLB
672075SN/A{
682075SN/A  public:
692075SN/A    enum ArmFlags {
702075SN/A        AlignmentMask = 0x7,
712075SN/A
722075SN/A        AlignByte = 0x0,
732075SN/A        AlignHalfWord = 0x1,
742735Sktlim@umich.edu        AlignWord = 0x2,
752069SN/A        AlignDoubleWord = 0x3,
762069SN/A        AlignQuadWord = 0x4,
772075SN/A        AlignOctWord = 0x5,
782735Sktlim@umich.edu
792068SN/A        AllowUnaligned = 0x8,
802068SN/A        // Priv code operating as if it wasn't
812068SN/A        UserMode = 0x10,
822075SN/A        // Because zero otherwise looks like a valid setting and may be used
832068SN/A        // accidentally, this bit must be non-zero to show it was used on
842069SN/A        // purpose.
852068SN/A        MustBeOne = 0x40
862068SN/A    };
872336SN/A
882075SN/A    enum ArmTranslationType {
892068SN/A        NormalTran = 0,
902069SN/A        S1CTran = 0x1,
912068SN/A        HypMode = 0x2,
922068SN/A        // Secure code operating as if it wasn't (required by some Address
932068SN/A        // Translate operations)
942068SN/A        S1S2NsTran = 0x4
952068SN/A    };
962068SN/A  protected:
972068SN/A    TlbEntry* table;     // the Page Table
982068SN/A    int size;            // TLB Size
992336SN/A    bool isStage2;       // Indicates this TLB is part of the second stage MMU
1002068SN/A    bool stage2Req;      // Indicates whether a stage 2 lookup is also required
1012068SN/A    uint64_t _attr;      // Memory attributes for last accessed TLB entry
1022068SN/A    bool directToStage2; // Indicates whether all translation requests should
1032068SN/A                         // be routed directly to the stage 2 TLB
1042068SN/A
1052068SN/A    TableWalker *tableWalker;
1062068SN/A    TLB *stage2Tlb;
1072068SN/A    Stage2MMU *stage2Mmu;
1082068SN/A
1092068SN/A    // Access Stats
1102068SN/A    mutable Stats::Scalar instHits;
1112068SN/A    mutable Stats::Scalar instMisses;
1122147SN/A    mutable Stats::Scalar readHits;
1132068SN/A    mutable Stats::Scalar readMisses;
1142068SN/A    mutable Stats::Scalar writeHits;
1152068SN/A    mutable Stats::Scalar writeMisses;
1162068SN/A    mutable Stats::Scalar inserts;
1172068SN/A    mutable Stats::Scalar flushTlb;
1182068SN/A    mutable Stats::Scalar flushTlbMva;
1192068SN/A    mutable Stats::Scalar flushTlbMvaAsid;
1202068SN/A    mutable Stats::Scalar flushTlbAsid;
1212068SN/A    mutable Stats::Scalar flushedEntries;
1222068SN/A    mutable Stats::Scalar alignFaults;
1232068SN/A    mutable Stats::Scalar prefetchFaults;
1242147SN/A    mutable Stats::Scalar domainFaults;
1252068SN/A    mutable Stats::Scalar permsFaults;
1262068SN/A
1272068SN/A    Stats::Formula readAccesses;
1282068SN/A    Stats::Formula writeAccesses;
1292068SN/A    Stats::Formula instAccesses;
1302068SN/A    Stats::Formula hits;
1312068SN/A    Stats::Formula misses;
1322068SN/A    Stats::Formula accesses;
1332068SN/A
1342068SN/A    /** PMU probe for TLB refills */
1352068SN/A    ProbePoints::PMUUPtr ppRefills;
1362068SN/A
1372068SN/A    int rangeMRU; //On lookup, only move entries ahead when outside rangeMRU
1382147SN/A
1392068SN/A  public:
1402068SN/A    TLB(const ArmTLBParams *p);
1412068SN/A    TLB(const Params *p, int _size, TableWalker *_walker);
1422068SN/A
1432068SN/A    /** Lookup an entry in the TLB
1442068SN/A     * @param vpn virtual address
1452068SN/A     * @param asn context id/address space id to use
1462068SN/A     * @param vmid The virtual machine ID used for stage 2 translation
1472068SN/A     * @param secure if the lookup is secure
1482068SN/A     * @param hyp if the lookup is done from hyp mode
1492068SN/A     * @param functional if the lookup should modify state
1502068SN/A     * @param ignore_asn if on lookup asn should be ignored
1512068SN/A     * @return pointer to TLB entry if it exists
1522147SN/A     */
1532068SN/A    TlbEntry *lookup(Addr vpn, uint16_t asn, uint8_t vmid, bool hyp,
1542068SN/A                     bool secure, bool functional,
1552068SN/A                     bool ignore_asn, uint8_t target_el);
1562068SN/A
1572068SN/A    virtual ~TLB();
1582068SN/A
1592068SN/A    void takeOverFrom(BaseTLB *otlb);
1602068SN/A
1612068SN/A    /// setup all the back pointers
1622068SN/A    virtual void init();
1632068SN/A
1642068SN/A    TableWalker *getTableWalker() { return tableWalker; }
1652068SN/A
1662068SN/A    void setMMU(Stage2MMU *m, MasterID master_id);
1672068SN/A
1682068SN/A    int getsize() const { return size; }
1692068SN/A
1702068SN/A    void insert(Addr vaddr, TlbEntry &pte);
1712068SN/A
1722068SN/A    Fault getTE(TlbEntry **te, RequestPtr req, ThreadContext *tc, Mode mode,
1732068SN/A                Translation *translation, bool timing, bool functional,
1742068SN/A                bool is_secure, ArmTranslationType tranType);
1752068SN/A
1762068SN/A    Fault getResultTe(TlbEntry **te, RequestPtr req, ThreadContext *tc,
1772068SN/A                      Mode mode, Translation *translation, bool timing,
1782068SN/A                      bool functional, TlbEntry *mergeTe);
1792068SN/A
1802068SN/A    Fault checkPermissions(TlbEntry *te, RequestPtr req, Mode mode);
1812068SN/A    Fault checkPermissions64(TlbEntry *te, RequestPtr req, Mode mode,
1822068SN/A                             ThreadContext *tc);
1832068SN/A
1842068SN/A
1852068SN/A    /** Reset the entire TLB
1862068SN/A     * @param secure_lookup if the operation affects the secure world
1872068SN/A     */
1882068SN/A    void flushAllSecurity(bool secure_lookup, uint8_t target_el,
1892068SN/A                          bool ignore_el = false);
1902068SN/A
1912068SN/A    /** Remove all entries in the non secure world, depending on whether they
1922068SN/A     *  were allocated in hyp mode or not
1932068SN/A     * @param hyp if the opperation affects hyp mode
1942068SN/A     */
1952068SN/A    void flushAllNs(bool hyp, uint8_t target_el, bool ignore_el = false);
1962068SN/A
1972068SN/A
1982068SN/A    /** Reset the entire TLB. Used for CPU switching to prevent stale
1992068SN/A     * translations after multiple switches
2002068SN/A     */
2012068SN/A    void flushAll()
2022068SN/A    {
2032068SN/A        flushAllSecurity(false, 0, true);
2042068SN/A        flushAllSecurity(true, 0, true);
2052068SN/A    }
2062068SN/A
2072068SN/A    /** Remove any entries that match both a va and asn
2082068SN/A     * @param mva virtual address to flush
2092068SN/A     * @param asn contextid/asn to flush on match
2102068SN/A     * @param secure_lookup if the operation affects the secure world
2112068SN/A     */
2122068SN/A    void flushMvaAsid(Addr mva, uint64_t asn, bool secure_lookup,
2132068SN/A                      uint8_t target_el);
2142068SN/A
2152068SN/A    /** Remove any entries that match the asn
2162068SN/A     * @param asn contextid/asn to flush on match
2172068SN/A     * @param secure_lookup if the operation affects the secure world
2182068SN/A     */
2192068SN/A    void flushAsid(uint64_t asn, bool secure_lookup, uint8_t target_el);
2202068SN/A
2212068SN/A    /** Remove all entries that match the va regardless of asn
2222068SN/A     * @param mva address to flush from cache
2232068SN/A     * @param secure_lookup if the operation affects the secure world
2242068SN/A     * @param hyp if the operation affects hyp mode
2252068SN/A     */
2262068SN/A    void flushMva(Addr mva, bool secure_lookup, bool hyp, uint8_t target_el);
2272068SN/A
2282068SN/A    Fault trickBoxCheck(RequestPtr req, Mode mode, TlbEntry::DomainType domain);
2292068SN/A    Fault walkTrickBoxCheck(Addr pa, bool is_secure, Addr va, Addr sz, bool is_exec,
2302068SN/A            bool is_write, TlbEntry::DomainType domain, LookupLevel lookup_level);
2312068SN/A
2322068SN/A    void printTlb() const;
2332068SN/A
2342068SN/A    void demapPage(Addr vaddr, uint64_t asn)
2352068SN/A    {
2362068SN/A        // needed for x86 only
2372068SN/A        panic("demapPage() is not implemented.\n");
2382068SN/A    }
2392068SN/A
2402068SN/A    static bool validVirtualAddress(Addr vaddr);
2412068SN/A
2422068SN/A    /**
2432068SN/A     * Do a functional lookup on the TLB (for debugging)
2442068SN/A     * and don't modify any internal state
2452068SN/A     * @param tc thread context to get the context id from
2462068SN/A     * @param vaddr virtual address to translate
2472068SN/A     * @param pa returned physical address
2482068SN/A     * @return if the translation was successful
2492068SN/A     */
2502068SN/A    bool translateFunctional(ThreadContext *tc, Addr vaddr, Addr &paddr);
2512068SN/A
2522068SN/A    /**
2532068SN/A     * Do a functional lookup on the TLB (for checker cpu) that
2542068SN/A     * behaves like a normal lookup without modifying any page table state.
2552068SN/A     */
2562068SN/A    Fault translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode,
2572068SN/A            ArmTranslationType tranType = NormalTran);
2582068SN/A
2592068SN/A    /** Accessor functions for memory attributes for last accessed TLB entry
2602068SN/A     */
2612068SN/A    void
2622068SN/A    setAttr(uint64_t attr)
2632068SN/A    {
2642068SN/A        _attr = attr;
2652068SN/A    }
2662068SN/A
2672068SN/A    uint64_t
2682068SN/A    getAttr() const
2692068SN/A    {
2702068SN/A        return _attr;
2712068SN/A    }
2722068SN/A
2732068SN/A    Fault translateFs(RequestPtr req, ThreadContext *tc, Mode mode,
2742068SN/A            Translation *translation, bool &delay,
2752068SN/A            bool timing, ArmTranslationType tranType, bool functional = false);
2762068SN/A    Fault translateSe(RequestPtr req, ThreadContext *tc, Mode mode,
2772068SN/A            Translation *translation, bool &delay, bool timing);
2782068SN/A    Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode,
2792068SN/A            ArmTranslationType tranType = NormalTran);
2802068SN/A    Fault translateTiming(RequestPtr req, ThreadContext *tc,
2812068SN/A            Translation *translation, Mode mode,
2822068SN/A            ArmTranslationType tranType = NormalTran);
2832068SN/A    Fault translateComplete(RequestPtr req, ThreadContext *tc,
2842068SN/A            Translation *translation, Mode mode, ArmTranslationType tranType,
2852068SN/A            bool callFromS2);
2862068SN/A    Fault finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const;
2872068SN/A
2882068SN/A    void drainResume();
2892068SN/A
2902068SN/A    // Checkpointing
2912068SN/A    void serialize(std::ostream &os);
2922068SN/A    void unserialize(Checkpoint *cp, const std::string &section);
2932068SN/A
2942068SN/A    void regStats();
2952068SN/A
2962068SN/A    void regProbePoints() M5_ATTR_OVERRIDE;
2972068SN/A
2982068SN/A    /**
2992068SN/A     * Get the table walker master port. This is used for migrating
3002068SN/A     * port connections during a CPU takeOverFrom() call. For
3012068SN/A     * architectures that do not have a table walker, NULL is
3022068SN/A     * returned, hence the use of a pointer rather than a
3032068SN/A     * reference. For ARM this method will always return a valid port
3042068SN/A     * pointer.
3052068SN/A     *
3062068SN/A     * @return A pointer to the walker master port
3072068SN/A     */
3082068SN/A    virtual BaseMasterPort* getMasterPort();
3092068SN/A
3102068SN/A    // Caching misc register values here.
3112068SN/A    // Writing to misc registers needs to invalidate them.
3122068SN/A    // translateFunctional/translateSe/translateFs checks if they are
3132147SN/A    // invalid and call updateMiscReg if necessary.
3142068SN/Aprotected:
3152068SN/A    bool aarch64;
3162068SN/A    ExceptionLevel aarch64EL;
3172068SN/A    SCTLR sctlr;
3182068SN/A    SCR scr;
3192068SN/A    bool isPriv;
3202068SN/A    bool isSecure;
3212068SN/A    bool isHyp;
3222068SN/A    TTBCR ttbcr;
3232068SN/A    uint16_t asid;
3242147SN/A    uint8_t vmid;
3252068SN/A    PRRR prrr;
3262068SN/A    NMRR nmrr;
3272068SN/A    HCR hcr;
3282068SN/A    uint32_t dacr;
3292068SN/A    bool miscRegValid;
3302068SN/A    ArmTranslationType curTranType;
3312068SN/A
3322068SN/A    // Cached copies of system-level properties
3332068SN/A    bool haveLPAE;
3342068SN/A    bool haveVirtualization;
3352068SN/A    bool haveLargeAsid64;
3362068SN/A
3372068SN/A    void updateMiscReg(ThreadContext *tc,
3382068SN/A                       ArmTranslationType tranType = NormalTran);
3392068SN/A
3402068SN/Apublic:
3412068SN/A    const Params *
3422068SN/A    params() const
3432068SN/A    {
3442068SN/A        return dynamic_cast<const Params *>(_params);
3452068SN/A    }
3462068SN/A    inline void invalidateMiscReg() { miscRegValid = false; }
3472068SN/A
3482068SN/Aprivate:
3492068SN/A    /** Remove any entries that match both a va and asn
3502068SN/A     * @param mva virtual address to flush
3512068SN/A     * @param asn contextid/asn to flush on match
3522068SN/A     * @param secure_lookup if the operation affects the secure world
3532068SN/A     * @param hyp if the operation affects hyp mode
3542068SN/A     * @param ignore_asn if the flush should ignore the asn
3552068SN/A     */
3562068SN/A    void _flushMva(Addr mva, uint64_t asn, bool secure_lookup,
3572068SN/A                   bool hyp, bool ignore_asn, uint8_t target_el);
3582068SN/A
3592068SN/A    bool checkELMatch(uint8_t target_el, uint8_t tentry_el, bool ignore_el);
3602068SN/A};
3612068SN/A
3622068SN/A} // namespace ArmISA
3632068SN/A
3642068SN/A#endif // __ARCH_ARM_TLB_HH__
3652068SN/A