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
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);
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;
385 }
386
382 if ( hpstate >> 2 & 0x1 || hpstate >> 5 & 0x1 ) {
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
401 if (!lsuIm) {
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! */
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
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);
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;
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;
489 } else {
481 context = tc->readMiscReg(MISCREG_MMU_P_CONTEXT);
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;
499 context = tc->readMiscReg(MISCREG_MMU_P_CONTEXT);
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
550 if ((!lsuDm && !hpriv) || AsiIsReal(asi)) {
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 ---