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

Generated on Tue Sep 21 2021 12:25:33 for gem5 by doxygen 1.8.17