Upgrade to 4.4.50-rt62
[kvmfornfv.git] / kernel / arch / sparc / kernel / spiterrs.S
1         /* We need to carefully read the error status, ACK the errors,
2          * prevent recursive traps, and pass the information on to C
3          * code for logging.
4          *
5          * We pass the AFAR in as-is, and we encode the status
6          * information as described in asm-sparc64/sfafsr.h
7          */
8         .type           __spitfire_access_error,#function
9 __spitfire_access_error:
10         /* Disable ESTATE error reporting so that we do not take
11          * recursive traps and RED state the processor.
12          */
13         stxa            %g0, [%g0] ASI_ESTATE_ERROR_EN
14         membar          #Sync
15
16         mov             UDBE_UE, %g1
17         ldxa            [%g0] ASI_AFSR, %g4     ! Get AFSR
18
19         /* __spitfire_cee_trap branches here with AFSR in %g4 and
20          * UDBE_CE in %g1.  It only clears ESTATE_ERR_CE in the ESTATE
21          * Error Enable register.
22          */
23 __spitfire_cee_trap_continue:
24         ldxa            [%g0] ASI_AFAR, %g5     ! Get AFAR
25
26         rdpr            %tt, %g3
27         and             %g3, 0x1ff, %g3         ! Paranoia
28         sllx            %g3, SFSTAT_TRAP_TYPE_SHIFT, %g3
29         or              %g4, %g3, %g4
30         rdpr            %tl, %g3
31         cmp             %g3, 1
32         mov             1, %g3
33         bleu            %xcc, 1f
34          sllx           %g3, SFSTAT_TL_GT_ONE_SHIFT, %g3
35
36         or              %g4, %g3, %g4
37
38         /* Read in the UDB error register state, clearing the sticky
39          * error bits as-needed.  We only clear them if the UE bit is
40          * set.  Likewise, __spitfire_cee_trap below will only do so
41          * if the CE bit is set.
42          *
43          * NOTE: UltraSparc-I/II have high and low UDB error
44          *       registers, corresponding to the two UDB units
45          *       present on those chips.  UltraSparc-IIi only
46          *       has a single UDB, called "SDB" in the manual.
47          *       For IIi the upper UDB register always reads
48          *       as zero so for our purposes things will just
49          *       work with the checks below.
50          */
51 1:      ldxa            [%g0] ASI_UDBH_ERROR_R, %g3
52         and             %g3, 0x3ff, %g7         ! Paranoia
53         sllx            %g7, SFSTAT_UDBH_SHIFT, %g7
54         or              %g4, %g7, %g4
55         andcc           %g3, %g1, %g3           ! UDBE_UE or UDBE_CE
56         be,pn           %xcc, 1f
57          nop
58         stxa            %g3, [%g0] ASI_UDB_ERROR_W
59         membar          #Sync
60
61 1:      mov             0x18, %g3
62         ldxa            [%g3] ASI_UDBL_ERROR_R, %g3
63         and             %g3, 0x3ff, %g7         ! Paranoia
64         sllx            %g7, SFSTAT_UDBL_SHIFT, %g7
65         or              %g4, %g7, %g4
66         andcc           %g3, %g1, %g3           ! UDBE_UE or UDBE_CE
67         be,pn           %xcc, 1f
68          nop
69         mov             0x18, %g7
70         stxa            %g3, [%g7] ASI_UDB_ERROR_W
71         membar          #Sync
72
73 1:      /* Ok, now that we've latched the error state, clear the
74          * sticky bits in the AFSR.
75          */
76         stxa            %g4, [%g0] ASI_AFSR
77         membar          #Sync
78
79         rdpr            %tl, %g2
80         cmp             %g2, 1
81         rdpr            %pil, %g2
82         bleu,pt         %xcc, 1f
83          wrpr           %g0, PIL_NORMAL_MAX, %pil
84
85         ba,pt           %xcc, etraptl1
86          rd             %pc, %g7
87
88         ba,a,pt         %xcc, 2f
89
90 1:      ba,pt           %xcc, etrap_irq
91          rd             %pc, %g7
92
93 2:
94 #ifdef CONFIG_TRACE_IRQFLAGS
95         call    trace_hardirqs_off
96          nop
97 #endif
98         mov             %l4, %o1
99         mov             %l5, %o2
100         call            spitfire_access_error
101          add            %sp, PTREGS_OFF, %o0
102         ba,a,pt         %xcc, rtrap
103         .size           __spitfire_access_error,.-__spitfire_access_error
104
105         /* This is the trap handler entry point for ECC correctable
106          * errors.  They are corrected, but we listen for the trap so
107          * that the event can be logged.
108          *
109          * Disrupting errors are either:
110          * 1) single-bit ECC errors during UDB reads to system
111          *    memory
112          * 2) data parity errors during write-back events
113          *
114          * As far as I can make out from the manual, the CEE trap is
115          * only for correctable errors during memory read accesses by
116          * the front-end of the processor.
117          *
118          * The code below is only for trap level 1 CEE events, as it
119          * is the only situation where we can safely record and log.
120          * For trap level >1 we just clear the CE bit in the AFSR and
121          * return.
122          *
123          * This is just like __spiftire_access_error above, but it
124          * specifically handles correctable errors.  If an
125          * uncorrectable error is indicated in the AFSR we will branch
126          * directly above to __spitfire_access_error to handle it
127          * instead.  Uncorrectable therefore takes priority over
128          * correctable, and the error logging C code will notice this
129          * case by inspecting the trap type.
130          */
131         .type           __spitfire_cee_trap,#function
132 __spitfire_cee_trap:
133         ldxa            [%g0] ASI_AFSR, %g4     ! Get AFSR
134         mov             1, %g3
135         sllx            %g3, SFAFSR_UE_SHIFT, %g3
136         andcc           %g4, %g3, %g0           ! Check for UE
137         bne,pn          %xcc, __spitfire_access_error
138          nop
139
140         /* Ok, in this case we only have a correctable error.
141          * Indicate we only wish to capture that state in register
142          * %g1, and we only disable CE error reporting unlike UE
143          * handling which disables all errors.
144          */
145         ldxa            [%g0] ASI_ESTATE_ERROR_EN, %g3
146         andn            %g3, ESTATE_ERR_CE, %g3
147         stxa            %g3, [%g0] ASI_ESTATE_ERROR_EN
148         membar          #Sync
149
150         /* Preserve AFSR in %g4, indicate UDB state to capture in %g1 */
151         ba,pt           %xcc, __spitfire_cee_trap_continue
152          mov            UDBE_CE, %g1
153         .size           __spitfire_cee_trap,.-__spitfire_cee_trap
154
155         .type           __spitfire_data_access_exception_tl1,#function
156 __spitfire_data_access_exception_tl1:
157         rdpr            %pstate, %g4
158         wrpr            %g4, PSTATE_MG|PSTATE_AG, %pstate
159         mov             TLB_SFSR, %g3
160         mov             DMMU_SFAR, %g5
161         ldxa            [%g3] ASI_DMMU, %g4     ! Get SFSR
162         ldxa            [%g5] ASI_DMMU, %g5     ! Get SFAR
163         stxa            %g0, [%g3] ASI_DMMU     ! Clear SFSR.FaultValid bit
164         membar          #Sync
165         rdpr            %tt, %g3
166         cmp             %g3, 0x80               ! first win spill/fill trap
167         blu,pn          %xcc, 1f
168          cmp            %g3, 0xff               ! last win spill/fill trap
169         bgu,pn          %xcc, 1f
170          nop
171         ba,pt           %xcc, winfix_dax
172          rdpr           %tpc, %g3
173 1:      sethi           %hi(109f), %g7
174         ba,pt           %xcc, etraptl1
175 109:     or             %g7, %lo(109b), %g7
176         mov             %l4, %o1
177         mov             %l5, %o2
178         call            spitfire_data_access_exception_tl1
179          add            %sp, PTREGS_OFF, %o0
180         ba,a,pt         %xcc, rtrap
181         .size           __spitfire_data_access_exception_tl1,.-__spitfire_data_access_exception_tl1
182
183         .type           __spitfire_data_access_exception,#function
184 __spitfire_data_access_exception:
185         rdpr            %pstate, %g4
186         wrpr            %g4, PSTATE_MG|PSTATE_AG, %pstate
187         mov             TLB_SFSR, %g3
188         mov             DMMU_SFAR, %g5
189         ldxa            [%g3] ASI_DMMU, %g4     ! Get SFSR
190         ldxa            [%g5] ASI_DMMU, %g5     ! Get SFAR
191         stxa            %g0, [%g3] ASI_DMMU     ! Clear SFSR.FaultValid bit
192         membar          #Sync
193         sethi           %hi(109f), %g7
194         ba,pt           %xcc, etrap
195 109:     or             %g7, %lo(109b), %g7
196         mov             %l4, %o1
197         mov             %l5, %o2
198         call            spitfire_data_access_exception
199          add            %sp, PTREGS_OFF, %o0
200         ba,a,pt         %xcc, rtrap
201         .size           __spitfire_data_access_exception,.-__spitfire_data_access_exception
202
203         .type           __spitfire_insn_access_exception_tl1,#function
204 __spitfire_insn_access_exception_tl1:
205         rdpr            %pstate, %g4
206         wrpr            %g4, PSTATE_MG|PSTATE_AG, %pstate
207         mov             TLB_SFSR, %g3
208         ldxa            [%g3] ASI_IMMU, %g4     ! Get SFSR
209         rdpr            %tpc, %g5               ! IMMU has no SFAR, use TPC
210         stxa            %g0, [%g3] ASI_IMMU     ! Clear FaultValid bit
211         membar          #Sync
212         sethi           %hi(109f), %g7
213         ba,pt           %xcc, etraptl1
214 109:     or             %g7, %lo(109b), %g7
215         mov             %l4, %o1
216         mov             %l5, %o2
217         call            spitfire_insn_access_exception_tl1
218          add            %sp, PTREGS_OFF, %o0
219         ba,a,pt         %xcc, rtrap
220         .size           __spitfire_insn_access_exception_tl1,.-__spitfire_insn_access_exception_tl1
221
222         .type           __spitfire_insn_access_exception,#function
223 __spitfire_insn_access_exception:
224         rdpr            %pstate, %g4
225         wrpr            %g4, PSTATE_MG|PSTATE_AG, %pstate
226         mov             TLB_SFSR, %g3
227         ldxa            [%g3] ASI_IMMU, %g4     ! Get SFSR
228         rdpr            %tpc, %g5               ! IMMU has no SFAR, use TPC
229         stxa            %g0, [%g3] ASI_IMMU     ! Clear FaultValid bit
230         membar          #Sync
231         sethi           %hi(109f), %g7
232         ba,pt           %xcc, etrap
233 109:     or             %g7, %lo(109b), %g7
234         mov             %l4, %o1
235         mov             %l5, %o2
236         call            spitfire_insn_access_exception
237          add            %sp, PTREGS_OFF, %o0
238         ba,a,pt         %xcc, rtrap
239         .size           __spitfire_insn_access_exception,.-__spitfire_insn_access_exception