faults.cc (12406:86bde4a026b5) faults.cc (12455:c88f0b37f433)
1/*
2 * Copyright (c) 2003-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;

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

624 const StaticInstPtr &inst)
625{
626 if (FullSystem) {
627 SparcFaultBase::invoke(tc, inst);
628 return;
629 }
630
631 Process *p = tc->getProcessPtr();
1/*
2 * Copyright (c) 2003-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;

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

624 const StaticInstPtr &inst)
625{
626 if (FullSystem) {
627 SparcFaultBase::invoke(tc, inst);
628 return;
629 }
630
631 Process *p = tc->getProcessPtr();
632 TlbEntry entry;
633 bool success = p->pTable->lookup(vaddr, entry);
634 if (!success) {
635 panic("Tried to execute unmapped address %#x.\n", vaddr);
636 } else {
637 Addr alignedvaddr = p->pTable->pageAlign(vaddr);
632 TlbEntry *entry = p->pTable->lookup(vaddr);
633 panic_if(!entry, "Tried to execute unmapped address %#x.\n", vaddr);
638
634
639 // Grab fields used during instruction translation to figure out
640 // which context to use.
641 uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
635 Addr alignedvaddr = p->pTable->pageAlign(vaddr);
642
636
643 // Inside a VM, a real address is the address that guest OS would
644 // interpret to be a physical address. To map to the physical address,
645 // it still needs to undergo a translation. The instruction
646 // translation code in the SPARC ITLB code assumes that the context is
647 // zero (kernel-level) if real addressing is being used.
648 bool is_real_address = !bits(tlbdata, 4);
637 // Grab fields used during instruction translation to figure out
638 // which context to use.
639 uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
649
640
650 // The SPARC ITLB code assumes that traps are executed in context
651 // zero so we carry that assumption through here.
652 bool trapped = bits(tlbdata, 18, 16) > 0;
641 // Inside a VM, a real address is the address that guest OS would
642 // interpret to be a physical address. To map to the physical address,
643 // it still needs to undergo a translation. The instruction
644 // translation code in the SPARC ITLB code assumes that the context is
645 // zero (kernel-level) if real addressing is being used.
646 bool is_real_address = !bits(tlbdata, 4);
653
647
654 // The primary context acts as a PASID. It allows the MMU to
655 // distinguish between virtual addresses that would alias to the
656 // same physical address (if two or more processes shared the same
657 // virtual address mapping).
658 int primary_context = bits(tlbdata, 47, 32);
648 // The SPARC ITLB code assumes that traps are executed in context
649 // zero so we carry that assumption through here.
650 bool trapped = bits(tlbdata, 18, 16) > 0;
659
651
660 // The partition id distinguishes between virtualized environments.
661 int const partition_id = 0;
652 // The primary context acts as a PASID. It allows the MMU to
653 // distinguish between virtual addresses that would alias to the
654 // same physical address (if two or more processes shared the same
655 // virtual address mapping).
656 int primary_context = bits(tlbdata, 47, 32);
662
657
663 // Given the assumptions in the translateInst code in the SPARC ITLB,
664 // the logic works out to the following for the context.
665 int context_id = (is_real_address || trapped) ? 0 : primary_context;
658 // The partition id distinguishes between virtualized environments.
659 int const partition_id = 0;
666
660
667 // Insert the TLB entry.
668 // The entry specifying whether the address is "real" is set to
669 // false for syscall emulation mode regardless of whether the
670 // address is real in preceding code. Not sure sure that this is
671 // correct, but also not sure if it matters at all.
672 dynamic_cast<TLB *>(tc->getITBPtr())->
673 insert(alignedvaddr, partition_id, context_id, false, entry.pte);
674 }
661 // Given the assumptions in the translateInst code in the SPARC ITLB,
662 // the logic works out to the following for the context.
663 int context_id = (is_real_address || trapped) ? 0 : primary_context;
664
665 // Insert the TLB entry.
666 // The entry specifying whether the address is "real" is set to
667 // false for syscall emulation mode regardless of whether the
668 // address is real in preceding code. Not sure sure that this is
669 // correct, but also not sure if it matters at all.
670 dynamic_cast<TLB *>(tc->getITBPtr())->
671 insert(alignedvaddr, partition_id, context_id, false, entry->pte);
675}
676
677void
678FastDataAccessMMUMiss::invoke(ThreadContext *tc, const StaticInstPtr &inst)
679{
680 if (FullSystem) {
681 SparcFaultBase::invoke(tc, inst);
682 return;
683 }
684
685 Process *p = tc->getProcessPtr();
672}
673
674void
675FastDataAccessMMUMiss::invoke(ThreadContext *tc, const StaticInstPtr &inst)
676{
677 if (FullSystem) {
678 SparcFaultBase::invoke(tc, inst);
679 return;
680 }
681
682 Process *p = tc->getProcessPtr();
686 TlbEntry entry;
687 bool success = p->pTable->lookup(vaddr, entry);
688 if (!success) {
689 if (p->fixupStackFault(vaddr))
690 success = p->pTable->lookup(vaddr, entry);
691 }
692 if (!success) {
693 panic("Tried to access unmapped address %#x.\n", vaddr);
694 } else {
695 Addr alignedvaddr = p->pTable->pageAlign(vaddr);
683 TlbEntry *entry = p->pTable->lookup(vaddr);
684 if (!entry && p->fixupStackFault(vaddr))
685 entry = p->pTable->lookup(vaddr);
686 panic_if(!entry, "Tried to access unmapped address %#x.\n", vaddr);
696
687
697 // Grab fields used during data translation to figure out
698 // which context to use.
699 uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
688 Addr alignedvaddr = p->pTable->pageAlign(vaddr);
700
689
701 // The primary context acts as a PASID. It allows the MMU to
702 // distinguish between virtual addresses that would alias to the
703 // same physical address (if two or more processes shared the same
704 // virtual address mapping). There's a secondary context used in the
705 // DTLB translation code, but it should __probably__ be zero for
706 // syscall emulation code. (The secondary context is used by Solaris
707 // to allow kernel privilege code to access user space code:
708 // [ISBN 0-13-022496-0]:PG199.)
709 int primary_context = bits(tlbdata, 47, 32);
690 // Grab fields used during data translation to figure out
691 // which context to use.
692 uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
710
693
711 // "Hyper-Privileged Mode" is in use. There are three main modes of
712 // operation for Sparc: Hyper-Privileged Mode, Privileged Mode, and
713 // User Mode.
714 int hpriv = bits(tlbdata, 0);
694 // The primary context acts as a PASID. It allows the MMU to
695 // distinguish between virtual addresses that would alias to the
696 // same physical address (if two or more processes shared the same
697 // virtual address mapping). There's a secondary context used in the
698 // DTLB translation code, but it should __probably__ be zero for
699 // syscall emulation code. (The secondary context is used by Solaris
700 // to allow kernel privilege code to access user space code:
701 // [ISBN 0-13-022496-0]:PG199.)
702 int primary_context = bits(tlbdata, 47, 32);
715
703
716 // Reset, Error and Debug state is in use. Something horrible has
717 // happened or the system is operating in Reset Mode.
718 int red = bits(tlbdata, 1);
704 // "Hyper-Privileged Mode" is in use. There are three main modes of
705 // operation for Sparc: Hyper-Privileged Mode, Privileged Mode, and
706 // User Mode.
707 int hpriv = bits(tlbdata, 0);
719
708
720 // Inside a VM, a real address is the address that guest OS would
721 // interpret to be a physical address. To map to the physical address,
722 // it still needs to undergo a translation. The instruction
723 // translation code in the SPARC ITLB code assumes that the context is
724 // zero (kernel-level) if real addressing is being used.
725 int is_real_address = !bits(tlbdata, 5);
709 // Reset, Error and Debug state is in use. Something horrible has
710 // happened or the system is operating in Reset Mode.
711 int red = bits(tlbdata, 1);
726
712
727 // Grab the address space identifier register from the thread context.
728 // XXX: Inspecting how setMiscReg and setMiscRegNoEffect behave for
729 // MISCREG_ASI causes me to think that the ASI register implementation
730 // might be bugged. The NoEffect variant changes the ASI register
731 // value in the architectural state while the normal variant changes
732 // the context field in the thread context's currently decoded request
733 // but does not directly affect the ASI register value in the
734 // architectural state. The ASI values and the context field in the
735 // request packet seem to have completely different uses.
736 MiscReg reg_asi = tc->readMiscRegNoEffect(MISCREG_ASI);
737 ASI asi = static_cast<ASI>(reg_asi);
713 // Inside a VM, a real address is the address that guest OS would
714 // interpret to be a physical address. To map to the physical address,
715 // it still needs to undergo a translation. The instruction
716 // translation code in the SPARC ITLB code assumes that the context is
717 // zero (kernel-level) if real addressing is being used.
718 int is_real_address = !bits(tlbdata, 5);
738
719
739 // The SPARC DTLB code assumes that traps are executed in context
740 // zero if the asi value is ASI_IMPLICIT (which is 0x0). There's also
741 // an assumption that the nucleus address space is being used, but
742 // the context is the relevant issue since we need to pass it to TLB.
743 bool trapped = bits(tlbdata, 18, 16) > 0;
720 // Grab the address space identifier register from the thread context.
721 // XXX: Inspecting how setMiscReg and setMiscRegNoEffect behave for
722 // MISCREG_ASI causes me to think that the ASI register implementation
723 // might be bugged. The NoEffect variant changes the ASI register
724 // value in the architectural state while the normal variant changes
725 // the context field in the thread context's currently decoded request
726 // but does not directly affect the ASI register value in the
727 // architectural state. The ASI values and the context field in the
728 // request packet seem to have completely different uses.
729 MiscReg reg_asi = tc->readMiscRegNoEffect(MISCREG_ASI);
730 ASI asi = static_cast<ASI>(reg_asi);
744
731
745 // Given the assumptions in the translateData code in the SPARC DTLB,
746 // the logic works out to the following for the context.
747 int context_id = ((!hpriv && !red && is_real_address) ||
748 asiIsReal(asi) ||
749 (trapped && asi == ASI_IMPLICIT))
750 ? 0 : primary_context;
732 // The SPARC DTLB code assumes that traps are executed in context
733 // zero if the asi value is ASI_IMPLICIT (which is 0x0). There's also
734 // an assumption that the nucleus address space is being used, but
735 // the context is the relevant issue since we need to pass it to TLB.
736 bool trapped = bits(tlbdata, 18, 16) > 0;
751
737
752 // The partition id distinguishes between virtualized environments.
753 int const partition_id = 0;
738 // Given the assumptions in the translateData code in the SPARC DTLB,
739 // the logic works out to the following for the context.
740 int context_id = ((!hpriv && !red && is_real_address) ||
741 asiIsReal(asi) ||
742 (trapped && asi == ASI_IMPLICIT))
743 ? 0 : primary_context;
754
744
755 // Insert the TLB entry.
756 // The entry specifying whether the address is "real" is set to
757 // false for syscall emulation mode regardless of whether the
758 // address is real in preceding code. Not sure sure that this is
759 // correct, but also not sure if it matters at all.
760 dynamic_cast<TLB *>(tc->getDTBPtr())->
761 insert(alignedvaddr, partition_id, context_id, false, entry.pte);
762 }
745 // The partition id distinguishes between virtualized environments.
746 int const partition_id = 0;
747
748 // Insert the TLB entry.
749 // The entry specifying whether the address is "real" is set to
750 // false for syscall emulation mode regardless of whether the
751 // address is real in preceding code. Not sure sure that this is
752 // correct, but also not sure if it matters at all.
753 dynamic_cast<TLB *>(tc->getDTBPtr())->
754 insert(alignedvaddr, partition_id, context_id, false, entry->pte);
763}
764
765void
766SpillNNormal::invoke(ThreadContext *tc, const StaticInstPtr &inst)
767{
768 if (FullSystem) {
769 SparcFaultBase::invoke(tc, inst);
770 return;

--- 61 unchanged lines hidden ---
755}
756
757void
758SpillNNormal::invoke(ThreadContext *tc, const StaticInstPtr &inst)
759{
760 if (FullSystem) {
761 SparcFaultBase::invoke(tc, inst);
762 return;

--- 61 unchanged lines hidden ---