gem5  v22.1.0.0
page_table.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 Advanced Micro Devices, Inc.
3  * Copyright (c) 2003 The Regents of The University of Michigan
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met: redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer;
10  * redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution;
13  * neither the name of the copyright holders nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
34 #include "mem/page_table.hh"
35 
36 #include <string>
37 
38 #include "base/compiler.hh"
39 #include "base/trace.hh"
40 #include "debug/MMU.hh"
41 #include "sim/faults.hh"
42 #include "sim/serialize.hh"
43 
44 namespace gem5
45 {
46 
47 void
48 EmulationPageTable::map(Addr vaddr, Addr paddr, int64_t size, uint64_t flags)
49 {
50  bool clobber = flags & Clobber;
51  // starting address must be page aligned
52  assert(pageOffset(vaddr) == 0);
53 
54  DPRINTF(MMU, "Allocating Page: %#x-%#x\n", vaddr, vaddr + size);
55 
56  while (size > 0) {
57  auto it = pTable.find(vaddr);
58  if (it != pTable.end()) {
59  // already mapped
60  panic_if(!clobber,
61  "EmulationPageTable::allocate: addr %#x already mapped",
62  vaddr);
63  it->second = Entry(paddr, flags);
64  } else {
65  pTable.emplace(vaddr, Entry(paddr, flags));
66  }
67 
68  size -= _pageSize;
69  vaddr += _pageSize;
70  paddr += _pageSize;
71  }
72 }
73 
74 void
75 EmulationPageTable::remap(Addr vaddr, int64_t size, Addr new_vaddr)
76 {
77  assert(pageOffset(vaddr) == 0);
78  assert(pageOffset(new_vaddr) == 0);
79 
80  DPRINTF(MMU, "moving pages from vaddr %08p to %08p, size = %d\n", vaddr,
81  new_vaddr, size);
82 
83  while (size > 0) {
84  [[maybe_unused]] auto new_it = pTable.find(new_vaddr);
85  auto old_it = pTable.find(vaddr);
86  assert(old_it != pTable.end() && new_it == pTable.end());
87 
88  pTable.emplace(new_vaddr, old_it->second);
89  pTable.erase(old_it);
90  size -= _pageSize;
91  vaddr += _pageSize;
92  new_vaddr += _pageSize;
93  }
94 }
95 
96 void
98 {
99  for (auto &iter : pTable)
100  addr_maps->push_back(std::make_pair(iter.first, iter.second.paddr));
101 }
102 
103 void
105 {
106  assert(pageOffset(vaddr) == 0);
107 
108  DPRINTF(MMU, "Unmapping page: %#x-%#x\n", vaddr, vaddr + size);
109 
110  while (size > 0) {
111  auto it = pTable.find(vaddr);
112  assert(it != pTable.end());
113  pTable.erase(it);
114  size -= _pageSize;
115  vaddr += _pageSize;
116  }
117 }
118 
119 bool
121 {
122  // starting address must be page aligned
123  assert(pageOffset(vaddr) == 0);
124 
125  for (int64_t offset = 0; offset < size; offset += _pageSize)
126  if (pTable.find(vaddr + offset) != pTable.end())
127  return false;
128 
129  return true;
130 }
131 
134 {
135  Addr page_addr = pageAlign(vaddr);
136  PTableItr iter = pTable.find(page_addr);
137  if (iter == pTable.end())
138  return nullptr;
139  return &(iter->second);
140 }
141 
142 bool
144 {
145  const Entry *entry = lookup(vaddr);
146  if (!entry) {
147  DPRINTF(MMU, "Couldn't Translate: %#x\n", vaddr);
148  return false;
149  }
150  paddr = pageOffset(vaddr) + entry->paddr;
151  DPRINTF(MMU, "Translating: %#x->%#x\n", vaddr, paddr);
152  return true;
153 }
154 
155 Fault
157 {
158  Addr paddr;
159  assert(pageAlign(req->getVaddr() + req->getSize() - 1) ==
160  pageAlign(req->getVaddr()));
161  if (!translate(req->getVaddr(), paddr))
162  return Fault(new GenericPageTableFault(req->getVaddr()));
163  req->setPaddr(paddr);
164  if ((paddr & (_pageSize - 1)) + req->getSize() > _pageSize) {
165  panic("Request spans page boundaries!\n");
166  return NoFault;
167  }
168  return NoFault;
169 }
170 
171 void
173 {
174  const Addr page_size = pt->pageSize();
175 
176  Addr next = roundUp(range.vaddr, page_size);
177  if (next == range.vaddr)
178  next += page_size;
179  range.size = std::min(range.size, next - range.vaddr);
180 
181  if (!pt->translate(range.vaddr, range.paddr))
182  range.fault = Fault(new GenericPageTableFault(range.vaddr));
183 }
184 
185 void
187 {
188  ScopedCheckpointSection sec(cp, "ptable");
189  paramOut(cp, "size", pTable.size());
190 
192  for (auto &pte : pTable) {
193  ScopedCheckpointSection sec(cp, csprintf("Entry%d", count++));
194 
195  paramOut(cp, "vaddr", pte.first);
196  paramOut(cp, "paddr", pte.second.paddr);
197  paramOut(cp, "flags", pte.second.flags);
198  }
199  assert(count == pTable.size());
200 }
201 
202 void
204 {
205  int count;
206  ScopedCheckpointSection sec(cp, "ptable");
207  paramIn(cp, "size", count);
208 
209  for (int i = 0; i < count; ++i) {
210  ScopedCheckpointSection sec(cp, csprintf("Entry%d", i));
211 
212  Addr vaddr;
214  Addr paddr;
215  uint64_t flags;
216  UNSERIALIZE_SCALAR(paddr);
218 
219  pTable.emplace(vaddr, Entry(paddr, flags));
220  }
221 }
222 
223 const std::string
225 {
226  std::stringstream ss;
227  for (PTable::const_iterator it=pTable.begin(); it != pTable.end(); ++it) {
228  ss << std::hex << it->first << ":" << it->second.paddr << ";";
229  }
230  return ss.str();
231 }
232 
233 } // namespace gem5
#define DPRINTF(x,...)
Definition: trace.hh:186
void translate(Range &range) const override
Subclasses implement this function to complete TranslationGen.
Definition: page_table.cc:172
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
const Entry * lookup(Addr vaddr)
Lookup function.
Definition: page_table.cc:133
virtual void remap(Addr vaddr, int64_t size, Addr new_vaddr)
Definition: page_table.cc:75
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: page_table.cc:186
bool translate(Addr vaddr, Addr &paddr)
Translate function.
Definition: page_table.cc:143
PTable::iterator PTableItr
Definition: page_table.hh:67
virtual void unmap(Addr vaddr, int64_t size)
Definition: page_table.cc:104
const std::string externalize() const
Dump all items in the pTable, to a concatenation of strings of the form Addr:Entry;.
Definition: page_table.cc:224
virtual bool isUnmapped(Addr vaddr, int64_t size)
Check if any pages in a region are already allocated.
Definition: page_table.cc:120
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: page_table.cc:203
void getMappings(std::vector< std::pair< Addr, Addr >> *addr_mappings)
Definition: page_table.cc:97
STL vector class.
Definition: stl.hh:37
static constexpr T roundUp(const T &val, const U &align)
This function is used to align addresses in memory.
Definition: intmath.hh:260
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:204
uint8_t flags
Definition: helpers.cc:66
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 23, 0 > offset
Definition: types.hh:144
unsigned int size_type
Definition: types.hh:60
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::shared_ptr< FaultBase > Fault
Definition: types.hh:248
std::shared_ptr< Request > RequestPtr
Definition: request.hh:92
std::ostream CheckpointOut
Definition: serialize.hh:66
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
void paramOut(CheckpointOut &cp, const std::string &name, ExtMachInst const &machInst)
Definition: types.cc:40
void paramIn(CheckpointIn &cp, const std::string &name, ExtMachInst &machInst)
Definition: types.cc:72
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:161
constexpr decltype(nullptr) NoFault
Definition: types.hh:253
Declarations of a non-full system Page Table.
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:575
This structure represents a single, contiguous translation, or carries information about whatever fau...
std::stringstream ss
Definition: trace.test.cc:45

Generated on Wed Dec 21 2022 10:22:37 for gem5 by doxygen 1.9.1