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

Generated on Wed Sep 30 2020 14:02:13 for gem5 by doxygen 1.8.17