Print this page
restore sparc comments
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 1403 /*
1747 1404 * This trap cannot happen at TL>0 which means this routine will never
1748 1405 * actually be called and so we treat this like a BAD TRAP panic.
1749 1406 */
1750 -void
1751 -ce_err_tl1(void)
1752 -{}
1753 -
1754 -#else /* lint */
1755 -
1756 1407 .align 64
1757 1408 ENTRY_NP(ce_err_tl1)
1758 1409
1759 1410 call ptl1_panic
1760 1411 mov PTL1_BAD_TRAP, %g1
1761 1412
1762 1413 SET_SIZE(ce_err_tl1)
1763 1414
1764 -#endif /* lint */
1765 -
1766 1415
1767 -#if defined(lint)
1768 -
1769 -void
1770 -async_err(void)
1771 -{}
1772 -
1773 -#else /* lint */
1774 -
1775 1416 /*
1776 1417 * The async_err function handles deferred trap types 0xA
1777 1418 * (instruction_access_error) and 0x32 (data_access_error) at TL>=0.
1778 1419 *
1779 1420 * AFSR errors bits which cause this trap are:
1780 1421 * UE, EMU, EDU:BLD, L3_EDU:BLD, TO, BERR
1781 1422 * On some platforms, EMU may causes cheetah to pull the error pin
1782 1423 * never giving Solaris a chance to take a trap.
1783 1424 *
1784 1425 * NCEEN Bit of Cheetah External Cache Error Enable Register enables
1785 1426 * the following AFSR deferred traps: UE, EMU, EDU:BLD, TO, BERR
1786 1427 *
1787 1428 * Steps:
1788 1429 * 1. Disable CEEN and NCEEN errors to prevent recursive errors.
1789 1430 * 2. Turn D$ off per Cheetah PRM P.5 Note 6, turn I$ off to capture
1790 1431 * I$ line in DO_CPU_LOGOUT.
1791 1432 * 3. Park sibling core if caches are shared (to avoid race
1792 1433 * condition while accessing shared resources such as L3
1793 1434 * data staging register during CPU logout.
1794 1435 * 4. If the CPU logout structure is not currently being used:
1795 1436 * 5. Clear AFSR error bits
1796 1437 * 6. Capture Ecache, Dcache and Icache lines associated
1797 1438 * with AFAR.
1798 1439 * 7. Unpark sibling core if we parked it earlier.
1799 1440 * 8. call cpu_deferred_error via sys_trap.
1800 1441 * 5. Otherwise, if the CPU logout structure is busy:
1801 1442 * 6. Incriment "logout busy count"
1802 1443 * 7. Unpark sibling core if we parked it earlier.
1803 1444 * 8) Issue a retry since the other CPU error logging
1804 1445 * code will end up finding this error bit and logging
1805 1446 * information about it later.
1806 1447 * 6. Alternatively (to 4 and 5 above), if the cpu_private struct is
1807 1448 * not yet initialized such that we can't even check the logout
1808 1449 * struct, then we place the clo_flags data into %g2
1809 1450 * (sys_trap->have_win arg #1) and call cpu_deferred_error via
1810 1451 * systrap. The clo_flags parameter is used to determine information
1811 1452 * such as TL, TT, CEEN settings, etc in the high level trap handler
1812 1453 * since we don't have access to detailed logout information in cases
1813 1454 * where the cpu_private struct is not yet initialized.
1814 1455 *
1815 1456 * %g2: [ clo_flags if cpu_private unavailable ] - sys_trap->have_win: arg #1
1816 1457 * %g3: [ logout busy count ] - arg #2
1817 1458 */
1818 1459
1819 1460 ENTRY_NP(async_err)
1820 1461 membar #Sync ! Cheetah requires membar #Sync
1821 1462
1822 1463 /*
1823 1464 * Disable CEEN and NCEEN.
1824 1465 */
1825 1466 ldxa [%g0]ASI_ESTATE_ERR, %g3
1826 1467 andn %g3, EN_REG_NCEEN + EN_REG_CEEN, %g4
1827 1468 stxa %g4, [%g0]ASI_ESTATE_ERR
1828 1469 membar #Sync ! membar sync required
1829 1470
1830 1471 /*
1831 1472 * Save current DCU state.
1832 1473 * Disable Icache to allow capture of Icache data by DO_CPU_LOGOUT.
1833 1474 * Do this regardless of whether this is a Data Access Error or
1834 1475 * Instruction Access Error Trap.
1835 1476 * Disable Dcache for both Data Access Error and Instruction Access
1836 1477 * Error per Cheetah PRM P.5 Note 6.
1837 1478 */
1838 1479 ldxa [%g0]ASI_DCU, %g1 ! save DCU in %g1
1839 1480 andn %g1, DCU_IC + DCU_DC, %g4
1840 1481 stxa %g4, [%g0]ASI_DCU
1841 1482 flush %g0 /* flush required after changing the IC bit */
1842 1483
1843 1484 /*
1844 1485 * Check to see whether we need to park our sibling core
1845 1486 * before recording diagnostic information from caches
1846 1487 * which may be shared by both cores.
1847 1488 * We use %g1 to store information about whether or not
1848 1489 * we had to park the core (%g1 holds our DCUCR value and
1849 1490 * we only use bits from that register which are "reserved"
1850 1491 * to keep track of core parking) so that we know whether
1851 1492 * or not to unpark later. %g6 and %g4 are scratch registers.
1852 1493 */
1853 1494 PARK_SIBLING_CORE(%g1, %g6, %g4)
1854 1495
1855 1496 /*
1856 1497 * Do the CPU logout capture.
1857 1498 *
1858 1499 * %g3 = "failed?" return value.
1859 1500 * %g2 = Input = AFAR. Output the clo_flags info which is passed
1860 1501 * into this macro via %g4. Output only valid if cpu_private
1861 1502 * struct has not been initialized.
1862 1503 * CHPR_ASYNC_LOGOUT = cpu logout structure offset input
1863 1504 * %g4 = Trap information stored in the cpu logout flags field
1864 1505 * %g5 = scr1
1865 1506 * %g6 = scr2
1866 1507 * %g3 = scr3
1867 1508 * %g4 = scr4
1868 1509 */
1869 1510 andcc %g5, T_TL1, %g0
1870 1511 clr %g6
1871 1512 movnz %xcc, 1, %g6 ! set %g6 if T_TL1 set
1872 1513 sllx %g6, CLO_FLAGS_TL_SHIFT, %g6
1873 1514 sllx %g5, CLO_FLAGS_TT_SHIFT, %g4
1874 1515 set CLO_FLAGS_TT_MASK, %g2
1875 1516 and %g4, %g2, %g4 ! ttype
1876 1517 or %g6, %g4, %g4 ! TT and TL
1877 1518 and %g3, EN_REG_CEEN, %g3 ! CEEN value
1878 1519 or %g3, %g4, %g4 ! TT and TL and CEEN
1879 1520 set CHPR_ASYNC_LOGOUT, %g6
1880 1521 DO_CPU_LOGOUT(%g3, %g2, %g6, %g4, %g5, %g6, %g3, %g4)
1881 1522
1882 1523 /*
1883 1524 * If the logout struct was busy, we may need to pass the
1884 1525 * TT, TL, and CEEN information to the TL=0 handler via
1885 1526 * systrap parameter so save it off here.
1886 1527 */
1887 1528 cmp %g3, %g0
1888 1529 be 1f
1889 1530 nop
1890 1531 sllx %g4, 32, %g4
1891 1532 or %g4, %g3, %g3
1892 1533 1:
1893 1534 /*
1894 1535 * Flush the Icache. Since we turned off the Icache to capture the
1895 1536 * Icache line it is now stale or corrupted and we must flush it
1896 1537 * before re-enabling it.
1897 1538 */
1898 1539 GET_CPU_PRIVATE_PTR(%g0, %g5, %g7, async_err_1);
1899 1540 ld [%g5 + CHPR_ICACHE_LINESIZE], %g6
1900 1541 ba,pt %icc, 2f
1901 1542 ld [%g5 + CHPR_ICACHE_SIZE], %g5
1902 1543 async_err_1:
1903 1544 ASM_LD(%g5, icache_size)
1904 1545 ASM_LD(%g6, icache_linesize)
1905 1546 2:
1906 1547 CH_ICACHE_FLUSHALL(%g5, %g6, %g7, %g4)
1907 1548
1908 1549 /*
1909 1550 * XXX - Don't we need to flush the Dcache before turning it back
1910 1551 * on to avoid stale or corrupt data? Was this broken?
1911 1552 */
1912 1553 /*
1913 1554 * Flush the Dcache before turning it back on since it may now
1914 1555 * contain stale or corrupt data.
1915 1556 */
1916 1557 ASM_LD(%g5, dcache_size)
1917 1558 ASM_LD(%g6, dcache_linesize)
1918 1559 CH_DCACHE_FLUSHALL(%g5, %g6, %g7)
1919 1560
1920 1561 /*
1921 1562 * check to see whether we parked our sibling core at the start
1922 1563 * of this handler. If so, we need to unpark it here.
1923 1564 * We use DCUCR reserved bits (stored in %g1) to keep track of
1924 1565 * whether or not we need to unpark. %g5 and %g7 are scratch registers.
1925 1566 */
1926 1567 UNPARK_SIBLING_CORE(%g1, %g5, %g7)
1927 1568
1928 1569 /*
1929 1570 * Restore Icache and Dcache to previous state.
1930 1571 */
1931 1572 stxa %g1, [%g0]ASI_DCU
1932 1573 flush %g0 /* flush required after changing the IC bit */
1933 1574
1934 1575 /*
1935 1576 * Make sure our CPU logout operation was successful.
1936 1577 */
1937 1578 cmp %g3, %g0
1938 1579 be 4f
1939 1580 nop
1940 1581
1941 1582 /*
1942 1583 * If the logout structure had been busy, how many times have
1943 1584 * we tried to use it and failed (nesting count)? If we have
1944 1585 * already recursed a substantial number of times, then we can
1945 1586 * assume things are not going to get better by themselves and
1946 1587 * so it would be best to panic.
1947 1588 */
1948 1589 cmp %g3, CLO_NESTING_MAX
1949 1590 blt 3f
1950 1591 nop
1951 1592
1952 1593 call ptl1_panic
1953 1594 mov PTL1_BAD_ECC, %g1
1954 1595
1955 1596 3:
1956 1597 /*
1957 1598 * Otherwise, if the logout structure was busy but we have not
1958 1599 * nested more times than our maximum value, then we simply
1959 1600 * issue a retry. Our TL=0 trap handler code will check and
1960 1601 * clear the AFSR after it is done logging what is currently
1961 1602 * in the logout struct and handle this event at that time.
↓ open down ↓ |
177 lines elided |
↑ open up ↑ |
1962 1603 */
1963 1604 retry
1964 1605 4:
1965 1606 RESET_USER_RTT_REGS(%g4, %g5, async_err_resetskip)
1966 1607 async_err_resetskip:
1967 1608 set cpu_deferred_error, %g1
1968 1609 ba sys_trap
1969 1610 mov PIL_15, %g4 ! run at pil 15
1970 1611 SET_SIZE(async_err)
1971 1612
1972 -#endif /* lint */
1973 -
1974 1613 #if defined(CPU_IMP_L1_CACHE_PARITY)
1975 1614
1976 1615 /*
1977 1616 * D$ parity error trap (trap 71) at TL=0.
1978 1617 * tt0_dperr is replaced by dcache_parity_instr in cpu_init_trap of
1979 1618 * the various architecture-specific files. This merely sets up the
1980 1619 * arguments for cpu_parity_error and calls it via sys_trap.
1981 1620 * NB: Must be 8 instructions or less to fit in trap table and code must
1982 1621 * be relocatable.
1983 1622 */
1984 -#if defined(lint)
1985 -
1986 -void
1987 -dcache_parity_instr(void)
1988 -{}
1989 -
1990 -#else /* lint */
1991 1623 ENTRY_NP(dcache_parity_instr)
1992 1624 membar #Sync ! Cheetah+ requires membar #Sync
1993 1625 set cpu_parity_error, %g1
1994 1626 or %g0, CH_ERR_DPE, %g2
1995 1627 rdpr %tpc, %g3
1996 1628 sethi %hi(sys_trap), %g7
1997 1629 jmp %g7 + %lo(sys_trap)
1998 1630 mov PIL_15, %g4 ! run at pil 15
1999 1631 SET_SIZE(dcache_parity_instr)
2000 1632
2001 -#endif /* lint */
2002 1633
2003 -
2004 1634 /*
2005 1635 * D$ parity error trap (trap 71) at TL>0.
2006 1636 * tt1_dperr is replaced by dcache_parity_tl1_instr in cpu_init_trap of
2007 1637 * the various architecture-specific files. This generates a "Software
2008 1638 * Trap 1" at TL>0, which goes to dcache_parity_tl1_cont_instr, and we
2009 1639 * continue the handling there.
2010 1640 * NB: Must be 8 instructions or less to fit in trap table and code must
2011 1641 * be relocatable.
2012 1642 */
2013 -#if defined(lint)
2014 -
2015 -void
2016 -dcache_parity_tl1_instr(void)
2017 -{}
2018 -
2019 -#else /* lint */
2020 1643 ENTRY_NP(dcache_parity_tl1_instr)
2021 1644 CH_ERR_TL1_TRAPENTRY(SWTRAP_1);
2022 1645 SET_SIZE(dcache_parity_tl1_instr)
2023 1646
2024 -#endif /* lint */
2025 1647
2026 -
2027 1648 /*
2028 1649 * Software trap 1 at TL>0.
2029 1650 * tt1_swtrap1 is replaced by dcache_parity_tl1_cont_instr in cpu_init_trap
2030 1651 * of the various architecture-specific files. This is used as a continuation
2031 1652 * of the dcache parity handling where we've bought an extra TL level, so we
2032 1653 * can use %tpc, %tnpc, %tstate to temporarily save the value of registers %g1
2033 1654 * and %g2. Note that %tstate has bits 0-2 and then bits 8-19 as r/w,
2034 1655 * there's a reserved hole from 3-7. We only use bits 0-1 and 8-9 (the low
2035 1656 * order two bits from %g1 and %g2 respectively).
2036 1657 * NB: Must be 8 instructions or less to fit in trap table and code must
2037 1658 * be relocatable.
2038 1659 */
2039 -#if defined(lint)
2040 -
2041 -void
2042 -dcache_parity_tl1_cont_instr(void)
2043 -{}
2044 -
2045 -#else /* lint */
2046 1660 ENTRY_NP(dcache_parity_tl1_cont_instr)
2047 1661 CH_ERR_TL1_SWTRAPENTRY(dcache_parity_tl1_err);
2048 1662 SET_SIZE(dcache_parity_tl1_cont_instr)
2049 1663
2050 -#endif /* lint */
2051 -
2052 1664 /*
2053 1665 * D$ parity error at TL>0 handler
2054 1666 * We get here via trap 71 at TL>0->Software trap 1 at TL>0. We enter
2055 1667 * this routine with %g1 and %g2 already saved in %tpc, %tnpc and %tstate.
2056 1668 */
2057 -#if defined(lint)
2058 1669
2059 -void
2060 -dcache_parity_tl1_err(void)
2061 -{}
2062 -
2063 -#else /* lint */
2064 -
2065 1670 ENTRY_NP(dcache_parity_tl1_err)
2066 1671
2067 1672 /*
2068 1673 * This macro saves all the %g registers in the ch_err_tl1_data
2069 1674 * structure, updates the ch_err_tl1_flags and saves the %tpc in
2070 1675 * ch_err_tl1_tpc. At the end of this macro, %g1 will point to
2071 1676 * the ch_err_tl1_data structure and %g2 will have the original
2072 1677 * flags in the ch_err_tl1_data structure. All %g registers
2073 1678 * except for %g1 and %g2 will be available.
2074 1679 */
2075 1680 CH_ERR_TL1_ENTER(CH_ERR_DPE);
2076 1681
2077 1682 #ifdef TRAPTRACE
2078 1683 /*
2079 1684 * Get current trap trace entry physical pointer.
2080 1685 */
2081 1686 CPU_INDEX(%g6, %g5)
2082 1687 sll %g6, TRAPTR_SIZE_SHIFT, %g6
2083 1688 set trap_trace_ctl, %g5
2084 1689 add %g6, %g5, %g6
2085 1690 ld [%g6 + TRAPTR_LIMIT], %g5
2086 1691 tst %g5
2087 1692 be %icc, dpe_tl1_skip_tt
2088 1693 nop
2089 1694 ldx [%g6 + TRAPTR_PBASE], %g5
2090 1695 ld [%g6 + TRAPTR_OFFSET], %g4
2091 1696 add %g5, %g4, %g5
2092 1697
2093 1698 /*
2094 1699 * Create trap trace entry.
2095 1700 */
2096 1701 rd %asi, %g7
2097 1702 wr %g0, TRAPTR_ASI, %asi
2098 1703 rd STICK, %g4
2099 1704 stxa %g4, [%g5 + TRAP_ENT_TICK]%asi
2100 1705 rdpr %tl, %g4
2101 1706 stha %g4, [%g5 + TRAP_ENT_TL]%asi
2102 1707 rdpr %tt, %g4
2103 1708 stha %g4, [%g5 + TRAP_ENT_TT]%asi
2104 1709 rdpr %tpc, %g4
2105 1710 stna %g4, [%g5 + TRAP_ENT_TPC]%asi
2106 1711 rdpr %tstate, %g4
2107 1712 stxa %g4, [%g5 + TRAP_ENT_TSTATE]%asi
2108 1713 stna %sp, [%g5 + TRAP_ENT_SP]%asi
2109 1714 stna %g0, [%g5 + TRAP_ENT_TR]%asi
2110 1715 stna %g0, [%g5 + TRAP_ENT_F1]%asi
2111 1716 stna %g0, [%g5 + TRAP_ENT_F2]%asi
2112 1717 stna %g0, [%g5 + TRAP_ENT_F3]%asi
2113 1718 stna %g0, [%g5 + TRAP_ENT_F4]%asi
2114 1719 wr %g0, %g7, %asi
2115 1720
2116 1721 /*
2117 1722 * Advance trap trace pointer.
2118 1723 */
2119 1724 ld [%g6 + TRAPTR_OFFSET], %g5
2120 1725 ld [%g6 + TRAPTR_LIMIT], %g4
2121 1726 st %g5, [%g6 + TRAPTR_LAST_OFFSET]
2122 1727 add %g5, TRAP_ENT_SIZE, %g5
2123 1728 sub %g4, TRAP_ENT_SIZE, %g4
2124 1729 cmp %g5, %g4
2125 1730 movge %icc, 0, %g5
2126 1731 st %g5, [%g6 + TRAPTR_OFFSET]
2127 1732 dpe_tl1_skip_tt:
2128 1733 #endif /* TRAPTRACE */
2129 1734
2130 1735 /*
2131 1736 * I$ and D$ are automatically turned off by HW when the CPU hits
2132 1737 * a dcache or icache parity error so we will just leave those two
2133 1738 * off for now to avoid repeating this trap.
2134 1739 * For Panther, however, since we trap on P$ data parity errors
2135 1740 * and HW does not automatically disable P$, we need to disable it
2136 1741 * here so that we don't encounter any recursive traps when we
2137 1742 * issue the retry.
2138 1743 */
2139 1744 ldxa [%g0]ASI_DCU, %g3
2140 1745 mov 1, %g4
2141 1746 sllx %g4, DCU_PE_SHIFT, %g4
2142 1747 andn %g3, %g4, %g3
2143 1748 stxa %g3, [%g0]ASI_DCU
2144 1749 membar #Sync
↓ open down ↓ |
70 lines elided |
↑ open up ↑ |
2145 1750
2146 1751 /*
2147 1752 * We fall into this macro if we've successfully logged the error in
2148 1753 * the ch_err_tl1_data structure and want the PIL15 softint to pick
2149 1754 * it up and log it. %g1 must point to the ch_err_tl1_data structure.
2150 1755 * Restores the %g registers and issues retry.
2151 1756 */
2152 1757 CH_ERR_TL1_EXIT;
2153 1758 SET_SIZE(dcache_parity_tl1_err)
2154 1759
2155 -#endif /* lint */
2156 -
2157 1760 /*
2158 1761 * I$ parity error trap (trap 72) at TL=0.
2159 1762 * tt0_iperr is replaced by icache_parity_instr in cpu_init_trap of
2160 1763 * the various architecture-specific files. This merely sets up the
2161 1764 * arguments for cpu_parity_error and calls it via sys_trap.
2162 1765 * NB: Must be 8 instructions or less to fit in trap table and code must
2163 1766 * be relocatable.
2164 1767 */
2165 -#if defined(lint)
2166 1768
2167 -void
2168 -icache_parity_instr(void)
2169 -{}
2170 -
2171 -#else /* lint */
2172 -
2173 1769 ENTRY_NP(icache_parity_instr)
2174 1770 membar #Sync ! Cheetah+ requires membar #Sync
2175 1771 set cpu_parity_error, %g1
2176 1772 or %g0, CH_ERR_IPE, %g2
2177 1773 rdpr %tpc, %g3
2178 1774 sethi %hi(sys_trap), %g7
2179 1775 jmp %g7 + %lo(sys_trap)
2180 1776 mov PIL_15, %g4 ! run at pil 15
2181 1777 SET_SIZE(icache_parity_instr)
2182 1778
2183 -#endif /* lint */
2184 -
2185 1779 /*
2186 1780 * I$ parity error trap (trap 72) at TL>0.
2187 1781 * tt1_iperr is replaced by icache_parity_tl1_instr in cpu_init_trap of
2188 1782 * the various architecture-specific files. This generates a "Software
2189 1783 * Trap 2" at TL>0, which goes to icache_parity_tl1_cont_instr, and we
2190 1784 * continue the handling there.
2191 1785 * NB: Must be 8 instructions or less to fit in trap table and code must
2192 1786 * be relocatable.
2193 1787 */
2194 -#if defined(lint)
2195 -
2196 -void
2197 -icache_parity_tl1_instr(void)
2198 -{}
2199 -
2200 -#else /* lint */
2201 1788 ENTRY_NP(icache_parity_tl1_instr)
2202 1789 CH_ERR_TL1_TRAPENTRY(SWTRAP_2);
2203 1790 SET_SIZE(icache_parity_tl1_instr)
2204 1791
2205 -#endif /* lint */
2206 -
2207 1792 /*
2208 1793 * Software trap 2 at TL>0.
2209 1794 * tt1_swtrap2 is replaced by icache_parity_tl1_cont_instr in cpu_init_trap
2210 1795 * of the various architecture-specific files. This is used as a continuation
2211 1796 * of the icache parity handling where we've bought an extra TL level, so we
2212 1797 * can use %tpc, %tnpc, %tstate to temporarily save the value of registers %g1
2213 1798 * and %g2. Note that %tstate has bits 0-2 and then bits 8-19 as r/w,
2214 1799 * there's a reserved hole from 3-7. We only use bits 0-1 and 8-9 (the low
2215 1800 * order two bits from %g1 and %g2 respectively).
2216 1801 * NB: Must be 8 instructions or less to fit in trap table and code must
2217 1802 * be relocatable.
2218 1803 */
2219 -#if defined(lint)
2220 -
2221 -void
2222 -icache_parity_tl1_cont_instr(void)
2223 -{}
2224 -
2225 -#else /* lint */
2226 1804 ENTRY_NP(icache_parity_tl1_cont_instr)
2227 1805 CH_ERR_TL1_SWTRAPENTRY(icache_parity_tl1_err);
2228 1806 SET_SIZE(icache_parity_tl1_cont_instr)
2229 1807
2230 -#endif /* lint */
2231 1808
2232 -
2233 1809 /*
2234 1810 * I$ parity error at TL>0 handler
2235 1811 * We get here via trap 72 at TL>0->Software trap 2 at TL>0. We enter
2236 1812 * this routine with %g1 and %g2 already saved in %tpc, %tnpc and %tstate.
2237 1813 */
2238 -#if defined(lint)
2239 1814
2240 -void
2241 -icache_parity_tl1_err(void)
2242 -{}
2243 -
2244 -#else /* lint */
2245 -
2246 1815 ENTRY_NP(icache_parity_tl1_err)
2247 1816
2248 1817 /*
2249 1818 * This macro saves all the %g registers in the ch_err_tl1_data
2250 1819 * structure, updates the ch_err_tl1_flags and saves the %tpc in
2251 1820 * ch_err_tl1_tpc. At the end of this macro, %g1 will point to
2252 1821 * the ch_err_tl1_data structure and %g2 will have the original
2253 1822 * flags in the ch_err_tl1_data structure. All %g registers
2254 1823 * except for %g1 and %g2 will be available.
2255 1824 */
2256 1825 CH_ERR_TL1_ENTER(CH_ERR_IPE);
2257 1826
2258 1827 #ifdef TRAPTRACE
2259 1828 /*
2260 1829 * Get current trap trace entry physical pointer.
2261 1830 */
2262 1831 CPU_INDEX(%g6, %g5)
2263 1832 sll %g6, TRAPTR_SIZE_SHIFT, %g6
2264 1833 set trap_trace_ctl, %g5
2265 1834 add %g6, %g5, %g6
2266 1835 ld [%g6 + TRAPTR_LIMIT], %g5
2267 1836 tst %g5
2268 1837 be %icc, ipe_tl1_skip_tt
2269 1838 nop
2270 1839 ldx [%g6 + TRAPTR_PBASE], %g5
2271 1840 ld [%g6 + TRAPTR_OFFSET], %g4
2272 1841 add %g5, %g4, %g5
2273 1842
2274 1843 /*
2275 1844 * Create trap trace entry.
2276 1845 */
2277 1846 rd %asi, %g7
2278 1847 wr %g0, TRAPTR_ASI, %asi
2279 1848 rd STICK, %g4
2280 1849 stxa %g4, [%g5 + TRAP_ENT_TICK]%asi
2281 1850 rdpr %tl, %g4
2282 1851 stha %g4, [%g5 + TRAP_ENT_TL]%asi
2283 1852 rdpr %tt, %g4
2284 1853 stha %g4, [%g5 + TRAP_ENT_TT]%asi
2285 1854 rdpr %tpc, %g4
2286 1855 stna %g4, [%g5 + TRAP_ENT_TPC]%asi
2287 1856 rdpr %tstate, %g4
2288 1857 stxa %g4, [%g5 + TRAP_ENT_TSTATE]%asi
2289 1858 stna %sp, [%g5 + TRAP_ENT_SP]%asi
2290 1859 stna %g0, [%g5 + TRAP_ENT_TR]%asi
2291 1860 stna %g0, [%g5 + TRAP_ENT_F1]%asi
2292 1861 stna %g0, [%g5 + TRAP_ENT_F2]%asi
2293 1862 stna %g0, [%g5 + TRAP_ENT_F3]%asi
2294 1863 stna %g0, [%g5 + TRAP_ENT_F4]%asi
2295 1864 wr %g0, %g7, %asi
2296 1865
2297 1866 /*
2298 1867 * Advance trap trace pointer.
2299 1868 */
2300 1869 ld [%g6 + TRAPTR_OFFSET], %g5
2301 1870 ld [%g6 + TRAPTR_LIMIT], %g4
2302 1871 st %g5, [%g6 + TRAPTR_LAST_OFFSET]
2303 1872 add %g5, TRAP_ENT_SIZE, %g5
2304 1873 sub %g4, TRAP_ENT_SIZE, %g4
2305 1874 cmp %g5, %g4
2306 1875 movge %icc, 0, %g5
2307 1876 st %g5, [%g6 + TRAPTR_OFFSET]
2308 1877 ipe_tl1_skip_tt:
2309 1878 #endif /* TRAPTRACE */
2310 1879
↓ open down ↓ |
55 lines elided |
↑ open up ↑ |
2311 1880 /*
2312 1881 * We fall into this macro if we've successfully logged the error in
2313 1882 * the ch_err_tl1_data structure and want the PIL15 softint to pick
2314 1883 * it up and log it. %g1 must point to the ch_err_tl1_data structure.
2315 1884 * Restores the %g registers and issues retry.
2316 1885 */
2317 1886 CH_ERR_TL1_EXIT;
2318 1887
2319 1888 SET_SIZE(icache_parity_tl1_err)
2320 1889
2321 -#endif /* lint */
2322 -
2323 1890 #endif /* CPU_IMP_L1_CACHE_PARITY */
2324 1891
2325 1892
2326 1893 /*
2327 1894 * The itlb_rd_entry and dtlb_rd_entry functions return the tag portion of the
2328 1895 * tte, the virtual address, and the ctxnum of the specified tlb entry. They
2329 1896 * should only be used in places where you have no choice but to look at the
2330 1897 * tlb itself.
2331 1898 *
2332 1899 * Note: These two routines are required by the Estar "cpr" loadable module.
2333 1900 */
2334 1901
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 1902 ENTRY_NP(itlb_rd_entry)
2345 1903 sllx %o0, 3, %o0
2346 1904 ldxa [%o0]ASI_ITLB_ACCESS, %g1
2347 1905 stx %g1, [%o1]
2348 1906 ldxa [%o0]ASI_ITLB_TAGREAD, %g2
2349 1907 set TAGREAD_CTX_MASK, %o4
2350 1908 andn %g2, %o4, %o5
2351 1909 retl
2352 1910 stx %o5, [%o2]
2353 1911 SET_SIZE(itlb_rd_entry)
2354 1912
2355 -#endif /* lint */
2356 1913
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 1914 ENTRY_NP(dtlb_rd_entry)
2368 1915 sllx %o0, 3, %o0
2369 1916 ldxa [%o0]ASI_DTLB_ACCESS, %g1
2370 1917 stx %g1, [%o1]
2371 1918 ldxa [%o0]ASI_DTLB_TAGREAD, %g2
2372 1919 set TAGREAD_CTX_MASK, %o4
2373 1920 andn %g2, %o4, %o5
2374 1921 retl
2375 1922 stx %o5, [%o2]
2376 1923 SET_SIZE(dtlb_rd_entry)
2377 -#endif /* lint */
2378 1924
2379 1925
2380 1926 #if !(defined(JALAPENO) || defined(SERRANO))
2381 1927
2382 -#if defined(lint)
2383 -
2384 -uint64_t
2385 -get_safari_config(void)
2386 -{ return (0); }
2387 -
2388 -#else /* lint */
2389 -
2390 1928 ENTRY(get_safari_config)
2391 1929 ldxa [%g0]ASI_SAFARI_CONFIG, %o0
2392 1930 retl
2393 1931 nop
2394 1932 SET_SIZE(get_safari_config)
2395 1933
2396 -#endif /* lint */
2397 1934
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 1935 ENTRY(set_safari_config)
2409 1936 stxa %o0, [%g0]ASI_SAFARI_CONFIG
2410 1937 membar #Sync
2411 1938 retl
2412 1939 nop
2413 1940 SET_SIZE(set_safari_config)
2414 1941
2415 -#endif /* lint */
2416 -
2417 1942 #endif /* !(JALAPENO || SERRANO) */
2418 1943
2419 1944
2420 -#if defined(lint)
2421 -
2422 -void
2423 -cpu_cleartickpnt(void)
2424 -{}
2425 -
2426 -#else /* lint */
2427 1945 /*
2428 1946 * Clear the NPT (non-privileged trap) bit in the %tick/%stick
2429 1947 * registers. In an effort to make the change in the
2430 1948 * tick/stick counter as consistent as possible, we disable
2431 1949 * all interrupts while we're changing the registers. We also
2432 1950 * ensure that the read and write instructions are in the same
2433 1951 * line in the instruction cache.
2434 1952 */
2435 1953 ENTRY_NP(cpu_clearticknpt)
2436 1954 rdpr %pstate, %g1 /* save processor state */
2437 1955 andn %g1, PSTATE_IE, %g3 /* turn off */
2438 1956 wrpr %g0, %g3, %pstate /* interrupts */
2439 1957 rdpr %tick, %g2 /* get tick register */
2440 1958 brgez,pn %g2, 1f /* if NPT bit off, we're done */
2441 1959 mov 1, %g3 /* create mask */
2442 1960 sllx %g3, 63, %g3 /* for NPT bit */
2443 1961 ba,a,pt %xcc, 2f
2444 1962 .align 8 /* Ensure rd/wr in same i$ line */
2445 1963 2:
2446 1964 rdpr %tick, %g2 /* get tick register */
2447 1965 wrpr %g3, %g2, %tick /* write tick register, */
2448 1966 /* clearing NPT bit */
2449 1967 1:
2450 1968 rd STICK, %g2 /* get stick register */
2451 1969 brgez,pn %g2, 3f /* if NPT bit off, we're done */
2452 1970 mov 1, %g3 /* create mask */
2453 1971 sllx %g3, 63, %g3 /* for NPT bit */
2454 1972 ba,a,pt %xcc, 4f
2455 1973 .align 8 /* Ensure rd/wr in same i$ line */
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
2456 1974 4:
2457 1975 rd STICK, %g2 /* get stick register */
2458 1976 wr %g3, %g2, STICK /* write stick register, */
2459 1977 /* clearing NPT bit */
2460 1978 3:
2461 1979 jmp %g4 + 4
2462 1980 wrpr %g0, %g1, %pstate /* restore processor state */
2463 1981
2464 1982 SET_SIZE(cpu_clearticknpt)
2465 1983
2466 -#endif /* lint */
2467 1984
2468 -
2469 1985 #if defined(CPU_IMP_L1_CACHE_PARITY)
2470 1986
2471 -#if defined(lint)
2472 1987 /*
2473 1988 * correct_dcache_parity(size_t size, size_t linesize)
2474 1989 *
2475 1990 * Correct D$ data parity by zeroing the data and initializing microtag
2476 1991 * for all indexes and all ways of the D$.
2477 - *
1992 + *
2478 1993 */
2479 -/* ARGSUSED */
2480 -void
2481 -correct_dcache_parity(size_t size, size_t linesize)
2482 -{}
2483 -
2484 -#else /* lint */
2485 -
2486 1994 ENTRY(correct_dcache_parity)
2487 1995 /*
2488 1996 * Register Usage:
2489 1997 *
2490 1998 * %o0 = input D$ size
2491 1999 * %o1 = input D$ line size
2492 2000 * %o2 = scratch
2493 2001 * %o3 = scratch
2494 2002 * %o4 = scratch
2495 2003 */
2496 2004
2497 2005 sub %o0, %o1, %o0 ! init cache line address
2498 2006
2499 2007 /*
2500 2008 * For Panther CPUs, we also need to clear the data parity bits
2501 2009 * using DC_data_parity bit of the ASI_DCACHE_DATA register.
2502 2010 */
2503 2011 GET_CPU_IMPL(%o3)
2504 2012 cmp %o3, PANTHER_IMPL
2505 2013 bne 1f
2506 2014 clr %o3 ! zero for non-Panther
2507 2015 mov 1, %o3
2508 2016 sll %o3, PN_DC_DATA_PARITY_BIT_SHIFT, %o3
2509 2017
2510 2018 1:
2511 2019 /*
2512 2020 * Set utag = way since it must be unique within an index.
2513 2021 */
2514 2022 srl %o0, 14, %o2 ! get cache way (DC_way)
2515 2023 membar #Sync ! required before ASI_DC_UTAG
2516 2024 stxa %o2, [%o0]ASI_DC_UTAG ! set D$ utag = cache way
2517 2025 membar #Sync ! required after ASI_DC_UTAG
2518 2026
2519 2027 /*
2520 2028 * Zero line of D$ data (and data parity bits for Panther)
2521 2029 */
2522 2030 sub %o1, 8, %o2
2523 2031 or %o0, %o3, %o4 ! same address + DC_data_parity
2524 2032 2:
2525 2033 membar #Sync ! required before ASI_DC_DATA
2526 2034 stxa %g0, [%o0 + %o2]ASI_DC_DATA ! zero 8 bytes of D$ data
2527 2035 membar #Sync ! required after ASI_DC_DATA
2528 2036 /*
2529 2037 * We also clear the parity bits if this is a panther. For non-Panther
2530 2038 * CPUs, we simply end up clearing the $data register twice.
2531 2039 */
2532 2040 stxa %g0, [%o4 + %o2]ASI_DC_DATA
2533 2041 membar #Sync
2534 2042
2535 2043 subcc %o2, 8, %o2
2536 2044 bge 2b
↓ open down ↓ |
41 lines elided |
↑ open up ↑ |
2537 2045 nop
2538 2046
2539 2047 subcc %o0, %o1, %o0
2540 2048 bge 1b
2541 2049 nop
2542 2050
2543 2051 retl
2544 2052 nop
2545 2053 SET_SIZE(correct_dcache_parity)
2546 2054
2547 -#endif /* lint */
2548 -
2549 2055 #endif /* CPU_IMP_L1_CACHE_PARITY */
2550 2056
2551 2057
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 2058 ENTRY_NP(stick_timestamp)
2565 2059 rd STICK, %g1 ! read stick reg
2566 2060 sllx %g1, 1, %g1
2567 2061 srlx %g1, 1, %g1 ! clear npt bit
2568 2062
2569 2063 retl
2570 2064 stx %g1, [%o0] ! store the timestamp
2571 2065 SET_SIZE(stick_timestamp)
2572 2066
2573 -#endif /* lint */
2574 2067
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 2068 ENTRY_NP(stick_adj)
2589 2069 rdpr %pstate, %g1 ! save processor state
2590 2070 andn %g1, PSTATE_IE, %g3
2591 2071 ba 1f ! cache align stick adj
2592 2072 wrpr %g0, %g3, %pstate ! turn off interrupts
2593 2073
2594 2074 .align 16
2595 2075 1: nop
2596 2076
2597 2077 rd STICK, %g4 ! read stick reg
2598 2078 add %g4, %o0, %o1 ! adjust stick with skew
2599 2079 wr %o1, %g0, STICK ! write stick reg
2600 2080
2601 2081 retl
2602 2082 wrpr %g1, %pstate ! restore processor state
2603 2083 SET_SIZE(stick_adj)
2604 2084
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 2085 ENTRY_NP(kdi_get_stick)
2621 2086 rd STICK, %g1
2622 2087 stx %g1, [%o0]
2623 2088 retl
2624 2089 mov %g0, %o0
2625 2090 SET_SIZE(kdi_get_stick)
2626 2091
2627 -#endif /* lint */
2628 -
2629 -#if defined(lint)
2630 2092 /*
2631 2093 * Invalidate the specified line from the D$.
2632 2094 *
2633 2095 * Register usage:
2634 2096 * %o0 - index for the invalidation, specifies DC_way and DC_addr
2635 2097 *
2636 2098 * ASI_DC_TAG, 0x47, is used in the following manner. A 64-bit value is
2637 2099 * stored to a particular DC_way and DC_addr in ASI_DC_TAG.
2638 2100 *
2639 2101 * The format of the stored 64-bit value is:
2640 2102 *
2641 2103 * +----------+--------+----------+
2642 2104 * | Reserved | DC_tag | DC_valid |
2643 2105 * +----------+--------+----------+
2644 2106 * 63 31 30 1 0
2645 2107 *
2646 2108 * DC_tag is the 30-bit physical tag of the associated line.
2647 2109 * DC_valid is the 1-bit valid field for both the physical and snoop tags.
2648 2110 *
2649 2111 * The format of the 64-bit DC_way and DC_addr into ASI_DC_TAG is:
2650 2112 *
2651 2113 * +----------+--------+----------+----------+
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
2652 2114 * | Reserved | DC_way | DC_addr | Reserved |
2653 2115 * +----------+--------+----------+----------+
2654 2116 * 63 16 15 14 13 5 4 0
2655 2117 *
2656 2118 * DC_way is a 2-bit index that selects one of the 4 ways.
2657 2119 * DC_addr is a 9-bit index that selects one of 512 tag/valid fields.
2658 2120 *
2659 2121 * Setting the DC_valid bit to zero for the specified DC_way and
2660 2122 * DC_addr index into the D$ results in an invalidation of a D$ line.
2661 2123 */
2662 -/*ARGSUSED*/
2663 -void
2664 -dcache_inval_line(int index)
2665 -{
2666 -}
2667 -#else /* lint */
2668 2124 ENTRY(dcache_inval_line)
2669 2125 sll %o0, 5, %o0 ! shift index into DC_way and DC_addr
2670 2126 stxa %g0, [%o0]ASI_DC_TAG ! zero the DC_valid and DC_tag bits
2671 2127 membar #Sync
2672 2128 retl
2673 2129 nop
2674 2130 SET_SIZE(dcache_inval_line)
2675 -#endif /* lint */
2676 2131
2677 -#if defined(lint)
2678 2132 /*
2679 2133 * Invalidate the entire I$
2680 2134 *
2681 2135 * Register usage:
2682 2136 * %o0 - specifies IC_way, IC_addr, IC_tag
2683 2137 * %o1 - scratch
2684 2138 * %o2 - used to save and restore DCU value
2685 2139 * %o3 - scratch
2686 2140 * %o5 - used to save and restore PSTATE
2687 2141 *
2688 2142 * Due to the behavior of the I$ control logic when accessing ASI_IC_TAG,
2689 2143 * the I$ should be turned off. Accesses to ASI_IC_TAG may collide and
2690 2144 * block out snoops and invalidates to the I$, causing I$ consistency
2691 2145 * to be broken. Before turning on the I$, all I$ lines must be invalidated.
2692 2146 *
2693 2147 * ASI_IC_TAG, 0x67, is used in the following manner. A 64-bit value is
2694 2148 * stored to a particular IC_way, IC_addr, IC_tag in ASI_IC_TAG. The
2695 2149 * info below describes store (write) use of ASI_IC_TAG. Note that read
2696 2150 * use of ASI_IC_TAG behaves differently.
2697 2151 *
2698 2152 * The format of the stored 64-bit value is:
2699 2153 *
2700 2154 * +----------+--------+---------------+-----------+
2701 2155 * | Reserved | Valid | IC_vpred<7:0> | Undefined |
2702 2156 * +----------+--------+---------------+-----------+
2703 2157 * 63 55 54 53 46 45 0
2704 2158 *
2705 2159 * Valid is the 1-bit valid field for both the physical and snoop tags.
2706 2160 * IC_vpred is the 8-bit LPB bits for 8 instructions starting at
2707 2161 * the 32-byte boundary aligned address specified by IC_addr.
2708 2162 *
2709 2163 * The format of the 64-bit IC_way, IC_addr, IC_tag into ASI_IC_TAG is:
2710 2164 *
2711 2165 * +----------+--------+---------+--------+---------+
2712 2166 * | Reserved | IC_way | IC_addr | IC_tag |Reserved |
2713 2167 * +----------+--------+---------+--------+---------+
2714 2168 * 63 16 15 14 13 5 4 3 2 0
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
2715 2169 *
2716 2170 * IC_way is a 2-bit index that selects one of the 4 ways.
2717 2171 * IC_addr[13:6] is an 8-bit index that selects one of 256 valid fields.
2718 2172 * IC_addr[5] is a "don't care" for a store.
2719 2173 * IC_tag set to 2 specifies that the stored value is to be interpreted
2720 2174 * as containing Valid and IC_vpred as described above.
2721 2175 *
2722 2176 * Setting the Valid bit to zero for the specified IC_way and
2723 2177 * IC_addr index into the I$ results in an invalidation of an I$ line.
2724 2178 */
2725 -/*ARGSUSED*/
2726 -void
2727 -icache_inval_all(void)
2728 -{
2729 -}
2730 -#else /* lint */
2731 2179 ENTRY(icache_inval_all)
2732 2180 rdpr %pstate, %o5
2733 2181 andn %o5, PSTATE_IE, %o3
2734 2182 wrpr %g0, %o3, %pstate ! clear IE bit
2735 2183
2736 2184 GET_CPU_PRIVATE_PTR(%g0, %o0, %o2, icache_inval_all_1);
2737 2185 ld [%o0 + CHPR_ICACHE_LINESIZE], %o1
2738 2186 ba,pt %icc, 2f
2739 2187 ld [%o0 + CHPR_ICACHE_SIZE], %o0
2740 2188 icache_inval_all_1:
2741 2189 ASM_LD(%o0, icache_size)
2742 2190 ASM_LD(%o1, icache_linesize)
2743 2191 2:
2744 2192 CH_ICACHE_FLUSHALL(%o0, %o1, %o2, %o4)
2745 2193
2746 2194 retl
2747 2195 wrpr %g0, %o5, %pstate ! restore earlier pstate
2748 2196 SET_SIZE(icache_inval_all)
2749 -#endif /* lint */
2750 2197
2751 2198
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 2199 /*
2761 2200 * cache_scrubreq_tl1 is the crosstrap handler called on offlined cpus via a
2762 2201 * crosstrap. It atomically increments the outstanding request counter and,
2763 2202 * if there was not already an outstanding request, branches to setsoftint_tl1
2764 2203 * to enqueue an intr_vec for the given inum.
2765 2204 */
2766 2205
2767 2206 ! Register usage:
2768 2207 !
2769 2208 ! Arguments:
2770 2209 ! %g1 - inum
2771 2210 ! %g2 - index into chsm_outstanding array
2772 2211 !
2773 2212 ! Internal:
2774 2213 ! %g2, %g3, %g5 - scratch
2775 2214 ! %g4 - ptr. to scrub_misc chsm_outstanding[index].
2776 2215 ! %g6 - setsoftint_tl1 address
2777 2216
2778 2217 ENTRY_NP(cache_scrubreq_tl1)
2779 2218 mulx %g2, CHSM_OUTSTANDING_INCR, %g2
2780 2219 set CHPR_SCRUB_MISC + CHSM_OUTSTANDING, %g3
2781 2220 add %g2, %g3, %g2
2782 2221 GET_CPU_PRIVATE_PTR(%g2, %g4, %g5, 1f);
2783 2222 ld [%g4], %g2 ! cpu's chsm_outstanding[index]
2784 2223 !
2785 2224 ! no need to use atomic instructions for the following
2786 2225 ! increment - we're at tl1
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
2787 2226 !
2788 2227 add %g2, 0x1, %g3
2789 2228 brnz,pn %g2, 1f ! no need to enqueue more intr_vec
2790 2229 st %g3, [%g4] ! delay - store incremented counter
2791 2230 ASM_JMP(%g6, setsoftint_tl1)
2792 2231 ! not reached
2793 2232 1:
2794 2233 retry
2795 2234 SET_SIZE(cache_scrubreq_tl1)
2796 2235
2797 -#endif /* lint */
2798 2236
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 2237 /*
2810 2238 * Get the error state for the processor.
2811 2239 * Note that this must not be used at TL>0
2812 2240 */
2813 2241 ENTRY(get_cpu_error_state)
2814 2242 #if defined(CHEETAH_PLUS)
2815 2243 set ASI_SHADOW_REG_VA, %o2
2816 2244 ldxa [%o2]ASI_AFSR, %o1 ! shadow afsr reg
2817 2245 stx %o1, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR]
2818 2246 ldxa [%o2]ASI_AFAR, %o1 ! shadow afar reg
2819 2247 stx %o1, [%o0 + CH_CPU_ERRORS_SHADOW_AFAR]
2820 2248 GET_CPU_IMPL(%o3) ! Only panther has AFSR_EXT registers
2821 2249 cmp %o3, PANTHER_IMPL
2822 2250 bne,a 1f
2823 2251 stx %g0, [%o0 + CH_CPU_ERRORS_AFSR_EXT] ! zero for non-PN
2824 2252 set ASI_AFSR_EXT_VA, %o2
2825 2253 ldxa [%o2]ASI_AFSR, %o1 ! afsr_ext reg
2826 2254 stx %o1, [%o0 + CH_CPU_ERRORS_AFSR_EXT]
2827 2255 set ASI_SHADOW_AFSR_EXT_VA, %o2
2828 2256 ldxa [%o2]ASI_AFSR, %o1 ! shadow afsr_ext reg
2829 2257 stx %o1, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR_EXT]
2830 2258 b 2f
2831 2259 nop
2832 2260 1:
2833 2261 stx %g0, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR_EXT] ! zero for non-PN
2834 2262 2:
2835 2263 #else /* CHEETAH_PLUS */
2836 2264 stx %g0, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR]
2837 2265 stx %g0, [%o0 + CH_CPU_ERRORS_SHADOW_AFAR]
2838 2266 stx %g0, [%o0 + CH_CPU_ERRORS_AFSR_EXT]
2839 2267 stx %g0, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR_EXT]
2840 2268 #endif /* CHEETAH_PLUS */
2841 2269 #if defined(SERRANO)
2842 2270 /*
2843 2271 * Serrano has an afar2 which captures the address on FRC/FRU errors.
2844 2272 * We save this in the afar2 of the register save area.
2845 2273 */
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
2846 2274 set ASI_MCU_AFAR2_VA, %o2
2847 2275 ldxa [%o2]ASI_MCU_CTRL, %o1
2848 2276 stx %o1, [%o0 + CH_CPU_ERRORS_AFAR2]
2849 2277 #endif /* SERRANO */
2850 2278 ldxa [%g0]ASI_AFSR, %o1 ! primary afsr reg
2851 2279 stx %o1, [%o0 + CH_CPU_ERRORS_AFSR]
2852 2280 ldxa [%g0]ASI_AFAR, %o1 ! primary afar reg
2853 2281 retl
2854 2282 stx %o1, [%o0 + CH_CPU_ERRORS_AFAR]
2855 2283 SET_SIZE(get_cpu_error_state)
2856 -#endif /* lint */
2857 2284
2858 -#if defined(lint)
2859 -
2860 2285 /*
2861 2286 * Check a page of memory for errors.
2862 2287 *
2863 2288 * Load each 64 byte block from physical memory.
2864 2289 * Check AFSR after each load to see if an error
2865 2290 * was caused. If so, log/scrub that error.
2866 2291 *
2867 2292 * Used to determine if a page contains
2868 2293 * CEs when CEEN is disabled.
2869 2294 */
2870 -/*ARGSUSED*/
2871 -void
2872 -cpu_check_block(caddr_t va, uint_t psz)
2873 -{}
2874 -
2875 -#else /* lint */
2876 -
2877 2295 ENTRY(cpu_check_block)
2878 2296 !
2879 2297 ! get a new window with room for the error regs
2880 2298 !
2881 2299 save %sp, -SA(MINFRAME + CH_CPU_ERROR_SIZE), %sp
2882 2300 srl %i1, 6, %l4 ! clear top bits of psz
2883 2301 ! and divide by 64
2884 2302 rd %fprs, %l2 ! store FP
2885 2303 wr %g0, FPRS_FEF, %fprs ! enable FP
2886 2304 1:
2887 2305 ldda [%i0]ASI_BLK_P, %d0 ! load a block
2888 2306 membar #Sync
2889 2307 ldxa [%g0]ASI_AFSR, %l3 ! read afsr reg
2890 2308 brz,a,pt %l3, 2f ! check for error
2891 2309 nop
2892 2310
2893 2311 !
2894 2312 ! if error, read the error regs and log it
2895 2313 !
2896 2314 call get_cpu_error_state
2897 2315 add %fp, STACK_BIAS - CH_CPU_ERROR_SIZE, %o0
2898 2316
2899 2317 !
2900 2318 ! cpu_ce_detected(ch_cpu_errors_t *, flag)
2901 2319 !
2902 2320 call cpu_ce_detected ! log the error
2903 2321 mov CE_CEEN_TIMEOUT, %o1
2904 2322 2:
↓ open down ↓ |
18 lines elided |
↑ open up ↑ |
2905 2323 dec %l4 ! next 64-byte block
2906 2324 brnz,a,pt %l4, 1b
2907 2325 add %i0, 64, %i0 ! increment block addr
2908 2326
2909 2327 wr %l2, %g0, %fprs ! restore FP
2910 2328 ret
2911 2329 restore
2912 2330
2913 2331 SET_SIZE(cpu_check_block)
2914 2332
2915 -#endif /* lint */
2916 -
2917 -#if defined(lint)
2918 -
2919 2333 /*
2920 2334 * Perform a cpu logout called from C. This is used where we did not trap
2921 2335 * for the error but still want to gather "what we can". Caller must make
2922 2336 * sure cpu private area exists and that the indicated logout area is free
2923 2337 * for use, and that we are unable to migrate cpus.
2924 2338 */
2925 -/*ARGSUSED*/
2926 -void
2927 -cpu_delayed_logout(uint64_t afar, ch_cpu_logout_t *clop)
2928 -{ }
2929 -
2930 -#else
2931 2339 ENTRY(cpu_delayed_logout)
2932 2340 rdpr %pstate, %o2
2933 2341 andn %o2, PSTATE_IE, %o2
2934 2342 wrpr %g0, %o2, %pstate ! disable interrupts
2935 2343 PARK_SIBLING_CORE(%o2, %o3, %o4) ! %o2 has DCU value
2936 2344 add %o1, CH_CLO_DATA + CH_CHD_EC_DATA, %o1
2937 2345 rd %asi, %g1
2938 2346 wr %g0, ASI_P, %asi
2939 2347 GET_ECACHE_DTAGS(%o0, %o1, %o3, %o4, %o5)
2940 2348 wr %g1, %asi
2941 2349 UNPARK_SIBLING_CORE(%o2, %o3, %o4) ! can use %o2 again
2942 2350 rdpr %pstate, %o2
2943 2351 or %o2, PSTATE_IE, %o2
2944 2352 wrpr %g0, %o2, %pstate
2945 2353 retl
2946 2354 nop
2947 2355 SET_SIZE(cpu_delayed_logout)
2948 2356
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 2357 ENTRY(dtrace_blksuword32)
2961 2358 save %sp, -SA(MINFRAME + 4), %sp
2962 2359
2963 2360 rdpr %pstate, %l1
2964 2361 andn %l1, PSTATE_IE, %l2 ! disable interrupts to
2965 2362 wrpr %g0, %l2, %pstate ! protect our FPU diddling
2966 2363
2967 2364 rd %fprs, %l0
2968 2365 andcc %l0, FPRS_FEF, %g0
2969 2366 bz,a,pt %xcc, 1f ! if the fpu is disabled
2970 2367 wr %g0, FPRS_FEF, %fprs ! ... enable the fpu
2971 2368
2972 2369 st %f0, [%fp + STACK_BIAS - 4] ! save %f0 to the stack
2973 2370 1:
2974 2371 set 0f, %l5
2975 2372 /*
2976 2373 * We're about to write a block full or either total garbage
2977 2374 * (not kernel data, don't worry) or user floating-point data
2978 2375 * (so it only _looks_ like garbage).
2979 2376 */
2980 2377 ld [%i1], %f0 ! modify the block
2981 2378 membar #Sync
2982 2379 stn %l5, [THREAD_REG + T_LOFAULT] ! set up the lofault handler
2983 2380 stda %d0, [%i0]ASI_BLK_COMMIT_S ! store the modified block
2984 2381 membar #Sync
2985 2382 stn %g0, [THREAD_REG + T_LOFAULT] ! remove the lofault handler
2986 2383
2987 2384 bz,a,pt %xcc, 1f
2988 2385 wr %g0, %l0, %fprs ! restore %fprs
2989 2386
2990 2387 ld [%fp + STACK_BIAS - 4], %f0 ! restore %f0
2991 2388 1:
2992 2389
2993 2390 wrpr %g0, %l1, %pstate ! restore interrupts
2994 2391
2995 2392 ret
2996 2393 restore %g0, %g0, %o0
2997 2394
2998 2395 0:
2999 2396 membar #Sync
3000 2397 stn %g0, [THREAD_REG + T_LOFAULT] ! remove the lofault handler
3001 2398
3002 2399 bz,a,pt %xcc, 1f
3003 2400 wr %g0, %l0, %fprs ! restore %fprs
3004 2401
3005 2402 ld [%fp + STACK_BIAS - 4], %f0 ! restore %f0
3006 2403 1:
3007 2404
3008 2405 wrpr %g0, %l1, %pstate ! restore interrupts
3009 2406
3010 2407 /*
3011 2408 * If tryagain is set (%i2) we tail-call dtrace_blksuword32_err()
3012 2409 * which deals with watchpoints. Otherwise, just return -1.
3013 2410 */
↓ open down ↓ |
44 lines elided |
↑ open up ↑ |
3014 2411 brnz,pt %i2, 1f
3015 2412 nop
3016 2413 ret
3017 2414 restore %g0, -1, %o0
3018 2415 1:
3019 2416 call dtrace_blksuword32_err
3020 2417 restore
3021 2418
3022 2419 SET_SIZE(dtrace_blksuword32)
3023 2420
3024 -#endif /* lint */
3025 -
3026 2421 #ifdef CHEETAHPLUS_ERRATUM_25
3027 2422
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 2423 ENTRY(claimlines)
3038 2424 1:
3039 2425 subcc %o1, %o2, %o1
3040 2426 add %o0, %o1, %o3
3041 2427 bgeu,a,pt %xcc, 1b
3042 2428 casxa [%o3]ASI_MEM, %g0, %g0
3043 2429 membar #Sync
3044 2430 retl
3045 2431 nop
3046 2432 SET_SIZE(claimlines)
3047 -#endif /* lint */
3048 2433
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 2434 ENTRY(cpu_feature_init)
3061 2435 save %sp, -SA(MINFRAME), %sp
3062 2436 sethi %hi(cheetah_bpe_off), %o0
3063 2437 ld [%o0 + %lo(cheetah_bpe_off)], %o0
3064 2438 brz %o0, 1f
3065 2439 nop
3066 2440 rd ASR_DISPATCH_CONTROL, %o0
3067 2441 andn %o0, ASR_DISPATCH_CONTROL_BPE, %o0
3068 2442 wr %o0, 0, ASR_DISPATCH_CONTROL
3069 2443 1:
3070 2444 !
3071 2445 ! get the device_id and store the device_id
3072 2446 ! in the appropriate cpunodes structure
3073 2447 ! given the cpus index
3074 2448 !
3075 2449 CPU_INDEX(%o0, %o1)
3076 2450 mulx %o0, CPU_NODE_SIZE, %o0
3077 2451 set cpunodes + DEVICE_ID, %o1
3078 2452 ldxa [%g0] ASI_DEVICE_SERIAL_ID, %o2
3079 2453 stx %o2, [%o0 + %o1]
3080 2454 #ifdef CHEETAHPLUS_ERRATUM_34
3081 2455 !
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
3082 2456 ! apply Cheetah+ erratum 34 workaround
3083 2457 !
3084 2458 call itlb_erratum34_fixup
3085 2459 nop
3086 2460 call dtlb_erratum34_fixup
3087 2461 nop
3088 2462 #endif /* CHEETAHPLUS_ERRATUM_34 */
3089 2463 ret
3090 2464 restore
3091 2465 SET_SIZE(cpu_feature_init)
3092 -#endif /* lint */
3093 2466
3094 -#if defined(lint)
3095 2467 /*
3096 2468 * Copy a tsb entry atomically, from src to dest.
3097 2469 * src must be 128 bit aligned.
3098 2470 */
3099 -/*ARGSUSED*/
3100 -void
3101 -copy_tsb_entry(uintptr_t src, uintptr_t dest)
3102 -{}
3103 -#else /* lint */
3104 2471 ENTRY(copy_tsb_entry)
3105 2472 ldda [%o0]ASI_NQUAD_LD, %o2 ! %o2 = tag, %o3 = data
3106 2473 stx %o2, [%o1]
3107 2474 stx %o3, [%o1 + 8 ]
3108 2475 retl
3109 2476 nop
3110 2477 SET_SIZE(copy_tsb_entry)
3111 -#endif /* lint */
3112 2478
3113 2479 #endif /* CHEETAHPLUS_ERRATUM_25 */
3114 2480
3115 2481 #ifdef CHEETAHPLUS_ERRATUM_34
3116 2482
3117 -#if defined(lint)
3118 -
3119 -/*ARGSUSED*/
3120 -void
3121 -itlb_erratum34_fixup(void)
3122 -{}
3123 -
3124 -#else /* lint */
3125 -
3126 2483 !
3127 2484 ! In Cheetah+ erratum 34, under certain conditions an ITLB locked
3128 2485 ! index 0 TTE will erroneously be displaced when a new TTE is
3129 2486 ! loaded via ASI_ITLB_IN. In order to avoid cheetah+ erratum 34,
3130 2487 ! locked index 0 TTEs must be relocated.
3131 2488 !
3132 2489 ! NOTE: Care must be taken to avoid an ITLB miss in this routine.
3133 2490 !
3134 2491 ENTRY_NP(itlb_erratum34_fixup)
3135 2492 rdpr %pstate, %o3
3136 2493 #ifdef DEBUG
3137 2494 PANIC_IF_INTR_DISABLED_PSTR(%o3, u3_di_label1, %g1)
3138 2495 #endif /* DEBUG */
3139 2496 wrpr %o3, PSTATE_IE, %pstate ! Disable interrupts
3140 2497 ldxa [%g0]ASI_ITLB_ACCESS, %o1 ! %o1 = entry 0 data
3141 2498 ldxa [%g0]ASI_ITLB_TAGREAD, %o2 ! %o2 = entry 0 tag
3142 2499
3143 2500 cmp %o1, %g0 ! Is this entry valid?
3144 2501 bge %xcc, 1f
3145 2502 andcc %o1, TTE_LCK_INT, %g0 ! Is this entry locked?
3146 2503 bnz %icc, 2f
3147 2504 nop
3148 2505 1:
3149 2506 retl ! Nope, outta here...
3150 2507 wrpr %g0, %o3, %pstate ! Enable interrupts
3151 2508 2:
3152 2509 sethi %hi(FLUSH_ADDR), %o4
3153 2510 stxa %g0, [%o2]ASI_ITLB_DEMAP ! Flush this mapping
3154 2511 flush %o4 ! Flush required for I-MMU
3155 2512 !
3156 2513 ! Start search from index 1 up. This is because the kernel force
3157 2514 ! loads its text page at index 15 in sfmmu_kernel_remap() and we
3158 2515 ! don't want our relocated entry evicted later.
3159 2516 !
3160 2517 ! NOTE: We assume that we'll be successful in finding an unlocked
3161 2518 ! or invalid entry. If that isn't the case there are bound to
3162 2519 ! bigger problems.
3163 2520 !
3164 2521 set (1 << 3), %g3
3165 2522 3:
3166 2523 ldxa [%g3]ASI_ITLB_ACCESS, %o4 ! Load TTE from t16
3167 2524 !
3168 2525 ! If this entry isn't valid, we'll choose to displace it (regardless
3169 2526 ! of the lock bit).
3170 2527 !
3171 2528 cmp %o4, %g0 ! TTE is > 0 iff not valid
3172 2529 bge %xcc, 4f ! If invalid, go displace
3173 2530 andcc %o4, TTE_LCK_INT, %g0 ! Check for lock bit
3174 2531 bnz,a %icc, 3b ! If locked, look at next
3175 2532 add %g3, (1 << 3), %g3 ! entry
3176 2533 4:
3177 2534 !
3178 2535 ! We found an unlocked or invalid entry; we'll explicitly load
3179 2536 ! the former index 0 entry here.
↓ open down ↓ |
44 lines elided |
↑ open up ↑ |
3180 2537 !
3181 2538 sethi %hi(FLUSH_ADDR), %o4
3182 2539 set MMU_TAG_ACCESS, %g4
3183 2540 stxa %o2, [%g4]ASI_IMMU
3184 2541 stxa %o1, [%g3]ASI_ITLB_ACCESS
3185 2542 flush %o4 ! Flush required for I-MMU
3186 2543 retl
3187 2544 wrpr %g0, %o3, %pstate ! Enable interrupts
3188 2545 SET_SIZE(itlb_erratum34_fixup)
3189 2546
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 2547 !
3202 2548 ! In Cheetah+ erratum 34, under certain conditions a DTLB locked
3203 2549 ! index 0 TTE will erroneously be displaced when a new TTE is
3204 2550 ! loaded. In order to avoid cheetah+ erratum 34, locked index 0
3205 2551 ! TTEs must be relocated.
3206 2552 !
3207 2553 ENTRY_NP(dtlb_erratum34_fixup)
3208 2554 rdpr %pstate, %o3
3209 2555 #ifdef DEBUG
3210 2556 PANIC_IF_INTR_DISABLED_PSTR(%o3, u3_di_label2, %g1)
3211 2557 #endif /* DEBUG */
3212 2558 wrpr %o3, PSTATE_IE, %pstate ! Disable interrupts
3213 2559 ldxa [%g0]ASI_DTLB_ACCESS, %o1 ! %o1 = entry 0 data
3214 2560 ldxa [%g0]ASI_DTLB_TAGREAD, %o2 ! %o2 = entry 0 tag
3215 2561
3216 2562 cmp %o1, %g0 ! Is this entry valid?
3217 2563 bge %xcc, 1f
3218 2564 andcc %o1, TTE_LCK_INT, %g0 ! Is this entry locked?
3219 2565 bnz %icc, 2f
3220 2566 nop
3221 2567 1:
3222 2568 retl ! Nope, outta here...
3223 2569 wrpr %g0, %o3, %pstate ! Enable interrupts
3224 2570 2:
3225 2571 stxa %g0, [%o2]ASI_DTLB_DEMAP ! Flush this mapping
3226 2572 membar #Sync
3227 2573 !
3228 2574 ! Start search from index 1 up.
3229 2575 !
3230 2576 ! NOTE: We assume that we'll be successful in finding an unlocked
3231 2577 ! or invalid entry. If that isn't the case there are bound to
3232 2578 ! bigger problems.
3233 2579 !
3234 2580 set (1 << 3), %g3
3235 2581 3:
3236 2582 ldxa [%g3]ASI_DTLB_ACCESS, %o4 ! Load TTE from t16
3237 2583 !
3238 2584 ! If this entry isn't valid, we'll choose to displace it (regardless
3239 2585 ! of the lock bit).
3240 2586 !
3241 2587 cmp %o4, %g0 ! TTE is > 0 iff not valid
3242 2588 bge %xcc, 4f ! If invalid, go displace
3243 2589 andcc %o4, TTE_LCK_INT, %g0 ! Check for lock bit
3244 2590 bnz,a %icc, 3b ! If locked, look at next
3245 2591 add %g3, (1 << 3), %g3 ! entry
3246 2592 4:
3247 2593 !
3248 2594 ! We found an unlocked or invalid entry; we'll explicitly load
↓ open down ↓ |
38 lines elided |
↑ open up ↑ |
3249 2595 ! the former index 0 entry here.
3250 2596 !
3251 2597 set MMU_TAG_ACCESS, %g4
3252 2598 stxa %o2, [%g4]ASI_DMMU
3253 2599 stxa %o1, [%g3]ASI_DTLB_ACCESS
3254 2600 membar #Sync
3255 2601 retl
3256 2602 wrpr %g0, %o3, %pstate ! Enable interrupts
3257 2603 SET_SIZE(dtlb_erratum34_fixup)
3258 2604
3259 -#endif /* lint */
3260 -
3261 2605 #endif /* CHEETAHPLUS_ERRATUM_34 */
3262 2606
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX