pagetable.hh revision 5555
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 343804Ssaidi@eecs.umich.edu#include "arch/sparc/isa_traits.hh" 353826Ssaidi@eecs.umich.edu#include "base/bitfield.hh" 363809Sgblack@eecs.umich.edu#include "base/misc.hh" 373804Ssaidi@eecs.umich.edu#include "config/full_system.hh" 383804Ssaidi@eecs.umich.edu 393809Sgblack@eecs.umich.educlass Checkpoint; 403809Sgblack@eecs.umich.edu 415555Snate@binkert.orgnamespace SparcISA { 425555Snate@binkert.org 433804Ssaidi@eecs.umich.edustruct VAddr 443804Ssaidi@eecs.umich.edu{ 453804Ssaidi@eecs.umich.edu VAddr(Addr a) { panic("not implemented yet."); } 463804Ssaidi@eecs.umich.edu}; 473804Ssaidi@eecs.umich.edu 484070Ssaidi@eecs.umich.educlass TteTag 494070Ssaidi@eecs.umich.edu{ 504070Ssaidi@eecs.umich.edu private: 514070Ssaidi@eecs.umich.edu uint64_t entry; 524070Ssaidi@eecs.umich.edu bool populated; 534070Ssaidi@eecs.umich.edu 544070Ssaidi@eecs.umich.edu public: 554070Ssaidi@eecs.umich.edu TteTag() : entry(0), populated(false) {} 564070Ssaidi@eecs.umich.edu TteTag(uint64_t e) : entry(e), populated(true) {} 575555Snate@binkert.org 585555Snate@binkert.org const TteTag & 595555Snate@binkert.org operator=(uint64_t e) 605555Snate@binkert.org { 615555Snate@binkert.org populated = true; 625555Snate@binkert.org entry = e; 635555Snate@binkert.org return *this; 645555Snate@binkert.org } 655555Snate@binkert.org 664070Ssaidi@eecs.umich.edu bool valid() const {assert(populated); return !bits(entry,62,62); } 674070Ssaidi@eecs.umich.edu Addr va() const {assert(populated); return bits(entry,41,0); } 684070Ssaidi@eecs.umich.edu}; 694070Ssaidi@eecs.umich.edu 704070Ssaidi@eecs.umich.edu 713804Ssaidi@eecs.umich.educlass PageTableEntry 723804Ssaidi@eecs.umich.edu{ 733804Ssaidi@eecs.umich.edu public: 743804Ssaidi@eecs.umich.edu enum EntryType { 753804Ssaidi@eecs.umich.edu sun4v, 763804Ssaidi@eecs.umich.edu sun4u, 773804Ssaidi@eecs.umich.edu invalid 783804Ssaidi@eecs.umich.edu }; 793804Ssaidi@eecs.umich.edu 803804Ssaidi@eecs.umich.edu private: 813804Ssaidi@eecs.umich.edu uint64_t entry; 823804Ssaidi@eecs.umich.edu EntryType type; 833804Ssaidi@eecs.umich.edu uint64_t entry4u; 843804Ssaidi@eecs.umich.edu bool populated; 853804Ssaidi@eecs.umich.edu 863804Ssaidi@eecs.umich.edu public: 875555Snate@binkert.org PageTableEntry() 885555Snate@binkert.org : 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 973804Ssaidi@eecs.umich.edu void populate(uint64_t e, EntryType t = sun4u) 983804Ssaidi@eecs.umich.edu { 993804Ssaidi@eecs.umich.edu entry = e; 1003804Ssaidi@eecs.umich.edu type = t; 1013804Ssaidi@eecs.umich.edu populated = true; 1023804Ssaidi@eecs.umich.edu 1033804Ssaidi@eecs.umich.edu // If we get a sun4v format TTE, turn it into a sun4u 1043804Ssaidi@eecs.umich.edu if (type == sun4u) 1053804Ssaidi@eecs.umich.edu entry4u = entry; 1063804Ssaidi@eecs.umich.edu else { 1073826Ssaidi@eecs.umich.edu entry4u = 0; 1083826Ssaidi@eecs.umich.edu entry4u |= mbits(entry,63,63); //valid 1093826Ssaidi@eecs.umich.edu entry4u |= bits(entry,1,0) << 61; //size[1:0] 1103826Ssaidi@eecs.umich.edu entry4u |= bits(entry,62,62) << 60; //nfo 1113826Ssaidi@eecs.umich.edu entry4u |= bits(entry,12,12) << 59; //ie 1123826Ssaidi@eecs.umich.edu entry4u |= bits(entry,2,2) << 48; //size[2] 1133826Ssaidi@eecs.umich.edu entry4u |= mbits(entry,39,13); //paddr 1143826Ssaidi@eecs.umich.edu entry4u |= bits(entry,61,61) << 6;; // locked 1153826Ssaidi@eecs.umich.edu entry4u |= bits(entry,10,10) << 5; //cp 1163826Ssaidi@eecs.umich.edu entry4u |= bits(entry,9,9) << 4; //cv 1173826Ssaidi@eecs.umich.edu entry4u |= bits(entry,11,11) << 3; //e 1183826Ssaidi@eecs.umich.edu entry4u |= bits(entry,8,8) << 2; //p 1193826Ssaidi@eecs.umich.edu entry4u |= bits(entry,6,6) << 1; //w 1203804Ssaidi@eecs.umich.edu } 1213804Ssaidi@eecs.umich.edu } 1223804Ssaidi@eecs.umich.edu 1235555Snate@binkert.org void 1245555Snate@binkert.org clear() 1253804Ssaidi@eecs.umich.edu { 1263804Ssaidi@eecs.umich.edu populated = false; 1273804Ssaidi@eecs.umich.edu } 1283804Ssaidi@eecs.umich.edu 1293804Ssaidi@eecs.umich.edu static int pageSizes[6]; 1303804Ssaidi@eecs.umich.edu 1315555Snate@binkert.org uint64_t operator()() const { assert(populated); return entry4u; } 1325555Snate@binkert.org const PageTableEntry & 1335555Snate@binkert.org operator=(uint64_t e) 1345555Snate@binkert.org { 1355555Snate@binkert.org populated = true; 1365555Snate@binkert.org entry4u = e; 1375555Snate@binkert.org return *this; 1385555Snate@binkert.org } 1393804Ssaidi@eecs.umich.edu 1405555Snate@binkert.org const PageTableEntry & 1415555Snate@binkert.org operator=(const PageTableEntry &e) 1425555Snate@binkert.org { 1435555Snate@binkert.org populated = true; 1445555Snate@binkert.org entry4u = e.entry4u; 1455555Snate@binkert.org type = e.type; 1465555Snate@binkert.org return *this; 1475555Snate@binkert.org } 1483804Ssaidi@eecs.umich.edu 1495555Snate@binkert.org bool valid() const { return bits(entry4u,63,63) && populated; } 1503804Ssaidi@eecs.umich.edu 1515555Snate@binkert.org uint8_t 1525555Snate@binkert.org _size() const 1535555Snate@binkert.org { 1545555Snate@binkert.org assert(populated); 1555555Snate@binkert.org return bits(entry4u, 62,61) | bits(entry4u, 48,48) << 2; 1565555Snate@binkert.org } 1575555Snate@binkert.org 1585555Snate@binkert.org Addr size() const { assert(_size() < 6); return pageSizes[_size()]; } 1595555Snate@binkert.org Addr sizeMask() const { return size() - 1; } 1605555Snate@binkert.org bool ie() const { return bits(entry4u, 59,59); } 1615555Snate@binkert.org Addr pfn() const { assert(populated); return bits(entry4u,39,13); } 1625555Snate@binkert.org Addr paddr() const { assert(populated); return mbits(entry4u, 39,13);} 1635555Snate@binkert.org bool locked() const { assert(populated); return bits(entry4u,6,6); } 1645555Snate@binkert.org bool cv() const { assert(populated); return bits(entry4u,4,4); } 1655555Snate@binkert.org bool cp() const { assert(populated); return bits(entry4u,5,5); } 1665555Snate@binkert.org bool priv() const { assert(populated); return bits(entry4u,2,2); } 1675555Snate@binkert.org bool writable() const { assert(populated); return bits(entry4u,1,1); } 1685555Snate@binkert.org bool nofault() const { assert(populated); return bits(entry4u,60,60); } 1695555Snate@binkert.org bool sideffect() const { assert(populated); return bits(entry4u,3,3); } 1705555Snate@binkert.org Addr paddrMask() const { assert(populated); return paddr() & ~sizeMask(); } 1715555Snate@binkert.org 1725555Snate@binkert.org Addr 1735555Snate@binkert.org translate(Addr vaddr) const 1745555Snate@binkert.org { 1755555Snate@binkert.org assert(populated); 1765555Snate@binkert.org Addr mask = sizeMask(); 1775555Snate@binkert.org return (paddr() & ~mask) | (vaddr & mask); 1785555Snate@binkert.org } 1793804Ssaidi@eecs.umich.edu}; 1803804Ssaidi@eecs.umich.edu 1815555Snate@binkert.orgstruct TlbRange 1825555Snate@binkert.org{ 1833804Ssaidi@eecs.umich.edu Addr va; 1843804Ssaidi@eecs.umich.edu Addr size; 1853804Ssaidi@eecs.umich.edu int contextId; 1863804Ssaidi@eecs.umich.edu int partitionId; 1873804Ssaidi@eecs.umich.edu bool real; 1883804Ssaidi@eecs.umich.edu 1895555Snate@binkert.org inline bool 1905555Snate@binkert.org operator<(const TlbRange &r2) const 1913804Ssaidi@eecs.umich.edu { 1923804Ssaidi@eecs.umich.edu if (real && !r2.real) 1933804Ssaidi@eecs.umich.edu return true; 1943804Ssaidi@eecs.umich.edu if (!real && r2.real) 1953804Ssaidi@eecs.umich.edu return false; 1963804Ssaidi@eecs.umich.edu 1973804Ssaidi@eecs.umich.edu if (!real && !r2.real) { 1983804Ssaidi@eecs.umich.edu if (contextId < r2.contextId) 1993804Ssaidi@eecs.umich.edu return true; 2003804Ssaidi@eecs.umich.edu else if (contextId > r2.contextId) 2013804Ssaidi@eecs.umich.edu return false; 2023804Ssaidi@eecs.umich.edu } 2033804Ssaidi@eecs.umich.edu 2043804Ssaidi@eecs.umich.edu if (partitionId < r2.partitionId) 2053804Ssaidi@eecs.umich.edu return true; 2063804Ssaidi@eecs.umich.edu else if (partitionId > r2.partitionId) 2073804Ssaidi@eecs.umich.edu return false; 2083804Ssaidi@eecs.umich.edu 2093804Ssaidi@eecs.umich.edu if (va < r2.va) 2103804Ssaidi@eecs.umich.edu return true; 2113804Ssaidi@eecs.umich.edu return false; 2123804Ssaidi@eecs.umich.edu } 2135555Snate@binkert.org 2145555Snate@binkert.org inline bool 2155555Snate@binkert.org operator==(const TlbRange &r2) const 2163804Ssaidi@eecs.umich.edu { 2173804Ssaidi@eecs.umich.edu return va == r2.va && 2183804Ssaidi@eecs.umich.edu size == r2.size && 2193804Ssaidi@eecs.umich.edu contextId == r2.contextId && 2203804Ssaidi@eecs.umich.edu partitionId == r2.partitionId && 2213804Ssaidi@eecs.umich.edu real == r2.real; 2223804Ssaidi@eecs.umich.edu } 2233804Ssaidi@eecs.umich.edu}; 2243804Ssaidi@eecs.umich.edu 2253804Ssaidi@eecs.umich.edu 2265555Snate@binkert.orgstruct TlbEntry 2275555Snate@binkert.org{ 2285555Snate@binkert.org TlbEntry() 2295555Snate@binkert.org {} 2305555Snate@binkert.org 2315184Sgblack@eecs.umich.edu TlbEntry(Addr asn, Addr vaddr, Addr paddr) 2325184Sgblack@eecs.umich.edu { 2335184Sgblack@eecs.umich.edu uint64_t entry = 0; 2345184Sgblack@eecs.umich.edu entry |= 1ULL << 1; // Writable 2355184Sgblack@eecs.umich.edu entry |= 0ULL << 2; // Available in nonpriveleged mode 2365184Sgblack@eecs.umich.edu entry |= 0ULL << 3; // No side effects 2375184Sgblack@eecs.umich.edu entry |= 1ULL << 4; // Virtually cachable 2385184Sgblack@eecs.umich.edu entry |= 1ULL << 5; // Physically cachable 2395184Sgblack@eecs.umich.edu entry |= 0ULL << 6; // Not locked 2405184Sgblack@eecs.umich.edu entry |= mbits(paddr, 39, 13); // Physical address 2415184Sgblack@eecs.umich.edu entry |= 0ULL << 48; // size = 8k 2425184Sgblack@eecs.umich.edu entry |= 0uLL << 59; // Endianness not inverted 2435184Sgblack@eecs.umich.edu entry |= 0ULL << 60; // Not no fault only 2445184Sgblack@eecs.umich.edu entry |= 0ULL << 61; // size = 8k 2455184Sgblack@eecs.umich.edu entry |= 1ULL << 63; // valid 2465184Sgblack@eecs.umich.edu pte = PageTableEntry(entry); 2475184Sgblack@eecs.umich.edu 2485184Sgblack@eecs.umich.edu range.va = vaddr; 2495184Sgblack@eecs.umich.edu range.size = 8*(1<<10); 2505184Sgblack@eecs.umich.edu range.contextId = asn; 2515184Sgblack@eecs.umich.edu range.partitionId = 0; 2525184Sgblack@eecs.umich.edu range.real = false; 2535184Sgblack@eecs.umich.edu 2545184Sgblack@eecs.umich.edu valid = true; 2555184Sgblack@eecs.umich.edu } 2565555Snate@binkert.org 2573804Ssaidi@eecs.umich.edu TlbRange range; 2583804Ssaidi@eecs.umich.edu PageTableEntry pte; 2593804Ssaidi@eecs.umich.edu bool used; 2603804Ssaidi@eecs.umich.edu bool valid; 2613804Ssaidi@eecs.umich.edu 2625184Sgblack@eecs.umich.edu Addr pageStart() 2635184Sgblack@eecs.umich.edu { 2645184Sgblack@eecs.umich.edu return pte.paddr(); 2655184Sgblack@eecs.umich.edu } 2665184Sgblack@eecs.umich.edu 2673804Ssaidi@eecs.umich.edu void serialize(std::ostream &os); 2683804Ssaidi@eecs.umich.edu void unserialize(Checkpoint *cp, const std::string §ion); 2693804Ssaidi@eecs.umich.edu}; 2703804Ssaidi@eecs.umich.edu 2715555Snate@binkert.org} // namespace SparcISA 2723804Ssaidi@eecs.umich.edu 2733804Ssaidi@eecs.umich.edu#endif // __ARCH_SPARC_PAGE_TABLE_HH__ 2743804Ssaidi@eecs.umich.edu 275