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