Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * Hypervisor Software File: errors_traps.s | |
5 | * | |
6 | * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
7 | * | |
8 | * - Do no alter or remove copyright notices | |
9 | * | |
10 | * - Redistribution and use of this software in source and binary forms, with | |
11 | * or without modification, are permitted provided that the following | |
12 | * conditions are met: | |
13 | * | |
14 | * - Redistribution of source code must retain the above copyright notice, | |
15 | * this list of conditions and the following disclaimer. | |
16 | * | |
17 | * - Redistribution in binary form must reproduce the above copyright notice, | |
18 | * this list of conditions and the following disclaimer in the | |
19 | * documentation and/or other materials provided with the distribution. | |
20 | * | |
21 | * Neither the name of Sun Microsystems, Inc. or the names of contributors | |
22 | * may be used to endorse or promote products derived from this software | |
23 | * without specific prior written permission. | |
24 | * | |
25 | * This software is provided "AS IS," without a warranty of any kind. | |
26 | * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, | |
27 | * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A | |
28 | * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN | |
29 | * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR | |
30 | * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR | |
31 | * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN | |
32 | * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR | |
33 | * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE | |
34 | * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, | |
35 | * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF | |
36 | * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
37 | * | |
38 | * You acknowledge that this software is not designed, licensed or | |
39 | * intended for use in the design, construction, operation or maintenance of | |
40 | * any nuclear facility. | |
41 | * | |
42 | * ========== Copyright Header End ============================================ | |
43 | */ | |
44 | /* | |
45 | * Copyright 2007 Sun Microsystems, Inc. All rights reserved. | |
46 | * Use is subject to license terms. | |
47 | */ | |
48 | ||
49 | #pragma ident "@(#)errors_traps.s 1.7 07/08/17 SMI" | |
50 | ||
51 | #include <sys/asm_linkage.h> | |
52 | #include <hypervisor.h> | |
53 | #include <asi.h> | |
54 | #include <mmu.h> | |
55 | #include <hprivregs.h> | |
56 | #include <sun4v/traps.h> | |
57 | ||
58 | #include <offsets.h> | |
59 | #include <util.h> | |
60 | #include <error_defs.h> | |
61 | #include <error_regs.h> | |
62 | #include <error_asm.h> | |
63 | #include <error_soc.h> | |
64 | #include <error_ssi.h> | |
65 | #include <cmp.h> | |
66 | ||
67 | ||
68 | /* | |
69 | * %g1 I-SFSR | |
70 | */ | |
71 | ENTRY(instruction_access_MMU_error) | |
72 | ||
73 | CLEAR_SOC_INJECTOR_REG(%g2, %g3) | |
74 | ||
75 | SAVE_GLOBALS(%g1) | |
76 | ||
77 | PARK_ALL_STRANDS(%g2, %g3, %g4, %g5) | |
78 | ||
79 | ! clear cached copy of ESRs from strand struct | |
80 | STORE_ERR_DESR(%g0, %g3, %g4) | |
81 | STORE_ERR_DFESR(%g0, %g3, %g4) | |
82 | STORE_ERR_DSFSR(%g0, %g3, %g4) | |
83 | STORE_ERR_DSFAR(%g0, %g3, %g4) | |
84 | STORE_ERR_ISFSR(%g0, %g3, %g4) | |
85 | ||
86 | /* | |
87 | * Identify the error from the I-SFSR and get the | |
88 | * instruction_access_MMU_errors[] entry for that error | |
89 | */ | |
90 | mov MMU_SFAR, %g2 | |
91 | ldxa [%g2]ASI_DMMU, %g1 | |
92 | STORE_ERR_DSFAR(%g1, %g3, %g4) | |
93 | mov MMU_SFSR, %g2 | |
94 | ldxa [%g2]ASI_IMMU, %g1 | |
95 | STORE_ERR_ISFSR(%g1, %g3, %g4) | |
96 | stxa %g0, [%g2]ASI_IMMU | |
97 | ||
98 | and %g1, ISFSR_ERRTYPE_MASK, %g1 | |
99 | mulx %g1, ERROR_TABLE_ENTRY_SIZE, %g1 | |
100 | setx instruction_access_MMU_errors, %g2, %g3 | |
101 | add %g1, %g3, %g1 | |
102 | RELOC_OFFSET(%g6, %g5) | |
103 | sub %g1, %g5, %g1 | |
104 | ba error_handler | |
105 | nop | |
106 | ||
107 | SET_SIZE(instruction_access_MMU_error) | |
108 | ||
109 | /* | |
110 | * %g1 D-SFSR | |
111 | */ | |
112 | ENTRY(data_access_MMU_error) | |
113 | ||
114 | CLEAR_SOC_INJECTOR_REG(%g2, %g3) | |
115 | ||
116 | SAVE_GLOBALS(%g1) | |
117 | ||
118 | PARK_ALL_STRANDS(%g2, %g3, %g4, %g5) | |
119 | ||
120 | ! clear cached copy of ESRs from strand struct | |
121 | STORE_ERR_DESR(%g0, %g3, %g4) | |
122 | STORE_ERR_DFESR(%g0, %g3, %g4) | |
123 | STORE_ERR_DSFSR(%g0, %g3, %g4) | |
124 | STORE_ERR_DSFAR(%g0, %g3, %g4) | |
125 | STORE_ERR_ISFSR(%g0, %g3, %g4) | |
126 | ||
127 | /* | |
128 | * Identify the error from the D-SFSR and get the | |
129 | * data_access_MMU_errors[] entry for that error | |
130 | */ | |
131 | mov MMU_SFAR, %g2 | |
132 | ldxa [%g2]ASI_DMMU, %g1 | |
133 | STORE_ERR_DSFAR(%g1, %g3, %g4) | |
134 | mov MMU_SFSR, %g2 | |
135 | ldxa [%g2]ASI_DMMU, %g1 | |
136 | STORE_ERR_DSFSR(%g1, %g3, %g4) | |
137 | stxa %g0, [%g2]ASI_DMMU | |
138 | ||
139 | and %g1, DSFSR_ERRTYPE_MASK, %g1 | |
140 | mulx %g1, ERROR_TABLE_ENTRY_SIZE, %g1 | |
141 | setx data_access_MMU_errors, %g2, %g3 | |
142 | add %g1, %g3, %g1 | |
143 | RELOC_OFFSET(%g6, %g5) | |
144 | sub %g1, %g5, %g1 | |
145 | ba error_handler | |
146 | nop | |
147 | ||
148 | SET_SIZE(data_access_MMU_error) | |
149 | ||
150 | /* | |
151 | * No args | |
152 | */ | |
153 | ENTRY(internal_processor_error) | |
154 | ||
155 | CLEAR_SOC_INJECTOR_REG(%g2, %g3) | |
156 | ||
157 | SAVE_GLOBALS(%g1) | |
158 | ||
159 | SCRATCHPAD_ERROR() | |
160 | ||
161 | PARK_ALL_STRANDS(%g2, %g3, %g4, %g5) | |
162 | ||
163 | ! clear cached copy of ESRs from strand struct | |
164 | STORE_ERR_DESR(%g0, %g3, %g4) | |
165 | STORE_ERR_DFESR(%g0, %g3, %g4) | |
166 | STORE_ERR_DSFSR(%g0, %g3, %g4) | |
167 | STORE_ERR_DSFAR(%g0, %g3, %g4) | |
168 | STORE_ERR_ISFSR(%g0, %g3, %g4) | |
169 | ||
170 | mov MMU_SFAR, %g2 | |
171 | ldxa [%g2]ASI_DMMU, %g1 | |
172 | STORE_ERR_DSFAR(%g1, %g3, %g4) | |
173 | mov MMU_SFSR, %g2 | |
174 | ldxa [%g2]ASI_DMMU, %g1 | |
175 | STORE_ERR_DSFSR(%g1, %g3, %g4) | |
176 | stxa %g0, [%g2]ASI_DMMU | |
177 | ||
178 | /* | |
179 | * Identify the error from the D-SFSR and get the | |
180 | * internal_processor_errors[] entry for that error | |
181 | */ | |
182 | and %g1, DSFSR_ERRTYPE_MASK, %g1 | |
183 | mulx %g1, ERROR_TABLE_ENTRY_SIZE, %g1 | |
184 | setx internal_processor_errors, %g2, %g3 | |
185 | add %g1, %g3, %g1 | |
186 | RELOC_OFFSET(%g6, %g5) | |
187 | sub %g1, %g5, %g1 | |
188 | ba error_handler | |
189 | nop | |
190 | ||
191 | SET_SIZE(internal_processor_error) | |
192 | ||
193 | /* | |
194 | * Common routine for both hw_corrected and | |
195 | * sw_recoverable traps. | |
196 | * | |
197 | * No args | |
198 | */ | |
199 | ENTRY(hw_corrected_error) | |
200 | ALTENTRY(sw_recoverable_error) | |
201 | ||
202 | CLEAR_SOC_INJECTOR_REG(%g2, %g3) | |
203 | ||
204 | ! clear cached copy of ESRs from strand struct | |
205 | STORE_ERR_DESR(%g0, %g3, %g4) | |
206 | STORE_ERR_DFESR(%g0, %g3, %g4) | |
207 | STORE_ERR_DSFSR(%g0, %g3, %g4) | |
208 | STORE_ERR_DSFAR(%g0, %g3, %g4) | |
209 | STORE_ERR_ISFSR(%g0, %g3, %g4) | |
210 | ||
211 | /* | |
212 | * Identify the error from the DESR and get the | |
213 | * correct errors table[] entry for that error | |
214 | */ | |
215 | mov DESR_VA, %g1 | |
216 | ldxa [%g1]ASI_DESR, %g1 | |
217 | ||
218 | /* | |
219 | * Note: Reading the DESR will clear the register. We need | |
220 | * to store it for later use by the error handler. | |
221 | */ | |
222 | STORE_ERR_DESR(%g1, %g3, %g4) | |
223 | ||
224 | setx DESR_S, %g2, %g3 | |
225 | btst %g3, %g1 | |
226 | bz %xcc, 1f | |
227 | nop | |
228 | ||
229 | setx sw_recoverable_errors, %g2, %g3 | |
230 | ba 2f | |
231 | nop | |
232 | 1: | |
233 | setx hw_corrected_errors, %g2, %g3 | |
234 | 2: | |
235 | srlx %g1, DESR_ERRTYPE_SHIFT, %g1 | |
236 | and %g1, DESR_ERRTYPE_MASK, %g1 | |
237 | mulx %g1, ERROR_TABLE_ENTRY_SIZE, %g1 | |
238 | add %g1, %g3, %g1 | |
239 | RELOC_OFFSET(%g6, %g5) | |
240 | sub %g1, %g5, %g1 | |
241 | ||
242 | ba common_correctable_errors | |
243 | nop | |
244 | ||
245 | SET_SIZE(sw_recoverable_error) | |
246 | SET_SIZE(hw_corrected_error) | |
247 | ||
248 | ! %g1 error table entry | |
249 | ENTRY(common_correctable_errors) | |
250 | ||
251 | /* | |
252 | * Check if we need to differentiate between L2 Cache and DRAM | |
253 | * uncorrectable/correctable errors for this error type. | |
254 | * Check if this is an L2$ error and we need to use | |
255 | * the L2 error table | |
256 | */ | |
257 | ld [%g1 + ERR_FLAGS], %g2 | |
258 | set ERR_CHECK_DAU_TYPE, %g3 | |
259 | btst %g3, %g2 | |
260 | bnz,pn %xcc, common_l2u_errors | |
261 | .empty | |
262 | btst ERR_USE_L2_CACHE_TABLE, %g2 | |
263 | bnz,pn %xcc, 0f | |
264 | nop | |
265 | btst ERR_USE_SOC_TABLE, %g2 | |
266 | bnz,pn %xcc, 3f | |
267 | nop | |
268 | set ERR_USE_DRAM_TABLE, %g3 | |
269 | btst %g3, %g2 | |
270 | bnz,pn %xcc, 4f | |
271 | nop | |
272 | ||
273 | ba,pt %xcc, error_handler | |
274 | nop | |
275 | ||
276 | ! check L2 ESRs | |
277 | 0: | |
278 | /* | |
279 | * Find the bank/ESR in error | |
280 | */ | |
281 | setx (L2_ESR_VEU | L2_ESR_VEC | L2_ESR_DSC | L2_ESR_DSU), %g3, %g2 | |
282 | set (NO_L2_BANKS - 1), %g3 | |
283 | 1: | |
284 | ! skip banks which are disabled. causes hang. | |
285 | SKIP_DISABLED_L2_BANK(%g3, %g4, %g5, 2f) | |
286 | ||
287 | setx L2_ERROR_STATUS_REG, %g4, %g5 | |
288 | sllx %g3, L2_BANK_SHIFT, %g4 | |
289 | or %g5, %g4, %g4 | |
290 | ldx [%g4], %g5 | |
291 | btst %g2, %g5 | |
292 | bz,pt %xcc, 2f ! no valid error on this bank | |
293 | nop | |
294 | ||
295 | setx L2_ESR_ERRORS, %g4, %g6 | |
296 | and %g5, %g6, %g5 | |
297 | brz,pt %g5, 2f ! no error bit set on this bank | |
298 | ||
299 | /* | |
300 | * find first bit set in L2 ESR | |
301 | */ | |
302 | srlx %g5, L2_ESR_ERROR_SHIFT, %g5 | |
303 | neg %g5, %g4 | |
304 | xnor %g5, %g4, %g6 | |
305 | popc %g6, %g4 | |
306 | dec %g4 | |
307 | movrz %g5, %g0, %g4 | |
308 | mulx %g4, ERROR_TABLE_ENTRY_SIZE, %g4 | |
309 | setx l2c_errors, %g2, %g3 | |
310 | add %g4, %g3, %g1 | |
311 | RELOC_OFFSET(%g6, %g5) | |
312 | sub %g1, %g5, %g1 | |
313 | ||
314 | ! some L2C errors are DRAM errors ... | |
315 | setx ERR_USE_DRAM_TABLE, %g4, %g5 | |
316 | ld [%g1 + ERR_FLAGS], %g2 | |
317 | btst %g5, %g2 | |
318 | bnz,pn %xcc, 4f ! check DRAM ESRs | |
319 | nop | |
320 | ||
321 | ba error_handler | |
322 | nop | |
323 | 2: | |
324 | brgz,pt %g3, 1b | |
325 | dec %g3 | |
326 | ||
327 | 3: | |
328 | /* | |
329 | * Check if this is an SOC error and we need to use | |
330 | * the SOC error table | |
331 | */ | |
332 | setx SOC_PENDING_ERROR_STATUS_REG, %g4, %g5 | |
333 | ldx [%g5], %g5 | |
334 | brz,pn %g5, 4f | |
335 | nop | |
336 | ||
337 | /* | |
338 | * find first bit set in SOC ESR | |
339 | */ | |
340 | neg %g5, %g4 | |
341 | xnor %g5, %g4, %g6 | |
342 | popc %g6, %g4 | |
343 | dec %g4 | |
344 | movrz %g5, %g0, %g4 | |
345 | mulx %g4, ERROR_TABLE_ENTRY_SIZE, %g4 | |
346 | setx soc_errors, %g2, %g3 | |
347 | add %g4, %g3, %g1 | |
348 | RELOC_OFFSET(%g6, %g5) | |
349 | sub %g1, %g5, %g1 | |
350 | ba error_handler | |
351 | nop | |
352 | ||
353 | ! check DRAM errors | |
354 | 4: | |
355 | set (NO_DRAM_BANKS - 1), %g3 | |
356 | 5: | |
357 | ! skip banks which are disabled. causes hang. | |
358 | SKIP_DISABLED_DRAM_BANK(%g3, %g4, %g5, 6f) | |
359 | ||
360 | setx DRAM_ESR_BASE, %g4, %g5 | |
361 | sllx %g3, DRAM_BANK_SHIFT, %g2 | |
362 | or %g5, %g2, %g5 | |
363 | ldx [%g5], %g5 | |
364 | brz,pt %g5, 6f ! no error on this bank | |
365 | nop | |
366 | ||
367 | /* | |
368 | * find first bit set in DRAM ESR | |
369 | */ | |
370 | srlx %g5, DRAM_ESR_ERROR_SHIFT, %g5 | |
371 | neg %g5, %g4 | |
372 | xnor %g5, %g4, %g6 | |
373 | popc %g6, %g4 | |
374 | dec %g4 | |
375 | movrz %g5, %g0, %g4 | |
376 | mulx %g4, ERROR_TABLE_ENTRY_SIZE, %g4 | |
377 | setx dram_errors, %g2, %g3 | |
378 | add %g4, %g3, %g1 | |
379 | RELOC_OFFSET(%g6, %g5) | |
380 | sub %g1, %g5, %g1 | |
381 | ba error_handler | |
382 | nop | |
383 | 6: | |
384 | ||
385 | brgz,pt %g3, 5b | |
386 | dec %g3 | |
387 | ||
388 | ! No error found - we cleared the L2 ESR out on an earlier trap | |
389 | retry | |
390 | ||
391 | SET_SIZE(common_correctable_errors) | |
392 | ||
393 | ENTRY(data_access_error) | |
394 | ||
395 | CLEAR_SOC_INJECTOR_REG(%g2, %g3) | |
396 | ||
397 | SAVE_GLOBALS(%g2) | |
398 | ||
399 | PARK_ALL_STRANDS(%g2, %g3, %g4, %g5) | |
400 | ||
401 | ! clear cached copy of ESRs from strand struct | |
402 | STORE_ERR_DESR(%g0, %g3, %g4) | |
403 | STORE_ERR_DFESR(%g0, %g3, %g4) | |
404 | STORE_ERR_DSFSR(%g0, %g3, %g4) | |
405 | STORE_ERR_DSFAR(%g0, %g3, %g4) | |
406 | STORE_ERR_ISFSR(%g0, %g3, %g4) | |
407 | ||
408 | /* | |
409 | * First check for DBU errors | |
410 | */ | |
411 | setx DRAM_ESR_BASE, %g4, %g5 | |
412 | setx DRAM_ESR_DBU, %g4, %g2 | |
413 | set (NO_DRAM_BANKS - 1), %g3 | |
414 | 1: | |
415 | ! skip banks which are disabled. causes hang. | |
416 | SKIP_DISABLED_DRAM_BANK(%g3, %g4, %g6, 2f) | |
417 | ||
418 | sllx %g3, DRAM_BANK_SHIFT, %g4 | |
419 | or %g5, %g4, %g4 | |
420 | ldx [%g4], %g4 | |
421 | btst %g2, %g4 ! check for DBU | |
422 | bz,pt %xcc, 2f | |
423 | nop | |
424 | ||
425 | setx dbu_errors, %g2, %g1 | |
426 | RELOC_OFFSET(%g6, %g5) | |
427 | sub %g1, %g5, %g1 | |
428 | ba error_handler | |
429 | nop | |
430 | 2: | |
431 | ||
432 | brgz,pt %g3, 1b | |
433 | dec %g3 | |
434 | ||
435 | /* | |
436 | * Identify the error from the D-SFSR and get the | |
437 | * data_access_errors[] entry for that error | |
438 | */ | |
439 | mov MMU_SFAR, %g2 | |
440 | ldxa [%g2]ASI_DMMU, %g1 | |
441 | STORE_ERR_DSFAR(%g1, %g3, %g4) | |
442 | mov MMU_SFSR, %g2 | |
443 | ldxa [%g2]ASI_DMMU, %g1 | |
444 | STORE_ERR_DSFSR(%g1, %g3, %g4) | |
445 | stxa %g0, [%g2]ASI_DMMU | |
446 | ||
447 | and %g1, DSFSR_ERRTYPE_MASK, %g1 | |
448 | mulx %g1, ERROR_TABLE_ENTRY_SIZE, %g1 | |
449 | setx data_access_errors, %g2, %g3 | |
450 | add %g1, %g3, %g1 | |
451 | RELOC_OFFSET(%g6, %g5) | |
452 | sub %g1, %g5, %g1 | |
453 | ||
454 | ld [%g1 + ERR_FLAGS], %g2 | |
455 | set ERR_CHECK_DAU_TYPE, %g3 | |
456 | btst %g3, %g2 | |
457 | bnz,pn %xcc, common_l2u_errors | |
458 | nop | |
459 | ||
460 | ba error_handler | |
461 | nop | |
462 | ||
463 | SET_SIZE(data_access_error) | |
464 | ||
465 | /* | |
466 | * deferred store_error trap | |
467 | */ | |
468 | ENTRY(store_error) | |
469 | ||
470 | CLEAR_SOC_INJECTOR_REG(%g2, %g3) | |
471 | ||
472 | SAVE_GLOBALS(%g1) | |
473 | ||
474 | ! clear cached copy of ESRs from strand struct | |
475 | STORE_ERR_DESR(%g0, %g3, %g4) | |
476 | STORE_ERR_DFESR(%g0, %g3, %g4) | |
477 | STORE_ERR_DSFSR(%g0, %g3, %g4) | |
478 | STORE_ERR_DSFAR(%g0, %g3, %g4) | |
479 | STORE_ERR_ISFSR(%g0, %g3, %g4) | |
480 | ||
481 | /* | |
482 | * Identify the error from the DFESR and get the | |
483 | * store_errors[] entry for that error | |
484 | */ | |
485 | mov DFESR_VA, %g1 | |
486 | ldxa [%g1]ASI_DFESR, %g1 | |
487 | ||
488 | /* | |
489 | * Note: Reading the DFESR will clear the register. We need | |
490 | * to store it for later use by the error handler. | |
491 | */ | |
492 | STORE_ERR_DFESR(%g1, %g3, %g4) | |
493 | ||
494 | srlx %g1, DFESR_ERRTYPE_SHIFT, %g1 | |
495 | and %g1, DFESR_ERRTYPE_MASK, %g1 | |
496 | mulx %g1, ERROR_TABLE_ENTRY_SIZE, %g1 | |
497 | setx store_errors, %g2, %g3 | |
498 | add %g1, %g3, %g1 | |
499 | RELOC_OFFSET(%g6, %g5) | |
500 | sub %g1, %g5, %g1 | |
501 | ba error_handler | |
502 | nop | |
503 | ||
504 | SET_SIZE(store_error) | |
505 | ||
506 | /* | |
507 | * %g1 I-SFSR | |
508 | */ | |
509 | ENTRY(instruction_access_error) | |
510 | ||
511 | CLEAR_SOC_INJECTOR_REG(%g2, %g3) | |
512 | ||
513 | SAVE_GLOBALS(%g2) | |
514 | ||
515 | PARK_ALL_STRANDS(%g2, %g3, %g4, %g5) | |
516 | ||
517 | ! clear cached copy of ESRs from strand struct | |
518 | STORE_ERR_DESR(%g0, %g3, %g4) | |
519 | STORE_ERR_DFESR(%g0, %g3, %g4) | |
520 | STORE_ERR_DSFSR(%g0, %g3, %g4) | |
521 | STORE_ERR_DSFAR(%g0, %g3, %g4) | |
522 | STORE_ERR_ISFSR(%g0, %g3, %g4) | |
523 | ||
524 | /* | |
525 | * First check for DBU errors | |
526 | */ | |
527 | setx DRAM_ESR_DBU, %g4, %g2 | |
528 | set (NO_DRAM_BANKS - 1), %g3 | |
529 | setx DRAM_ESR_BASE, %g4, %g5 | |
530 | 1: | |
531 | ! skip banks which are disabled. causes hang. | |
532 | SKIP_DISABLED_DRAM_BANK(%g3, %g4, %g6, 2f) | |
533 | ||
534 | sllx %g3, DRAM_BANK_SHIFT, %g4 | |
535 | or %g5, %g4, %g4 | |
536 | ldx [%g4], %g4 | |
537 | btst %g2, %g4 ! check for DBU | |
538 | bz,pt %xcc, 2f | |
539 | nop | |
540 | ||
541 | setx dbu_errors, %g2, %g1 | |
542 | RELOC_OFFSET(%g6, %g5) | |
543 | sub %g1, %g5, %g1 | |
544 | ba error_handler | |
545 | nop | |
546 | 2: | |
547 | ||
548 | brgz,pt %g3, 1b | |
549 | dec %g3 | |
550 | ||
551 | mov MMU_SFAR, %g2 | |
552 | ldxa [%g2]ASI_DMMU, %g1 | |
553 | STORE_ERR_DSFAR(%g1, %g3, %g4) | |
554 | mov MMU_SFSR, %g2 | |
555 | ldxa [%g2]ASI_IMMU, %g1 | |
556 | STORE_ERR_ISFSR(%g1, %g3, %g4) | |
557 | stxa %g0, [%g2]ASI_IMMU | |
558 | ||
559 | and %g1, ISFSR_ERRTYPE_MASK, %g1 | |
560 | mulx %g1, ERROR_TABLE_ENTRY_SIZE, %g1 | |
561 | setx instruction_access_errors, %g4, %g3 | |
562 | add %g1, %g3, %g1 | |
563 | RELOC_OFFSET(%g6, %g5) | |
564 | sub %g1, %g5, %g1 | |
565 | ||
566 | ld [%g1 + ERR_FLAGS], %g2 | |
567 | set ERR_CHECK_DAU_TYPE, %g3 | |
568 | btst %g3, %g2 | |
569 | bnz,pn %xcc, common_l2u_errors | |
570 | nop | |
571 | ||
572 | ba error_handler | |
573 | nop | |
574 | ||
575 | SET_SIZE(instruction_access_error) | |
576 | ||
577 | /* | |
578 | * SSI error interrupt handler | |
579 | */ | |
580 | ENTRY(ssi_mondo) | |
581 | ||
582 | ! clear cached copy of ESRs from strand struct | |
583 | STORE_ERR_DESR(%g0, %g3, %g4) | |
584 | STORE_ERR_DFESR(%g0, %g3, %g4) | |
585 | STORE_ERR_DSFSR(%g0, %g3, %g4) | |
586 | STORE_ERR_DSFAR(%g0, %g3, %g4) | |
587 | STORE_ERR_ISFSR(%g0, %g3, %g4) | |
588 | ||
589 | setx SSI_LOG, %g2, %g1 | |
590 | ldx [%g1], %g1 | |
591 | and %g1, SSI_LOG_MASK, %g1 | |
592 | brnz,pn %g1, 1f | |
593 | nop | |
594 | ||
595 | ! no error bits set | |
596 | ||
597 | retry | |
598 | ||
599 | 1: | |
600 | ||
601 | /* | |
602 | * find first bit set in SSI LOG | |
603 | */ | |
604 | neg %g1, %g2 | |
605 | xnor %g1, %g2, %g6 | |
606 | popc %g6, %g2 | |
607 | dec %g2 | |
608 | movrz %g1, %g0, %g2 | |
609 | mulx %g2, ERROR_TABLE_ENTRY_SIZE, %g2 | |
610 | setx ssi_errors, %g4, %g3 | |
611 | add %g2, %g3, %g1 | |
612 | RELOC_OFFSET(%g6, %g5) | |
613 | sub %g1, %g5, %g1 | |
614 | ba error_handler | |
615 | nop | |
616 | ||
617 | SET_SIZE(ssi_mondo) | |
618 | ||
619 | /* | |
620 | * Check if this is an LDAU or DAU error | |
621 | * %g1 error table entry | |
622 | */ | |
623 | ENTRY(common_l2u_errors) | |
624 | ||
625 | /* | |
626 | * Find the bank/ESR in error | |
627 | */ | |
628 | setx L2_ESR_LDAU, %g3, %g2 | |
629 | set (NO_L2_BANKS - 1), %g3 | |
630 | 1: | |
631 | ! skip banks which are disabled. causes hang. | |
632 | SKIP_DISABLED_L2_BANK(%g3, %g4, %g5, 4f) | |
633 | ||
634 | setx L2_ERROR_STATUS_REG, %g4, %g5 | |
635 | sllx %g3, L2_BANK_SHIFT, %g4 | |
636 | or %g5, %g4, %g5 | |
637 | ldx [%g5], %g5 | |
638 | ||
639 | btst %g2, %g5 | |
640 | bz,pt %xcc, 4f ! no valid LDAU error on this bank | |
641 | nop | |
642 | ||
643 | rdpr %tt, %g2 | |
644 | cmp %g2, TT_ASYNCERR | |
645 | bne %xcc, 2f | |
646 | nop | |
647 | ||
648 | setx disrupting_ldau_errors, %g2, %g1 | |
649 | RELOC_OFFSET(%g6, %g5) | |
650 | sub %g1, %g5, %g1 | |
651 | ba error_handler | |
652 | nop | |
653 | ||
654 | 2: | |
655 | setx precise_ldau_errors, %g2, %g1 | |
656 | RELOC_OFFSET(%g6, %g5) | |
657 | sub %g1, %g5, %g1 | |
658 | ba error_handler | |
659 | nop | |
660 | 4: | |
661 | brgz,pt %g3, 1b | |
662 | dec %g3 | |
663 | ||
664 | /* | |
665 | * Check if this is an DAU error | |
666 | */ | |
667 | setx DRAM_ESR_DAU, %g3, %g2 | |
668 | set (NO_DRAM_BANKS - 1), %g3 | |
669 | 5: | |
670 | ! skip banks which are disabled. causes hang. | |
671 | SKIP_DISABLED_DRAM_BANK(%g3, %g4, %g5, 7f) | |
672 | ||
673 | setx DRAM_ESR_BASE, %g4, %g5 | |
674 | sllx %g3, DRAM_BANK_SHIFT, %g4 | |
675 | or %g5, %g4, %g5 | |
676 | ldx [%g5], %g5 | |
677 | ||
678 | btst %g2, %g5 | |
679 | bz %xcc, 7f | |
680 | nop | |
681 | ||
682 | rdpr %tt, %g2 | |
683 | cmp %g2, TT_ASYNCERR | |
684 | bne %xcc, 6f | |
685 | nop | |
686 | ||
687 | setx disrupting_dau_errors, %g2, %g1 | |
688 | RELOC_OFFSET(%g6, %g5) | |
689 | sub %g1, %g5, %g1 | |
690 | ba error_handler | |
691 | nop | |
692 | ||
693 | 6: | |
694 | setx precise_dau_errors, %g2, %g1 | |
695 | RELOC_OFFSET(%g6, %g5) | |
696 | sub %g1, %g5, %g1 | |
697 | ba error_handler | |
698 | nop | |
699 | 7: | |
700 | ||
701 | brgz,pt %g3, 5b | |
702 | dec %g3 | |
703 | ||
704 | ba error_handler | |
705 | nop | |
706 | ||
707 | SET_SIZE(common_l2u_errors) |