tlb.cc (3908:0a072cce91dd) tlb.cc (3910:bad95ceb5efe)
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;

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

626 asi = ASI_N;
627 ct = Nucleus;
628 context = 0;
629 } else {
630 asi = ASI_P;
631 ct = Primary;
632 context = pri_context;
633 }
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;

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

626 asi = ASI_N;
627 ct = Nucleus;
628 context = 0;
629 } else {
630 asi = ASI_P;
631 ct = Primary;
632 context = pri_context;
633 }
634 } else if (!hpriv && !red) {
635 if (tl > 0 || AsiIsNucleus(asi)) {
636 ct = Nucleus;
637 context = 0;
638 } else if (AsiIsSecondary(asi)) {
639 ct = Secondary;
640 context = sec_context;
641 } else {
642 context = pri_context;
643 ct = Primary; //???
644 }
645
634 } else {
646 // We need to check for priv level/asi priv
635 // We need to check for priv level/asi priv
647 if (!priv && !AsiIsUnPriv(asi)) {
636 if (!priv && !hpriv && !AsiIsUnPriv(asi)) {
648 // It appears that context should be Nucleus in these cases?
649 writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi);
650 return new PrivilegedAction;
651 }
637 // It appears that context should be Nucleus in these cases?
638 writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi);
639 return new PrivilegedAction;
640 }
652 if (priv && AsiIsHPriv(asi)) {
641
642 if (!hpriv && AsiIsHPriv(asi)) {
653 writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi);
654 return new DataAccessException;
655 }
656
643 writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi);
644 return new DataAccessException;
645 }
646
647 if (AsiIsPrimary(asi)) {
648 context = pri_context;
649 ct = Primary;
650 } else if (AsiIsSecondary(asi)) {
651 context = sec_context;
652 ct = Secondary;
653 } else if (AsiIsNucleus(asi)) {
654 ct = Nucleus;
655 context = 0;
656 } else { // ????
657 ct = Primary;
658 context = pri_context;
659 }
657 }
660 }
658 if (asi == ASI_P || asi == ASI_LDTX_P) {
659 ct = Primary;
660 context = pri_context;
661 goto continueDtbFlow;
662 }
663
664 if (!implicit) {
665 if (AsiIsLittle(asi))
666 panic("Little Endian ASIs not supported\n");
667 if (AsiIsBlock(asi))
668 panic("Block ASIs not supported\n");
669 if (AsiIsNoFault(asi))
670 panic("No Fault ASIs not supported\n");
661
662 if (!implicit) {
663 if (AsiIsLittle(asi))
664 panic("Little Endian ASIs not supported\n");
665 if (AsiIsBlock(asi))
666 panic("Block ASIs not supported\n");
667 if (AsiIsNoFault(asi))
668 panic("No Fault ASIs not supported\n");
669
670 // These twin ASIs are OK
671 if (asi == ASI_P || asi == ASI_LDTX_P)
672 goto continueDtbFlow;
671 if (!write && (asi == ASI_QUAD_LDD || asi == ASI_LDTX_REAL))
672 goto continueDtbFlow;
673
674 if (AsiIsTwin(asi))
675 panic("Twin ASIs not supported\n");
676 if (AsiIsPartialStore(asi))
677 panic("Partial Store ASIs not supported\n");
678 if (AsiIsInterrupt(asi))
679 panic("Interrupt ASIs not supported\n");
680
681 if (AsiIsMmu(asi))
682 goto handleMmuRegAccess;
683 if (AsiIsScratchPad(asi))
684 goto handleScratchRegAccess;
685 if (AsiIsQueue(asi))
686 goto handleQueueRegAccess;
687 if (AsiIsSparcError(asi))
688 goto handleSparcErrorRegAccess;
689
673 if (!write && (asi == ASI_QUAD_LDD || asi == ASI_LDTX_REAL))
674 goto continueDtbFlow;
675
676 if (AsiIsTwin(asi))
677 panic("Twin ASIs not supported\n");
678 if (AsiIsPartialStore(asi))
679 panic("Partial Store ASIs not supported\n");
680 if (AsiIsInterrupt(asi))
681 panic("Interrupt ASIs not supported\n");
682
683 if (AsiIsMmu(asi))
684 goto handleMmuRegAccess;
685 if (AsiIsScratchPad(asi))
686 goto handleScratchRegAccess;
687 if (AsiIsQueue(asi))
688 goto handleQueueRegAccess;
689 if (AsiIsSparcError(asi))
690 goto handleSparcErrorRegAccess;
691
690 if (!AsiIsReal(asi) && !AsiIsNucleus(asi))
692 if (!AsiIsReal(asi) && !AsiIsNucleus(asi) && !AsiIsAsIfUser(asi))
691 panic("Accessing ASI %#X. Should we?\n", asi);
692 }
693
694continueDtbFlow:
695 // If the asi is unaligned trap
696 if (vaddr & size-1) {
697 writeSfr(tc, vaddr, false, ct, false, OtherFault, asi);
698 return new MemAddressNotAligned;
699 }
700
701 if (addr_mask)
702 vaddr = vaddr & VAddrAMask;
703
704 if (!validVirtualAddress(vaddr, addr_mask)) {
705 writeSfr(tc, vaddr, false, ct, true, VaOutOfRange, asi);
706 return new DataAccessException;
707 }
708
709
693 panic("Accessing ASI %#X. Should we?\n", asi);
694 }
695
696continueDtbFlow:
697 // If the asi is unaligned trap
698 if (vaddr & size-1) {
699 writeSfr(tc, vaddr, false, ct, false, OtherFault, asi);
700 return new MemAddressNotAligned;
701 }
702
703 if (addr_mask)
704 vaddr = vaddr & VAddrAMask;
705
706 if (!validVirtualAddress(vaddr, addr_mask)) {
707 writeSfr(tc, vaddr, false, ct, true, VaOutOfRange, asi);
708 return new DataAccessException;
709 }
710
711
710 if ((!lsu_dm && !hpriv) || AsiIsReal(asi)) {
712 if ((!lsu_dm && !hpriv && !red) || AsiIsReal(asi)) {
711 real = true;
712 context = 0;
713 };
714
715 if (hpriv && (implicit || (!AsiIsAsIfUser(asi) && !AsiIsReal(asi)))) {
716 req->setPaddr(vaddr & PAddrImplMask);
717 return NoFault;
718 }

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

888 pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS1));
889 break;
890 case ASI_IMMU_CTXT_NONZERO_CONFIG:
891 assert(va == 0);
892 pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG));
893 break;
894 case ASI_SPARC_ERROR_STATUS_REG:
895 warn("returning 0 for SPARC ERROR regsiter read\n");
713 real = true;
714 context = 0;
715 };
716
717 if (hpriv && (implicit || (!AsiIsAsIfUser(asi) && !AsiIsReal(asi)))) {
718 req->setPaddr(vaddr & PAddrImplMask);
719 return NoFault;
720 }

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

