tlb.cc (3832:49c95a73e29c) | tlb.cc (3833:b5faabcf350e) |
---|---|
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; --- 334 unchanged lines hidden (view full) --- 343 TLB::writeTagAccess(tc, MISCREG_MMU_DTLB_TAG_ACCESS, va, context); 344} 345 346 347 348Fault 349ITB::translate(RequestPtr &req, ThreadContext *tc) 350{ | 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; --- 334 unchanged lines hidden (view full) --- 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 hpstate = tc->readMiscReg(MISCREG_HPSTATE); 352 uint64_t pstate = tc->readMiscReg(MISCREG_PSTATE); 353 bool lsuIm = tc->readMiscReg(MISCREG_MMU_LSU_CTRL) >> 2 & 0x1; 354 uint64_t tl = tc->readMiscReg(MISCREG_TL); 355 uint64_t part_id = tc->readMiscReg(MISCREG_MMU_PART_ID); 356 bool addr_mask = pstate >> 3 & 0x1; 357 bool priv = pstate >> 2 & 0x1; | 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 |
358 Addr vaddr = req->getVaddr(); 359 int context; 360 ContextType ct; 361 int asi; 362 bool real = false; 363 TlbEntry *e; 364 365 DPRINTF(TLB, "TLB: ITB Request to translate va=%#x size=%d\n", 366 vaddr, req->getSize()); | 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()); |
367 DPRINTF(TLB, "TLB: pstate: %#X hpstate: %#X lsudm: %#X part_id: %#X\n", 368 pstate, hpstate, lsuIm, part_id); | 372 DPRINTF(TLB, "TLB: priv:%d hpriv:%d red:%d lsuim:%d part_id: %#X\n", 373 priv, hpriv, red, lsu_im, part_id); |
369 370 assert(req->getAsi() == ASI_IMPLICIT); 371 372 if (tl > 0) { 373 asi = ASI_N; 374 ct = Nucleus; 375 context = 0; 376 } else { 377 asi = ASI_P; 378 ct = Primary; | 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; |
379 context = tc->readMiscReg(MISCREG_MMU_P_CONTEXT); | 384 context = pri_context; |
380 } 381 | 385 } 386 |
382 if ( hpstate >> 2 & 0x1 || hpstate >> 5 & 0x1 ) { | 387 if ( hpriv || red ) { |
383 req->setPaddr(req->getVaddr() & PAddrImplMask); 384 return NoFault; 385 } 386 387 // If the asi is unaligned trap 388 if (vaddr & req->getSize()-1) { 389 writeSfsr(tc, false, ct, false, OtherFault, asi); 390 return new MemAddressNotAligned; 391 } 392 393 if (addr_mask) 394 vaddr = vaddr & VAddrAMask; 395 396 if (!validVirtualAddress(vaddr, addr_mask)) { 397 writeSfsr(tc, false, ct, false, VaOutOfRange, asi); 398 return new InstructionAccessException; 399 } 400 | 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 |
401 if (!lsuIm) { | 406 if (!lsu_im) { |
402 e = lookup(req->getVaddr(), part_id, true); 403 real = true; 404 context = 0; 405 } else { 406 e = lookup(vaddr, part_id, false, context); 407 } 408 409 if (e == NULL || !e->valid) { --- 18 unchanged lines hidden (view full) --- 428} 429 430 431 432Fault 433DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) 434{ 435 /* @todo this could really use some profiling and fixing to make it faster! */ | 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) { --- 18 unchanged lines hidden (view full) --- 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! */ |
436 uint64_t hpstate = tc->readMiscReg(MISCREG_HPSTATE); 437 uint64_t pstate = tc->readMiscReg(MISCREG_PSTATE); 438 bool lsuDm = tc->readMiscReg(MISCREG_MMU_LSU_CTRL) >> 3 & 0x1; 439 uint64_t tl = tc->readMiscReg(MISCREG_TL); 440 uint64_t part_id = tc->readMiscReg(MISCREG_MMU_PART_ID); 441 bool hpriv = hpstate >> 2 & 0x1; 442 bool red = hpstate >> 5 >> 0x1; 443 bool addr_mask = pstate >> 3 & 0x1; 444 bool priv = pstate >> 2 & 0x1; | 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 |
445 bool implicit = false; 446 bool real = false; 447 Addr vaddr = req->getVaddr(); 448 Addr size = req->getSize(); 449 ContextType ct = Primary; 450 int context = 0; 451 ASI asi; 452 453 TlbEntry *e; 454 455 asi = (ASI)req->getAsi(); 456 DPRINTF(TLB, "TLB: DTB Request to translate va=%#x size=%d asi=%#x\n", 457 vaddr, size, asi); | 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); |
458 DPRINTF(TLB, "TLB: pstate: %#X hpstate: %#X lsudm: %#X part_id: %#X\n", 459 pstate, hpstate, lsuDm, part_id); | 467 DPRINTF(TLB, "TLB: priv:%d hpriv:%d red:%d lsudm:%d part_id: %#X\n", 468 priv, hpriv, red, lsu_dm, part_id); |
460 if (asi == ASI_IMPLICIT) 461 implicit = true; 462 463 if (implicit) { 464 if (tl > 0) { 465 asi = ASI_N; 466 ct = Nucleus; 467 context = 0; 468 } else { 469 asi = ASI_P; 470 ct = Primary; | 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; 479 ct = Primary; |
471 context = tc->readMiscReg(MISCREG_MMU_P_CONTEXT); | 480 context = pri_context; |
472 } 473 } else if (!hpriv && !red) { 474 if (tl > 0 || AsiIsNucleus(asi)) { 475 ct = Nucleus; 476 context = 0; 477 } else if (AsiIsSecondary(asi)) { 478 ct = Secondary; | 481 } 482 } else if (!hpriv && !red) { 483 if (tl > 0 || AsiIsNucleus(asi)) { 484 ct = Nucleus; 485 context = 0; 486 } else if (AsiIsSecondary(asi)) { 487 ct = Secondary; |
479 context = tc->readMiscReg(MISCREG_MMU_S_CONTEXT); | 488 context = sec_context; |
480 } else { | 489 } else { |
481 context = tc->readMiscReg(MISCREG_MMU_P_CONTEXT); | 490 context = pri_context; |
482 ct = Primary; //??? 483 } 484 485 // We need to check for priv level/asi priv 486 if (!priv && !AsiIsUnPriv(asi)) { 487 // It appears that context should be Nucleus in these cases? 488 writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi); 489 return new PrivilegedAction; 490 } 491 if (priv && AsiIsHPriv(asi)) { 492 writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi); 493 return new DataAccessException; 494 } 495 496 } else if (hpriv) { 497 if (asi == ASI_P) { 498 ct = Primary; | 491 ct = Primary; //??? 492 } 493 494 // We need to check for priv level/asi priv 495 if (!priv && !AsiIsUnPriv(asi)) { 496 // It appears that context should be Nucleus in these cases? 497 writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi); 498 return new PrivilegedAction; 499 } 500 if (priv && AsiIsHPriv(asi)) { 501 writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi); 502 return new DataAccessException; 503 } 504 505 } else if (hpriv) { 506 if (asi == ASI_P) { 507 ct = Primary; |
499 context = tc->readMiscReg(MISCREG_MMU_P_CONTEXT); | 508 context = pri_context; |
500 goto continueDtbFlow; 501 } 502 } 503 504 if (!implicit) { 505 if (AsiIsLittle(asi)) 506 panic("Little Endian ASIs not supported\n"); 507 if (AsiIsBlock(asi)) --- 34 unchanged lines hidden (view full) --- 542 vaddr = vaddr & VAddrAMask; 543 544 if (!validVirtualAddress(vaddr, addr_mask)) { 545 writeSfr(tc, vaddr, false, ct, true, VaOutOfRange, asi); 546 return new DataAccessException; 547 } 548 549 | 509 goto continueDtbFlow; 510 } 511 } 512 513 if (!implicit) { 514 if (AsiIsLittle(asi)) 515 panic("Little Endian ASIs not supported\n"); 516 if (AsiIsBlock(asi)) --- 34 unchanged lines hidden (view full) --- 551 vaddr = vaddr & VAddrAMask; 552 553 if (!validVirtualAddress(vaddr, addr_mask)) { 554 writeSfr(tc, vaddr, false, ct, true, VaOutOfRange, asi); 555 return new DataAccessException; 556 } 557 558 |
550 if ((!lsuDm && !hpriv) || AsiIsReal(asi)) { | 559 if ((!lsu_dm && !hpriv) || AsiIsReal(asi)) { |
551 real = true; 552 context = 0; 553 }; 554 555 if (hpriv && (implicit || (!AsiIsAsIfUser(asi) && !AsiIsReal(asi)))) { 556 req->setPaddr(req->getVaddr() & PAddrImplMask); 557 return NoFault; 558 } --- 76 unchanged lines hidden (view full) --- 635 return NoFault; 636}; 637 638Tick 639DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) 640{ 641 Addr va = pkt->getAddr(); 642 ASI asi = (ASI)pkt->req->getAsi(); | 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 } --- 76 unchanged lines hidden (view full) --- 644 return NoFault; 645}; 646 647Tick 648DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) 649{ 650 Addr va = pkt->getAddr(); 651 ASI asi = (ASI)pkt->req->getAsi(); |
652 uint64_t temp, data; 653 uint64_t tsbtemp, cnftemp; |
|
643 644 DPRINTF(IPR, "Memory Mapped IPR Read: asi=%#X a=%#x\n", 645 (uint32_t)pkt->req->getAsi(), pkt->getAddr()); 646 647 switch (asi) { 648 case ASI_LSU_CONTROL_REG: 649 assert(va == 0); 650 pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_LSU_CTRL)); --- 67 unchanged lines hidden (view full) --- 718 pkt->set(0); 719 break; 720 case ASI_HYP_SCRATCHPAD: 721 case ASI_SCRATCHPAD: 722 pkt->set(tc->readMiscRegWithEffect(MISCREG_SCRATCHPAD_R0 + (va >> 3))); 723 break; 724 case ASI_IMMU: 725 switch (va) { | 654 655 DPRINTF(IPR, "Memory Mapped IPR Read: asi=%#X a=%#x\n", 656 (uint32_t)pkt->req->getAsi(), pkt->getAddr()); 657 658 switch (asi) { 659 case ASI_LSU_CONTROL_REG: 660 assert(va == 0); 661 pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_LSU_CTRL)); --- 67 unchanged lines hidden (view full) --- 729 pkt->set(0); 730 break; 731 case ASI_HYP_SCRATCHPAD: 732 case ASI_SCRATCHPAD: 733 pkt->set(tc->readMiscRegWithEffect(MISCREG_SCRATCHPAD_R0 + (va >> 3))); 734 break; 735 case ASI_IMMU: 736 switch (va) { |
737 case 0x0: 738 temp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS); 739 pkt->set(bits(temp,63,22) | bits(temp,12,0) << 48); 740 break; |
|
726 case 0x30: 727 pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS)); 728 break; 729 default: 730 goto doMmuReadError; 731 } 732 break; 733 case ASI_DMMU: 734 switch (va) { | 741 case 0x30: 742 pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS)); 743 break; 744 default: 745 goto doMmuReadError; 746 } 747 break; 748 case ASI_DMMU: 749 switch (va) { |
750 case 0x0: 751 temp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS); 752 pkt->set(bits(temp,63,22) | bits(temp,12,0) << 48); 753 break; |
|
735 case 0x30: 736 pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS)); 737 break; 738 case 0x80: 739 pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_PART_ID)); 740 break; 741 default: 742 goto doMmuReadError; 743 } 744 break; | 754 case 0x30: 755 pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS)); 756 break; 757 case 0x80: 758 pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_PART_ID)); 759 break; 760 default: 761 goto doMmuReadError; 762 } 763 break; |
764 case ASI_DMMU_TSB_PS0_PTR_REG: 765 temp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS); 766 if (bits(temp,12,0) == 0) { 767 tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS0); 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 { 786 tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS1); 787 cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_CONFIG); 788 } 789 data = mbits(tsbtemp,63,13); 790 if (bits(tsbtemp,12,12)) 791 data |= ULL(1) << (13+bits(tsbtemp,3,0)); 792 data |= temp >> (9 + bits(cnftemp,2,0) * 3) & 793 mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4); 794 pkt->set(data); 795 break; 796 |
|
745 default: 746doMmuReadError: 747 panic("need to impl DTB::doMmuRegRead() got asi=%#x, va=%#x\n", 748 (uint32_t)asi, va); 749 } 750 pkt->result = Packet::Success; 751 return tc->getCpuPtr()->cycles(1); 752} --- 209 unchanged lines hidden --- | 797 default: 798doMmuReadError: 799 panic("need to impl DTB::doMmuRegRead() got asi=%#x, va=%#x\n", 800 (uint32_t)asi, va); 801 } 802 pkt->result = Packet::Success; 803 return tc->getCpuPtr()->cycles(1); 804} --- 209 unchanged lines hidden --- |