9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 *
26 * Assembly code support for the Cheetah module
27 */
28
29 #pragma ident "%Z%%M% %I% %E% SMI"
30
31 #if !defined(lint)
32 #include "assym.h"
33 #endif /* lint */
34
35 #include <sys/asm_linkage.h>
36 #include <sys/mmu.h>
37 #include <vm/hat_sfmmu.h>
38 #include <sys/machparam.h>
39 #include <sys/machcpuvar.h>
40 #include <sys/machthread.h>
41 #include <sys/machtrap.h>
42 #include <sys/privregs.h>
43 #include <sys/asm_linkage.h>
44 #include <sys/trap.h>
45 #include <sys/cheetahregs.h>
46 #include <sys/us3_module.h>
47 #include <sys/xc_impl.h>
48 #include <sys/intreg.h>
49 #include <sys/async.h>
50 #include <sys/clock.h>
51 #include <sys/cheetahasm.h>
52
53 #ifdef TRAPTRACE
54 #include <sys/traptrace.h>
55 #endif /* TRAPTRACE */
56
57 #if !defined(lint)
58
59 /* BEGIN CSTYLED */
60
61 /*
62 * Cheetah version to flush an Ecache line by index (aliased address)
63 */
64 #define ECACHE_REFLUSH_LINE(ecache_size, alias_address, scr2) \
65 ldxa [alias_address]ASI_MEM, %g0
66
67 #define ECACHE_FLUSH_LINE(physaddr, ecache_size, scr1, scr2) \
68 xor physaddr, ecache_size, scr1; \
69 add ecache_size, ecache_size, scr2; \
70 sub scr2, 1, scr2; \
71 and scr1, scr2, scr1; \
72 ASM_LDX(scr2, ecache_flushaddr); \
73 add scr1, scr2, scr1; \
74 ECACHE_REFLUSH_LINE(ecache_size, scr1, scr2)
75
76 /* END CSTYLED */
77
78 #endif /* !lint */
79
80
81 /*
82 * Fast ECC error at TL>0 handler
83 * We get here via trap 70 at TL>0->Software trap 0 at TL>0. We enter
84 * this routine with %g1 and %g2 already saved in %tpc, %tnpc and %tstate.
85 * For a complete description of the Fast ECC at TL>0 handling see the
86 * comment block "Cheetah/Cheetah+ Fast ECC at TL>0 trap strategy" in
87 * us3_common_asm.s
88 */
89 #if defined(lint)
90
91 void
92 fast_ecc_tl1_err(void)
93 {}
94
95 #else /* lint */
96
97 .section ".text"
98 .align 64
99 ENTRY_NP(fast_ecc_tl1_err)
100
101 /*
102 * This macro turns off the D$/I$ if they are on and saves their
103 * original state in ch_err_tl1_tmp, saves all the %g registers in the
104 * ch_err_tl1_data structure, updates the ch_err_tl1_flags and saves
105 * the %tpc in ch_err_tl1_tpc. At the end of this macro, %g1 will
106 * point to the ch_err_tl1_data structure and the original D$/I$ state
107 * will be saved in ch_err_tl1_tmp. All %g registers except for %g1
108 * will be available.
109 */
110 CH_ERR_TL1_FECC_ENTER;
111
112 /*
113 * Get the diagnostic logout data. %g4 must be initialized to
114 * current CEEN state, %g5 must point to logout structure in
115 * ch_err_tl1_data_t. %g3 will contain the nesting count upon
116 * return.
295 btst %g4, %g3 ! WDU in original or current AFSR?
296 bnz %xcc, fecc_tl1_err
297 nop
298
299 6:
300 /*
301 * We fall into this macro if we've successfully logged the error in
302 * the ch_err_tl1_data structure and want the PIL15 softint to pick
303 * it up and log it. %g1 must point to the ch_err_tl1_data structure.
304 * Restores the %g registers and issues retry.
305 */
306 CH_ERR_TL1_EXIT;
307
308 /*
309 * Establish panic exit label.
310 */
311 CH_ERR_TL1_PANIC_EXIT(fecc_tl1_err);
312
313 SET_SIZE(fast_ecc_tl1_err)
314
315 #endif /* lint */
316
317
318 #if defined(lint)
319 /*
320 * scrubphys - Pass in the aligned physical memory address
321 * that you want to scrub, along with the ecache set size.
322 *
323 * 1) Displacement flush the E$ line corresponding to %addr.
324 * The first ldxa guarantees that the %addr is no longer in
325 * M, O, or E (goes to I or S (if instruction fetch also happens).
326 * 2) "Write" the data using a CAS %addr,%g0,%g0.
327 * The casxa guarantees a transition from I to M or S to M.
328 * 3) Displacement flush the E$ line corresponding to %addr.
329 * The second ldxa pushes the M line out of the ecache, into the
330 * writeback buffers, on the way to memory.
331 * 4) The "membar #Sync" pushes the cache line out of the writeback
332 * buffers onto the bus, on the way to dram finally.
333 *
334 * This is a modified version of the algorithm suggested by Gary Lauterbach.
335 * In theory the CAS %addr,%g0,%g0 is supposed to mark the addr's cache line
336 * as modified, but then we found out that for spitfire, if it misses in the
337 * E$ it will probably install as an M, but if it hits in the E$, then it
338 * will stay E, if the store doesn't happen. So the first displacement flush
339 * should ensure that the CAS will miss in the E$. Arrgh.
340 */
341 /* ARGSUSED */
342 void
343 scrubphys(uint64_t paddr, int ecache_set_size)
344 {}
345
346 #else /* lint */
347 ENTRY(scrubphys)
348 rdpr %pstate, %o4
349 andn %o4, PSTATE_IE | PSTATE_AM, %o5
350 wrpr %o5, %g0, %pstate ! clear IE, AM bits
351
352 ECACHE_FLUSH_LINE(%o0, %o1, %o2, %o3)
353 casxa [%o0]ASI_MEM, %g0, %g0
354 ECACHE_REFLUSH_LINE(%o1, %o2, %o3)
355
356 wrpr %g0, %o4, %pstate ! restore earlier pstate register value
357
358 retl
359 membar #Sync ! move the data out of the load buffer
360 SET_SIZE(scrubphys)
361
362 #endif /* lint */
363
364
365 #if defined(lint)
366 /*
367 * clearphys - Pass in the physical memory address of the checkblock
368 * that you want to push out, cleared with a recognizable pattern,
369 * from the ecache.
370 *
371 * To ensure that the ecc gets recalculated after the bad data is cleared,
372 * we must write out enough data to fill the w$ line (64 bytes). So we read
373 * in an entire ecache subblock's worth of data, and write it back out.
374 * Then we overwrite the 16 bytes of bad data with the pattern.
375 */
376 /* ARGSUSED */
377 void
378 clearphys(uint64_t paddr, int ecache_set_size, int ecache_linesize)
379 {
380 }
381
382 #else /* lint */
383 ENTRY(clearphys)
384 /* turn off IE, AM bits */
385 rdpr %pstate, %o4
386 andn %o4, PSTATE_IE | PSTATE_AM, %o5
387 wrpr %o5, %g0, %pstate
388
389 /* turn off NCEEN */
390 ldxa [%g0]ASI_ESTATE_ERR, %o5
391 andn %o5, EN_REG_NCEEN, %o3
392 stxa %o3, [%g0]ASI_ESTATE_ERR
393 membar #Sync
394
395 /* align address passed with 64 bytes subblock size */
396 mov CH_ECACHE_SUBBLK_SIZE, %o2
397 andn %o0, (CH_ECACHE_SUBBLK_SIZE - 1), %g1
398
399 /* move the good data into the W$ */
400 1:
401 subcc %o2, 8, %o2
402 ldxa [%g1 + %o2]ASI_MEM, %g2
410 stxa %g2, [%o0 + %g1]ASI_MEM
411
412 ECACHE_FLUSH_LINE(%o0, %o1, %o2, %o3)
413 casxa [%o0]ASI_MEM, %g0, %g0
414 ECACHE_REFLUSH_LINE(%o1, %o2, %o3)
415
416 /* clear the AFSR */
417 ldxa [%g0]ASI_AFSR, %o1
418 stxa %o1, [%g0]ASI_AFSR
419 membar #Sync
420
421 /* turn NCEEN back on */
422 stxa %o5, [%g0]ASI_ESTATE_ERR
423 membar #Sync
424
425 /* return and re-enable IE and AM */
426 retl
427 wrpr %g0, %o4, %pstate
428 SET_SIZE(clearphys)
429
430 #endif /* lint */
431
432
433 #if defined(lint)
434 /*
435 * Cheetah Ecache displacement flush the specified line from the E$
436 *
437 * Register usage:
438 * %o0 - 64 bit physical address for flushing
439 * %o1 - Ecache set size
440 */
441 /*ARGSUSED*/
442 void
443 ecache_flush_line(uint64_t flushaddr, int ec_set_size)
444 {
445 }
446 #else /* lint */
447 ENTRY(ecache_flush_line)
448
449 ECACHE_FLUSH_LINE(%o0, %o1, %o2, %o3)
450
451 retl
452 nop
453 SET_SIZE(ecache_flush_line)
454 #endif /* lint */
455
456
457 #if defined(lint)
458 /*
459 * This routine will not be called in Cheetah systems.
460 */
461 void
462 flush_ipb(void)
463 { return; }
464
465 #else /* lint */
466
467 ENTRY(flush_ipb)
468 retl
469 nop
470 SET_SIZE(flush_ipb)
471
472 #endif /* lint */
|
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 *
26 * Assembly code support for the Cheetah module
27 */
28
29 #include "assym.h"
30
31 #include <sys/asm_linkage.h>
32 #include <sys/mmu.h>
33 #include <vm/hat_sfmmu.h>
34 #include <sys/machparam.h>
35 #include <sys/machcpuvar.h>
36 #include <sys/machthread.h>
37 #include <sys/machtrap.h>
38 #include <sys/privregs.h>
39 #include <sys/asm_linkage.h>
40 #include <sys/trap.h>
41 #include <sys/cheetahregs.h>
42 #include <sys/us3_module.h>
43 #include <sys/xc_impl.h>
44 #include <sys/intreg.h>
45 #include <sys/async.h>
46 #include <sys/clock.h>
47 #include <sys/cheetahasm.h>
48
49 #ifdef TRAPTRACE
50 #include <sys/traptrace.h>
51 #endif /* TRAPTRACE */
52
53 /* BEGIN CSTYLED */
54
55 /*
56 * Cheetah version to flush an Ecache line by index (aliased address)
57 */
58 #define ECACHE_REFLUSH_LINE(ecache_size, alias_address, scr2) \
59 ldxa [alias_address]ASI_MEM, %g0
60
61 #define ECACHE_FLUSH_LINE(physaddr, ecache_size, scr1, scr2) \
62 xor physaddr, ecache_size, scr1; \
63 add ecache_size, ecache_size, scr2; \
64 sub scr2, 1, scr2; \
65 and scr1, scr2, scr1; \
66 ASM_LDX(scr2, ecache_flushaddr); \
67 add scr1, scr2, scr1; \
68 ECACHE_REFLUSH_LINE(ecache_size, scr1, scr2)
69
70 /* END CSTYLED */
71
72
73 /*
74 * Fast ECC error at TL>0 handler
75 * We get here via trap 70 at TL>0->Software trap 0 at TL>0. We enter
76 * this routine with %g1 and %g2 already saved in %tpc, %tnpc and %tstate.
77 * For a complete description of the Fast ECC at TL>0 handling see the
78 * comment block "Cheetah/Cheetah+ Fast ECC at TL>0 trap strategy" in
79 * us3_common_asm.s
80 */
81
82 .section ".text"
83 .align 64
84 ENTRY_NP(fast_ecc_tl1_err)
85
86 /*
87 * This macro turns off the D$/I$ if they are on and saves their
88 * original state in ch_err_tl1_tmp, saves all the %g registers in the
89 * ch_err_tl1_data structure, updates the ch_err_tl1_flags and saves
90 * the %tpc in ch_err_tl1_tpc. At the end of this macro, %g1 will
91 * point to the ch_err_tl1_data structure and the original D$/I$ state
92 * will be saved in ch_err_tl1_tmp. All %g registers except for %g1
93 * will be available.
94 */
95 CH_ERR_TL1_FECC_ENTER;
96
97 /*
98 * Get the diagnostic logout data. %g4 must be initialized to
99 * current CEEN state, %g5 must point to logout structure in
100 * ch_err_tl1_data_t. %g3 will contain the nesting count upon
101 * return.
280 btst %g4, %g3 ! WDU in original or current AFSR?
281 bnz %xcc, fecc_tl1_err
282 nop
283
284 6:
285 /*
286 * We fall into this macro if we've successfully logged the error in
287 * the ch_err_tl1_data structure and want the PIL15 softint to pick
288 * it up and log it. %g1 must point to the ch_err_tl1_data structure.
289 * Restores the %g registers and issues retry.
290 */
291 CH_ERR_TL1_EXIT;
292
293 /*
294 * Establish panic exit label.
295 */
296 CH_ERR_TL1_PANIC_EXIT(fecc_tl1_err);
297
298 SET_SIZE(fast_ecc_tl1_err)
299
300
301 ENTRY(scrubphys)
302 rdpr %pstate, %o4
303 andn %o4, PSTATE_IE | PSTATE_AM, %o5
304 wrpr %o5, %g0, %pstate ! clear IE, AM bits
305
306 ECACHE_FLUSH_LINE(%o0, %o1, %o2, %o3)
307 casxa [%o0]ASI_MEM, %g0, %g0
308 ECACHE_REFLUSH_LINE(%o1, %o2, %o3)
309
310 wrpr %g0, %o4, %pstate ! restore earlier pstate register value
311
312 retl
313 membar #Sync ! move the data out of the load buffer
314 SET_SIZE(scrubphys)
315
316
317 ENTRY(clearphys)
318 /* turn off IE, AM bits */
319 rdpr %pstate, %o4
320 andn %o4, PSTATE_IE | PSTATE_AM, %o5
321 wrpr %o5, %g0, %pstate
322
323 /* turn off NCEEN */
324 ldxa [%g0]ASI_ESTATE_ERR, %o5
325 andn %o5, EN_REG_NCEEN, %o3
326 stxa %o3, [%g0]ASI_ESTATE_ERR
327 membar #Sync
328
329 /* align address passed with 64 bytes subblock size */
330 mov CH_ECACHE_SUBBLK_SIZE, %o2
331 andn %o0, (CH_ECACHE_SUBBLK_SIZE - 1), %g1
332
333 /* move the good data into the W$ */
334 1:
335 subcc %o2, 8, %o2
336 ldxa [%g1 + %o2]ASI_MEM, %g2
344 stxa %g2, [%o0 + %g1]ASI_MEM
345
346 ECACHE_FLUSH_LINE(%o0, %o1, %o2, %o3)
347 casxa [%o0]ASI_MEM, %g0, %g0
348 ECACHE_REFLUSH_LINE(%o1, %o2, %o3)
349
350 /* clear the AFSR */
351 ldxa [%g0]ASI_AFSR, %o1
352 stxa %o1, [%g0]ASI_AFSR
353 membar #Sync
354
355 /* turn NCEEN back on */
356 stxa %o5, [%g0]ASI_ESTATE_ERR
357 membar #Sync
358
359 /* return and re-enable IE and AM */
360 retl
361 wrpr %g0, %o4, %pstate
362 SET_SIZE(clearphys)
363
364
365 ENTRY(ecache_flush_line)
366
367 ECACHE_FLUSH_LINE(%o0, %o1, %o2, %o3)
368
369 retl
370 nop
371 SET_SIZE(ecache_flush_line)
372
373
374 ENTRY(flush_ipb)
375 retl
376 nop
377 SET_SIZE(flush_ipb)
378
|