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 --- |