diff options
Diffstat (limited to 'arch/sparc64/kernel')
29 files changed, 948 insertions, 925 deletions
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index 093281bdf85f..6f00ab8b9d23 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile | |||
@@ -8,7 +8,7 @@ EXTRA_CFLAGS := -Werror | |||
8 | extra-y := head.o init_task.o vmlinux.lds | 8 | extra-y := head.o init_task.o vmlinux.lds |
9 | 9 | ||
10 | obj-y := process.o setup.o cpu.o idprom.o \ | 10 | obj-y := process.o setup.o cpu.o idprom.o \ |
11 | traps.o devices.o auxio.o \ | 11 | traps.o devices.o auxio.o una_asm.o \ |
12 | irq.o ptrace.o time.o sys_sparc.o signal.o \ | 12 | irq.o ptrace.o time.o sys_sparc.o signal.o \ |
13 | unaligned.o central.o pci.o starfire.o semaphore.o \ | 13 | unaligned.o central.o pci.o starfire.o semaphore.o \ |
14 | power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o | 14 | power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o |
diff --git a/arch/sparc64/kernel/asm-offsets.c b/arch/sparc64/kernel/asm-offsets.c new file mode 100644 index 000000000000..9e263112a6e2 --- /dev/null +++ b/arch/sparc64/kernel/asm-offsets.c | |||
@@ -0,0 +1 @@ | |||
/* Dummy asm-offsets.c file. Required by kbuild and ready to be used - hint! */ | |||
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index 88332f00094a..3e0badb820c5 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/visasm.h> | 21 | #include <asm/visasm.h> |
22 | #include <asm/estate.h> | 22 | #include <asm/estate.h> |
23 | #include <asm/auxio.h> | 23 | #include <asm/auxio.h> |
24 | #include <asm/sfafsr.h> | ||
24 | 25 | ||
25 | #define curptr g6 | 26 | #define curptr g6 |
26 | 27 | ||
@@ -690,14 +691,159 @@ netbsd_syscall: | |||
690 | retl | 691 | retl |
691 | nop | 692 | nop |
692 | 693 | ||
693 | /* These next few routines must be sure to clear the | 694 | /* We need to carefully read the error status, ACK |
694 | * SFSR FaultValid bit so that the fast tlb data protection | 695 | * the errors, prevent recursive traps, and pass the |
695 | * handler does not flush the wrong context and lock up the | 696 | * information on to C code for logging. |
696 | * box. | 697 | * |
698 | * We pass the AFAR in as-is, and we encode the status | ||
699 | * information as described in asm-sparc64/sfafsr.h | ||
700 | */ | ||
701 | .globl __spitfire_access_error | ||
702 | __spitfire_access_error: | ||
703 | /* Disable ESTATE error reporting so that we do not | ||
704 | * take recursive traps and RED state the processor. | ||
705 | */ | ||
706 | stxa %g0, [%g0] ASI_ESTATE_ERROR_EN | ||
707 | membar #Sync | ||
708 | |||
709 | mov UDBE_UE, %g1 | ||
710 | ldxa [%g0] ASI_AFSR, %g4 ! Get AFSR | ||
711 | |||
712 | /* __spitfire_cee_trap branches here with AFSR in %g4 and | ||
713 | * UDBE_CE in %g1. It only clears ESTATE_ERR_CE in the | ||
714 | * ESTATE Error Enable register. | ||
715 | */ | ||
716 | __spitfire_cee_trap_continue: | ||
717 | ldxa [%g0] ASI_AFAR, %g5 ! Get AFAR | ||
718 | |||
719 | rdpr %tt, %g3 | ||
720 | and %g3, 0x1ff, %g3 ! Paranoia | ||
721 | sllx %g3, SFSTAT_TRAP_TYPE_SHIFT, %g3 | ||
722 | or %g4, %g3, %g4 | ||
723 | rdpr %tl, %g3 | ||
724 | cmp %g3, 1 | ||
725 | mov 1, %g3 | ||
726 | bleu %xcc, 1f | ||
727 | sllx %g3, SFSTAT_TL_GT_ONE_SHIFT, %g3 | ||
728 | |||
729 | or %g4, %g3, %g4 | ||
730 | |||
731 | /* Read in the UDB error register state, clearing the | ||
732 | * sticky error bits as-needed. We only clear them if | ||
733 | * the UE bit is set. Likewise, __spitfire_cee_trap | ||
734 | * below will only do so if the CE bit is set. | ||
735 | * | ||
736 | * NOTE: UltraSparc-I/II have high and low UDB error | ||
737 | * registers, corresponding to the two UDB units | ||
738 | * present on those chips. UltraSparc-IIi only | ||
739 | * has a single UDB, called "SDB" in the manual. | ||
740 | * For IIi the upper UDB register always reads | ||
741 | * as zero so for our purposes things will just | ||
742 | * work with the checks below. | ||
697 | */ | 743 | */ |
698 | .globl __do_data_access_exception | 744 | 1: ldxa [%g0] ASI_UDBH_ERROR_R, %g3 |
699 | .globl __do_data_access_exception_tl1 | 745 | and %g3, 0x3ff, %g7 ! Paranoia |
700 | __do_data_access_exception_tl1: | 746 | sllx %g7, SFSTAT_UDBH_SHIFT, %g7 |
747 | or %g4, %g7, %g4 | ||
748 | andcc %g3, %g1, %g3 ! UDBE_UE or UDBE_CE | ||
749 | be,pn %xcc, 1f | ||
750 | nop | ||
751 | stxa %g3, [%g0] ASI_UDB_ERROR_W | ||
752 | membar #Sync | ||
753 | |||
754 | 1: mov 0x18, %g3 | ||
755 | ldxa [%g3] ASI_UDBL_ERROR_R, %g3 | ||
756 | and %g3, 0x3ff, %g7 ! Paranoia | ||
757 | sllx %g7, SFSTAT_UDBL_SHIFT, %g7 | ||
758 | or %g4, %g7, %g4 | ||
759 | andcc %g3, %g1, %g3 ! UDBE_UE or UDBE_CE | ||
760 | be,pn %xcc, 1f | ||
761 | nop | ||
762 | mov 0x18, %g7 | ||
763 | stxa %g3, [%g7] ASI_UDB_ERROR_W | ||
764 | membar #Sync | ||
765 | |||
766 | 1: /* Ok, now that we've latched the error state, | ||
767 | * clear the sticky bits in the AFSR. | ||
768 | */ | ||
769 | stxa %g4, [%g0] ASI_AFSR | ||
770 | membar #Sync | ||
771 | |||
772 | rdpr %tl, %g2 | ||
773 | cmp %g2, 1 | ||
774 | rdpr %pil, %g2 | ||
775 | bleu,pt %xcc, 1f | ||
776 | wrpr %g0, 15, %pil | ||
777 | |||
778 | ba,pt %xcc, etraptl1 | ||
779 | rd %pc, %g7 | ||
780 | |||
781 | ba,pt %xcc, 2f | ||
782 | nop | ||
783 | |||
784 | 1: ba,pt %xcc, etrap_irq | ||
785 | rd %pc, %g7 | ||
786 | |||
787 | 2: mov %l4, %o1 | ||
788 | mov %l5, %o2 | ||
789 | call spitfire_access_error | ||
790 | add %sp, PTREGS_OFF, %o0 | ||
791 | ba,pt %xcc, rtrap | ||
792 | clr %l6 | ||
793 | |||
794 | /* This is the trap handler entry point for ECC correctable | ||
795 | * errors. They are corrected, but we listen for the trap | ||
796 | * so that the event can be logged. | ||
797 | * | ||
798 | * Disrupting errors are either: | ||
799 | * 1) single-bit ECC errors during UDB reads to system | ||
800 | * memory | ||
801 | * 2) data parity errors during write-back events | ||
802 | * | ||
803 | * As far as I can make out from the manual, the CEE trap | ||
804 | * is only for correctable errors during memory read | ||
805 | * accesses by the front-end of the processor. | ||
806 | * | ||
807 | * The code below is only for trap level 1 CEE events, | ||
808 | * as it is the only situation where we can safely record | ||
809 | * and log. For trap level >1 we just clear the CE bit | ||
810 | * in the AFSR and return. | ||
811 | * | ||
812 | * This is just like __spiftire_access_error above, but it | ||
813 | * specifically handles correctable errors. If an | ||
814 | * uncorrectable error is indicated in the AFSR we | ||
815 | * will branch directly above to __spitfire_access_error | ||
816 | * to handle it instead. Uncorrectable therefore takes | ||
817 | * priority over correctable, and the error logging | ||
818 | * C code will notice this case by inspecting the | ||
819 | * trap type. | ||
820 | */ | ||
821 | .globl __spitfire_cee_trap | ||
822 | __spitfire_cee_trap: | ||
823 | ldxa [%g0] ASI_AFSR, %g4 ! Get AFSR | ||
824 | mov 1, %g3 | ||
825 | sllx %g3, SFAFSR_UE_SHIFT, %g3 | ||
826 | andcc %g4, %g3, %g0 ! Check for UE | ||
827 | bne,pn %xcc, __spitfire_access_error | ||
828 | nop | ||
829 | |||
830 | /* Ok, in this case we only have a correctable error. | ||
831 | * Indicate we only wish to capture that state in register | ||
832 | * %g1, and we only disable CE error reporting unlike UE | ||
833 | * handling which disables all errors. | ||
834 | */ | ||
835 | ldxa [%g0] ASI_ESTATE_ERROR_EN, %g3 | ||
836 | andn %g3, ESTATE_ERR_CE, %g3 | ||
837 | stxa %g3, [%g0] ASI_ESTATE_ERROR_EN | ||
838 | membar #Sync | ||
839 | |||
840 | /* Preserve AFSR in %g4, indicate UDB state to capture in %g1 */ | ||
841 | ba,pt %xcc, __spitfire_cee_trap_continue | ||
842 | mov UDBE_CE, %g1 | ||
843 | |||
844 | .globl __spitfire_data_access_exception | ||
845 | .globl __spitfire_data_access_exception_tl1 | ||
846 | __spitfire_data_access_exception_tl1: | ||
701 | rdpr %pstate, %g4 | 847 | rdpr %pstate, %g4 |
702 | wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate | 848 | wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate |
703 | mov TLB_SFSR, %g3 | 849 | mov TLB_SFSR, %g3 |
@@ -706,9 +852,25 @@ __do_data_access_exception_tl1: | |||
706 | ldxa [%g5] ASI_DMMU, %g5 ! Get SFAR | 852 | ldxa [%g5] ASI_DMMU, %g5 ! Get SFAR |
707 | stxa %g0, [%g3] ASI_DMMU ! Clear SFSR.FaultValid bit | 853 | stxa %g0, [%g3] ASI_DMMU ! Clear SFSR.FaultValid bit |
708 | membar #Sync | 854 | membar #Sync |
855 | rdpr %tt, %g3 | ||
856 | cmp %g3, 0x80 ! first win spill/fill trap | ||
857 | blu,pn %xcc, 1f | ||
858 | cmp %g3, 0xff ! last win spill/fill trap | ||
859 | bgu,pn %xcc, 1f | ||
860 | nop | ||
709 | ba,pt %xcc, winfix_dax | 861 | ba,pt %xcc, winfix_dax |
710 | rdpr %tpc, %g3 | 862 | rdpr %tpc, %g3 |
711 | __do_data_access_exception: | 863 | 1: sethi %hi(109f), %g7 |
864 | ba,pt %xcc, etraptl1 | ||
865 | 109: or %g7, %lo(109b), %g7 | ||
866 | mov %l4, %o1 | ||
867 | mov %l5, %o2 | ||
868 | call spitfire_data_access_exception_tl1 | ||
869 | add %sp, PTREGS_OFF, %o0 | ||
870 | ba,pt %xcc, rtrap | ||
871 | clr %l6 | ||
872 | |||
873 | __spitfire_data_access_exception: | ||
712 | rdpr %pstate, %g4 | 874 | rdpr %pstate, %g4 |
713 | wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate | 875 | wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate |
714 | mov TLB_SFSR, %g3 | 876 | mov TLB_SFSR, %g3 |
@@ -722,20 +884,19 @@ __do_data_access_exception: | |||
722 | 109: or %g7, %lo(109b), %g7 | 884 | 109: or %g7, %lo(109b), %g7 |
723 | mov %l4, %o1 | 885 | mov %l4, %o1 |
724 | mov %l5, %o2 | 886 | mov %l5, %o2 |
725 | call data_access_exception | 887 | call spitfire_data_access_exception |
726 | add %sp, PTREGS_OFF, %o0 | 888 | add %sp, PTREGS_OFF, %o0 |
727 | ba,pt %xcc, rtrap | 889 | ba,pt %xcc, rtrap |
728 | clr %l6 | 890 | clr %l6 |
729 | 891 | ||
730 | .globl __do_instruction_access_exception | 892 | .globl __spitfire_insn_access_exception |
731 | .globl __do_instruction_access_exception_tl1 | 893 | .globl __spitfire_insn_access_exception_tl1 |
732 | __do_instruction_access_exception_tl1: | 894 | __spitfire_insn_access_exception_tl1: |
733 | rdpr %pstate, %g4 | 895 | rdpr %pstate, %g4 |
734 | wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate | 896 | wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate |
735 | mov TLB_SFSR, %g3 | 897 | mov TLB_SFSR, %g3 |
736 | mov DMMU_SFAR, %g5 | 898 | ldxa [%g3] ASI_IMMU, %g4 ! Get SFSR |
737 | ldxa [%g3] ASI_DMMU, %g4 ! Get SFSR | 899 | rdpr %tpc, %g5 ! IMMU has no SFAR, use TPC |
738 | ldxa [%g5] ASI_DMMU, %g5 ! Get SFAR | ||
739 | stxa %g0, [%g3] ASI_IMMU ! Clear FaultValid bit | 900 | stxa %g0, [%g3] ASI_IMMU ! Clear FaultValid bit |
740 | membar #Sync | 901 | membar #Sync |
741 | sethi %hi(109f), %g7 | 902 | sethi %hi(109f), %g7 |
@@ -743,18 +904,17 @@ __do_instruction_access_exception_tl1: | |||
743 | 109: or %g7, %lo(109b), %g7 | 904 | 109: or %g7, %lo(109b), %g7 |
744 | mov %l4, %o1 | 905 | mov %l4, %o1 |
745 | mov %l5, %o2 | 906 | mov %l5, %o2 |
746 | call instruction_access_exception_tl1 | 907 | call spitfire_insn_access_exception_tl1 |
747 | add %sp, PTREGS_OFF, %o0 | 908 | add %sp, PTREGS_OFF, %o0 |
748 | ba,pt %xcc, rtrap | 909 | ba,pt %xcc, rtrap |
749 | clr %l6 | 910 | clr %l6 |
750 | 911 | ||
751 | __do_instruction_access_exception: | 912 | __spitfire_insn_access_exception: |
752 | rdpr %pstate, %g4 | 913 | rdpr %pstate, %g4 |
753 | wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate | 914 | wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate |
754 | mov TLB_SFSR, %g3 | 915 | mov TLB_SFSR, %g3 |
755 | mov DMMU_SFAR, %g5 | 916 | ldxa [%g3] ASI_IMMU, %g4 ! Get SFSR |
756 | ldxa [%g3] ASI_DMMU, %g4 ! Get SFSR | 917 | rdpr %tpc, %g5 ! IMMU has no SFAR, use TPC |
757 | ldxa [%g5] ASI_DMMU, %g5 ! Get SFAR | ||
758 | stxa %g0, [%g3] ASI_IMMU ! Clear FaultValid bit | 918 | stxa %g0, [%g3] ASI_IMMU ! Clear FaultValid bit |
759 | membar #Sync | 919 | membar #Sync |
760 | sethi %hi(109f), %g7 | 920 | sethi %hi(109f), %g7 |
@@ -762,235 +922,11 @@ __do_instruction_access_exception: | |||
762 | 109: or %g7, %lo(109b), %g7 | 922 | 109: or %g7, %lo(109b), %g7 |
763 | mov %l4, %o1 | 923 | mov %l4, %o1 |
764 | mov %l5, %o2 | 924 | mov %l5, %o2 |
765 | call instruction_access_exception | 925 | call spitfire_insn_access_exception |
766 | add %sp, PTREGS_OFF, %o0 | 926 | add %sp, PTREGS_OFF, %o0 |
767 | ba,pt %xcc, rtrap | 927 | ba,pt %xcc, rtrap |
768 | clr %l6 | 928 | clr %l6 |
769 | 929 | ||
770 | /* This is the trap handler entry point for ECC correctable | ||
771 | * errors. They are corrected, but we listen for the trap | ||
772 | * so that the event can be logged. | ||
773 | * | ||
774 | * Disrupting errors are either: | ||
775 | * 1) single-bit ECC errors during UDB reads to system | ||
776 | * memory | ||
777 | * 2) data parity errors during write-back events | ||
778 | * | ||
779 | * As far as I can make out from the manual, the CEE trap | ||
780 | * is only for correctable errors during memory read | ||
781 | * accesses by the front-end of the processor. | ||
782 | * | ||
783 | * The code below is only for trap level 1 CEE events, | ||
784 | * as it is the only situation where we can safely record | ||
785 | * and log. For trap level >1 we just clear the CE bit | ||
786 | * in the AFSR and return. | ||
787 | */ | ||
788 | |||
789 | /* Our trap handling infrastructure allows us to preserve | ||
790 | * two 64-bit values during etrap for arguments to | ||
791 | * subsequent C code. Therefore we encode the information | ||
792 | * as follows: | ||
793 | * | ||
794 | * value 1) Full 64-bits of AFAR | ||
795 | * value 2) Low 33-bits of AFSR, then bits 33-->42 | ||
796 | * are UDBL error status and bits 43-->52 | ||
797 | * are UDBH error status | ||
798 | */ | ||
799 | .align 64 | ||
800 | .globl cee_trap | ||
801 | cee_trap: | ||
802 | ldxa [%g0] ASI_AFSR, %g1 ! Read AFSR | ||
803 | ldxa [%g0] ASI_AFAR, %g2 ! Read AFAR | ||
804 | sllx %g1, 31, %g1 ! Clear reserved bits | ||
805 | srlx %g1, 31, %g1 ! in AFSR | ||
806 | |||
807 | /* NOTE: UltraSparc-I/II have high and low UDB error | ||
808 | * registers, corresponding to the two UDB units | ||
809 | * present on those chips. UltraSparc-IIi only | ||
810 | * has a single UDB, called "SDB" in the manual. | ||
811 | * For IIi the upper UDB register always reads | ||
812 | * as zero so for our purposes things will just | ||
813 | * work with the checks below. | ||
814 | */ | ||
815 | ldxa [%g0] ASI_UDBL_ERROR_R, %g3 ! Read UDB-Low error status | ||
816 | andcc %g3, (1 << 8), %g4 ! Check CE bit | ||
817 | sllx %g3, (64 - 10), %g3 ! Clear reserved bits | ||
818 | srlx %g3, (64 - 10), %g3 ! in UDB-Low error status | ||
819 | |||
820 | sllx %g3, (33 + 0), %g3 ! Shift up to encoding area | ||
821 | or %g1, %g3, %g1 ! Or it in | ||
822 | be,pn %xcc, 1f ! Branch if CE bit was clear | ||
823 | nop | ||
824 | stxa %g4, [%g0] ASI_UDB_ERROR_W ! Clear CE sticky bit in UDBL | ||
825 | membar #Sync ! Synchronize ASI stores | ||
826 | 1: mov 0x18, %g5 ! Addr of UDB-High error status | ||
827 | ldxa [%g5] ASI_UDBH_ERROR_R, %g3 ! Read it | ||
828 | |||
829 | andcc %g3, (1 << 8), %g4 ! Check CE bit | ||
830 | sllx %g3, (64 - 10), %g3 ! Clear reserved bits | ||
831 | srlx %g3, (64 - 10), %g3 ! in UDB-High error status | ||
832 | sllx %g3, (33 + 10), %g3 ! Shift up to encoding area | ||
833 | or %g1, %g3, %g1 ! Or it in | ||
834 | be,pn %xcc, 1f ! Branch if CE bit was clear | ||
835 | nop | ||
836 | nop | ||
837 | |||
838 | stxa %g4, [%g5] ASI_UDB_ERROR_W ! Clear CE sticky bit in UDBH | ||
839 | membar #Sync ! Synchronize ASI stores | ||
840 | 1: mov 1, %g5 ! AFSR CE bit is | ||
841 | sllx %g5, 20, %g5 ! bit 20 | ||
842 | stxa %g5, [%g0] ASI_AFSR ! Clear CE sticky bit in AFSR | ||
843 | membar #Sync ! Synchronize ASI stores | ||
844 | sllx %g2, (64 - 41), %g2 ! Clear reserved bits | ||
845 | srlx %g2, (64 - 41), %g2 ! in latched AFAR | ||
846 | |||
847 | andn %g2, 0x0f, %g2 ! Finish resv bit clearing | ||
848 | mov %g1, %g4 ! Move AFSR+UDB* into save reg | ||
849 | mov %g2, %g5 ! Move AFAR into save reg | ||
850 | rdpr %pil, %g2 | ||
851 | wrpr %g0, 15, %pil | ||
852 | ba,pt %xcc, etrap_irq | ||
853 | rd %pc, %g7 | ||
854 | mov %l4, %o0 | ||
855 | |||
856 | mov %l5, %o1 | ||
857 | call cee_log | ||
858 | add %sp, PTREGS_OFF, %o2 | ||
859 | ba,a,pt %xcc, rtrap_irq | ||
860 | |||
861 | /* Capture I/D/E-cache state into per-cpu error scoreboard. | ||
862 | * | ||
863 | * %g1: (TL>=0) ? 1 : 0 | ||
864 | * %g2: scratch | ||
865 | * %g3: scratch | ||
866 | * %g4: AFSR | ||
867 | * %g5: AFAR | ||
868 | * %g6: current thread ptr | ||
869 | * %g7: scratch | ||
870 | */ | ||
871 | #define CHEETAH_LOG_ERROR \ | ||
872 | /* Put "TL1" software bit into AFSR. */ \ | ||
873 | and %g1, 0x1, %g1; \ | ||
874 | sllx %g1, 63, %g2; \ | ||
875 | or %g4, %g2, %g4; \ | ||
876 | /* Get log entry pointer for this cpu at this trap level. */ \ | ||
877 | BRANCH_IF_JALAPENO(g2,g3,50f) \ | ||
878 | ldxa [%g0] ASI_SAFARI_CONFIG, %g2; \ | ||
879 | srlx %g2, 17, %g2; \ | ||
880 | ba,pt %xcc, 60f; \ | ||
881 | and %g2, 0x3ff, %g2; \ | ||
882 | 50: ldxa [%g0] ASI_JBUS_CONFIG, %g2; \ | ||
883 | srlx %g2, 17, %g2; \ | ||
884 | and %g2, 0x1f, %g2; \ | ||
885 | 60: sllx %g2, 9, %g2; \ | ||
886 | sethi %hi(cheetah_error_log), %g3; \ | ||
887 | ldx [%g3 + %lo(cheetah_error_log)], %g3; \ | ||
888 | brz,pn %g3, 80f; \ | ||
889 | nop; \ | ||
890 | add %g3, %g2, %g3; \ | ||
891 | sllx %g1, 8, %g1; \ | ||
892 | add %g3, %g1, %g1; \ | ||
893 | /* %g1 holds pointer to the top of the logging scoreboard */ \ | ||
894 | ldx [%g1 + 0x0], %g7; \ | ||
895 | cmp %g7, -1; \ | ||
896 | bne,pn %xcc, 80f; \ | ||
897 | nop; \ | ||
898 | stx %g4, [%g1 + 0x0]; \ | ||
899 | stx %g5, [%g1 + 0x8]; \ | ||
900 | add %g1, 0x10, %g1; \ | ||
901 | /* %g1 now points to D-cache logging area */ \ | ||
902 | set 0x3ff8, %g2; /* DC_addr mask */ \ | ||
903 | and %g5, %g2, %g2; /* DC_addr bits of AFAR */ \ | ||
904 | srlx %g5, 12, %g3; \ | ||
905 | or %g3, 1, %g3; /* PHYS tag + valid */ \ | ||
906 | 10: ldxa [%g2] ASI_DCACHE_TAG, %g7; \ | ||
907 | cmp %g3, %g7; /* TAG match? */ \ | ||
908 | bne,pt %xcc, 13f; \ | ||
909 | nop; \ | ||
910 | /* Yep, what we want, capture state. */ \ | ||
911 | stx %g2, [%g1 + 0x20]; \ | ||
912 | stx %g7, [%g1 + 0x28]; \ | ||
913 | /* A membar Sync is required before and after utag access. */ \ | ||
914 | membar #Sync; \ | ||
915 | ldxa [%g2] ASI_DCACHE_UTAG, %g7; \ | ||
916 | membar #Sync; \ | ||
917 | stx %g7, [%g1 + 0x30]; \ | ||
918 | ldxa [%g2] ASI_DCACHE_SNOOP_TAG, %g7; \ | ||
919 | stx %g7, [%g1 + 0x38]; \ | ||
920 | clr %g3; \ | ||
921 | 12: ldxa [%g2 + %g3] ASI_DCACHE_DATA, %g7; \ | ||
922 | stx %g7, [%g1]; \ | ||
923 | add %g3, (1 << 5), %g3; \ | ||
924 | cmp %g3, (4 << 5); \ | ||
925 | bl,pt %xcc, 12b; \ | ||
926 | add %g1, 0x8, %g1; \ | ||
927 | ba,pt %xcc, 20f; \ | ||
928 | add %g1, 0x20, %g1; \ | ||
929 | 13: sethi %hi(1 << 14), %g7; \ | ||
930 | add %g2, %g7, %g2; \ | ||
931 | srlx %g2, 14, %g7; \ | ||
932 | cmp %g7, 4; \ | ||
933 | bl,pt %xcc, 10b; \ | ||
934 | nop; \ | ||
935 | add %g1, 0x40, %g1; \ | ||
936 | 20: /* %g1 now points to I-cache logging area */ \ | ||
937 | set 0x1fe0, %g2; /* IC_addr mask */ \ | ||
938 | and %g5, %g2, %g2; /* IC_addr bits of AFAR */ \ | ||
939 | sllx %g2, 1, %g2; /* IC_addr[13:6]==VA[12:5] */ \ | ||
940 | srlx %g5, (13 - 8), %g3; /* Make PTAG */ \ | ||
941 | andn %g3, 0xff, %g3; /* Mask off undefined bits */ \ | ||
942 | 21: ldxa [%g2] ASI_IC_TAG, %g7; \ | ||
943 | andn %g7, 0xff, %g7; \ | ||
944 | cmp %g3, %g7; \ | ||
945 | bne,pt %xcc, 23f; \ | ||
946 | nop; \ | ||
947 | /* Yep, what we want, capture state. */ \ | ||
948 | stx %g2, [%g1 + 0x40]; \ | ||
949 | stx %g7, [%g1 + 0x48]; \ | ||
950 | add %g2, (1 << 3), %g2; \ | ||
951 | ldxa [%g2] ASI_IC_TAG, %g7; \ | ||
952 | add %g2, (1 << 3), %g2; \ | ||
953 | stx %g7, [%g1 + 0x50]; \ | ||
954 | ldxa [%g2] ASI_IC_TAG, %g7; \ | ||
955 | add %g2, (1 << 3), %g2; \ | ||
956 | stx %g7, [%g1 + 0x60]; \ | ||
957 | ldxa [%g2] ASI_IC_TAG, %g7; \ | ||
958 | stx %g7, [%g1 + 0x68]; \ | ||
959 | sub %g2, (3 << 3), %g2; \ | ||
960 | ldxa [%g2] ASI_IC_STAG, %g7; \ | ||
961 | stx %g7, [%g1 + 0x58]; \ | ||
962 | clr %g3; \ | ||
963 | srlx %g2, 2, %g2; \ | ||
964 | 22: ldxa [%g2 + %g3] ASI_IC_INSTR, %g7; \ | ||
965 | stx %g7, [%g1]; \ | ||
966 | add %g3, (1 << 3), %g3; \ | ||
967 | cmp %g3, (8 << 3); \ | ||
968 | bl,pt %xcc, 22b; \ | ||
969 | add %g1, 0x8, %g1; \ | ||
970 | ba,pt %xcc, 30f; \ | ||
971 | add %g1, 0x30, %g1; \ | ||
972 | 23: sethi %hi(1 << 14), %g7; \ | ||
973 | add %g2, %g7, %g2; \ | ||
974 | srlx %g2, 14, %g7; \ | ||
975 | cmp %g7, 4; \ | ||
976 | bl,pt %xcc, 21b; \ | ||
977 | nop; \ | ||
978 | add %g1, 0x70, %g1; \ | ||
979 | 30: /* %g1 now points to E-cache logging area */ \ | ||
980 | andn %g5, (32 - 1), %g2; /* E-cache subblock */ \ | ||
981 | stx %g2, [%g1 + 0x20]; \ | ||
982 | ldxa [%g2] ASI_EC_TAG_DATA, %g7; \ | ||
983 | stx %g7, [%g1 + 0x28]; \ | ||
984 | ldxa [%g2] ASI_EC_R, %g0; \ | ||
985 | clr %g3; \ | ||
986 | 31: ldxa [%g3] ASI_EC_DATA, %g7; \ | ||
987 | stx %g7, [%g1 + %g3]; \ | ||
988 | add %g3, 0x8, %g3; \ | ||
989 | cmp %g3, 0x20; \ | ||
990 | bl,pt %xcc, 31b; \ | ||
991 | nop; \ | ||
992 | 80: /* DONE */ | ||
993 | |||
994 | /* These get patched into the trap table at boot time | 930 | /* These get patched into the trap table at boot time |
995 | * once we know we have a cheetah processor. | 931 | * once we know we have a cheetah processor. |
996 | */ | 932 | */ |
@@ -1227,6 +1163,170 @@ dcpe_icpe_tl1_common: | |||
1227 | membar #Sync | 1163 | membar #Sync |
1228 | retry | 1164 | retry |
1229 | 1165 | ||
1166 | /* Capture I/D/E-cache state into per-cpu error scoreboard. | ||
1167 | * | ||
1168 | * %g1: (TL>=0) ? 1 : 0 | ||
1169 | * %g2: scratch | ||
1170 | * %g3: scratch | ||
1171 | * %g4: AFSR | ||
1172 | * %g5: AFAR | ||
1173 | * %g6: current thread ptr | ||
1174 | * %g7: scratch | ||
1175 | */ | ||
1176 | __cheetah_log_error: | ||
1177 | /* Put "TL1" software bit into AFSR. */ | ||
1178 | and %g1, 0x1, %g1 | ||
1179 | sllx %g1, 63, %g2 | ||
1180 | or %g4, %g2, %g4 | ||
1181 | |||
1182 | /* Get log entry pointer for this cpu at this trap level. */ | ||
1183 | BRANCH_IF_JALAPENO(g2,g3,50f) | ||
1184 | ldxa [%g0] ASI_SAFARI_CONFIG, %g2 | ||
1185 | srlx %g2, 17, %g2 | ||
1186 | ba,pt %xcc, 60f | ||
1187 | and %g2, 0x3ff, %g2 | ||
1188 | |||
1189 | 50: ldxa [%g0] ASI_JBUS_CONFIG, %g2 | ||
1190 | srlx %g2, 17, %g2 | ||
1191 | and %g2, 0x1f, %g2 | ||
1192 | |||
1193 | 60: sllx %g2, 9, %g2 | ||
1194 | sethi %hi(cheetah_error_log), %g3 | ||
1195 | ldx [%g3 + %lo(cheetah_error_log)], %g3 | ||
1196 | brz,pn %g3, 80f | ||
1197 | nop | ||
1198 | |||
1199 | add %g3, %g2, %g3 | ||
1200 | sllx %g1, 8, %g1 | ||
1201 | add %g3, %g1, %g1 | ||
1202 | |||
1203 | /* %g1 holds pointer to the top of the logging scoreboard */ | ||
1204 | ldx [%g1 + 0x0], %g7 | ||
1205 | cmp %g7, -1 | ||
1206 | bne,pn %xcc, 80f | ||
1207 | nop | ||
1208 | |||
1209 | stx %g4, [%g1 + 0x0] | ||
1210 | stx %g5, [%g1 + 0x8] | ||
1211 | add %g1, 0x10, %g1 | ||
1212 | |||
1213 | /* %g1 now points to D-cache logging area */ | ||
1214 | set 0x3ff8, %g2 /* DC_addr mask */ | ||
1215 | and %g5, %g2, %g2 /* DC_addr bits of AFAR */ | ||
1216 | srlx %g5, 12, %g3 | ||
1217 | or %g3, 1, %g3 /* PHYS tag + valid */ | ||
1218 | |||
1219 | 10: ldxa [%g2] ASI_DCACHE_TAG, %g7 | ||
1220 | cmp %g3, %g7 /* TAG match? */ | ||
1221 | bne,pt %xcc, 13f | ||
1222 | nop | ||
1223 | |||
1224 | /* Yep, what we want, capture state. */ | ||
1225 | stx %g2, [%g1 + 0x20] | ||
1226 | stx %g7, [%g1 + 0x28] | ||
1227 | |||
1228 | /* A membar Sync is required before and after utag access. */ | ||
1229 | membar #Sync | ||
1230 | ldxa [%g2] ASI_DCACHE_UTAG, %g7 | ||
1231 | membar #Sync | ||
1232 | stx %g7, [%g1 + 0x30] | ||
1233 | ldxa [%g2] ASI_DCACHE_SNOOP_TAG, %g7 | ||
1234 | stx %g7, [%g1 + 0x38] | ||
1235 | clr %g3 | ||
1236 | |||
1237 | 12: ldxa [%g2 + %g3] ASI_DCACHE_DATA, %g7 | ||
1238 | stx %g7, [%g1] | ||
1239 | add %g3, (1 << 5), %g3 | ||
1240 | cmp %g3, (4 << 5) | ||
1241 | bl,pt %xcc, 12b | ||
1242 | add %g1, 0x8, %g1 | ||
1243 | |||
1244 | ba,pt %xcc, 20f | ||
1245 | add %g1, 0x20, %g1 | ||
1246 | |||
1247 | 13: sethi %hi(1 << 14), %g7 | ||
1248 | add %g2, %g7, %g2 | ||
1249 | srlx %g2, 14, %g7 | ||
1250 | cmp %g7, 4 | ||
1251 | bl,pt %xcc, 10b | ||
1252 | nop | ||
1253 | |||
1254 | add %g1, 0x40, %g1 | ||
1255 | |||
1256 | /* %g1 now points to I-cache logging area */ | ||
1257 | 20: set 0x1fe0, %g2 /* IC_addr mask */ | ||
1258 | and %g5, %g2, %g2 /* IC_addr bits of AFAR */ | ||
1259 | sllx %g2, 1, %g2 /* IC_addr[13:6]==VA[12:5] */ | ||
1260 | srlx %g5, (13 - 8), %g3 /* Make PTAG */ | ||
1261 | andn %g3, 0xff, %g3 /* Mask off undefined bits */ | ||
1262 | |||
1263 | 21: ldxa [%g2] ASI_IC_TAG, %g7 | ||
1264 | andn %g7, 0xff, %g7 | ||
1265 | cmp %g3, %g7 | ||
1266 | bne,pt %xcc, 23f | ||
1267 | nop | ||
1268 | |||
1269 | /* Yep, what we want, capture state. */ | ||
1270 | stx %g2, [%g1 + 0x40] | ||
1271 | stx %g7, [%g1 + 0x48] | ||
1272 | add %g2, (1 << 3), %g2 | ||
1273 | ldxa [%g2] ASI_IC_TAG, %g7 | ||
1274 | add %g2, (1 << 3), %g2 | ||
1275 | stx %g7, [%g1 + 0x50] | ||
1276 | ldxa [%g2] ASI_IC_TAG, %g7 | ||
1277 | add %g2, (1 << 3), %g2 | ||
1278 | stx %g7, [%g1 + 0x60] | ||
1279 | ldxa [%g2] ASI_IC_TAG, %g7 | ||
1280 | stx %g7, [%g1 + 0x68] | ||
1281 | sub %g2, (3 << 3), %g2 | ||
1282 | ldxa [%g2] ASI_IC_STAG, %g7 | ||
1283 | stx %g7, [%g1 + 0x58] | ||
1284 | clr %g3 | ||
1285 | srlx %g2, 2, %g2 | ||
1286 | |||
1287 | 22: ldxa [%g2 + %g3] ASI_IC_INSTR, %g7 | ||
1288 | stx %g7, [%g1] | ||
1289 | add %g3, (1 << 3), %g3 | ||
1290 | cmp %g3, (8 << 3) | ||
1291 | bl,pt %xcc, 22b | ||
1292 | add %g1, 0x8, %g1 | ||
1293 | |||
1294 | ba,pt %xcc, 30f | ||
1295 | add %g1, 0x30, %g1 | ||
1296 | |||
1297 | 23: sethi %hi(1 << 14), %g7 | ||
1298 | add %g2, %g7, %g2 | ||
1299 | srlx %g2, 14, %g7 | ||
1300 | cmp %g7, 4 | ||
1301 | bl,pt %xcc, 21b | ||
1302 | nop | ||
1303 | |||
1304 | add %g1, 0x70, %g1 | ||
1305 | |||
1306 | /* %g1 now points to E-cache logging area */ | ||
1307 | 30: andn %g5, (32 - 1), %g2 | ||
1308 | stx %g2, [%g1 + 0x20] | ||
1309 | ldxa [%g2] ASI_EC_TAG_DATA, %g7 | ||
1310 | stx %g7, [%g1 + 0x28] | ||
1311 | ldxa [%g2] ASI_EC_R, %g0 | ||
1312 | clr %g3 | ||
1313 | |||
1314 | 31: ldxa [%g3] ASI_EC_DATA, %g7 | ||
1315 | stx %g7, [%g1 + %g3] | ||
1316 | add %g3, 0x8, %g3 | ||
1317 | cmp %g3, 0x20 | ||
1318 | |||
1319 | bl,pt %xcc, 31b | ||
1320 | nop | ||
1321 | 80: | ||
1322 | rdpr %tt, %g2 | ||
1323 | cmp %g2, 0x70 | ||
1324 | be c_fast_ecc | ||
1325 | cmp %g2, 0x63 | ||
1326 | be c_cee | ||
1327 | nop | ||
1328 | ba,pt %xcc, c_deferred | ||
1329 | |||
1230 | /* Cheetah FECC trap handling, we get here from tl{0,1}_fecc | 1330 | /* Cheetah FECC trap handling, we get here from tl{0,1}_fecc |
1231 | * in the trap table. That code has done a memory barrier | 1331 | * in the trap table. That code has done a memory barrier |
1232 | * and has disabled both the I-cache and D-cache in the DCU | 1332 | * and has disabled both the I-cache and D-cache in the DCU |
@@ -1252,8 +1352,10 @@ cheetah_fast_ecc: | |||
1252 | stxa %g4, [%g0] ASI_AFSR | 1352 | stxa %g4, [%g0] ASI_AFSR |
1253 | membar #Sync | 1353 | membar #Sync |
1254 | 1354 | ||
1255 | CHEETAH_LOG_ERROR | 1355 | ba,pt %xcc, __cheetah_log_error |
1356 | nop | ||
1256 | 1357 | ||
1358 | c_fast_ecc: | ||
1257 | rdpr %pil, %g2 | 1359 | rdpr %pil, %g2 |
1258 | wrpr %g0, 15, %pil | 1360 | wrpr %g0, 15, %pil |
1259 | ba,pt %xcc, etrap_irq | 1361 | ba,pt %xcc, etrap_irq |
@@ -1278,8 +1380,10 @@ cheetah_cee: | |||
1278 | stxa %g4, [%g0] ASI_AFSR | 1380 | stxa %g4, [%g0] ASI_AFSR |
1279 | membar #Sync | 1381 | membar #Sync |
1280 | 1382 | ||
1281 | CHEETAH_LOG_ERROR | 1383 | ba,pt %xcc, __cheetah_log_error |
1384 | nop | ||
1282 | 1385 | ||
1386 | c_cee: | ||
1283 | rdpr %pil, %g2 | 1387 | rdpr %pil, %g2 |
1284 | wrpr %g0, 15, %pil | 1388 | wrpr %g0, 15, %pil |
1285 | ba,pt %xcc, etrap_irq | 1389 | ba,pt %xcc, etrap_irq |
@@ -1304,8 +1408,10 @@ cheetah_deferred_trap: | |||
1304 | stxa %g4, [%g0] ASI_AFSR | 1408 | stxa %g4, [%g0] ASI_AFSR |
1305 | membar #Sync | 1409 | membar #Sync |
1306 | 1410 | ||
1307 | CHEETAH_LOG_ERROR | 1411 | ba,pt %xcc, __cheetah_log_error |
1412 | nop | ||
1308 | 1413 | ||
1414 | c_deferred: | ||
1309 | rdpr %pil, %g2 | 1415 | rdpr %pil, %g2 |
1310 | wrpr %g0, 15, %pil | 1416 | wrpr %g0, 15, %pil |
1311 | ba,pt %xcc, etrap_irq | 1417 | ba,pt %xcc, etrap_irq |
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S index 8104a56ca2d8..1fa06c4e3bdb 100644 --- a/arch/sparc64/kernel/head.S +++ b/arch/sparc64/kernel/head.S | |||
@@ -538,11 +538,12 @@ cheetah_tlb_fixup: | |||
538 | nop | 538 | nop |
539 | call cheetah_plus_patch_winfixup | 539 | call cheetah_plus_patch_winfixup |
540 | nop | 540 | nop |
541 | |||
542 | 541 | ||
543 | 2: /* Patch copy/page operations to cheetah optimized versions. */ | 542 | 2: /* Patch copy/page operations to cheetah optimized versions. */ |
544 | call cheetah_patch_copyops | 543 | call cheetah_patch_copyops |
545 | nop | 544 | nop |
545 | call cheetah_patch_copy_page | ||
546 | nop | ||
546 | call cheetah_patch_cachetlbops | 547 | call cheetah_patch_cachetlbops |
547 | nop | 548 | nop |
548 | 549 | ||
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c index bbf11f85dab1..0d66d07c8c6e 100644 --- a/arch/sparc64/kernel/kprobes.c +++ b/arch/sparc64/kernel/kprobes.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/kprobes.h> | 8 | #include <linux/kprobes.h> |
9 | #include <asm/kdebug.h> | 9 | #include <asm/kdebug.h> |
10 | #include <asm/signal.h> | 10 | #include <asm/signal.h> |
11 | #include <asm/cacheflush.h> | ||
11 | 12 | ||
12 | /* We do not have hardware single-stepping on sparc64. | 13 | /* We do not have hardware single-stepping on sparc64. |
13 | * So we implement software single-stepping with breakpoint | 14 | * So we implement software single-stepping with breakpoint |
@@ -37,31 +38,31 @@ | |||
37 | * - Mark that we are no longer actively in a kprobe. | 38 | * - Mark that we are no longer actively in a kprobe. |
38 | */ | 39 | */ |
39 | 40 | ||
40 | int arch_prepare_kprobe(struct kprobe *p) | 41 | int __kprobes arch_prepare_kprobe(struct kprobe *p) |
41 | { | 42 | { |
42 | return 0; | 43 | return 0; |
43 | } | 44 | } |
44 | 45 | ||
45 | void arch_copy_kprobe(struct kprobe *p) | 46 | void __kprobes arch_copy_kprobe(struct kprobe *p) |
46 | { | 47 | { |
47 | p->ainsn.insn[0] = *p->addr; | 48 | p->ainsn.insn[0] = *p->addr; |
48 | p->ainsn.insn[1] = BREAKPOINT_INSTRUCTION_2; | 49 | p->ainsn.insn[1] = BREAKPOINT_INSTRUCTION_2; |
49 | p->opcode = *p->addr; | 50 | p->opcode = *p->addr; |
50 | } | 51 | } |
51 | 52 | ||
52 | void arch_arm_kprobe(struct kprobe *p) | 53 | void __kprobes arch_arm_kprobe(struct kprobe *p) |
53 | { | 54 | { |
54 | *p->addr = BREAKPOINT_INSTRUCTION; | 55 | *p->addr = BREAKPOINT_INSTRUCTION; |
55 | flushi(p->addr); | 56 | flushi(p->addr); |
56 | } | 57 | } |
57 | 58 | ||
58 | void arch_disarm_kprobe(struct kprobe *p) | 59 | void __kprobes arch_disarm_kprobe(struct kprobe *p) |
59 | { | 60 | { |
60 | *p->addr = p->opcode; | 61 | *p->addr = p->opcode; |
61 | flushi(p->addr); | 62 | flushi(p->addr); |
62 | } | 63 | } |
63 | 64 | ||
64 | void arch_remove_kprobe(struct kprobe *p) | 65 | void __kprobes arch_remove_kprobe(struct kprobe *p) |
65 | { | 66 | { |
66 | } | 67 | } |
67 | 68 | ||
@@ -111,7 +112,7 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) | |||
111 | } | 112 | } |
112 | } | 113 | } |
113 | 114 | ||
114 | static int kprobe_handler(struct pt_regs *regs) | 115 | static int __kprobes kprobe_handler(struct pt_regs *regs) |
115 | { | 116 | { |
116 | struct kprobe *p; | 117 | struct kprobe *p; |
117 | void *addr = (void *) regs->tpc; | 118 | void *addr = (void *) regs->tpc; |
@@ -191,8 +192,9 @@ no_kprobe: | |||
191 | * The original INSN location was REAL_PC, it actually | 192 | * The original INSN location was REAL_PC, it actually |
192 | * executed at PC and produced destination address NPC. | 193 | * executed at PC and produced destination address NPC. |
193 | */ | 194 | */ |
194 | static unsigned long relbranch_fixup(u32 insn, unsigned long real_pc, | 195 | static unsigned long __kprobes relbranch_fixup(u32 insn, unsigned long real_pc, |
195 | unsigned long pc, unsigned long npc) | 196 | unsigned long pc, |
197 | unsigned long npc) | ||
196 | { | 198 | { |
197 | /* Branch not taken, no mods necessary. */ | 199 | /* Branch not taken, no mods necessary. */ |
198 | if (npc == pc + 0x4UL) | 200 | if (npc == pc + 0x4UL) |
@@ -217,7 +219,8 @@ static unsigned long relbranch_fixup(u32 insn, unsigned long real_pc, | |||
217 | /* If INSN is an instruction which writes it's PC location | 219 | /* If INSN is an instruction which writes it's PC location |
218 | * into a destination register, fix that up. | 220 | * into a destination register, fix that up. |
219 | */ | 221 | */ |
220 | static void retpc_fixup(struct pt_regs *regs, u32 insn, unsigned long real_pc) | 222 | static void __kprobes retpc_fixup(struct pt_regs *regs, u32 insn, |
223 | unsigned long real_pc) | ||
221 | { | 224 | { |
222 | unsigned long *slot = NULL; | 225 | unsigned long *slot = NULL; |
223 | 226 | ||
@@ -257,7 +260,7 @@ static void retpc_fixup(struct pt_regs *regs, u32 insn, unsigned long real_pc) | |||
257 | * This function prepares to return from the post-single-step | 260 | * This function prepares to return from the post-single-step |
258 | * breakpoint trap. | 261 | * breakpoint trap. |
259 | */ | 262 | */ |
260 | static void resume_execution(struct kprobe *p, struct pt_regs *regs) | 263 | static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) |
261 | { | 264 | { |
262 | u32 insn = p->ainsn.insn[0]; | 265 | u32 insn = p->ainsn.insn[0]; |
263 | 266 | ||
@@ -315,8 +318,8 @@ static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) | |||
315 | /* | 318 | /* |
316 | * Wrapper routine to for handling exceptions. | 319 | * Wrapper routine to for handling exceptions. |
317 | */ | 320 | */ |
318 | int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, | 321 | int __kprobes kprobe_exceptions_notify(struct notifier_block *self, |
319 | void *data) | 322 | unsigned long val, void *data) |
320 | { | 323 | { |
321 | struct die_args *args = (struct die_args *)data; | 324 | struct die_args *args = (struct die_args *)data; |
322 | switch (val) { | 325 | switch (val) { |
@@ -344,7 +347,8 @@ int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, | |||
344 | return NOTIFY_DONE; | 347 | return NOTIFY_DONE; |
345 | } | 348 | } |
346 | 349 | ||
347 | asmlinkage void kprobe_trap(unsigned long trap_level, struct pt_regs *regs) | 350 | asmlinkage void __kprobes kprobe_trap(unsigned long trap_level, |
351 | struct pt_regs *regs) | ||
348 | { | 352 | { |
349 | BUG_ON(trap_level != 0x170 && trap_level != 0x171); | 353 | BUG_ON(trap_level != 0x170 && trap_level != 0x171); |
350 | 354 | ||
@@ -368,7 +372,7 @@ static struct pt_regs jprobe_saved_regs; | |||
368 | static struct pt_regs *jprobe_saved_regs_location; | 372 | static struct pt_regs *jprobe_saved_regs_location; |
369 | static struct sparc_stackf jprobe_saved_stack; | 373 | static struct sparc_stackf jprobe_saved_stack; |
370 | 374 | ||
371 | int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | 375 | int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) |
372 | { | 376 | { |
373 | struct jprobe *jp = container_of(p, struct jprobe, kp); | 377 | struct jprobe *jp = container_of(p, struct jprobe, kp); |
374 | 378 | ||
@@ -390,7 +394,7 @@ int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | |||
390 | return 1; | 394 | return 1; |
391 | } | 395 | } |
392 | 396 | ||
393 | void jprobe_return(void) | 397 | void __kprobes jprobe_return(void) |
394 | { | 398 | { |
395 | preempt_enable_no_resched(); | 399 | preempt_enable_no_resched(); |
396 | __asm__ __volatile__( | 400 | __asm__ __volatile__( |
@@ -403,7 +407,7 @@ extern void jprobe_return_trap_instruction(void); | |||
403 | 407 | ||
404 | extern void __show_regs(struct pt_regs * regs); | 408 | extern void __show_regs(struct pt_regs * regs); |
405 | 409 | ||
406 | int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | 410 | int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) |
407 | { | 411 | { |
408 | u32 *addr = (u32 *) regs->tpc; | 412 | u32 *addr = (u32 *) regs->tpc; |
409 | 413 | ||
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index bba140d98b1b..2ff7c32ab0ce 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c | |||
@@ -359,134 +359,17 @@ void pcibios_fixup_bus(struct pci_bus *pbus) | |||
359 | pbus->resource[1] = &pbm->mem_space; | 359 | pbus->resource[1] = &pbm->mem_space; |
360 | } | 360 | } |
361 | 361 | ||
362 | int pci_claim_resource(struct pci_dev *pdev, int resource) | 362 | struct resource *pcibios_select_root(struct pci_dev *pdev, struct resource *r) |
363 | { | 363 | { |
364 | struct pci_pbm_info *pbm = pdev->bus->sysdata; | 364 | struct pci_pbm_info *pbm = pdev->bus->sysdata; |
365 | struct resource *res = &pdev->resource[resource]; | 365 | struct resource *root = NULL; |
366 | struct resource *root; | ||
367 | |||
368 | if (!pbm) | ||
369 | return -EINVAL; | ||
370 | 366 | ||
371 | if (res->flags & IORESOURCE_IO) | 367 | if (r->flags & IORESOURCE_IO) |
372 | root = &pbm->io_space; | 368 | root = &pbm->io_space; |
373 | else | 369 | if (r->flags & IORESOURCE_MEM) |
374 | root = &pbm->mem_space; | 370 | root = &pbm->mem_space; |
375 | 371 | ||
376 | pbm->parent->resource_adjust(pdev, res, root); | 372 | return root; |
377 | |||
378 | return request_resource(root, res); | ||
379 | } | ||
380 | |||
381 | /* | ||
382 | * Given the PCI bus a device resides on, try to | ||
383 | * find an acceptable resource allocation for a | ||
384 | * specific device resource.. | ||
385 | */ | ||
386 | static int pci_assign_bus_resource(const struct pci_bus *bus, | ||
387 | struct pci_dev *dev, | ||
388 | struct resource *res, | ||
389 | unsigned long size, | ||
390 | unsigned long min, | ||
391 | int resno) | ||
392 | { | ||
393 | unsigned int type_mask; | ||
394 | int i; | ||
395 | |||
396 | type_mask = IORESOURCE_IO | IORESOURCE_MEM; | ||
397 | for (i = 0 ; i < 4; i++) { | ||
398 | struct resource *r = bus->resource[i]; | ||
399 | if (!r) | ||
400 | continue; | ||
401 | |||
402 | /* type_mask must match */ | ||
403 | if ((res->flags ^ r->flags) & type_mask) | ||
404 | continue; | ||
405 | |||
406 | /* Ok, try it out.. */ | ||
407 | if (allocate_resource(r, res, size, min, -1, size, NULL, NULL) < 0) | ||
408 | continue; | ||
409 | |||
410 | /* PCI config space updated by caller. */ | ||
411 | return 0; | ||
412 | } | ||
413 | return -EBUSY; | ||
414 | } | ||
415 | |||
416 | int pci_assign_resource(struct pci_dev *pdev, int resource) | ||
417 | { | ||
418 | struct pcidev_cookie *pcp = pdev->sysdata; | ||
419 | struct pci_pbm_info *pbm = pcp->pbm; | ||
420 | struct resource *res = &pdev->resource[resource]; | ||
421 | unsigned long min, size; | ||
422 | int err; | ||
423 | |||
424 | if (res->flags & IORESOURCE_IO) | ||
425 | min = pbm->io_space.start + 0x400UL; | ||
426 | else | ||
427 | min = pbm->mem_space.start; | ||
428 | |||
429 | size = res->end - res->start + 1; | ||
430 | |||
431 | err = pci_assign_bus_resource(pdev->bus, pdev, res, size, min, resource); | ||
432 | |||
433 | if (err < 0) { | ||
434 | printk("PCI: Failed to allocate resource %d for %s\n", | ||
435 | resource, pci_name(pdev)); | ||
436 | } else { | ||
437 | /* Update PCI config space. */ | ||
438 | pbm->parent->base_address_update(pdev, resource); | ||
439 | } | ||
440 | |||
441 | return err; | ||
442 | } | ||
443 | |||
444 | /* Sort resources by alignment */ | ||
445 | void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) | ||
446 | { | ||
447 | int i; | ||
448 | |||
449 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | ||
450 | struct resource *r; | ||
451 | struct resource_list *list, *tmp; | ||
452 | unsigned long r_align; | ||
453 | |||
454 | r = &dev->resource[i]; | ||
455 | r_align = r->end - r->start; | ||
456 | |||
457 | if (!(r->flags) || r->parent) | ||
458 | continue; | ||
459 | if (!r_align) { | ||
460 | printk(KERN_WARNING "PCI: Ignore bogus resource %d " | ||
461 | "[%lx:%lx] of %s\n", | ||
462 | i, r->start, r->end, pci_name(dev)); | ||
463 | continue; | ||
464 | } | ||
465 | r_align = (i < PCI_BRIDGE_RESOURCES) ? r_align + 1 : r->start; | ||
466 | for (list = head; ; list = list->next) { | ||
467 | unsigned long align = 0; | ||
468 | struct resource_list *ln = list->next; | ||
469 | int idx; | ||
470 | |||
471 | if (ln) { | ||
472 | idx = ln->res - &ln->dev->resource[0]; | ||
473 | align = (idx < PCI_BRIDGE_RESOURCES) ? | ||
474 | ln->res->end - ln->res->start + 1 : | ||
475 | ln->res->start; | ||
476 | } | ||
477 | if (r_align > align) { | ||
478 | tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); | ||
479 | if (!tmp) | ||
480 | panic("pdev_sort_resources(): " | ||
481 | "kmalloc() failed!\n"); | ||
482 | tmp->next = ln; | ||
483 | tmp->res = r; | ||
484 | tmp->dev = dev; | ||
485 | list->next = tmp; | ||
486 | break; | ||
487 | } | ||
488 | } | ||
489 | } | ||
490 | } | 373 | } |
491 | 374 | ||
492 | void pcibios_update_irq(struct pci_dev *pdev, int irq) | 375 | void pcibios_update_irq(struct pci_dev *pdev, int irq) |
@@ -540,6 +423,7 @@ void pcibios_bus_to_resource(struct pci_dev *pdev, struct resource *res, | |||
540 | 423 | ||
541 | pbm->parent->resource_adjust(pdev, res, root); | 424 | pbm->parent->resource_adjust(pdev, res, root); |
542 | } | 425 | } |
426 | EXPORT_SYMBOL(pcibios_bus_to_resource); | ||
543 | 427 | ||
544 | char * __init pcibios_setup(char *str) | 428 | char * __init pcibios_setup(char *str) |
545 | { | 429 | { |
@@ -735,8 +619,7 @@ static void __pci_mmap_set_flags(struct pci_dev *dev, struct vm_area_struct *vma | |||
735 | static void __pci_mmap_set_pgprot(struct pci_dev *dev, struct vm_area_struct *vma, | 619 | static void __pci_mmap_set_pgprot(struct pci_dev *dev, struct vm_area_struct *vma, |
736 | enum pci_mmap_state mmap_state) | 620 | enum pci_mmap_state mmap_state) |
737 | { | 621 | { |
738 | /* Our io_remap_page_range/io_remap_pfn_range takes care of this, | 622 | /* Our io_remap_pfn_range takes care of this, do nothing. */ |
739 | do nothing. */ | ||
740 | } | 623 | } |
741 | 624 | ||
742 | /* Perform the actual remap of the pages for a PCI device mapping, as appropriate | 625 | /* Perform the actual remap of the pages for a PCI device mapping, as appropriate |
diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c index 2803bc7c2c79..425c60cfea19 100644 --- a/arch/sparc64/kernel/pci_iommu.c +++ b/arch/sparc64/kernel/pci_iommu.c | |||
@@ -466,7 +466,7 @@ do_flush_sync: | |||
466 | if (!limit) | 466 | if (!limit) |
467 | break; | 467 | break; |
468 | udelay(1); | 468 | udelay(1); |
469 | membar("#LoadLoad"); | 469 | rmb(); |
470 | } | 470 | } |
471 | if (!limit) | 471 | if (!limit) |
472 | printk(KERN_WARNING "pci_strbuf_flush: flushflag timeout " | 472 | printk(KERN_WARNING "pci_strbuf_flush: flushflag timeout " |
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 91ab466d6c66..6ed1ef25e0ac 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c | |||
@@ -307,7 +307,7 @@ static unsigned char psycho_pil_table[] = { | |||
307 | /*0x32*/15, /* Power Management */ | 307 | /*0x32*/15, /* Power Management */ |
308 | }; | 308 | }; |
309 | 309 | ||
310 | static int __init psycho_ino_to_pil(struct pci_dev *pdev, unsigned int ino) | 310 | static int psycho_ino_to_pil(struct pci_dev *pdev, unsigned int ino) |
311 | { | 311 | { |
312 | int ret; | 312 | int ret; |
313 | 313 | ||
@@ -344,9 +344,9 @@ static int __init psycho_ino_to_pil(struct pci_dev *pdev, unsigned int ino) | |||
344 | return ret; | 344 | return ret; |
345 | } | 345 | } |
346 | 346 | ||
347 | static unsigned int __init psycho_irq_build(struct pci_pbm_info *pbm, | 347 | static unsigned int psycho_irq_build(struct pci_pbm_info *pbm, |
348 | struct pci_dev *pdev, | 348 | struct pci_dev *pdev, |
349 | unsigned int ino) | 349 | unsigned int ino) |
350 | { | 350 | { |
351 | struct ino_bucket *bucket; | 351 | struct ino_bucket *bucket; |
352 | unsigned long imap, iclr; | 352 | unsigned long imap, iclr; |
@@ -1024,7 +1024,7 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id, struct pt_regs *reg | |||
1024 | #define PSYCHO_CE_INO 0x2f | 1024 | #define PSYCHO_CE_INO 0x2f |
1025 | #define PSYCHO_PCIERR_A_INO 0x30 | 1025 | #define PSYCHO_PCIERR_A_INO 0x30 |
1026 | #define PSYCHO_PCIERR_B_INO 0x31 | 1026 | #define PSYCHO_PCIERR_B_INO 0x31 |
1027 | static void __init psycho_register_error_handlers(struct pci_controller_info *p) | 1027 | static void psycho_register_error_handlers(struct pci_controller_info *p) |
1028 | { | 1028 | { |
1029 | struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */ | 1029 | struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */ |
1030 | unsigned long base = p->pbm_A.controller_regs; | 1030 | unsigned long base = p->pbm_A.controller_regs; |
@@ -1091,15 +1091,15 @@ static void __init psycho_register_error_handlers(struct pci_controller_info *p) | |||
1091 | } | 1091 | } |
1092 | 1092 | ||
1093 | /* PSYCHO boot time probing and initialization. */ | 1093 | /* PSYCHO boot time probing and initialization. */ |
1094 | static void __init psycho_resource_adjust(struct pci_dev *pdev, | 1094 | static void psycho_resource_adjust(struct pci_dev *pdev, |
1095 | struct resource *res, | 1095 | struct resource *res, |
1096 | struct resource *root) | 1096 | struct resource *root) |
1097 | { | 1097 | { |
1098 | res->start += root->start; | 1098 | res->start += root->start; |
1099 | res->end += root->start; | 1099 | res->end += root->start; |
1100 | } | 1100 | } |
1101 | 1101 | ||
1102 | static void __init psycho_base_address_update(struct pci_dev *pdev, int resource) | 1102 | static void psycho_base_address_update(struct pci_dev *pdev, int resource) |
1103 | { | 1103 | { |
1104 | struct pcidev_cookie *pcp = pdev->sysdata; | 1104 | struct pcidev_cookie *pcp = pdev->sysdata; |
1105 | struct pci_pbm_info *pbm = pcp->pbm; | 1105 | struct pci_pbm_info *pbm = pcp->pbm; |
@@ -1144,7 +1144,7 @@ static void __init psycho_base_address_update(struct pci_dev *pdev, int resource | |||
1144 | pci_write_config_dword(pdev, where + 4, 0); | 1144 | pci_write_config_dword(pdev, where + 4, 0); |
1145 | } | 1145 | } |
1146 | 1146 | ||
1147 | static void __init pbm_config_busmastering(struct pci_pbm_info *pbm) | 1147 | static void pbm_config_busmastering(struct pci_pbm_info *pbm) |
1148 | { | 1148 | { |
1149 | u8 *addr; | 1149 | u8 *addr; |
1150 | 1150 | ||
@@ -1161,8 +1161,8 @@ static void __init pbm_config_busmastering(struct pci_pbm_info *pbm) | |||
1161 | pci_config_write8(addr, 64); | 1161 | pci_config_write8(addr, 64); |
1162 | } | 1162 | } |
1163 | 1163 | ||
1164 | static void __init pbm_scan_bus(struct pci_controller_info *p, | 1164 | static void pbm_scan_bus(struct pci_controller_info *p, |
1165 | struct pci_pbm_info *pbm) | 1165 | struct pci_pbm_info *pbm) |
1166 | { | 1166 | { |
1167 | struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL); | 1167 | struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL); |
1168 | 1168 | ||
@@ -1189,7 +1189,7 @@ static void __init pbm_scan_bus(struct pci_controller_info *p, | |||
1189 | pci_setup_busmastering(pbm, pbm->pci_bus); | 1189 | pci_setup_busmastering(pbm, pbm->pci_bus); |
1190 | } | 1190 | } |
1191 | 1191 | ||
1192 | static void __init psycho_scan_bus(struct pci_controller_info *p) | 1192 | static void psycho_scan_bus(struct pci_controller_info *p) |
1193 | { | 1193 | { |
1194 | pbm_config_busmastering(&p->pbm_B); | 1194 | pbm_config_busmastering(&p->pbm_B); |
1195 | p->pbm_B.is_66mhz_capable = 0; | 1195 | p->pbm_B.is_66mhz_capable = 0; |
@@ -1204,7 +1204,7 @@ static void __init psycho_scan_bus(struct pci_controller_info *p) | |||
1204 | psycho_register_error_handlers(p); | 1204 | psycho_register_error_handlers(p); |
1205 | } | 1205 | } |
1206 | 1206 | ||
1207 | static void __init psycho_iommu_init(struct pci_controller_info *p) | 1207 | static void psycho_iommu_init(struct pci_controller_info *p) |
1208 | { | 1208 | { |
1209 | struct pci_iommu *iommu = p->pbm_A.iommu; | 1209 | struct pci_iommu *iommu = p->pbm_A.iommu; |
1210 | unsigned long tsbbase, i; | 1210 | unsigned long tsbbase, i; |
@@ -1327,8 +1327,8 @@ static void psycho_controller_hwinit(struct pci_controller_info *p) | |||
1327 | psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIB_DIAG, tmp); | 1327 | psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIB_DIAG, tmp); |
1328 | } | 1328 | } |
1329 | 1329 | ||
1330 | static void __init pbm_register_toplevel_resources(struct pci_controller_info *p, | 1330 | static void pbm_register_toplevel_resources(struct pci_controller_info *p, |
1331 | struct pci_pbm_info *pbm) | 1331 | struct pci_pbm_info *pbm) |
1332 | { | 1332 | { |
1333 | char *name = pbm->name; | 1333 | char *name = pbm->name; |
1334 | 1334 | ||
@@ -1481,7 +1481,7 @@ static void psycho_pbm_init(struct pci_controller_info *p, | |||
1481 | 1481 | ||
1482 | #define PSYCHO_CONFIGSPACE 0x001000000UL | 1482 | #define PSYCHO_CONFIGSPACE 0x001000000UL |
1483 | 1483 | ||
1484 | void __init psycho_init(int node, char *model_name) | 1484 | void psycho_init(int node, char *model_name) |
1485 | { | 1485 | { |
1486 | struct linux_prom64_registers pr_regs[3]; | 1486 | struct linux_prom64_registers pr_regs[3]; |
1487 | struct pci_controller_info *p; | 1487 | struct pci_controller_info *p; |
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 52bf3431a422..0ee6bd5b9ac6 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c | |||
@@ -554,7 +554,7 @@ static unsigned char sabre_pil_table[] = { | |||
554 | /*0x32*/15, /* Power Management */ | 554 | /*0x32*/15, /* Power Management */ |
555 | }; | 555 | }; |
556 | 556 | ||
557 | static int __init sabre_ino_to_pil(struct pci_dev *pdev, unsigned int ino) | 557 | static int sabre_ino_to_pil(struct pci_dev *pdev, unsigned int ino) |
558 | { | 558 | { |
559 | int ret; | 559 | int ret; |
560 | 560 | ||
@@ -612,9 +612,9 @@ static void sabre_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_a | |||
612 | sabre_read(sync_reg); | 612 | sabre_read(sync_reg); |
613 | } | 613 | } |
614 | 614 | ||
615 | static unsigned int __init sabre_irq_build(struct pci_pbm_info *pbm, | 615 | static unsigned int sabre_irq_build(struct pci_pbm_info *pbm, |
616 | struct pci_dev *pdev, | 616 | struct pci_dev *pdev, |
617 | unsigned int ino) | 617 | unsigned int ino) |
618 | { | 618 | { |
619 | struct ino_bucket *bucket; | 619 | struct ino_bucket *bucket; |
620 | unsigned long imap, iclr; | 620 | unsigned long imap, iclr; |
@@ -1009,7 +1009,7 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs | |||
1009 | #define SABRE_UE_INO 0x2e | 1009 | #define SABRE_UE_INO 0x2e |
1010 | #define SABRE_CE_INO 0x2f | 1010 | #define SABRE_CE_INO 0x2f |
1011 | #define SABRE_PCIERR_INO 0x30 | 1011 | #define SABRE_PCIERR_INO 0x30 |
1012 | static void __init sabre_register_error_handlers(struct pci_controller_info *p) | 1012 | static void sabre_register_error_handlers(struct pci_controller_info *p) |
1013 | { | 1013 | { |
1014 | struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */ | 1014 | struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */ |
1015 | unsigned long base = pbm->controller_regs; | 1015 | unsigned long base = pbm->controller_regs; |
@@ -1056,9 +1056,9 @@ static void __init sabre_register_error_handlers(struct pci_controller_info *p) | |||
1056 | sabre_write(base + SABRE_PCICTRL, tmp); | 1056 | sabre_write(base + SABRE_PCICTRL, tmp); |
1057 | } | 1057 | } |
1058 | 1058 | ||
1059 | static void __init sabre_resource_adjust(struct pci_dev *pdev, | 1059 | static void sabre_resource_adjust(struct pci_dev *pdev, |
1060 | struct resource *res, | 1060 | struct resource *res, |
1061 | struct resource *root) | 1061 | struct resource *root) |
1062 | { | 1062 | { |
1063 | struct pci_pbm_info *pbm = pdev->bus->sysdata; | 1063 | struct pci_pbm_info *pbm = pdev->bus->sysdata; |
1064 | unsigned long base; | 1064 | unsigned long base; |
@@ -1072,7 +1072,7 @@ static void __init sabre_resource_adjust(struct pci_dev *pdev, | |||
1072 | res->end += base; | 1072 | res->end += base; |
1073 | } | 1073 | } |
1074 | 1074 | ||
1075 | static void __init sabre_base_address_update(struct pci_dev *pdev, int resource) | 1075 | static void sabre_base_address_update(struct pci_dev *pdev, int resource) |
1076 | { | 1076 | { |
1077 | struct pcidev_cookie *pcp = pdev->sysdata; | 1077 | struct pcidev_cookie *pcp = pdev->sysdata; |
1078 | struct pci_pbm_info *pbm = pcp->pbm; | 1078 | struct pci_pbm_info *pbm = pcp->pbm; |
@@ -1118,7 +1118,7 @@ static void __init sabre_base_address_update(struct pci_dev *pdev, int resource) | |||
1118 | pci_write_config_dword(pdev, where + 4, 0); | 1118 | pci_write_config_dword(pdev, where + 4, 0); |
1119 | } | 1119 | } |
1120 | 1120 | ||
1121 | static void __init apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus) | 1121 | static void apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus) |
1122 | { | 1122 | { |
1123 | struct pci_dev *pdev; | 1123 | struct pci_dev *pdev; |
1124 | 1124 | ||
@@ -1181,7 +1181,7 @@ static struct pcidev_cookie *alloc_bridge_cookie(struct pci_pbm_info *pbm) | |||
1181 | return cookie; | 1181 | return cookie; |
1182 | } | 1182 | } |
1183 | 1183 | ||
1184 | static void __init sabre_scan_bus(struct pci_controller_info *p) | 1184 | static void sabre_scan_bus(struct pci_controller_info *p) |
1185 | { | 1185 | { |
1186 | static int once; | 1186 | static int once; |
1187 | struct pci_bus *sabre_bus, *pbus; | 1187 | struct pci_bus *sabre_bus, *pbus; |
@@ -1262,9 +1262,9 @@ static void __init sabre_scan_bus(struct pci_controller_info *p) | |||
1262 | sabre_register_error_handlers(p); | 1262 | sabre_register_error_handlers(p); |
1263 | } | 1263 | } |
1264 | 1264 | ||
1265 | static void __init sabre_iommu_init(struct pci_controller_info *p, | 1265 | static void sabre_iommu_init(struct pci_controller_info *p, |
1266 | int tsbsize, unsigned long dvma_offset, | 1266 | int tsbsize, unsigned long dvma_offset, |
1267 | u32 dma_mask) | 1267 | u32 dma_mask) |
1268 | { | 1268 | { |
1269 | struct pci_iommu *iommu = p->pbm_A.iommu; | 1269 | struct pci_iommu *iommu = p->pbm_A.iommu; |
1270 | unsigned long tsbbase, i, order; | 1270 | unsigned long tsbbase, i, order; |
@@ -1345,8 +1345,8 @@ static void __init sabre_iommu_init(struct pci_controller_info *p, | |||
1345 | } | 1345 | } |
1346 | } | 1346 | } |
1347 | 1347 | ||
1348 | static void __init pbm_register_toplevel_resources(struct pci_controller_info *p, | 1348 | static void pbm_register_toplevel_resources(struct pci_controller_info *p, |
1349 | struct pci_pbm_info *pbm) | 1349 | struct pci_pbm_info *pbm) |
1350 | { | 1350 | { |
1351 | char *name = pbm->name; | 1351 | char *name = pbm->name; |
1352 | unsigned long ibase = p->pbm_A.controller_regs + SABRE_IOSPACE; | 1352 | unsigned long ibase = p->pbm_A.controller_regs + SABRE_IOSPACE; |
@@ -1415,7 +1415,7 @@ static void __init pbm_register_toplevel_resources(struct pci_controller_info *p | |||
1415 | &pbm->mem_space); | 1415 | &pbm->mem_space); |
1416 | } | 1416 | } |
1417 | 1417 | ||
1418 | static void __init sabre_pbm_init(struct pci_controller_info *p, int sabre_node, u32 dma_begin) | 1418 | static void sabre_pbm_init(struct pci_controller_info *p, int sabre_node, u32 dma_begin) |
1419 | { | 1419 | { |
1420 | struct pci_pbm_info *pbm; | 1420 | struct pci_pbm_info *pbm; |
1421 | char namebuf[128]; | 1421 | char namebuf[128]; |
@@ -1552,7 +1552,7 @@ static void __init sabre_pbm_init(struct pci_controller_info *p, int sabre_node, | |||
1552 | } | 1552 | } |
1553 | } | 1553 | } |
1554 | 1554 | ||
1555 | void __init sabre_init(int pnode, char *model_name) | 1555 | void sabre_init(int pnode, char *model_name) |
1556 | { | 1556 | { |
1557 | struct linux_prom64_registers pr_regs[2]; | 1557 | struct linux_prom64_registers pr_regs[2]; |
1558 | struct pci_controller_info *p; | 1558 | struct pci_controller_info *p; |
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 6a182bb66281..331382e1a75d 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c | |||
@@ -285,7 +285,7 @@ static unsigned char schizo_pil_table[] = { | |||
285 | /*0x3f*/0, /* Reserved for NewLink */ | 285 | /*0x3f*/0, /* Reserved for NewLink */ |
286 | }; | 286 | }; |
287 | 287 | ||
288 | static int __init schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino) | 288 | static int schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino) |
289 | { | 289 | { |
290 | int ret; | 290 | int ret; |
291 | 291 | ||
@@ -1221,7 +1221,7 @@ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id, struct pt_regs * | |||
1221 | * PCI bus units of the same Tomatillo. I still have not really | 1221 | * PCI bus units of the same Tomatillo. I still have not really |
1222 | * figured this out... | 1222 | * figured this out... |
1223 | */ | 1223 | */ |
1224 | static void __init tomatillo_register_error_handlers(struct pci_controller_info *p) | 1224 | static void tomatillo_register_error_handlers(struct pci_controller_info *p) |
1225 | { | 1225 | { |
1226 | struct pci_pbm_info *pbm; | 1226 | struct pci_pbm_info *pbm; |
1227 | unsigned int irq; | 1227 | unsigned int irq; |
@@ -1359,7 +1359,7 @@ static void __init tomatillo_register_error_handlers(struct pci_controller_info | |||
1359 | (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP))); | 1359 | (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP))); |
1360 | } | 1360 | } |
1361 | 1361 | ||
1362 | static void __init schizo_register_error_handlers(struct pci_controller_info *p) | 1362 | static void schizo_register_error_handlers(struct pci_controller_info *p) |
1363 | { | 1363 | { |
1364 | struct pci_pbm_info *pbm; | 1364 | struct pci_pbm_info *pbm; |
1365 | unsigned int irq; | 1365 | unsigned int irq; |
@@ -1505,7 +1505,7 @@ static void __init schizo_register_error_handlers(struct pci_controller_info *p) | |||
1505 | (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP))); | 1505 | (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP))); |
1506 | } | 1506 | } |
1507 | 1507 | ||
1508 | static void __init pbm_config_busmastering(struct pci_pbm_info *pbm) | 1508 | static void pbm_config_busmastering(struct pci_pbm_info *pbm) |
1509 | { | 1509 | { |
1510 | u8 *addr; | 1510 | u8 *addr; |
1511 | 1511 | ||
@@ -1522,8 +1522,8 @@ static void __init pbm_config_busmastering(struct pci_pbm_info *pbm) | |||
1522 | pci_config_write8(addr, 64); | 1522 | pci_config_write8(addr, 64); |
1523 | } | 1523 | } |
1524 | 1524 | ||
1525 | static void __init pbm_scan_bus(struct pci_controller_info *p, | 1525 | static void pbm_scan_bus(struct pci_controller_info *p, |
1526 | struct pci_pbm_info *pbm) | 1526 | struct pci_pbm_info *pbm) |
1527 | { | 1527 | { |
1528 | struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL); | 1528 | struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL); |
1529 | 1529 | ||
@@ -1550,8 +1550,8 @@ static void __init pbm_scan_bus(struct pci_controller_info *p, | |||
1550 | pci_setup_busmastering(pbm, pbm->pci_bus); | 1550 | pci_setup_busmastering(pbm, pbm->pci_bus); |
1551 | } | 1551 | } |
1552 | 1552 | ||
1553 | static void __init __schizo_scan_bus(struct pci_controller_info *p, | 1553 | static void __schizo_scan_bus(struct pci_controller_info *p, |
1554 | int chip_type) | 1554 | int chip_type) |
1555 | { | 1555 | { |
1556 | if (!p->pbm_B.prom_node || !p->pbm_A.prom_node) { | 1556 | if (!p->pbm_B.prom_node || !p->pbm_A.prom_node) { |
1557 | printk("PCI: Only one PCI bus module of controller found.\n"); | 1557 | printk("PCI: Only one PCI bus module of controller found.\n"); |
@@ -1577,17 +1577,17 @@ static void __init __schizo_scan_bus(struct pci_controller_info *p, | |||
1577 | schizo_register_error_handlers(p); | 1577 | schizo_register_error_handlers(p); |
1578 | } | 1578 | } |
1579 | 1579 | ||
1580 | static void __init schizo_scan_bus(struct pci_controller_info *p) | 1580 | static void schizo_scan_bus(struct pci_controller_info *p) |
1581 | { | 1581 | { |
1582 | __schizo_scan_bus(p, PBM_CHIP_TYPE_SCHIZO); | 1582 | __schizo_scan_bus(p, PBM_CHIP_TYPE_SCHIZO); |
1583 | } | 1583 | } |
1584 | 1584 | ||
1585 | static void __init tomatillo_scan_bus(struct pci_controller_info *p) | 1585 | static void tomatillo_scan_bus(struct pci_controller_info *p) |
1586 | { | 1586 | { |
1587 | __schizo_scan_bus(p, PBM_CHIP_TYPE_TOMATILLO); | 1587 | __schizo_scan_bus(p, PBM_CHIP_TYPE_TOMATILLO); |
1588 | } | 1588 | } |
1589 | 1589 | ||
1590 | static void __init schizo_base_address_update(struct pci_dev *pdev, int resource) | 1590 | static void schizo_base_address_update(struct pci_dev *pdev, int resource) |
1591 | { | 1591 | { |
1592 | struct pcidev_cookie *pcp = pdev->sysdata; | 1592 | struct pcidev_cookie *pcp = pdev->sysdata; |
1593 | struct pci_pbm_info *pbm = pcp->pbm; | 1593 | struct pci_pbm_info *pbm = pcp->pbm; |
@@ -1632,9 +1632,9 @@ static void __init schizo_base_address_update(struct pci_dev *pdev, int resource | |||
1632 | pci_write_config_dword(pdev, where + 4, 0); | 1632 | pci_write_config_dword(pdev, where + 4, 0); |
1633 | } | 1633 | } |
1634 | 1634 | ||
1635 | static void __init schizo_resource_adjust(struct pci_dev *pdev, | 1635 | static void schizo_resource_adjust(struct pci_dev *pdev, |
1636 | struct resource *res, | 1636 | struct resource *res, |
1637 | struct resource *root) | 1637 | struct resource *root) |
1638 | { | 1638 | { |
1639 | res->start += root->start; | 1639 | res->start += root->start; |
1640 | res->end += root->start; | 1640 | res->end += root->start; |
@@ -1702,8 +1702,8 @@ static void schizo_determine_mem_io_space(struct pci_pbm_info *pbm) | |||
1702 | pbm->mem_space.start); | 1702 | pbm->mem_space.start); |
1703 | } | 1703 | } |
1704 | 1704 | ||
1705 | static void __init pbm_register_toplevel_resources(struct pci_controller_info *p, | 1705 | static void pbm_register_toplevel_resources(struct pci_controller_info *p, |
1706 | struct pci_pbm_info *pbm) | 1706 | struct pci_pbm_info *pbm) |
1707 | { | 1707 | { |
1708 | pbm->io_space.name = pbm->mem_space.name = pbm->name; | 1708 | pbm->io_space.name = pbm->mem_space.name = pbm->name; |
1709 | 1709 | ||
@@ -1932,7 +1932,7 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm) | |||
1932 | #define TOMATILLO_PCI_IOC_TDIAG (0x2250UL) | 1932 | #define TOMATILLO_PCI_IOC_TDIAG (0x2250UL) |
1933 | #define TOMATILLO_PCI_IOC_DDIAG (0x2290UL) | 1933 | #define TOMATILLO_PCI_IOC_DDIAG (0x2290UL) |
1934 | 1934 | ||
1935 | static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm) | 1935 | static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) |
1936 | { | 1936 | { |
1937 | u64 tmp; | 1937 | u64 tmp; |
1938 | 1938 | ||
@@ -1986,9 +1986,9 @@ static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm) | |||
1986 | } | 1986 | } |
1987 | } | 1987 | } |
1988 | 1988 | ||
1989 | static void __init schizo_pbm_init(struct pci_controller_info *p, | 1989 | static void schizo_pbm_init(struct pci_controller_info *p, |
1990 | int prom_node, u32 portid, | 1990 | int prom_node, u32 portid, |
1991 | int chip_type) | 1991 | int chip_type) |
1992 | { | 1992 | { |
1993 | struct linux_prom64_registers pr_regs[4]; | 1993 | struct linux_prom64_registers pr_regs[4]; |
1994 | unsigned int busrange[2]; | 1994 | unsigned int busrange[2]; |
@@ -2145,7 +2145,7 @@ static inline int portid_compare(u32 x, u32 y, int chip_type) | |||
2145 | return (x == y); | 2145 | return (x == y); |
2146 | } | 2146 | } |
2147 | 2147 | ||
2148 | static void __init __schizo_init(int node, char *model_name, int chip_type) | 2148 | static void __schizo_init(int node, char *model_name, int chip_type) |
2149 | { | 2149 | { |
2150 | struct pci_controller_info *p; | 2150 | struct pci_controller_info *p; |
2151 | struct pci_iommu *iommu; | 2151 | struct pci_iommu *iommu; |
@@ -2213,17 +2213,17 @@ static void __init __schizo_init(int node, char *model_name, int chip_type) | |||
2213 | schizo_pbm_init(p, node, portid, chip_type); | 2213 | schizo_pbm_init(p, node, portid, chip_type); |
2214 | } | 2214 | } |
2215 | 2215 | ||
2216 | void __init schizo_init(int node, char *model_name) | 2216 | void schizo_init(int node, char *model_name) |
2217 | { | 2217 | { |
2218 | __schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO); | 2218 | __schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO); |
2219 | } | 2219 | } |
2220 | 2220 | ||
2221 | void __init schizo_plus_init(int node, char *model_name) | 2221 | void schizo_plus_init(int node, char *model_name) |
2222 | { | 2222 | { |
2223 | __schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO_PLUS); | 2223 | __schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO_PLUS); |
2224 | } | 2224 | } |
2225 | 2225 | ||
2226 | void __init tomatillo_init(int node, char *model_name) | 2226 | void tomatillo_init(int node, char *model_name) |
2227 | { | 2227 | { |
2228 | __schizo_init(node, model_name, PBM_CHIP_TYPE_TOMATILLO); | 2228 | __schizo_init(node, model_name, PBM_CHIP_TYPE_TOMATILLO); |
2229 | } | 2229 | } |
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index 07424b075938..7d10b0397091 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c | |||
@@ -103,7 +103,7 @@ void cpu_idle(void) | |||
103 | * other cpus see our increasing idleness for the buddy | 103 | * other cpus see our increasing idleness for the buddy |
104 | * redistribution algorithm. -DaveM | 104 | * redistribution algorithm. -DaveM |
105 | */ | 105 | */ |
106 | membar("#StoreStore | #StoreLoad"); | 106 | membar_storeload_storestore(); |
107 | } | 107 | } |
108 | } | 108 | } |
109 | 109 | ||
@@ -607,11 +607,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, | |||
607 | struct thread_info *t = p->thread_info; | 607 | struct thread_info *t = p->thread_info; |
608 | char *child_trap_frame; | 608 | char *child_trap_frame; |
609 | 609 | ||
610 | #ifdef CONFIG_DEBUG_SPINLOCK | ||
611 | p->thread.smp_lock_count = 0; | ||
612 | p->thread.smp_lock_pc = 0; | ||
613 | #endif | ||
614 | |||
615 | /* Calculate offset to stack_frame & pt_regs */ | 610 | /* Calculate offset to stack_frame & pt_regs */ |
616 | child_trap_frame = ((char *)t) + (THREAD_SIZE - (TRACEREG_SZ+STACKFRAME_SZ)); | 611 | child_trap_frame = ((char *)t) + (THREAD_SIZE - (TRACEREG_SZ+STACKFRAME_SZ)); |
617 | memcpy(child_trap_frame, (((struct sparc_stackf *)regs)-1), (TRACEREG_SZ+STACKFRAME_SZ)); | 612 | memcpy(child_trap_frame, (((struct sparc_stackf *)regs)-1), (TRACEREG_SZ+STACKFRAME_SZ)); |
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S index 0696ed4b9d64..fafd227735fa 100644 --- a/arch/sparc64/kernel/rtrap.S +++ b/arch/sparc64/kernel/rtrap.S | |||
@@ -153,11 +153,14 @@ __handle_signal: | |||
153 | rtrap_irq: | 153 | rtrap_irq: |
154 | rtrap_clr_l6: clr %l6 | 154 | rtrap_clr_l6: clr %l6 |
155 | rtrap: | 155 | rtrap: |
156 | ldub [%g6 + TI_CPU], %l0 | 156 | #ifndef CONFIG_SMP |
157 | sethi %hi(irq_stat), %l2 ! &softirq_active | 157 | sethi %hi(per_cpu____cpu_data), %l0 |
158 | or %l2, %lo(irq_stat), %l2 ! &softirq_active | 158 | lduw [%l0 + %lo(per_cpu____cpu_data)], %l1 |
159 | irqsz_patchme: sllx %l0, 0, %l0 | 159 | #else |
160 | lduw [%l2 + %l0], %l1 ! softirq_pending | 160 | sethi %hi(per_cpu____cpu_data), %l0 |
161 | or %l0, %lo(per_cpu____cpu_data), %l0 | ||
162 | lduw [%l0 + %g5], %l1 | ||
163 | #endif | ||
161 | cmp %l1, 0 | 164 | cmp %l1, 0 |
162 | 165 | ||
163 | /* mm/ultra.S:xcall_report_regs KNOWS about this load. */ | 166 | /* mm/ultra.S:xcall_report_regs KNOWS about this load. */ |
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c index 89f5e019f24c..e09ddf927655 100644 --- a/arch/sparc64/kernel/sbus.c +++ b/arch/sparc64/kernel/sbus.c | |||
@@ -147,7 +147,7 @@ static void sbus_strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long | |||
147 | if (!limit) | 147 | if (!limit) |
148 | break; | 148 | break; |
149 | udelay(1); | 149 | udelay(1); |
150 | membar("#LoadLoad"); | 150 | rmb(); |
151 | } | 151 | } |
152 | if (!limit) | 152 | if (!limit) |
153 | printk(KERN_WARNING "sbus_strbuf_flush: flushflag timeout " | 153 | printk(KERN_WARNING "sbus_strbuf_flush: flushflag timeout " |
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index b7e6a91952b2..ddbed3341a23 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/cpu.h> | 33 | #include <linux/cpu.h> |
34 | #include <linux/initrd.h> | 34 | #include <linux/initrd.h> |
35 | 35 | ||
36 | #include <asm/segment.h> | ||
37 | #include <asm/system.h> | 36 | #include <asm/system.h> |
38 | #include <asm/io.h> | 37 | #include <asm/io.h> |
39 | #include <asm/processor.h> | 38 | #include <asm/processor.h> |
@@ -512,18 +511,6 @@ void __init setup_arch(char **cmdline_p) | |||
512 | conswitchp = &prom_con; | 511 | conswitchp = &prom_con; |
513 | #endif | 512 | #endif |
514 | 513 | ||
515 | #ifdef CONFIG_SMP | ||
516 | i = (unsigned long)&irq_stat[1] - (unsigned long)&irq_stat[0]; | ||
517 | if ((i == SMP_CACHE_BYTES) || (i == (2 * SMP_CACHE_BYTES))) { | ||
518 | extern unsigned int irqsz_patchme[1]; | ||
519 | irqsz_patchme[0] |= ((i == SMP_CACHE_BYTES) ? SMP_CACHE_BYTES_SHIFT : \ | ||
520 | SMP_CACHE_BYTES_SHIFT + 1); | ||
521 | flushi((long)&irqsz_patchme[0]); | ||
522 | } else { | ||
523 | prom_printf("Unexpected size of irq_stat[] elements\n"); | ||
524 | prom_halt(); | ||
525 | } | ||
526 | #endif | ||
527 | /* Work out if we are starfire early on */ | 514 | /* Work out if we are starfire early on */ |
528 | check_if_starfire(); | 515 | check_if_starfire(); |
529 | 516 | ||
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index b27934671c35..60f5dfabb1e1 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c | |||
@@ -574,13 +574,12 @@ static inline void handle_signal(unsigned long signr, struct k_sigaction *ka, | |||
574 | { | 574 | { |
575 | setup_rt_frame(ka, regs, signr, oldset, | 575 | setup_rt_frame(ka, regs, signr, oldset, |
576 | (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); | 576 | (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); |
577 | if (!(ka->sa.sa_flags & SA_NOMASK)) { | 577 | spin_lock_irq(¤t->sighand->siglock); |
578 | spin_lock_irq(¤t->sighand->siglock); | 578 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
579 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 579 | if (!(ka->sa.sa_flags & SA_NOMASK)) |
580 | sigaddset(¤t->blocked,signr); | 580 | sigaddset(¤t->blocked,signr); |
581 | recalc_sigpending(); | 581 | recalc_sigpending(); |
582 | spin_unlock_irq(¤t->sighand->siglock); | 582 | spin_unlock_irq(¤t->sighand->siglock); |
583 | } | ||
584 | } | 583 | } |
585 | 584 | ||
586 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, | 585 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, |
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index f28428f4170e..aecccd0df1d1 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c | |||
@@ -877,11 +877,12 @@ static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
877 | unsigned long page = (unsigned long) | 877 | unsigned long page = (unsigned long) |
878 | page_address(pte_page(*ptep)); | 878 | page_address(pte_page(*ptep)); |
879 | 879 | ||
880 | __asm__ __volatile__( | 880 | wmb(); |
881 | " membar #StoreStore\n" | 881 | __asm__ __volatile__("flush %0 + %1" |
882 | " flush %0 + %1" | 882 | : /* no outputs */ |
883 | : : "r" (page), "r" (address & (PAGE_SIZE - 1)) | 883 | : "r" (page), |
884 | : "memory"); | 884 | "r" (address & (PAGE_SIZE - 1)) |
885 | : "memory"); | ||
885 | } | 886 | } |
886 | pte_unmap(ptep); | 887 | pte_unmap(ptep); |
887 | preempt_enable(); | 888 | preempt_enable(); |
@@ -1292,11 +1293,12 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
1292 | unsigned long page = (unsigned long) | 1293 | unsigned long page = (unsigned long) |
1293 | page_address(pte_page(*ptep)); | 1294 | page_address(pte_page(*ptep)); |
1294 | 1295 | ||
1295 | __asm__ __volatile__( | 1296 | wmb(); |
1296 | " membar #StoreStore\n" | 1297 | __asm__ __volatile__("flush %0 + %1" |
1297 | " flush %0 + %1" | 1298 | : /* no outputs */ |
1298 | : : "r" (page), "r" (address & (PAGE_SIZE - 1)) | 1299 | : "r" (page), |
1299 | : "memory"); | 1300 | "r" (address & (PAGE_SIZE - 1)) |
1301 | : "memory"); | ||
1300 | } | 1302 | } |
1301 | pte_unmap(ptep); | 1303 | pte_unmap(ptep); |
1302 | preempt_enable(); | 1304 | preempt_enable(); |
@@ -1325,13 +1327,12 @@ static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, | |||
1325 | else | 1327 | else |
1326 | setup_frame32(&ka->sa, regs, signr, oldset, info); | 1328 | setup_frame32(&ka->sa, regs, signr, oldset, info); |
1327 | } | 1329 | } |
1328 | if (!(ka->sa.sa_flags & SA_NOMASK)) { | 1330 | spin_lock_irq(¤t->sighand->siglock); |
1329 | spin_lock_irq(¤t->sighand->siglock); | 1331 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
1330 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 1332 | if (!(ka->sa.sa_flags & SA_NOMASK)) |
1331 | sigaddset(¤t->blocked,signr); | 1333 | sigaddset(¤t->blocked,signr); |
1332 | recalc_sigpending(); | 1334 | recalc_sigpending(); |
1333 | spin_unlock_irq(¤t->sighand->siglock); | 1335 | spin_unlock_irq(¤t->sighand->siglock); |
1334 | } | ||
1335 | } | 1336 | } |
1336 | 1337 | ||
1337 | static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, | 1338 | static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, |
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index b9b42491e118..b4fc6a5462b2 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c | |||
@@ -144,7 +144,7 @@ void __init smp_callin(void) | |||
144 | current->active_mm = &init_mm; | 144 | current->active_mm = &init_mm; |
145 | 145 | ||
146 | while (!cpu_isset(cpuid, smp_commenced_mask)) | 146 | while (!cpu_isset(cpuid, smp_commenced_mask)) |
147 | membar("#LoadLoad"); | 147 | rmb(); |
148 | 148 | ||
149 | cpu_set(cpuid, cpu_online_map); | 149 | cpu_set(cpuid, cpu_online_map); |
150 | } | 150 | } |
@@ -184,11 +184,11 @@ static inline long get_delta (long *rt, long *master) | |||
184 | for (i = 0; i < NUM_ITERS; i++) { | 184 | for (i = 0; i < NUM_ITERS; i++) { |
185 | t0 = tick_ops->get_tick(); | 185 | t0 = tick_ops->get_tick(); |
186 | go[MASTER] = 1; | 186 | go[MASTER] = 1; |
187 | membar("#StoreLoad"); | 187 | membar_storeload(); |
188 | while (!(tm = go[SLAVE])) | 188 | while (!(tm = go[SLAVE])) |
189 | membar("#LoadLoad"); | 189 | rmb(); |
190 | go[SLAVE] = 0; | 190 | go[SLAVE] = 0; |
191 | membar("#StoreStore"); | 191 | wmb(); |
192 | t1 = tick_ops->get_tick(); | 192 | t1 = tick_ops->get_tick(); |
193 | 193 | ||
194 | if (t1 - t0 < best_t1 - best_t0) | 194 | if (t1 - t0 < best_t1 - best_t0) |
@@ -221,7 +221,7 @@ void smp_synchronize_tick_client(void) | |||
221 | go[MASTER] = 1; | 221 | go[MASTER] = 1; |
222 | 222 | ||
223 | while (go[MASTER]) | 223 | while (go[MASTER]) |
224 | membar("#LoadLoad"); | 224 | rmb(); |
225 | 225 | ||
226 | local_irq_save(flags); | 226 | local_irq_save(flags); |
227 | { | 227 | { |
@@ -273,21 +273,21 @@ static void smp_synchronize_one_tick(int cpu) | |||
273 | 273 | ||
274 | /* wait for client to be ready */ | 274 | /* wait for client to be ready */ |
275 | while (!go[MASTER]) | 275 | while (!go[MASTER]) |
276 | membar("#LoadLoad"); | 276 | rmb(); |
277 | 277 | ||
278 | /* now let the client proceed into his loop */ | 278 | /* now let the client proceed into his loop */ |
279 | go[MASTER] = 0; | 279 | go[MASTER] = 0; |
280 | membar("#StoreLoad"); | 280 | membar_storeload(); |
281 | 281 | ||
282 | spin_lock_irqsave(&itc_sync_lock, flags); | 282 | spin_lock_irqsave(&itc_sync_lock, flags); |
283 | { | 283 | { |
284 | for (i = 0; i < NUM_ROUNDS*NUM_ITERS; i++) { | 284 | for (i = 0; i < NUM_ROUNDS*NUM_ITERS; i++) { |
285 | while (!go[MASTER]) | 285 | while (!go[MASTER]) |
286 | membar("#LoadLoad"); | 286 | rmb(); |
287 | go[MASTER] = 0; | 287 | go[MASTER] = 0; |
288 | membar("#StoreStore"); | 288 | wmb(); |
289 | go[SLAVE] = tick_ops->get_tick(); | 289 | go[SLAVE] = tick_ops->get_tick(); |
290 | membar("#StoreLoad"); | 290 | membar_storeload(); |
291 | } | 291 | } |
292 | } | 292 | } |
293 | spin_unlock_irqrestore(&itc_sync_lock, flags); | 293 | spin_unlock_irqrestore(&itc_sync_lock, flags); |
@@ -927,11 +927,11 @@ void smp_capture(void) | |||
927 | smp_processor_id()); | 927 | smp_processor_id()); |
928 | #endif | 928 | #endif |
929 | penguins_are_doing_time = 1; | 929 | penguins_are_doing_time = 1; |
930 | membar("#StoreStore | #LoadStore"); | 930 | membar_storestore_loadstore(); |
931 | atomic_inc(&smp_capture_registry); | 931 | atomic_inc(&smp_capture_registry); |
932 | smp_cross_call(&xcall_capture, 0, 0, 0); | 932 | smp_cross_call(&xcall_capture, 0, 0, 0); |
933 | while (atomic_read(&smp_capture_registry) != ncpus) | 933 | while (atomic_read(&smp_capture_registry) != ncpus) |
934 | membar("#LoadLoad"); | 934 | rmb(); |
935 | #ifdef CAPTURE_DEBUG | 935 | #ifdef CAPTURE_DEBUG |
936 | printk("done\n"); | 936 | printk("done\n"); |
937 | #endif | 937 | #endif |
@@ -947,7 +947,7 @@ void smp_release(void) | |||
947 | smp_processor_id()); | 947 | smp_processor_id()); |
948 | #endif | 948 | #endif |
949 | penguins_are_doing_time = 0; | 949 | penguins_are_doing_time = 0; |
950 | membar("#StoreStore | #StoreLoad"); | 950 | membar_storeload_storestore(); |
951 | atomic_dec(&smp_capture_registry); | 951 | atomic_dec(&smp_capture_registry); |
952 | } | 952 | } |
953 | } | 953 | } |
@@ -970,9 +970,9 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs) | |||
970 | save_alternate_globals(global_save); | 970 | save_alternate_globals(global_save); |
971 | prom_world(1); | 971 | prom_world(1); |
972 | atomic_inc(&smp_capture_registry); | 972 | atomic_inc(&smp_capture_registry); |
973 | membar("#StoreLoad | #StoreStore"); | 973 | membar_storeload_storestore(); |
974 | while (penguins_are_doing_time) | 974 | while (penguins_are_doing_time) |
975 | membar("#LoadLoad"); | 975 | rmb(); |
976 | restore_alternate_globals(global_save); | 976 | restore_alternate_globals(global_save); |
977 | atomic_dec(&smp_capture_registry); | 977 | atomic_dec(&smp_capture_registry); |
978 | prom_world(0); | 978 | prom_world(0); |
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 9202d925a9ce..cbb5e59824e5 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c | |||
@@ -88,8 +88,6 @@ extern int svr4_setcontext(svr4_ucontext_t *uc, struct pt_regs *regs); | |||
88 | extern int compat_sys_ioctl(unsigned int fd, unsigned int cmd, u32 arg); | 88 | extern int compat_sys_ioctl(unsigned int fd, unsigned int cmd, u32 arg); |
89 | extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *); | 89 | extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *); |
90 | extern long sparc32_open(const char __user * filename, int flags, int mode); | 90 | extern long sparc32_open(const char __user * filename, int flags, int mode); |
91 | extern int io_remap_page_range(struct vm_area_struct *vma, unsigned long from, | ||
92 | unsigned long offset, unsigned long size, pgprot_t prot, int space); | ||
93 | extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from, | 91 | extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from, |
94 | unsigned long pfn, unsigned long size, pgprot_t prot); | 92 | unsigned long pfn, unsigned long size, pgprot_t prot); |
95 | extern void (*prom_palette)(int); | 93 | extern void (*prom_palette)(int); |
@@ -99,17 +97,6 @@ extern int __ashrdi3(int, int); | |||
99 | extern void dump_thread(struct pt_regs *, struct user *); | 97 | extern void dump_thread(struct pt_regs *, struct user *); |
100 | extern int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs); | 98 | extern int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs); |
101 | 99 | ||
102 | #if defined(CONFIG_SMP) && defined(CONFIG_DEBUG_SPINLOCK) | ||
103 | extern void _do_spin_lock (spinlock_t *lock, char *str); | ||
104 | extern void _do_spin_unlock (spinlock_t *lock); | ||
105 | extern int _spin_trylock (spinlock_t *lock); | ||
106 | extern void _do_read_lock(rwlock_t *rw, char *str); | ||
107 | extern void _do_read_unlock(rwlock_t *rw, char *str); | ||
108 | extern void _do_write_lock(rwlock_t *rw, char *str); | ||
109 | extern void _do_write_unlock(rwlock_t *rw); | ||
110 | extern int _do_write_trylock(rwlock_t *rw, char *str); | ||
111 | #endif | ||
112 | |||
113 | extern unsigned long phys_base; | 100 | extern unsigned long phys_base; |
114 | extern unsigned long pfn_base; | 101 | extern unsigned long pfn_base; |
115 | 102 | ||
@@ -128,17 +115,12 @@ EXPORT_PER_CPU_SYMBOL(__cpu_data); | |||
128 | 115 | ||
129 | /* used by various drivers */ | 116 | /* used by various drivers */ |
130 | #ifdef CONFIG_SMP | 117 | #ifdef CONFIG_SMP |
131 | #ifndef CONFIG_DEBUG_SPINLOCK | ||
132 | /* Out of line rw-locking implementation. */ | 118 | /* Out of line rw-locking implementation. */ |
133 | EXPORT_SYMBOL(__read_lock); | 119 | EXPORT_SYMBOL(__read_lock); |
134 | EXPORT_SYMBOL(__read_unlock); | 120 | EXPORT_SYMBOL(__read_unlock); |
135 | EXPORT_SYMBOL(__write_lock); | 121 | EXPORT_SYMBOL(__write_lock); |
136 | EXPORT_SYMBOL(__write_unlock); | 122 | EXPORT_SYMBOL(__write_unlock); |
137 | EXPORT_SYMBOL(__write_trylock); | 123 | EXPORT_SYMBOL(__write_trylock); |
138 | /* Out of line spin-locking implementation. */ | ||
139 | EXPORT_SYMBOL(_raw_spin_lock); | ||
140 | EXPORT_SYMBOL(_raw_spin_lock_flags); | ||
141 | #endif | ||
142 | 124 | ||
143 | /* Hard IRQ locking */ | 125 | /* Hard IRQ locking */ |
144 | EXPORT_SYMBOL(synchronize_irq); | 126 | EXPORT_SYMBOL(synchronize_irq); |
@@ -152,18 +134,6 @@ EXPORT_SYMBOL(_mcount); | |||
152 | EXPORT_SYMBOL(cpu_online_map); | 134 | EXPORT_SYMBOL(cpu_online_map); |
153 | EXPORT_SYMBOL(phys_cpu_present_map); | 135 | EXPORT_SYMBOL(phys_cpu_present_map); |
154 | 136 | ||
155 | /* Spinlock debugging library, optional. */ | ||
156 | #ifdef CONFIG_DEBUG_SPINLOCK | ||
157 | EXPORT_SYMBOL(_do_spin_lock); | ||
158 | EXPORT_SYMBOL(_do_spin_unlock); | ||
159 | EXPORT_SYMBOL(_spin_trylock); | ||
160 | EXPORT_SYMBOL(_do_read_lock); | ||
161 | EXPORT_SYMBOL(_do_read_unlock); | ||
162 | EXPORT_SYMBOL(_do_write_lock); | ||
163 | EXPORT_SYMBOL(_do_write_unlock); | ||
164 | EXPORT_SYMBOL(_do_write_trylock); | ||
165 | #endif | ||
166 | |||
167 | EXPORT_SYMBOL(smp_call_function); | 137 | EXPORT_SYMBOL(smp_call_function); |
168 | #endif /* CONFIG_SMP */ | 138 | #endif /* CONFIG_SMP */ |
169 | 139 | ||
@@ -268,7 +238,6 @@ EXPORT_SYMBOL(pci_dma_supported); | |||
268 | #endif | 238 | #endif |
269 | 239 | ||
270 | /* I/O device mmaping on Sparc64. */ | 240 | /* I/O device mmaping on Sparc64. */ |
271 | EXPORT_SYMBOL(io_remap_page_range); | ||
272 | EXPORT_SYMBOL(io_remap_pfn_range); | 241 | EXPORT_SYMBOL(io_remap_pfn_range); |
273 | 242 | ||
274 | /* Solaris/SunOS binary compatibility */ | 243 | /* Solaris/SunOS binary compatibility */ |
diff --git a/arch/sparc64/kernel/sunos_ioctl32.c b/arch/sparc64/kernel/sunos_ioctl32.c index 87c1aeb02220..7654b8a7f03a 100644 --- a/arch/sparc64/kernel/sunos_ioctl32.c +++ b/arch/sparc64/kernel/sunos_ioctl32.c | |||
@@ -152,11 +152,12 @@ asmlinkage int sunos_ioctl (int fd, u32 cmd, u32 arg) | |||
152 | ret = compat_sys_ioctl(fd, SIOCGIFCONF, arg); | 152 | ret = compat_sys_ioctl(fd, SIOCGIFCONF, arg); |
153 | goto out; | 153 | goto out; |
154 | 154 | ||
155 | case _IOW('i', 21, struct ifreq): /* SIOCSIFMTU */ | 155 | case _IOW('i', 21, struct ifreq32): |
156 | ret = sys_ioctl(fd, SIOCSIFMTU, arg); | 156 | ret = compat_sys_ioctl(fd, SIOCSIFMTU, arg); |
157 | goto out; | 157 | goto out; |
158 | case _IOWR('i', 22, struct ifreq): /* SIOCGIFMTU */ | 158 | |
159 | ret = sys_ioctl(fd, SIOCGIFMTU, arg); | 159 | case _IOWR('i', 22, struct ifreq32): |
160 | ret = compat_sys_ioctl(fd, SIOCGIFMTU, arg); | ||
160 | goto out; | 161 | goto out; |
161 | 162 | ||
162 | case _IOWR('i', 23, struct ifreq32): | 163 | case _IOWR('i', 23, struct ifreq32): |
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index 1d3aa588df8a..7f6239ed2521 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c | |||
@@ -1002,29 +1002,7 @@ asmlinkage long sys32_adjtimex(struct timex32 __user *utp) | |||
1002 | asmlinkage long sparc32_open(const char __user *filename, | 1002 | asmlinkage long sparc32_open(const char __user *filename, |
1003 | int flags, int mode) | 1003 | int flags, int mode) |
1004 | { | 1004 | { |
1005 | char * tmp; | 1005 | return do_sys_open(filename, flags, mode); |
1006 | int fd, error; | ||
1007 | |||
1008 | tmp = getname(filename); | ||
1009 | fd = PTR_ERR(tmp); | ||
1010 | if (!IS_ERR(tmp)) { | ||
1011 | fd = get_unused_fd(); | ||
1012 | if (fd >= 0) { | ||
1013 | struct file * f = filp_open(tmp, flags, mode); | ||
1014 | error = PTR_ERR(f); | ||
1015 | if (IS_ERR(f)) | ||
1016 | goto out_error; | ||
1017 | fd_install(fd, f); | ||
1018 | } | ||
1019 | out: | ||
1020 | putname(tmp); | ||
1021 | } | ||
1022 | return fd; | ||
1023 | |||
1024 | out_error: | ||
1025 | put_unused_fd(fd); | ||
1026 | fd = error; | ||
1027 | goto out; | ||
1028 | } | 1006 | } |
1029 | 1007 | ||
1030 | extern unsigned long do_mremap(unsigned long addr, | 1008 | extern unsigned long do_mremap(unsigned long addr, |
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index 362b9c26871b..3f08a32f51a1 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c | |||
@@ -449,7 +449,7 @@ static inline void timer_check_rtc(void) | |||
449 | static long last_rtc_update; | 449 | static long last_rtc_update; |
450 | 450 | ||
451 | /* Determine when to update the Mostek clock. */ | 451 | /* Determine when to update the Mostek clock. */ |
452 | if ((time_status & STA_UNSYNC) == 0 && | 452 | if (ntp_synced() && |
453 | xtime.tv_sec > last_rtc_update + 660 && | 453 | xtime.tv_sec > last_rtc_update + 660 && |
454 | (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && | 454 | (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && |
455 | (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { | 455 | (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { |
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index 100b0107c4be..b280b2ef674f 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <asm/dcu.h> | 33 | #include <asm/dcu.h> |
34 | #include <asm/estate.h> | 34 | #include <asm/estate.h> |
35 | #include <asm/chafsr.h> | 35 | #include <asm/chafsr.h> |
36 | #include <asm/sfafsr.h> | ||
36 | #include <asm/psrcompat.h> | 37 | #include <asm/psrcompat.h> |
37 | #include <asm/processor.h> | 38 | #include <asm/processor.h> |
38 | #include <asm/timer.h> | 39 | #include <asm/timer.h> |
@@ -143,8 +144,7 @@ void do_BUG(const char *file, int line) | |||
143 | } | 144 | } |
144 | #endif | 145 | #endif |
145 | 146 | ||
146 | void instruction_access_exception(struct pt_regs *regs, | 147 | void spitfire_insn_access_exception(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) |
147 | unsigned long sfsr, unsigned long sfar) | ||
148 | { | 148 | { |
149 | siginfo_t info; | 149 | siginfo_t info; |
150 | 150 | ||
@@ -153,8 +153,8 @@ void instruction_access_exception(struct pt_regs *regs, | |||
153 | return; | 153 | return; |
154 | 154 | ||
155 | if (regs->tstate & TSTATE_PRIV) { | 155 | if (regs->tstate & TSTATE_PRIV) { |
156 | printk("instruction_access_exception: SFSR[%016lx] SFAR[%016lx], going.\n", | 156 | printk("spitfire_insn_access_exception: SFSR[%016lx] " |
157 | sfsr, sfar); | 157 | "SFAR[%016lx], going.\n", sfsr, sfar); |
158 | die_if_kernel("Iax", regs); | 158 | die_if_kernel("Iax", regs); |
159 | } | 159 | } |
160 | if (test_thread_flag(TIF_32BIT)) { | 160 | if (test_thread_flag(TIF_32BIT)) { |
@@ -169,19 +169,17 @@ void instruction_access_exception(struct pt_regs *regs, | |||
169 | force_sig_info(SIGSEGV, &info, current); | 169 | force_sig_info(SIGSEGV, &info, current); |
170 | } | 170 | } |
171 | 171 | ||
172 | void instruction_access_exception_tl1(struct pt_regs *regs, | 172 | void spitfire_insn_access_exception_tl1(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) |
173 | unsigned long sfsr, unsigned long sfar) | ||
174 | { | 173 | { |
175 | if (notify_die(DIE_TRAP_TL1, "instruction access exception tl1", regs, | 174 | if (notify_die(DIE_TRAP_TL1, "instruction access exception tl1", regs, |
176 | 0, 0x8, SIGTRAP) == NOTIFY_STOP) | 175 | 0, 0x8, SIGTRAP) == NOTIFY_STOP) |
177 | return; | 176 | return; |
178 | 177 | ||
179 | dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); | 178 | dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); |
180 | instruction_access_exception(regs, sfsr, sfar); | 179 | spitfire_insn_access_exception(regs, sfsr, sfar); |
181 | } | 180 | } |
182 | 181 | ||
183 | void data_access_exception(struct pt_regs *regs, | 182 | void spitfire_data_access_exception(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) |
184 | unsigned long sfsr, unsigned long sfar) | ||
185 | { | 183 | { |
186 | siginfo_t info; | 184 | siginfo_t info; |
187 | 185 | ||
@@ -207,8 +205,8 @@ void data_access_exception(struct pt_regs *regs, | |||
207 | return; | 205 | return; |
208 | } | 206 | } |
209 | /* Shit... */ | 207 | /* Shit... */ |
210 | printk("data_access_exception: SFSR[%016lx] SFAR[%016lx], going.\n", | 208 | printk("spitfire_data_access_exception: SFSR[%016lx] " |
211 | sfsr, sfar); | 209 | "SFAR[%016lx], going.\n", sfsr, sfar); |
212 | die_if_kernel("Dax", regs); | 210 | die_if_kernel("Dax", regs); |
213 | } | 211 | } |
214 | 212 | ||
@@ -220,6 +218,16 @@ void data_access_exception(struct pt_regs *regs, | |||
220 | force_sig_info(SIGSEGV, &info, current); | 218 | force_sig_info(SIGSEGV, &info, current); |
221 | } | 219 | } |
222 | 220 | ||
221 | void spitfire_data_access_exception_tl1(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) | ||
222 | { | ||
223 | if (notify_die(DIE_TRAP_TL1, "data access exception tl1", regs, | ||
224 | 0, 0x30, SIGTRAP) == NOTIFY_STOP) | ||
225 | return; | ||
226 | |||
227 | dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); | ||
228 | spitfire_data_access_exception(regs, sfsr, sfar); | ||
229 | } | ||
230 | |||
223 | #ifdef CONFIG_PCI | 231 | #ifdef CONFIG_PCI |
224 | /* This is really pathetic... */ | 232 | /* This is really pathetic... */ |
225 | extern volatile int pci_poke_in_progress; | 233 | extern volatile int pci_poke_in_progress; |
@@ -253,54 +261,13 @@ static void spitfire_clean_and_reenable_l1_caches(void) | |||
253 | : "memory"); | 261 | : "memory"); |
254 | } | 262 | } |
255 | 263 | ||
256 | void do_iae(struct pt_regs *regs) | 264 | static void spitfire_enable_estate_errors(void) |
257 | { | 265 | { |
258 | siginfo_t info; | 266 | __asm__ __volatile__("stxa %0, [%%g0] %1\n\t" |
259 | 267 | "membar #Sync" | |
260 | spitfire_clean_and_reenable_l1_caches(); | 268 | : /* no outputs */ |
261 | 269 | : "r" (ESTATE_ERR_ALL), | |
262 | if (notify_die(DIE_TRAP, "instruction access exception", regs, | 270 | "i" (ASI_ESTATE_ERROR_EN)); |
263 | 0, 0x8, SIGTRAP) == NOTIFY_STOP) | ||
264 | return; | ||
265 | |||
266 | info.si_signo = SIGBUS; | ||
267 | info.si_errno = 0; | ||
268 | info.si_code = BUS_OBJERR; | ||
269 | info.si_addr = (void *)0; | ||
270 | info.si_trapno = 0; | ||
271 | force_sig_info(SIGBUS, &info, current); | ||
272 | } | ||
273 | |||
274 | void do_dae(struct pt_regs *regs) | ||
275 | { | ||
276 | siginfo_t info; | ||
277 | |||
278 | #ifdef CONFIG_PCI | ||
279 | if (pci_poke_in_progress && pci_poke_cpu == smp_processor_id()) { | ||
280 | spitfire_clean_and_reenable_l1_caches(); | ||
281 | |||
282 | pci_poke_faulted = 1; | ||
283 | |||
284 | /* Why the fuck did they have to change this? */ | ||
285 | if (tlb_type == cheetah || tlb_type == cheetah_plus) | ||
286 | regs->tpc += 4; | ||
287 | |||
288 | regs->tnpc = regs->tpc + 4; | ||
289 | return; | ||
290 | } | ||
291 | #endif | ||
292 | spitfire_clean_and_reenable_l1_caches(); | ||
293 | |||
294 | if (notify_die(DIE_TRAP, "data access exception", regs, | ||
295 | 0, 0x30, SIGTRAP) == NOTIFY_STOP) | ||
296 | return; | ||
297 | |||
298 | info.si_signo = SIGBUS; | ||
299 | info.si_errno = 0; | ||
300 | info.si_code = BUS_OBJERR; | ||
301 | info.si_addr = (void *)0; | ||
302 | info.si_trapno = 0; | ||
303 | force_sig_info(SIGBUS, &info, current); | ||
304 | } | 271 | } |
305 | 272 | ||
306 | static char ecc_syndrome_table[] = { | 273 | static char ecc_syndrome_table[] = { |
@@ -338,65 +305,15 @@ static char ecc_syndrome_table[] = { | |||
338 | 0x0b, 0x48, 0x48, 0x4b, 0x48, 0x4b, 0x4b, 0x4a | 305 | 0x0b, 0x48, 0x48, 0x4b, 0x48, 0x4b, 0x4b, 0x4a |
339 | }; | 306 | }; |
340 | 307 | ||
341 | /* cee_trap in entry.S encodes AFSR/UDBH/UDBL error status | ||
342 | * in the following format. The AFAR is left as is, with | ||
343 | * reserved bits cleared, and is a raw 40-bit physical | ||
344 | * address. | ||
345 | */ | ||
346 | #define CE_STATUS_UDBH_UE (1UL << (43 + 9)) | ||
347 | #define CE_STATUS_UDBH_CE (1UL << (43 + 8)) | ||
348 | #define CE_STATUS_UDBH_ESYNDR (0xffUL << 43) | ||
349 | #define CE_STATUS_UDBH_SHIFT 43 | ||
350 | #define CE_STATUS_UDBL_UE (1UL << (33 + 9)) | ||
351 | #define CE_STATUS_UDBL_CE (1UL << (33 + 8)) | ||
352 | #define CE_STATUS_UDBL_ESYNDR (0xffUL << 33) | ||
353 | #define CE_STATUS_UDBL_SHIFT 33 | ||
354 | #define CE_STATUS_AFSR_MASK (0x1ffffffffUL) | ||
355 | #define CE_STATUS_AFSR_ME (1UL << 32) | ||
356 | #define CE_STATUS_AFSR_PRIV (1UL << 31) | ||
357 | #define CE_STATUS_AFSR_ISAP (1UL << 30) | ||
358 | #define CE_STATUS_AFSR_ETP (1UL << 29) | ||
359 | #define CE_STATUS_AFSR_IVUE (1UL << 28) | ||
360 | #define CE_STATUS_AFSR_TO (1UL << 27) | ||
361 | #define CE_STATUS_AFSR_BERR (1UL << 26) | ||
362 | #define CE_STATUS_AFSR_LDP (1UL << 25) | ||
363 | #define CE_STATUS_AFSR_CP (1UL << 24) | ||
364 | #define CE_STATUS_AFSR_WP (1UL << 23) | ||
365 | #define CE_STATUS_AFSR_EDP (1UL << 22) | ||
366 | #define CE_STATUS_AFSR_UE (1UL << 21) | ||
367 | #define CE_STATUS_AFSR_CE (1UL << 20) | ||
368 | #define CE_STATUS_AFSR_ETS (0xfUL << 16) | ||
369 | #define CE_STATUS_AFSR_ETS_SHIFT 16 | ||
370 | #define CE_STATUS_AFSR_PSYND (0xffffUL << 0) | ||
371 | #define CE_STATUS_AFSR_PSYND_SHIFT 0 | ||
372 | |||
373 | /* Layout of Ecache TAG Parity Syndrome of AFSR */ | ||
374 | #define AFSR_ETSYNDROME_7_0 0x1UL /* E$-tag bus bits <7:0> */ | ||
375 | #define AFSR_ETSYNDROME_15_8 0x2UL /* E$-tag bus bits <15:8> */ | ||
376 | #define AFSR_ETSYNDROME_21_16 0x4UL /* E$-tag bus bits <21:16> */ | ||
377 | #define AFSR_ETSYNDROME_24_22 0x8UL /* E$-tag bus bits <24:22> */ | ||
378 | |||
379 | static char *syndrome_unknown = "<Unknown>"; | 308 | static char *syndrome_unknown = "<Unknown>"; |
380 | 309 | ||
381 | asmlinkage void cee_log(unsigned long ce_status, | 310 | static void spitfire_log_udb_syndrome(unsigned long afar, unsigned long udbh, unsigned long udbl, unsigned long bit) |
382 | unsigned long afar, | ||
383 | struct pt_regs *regs) | ||
384 | { | 311 | { |
385 | char memmod_str[64]; | 312 | unsigned short scode; |
386 | char *p; | 313 | char memmod_str[64], *p; |
387 | unsigned short scode, udb_reg; | ||
388 | 314 | ||
389 | printk(KERN_WARNING "CPU[%d]: Correctable ECC Error " | 315 | if (udbl & bit) { |
390 | "AFSR[%lx] AFAR[%016lx] UDBL[%lx] UDBH[%lx]\n", | 316 | scode = ecc_syndrome_table[udbl & 0xff]; |
391 | smp_processor_id(), | ||
392 | (ce_status & CE_STATUS_AFSR_MASK), | ||
393 | afar, | ||
394 | ((ce_status >> CE_STATUS_UDBL_SHIFT) & 0x3ffUL), | ||
395 | ((ce_status >> CE_STATUS_UDBH_SHIFT) & 0x3ffUL)); | ||
396 | |||
397 | udb_reg = ((ce_status >> CE_STATUS_UDBL_SHIFT) & 0x3ffUL); | ||
398 | if (udb_reg & (1 << 8)) { | ||
399 | scode = ecc_syndrome_table[udb_reg & 0xff]; | ||
400 | if (prom_getunumber(scode, afar, | 317 | if (prom_getunumber(scode, afar, |
401 | memmod_str, sizeof(memmod_str)) == -1) | 318 | memmod_str, sizeof(memmod_str)) == -1) |
402 | p = syndrome_unknown; | 319 | p = syndrome_unknown; |
@@ -407,9 +324,8 @@ asmlinkage void cee_log(unsigned long ce_status, | |||
407 | smp_processor_id(), scode, p); | 324 | smp_processor_id(), scode, p); |
408 | } | 325 | } |
409 | 326 | ||
410 | udb_reg = ((ce_status >> CE_STATUS_UDBH_SHIFT) & 0x3ffUL); | 327 | if (udbh & bit) { |
411 | if (udb_reg & (1 << 8)) { | 328 | scode = ecc_syndrome_table[udbh & 0xff]; |
412 | scode = ecc_syndrome_table[udb_reg & 0xff]; | ||
413 | if (prom_getunumber(scode, afar, | 329 | if (prom_getunumber(scode, afar, |
414 | memmod_str, sizeof(memmod_str)) == -1) | 330 | memmod_str, sizeof(memmod_str)) == -1) |
415 | p = syndrome_unknown; | 331 | p = syndrome_unknown; |
@@ -419,6 +335,127 @@ asmlinkage void cee_log(unsigned long ce_status, | |||
419 | "Memory Module \"%s\"\n", | 335 | "Memory Module \"%s\"\n", |
420 | smp_processor_id(), scode, p); | 336 | smp_processor_id(), scode, p); |
421 | } | 337 | } |
338 | |||
339 | } | ||
340 | |||
341 | static void spitfire_cee_log(unsigned long afsr, unsigned long afar, unsigned long udbh, unsigned long udbl, int tl1, struct pt_regs *regs) | ||
342 | { | ||
343 | |||
344 | printk(KERN_WARNING "CPU[%d]: Correctable ECC Error " | ||
345 | "AFSR[%lx] AFAR[%016lx] UDBL[%lx] UDBH[%lx] TL>1[%d]\n", | ||
346 | smp_processor_id(), afsr, afar, udbl, udbh, tl1); | ||
347 | |||
348 | spitfire_log_udb_syndrome(afar, udbh, udbl, UDBE_CE); | ||
349 | |||
350 | /* We always log it, even if someone is listening for this | ||
351 | * trap. | ||
352 | */ | ||
353 | notify_die(DIE_TRAP, "Correctable ECC Error", regs, | ||
354 | 0, TRAP_TYPE_CEE, SIGTRAP); | ||
355 | |||
356 | /* The Correctable ECC Error trap does not disable I/D caches. So | ||
357 | * we only have to restore the ESTATE Error Enable register. | ||
358 | */ | ||
359 | spitfire_enable_estate_errors(); | ||
360 | } | ||
361 | |||
362 | static void spitfire_ue_log(unsigned long afsr, unsigned long afar, unsigned long udbh, unsigned long udbl, unsigned long tt, int tl1, struct pt_regs *regs) | ||
363 | { | ||
364 | siginfo_t info; | ||
365 | |||
366 | printk(KERN_WARNING "CPU[%d]: Uncorrectable Error AFSR[%lx] " | ||
367 | "AFAR[%lx] UDBL[%lx] UDBH[%ld] TT[%lx] TL>1[%d]\n", | ||
368 | smp_processor_id(), afsr, afar, udbl, udbh, tt, tl1); | ||
369 | |||
370 | /* XXX add more human friendly logging of the error status | ||
371 | * XXX as is implemented for cheetah | ||
372 | */ | ||
373 | |||
374 | spitfire_log_udb_syndrome(afar, udbh, udbl, UDBE_UE); | ||
375 | |||
376 | /* We always log it, even if someone is listening for this | ||
377 | * trap. | ||
378 | */ | ||
379 | notify_die(DIE_TRAP, "Uncorrectable Error", regs, | ||
380 | 0, tt, SIGTRAP); | ||
381 | |||
382 | if (regs->tstate & TSTATE_PRIV) { | ||
383 | if (tl1) | ||
384 | dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); | ||
385 | die_if_kernel("UE", regs); | ||
386 | } | ||
387 | |||
388 | /* XXX need more intelligent processing here, such as is implemented | ||
389 | * XXX for cheetah errors, in fact if the E-cache still holds the | ||
390 | * XXX line with bad parity this will loop | ||
391 | */ | ||
392 | |||
393 | spitfire_clean_and_reenable_l1_caches(); | ||
394 | spitfire_enable_estate_errors(); | ||
395 | |||
396 | if (test_thread_flag(TIF_32BIT)) { | ||
397 | regs->tpc &= 0xffffffff; | ||
398 | regs->tnpc &= 0xffffffff; | ||
399 | } | ||
400 | info.si_signo = SIGBUS; | ||
401 | info.si_errno = 0; | ||
402 | info.si_code = BUS_OBJERR; | ||
403 | info.si_addr = (void *)0; | ||
404 | info.si_trapno = 0; | ||
405 | force_sig_info(SIGBUS, &info, current); | ||
406 | } | ||
407 | |||
408 | void spitfire_access_error(struct pt_regs *regs, unsigned long status_encoded, unsigned long afar) | ||
409 | { | ||
410 | unsigned long afsr, tt, udbh, udbl; | ||
411 | int tl1; | ||
412 | |||
413 | afsr = (status_encoded & SFSTAT_AFSR_MASK) >> SFSTAT_AFSR_SHIFT; | ||
414 | tt = (status_encoded & SFSTAT_TRAP_TYPE) >> SFSTAT_TRAP_TYPE_SHIFT; | ||
415 | tl1 = (status_encoded & SFSTAT_TL_GT_ONE) ? 1 : 0; | ||
416 | udbl = (status_encoded & SFSTAT_UDBL_MASK) >> SFSTAT_UDBL_SHIFT; | ||
417 | udbh = (status_encoded & SFSTAT_UDBH_MASK) >> SFSTAT_UDBH_SHIFT; | ||
418 | |||
419 | #ifdef CONFIG_PCI | ||
420 | if (tt == TRAP_TYPE_DAE && | ||
421 | pci_poke_in_progress && pci_poke_cpu == smp_processor_id()) { | ||
422 | spitfire_clean_and_reenable_l1_caches(); | ||
423 | spitfire_enable_estate_errors(); | ||
424 | |||
425 | pci_poke_faulted = 1; | ||
426 | regs->tnpc = regs->tpc + 4; | ||
427 | return; | ||
428 | } | ||
429 | #endif | ||
430 | |||
431 | if (afsr & SFAFSR_UE) | ||
432 | spitfire_ue_log(afsr, afar, udbh, udbl, tt, tl1, regs); | ||
433 | |||
434 | if (tt == TRAP_TYPE_CEE) { | ||
435 | /* Handle the case where we took a CEE trap, but ACK'd | ||
436 | * only the UE state in the UDB error registers. | ||
437 | */ | ||
438 | if (afsr & SFAFSR_UE) { | ||
439 | if (udbh & UDBE_CE) { | ||
440 | __asm__ __volatile__( | ||
441 | "stxa %0, [%1] %2\n\t" | ||
442 | "membar #Sync" | ||
443 | : /* no outputs */ | ||
444 | : "r" (udbh & UDBE_CE), | ||
445 | "r" (0x0), "i" (ASI_UDB_ERROR_W)); | ||
446 | } | ||
447 | if (udbl & UDBE_CE) { | ||
448 | __asm__ __volatile__( | ||
449 | "stxa %0, [%1] %2\n\t" | ||
450 | "membar #Sync" | ||
451 | : /* no outputs */ | ||
452 | : "r" (udbl & UDBE_CE), | ||
453 | "r" (0x18), "i" (ASI_UDB_ERROR_W)); | ||
454 | } | ||
455 | } | ||
456 | |||
457 | spitfire_cee_log(afsr, afar, udbh, udbl, tl1, regs); | ||
458 | } | ||
422 | } | 459 | } |
423 | 460 | ||
424 | int cheetah_pcache_forced_on; | 461 | int cheetah_pcache_forced_on; |
@@ -2127,6 +2164,9 @@ void __init trap_init(void) | |||
2127 | TI_PRE_COUNT != offsetof(struct thread_info, preempt_count) || | 2164 | TI_PRE_COUNT != offsetof(struct thread_info, preempt_count) || |
2128 | TI_NEW_CHILD != offsetof(struct thread_info, new_child) || | 2165 | TI_NEW_CHILD != offsetof(struct thread_info, new_child) || |
2129 | TI_SYS_NOERROR != offsetof(struct thread_info, syscall_noerror) || | 2166 | TI_SYS_NOERROR != offsetof(struct thread_info, syscall_noerror) || |
2167 | TI_RESTART_BLOCK != offsetof(struct thread_info, restart_block) || | ||
2168 | TI_KUNA_REGS != offsetof(struct thread_info, kern_una_regs) || | ||
2169 | TI_KUNA_INSN != offsetof(struct thread_info, kern_una_insn) || | ||
2130 | TI_FPREGS != offsetof(struct thread_info, fpregs) || | 2170 | TI_FPREGS != offsetof(struct thread_info, fpregs) || |
2131 | (TI_FPREGS & (64 - 1))) | 2171 | (TI_FPREGS & (64 - 1))) |
2132 | thread_info_offsets_are_bolixed_dave(); | 2172 | thread_info_offsets_are_bolixed_dave(); |
diff --git a/arch/sparc64/kernel/ttable.S b/arch/sparc64/kernel/ttable.S index 491bb3681f9d..8365bc1f81f3 100644 --- a/arch/sparc64/kernel/ttable.S +++ b/arch/sparc64/kernel/ttable.S | |||
@@ -18,9 +18,10 @@ sparc64_ttable_tl0: | |||
18 | tl0_resv000: BOOT_KERNEL BTRAP(0x1) BTRAP(0x2) BTRAP(0x3) | 18 | tl0_resv000: BOOT_KERNEL BTRAP(0x1) BTRAP(0x2) BTRAP(0x3) |
19 | tl0_resv004: BTRAP(0x4) BTRAP(0x5) BTRAP(0x6) BTRAP(0x7) | 19 | tl0_resv004: BTRAP(0x4) BTRAP(0x5) BTRAP(0x6) BTRAP(0x7) |
20 | tl0_iax: membar #Sync | 20 | tl0_iax: membar #Sync |
21 | TRAP_NOSAVE_7INSNS(__do_instruction_access_exception) | 21 | TRAP_NOSAVE_7INSNS(__spitfire_insn_access_exception) |
22 | tl0_resv009: BTRAP(0x9) | 22 | tl0_resv009: BTRAP(0x9) |
23 | tl0_iae: TRAP(do_iae) | 23 | tl0_iae: membar #Sync |
24 | TRAP_NOSAVE_7INSNS(__spitfire_access_error) | ||
24 | tl0_resv00b: BTRAP(0xb) BTRAP(0xc) BTRAP(0xd) BTRAP(0xe) BTRAP(0xf) | 25 | tl0_resv00b: BTRAP(0xb) BTRAP(0xc) BTRAP(0xd) BTRAP(0xe) BTRAP(0xf) |
25 | tl0_ill: membar #Sync | 26 | tl0_ill: membar #Sync |
26 | TRAP_7INSNS(do_illegal_instruction) | 27 | TRAP_7INSNS(do_illegal_instruction) |
@@ -36,9 +37,10 @@ tl0_cwin: CLEAN_WINDOW | |||
36 | tl0_div0: TRAP(do_div0) | 37 | tl0_div0: TRAP(do_div0) |
37 | tl0_resv029: BTRAP(0x29) BTRAP(0x2a) BTRAP(0x2b) BTRAP(0x2c) BTRAP(0x2d) BTRAP(0x2e) | 38 | tl0_resv029: BTRAP(0x29) BTRAP(0x2a) BTRAP(0x2b) BTRAP(0x2c) BTRAP(0x2d) BTRAP(0x2e) |
38 | tl0_resv02f: BTRAP(0x2f) | 39 | tl0_resv02f: BTRAP(0x2f) |
39 | tl0_dax: TRAP_NOSAVE(__do_data_access_exception) | 40 | tl0_dax: TRAP_NOSAVE(__spitfire_data_access_exception) |
40 | tl0_resv031: BTRAP(0x31) | 41 | tl0_resv031: BTRAP(0x31) |
41 | tl0_dae: TRAP(do_dae) | 42 | tl0_dae: membar #Sync |
43 | TRAP_NOSAVE_7INSNS(__spitfire_access_error) | ||
42 | tl0_resv033: BTRAP(0x33) | 44 | tl0_resv033: BTRAP(0x33) |
43 | tl0_mna: TRAP_NOSAVE(do_mna) | 45 | tl0_mna: TRAP_NOSAVE(do_mna) |
44 | tl0_lddfmna: TRAP_NOSAVE(do_lddfmna) | 46 | tl0_lddfmna: TRAP_NOSAVE(do_lddfmna) |
@@ -73,7 +75,8 @@ tl0_resv05c: BTRAP(0x5c) BTRAP(0x5d) BTRAP(0x5e) BTRAP(0x5f) | |||
73 | tl0_ivec: TRAP_IVEC | 75 | tl0_ivec: TRAP_IVEC |
74 | tl0_paw: TRAP(do_paw) | 76 | tl0_paw: TRAP(do_paw) |
75 | tl0_vaw: TRAP(do_vaw) | 77 | tl0_vaw: TRAP(do_vaw) |
76 | tl0_cee: TRAP_NOSAVE(cee_trap) | 78 | tl0_cee: membar #Sync |
79 | TRAP_NOSAVE_7INSNS(__spitfire_cee_trap) | ||
77 | tl0_iamiss: | 80 | tl0_iamiss: |
78 | #include "itlb_base.S" | 81 | #include "itlb_base.S" |
79 | tl0_damiss: | 82 | tl0_damiss: |
@@ -175,9 +178,10 @@ tl0_resv1f0: BTRAPS(0x1f0) BTRAPS(0x1f8) | |||
175 | sparc64_ttable_tl1: | 178 | sparc64_ttable_tl1: |
176 | tl1_resv000: BOOT_KERNEL BTRAPTL1(0x1) BTRAPTL1(0x2) BTRAPTL1(0x3) | 179 | tl1_resv000: BOOT_KERNEL BTRAPTL1(0x1) BTRAPTL1(0x2) BTRAPTL1(0x3) |
177 | tl1_resv004: BTRAPTL1(0x4) BTRAPTL1(0x5) BTRAPTL1(0x6) BTRAPTL1(0x7) | 180 | tl1_resv004: BTRAPTL1(0x4) BTRAPTL1(0x5) BTRAPTL1(0x6) BTRAPTL1(0x7) |
178 | tl1_iax: TRAP_NOSAVE(__do_instruction_access_exception_tl1) | 181 | tl1_iax: TRAP_NOSAVE(__spitfire_insn_access_exception_tl1) |
179 | tl1_resv009: BTRAPTL1(0x9) | 182 | tl1_resv009: BTRAPTL1(0x9) |
180 | tl1_iae: TRAPTL1(do_iae_tl1) | 183 | tl1_iae: membar #Sync |
184 | TRAP_NOSAVE_7INSNS(__spitfire_access_error) | ||
181 | tl1_resv00b: BTRAPTL1(0xb) BTRAPTL1(0xc) BTRAPTL1(0xd) BTRAPTL1(0xe) BTRAPTL1(0xf) | 185 | tl1_resv00b: BTRAPTL1(0xb) BTRAPTL1(0xc) BTRAPTL1(0xd) BTRAPTL1(0xe) BTRAPTL1(0xf) |
182 | tl1_ill: TRAPTL1(do_ill_tl1) | 186 | tl1_ill: TRAPTL1(do_ill_tl1) |
183 | tl1_privop: BTRAPTL1(0x11) | 187 | tl1_privop: BTRAPTL1(0x11) |
@@ -193,9 +197,10 @@ tl1_cwin: CLEAN_WINDOW | |||
193 | tl1_div0: TRAPTL1(do_div0_tl1) | 197 | tl1_div0: TRAPTL1(do_div0_tl1) |
194 | tl1_resv029: BTRAPTL1(0x29) BTRAPTL1(0x2a) BTRAPTL1(0x2b) BTRAPTL1(0x2c) | 198 | tl1_resv029: BTRAPTL1(0x29) BTRAPTL1(0x2a) BTRAPTL1(0x2b) BTRAPTL1(0x2c) |
195 | tl1_resv02d: BTRAPTL1(0x2d) BTRAPTL1(0x2e) BTRAPTL1(0x2f) | 199 | tl1_resv02d: BTRAPTL1(0x2d) BTRAPTL1(0x2e) BTRAPTL1(0x2f) |
196 | tl1_dax: TRAP_NOSAVE(__do_data_access_exception_tl1) | 200 | tl1_dax: TRAP_NOSAVE(__spitfire_data_access_exception_tl1) |
197 | tl1_resv031: BTRAPTL1(0x31) | 201 | tl1_resv031: BTRAPTL1(0x31) |
198 | tl1_dae: TRAPTL1(do_dae_tl1) | 202 | tl1_dae: membar #Sync |
203 | TRAP_NOSAVE_7INSNS(__spitfire_access_error) | ||
199 | tl1_resv033: BTRAPTL1(0x33) | 204 | tl1_resv033: BTRAPTL1(0x33) |
200 | tl1_mna: TRAP_NOSAVE(do_mna) | 205 | tl1_mna: TRAP_NOSAVE(do_mna) |
201 | tl1_lddfmna: TRAPTL1(do_lddfmna_tl1) | 206 | tl1_lddfmna: TRAPTL1(do_lddfmna_tl1) |
@@ -219,8 +224,8 @@ tl1_paw: TRAPTL1(do_paw_tl1) | |||
219 | tl1_vaw: TRAPTL1(do_vaw_tl1) | 224 | tl1_vaw: TRAPTL1(do_vaw_tl1) |
220 | 225 | ||
221 | /* The grotty trick to save %g1 into current->thread.cee_stuff | 226 | /* The grotty trick to save %g1 into current->thread.cee_stuff |
222 | * is because when we take this trap we could be interrupting trap | 227 | * is because when we take this trap we could be interrupting |
223 | * code already using the trap alternate global registers. | 228 | * trap code already using the trap alternate global registers. |
224 | * | 229 | * |
225 | * We cross our fingers and pray that this store/load does | 230 | * We cross our fingers and pray that this store/load does |
226 | * not cause yet another CEE trap. | 231 | * not cause yet another CEE trap. |
diff --git a/arch/sparc64/kernel/una_asm.S b/arch/sparc64/kernel/una_asm.S new file mode 100644 index 000000000000..cbb40585253c --- /dev/null +++ b/arch/sparc64/kernel/una_asm.S | |||
@@ -0,0 +1,153 @@ | |||
1 | /* una_asm.S: Kernel unaligned trap assembler helpers. | ||
2 | * | ||
3 | * Copyright (C) 1996,2005 David S. Miller (davem@davemloft.net) | ||
4 | * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) | ||
5 | */ | ||
6 | |||
7 | .text | ||
8 | |||
9 | kernel_unaligned_trap_fault: | ||
10 | call kernel_mna_trap_fault | ||
11 | nop | ||
12 | retl | ||
13 | nop | ||
14 | .size kern_unaligned_trap_fault, .-kern_unaligned_trap_fault | ||
15 | |||
16 | .globl __do_int_store | ||
17 | __do_int_store: | ||
18 | rd %asi, %o4 | ||
19 | wr %o3, 0, %asi | ||
20 | ldx [%o2], %g3 | ||
21 | cmp %o1, 2 | ||
22 | be,pn %icc, 2f | ||
23 | cmp %o1, 4 | ||
24 | be,pt %icc, 1f | ||
25 | srlx %g3, 24, %g2 | ||
26 | srlx %g3, 56, %g1 | ||
27 | srlx %g3, 48, %g7 | ||
28 | 4: stba %g1, [%o0] %asi | ||
29 | srlx %g3, 40, %g1 | ||
30 | 5: stba %g7, [%o0 + 1] %asi | ||
31 | srlx %g3, 32, %g7 | ||
32 | 6: stba %g1, [%o0 + 2] %asi | ||
33 | 7: stba %g7, [%o0 + 3] %asi | ||
34 | srlx %g3, 16, %g1 | ||
35 | 8: stba %g2, [%o0 + 4] %asi | ||
36 | srlx %g3, 8, %g7 | ||
37 | 9: stba %g1, [%o0 + 5] %asi | ||
38 | 10: stba %g7, [%o0 + 6] %asi | ||
39 | ba,pt %xcc, 0f | ||
40 | 11: stba %g3, [%o0 + 7] %asi | ||
41 | 1: srl %g3, 16, %g7 | ||
42 | 12: stba %g2, [%o0] %asi | ||
43 | srl %g3, 8, %g2 | ||
44 | 13: stba %g7, [%o0 + 1] %asi | ||
45 | 14: stba %g2, [%o0 + 2] %asi | ||
46 | ba,pt %xcc, 0f | ||
47 | 15: stba %g3, [%o0 + 3] %asi | ||
48 | 2: srl %g3, 8, %g2 | ||
49 | 16: stba %g2, [%o0] %asi | ||
50 | 17: stba %g3, [%o0 + 1] %asi | ||
51 | 0: | ||
52 | wr %o4, 0x0, %asi | ||
53 | retl | ||
54 | nop | ||
55 | .size __do_int_store, .-__do_int_store | ||
56 | |||
57 | .section __ex_table | ||
58 | .word 4b, kernel_unaligned_trap_fault | ||
59 | .word 5b, kernel_unaligned_trap_fault | ||
60 | .word 6b, kernel_unaligned_trap_fault | ||
61 | .word 7b, kernel_unaligned_trap_fault | ||
62 | .word 8b, kernel_unaligned_trap_fault | ||
63 | .word 9b, kernel_unaligned_trap_fault | ||
64 | .word 10b, kernel_unaligned_trap_fault | ||
65 | .word 11b, kernel_unaligned_trap_fault | ||
66 | .word 12b, kernel_unaligned_trap_fault | ||
67 | .word 13b, kernel_unaligned_trap_fault | ||
68 | .word 14b, kernel_unaligned_trap_fault | ||
69 | .word 15b, kernel_unaligned_trap_fault | ||
70 | .word 16b, kernel_unaligned_trap_fault | ||
71 | .word 17b, kernel_unaligned_trap_fault | ||
72 | .previous | ||
73 | |||
74 | .globl do_int_load | ||
75 | do_int_load: | ||
76 | rd %asi, %o5 | ||
77 | wr %o4, 0, %asi | ||
78 | cmp %o1, 8 | ||
79 | bge,pn %icc, 9f | ||
80 | cmp %o1, 4 | ||
81 | be,pt %icc, 6f | ||
82 | 4: lduba [%o2] %asi, %g2 | ||
83 | 5: lduba [%o2 + 1] %asi, %g3 | ||
84 | sll %g2, 8, %g2 | ||
85 | brz,pt %o3, 3f | ||
86 | add %g2, %g3, %g2 | ||
87 | sllx %g2, 48, %g2 | ||
88 | srax %g2, 48, %g2 | ||
89 | 3: ba,pt %xcc, 0f | ||
90 | stx %g2, [%o0] | ||
91 | 6: lduba [%o2 + 1] %asi, %g3 | ||
92 | sll %g2, 24, %g2 | ||
93 | 7: lduba [%o2 + 2] %asi, %g7 | ||
94 | sll %g3, 16, %g3 | ||
95 | 8: lduba [%o2 + 3] %asi, %g1 | ||
96 | sll %g7, 8, %g7 | ||
97 | or %g2, %g3, %g2 | ||
98 | or %g7, %g1, %g7 | ||
99 | or %g2, %g7, %g2 | ||
100 | brnz,a,pt %o3, 3f | ||
101 | sra %g2, 0, %g2 | ||
102 | 3: ba,pt %xcc, 0f | ||
103 | stx %g2, [%o0] | ||
104 | 9: lduba [%o2] %asi, %g2 | ||
105 | 10: lduba [%o2 + 1] %asi, %g3 | ||
106 | sllx %g2, 56, %g2 | ||
107 | 11: lduba [%o2 + 2] %asi, %g7 | ||
108 | sllx %g3, 48, %g3 | ||
109 | 12: lduba [%o2 + 3] %asi, %g1 | ||
110 | sllx %g7, 40, %g7 | ||
111 | sllx %g1, 32, %g1 | ||
112 | or %g2, %g3, %g2 | ||
113 | or %g7, %g1, %g7 | ||
114 | 13: lduba [%o2 + 4] %asi, %g3 | ||
115 | or %g2, %g7, %g7 | ||
116 | 14: lduba [%o2 + 5] %asi, %g1 | ||
117 | sllx %g3, 24, %g3 | ||
118 | 15: lduba [%o2 + 6] %asi, %g2 | ||
119 | sllx %g1, 16, %g1 | ||
120 | or %g7, %g3, %g7 | ||
121 | 16: lduba [%o2 + 7] %asi, %g3 | ||
122 | sllx %g2, 8, %g2 | ||
123 | or %g7, %g1, %g7 | ||
124 | or %g2, %g3, %g2 | ||
125 | or %g7, %g2, %g7 | ||
126 | cmp %o1, 8 | ||
127 | be,a,pt %icc, 0f | ||
128 | stx %g7, [%o0] | ||
129 | srlx %g7, 32, %g2 | ||
130 | sra %g7, 0, %g7 | ||
131 | stx %g2, [%o0] | ||
132 | stx %g7, [%o0 + 8] | ||
133 | 0: | ||
134 | wr %o5, 0x0, %asi | ||
135 | retl | ||
136 | nop | ||
137 | .size __do_int_load, .-__do_int_load | ||
138 | |||
139 | .section __ex_table | ||
140 | .word 4b, kernel_unaligned_trap_fault | ||
141 | .word 5b, kernel_unaligned_trap_fault | ||
142 | .word 6b, kernel_unaligned_trap_fault | ||
143 | .word 7b, kernel_unaligned_trap_fault | ||
144 | .word 8b, kernel_unaligned_trap_fault | ||
145 | .word 9b, kernel_unaligned_trap_fault | ||
146 | .word 10b, kernel_unaligned_trap_fault | ||
147 | .word 11b, kernel_unaligned_trap_fault | ||
148 | .word 12b, kernel_unaligned_trap_fault | ||
149 | .word 13b, kernel_unaligned_trap_fault | ||
150 | .word 14b, kernel_unaligned_trap_fault | ||
151 | .word 15b, kernel_unaligned_trap_fault | ||
152 | .word 16b, kernel_unaligned_trap_fault | ||
153 | .previous | ||
diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c index 4372bf32ecf6..da9739f0d437 100644 --- a/arch/sparc64/kernel/unaligned.c +++ b/arch/sparc64/kernel/unaligned.c | |||
@@ -180,169 +180,28 @@ static void __attribute_used__ unaligned_panic(char *str, struct pt_regs *regs) | |||
180 | die_if_kernel(str, regs); | 180 | die_if_kernel(str, regs); |
181 | } | 181 | } |
182 | 182 | ||
183 | #define do_integer_load(dest_reg, size, saddr, is_signed, asi, errh) ({ \ | 183 | extern void do_int_load(unsigned long *dest_reg, int size, |
184 | __asm__ __volatile__ ( \ | 184 | unsigned long *saddr, int is_signed, int asi); |
185 | "wr %4, 0, %%asi\n\t" \ | ||
186 | "cmp %1, 8\n\t" \ | ||
187 | "bge,pn %%icc, 9f\n\t" \ | ||
188 | " cmp %1, 4\n\t" \ | ||
189 | "be,pt %%icc, 6f\n" \ | ||
190 | "4:\t" " lduba [%2] %%asi, %%l1\n" \ | ||
191 | "5:\t" "lduba [%2 + 1] %%asi, %%l2\n\t" \ | ||
192 | "sll %%l1, 8, %%l1\n\t" \ | ||
193 | "brz,pt %3, 3f\n\t" \ | ||
194 | " add %%l1, %%l2, %%l1\n\t" \ | ||
195 | "sllx %%l1, 48, %%l1\n\t" \ | ||
196 | "srax %%l1, 48, %%l1\n" \ | ||
197 | "3:\t" "ba,pt %%xcc, 0f\n\t" \ | ||
198 | " stx %%l1, [%0]\n" \ | ||
199 | "6:\t" "lduba [%2 + 1] %%asi, %%l2\n\t" \ | ||
200 | "sll %%l1, 24, %%l1\n" \ | ||
201 | "7:\t" "lduba [%2 + 2] %%asi, %%g7\n\t" \ | ||
202 | "sll %%l2, 16, %%l2\n" \ | ||
203 | "8:\t" "lduba [%2 + 3] %%asi, %%g1\n\t" \ | ||
204 | "sll %%g7, 8, %%g7\n\t" \ | ||
205 | "or %%l1, %%l2, %%l1\n\t" \ | ||
206 | "or %%g7, %%g1, %%g7\n\t" \ | ||
207 | "or %%l1, %%g7, %%l1\n\t" \ | ||
208 | "brnz,a,pt %3, 3f\n\t" \ | ||
209 | " sra %%l1, 0, %%l1\n" \ | ||
210 | "3:\t" "ba,pt %%xcc, 0f\n\t" \ | ||
211 | " stx %%l1, [%0]\n" \ | ||
212 | "9:\t" "lduba [%2] %%asi, %%l1\n" \ | ||
213 | "10:\t" "lduba [%2 + 1] %%asi, %%l2\n\t" \ | ||
214 | "sllx %%l1, 56, %%l1\n" \ | ||
215 | "11:\t" "lduba [%2 + 2] %%asi, %%g7\n\t" \ | ||
216 | "sllx %%l2, 48, %%l2\n" \ | ||
217 | "12:\t" "lduba [%2 + 3] %%asi, %%g1\n\t" \ | ||
218 | "sllx %%g7, 40, %%g7\n\t" \ | ||
219 | "sllx %%g1, 32, %%g1\n\t" \ | ||
220 | "or %%l1, %%l2, %%l1\n\t" \ | ||
221 | "or %%g7, %%g1, %%g7\n" \ | ||
222 | "13:\t" "lduba [%2 + 4] %%asi, %%l2\n\t" \ | ||
223 | "or %%l1, %%g7, %%g7\n" \ | ||
224 | "14:\t" "lduba [%2 + 5] %%asi, %%g1\n\t" \ | ||
225 | "sllx %%l2, 24, %%l2\n" \ | ||
226 | "15:\t" "lduba [%2 + 6] %%asi, %%l1\n\t" \ | ||
227 | "sllx %%g1, 16, %%g1\n\t" \ | ||
228 | "or %%g7, %%l2, %%g7\n" \ | ||
229 | "16:\t" "lduba [%2 + 7] %%asi, %%l2\n\t" \ | ||
230 | "sllx %%l1, 8, %%l1\n\t" \ | ||
231 | "or %%g7, %%g1, %%g7\n\t" \ | ||
232 | "or %%l1, %%l2, %%l1\n\t" \ | ||
233 | "or %%g7, %%l1, %%g7\n\t" \ | ||
234 | "cmp %1, 8\n\t" \ | ||
235 | "be,a,pt %%icc, 0f\n\t" \ | ||
236 | " stx %%g7, [%0]\n\t" \ | ||
237 | "srlx %%g7, 32, %%l1\n\t" \ | ||
238 | "sra %%g7, 0, %%g7\n\t" \ | ||
239 | "stx %%l1, [%0]\n\t" \ | ||
240 | "stx %%g7, [%0 + 8]\n" \ | ||
241 | "0:\n\t" \ | ||
242 | "wr %%g0, %5, %%asi\n\n\t" \ | ||
243 | ".section __ex_table\n\t" \ | ||
244 | ".word 4b, " #errh "\n\t" \ | ||
245 | ".word 5b, " #errh "\n\t" \ | ||
246 | ".word 6b, " #errh "\n\t" \ | ||
247 | ".word 7b, " #errh "\n\t" \ | ||
248 | ".word 8b, " #errh "\n\t" \ | ||
249 | ".word 9b, " #errh "\n\t" \ | ||
250 | ".word 10b, " #errh "\n\t" \ | ||
251 | ".word 11b, " #errh "\n\t" \ | ||
252 | ".word 12b, " #errh "\n\t" \ | ||
253 | ".word 13b, " #errh "\n\t" \ | ||
254 | ".word 14b, " #errh "\n\t" \ | ||
255 | ".word 15b, " #errh "\n\t" \ | ||
256 | ".word 16b, " #errh "\n\n\t" \ | ||
257 | ".previous\n\t" \ | ||
258 | : : "r" (dest_reg), "r" (size), "r" (saddr), "r" (is_signed), \ | ||
259 | "r" (asi), "i" (ASI_AIUS) \ | ||
260 | : "l1", "l2", "g7", "g1", "cc"); \ | ||
261 | }) | ||
262 | 185 | ||
263 | #define store_common(dst_addr, size, src_val, asi, errh) ({ \ | 186 | extern void __do_int_store(unsigned long *dst_addr, int size, |
264 | __asm__ __volatile__ ( \ | 187 | unsigned long *src_val, int asi); |
265 | "wr %3, 0, %%asi\n\t" \ | 188 | |
266 | "ldx [%2], %%l1\n" \ | 189 | static inline void do_int_store(int reg_num, int size, unsigned long *dst_addr, |
267 | "cmp %1, 2\n\t" \ | 190 | struct pt_regs *regs, int asi) |
268 | "be,pn %%icc, 2f\n\t" \ | 191 | { |
269 | " cmp %1, 4\n\t" \ | 192 | unsigned long zero = 0; |
270 | "be,pt %%icc, 1f\n\t" \ | 193 | unsigned long *src_val = &zero; |
271 | " srlx %%l1, 24, %%l2\n\t" \ | 194 | |
272 | "srlx %%l1, 56, %%g1\n\t" \ | 195 | if (size == 16) { |
273 | "srlx %%l1, 48, %%g7\n" \ | 196 | size = 8; |
274 | "4:\t" "stba %%g1, [%0] %%asi\n\t" \ | 197 | zero = (((long)(reg_num ? |
275 | "srlx %%l1, 40, %%g1\n" \ | 198 | (unsigned)fetch_reg(reg_num, regs) : 0)) << 32) | |
276 | "5:\t" "stba %%g7, [%0 + 1] %%asi\n\t" \ | 199 | (unsigned)fetch_reg(reg_num + 1, regs); |
277 | "srlx %%l1, 32, %%g7\n" \ | 200 | } else if (reg_num) { |
278 | "6:\t" "stba %%g1, [%0 + 2] %%asi\n" \ | 201 | src_val = fetch_reg_addr(reg_num, regs); |
279 | "7:\t" "stba %%g7, [%0 + 3] %%asi\n\t" \ | 202 | } |
280 | "srlx %%l1, 16, %%g1\n" \ | 203 | __do_int_store(dst_addr, size, src_val, asi); |
281 | "8:\t" "stba %%l2, [%0 + 4] %%asi\n\t" \ | 204 | } |
282 | "srlx %%l1, 8, %%g7\n" \ | ||
283 | "9:\t" "stba %%g1, [%0 + 5] %%asi\n" \ | ||
284 | "10:\t" "stba %%g7, [%0 + 6] %%asi\n\t" \ | ||
285 | "ba,pt %%xcc, 0f\n" \ | ||
286 | "11:\t" " stba %%l1, [%0 + 7] %%asi\n" \ | ||
287 | "1:\t" "srl %%l1, 16, %%g7\n" \ | ||
288 | "12:\t" "stba %%l2, [%0] %%asi\n\t" \ | ||
289 | "srl %%l1, 8, %%l2\n" \ | ||
290 | "13:\t" "stba %%g7, [%0 + 1] %%asi\n" \ | ||
291 | "14:\t" "stba %%l2, [%0 + 2] %%asi\n\t" \ | ||
292 | "ba,pt %%xcc, 0f\n" \ | ||
293 | "15:\t" " stba %%l1, [%0 + 3] %%asi\n" \ | ||
294 | "2:\t" "srl %%l1, 8, %%l2\n" \ | ||
295 | "16:\t" "stba %%l2, [%0] %%asi\n" \ | ||
296 | "17:\t" "stba %%l1, [%0 + 1] %%asi\n" \ | ||
297 | "0:\n\t" \ | ||
298 | "wr %%g0, %4, %%asi\n\n\t" \ | ||
299 | ".section __ex_table\n\t" \ | ||
300 | ".word 4b, " #errh "\n\t" \ | ||
301 | ".word 5b, " #errh "\n\t" \ | ||
302 | ".word 6b, " #errh "\n\t" \ | ||
303 | ".word 7b, " #errh "\n\t" \ | ||
304 | ".word 8b, " #errh "\n\t" \ | ||
305 | ".word 9b, " #errh "\n\t" \ | ||
306 | ".word 10b, " #errh "\n\t" \ | ||
307 | ".word 11b, " #errh "\n\t" \ | ||
308 | ".word 12b, " #errh "\n\t" \ | ||
309 | ".word 13b, " #errh "\n\t" \ | ||
310 | ".word 14b, " #errh "\n\t" \ | ||
311 | ".word 15b, " #errh "\n\t" \ | ||
312 | ".word 16b, " #errh "\n\t" \ | ||
313 | ".word 17b, " #errh "\n\n\t" \ | ||
314 | ".previous\n\t" \ | ||
315 | : : "r" (dst_addr), "r" (size), "r" (src_val), "r" (asi), "i" (ASI_AIUS)\ | ||
316 | : "l1", "l2", "g7", "g1", "cc"); \ | ||
317 | }) | ||
318 | |||
319 | #define do_integer_store(reg_num, size, dst_addr, regs, asi, errh) ({ \ | ||
320 | unsigned long zero = 0; \ | ||
321 | unsigned long *src_val = &zero; \ | ||
322 | \ | ||
323 | if (size == 16) { \ | ||
324 | size = 8; \ | ||
325 | zero = (((long)(reg_num ? \ | ||
326 | (unsigned)fetch_reg(reg_num, regs) : 0)) << 32) | \ | ||
327 | (unsigned)fetch_reg(reg_num + 1, regs); \ | ||
328 | } else if (reg_num) src_val = fetch_reg_addr(reg_num, regs); \ | ||
329 | store_common(dst_addr, size, src_val, asi, errh); \ | ||
330 | }) | ||
331 | |||
332 | extern void smp_capture(void); | ||
333 | extern void smp_release(void); | ||
334 | |||
335 | #define do_atomic(srcdest_reg, mem, errh) ({ \ | ||
336 | unsigned long flags, tmp; \ | ||
337 | \ | ||
338 | smp_capture(); \ | ||
339 | local_irq_save(flags); \ | ||
340 | tmp = *srcdest_reg; \ | ||
341 | do_integer_load(srcdest_reg, 4, mem, 0, errh); \ | ||
342 | store_common(mem, 4, &tmp, errh); \ | ||
343 | local_irq_restore(flags); \ | ||
344 | smp_release(); \ | ||
345 | }) | ||
346 | 205 | ||
347 | static inline void advance(struct pt_regs *regs) | 206 | static inline void advance(struct pt_regs *regs) |
348 | { | 207 | { |
@@ -364,24 +223,29 @@ static inline int ok_for_kernel(unsigned int insn) | |||
364 | return !floating_point_load_or_store_p(insn); | 223 | return !floating_point_load_or_store_p(insn); |
365 | } | 224 | } |
366 | 225 | ||
367 | void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("kernel_mna_trap_fault"); | 226 | void kernel_mna_trap_fault(void) |
368 | |||
369 | void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn) | ||
370 | { | 227 | { |
371 | unsigned long g2 = regs->u_regs [UREG_G2]; | 228 | struct pt_regs *regs = current_thread_info()->kern_una_regs; |
229 | unsigned int insn = current_thread_info()->kern_una_insn; | ||
230 | unsigned long g2 = regs->u_regs[UREG_G2]; | ||
372 | unsigned long fixup = search_extables_range(regs->tpc, &g2); | 231 | unsigned long fixup = search_extables_range(regs->tpc, &g2); |
373 | 232 | ||
374 | if (!fixup) { | 233 | if (!fixup) { |
375 | unsigned long address = compute_effective_address(regs, insn, ((insn >> 25) & 0x1f)); | 234 | unsigned long address; |
235 | |||
236 | address = compute_effective_address(regs, insn, | ||
237 | ((insn >> 25) & 0x1f)); | ||
376 | if (address < PAGE_SIZE) { | 238 | if (address < PAGE_SIZE) { |
377 | printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference in mna handler"); | 239 | printk(KERN_ALERT "Unable to handle kernel NULL " |
240 | "pointer dereference in mna handler"); | ||
378 | } else | 241 | } else |
379 | printk(KERN_ALERT "Unable to handle kernel paging request in mna handler"); | 242 | printk(KERN_ALERT "Unable to handle kernel paging " |
243 | "request in mna handler"); | ||
380 | printk(KERN_ALERT " at virtual address %016lx\n",address); | 244 | printk(KERN_ALERT " at virtual address %016lx\n",address); |
381 | printk(KERN_ALERT "current->{mm,active_mm}->context = %016lx\n", | 245 | printk(KERN_ALERT "current->{active_,}mm->context = %016lx\n", |
382 | (current->mm ? CTX_HWBITS(current->mm->context) : | 246 | (current->mm ? CTX_HWBITS(current->mm->context) : |
383 | CTX_HWBITS(current->active_mm->context))); | 247 | CTX_HWBITS(current->active_mm->context))); |
384 | printk(KERN_ALERT "current->{mm,active_mm}->pgd = %016lx\n", | 248 | printk(KERN_ALERT "current->{active_,}mm->pgd = %016lx\n", |
385 | (current->mm ? (unsigned long) current->mm->pgd : | 249 | (current->mm ? (unsigned long) current->mm->pgd : |
386 | (unsigned long) current->active_mm->pgd)); | 250 | (unsigned long) current->active_mm->pgd)); |
387 | die_if_kernel("Oops", regs); | 251 | die_if_kernel("Oops", regs); |
@@ -400,48 +264,41 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn, u | |||
400 | enum direction dir = decode_direction(insn); | 264 | enum direction dir = decode_direction(insn); |
401 | int size = decode_access_size(insn); | 265 | int size = decode_access_size(insn); |
402 | 266 | ||
267 | current_thread_info()->kern_una_regs = regs; | ||
268 | current_thread_info()->kern_una_insn = insn; | ||
269 | |||
403 | if (!ok_for_kernel(insn) || dir == both) { | 270 | if (!ok_for_kernel(insn) || dir == both) { |
404 | printk("Unsupported unaligned load/store trap for kernel at <%016lx>.\n", | 271 | printk("Unsupported unaligned load/store trap for kernel " |
405 | regs->tpc); | 272 | "at <%016lx>.\n", regs->tpc); |
406 | unaligned_panic("Kernel does fpu/atomic unaligned load/store.", regs); | 273 | unaligned_panic("Kernel does fpu/atomic " |
407 | 274 | "unaligned load/store.", regs); | |
408 | __asm__ __volatile__ ("\n" | 275 | |
409 | "kernel_unaligned_trap_fault:\n\t" | 276 | kernel_mna_trap_fault(); |
410 | "mov %0, %%o0\n\t" | ||
411 | "call kernel_mna_trap_fault\n\t" | ||
412 | " mov %1, %%o1\n\t" | ||
413 | : | ||
414 | : "r" (regs), "r" (insn) | ||
415 | : "o0", "o1", "o2", "o3", "o4", "o5", "o7", | ||
416 | "g1", "g2", "g3", "g4", "g7", "cc"); | ||
417 | } else { | 277 | } else { |
418 | unsigned long addr = compute_effective_address(regs, insn, ((insn >> 25) & 0x1f)); | 278 | unsigned long addr; |
419 | 279 | ||
280 | addr = compute_effective_address(regs, insn, | ||
281 | ((insn >> 25) & 0x1f)); | ||
420 | #ifdef DEBUG_MNA | 282 | #ifdef DEBUG_MNA |
421 | printk("KMNA: pc=%016lx [dir=%s addr=%016lx size=%d] retpc[%016lx]\n", | 283 | printk("KMNA: pc=%016lx [dir=%s addr=%016lx size=%d] " |
422 | regs->tpc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]); | 284 | "retpc[%016lx]\n", |
285 | regs->tpc, dirstrings[dir], addr, size, | ||
286 | regs->u_regs[UREG_RETPC]); | ||
423 | #endif | 287 | #endif |
424 | switch (dir) { | 288 | switch (dir) { |
425 | case load: | 289 | case load: |
426 | do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs), | 290 | do_int_load(fetch_reg_addr(((insn>>25)&0x1f), regs), |
427 | size, (unsigned long *) addr, | 291 | size, (unsigned long *) addr, |
428 | decode_signedness(insn), decode_asi(insn, regs), | 292 | decode_signedness(insn), |
429 | kernel_unaligned_trap_fault); | 293 | decode_asi(insn, regs)); |
430 | break; | 294 | break; |
431 | 295 | ||
432 | case store: | 296 | case store: |
433 | do_integer_store(((insn>>25)&0x1f), size, | 297 | do_int_store(((insn>>25)&0x1f), size, |
434 | (unsigned long *) addr, regs, | 298 | (unsigned long *) addr, regs, |
435 | decode_asi(insn, regs), | 299 | decode_asi(insn, regs)); |
436 | kernel_unaligned_trap_fault); | ||
437 | break; | ||
438 | #if 0 /* unsupported */ | ||
439 | case both: | ||
440 | do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs), | ||
441 | (unsigned long *) addr, | ||
442 | kernel_unaligned_trap_fault); | ||
443 | break; | 300 | break; |
444 | #endif | 301 | |
445 | default: | 302 | default: |
446 | panic("Impossible kernel unaligned trap."); | 303 | panic("Impossible kernel unaligned trap."); |
447 | /* Not reached... */ | 304 | /* Not reached... */ |
@@ -492,9 +349,9 @@ int handle_popc(u32 insn, struct pt_regs *regs) | |||
492 | 349 | ||
493 | extern void do_fpother(struct pt_regs *regs); | 350 | extern void do_fpother(struct pt_regs *regs); |
494 | extern void do_privact(struct pt_regs *regs); | 351 | extern void do_privact(struct pt_regs *regs); |
495 | extern void data_access_exception(struct pt_regs *regs, | 352 | extern void spitfire_data_access_exception(struct pt_regs *regs, |
496 | unsigned long sfsr, | 353 | unsigned long sfsr, |
497 | unsigned long sfar); | 354 | unsigned long sfar); |
498 | 355 | ||
499 | int handle_ldf_stq(u32 insn, struct pt_regs *regs) | 356 | int handle_ldf_stq(u32 insn, struct pt_regs *regs) |
500 | { | 357 | { |
@@ -537,14 +394,14 @@ int handle_ldf_stq(u32 insn, struct pt_regs *regs) | |||
537 | break; | 394 | break; |
538 | } | 395 | } |
539 | default: | 396 | default: |
540 | data_access_exception(regs, 0, addr); | 397 | spitfire_data_access_exception(regs, 0, addr); |
541 | return 1; | 398 | return 1; |
542 | } | 399 | } |
543 | if (put_user (first >> 32, (u32 __user *)addr) || | 400 | if (put_user (first >> 32, (u32 __user *)addr) || |
544 | __put_user ((u32)first, (u32 __user *)(addr + 4)) || | 401 | __put_user ((u32)first, (u32 __user *)(addr + 4)) || |
545 | __put_user (second >> 32, (u32 __user *)(addr + 8)) || | 402 | __put_user (second >> 32, (u32 __user *)(addr + 8)) || |
546 | __put_user ((u32)second, (u32 __user *)(addr + 12))) { | 403 | __put_user ((u32)second, (u32 __user *)(addr + 12))) { |
547 | data_access_exception(regs, 0, addr); | 404 | spitfire_data_access_exception(regs, 0, addr); |
548 | return 1; | 405 | return 1; |
549 | } | 406 | } |
550 | } else { | 407 | } else { |
@@ -557,7 +414,7 @@ int handle_ldf_stq(u32 insn, struct pt_regs *regs) | |||
557 | do_privact(regs); | 414 | do_privact(regs); |
558 | return 1; | 415 | return 1; |
559 | } else if (asi > ASI_SNFL) { | 416 | } else if (asi > ASI_SNFL) { |
560 | data_access_exception(regs, 0, addr); | 417 | spitfire_data_access_exception(regs, 0, addr); |
561 | return 1; | 418 | return 1; |
562 | } | 419 | } |
563 | switch (insn & 0x180000) { | 420 | switch (insn & 0x180000) { |
@@ -574,7 +431,7 @@ int handle_ldf_stq(u32 insn, struct pt_regs *regs) | |||
574 | err |= __get_user (data[i], (u32 __user *)(addr + 4*i)); | 431 | err |= __get_user (data[i], (u32 __user *)(addr + 4*i)); |
575 | } | 432 | } |
576 | if (err && !(asi & 0x2 /* NF */)) { | 433 | if (err && !(asi & 0x2 /* NF */)) { |
577 | data_access_exception(regs, 0, addr); | 434 | spitfire_data_access_exception(regs, 0, addr); |
578 | return 1; | 435 | return 1; |
579 | } | 436 | } |
580 | if (asi & 0x8) /* Little */ { | 437 | if (asi & 0x8) /* Little */ { |
@@ -677,7 +534,7 @@ void handle_lddfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr | |||
677 | *(u64 *)(f->regs + freg) = value; | 534 | *(u64 *)(f->regs + freg) = value; |
678 | current_thread_info()->fpsaved[0] |= flag; | 535 | current_thread_info()->fpsaved[0] |= flag; |
679 | } else { | 536 | } else { |
680 | daex: data_access_exception(regs, sfsr, sfar); | 537 | daex: spitfire_data_access_exception(regs, sfsr, sfar); |
681 | return; | 538 | return; |
682 | } | 539 | } |
683 | advance(regs); | 540 | advance(regs); |
@@ -721,7 +578,7 @@ void handle_stdfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr | |||
721 | __put_user ((u32)value, (u32 __user *)(sfar + 4))) | 578 | __put_user ((u32)value, (u32 __user *)(sfar + 4))) |
722 | goto daex; | 579 | goto daex; |
723 | } else { | 580 | } else { |
724 | daex: data_access_exception(regs, sfsr, sfar); | 581 | daex: spitfire_data_access_exception(regs, sfsr, sfar); |
725 | return; | 582 | return; |
726 | } | 583 | } |
727 | advance(regs); | 584 | advance(regs); |
diff --git a/arch/sparc64/kernel/us2e_cpufreq.c b/arch/sparc64/kernel/us2e_cpufreq.c index 7aae0a18aabe..686e526bec04 100644 --- a/arch/sparc64/kernel/us2e_cpufreq.c +++ b/arch/sparc64/kernel/us2e_cpufreq.c | |||
@@ -88,7 +88,6 @@ static void frob_mem_refresh(int cpu_slowing_down, | |||
88 | { | 88 | { |
89 | unsigned long old_refr_count, refr_count, mctrl; | 89 | unsigned long old_refr_count, refr_count, mctrl; |
90 | 90 | ||
91 | |||
92 | refr_count = (clock_tick * MCTRL0_REFR_INTERVAL); | 91 | refr_count = (clock_tick * MCTRL0_REFR_INTERVAL); |
93 | refr_count /= (MCTRL0_REFR_CLKS_P_CNT * divisor * 1000000000UL); | 92 | refr_count /= (MCTRL0_REFR_CLKS_P_CNT * divisor * 1000000000UL); |
94 | 93 | ||
@@ -230,6 +229,25 @@ static unsigned long estar_to_divisor(unsigned long estar) | |||
230 | return ret; | 229 | return ret; |
231 | } | 230 | } |
232 | 231 | ||
232 | static unsigned int us2e_freq_get(unsigned int cpu) | ||
233 | { | ||
234 | cpumask_t cpus_allowed; | ||
235 | unsigned long clock_tick, estar; | ||
236 | |||
237 | if (!cpu_online(cpu)) | ||
238 | return 0; | ||
239 | |||
240 | cpus_allowed = current->cpus_allowed; | ||
241 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | ||
242 | |||
243 | clock_tick = sparc64_get_clock_tick(cpu) / 1000; | ||
244 | estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR); | ||
245 | |||
246 | set_cpus_allowed(current, cpus_allowed); | ||
247 | |||
248 | return clock_tick / estar_to_divisor(estar); | ||
249 | } | ||
250 | |||
233 | static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index) | 251 | static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index) |
234 | { | 252 | { |
235 | unsigned long new_bits, new_freq; | 253 | unsigned long new_bits, new_freq; |
@@ -243,7 +261,7 @@ static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index) | |||
243 | cpus_allowed = current->cpus_allowed; | 261 | cpus_allowed = current->cpus_allowed; |
244 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | 262 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); |
245 | 263 | ||
246 | new_freq = clock_tick = sparc64_get_clock_tick(cpu); | 264 | new_freq = clock_tick = sparc64_get_clock_tick(cpu) / 1000; |
247 | new_bits = index_to_estar_mode(index); | 265 | new_bits = index_to_estar_mode(index); |
248 | divisor = index_to_divisor(index); | 266 | divisor = index_to_divisor(index); |
249 | new_freq /= divisor; | 267 | new_freq /= divisor; |
@@ -258,7 +276,8 @@ static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index) | |||
258 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | 276 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); |
259 | 277 | ||
260 | if (old_divisor != divisor) | 278 | if (old_divisor != divisor) |
261 | us2e_transition(estar, new_bits, clock_tick, old_divisor, divisor); | 279 | us2e_transition(estar, new_bits, clock_tick * 1000, |
280 | old_divisor, divisor); | ||
262 | 281 | ||
263 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | 282 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); |
264 | 283 | ||
@@ -272,10 +291,8 @@ static int us2e_freq_target(struct cpufreq_policy *policy, | |||
272 | unsigned int new_index = 0; | 291 | unsigned int new_index = 0; |
273 | 292 | ||
274 | if (cpufreq_frequency_table_target(policy, | 293 | if (cpufreq_frequency_table_target(policy, |
275 | &us2e_freq_table[policy->cpu].table[0], | 294 | &us2e_freq_table[policy->cpu].table[0], |
276 | target_freq, | 295 | target_freq, relation, &new_index)) |
277 | relation, | ||
278 | &new_index)) | ||
279 | return -EINVAL; | 296 | return -EINVAL; |
280 | 297 | ||
281 | us2e_set_cpu_divider_index(policy->cpu, new_index); | 298 | us2e_set_cpu_divider_index(policy->cpu, new_index); |
@@ -292,7 +309,7 @@ static int us2e_freq_verify(struct cpufreq_policy *policy) | |||
292 | static int __init us2e_freq_cpu_init(struct cpufreq_policy *policy) | 309 | static int __init us2e_freq_cpu_init(struct cpufreq_policy *policy) |
293 | { | 310 | { |
294 | unsigned int cpu = policy->cpu; | 311 | unsigned int cpu = policy->cpu; |
295 | unsigned long clock_tick = sparc64_get_clock_tick(cpu); | 312 | unsigned long clock_tick = sparc64_get_clock_tick(cpu) / 1000; |
296 | struct cpufreq_frequency_table *table = | 313 | struct cpufreq_frequency_table *table = |
297 | &us2e_freq_table[cpu].table[0]; | 314 | &us2e_freq_table[cpu].table[0]; |
298 | 315 | ||
@@ -351,9 +368,10 @@ static int __init us2e_freq_init(void) | |||
351 | memset(us2e_freq_table, 0, | 368 | memset(us2e_freq_table, 0, |
352 | (NR_CPUS * sizeof(struct us2e_freq_percpu_info))); | 369 | (NR_CPUS * sizeof(struct us2e_freq_percpu_info))); |
353 | 370 | ||
371 | driver->init = us2e_freq_cpu_init; | ||
354 | driver->verify = us2e_freq_verify; | 372 | driver->verify = us2e_freq_verify; |
355 | driver->target = us2e_freq_target; | 373 | driver->target = us2e_freq_target; |
356 | driver->init = us2e_freq_cpu_init; | 374 | driver->get = us2e_freq_get; |
357 | driver->exit = us2e_freq_cpu_exit; | 375 | driver->exit = us2e_freq_cpu_exit; |
358 | driver->owner = THIS_MODULE, | 376 | driver->owner = THIS_MODULE, |
359 | strcpy(driver->name, "UltraSPARC-IIe"); | 377 | strcpy(driver->name, "UltraSPARC-IIe"); |
diff --git a/arch/sparc64/kernel/us3_cpufreq.c b/arch/sparc64/kernel/us3_cpufreq.c index 18fe54b8aa55..9080e7cd4bb0 100644 --- a/arch/sparc64/kernel/us3_cpufreq.c +++ b/arch/sparc64/kernel/us3_cpufreq.c | |||
@@ -56,7 +56,7 @@ static void write_safari_cfg(unsigned long val) | |||
56 | 56 | ||
57 | static unsigned long get_current_freq(unsigned int cpu, unsigned long safari_cfg) | 57 | static unsigned long get_current_freq(unsigned int cpu, unsigned long safari_cfg) |
58 | { | 58 | { |
59 | unsigned long clock_tick = sparc64_get_clock_tick(cpu); | 59 | unsigned long clock_tick = sparc64_get_clock_tick(cpu) / 1000; |
60 | unsigned long ret; | 60 | unsigned long ret; |
61 | 61 | ||
62 | switch (safari_cfg & SAFARI_CFG_DIV_MASK) { | 62 | switch (safari_cfg & SAFARI_CFG_DIV_MASK) { |
@@ -76,6 +76,26 @@ static unsigned long get_current_freq(unsigned int cpu, unsigned long safari_cfg | |||
76 | return ret; | 76 | return ret; |
77 | } | 77 | } |
78 | 78 | ||
79 | static unsigned int us3_freq_get(unsigned int cpu) | ||
80 | { | ||
81 | cpumask_t cpus_allowed; | ||
82 | unsigned long reg; | ||
83 | unsigned int ret; | ||
84 | |||
85 | if (!cpu_online(cpu)) | ||
86 | return 0; | ||
87 | |||
88 | cpus_allowed = current->cpus_allowed; | ||
89 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | ||
90 | |||
91 | reg = read_safari_cfg(); | ||
92 | ret = get_current_freq(cpu, reg); | ||
93 | |||
94 | set_cpus_allowed(current, cpus_allowed); | ||
95 | |||
96 | return ret; | ||
97 | } | ||
98 | |||
79 | static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index) | 99 | static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index) |
80 | { | 100 | { |
81 | unsigned long new_bits, new_freq, reg; | 101 | unsigned long new_bits, new_freq, reg; |
@@ -88,7 +108,7 @@ static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index) | |||
88 | cpus_allowed = current->cpus_allowed; | 108 | cpus_allowed = current->cpus_allowed; |
89 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | 109 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); |
90 | 110 | ||
91 | new_freq = sparc64_get_clock_tick(cpu); | 111 | new_freq = sparc64_get_clock_tick(cpu) / 1000; |
92 | switch (index) { | 112 | switch (index) { |
93 | case 0: | 113 | case 0: |
94 | new_bits = SAFARI_CFG_DIV_1; | 114 | new_bits = SAFARI_CFG_DIV_1; |
@@ -150,7 +170,7 @@ static int us3_freq_verify(struct cpufreq_policy *policy) | |||
150 | static int __init us3_freq_cpu_init(struct cpufreq_policy *policy) | 170 | static int __init us3_freq_cpu_init(struct cpufreq_policy *policy) |
151 | { | 171 | { |
152 | unsigned int cpu = policy->cpu; | 172 | unsigned int cpu = policy->cpu; |
153 | unsigned long clock_tick = sparc64_get_clock_tick(cpu); | 173 | unsigned long clock_tick = sparc64_get_clock_tick(cpu) / 1000; |
154 | struct cpufreq_frequency_table *table = | 174 | struct cpufreq_frequency_table *table = |
155 | &us3_freq_table[cpu].table[0]; | 175 | &us3_freq_table[cpu].table[0]; |
156 | 176 | ||
@@ -206,9 +226,10 @@ static int __init us3_freq_init(void) | |||
206 | memset(us3_freq_table, 0, | 226 | memset(us3_freq_table, 0, |
207 | (NR_CPUS * sizeof(struct us3_freq_percpu_info))); | 227 | (NR_CPUS * sizeof(struct us3_freq_percpu_info))); |
208 | 228 | ||
229 | driver->init = us3_freq_cpu_init; | ||
209 | driver->verify = us3_freq_verify; | 230 | driver->verify = us3_freq_verify; |
210 | driver->target = us3_freq_target; | 231 | driver->target = us3_freq_target; |
211 | driver->init = us3_freq_cpu_init; | 232 | driver->get = us3_freq_get; |
212 | driver->exit = us3_freq_cpu_exit; | 233 | driver->exit = us3_freq_cpu_exit; |
213 | driver->owner = THIS_MODULE, | 234 | driver->owner = THIS_MODULE, |
214 | strcpy(driver->name, "UltraSPARC-III"); | 235 | strcpy(driver->name, "UltraSPARC-III"); |
diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S index 950423da8a6a..f47d0be39378 100644 --- a/arch/sparc64/kernel/vmlinux.lds.S +++ b/arch/sparc64/kernel/vmlinux.lds.S | |||
@@ -17,6 +17,7 @@ SECTIONS | |||
17 | *(.text) | 17 | *(.text) |
18 | SCHED_TEXT | 18 | SCHED_TEXT |
19 | LOCK_TEXT | 19 | LOCK_TEXT |
20 | KPROBES_TEXT | ||
20 | *(.gnu.warning) | 21 | *(.gnu.warning) |
21 | } =0 | 22 | } =0 |
22 | _etext = .; | 23 | _etext = .; |
diff --git a/arch/sparc64/kernel/winfixup.S b/arch/sparc64/kernel/winfixup.S index dfbc7e0dcf70..99c809a1e5ac 100644 --- a/arch/sparc64/kernel/winfixup.S +++ b/arch/sparc64/kernel/winfixup.S | |||
@@ -318,7 +318,7 @@ fill_fixup_dax: | |||
318 | nop | 318 | nop |
319 | rdpr %pstate, %l1 ! Prepare to change globals. | 319 | rdpr %pstate, %l1 ! Prepare to change globals. |
320 | mov %g4, %o1 ! Setup args for | 320 | mov %g4, %o1 ! Setup args for |
321 | mov %g5, %o2 ! final call to data_access_exception. | 321 | mov %g5, %o2 ! final call to spitfire_data_access_exception. |
322 | andn %l1, PSTATE_MM, %l1 ! We want to be in RMO | 322 | andn %l1, PSTATE_MM, %l1 ! We want to be in RMO |
323 | 323 | ||
324 | mov %g6, %o7 ! Stash away current. | 324 | mov %g6, %o7 ! Stash away current. |
@@ -330,7 +330,7 @@ fill_fixup_dax: | |||
330 | mov TSB_REG, %g1 | 330 | mov TSB_REG, %g1 |
331 | ldxa [%g1] ASI_IMMU, %g5 | 331 | ldxa [%g1] ASI_IMMU, %g5 |
332 | #endif | 332 | #endif |
333 | call data_access_exception | 333 | call spitfire_data_access_exception |
334 | add %sp, PTREGS_OFF, %o0 | 334 | add %sp, PTREGS_OFF, %o0 |
335 | 335 | ||
336 | b,pt %xcc, rtrap | 336 | b,pt %xcc, rtrap |
@@ -391,7 +391,7 @@ window_dax_from_user_common: | |||
391 | 109: or %g7, %lo(109b), %g7 | 391 | 109: or %g7, %lo(109b), %g7 |
392 | mov %l4, %o1 | 392 | mov %l4, %o1 |
393 | mov %l5, %o2 | 393 | mov %l5, %o2 |
394 | call data_access_exception | 394 | call spitfire_data_access_exception |
395 | add %sp, PTREGS_OFF, %o0 | 395 | add %sp, PTREGS_OFF, %o0 |
396 | ba,pt %xcc, rtrap | 396 | ba,pt %xcc, rtrap |
397 | clr %l6 | 397 | clr %l6 |