multi_level_page_table.hh revision 10556:1e3b3c7a0cba
1/* 2 * Copyright (c) 2014 Advanced Micro Devices, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Alexandru Dutu 29 */ 30 31/** 32 * @file 33 * Declaration of a multi-level page table. 34 */ 35 36#ifndef __MEM_MULTI_LEVEL_PAGE_TABLE_HH__ 37#define __MEM_MULTI_LEVEL_PAGE_TABLE_HH__ 38 39#include <string> 40 41#include "arch/isa_traits.hh" 42#include "arch/tlb.hh" 43#include "base/types.hh" 44#include "config/the_isa.hh" 45#include "mem/page_table.hh" 46#include "sim/serialize.hh" 47#include "sim/system.hh" 48 49/** 50 * This class implements an in-memory multi-level page table that can be 51 * configured to follow ISA specifications. It can be used instead of the 52 * PageTable class in SE mode to allow CPU models (e.g. X86KvmCPU) 53 * to do a normal page table walk. 54 * 55 * To reduce memory required to store the page table, a multi-level page 56 * table stores its translations similarly with a radix tree. Let n be 57 * the number of levels and {Ln, Ln-1, ..., L1, L0} a set that specifies 58 * the number of entries for each level as base 2 logarithm values. A 59 * multi-level page table will store its translations at level 0 (the 60 * leaves of the tree) and it will be layed out in memory in the 61 * following way: 62 * 63 * +------------------------------+ 64 * level n |Ln-1_E0|Ln-1_E1|...|Ln-1_E2^Ln| 65 * +------------------------------+ 66 * / \ 67 * +------------------------+ +------------------------+ 68 * level n-1 |Ln-2_E0|...|Ln-2_E2^Ln-1| |Ln-2_E0|...|Ln-2_E2^Ln-1| 69 * +------------------------+ +------------------------+ 70 * / \ / \ 71 * . 72 * . 73 * . 74 * / / \ 75 * +------------------+ +------------+ +------------+ 76 * level 1 |L0_E1|...|L0_E2^L1| |...|L0_E2^L1| ... |...|L0_E2^L1| 77 * +------------------+ +------------+ +------------+ 78 * , where 79 * +------------------------------+ 80 * |Lk-1_E0|Lk-1_E1|...|Lk-1_E2^Lk| 81 * +------------------------------+ 82 * is a level k entry that holds 2^Lk entries in Lk-1 level. 83 * 84 * Essentially, a level n entry will contain 2^Ln level n-1 entries, 85 * a level n-1 entry will hold 2^Ln-1 level n-2 entries etc. 86 * 87 * The virtual address is split into offsets that index into the 88 * different levels of the page table. 89 * 90 * +--------------------------------+ 91 * |LnOffset|...|L1Offset|PageOffset| 92 * +--------------------------------+ 93 * 94 * For example L0Offset will be formed by the bits in range 95 * [log2(PageOffset), log2(PageOffset)+L0]. 96 * 97 * For every level of the page table, from n to 1, the base address 98 * of the entry is loaded, the offset in the virtual address for 99 * that particular level is used to index into the entry which 100 * will reveal the memory address of the entry in the next level. 101 * 102 * @see MultiLevelPageTable 103 */ 104template <class ISAOps> 105class MultiLevelPageTable : public PageTableBase 106{ 107 /** 108 * ISA specific operations 109 */ 110 ISAOps pTableISAOps; 111 112 /** 113 * Pointer to System object 114 */ 115 System *system; 116 117 /** 118 * Physical address to the last level of the page table 119 */ 120 Addr basePtr; 121 122 /** 123 * Vector with sizes of all levels in base 2 logarithmic 124 */ 125 const std::vector<uint8_t> logLevelSize; 126 127 /** 128 * Number of levels contained by the page table 129 */ 130 const uint64_t numLevels; 131 132 /** 133 * Method for walking the page table 134 * 135 * @param vaddr Virtual address that is being looked-up 136 * @param allocate Specifies whether memory should be allocated while 137 * walking the page table 138 * @return PTE_addr The address of the found PTE 139 * @retval true if the page table walk has succeded, false otherwhise 140 */ 141 bool walk(Addr vaddr, bool allocate, Addr &PTE_addr); 142 143public: 144 MultiLevelPageTable(const std::string &__name, uint64_t _pid, 145 System *_sys); 146 ~MultiLevelPageTable(); 147 148 void initState(ThreadContext* tc); 149 150 void map(Addr vaddr, Addr paddr, int64_t size, bool clobber = false); 151 void remap(Addr vaddr, int64_t size, Addr new_vaddr); 152 void unmap(Addr vaddr, int64_t size); 153 bool isUnmapped(Addr vaddr, int64_t size); 154 bool lookup(Addr vaddr, TheISA::TlbEntry &entry); 155 void serialize(std::ostream &os); 156 void unserialize(Checkpoint *cp, const std::string §ion); 157}; 158#endif // __MEM_MULTI_LEVEL_PAGE_TABLE_HH__ 159