gem5  v19.0.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  * Authors: Alexandru Dutu
29  */
30 
36 #ifndef __MEM_MULTI_LEVEL_PAGE_TABLE_HH__
37 #define __MEM_MULTI_LEVEL_PAGE_TABLE_HH__
38 
39 #include <string>
40 
41 #include "base/types.hh"
42 #include "mem/page_table.hh"
43 
44 class System;
45 
102 namespace {
103 
104 template <class First, class ...Rest>
105 Addr
106 prepTopTable(System *system, Addr pageSize)
107 {
108  Addr addr = system->allocPhysPages(First::tableSize());
109  PortProxy &p = system->physProxy;
110  p.memsetBlob(addr, 0, First::tableSize() * pageSize);
111  return addr;
112 }
113 
114 template <class ...Types>
115 struct LastType;
116 
117 template <class First, class Second, class ...Rest>
118 struct LastType<First, Second, Rest...>
119 {
120  typedef typename LastType<Second, Rest...>::type type;
121 };
122 
123 template <class Only>
124 struct LastType<Only>
125 {
126  typedef Only type;
127 };
128 
129 
130 template <class ...Types>
131 struct WalkWrapper;
132 
133 template <class Final, class Only>
134 struct WalkWrapper<Final, Only>
135 {
136  static void
137  walk(System *system, Addr pageSize, Addr table, Addr vaddr,
138  bool allocate, Final *entry)
139  {
140  entry->read(system->physProxy, table, vaddr);
141  }
142 };
143 
144 template <class Final, class First, class Second, class ...Rest>
145 struct WalkWrapper<Final, First, Second, Rest...>
146 {
147  static void
148  walk(System *system, Addr pageSize, Addr table, Addr vaddr,
149  bool allocate, Final *entry)
150  {
151  First first;
152  first.read(system->physProxy, table, vaddr);
153 
154  Addr next;
155  if (!first.present()) {
156  fatal_if(!allocate,
157  "Page fault while walking the page table.");
158  next = prepTopTable<Second>(system, pageSize);
159  first.reset(next);
160  first.write(system->physProxy);
161  } else {
162  next = first.paddr();
163  }
164  WalkWrapper<Final, Second, Rest...>::walk(
165  system, pageSize, next, vaddr, allocate, entry);
166  }
167 };
168 
169 template <class ...EntryTypes>
170 void
171 walk(System *system, Addr pageSize, Addr table, Addr vaddr,
172  bool allocate, typename LastType<EntryTypes...>::type *entry)
173 {
174  WalkWrapper<typename LastType<EntryTypes...>::type, EntryTypes...>::walk(
175  system, pageSize, table, vaddr, allocate, entry);
176 }
177 
178 }
179 
180 
181 template <class ...EntryTypes>
183 {
184  typedef typename LastType<EntryTypes...>::type Final;
185 
190 
195 
196 public:
197  MultiLevelPageTable(const std::string &__name, uint64_t _pid,
198  System *_sys, Addr pageSize) :
199  EmulationPageTable(__name, _pid, pageSize), system(_sys)
200  {}
201 
203 
204  void
205  initState() override
206  {
207  if (shared)
208  return;
209 
210  _basePtr = prepTopTable<EntryTypes...>(system, pageSize);
211  }
212 
213  Addr basePtr() { return _basePtr; }
214 
215  void
216  map(Addr vaddr, Addr paddr, int64_t size, uint64_t flags = 0) override
217  {
218  EmulationPageTable::map(vaddr, paddr, size, flags);
219 
220  Final entry;
221 
222  for (int64_t offset = 0; offset < size; offset += pageSize) {
223  walk<EntryTypes...>(system, pageSize, _basePtr,
224  vaddr + offset, true, &entry);
225 
226  entry.reset(paddr + offset, true, flags & Uncacheable,
227  flags & ReadOnly);
228  entry.write(system->physProxy);
229 
230  DPRINTF(MMU, "New mapping: %#x-%#x\n",
231  vaddr + offset, paddr + offset);
232  }
233  }
234 
235  void
236  remap(Addr vaddr, int64_t size, Addr new_vaddr) override
237  {
238  EmulationPageTable::remap(vaddr, size, new_vaddr);
239 
240  Final old_entry, new_entry;
241 
242  for (int64_t offset = 0; offset < size; offset += pageSize) {
243  // Unmap the original mapping.
244  walk<EntryTypes...>(system, pageSize, _basePtr, vaddr + offset,
245  false, &old_entry);
246  old_entry.present(false);
247  old_entry.write(system->physProxy);
248 
249  // Map the new one.
250  walk<EntryTypes...>(system, pageSize, _basePtr, new_vaddr + offset,
251  true, &new_entry);
252  new_entry.reset(old_entry.paddr(), true, old_entry.uncacheable(),
253  old_entry.readonly());
254  new_entry.write(system->physProxy);
255  }
256  }
257 
258  void
259  unmap(Addr vaddr, int64_t size) override
260  {
261  EmulationPageTable::unmap(vaddr, size);
262 
263  Final entry;
264 
265  for (int64_t offset = 0; offset < size; offset += pageSize) {
266  walk<EntryTypes...>(system, pageSize, _basePtr,
267  vaddr + offset, false, &entry);
268  fatal_if(!entry.present(),
269  "PageTable::unmap: Address %#x not mapped.", vaddr);
270  entry.present(false);
271  entry.write(system->physProxy);
272  DPRINTF(MMU, "Unmapping: %#x\n", vaddr);
273  }
274  }
275 
276  void
277  serialize(CheckpointOut &cp) const override
278  {
284  paramOut(cp, "ptable.pointer", _basePtr);
285  }
286 
287  void
289  {
291  paramIn(cp, "ptable.pointer", _basePtr);
292  }
293 };
294 #endif // __MEM_MULTI_LEVEL_PAGE_TABLE_HH__
#define DPRINTF(x,...)
Definition: trace.hh:229
virtual void remap(Addr vaddr, int64_t size, Addr new_vaddr)
Definition: page_table.cc:76
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:49
MultiLevelPageTable(const std::string &__name, uint64_t _pid, System *_sys, Addr pageSize)
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: page_table.cc:189
ip6_addr_t addr
Definition: inet.hh:335
void remap(Addr vaddr, int64_t size, Addr new_vaddr) override
void unmap(Addr vaddr, int64_t size) override
Addr allocPhysPages(int npages)
Allocate npages contiguous unused physical pages.
Definition: system.cc:428
LastType< EntryTypes... >::type Final
Definition: system.hh:77
Bitfield< 23, 0 > offset
Definition: types.hh:154
Definition: cprintf.cc:42
PortProxy physProxy
Port to physical memory used for writing object files into ram at boot.
Definition: system.hh:218
uint8_t type
Definition: inet.hh:333
Addr _basePtr
Physical address to the last level of the page table.
void memsetBlob(Addr addr, uint8_t v, int size) const
Same as tryMemsetBlob, but insists on success.
Definition: port_proxy.hh:199
void paramOut(CheckpointOut &cp, const string &name, ExtMachInst const &machInst)
Definition: types.cc:40
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:203
void map(Addr vaddr, Addr paddr, int64_t size, uint64_t flags=0) override
Maps a virtual memory region to a physical memory region.
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,16,32,64}_t.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
Bitfield< 15 > system
Definition: misc.hh:999
This object is a proxy for a port or other object which implements the functional response protocol...
Definition: port_proxy.hh:82
Declarations of a non-full system Page Table.
void serialize(CheckpointOut &cp) const override
Serialize an object.
std::ostream CheckpointOut
Definition: serialize.hh:68
System * system
Pointer to System object.
void paramIn(CheckpointIn &cp, const string &name, ExtMachInst &machInst)
Definition: types.cc:71
virtual void unmap(Addr vaddr, int64_t size)
Definition: page_table.cc:105
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: page_table.cc:173
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Bitfield< 0 > p

Generated on Fri Feb 28 2020 16:27:02 for gem5 by doxygen 1.8.13