/*
 * 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.
 *
 * Authors: Ali Saidi
 */

#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"

class Checkpoint;

namespace SparcISA {

struct VAddr
{
    VAddr(Addr a) { panic("not implemented yet."); }
};

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__

