page_table.hh revision 10318
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 8810298Salexandru.dutu@amd.com virtual void initState(ThreadContext* tc) = 0; 892379SN/A 908601Ssteve.reinhardt@amd.com // for DPRINTF compatibility 918601Ssteve.reinhardt@amd.com const std::string name() const { return _name; } 928601Ssteve.reinhardt@amd.com 932399SN/A Addr pageAlign(Addr a) { return (a & ~offsetMask); } 942399SN/A Addr pageOffset(Addr a) { return (a & offsetMask); } 952379SN/A 9610298Salexandru.dutu@amd.com virtual void map(Addr vaddr, Addr paddr, int64_t size, bool clobber = false) = 0; 9710298Salexandru.dutu@amd.com virtual void remap(Addr vaddr, int64_t size, Addr new_vaddr) = 0; 9810298Salexandru.dutu@amd.com virtual void unmap(Addr vaddr, int64_t size) = 0; 992379SN/A 1005004Sgblack@eecs.umich.edu /** 1018600Ssteve.reinhardt@amd.com * Check if any pages in a region are already allocated 1028600Ssteve.reinhardt@amd.com * @param vaddr The starting virtual address of the region. 1038600Ssteve.reinhardt@amd.com * @param size The length of the region. 1048600Ssteve.reinhardt@amd.com * @return True if no pages in the region are mapped. 1058600Ssteve.reinhardt@amd.com */ 10610298Salexandru.dutu@amd.com virtual bool isUnmapped(Addr vaddr, int64_t size) = 0; 1078600Ssteve.reinhardt@amd.com 1088600Ssteve.reinhardt@amd.com /** 1095004Sgblack@eecs.umich.edu * Lookup function 1105004Sgblack@eecs.umich.edu * @param vaddr The virtual address. 1115004Sgblack@eecs.umich.edu * @return entry The page table entry corresponding to vaddr. 1125004Sgblack@eecs.umich.edu */ 11310298Salexandru.dutu@amd.com virtual bool lookup(Addr vaddr, TheISA::TlbEntry &entry) = 0; 1142399SN/A 1152379SN/A /** 1162379SN/A * Translate function 1172379SN/A * @param vaddr The virtual address. 1185748SSteve.Reinhardt@amd.com * @param paddr Physical address from translation. 1195748SSteve.Reinhardt@amd.com * @return True if translation exists 1202379SN/A */ 1212399SN/A bool translate(Addr vaddr, Addr &paddr); 1222379SN/A 1232379SN/A /** 1245748SSteve.Reinhardt@amd.com * Simplified translate function (just check for translation) 1255748SSteve.Reinhardt@amd.com * @param vaddr The virtual address. 1265748SSteve.Reinhardt@amd.com * @return True if translation exists 1275748SSteve.Reinhardt@amd.com */ 1285748SSteve.Reinhardt@amd.com bool translate(Addr vaddr) { Addr dummy; return translate(vaddr, dummy); } 1295748SSteve.Reinhardt@amd.com 1305748SSteve.Reinhardt@amd.com /** 1312399SN/A * Perform a translation on the memory request, fills in paddr 1325004Sgblack@eecs.umich.edu * field of req. 1332379SN/A * @param req The memory request. 1342379SN/A */ 1355004Sgblack@eecs.umich.edu Fault translate(RequestPtr req); 1362379SN/A 1374521Ssaidi@eecs.umich.edu /** 1384521Ssaidi@eecs.umich.edu * Update the page table cache. 1394521Ssaidi@eecs.umich.edu * @param vaddr virtual address (page aligned) to check 1405004Sgblack@eecs.umich.edu * @param pte page table entry to return 1414521Ssaidi@eecs.umich.edu */ 1425004Sgblack@eecs.umich.edu inline void updateCache(Addr vaddr, TheISA::TlbEntry entry) 1434521Ssaidi@eecs.umich.edu { 1445004Sgblack@eecs.umich.edu pTableCache[2].entry = pTableCache[1].entry; 1454521Ssaidi@eecs.umich.edu pTableCache[2].vaddr = pTableCache[1].vaddr; 1469676Smitch.hayenga+gem5@gmail.com pTableCache[2].valid = pTableCache[1].valid; 1479676Smitch.hayenga+gem5@gmail.com 1485004Sgblack@eecs.umich.edu pTableCache[1].entry = pTableCache[0].entry; 1494521Ssaidi@eecs.umich.edu pTableCache[1].vaddr = pTableCache[0].vaddr; 1509676Smitch.hayenga+gem5@gmail.com pTableCache[1].valid = pTableCache[0].valid; 1519676Smitch.hayenga+gem5@gmail.com 1525004Sgblack@eecs.umich.edu pTableCache[0].entry = entry; 1534521Ssaidi@eecs.umich.edu pTableCache[0].vaddr = vaddr; 1549676Smitch.hayenga+gem5@gmail.com pTableCache[0].valid = true; 1554521Ssaidi@eecs.umich.edu } 1564521Ssaidi@eecs.umich.edu 1579676Smitch.hayenga+gem5@gmail.com /** 1589676Smitch.hayenga+gem5@gmail.com * Erase an entry from the page table cache. 1599676Smitch.hayenga+gem5@gmail.com * @param vaddr virtual address (page aligned) to check 1609676Smitch.hayenga+gem5@gmail.com */ 1619676Smitch.hayenga+gem5@gmail.com inline void eraseCacheEntry(Addr vaddr) 1629676Smitch.hayenga+gem5@gmail.com { 1639676Smitch.hayenga+gem5@gmail.com // Invalidate cached entries if necessary 1649676Smitch.hayenga+gem5@gmail.com if (pTableCache[0].valid && pTableCache[0].vaddr == vaddr) { 1659676Smitch.hayenga+gem5@gmail.com pTableCache[0].valid = false; 1669676Smitch.hayenga+gem5@gmail.com } else if (pTableCache[1].valid && pTableCache[1].vaddr == vaddr) { 1679676Smitch.hayenga+gem5@gmail.com pTableCache[1].valid = false; 1689676Smitch.hayenga+gem5@gmail.com } else if (pTableCache[2].valid && pTableCache[2].vaddr == vaddr) { 1699676Smitch.hayenga+gem5@gmail.com pTableCache[2].valid = false; 1709676Smitch.hayenga+gem5@gmail.com } 1719676Smitch.hayenga+gem5@gmail.com } 1724521Ssaidi@eecs.umich.edu 17310298Salexandru.dutu@amd.com virtual void serialize(std::ostream &os) = 0; 17410298Salexandru.dutu@amd.com 17510298Salexandru.dutu@amd.com virtual void unserialize(Checkpoint *cp, const std::string §ion) = 0; 17610298Salexandru.dutu@amd.com}; 17710298Salexandru.dutu@amd.com 17810298Salexandru.dutu@amd.com/** 17910298Salexandru.dutu@amd.com * Declaration of functional page table. 18010298Salexandru.dutu@amd.com */ 18110298Salexandru.dutu@amd.comclass FuncPageTable : public PageTableBase 18210298Salexandru.dutu@amd.com{ 18310298Salexandru.dutu@amd.com private: 18410298Salexandru.dutu@amd.com typedef m5::hash_map<Addr, TheISA::TlbEntry> PTable; 18510298Salexandru.dutu@amd.com typedef PTable::iterator PTableItr; 18610298Salexandru.dutu@amd.com PTable pTable; 18710298Salexandru.dutu@amd.com 18810298Salexandru.dutu@amd.com public: 18910298Salexandru.dutu@amd.com 19010298Salexandru.dutu@amd.com FuncPageTable(const std::string &__name, uint64_t _pid, 19110318Sandreas.hansson@arm.com Addr _pageSize = TheISA::PageBytes); 19210298Salexandru.dutu@amd.com 19310298Salexandru.dutu@amd.com ~FuncPageTable(); 19410298Salexandru.dutu@amd.com 19510298Salexandru.dutu@amd.com void initState(ThreadContext* tc) 19610298Salexandru.dutu@amd.com { 19710298Salexandru.dutu@amd.com } 19810298Salexandru.dutu@amd.com 19910298Salexandru.dutu@amd.com void map(Addr vaddr, Addr paddr, int64_t size, bool clobber = false); 20010298Salexandru.dutu@amd.com void remap(Addr vaddr, int64_t size, Addr new_vaddr); 20110298Salexandru.dutu@amd.com void unmap(Addr vaddr, int64_t size); 20210298Salexandru.dutu@amd.com 20310298Salexandru.dutu@amd.com /** 20410298Salexandru.dutu@amd.com * Check if any pages in a region are already allocated 20510298Salexandru.dutu@amd.com * @param vaddr The starting virtual address of the region. 20610298Salexandru.dutu@amd.com * @param size The length of the region. 20710298Salexandru.dutu@amd.com * @return True if no pages in the region are mapped. 20810298Salexandru.dutu@amd.com */ 20910298Salexandru.dutu@amd.com bool isUnmapped(Addr vaddr, int64_t size); 21010298Salexandru.dutu@amd.com 21110298Salexandru.dutu@amd.com /** 21210298Salexandru.dutu@amd.com * Lookup function 21310298Salexandru.dutu@amd.com * @param vaddr The virtual address. 21410298Salexandru.dutu@amd.com * @return entry The page table entry corresponding to vaddr. 21510298Salexandru.dutu@amd.com */ 21610298Salexandru.dutu@amd.com bool lookup(Addr vaddr, TheISA::TlbEntry &entry); 21710298Salexandru.dutu@amd.com 2183311Ssaidi@eecs.umich.edu void serialize(std::ostream &os); 2195004Sgblack@eecs.umich.edu 2203311Ssaidi@eecs.umich.edu void unserialize(Checkpoint *cp, const std::string §ion); 2212379SN/A}; 2222379SN/A 22310298Salexandru.dutu@amd.com/** 22410298Salexandru.dutu@amd.com * Faux page table class indended to stop the usage of 22510298Salexandru.dutu@amd.com * an architectural page table, when there is none defined 22610298Salexandru.dutu@amd.com * for a particular ISA. 22710298Salexandru.dutu@amd.com */ 22810298Salexandru.dutu@amd.comclass NoArchPageTable : public FuncPageTable 22910298Salexandru.dutu@amd.com{ 23010298Salexandru.dutu@amd.com public: 23110298Salexandru.dutu@amd.com NoArchPageTable(const std::string &__name, uint64_t _pid, System *_sys, 23210318Sandreas.hansson@arm.com Addr _pageSize = TheISA::PageBytes) : FuncPageTable(__name, _pid) 23310298Salexandru.dutu@amd.com { 23410298Salexandru.dutu@amd.com fatal("No architectural page table defined for this ISA.\n"); 23510298Salexandru.dutu@amd.com } 23610298Salexandru.dutu@amd.com}; 23710298Salexandru.dutu@amd.com 2386216Snate@binkert.org#endif // __MEM_PAGE_TABLE_HH__ 239