]> git.karo-electronics.de Git - karo-tx-linux.git/blob - arch/sparc/kernel/spiterrs.S
Merge intel_pstate driver updates for v4.12.
[karo-tx-linux.git] / 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          nop
90
91 1:      ba,pt           %xcc, etrap_irq
92          rd             %pc, %g7
93
94 2:
95 #ifdef CONFIG_TRACE_IRQFLAGS
96         call    trace_hardirqs_off
97          nop
98 #endif
99         mov             %l4, %o1
100         mov             %l5, %o2
101         call            spitfire_access_error
102          add            %sp, PTREGS_OFF, %o0
103         ba,a,pt         %xcc, rtrap
104         .size           __spitfire_access_error,.-__spitfire_access_error
105
106         /* This is the trap handler entry point for ECC correctable
107          * errors.  They are corrected, but we listen for the trap so
108          * that the event can be logged.
109          *
110          * Disrupting errors are either:
111          * 1) single-bit ECC errors during UDB reads to system
112          *    memory
113          * 2) data parity errors during write-back events
114          *
115          * As far as I can make out from the manual, the CEE trap is
116          * only for correctable errors during memory read accesses by
117          * the front-end of the processor.
118          *
119          * The code below is only for trap level 1 CEE events, as it
120          * is the only situation where we can safely record and log.
121          * For trap level >1 we just clear the CE bit in the AFSR and
122          * return.
123          *
124          * This is just like __spiftire_access_error above, but it
125          * specifically handles correctable errors.  If an
126          * uncorrectable error is indicated in the AFSR we will branch
127          * directly above to __spitfire_access_error to handle it
128          * instead.  Uncorrectable therefore takes priority over
129          * correctable, and the error logging C code will notice this
130          * case by inspecting the trap type.
131          */
132         .type           __spitfire_cee_trap,#function
133 __spitfire_cee_trap:
134         ldxa            [%g0] ASI_AFSR, %g4     ! Get AFSR
135         mov             1, %g3
136         sllx            %g3, SFAFSR_UE_SHIFT, %g3
137         andcc           %g4, %g3, %g0           ! Check for UE
138         bne,pn          %xcc, __spitfire_access_error
139          nop
140
141         /* Ok, in this case we only have a correctable error.
142          * Indicate we only wish to capture that state in register
143          * %g1, and we only disable CE error reporting unlike UE
144          * handling which disables all errors.
145          */
146         ldxa            [%g0] ASI_ESTATE_ERROR_EN, %g3
147         andn            %g3, ESTATE_ERR_CE, %g3
148         stxa            %g3, [%g0] ASI_ESTATE_ERROR_EN
149         membar          #Sync
150
151         /* Preserve AFSR in %g4, indicate UDB state to capture in %g1 */
152         ba,pt           %xcc, __spitfire_cee_trap_continue
153          mov            UDBE_CE, %g1
154         .size           __spitfire_cee_trap,.-__spitfire_cee_trap
155
156         .type           __spitfire_data_access_exception_tl1,#function
157 __spitfire_data_access_exception_tl1:
158         rdpr            %pstate, %g4
159         wrpr            %g4, PSTATE_MG|PSTATE_AG, %pstate
160         mov             TLB_SFSR, %g3
161         mov             DMMU_SFAR, %g5
162         ldxa            [%g3] ASI_DMMU, %g4     ! Get SFSR
163         ldxa            [%g5] ASI_DMMU, %g5     ! Get SFAR
164         stxa            %g0, [%g3] ASI_DMMU     ! Clear SFSR.FaultValid bit
165         membar          #Sync
166         rdpr            %tt, %g3
167         cmp             %g3, 0x80               ! first win spill/fill trap
168         blu,pn          %xcc, 1f
169          cmp            %g3, 0xff               ! last win spill/fill trap
170         bgu,pn          %xcc, 1f
171          nop
172         ba,pt           %xcc, winfix_dax
173          rdpr           %tpc, %g3
174 1:      sethi           %hi(109f), %g7
175         ba,pt           %xcc, etraptl1
176 109:     or             %g7, %lo(109b), %g7
177         mov             %l4, %o1
178         mov             %l5, %o2
179         call            spitfire_data_access_exception_tl1
180          add            %sp, PTREGS_OFF, %o0
181         ba,a,pt         %xcc, rtrap
182         .size           __spitfire_data_access_exception_tl1,.-__spitfire_data_access_exception_tl1
183
184         .type           __spitfire_data_access_exception,#function
185 __spitfire_data_access_exception:
186         rdpr            %pstate, %g4
187         wrpr            %g4, PSTATE_MG|PSTATE_AG, %pstate
188         mov             TLB_SFSR, %g3
189         mov             DMMU_SFAR, %g5
190         ldxa            [%g3] ASI_DMMU, %g4     ! Get SFSR
191         ldxa            [%g5] ASI_DMMU, %g5     ! Get SFAR
192         stxa            %g0, [%g3] ASI_DMMU     ! Clear SFSR.FaultValid bit
193         membar          #Sync
194         sethi           %hi(109f), %g7
195         ba,pt           %xcc, etrap
196 109:     or             %g7, %lo(109b), %g7
197         mov             %l4, %o1
198         mov             %l5, %o2
199         call            spitfire_data_access_exception
200          add            %sp, PTREGS_OFF, %o0
201         ba,a,pt         %xcc, rtrap
202         .size           __spitfire_data_access_exception,.-__spitfire_data_access_exception
203
204         .type           __spitfire_insn_access_exception_tl1,#function
205 __spitfire_insn_access_exception_tl1:
206         rdpr            %pstate, %g4
207         wrpr            %g4, PSTATE_MG|PSTATE_AG, %pstate
208         mov             TLB_SFSR, %g3
209         ldxa            [%g3] ASI_IMMU, %g4     ! Get SFSR
210         rdpr            %tpc, %g5               ! IMMU has no SFAR, use TPC
211         stxa            %g0, [%g3] ASI_IMMU     ! Clear FaultValid bit
212         membar          #Sync
213         sethi           %hi(109f), %g7
214         ba,pt           %xcc, etraptl1
215 109:     or             %g7, %lo(109b), %g7
216         mov             %l4, %o1
217         mov             %l5, %o2
218         call            spitfire_insn_access_exception_tl1
219          add            %sp, PTREGS_OFF, %o0
220         ba,a,pt         %xcc, rtrap
221         .size           __spitfire_insn_access_exception_tl1,.-__spitfire_insn_access_exception_tl1
222
223         .type           __spitfire_insn_access_exception,#function
224 __spitfire_insn_access_exception:
225         rdpr            %pstate, %g4
226         wrpr            %g4, PSTATE_MG|PSTATE_AG, %pstate
227         mov             TLB_SFSR, %g3
228         ldxa            [%g3] ASI_IMMU, %g4     ! Get SFSR
229         rdpr            %tpc, %g5               ! IMMU has no SFAR, use TPC
230         stxa            %g0, [%g3] ASI_IMMU     ! Clear FaultValid bit
231         membar          #Sync
232         sethi           %hi(109f), %g7
233         ba,pt           %xcc, etrap
234 109:     or             %g7, %lo(109b), %g7
235         mov             %l4, %o1
236         mov             %l5, %o2
237         call            spitfire_insn_access_exception
238          add            %sp, PTREGS_OFF, %o0
239         ba,a,pt         %xcc, rtrap
240         .size           __spitfire_insn_access_exception,.-__spitfire_insn_access_exception