1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 *
25 * Assembly code support for the Cheetah+ module
26 */
27
28 #pragma ident "%Z%%M% %I% %E% SMI"
29
30 #if !defined(lint)
31 #include "assym.h"
32 #endif /* lint */
33
34 #include <sys/asm_linkage.h>
35 #include <sys/mmu.h>
36 #include <vm/hat_sfmmu.h>
37 #include <sys/machparam.h>
38 #include <sys/machcpuvar.h>
39 #include <sys/machthread.h>
40 #include <sys/machtrap.h>
41 #include <sys/privregs.h>
42 #include <sys/asm_linkage.h>
43 #include <sys/trap.h>
44 #include <sys/cheetahregs.h>
45 #include <sys/xc_impl.h>
46 #include <sys/intreg.h>
47 #include <sys/async.h>
48 #include <sys/clock.h>
49 #include <sys/cheetahasm.h>
50 #include <sys/cmpregs.h>
51
52 #ifdef TRAPTRACE
53 #include <sys/traptrace.h>
54 #endif /* TRAPTRACE */
55
56
57 #if !defined(lint)
58
59 .global retire_l2_start
60 .global retire_l2_end
61 .global unretire_l2_start
62 .global unretire_l2_end
63 .global retire_l3_start
64 .global retire_l3_end
65 .global unretire_l3_start
66 .global unretire_l3_end
67
68 /*
69 * Panther version to reflush a line from both the L2 cache and L3
70 * cache by the respective indexes. Flushes all ways of the line from
71 * each cache.
72 *
73 * l2_index Index into the L2$ of the line to be flushed. This
74 * register will not be modified by this routine.
75 * l3_index Index into the L3$ of the line to be flushed. This
76 * register will not be modified by this routine.
77 * scr2 scratch register.
78 * scr3 scratch register.
79 *
80 */
81 #define PN_ECACHE_REFLUSH_LINE(l2_index, l3_index, scr2, scr3) \
82 set PN_L2_MAX_SET, scr2; \
83 set PN_L2_SET_SIZE, scr3; \
84 1: \
85 ldxa [l2_index + scr2]ASI_L2_TAG, %g0; \
86 cmp scr2, %g0; \
87 bg,a 1b; \
88 sub scr2, scr3, scr2; \
89 mov 6, scr2; \
90 6: \
91 cmp scr2, %g0; \
92 bg,a 6b; \
93 sub scr2, 1, scr2; \
94 set PN_L3_MAX_SET, scr2; \
95 set PN_L3_SET_SIZE, scr3; \
96 2: \
97 ldxa [l3_index + scr2]ASI_EC_DIAG, %g0; \
98 cmp scr2, %g0; \
99 bg,a 2b; \
100 sub scr2, scr3, scr2;
101
102 /*
103 * Panther version of ecache_flush_line. Flushes the line corresponding
104 * to physaddr from both the L2 cache and the L3 cache.
105 *
106 * physaddr Input: Physical address to flush.
107 * Output: Physical address to flush (preserved).
108 * l2_idx_out Input: scratch register.
109 * Output: Index into the L2$ of the line to be flushed.
110 * l3_idx_out Input: scratch register.
111 * Output: Index into the L3$ of the line to be flushed.
112 * scr3 scratch register.
113 * scr4 scratch register.
114 *
115 */
116 #define PN_ECACHE_FLUSH_LINE(physaddr, l2_idx_out, l3_idx_out, scr3, scr4) \
117 set PN_L3_SET_SIZE, l2_idx_out; \
118 sub l2_idx_out, 1, l2_idx_out; \
119 and physaddr, l2_idx_out, l3_idx_out; \
120 set PN_L3_IDX_DISP_FLUSH, l2_idx_out; \
121 or l2_idx_out, l3_idx_out, l3_idx_out; \
122 set PN_L2_SET_SIZE, l2_idx_out; \
123 sub l2_idx_out, 1, l2_idx_out; \
124 and physaddr, l2_idx_out, l2_idx_out; \
125 set PN_L2_IDX_DISP_FLUSH, scr3; \
126 or l2_idx_out, scr3, l2_idx_out; \
127 PN_ECACHE_REFLUSH_LINE(l2_idx_out, l3_idx_out, scr3, scr4)
128
129
130 #endif /* !lint */
131
132 #if defined(lint)
133
134 /*ARGSUSED*/
135 int
136 retire_l2(uint64_t tag_addr, uint64_t pattern)
137 {return 0;}
138
139 #else
140 .align 4096
141 ENTRY(retire_l2)
142 retire_l2_start:
143
144 ! since we disable interrupts, we don't need to do kpreempt_disable()
145 rdpr %pstate, %o2
146 andn %o2, PSTATE_IE, %g1
147 wrpr %g0, %g1, %pstate ! disable interrupts
148 /*
149 * Save current DCU state. Turn off IPS
150 */
151 setx DCU_IPS_MASK, %g2, %o3
152 ldxa [%g0]ASI_DCU, %g1 ! save DCU in %g1
153 andn %g1, %o3, %g4
154 stxa %g4, [%g0]ASI_DCU
155 flush %g0
156 PARK_SIBLING_CORE(%g1, %o3, %o4) ! %g1 has DCU value
157 clr %o5 ! assume success
158 8:
159 PN_ECACHE_FLUSH_LINE(%o0, %o3, %o4, %g2, %g3)
160 1:
161 ! Check if line is invalid; if so, NA it.
162 ldxa [%o0]ASI_L2_TAG, %o3
163 btst 0x7, %o3
164 bnz %xcc, 2f
165 nop
166 stxa %o1, [%o0]ASI_L2_TAG
167 membar #Sync ! still on same cache line
168 ! now delay 15 cycles so we don't have hazard when we return
169 mov 16, %o1
170 1:
171 brnz,pt %o1, 1b
172 dec %o1
173 9:
174 ! UNPARK-SIBLING_CORE is 7 instructions, so we cross a cache boundary
175 UNPARK_SIBLING_CORE(%g1, %o3, %o4) ! 7 instructions
176 /*
177 * Restore the DCU
178 */
179 stxa %g1, [%g0]ASI_DCU
180 flush %g0
181 wrpr %g0, %o2, %pstate !restore pstate
182 retl
183 mov %o5, %o0
184 2:
185 ! It is OK to have STATE as NA (if so, nothing to do!)
186 and %o3, 0x7, %o3
187 cmp %o3, 0x5
188 be,a,pt %xcc, 9b
189 mov 1, %o5 ! indicate was already NA
190 ! Hmm. Not INV, not NA.
191 cmp %o5, 0
192 be,a,pt %xcc, 8b ! Flush the cacheline again
193 mov 2, %o5 ! indicate retry was done
194 ! We already Flushed cacheline second time. Return -1
195 clr %o5
196 ba 9b
197 dec %o5
198 retire_l2_end:
199 SET_SIZE(retire_l2)
200
201 #endif /* lint */
202
203 #if defined(lint)
204
205 /*
206 */
207 /*ARGSUSED*/
208 int
209 unretire_l2(uint64_t tag_addr, uint64_t pattern)
210 {return 0;}
211
212 #else
213 ENTRY(unretire_l2)
214 unretire_l2_start:
215
216 ! since we disable interrupts, we don't need to do kpreempt_disable()
217 rdpr %pstate, %o2
218 andn %o2, PSTATE_IE, %g1
219 wrpr %g0, %g1, %pstate ! disable interrupts
220 /*
221 * Save current DCU state. Turn off IPS
222 */
223 setx DCU_IPS_MASK, %g2, %o3
224 ldxa [%g0]ASI_DCU, %g1 ! save DCU in %g1
225 andn %g1, %o3, %g4
226 stxa %g4, [%g0]ASI_DCU
227 flush %g0 /* flush required after changing the IC bit */
228 PARK_SIBLING_CORE(%g1, %o3, %o4) ! %g1 has DCU value
229
230 PN_ECACHE_FLUSH_LINE(%o0, %o3, %o4, %o5, %g2)
231 1:
232 clr %o5 ! assume success
233 ! Check that line is in NA state; if so, INV it.
234 ldxa [%o0]ASI_L2_TAG, %o3
235 and %o3, 0x7, %o3
236 cmp %o3, 0x5
237 bne,a,pt %xcc, 9f ! Wasn't NA, so something is wrong
238 dec %o5 ! indicate not NA
239 stxa %g0, [%o0]ASI_L2_TAG
240 membar #Sync
241 ! now delay 15 cycles so we don't have hazard when we return
242 mov 16, %o1
243 1:
244 brnz,pt %o1, 1b
245 dec %o1
246 9:
247 ! UNPARK-SIBLING_CORE is 7 instructions
248 UNPARK_SIBLING_CORE(%g1, %o3, %o4) ! 7 instructions
249 /*
250 * Restore the DCU
251 */
252 stxa %g1, [%g0]ASI_DCU
253 flush %g0
254 wrpr %g0, %o2, %pstate !restore pstate
255 retl
256 mov %o5, %o0
257 unretire_l2_end:
258 SET_SIZE(unretire_l2)
259
260 #endif /* lint */
261
262 #if defined(lint)
263
264 /*ARGSUSED*/
265 int
266 retire_l3(uint64_t tag_addr, uint64_t pattern)
267 {return 0;}
268
269 #else
270 ENTRY(retire_l3)
271 retire_l3_start:
272
273 ! since we disable interrupts, we don't need to do kpreempt_disable()
274 rdpr %pstate, %o2
275 andn %o2, PSTATE_IE, %g1
276 wrpr %g0, %g1, %pstate ! disable interrupts
277 /*
278 * Save current DCU state. Turn off IPS
279 */
280 setx DCU_IPS_MASK, %g2, %o3
281 ldxa [%g0]ASI_DCU, %g1 ! save DCU in %g1
282 andn %g1, %o3, %g4
283 stxa %g4, [%g0]ASI_DCU
284 flush %g0 /* flush required after changing the IC bit */
285 PARK_SIBLING_CORE(%g1, %o3, %o4) ! %g1 has DCU value
286
287 ! PN-ECACHE-FLUSH_LINE is 30 instructions
288 PN_ECACHE_FLUSH_LINE(%o0, %o3, %o4, %o5, %g2)
289 1:
290 clr %o5 ! assume success
291 ! Check if line is invalid; if so, NA it.
292 ldxa [%o0]ASI_EC_DIAG, %o3
293 btst 0x7, %o3
294 bnz %xcc, 2f
295 nop
296 stxa %o1, [%o0]ASI_EC_DIAG
297 membar #Sync ! still on same cache line
298 ! now delay 15 cycles so we don't have hazard when we return
299 mov 16, %o1
300 1:
301 brnz,pt %o1, 1b
302 dec %o1
303 9:
304 ! UNPARK-SIBLING_CORE is 7 instructions, so we cross a cache boundary
305 UNPARK_SIBLING_CORE(%g1, %o3, %o4) ! 7 instructions
306 /*
307 * Restore the DCU
308 */
309 stxa %g1, [%g0]ASI_DCU
310 flush %g0
311 wrpr %g0, %o2, %pstate !restore pstate
312 retl
313 mov %o5, %o0
314 2:
315 ! It is OK to have STATE as NA (if so, nothing to do!)
316 and %o3, 0x7, %o3
317 cmp %o3, 0x5
318 be,a,pt %xcc, 9b
319 inc %o5 ! indicate was already NA
320 ! Hmm. Not INV, not NA
321 ba 9b
322 dec %o5
323 retire_l3_end:
324 SET_SIZE(retire_l3)
325
326 #endif /* lint */
327
328 #if defined(lint)
329
330 /*
331 */
332 /*ARGSUSED*/
333 int
334 unretire_l3(uint64_t tag_addr, uint64_t pattern)
335 {return 0;}
336
337 #else
338 ENTRY(unretire_l3)
339 unretire_l3_start:
340
341 ! since we disable interrupts, we don't need to do kpreempt_disable()
342 rdpr %pstate, %o2
343 andn %o2, PSTATE_IE, %g1
344 wrpr %g0, %g1, %pstate ! disable interrupts
345 /*
346 * Save current DCU state. Turn off IPS
347 */
348 setx DCU_IPS_MASK, %g2, %o3
349 ldxa [%g0]ASI_DCU, %g1 ! save DCU in %g1
350 andn %g1, %o3, %g4
351 stxa %g4, [%g0]ASI_DCU
352 flush %g0 /* flush required after changing the IC bit */
353 PARK_SIBLING_CORE(%g1, %o3, %o4) ! %g1 has DCU value
354
355 PN_ECACHE_FLUSH_LINE(%o0, %o3, %o4, %o5, %g2)
356 1:
357 clr %o5 ! assume success
358 ! Check that line is in NA state; if so, INV it.
359 ldxa [%o0]ASI_EC_DIAG, %o3
360 and %o3, 0x7, %o3
361 cmp %o3, 0x5
362 bne,a,pt %xcc, 9f ! Wasn't NA, so something is wrong
363 dec %o5 ! indicate not NA
364 stxa %g0, [%o0]ASI_EC_DIAG
365 membar #Sync
366 ! now delay 15 cycles so we don't have hazard when we return
367 mov 16, %o1
368 1:
369 brnz,pt %o1, 1b
370 dec %o1
371 9:
372 ! UNPARK-SIBLING_CORE is 7 instructions
373 UNPARK_SIBLING_CORE(%g1, %o3, %o4) ! 7 instructions
374 /*
375 * Restore the DCU
376 */
377 stxa %g1, [%g0]ASI_DCU
378 flush %g0
379 wrpr %g0, %o2, %pstate !restore pstate
380 retl
381 mov %o5, %o0
382 unretire_l3_end:
383 SET_SIZE(unretire_l3)
384
385 #endif /* lint */
386
387 #if defined(lint)
388
389 /*ARGSUSED*/
390 int
391 retire_l2_alternate(uint64_t tag_addr, uint64_t pattern)
392 {return 0;}
393
394 #else
395 .align 2048
396
397 ENTRY(retire_l2_alternate)
398
399 ! since we disable interrupts, we don't need to do kpreempt_disable()
400 rdpr %pstate, %o2
401 andn %o2, PSTATE_IE, %g1
402 wrpr %g0, %g1, %pstate ! disable interrupts
403 /*
404 * Save current DCU state. Turn off IPS
405 */
406 setx DCU_IPS_MASK, %g2, %o3
407 ldxa [%g0]ASI_DCU, %g1 ! save DCU in %g1
408 andn %g1, %o3, %g4
409 stxa %g4, [%g0]ASI_DCU
410 flush %g0
411 PARK_SIBLING_CORE(%g1, %o3, %o4) ! %g1 has DCU value
412 clr %o5 ! assume success
413 8:
414 PN_ECACHE_FLUSH_LINE(%o0, %o3, %o4, %g2, %g3)
415 1:
416 ! Check if line is invalid; if so, NA it.
417 ldxa [%o0]ASI_L2_TAG, %o3
418 btst 0x7, %o3
419 bnz %xcc, 2f
420 nop
421 stxa %o1, [%o0]ASI_L2_TAG
422 membar #Sync ! still on same cache line
423 ! now delay 15 cycles so we don't have hazard when we return
424 mov 16, %o1
425 1:
426 brnz,pt %o1, 1b
427 dec %o1
428 9:
429 ! UNPARK-SIBLING_CORE is 7 instructions, so we cross a cache boundary
430 UNPARK_SIBLING_CORE(%g1, %o3, %o4) ! 7 instructions
431 /*
432 * Restore the DCU
433 */
434 stxa %g1, [%g0]ASI_DCU
435 flush %g0
436 wrpr %g0, %o2, %pstate !restore pstate
437 retl
438 mov %o5, %o0
439 2:
440 ! It is OK to have STATE as NA (if so, nothing to do!)
441 and %o3, 0x7, %o3
442 cmp %o3, 0x5
443 be,a,pt %xcc, 9b
444 mov 1, %o5 ! indicate was already NA
445 ! Hmm. Not INV, not NA.
446 cmp %o5, 0
447 be,a,pt %xcc, 8b ! Flush the cacheline again
448 mov 2, %o5 ! indicate retry was done
449 ! We already Flushed cacheline second time. Return -1
450 clr %o5
451 ba 9b
452 dec %o5
453 SET_SIZE(retire_l2_alternate)
454
455 #endif /* lint */
456
457 #if defined(lint)
458
459 /*
460 */
461 /*ARGSUSED*/
462 int
463 unretire_l2_alternate(uint64_t tag_addr, uint64_t pattern)
464 {return 0;}
465
466 #else
467 ENTRY(unretire_l2_alternate)
468
469 ! since we disable interrupts, we don't need to do kpreempt_disable()
470 rdpr %pstate, %o2
471 andn %o2, PSTATE_IE, %g1
472 wrpr %g0, %g1, %pstate ! disable interrupts
473 /*
474 * Save current DCU state. Turn off IPS
475 */
476 setx DCU_IPS_MASK, %g2, %o3
477 ldxa [%g0]ASI_DCU, %g1 ! save DCU in %g1
478 andn %g1, %o3, %g4
479 stxa %g4, [%g0]ASI_DCU
480 flush %g0 /* flush required after changing the IC bit */
481 PARK_SIBLING_CORE(%g1, %o3, %o4) ! %g1 has DCU value
482
483 PN_ECACHE_FLUSH_LINE(%o0, %o3, %o4, %o5, %g2)
484 1:
485 clr %o5 ! assume success
486 ! Check that line is in NA state; if so, INV it.
487 ldxa [%o0]ASI_L2_TAG, %o3
488 and %o3, 0x7, %o3
489 cmp %o3, 0x5
490 bne,a,pt %xcc, 9f ! Wasn't NA, so something is wrong
491 dec %o5 ! indicate not NA
492 stxa %g0, [%o0]ASI_L2_TAG
493 membar #Sync
494 ! now delay 15 cycles so we don't have hazard when we return
495 mov 16, %o1
496 1:
497 brnz,pt %o1, 1b
498 dec %o1
499 9:
500 ! UNPARK-SIBLING_CORE is 7 instructions
501 UNPARK_SIBLING_CORE(%g1, %o3, %o4) ! 7 instructions
502 /*
503 * Restore the DCU
504 */
505 stxa %g1, [%g0]ASI_DCU
506 flush %g0
507 wrpr %g0, %o2, %pstate !restore pstate
508 retl
509 mov %o5, %o0
510 SET_SIZE(unretire_l2_alternate)
511
512 #endif /* lint */
513
514 #if defined(lint)
515
516 /*ARGSUSED*/
517 int
518 retire_l3_alternate(uint64_t tag_addr, uint64_t pattern)
519 {return 0;}
520
521 #else
522 ENTRY(retire_l3_alternate)
523
524 ! since we disable interrupts, we don't need to do kpreempt_disable()
525 rdpr %pstate, %o2
526 andn %o2, PSTATE_IE, %g1
527 wrpr %g0, %g1, %pstate ! disable interrupts
528 /*
529 * Save current DCU state. Turn off IPS
530 */
531 setx DCU_IPS_MASK, %g2, %o3
532 ldxa [%g0]ASI_DCU, %g1 ! save DCU in %g1
533 andn %g1, %o3, %g4
534 stxa %g4, [%g0]ASI_DCU
535 flush %g0 /* flush required after changing the IC bit */
536 PARK_SIBLING_CORE(%g1, %o3, %o4) ! %g1 has DCU value
537
538 ! PN-ECACHE-FLUSH_LINE is 30 instructions
539 PN_ECACHE_FLUSH_LINE(%o0, %o3, %o4, %o5, %g2)
540 1:
541 clr %o5 ! assume success
542 ! Check if line is invalid; if so, NA it.
543 ldxa [%o0]ASI_EC_DIAG, %o3
544 btst 0x7, %o3
545 bnz %xcc, 2f
546 nop
547 stxa %o1, [%o0]ASI_EC_DIAG
548 membar #Sync ! still on same cache line
549 ! now delay 15 cycles so we don't have hazard when we return
550 mov 16, %o1
551 1:
552 brnz,pt %o1, 1b
553 dec %o1
554 9:
555 ! UNPARK-SIBLING_CORE is 7 instructions, so we cross a cache boundary
556 UNPARK_SIBLING_CORE(%g1, %o3, %o4) ! 7 instructions
557 /*
558 * Restore the DCU
559 */
560 stxa %g1, [%g0]ASI_DCU
561 flush %g0
562 wrpr %g0, %o2, %pstate !restore pstate
563 retl
564 mov %o5, %o0
565 2:
566 ! It is OK to have STATE as NA (if so, nothing to do!)
567 and %o3, 0x7, %o3
568 cmp %o3, 0x5
569 be,a,pt %xcc, 9b
570 inc %o5 ! indicate was already NA
571 ! Hmm. Not INV, not NA
572 ba 9b
573 dec %o5
574 SET_SIZE(retire_l3_alternate)
575
576 #endif /* lint */
577
578 #if defined(lint)
579
580 /*
581 */
582 /*ARGSUSED*/
583 int
584 unretire_l3_alternate(uint64_t tag_addr, uint64_t pattern)
585 {return 0;}
586
587 #else
588 ENTRY(unretire_l3_alternate)
589
590 ! since we disable interrupts, we don't need to do kpreempt_disable()
591 rdpr %pstate, %o2
592 andn %o2, PSTATE_IE, %g1
593 wrpr %g0, %g1, %pstate ! disable interrupts
594 /*
595 * Save current DCU state. Turn off IPS
596 */
597 setx DCU_IPS_MASK, %g2, %o3
598 ldxa [%g0]ASI_DCU, %g1 ! save DCU in %g1
599 andn %g1, %o3, %g4
600 stxa %g4, [%g0]ASI_DCU
601 flush %g0 /* flush required after changing the IC bit */
602 PARK_SIBLING_CORE(%g1, %o3, %o4) ! %g1 has DCU value
603
604 PN_ECACHE_FLUSH_LINE(%o0, %o3, %o4, %o5, %g2)
605 1:
606 clr %o5 ! assume success
607 ! Check that line is in NA state; if so, INV it.
608 ldxa [%o0]ASI_EC_DIAG, %o3
609 and %o3, 0x7, %o3
610 cmp %o3, 0x5
611 bne,a,pt %xcc, 9f ! Wasn't NA, so something is wrong
612 dec %o5 ! indicate not NA
613 stxa %g0, [%o0]ASI_EC_DIAG
614 membar #Sync
615 ! now delay 15 cycles so we don't have hazard when we return
616 mov 16, %o1
617 1:
618 brnz,pt %o1, 1b
619 dec %o1
620 9:
621 ! UNPARK-SIBLING_CORE is 7 instructions
622 UNPARK_SIBLING_CORE(%g1, %o3, %o4) ! 7 instructions
623 /*
624 * Restore the DCU
625 */
626 stxa %g1, [%g0]ASI_DCU
627 flush %g0
628 wrpr %g0, %o2, %pstate !restore pstate
629 retl
630 mov %o5, %o0
631 SET_SIZE(unretire_l3_alternate)
632
633 #endif /* lint */
634
635 #if defined(lint)
636
637 /*ARGSUSED*/
638 void
639 get_ecache_dtags_tl1(uint64_t afar, ch_cpu_logout_t *clop)
640 { }
641
642 #else
643 ENTRY(get_ecache_dtags_tl1)
644
645
646 PARK_SIBLING_CORE(%g3, %g4, %g5)
647 add %g2, CH_CLO_DATA + CH_CHD_EC_DATA, %g2
648 rd %asi, %g4
649 wr %g0, ASI_N, %asi
650 GET_ECACHE_DTAGS(%g1, %g2, %g5, %g6, %g7)
651 wr %g4, %asi
652 UNPARK_SIBLING_CORE(%g3, %g4, %g5) ! can use %g3 again
653
654 retry
655 SET_SIZE(get_ecache_dtags_tl1)
656
657 #endif /* lint */
658
659 #if defined(lint)
660 /*ARGSUSED*/
661 void
662 get_l2_tag_tl1(uint64_t tag_addr, uint64_t tag_data_ptr)
663 { }
664
665 #else
666 ENTRY(get_l2_tag_tl1)
667
668 /*
669 * Now read the tag data
670 */
671 ldxa [%g1]ASI_L2_TAG, %g4 ! save tag_data
672 stx %g4, [%g2]
673
674 retry
675 SET_SIZE(get_l2_tag_tl1)
676
677 #endif /* lint */
678
679 #if defined(lint)
680 /*ARGSUSED*/
681 void
682 get_l3_tag_tl1(uint64_t tag_addr, uint64_t tag_data_ptr)
683 { }
684
685 #else
686 ENTRY(get_l3_tag_tl1)
687
688 /*
689 * Now read the tag data
690 */
691 ldxa [%g1]ASI_EC_DIAG, %g4 ! save tag_data
692 stx %g4, [%g2]
693
694 retry
695 SET_SIZE(get_l3_tag_tl1)
696
697 #endif /* lint */
698