page_table.hh revision 10298
110779SCurtis.Dunham@arm.com/* 210779SCurtis.Dunham@arm.com * Copyright (c) 2014 Advanced Micro Devices, Inc. 310779SCurtis.Dunham@arm.com * Copyright (c) 2003 The Regents of The University of Michigan 410779SCurtis.Dunham@arm.com * All rights reserved. 510779SCurtis.Dunham@arm.com * 610779SCurtis.Dunham@arm.com * Redistribution and use in source and binary forms, with or without 710779SCurtis.Dunham@arm.com * modification, are permitted provided that the following conditions are 810779SCurtis.Dunham@arm.com * met: redistributions of source code must retain the above copyright 910779SCurtis.Dunham@arm.com * notice, this list of conditions and the following disclaimer; 1010779SCurtis.Dunham@arm.com * redistributions in binary form must reproduce the above copyright 1110779SCurtis.Dunham@arm.com * notice, this list of conditions and the following disclaimer in the 1210779SCurtis.Dunham@arm.com * documentation and/or other materials provided with the distribution; 1310779SCurtis.Dunham@arm.com * neither the name of the copyright holders nor the names of its 1410779SCurtis.Dunham@arm.com * contributors may be used to endorse or promote products derived from 1510779SCurtis.Dunham@arm.com * this software without specific prior written permission. 1610779SCurtis.Dunham@arm.com * 1710779SCurtis.Dunham@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1810779SCurtis.Dunham@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1910779SCurtis.Dunham@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2010779SCurtis.Dunham@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2110779SCurtis.Dunham@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2210779SCurtis.Dunham@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2310779SCurtis.Dunham@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2410779SCurtis.Dunham@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2510779SCurtis.Dunham@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2610779SCurtis.Dunham@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2710779SCurtis.Dunham@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2810779SCurtis.Dunham@arm.com * 2910779SCurtis.Dunham@arm.com * Authors: Steve Reinhardt 3010779SCurtis.Dunham@arm.com */ 3110779SCurtis.Dunham@arm.com 3210779SCurtis.Dunham@arm.com/** 3310779SCurtis.Dunham@arm.com * @file 3410779SCurtis.Dunham@arm.com * Declarations of a non-full system Page Table. 3510779SCurtis.Dunham@arm.com */ 3610779SCurtis.Dunham@arm.com 3710779SCurtis.Dunham@arm.com#ifndef __MEM_PAGE_TABLE_HH__ 3810779SCurtis.Dunham@arm.com#define __MEM_PAGE_TABLE_HH__ 3910779SCurtis.Dunham@arm.com 4010779SCurtis.Dunham@arm.com#include <string> 4110779SCurtis.Dunham@arm.com 4210779SCurtis.Dunham@arm.com#include "arch/isa_traits.hh" 4310779SCurtis.Dunham@arm.com#include "arch/tlb.hh" 4410779SCurtis.Dunham@arm.com#include "base/hashmap.hh" 4510779SCurtis.Dunham@arm.com#include "base/types.hh" 4610779SCurtis.Dunham@arm.com#include "config/the_isa.hh" 4711315SCurtis.Dunham@arm.com#include "mem/request.hh" 4811315SCurtis.Dunham@arm.com#include "sim/serialize.hh" 4911315SCurtis.Dunham@arm.com#include "sim/system.hh" 5011315SCurtis.Dunham@arm.com 5110779SCurtis.Dunham@arm.comclass ThreadContext; 5210779SCurtis.Dunham@arm.com 5310779SCurtis.Dunham@arm.com/** 5410779SCurtis.Dunham@arm.com * Declaration of base class for page table 5510779SCurtis.Dunham@arm.com */ 5610779SCurtis.Dunham@arm.comclass PageTableBase 5710779SCurtis.Dunham@arm.com{ 5810779SCurtis.Dunham@arm.com protected: 5910779SCurtis.Dunham@arm.com struct cacheElement { 6010779SCurtis.Dunham@arm.com bool valid; 6110779SCurtis.Dunham@arm.com Addr vaddr; 6210779SCurtis.Dunham@arm.com TheISA::TlbEntry entry; 6310779SCurtis.Dunham@arm.com }; 6410779SCurtis.Dunham@arm.com 6510779SCurtis.Dunham@arm.com struct cacheElement pTableCache[3]; 6610779SCurtis.Dunham@arm.com 6710779SCurtis.Dunham@arm.com const Addr pageSize; 6810779SCurtis.Dunham@arm.com const Addr offsetMask; 6910779SCurtis.Dunham@arm.com 7010779SCurtis.Dunham@arm.com const uint64_t pid; 7110779SCurtis.Dunham@arm.com const std::string _name; 7210779SCurtis.Dunham@arm.com 7310779SCurtis.Dunham@arm.com public: 7410779SCurtis.Dunham@arm.com 7510779SCurtis.Dunham@arm.com PageTableBase(const std::string &__name, uint64_t _pid, 7610779SCurtis.Dunham@arm.com Addr _pageSize = TheISA::VMPageSize) 7710779SCurtis.Dunham@arm.com : pageSize(_pageSize), offsetMask(mask(floorLog2(_pageSize))), 7810779SCurtis.Dunham@arm.com pid(_pid), _name(__name) 7910779SCurtis.Dunham@arm.com { 8010779SCurtis.Dunham@arm.com assert(isPowerOf2(pageSize)); 8110779SCurtis.Dunham@arm.com pTableCache[0].valid = false; 8210779SCurtis.Dunham@arm.com pTableCache[1].valid = false; 8310779SCurtis.Dunham@arm.com pTableCache[2].valid = false; 8410779SCurtis.Dunham@arm.com } 8510779SCurtis.Dunham@arm.com 8610779SCurtis.Dunham@arm.com virtual ~PageTableBase() {}; 8710779SCurtis.Dunham@arm.com 8810779SCurtis.Dunham@arm.com virtual void initState(ThreadContext* tc) = 0; 8910779SCurtis.Dunham@arm.com 9010779SCurtis.Dunham@arm.com // for DPRINTF compatibility 9110779SCurtis.Dunham@arm.com const std::string name() const { return _name; } 9210779SCurtis.Dunham@arm.com 9310779SCurtis.Dunham@arm.com Addr pageAlign(Addr a) { return (a & ~offsetMask); } 9410779SCurtis.Dunham@arm.com Addr pageOffset(Addr a) { return (a & offsetMask); } 9510779SCurtis.Dunham@arm.com 9610779SCurtis.Dunham@arm.com virtual void map(Addr vaddr, Addr paddr, int64_t size, bool clobber = false) = 0; 9710779SCurtis.Dunham@arm.com virtual void remap(Addr vaddr, int64_t size, Addr new_vaddr) = 0; 9810779SCurtis.Dunham@arm.com virtual void unmap(Addr vaddr, int64_t size) = 0; 9910779SCurtis.Dunham@arm.com 10010779SCurtis.Dunham@arm.com /** 10110779SCurtis.Dunham@arm.com * Check if any pages in a region are already allocated 10210779SCurtis.Dunham@arm.com * @param vaddr The starting virtual address of the region. 10310779SCurtis.Dunham@arm.com * @param size The length of the region. 10410779SCurtis.Dunham@arm.com * @return True if no pages in the region are mapped. 10510779SCurtis.Dunham@arm.com */ 10610779SCurtis.Dunham@arm.com virtual bool isUnmapped(Addr vaddr, int64_t size) = 0; 10710779SCurtis.Dunham@arm.com 10810779SCurtis.Dunham@arm.com /** 10910779SCurtis.Dunham@arm.com * Lookup function 11010779SCurtis.Dunham@arm.com * @param vaddr The virtual address. 11110779SCurtis.Dunham@arm.com * @return entry The page table entry corresponding to vaddr. 11210779SCurtis.Dunham@arm.com */ 11310779SCurtis.Dunham@arm.com virtual bool lookup(Addr vaddr, TheISA::TlbEntry &entry) = 0; 11410779SCurtis.Dunham@arm.com 11510779SCurtis.Dunham@arm.com /** 11610779SCurtis.Dunham@arm.com * Translate function 11710779SCurtis.Dunham@arm.com * @param vaddr The virtual address. 11810779SCurtis.Dunham@arm.com * @param paddr Physical address from translation. 11910779SCurtis.Dunham@arm.com * @return True if translation exists 12010779SCurtis.Dunham@arm.com */ 12110779SCurtis.Dunham@arm.com bool translate(Addr vaddr, Addr &paddr); 12210779SCurtis.Dunham@arm.com 12310779SCurtis.Dunham@arm.com /** 12410779SCurtis.Dunham@arm.com * Simplified translate function (just check for translation) 12510779SCurtis.Dunham@arm.com * @param vaddr The virtual address. 12610779SCurtis.Dunham@arm.com * @return True if translation exists 12710779SCurtis.Dunham@arm.com */ 12810779SCurtis.Dunham@arm.com bool translate(Addr vaddr) { Addr dummy; return translate(vaddr, dummy); } 12910779SCurtis.Dunham@arm.com 13010779SCurtis.Dunham@arm.com /** 13110779SCurtis.Dunham@arm.com * Perform a translation on the memory request, fills in paddr 13210779SCurtis.Dunham@arm.com * field of req. 13310779SCurtis.Dunham@arm.com * @param req The memory request. 13410779SCurtis.Dunham@arm.com */ 13510779SCurtis.Dunham@arm.com Fault translate(RequestPtr req); 13610779SCurtis.Dunham@arm.com 13710779SCurtis.Dunham@arm.com /** 13810779SCurtis.Dunham@arm.com * Update the page table cache. 13910779SCurtis.Dunham@arm.com * @param vaddr virtual address (page aligned) to check 14010779SCurtis.Dunham@arm.com * @param pte page table entry to return 14110779SCurtis.Dunham@arm.com */ 14210779SCurtis.Dunham@arm.com inline void updateCache(Addr vaddr, TheISA::TlbEntry entry) 14310779SCurtis.Dunham@arm.com { 14410779SCurtis.Dunham@arm.com pTableCache[2].entry = pTableCache[1].entry; 14510779SCurtis.Dunham@arm.com pTableCache[2].vaddr = pTableCache[1].vaddr; 14610779SCurtis.Dunham@arm.com pTableCache[2].valid = pTableCache[1].valid; 14710779SCurtis.Dunham@arm.com 14810779SCurtis.Dunham@arm.com pTableCache[1].entry = pTableCache[0].entry; 14910779SCurtis.Dunham@arm.com pTableCache[1].vaddr = pTableCache[0].vaddr; 15010779SCurtis.Dunham@arm.com pTableCache[1].valid = pTableCache[0].valid; 15110779SCurtis.Dunham@arm.com 15210779SCurtis.Dunham@arm.com pTableCache[0].entry = entry; 15310779SCurtis.Dunham@arm.com pTableCache[0].vaddr = vaddr; 15410779SCurtis.Dunham@arm.com pTableCache[0].valid = true; 15510779SCurtis.Dunham@arm.com } 15610779SCurtis.Dunham@arm.com 15710779SCurtis.Dunham@arm.com /** 15810779SCurtis.Dunham@arm.com * Erase an entry from the page table cache. 15910779SCurtis.Dunham@arm.com * @param vaddr virtual address (page aligned) to check 16010779SCurtis.Dunham@arm.com */ 16110779SCurtis.Dunham@arm.com inline void eraseCacheEntry(Addr vaddr) 16210779SCurtis.Dunham@arm.com { 16310779SCurtis.Dunham@arm.com // Invalidate cached entries if necessary 16410779SCurtis.Dunham@arm.com if (pTableCache[0].valid && pTableCache[0].vaddr == vaddr) { 16510779SCurtis.Dunham@arm.com pTableCache[0].valid = false; 16610779SCurtis.Dunham@arm.com } else if (pTableCache[1].valid && pTableCache[1].vaddr == vaddr) { 16710779SCurtis.Dunham@arm.com pTableCache[1].valid = false; 16811158SCurtis.Dunham@arm.com } else if (pTableCache[2].valid && pTableCache[2].vaddr == vaddr) { 16910779SCurtis.Dunham@arm.com pTableCache[2].valid = false; 17010779SCurtis.Dunham@arm.com } 17110779SCurtis.Dunham@arm.com } 17210779SCurtis.Dunham@arm.com 17310779SCurtis.Dunham@arm.com virtual void serialize(std::ostream &os) = 0; 17410779SCurtis.Dunham@arm.com 17510779SCurtis.Dunham@arm.com virtual void unserialize(Checkpoint *cp, const std::string §ion) = 0; 17610779SCurtis.Dunham@arm.com}; 17710779SCurtis.Dunham@arm.com 17810779SCurtis.Dunham@arm.com/** 17910779SCurtis.Dunham@arm.com * Declaration of functional page table. 18011435Smitch.hayenga@arm.com */ 18110779SCurtis.Dunham@arm.comclass FuncPageTable : public PageTableBase 18210779SCurtis.Dunham@arm.com{ 18310779SCurtis.Dunham@arm.com private: 18410779SCurtis.Dunham@arm.com typedef m5::hash_map<Addr, TheISA::TlbEntry> PTable; 18510779SCurtis.Dunham@arm.com typedef PTable::iterator PTableItr; 18610779SCurtis.Dunham@arm.com PTable pTable; 18710779SCurtis.Dunham@arm.com 18810779SCurtis.Dunham@arm.com public: 18910779SCurtis.Dunham@arm.com 19010779SCurtis.Dunham@arm.com FuncPageTable(const std::string &__name, uint64_t _pid, 19110779SCurtis.Dunham@arm.com Addr _pageSize = TheISA::VMPageSize); 19210779SCurtis.Dunham@arm.com 19310779SCurtis.Dunham@arm.com ~FuncPageTable(); 19410779SCurtis.Dunham@arm.com 19510779SCurtis.Dunham@arm.com void initState(ThreadContext* tc) 19610779SCurtis.Dunham@arm.com { 19710779SCurtis.Dunham@arm.com } 19810779SCurtis.Dunham@arm.com 19910779SCurtis.Dunham@arm.com void map(Addr vaddr, Addr paddr, int64_t size, bool clobber = false); 20010779SCurtis.Dunham@arm.com void remap(Addr vaddr, int64_t size, Addr new_vaddr); 20110779SCurtis.Dunham@arm.com void unmap(Addr vaddr, int64_t size); 20210779SCurtis.Dunham@arm.com 20310779SCurtis.Dunham@arm.com /** 20410779SCurtis.Dunham@arm.com * Check if any pages in a region are already allocated 20510779SCurtis.Dunham@arm.com * @param vaddr The starting virtual address of the region. 20610779SCurtis.Dunham@arm.com * @param size The length of the region. 20710779SCurtis.Dunham@arm.com * @return True if no pages in the region are mapped. 20810779SCurtis.Dunham@arm.com */ 20910779SCurtis.Dunham@arm.com bool isUnmapped(Addr vaddr, int64_t size); 21010779SCurtis.Dunham@arm.com 21110779SCurtis.Dunham@arm.com /** 21210779SCurtis.Dunham@arm.com * Lookup function 21310779SCurtis.Dunham@arm.com * @param vaddr The virtual address. 21410779SCurtis.Dunham@arm.com * @return entry The page table entry corresponding to vaddr. 21510779SCurtis.Dunham@arm.com */ 21610779SCurtis.Dunham@arm.com bool lookup(Addr vaddr, TheISA::TlbEntry &entry); 21710779SCurtis.Dunham@arm.com 21810779SCurtis.Dunham@arm.com void serialize(std::ostream &os); 21910779SCurtis.Dunham@arm.com 22010779SCurtis.Dunham@arm.com void unserialize(Checkpoint *cp, const std::string §ion); 22110779SCurtis.Dunham@arm.com}; 22210779SCurtis.Dunham@arm.com 22310779SCurtis.Dunham@arm.com/** 22410779SCurtis.Dunham@arm.com * Faux page table class indended to stop the usage of 22510779SCurtis.Dunham@arm.com * an architectural page table, when there is none defined 22610779SCurtis.Dunham@arm.com * for a particular ISA. 22710779SCurtis.Dunham@arm.com */ 22810779SCurtis.Dunham@arm.comclass NoArchPageTable : public FuncPageTable 22910779SCurtis.Dunham@arm.com{ 23010779SCurtis.Dunham@arm.com public: 23110779SCurtis.Dunham@arm.com NoArchPageTable(const std::string &__name, uint64_t _pid, System *_sys, 23210779SCurtis.Dunham@arm.com Addr _pageSize = TheISA::VMPageSize) : FuncPageTable(__name, _pid) 23310779SCurtis.Dunham@arm.com { 23410779SCurtis.Dunham@arm.com fatal("No architectural page table defined for this ISA.\n"); 23510779SCurtis.Dunham@arm.com } 23610779SCurtis.Dunham@arm.com}; 23710779SCurtis.Dunham@arm.com 23810779SCurtis.Dunham@arm.com#endif // __MEM_PAGE_TABLE_HH__ 23910779SCurtis.Dunham@arm.com