/*
 * Copyright (c) 2006 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.
 */

#ifndef __ARCH_SPARC_PAGETABLE_HH__
#define __ARCH_SPARC_PAGETABLE_HH__

#include <cassert>

#include "arch/sparc/isa_traits.hh"
#include "base/bitfield.hh"
#include "base/logging.hh"
#include "sim/serialize.hh"

namespace SparcISA
{

class TteTag
{
  private:
    uint64_t entry;
    bool populated;

  public:
    TteTag() : entry(0), populated(false) {}
    TteTag(uint64_t e) : entry(e), populated(true) {}

    const TteTag &
    operator=(uint64_t e)
    {
        populated = true;
        entry = e;
        return *this;
    }

    bool valid() const { assert(populated); return !bits(entry,62,62); }
    Addr va()    const { assert(populated); return bits(entry,41,0); }
};


class PageTableEntry
{
  public:
    enum EntryType {
      sun4v,
      sun4u,
      invalid
    };

  private:
    uint64_t entry;
    EntryType type;
    uint64_t entry4u;
    bool populated;

  public:
    PageTableEntry() : entry(0), type(invalid), populated(false)
    {}

    PageTableEntry(uint64_t e, EntryType t = sun4u)
        : entry(e), type(t), populated(true)
    {
        populate(entry, type);
    }

    void
    populate(uint64_t e, EntryType t = sun4u)
    {
        entry = e;
        type = t;
        populated = true;

        // If we get a sun4v format TTE, turn it into a sun4u
        if (type == sun4u)
            entry4u = entry;
        else {
            entry4u = 0;
            entry4u |= mbits(entry,63,63);         // valid
            entry4u |= bits(entry,1,0) << 61;      // size[1:0]
            entry4u |= bits(entry,62,62) << 60;    // nfo
            entry4u |= bits(entry,12,12) << 59;    // ie
            entry4u |= bits(entry,2,2) << 48;      // size[2]
            entry4u |= mbits(entry,39,13);         // paddr
            entry4u |= bits(entry,61,61) << 6;;    // locked
            entry4u |= bits(entry,10,10) << 5;     // cp
            entry4u |= bits(entry,9,9) << 4;       // cv
            entry4u |= bits(entry,11,11) << 3;     // e
            entry4u |= bits(entry,8,8) << 2;       // p
            entry4u |= bits(entry,6,6) << 1;       // w
        }
    }

    void
    clear()
    {
        populated = false;
    }

    static int pageSizes[6];

    uint64_t operator()() const { assert(populated); return entry4u; }

    const PageTableEntry &
    operator=(uint64_t e)
    {
        populated = true;
        entry4u = e;
        return *this;
    }

    const PageTableEntry &
    operator=(const PageTableEntry &e)
    {
        populated = true;
        entry4u = e.entry4u;
        type = e.type;
        return *this;
    }

    bool valid() const { return bits(entry4u,63,63) && populated; }

    uint8_t
    _size() const
    {
        assert(populated);
        return bits(entry4u, 62,61) | bits(entry4u, 48,48) << 2;
    }

    Addr size()     const { assert(_size() < 6); return pageSizes[_size()]; }
    Addr sizeMask() const { return size() - 1; }
    bool ie()       const { return bits(entry4u, 59,59); }
    Addr pfn()      const { assert(populated); return bits(entry4u,39,13); }
    Addr paddr()    const { assert(populated); return mbits(entry4u, 39,13);}
    bool locked()   const { assert(populated); return bits(entry4u,6,6); }
    bool cv()       const { assert(populated); return bits(entry4u,4,4); }
    bool cp()       const { assert(populated); return bits(entry4u,5,5); }
    bool priv()     const { assert(populated); return bits(entry4u,2,2); }
    bool writable() const { assert(populated); return bits(entry4u,1,1); }
    bool nofault()  const { assert(populated); return bits(entry4u,60,60); }
    bool sideffect() const { assert(populated); return bits(entry4u,3,3); }
    Addr paddrMask() const { assert(populated); return paddr() & ~sizeMask(); }

    Addr
    translate(Addr vaddr) const
    {
        assert(populated);
        Addr mask = sizeMask();
        return (paddr() & ~mask) | (vaddr & mask);
    }
};

struct TlbRange
{
    Addr va;
    Addr size;
    int contextId;
    int partitionId;
    bool real;

    inline bool
    operator<(const TlbRange &r2) const
    {
        if (real && !r2.real)
            return true;
        if (!real && r2.real)
            return false;

        if (!real && !r2.real) {
            if (contextId < r2.contextId)
                return true;
            else if (contextId > r2.contextId)
                return false;
        }

        if (partitionId < r2.partitionId)
            return true;
        else if (partitionId > r2.partitionId)
            return false;

        if (va < r2.va)
            return true;
        return false;
    }

    inline bool
    operator==(const TlbRange &r2) const
    {
        return va == r2.va &&
               size == r2.size &&
               contextId == r2.contextId &&
               partitionId == r2.partitionId &&
               real == r2.real;
    }
};


struct TlbEntry
{
    TlbEntry()
    {}

    TlbEntry(Addr asn, Addr vaddr, Addr paddr,
             bool uncacheable, bool read_only)
    {
        uint64_t entry = 0;
        if (!read_only)
            entry |= 1ULL << 1; // Writable
        entry |= 0ULL << 2; // Available in nonpriveleged mode
        entry |= 0ULL << 3; // No side effects
        if (!uncacheable) {
            entry |= 1ULL << 4; // Virtually cachable
            entry |= 1ULL << 5; // Physically cachable
        }
        entry |= 0ULL << 6; // Not locked
        entry |= mbits(paddr, 39, 13); // Physical address
        entry |= 0ULL << 48; // size = 8k
        entry |= 0uLL << 59; // Endianness not inverted
        entry |= 0ULL << 60; // Not no fault only
        entry |= 0ULL << 61; // size = 8k
        entry |= 1ULL << 63; // valid
        pte = PageTableEntry(entry);

        range.va = vaddr;
        range.size = 8*(1<<10);
        range.contextId = asn;
        range.partitionId = 0;
        range.real = false;

        valid = true;
    }

    TlbRange range;
    PageTableEntry pte;
    bool used;
    bool valid;

    Addr
    pageStart()
    {
        return pte.paddr();
    }

    void
    updateVaddr(Addr new_vaddr)
    {
        range.va = new_vaddr;
    }

    void serialize(CheckpointOut &cp) const;
    void unserialize(CheckpointIn &cp);
};

} // namespace SparcISA

#endif // __ARCH_SPARC_PAGE_TABLE_HH__