890 pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS1));
891 break;
892 case ASI_IMMU_CTXT_NONZERO_CONFIG:
893 assert(va == 0);
894 pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG));
895 break;
896 case ASI_SPARC_ERROR_STATUS_REG:
897 warn("returning 0 for SPARC ERROR regsiter read\n");
896 pkt->set(0);
898 pkt->set(ULL(0));
897 break;
898 case ASI_HYP_SCRATCHPAD:
899 case ASI_SCRATCHPAD:
900 pkt->set(tc->readMiscRegWithEffect(MISCREG_SCRATCHPAD_R0 + (va >> 3)));
901 break;
902 case ASI_IMMU:
903 switch (va) {
904 case 0x0:

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

958 cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_CONFIG);
959 } else {
960 tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS1);
961 cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_CONFIG);
962 }
963 data = mbits(tsbtemp,63,13);
964 if (bits(tsbtemp,12,12))
965 data |= ULL(1) << (13+bits(tsbtemp,3,0));
899 break;
900 case ASI_HYP_SCRATCHPAD:
901 case ASI_SCRATCHPAD:
902 pkt->set(tc->readMiscRegWithEffect(MISCREG_SCRATCHPAD_R0 + (va >> 3)));
903 break;
904 case ASI_IMMU:
905 switch (va) {
906 case 0x0:

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

960 cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_CONFIG);
961 } else {
962 tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS1);
963 cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_CONFIG);
964 }
965 data = mbits(tsbtemp,63,13);
966 if (bits(tsbtemp,12,12))
967 data |= ULL(1) << (13+bits(tsbtemp,3,0));
966 data |= temp >> (9 + bits(cnftemp,2,0) * 3) &
968 data |= temp >> (9 + bits(cnftemp,10,8) * 3) &
967 mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4);
968 pkt->set(data);
969 break;
970 case ASI_IMMU_TSB_PS0_PTR_REG:
971 temp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS);
972 if (bits(temp,12,0) == 0) {
973 tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_TSB_PS0);
974 cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_CONFIG);

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

988 cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_CONFIG);
989 } else {
990 tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS1);
991 cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG);
992 }
993 data = mbits(tsbtemp,63,13);
994 if (bits(tsbtemp,12,12))
995 data |= ULL(1) << (13+bits(tsbtemp,3,0));
969 mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4);
970 pkt->set(data);
971 break;
972 case ASI_IMMU_TSB_PS0_PTR_REG:
973 temp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS);
974 if (bits(temp,12,0) == 0) {
975 tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_TSB_PS0);
976 cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_CONFIG);

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

990 cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_CONFIG);
991 } else {
992 tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS1);
993 cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG);
994 }
995 data = mbits(tsbtemp,63,13);
996 if (bits(tsbtemp,12,12))
997 data |= ULL(1) << (13+bits(tsbtemp,3,0));
996 data |= temp >> (9 + bits(cnftemp,2,0) * 3) &
998 data |= temp >> (9 + bits(cnftemp,10,8) * 3) &
997 mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4);
998 pkt->set(data);
999 break;
1000
1001 default:
1002doMmuReadError:
1003 panic("need to impl DTB::doMmuRegRead() got asi=%#x, va=%#x\n",
1004 (uint32_t)asi, va);

--- 291 unchanged lines hidden ---
999 mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4);
1000 pkt->set(data);
1001 break;
1002
1003 default:
1004doMmuReadError:
1005 panic("need to impl DTB::doMmuRegRead() got asi=%#x, va=%#x\n",
1006 (uint32_t)asi, va);

--- 291 unchanged lines hidden ---