Print this page
de-linting of .s files
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/sun4u/cpu/us3_common_asm.s
+++ new/usr/src/uts/sun4u/cpu/us3_common_asm.s
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 *
25 25 * Assembly code support for Cheetah/Cheetah+ modules
26 26 */
27 27
28 -#if !defined(lint)
29 28 #include "assym.h"
30 -#endif /* !lint */
31 29
32 30 #include <sys/asm_linkage.h>
33 31 #include <sys/mmu.h>
34 32 #include <vm/hat_sfmmu.h>
35 33 #include <sys/machparam.h>
36 34 #include <sys/machcpuvar.h>
37 35 #include <sys/machthread.h>
38 36 #include <sys/machtrap.h>
39 37 #include <sys/privregs.h>
40 38 #include <sys/trap.h>
41 39 #include <sys/cheetahregs.h>
42 40 #include <sys/us3_module.h>
43 41 #include <sys/xc_impl.h>
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
44 42 #include <sys/intreg.h>
45 43 #include <sys/async.h>
46 44 #include <sys/clock.h>
47 45 #include <sys/cheetahasm.h>
48 46 #include <sys/cmpregs.h>
49 47
50 48 #ifdef TRAPTRACE
51 49 #include <sys/traptrace.h>
52 50 #endif /* TRAPTRACE */
53 51
54 -#if !defined(lint)
55 -
56 52 /* BEGIN CSTYLED */
57 53
58 54 #define DCACHE_FLUSHPAGE(arg1, arg2, tmp1, tmp2, tmp3) \
59 55 ldxa [%g0]ASI_DCU, tmp1 ;\
60 56 btst DCU_DC, tmp1 /* is dcache enabled? */ ;\
61 57 bz,pn %icc, 1f ;\
62 58 ASM_LD(tmp1, dcache_linesize) ;\
63 59 ASM_LD(tmp2, dflush_type) ;\
64 60 cmp tmp2, FLUSHPAGE_TYPE ;\
65 61 be,pt %icc, 2f ;\
66 62 nop ;\
67 63 sllx arg1, CHEETAH_DC_VBIT_SHIFT, arg1/* tag to compare */ ;\
68 64 ASM_LD(tmp3, dcache_size) ;\
69 65 cmp tmp2, FLUSHMATCH_TYPE ;\
70 66 be,pt %icc, 3f ;\
71 67 nop ;\
72 68 /* \
73 69 * flushtype = FLUSHALL_TYPE, flush the whole thing \
74 70 * tmp3 = cache size \
75 71 * tmp1 = cache line size \
76 72 */ \
77 73 sub tmp3, tmp1, tmp2 ;\
78 74 4: \
79 75 stxa %g0, [tmp2]ASI_DC_TAG ;\
80 76 membar #Sync ;\
81 77 cmp %g0, tmp2 ;\
82 78 bne,pt %icc, 4b ;\
83 79 sub tmp2, tmp1, tmp2 ;\
84 80 ba,pt %icc, 1f ;\
85 81 nop ;\
86 82 /* \
87 83 * flushtype = FLUSHPAGE_TYPE \
88 84 * arg1 = pfn \
89 85 * arg2 = virtual color \
90 86 * tmp1 = cache line size \
91 87 * tmp2 = tag from cache \
92 88 * tmp3 = counter \
93 89 */ \
94 90 2: \
95 91 set MMU_PAGESIZE, tmp3 ;\
96 92 sllx arg1, MMU_PAGESHIFT, arg1 /* pfn to 43 bit PA */ ;\
97 93 sub tmp3, tmp1, tmp3 ;\
98 94 4: \
99 95 stxa %g0, [arg1 + tmp3]ASI_DC_INVAL ;\
100 96 membar #Sync ;\
101 97 5: \
102 98 cmp %g0, tmp3 ;\
103 99 bnz,pt %icc, 4b /* branch if not done */ ;\
104 100 sub tmp3, tmp1, tmp3 ;\
105 101 ba,pt %icc, 1f ;\
106 102 nop ;\
107 103 /* \
108 104 * flushtype = FLUSHMATCH_TYPE \
109 105 * arg1 = tag to compare against \
110 106 * tmp1 = cache line size \
111 107 * tmp3 = cache size \
112 108 * arg2 = counter \
113 109 * tmp2 = cache tag \
114 110 */ \
115 111 3: \
116 112 sub tmp3, tmp1, arg2 ;\
117 113 4: \
118 114 ldxa [arg2]ASI_DC_TAG, tmp2 /* read tag */ ;\
119 115 btst CHEETAH_DC_VBIT_MASK, tmp2 ;\
120 116 bz,pn %icc, 5f /* br if no valid sub-blocks */ ;\
121 117 andn tmp2, CHEETAH_DC_VBIT_MASK, tmp2 /* clear out v bits */ ;\
122 118 cmp tmp2, arg1 ;\
123 119 bne,pn %icc, 5f /* branch if tag miss */ ;\
124 120 nop ;\
125 121 stxa %g0, [arg2]ASI_DC_TAG ;\
126 122 membar #Sync ;\
127 123 5: \
128 124 cmp %g0, arg2 ;\
129 125 bne,pt %icc, 4b /* branch if not done */ ;\
130 126 sub arg2, tmp1, arg2 ;\
131 127 1:
132 128
133 129 /*
134 130 * macro that flushes the entire dcache color
135 131 * dcache size = 64K, one way 16K
136 132 *
137 133 * In:
138 134 * arg = virtual color register (not clobbered)
139 135 * way = way#, can either be a constant or a register (not clobbered)
140 136 * tmp1, tmp2, tmp3 = scratch registers
141 137 *
142 138 */
143 139 #define DCACHE_FLUSHCOLOR(arg, way, tmp1, tmp2, tmp3) \
144 140 ldxa [%g0]ASI_DCU, tmp1; \
145 141 btst DCU_DC, tmp1; /* is dcache enabled? */ \
146 142 bz,pn %icc, 1f; \
147 143 ASM_LD(tmp1, dcache_linesize) \
148 144 /* \
149 145 * arg = virtual color \
150 146 * tmp1 = cache line size \
151 147 */ \
152 148 sllx arg, MMU_PAGESHIFT, tmp2; /* color to dcache page */ \
153 149 mov way, tmp3; \
154 150 sllx tmp3, 14, tmp3; /* One way 16K */ \
155 151 or tmp2, tmp3, tmp3; \
156 152 set MMU_PAGESIZE, tmp2; \
157 153 /* \
158 154 * tmp2 = page size \
159 155 * tmp3 = cached page in dcache \
160 156 */ \
161 157 sub tmp2, tmp1, tmp2; \
↓ open down ↓ |
96 lines elided |
↑ open up ↑ |
162 158 2: \
163 159 stxa %g0, [tmp3 + tmp2]ASI_DC_TAG; \
164 160 membar #Sync; \
165 161 cmp %g0, tmp2; \
166 162 bne,pt %icc, 2b; \
167 163 sub tmp2, tmp1, tmp2; \
168 164 1:
169 165
170 166 /* END CSTYLED */
171 167
172 -#endif /* !lint */
173 -
174 168 /*
175 169 * Cheetah MMU and Cache operations.
176 170 */
177 171
178 -#if defined(lint)
179 -
180 -/* ARGSUSED */
181 -void
182 -vtag_flushpage(caddr_t vaddr, uint64_t sfmmup)
183 -{}
184 -
185 -#else /* lint */
186 -
187 172 ENTRY_NP(vtag_flushpage)
188 173 /*
189 174 * flush page from the tlb
190 175 *
191 176 * %o0 = vaddr
192 177 * %o1 = sfmmup
193 178 */
194 179 rdpr %pstate, %o5
195 180 #ifdef DEBUG
196 181 PANIC_IF_INTR_DISABLED_PSTR(%o5, u3_di_label0, %g1)
197 182 #endif /* DEBUG */
198 183 /*
199 184 * disable ints
200 185 */
201 186 andn %o5, PSTATE_IE, %o4
202 187 wrpr %o4, 0, %pstate
203 188
204 189 /*
205 190 * Then, blow out the tlb
206 191 * Interrupts are disabled to prevent the primary ctx register
207 192 * from changing underneath us.
208 193 */
209 194 sethi %hi(ksfmmup), %o3
210 195 ldx [%o3 + %lo(ksfmmup)], %o3
211 196 cmp %o3, %o1
212 197 bne,pt %xcc, 1f ! if not kernel as, go to 1
213 198 sethi %hi(FLUSH_ADDR), %o3
214 199 /*
215 200 * For Kernel demaps use primary. type = page implicitly
216 201 */
217 202 stxa %g0, [%o0]ASI_DTLB_DEMAP /* dmmu flush for KCONTEXT */
218 203 stxa %g0, [%o0]ASI_ITLB_DEMAP /* immu flush for KCONTEXT */
219 204 flush %o3
220 205 retl
221 206 wrpr %g0, %o5, %pstate /* enable interrupts */
222 207 1:
223 208 /*
224 209 * User demap. We need to set the primary context properly.
225 210 * Secondary context cannot be used for Cheetah IMMU.
226 211 * %o0 = vaddr
227 212 * %o1 = sfmmup
228 213 * %o3 = FLUSH_ADDR
229 214 */
230 215 SFMMU_CPU_CNUM(%o1, %g1, %g2) ! %g1 = sfmmu cnum on this CPU
231 216
232 217 ldub [%o1 + SFMMU_CEXT], %o4 ! %o4 = sfmmup->sfmmu_cext
233 218 sll %o4, CTXREG_EXT_SHIFT, %o4
234 219 or %g1, %o4, %g1 ! %g1 = primary pgsz | cnum
235 220
236 221 wrpr %g0, 1, %tl
237 222 set MMU_PCONTEXT, %o4
238 223 or DEMAP_PRIMARY | DEMAP_PAGE_TYPE, %o0, %o0
239 224 ldxa [%o4]ASI_DMMU, %o2 ! %o2 = save old ctxnum
240 225 srlx %o2, CTXREG_NEXT_SHIFT, %o1 ! need to preserve nucleus pgsz
241 226 sllx %o1, CTXREG_NEXT_SHIFT, %o1 ! %o1 = nucleus pgsz
242 227 or %g1, %o1, %g1 ! %g1 = nucleus pgsz | primary pgsz | cnum
243 228 stxa %g1, [%o4]ASI_DMMU ! wr new ctxum
244 229
↓ open down ↓ |
48 lines elided |
↑ open up ↑ |
245 230 stxa %g0, [%o0]ASI_DTLB_DEMAP
246 231 stxa %g0, [%o0]ASI_ITLB_DEMAP
247 232 stxa %o2, [%o4]ASI_DMMU /* restore old ctxnum */
248 233 flush %o3
249 234 wrpr %g0, 0, %tl
250 235
251 236 retl
252 237 wrpr %g0, %o5, %pstate /* enable interrupts */
253 238 SET_SIZE(vtag_flushpage)
254 239
255 -#endif /* lint */
256 -
257 -#if defined(lint)
258 -
259 -void
260 -vtag_flushall(void)
261 -{}
262 -
263 -#else /* lint */
264 -
265 240 ENTRY_NP2(vtag_flushall, demap_all)
266 241 /*
267 242 * flush the tlb
268 243 */
269 244 sethi %hi(FLUSH_ADDR), %o3
270 245 set DEMAP_ALL_TYPE, %g1
271 246 stxa %g0, [%g1]ASI_DTLB_DEMAP
272 247 stxa %g0, [%g1]ASI_ITLB_DEMAP
273 248 flush %o3
274 249 retl
275 250 nop
276 251 SET_SIZE(demap_all)
277 252 SET_SIZE(vtag_flushall)
278 253
279 -#endif /* lint */
280 254
281 -
282 -#if defined(lint)
283 -
284 -/* ARGSUSED */
285 -void
286 -vtag_flushpage_tl1(uint64_t vaddr, uint64_t sfmmup)
287 -{}
288 -
289 -#else /* lint */
290 -
291 255 ENTRY_NP(vtag_flushpage_tl1)
292 256 /*
293 257 * x-trap to flush page from tlb and tsb
294 258 *
295 259 * %g1 = vaddr, zero-extended on 32-bit kernel
296 260 * %g2 = sfmmup
297 261 *
298 262 * assumes TSBE_TAG = 0
299 263 */
300 264 srln %g1, MMU_PAGESHIFT, %g1
301 265
302 266 sethi %hi(ksfmmup), %g3
303 267 ldx [%g3 + %lo(ksfmmup)], %g3
304 268 cmp %g3, %g2
305 269 bne,pt %xcc, 1f ! if not kernel as, go to 1
306 270 slln %g1, MMU_PAGESHIFT, %g1 /* g1 = vaddr */
307 271
308 272 /* We need to demap in the kernel context */
309 273 or DEMAP_NUCLEUS | DEMAP_PAGE_TYPE, %g1, %g1
310 274 stxa %g0, [%g1]ASI_DTLB_DEMAP
311 275 stxa %g0, [%g1]ASI_ITLB_DEMAP
312 276 retry
313 277 1:
314 278 /* We need to demap in a user context */
315 279 or DEMAP_PRIMARY | DEMAP_PAGE_TYPE, %g1, %g1
316 280
317 281 SFMMU_CPU_CNUM(%g2, %g6, %g3) ! %g6 = sfmmu cnum on this CPU
318 282
319 283 ldub [%g2 + SFMMU_CEXT], %g4 ! %g4 = sfmmup->cext
320 284 sll %g4, CTXREG_EXT_SHIFT, %g4
321 285 or %g6, %g4, %g6 ! %g6 = pgsz | cnum
322 286
323 287 set MMU_PCONTEXT, %g4
324 288 ldxa [%g4]ASI_DMMU, %g5 /* rd old ctxnum */
↓ open down ↓ |
24 lines elided |
↑ open up ↑ |
325 289 srlx %g5, CTXREG_NEXT_SHIFT, %g2 /* %g2 = nucleus pgsz */
326 290 sllx %g2, CTXREG_NEXT_SHIFT, %g2 /* preserve nucleus pgsz */
327 291 or %g6, %g2, %g6 /* %g6 = nucleus pgsz | primary pgsz | cnum */
328 292 stxa %g6, [%g4]ASI_DMMU /* wr new ctxum */
329 293 stxa %g0, [%g1]ASI_DTLB_DEMAP
330 294 stxa %g0, [%g1]ASI_ITLB_DEMAP
331 295 stxa %g5, [%g4]ASI_DMMU /* restore old ctxnum */
332 296 retry
333 297 SET_SIZE(vtag_flushpage_tl1)
334 298
335 -#endif /* lint */
336 299
337 -
338 -#if defined(lint)
339 -
340 -/* ARGSUSED */
341 -void
342 -vtag_flush_pgcnt_tl1(uint64_t vaddr, uint64_t sfmmup_pgcnt)
343 -{}
344 -
345 -#else /* lint */
346 -
347 300 ENTRY_NP(vtag_flush_pgcnt_tl1)
348 301 /*
349 302 * x-trap to flush pgcnt MMU_PAGESIZE pages from tlb
350 303 *
351 304 * %g1 = vaddr, zero-extended on 32-bit kernel
352 305 * %g2 = <sfmmup58|pgcnt6>, (pgcnt - 1) is pass'ed in via pgcnt6 bits.
353 306 *
354 307 * NOTE: this handler relies on the fact that no
355 308 * interrupts or traps can occur during the loop
356 309 * issuing the TLB_DEMAP operations. It is assumed
357 310 * that interrupts are disabled and this code is
358 311 * fetching from the kernel locked text address.
359 312 *
360 313 * assumes TSBE_TAG = 0
361 314 */
362 315 set SFMMU_PGCNT_MASK, %g4
363 316 and %g4, %g2, %g3 /* g3 = pgcnt - 1 */
364 317 add %g3, 1, %g3 /* g3 = pgcnt */
365 318
366 319 andn %g2, SFMMU_PGCNT_MASK, %g2 /* g2 = sfmmup */
367 320 srln %g1, MMU_PAGESHIFT, %g1
368 321
369 322 sethi %hi(ksfmmup), %g4
370 323 ldx [%g4 + %lo(ksfmmup)], %g4
371 324 cmp %g4, %g2
372 325 bne,pn %xcc, 1f /* if not kernel as, go to 1 */
373 326 slln %g1, MMU_PAGESHIFT, %g1 /* g1 = vaddr */
374 327
375 328 /* We need to demap in the kernel context */
376 329 or DEMAP_NUCLEUS | DEMAP_PAGE_TYPE, %g1, %g1
377 330 set MMU_PAGESIZE, %g2 /* g2 = pgsize */
378 331 sethi %hi(FLUSH_ADDR), %g5
379 332 4:
380 333 stxa %g0, [%g1]ASI_DTLB_DEMAP
381 334 stxa %g0, [%g1]ASI_ITLB_DEMAP
382 335 flush %g5 ! flush required by immu
383 336
384 337 deccc %g3 /* decr pgcnt */
385 338 bnz,pt %icc,4b
386 339 add %g1, %g2, %g1 /* next page */
387 340 retry
388 341 1:
389 342 /*
390 343 * We need to demap in a user context
391 344 *
392 345 * g2 = sfmmup
393 346 * g3 = pgcnt
394 347 */
395 348 SFMMU_CPU_CNUM(%g2, %g5, %g6) ! %g5 = sfmmu cnum on this CPU
396 349
397 350 or DEMAP_PRIMARY | DEMAP_PAGE_TYPE, %g1, %g1
398 351
399 352 ldub [%g2 + SFMMU_CEXT], %g4 ! %g4 = sfmmup->cext
400 353 sll %g4, CTXREG_EXT_SHIFT, %g4
401 354 or %g5, %g4, %g5
402 355
403 356 set MMU_PCONTEXT, %g4
404 357 ldxa [%g4]ASI_DMMU, %g6 /* rd old ctxnum */
405 358 srlx %g6, CTXREG_NEXT_SHIFT, %g2 /* %g2 = nucleus pgsz */
406 359 sllx %g2, CTXREG_NEXT_SHIFT, %g2 /* preserve nucleus pgsz */
407 360 or %g5, %g2, %g5 /* %g5 = nucleus pgsz | primary pgsz | cnum */
408 361 stxa %g5, [%g4]ASI_DMMU /* wr new ctxum */
409 362
410 363 set MMU_PAGESIZE, %g2 /* g2 = pgsize */
411 364 sethi %hi(FLUSH_ADDR), %g5
412 365 3:
413 366 stxa %g0, [%g1]ASI_DTLB_DEMAP
414 367 stxa %g0, [%g1]ASI_ITLB_DEMAP
↓ open down ↓ |
58 lines elided |
↑ open up ↑ |
415 368 flush %g5 ! flush required by immu
416 369
417 370 deccc %g3 /* decr pgcnt */
418 371 bnz,pt %icc,3b
419 372 add %g1, %g2, %g1 /* next page */
420 373
421 374 stxa %g6, [%g4]ASI_DMMU /* restore old ctxnum */
422 375 retry
423 376 SET_SIZE(vtag_flush_pgcnt_tl1)
424 377
425 -#endif /* lint */
426 -
427 -#if defined(lint)
428 -
429 -/*ARGSUSED*/
430 -void
431 -vtag_flushall_tl1(uint64_t dummy1, uint64_t dummy2)
432 -{}
433 -
434 -#else /* lint */
435 -
436 378 ENTRY_NP(vtag_flushall_tl1)
437 379 /*
438 380 * x-trap to flush tlb
439 381 */
440 382 set DEMAP_ALL_TYPE, %g4
441 383 stxa %g0, [%g4]ASI_DTLB_DEMAP
442 384 stxa %g0, [%g4]ASI_ITLB_DEMAP
443 385 retry
444 386 SET_SIZE(vtag_flushall_tl1)
445 387
446 -#endif /* lint */
447 388
448 -
449 -#if defined(lint)
450 -
451 -/* ARGSUSED */
452 -void
453 -vac_flushpage(pfn_t pfnum, int vcolor)
454 -{}
455 -
456 -#else /* lint */
457 -
458 389 /*
459 390 * vac_flushpage(pfnum, color)
460 391 * Flush 1 8k page of the D-$ with physical page = pfnum
461 392 * Algorithm:
462 393 * The cheetah dcache is a 64k psuedo 4 way accaociative cache.
463 394 * It is virtual indexed, physically tagged cache.
464 395 */
465 396 .seg ".data"
466 397 .align 8
467 398 .global dflush_type
468 399 dflush_type:
469 400 .word FLUSHPAGE_TYPE
470 401
471 402 ENTRY(vac_flushpage)
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
472 403 /*
473 404 * flush page from the d$
474 405 *
475 406 * %o0 = pfnum, %o1 = color
476 407 */
477 408 DCACHE_FLUSHPAGE(%o0, %o1, %o2, %o3, %o4)
478 409 retl
479 410 nop
480 411 SET_SIZE(vac_flushpage)
481 412
482 -#endif /* lint */
483 413
484 -
485 -#if defined(lint)
486 -
487 -/* ARGSUSED */
488 -void
489 -vac_flushpage_tl1(uint64_t pfnum, uint64_t vcolor)
490 -{}
491 -
492 -#else /* lint */
493 -
494 414 ENTRY_NP(vac_flushpage_tl1)
495 415 /*
496 416 * x-trap to flush page from the d$
497 417 *
498 418 * %g1 = pfnum, %g2 = color
499 419 */
500 420 DCACHE_FLUSHPAGE(%g1, %g2, %g3, %g4, %g5)
501 421 retry
502 422 SET_SIZE(vac_flushpage_tl1)
503 423
504 -#endif /* lint */
505 424
506 -
507 -#if defined(lint)
508 -
509 -/* ARGSUSED */
510 -void
511 -vac_flushcolor(int vcolor, pfn_t pfnum)
512 -{}
513 -
514 -#else /* lint */
515 -
516 425 ENTRY(vac_flushcolor)
517 426 /*
518 427 * %o0 = vcolor
519 428 */
520 429 DCACHE_FLUSHCOLOR(%o0, 0, %o1, %o2, %o3)
521 430 DCACHE_FLUSHCOLOR(%o0, 1, %o1, %o2, %o3)
522 431 DCACHE_FLUSHCOLOR(%o0, 2, %o1, %o2, %o3)
523 432 DCACHE_FLUSHCOLOR(%o0, 3, %o1, %o2, %o3)
524 433 retl
525 434 nop
526 435 SET_SIZE(vac_flushcolor)
527 436
528 -#endif /* lint */
529 437
530 -
531 -#if defined(lint)
532 -
533 -/* ARGSUSED */
534 -void
535 -vac_flushcolor_tl1(uint64_t vcolor, uint64_t pfnum)
536 -{}
537 -
538 -#else /* lint */
539 -
540 438 ENTRY(vac_flushcolor_tl1)
541 439 /*
542 440 * %g1 = vcolor
543 441 */
544 442 DCACHE_FLUSHCOLOR(%g1, 0, %g2, %g3, %g4)
545 443 DCACHE_FLUSHCOLOR(%g1, 1, %g2, %g3, %g4)
546 444 DCACHE_FLUSHCOLOR(%g1, 2, %g2, %g3, %g4)
547 445 DCACHE_FLUSHCOLOR(%g1, 3, %g2, %g3, %g4)
548 446 retry
549 447 SET_SIZE(vac_flushcolor_tl1)
550 448
551 -#endif /* lint */
552 -
553 -#if defined(lint)
554 -
555 -int
556 -idsr_busy(void)
557 -{
558 - return (0);
559 -}
560 -
561 -#else /* lint */
562 -
563 449 /*
564 450 * Determine whether or not the IDSR is busy.
565 451 * Entry: no arguments
566 452 * Returns: 1 if busy, 0 otherwise
567 453 */
568 454 ENTRY(idsr_busy)
569 455 ldxa [%g0]ASI_INTR_DISPATCH_STATUS, %g1
570 456 clr %o0
571 457 btst IDSR_BUSY, %g1
572 458 bz,a,pt %xcc, 1f
573 459 mov 1, %o0
574 460 1:
575 461 retl
576 462 nop
577 463 SET_SIZE(idsr_busy)
578 464
579 -#endif /* lint */
580 -
581 -#if defined(lint)
582 -
583 -/* ARGSUSED */
584 -void
585 -init_mondo(xcfunc_t *func, uint64_t arg1, uint64_t arg2)
586 -{}
587 -
588 -/* ARGSUSED */
589 -void
590 -init_mondo_nocheck(xcfunc_t *func, uint64_t arg1, uint64_t arg2)
591 -{}
592 -
593 -#else /* lint */
594 -
595 465 .global _dispatch_status_busy
596 466 _dispatch_status_busy:
597 467 .asciz "ASI_INTR_DISPATCH_STATUS error: busy"
598 468 .align 4
599 469
600 470 /*
601 471 * Setup interrupt dispatch data registers
602 472 * Entry:
603 473 * %o0 - function or inumber to call
604 474 * %o1, %o2 - arguments (2 uint64_t's)
605 475 */
606 476 .seg "text"
607 477
608 478 ENTRY(init_mondo)
609 479 #ifdef DEBUG
610 480 !
611 481 ! IDSR should not be busy at the moment
612 482 !
613 483 ldxa [%g0]ASI_INTR_DISPATCH_STATUS, %g1
614 484 btst IDSR_BUSY, %g1
615 485 bz,pt %xcc, 1f
616 486 nop
617 487 sethi %hi(_dispatch_status_busy), %o0
618 488 call panic
619 489 or %o0, %lo(_dispatch_status_busy), %o0
620 490 #endif /* DEBUG */
621 491
622 492 ALTENTRY(init_mondo_nocheck)
623 493 !
624 494 ! interrupt vector dispatch data reg 0
625 495 !
626 496 1:
627 497 mov IDDR_0, %g1
628 498 mov IDDR_1, %g2
629 499 mov IDDR_2, %g3
630 500 stxa %o0, [%g1]ASI_INTR_DISPATCH
631 501
632 502 !
633 503 ! interrupt vector dispatch data reg 1
634 504 !
635 505 stxa %o1, [%g2]ASI_INTR_DISPATCH
636 506
637 507 !
↓ open down ↓ |
33 lines elided |
↑ open up ↑ |
638 508 ! interrupt vector dispatch data reg 2
639 509 !
640 510 stxa %o2, [%g3]ASI_INTR_DISPATCH
641 511
642 512 membar #Sync
643 513 retl
644 514 nop
645 515 SET_SIZE(init_mondo_nocheck)
646 516 SET_SIZE(init_mondo)
647 517
648 -#endif /* lint */
649 518
650 -
651 519 #if !(defined(JALAPENO) || defined(SERRANO))
652 520
653 -#if defined(lint)
654 -
655 -/* ARGSUSED */
656 -void
657 -shipit(int upaid, int bn)
658 -{ return; }
659 -
660 -#else /* lint */
661 -
662 521 /*
663 522 * Ship mondo to aid using busy/nack pair bn
664 523 */
665 524 ENTRY_NP(shipit)
666 525 sll %o0, IDCR_PID_SHIFT, %g1 ! IDCR<18:14> = agent id
667 526 sll %o1, IDCR_BN_SHIFT, %g2 ! IDCR<28:24> = b/n pair
668 527 or %g1, IDCR_OFFSET, %g1 ! IDCR<13:0> = 0x70
669 528 or %g1, %g2, %g1
670 529 stxa %g0, [%g1]ASI_INTR_DISPATCH ! interrupt vector dispatch
671 530 membar #Sync
672 531 retl
673 532 nop
674 533 SET_SIZE(shipit)
675 534
676 -#endif /* lint */
677 -
678 535 #endif /* !(JALAPENO || SERRANO) */
679 536
680 537
681 -#if defined(lint)
682 -
683 -/* ARGSUSED */
684 -void
685 -flush_instr_mem(caddr_t vaddr, size_t len)
686 -{}
687 -
688 -#else /* lint */
689 -
690 538 /*
691 539 * flush_instr_mem:
692 540 * Flush 1 page of the I-$ starting at vaddr
693 541 * %o0 vaddr
694 542 * %o1 bytes to be flushed
695 543 * UltraSPARC-III maintains consistency of the on-chip Instruction Cache with
696 544 * the stores from all processors so that a FLUSH instruction is only needed
697 545 * to ensure pipeline is consistent. This means a single flush is sufficient at
698 546 * the end of a sequence of stores that updates the instruction stream to
699 547 * ensure correct operation.
700 548 */
701 549
702 550 ENTRY(flush_instr_mem)
703 551 flush %o0 ! address irrelevant
704 552 retl
705 553 nop
706 554 SET_SIZE(flush_instr_mem)
707 555
708 -#endif /* lint */
709 556
710 -
711 557 #if defined(CPU_IMP_ECACHE_ASSOC)
712 558
713 -#if defined(lint)
714 -
715 -/* ARGSUSED */
716 -uint64_t
717 -get_ecache_ctrl(void)
718 -{ return (0); }
719 -
720 -#else /* lint */
721 -
722 559 ENTRY(get_ecache_ctrl)
723 560 GET_CPU_IMPL(%o0)
724 561 cmp %o0, JAGUAR_IMPL
725 562 !
726 563 ! Putting an ASI access in the delay slot may
727 564 ! cause it to be accessed, even when annulled.
728 565 !
729 566 bne 1f
730 567 nop
731 568 ldxa [%g0]ASI_EC_CFG_TIMING, %o0 ! read Jaguar shared E$ ctrl reg
732 569 b 2f
733 570 nop
734 571 1:
735 572 ldxa [%g0]ASI_EC_CTRL, %o0 ! read Ch/Ch+ E$ control reg
736 573 2:
737 574 retl
738 575 nop
739 576 SET_SIZE(get_ecache_ctrl)
740 577
741 -#endif /* lint */
742 -
743 578 #endif /* CPU_IMP_ECACHE_ASSOC */
744 579
745 580
746 581 #if !(defined(JALAPENO) || defined(SERRANO))
747 582
748 583 /*
749 584 * flush_ecache:
750 585 * %o0 - 64 bit physical address
751 586 * %o1 - ecache size
752 587 * %o2 - ecache linesize
753 588 */
754 -#if defined(lint)
755 589
756 -/*ARGSUSED*/
757 -void
758 -flush_ecache(uint64_t physaddr, size_t ecache_size, size_t ecache_linesize)
759 -{}
760 -
761 -#else /* !lint */
762 -
763 590 ENTRY(flush_ecache)
764 591
765 592 /*
766 593 * For certain CPU implementations, we have to flush the L2 cache
767 594 * before flushing the ecache.
768 595 */
769 596 PN_L2_FLUSHALL(%g3, %g4, %g5)
770 597
771 598 /*
772 599 * Flush the entire Ecache using displacement flush.
773 600 */
774 601 ECACHE_FLUSHALL(%o1, %o2, %o0, %o4)
775 602
776 603 retl
777 604 nop
778 605 SET_SIZE(flush_ecache)
779 606
780 -#endif /* lint */
781 -
782 607 #endif /* !(JALAPENO || SERRANO) */
783 608
784 609
785 -#if defined(lint)
786 -
787 -void
788 -flush_dcache(void)
789 -{}
790 -
791 -#else /* lint */
792 -
793 610 ENTRY(flush_dcache)
794 611 ASM_LD(%o0, dcache_size)
795 612 ASM_LD(%o1, dcache_linesize)
796 613 CH_DCACHE_FLUSHALL(%o0, %o1, %o2)
797 614 retl
798 615 nop
799 616 SET_SIZE(flush_dcache)
800 617
801 -#endif /* lint */
802 618
803 -
804 -#if defined(lint)
805 -
806 -void
807 -flush_icache(void)
808 -{}
809 -
810 -#else /* lint */
811 -
812 619 ENTRY(flush_icache)
813 620 GET_CPU_PRIVATE_PTR(%g0, %o0, %o2, flush_icache_1);
814 621 ld [%o0 + CHPR_ICACHE_LINESIZE], %o1
815 622 ba,pt %icc, 2f
816 623 ld [%o0 + CHPR_ICACHE_SIZE], %o0
817 624 flush_icache_1:
818 625 ASM_LD(%o0, icache_size)
819 626 ASM_LD(%o1, icache_linesize)
820 627 2:
821 628 CH_ICACHE_FLUSHALL(%o0, %o1, %o2, %o4)
822 629 retl
823 630 nop
824 631 SET_SIZE(flush_icache)
825 632
826 -#endif /* lint */
827 -
828 -#if defined(lint)
829 -
830 -/*ARGSUSED*/
831 -void
832 -kdi_flush_idcache(int dcache_size, int dcache_lsize, int icache_size,
833 - int icache_lsize)
834 -{
835 -}
836 -
837 -#else /* lint */
838 -
839 633 ENTRY(kdi_flush_idcache)
840 634 CH_DCACHE_FLUSHALL(%o0, %o1, %g1)
841 635 CH_ICACHE_FLUSHALL(%o2, %o3, %g1, %g2)
842 636 membar #Sync
843 637 retl
844 638 nop
845 639 SET_SIZE(kdi_flush_idcache)
846 640
847 -#endif /* lint */
848 -
849 -#if defined(lint)
850 -
851 -void
852 -flush_pcache(void)
853 -{}
854 -
855 -#else /* lint */
856 -
857 641 ENTRY(flush_pcache)
858 642 PCACHE_FLUSHALL(%o0, %o1, %o2)
859 643 retl
860 644 nop
861 645 SET_SIZE(flush_pcache)
862 646
863 -#endif /* lint */
864 647
865 -
866 648 #if defined(CPU_IMP_L1_CACHE_PARITY)
867 649
868 -#if defined(lint)
869 -
870 -/* ARGSUSED */
871 -void
872 -get_dcache_dtag(uint32_t dcache_idx, uint64_t *data)
873 -{}
874 -
875 -#else /* lint */
876 -
877 650 /*
878 651 * Get dcache data and tag. The Dcache data is a pointer to a ch_dc_data_t
879 652 * structure (see cheetahregs.h):
880 653 * The Dcache *should* be turned off when this code is executed.
881 654 */
882 655 .align 128
883 656 ENTRY(get_dcache_dtag)
884 657 rdpr %pstate, %o5
885 658 andn %o5, PSTATE_IE | PSTATE_AM, %o3
886 659 wrpr %g0, %o3, %pstate
887 660 b 1f
888 661 stx %o0, [%o1 + CH_DC_IDX]
889 662
890 663 .align 128
891 664 1:
892 665 ldxa [%o0]ASI_DC_TAG, %o2
893 666 stx %o2, [%o1 + CH_DC_TAG]
894 667 membar #Sync
895 668 ldxa [%o0]ASI_DC_UTAG, %o2
896 669 membar #Sync
897 670 stx %o2, [%o1 + CH_DC_UTAG]
898 671 ldxa [%o0]ASI_DC_SNP_TAG, %o2
899 672 stx %o2, [%o1 + CH_DC_SNTAG]
900 673 add %o1, CH_DC_DATA, %o1
901 674 clr %o3
902 675 2:
903 676 membar #Sync ! required before ASI_DC_DATA
904 677 ldxa [%o0 + %o3]ASI_DC_DATA, %o2
905 678 membar #Sync ! required after ASI_DC_DATA
906 679 stx %o2, [%o1 + %o3]
907 680 cmp %o3, CH_DC_DATA_REG_SIZE - 8
908 681 blt 2b
909 682 add %o3, 8, %o3
910 683
911 684 /*
912 685 * Unlike other CPUs in the family, D$ data parity bits for Panther
913 686 * do not reside in the microtag. Instead, we have to read them
914 687 * using the DC_data_parity bit of ASI_DCACHE_DATA. Also, instead
915 688 * of just having 8 parity bits to protect all 32 bytes of data
916 689 * per line, we now have 32 bits of parity.
917 690 */
918 691 GET_CPU_IMPL(%o3)
919 692 cmp %o3, PANTHER_IMPL
920 693 bne 4f
921 694 clr %o3
922 695
923 696 /*
924 697 * move our pointer to the next field where we store parity bits
925 698 * and add the offset of the last parity byte since we will be
926 699 * storing all 4 parity bytes within one 64 bit field like this:
927 700 *
928 701 * +------+------------+------------+------------+------------+
929 702 * | - | DC_parity | DC_parity | DC_parity | DC_parity |
930 703 * | - | for word 3 | for word 2 | for word 1 | for word 0 |
931 704 * +------+------------+------------+------------+------------+
932 705 * 63:32 31:24 23:16 15:8 7:0
933 706 */
934 707 add %o1, CH_DC_PN_DATA_PARITY - CH_DC_DATA + 7, %o1
935 708
936 709 /* add the DC_data_parity bit into our working index */
937 710 mov 1, %o2
938 711 sll %o2, PN_DC_DATA_PARITY_BIT_SHIFT, %o2
939 712 or %o0, %o2, %o0
940 713 3:
941 714 membar #Sync ! required before ASI_DC_DATA
942 715 ldxa [%o0 + %o3]ASI_DC_DATA, %o2
943 716 membar #Sync ! required after ASI_DC_DATA
↓ open down ↓ |
57 lines elided |
↑ open up ↑ |
944 717 stb %o2, [%o1]
945 718 dec %o1
946 719 cmp %o3, CH_DC_DATA_REG_SIZE - 8
947 720 blt 3b
948 721 add %o3, 8, %o3
949 722 4:
950 723 retl
951 724 wrpr %g0, %o5, %pstate
952 725 SET_SIZE(get_dcache_dtag)
953 726
954 -#endif /* lint */
955 727
956 -
957 -#if defined(lint)
958 -
959 -/* ARGSUSED */
960 -void
961 -get_icache_dtag(uint32_t ecache_idx, uint64_t *data)
962 -{}
963 -
964 -#else /* lint */
965 -
966 728 /*
967 729 * Get icache data and tag. The data argument is a pointer to a ch_ic_data_t
968 730 * structure (see cheetahregs.h):
969 731 * The Icache *Must* be turned off when this function is called.
970 732 * This is because diagnostic accesses to the Icache interfere with cache
971 733 * consistency.
972 734 */
973 735 .align 128
974 736 ENTRY(get_icache_dtag)
975 737 rdpr %pstate, %o5
976 738 andn %o5, PSTATE_IE | PSTATE_AM, %o3
977 739 wrpr %g0, %o3, %pstate
978 740
979 741 stx %o0, [%o1 + CH_IC_IDX]
980 742 ldxa [%o0]ASI_IC_TAG, %o2
981 743 stx %o2, [%o1 + CH_IC_PATAG]
982 744 add %o0, CH_ICTAG_UTAG, %o0
983 745 ldxa [%o0]ASI_IC_TAG, %o2
984 746 add %o0, (CH_ICTAG_UPPER - CH_ICTAG_UTAG), %o0
985 747 stx %o2, [%o1 + CH_IC_UTAG]
986 748 ldxa [%o0]ASI_IC_TAG, %o2
987 749 add %o0, (CH_ICTAG_LOWER - CH_ICTAG_UPPER), %o0
988 750 stx %o2, [%o1 + CH_IC_UPPER]
989 751 ldxa [%o0]ASI_IC_TAG, %o2
990 752 andn %o0, CH_ICTAG_TMASK, %o0
991 753 stx %o2, [%o1 + CH_IC_LOWER]
992 754 ldxa [%o0]ASI_IC_SNP_TAG, %o2
993 755 stx %o2, [%o1 + CH_IC_SNTAG]
994 756 add %o1, CH_IC_DATA, %o1
995 757 clr %o3
996 758 2:
↓ open down ↓ |
21 lines elided |
↑ open up ↑ |
997 759 ldxa [%o0 + %o3]ASI_IC_DATA, %o2
998 760 stx %o2, [%o1 + %o3]
999 761 cmp %o3, PN_IC_DATA_REG_SIZE - 8
1000 762 blt 2b
1001 763 add %o3, 8, %o3
1002 764
1003 765 retl
1004 766 wrpr %g0, %o5, %pstate
1005 767 SET_SIZE(get_icache_dtag)
1006 768
1007 -#endif /* lint */
1008 -
1009 -#if defined(lint)
1010 -
1011 -/* ARGSUSED */
1012 -void
1013 -get_pcache_dtag(uint32_t pcache_idx, uint64_t *data)
1014 -{}
1015 -
1016 -#else /* lint */
1017 -
1018 769 /*
1019 770 * Get pcache data and tags.
1020 771 * inputs:
1021 772 * pcache_idx - fully constructed VA for for accessing P$ diagnostic
1022 773 * registers. Contains PC_way and PC_addr shifted into
1023 774 * the correct bit positions. See the PRM for more details.
1024 775 * data - pointer to a ch_pc_data_t
1025 776 * structure (see cheetahregs.h):
1026 777 */
1027 778 .align 128
1028 779 ENTRY(get_pcache_dtag)
1029 780 rdpr %pstate, %o5
1030 781 andn %o5, PSTATE_IE | PSTATE_AM, %o3
1031 782 wrpr %g0, %o3, %pstate
1032 783
1033 784 stx %o0, [%o1 + CH_PC_IDX]
1034 785 ldxa [%o0]ASI_PC_STATUS_DATA, %o2
1035 786 stx %o2, [%o1 + CH_PC_STATUS]
1036 787 ldxa [%o0]ASI_PC_TAG, %o2
1037 788 stx %o2, [%o1 + CH_PC_TAG]
1038 789 ldxa [%o0]ASI_PC_SNP_TAG, %o2
1039 790 stx %o2, [%o1 + CH_PC_SNTAG]
1040 791 add %o1, CH_PC_DATA, %o1
1041 792 clr %o3
1042 793 2:
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
1043 794 ldxa [%o0 + %o3]ASI_PC_DATA, %o2
1044 795 stx %o2, [%o1 + %o3]
1045 796 cmp %o3, CH_PC_DATA_REG_SIZE - 8
1046 797 blt 2b
1047 798 add %o3, 8, %o3
1048 799
1049 800 retl
1050 801 wrpr %g0, %o5, %pstate
1051 802 SET_SIZE(get_pcache_dtag)
1052 803
1053 -#endif /* lint */
1054 -
1055 804 #endif /* CPU_IMP_L1_CACHE_PARITY */
1056 805
1057 -#if defined(lint)
1058 -
1059 -/* ARGSUSED */
1060 -void
1061 -set_dcu(uint64_t dcu)
1062 -{}
1063 -
1064 -#else /* lint */
1065 -
1066 806 /*
1067 807 * re-enable the i$, d$, w$, and p$ according to bootup cache state.
1068 808 * Turn on WE, HPE, SPE, PE, IC, and DC bits defined as DCU_CACHE.
1069 809 * %o0 - 64 bit constant
1070 810 */
1071 811 ENTRY(set_dcu)
1072 812 stxa %o0, [%g0]ASI_DCU ! Store to DCU
1073 813 flush %g0 /* flush required after changing the IC bit */
1074 814 retl
1075 815 nop
1076 816 SET_SIZE(set_dcu)
1077 817
1078 -#endif /* lint */
1079 818
1080 -
1081 -#if defined(lint)
1082 -
1083 -uint64_t
1084 -get_dcu(void)
1085 -{
1086 - return ((uint64_t)0);
1087 -}
1088 -
1089 -#else /* lint */
1090 -
1091 819 /*
1092 820 * Return DCU register.
1093 821 */
1094 822 ENTRY(get_dcu)
1095 823 ldxa [%g0]ASI_DCU, %o0 /* DCU control register */
1096 824 retl
1097 825 nop
1098 826 SET_SIZE(get_dcu)
1099 827
1100 -#endif /* lint */
1101 -
1102 828 /*
1103 829 * Cheetah/Cheetah+ level 15 interrupt handler trap table entry.
1104 830 *
1105 831 * This handler is used to check for softints generated by error trap
1106 832 * handlers to report errors. On Cheetah, this mechanism is used by the
1107 833 * Fast ECC at TL>0 error trap handler and, on Cheetah+, by both the Fast
1108 834 * ECC at TL>0 error and the I$/D$ parity error at TL>0 trap handlers.
1109 835 * NB: Must be 8 instructions or less to fit in trap table and code must
1110 836 * be relocatable.
1111 837 */
1112 -#if defined(lint)
1113 838
1114 -void
1115 -ch_pil15_interrupt_instr(void)
1116 -{}
1117 -
1118 -#else /* lint */
1119 -
1120 839 ENTRY_NP(ch_pil15_interrupt_instr)
1121 840 ASM_JMP(%g1, ch_pil15_interrupt)
1122 841 SET_SIZE(ch_pil15_interrupt_instr)
1123 842
1124 -#endif
1125 843
1126 -
1127 -#if defined(lint)
1128 -
1129 -void
1130 -ch_pil15_interrupt(void)
1131 -{}
1132 -
1133 -#else /* lint */
1134 -
1135 844 ENTRY_NP(ch_pil15_interrupt)
1136 845
1137 846 /*
1138 847 * Since pil_interrupt is hacked to assume that every level 15
1139 848 * interrupt is generated by the CPU to indicate a performance
1140 849 * counter overflow this gets ugly. Before calling pil_interrupt
1141 850 * the Error at TL>0 pending status is inspected. If it is
1142 851 * non-zero, then an error has occurred and it is handled.
1143 852 * Otherwise control is transfered to pil_interrupt. Note that if
1144 853 * an error is detected pil_interrupt will not be called and
1145 854 * overflow interrupts may be lost causing erroneous performance
1146 855 * measurements. However, error-recovery will have a detrimental
1147 856 * effect on performance anyway.
1148 857 */
1149 858 CPU_INDEX(%g1, %g4)
1150 859 set ch_err_tl1_pending, %g4
1151 860 ldub [%g1 + %g4], %g2
1152 861 brz %g2, 1f
1153 862 nop
1154 863
1155 864 /*
1156 865 * We have a pending TL>0 error, clear the TL>0 pending status.
1157 866 */
1158 867 stb %g0, [%g1 + %g4]
1159 868
1160 869 /*
1161 870 * Clear the softint.
1162 871 */
1163 872 mov 1, %g5
1164 873 sll %g5, PIL_15, %g5
1165 874 wr %g5, CLEAR_SOFTINT
1166 875
1167 876 /*
1168 877 * For Cheetah*, call cpu_tl1_error via systrap at PIL 15
1169 878 * to process the Fast ECC/Cache Parity at TL>0 error. Clear
1170 879 * panic flag (%g2).
1171 880 */
1172 881 set cpu_tl1_error, %g1
1173 882 clr %g2
1174 883 ba sys_trap
1175 884 mov PIL_15, %g4
1176 885
1177 886 1:
↓ open down ↓ |
33 lines elided |
↑ open up ↑ |
1178 887 /*
1179 888 * The logout is invalid.
1180 889 *
1181 890 * Call the default interrupt handler.
1182 891 */
1183 892 sethi %hi(pil_interrupt), %g1
1184 893 jmp %g1 + %lo(pil_interrupt)
1185 894 mov PIL_15, %g4
1186 895
1187 896 SET_SIZE(ch_pil15_interrupt)
1188 -#endif
1189 897
1190 898
1191 899 /*
1192 900 * Error Handling
1193 901 *
1194 902 * Cheetah provides error checking for all memory access paths between
1195 903 * the CPU, External Cache, Cheetah Data Switch and system bus. Error
1196 904 * information is logged in the AFSR, (also AFSR_EXT for Panther) and
1197 905 * AFAR and one of the following traps is generated (provided that it
1198 906 * is enabled in External Cache Error Enable Register) to handle that
1199 907 * error:
1200 908 * 1. trap 0x70: Precise trap
1201 909 * tt0_fecc for errors at trap level(TL)>=0
1202 910 * 2. trap 0x0A and 0x32: Deferred trap
1203 911 * async_err for errors at TL>=0
1204 912 * 3. trap 0x63: Disrupting trap
1205 913 * ce_err for errors at TL=0
1206 914 * (Note that trap 0x63 cannot happen at trap level > 0)
1207 915 *
1208 916 * Trap level one handlers panic the system except for the fast ecc
1209 917 * error handler which tries to recover from certain errors.
1210 918 */
1211 919
1212 920 /*
1213 921 * FAST ECC TRAP STRATEGY:
1214 922 *
1215 923 * Software must handle single and multi bit errors which occur due to data
1216 924 * or instruction cache reads from the external cache. A single or multi bit
1217 925 * error occuring in one of these situations results in a precise trap.
1218 926 *
1219 927 * The basic flow of this trap handler is as follows:
1220 928 *
1221 929 * 1) Record the state and then turn off the Dcache and Icache. The Dcache
1222 930 * is disabled because bad data could have been installed. The Icache is
1223 931 * turned off because we want to capture the Icache line related to the
1224 932 * AFAR.
1225 933 * 2) Disable trapping on CEEN/NCCEN errors during TL=0 processing.
1226 934 * 3) Park sibling core if caches are shared (to avoid race condition while
1227 935 * accessing shared resources such as L3 data staging register during
1228 936 * CPU logout.
1229 937 * 4) Read the AFAR and AFSR.
1230 938 * 5) If CPU logout structure is not being used, then:
1231 939 * 6) Clear all errors from the AFSR.
1232 940 * 7) Capture Ecache, Dcache and Icache lines in "CPU log out" structure.
1233 941 * 8) Flush Ecache then Flush Dcache and Icache and restore to previous
1234 942 * state.
1235 943 * 9) Unpark sibling core if we parked it earlier.
1236 944 * 10) call cpu_fast_ecc_error via systrap at PIL 14 unless we're already
1237 945 * running at PIL 15.
1238 946 * 6) Otherwise, if CPU logout structure is being used:
1239 947 * 7) Incriment the "logout busy count".
1240 948 * 8) Flush Ecache then Flush Dcache and Icache and restore to previous
1241 949 * state.
1242 950 * 9) Unpark sibling core if we parked it earlier.
1243 951 * 10) Issue a retry since the other CPU error logging code will end up
1244 952 * finding this error bit and logging information about it later.
1245 953 * 7) Alternatively (to 5 and 6 above), if the cpu_private struct is not
1246 954 * yet initialized such that we can't even check the logout struct, then
1247 955 * we place the clo_flags data into %g2 (sys_trap->have_win arg #1) and
1248 956 * call cpu_fast_ecc_error via systrap. The clo_flags parameter is used
1249 957 * to determine information such as TL, TT, CEEN and NCEEN settings, etc
1250 958 * in the high level trap handler since we don't have access to detailed
1251 959 * logout information in cases where the cpu_private struct is not yet
1252 960 * initialized.
1253 961 *
1254 962 * We flush the E$ and D$ here on TL=1 code to prevent getting nested
1255 963 * Fast ECC traps in the TL=0 code. If we get a Fast ECC event here in
1256 964 * the TL=1 code, we will go to the Fast ECC at TL>0 handler which,
1257 965 * since it is uses different code/data from this handler, has a better
1258 966 * chance of fixing things up than simply recursing through this code
1259 967 * again (this would probably cause an eventual kernel stack overflow).
1260 968 * If the Fast ECC at TL>0 handler encounters a Fast ECC error before it
1261 969 * can flush the E$ (or the error is a stuck-at bit), we will recurse in
1262 970 * the Fast ECC at TL>0 handler and eventually Red Mode.
1263 971 *
1264 972 * Note that for Cheetah (and only Cheetah), we use alias addresses for
1265 973 * flushing rather than ASI accesses (which don't exist on Cheetah).
1266 974 * Should we encounter a Fast ECC error within this handler on Cheetah,
1267 975 * there's a good chance it's within the ecache_flushaddr buffer (since
1268 976 * it's the largest piece of memory we touch in the handler and it is
1269 977 * usually kernel text/data). For that reason the Fast ECC at TL>0
1270 978 * handler for Cheetah uses an alternate buffer: ecache_tl1_flushaddr.
↓ open down ↓ |
72 lines elided |
↑ open up ↑ |
1271 979 */
1272 980
1273 981 /*
1274 982 * Cheetah ecc-protected E$ trap (Trap 70) at TL=0
1275 983 * tt0_fecc is replaced by fecc_err_instr in cpu_init_trap of the various
1276 984 * architecture-specific files.
1277 985 * NB: Must be 8 instructions or less to fit in trap table and code must
1278 986 * be relocatable.
1279 987 */
1280 988
1281 -#if defined(lint)
1282 -
1283 -void
1284 -fecc_err_instr(void)
1285 -{}
1286 -
1287 -#else /* lint */
1288 -
1289 989 ENTRY_NP(fecc_err_instr)
1290 990 membar #Sync ! Cheetah requires membar #Sync
1291 991
1292 992 /*
1293 993 * Save current DCU state. Turn off the Dcache and Icache.
1294 994 */
1295 995 ldxa [%g0]ASI_DCU, %g1 ! save DCU in %g1
1296 996 andn %g1, DCU_DC + DCU_IC, %g4
1297 997 stxa %g4, [%g0]ASI_DCU
1298 998 flush %g0 /* flush required after changing the IC bit */
1299 999
1300 1000 ASM_JMP(%g4, fast_ecc_err)
1301 1001 SET_SIZE(fecc_err_instr)
1302 1002
1303 -#endif /* lint */
1304 1003
1305 -
1306 1004 #if !(defined(JALAPENO) || defined(SERRANO))
1307 1005
1308 -#if defined(lint)
1309 -
1310 -void
1311 -fast_ecc_err(void)
1312 -{}
1313 -
1314 -#else /* lint */
1315 -
1316 1006 .section ".text"
1317 1007 .align 64
1318 1008 ENTRY_NP(fast_ecc_err)
1319 1009
1320 1010 /*
1321 1011 * Turn off CEEN and NCEEN.
1322 1012 */
1323 1013 ldxa [%g0]ASI_ESTATE_ERR, %g3
1324 1014 andn %g3, EN_REG_NCEEN + EN_REG_CEEN, %g4
1325 1015 stxa %g4, [%g0]ASI_ESTATE_ERR
1326 1016 membar #Sync ! membar sync required
1327 1017
1328 1018 /*
1329 1019 * Check to see whether we need to park our sibling core
1330 1020 * before recording diagnostic information from caches
1331 1021 * which may be shared by both cores.
1332 1022 * We use %g1 to store information about whether or not
1333 1023 * we had to park the core (%g1 holds our DCUCR value and
1334 1024 * we only use bits from that register which are "reserved"
1335 1025 * to keep track of core parking) so that we know whether
1336 1026 * or not to unpark later. %g5 and %g4 are scratch registers.
1337 1027 */
1338 1028 PARK_SIBLING_CORE(%g1, %g5, %g4)
1339 1029
1340 1030 /*
1341 1031 * Do the CPU log out capture.
1342 1032 * %g3 = "failed?" return value.
1343 1033 * %g2 = Input = AFAR. Output the clo_flags info which is passed
1344 1034 * into this macro via %g4. Output only valid if cpu_private
1345 1035 * struct has not been initialized.
1346 1036 * CHPR_FECCTL0_LOGOUT = cpu logout structure offset input
1347 1037 * %g4 = Trap information stored in the cpu logout flags field
1348 1038 * %g5 = scr1
1349 1039 * %g6 = scr2
1350 1040 * %g3 = scr3
1351 1041 * %g4 = scr4
1352 1042 */
1353 1043 /* store the CEEN and NCEEN values, TL=0 */
1354 1044 and %g3, EN_REG_CEEN + EN_REG_NCEEN, %g4
1355 1045 set CHPR_FECCTL0_LOGOUT, %g6
1356 1046 DO_CPU_LOGOUT(%g3, %g2, %g6, %g4, %g5, %g6, %g3, %g4)
1357 1047
1358 1048 /*
1359 1049 * Flush the Ecache (and L2 cache for Panther) to get the error out
1360 1050 * of the Ecache. If the UCC or UCU is on a dirty line, then the
1361 1051 * following flush will turn that into a WDC or WDU, respectively.
1362 1052 */
1363 1053 PN_L2_FLUSHALL(%g4, %g5, %g6)
1364 1054
1365 1055 CPU_INDEX(%g4, %g5)
1366 1056 mulx %g4, CPU_NODE_SIZE, %g4
1367 1057 set cpunodes, %g5
1368 1058 add %g4, %g5, %g4
1369 1059 ld [%g4 + ECACHE_LINESIZE], %g5
1370 1060 ld [%g4 + ECACHE_SIZE], %g4
1371 1061
1372 1062 ASM_LDX(%g6, ecache_flushaddr)
1373 1063 ECACHE_FLUSHALL(%g4, %g5, %g6, %g7)
1374 1064
1375 1065 /*
1376 1066 * Flush the Dcache. Since bad data could have been installed in
1377 1067 * the Dcache we must flush it before re-enabling it.
1378 1068 */
1379 1069 ASM_LD(%g5, dcache_size)
1380 1070 ASM_LD(%g6, dcache_linesize)
1381 1071 CH_DCACHE_FLUSHALL(%g5, %g6, %g7)
1382 1072
1383 1073 /*
1384 1074 * Flush the Icache. Since we turned off the Icache to capture the
1385 1075 * Icache line it is now stale or corrupted and we must flush it
1386 1076 * before re-enabling it.
1387 1077 */
1388 1078 GET_CPU_PRIVATE_PTR(%g0, %g5, %g7, fast_ecc_err_5);
1389 1079 ld [%g5 + CHPR_ICACHE_LINESIZE], %g6
1390 1080 ba,pt %icc, 6f
1391 1081 ld [%g5 + CHPR_ICACHE_SIZE], %g5
1392 1082 fast_ecc_err_5:
1393 1083 ASM_LD(%g5, icache_size)
1394 1084 ASM_LD(%g6, icache_linesize)
1395 1085 6:
1396 1086 CH_ICACHE_FLUSHALL(%g5, %g6, %g7, %g4)
1397 1087
1398 1088 /*
1399 1089 * check to see whether we parked our sibling core at the start
1400 1090 * of this handler. If so, we need to unpark it here.
1401 1091 * We use DCUCR reserved bits (stored in %g1) to keep track of
1402 1092 * whether or not we need to unpark. %g5 and %g4 are scratch registers.
1403 1093 */
1404 1094 UNPARK_SIBLING_CORE(%g1, %g5, %g4)
1405 1095
1406 1096 /*
1407 1097 * Restore the Dcache and Icache to the previous state.
1408 1098 */
1409 1099 stxa %g1, [%g0]ASI_DCU
1410 1100 flush %g0 /* flush required after changing the IC bit */
1411 1101
1412 1102 /*
1413 1103 * Make sure our CPU logout operation was successful.
1414 1104 */
1415 1105 cmp %g3, %g0
1416 1106 be 8f
1417 1107 nop
1418 1108
1419 1109 /*
1420 1110 * If the logout structure had been busy, how many times have
1421 1111 * we tried to use it and failed (nesting count)? If we have
1422 1112 * already recursed a substantial number of times, then we can
1423 1113 * assume things are not going to get better by themselves and
1424 1114 * so it would be best to panic.
1425 1115 */
1426 1116 cmp %g3, CLO_NESTING_MAX
1427 1117 blt 7f
1428 1118 nop
1429 1119
1430 1120 call ptl1_panic
1431 1121 mov PTL1_BAD_ECC, %g1
1432 1122
1433 1123 7:
1434 1124 /*
1435 1125 * Otherwise, if the logout structure was busy but we have not
1436 1126 * nested more times than our maximum value, then we simply
1437 1127 * issue a retry. Our TL=0 trap handler code will check and
1438 1128 * clear the AFSR after it is done logging what is currently
1439 1129 * in the logout struct and handle this event at that time.
1440 1130 */
1441 1131 retry
1442 1132 8:
1443 1133 /*
1444 1134 * Call cpu_fast_ecc_error via systrap at PIL 14 unless we're
↓ open down ↓ |
119 lines elided |
↑ open up ↑ |
1445 1135 * already at PIL 15.
1446 1136 */
1447 1137 set cpu_fast_ecc_error, %g1
1448 1138 rdpr %pil, %g4
1449 1139 cmp %g4, PIL_14
1450 1140 ba sys_trap
1451 1141 movl %icc, PIL_14, %g4
1452 1142
1453 1143 SET_SIZE(fast_ecc_err)
1454 1144
1455 -#endif /* lint */
1456 -
1457 1145 #endif /* !(JALAPENO || SERRANO) */
1458 1146
1459 1147
1460 1148 /*
1461 1149 * Cheetah/Cheetah+ Fast ECC at TL>0 trap strategy:
1462 1150 *
1463 1151 * The basic flow of this trap handler is as follows:
1464 1152 *
1465 1153 * 1) In the "trap 70" trap table code (fecc_err_tl1_instr), generate a
1466 1154 * software trap 0 ("ta 0") to buy an extra set of %tpc, etc. which we
1467 1155 * will use to save %g1 and %g2.
1468 1156 * 2) At the software trap 0 at TL>0 trap table code (fecc_err_tl1_cont_instr),
1469 1157 * we save %g1+%g2 using %tpc, %tnpc + %tstate and jump to the fast ecc
1470 1158 * handler (using the just saved %g1).
1471 1159 * 3) Turn off the Dcache if it was on and save the state of the Dcache
1472 1160 * (whether on or off) in Bit2 (CH_ERR_TSTATE_DC_ON) of %tstate.
1473 1161 * NB: we don't turn off the Icache because bad data is not installed nor
1474 1162 * will we be doing any diagnostic accesses.
1475 1163 * 4) compute physical address of the per-cpu/per-tl save area using %g1+%g2
1476 1164 * 5) Save %g1-%g7 into the per-cpu/per-tl save area (%g1 + %g2 from the
1477 1165 * %tpc, %tnpc, %tstate values previously saved).
1478 1166 * 6) set %tl to %tl - 1.
1479 1167 * 7) Save the appropriate flags and TPC in the ch_err_tl1_data structure.
1480 1168 * 8) Save the value of CH_ERR_TSTATE_DC_ON in the ch_err_tl1_tmp field.
1481 1169 * 9) For Cheetah and Jalapeno, read the AFAR and AFSR and clear. For
1482 1170 * Cheetah+ (and later), read the shadow AFAR and AFSR but don't clear.
1483 1171 * Save the values in ch_err_tl1_data. For Panther, read the shadow
1484 1172 * AFSR_EXT and save the value in ch_err_tl1_data.
1485 1173 * 10) Disable CEEN/NCEEN to prevent any disrupting/deferred errors from
1486 1174 * being queued. We'll report them via the AFSR/AFAR capture in step 13.
1487 1175 * 11) Flush the Ecache.
1488 1176 * NB: the Ecache is flushed assuming the largest possible size with
1489 1177 * the smallest possible line size since access to the cpu_nodes may
1490 1178 * cause an unrecoverable DTLB miss.
1491 1179 * 12) Reenable CEEN/NCEEN with the value saved from step 10.
1492 1180 * 13) For Cheetah and Jalapeno, read the AFAR and AFSR and clear again.
1493 1181 * For Cheetah+ (and later), read the primary AFAR and AFSR and now clear.
1494 1182 * Save the read AFSR/AFAR values in ch_err_tl1_data. For Panther,
1495 1183 * read and clear the primary AFSR_EXT and save it in ch_err_tl1_data.
1496 1184 * 14) Flush and re-enable the Dcache if it was on at step 3.
1497 1185 * 15) Do TRAPTRACE if enabled.
1498 1186 * 16) Check if a UCU->WDU (or L3_UCU->WDU for Panther) happened, panic if so.
1499 1187 * 17) Set the event pending flag in ch_err_tl1_pending[CPU]
1500 1188 * 18) Cause a softint 15. The pil15_interrupt handler will inspect the
1501 1189 * event pending flag and call cpu_tl1_error via systrap if set.
1502 1190 * 19) Restore the registers from step 5 and issue retry.
1503 1191 */
↓ open down ↓ |
37 lines elided |
↑ open up ↑ |
1504 1192
1505 1193 /*
1506 1194 * Cheetah ecc-protected E$ trap (Trap 70) at TL>0
1507 1195 * tt1_fecc is replaced by fecc_err_tl1_instr in cpu_init_trap of the various
1508 1196 * architecture-specific files. This generates a "Software Trap 0" at TL>0,
1509 1197 * which goes to fecc_err_tl1_cont_instr, and we continue the handling there.
1510 1198 * NB: Must be 8 instructions or less to fit in trap table and code must
1511 1199 * be relocatable.
1512 1200 */
1513 1201
1514 -#if defined(lint)
1515 -
1516 -void
1517 -fecc_err_tl1_instr(void)
1518 -{}
1519 -
1520 -#else /* lint */
1521 -
1522 1202 ENTRY_NP(fecc_err_tl1_instr)
1523 1203 CH_ERR_TL1_TRAPENTRY(SWTRAP_0);
1524 1204 SET_SIZE(fecc_err_tl1_instr)
1525 1205
1526 -#endif /* lint */
1527 -
1528 1206 /*
1529 1207 * Software trap 0 at TL>0.
1530 1208 * tt1_swtrap0 is replaced by fecc_err_tl1_cont_instr in cpu_init_trap of
1531 1209 * the various architecture-specific files. This is used as a continuation
1532 1210 * of the fast ecc handling where we've bought an extra TL level, so we can
1533 1211 * use %tpc, %tnpc, %tstate to temporarily save the value of registers %g1
1534 1212 * and %g2. Note that %tstate has bits 0-2 and then bits 8-19 as r/w,
1535 1213 * there's a reserved hole from 3-7. We only use bits 0-1 and 8-9 (the low
1536 1214 * order two bits from %g1 and %g2 respectively).
1537 1215 * NB: Must be 8 instructions or less to fit in trap table and code must
1538 1216 * be relocatable.
1539 1217 */
1540 -#if defined(lint)
1541 1218
1542 -void
1543 -fecc_err_tl1_cont_instr(void)
1544 -{}
1545 -
1546 -#else /* lint */
1547 -
1548 1219 ENTRY_NP(fecc_err_tl1_cont_instr)
1549 1220 CH_ERR_TL1_SWTRAPENTRY(fast_ecc_tl1_err)
1550 1221 SET_SIZE(fecc_err_tl1_cont_instr)
1551 1222
1552 -#endif /* lint */
1553 1223
1554 -
1555 -#if defined(lint)
1556 -
1557 -void
1558 -ce_err(void)
1559 -{}
1560 -
1561 -#else /* lint */
1562 -
1563 1224 /*
1564 1225 * The ce_err function handles disrupting trap type 0x63 at TL=0.
1565 1226 *
1566 1227 * AFSR errors bits which cause this trap are:
1567 1228 * CE, EMC, EDU:ST, EDC, WDU, WDC, CPU, CPC, IVU, IVC
1568 1229 *
1569 1230 * NCEEN Bit of Cheetah External Cache Error Enable Register enables
1570 1231 * the following AFSR disrupting traps: EDU:ST, WDU, CPU, IVU
1571 1232 *
1572 1233 * CEEN Bit of Cheetah External Cache Error Enable Register enables
1573 1234 * the following AFSR disrupting traps: CE, EMC, EDC, WDC, CPC, IVC
1574 1235 *
1575 1236 * Cheetah+ also handles (No additional processing required):
1576 1237 * DUE, DTO, DBERR (NCEEN controlled)
1577 1238 * THCE (CEEN and ET_ECC_en controlled)
1578 1239 * TUE (ET_ECC_en controlled)
1579 1240 *
1580 1241 * Panther further adds:
1581 1242 * IMU, L3_EDU, L3_WDU, L3_CPU (NCEEN controlled)
1582 1243 * IMC, L3_EDC, L3_WDC, L3_CPC, L3_THCE (CEEN controlled)
1583 1244 * TUE_SH, TUE (NCEEN and L2_tag_ECC_en controlled)
1584 1245 * L3_TUE, L3_TUE_SH (NCEEN and ET_ECC_en controlled)
1585 1246 * THCE (CEEN and L2_tag_ECC_en controlled)
1586 1247 * L3_THCE (CEEN and ET_ECC_en controlled)
1587 1248 *
1588 1249 * Steps:
1589 1250 * 1. Disable hardware corrected disrupting errors only (CEEN)
1590 1251 * 2. Park sibling core if caches are shared (to avoid race
1591 1252 * condition while accessing shared resources such as L3
1592 1253 * data staging register during CPU logout.
1593 1254 * 3. If the CPU logout structure is not currently being used:
1594 1255 * 4. Clear AFSR error bits
1595 1256 * 5. Capture Ecache, Dcache and Icache lines associated
1596 1257 * with AFAR.
1597 1258 * 6. Unpark sibling core if we parked it earlier.
1598 1259 * 7. call cpu_disrupting_error via sys_trap at PIL 14
1599 1260 * unless we're already running at PIL 15.
1600 1261 * 4. Otherwise, if the CPU logout structure is busy:
1601 1262 * 5. Incriment "logout busy count" and place into %g3
1602 1263 * 6. Unpark sibling core if we parked it earlier.
1603 1264 * 7. Issue a retry since the other CPU error logging
1604 1265 * code will end up finding this error bit and logging
1605 1266 * information about it later.
1606 1267 * 5. Alternatively (to 3 and 4 above), if the cpu_private struct is
1607 1268 * not yet initialized such that we can't even check the logout
1608 1269 * struct, then we place the clo_flags data into %g2
1609 1270 * (sys_trap->have_win arg #1) and call cpu_disrupting_error via
1610 1271 * systrap. The clo_flags parameter is used to determine information
1611 1272 * such as TL, TT, CEEN settings, etc in the high level trap
1612 1273 * handler since we don't have access to detailed logout information
1613 1274 * in cases where the cpu_private struct is not yet initialized.
1614 1275 *
1615 1276 * %g3: [ logout busy count ] - arg #2
1616 1277 * %g2: [ clo_flags if cpu_private unavailable ] - sys_trap->have_win: arg #1
1617 1278 */
1618 1279
1619 1280 .align 128
1620 1281 ENTRY_NP(ce_err)
1621 1282 membar #Sync ! Cheetah requires membar #Sync
1622 1283
1623 1284 /*
1624 1285 * Disable trap on hardware corrected errors (CEEN) while at TL=0
1625 1286 * to prevent recursion.
1626 1287 */
1627 1288 ldxa [%g0]ASI_ESTATE_ERR, %g1
1628 1289 bclr EN_REG_CEEN, %g1
1629 1290 stxa %g1, [%g0]ASI_ESTATE_ERR
1630 1291 membar #Sync ! membar sync required
1631 1292
1632 1293 /*
1633 1294 * Save current DCU state. Turn off Icache to allow capture of
1634 1295 * Icache data by DO_CPU_LOGOUT.
1635 1296 */
1636 1297 ldxa [%g0]ASI_DCU, %g1 ! save DCU in %g1
1637 1298 andn %g1, DCU_IC, %g4
1638 1299 stxa %g4, [%g0]ASI_DCU
1639 1300 flush %g0 /* flush required after changing the IC bit */
1640 1301
1641 1302 /*
1642 1303 * Check to see whether we need to park our sibling core
1643 1304 * before recording diagnostic information from caches
1644 1305 * which may be shared by both cores.
1645 1306 * We use %g1 to store information about whether or not
1646 1307 * we had to park the core (%g1 holds our DCUCR value and
1647 1308 * we only use bits from that register which are "reserved"
1648 1309 * to keep track of core parking) so that we know whether
1649 1310 * or not to unpark later. %g5 and %g4 are scratch registers.
1650 1311 */
1651 1312 PARK_SIBLING_CORE(%g1, %g5, %g4)
1652 1313
1653 1314 /*
1654 1315 * Do the CPU log out capture.
1655 1316 * %g3 = "failed?" return value.
1656 1317 * %g2 = Input = AFAR. Output the clo_flags info which is passed
1657 1318 * into this macro via %g4. Output only valid if cpu_private
1658 1319 * struct has not been initialized.
1659 1320 * CHPR_CECC_LOGOUT = cpu logout structure offset input
1660 1321 * %g4 = Trap information stored in the cpu logout flags field
1661 1322 * %g5 = scr1
1662 1323 * %g6 = scr2
1663 1324 * %g3 = scr3
1664 1325 * %g4 = scr4
1665 1326 */
1666 1327 clr %g4 ! TL=0 bit in afsr
1667 1328 set CHPR_CECC_LOGOUT, %g6
1668 1329 DO_CPU_LOGOUT(%g3, %g2, %g6, %g4, %g5, %g6, %g3, %g4)
1669 1330
1670 1331 /*
1671 1332 * Flush the Icache. Since we turned off the Icache to capture the
1672 1333 * Icache line it is now stale or corrupted and we must flush it
1673 1334 * before re-enabling it.
1674 1335 */
1675 1336 GET_CPU_PRIVATE_PTR(%g0, %g5, %g7, ce_err_1);
1676 1337 ld [%g5 + CHPR_ICACHE_LINESIZE], %g6
1677 1338 ba,pt %icc, 2f
1678 1339 ld [%g5 + CHPR_ICACHE_SIZE], %g5
1679 1340 ce_err_1:
1680 1341 ASM_LD(%g5, icache_size)
1681 1342 ASM_LD(%g6, icache_linesize)
1682 1343 2:
1683 1344 CH_ICACHE_FLUSHALL(%g5, %g6, %g7, %g4)
1684 1345
1685 1346 /*
1686 1347 * check to see whether we parked our sibling core at the start
1687 1348 * of this handler. If so, we need to unpark it here.
1688 1349 * We use DCUCR reserved bits (stored in %g1) to keep track of
1689 1350 * whether or not we need to unpark. %g5 and %g4 are scratch registers.
1690 1351 */
1691 1352 UNPARK_SIBLING_CORE(%g1, %g5, %g4)
1692 1353
1693 1354 /*
1694 1355 * Restore Icache to previous state.
1695 1356 */
1696 1357 stxa %g1, [%g0]ASI_DCU
1697 1358 flush %g0 /* flush required after changing the IC bit */
1698 1359
1699 1360 /*
1700 1361 * Make sure our CPU logout operation was successful.
1701 1362 */
1702 1363 cmp %g3, %g0
1703 1364 be 4f
1704 1365 nop
1705 1366
1706 1367 /*
1707 1368 * If the logout structure had been busy, how many times have
1708 1369 * we tried to use it and failed (nesting count)? If we have
1709 1370 * already recursed a substantial number of times, then we can
1710 1371 * assume things are not going to get better by themselves and
1711 1372 * so it would be best to panic.
1712 1373 */
1713 1374 cmp %g3, CLO_NESTING_MAX
1714 1375 blt 3f
1715 1376 nop
1716 1377
1717 1378 call ptl1_panic
1718 1379 mov PTL1_BAD_ECC, %g1
1719 1380
1720 1381 3:
1721 1382 /*
1722 1383 * Otherwise, if the logout structure was busy but we have not
1723 1384 * nested more times than our maximum value, then we simply
1724 1385 * issue a retry. Our TL=0 trap handler code will check and
1725 1386 * clear the AFSR after it is done logging what is currently
1726 1387 * in the logout struct and handle this event at that time.
1727 1388 */
1728 1389 retry
1729 1390 4:
1730 1391 /*
↓ open down ↓ |
158 lines elided |
↑ open up ↑ |
1731 1392 * Call cpu_disrupting_error via systrap at PIL 14 unless we're
1732 1393 * already at PIL 15.
1733 1394 */
1734 1395 set cpu_disrupting_error, %g1
1735 1396 rdpr %pil, %g4
1736 1397 cmp %g4, PIL_14
1737 1398 ba sys_trap
1738 1399 movl %icc, PIL_14, %g4
1739 1400 SET_SIZE(ce_err)
1740 1401
1741 -#endif /* lint */
1742 1402
1743 -
1744 -#if defined(lint)
1745 -
1746 -/*
1747 - * This trap cannot happen at TL>0 which means this routine will never
1748 - * actually be called and so we treat this like a BAD TRAP panic.
1749 - */
1750 -void
1751 -ce_err_tl1(void)
1752 -{}
1753 -
1754 -#else /* lint */
1755 -
1756 1403 .align 64
1757 1404 ENTRY_NP(ce_err_tl1)
1758 1405
1759 1406 call ptl1_panic
1760 1407 mov PTL1_BAD_TRAP, %g1
1761 1408
1762 1409 SET_SIZE(ce_err_tl1)
1763 1410
1764 -#endif /* lint */
1765 -
1766 1411
1767 -#if defined(lint)
1768 -
1769 -void
1770 -async_err(void)
1771 -{}
1772 -
1773 -#else /* lint */
1774 -
1775 1412 /*
1776 1413 * The async_err function handles deferred trap types 0xA
1777 1414 * (instruction_access_error) and 0x32 (data_access_error) at TL>=0.
1778 1415 *
1779 1416 * AFSR errors bits which cause this trap are:
1780 1417 * UE, EMU, EDU:BLD, L3_EDU:BLD, TO, BERR
1781 1418 * On some platforms, EMU may causes cheetah to pull the error pin
1782 1419 * never giving Solaris a chance to take a trap.
1783 1420 *
1784 1421 * NCEEN Bit of Cheetah External Cache Error Enable Register enables
1785 1422 * the following AFSR deferred traps: UE, EMU, EDU:BLD, TO, BERR
1786 1423 *
1787 1424 * Steps:
1788 1425 * 1. Disable CEEN and NCEEN errors to prevent recursive errors.
1789 1426 * 2. Turn D$ off per Cheetah PRM P.5 Note 6, turn I$ off to capture
1790 1427 * I$ line in DO_CPU_LOGOUT.
1791 1428 * 3. Park sibling core if caches are shared (to avoid race
1792 1429 * condition while accessing shared resources such as L3
1793 1430 * data staging register during CPU logout.
1794 1431 * 4. If the CPU logout structure is not currently being used:
1795 1432 * 5. Clear AFSR error bits
1796 1433 * 6. Capture Ecache, Dcache and Icache lines associated
1797 1434 * with AFAR.
1798 1435 * 7. Unpark sibling core if we parked it earlier.
1799 1436 * 8. call cpu_deferred_error via sys_trap.
1800 1437 * 5. Otherwise, if the CPU logout structure is busy:
1801 1438 * 6. Incriment "logout busy count"
1802 1439 * 7. Unpark sibling core if we parked it earlier.
1803 1440 * 8) Issue a retry since the other CPU error logging
1804 1441 * code will end up finding this error bit and logging
1805 1442 * information about it later.
1806 1443 * 6. Alternatively (to 4 and 5 above), if the cpu_private struct is
1807 1444 * not yet initialized such that we can't even check the logout
1808 1445 * struct, then we place the clo_flags data into %g2
1809 1446 * (sys_trap->have_win arg #1) and call cpu_deferred_error via
1810 1447 * systrap. The clo_flags parameter is used to determine information
1811 1448 * such as TL, TT, CEEN settings, etc in the high level trap handler
1812 1449 * since we don't have access to detailed logout information in cases
1813 1450 * where the cpu_private struct is not yet initialized.
1814 1451 *
1815 1452 * %g2: [ clo_flags if cpu_private unavailable ] - sys_trap->have_win: arg #1
1816 1453 * %g3: [ logout busy count ] - arg #2
1817 1454 */
1818 1455
1819 1456 ENTRY_NP(async_err)
1820 1457 membar #Sync ! Cheetah requires membar #Sync
1821 1458
1822 1459 /*
1823 1460 * Disable CEEN and NCEEN.
1824 1461 */
1825 1462 ldxa [%g0]ASI_ESTATE_ERR, %g3
1826 1463 andn %g3, EN_REG_NCEEN + EN_REG_CEEN, %g4
1827 1464 stxa %g4, [%g0]ASI_ESTATE_ERR
1828 1465 membar #Sync ! membar sync required
1829 1466
1830 1467 /*
1831 1468 * Save current DCU state.
1832 1469 * Disable Icache to allow capture of Icache data by DO_CPU_LOGOUT.
1833 1470 * Do this regardless of whether this is a Data Access Error or
1834 1471 * Instruction Access Error Trap.
1835 1472 * Disable Dcache for both Data Access Error and Instruction Access
1836 1473 * Error per Cheetah PRM P.5 Note 6.
1837 1474 */
1838 1475 ldxa [%g0]ASI_DCU, %g1 ! save DCU in %g1
1839 1476 andn %g1, DCU_IC + DCU_DC, %g4
1840 1477 stxa %g4, [%g0]ASI_DCU
1841 1478 flush %g0 /* flush required after changing the IC bit */
1842 1479
1843 1480 /*
1844 1481 * Check to see whether we need to park our sibling core
1845 1482 * before recording diagnostic information from caches
1846 1483 * which may be shared by both cores.
1847 1484 * We use %g1 to store information about whether or not
1848 1485 * we had to park the core (%g1 holds our DCUCR value and
1849 1486 * we only use bits from that register which are "reserved"
1850 1487 * to keep track of core parking) so that we know whether
1851 1488 * or not to unpark later. %g6 and %g4 are scratch registers.
1852 1489 */
1853 1490 PARK_SIBLING_CORE(%g1, %g6, %g4)
1854 1491
1855 1492 /*
1856 1493 * Do the CPU logout capture.
1857 1494 *
1858 1495 * %g3 = "failed?" return value.
1859 1496 * %g2 = Input = AFAR. Output the clo_flags info which is passed
1860 1497 * into this macro via %g4. Output only valid if cpu_private
1861 1498 * struct has not been initialized.
1862 1499 * CHPR_ASYNC_LOGOUT = cpu logout structure offset input
1863 1500 * %g4 = Trap information stored in the cpu logout flags field
1864 1501 * %g5 = scr1
1865 1502 * %g6 = scr2
1866 1503 * %g3 = scr3
1867 1504 * %g4 = scr4
1868 1505 */
1869 1506 andcc %g5, T_TL1, %g0
1870 1507 clr %g6
1871 1508 movnz %xcc, 1, %g6 ! set %g6 if T_TL1 set
1872 1509 sllx %g6, CLO_FLAGS_TL_SHIFT, %g6
1873 1510 sllx %g5, CLO_FLAGS_TT_SHIFT, %g4
1874 1511 set CLO_FLAGS_TT_MASK, %g2
1875 1512 and %g4, %g2, %g4 ! ttype
1876 1513 or %g6, %g4, %g4 ! TT and TL
1877 1514 and %g3, EN_REG_CEEN, %g3 ! CEEN value
1878 1515 or %g3, %g4, %g4 ! TT and TL and CEEN
1879 1516 set CHPR_ASYNC_LOGOUT, %g6
1880 1517 DO_CPU_LOGOUT(%g3, %g2, %g6, %g4, %g5, %g6, %g3, %g4)
1881 1518
1882 1519 /*
1883 1520 * If the logout struct was busy, we may need to pass the
1884 1521 * TT, TL, and CEEN information to the TL=0 handler via
1885 1522 * systrap parameter so save it off here.
1886 1523 */
1887 1524 cmp %g3, %g0
1888 1525 be 1f
1889 1526 nop
1890 1527 sllx %g4, 32, %g4
1891 1528 or %g4, %g3, %g3
1892 1529 1:
1893 1530 /*
1894 1531 * Flush the Icache. Since we turned off the Icache to capture the
1895 1532 * Icache line it is now stale or corrupted and we must flush it
1896 1533 * before re-enabling it.
1897 1534 */
1898 1535 GET_CPU_PRIVATE_PTR(%g0, %g5, %g7, async_err_1);
1899 1536 ld [%g5 + CHPR_ICACHE_LINESIZE], %g6
1900 1537 ba,pt %icc, 2f
1901 1538 ld [%g5 + CHPR_ICACHE_SIZE], %g5
1902 1539 async_err_1:
1903 1540 ASM_LD(%g5, icache_size)
1904 1541 ASM_LD(%g6, icache_linesize)
1905 1542 2:
1906 1543 CH_ICACHE_FLUSHALL(%g5, %g6, %g7, %g4)
1907 1544
1908 1545 /*
1909 1546 * XXX - Don't we need to flush the Dcache before turning it back
1910 1547 * on to avoid stale or corrupt data? Was this broken?
1911 1548 */
1912 1549 /*
1913 1550 * Flush the Dcache before turning it back on since it may now
1914 1551 * contain stale or corrupt data.
1915 1552 */
1916 1553 ASM_LD(%g5, dcache_size)
1917 1554 ASM_LD(%g6, dcache_linesize)
1918 1555 CH_DCACHE_FLUSHALL(%g5, %g6, %g7)
1919 1556
1920 1557 /*
1921 1558 * check to see whether we parked our sibling core at the start
1922 1559 * of this handler. If so, we need to unpark it here.
1923 1560 * We use DCUCR reserved bits (stored in %g1) to keep track of
1924 1561 * whether or not we need to unpark. %g5 and %g7 are scratch registers.
1925 1562 */
1926 1563 UNPARK_SIBLING_CORE(%g1, %g5, %g7)
1927 1564
1928 1565 /*
1929 1566 * Restore Icache and Dcache to previous state.
1930 1567 */
1931 1568 stxa %g1, [%g0]ASI_DCU
1932 1569 flush %g0 /* flush required after changing the IC bit */
1933 1570
1934 1571 /*
1935 1572 * Make sure our CPU logout operation was successful.
1936 1573 */
1937 1574 cmp %g3, %g0
1938 1575 be 4f
1939 1576 nop
1940 1577
1941 1578 /*
1942 1579 * If the logout structure had been busy, how many times have
1943 1580 * we tried to use it and failed (nesting count)? If we have
1944 1581 * already recursed a substantial number of times, then we can
1945 1582 * assume things are not going to get better by themselves and
1946 1583 * so it would be best to panic.
1947 1584 */
1948 1585 cmp %g3, CLO_NESTING_MAX
1949 1586 blt 3f
1950 1587 nop
1951 1588
1952 1589 call ptl1_panic
1953 1590 mov PTL1_BAD_ECC, %g1
1954 1591
1955 1592 3:
1956 1593 /*
1957 1594 * Otherwise, if the logout structure was busy but we have not
1958 1595 * nested more times than our maximum value, then we simply
1959 1596 * issue a retry. Our TL=0 trap handler code will check and
1960 1597 * clear the AFSR after it is done logging what is currently
1961 1598 * in the logout struct and handle this event at that time.
↓ open down ↓ |
177 lines elided |
↑ open up ↑ |
1962 1599 */
1963 1600 retry
1964 1601 4:
1965 1602 RESET_USER_RTT_REGS(%g4, %g5, async_err_resetskip)
1966 1603 async_err_resetskip:
1967 1604 set cpu_deferred_error, %g1
1968 1605 ba sys_trap
1969 1606 mov PIL_15, %g4 ! run at pil 15
1970 1607 SET_SIZE(async_err)
1971 1608
1972 -#endif /* lint */
1973 -
1974 1609 #if defined(CPU_IMP_L1_CACHE_PARITY)
1975 1610
1976 1611 /*
1977 1612 * D$ parity error trap (trap 71) at TL=0.
1978 1613 * tt0_dperr is replaced by dcache_parity_instr in cpu_init_trap of
1979 1614 * the various architecture-specific files. This merely sets up the
1980 1615 * arguments for cpu_parity_error and calls it via sys_trap.
1981 1616 * NB: Must be 8 instructions or less to fit in trap table and code must
1982 1617 * be relocatable.
1983 1618 */
1984 -#if defined(lint)
1985 -
1986 -void
1987 -dcache_parity_instr(void)
1988 -{}
1989 -
1990 -#else /* lint */
1991 1619 ENTRY_NP(dcache_parity_instr)
1992 1620 membar #Sync ! Cheetah+ requires membar #Sync
1993 1621 set cpu_parity_error, %g1
1994 1622 or %g0, CH_ERR_DPE, %g2
1995 1623 rdpr %tpc, %g3
1996 1624 sethi %hi(sys_trap), %g7
1997 1625 jmp %g7 + %lo(sys_trap)
1998 1626 mov PIL_15, %g4 ! run at pil 15
1999 1627 SET_SIZE(dcache_parity_instr)
2000 1628
2001 -#endif /* lint */
2002 1629
2003 -
2004 1630 /*
2005 1631 * D$ parity error trap (trap 71) at TL>0.
2006 1632 * tt1_dperr is replaced by dcache_parity_tl1_instr in cpu_init_trap of
2007 1633 * the various architecture-specific files. This generates a "Software
2008 1634 * Trap 1" at TL>0, which goes to dcache_parity_tl1_cont_instr, and we
2009 1635 * continue the handling there.
2010 1636 * NB: Must be 8 instructions or less to fit in trap table and code must
2011 1637 * be relocatable.
2012 1638 */
2013 -#if defined(lint)
2014 -
2015 -void
2016 -dcache_parity_tl1_instr(void)
2017 -{}
2018 -
2019 -#else /* lint */
2020 1639 ENTRY_NP(dcache_parity_tl1_instr)
2021 1640 CH_ERR_TL1_TRAPENTRY(SWTRAP_1);
2022 1641 SET_SIZE(dcache_parity_tl1_instr)
2023 1642
2024 -#endif /* lint */
2025 1643
2026 -
2027 1644 /*
2028 1645 * Software trap 1 at TL>0.
2029 1646 * tt1_swtrap1 is replaced by dcache_parity_tl1_cont_instr in cpu_init_trap
2030 1647 * of the various architecture-specific files. This is used as a continuation
2031 1648 * of the dcache parity handling where we've bought an extra TL level, so we
2032 1649 * can use %tpc, %tnpc, %tstate to temporarily save the value of registers %g1
2033 1650 * and %g2. Note that %tstate has bits 0-2 and then bits 8-19 as r/w,
2034 1651 * there's a reserved hole from 3-7. We only use bits 0-1 and 8-9 (the low
2035 1652 * order two bits from %g1 and %g2 respectively).
2036 1653 * NB: Must be 8 instructions or less to fit in trap table and code must
2037 1654 * be relocatable.
2038 1655 */
2039 -#if defined(lint)
2040 -
2041 -void
2042 -dcache_parity_tl1_cont_instr(void)
2043 -{}
2044 -
2045 -#else /* lint */
2046 1656 ENTRY_NP(dcache_parity_tl1_cont_instr)
2047 1657 CH_ERR_TL1_SWTRAPENTRY(dcache_parity_tl1_err);
2048 1658 SET_SIZE(dcache_parity_tl1_cont_instr)
2049 1659
2050 -#endif /* lint */
2051 -
2052 1660 /*
2053 1661 * D$ parity error at TL>0 handler
2054 1662 * We get here via trap 71 at TL>0->Software trap 1 at TL>0. We enter
2055 1663 * this routine with %g1 and %g2 already saved in %tpc, %tnpc and %tstate.
2056 1664 */
2057 -#if defined(lint)
2058 1665
2059 -void
2060 -dcache_parity_tl1_err(void)
2061 -{}
2062 -
2063 -#else /* lint */
2064 -
2065 1666 ENTRY_NP(dcache_parity_tl1_err)
2066 1667
2067 1668 /*
2068 1669 * This macro saves all the %g registers in the ch_err_tl1_data
2069 1670 * structure, updates the ch_err_tl1_flags and saves the %tpc in
2070 1671 * ch_err_tl1_tpc. At the end of this macro, %g1 will point to
2071 1672 * the ch_err_tl1_data structure and %g2 will have the original
2072 1673 * flags in the ch_err_tl1_data structure. All %g registers
2073 1674 * except for %g1 and %g2 will be available.
2074 1675 */
2075 1676 CH_ERR_TL1_ENTER(CH_ERR_DPE);
2076 1677
2077 1678 #ifdef TRAPTRACE
2078 1679 /*
2079 1680 * Get current trap trace entry physical pointer.
2080 1681 */
2081 1682 CPU_INDEX(%g6, %g5)
2082 1683 sll %g6, TRAPTR_SIZE_SHIFT, %g6
2083 1684 set trap_trace_ctl, %g5
2084 1685 add %g6, %g5, %g6
2085 1686 ld [%g6 + TRAPTR_LIMIT], %g5
2086 1687 tst %g5
2087 1688 be %icc, dpe_tl1_skip_tt
2088 1689 nop
2089 1690 ldx [%g6 + TRAPTR_PBASE], %g5
2090 1691 ld [%g6 + TRAPTR_OFFSET], %g4
2091 1692 add %g5, %g4, %g5
2092 1693
2093 1694 /*
2094 1695 * Create trap trace entry.
2095 1696 */
2096 1697 rd %asi, %g7
2097 1698 wr %g0, TRAPTR_ASI, %asi
2098 1699 rd STICK, %g4
2099 1700 stxa %g4, [%g5 + TRAP_ENT_TICK]%asi
2100 1701 rdpr %tl, %g4
2101 1702 stha %g4, [%g5 + TRAP_ENT_TL]%asi
2102 1703 rdpr %tt, %g4
2103 1704 stha %g4, [%g5 + TRAP_ENT_TT]%asi
2104 1705 rdpr %tpc, %g4
2105 1706 stna %g4, [%g5 + TRAP_ENT_TPC]%asi
2106 1707 rdpr %tstate, %g4
2107 1708 stxa %g4, [%g5 + TRAP_ENT_TSTATE]%asi
2108 1709 stna %sp, [%g5 + TRAP_ENT_SP]%asi
2109 1710 stna %g0, [%g5 + TRAP_ENT_TR]%asi
2110 1711 stna %g0, [%g5 + TRAP_ENT_F1]%asi
2111 1712 stna %g0, [%g5 + TRAP_ENT_F2]%asi
2112 1713 stna %g0, [%g5 + TRAP_ENT_F3]%asi
2113 1714 stna %g0, [%g5 + TRAP_ENT_F4]%asi
2114 1715 wr %g0, %g7, %asi
2115 1716
2116 1717 /*
2117 1718 * Advance trap trace pointer.
2118 1719 */
2119 1720 ld [%g6 + TRAPTR_OFFSET], %g5
2120 1721 ld [%g6 + TRAPTR_LIMIT], %g4
2121 1722 st %g5, [%g6 + TRAPTR_LAST_OFFSET]
2122 1723 add %g5, TRAP_ENT_SIZE, %g5
2123 1724 sub %g4, TRAP_ENT_SIZE, %g4
2124 1725 cmp %g5, %g4
2125 1726 movge %icc, 0, %g5
2126 1727 st %g5, [%g6 + TRAPTR_OFFSET]
2127 1728 dpe_tl1_skip_tt:
2128 1729 #endif /* TRAPTRACE */
2129 1730
2130 1731 /*
2131 1732 * I$ and D$ are automatically turned off by HW when the CPU hits
2132 1733 * a dcache or icache parity error so we will just leave those two
2133 1734 * off for now to avoid repeating this trap.
2134 1735 * For Panther, however, since we trap on P$ data parity errors
2135 1736 * and HW does not automatically disable P$, we need to disable it
2136 1737 * here so that we don't encounter any recursive traps when we
2137 1738 * issue the retry.
2138 1739 */
2139 1740 ldxa [%g0]ASI_DCU, %g3
2140 1741 mov 1, %g4
2141 1742 sllx %g4, DCU_PE_SHIFT, %g4
2142 1743 andn %g3, %g4, %g3
2143 1744 stxa %g3, [%g0]ASI_DCU
2144 1745 membar #Sync
↓ open down ↓ |
70 lines elided |
↑ open up ↑ |
2145 1746
2146 1747 /*
2147 1748 * We fall into this macro if we've successfully logged the error in
2148 1749 * the ch_err_tl1_data structure and want the PIL15 softint to pick
2149 1750 * it up and log it. %g1 must point to the ch_err_tl1_data structure.
2150 1751 * Restores the %g registers and issues retry.
2151 1752 */
2152 1753 CH_ERR_TL1_EXIT;
2153 1754 SET_SIZE(dcache_parity_tl1_err)
2154 1755
2155 -#endif /* lint */
2156 -
2157 1756 /*
2158 1757 * I$ parity error trap (trap 72) at TL=0.
2159 1758 * tt0_iperr is replaced by icache_parity_instr in cpu_init_trap of
2160 1759 * the various architecture-specific files. This merely sets up the
2161 1760 * arguments for cpu_parity_error and calls it via sys_trap.
2162 1761 * NB: Must be 8 instructions or less to fit in trap table and code must
2163 1762 * be relocatable.
2164 1763 */
2165 -#if defined(lint)
2166 1764
2167 -void
2168 -icache_parity_instr(void)
2169 -{}
2170 -
2171 -#else /* lint */
2172 -
2173 1765 ENTRY_NP(icache_parity_instr)
2174 1766 membar #Sync ! Cheetah+ requires membar #Sync
2175 1767 set cpu_parity_error, %g1
2176 1768 or %g0, CH_ERR_IPE, %g2
2177 1769 rdpr %tpc, %g3
2178 1770 sethi %hi(sys_trap), %g7
2179 1771 jmp %g7 + %lo(sys_trap)
2180 1772 mov PIL_15, %g4 ! run at pil 15
2181 1773 SET_SIZE(icache_parity_instr)
2182 1774
2183 -#endif /* lint */
2184 -
2185 1775 /*
2186 1776 * I$ parity error trap (trap 72) at TL>0.
2187 1777 * tt1_iperr is replaced by icache_parity_tl1_instr in cpu_init_trap of
2188 1778 * the various architecture-specific files. This generates a "Software
2189 1779 * Trap 2" at TL>0, which goes to icache_parity_tl1_cont_instr, and we
2190 1780 * continue the handling there.
2191 1781 * NB: Must be 8 instructions or less to fit in trap table and code must
2192 1782 * be relocatable.
2193 1783 */
2194 -#if defined(lint)
2195 -
2196 -void
2197 -icache_parity_tl1_instr(void)
2198 -{}
2199 -
2200 -#else /* lint */
2201 1784 ENTRY_NP(icache_parity_tl1_instr)
2202 1785 CH_ERR_TL1_TRAPENTRY(SWTRAP_2);
2203 1786 SET_SIZE(icache_parity_tl1_instr)
2204 1787
2205 -#endif /* lint */
2206 -
2207 1788 /*
2208 1789 * Software trap 2 at TL>0.
2209 1790 * tt1_swtrap2 is replaced by icache_parity_tl1_cont_instr in cpu_init_trap
2210 1791 * of the various architecture-specific files. This is used as a continuation
2211 1792 * of the icache parity handling where we've bought an extra TL level, so we
2212 1793 * can use %tpc, %tnpc, %tstate to temporarily save the value of registers %g1
2213 1794 * and %g2. Note that %tstate has bits 0-2 and then bits 8-19 as r/w,
2214 1795 * there's a reserved hole from 3-7. We only use bits 0-1 and 8-9 (the low
2215 1796 * order two bits from %g1 and %g2 respectively).
2216 1797 * NB: Must be 8 instructions or less to fit in trap table and code must
2217 1798 * be relocatable.
2218 1799 */
2219 -#if defined(lint)
2220 -
2221 -void
2222 -icache_parity_tl1_cont_instr(void)
2223 -{}
2224 -
2225 -#else /* lint */
2226 1800 ENTRY_NP(icache_parity_tl1_cont_instr)
2227 1801 CH_ERR_TL1_SWTRAPENTRY(icache_parity_tl1_err);
2228 1802 SET_SIZE(icache_parity_tl1_cont_instr)
2229 1803
2230 -#endif /* lint */
2231 1804
2232 -
2233 1805 /*
2234 1806 * I$ parity error at TL>0 handler
2235 1807 * We get here via trap 72 at TL>0->Software trap 2 at TL>0. We enter
2236 1808 * this routine with %g1 and %g2 already saved in %tpc, %tnpc and %tstate.
2237 1809 */
2238 -#if defined(lint)
2239 1810
2240 -void
2241 -icache_parity_tl1_err(void)
2242 -{}
2243 -
2244 -#else /* lint */
2245 -
2246 1811 ENTRY_NP(icache_parity_tl1_err)
2247 1812
2248 1813 /*
2249 1814 * This macro saves all the %g registers in the ch_err_tl1_data
2250 1815 * structure, updates the ch_err_tl1_flags and saves the %tpc in
2251 1816 * ch_err_tl1_tpc. At the end of this macro, %g1 will point to
2252 1817 * the ch_err_tl1_data structure and %g2 will have the original
2253 1818 * flags in the ch_err_tl1_data structure. All %g registers
2254 1819 * except for %g1 and %g2 will be available.
2255 1820 */
2256 1821 CH_ERR_TL1_ENTER(CH_ERR_IPE);
2257 1822
2258 1823 #ifdef TRAPTRACE
2259 1824 /*
2260 1825 * Get current trap trace entry physical pointer.
2261 1826 */
2262 1827 CPU_INDEX(%g6, %g5)
2263 1828 sll %g6, TRAPTR_SIZE_SHIFT, %g6
2264 1829 set trap_trace_ctl, %g5
2265 1830 add %g6, %g5, %g6
2266 1831 ld [%g6 + TRAPTR_LIMIT], %g5
2267 1832 tst %g5
2268 1833 be %icc, ipe_tl1_skip_tt
2269 1834 nop
2270 1835 ldx [%g6 + TRAPTR_PBASE], %g5
2271 1836 ld [%g6 + TRAPTR_OFFSET], %g4
2272 1837 add %g5, %g4, %g5
2273 1838
2274 1839 /*
2275 1840 * Create trap trace entry.
2276 1841 */
2277 1842 rd %asi, %g7
2278 1843 wr %g0, TRAPTR_ASI, %asi
2279 1844 rd STICK, %g4
2280 1845 stxa %g4, [%g5 + TRAP_ENT_TICK]%asi
2281 1846 rdpr %tl, %g4
2282 1847 stha %g4, [%g5 + TRAP_ENT_TL]%asi
2283 1848 rdpr %tt, %g4
2284 1849 stha %g4, [%g5 + TRAP_ENT_TT]%asi
2285 1850 rdpr %tpc, %g4
2286 1851 stna %g4, [%g5 + TRAP_ENT_TPC]%asi
2287 1852 rdpr %tstate, %g4
2288 1853 stxa %g4, [%g5 + TRAP_ENT_TSTATE]%asi
2289 1854 stna %sp, [%g5 + TRAP_ENT_SP]%asi
2290 1855 stna %g0, [%g5 + TRAP_ENT_TR]%asi
2291 1856 stna %g0, [%g5 + TRAP_ENT_F1]%asi
2292 1857 stna %g0, [%g5 + TRAP_ENT_F2]%asi
2293 1858 stna %g0, [%g5 + TRAP_ENT_F3]%asi
2294 1859 stna %g0, [%g5 + TRAP_ENT_F4]%asi
2295 1860 wr %g0, %g7, %asi
2296 1861
2297 1862 /*
2298 1863 * Advance trap trace pointer.
2299 1864 */
2300 1865 ld [%g6 + TRAPTR_OFFSET], %g5
2301 1866 ld [%g6 + TRAPTR_LIMIT], %g4
2302 1867 st %g5, [%g6 + TRAPTR_LAST_OFFSET]
2303 1868 add %g5, TRAP_ENT_SIZE, %g5
2304 1869 sub %g4, TRAP_ENT_SIZE, %g4
2305 1870 cmp %g5, %g4
2306 1871 movge %icc, 0, %g5
2307 1872 st %g5, [%g6 + TRAPTR_OFFSET]
2308 1873 ipe_tl1_skip_tt:
2309 1874 #endif /* TRAPTRACE */
2310 1875
↓ open down ↓ |
55 lines elided |
↑ open up ↑ |
2311 1876 /*
2312 1877 * We fall into this macro if we've successfully logged the error in
2313 1878 * the ch_err_tl1_data structure and want the PIL15 softint to pick
2314 1879 * it up and log it. %g1 must point to the ch_err_tl1_data structure.
2315 1880 * Restores the %g registers and issues retry.
2316 1881 */
2317 1882 CH_ERR_TL1_EXIT;
2318 1883
2319 1884 SET_SIZE(icache_parity_tl1_err)
2320 1885
2321 -#endif /* lint */
2322 -
2323 1886 #endif /* CPU_IMP_L1_CACHE_PARITY */
2324 1887
2325 1888
2326 1889 /*
2327 1890 * The itlb_rd_entry and dtlb_rd_entry functions return the tag portion of the
2328 1891 * tte, the virtual address, and the ctxnum of the specified tlb entry. They
2329 1892 * should only be used in places where you have no choice but to look at the
2330 1893 * tlb itself.
2331 1894 *
2332 1895 * Note: These two routines are required by the Estar "cpr" loadable module.
2333 1896 */
2334 1897
2335 -#if defined(lint)
2336 -
2337 -/* ARGSUSED */
2338 -void
2339 -itlb_rd_entry(uint_t entry, tte_t *tte, uint64_t *va_tag)
2340 -{}
2341 -
2342 -#else /* lint */
2343 -
2344 1898 ENTRY_NP(itlb_rd_entry)
2345 1899 sllx %o0, 3, %o0
2346 1900 ldxa [%o0]ASI_ITLB_ACCESS, %g1
2347 1901 stx %g1, [%o1]
2348 1902 ldxa [%o0]ASI_ITLB_TAGREAD, %g2
2349 1903 set TAGREAD_CTX_MASK, %o4
2350 1904 andn %g2, %o4, %o5
2351 1905 retl
2352 1906 stx %o5, [%o2]
2353 1907 SET_SIZE(itlb_rd_entry)
2354 1908
2355 -#endif /* lint */
2356 1909
2357 -
2358 -#if defined(lint)
2359 -
2360 -/* ARGSUSED */
2361 -void
2362 -dtlb_rd_entry(uint_t entry, tte_t *tte, uint64_t *va_tag)
2363 -{}
2364 -
2365 -#else /* lint */
2366 -
2367 1910 ENTRY_NP(dtlb_rd_entry)
2368 1911 sllx %o0, 3, %o0
2369 1912 ldxa [%o0]ASI_DTLB_ACCESS, %g1
2370 1913 stx %g1, [%o1]
2371 1914 ldxa [%o0]ASI_DTLB_TAGREAD, %g2
2372 1915 set TAGREAD_CTX_MASK, %o4
2373 1916 andn %g2, %o4, %o5
2374 1917 retl
2375 1918 stx %o5, [%o2]
2376 1919 SET_SIZE(dtlb_rd_entry)
2377 -#endif /* lint */
2378 1920
2379 1921
2380 1922 #if !(defined(JALAPENO) || defined(SERRANO))
2381 1923
2382 -#if defined(lint)
2383 -
2384 -uint64_t
2385 -get_safari_config(void)
2386 -{ return (0); }
2387 -
2388 -#else /* lint */
2389 -
2390 1924 ENTRY(get_safari_config)
2391 1925 ldxa [%g0]ASI_SAFARI_CONFIG, %o0
2392 1926 retl
2393 1927 nop
2394 1928 SET_SIZE(get_safari_config)
2395 1929
2396 -#endif /* lint */
2397 1930
2398 -
2399 -#if defined(lint)
2400 -
2401 -/* ARGSUSED */
2402 -void
2403 -set_safari_config(uint64_t safari_config)
2404 -{}
2405 -
2406 -#else /* lint */
2407 -
2408 1931 ENTRY(set_safari_config)
2409 1932 stxa %o0, [%g0]ASI_SAFARI_CONFIG
2410 1933 membar #Sync
2411 1934 retl
2412 1935 nop
2413 1936 SET_SIZE(set_safari_config)
2414 1937
2415 -#endif /* lint */
2416 -
2417 1938 #endif /* !(JALAPENO || SERRANO) */
2418 1939
2419 1940
2420 -#if defined(lint)
2421 -
2422 -void
2423 -cpu_cleartickpnt(void)
2424 -{}
2425 -
2426 -#else /* lint */
2427 1941 /*
2428 1942 * Clear the NPT (non-privileged trap) bit in the %tick/%stick
2429 1943 * registers. In an effort to make the change in the
2430 1944 * tick/stick counter as consistent as possible, we disable
2431 1945 * all interrupts while we're changing the registers. We also
2432 1946 * ensure that the read and write instructions are in the same
2433 1947 * line in the instruction cache.
2434 1948 */
2435 1949 ENTRY_NP(cpu_clearticknpt)
2436 1950 rdpr %pstate, %g1 /* save processor state */
2437 1951 andn %g1, PSTATE_IE, %g3 /* turn off */
2438 1952 wrpr %g0, %g3, %pstate /* interrupts */
2439 1953 rdpr %tick, %g2 /* get tick register */
2440 1954 brgez,pn %g2, 1f /* if NPT bit off, we're done */
2441 1955 mov 1, %g3 /* create mask */
2442 1956 sllx %g3, 63, %g3 /* for NPT bit */
2443 1957 ba,a,pt %xcc, 2f
2444 1958 .align 8 /* Ensure rd/wr in same i$ line */
2445 1959 2:
2446 1960 rdpr %tick, %g2 /* get tick register */
2447 1961 wrpr %g3, %g2, %tick /* write tick register, */
2448 1962 /* clearing NPT bit */
2449 1963 1:
2450 1964 rd STICK, %g2 /* get stick register */
2451 1965 brgez,pn %g2, 3f /* if NPT bit off, we're done */
2452 1966 mov 1, %g3 /* create mask */
2453 1967 sllx %g3, 63, %g3 /* for NPT bit */
2454 1968 ba,a,pt %xcc, 4f
2455 1969 .align 8 /* Ensure rd/wr in same i$ line */
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
2456 1970 4:
2457 1971 rd STICK, %g2 /* get stick register */
2458 1972 wr %g3, %g2, STICK /* write stick register, */
2459 1973 /* clearing NPT bit */
2460 1974 3:
2461 1975 jmp %g4 + 4
2462 1976 wrpr %g0, %g1, %pstate /* restore processor state */
2463 1977
2464 1978 SET_SIZE(cpu_clearticknpt)
2465 1979
2466 -#endif /* lint */
2467 1980
2468 -
2469 1981 #if defined(CPU_IMP_L1_CACHE_PARITY)
2470 1982
2471 -#if defined(lint)
2472 -/*
2473 - * correct_dcache_parity(size_t size, size_t linesize)
2474 - *
2475 - * Correct D$ data parity by zeroing the data and initializing microtag
2476 - * for all indexes and all ways of the D$.
2477 - *
2478 - */
2479 -/* ARGSUSED */
2480 -void
2481 -correct_dcache_parity(size_t size, size_t linesize)
2482 -{}
2483 -
2484 -#else /* lint */
2485 -
2486 1983 ENTRY(correct_dcache_parity)
2487 1984 /*
2488 1985 * Register Usage:
2489 1986 *
2490 1987 * %o0 = input D$ size
2491 1988 * %o1 = input D$ line size
2492 1989 * %o2 = scratch
2493 1990 * %o3 = scratch
2494 1991 * %o4 = scratch
2495 1992 */
2496 1993
2497 1994 sub %o0, %o1, %o0 ! init cache line address
2498 1995
2499 1996 /*
2500 1997 * For Panther CPUs, we also need to clear the data parity bits
2501 1998 * using DC_data_parity bit of the ASI_DCACHE_DATA register.
2502 1999 */
2503 2000 GET_CPU_IMPL(%o3)
2504 2001 cmp %o3, PANTHER_IMPL
2505 2002 bne 1f
2506 2003 clr %o3 ! zero for non-Panther
2507 2004 mov 1, %o3
2508 2005 sll %o3, PN_DC_DATA_PARITY_BIT_SHIFT, %o3
2509 2006
2510 2007 1:
2511 2008 /*
2512 2009 * Set utag = way since it must be unique within an index.
2513 2010 */
2514 2011 srl %o0, 14, %o2 ! get cache way (DC_way)
2515 2012 membar #Sync ! required before ASI_DC_UTAG
2516 2013 stxa %o2, [%o0]ASI_DC_UTAG ! set D$ utag = cache way
2517 2014 membar #Sync ! required after ASI_DC_UTAG
2518 2015
2519 2016 /*
2520 2017 * Zero line of D$ data (and data parity bits for Panther)
2521 2018 */
2522 2019 sub %o1, 8, %o2
2523 2020 or %o0, %o3, %o4 ! same address + DC_data_parity
2524 2021 2:
2525 2022 membar #Sync ! required before ASI_DC_DATA
2526 2023 stxa %g0, [%o0 + %o2]ASI_DC_DATA ! zero 8 bytes of D$ data
2527 2024 membar #Sync ! required after ASI_DC_DATA
2528 2025 /*
2529 2026 * We also clear the parity bits if this is a panther. For non-Panther
2530 2027 * CPUs, we simply end up clearing the $data register twice.
2531 2028 */
2532 2029 stxa %g0, [%o4 + %o2]ASI_DC_DATA
2533 2030 membar #Sync
2534 2031
2535 2032 subcc %o2, 8, %o2
2536 2033 bge 2b
↓ open down ↓ |
41 lines elided |
↑ open up ↑ |
2537 2034 nop
2538 2035
2539 2036 subcc %o0, %o1, %o0
2540 2037 bge 1b
2541 2038 nop
2542 2039
2543 2040 retl
2544 2041 nop
2545 2042 SET_SIZE(correct_dcache_parity)
2546 2043
2547 -#endif /* lint */
2548 -
2549 2044 #endif /* CPU_IMP_L1_CACHE_PARITY */
2550 2045
2551 2046
2552 -#if defined(lint)
2553 -/*
2554 - * Get timestamp (stick).
2555 - */
2556 -/* ARGSUSED */
2557 -void
2558 -stick_timestamp(int64_t *ts)
2559 -{
2560 -}
2561 -
2562 -#else /* lint */
2563 -
2564 2047 ENTRY_NP(stick_timestamp)
2565 2048 rd STICK, %g1 ! read stick reg
2566 2049 sllx %g1, 1, %g1
2567 2050 srlx %g1, 1, %g1 ! clear npt bit
2568 2051
2569 2052 retl
2570 2053 stx %g1, [%o0] ! store the timestamp
2571 2054 SET_SIZE(stick_timestamp)
2572 2055
2573 -#endif /* lint */
2574 2056
2575 -
2576 -#if defined(lint)
2577 -/*
2578 - * Set STICK adjusted by skew.
2579 - */
2580 -/* ARGSUSED */
2581 -void
2582 -stick_adj(int64_t skew)
2583 -{
2584 -}
2585 -
2586 -#else /* lint */
2587 -
2588 2057 ENTRY_NP(stick_adj)
2589 2058 rdpr %pstate, %g1 ! save processor state
2590 2059 andn %g1, PSTATE_IE, %g3
2591 2060 ba 1f ! cache align stick adj
2592 2061 wrpr %g0, %g3, %pstate ! turn off interrupts
2593 2062
2594 2063 .align 16
2595 2064 1: nop
2596 2065
2597 2066 rd STICK, %g4 ! read stick reg
2598 2067 add %g4, %o0, %o1 ! adjust stick with skew
2599 2068 wr %o1, %g0, STICK ! write stick reg
2600 2069
2601 2070 retl
2602 2071 wrpr %g1, %pstate ! restore processor state
2603 2072 SET_SIZE(stick_adj)
2604 2073
2605 -#endif /* lint */
2606 -
2607 -#if defined(lint)
2608 -/*
2609 - * Debugger-specific stick retrieval
2610 - */
2611 -/*ARGSUSED*/
2612 -int
2613 -kdi_get_stick(uint64_t *stickp)
2614 -{
2615 - return (0);
2616 -}
2617 -
2618 -#else /* lint */
2619 -
2620 2074 ENTRY_NP(kdi_get_stick)
2621 2075 rd STICK, %g1
2622 2076 stx %g1, [%o0]
2623 2077 retl
2624 2078 mov %g0, %o0
2625 2079 SET_SIZE(kdi_get_stick)
2626 2080
2627 -#endif /* lint */
2628 -
2629 -#if defined(lint)
2630 -/*
2631 - * Invalidate the specified line from the D$.
2632 - *
2633 - * Register usage:
2634 - * %o0 - index for the invalidation, specifies DC_way and DC_addr
2635 - *
2636 - * ASI_DC_TAG, 0x47, is used in the following manner. A 64-bit value is
2637 - * stored to a particular DC_way and DC_addr in ASI_DC_TAG.
2638 - *
2639 - * The format of the stored 64-bit value is:
2640 - *
2641 - * +----------+--------+----------+
2642 - * | Reserved | DC_tag | DC_valid |
2643 - * +----------+--------+----------+
2644 - * 63 31 30 1 0
2645 - *
2646 - * DC_tag is the 30-bit physical tag of the associated line.
2647 - * DC_valid is the 1-bit valid field for both the physical and snoop tags.
2648 - *
2649 - * The format of the 64-bit DC_way and DC_addr into ASI_DC_TAG is:
2650 - *
2651 - * +----------+--------+----------+----------+
2652 - * | Reserved | DC_way | DC_addr | Reserved |
2653 - * +----------+--------+----------+----------+
2654 - * 63 16 15 14 13 5 4 0
2655 - *
2656 - * DC_way is a 2-bit index that selects one of the 4 ways.
2657 - * DC_addr is a 9-bit index that selects one of 512 tag/valid fields.
2658 - *
2659 - * Setting the DC_valid bit to zero for the specified DC_way and
2660 - * DC_addr index into the D$ results in an invalidation of a D$ line.
2661 - */
2662 -/*ARGSUSED*/
2663 -void
2664 -dcache_inval_line(int index)
2665 -{
2666 -}
2667 -#else /* lint */
2668 2081 ENTRY(dcache_inval_line)
2669 2082 sll %o0, 5, %o0 ! shift index into DC_way and DC_addr
2670 2083 stxa %g0, [%o0]ASI_DC_TAG ! zero the DC_valid and DC_tag bits
2671 2084 membar #Sync
2672 2085 retl
2673 2086 nop
2674 2087 SET_SIZE(dcache_inval_line)
2675 -#endif /* lint */
2676 2088
2677 -#if defined(lint)
2678 -/*
2679 - * Invalidate the entire I$
2680 - *
2681 - * Register usage:
2682 - * %o0 - specifies IC_way, IC_addr, IC_tag
2683 - * %o1 - scratch
2684 - * %o2 - used to save and restore DCU value
2685 - * %o3 - scratch
2686 - * %o5 - used to save and restore PSTATE
2687 - *
2688 - * Due to the behavior of the I$ control logic when accessing ASI_IC_TAG,
2689 - * the I$ should be turned off. Accesses to ASI_IC_TAG may collide and
2690 - * block out snoops and invalidates to the I$, causing I$ consistency
2691 - * to be broken. Before turning on the I$, all I$ lines must be invalidated.
2692 - *
2693 - * ASI_IC_TAG, 0x67, is used in the following manner. A 64-bit value is
2694 - * stored to a particular IC_way, IC_addr, IC_tag in ASI_IC_TAG. The
2695 - * info below describes store (write) use of ASI_IC_TAG. Note that read
2696 - * use of ASI_IC_TAG behaves differently.
2697 - *
2698 - * The format of the stored 64-bit value is:
2699 - *
2700 - * +----------+--------+---------------+-----------+
2701 - * | Reserved | Valid | IC_vpred<7:0> | Undefined |
2702 - * +----------+--------+---------------+-----------+
2703 - * 63 55 54 53 46 45 0
2704 - *
2705 - * Valid is the 1-bit valid field for both the physical and snoop tags.
2706 - * IC_vpred is the 8-bit LPB bits for 8 instructions starting at
2707 - * the 32-byte boundary aligned address specified by IC_addr.
2708 - *
2709 - * The format of the 64-bit IC_way, IC_addr, IC_tag into ASI_IC_TAG is:
2710 - *
2711 - * +----------+--------+---------+--------+---------+
2712 - * | Reserved | IC_way | IC_addr | IC_tag |Reserved |
2713 - * +----------+--------+---------+--------+---------+
2714 - * 63 16 15 14 13 5 4 3 2 0
2715 - *
2716 - * IC_way is a 2-bit index that selects one of the 4 ways.
2717 - * IC_addr[13:6] is an 8-bit index that selects one of 256 valid fields.
2718 - * IC_addr[5] is a "don't care" for a store.
2719 - * IC_tag set to 2 specifies that the stored value is to be interpreted
2720 - * as containing Valid and IC_vpred as described above.
2721 - *
2722 - * Setting the Valid bit to zero for the specified IC_way and
2723 - * IC_addr index into the I$ results in an invalidation of an I$ line.
2724 - */
2725 -/*ARGSUSED*/
2726 -void
2727 -icache_inval_all(void)
2728 -{
2729 -}
2730 -#else /* lint */
2731 2089 ENTRY(icache_inval_all)
2732 2090 rdpr %pstate, %o5
2733 2091 andn %o5, PSTATE_IE, %o3
2734 2092 wrpr %g0, %o3, %pstate ! clear IE bit
2735 2093
2736 2094 GET_CPU_PRIVATE_PTR(%g0, %o0, %o2, icache_inval_all_1);
2737 2095 ld [%o0 + CHPR_ICACHE_LINESIZE], %o1
2738 2096 ba,pt %icc, 2f
2739 2097 ld [%o0 + CHPR_ICACHE_SIZE], %o0
2740 2098 icache_inval_all_1:
2741 2099 ASM_LD(%o0, icache_size)
2742 2100 ASM_LD(%o1, icache_linesize)
2743 2101 2:
2744 2102 CH_ICACHE_FLUSHALL(%o0, %o1, %o2, %o4)
2745 2103
2746 2104 retl
2747 2105 wrpr %g0, %o5, %pstate ! restore earlier pstate
2748 2106 SET_SIZE(icache_inval_all)
2749 -#endif /* lint */
2750 2107
2751 2108
2752 -#if defined(lint)
2753 -/* ARGSUSED */
2754 -void
2755 -cache_scrubreq_tl1(uint64_t inum, uint64_t index)
2756 -{
2757 -}
2758 -
2759 -#else /* lint */
2760 2109 /*
2761 2110 * cache_scrubreq_tl1 is the crosstrap handler called on offlined cpus via a
2762 2111 * crosstrap. It atomically increments the outstanding request counter and,
2763 2112 * if there was not already an outstanding request, branches to setsoftint_tl1
2764 2113 * to enqueue an intr_vec for the given inum.
2765 2114 */
2766 2115
2767 2116 ! Register usage:
2768 2117 !
2769 2118 ! Arguments:
2770 2119 ! %g1 - inum
2771 2120 ! %g2 - index into chsm_outstanding array
2772 2121 !
2773 2122 ! Internal:
2774 2123 ! %g2, %g3, %g5 - scratch
2775 2124 ! %g4 - ptr. to scrub_misc chsm_outstanding[index].
2776 2125 ! %g6 - setsoftint_tl1 address
2777 2126
2778 2127 ENTRY_NP(cache_scrubreq_tl1)
2779 2128 mulx %g2, CHSM_OUTSTANDING_INCR, %g2
2780 2129 set CHPR_SCRUB_MISC + CHSM_OUTSTANDING, %g3
2781 2130 add %g2, %g3, %g2
2782 2131 GET_CPU_PRIVATE_PTR(%g2, %g4, %g5, 1f);
2783 2132 ld [%g4], %g2 ! cpu's chsm_outstanding[index]
2784 2133 !
2785 2134 ! no need to use atomic instructions for the following
2786 2135 ! increment - we're at tl1
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
2787 2136 !
2788 2137 add %g2, 0x1, %g3
2789 2138 brnz,pn %g2, 1f ! no need to enqueue more intr_vec
2790 2139 st %g3, [%g4] ! delay - store incremented counter
2791 2140 ASM_JMP(%g6, setsoftint_tl1)
2792 2141 ! not reached
2793 2142 1:
2794 2143 retry
2795 2144 SET_SIZE(cache_scrubreq_tl1)
2796 2145
2797 -#endif /* lint */
2798 2146
2799 -
2800 -#if defined(lint)
2801 -
2802 -/* ARGSUSED */
2803 -void
2804 -get_cpu_error_state(ch_cpu_errors_t *cpu_error_regs)
2805 -{}
2806 -
2807 -#else /* lint */
2808 -
2809 2147 /*
2810 2148 * Get the error state for the processor.
2811 2149 * Note that this must not be used at TL>0
2812 2150 */
2813 2151 ENTRY(get_cpu_error_state)
2814 2152 #if defined(CHEETAH_PLUS)
2815 2153 set ASI_SHADOW_REG_VA, %o2
2816 2154 ldxa [%o2]ASI_AFSR, %o1 ! shadow afsr reg
2817 2155 stx %o1, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR]
2818 2156 ldxa [%o2]ASI_AFAR, %o1 ! shadow afar reg
2819 2157 stx %o1, [%o0 + CH_CPU_ERRORS_SHADOW_AFAR]
2820 2158 GET_CPU_IMPL(%o3) ! Only panther has AFSR_EXT registers
2821 2159 cmp %o3, PANTHER_IMPL
2822 2160 bne,a 1f
2823 2161 stx %g0, [%o0 + CH_CPU_ERRORS_AFSR_EXT] ! zero for non-PN
2824 2162 set ASI_AFSR_EXT_VA, %o2
2825 2163 ldxa [%o2]ASI_AFSR, %o1 ! afsr_ext reg
2826 2164 stx %o1, [%o0 + CH_CPU_ERRORS_AFSR_EXT]
2827 2165 set ASI_SHADOW_AFSR_EXT_VA, %o2
2828 2166 ldxa [%o2]ASI_AFSR, %o1 ! shadow afsr_ext reg
2829 2167 stx %o1, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR_EXT]
2830 2168 b 2f
2831 2169 nop
2832 2170 1:
2833 2171 stx %g0, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR_EXT] ! zero for non-PN
2834 2172 2:
2835 2173 #else /* CHEETAH_PLUS */
2836 2174 stx %g0, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR]
2837 2175 stx %g0, [%o0 + CH_CPU_ERRORS_SHADOW_AFAR]
2838 2176 stx %g0, [%o0 + CH_CPU_ERRORS_AFSR_EXT]
2839 2177 stx %g0, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR_EXT]
2840 2178 #endif /* CHEETAH_PLUS */
2841 2179 #if defined(SERRANO)
2842 2180 /*
2843 2181 * Serrano has an afar2 which captures the address on FRC/FRU errors.
2844 2182 * We save this in the afar2 of the register save area.
2845 2183 */
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
2846 2184 set ASI_MCU_AFAR2_VA, %o2
2847 2185 ldxa [%o2]ASI_MCU_CTRL, %o1
2848 2186 stx %o1, [%o0 + CH_CPU_ERRORS_AFAR2]
2849 2187 #endif /* SERRANO */
2850 2188 ldxa [%g0]ASI_AFSR, %o1 ! primary afsr reg
2851 2189 stx %o1, [%o0 + CH_CPU_ERRORS_AFSR]
2852 2190 ldxa [%g0]ASI_AFAR, %o1 ! primary afar reg
2853 2191 retl
2854 2192 stx %o1, [%o0 + CH_CPU_ERRORS_AFAR]
2855 2193 SET_SIZE(get_cpu_error_state)
2856 -#endif /* lint */
2857 2194
2858 -#if defined(lint)
2859 -
2860 -/*
2861 - * Check a page of memory for errors.
2862 - *
2863 - * Load each 64 byte block from physical memory.
2864 - * Check AFSR after each load to see if an error
2865 - * was caused. If so, log/scrub that error.
2866 - *
2867 - * Used to determine if a page contains
2868 - * CEs when CEEN is disabled.
2869 - */
2870 -/*ARGSUSED*/
2871 -void
2872 -cpu_check_block(caddr_t va, uint_t psz)
2873 -{}
2874 -
2875 -#else /* lint */
2876 -
2877 2195 ENTRY(cpu_check_block)
2878 2196 !
2879 2197 ! get a new window with room for the error regs
2880 2198 !
2881 2199 save %sp, -SA(MINFRAME + CH_CPU_ERROR_SIZE), %sp
2882 2200 srl %i1, 6, %l4 ! clear top bits of psz
2883 2201 ! and divide by 64
2884 2202 rd %fprs, %l2 ! store FP
2885 2203 wr %g0, FPRS_FEF, %fprs ! enable FP
2886 2204 1:
2887 2205 ldda [%i0]ASI_BLK_P, %d0 ! load a block
2888 2206 membar #Sync
2889 2207 ldxa [%g0]ASI_AFSR, %l3 ! read afsr reg
2890 2208 brz,a,pt %l3, 2f ! check for error
2891 2209 nop
2892 2210
2893 2211 !
2894 2212 ! if error, read the error regs and log it
2895 2213 !
2896 2214 call get_cpu_error_state
2897 2215 add %fp, STACK_BIAS - CH_CPU_ERROR_SIZE, %o0
2898 2216
2899 2217 !
2900 2218 ! cpu_ce_detected(ch_cpu_errors_t *, flag)
2901 2219 !
2902 2220 call cpu_ce_detected ! log the error
2903 2221 mov CE_CEEN_TIMEOUT, %o1
2904 2222 2:
↓ open down ↓ |
18 lines elided |
↑ open up ↑ |
2905 2223 dec %l4 ! next 64-byte block
2906 2224 brnz,a,pt %l4, 1b
2907 2225 add %i0, 64, %i0 ! increment block addr
2908 2226
2909 2227 wr %l2, %g0, %fprs ! restore FP
2910 2228 ret
2911 2229 restore
2912 2230
2913 2231 SET_SIZE(cpu_check_block)
2914 2232
2915 -#endif /* lint */
2916 -
2917 -#if defined(lint)
2918 -
2919 -/*
2920 - * Perform a cpu logout called from C. This is used where we did not trap
2921 - * for the error but still want to gather "what we can". Caller must make
2922 - * sure cpu private area exists and that the indicated logout area is free
2923 - * for use, and that we are unable to migrate cpus.
2924 - */
2925 -/*ARGSUSED*/
2926 -void
2927 -cpu_delayed_logout(uint64_t afar, ch_cpu_logout_t *clop)
2928 -{ }
2929 -
2930 -#else
2931 2233 ENTRY(cpu_delayed_logout)
2932 2234 rdpr %pstate, %o2
2933 2235 andn %o2, PSTATE_IE, %o2
2934 2236 wrpr %g0, %o2, %pstate ! disable interrupts
2935 2237 PARK_SIBLING_CORE(%o2, %o3, %o4) ! %o2 has DCU value
2936 2238 add %o1, CH_CLO_DATA + CH_CHD_EC_DATA, %o1
2937 2239 rd %asi, %g1
2938 2240 wr %g0, ASI_P, %asi
2939 2241 GET_ECACHE_DTAGS(%o0, %o1, %o3, %o4, %o5)
2940 2242 wr %g1, %asi
2941 2243 UNPARK_SIBLING_CORE(%o2, %o3, %o4) ! can use %o2 again
2942 2244 rdpr %pstate, %o2
2943 2245 or %o2, PSTATE_IE, %o2
2944 2246 wrpr %g0, %o2, %pstate
2945 2247 retl
2946 2248 nop
2947 2249 SET_SIZE(cpu_delayed_logout)
2948 2250
2949 -#endif /* lint */
2950 -
2951 -#if defined(lint)
2952 -
2953 -/*ARGSUSED*/
2954 -int
2955 -dtrace_blksuword32(uintptr_t addr, uint32_t *data, int tryagain)
2956 -{ return (0); }
2957 -
2958 -#else
2959 -
2960 2251 ENTRY(dtrace_blksuword32)
2961 2252 save %sp, -SA(MINFRAME + 4), %sp
2962 2253
2963 2254 rdpr %pstate, %l1
2964 2255 andn %l1, PSTATE_IE, %l2 ! disable interrupts to
2965 2256 wrpr %g0, %l2, %pstate ! protect our FPU diddling
2966 2257
2967 2258 rd %fprs, %l0
2968 2259 andcc %l0, FPRS_FEF, %g0
2969 2260 bz,a,pt %xcc, 1f ! if the fpu is disabled
2970 2261 wr %g0, FPRS_FEF, %fprs ! ... enable the fpu
2971 2262
2972 2263 st %f0, [%fp + STACK_BIAS - 4] ! save %f0 to the stack
2973 2264 1:
2974 2265 set 0f, %l5
2975 2266 /*
2976 2267 * We're about to write a block full or either total garbage
2977 2268 * (not kernel data, don't worry) or user floating-point data
2978 2269 * (so it only _looks_ like garbage).
2979 2270 */
2980 2271 ld [%i1], %f0 ! modify the block
2981 2272 membar #Sync
2982 2273 stn %l5, [THREAD_REG + T_LOFAULT] ! set up the lofault handler
2983 2274 stda %d0, [%i0]ASI_BLK_COMMIT_S ! store the modified block
2984 2275 membar #Sync
2985 2276 stn %g0, [THREAD_REG + T_LOFAULT] ! remove the lofault handler
2986 2277
2987 2278 bz,a,pt %xcc, 1f
2988 2279 wr %g0, %l0, %fprs ! restore %fprs
2989 2280
2990 2281 ld [%fp + STACK_BIAS - 4], %f0 ! restore %f0
2991 2282 1:
2992 2283
2993 2284 wrpr %g0, %l1, %pstate ! restore interrupts
2994 2285
2995 2286 ret
2996 2287 restore %g0, %g0, %o0
2997 2288
2998 2289 0:
2999 2290 membar #Sync
3000 2291 stn %g0, [THREAD_REG + T_LOFAULT] ! remove the lofault handler
3001 2292
3002 2293 bz,a,pt %xcc, 1f
3003 2294 wr %g0, %l0, %fprs ! restore %fprs
3004 2295
3005 2296 ld [%fp + STACK_BIAS - 4], %f0 ! restore %f0
3006 2297 1:
3007 2298
3008 2299 wrpr %g0, %l1, %pstate ! restore interrupts
3009 2300
3010 2301 /*
3011 2302 * If tryagain is set (%i2) we tail-call dtrace_blksuword32_err()
3012 2303 * which deals with watchpoints. Otherwise, just return -1.
3013 2304 */
↓ open down ↓ |
44 lines elided |
↑ open up ↑ |
3014 2305 brnz,pt %i2, 1f
3015 2306 nop
3016 2307 ret
3017 2308 restore %g0, -1, %o0
3018 2309 1:
3019 2310 call dtrace_blksuword32_err
3020 2311 restore
3021 2312
3022 2313 SET_SIZE(dtrace_blksuword32)
3023 2314
3024 -#endif /* lint */
3025 -
3026 2315 #ifdef CHEETAHPLUS_ERRATUM_25
3027 2316
3028 -#if defined(lint)
3029 -/*
3030 - * Claim a chunk of physical address space.
3031 - */
3032 -/*ARGSUSED*/
3033 -void
3034 -claimlines(uint64_t pa, size_t sz, int stride)
3035 -{}
3036 -#else /* lint */
3037 2317 ENTRY(claimlines)
3038 2318 1:
3039 2319 subcc %o1, %o2, %o1
3040 2320 add %o0, %o1, %o3
3041 2321 bgeu,a,pt %xcc, 1b
3042 2322 casxa [%o3]ASI_MEM, %g0, %g0
3043 2323 membar #Sync
3044 2324 retl
3045 2325 nop
3046 2326 SET_SIZE(claimlines)
3047 -#endif /* lint */
3048 2327
3049 -#if defined(lint)
3050 -/*
3051 - * CPU feature initialization,
3052 - * turn BPE off,
3053 - * get device id.
3054 - */
3055 -/*ARGSUSED*/
3056 -void
3057 -cpu_feature_init(void)
3058 -{}
3059 -#else /* lint */
3060 2328 ENTRY(cpu_feature_init)
3061 2329 save %sp, -SA(MINFRAME), %sp
3062 2330 sethi %hi(cheetah_bpe_off), %o0
3063 2331 ld [%o0 + %lo(cheetah_bpe_off)], %o0
3064 2332 brz %o0, 1f
3065 2333 nop
3066 2334 rd ASR_DISPATCH_CONTROL, %o0
3067 2335 andn %o0, ASR_DISPATCH_CONTROL_BPE, %o0
3068 2336 wr %o0, 0, ASR_DISPATCH_CONTROL
3069 2337 1:
3070 2338 !
3071 2339 ! get the device_id and store the device_id
3072 2340 ! in the appropriate cpunodes structure
3073 2341 ! given the cpus index
3074 2342 !
3075 2343 CPU_INDEX(%o0, %o1)
3076 2344 mulx %o0, CPU_NODE_SIZE, %o0
3077 2345 set cpunodes + DEVICE_ID, %o1
3078 2346 ldxa [%g0] ASI_DEVICE_SERIAL_ID, %o2
3079 2347 stx %o2, [%o0 + %o1]
3080 2348 #ifdef CHEETAHPLUS_ERRATUM_34
3081 2349 !
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
3082 2350 ! apply Cheetah+ erratum 34 workaround
3083 2351 !
3084 2352 call itlb_erratum34_fixup
3085 2353 nop
3086 2354 call dtlb_erratum34_fixup
3087 2355 nop
3088 2356 #endif /* CHEETAHPLUS_ERRATUM_34 */
3089 2357 ret
3090 2358 restore
3091 2359 SET_SIZE(cpu_feature_init)
3092 -#endif /* lint */
3093 2360
3094 -#if defined(lint)
3095 -/*
3096 - * Copy a tsb entry atomically, from src to dest.
3097 - * src must be 128 bit aligned.
3098 - */
3099 -/*ARGSUSED*/
3100 -void
3101 -copy_tsb_entry(uintptr_t src, uintptr_t dest)
3102 -{}
3103 -#else /* lint */
3104 2361 ENTRY(copy_tsb_entry)
3105 2362 ldda [%o0]ASI_NQUAD_LD, %o2 ! %o2 = tag, %o3 = data
3106 2363 stx %o2, [%o1]
3107 2364 stx %o3, [%o1 + 8 ]
3108 2365 retl
3109 2366 nop
3110 2367 SET_SIZE(copy_tsb_entry)
3111 -#endif /* lint */
3112 2368
3113 2369 #endif /* CHEETAHPLUS_ERRATUM_25 */
3114 2370
3115 2371 #ifdef CHEETAHPLUS_ERRATUM_34
3116 2372
3117 -#if defined(lint)
3118 -
3119 -/*ARGSUSED*/
3120 -void
3121 -itlb_erratum34_fixup(void)
3122 -{}
3123 -
3124 -#else /* lint */
3125 -
3126 2373 !
3127 2374 ! In Cheetah+ erratum 34, under certain conditions an ITLB locked
3128 2375 ! index 0 TTE will erroneously be displaced when a new TTE is
3129 2376 ! loaded via ASI_ITLB_IN. In order to avoid cheetah+ erratum 34,
3130 2377 ! locked index 0 TTEs must be relocated.
3131 2378 !
3132 2379 ! NOTE: Care must be taken to avoid an ITLB miss in this routine.
3133 2380 !
3134 2381 ENTRY_NP(itlb_erratum34_fixup)
3135 2382 rdpr %pstate, %o3
3136 2383 #ifdef DEBUG
3137 2384 PANIC_IF_INTR_DISABLED_PSTR(%o3, u3_di_label1, %g1)
3138 2385 #endif /* DEBUG */
3139 2386 wrpr %o3, PSTATE_IE, %pstate ! Disable interrupts
3140 2387 ldxa [%g0]ASI_ITLB_ACCESS, %o1 ! %o1 = entry 0 data
3141 2388 ldxa [%g0]ASI_ITLB_TAGREAD, %o2 ! %o2 = entry 0 tag
3142 2389
3143 2390 cmp %o1, %g0 ! Is this entry valid?
3144 2391 bge %xcc, 1f
3145 2392 andcc %o1, TTE_LCK_INT, %g0 ! Is this entry locked?
3146 2393 bnz %icc, 2f
3147 2394 nop
3148 2395 1:
3149 2396 retl ! Nope, outta here...
3150 2397 wrpr %g0, %o3, %pstate ! Enable interrupts
3151 2398 2:
3152 2399 sethi %hi(FLUSH_ADDR), %o4
3153 2400 stxa %g0, [%o2]ASI_ITLB_DEMAP ! Flush this mapping
3154 2401 flush %o4 ! Flush required for I-MMU
3155 2402 !
3156 2403 ! Start search from index 1 up. This is because the kernel force
3157 2404 ! loads its text page at index 15 in sfmmu_kernel_remap() and we
3158 2405 ! don't want our relocated entry evicted later.
3159 2406 !
3160 2407 ! NOTE: We assume that we'll be successful in finding an unlocked
3161 2408 ! or invalid entry. If that isn't the case there are bound to
3162 2409 ! bigger problems.
3163 2410 !
3164 2411 set (1 << 3), %g3
3165 2412 3:
3166 2413 ldxa [%g3]ASI_ITLB_ACCESS, %o4 ! Load TTE from t16
3167 2414 !
3168 2415 ! If this entry isn't valid, we'll choose to displace it (regardless
3169 2416 ! of the lock bit).
3170 2417 !
3171 2418 cmp %o4, %g0 ! TTE is > 0 iff not valid
3172 2419 bge %xcc, 4f ! If invalid, go displace
3173 2420 andcc %o4, TTE_LCK_INT, %g0 ! Check for lock bit
3174 2421 bnz,a %icc, 3b ! If locked, look at next
3175 2422 add %g3, (1 << 3), %g3 ! entry
3176 2423 4:
3177 2424 !
3178 2425 ! We found an unlocked or invalid entry; we'll explicitly load
3179 2426 ! the former index 0 entry here.
↓ open down ↓ |
44 lines elided |
↑ open up ↑ |
3180 2427 !
3181 2428 sethi %hi(FLUSH_ADDR), %o4
3182 2429 set MMU_TAG_ACCESS, %g4
3183 2430 stxa %o2, [%g4]ASI_IMMU
3184 2431 stxa %o1, [%g3]ASI_ITLB_ACCESS
3185 2432 flush %o4 ! Flush required for I-MMU
3186 2433 retl
3187 2434 wrpr %g0, %o3, %pstate ! Enable interrupts
3188 2435 SET_SIZE(itlb_erratum34_fixup)
3189 2436
3190 -#endif /* lint */
3191 -
3192 -#if defined(lint)
3193 -
3194 -/*ARGSUSED*/
3195 -void
3196 -dtlb_erratum34_fixup(void)
3197 -{}
3198 -
3199 -#else /* lint */
3200 -
3201 2437 !
3202 2438 ! In Cheetah+ erratum 34, under certain conditions a DTLB locked
3203 2439 ! index 0 TTE will erroneously be displaced when a new TTE is
3204 2440 ! loaded. In order to avoid cheetah+ erratum 34, locked index 0
3205 2441 ! TTEs must be relocated.
3206 2442 !
3207 2443 ENTRY_NP(dtlb_erratum34_fixup)
3208 2444 rdpr %pstate, %o3
3209 2445 #ifdef DEBUG
3210 2446 PANIC_IF_INTR_DISABLED_PSTR(%o3, u3_di_label2, %g1)
3211 2447 #endif /* DEBUG */
3212 2448 wrpr %o3, PSTATE_IE, %pstate ! Disable interrupts
3213 2449 ldxa [%g0]ASI_DTLB_ACCESS, %o1 ! %o1 = entry 0 data
3214 2450 ldxa [%g0]ASI_DTLB_TAGREAD, %o2 ! %o2 = entry 0 tag
3215 2451
3216 2452 cmp %o1, %g0 ! Is this entry valid?
3217 2453 bge %xcc, 1f
3218 2454 andcc %o1, TTE_LCK_INT, %g0 ! Is this entry locked?
3219 2455 bnz %icc, 2f
3220 2456 nop
3221 2457 1:
3222 2458 retl ! Nope, outta here...
3223 2459 wrpr %g0, %o3, %pstate ! Enable interrupts
3224 2460 2:
3225 2461 stxa %g0, [%o2]ASI_DTLB_DEMAP ! Flush this mapping
3226 2462 membar #Sync
3227 2463 !
3228 2464 ! Start search from index 1 up.
3229 2465 !
3230 2466 ! NOTE: We assume that we'll be successful in finding an unlocked
3231 2467 ! or invalid entry. If that isn't the case there are bound to
3232 2468 ! bigger problems.
3233 2469 !
3234 2470 set (1 << 3), %g3
3235 2471 3:
3236 2472 ldxa [%g3]ASI_DTLB_ACCESS, %o4 ! Load TTE from t16
3237 2473 !
3238 2474 ! If this entry isn't valid, we'll choose to displace it (regardless
3239 2475 ! of the lock bit).
3240 2476 !
3241 2477 cmp %o4, %g0 ! TTE is > 0 iff not valid
3242 2478 bge %xcc, 4f ! If invalid, go displace
3243 2479 andcc %o4, TTE_LCK_INT, %g0 ! Check for lock bit
3244 2480 bnz,a %icc, 3b ! If locked, look at next
3245 2481 add %g3, (1 << 3), %g3 ! entry
3246 2482 4:
3247 2483 !
3248 2484 ! We found an unlocked or invalid entry; we'll explicitly load
↓ open down ↓ |
38 lines elided |
↑ open up ↑ |
3249 2485 ! the former index 0 entry here.
3250 2486 !
3251 2487 set MMU_TAG_ACCESS, %g4
3252 2488 stxa %o2, [%g4]ASI_DMMU
3253 2489 stxa %o1, [%g3]ASI_DTLB_ACCESS
3254 2490 membar #Sync
3255 2491 retl
3256 2492 wrpr %g0, %o3, %pstate ! Enable interrupts
3257 2493 SET_SIZE(dtlb_erratum34_fixup)
3258 2494
3259 -#endif /* lint */
3260 -
3261 2495 #endif /* CHEETAHPLUS_ERRATUM_34 */
3262 2496
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX