page_table.hh revision 10558
12379SN/A/* 210298Salexandru.dutu@amd.com * Copyright (c) 2014 Advanced Micro Devices, Inc. 32379SN/A * Copyright (c) 2003 The Regents of The University of Michigan 42379SN/A * All rights reserved. 52379SN/A * 62379SN/A * Redistribution and use in source and binary forms, with or without 72379SN/A * modification, are permitted provided that the following conditions are 82379SN/A * met: redistributions of source code must retain the above copyright 92379SN/A * notice, this list of conditions and the following disclaimer; 102379SN/A * redistributions in binary form must reproduce the above copyright 112379SN/A * notice, this list of conditions and the following disclaimer in the 122379SN/A * documentation and/or other materials provided with the distribution; 132379SN/A * neither the name of the copyright holders nor the names of its 142379SN/A * contributors may be used to endorse or promote products derived from 152379SN/A * this software without specific prior written permission. 162379SN/A * 172379SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 182379SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 192379SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 202379SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 212379SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 222379SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 232379SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 242379SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 252379SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 262379SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 272379SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 282665Ssaidi@eecs.umich.edu * 292665Ssaidi@eecs.umich.edu * Authors: Steve Reinhardt 302379SN/A */ 312379SN/A 322379SN/A/** 332379SN/A * @file 3410298Salexandru.dutu@amd.com * Declarations of a non-full system Page Table. 352379SN/A */ 362379SN/A 376216Snate@binkert.org#ifndef __MEM_PAGE_TABLE_HH__ 386216Snate@binkert.org#define __MEM_PAGE_TABLE_HH__ 392379SN/A 402379SN/A#include <string> 412379SN/A 422423SN/A#include "arch/isa_traits.hh" 435004Sgblack@eecs.umich.edu#include "arch/tlb.hh" 442809Ssaidi@eecs.umich.edu#include "base/hashmap.hh" 456216Snate@binkert.org#include "base/types.hh" 466658Snate@binkert.org#include "config/the_isa.hh" 472394SN/A#include "mem/request.hh" 485004Sgblack@eecs.umich.edu#include "sim/serialize.hh" 4910298Salexandru.dutu@amd.com#include "sim/system.hh" 5010298Salexandru.dutu@amd.com 5110298Salexandru.dutu@amd.comclass ThreadContext; 522379SN/A 532379SN/A/** 5410298Salexandru.dutu@amd.com * Declaration of base class for page table 552379SN/A */ 5610298Salexandru.dutu@amd.comclass PageTableBase 572379SN/A{ 582379SN/A protected: 592809Ssaidi@eecs.umich.edu struct cacheElement { 609676Smitch.hayenga+gem5@gmail.com bool valid; 612809Ssaidi@eecs.umich.edu Addr vaddr; 625004Sgblack@eecs.umich.edu TheISA::TlbEntry entry; 635004Sgblack@eecs.umich.edu }; 642809Ssaidi@eecs.umich.edu 652809Ssaidi@eecs.umich.edu struct cacheElement pTableCache[3]; 662379SN/A 672399SN/A const Addr pageSize; 682399SN/A const Addr offsetMask; 692399SN/A 708601Ssteve.reinhardt@amd.com const uint64_t pid; 718601Ssteve.reinhardt@amd.com const std::string _name; 722379SN/A 732379SN/A public: 742379SN/A 7510298Salexandru.dutu@amd.com PageTableBase(const std::string &__name, uint64_t _pid, 7610318Sandreas.hansson@arm.com Addr _pageSize = TheISA::PageBytes) 7710298Salexandru.dutu@amd.com : pageSize(_pageSize), offsetMask(mask(floorLog2(_pageSize))), 7810298Salexandru.dutu@amd.com pid(_pid), _name(__name) 7910298Salexandru.dutu@amd.com { 8010298Salexandru.dutu@amd.com assert(isPowerOf2(pageSize)); 8110298Salexandru.dutu@amd.com pTableCache[0].valid = false; 8210298Salexandru.dutu@amd.com pTableCache[1].valid = false; 8310298Salexandru.dutu@amd.com pTableCache[2].valid = false; 8410298Salexandru.dutu@amd.com } 852379SN/A 8610298Salexandru.dutu@amd.com virtual ~PageTableBase() {}; 8710298Salexandru.dutu@amd.com 8810558Salexandru.dutu@amd.com /* generic page table mapping flags 8910558Salexandru.dutu@amd.com * unset | set 9010558Salexandru.dutu@amd.com * bit 0 - no-clobber | clobber 9110558Salexandru.dutu@amd.com * bit 1 - present | not-present 9210558Salexandru.dutu@amd.com * bit 2 - cacheable | uncacheable 9310558Salexandru.dutu@amd.com * bit 3 - read-write | read-only 9410558Salexandru.dutu@amd.com */ 9510558Salexandru.dutu@amd.com enum MappingFlags : uint32_t { 9610558Salexandru.dutu@amd.com Clobber = 1, 9710558Salexandru.dutu@amd.com NotPresent = 2, 9810558Salexandru.dutu@amd.com Uncacheable = 4, 9910558Salexandru.dutu@amd.com ReadOnly = 8, 10010558Salexandru.dutu@amd.com }; 10110558Salexandru.dutu@amd.com 10210298Salexandru.dutu@amd.com virtual void initState(ThreadContext* tc) = 0; 1032379SN/A 1048601Ssteve.reinhardt@amd.com // for DPRINTF compatibility 1058601Ssteve.reinhardt@amd.com const std::string name() const { return _name; } 1068601Ssteve.reinhardt@amd.com 1072399SN/A Addr pageAlign(Addr a) { return (a & ~offsetMask); } 1082399SN/A Addr pageOffset(Addr a) { return (a & offsetMask); } 1092379SN/A 11010558Salexandru.dutu@amd.com /** 11110558Salexandru.dutu@amd.com * Maps a virtual memory region to a physical memory region. 11210558Salexandru.dutu@amd.com * @param vaddr The starting virtual address of the region. 11310558Salexandru.dutu@amd.com * @param paddr The starting physical address where the region is mapped. 11410558Salexandru.dutu@amd.com * @param size The length of the region. 11510558Salexandru.dutu@amd.com * @param flags Generic mapping flags that can be set by or-ing values 11610558Salexandru.dutu@amd.com * from MappingFlags enum. 11710558Salexandru.dutu@amd.com */ 11810556Salexandru.dutu@amd.com virtual void map(Addr vaddr, Addr paddr, int64_t size, 11910558Salexandru.dutu@amd.com uint64_t flags = 0) = 0; 12010298Salexandru.dutu@amd.com virtual void remap(Addr vaddr, int64_t size, Addr new_vaddr) = 0; 12110298Salexandru.dutu@amd.com virtual void unmap(Addr vaddr, int64_t size) = 0; 1222379SN/A 1235004Sgblack@eecs.umich.edu /** 1248600Ssteve.reinhardt@amd.com * Check if any pages in a region are already allocated 1258600Ssteve.reinhardt@amd.com * @param vaddr The starting virtual address of the region. 1268600Ssteve.reinhardt@amd.com * @param size The length of the region. 1278600Ssteve.reinhardt@amd.com * @return True if no pages in the region are mapped. 1288600Ssteve.reinhardt@amd.com */ 12910298Salexandru.dutu@amd.com virtual bool isUnmapped(Addr vaddr, int64_t size) = 0; 1308600Ssteve.reinhardt@amd.com 1318600Ssteve.reinhardt@amd.com /** 1325004Sgblack@eecs.umich.edu * Lookup function 1335004Sgblack@eecs.umich.edu * @param vaddr The virtual address. 1345004Sgblack@eecs.umich.edu * @return entry The page table entry corresponding to vaddr. 1355004Sgblack@eecs.umich.edu */ 13610298Salexandru.dutu@amd.com virtual bool lookup(Addr vaddr, TheISA::TlbEntry &entry) = 0; 1372399SN/A 1382379SN/A /** 1392379SN/A * Translate function 1402379SN/A * @param vaddr The virtual address. 1415748SSteve.Reinhardt@amd.com * @param paddr Physical address from translation. 1425748SSteve.Reinhardt@amd.com * @return True if translation exists 1432379SN/A */ 1442399SN/A bool translate(Addr vaddr, Addr &paddr); 1452379SN/A 1462379SN/A /** 1475748SSteve.Reinhardt@amd.com * Simplified translate function (just check for translation) 1485748SSteve.Reinhardt@amd.com * @param vaddr The virtual address. 1495748SSteve.Reinhardt@amd.com * @return True if translation exists 1505748SSteve.Reinhardt@amd.com */ 1515748SSteve.Reinhardt@amd.com bool translate(Addr vaddr) { Addr dummy; return translate(vaddr, dummy); } 1525748SSteve.Reinhardt@amd.com 1535748SSteve.Reinhardt@amd.com /** 1542399SN/A * Perform a translation on the memory request, fills in paddr 1555004Sgblack@eecs.umich.edu * field of req. 1562379SN/A * @param req The memory request. 1572379SN/A */ 1585004Sgblack@eecs.umich.edu Fault translate(RequestPtr req); 1592379SN/A 1604521Ssaidi@eecs.umich.edu /** 1614521Ssaidi@eecs.umich.edu * Update the page table cache. 1624521Ssaidi@eecs.umich.edu * @param vaddr virtual address (page aligned) to check 1635004Sgblack@eecs.umich.edu * @param pte page table entry to return 1644521Ssaidi@eecs.umich.edu */ 1655004Sgblack@eecs.umich.edu inline void updateCache(Addr vaddr, TheISA::TlbEntry entry) 1664521Ssaidi@eecs.umich.edu { 1675004Sgblack@eecs.umich.edu pTableCache[2].entry = pTableCache[1].entry; 1684521Ssaidi@eecs.umich.edu pTableCache[2].vaddr = pTableCache[1].vaddr; 1699676Smitch.hayenga+gem5@gmail.com pTableCache[2].valid = pTableCache[1].valid; 1709676Smitch.hayenga+gem5@gmail.com 1715004Sgblack@eecs.umich.edu pTableCache[1].entry = pTableCache[0].entry; 1724521Ssaidi@eecs.umich.edu pTableCache[1].vaddr = pTableCache[0].vaddr; 1739676Smitch.hayenga+gem5@gmail.com pTableCache[1].valid = pTableCache[0].valid; 1749676Smitch.hayenga+gem5@gmail.com 1755004Sgblack@eecs.umich.edu pTableCache[0].entry = entry; 1764521Ssaidi@eecs.umich.edu pTableCache[0].vaddr = vaddr; 1779676Smitch.hayenga+gem5@gmail.com pTableCache[0].valid = true; 1784521Ssaidi@eecs.umich.edu } 1794521Ssaidi@eecs.umich.edu 1809676Smitch.hayenga+gem5@gmail.com /** 1819676Smitch.hayenga+gem5@gmail.com * Erase an entry from the page table cache. 1829676Smitch.hayenga+gem5@gmail.com * @param vaddr virtual address (page aligned) to check 1839676Smitch.hayenga+gem5@gmail.com */ 1849676Smitch.hayenga+gem5@gmail.com inline void eraseCacheEntry(Addr vaddr) 1859676Smitch.hayenga+gem5@gmail.com { 1869676Smitch.hayenga+gem5@gmail.com // Invalidate cached entries if necessary 1879676Smitch.hayenga+gem5@gmail.com if (pTableCache[0].valid && pTableCache[0].vaddr == vaddr) { 1889676Smitch.hayenga+gem5@gmail.com pTableCache[0].valid = false; 1899676Smitch.hayenga+gem5@gmail.com } else if (pTableCache[1].valid && pTableCache[1].vaddr == vaddr) { 1909676Smitch.hayenga+gem5@gmail.com pTableCache[1].valid = false; 1919676Smitch.hayenga+gem5@gmail.com } else if (pTableCache[2].valid && pTableCache[2].vaddr == vaddr) { 1929676Smitch.hayenga+gem5@gmail.com pTableCache[2].valid = false; 1939676Smitch.hayenga+gem5@gmail.com } 1949676Smitch.hayenga+gem5@gmail.com } 1954521Ssaidi@eecs.umich.edu 19610298Salexandru.dutu@amd.com virtual void serialize(std::ostream &os) = 0; 19710298Salexandru.dutu@amd.com 19810298Salexandru.dutu@amd.com virtual void unserialize(Checkpoint *cp, const std::string §ion) = 0; 19910298Salexandru.dutu@amd.com}; 20010298Salexandru.dutu@amd.com 20110298Salexandru.dutu@amd.com/** 20210298Salexandru.dutu@amd.com * Declaration of functional page table. 20310298Salexandru.dutu@amd.com */ 20410298Salexandru.dutu@amd.comclass FuncPageTable : public PageTableBase 20510298Salexandru.dutu@amd.com{ 20610298Salexandru.dutu@amd.com private: 20710298Salexandru.dutu@amd.com typedef m5::hash_map<Addr, TheISA::TlbEntry> PTable; 20810298Salexandru.dutu@amd.com typedef PTable::iterator PTableItr; 20910298Salexandru.dutu@amd.com PTable pTable; 21010298Salexandru.dutu@amd.com 21110298Salexandru.dutu@amd.com public: 21210298Salexandru.dutu@amd.com 21310298Salexandru.dutu@amd.com FuncPageTable(const std::string &__name, uint64_t _pid, 21410318Sandreas.hansson@arm.com Addr _pageSize = TheISA::PageBytes); 21510298Salexandru.dutu@amd.com 21610298Salexandru.dutu@amd.com ~FuncPageTable(); 21710298Salexandru.dutu@amd.com 21810298Salexandru.dutu@amd.com void initState(ThreadContext* tc) 21910298Salexandru.dutu@amd.com { 22010298Salexandru.dutu@amd.com } 22110298Salexandru.dutu@amd.com 22210558Salexandru.dutu@amd.com void map(Addr vaddr, Addr paddr, int64_t size, 22310558Salexandru.dutu@amd.com uint64_t flags = 0); 22410298Salexandru.dutu@amd.com void remap(Addr vaddr, int64_t size, Addr new_vaddr); 22510298Salexandru.dutu@amd.com void unmap(Addr vaddr, int64_t size); 22610298Salexandru.dutu@amd.com 22710298Salexandru.dutu@amd.com /** 22810298Salexandru.dutu@amd.com * Check if any pages in a region are already allocated 22910298Salexandru.dutu@amd.com * @param vaddr The starting virtual address of the region. 23010298Salexandru.dutu@amd.com * @param size The length of the region. 23110298Salexandru.dutu@amd.com * @return True if no pages in the region are mapped. 23210298Salexandru.dutu@amd.com */ 23310298Salexandru.dutu@amd.com bool isUnmapped(Addr vaddr, int64_t size); 23410298Salexandru.dutu@amd.com 23510298Salexandru.dutu@amd.com /** 23610298Salexandru.dutu@amd.com * Lookup function 23710298Salexandru.dutu@amd.com * @param vaddr The virtual address. 23810298Salexandru.dutu@amd.com * @return entry The page table entry corresponding to vaddr. 23910298Salexandru.dutu@amd.com */ 24010298Salexandru.dutu@amd.com bool lookup(Addr vaddr, TheISA::TlbEntry &entry); 24110298Salexandru.dutu@amd.com 2423311Ssaidi@eecs.umich.edu void serialize(std::ostream &os); 2435004Sgblack@eecs.umich.edu 2443311Ssaidi@eecs.umich.edu void unserialize(Checkpoint *cp, const std::string §ion); 2452379SN/A}; 2462379SN/A 24710298Salexandru.dutu@amd.com/** 24810298Salexandru.dutu@amd.com * Faux page table class indended to stop the usage of 24910298Salexandru.dutu@amd.com * an architectural page table, when there is none defined 25010298Salexandru.dutu@amd.com * for a particular ISA. 25110298Salexandru.dutu@amd.com */ 25210298Salexandru.dutu@amd.comclass NoArchPageTable : public FuncPageTable 25310298Salexandru.dutu@amd.com{ 25410298Salexandru.dutu@amd.com public: 25510298Salexandru.dutu@amd.com NoArchPageTable(const std::string &__name, uint64_t _pid, System *_sys, 25610318Sandreas.hansson@arm.com Addr _pageSize = TheISA::PageBytes) : FuncPageTable(__name, _pid) 25710298Salexandru.dutu@amd.com { 25810298Salexandru.dutu@amd.com fatal("No architectural page table defined for this ISA.\n"); 25910298Salexandru.dutu@amd.com } 26010298Salexandru.dutu@amd.com}; 26110298Salexandru.dutu@amd.com 2626216Snate@binkert.org#endif // __MEM_PAGE_TABLE_HH__ 263