gem5  v22.1.0.0
tlb.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2001-2005 The Regents of The University of Michigan
3  * Copyright (c) 2007 MIPS Technologies, Inc.
4  * Copyright (c) 2007-2008 The Florida State University
5  * Copyright (c) 2009 The University of Edinburgh
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are
10  * met: redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer;
12  * redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution;
15  * neither the name of the copyright holders nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include "arch/power/tlb.hh"
33 
34 #include <string>
35 #include <vector>
36 
37 #include "arch/power/faults.hh"
38 #include "arch/power/pagetable.hh"
39 #include "base/inifile.hh"
40 #include "base/str.hh"
41 #include "base/trace.hh"
42 #include "cpu/thread_context.hh"
43 #include "debug/Power.hh"
44 #include "debug/TLB.hh"
45 #include "mem/page_table.hh"
46 #include "params/PowerTLB.hh"
47 #include "sim/full_system.hh"
48 #include "sim/process.hh"
49 
50 namespace gem5
51 {
52 
53 using namespace PowerISA;
54 
56 //
57 // POWER TLB
58 //
59 
60 #define MODE2MASK(X) (1 << (X))
61 
62 TLB::TLB(const Params &p) : BaseTLB(p), size(p.size), nlu(0)
63 {
64  table = new PowerISA::PTE[size];
65  memset(table, 0, sizeof(PowerISA::PTE[size]));
66  smallPages = 0;
67 }
68 
69 TLB::~TLB()
70 {
71  if (table)
72  delete [] table;
73 }
74 
75 // look up an entry in the TLB
76 PowerISA::PTE *
77 TLB::lookup(Addr vpn, uint8_t asn) const
78 {
79  // assume not found...
80  PowerISA::PTE *retval = NULL;
81  PageTable::const_iterator i = lookupTable.find(vpn);
82  if (i != lookupTable.end()) {
83  while (i->first == vpn) {
84  int index = i->second;
85  PowerISA::PTE *pte = &table[index];
86  Addr Mask = pte->Mask;
87  Addr InvMask = ~Mask;
88  Addr VPN = pte->VPN;
89  if (((vpn & InvMask) == (VPN & InvMask))
90  && (pte->G || (asn == pte->asid))) {
91 
92  // We have a VPN + ASID Match
93  retval = pte;
94  break;
95  }
96  ++i;
97  }
98  }
99 
100  DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn,
101  retval ? "hit" : "miss", retval ? retval->PFN1 : 0);
102  return retval;
103 }
104 
105 PowerISA::PTE*
106 TLB::getEntry(unsigned Index) const
107 {
108  // Make sure that Index is valid
109  assert(Index<size);
110  return &table[Index];
111 }
112 
113 int
114 TLB::probeEntry(Addr vpn,uint8_t asn) const
115 {
116  // assume not found...
117  int Ind = -1;
118  PageTable::const_iterator i = lookupTable.find(vpn);
119  if (i != lookupTable.end()) {
120  while (i->first == vpn) {
121  int index = i->second;
122  PowerISA::PTE *pte = &table[index];
123  Addr Mask = pte->Mask;
124  Addr InvMask = ~Mask;
125  Addr VPN = pte->VPN;
126  if (((vpn & InvMask) == (VPN & InvMask))
127  && (pte->G || (asn == pte->asid))) {
128 
129  // We have a VPN + ASID Match
130  Ind = index;
131  break;
132  }
133  ++i;
134  }
135  }
136 
137  DPRINTF(Power, "VPN: %x, asid: %d, Result of TLBP: %d\n", vpn, asn, Ind);
138  return Ind;
139 }
140 
141 inline Fault
142 TLB::checkCacheability(const RequestPtr &req)
143 {
144  Addr VAddrUncacheable = 0xA0000000;
145  if ((req->getVaddr() & VAddrUncacheable) == VAddrUncacheable) {
146 
147  // mark request as uncacheable
148  req->setFlags(Request::UNCACHEABLE | Request::STRICT_ORDER);
149  }
150  return NoFault;
151 }
152 
153 void
154 TLB::insertAt(PowerISA::PTE &pte, unsigned Index, int _smallPages)
155 {
156  smallPages=_smallPages;
157  if (Index > size){
158  warn("Attempted to write at index (%d) beyond TLB size (%d)",
159  Index, size);
160  } else {
161 
162  // Update TLB
163  if (table[Index].V0 || table[Index].V1) {
164 
165  // Previous entry is valid
166  PageTable::iterator i = lookupTable.find(table[Index].VPN);
167  lookupTable.erase(i);
168  }
169  table[Index]=pte;
170 
171  // Update fast lookup table
172  lookupTable.insert(std::make_pair(table[Index].VPN, Index));
173  }
174 }
175 
176 // insert a new TLB entry
177 void
178 TLB::insert(Addr addr, PowerISA::PTE &pte)
179 {
180  fatal("TLB Insert not yet implemented\n");
181 }
182 
183 void
184 TLB::flushAll()
185 {
186  DPRINTF(TLB, "flushAll\n");
187  memset(table, 0, sizeof(PowerISA::PTE[size]));
188  lookupTable.clear();
189  nlu = 0;
190 }
191 
192 void
193 TLB::serialize(CheckpointOut &cp) const
194 {
195  SERIALIZE_SCALAR(size);
196  SERIALIZE_SCALAR(nlu);
197 
198  for (int i = 0; i < size; i++) {
199  ScopedCheckpointSection sec(cp, csprintf("PTE%d", i));
200  table[i].serialize(cp);
201  }
202 }
203 
204 void
205 TLB::unserialize(CheckpointIn &cp)
206 {
207  UNSERIALIZE_SCALAR(size);
208  UNSERIALIZE_SCALAR(nlu);
209 
210  for (int i = 0; i < size; i++) {
211  ScopedCheckpointSection sec(cp, csprintf("PTE%d", i));
212  if (table[i].V0 || table[i].V1) {
213  lookupTable.insert(std::make_pair(table[i].VPN, i));
214  }
215  }
216 }
217 
218 Fault
219 TLB::translateInst(const RequestPtr &req, ThreadContext *tc)
220 {
221  Addr vaddr = req->getVaddr();
222 
223  // Instruction accesses must be word-aligned
224  if (vaddr & 0x3) {
225  DPRINTF(TLB, "Alignment Fault on %#x, size = %d\n", vaddr,
226  req->getSize());
227  return std::make_shared<AlignmentFault>(vaddr);
228  }
229 
230  return tc->getProcessPtr()->pTable->translate(req);
231 }
232 
233 Fault
234 TLB::translateData(const RequestPtr &req, ThreadContext *tc, bool write)
235 {
236  return tc->getProcessPtr()->pTable->translate(req);
237 }
238 
239 Fault
240 TLB::translateAtomic(const RequestPtr &req, ThreadContext *tc,
242 {
244  "translateAtomic not yet implemented for full system.");
245 
246  if (mode == BaseMMU::Execute)
247  return translateInst(req, tc);
248  else
249  return translateData(req, tc, mode == BaseMMU::Write);
250 }
251 
252 Fault
253 TLB::translateFunctional(const RequestPtr &req, ThreadContext *tc,
255 {
257  "translateFunctional not implemented for full system.");
258  return tc->getProcessPtr()->pTable->translate(req);
259 }
260 
261 void
262 TLB::translateTiming(const RequestPtr &req, ThreadContext *tc,
263  BaseMMU::Translation *translation, BaseMMU::Mode mode)
264 {
265  assert(translation);
266  translation->finish(translateAtomic(req, tc, mode), req, tc, mode);
267 }
268 
269 Fault
270 TLB::finalizePhysical(const RequestPtr &req,
271  ThreadContext *tc, BaseMMU::Mode mode) const
272 {
273  return NoFault;
274 }
275 
276 PowerISA::PTE &
277 TLB::index(bool advance)
278 {
279  PowerISA::PTE *pte = &table[nlu];
280 
281  if (advance)
282  nextnlu();
283 
284  return *pte;
285 }
286 
287 } // namespace gem5
#define DPRINTF(x,...)
Definition: trace.hh:186
bool translate(Addr vaddr, Addr &paddr)
Translate function.
Definition: page_table.cc:143
TLB(const Params &p)
EmulationPageTable * pTable
Definition: process.hh:185
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual Process * getProcessPtr()=0
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:190
#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
Declaration of IniFile object.
#define warn(...)
Definition: logging.hh:246
Bitfield< 4, 0 > mode
Definition: misc_types.hh:74
Bitfield< 7 > i
Definition: misc_types.hh:67
constexpr RegId V1
Definition: int.hh:137
constexpr RegId V0
Definition: int.hh:136
Bitfield< 30, 0 > index
Bitfield< 54 > p
Definition: pagetable.hh:70
Bitfield< 3 > addr
Definition: types.hh:84
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 unserialize(ThreadContext &tc, CheckpointIn &cp)
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:220
void serialize(const ThreadContext &tc, CheckpointOut &cp)
Thread context serialization helpers.
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
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:568

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