/*
 * Copyright (c) 2010-2013 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2001-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Ali Saidi
 */

#ifndef __ARCH_ARM_TLB_HH__
#define __ARCH_ARM_TLB_HH__


#include "arch/arm/isa_traits.hh"
#include "arch/arm/pagetable.hh"
#include "arch/arm/utility.hh"
#include "arch/arm/vtophys.hh"
#include "base/statistics.hh"
#include "dev/dma_device.hh"
#include "mem/request.hh"
#include "params/ArmTLB.hh"
#include "sim/fault_fwd.hh"
#include "sim/tlb.hh"

class ThreadContext;

namespace ArmISA {

class TableWalker;
class Stage2LookUp;
class Stage2MMU;

class TLB : public BaseTLB
{
  public:
    enum ArmFlags {
        AlignmentMask = 0x7,

        AlignByte = 0x0,
        AlignHalfWord = 0x1,
        AlignWord = 0x2,
        AlignDoubleWord = 0x3,
        AlignQuadWord = 0x4,
        AlignOctWord = 0x5,

        AllowUnaligned = 0x8,
        // Priv code operating as if it wasn't
        UserMode = 0x10,
        // Because zero otherwise looks like a valid setting and may be used
        // accidentally, this bit must be non-zero to show it was used on
        // purpose.
        MustBeOne = 0x40
    };

    enum ArmTranslationType {
        NormalTran = 0,
        S1CTran = 0x1,
        HypMode = 0x2,
        // Secure code operating as if it wasn't (required by some Address
        // Translate operations)
        S1S2NsTran = 0x4
    };
  protected:
    TlbEntry* table;     // the Page Table
    int size;            // TLB Size
    bool isStage2;       // Indicates this TLB is part of the second stage MMU
    bool stage2Req;      // Indicates whether a stage 2 lookup is also required
    uint64_t _attr;      // Memory attributes for last accessed TLB entry
    bool directToStage2; // Indicates whether all translation requests should
                         // be routed directly to the stage 2 TLB

    TableWalker *tableWalker;
    TLB *stage2Tlb;
    Stage2MMU *stage2Mmu;

    // Access Stats
    mutable Stats::Scalar instHits;
    mutable Stats::Scalar instMisses;
    mutable Stats::Scalar readHits;
    mutable Stats::Scalar readMisses;
    mutable Stats::Scalar writeHits;
    mutable Stats::Scalar writeMisses;
    mutable Stats::Scalar inserts;
    mutable Stats::Scalar flushTlb;
    mutable Stats::Scalar flushTlbMva;
    mutable Stats::Scalar flushTlbMvaAsid;
    mutable Stats::Scalar flushTlbAsid;
    mutable Stats::Scalar flushedEntries;
    mutable Stats::Scalar alignFaults;
    mutable Stats::Scalar prefetchFaults;
    mutable Stats::Scalar domainFaults;
    mutable Stats::Scalar permsFaults;

    Stats::Formula readAccesses;
    Stats::Formula writeAccesses;
    Stats::Formula instAccesses;
    Stats::Formula hits;
    Stats::Formula misses;
    Stats::Formula accesses;

    int rangeMRU; //On lookup, only move entries ahead when outside rangeMRU

    bool bootUncacheability;

  public:
    TLB(const ArmTLBParams *p);
    TLB(const Params *p, int _size, TableWalker *_walker);

    /** Lookup an entry in the TLB
     * @param vpn virtual address
     * @param asn context id/address space id to use
     * @param vmid The virtual machine ID used for stage 2 translation
     * @param secure if the lookup is secure
     * @param hyp if the lookup is done from hyp mode
     * @param functional if the lookup should modify state
     * @param ignore_asn if on lookup asn should be ignored
     * @return pointer to TLB entry if it exists
     */
    TlbEntry *lookup(Addr vpn, uint16_t asn, uint8_t vmid, bool hyp,
                     bool secure, bool functional,
                     bool ignore_asn, uint8_t target_el);

    virtual ~TLB();

    void takeOverFrom(BaseTLB *otlb);

    /// setup all the back pointers
    virtual void init();

    void setMMU(Stage2MMU *m);

    int getsize() const { return size; }

    void insert(Addr vaddr, TlbEntry &pte);

    Fault getTE(TlbEntry **te, RequestPtr req, ThreadContext *tc, Mode mode,
                Translation *translation, bool timing, bool functional,
                bool is_secure, ArmTranslationType tranType);

    Fault getResultTe(TlbEntry **te, RequestPtr req, ThreadContext *tc,
                      Mode mode, Translation *translation, bool timing,
                      bool functional, TlbEntry *mergeTe);

    Fault checkPermissions(TlbEntry *te, RequestPtr req, Mode mode);
    Fault checkPermissions64(TlbEntry *te, RequestPtr req, Mode mode,
                             ThreadContext *tc);


    /** Reset the entire TLB
     * @param secure_lookup if the operation affects the secure world
     */
    void flushAllSecurity(bool secure_lookup, uint8_t target_el,
                          bool ignore_el = false);

    /** Remove all entries in the non secure world, depending on whether they
     *  were allocated in hyp mode or not
     * @param hyp if the opperation affects hyp mode
     */
    void flushAllNs(bool hyp, uint8_t target_el, bool ignore_el = false);


    /** Reset the entire TLB. Used for CPU switching to prevent stale
     * translations after multiple switches
     */
    void flushAll()
    {
        flushAllSecurity(false, 0, true);
        flushAllSecurity(true, 0, true);
    }

