xref: /titanic_41/usr/src/uts/sun4u/io/panther_asm.s (revision 43b9c05035ac59f7f7a8e7827598db5a15f30ed3)
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;					\
841:									\
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;						\
906:									\
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;					\
962:									\
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*/
135int
136retire_l2(uint64_t tag_addr, uint64_t pattern)
137{return 0;}
138
139#else
140	.align 4096
141	ENTRY(retire_l2)
142retire_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
1588:
159	PN_ECACHE_FLUSH_LINE(%o0, %o3, %o4, %g2, %g3)
1601:
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
1701:
171	brnz,pt	%o1, 1b
172	 dec	%o1
1739:
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
1842:
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
198retire_l2_end:
199	SET_SIZE(retire_l2)
200
201#endif	/* lint */
202
203#if defined(lint)
204
205/*
206 */
207/*ARGSUSED*/
208int
209unretire_l2(uint64_t tag_addr, uint64_t pattern)
210{return 0;}
211
212#else
213	ENTRY(unretire_l2)
214unretire_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)
2311:
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
2431:
244	brnz,pt	%o1, 1b
245	 dec	%o1
2469:
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
257unretire_l2_end:
258	SET_SIZE(unretire_l2)
259
260#endif	/* lint */
261
262#if defined(lint)
263
264/*ARGSUSED*/
265int
266retire_l3(uint64_t tag_addr, uint64_t pattern)
267{return 0;}
268
269#else
270	ENTRY(retire_l3)
271retire_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)
2891:
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
3001:
301	brnz,pt	%o1, 1b
302	 dec	%o1
3039:
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
3142:
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
323retire_l3_end:
324	SET_SIZE(retire_l3)
325
326#endif	/* lint */
327
328#if defined(lint)
329
330/*
331 */
332/*ARGSUSED*/
333int
334unretire_l3(uint64_t tag_addr, uint64_t pattern)
335{return 0;}
336
337#else
338	ENTRY(unretire_l3)
339unretire_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)
3561:
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
3681:
369	brnz,pt	%o1, 1b
370	 dec	%o1
3719:
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
382unretire_l3_end:
383	SET_SIZE(unretire_l3)
384
385#endif	/* lint */
386
387#if defined(lint)
388
389/*ARGSUSED*/
390int
391retire_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
4138:
414	PN_ECACHE_FLUSH_LINE(%o0, %o3, %o4, %g2, %g3)
4151:
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
4251:
426	brnz,pt	%o1, 1b
427	 dec	%o1
4289:
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
4392:
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*/
462int
463unretire_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)
4841:
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
4961:
497	brnz,pt	%o1, 1b
498	 dec	%o1
4999:
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*/
517int
518retire_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)
5401:
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
5511:
552	brnz,pt	%o1, 1b
553	 dec	%o1
5549:
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
5652:
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*/
583int
584unretire_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)
6051:
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
6171:
618	brnz,pt	%o1, 1b
619	 dec	%o1
6209:
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*/
638void
639get_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*/
661void
662get_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*/
681void
682get_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
699