pagetable.hh revision 7087
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" 383809Sgblack@eecs.umich.edu#include "base/misc.hh" 393804Ssaidi@eecs.umich.edu#include "config/full_system.hh" 403804Ssaidi@eecs.umich.edu 413809Sgblack@eecs.umich.educlass Checkpoint; 423809Sgblack@eecs.umich.edu 435555Snate@binkert.orgnamespace SparcISA { 445555Snate@binkert.org 453804Ssaidi@eecs.umich.edustruct VAddr 463804Ssaidi@eecs.umich.edu{ 473804Ssaidi@eecs.umich.edu VAddr(Addr a) { panic("not implemented yet."); } 483804Ssaidi@eecs.umich.edu}; 493804Ssaidi@eecs.umich.edu 504070Ssaidi@eecs.umich.educlass TteTag 514070Ssaidi@eecs.umich.edu{ 524070Ssaidi@eecs.umich.edu private: 534070Ssaidi@eecs.umich.edu uint64_t entry; 544070Ssaidi@eecs.umich.edu bool populated; 554070Ssaidi@eecs.umich.edu 564070Ssaidi@eecs.umich.edu public: 574070Ssaidi@eecs.umich.edu TteTag() : entry(0), populated(false) {} 584070Ssaidi@eecs.umich.edu TteTag(uint64_t e) : entry(e), populated(true) {} 595555Snate@binkert.org 605555Snate@binkert.org const TteTag & 615555Snate@binkert.org operator=(uint64_t e) 625555Snate@binkert.org { 635555Snate@binkert.org populated = true; 645555Snate@binkert.org entry = e; 655555Snate@binkert.org return *this; 665555Snate@binkert.org } 675555Snate@binkert.org 684070Ssaidi@eecs.umich.edu bool valid() const {assert(populated); return !bits(entry,62,62); } 694070Ssaidi@eecs.umich.edu Addr va() const {assert(populated); return bits(entry,41,0); } 704070Ssaidi@eecs.umich.edu}; 714070Ssaidi@eecs.umich.edu 724070Ssaidi@eecs.umich.edu 733804Ssaidi@eecs.umich.educlass PageTableEntry 743804Ssaidi@eecs.umich.edu{ 753804Ssaidi@eecs.umich.edu public: 763804Ssaidi@eecs.umich.edu enum EntryType { 773804Ssaidi@eecs.umich.edu sun4v, 783804Ssaidi@eecs.umich.edu sun4u, 793804Ssaidi@eecs.umich.edu invalid 803804Ssaidi@eecs.umich.edu }; 813804Ssaidi@eecs.umich.edu 823804Ssaidi@eecs.umich.edu private: 833804Ssaidi@eecs.umich.edu uint64_t entry; 843804Ssaidi@eecs.umich.edu EntryType type; 853804Ssaidi@eecs.umich.edu uint64_t entry4u; 863804Ssaidi@eecs.umich.edu bool populated; 873804Ssaidi@eecs.umich.edu 883804Ssaidi@eecs.umich.edu public: 895555Snate@binkert.org PageTableEntry() 905555Snate@binkert.org : entry(0), type(invalid), populated(false) 915555Snate@binkert.org {} 923804Ssaidi@eecs.umich.edu 933804Ssaidi@eecs.umich.edu PageTableEntry(uint64_t e, EntryType t = sun4u) 943804Ssaidi@eecs.umich.edu : entry(e), type(t), populated(true) 953804Ssaidi@eecs.umich.edu { 963804Ssaidi@eecs.umich.edu populate(entry, type); 973804Ssaidi@eecs.umich.edu } 983804Ssaidi@eecs.umich.edu 993804Ssaidi@eecs.umich.edu void populate(uint64_t e, EntryType t = sun4u) 1003804Ssaidi@eecs.umich.edu { 1013804Ssaidi@eecs.umich.edu entry = e; 1023804Ssaidi@eecs.umich.edu type = t; 1033804Ssaidi@eecs.umich.edu populated = true; 1043804Ssaidi@eecs.umich.edu 1053804Ssaidi@eecs.umich.edu // If we get a sun4v format TTE, turn it into a sun4u 1063804Ssaidi@eecs.umich.edu if (type == sun4u) 1073804Ssaidi@eecs.umich.edu entry4u = entry; 1083804Ssaidi@eecs.umich.edu else { 1093826Ssaidi@eecs.umich.edu entry4u = 0; 1103826Ssaidi@eecs.umich.edu entry4u |= mbits(entry,63,63); //valid 1113826Ssaidi@eecs.umich.edu entry4u |= bits(entry,1,0) << 61; //size[1:0] 1123826Ssaidi@eecs.umich.edu entry4u |= bits(entry,62,62) << 60; //nfo 1133826Ssaidi@eecs.umich.edu entry4u |= bits(entry,12,12) << 59; //ie 1143826Ssaidi@eecs.umich.edu entry4u |= bits(entry,2,2) << 48; //size[2] 1153826Ssaidi@eecs.umich.edu entry4u |= mbits(entry,39,13); //paddr 1163826Ssaidi@eecs.umich.edu entry4u |= bits(entry,61,61) << 6;; // locked 1173826Ssaidi@eecs.umich.edu entry4u |= bits(entry,10,10) << 5; //cp 1183826Ssaidi@eecs.umich.edu entry4u |= bits(entry,9,9) << 4; //cv 1193826Ssaidi@eecs.umich.edu entry4u |= bits(entry,11,11) << 3; //e 1203826Ssaidi@eecs.umich.edu entry4u |= bits(entry,8,8) << 2; //p 1213826Ssaidi@eecs.umich.edu entry4u |= bits(entry,6,6) << 1; //w 1223804Ssaidi@eecs.umich.edu } 1233804Ssaidi@eecs.umich.edu } 1243804Ssaidi@eecs.umich.edu 1255555Snate@binkert.org void 1265555Snate@binkert.org clear() 1273804Ssaidi@eecs.umich.edu { 1283804Ssaidi@eecs.umich.edu populated = false; 1293804Ssaidi@eecs.umich.edu } 1303804Ssaidi@eecs.umich.edu 1313804Ssaidi@eecs.umich.edu static int pageSizes[6]; 1323804Ssaidi@eecs.umich.edu 1335555Snate@binkert.org uint64_t operator()() const { assert(populated); return entry4u; } 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 2335184Sgblack@eecs.umich.edu TlbEntry(Addr asn, Addr vaddr, Addr paddr) 2345184Sgblack@eecs.umich.edu { 2355184Sgblack@eecs.umich.edu uint64_t entry = 0; 2365184Sgblack@eecs.umich.edu entry |= 1ULL << 1; // Writable 2375184Sgblack@eecs.umich.edu entry |= 0ULL << 2; // Available in nonpriveleged mode 2385184Sgblack@eecs.umich.edu entry |= 0ULL << 3; // No side effects 2395184Sgblack@eecs.umich.edu entry |= 1ULL << 4; // Virtually cachable 2405184Sgblack@eecs.umich.edu entry |= 1ULL << 5; // Physically cachable 2415184Sgblack@eecs.umich.edu entry |= 0ULL << 6; // Not locked 2425184Sgblack@eecs.umich.edu entry |= mbits(paddr, 39, 13); // Physical address 2435184Sgblack@eecs.umich.edu entry |= 0ULL << 48; // size = 8k 2445184Sgblack@eecs.umich.edu entry |= 0uLL << 59; // Endianness not inverted 2455184Sgblack@eecs.umich.edu entry |= 0ULL << 60; // Not no fault only 2465184Sgblack@eecs.umich.edu entry |= 0ULL << 61; // size = 8k 2475184Sgblack@eecs.umich.edu entry |= 1ULL << 63; // valid 2485184Sgblack@eecs.umich.edu pte = PageTableEntry(entry); 2495184Sgblack@eecs.umich.edu 2505184Sgblack@eecs.umich.edu range.va = vaddr; 2515184Sgblack@eecs.umich.edu range.size = 8*(1<<10); 2525184Sgblack@eecs.umich.edu range.contextId = asn; 2535184Sgblack@eecs.umich.edu range.partitionId = 0; 2545184Sgblack@eecs.umich.edu range.real = false; 2555184Sgblack@eecs.umich.edu 2565184Sgblack@eecs.umich.edu valid = true; 2575184Sgblack@eecs.umich.edu } 2585555Snate@binkert.org 2593804Ssaidi@eecs.umich.edu TlbRange range; 2603804Ssaidi@eecs.umich.edu PageTableEntry pte; 2613804Ssaidi@eecs.umich.edu bool used; 2623804Ssaidi@eecs.umich.edu bool valid; 2633804Ssaidi@eecs.umich.edu 2645184Sgblack@eecs.umich.edu Addr pageStart() 2655184Sgblack@eecs.umich.edu { 2665184Sgblack@eecs.umich.edu return pte.paddr(); 2675184Sgblack@eecs.umich.edu } 2685184Sgblack@eecs.umich.edu 2695877Shsul@eecs.umich.edu void 2705877Shsul@eecs.umich.edu updateVaddr(Addr new_vaddr) 2715877Shsul@eecs.umich.edu { 2725877Shsul@eecs.umich.edu range.va = new_vaddr; 2735877Shsul@eecs.umich.edu } 2745877Shsul@eecs.umich.edu 2753804Ssaidi@eecs.umich.edu void serialize(std::ostream &os); 2763804Ssaidi@eecs.umich.edu void unserialize(Checkpoint *cp, const std::string §ion); 2773804Ssaidi@eecs.umich.edu}; 2783804Ssaidi@eecs.umich.edu 2795555Snate@binkert.org} // namespace SparcISA 2803804Ssaidi@eecs.umich.edu 2813804Ssaidi@eecs.umich.edu#endif // __ARCH_SPARC_PAGE_TABLE_HH__ 2823804Ssaidi@eecs.umich.edu 283