aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/entry.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/entry.S')
-rw-r--r--arch/sparc64/kernel/entry.S293
1 files changed, 181 insertions, 112 deletions
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index 88332f00094a..cecdc0a7521f 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 7441: 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
7541: 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
7661: /* 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
7841: ba,pt %xcc, etrap_irq
785 rd %pc, %g7
786
7872: 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: 8631: sethi %hi(109f), %g7
864 ba,pt %xcc, etraptl1
865109: 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:
722109: or %g7, %lo(109b), %g7 884109: 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:
743109: or %g7, %lo(109b), %g7 904109: 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,102 +922,11 @@ __do_instruction_access_exception:
762109: or %g7, %lo(109b), %g7 922109: 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
801cee_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
8261: 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
8401: 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. 930 /* Capture I/D/E-cache state into per-cpu error scoreboard.
862 * 931 *
863 * %g1: (TL>=0) ? 1 : 0 932 * %g1: (TL>=0) ? 1 : 0