13804Ssaidi@eecs.umich.edu/*
23804Ssaidi@eecs.umich.edu * Copyright (c) 2006 The Regents of The University of Michigan
33804Ssaidi@eecs.umich.edu * All rights reserved.
43804Ssaidi@eecs.umich.edu *
53804Ssaidi@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
63804Ssaidi@eecs.umich.edu * modification, are permitted provided that the following conditions are
73804Ssaidi@eecs.umich.edu * met: redistributions of source code must retain the above copyright
83804Ssaidi@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
93804Ssaidi@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
103804Ssaidi@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
113804Ssaidi@eecs.umich.edu * documentation and/or other materials provided with the distribution;
123804Ssaidi@eecs.umich.edu * neither the name of the copyright holders nor the names of its
133804Ssaidi@eecs.umich.edu * contributors may be used to endorse or promote products derived from
143804Ssaidi@eecs.umich.edu * this software without specific prior written permission.
153804Ssaidi@eecs.umich.edu *
163804Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173804Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183804Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193804Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203804Ssaidi@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213804Ssaidi@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223804Ssaidi@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233804Ssaidi@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243804Ssaidi@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253804Ssaidi@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263804Ssaidi@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273804Ssaidi@eecs.umich.edu *
283804Ssaidi@eecs.umich.edu * Authors: Ali Saidi
293804Ssaidi@eecs.umich.edu */
303804Ssaidi@eecs.umich.edu
313804Ssaidi@eecs.umich.edu#ifndef __ARCH_SPARC_PAGETABLE_HH__
323804Ssaidi@eecs.umich.edu#define __ARCH_SPARC_PAGETABLE_HH__
333804Ssaidi@eecs.umich.edu
345616Snate@binkert.org#include <cassert>
355616Snate@binkert.org
363804Ssaidi@eecs.umich.edu#include "arch/sparc/isa_traits.hh"
373826Ssaidi@eecs.umich.edu#include "base/bitfield.hh"
3812334Sgabeblack@google.com#include "base/logging.hh"
393804Ssaidi@eecs.umich.edu
403809Sgblack@eecs.umich.educlass Checkpoint;
413809Sgblack@eecs.umich.edu
425555Snate@binkert.orgnamespace SparcISA {
435555Snate@binkert.org
443804Ssaidi@eecs.umich.edustruct VAddr
453804Ssaidi@eecs.umich.edu{
463804Ssaidi@eecs.umich.edu    VAddr(Addr a) { panic("not implemented yet."); }
473804Ssaidi@eecs.umich.edu};
483804Ssaidi@eecs.umich.edu
494070Ssaidi@eecs.umich.educlass TteTag
504070Ssaidi@eecs.umich.edu{
514070Ssaidi@eecs.umich.edu  private:
524070Ssaidi@eecs.umich.edu    uint64_t entry;
534070Ssaidi@eecs.umich.edu    bool populated;
544070Ssaidi@eecs.umich.edu
554070Ssaidi@eecs.umich.edu  public:
564070Ssaidi@eecs.umich.edu    TteTag() : entry(0), populated(false) {}
574070Ssaidi@eecs.umich.edu    TteTag(uint64_t e) : entry(e), populated(true) {}
585555Snate@binkert.org
595555Snate@binkert.org    const TteTag &
6011320Ssteve.reinhardt@amd.com    operator=(uint64_t e)
615555Snate@binkert.org    {
625555Snate@binkert.org        populated = true;
635555Snate@binkert.org        entry = e;
645555Snate@binkert.org        return *this;
655555Snate@binkert.org    }
665555Snate@binkert.org
677741Sgblack@eecs.umich.edu    bool valid() const { assert(populated); return !bits(entry,62,62); }
687741Sgblack@eecs.umich.edu    Addr va()    const { assert(populated); return bits(entry,41,0); }
694070Ssaidi@eecs.umich.edu};
704070Ssaidi@eecs.umich.edu
714070Ssaidi@eecs.umich.edu
723804Ssaidi@eecs.umich.educlass PageTableEntry
733804Ssaidi@eecs.umich.edu{
743804Ssaidi@eecs.umich.edu  public:
753804Ssaidi@eecs.umich.edu    enum EntryType {
763804Ssaidi@eecs.umich.edu      sun4v,
773804Ssaidi@eecs.umich.edu      sun4u,
783804Ssaidi@eecs.umich.edu      invalid
793804Ssaidi@eecs.umich.edu    };
803804Ssaidi@eecs.umich.edu
813804Ssaidi@eecs.umich.edu  private:
823804Ssaidi@eecs.umich.edu    uint64_t entry;
833804Ssaidi@eecs.umich.edu    EntryType type;
843804Ssaidi@eecs.umich.edu    uint64_t entry4u;
853804Ssaidi@eecs.umich.edu    bool populated;
863804Ssaidi@eecs.umich.edu
873804Ssaidi@eecs.umich.edu  public:
887741Sgblack@eecs.umich.edu    PageTableEntry() : entry(0), type(invalid), populated(false)
895555Snate@binkert.org    {}
903804Ssaidi@eecs.umich.edu
913804Ssaidi@eecs.umich.edu    PageTableEntry(uint64_t e, EntryType t = sun4u)
923804Ssaidi@eecs.umich.edu        : entry(e), type(t), populated(true)
933804Ssaidi@eecs.umich.edu    {
943804Ssaidi@eecs.umich.edu        populate(entry, type);
953804Ssaidi@eecs.umich.edu    }
963804Ssaidi@eecs.umich.edu
977741Sgblack@eecs.umich.edu    void
987741Sgblack@eecs.umich.edu    populate(uint64_t e, EntryType t = sun4u)
993804Ssaidi@eecs.umich.edu    {
1003804Ssaidi@eecs.umich.edu        entry = e;
1013804Ssaidi@eecs.umich.edu        type = t;
1023804Ssaidi@eecs.umich.edu        populated = true;
1033804Ssaidi@eecs.umich.edu
1043804Ssaidi@eecs.umich.edu        // If we get a sun4v format TTE, turn it into a sun4u
1053804Ssaidi@eecs.umich.edu        if (type == sun4u)
1063804Ssaidi@eecs.umich.edu            entry4u = entry;
1073804Ssaidi@eecs.umich.edu        else {
1083826Ssaidi@eecs.umich.edu            entry4u = 0;
1097741Sgblack@eecs.umich.edu            entry4u |= mbits(entry,63,63);         // valid
1107741Sgblack@eecs.umich.edu            entry4u |= bits(entry,1,0) << 61;      // size[1:0]
1117741Sgblack@eecs.umich.edu            entry4u |= bits(entry,62,62) << 60;    // nfo
1127741Sgblack@eecs.umich.edu            entry4u |= bits(entry,12,12) << 59;    // ie
1137741Sgblack@eecs.umich.edu            entry4u |= bits(entry,2,2) << 48;      // size[2]
1147741Sgblack@eecs.umich.edu            entry4u |= mbits(entry,39,13);         // paddr
1153826Ssaidi@eecs.umich.edu            entry4u |= bits(entry,61,61) << 6;;    // locked
1167741Sgblack@eecs.umich.edu            entry4u |= bits(entry,10,10) << 5;     // cp
1177741Sgblack@eecs.umich.edu            entry4u |= bits(entry,9,9) << 4;       // cv
1187741Sgblack@eecs.umich.edu            entry4u |= bits(entry,11,11) << 3;     // e
1197741Sgblack@eecs.umich.edu            entry4u |= bits(entry,8,8) << 2;       // p
1207741Sgblack@eecs.umich.edu            entry4u |= bits(entry,6,6) << 1;       // w
1213804Ssaidi@eecs.umich.edu        }
1223804Ssaidi@eecs.umich.edu    }
1233804Ssaidi@eecs.umich.edu
1245555Snate@binkert.org    void
1255555Snate@binkert.org    clear()
1263804Ssaidi@eecs.umich.edu    {
1273804Ssaidi@eecs.umich.edu        populated = false;
1283804Ssaidi@eecs.umich.edu    }
1293804Ssaidi@eecs.umich.edu
1303804Ssaidi@eecs.umich.edu    static int pageSizes[6];
1313804Ssaidi@eecs.umich.edu
1325555Snate@binkert.org    uint64_t operator()() const { assert(populated); return entry4u; }
1337741Sgblack@eecs.umich.edu
1345555Snate@binkert.org    const PageTableEntry &
1355555Snate@binkert.org    operator=(uint64_t e)
1365555Snate@binkert.org    {
1375555Snate@binkert.org        populated = true;
1385555Snate@binkert.org        entry4u = e;
1395555Snate@binkert.org        return *this;
1405555Snate@binkert.org    }
1413804Ssaidi@eecs.umich.edu
1425555Snate@binkert.org    const PageTableEntry &
1435555Snate@binkert.org    operator=(const PageTableEntry &e)
1445555Snate@binkert.org    {
1455555Snate@binkert.org        populated = true;
1465555Snate@binkert.org        entry4u = e.entry4u;
1475555Snate@binkert.org        type = e.type;
1485555Snate@binkert.org        return *this;
1495555Snate@binkert.org    }
1503804Ssaidi@eecs.umich.edu
1515555Snate@binkert.org    bool valid() const { return bits(entry4u,63,63) && populated; }
1523804Ssaidi@eecs.umich.edu
1535555Snate@binkert.org    uint8_t
1545555Snate@binkert.org    _size() const
1555555Snate@binkert.org    {
1565555Snate@binkert.org        assert(populated);
1575555Snate@binkert.org        return bits(entry4u, 62,61) | bits(entry4u, 48,48) << 2;
1585555Snate@binkert.org    }
1595555Snate@binkert.org
1605555Snate@binkert.org    Addr size()     const { assert(_size() < 6); return pageSizes[_size()]; }
1615555Snate@binkert.org    Addr sizeMask() const { return size() - 1; }
1625555Snate@binkert.org    bool ie()       const { return bits(entry4u, 59,59); }
1635555Snate@binkert.org    Addr pfn()      const { assert(populated); return bits(entry4u,39,13); }
1645555Snate@binkert.org    Addr paddr()    const { assert(populated); return mbits(entry4u, 39,13);}
1655555Snate@binkert.org    bool locked()   const { assert(populated); return bits(entry4u,6,6); }
1665555Snate@binkert.org    bool cv()       const { assert(populated); return bits(entry4u,4,4); }
1675555Snate@binkert.org    bool cp()       const { assert(populated); return bits(entry4u,5,5); }
1685555Snate@binkert.org    bool priv()     const { assert(populated); return bits(entry4u,2,2); }
1695555Snate@binkert.org    bool writable() const { assert(populated); return bits(entry4u,1,1); }
1705555Snate@binkert.org    bool nofault()  const { assert(populated); return bits(entry4u,60,60); }
1715555Snate@binkert.org    bool sideffect() const { assert(populated); return bits(entry4u,3,3); }
1725555Snate@binkert.org    Addr paddrMask() const { assert(populated); return paddr() & ~sizeMask(); }
1735555Snate@binkert.org
1745555Snate@binkert.org    Addr
1755555Snate@binkert.org    translate(Addr vaddr) const
1765555Snate@binkert.org    {
1775555Snate@binkert.org        assert(populated);
1785555Snate@binkert.org        Addr mask = sizeMask();
1795555Snate@binkert.org        return (paddr() & ~mask) | (vaddr & mask);
1805555Snate@binkert.org    }
1813804Ssaidi@eecs.umich.edu};
1823804Ssaidi@eecs.umich.edu
1835555Snate@binkert.orgstruct TlbRange
1845555Snate@binkert.org{
1853804Ssaidi@eecs.umich.edu    Addr va;
1863804Ssaidi@eecs.umich.edu    Addr size;
1873804Ssaidi@eecs.umich.edu    int contextId;
1883804Ssaidi@eecs.umich.edu    int partitionId;
1893804Ssaidi@eecs.umich.edu    bool real;
1903804Ssaidi@eecs.umich.edu
1915555Snate@binkert.org    inline bool
1925555Snate@binkert.org    operator<(const TlbRange &r2) const
1933804Ssaidi@eecs.umich.edu    {
1943804Ssaidi@eecs.umich.edu        if (real && !r2.real)
1953804Ssaidi@eecs.umich.edu            return true;
1963804Ssaidi@eecs.umich.edu        if (!real && r2.real)
1973804Ssaidi@eecs.umich.edu            return false;
1983804Ssaidi@eecs.umich.edu
1993804Ssaidi@eecs.umich.edu        if (!real && !r2.real) {
2003804Ssaidi@eecs.umich.edu            if (contextId < r2.contextId)
2013804Ssaidi@eecs.umich.edu                return true;
2023804Ssaidi@eecs.umich.edu            else if (contextId > r2.contextId)
2033804Ssaidi@eecs.umich.edu                return false;
2043804Ssaidi@eecs.umich.edu        }
2053804Ssaidi@eecs.umich.edu
2063804Ssaidi@eecs.umich.edu        if (partitionId < r2.partitionId)
2073804Ssaidi@eecs.umich.edu            return true;
2083804Ssaidi@eecs.umich.edu        else if (partitionId > r2.partitionId)
2093804Ssaidi@eecs.umich.edu            return false;
2103804Ssaidi@eecs.umich.edu
2113804Ssaidi@eecs.umich.edu        if (va < r2.va)
2123804Ssaidi@eecs.umich.edu            return true;
2133804Ssaidi@eecs.umich.edu        return false;
2143804Ssaidi@eecs.umich.edu    }
2155555Snate@binkert.org
2165555Snate@binkert.org    inline bool
2175555Snate@binkert.org    operator==(const TlbRange &r2) const
2183804Ssaidi@eecs.umich.edu    {
2193804Ssaidi@eecs.umich.edu        return va == r2.va &&
2203804Ssaidi@eecs.umich.edu               size == r2.size &&
2213804Ssaidi@eecs.umich.edu               contextId == r2.contextId &&
2223804Ssaidi@eecs.umich.edu               partitionId == r2.partitionId &&
2233804Ssaidi@eecs.umich.edu               real == r2.real;
2243804Ssaidi@eecs.umich.edu    }
2253804Ssaidi@eecs.umich.edu};
2263804Ssaidi@eecs.umich.edu
2273804Ssaidi@eecs.umich.edu
2285555Snate@binkert.orgstruct TlbEntry
2295555Snate@binkert.org{
2305555Snate@binkert.org    TlbEntry()
2315555Snate@binkert.org    {}
2325555Snate@binkert.org
23310558Salexandru.dutu@amd.com    TlbEntry(Addr asn, Addr vaddr, Addr paddr,
23410558Salexandru.dutu@amd.com             bool uncacheable, bool read_only)
2355184Sgblack@eecs.umich.edu    {
2365184Sgblack@eecs.umich.edu        uint64_t entry = 0;
23710558Salexandru.dutu@amd.com        if (!read_only)
23810558Salexandru.dutu@amd.com            entry |= 1ULL << 1; // Writable
2395184Sgblack@eecs.umich.edu        entry |= 0ULL << 2; // Available in nonpriveleged mode
2405184Sgblack@eecs.umich.edu        entry |= 0ULL << 3; // No side effects
24110558Salexandru.dutu@amd.com        if (!uncacheable) {
24210558Salexandru.dutu@amd.com            entry |= 1ULL << 4; // Virtually cachable
24310558Salexandru.dutu@amd.com            entry |= 1ULL << 5; // Physically cachable
24410558Salexandru.dutu@amd.com        }
2455184Sgblack@eecs.umich.edu        entry |= 0ULL << 6; // Not locked
2465184Sgblack@eecs.umich.edu        entry |= mbits(paddr, 39, 13); // Physical address
2475184Sgblack@eecs.umich.edu        entry |= 0ULL << 48; // size = 8k
2485184Sgblack@eecs.umich.edu        entry |= 0uLL << 59; // Endianness not inverted
2495184Sgblack@eecs.umich.edu        entry |= 0ULL << 60; // Not no fault only
2505184Sgblack@eecs.umich.edu        entry |= 0ULL << 61; // size = 8k
2515184Sgblack@eecs.umich.edu        entry |= 1ULL << 63; // valid
2525184Sgblack@eecs.umich.edu        pte = PageTableEntry(entry);
2535184Sgblack@eecs.umich.edu
2545184Sgblack@eecs.umich.edu        range.va = vaddr;
2555184Sgblack@eecs.umich.edu        range.size = 8*(1<<10);
2565184Sgblack@eecs.umich.edu        range.contextId = asn;
2575184Sgblack@eecs.umich.edu        range.partitionId = 0;
2585184Sgblack@eecs.umich.edu        range.real = false;
2595184Sgblack@eecs.umich.edu
2605184Sgblack@eecs.umich.edu        valid = true;
2615184Sgblack@eecs.umich.edu    }
2625555Snate@binkert.org
2633804Ssaidi@eecs.umich.edu    TlbRange range;
2643804Ssaidi@eecs.umich.edu    PageTableEntry pte;
2653804Ssaidi@eecs.umich.edu    bool used;
2663804Ssaidi@eecs.umich.edu    bool valid;
2673804Ssaidi@eecs.umich.edu
2687741Sgblack@eecs.umich.edu    Addr
2697741Sgblack@eecs.umich.edu    pageStart()
2705184Sgblack@eecs.umich.edu    {
2715184Sgblack@eecs.umich.edu        return pte.paddr();
2725184Sgblack@eecs.umich.edu    }
2735184Sgblack@eecs.umich.edu
2745877Shsul@eecs.umich.edu    void
2755877Shsul@eecs.umich.edu    updateVaddr(Addr new_vaddr)
2765877Shsul@eecs.umich.edu    {
2775877Shsul@eecs.umich.edu        range.va = new_vaddr;
2785877Shsul@eecs.umich.edu    }
2795877Shsul@eecs.umich.edu
28010905Sandreas.sandberg@arm.com    void serialize(CheckpointOut &cp) const;
28110905Sandreas.sandberg@arm.com    void unserialize(CheckpointIn &cp);
2823804Ssaidi@eecs.umich.edu};
2833804Ssaidi@eecs.umich.edu
2845555Snate@binkert.org} // namespace SparcISA
2853804Ssaidi@eecs.umich.edu
2863804Ssaidi@eecs.umich.edu#endif // __ARCH_SPARC_PAGE_TABLE_HH__
2873804Ssaidi@eecs.umich.edu
288