mips: Delete authors lists from mips files.
[gem5.git] / src / arch / mips / tlb.cc
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
30 #include "arch/mips/tlb.hh"
31
32 #include <string>
33 #include <vector>
34
35 #include "arch/mips/faults.hh"
36 #include "arch/mips/pagetable.hh"
37 #include "arch/mips/pra_constants.hh"
38 #include "arch/mips/utility.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/MipsPRA.hh"
44 #include "debug/TLB.hh"
45 #include "mem/page_table.hh"
46 #include "params/MipsTLB.hh"
47 #include "sim/process.hh"
48
49 using namespace std;
50 using namespace MipsISA;
51
52 ///////////////////////////////////////////////////////////////////////
53 //
54 // MIPS TLB
55 //
56
57 TLB::TLB(const Params *p)
58 : BaseTLB(p), size(p->size), nlu(0)
59 {
60 table = new PTE[size];
61 memset(table, 0, sizeof(PTE[size]));
62 smallPages = 0;
63 }
64
65 TLB::~TLB()
66 {
67 if (table)
68 delete [] table;
69 }
70
71 // look up an entry in the TLB
72 MipsISA::PTE *
73 TLB::lookup(Addr vpn, uint8_t asn) const
74 {
75 // assume not found...
76 PTE *retval = NULL;
77 PageTable::const_iterator i = lookupTable.find(vpn);
78 if (i != lookupTable.end()) {
79 while (i->first == vpn) {
80 int index = i->second;
81 PTE *pte = &table[index];
82
83 /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */
84 Addr Mask = pte->Mask;
85 Addr InvMask = ~Mask;
86 Addr VPN = pte->VPN;
87 if (((vpn & InvMask) == (VPN & InvMask)) &&
88 (pte->G || (asn == pte->asid))) {
89 // We have a VPN + ASID Match
90 retval = pte;
91 break;
92 }
93 ++i;
94 }
95 }
96
97 DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn,
98 retval ? "hit" : "miss", retval ? retval->PFN1 : 0);
99 return retval;
100 }
101
102 MipsISA::PTE*
103 TLB::getEntry(unsigned Index) const
104 {
105 // Make sure that Index is valid
106 assert(Index<size);
107 return &table[Index];
108 }
109
110 int
111 TLB::probeEntry(Addr vpn, uint8_t asn) const
112 {
113 // assume not found...
114 int Ind = -1;
115 PageTable::const_iterator i = lookupTable.find(vpn);
116 if (i != lookupTable.end()) {
117 while (i->first == vpn) {
118 int index = i->second;
119 PTE *pte = &table[index];
120
121 /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */
122 Addr Mask = pte->Mask;
123 Addr InvMask = ~Mask;
124 Addr VPN = pte->VPN;
125 if (((vpn & InvMask) == (VPN & InvMask)) &&
126 (pte->G || (asn == pte->asid))) {
127 // We have a VPN + ASID Match
128 Ind = index;
129 break;
130 }
131 ++i;
132 }
133 }
134 DPRINTF(MipsPRA,"VPN: %x, asid: %d, Result of TLBP: %d\n",vpn,asn,Ind);
135 return Ind;
136 }
137
138 inline Fault
139 TLB::checkCacheability(const RequestPtr &req)
140 {
141 Addr VAddrUncacheable = 0xA0000000;
142 // In MIPS, cacheability is controlled by certain bits of the virtual
143 // address or by the TLB entry
144 if ((req->getVaddr() & VAddrUncacheable) == VAddrUncacheable) {
145 // mark request as uncacheable
146 req->setFlags(Request::UNCACHEABLE | Request::STRICT_ORDER);
147 }
148 return NoFault;
149 }
150
151 void
152 TLB::insertAt(PTE &pte, unsigned Index, int _smallPages)
153 {
154 smallPages = _smallPages;
155 if (Index > size) {
156 warn("Attempted to write at index (%d) beyond TLB size (%d)",
157 Index, size);
158 } else {
159 // Update TLB
160 DPRINTF(TLB, "TLB[%d]: %x %x %x %x\n",
161 Index, pte.Mask << 11,
162 ((pte.VPN << 11) | pte.asid),
163 ((pte.PFN0 << 6) | (pte.C0 << 3) |
164 (pte.D0 << 2) | (pte.V0 <<1) | pte.G),
165 ((pte.PFN1 <<6) | (pte.C1 << 3) |
166 (pte.D1 << 2) | (pte.V1 <<1) | pte.G));
167 if (table[Index].V0 || table[Index].V1) {
168 // Previous entry is valid
169 PageTable::iterator i = lookupTable.find(table[Index].VPN);
170 lookupTable.erase(i);
171 }
172 table[Index]=pte;
173 // Update fast lookup table
174 lookupTable.insert(make_pair(table[Index].VPN, Index));
175 }
176 }
177
178 // insert a new TLB entry
179 void
180 TLB::insert(Addr addr, PTE &pte)
181 {
182 fatal("TLB Insert not yet implemented\n");
183 }
184
185 void
186 TLB::flushAll()
187 {
188 DPRINTF(TLB, "flushAll\n");
189 memset(table, 0, sizeof(PTE[size]));
190 lookupTable.clear();
191 nlu = 0;
192 }
193
194 void
195 TLB::serialize(CheckpointOut &cp) const
196 {
197 SERIALIZE_SCALAR(size);
198 SERIALIZE_SCALAR(nlu);
199
200 for (int i = 0; i < size; i++) {
201 ScopedCheckpointSection sec(cp, csprintf("PTE%d", i));
202 table[i].serialize(cp);
203 }
204 }
205
206 void
207 TLB::unserialize(CheckpointIn &cp)
208 {
209 UNSERIALIZE_SCALAR(size);
210 UNSERIALIZE_SCALAR(nlu);
211
212 for (int i = 0; i < size; i++) {
213 ScopedCheckpointSection sec(cp, csprintf("PTE%d", i));
214 table[i].unserialize(cp);
215 if (table[i].V0 || table[i].V1) {
216 lookupTable.insert(make_pair(table[i].VPN, i));
217 }
218 }
219 }
220
221 void
222 TLB::regStats()
223 {
224 BaseTLB::regStats();
225
226 read_hits
227 .name(name() + ".read_hits")
228 .desc("DTB read hits")
229 ;
230
231 read_misses
232 .name(name() + ".read_misses")
233 .desc("DTB read misses")
234 ;
235
236
237 read_accesses
238 .name(name() + ".read_accesses")
239 .desc("DTB read accesses")
240 ;
241
242 write_hits
243 .name(name() + ".write_hits")
244 .desc("DTB write hits")
245 ;
246
247 write_misses
248 .name(name() + ".write_misses")
249 .desc("DTB write misses")
250 ;
251
252
253 write_accesses
254 .name(name() + ".write_accesses")
255 .desc("DTB write accesses")
256 ;
257
258 hits
259 .name(name() + ".hits")
260 .desc("DTB hits")
261 ;
262
263 misses
264 .name(name() + ".misses")
265 .desc("DTB misses")
266 ;
267
268 accesses
269 .name(name() + ".accesses")
270 .desc("DTB accesses")
271 ;
272
273 hits = read_hits + write_hits;
274 misses = read_misses + write_misses;
275 accesses = read_accesses + write_accesses;
276 }
277
278 Fault
279 TLB::translateInst(const RequestPtr &req, ThreadContext *tc)
280 {
281 if (FullSystem)
282 panic("translateInst not implemented in MIPS.\n");
283
284 Process * p = tc->getProcessPtr();
285
286 Fault fault = p->pTable->translate(req);
287 if (fault != NoFault)
288 return fault;
289
290 return NoFault;
291 }
292
293 Fault
294 TLB::translateData(const RequestPtr &req, ThreadContext *tc, bool write)
295 {
296 if (FullSystem)
297 panic("translateData not implemented in MIPS.\n");
298
299 Process * p = tc->getProcessPtr();
300
301 Fault fault = p->pTable->translate(req);
302 if (fault != NoFault)
303 return fault;
304
305 return NoFault;
306 }
307
308 Fault
309 TLB::translateAtomic(const RequestPtr &req, ThreadContext *tc, Mode mode)
310 {
311 if (mode == Execute)
312 return translateInst(req, tc);
313 else
314 return translateData(req, tc, mode == Write);
315 }
316
317 void
318 TLB::translateTiming(const RequestPtr &req, ThreadContext *tc,
319 Translation *translation, Mode mode)
320 {
321 assert(translation);
322 translation->finish(translateAtomic(req, tc, mode), req, tc, mode);
323 }
324
325 Fault
326 TLB::finalizePhysical(const RequestPtr &req,
327 ThreadContext *tc, Mode mode) const
328 {
329 return NoFault;
330 }
331
332
333 MipsISA::PTE &
334 TLB::index(bool advance)
335 {
336 PTE *pte = &table[nlu];
337
338 if (advance)
339 nextnlu();
340
341 return *pte;
342 }
343
344 MipsISA::TLB *
345 MipsTLBParams::create()
346 {
347 return new TLB(this);
348 }