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 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) { --- 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! */ |
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; 479 ct = Primary; |
480 context = pri_context; |
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; |
488 context = sec_context; |
489 } else { |
490 context = pri_context; |
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; |
508 context = pri_context; |
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 |
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 } --- 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; |
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; |
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; |
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 |
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 --- |