gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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  * 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  * Authors: Nathan Binkert
30  * Steve Reinhardt
31  * Jaidev Patwardhan
32  * Zhengxing Li
33  * Deyuan Guo
34  */
35 
36 #include "arch/riscv/tlb.hh"
37 
38 #include <string>
39 #include <vector>
40 
41 #include "arch/riscv/faults.hh"
42 #include "arch/riscv/pagetable.hh"
44 #include "arch/riscv/utility.hh"
45 #include "base/inifile.hh"
46 #include "base/str.hh"
47 #include "base/trace.hh"
48 #include "cpu/thread_context.hh"
49 #include "debug/RiscvTLB.hh"
50 #include "debug/TLB.hh"
51 #include "mem/page_table.hh"
52 #include "params/RiscvTLB.hh"
53 #include "sim/full_system.hh"
54 #include "sim/process.hh"
55 
56 using namespace std;
57 using namespace RiscvISA;
58 
60 //
61 // RISC-V TLB
62 //
63 
64 TLB::TLB(const Params *p)
65  : BaseTLB(p), size(p->size), nlu(0)
66 {
67  table = new PTE[size];
68  memset(table, 0, sizeof(PTE[size]));
69  smallPages = 0;
70 }
71 
73 {
74  if (table)
75  delete [] table;
76 }
77 
78 // look up an entry in the TLB
80 TLB::lookup(Addr vpn, uint8_t asn) const
81 {
82  // assume not found...
83  PTE *retval = nullptr;
84  PageTable::const_iterator i = lookupTable.find(vpn);
85  if (i != lookupTable.end()) {
86  while (i->first == vpn) {
87  int index = i->second;
88  PTE *pte = &table[index];
89 
90  /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */
91  Addr Mask = pte->Mask;
92  Addr InvMask = ~Mask;
93  Addr VPN = pte->VPN;
94  if (((vpn & InvMask) == (VPN & InvMask)) &&
95  (pte->G || (asn == pte->asid))) {
96  // We have a VPN + ASID Match
97  retval = pte;
98  break;
99  }
100  ++i;
101  }
102  }
103 
104  DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn,
105  retval ? "hit" : "miss", retval ? retval->PFN1 : 0);
106  return retval;
107 }
108 
110 TLB::getEntry(unsigned Index) const
111 {
112  // Make sure that Index is valid
113  assert(Index<size);
114  return &table[Index];
115 }
116 
117 int
118 TLB::probeEntry(Addr vpn, uint8_t asn) const
119 {
120  // assume not found...
121  int Ind = -1;
122  PageTable::const_iterator i = lookupTable.find(vpn);
123  if (i != lookupTable.end()) {
124  while (i->first == vpn) {
125  int index = i->second;
126  PTE *pte = &table[index];
127 
128  /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */
129  Addr Mask = pte->Mask;
130  Addr InvMask = ~Mask;
131  Addr VPN = pte->VPN;
132  if (((vpn & InvMask) == (VPN & InvMask)) &&
133  (pte->G || (asn == pte->asid))) {
134  // We have a VPN + ASID Match
135  Ind = index;
136  break;
137  }
138  ++i;
139  }
140  }
141  DPRINTF(RiscvTLB,"VPN: %x, asid: %d, Result of TLBP: %d\n",vpn,asn,Ind);
142  return Ind;
143 }
144 
145 inline Fault
147 {
148  Addr VAddrUncacheable = 0xA0000000;
149  // In MIPS, cacheability is controlled by certain bits of the virtual
150  // address or by the TLB entry
151  if ((req->getVaddr() & VAddrUncacheable) == VAddrUncacheable) {
152  // mark request as uncacheable
154  }
155  return NoFault;
156 }
157 
158 void
159 TLB::insertAt(PTE &pte, unsigned Index, int _smallPages)
160 {
161  smallPages = _smallPages;
162  if (Index > size) {
163  warn("Attempted to write at index (%d) beyond TLB size (%d)",
164  Index, size);
165  } else {
166  // Update TLB
167  DPRINTF(TLB, "TLB[%d]: %x %x %x %x\n",
168  Index, pte.Mask << 11,
169  ((pte.VPN << 11) | pte.asid),
170  ((pte.PFN0 << 6) | (pte.C0 << 3) |
171  (pte.D0 << 2) | (pte.V0 <<1) | pte.G),
172  ((pte.PFN1 <<6) | (pte.C1 << 3) |
173  (pte.D1 << 2) | (pte.V1 <<1) | pte.G));
174  if (table[Index].V0 || table[Index].V1) {
175  // Previous entry is valid
176  PageTable::iterator i = lookupTable.find(table[Index].VPN);
177  lookupTable.erase(i);
178  }
179  table[Index]=pte;
180  // Update fast lookup table
181  lookupTable.insert(make_pair(table[Index].VPN, Index));
182  }
183 }
184 
185 // insert a new TLB entry
186 void
188 {
189  fatal("TLB Insert not yet implemented\n");
190 }
191 
192 void
194 {
195  DPRINTF(TLB, "flushAll\n");
196  memset(table, 0, sizeof(PTE[size]));
197  lookupTable.clear();
198  nlu = 0;
199 }
200 
201 void
203 {
206 
207  for (int i = 0; i < size; i++) {
208  ScopedCheckpointSection sec(cp, csprintf("PTE%d", i));
209  table[i].serialize(cp);
210  }
211 }
212 
213 void
215 {
218 
219  for (int i = 0; i < size; i++) {
220  ScopedCheckpointSection sec(cp, csprintf("PTE%d", i));
221  table[i].unserialize(cp);
222  if (table[i].V0 || table[i].V1) {
223  lookupTable.insert(make_pair(table[i].VPN, i));
224  }
225  }
226 }
227 
228 void
230 {
232 
233  read_hits
234  .name(name() + ".read_hits")
235  .desc("DTB read hits")
236  ;
237 
239  .name(name() + ".read_misses")
240  .desc("DTB read misses")
241  ;
242 
243 
245  .name(name() + ".read_accesses")
246  .desc("DTB read accesses")
247  ;
248 
249  write_hits
250  .name(name() + ".write_hits")
251  .desc("DTB write hits")
252  ;
253 
255  .name(name() + ".write_misses")
256  .desc("DTB write misses")
257  ;
258 
259 
261  .name(name() + ".write_accesses")
262  .desc("DTB write accesses")
263  ;
264 
265  hits
266  .name(name() + ".hits")
267  .desc("DTB hits")
268  ;
269 
270  misses
271  .name(name() + ".misses")
272  .desc("DTB misses")
273  ;
274 
275  accesses
276  .name(name() + ".accesses")
277  .desc("DTB accesses")
278  ;
279 
283 }
284 
285 Fault
287 {
288  if (FullSystem)
289  panic("translateInst not implemented in RISC-V.\n");
290 
291  Process * p = tc->getProcessPtr();
292 
293  Fault fault = p->pTable->translate(req);
294  if (fault != NoFault)
295  return fault;
296 
297  return NoFault;
298 }
299 
300 Fault
302 {
303  if (FullSystem)
304  panic("translateData not implemented in RISC-V.\n");
305 
306  // In the O3 CPU model, sometimes a memory access will be speculatively
307  // executed along a branch that will end up not being taken where the
308  // address is invalid. In that case, return a fault rather than trying
309  // to translate it (which will cause a panic). Since RISC-V allows
310  // unaligned memory accesses, this should only happen if the request's
311  // length is long enough to wrap around from the end of the memory to the
312  // start.
313  assert(req->getSize() > 0);
314  if (req->getVaddr() + req->getSize() - 1 < req->getVaddr())
315  return make_shared<GenericPageTableFault>(req->getVaddr());
316 
317  Process * p = tc->getProcessPtr();
318 
319  Fault fault = p->pTable->translate(req);
320  if (fault != NoFault)
321  return fault;
322 
323  return NoFault;
324 }
325 
326 Fault
328 {
329  if (mode == Execute)
330  return translateInst(req, tc);
331  else
332  return translateData(req, tc, mode == Write);
333 }
334 
335 void
337  Translation *translation, Mode mode)
338 {
339  assert(translation);
340  translation->finish(translateAtomic(req, tc, mode), req, tc, mode);
341 }
342 
343 Fault
345 {
346  panic("Not implemented\n");
347  return NoFault;
348 }
349 
350 Fault
352 {
353  return NoFault;
354 }
355 
356 
358 TLB::index(bool advance)
359 {
360  PTE *pte = &table[nlu];
361 
362  if (advance)
363  nextnlu();
364 
365  return *pte;
366 }
367 
369 RiscvTLBParams::create()
370 {
371  return new TLB(this);
372 }
#define DPRINTF(x,...)
Definition: trace.hh:212
void unserialize(CheckpointIn &cp)
Definition: pagetable.cc:61
Stats::Scalar write_accesses
Definition: tlb.hh:76
decltype(nullptr) constexpr NoFault
Definition: types.hh:189
void insert(Addr vaddr, RiscvISA::PTE &pte)
Definition: tlb.cc:187
void insertAt(RiscvISA::PTE &pte, unsigned Index, int _smallPages)
Definition: tlb.cc:159
int smallPages
Definition: tlb.hh:91
#define panic(...)
Definition: misc.hh:153
PageTable lookupTable
Definition: tlb.hh:60
Stats::Formula accesses
Definition: tlb.hh:79
Stats::Formula misses
Definition: tlb.hh:78
void nextnlu()
Definition: tlb.hh:66
Fault translateData(RequestPtr req, ThreadContext *tc, bool write)
Definition: tlb.cc:301
RiscvISA::PTE * lookup(Addr vpn, uint8_t asn) const
Definition: tlb.cc:80
ip6_addr_t addr
Definition: inet.hh:335
int probeEntry(Addr vpn, uint8_t) const
Definition: tlb.cc:118
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:146
virtual Process * getProcessPtr()=0
Bitfield< 4, 0 > mode
Definition: miscregs.hh:1385
virtual void regStats()
Register statistics for this object.
Definition: sim_object.cc:105
ThreadContext is the external interface to all thread state for anything outside of the CPU...
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: tlb.cc:202
RiscvISA::PTE * table
Definition: tlb.hh:62
Bitfield< 0 > p
int size
Definition: tlb.hh:63
#define warn(...)
Definition: misc.hh:219
Stats::Formula hits
Definition: tlb.hh:77
uint8_t C0
Definition: pagetable.hh:60
Definition: tlb.hh:53
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:145
uint8_t asid
Definition: pagetable.hh:52
void serialize(CheckpointOut &cp) const
Definition: pagetable.cc:42
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:161
void flushAll() override
Remove all entries from the TLB.
Definition: tlb.cc:193
Fault finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const
Definition: tlb.cc:351
bool translate(Addr vaddr, Addr &paddr)
Translate function.
Definition: page_table.cc:173
The request is to an uncacheable address.
Definition: request.hh:114
void regStats() override
Register statistics for this object.
Definition: tlb.cc:229
Stats::Scalar read_accesses
Definition: tlb.hh:72
#define fatal(...)
Definition: misc.hh:163
Bitfield< 2 > i
RiscvISA::PTE & index(bool advance=true)
Definition: tlb.cc:358
static Fault checkCacheability(RequestPtr &req)
Definition: tlb.cc:146
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
Declaration of IniFile object.
Fault translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode)
Function stub for CheckerCPU compilation issues.
Definition: tlb.cc:344
PageTableBase * pTable
Definition: process.hh:178
RiscvTLBParams Params
Definition: tlb.hh:82
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:143
Mode
Definition: tlb.hh:61
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
Definition: statistics.hh:254
Stats::Scalar read_misses
Definition: tlb.hh:70
int size()
Definition: pagetable.hh:146
Stats::Scalar read_hits
Definition: tlb.hh:69
virtual const std::string name() const
Definition: sim_object.hh:117
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: tlb.cc:214
void translateTiming(RequestPtr req, ThreadContext *tc, Translation *translation, Mode mode)
Definition: tlb.cc:336
Declarations of a non-full system Page Table.
std::ostream CheckpointOut
Definition: serialize.hh:67
Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
Definition: tlb.cc:327
Addr getVaddr() const
Definition: request.hh:616
Fault translateInst(RequestPtr req, ThreadContext *tc)
Definition: tlb.cc:286
int nlu
Definition: tlb.hh:64
The request is required to be strictly ordered by CPU models and is non-speculative.
Definition: request.hh:124
virtual ~TLB()
Definition: tlb.cc:72
Stats::Scalar write_hits
Definition: tlb.hh:73
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
Definition: statistics.hh:287
unsigned getSize() const
Definition: request.hh:552
Scoped checkpoint section helper class.
Definition: serialize.hh:240
Bitfield< 0 > p
virtual void finish(const Fault &fault, RequestPtr req, ThreadContext *tc, Mode mode)=0
void setFlags(Flags flags)
Note that unlike other accessors, this function sets specific flags (ORs them in); it does not assign...
Definition: request.hh:595
std::shared_ptr< FaultBase > Fault
Definition: types.hh:184
Stats::Scalar write_misses
Definition: tlb.hh:74
uint8_t C1
Definition: pagetable.hh:66
RiscvISA::PTE * getEntry(unsigned) const
Definition: tlb.cc:110

Generated on Fri Jun 9 2017 13:03:36 for gem5 by doxygen 1.8.6