Deleted Added
sdiff udiff text old ( 3833:b5faabcf350e ) new ( 3836:659b8c627478 )
full compact
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;

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

40#include "sim/builder.hh"
41
42/* @todo remove some of the magic constants. -- ali
43 * */
44namespace SparcISA
45{
46
47TLB::TLB(const std::string &name, int s)
48 : SimObject(name), size(s)
49{
50 // To make this work you'll have to change the hypervisor and OS
51 if (size > 64)
52 fatal("SPARC T1 TLB registers don't support more than 64 TLB entries.");
53
54 tlb = new TlbEntry[size];
55 memset(tlb, 0, sizeof(TlbEntry) * size);
56}

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

74 const PageTableEntry& PTE, int entry)
75{
76
77
78 MapIter i;
79 TlbEntry *new_entry = NULL;
80 int x;
81
82 DPRINTF(TLB, "TLB: Inserting TLB Entry; va=%#x pa=%#x pid=%d cid=%d r=%d\n",
83 va, PTE.paddr(), partition_id, context_id, (int)real);
84
85 if (entry != -1) {
86 assert(entry < size && entry >= 0);
87 new_entry = &tlb[entry];
88 } else {
89 for (x = 0; x < size; x++) {

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

189}
190
191void
192TLB::demapPage(Addr va, int partition_id, bool real, int context_id)
193{
194 TlbRange tr;
195 MapIter i;
196
197 // Assemble full address structure
198 tr.va = va;
199 tr.size = va + MachineBytes;
200 tr.contextId = context_id;
201 tr.partitionId = partition_id;
202 tr.real = real;
203
204 // Demap any entry that conflicts

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

212 lookupTable.erase(i);
213 }
214}
215
216void
217TLB::demapContext(int partition_id, int context_id)
218{
219 int x;
220 for (x = 0; x < size; x++) {
221 if (tlb[x].range.contextId == context_id &&
222 tlb[x].range.partitionId == partition_id) {
223 tlb[x].valid = false;
224 if (tlb[x].used) {
225 tlb[x].used = false;
226 usedEntries--;
227 }
228 lookupTable.erase(tlb[x].range);
229 }
230 }
231}
232
233void
234TLB::demapAll(int partition_id)
235{
236 int x;
237 for (x = 0; x < size; x++) {
238 if (!tlb[x].pte.locked() && tlb[x].range.partitionId == partition_id) {
239 tlb[x].valid = false;
240 if (tlb[x].used) {
241 tlb[x].used = false;
242 usedEntries--;
243 }
244 lookupTable.erase(tlb[x].range);
245 }
246 }
247}
248
249void
250TLB::invalidateAll()
251{
252 int x;
253 for (x = 0; x < size; x++) {
254 tlb[x].valid = false;
255 }
256 usedEntries = 0;
257}
258
259uint64_t
260TLB::TteRead(int entry) {

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

332 bool se, FaultTypes ft, int asi)
333{
334 DPRINTF(TLB, "TLB: DTB Fault: A=%#x w=%d ct=%d ft=%d asi=%d\n",
335 a, (int)write, ct, ft, asi);
336 TLB::writeSfsr(tc, MISCREG_MMU_DTLB_SFSR, write, ct, se, ft, asi);
337 tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_SFAR, a);
338}
339
340 void
341DTB::writeTagAccess(ThreadContext *tc, Addr va, int context)
342{
343 TLB::writeTagAccess(tc, MISCREG_MMU_DTLB_TAG_ACCESS, va, context);
344}
345
346
347
348Fault
349ITB::translate(RequestPtr &req, ThreadContext *tc)
350{
351 uint64_t tlbdata = tc->readMiscReg(MISCREG_TLB_DATA);
352
353 bool hpriv = bits(tlbdata,0,0);
354 bool red = bits(tlbdata,1,1);
355 bool priv = bits(tlbdata,2,2);
356 bool addr_mask = bits(tlbdata,3,3);
357 bool lsu_im = bits(tlbdata,4,4);
358
359 int part_id = bits(tlbdata,15,8);
360 int tl = bits(tlbdata,18,16);
361 int pri_context = bits(tlbdata,47,32);
362
363 Addr vaddr = req->getVaddr();
364 int context;
365 ContextType ct;
366 int asi;
367 bool real = false;
368 TlbEntry *e;
369
370 DPRINTF(TLB, "TLB: ITB Request to translate va=%#x size=%d\n",
371 vaddr, req->getSize());
372 DPRINTF(TLB, "TLB: priv:%d hpriv:%d red:%d lsuim:%d part_id: %#X\n",
373 priv, hpriv, red, lsu_im, part_id);
374
375 assert(req->getAsi() == ASI_IMPLICIT);
376
377 if (tl > 0) {
378 asi = ASI_N;
379 ct = Nucleus;
380 context = 0;
381 } else {
382 asi = ASI_P;
383 ct = Primary;
384 context = pri_context;
385 }
386
387 if ( hpriv || red ) {
388 req->setPaddr(req->getVaddr() & PAddrImplMask);
389 return NoFault;
390 }
391
392 // If the asi is unaligned trap
393 if (vaddr & req->getSize()-1) {
394 writeSfsr(tc, false, ct, false, OtherFault, asi);
395 return new MemAddressNotAligned;
396 }
397
398 if (addr_mask)
399 vaddr = vaddr & VAddrAMask;
400
401 if (!validVirtualAddress(vaddr, addr_mask)) {
402 writeSfsr(tc, false, ct, false, VaOutOfRange, asi);
403 return new InstructionAccessException;
404 }
405
406 if (!lsu_im) {
407 e = lookup(req->getVaddr(), part_id, true);
408 real = true;
409 context = 0;
410 } else {
411 e = lookup(vaddr, part_id, false, context);
412 }
413
414 if (e == NULL || !e->valid) {
415 tc->setMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS,

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

421 }
422
423 // were not priviledged accesing priv page
424 if (!priv && e->pte.priv()) {
425 writeSfsr(tc, false, ct, false, PrivViolation, asi);
426 return new InstructionAccessException;
427 }
428
429 req->setPaddr(e->pte.paddr() & ~(e->pte.size()-1) |
430 req->getVaddr() & e->pte.size()-1 );
431 DPRINTF(TLB, "TLB: %#X -> %#X\n", req->getVaddr(), req->getPaddr());
432 return NoFault;
433}
434
435
436
437Fault
438DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
439{
440 /* @todo this could really use some profiling and fixing to make it faster! */
441 uint64_t tlbdata = tc->readMiscReg(MISCREG_TLB_DATA);
442
443 bool hpriv = bits(tlbdata,0,0);
444 bool red = bits(tlbdata,1,1);
445 bool priv = bits(tlbdata,2,2);
446 bool addr_mask = bits(tlbdata,3,3);
447 bool lsu_dm = bits(tlbdata,5,5);
448
449 int part_id = bits(tlbdata,15,8);
450 int tl = bits(tlbdata,18,16);
451 int pri_context = bits(tlbdata,47,32);
452 int sec_context = bits(tlbdata,47,32);
453
454 bool implicit = false;
455 bool real = false;
456 Addr vaddr = req->getVaddr();
457 Addr size = req->getSize();
458 ContextType ct = Primary;
459 int context = 0;
460 ASI asi;
461
462 TlbEntry *e;
463
464 asi = (ASI)req->getAsi();
465 DPRINTF(TLB, "TLB: DTB Request to translate va=%#x size=%d asi=%#x\n",
466 vaddr, size, asi);
467 DPRINTF(TLB, "TLB: priv:%d hpriv:%d red:%d lsudm:%d part_id: %#X\n",
468 priv, hpriv, red, lsu_dm, part_id);
469 if (asi == ASI_IMPLICIT)
470 implicit = true;
471
472 if (implicit) {
473 if (tl > 0) {
474 asi = ASI_N;
475 ct = Nucleus;
476 context = 0;
477 } else {
478 asi = ASI_P;

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

557
558
559 if ((!lsu_dm && !hpriv) || AsiIsReal(asi)) {
560 real = true;
561 context = 0;
562 };
563
564 if (hpriv && (implicit || (!AsiIsAsIfUser(asi) && !AsiIsReal(asi)))) {
565 req->setPaddr(req->getVaddr() & PAddrImplMask);
566 return NoFault;
567 }
568
569 e = lookup(req->getVaddr(), part_id, real, context);
570
571 if (e == NULL || !e->valid) {
572 tc->setMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS,
573 vaddr & ~BytesInPageMask | context);
574 DPRINTF(TLB, "TLB: DTB Failed to find matching TLB entry\n");
575 if (real)
576 return new DataRealTranslationMiss;
577 else

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

594 req->setFlags(req->getFlags() | UNCACHEABLE);
595
596
597 if (!priv && e->pte.priv()) {
598 writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), PrivViolation, asi);
599 return new DataAccessException;
600 }
601
602 req->setPaddr(e->pte.paddr() & ~(e->pte.size()-1) |
603 req->getVaddr() & e->pte.size()-1);
604 DPRINTF(TLB, "TLB: %#X -> %#X\n", req->getVaddr(), req->getPaddr());
605 return NoFault;
606 /** Normal flow ends here. */
607
608handleScratchRegAccess:
609 if (vaddr > 0x38 || (vaddr >= 0x20 && vaddr < 0x30 && !hpriv)) {
610 writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
611 return new DataAccessException;
612 }

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

768 cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_CONFIG);
769 } else {
770 tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS0);
771 cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_CONFIG);
772 }
773 data = mbits(tsbtemp,63,13);
774 data |= temp >> (9 + bits(cnftemp,2,0) * 3) &
775 mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4);
776 warn("base addr: %#X tag access: %#X page size: %#X tsb size: %#X\n",
777 bits(tsbtemp,63,13), temp, bits(cnftemp,2,0), bits(tsbtemp,3,0));
778 pkt->set(data);
779 break;
780 case ASI_DMMU_TSB_PS1_PTR_REG:
781 temp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS);
782 if (bits(temp,12,0) == 0) {
783 tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS1);
784 cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_CONFIG);
785 } else {

--- 228 unchanged lines hidden ---