gem5  v21.0.1.0
multi_level_page_table.hh
Go to the documentation of this file.
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 
34 #ifndef __MEM_MULTI_LEVEL_PAGE_TABLE_HH__
35 #define __MEM_MULTI_LEVEL_PAGE_TABLE_HH__
36 
37 #include <string>
38 
39 #include "base/types.hh"
40 #include "debug/MMU.hh"
41 #include "mem/page_table.hh"
42 #include "sim/system.hh"
43 
100 namespace {
101 
102 template <class First, class ...Rest>
103 Addr
104 prepTopTable(System *system, Addr pageSize)
105 {
106  Addr addr = system->allocPhysPages(First::tableSize());
107  PortProxy &p = system->physProxy;
108  p.memsetBlob(addr, 0, First::tableSize() * pageSize);
109  return addr;
110 }
111 
112 template <class ...Types>
113 struct LastType;
114 
115 template <class First, class Second, class ...Rest>
116 struct LastType<First, Second, Rest...>
117 {
118  typedef typename LastType<Second, Rest...>::type type;
119 };
120 
121 template <class Only>
122 struct LastType<Only>
123 {
124  typedef Only type;
125 };
126 
127 
128 template <class ...Types>
129 struct WalkWrapper;
130 
131 template <class Final, class Only>
132 struct WalkWrapper<Final, Only>
133 {
134  static void
135  walk(System *system, Addr pageSize, Addr table, Addr vaddr,
136  bool allocate, Final *entry)
137  {
138  entry->read(system->physProxy, table, vaddr);
139  }
140 };
141 
142 template <class Final, class First, class Second, class ...Rest>
143 struct WalkWrapper<Final, First, Second, Rest...>
144 {
145  static void
146  walk(System *system, Addr pageSize, Addr table, Addr vaddr,
147  bool allocate, Final *entry)
148  {
149  First first;
150  first.read(system->physProxy, table, vaddr);
151 
152  Addr next;
153  if (!first.present()) {
154  fatal_if(!allocate,
155  "Page fault while walking the page table.");
156  next = prepTopTable<Second>(system, pageSize);
157  first.reset(next);
158  first.write(system->physProxy);
159  } else {
160  next = first.paddr();
161  }
162  WalkWrapper<Final, Second, Rest...>::walk(
163  system, pageSize, next, vaddr, allocate, entry);
164  }
165 };
166 
167 template <class ...EntryTypes>
168 void
169 walk(System *system, Addr pageSize, Addr table, Addr vaddr,
170  bool allocate, typename LastType<EntryTypes...>::type *entry)
171 {
172  WalkWrapper<typename LastType<EntryTypes...>::type, EntryTypes...>::walk(
173  system, pageSize, table, vaddr, allocate, entry);
174 }
175 
176 }
177 
178 
179 template <class ...EntryTypes>
181 {
182  typedef typename LastType<EntryTypes...>::type Final;
183 
188 
193 
194 public:
195  MultiLevelPageTable(const std::string &__name, uint64_t _pid,
196  System *_sys, Addr _pageSize) :
197  EmulationPageTable(__name, _pid, _pageSize), system(_sys)
198  {}
199 
201 
202  void
203  initState() override
204  {
205  if (shared)
206  return;
207 
208  _basePtr = prepTopTable<EntryTypes...>(system, _pageSize);
209  }
210 
211  Addr basePtr() { return _basePtr; }
212 
213  void
214  map(Addr vaddr, Addr paddr, int64_t size, uint64_t flags = 0) override
215  {
216  EmulationPageTable::map(vaddr, paddr, size, flags);
217 
218  Final entry;
219 
220  for (int64_t offset = 0; offset < size; offset += _pageSize) {
221  walk<EntryTypes...>(system, _pageSize, _basePtr,
222  vaddr + offset, true, &entry);
223 
224  entry.reset(paddr + offset, true, flags & Uncacheable,
225  flags & ReadOnly);
226  entry.write(system->physProxy);
227 
228  DPRINTF(MMU, "New mapping: %#x-%#x\n",
229  vaddr + offset, paddr + offset);
230  }
231  }
232 
233  void
234  remap(Addr vaddr, int64_t size, Addr new_vaddr) override
235  {
236  EmulationPageTable::remap(vaddr, size, new_vaddr);
237 
238  Final old_entry, new_entry;
239 
240  for (int64_t offset = 0; offset < size; offset += _pageSize) {
241  // Unmap the original mapping.
242  walk<EntryTypes...>(system, _pageSize, _basePtr, vaddr + offset,
243  false, &old_entry);
244  old_entry.present(false);
245  old_entry.write(system->physProxy);
246 
247  // Map the new one.
248  walk<EntryTypes...>(system, _pageSize, _basePtr,
249  new_vaddr + offset, true, &new_entry);
250  new_entry.reset(old_entry.paddr(), true, old_entry.uncacheable(),
251  old_entry.readonly());
252  new_entry.write(system->physProxy);
253  }
254  }
255 
256  void
257  unmap(Addr vaddr, int64_t size) override
258  {
260 
261  Final entry;
262 
263  for (int64_t offset = 0; offset < size; offset += _pageSize) {
264  walk<EntryTypes...>(system, _pageSize, _basePtr,
265  vaddr + offset, false, &entry);
266  fatal_if(!entry.present(),
267  "PageTable::unmap: Address %#x not mapped.", vaddr);
268  entry.present(false);
269  entry.write(system->physProxy);
270  DPRINTF(MMU, "Unmapping: %#x\n", vaddr);
271  }
272  }
273 
274  void
275  serialize(CheckpointOut &cp) const override
276  {
282  paramOut(cp, "ptable.pointer", _basePtr);
283  }
284 
285  void
287  {
289  paramIn(cp, "ptable.pointer", _basePtr);
290  }
291 };
292 #endif // __MEM_MULTI_LEVEL_PAGE_TABLE_HH__
system.hh
MultiLevelPageTable::Final
LastType< EntryTypes... >::type Final
Definition: multi_level_page_table.hh:182
MultiLevelPageTable::remap
void remap(Addr vaddr, int64_t size, Addr new_vaddr) override
Definition: multi_level_page_table.hh:234
EmulationPageTable::Uncacheable
@ Uncacheable
Definition: page_table.hh:94
System::physProxy
PortProxy physProxy
Port to physical memory used for writing object files into ram at boot.
Definition: system.hh:319
MultiLevelPageTable::_basePtr
Addr _basePtr
Physical address to the last level of the page table.
Definition: multi_level_page_table.hh:192
EmulationPageTable::unmap
virtual void unmap(Addr vaddr, int64_t size)
Definition: page_table.cc:101
EmulationPageTable::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: page_table.cc:186
EmulationPageTable::_pid
const uint64_t _pid
Definition: page_table.hh:69
EmulationPageTable::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: page_table.cc:169
X86ISA::system
Bitfield< 15 > system
Definition: misc.hh:997
MultiLevelPageTable::~MultiLevelPageTable
~MultiLevelPageTable()
Definition: multi_level_page_table.hh:200
cp
Definition: cprintf.cc:37
EmulationPageTable
Definition: page_table.hh:49
System
Definition: system.hh:73
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:237
EmulationPageTable::remap
virtual void remap(Addr vaddr, int64_t size, Addr new_vaddr)
Definition: page_table.cc:72
MultiLevelPageTable
Definition: multi_level_page_table.hh:180
MipsISA::vaddr
vaddr
Definition: pra_constants.hh:275
MultiLevelPageTable::initState
void initState() override
Definition: multi_level_page_table.hh:203
MultiLevelPageTable::MultiLevelPageTable
MultiLevelPageTable(const std::string &__name, uint64_t _pid, System *_sys, Addr _pageSize)
Definition: multi_level_page_table.hh:195
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:148
MultiLevelPageTable::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: multi_level_page_table.hh:275
MultiLevelPageTable::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: multi_level_page_table.hh:286
paramOut
void paramOut(CheckpointOut &cp, const std::string &name, ExtMachInst const &machInst)
Definition: types.cc:37
EmulationPageTable::shared
bool shared
Definition: page_table.hh:99
X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:80
MultiLevelPageTable::unmap
void unmap(Addr vaddr, int64_t size) override
Definition: multi_level_page_table.hh:257
EmulationPageTable::ReadOnly
@ ReadOnly
Definition: page_table.hh:95
PortProxy
This object is a proxy for a port or other object which implements the functional response protocol,...
Definition: port_proxy.hh:80
types.hh
MultiLevelPageTable::system
System * system
Pointer to System object.
Definition: multi_level_page_table.hh:187
CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:64
X86ISA::type
type
Definition: misc.hh:727
MultiLevelPageTable::map
void map(Addr vaddr, Addr paddr, int64_t size, uint64_t flags=0) override
Maps a virtual memory region to a physical memory region.
Definition: multi_level_page_table.hh:214
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
fatal_if
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:219
EmulationPageTable::map
virtual void map(Addr vaddr, Addr paddr, int64_t size, uint64_t flags=0)
Maps a virtual memory region to a physical memory region.
Definition: page_table.cc:45
page_table.hh
paramIn
void paramIn(CheckpointIn &cp, const std::string &name, ExtMachInst &machInst)
Definition: types.cc:69
CheckpointIn
Definition: serialize.hh:68
EmulationPageTable::_pageSize
const Addr _pageSize
Definition: page_table.hh:66
MultiLevelPageTable::basePtr
Addr basePtr()
Definition: multi_level_page_table.hh:211
ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:153

Generated on Tue Jun 22 2021 15:28:29 for gem5 by doxygen 1.8.17