tlb.cc (3806:65ae5388c059) tlb.cc (3811:ee71d61347f1)
1/*
2 * Copyright (c) 2001-2005 The Regents of The University of Michigan
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;

--- 15 unchanged lines hidden (view full) ---

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: Ali Saidi
29 */
30
31#include "arch/sparc/asi.hh"
1/*
2 * Copyright (c) 2001-2005 The Regents of The University of Michigan
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;

--- 15 unchanged lines hidden (view full) ---

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: Ali Saidi
29 */
30
31#include "arch/sparc/asi.hh"
32#include "arch/sparc/tlb.hh"
33#include "sim/builder.hh"
34#include "arch/sparc/miscregfile.hh"
32#include "arch/sparc/miscregfile.hh"
33#include "arch/sparc/tlb.hh"
34#include "base/trace.hh"
35#include "cpu/thread_context.hh"
35#include "cpu/thread_context.hh"
36#include "sim/builder.hh"
36
37/* @todo remove some of the magic constants. -- ali
38 * */
39namespace SparcISA
40{
41
42TLB::TLB(const std::string &name, int s)
43 : SimObject(name), size(s)

--- 23 unchanged lines hidden (view full) ---

67void
68TLB::insert(Addr va, int partition_id, int context_id, bool real,
69 const PageTableEntry& PTE)
70{
71
72
73 MapIter i;
74 TlbEntry *new_entry;
37
38/* @todo remove some of the magic constants. -- ali
39 * */
40namespace SparcISA
41{
42
43TLB::TLB(const std::string &name, int s)
44 : SimObject(name), size(s)

--- 23 unchanged lines hidden (view full) ---

68void
69TLB::insert(Addr va, int partition_id, int context_id, bool real,
70 const PageTableEntry& PTE)
71{
72
73
74 MapIter i;
75 TlbEntry *new_entry;
76
77 DPRINTF(TLB, "TLB: Inserting TLB Entry; va=%#x, pid=%d cid=%d r=%d\n",
78 va, partition_id, context_id, (int)real);
79
75 int x = -1;
76 for (x = 0; x < size; x++) {
77 if (!tlb[x].valid || !tlb[x].used) {
78 new_entry = &tlb[x];
79 break;
80 }
81 }
82

--- 16 unchanged lines hidden (view full) ---

99 // Demap any entry that conflicts
100 i = lookupTable.find(new_entry->range);
101 if (i != lookupTable.end()) {
102 i->second->valid = false;
103 if (i->second->used) {
104 i->second->used = false;
105 usedEntries--;
106 }
80 int x = -1;
81 for (x = 0; x < size; x++) {
82 if (!tlb[x].valid || !tlb[x].used) {
83 new_entry = &tlb[x];
84 break;
85 }
86 }
87

--- 16 unchanged lines hidden (view full) ---

104 // Demap any entry that conflicts
105 i = lookupTable.find(new_entry->range);
106 if (i != lookupTable.end()) {
107 i->second->valid = false;
108 if (i->second->used) {
109 i->second->used = false;
110 usedEntries--;
111 }
112 DPRINTF(TLB, "TLB: Found conflicting entry, deleting it\n");
107 lookupTable.erase(i);
108 }
109
110 lookupTable.insert(new_entry->range, new_entry);;
111
112 // If all entries have there used bit set, clear it on them all, but the
113 // one we just inserted
114 if (usedEntries == size) {

--- 7 unchanged lines hidden (view full) ---

122
123TlbEntry*
124TLB::lookup(Addr va, int partition_id, bool real, int context_id)
125{
126 MapIter i;
127 TlbRange tr;
128 TlbEntry *t;
129
113 lookupTable.erase(i);
114 }
115
116 lookupTable.insert(new_entry->range, new_entry);;
117
118 // If all entries have there used bit set, clear it on them all, but the
119 // one we just inserted
120 if (usedEntries == size) {

--- 7 unchanged lines hidden (view full) ---

128
129TlbEntry*
130TLB::lookup(Addr va, int partition_id, bool real, int context_id)
131{
132 MapIter i;
133 TlbRange tr;
134 TlbEntry *t;
135
136 DPRINTF(TLB, "TLB: Looking up entry va=%#x pid=%d cid=%d r=%d\n",
137 va, partition_id, context_id, real);
130 // Assemble full address structure
131 tr.va = va;
132 tr.size = va + MachineBytes;
133 tr.contextId = context_id;
134 tr.partitionId = partition_id;
135 tr.real = real;
136
137 // Try to find the entry
138 i = lookupTable.find(tr);
139 if (i == lookupTable.end()) {
138 // Assemble full address structure
139 tr.va = va;
140 tr.size = va + MachineBytes;
141 tr.contextId = context_id;
142 tr.partitionId = partition_id;
143 tr.real = real;
144
145 // Try to find the entry
146 i = lookupTable.find(tr);
147 if (i == lookupTable.end()) {
148 DPRINTF(TLB, "TLB: No valid entry found\n");
140 return NULL;
141 }
149 return NULL;
150 }
151 DPRINTF(TLB, "TLB: Valid entry found\n");
142
143 // Mark the entries used bit and clear other used bits in needed
144 t = i->second;
145 if (!t->used) {
146 t->used = true;
147 usedEntries++;
148 if (usedEntries == size) {
149 clearUsedBits();

--- 124 unchanged lines hidden (view full) ---

274 tc->setMiscReg(reg, sfsr);
275}
276
277
278void
279ITB::writeSfsr(ThreadContext *tc, bool write, ContextType ct,
280 bool se, FaultTypes ft, int asi)
281{
152
153 // Mark the entries used bit and clear other used bits in needed
154 t = i->second;
155 if (!t->used) {
156 t->used = true;
157 usedEntries++;
158 if (usedEntries == size) {
159 clearUsedBits();

--- 124 unchanged lines hidden (view full) ---

284 tc->setMiscReg(reg, sfsr);
285}
286
287
288void
289ITB::writeSfsr(ThreadContext *tc, bool write, ContextType ct,
290 bool se, FaultTypes ft, int asi)
291{
292 DPRINTF(TLB, "TLB: ITB Fault: w=%d ct=%d ft=%d asi=%d\n",
293 (int)write, ct, ft, asi);
282 TLB::writeSfsr(tc, MISCREG_MMU_ITLB_SFSR, write, ct, se, ft, asi);
283}
284
285void
286DTB::writeSfr(ThreadContext *tc, Addr a, bool write, ContextType ct,
287 bool se, FaultTypes ft, int asi)
288{
294 TLB::writeSfsr(tc, MISCREG_MMU_ITLB_SFSR, write, ct, se, ft, asi);
295}
296
297void
298DTB::writeSfr(ThreadContext *tc, Addr a, bool write, ContextType ct,
299 bool se, FaultTypes ft, int asi)
300{
301 DPRINTF(TLB, "TLB: DTB Fault: A=%#x w=%d ct=%d ft=%d asi=%d\n",
302 a, (int)write, ct, ft, asi);
289 TLB::writeSfsr(tc, MISCREG_MMU_DTLB_SFSR, write, ct, se, ft, asi);
290 tc->setMiscReg(MISCREG_MMU_DTLB_SFAR, a);
291}
292
293
294Fault
295ITB::translate(RequestPtr &req, ThreadContext *tc)
296{

--- 6 unchanged lines hidden (view full) ---

303 bool priv = pstate >> 2 & 0x1;
304 Addr vaddr = req->getVaddr();
305 int context;
306 ContextType ct;
307 int asi;
308 bool real = false;
309 TlbEntry *e;
310
303 TLB::writeSfsr(tc, MISCREG_MMU_DTLB_SFSR, write, ct, se, ft, asi);
304 tc->setMiscReg(MISCREG_MMU_DTLB_SFAR, a);
305}
306
307
308Fault
309ITB::translate(RequestPtr &req, ThreadContext *tc)
310{

--- 6 unchanged lines hidden (view full) ---

317 bool priv = pstate >> 2 & 0x1;
318 Addr vaddr = req->getVaddr();
319 int context;
320 ContextType ct;
321 int asi;
322 bool real = false;
323 TlbEntry *e;
324
325 DPRINTF(TLB, "TLB: ITB Request to translate va=%#x size=%d\n",
326 vaddr, req->getSize());
327
311 assert(req->getAsi() == ASI_IMPLICIT);
312
313 if (tl > 0) {
314 asi = ASI_N;
315 ct = Nucleus;
316 context = 0;
317 } else {
318 asi = ASI_P;

--- 61 unchanged lines hidden (view full) ---

380 uint64_t part_id = tc->readMiscReg(MISCREG_MMU_PART_ID);
381 bool hpriv = hpstate >> 2 & 0x1;
382 bool red = hpstate >> 5 >> 0x1;
383 bool addr_mask = pstate >> 3 & 0x1;
384 bool priv = pstate >> 2 & 0x1;
385 bool implicit = false;
386 bool real = false;
387 Addr vaddr = req->getVaddr();
328 assert(req->getAsi() == ASI_IMPLICIT);
329
330 if (tl > 0) {
331 asi = ASI_N;
332 ct = Nucleus;
333 context = 0;
334 } else {
335 asi = ASI_P;

--- 61 unchanged lines hidden (view full) ---

397 uint64_t part_id = tc->readMiscReg(MISCREG_MMU_PART_ID);
398 bool hpriv = hpstate >> 2 & 0x1;
399 bool red = hpstate >> 5 >> 0x1;
400 bool addr_mask = pstate >> 3 & 0x1;
401 bool priv = pstate >> 2 & 0x1;
402 bool implicit = false;
403 bool real = false;
404 Addr vaddr = req->getVaddr();
405 Addr size = req->getSize();
388 ContextType ct;
389 int context;
390 ASI asi;
391
392 TlbEntry *e;
393
406 ContextType ct;
407 int context;
408 ASI asi;
409
410 TlbEntry *e;
411
394
395 asi = (ASI)req->getAsi();
412 asi = (ASI)req->getAsi();
413 DPRINTF(TLB, "TLB: DTB Request to translate va=%#x size=%d asi=%#x\n",
414 vaddr, size, asi);
415
396 if (asi == ASI_IMPLICIT)
397 implicit = true;
398
399 if (implicit) {
400 if (tl > 0) {
401 asi = ASI_N;
402 ct = Nucleus;
403 context = 0;

--- 23 unchanged lines hidden (view full) ---

427 if (priv && AsiIsHPriv(asi)) {
428 writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi);
429 return new DataAccessException;
430 }
431
432 }
433
434 // If the asi is unaligned trap
416 if (asi == ASI_IMPLICIT)
417 implicit = true;
418
419 if (implicit) {
420 if (tl > 0) {
421 asi = ASI_N;
422 ct = Nucleus;
423 context = 0;

--- 23 unchanged lines hidden (view full) ---

447 if (priv && AsiIsHPriv(asi)) {
448 writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi);
449 return new DataAccessException;
450 }
451
452 }
453
454 // If the asi is unaligned trap
435 if (AsiIsBlock(asi) && vaddr & 0x3f || vaddr & 0x7) {
455 if (vaddr & size-1) {
436 writeSfr(tc, vaddr, false, ct, false, OtherFault, asi);
437 return new MemAddressNotAligned;
438 }
439
440 if (addr_mask)
441 vaddr = vaddr & VAddrAMask;
442
443 if (!validVirtualAddress(vaddr, addr_mask)) {

--- 29 unchanged lines hidden (view full) ---

473 return NoFault;
474 }
475
476 e = lookup(req->getVaddr(), part_id, real, context);
477
478 if (e == NULL || !e->valid) {
479 tc->setMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS,
480 vaddr & ~BytesInPageMask | context);
456 writeSfr(tc, vaddr, false, ct, false, OtherFault, asi);
457 return new MemAddressNotAligned;
458 }
459
460 if (addr_mask)
461 vaddr = vaddr & VAddrAMask;
462
463 if (!validVirtualAddress(vaddr, addr_mask)) {

--- 29 unchanged lines hidden (view full) ---

493 return NoFault;
494 }
495
496 e = lookup(req->getVaddr(), part_id, real, context);
497
498 if (e == NULL || !e->valid) {
499 tc->setMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS,
500 vaddr & ~BytesInPageMask | context);
501 DPRINTF(TLB, "TLB: DTB Failed to find matching TLB entry\n");
481 if (real)
482 return new DataRealTranslationMiss;
483 else
484 return new FastDataAccessMMUMiss;
485
486 }
487
488

--- 22 unchanged lines hidden (view full) ---

511 /** Normal flow ends here. */
512
513handleScratchRegAccess:
514 if (vaddr > 0x38 || (vaddr >= 0x20 && vaddr < 0x30 && !hpriv)) {
515 writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
516 return new DataAccessException;
517 }
518handleMmuRegAccess:
502 if (real)
503 return new DataRealTranslationMiss;
504 else
505 return new FastDataAccessMMUMiss;
506
507 }
508
509

--- 22 unchanged lines hidden (view full) ---

532 /** Normal flow ends here. */
533
534handleScratchRegAccess:
535 if (vaddr > 0x38 || (vaddr >= 0x20 && vaddr < 0x30 && !hpriv)) {
536 writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
537 return new DataAccessException;
538 }
539handleMmuRegAccess:
540 DPRINTF(TLB, "TLB: DTB Translating MM IPR access\n");
519 req->setMmapedIpr(true);
520 req->setPaddr(req->getVaddr());
521 return NoFault;
522};
523
524Tick
525DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
526{

--- 64 unchanged lines hidden ---
541 req->setMmapedIpr(true);
542 req->setPaddr(req->getVaddr());
543 return NoFault;
544};
545
546Tick
547DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
548{

--- 64 unchanged lines hidden ---