tlb.cc (8696:642f83fafffb) | tlb.cc (8767:e575781f71b8) |
---|---|
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 --- 15 unchanged lines hidden (view full) --- 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 | 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 --- 15 unchanged lines hidden (view full) --- 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 <string> 37#include <vector> 38 39#include "arch/mips/faults.hh" 40#include "arch/mips/pagetable.hh" 41#include "arch/mips/pra_constants.hh" --- 84 unchanged lines hidden (view full) --- 126 assert(Index<size); 127 return &table[Index]; 128} 129 130int 131TLB::probeEntry(Addr vpn, uint8_t asn) const 132{ 133 // assume not found... | 32 */ 33 34#include <string> 35#include <vector> 36 37#include "arch/mips/faults.hh" 38#include "arch/mips/pagetable.hh" 39#include "arch/mips/pra_constants.hh" --- 84 unchanged lines hidden (view full) --- 124 assert(Index<size); 125 return &table[Index]; 126} 127 128int 129TLB::probeEntry(Addr vpn, uint8_t asn) const 130{ 131 // assume not found... |
132 PTE *retval = NULL; |
|
134 int Ind = -1; 135 PageTable::const_iterator i = lookupTable.find(vpn); 136 if (i != lookupTable.end()) { 137 while (i->first == vpn) { 138 int index = i->second; 139 PTE *pte = &table[index]; 140 141 /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */ 142 Addr Mask = pte->Mask; 143 Addr InvMask = ~Mask; 144 Addr VPN = pte->VPN; 145 if (((vpn & InvMask) == (VPN & InvMask)) && 146 (pte->G || (asn == pte->asid))) { 147 // We have a VPN + ASID Match | 133 int Ind = -1; 134 PageTable::const_iterator i = lookupTable.find(vpn); 135 if (i != lookupTable.end()) { 136 while (i->first == vpn) { 137 int index = i->second; 138 PTE *pte = &table[index]; 139 140 /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */ 141 Addr Mask = pte->Mask; 142 Addr InvMask = ~Mask; 143 Addr VPN = pte->VPN; 144 if (((vpn & InvMask) == (VPN & InvMask)) && 145 (pte->G || (asn == pte->asid))) { 146 // We have a VPN + ASID Match |
147 retval = pte; |
|
148 Ind = index; 149 break; 150 } 151 ++i; 152 } 153 } 154 DPRINTF(MipsPRA,"VPN: %x, asid: %d, Result of TLBP: %d\n",vpn,asn,Ind); 155 return Ind; --- 134 unchanged lines hidden (view full) --- 290 hits = read_hits + write_hits; 291 misses = read_misses + write_misses; 292 accesses = read_accesses + write_accesses; 293} 294 295Fault 296TLB::translateInst(RequestPtr req, ThreadContext *tc) 297{ | 148 Ind = index; 149 break; 150 } 151 ++i; 152 } 153 } 154 DPRINTF(MipsPRA,"VPN: %x, asid: %d, Result of TLBP: %d\n",vpn,asn,Ind); 155 return Ind; --- 134 unchanged lines hidden (view full) --- 290 hits = read_hits + write_hits; 291 misses = read_misses + write_misses; 292 accesses = read_accesses + write_accesses; 293} 294 295Fault 296TLB::translateInst(RequestPtr req, ThreadContext *tc) 297{ |
298#if !FULL_SYSTEM 299 Process * p = tc->getProcessPtr(); | 298 if (!FullSystem) { 299 Process * p = tc->getProcessPtr(); |
300 | 300 |
301 Fault fault = p->pTable->translate(req); 302 if (fault != NoFault) 303 return fault; | 301 Fault fault = p->pTable->translate(req); 302 if (fault != NoFault) 303 return fault; |
304 | 304 |
305 return NoFault; 306#else 307 Addr vaddr = req->getVaddr(); 308 309 bool misaligned = (req->getSize() - 1) & vaddr; 310 311 if (IsKSeg0(vaddr)) { 312 // Address will not be translated through TLB, set response, and go! 313 req->setPaddr(KSeg02Phys(vaddr)); 314 if (getOperatingMode(tc->readMiscReg(MISCREG_STATUS)) != mode_kernel || 315 misaligned) { 316 return new AddressErrorFault(vaddr, false); 317 } 318 } else if(IsKSeg1(vaddr)) { 319 // Address will not be translated through TLB, set response, and go! 320 req->setPaddr(KSeg02Phys(vaddr)); | 305 return NoFault; |
321 } else { | 306 } else { |
322 /* 323 * This is an optimization - smallPages is updated every time a TLB 324 * operation is performed. That way, we don't need to look at 325 * Config3 _ SP and PageGrain _ ESP every time we do a TLB lookup 326 */ 327 Addr VPN; 328 if (smallPages == 1) { 329 VPN = (vaddr >> 11); 330 } else { 331 VPN = ((vaddr >> 11) & 0xFFFFFFFC); 332 } 333 uint8_t Asid = req->getAsid(); 334 if (misaligned) { 335 // Unaligned address! 336 return new AddressErrorFault(vaddr, false); 337 } 338 PTE *pte = lookup(VPN,Asid); 339 if (pte != NULL) { 340 // Ok, found something 341 /* Check for valid bits */ 342 int EvenOdd; 343 bool Valid; 344 if ((((vaddr) >> pte->AddrShiftAmount) & 1) == 0) { 345 // Check even bits 346 Valid = pte->V0; 347 EvenOdd = 0; 348 } else { 349 // Check odd bits 350 Valid = pte->V1; 351 EvenOdd = 1; 352 } 353 354 if (Valid == false) { 355 return new TlbInvalidFault(Asid, vaddr, VPN, false); 356 } else { 357 // Ok, this is really a match, set paddr 358 Addr PAddr; 359 if (EvenOdd == 0) { 360 PAddr = pte->PFN0; 361 } else { 362 PAddr = pte->PFN1; 363 } 364 PAddr >>= (pte->AddrShiftAmount - 12); 365 PAddr <<= pte->AddrShiftAmount; 366 PAddr |= (vaddr & pte->OffsetMask); 367 req->setPaddr(PAddr); 368 } 369 } else { 370 // Didn't find any match, return a TLB Refill Exception 371 return new TlbRefillFault(Asid, vaddr, VPN, false); 372 } | 307 panic("translateInst not implemented in MIPS.\n"); |
373 } | 308 } |
374 return checkCacheability(req); 375#endif | |
376} 377 378Fault 379TLB::translateData(RequestPtr req, ThreadContext *tc, bool write) 380{ | 309} 310 311Fault 312TLB::translateData(RequestPtr req, ThreadContext *tc, bool write) 313{ |
381#if !FULL_SYSTEM 382 //@TODO: This should actually use TLB instead of going directly 383 // to the page table in syscall mode. 384 /** 385 * Check for alignment faults 386 */ 387 if (req->getVaddr() & (req->getSize() - 1)) { 388 DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(), 389 req->getSize()); 390 return new AddressErrorFault(req->getVaddr(), write); 391 } | 314 if (!FullSystem) { 315 //@TODO: This should actually use TLB instead of going directly 316 // to the page table in syscall mode. 317 /** 318 * Check for alignment faults 319 */ 320 if (req->getVaddr() & (req->getSize() - 1)) { 321 DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(), 322 req->getSize()); 323 return new AddressErrorFault(req->getVaddr(), write); 324 } |
392 393 | 325 326 |
394 Process * p = tc->getProcessPtr(); | 327 Process * p = tc->getProcessPtr(); |
395 | 328 |
396 Fault fault = p->pTable->translate(req); 397 if (fault != NoFault) 398 return fault; | 329 Fault fault = p->pTable->translate(req); 330 if (fault != NoFault) 331 return fault; |
399 | 332 |
400 return NoFault; 401#else 402 Addr vaddr = req->getVaddr(); 403 404 bool misaligned = (req->getSize() - 1) & vaddr; 405 406 if (IsKSeg0(vaddr)) { 407 // Address will not be translated through TLB, set response, and go! 408 req->setPaddr(KSeg02Phys(vaddr)); 409 if (getOperatingMode(tc->readMiscReg(MISCREG_STATUS)) != mode_kernel || 410 misaligned) { 411 return new AddressErrorFault(vaddr, true); 412 } 413 } else if(IsKSeg1(vaddr)) { 414 // Address will not be translated through TLB, set response, and go! 415 req->setPaddr(KSeg02Phys(vaddr)); | 333 return NoFault; |
416 } else { | 334 } else { |
417 /* 418 * This is an optimization - smallPages is updated every time a TLB 419 * operation is performed. That way, we don't need to look at 420 * Config3 _ SP and PageGrain _ ESP every time we do a TLB lookup 421 */ 422 Addr VPN = (vaddr >> 11) & 0xFFFFFFFC; 423 if (smallPages == 1) { 424 VPN = vaddr >> 11; 425 } 426 uint8_t Asid = req->getAsid(); 427 PTE *pte = lookup(VPN, Asid); 428 if (misaligned) { 429 return new AddressErrorFault(vaddr, true); 430 } 431 if (pte != NULL) { 432 // Ok, found something 433 /* Check for valid bits */ 434 int EvenOdd; 435 bool Valid; 436 bool Dirty; 437 if ((((vaddr >> pte->AddrShiftAmount) & 1)) == 0) { 438 // Check even bits 439 Valid = pte->V0; 440 Dirty = pte->D0; 441 EvenOdd = 0; 442 } else { 443 // Check odd bits 444 Valid = pte->V1; 445 Dirty = pte->D1; 446 EvenOdd = 1; 447 } 448 449 if (Valid == false) { 450 return new TlbInvalidFault(Asid, vaddr, VPN, write); 451 } else { 452 // Ok, this is really a match, set paddr 453 if (!Dirty && write) { 454 return new TlbModifiedFault(Asid, vaddr, VPN); 455 } 456 Addr PAddr; 457 if (EvenOdd == 0) { 458 PAddr = pte->PFN0; 459 } else { 460 PAddr = pte->PFN1; 461 } 462 PAddr >>= (pte->AddrShiftAmount - 12); 463 PAddr <<= pte->AddrShiftAmount; 464 PAddr |= (vaddr & pte->OffsetMask); 465 req->setPaddr(PAddr); 466 } 467 } else { 468 // Didn't find any match, return a TLB Refill Exception 469 return new TlbRefillFault(Asid, vaddr, VPN, write); 470 } | 335 panic("translateData not implemented in MIPS.\n"); |
471 } | 336 } |
472 return checkCacheability(req); 473#endif | |
474} 475 476Fault 477TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode) 478{ 479 if (mode == Execute) 480 return translateInst(req, tc); 481 else --- 28 unchanged lines hidden --- | 337} 338 339Fault 340TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode) 341{ 342 if (mode == Execute) 343 return translateInst(req, tc); 344 else --- 28 unchanged lines hidden --- |