    /** Remove any entries that match both a va and asn
     * @param mva virtual address to flush
     * @param asn contextid/asn to flush on match
     * @param secure_lookup if the operation affects the secure world
     */
    void flushMvaAsid(Addr mva, uint64_t asn, bool secure_lookup,
                      uint8_t target_el);

    /** Remove any entries that match the asn
     * @param asn contextid/asn to flush on match
     * @param secure_lookup if the operation affects the secure world
     */
    void flushAsid(uint64_t asn, bool secure_lookup, uint8_t target_el);

    /** Remove all entries that match the va regardless of asn
     * @param mva address to flush from cache
     * @param secure_lookup if the operation affects the secure world
     * @param hyp if the operation affects hyp mode
     */
    void flushMva(Addr mva, bool secure_lookup, bool hyp, uint8_t target_el);

    Fault trickBoxCheck(RequestPtr req, Mode mode, TlbEntry::DomainType domain);
    Fault walkTrickBoxCheck(Addr pa, bool is_secure, Addr va, Addr sz, bool is_exec,
            bool is_write, TlbEntry::DomainType domain, LookupLevel lookup_level);

    void printTlb() const;

    void allCpusCaching() { bootUncacheability = true; }
    void demapPage(Addr vaddr, uint64_t asn)
    {
        // needed for x86 only
        panic("demapPage() is not implemented.\n");
    }

    static bool validVirtualAddress(Addr vaddr);

    /**
     * Do a functional lookup on the TLB (for debugging)
     * and don't modify any internal state
     * @param tc thread context to get the context id from
     * @param vaddr virtual address to translate
     * @param pa returned physical address
     * @return if the translation was successful
     */
    bool translateFunctional(ThreadContext *tc, Addr vaddr, Addr &paddr);

    /**
     * Do a functional lookup on the TLB (for checker cpu) that
     * behaves like a normal lookup without modifying any page table state.
     */
    Fault translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode,
            ArmTranslationType tranType = NormalTran);

    /** Accessor functions for memory attributes for last accessed TLB entry
     */
    void
    setAttr(uint64_t attr)
    {
        _attr = attr;
    }

    uint64_t
    getAttr() const
    {
        return _attr;
    }

    Fault translateFs(RequestPtr req, ThreadContext *tc, Mode mode,
            Translation *translation, bool &delay,
            bool timing, ArmTranslationType tranType, bool functional = false);
    Fault translateSe(RequestPtr req, ThreadContext *tc, Mode mode,
            Translation *translation, bool &delay, bool timing);
    Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode,
            ArmTranslationType tranType = NormalTran);
    Fault translateTiming(RequestPtr req, ThreadContext *tc,
            Translation *translation, Mode mode,
            ArmTranslationType tranType = NormalTran);
    Fault translateComplete(RequestPtr req, ThreadContext *tc,
            Translation *translation, Mode mode, ArmTranslationType tranType,
            bool callFromS2);
    Fault finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const;

    void drainResume();

    // Checkpointing
    void serialize(std::ostream &os);
    void unserialize(Checkpoint *cp, const std::string &section);

    void regStats();

    /**
     * Get the table walker master port. This is used for migrating
     * port connections during a CPU takeOverFrom() call. For
     * architectures that do not have a table walker, NULL is
     * returned, hence the use of a pointer rather than a
     * reference. For ARM this method will always return a valid port
     * pointer.
     *
     * @return A pointer to the walker master port
     */
    virtual BaseMasterPort* getMasterPort();

    /**
     * Allow the MMU (overseeing both stage 1 and stage 2 TLBs) to
     * access the table walker port of this TLB so that it can
     * orchestrate staged translations.
     *
     * @return The table walker DMA port
     */
    DmaPort& getWalkerPort();

    // Caching misc register values here.
    // Writing to misc registers needs to invalidate them.
    // translateFunctional/translateSe/translateFs checks if they are
    // invalid and call updateMiscReg if necessary.
protected:
    bool aarch64;
    ExceptionLevel aarch64EL;
    SCTLR sctlr;
    SCR scr;
    bool isPriv;
    bool isSecure;
    bool isHyp;
    TTBCR ttbcr;
    uint16_t asid;
    uint8_t vmid;
    PRRR prrr;
    NMRR nmrr;
    HCR hcr;
    uint32_t dacr;
    bool miscRegValid;
    ArmTranslationType curTranType;

    // Cached copies of system-level properties
    bool haveLPAE;
    bool haveVirtualization;
    bool haveLargeAsid64;

    void updateMiscReg(ThreadContext *tc,
                       ArmTranslationType tranType = NormalTran);

public:
    const Params *
    params() const
    {
        return dynamic_cast<const Params *>(_params);
    }
    inline void invalidateMiscReg() { miscRegValid = false; }

private:
    /** Remove any entries that match both a va and asn
     * @param mva virtual address to flush
     * @param asn contextid/asn to flush on match
     * @param secure_lookup if the operation affects the secure world
     * @param hyp if the operation affects hyp mode
     * @param ignore_asn if the flush should ignore the asn
     */
    void _flushMva(Addr mva, uint64_t asn, bool secure_lookup,
                   bool hyp, bool ignore_asn, uint8_t target_el);

    bool checkELMatch(uint8_t target_el, uint8_t tentry_el, bool ignore_el);
};

} // namespace ArmISA

#endif // __ARCH_ARM_TLB_HH__
