xref: /onnv-gate/usr/src/uts/sun4u/cpu/us3_common_asm.s (revision 10724:46ad20cc31ef)
10Sstevel@tonic-gate/*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
52241Shuah * Common Development and Distribution License (the "License").
62241Shuah * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate/*
22*10724SEthindra.Ramamurthy@Sun.COM * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate *
250Sstevel@tonic-gate * Assembly code support for Cheetah/Cheetah+ modules
260Sstevel@tonic-gate */
270Sstevel@tonic-gate
280Sstevel@tonic-gate#if !defined(lint)
290Sstevel@tonic-gate#include "assym.h"
300Sstevel@tonic-gate#endif	/* !lint */
310Sstevel@tonic-gate
320Sstevel@tonic-gate#include <sys/asm_linkage.h>
330Sstevel@tonic-gate#include <sys/mmu.h>
340Sstevel@tonic-gate#include <vm/hat_sfmmu.h>
350Sstevel@tonic-gate#include <sys/machparam.h>
360Sstevel@tonic-gate#include <sys/machcpuvar.h>
370Sstevel@tonic-gate#include <sys/machthread.h>
380Sstevel@tonic-gate#include <sys/machtrap.h>
390Sstevel@tonic-gate#include <sys/privregs.h>
400Sstevel@tonic-gate#include <sys/trap.h>
410Sstevel@tonic-gate#include <sys/cheetahregs.h>
420Sstevel@tonic-gate#include <sys/us3_module.h>
430Sstevel@tonic-gate#include <sys/xc_impl.h>
440Sstevel@tonic-gate#include <sys/intreg.h>
450Sstevel@tonic-gate#include <sys/async.h>
460Sstevel@tonic-gate#include <sys/clock.h>
470Sstevel@tonic-gate#include <sys/cheetahasm.h>
480Sstevel@tonic-gate#include <sys/cmpregs.h>
490Sstevel@tonic-gate
500Sstevel@tonic-gate#ifdef TRAPTRACE
510Sstevel@tonic-gate#include <sys/traptrace.h>
520Sstevel@tonic-gate#endif /* TRAPTRACE */
530Sstevel@tonic-gate
540Sstevel@tonic-gate#if !defined(lint)
550Sstevel@tonic-gate
560Sstevel@tonic-gate/* BEGIN CSTYLED */
570Sstevel@tonic-gate
580Sstevel@tonic-gate#define	DCACHE_FLUSHPAGE(arg1, arg2, tmp1, tmp2, tmp3)			\
590Sstevel@tonic-gate	ldxa	[%g0]ASI_DCU, tmp1					;\
600Sstevel@tonic-gate	btst	DCU_DC, tmp1		/* is dcache enabled? */	;\
610Sstevel@tonic-gate	bz,pn	%icc, 1f						;\
620Sstevel@tonic-gate	ASM_LD(tmp1, dcache_linesize)					;\
630Sstevel@tonic-gate	ASM_LD(tmp2, dflush_type)					;\
640Sstevel@tonic-gate	cmp	tmp2, FLUSHPAGE_TYPE					;\
650Sstevel@tonic-gate	be,pt	%icc, 2f						;\
660Sstevel@tonic-gate	nop								;\
670Sstevel@tonic-gate	sllx	arg1, CHEETAH_DC_VBIT_SHIFT, arg1/* tag to compare */	;\
680Sstevel@tonic-gate	ASM_LD(tmp3, dcache_size)					;\
690Sstevel@tonic-gate	cmp	tmp2, FLUSHMATCH_TYPE					;\
700Sstevel@tonic-gate	be,pt	%icc, 3f						;\
710Sstevel@tonic-gate	nop								;\
720Sstevel@tonic-gate	/*								\
730Sstevel@tonic-gate	 * flushtype = FLUSHALL_TYPE, flush the whole thing		\
740Sstevel@tonic-gate	 * tmp3 = cache size						\
750Sstevel@tonic-gate	 * tmp1 = cache line size					\
760Sstevel@tonic-gate	 */								\
770Sstevel@tonic-gate	sub	tmp3, tmp1, tmp2					;\
780Sstevel@tonic-gate4:									\
790Sstevel@tonic-gate	stxa	%g0, [tmp2]ASI_DC_TAG					;\
800Sstevel@tonic-gate	membar	#Sync							;\
810Sstevel@tonic-gate	cmp	%g0, tmp2						;\
820Sstevel@tonic-gate	bne,pt	%icc, 4b						;\
830Sstevel@tonic-gate	sub	tmp2, tmp1, tmp2					;\
840Sstevel@tonic-gate	ba,pt	%icc, 1f						;\
850Sstevel@tonic-gate	nop								;\
860Sstevel@tonic-gate	/*								\
870Sstevel@tonic-gate	 * flushtype = FLUSHPAGE_TYPE					\
880Sstevel@tonic-gate	 * arg1 = pfn							\
890Sstevel@tonic-gate	 * arg2 = virtual color						\
900Sstevel@tonic-gate	 * tmp1 = cache line size					\
910Sstevel@tonic-gate	 * tmp2 = tag from cache					\
920Sstevel@tonic-gate	 * tmp3 = counter						\
930Sstevel@tonic-gate	 */								\
940Sstevel@tonic-gate2:									\
950Sstevel@tonic-gate	set	MMU_PAGESIZE, tmp3					;\
960Sstevel@tonic-gate        sllx    arg1, MMU_PAGESHIFT, arg1  /* pfn to 43 bit PA	   */   ;\
970Sstevel@tonic-gate	sub	tmp3, tmp1, tmp3					;\
980Sstevel@tonic-gate4:									\
990Sstevel@tonic-gate	stxa	%g0, [arg1 + tmp3]ASI_DC_INVAL				;\
1000Sstevel@tonic-gate	membar	#Sync							;\
1010Sstevel@tonic-gate5:									\
1020Sstevel@tonic-gate	cmp	%g0, tmp3						;\
1030Sstevel@tonic-gate	bnz,pt	%icc, 4b		/* branch if not done */	;\
1040Sstevel@tonic-gate	sub	tmp3, tmp1, tmp3					;\
1050Sstevel@tonic-gate	ba,pt	%icc, 1f						;\
1060Sstevel@tonic-gate	nop								;\
1070Sstevel@tonic-gate	/*								\
1080Sstevel@tonic-gate	 * flushtype = FLUSHMATCH_TYPE					\
1090Sstevel@tonic-gate	 * arg1 = tag to compare against				\
1100Sstevel@tonic-gate	 * tmp1 = cache line size					\
1110Sstevel@tonic-gate	 * tmp3 = cache size						\
1120Sstevel@tonic-gate	 * arg2 = counter						\
1130Sstevel@tonic-gate	 * tmp2 = cache tag						\
1140Sstevel@tonic-gate	 */								\
1150Sstevel@tonic-gate3:									\
1160Sstevel@tonic-gate	sub	tmp3, tmp1, arg2					;\
1170Sstevel@tonic-gate4:									\
1180Sstevel@tonic-gate	ldxa	[arg2]ASI_DC_TAG, tmp2		/* read tag */		;\
1190Sstevel@tonic-gate	btst	CHEETAH_DC_VBIT_MASK, tmp2				;\
1200Sstevel@tonic-gate	bz,pn	%icc, 5f		/* br if no valid sub-blocks */	;\
1210Sstevel@tonic-gate	andn	tmp2, CHEETAH_DC_VBIT_MASK, tmp2 /* clear out v bits */	;\
1220Sstevel@tonic-gate	cmp	tmp2, arg1						;\
1230Sstevel@tonic-gate	bne,pn	%icc, 5f		/* branch if tag miss */	;\
1240Sstevel@tonic-gate	nop								;\
1250Sstevel@tonic-gate	stxa	%g0, [arg2]ASI_DC_TAG					;\
1260Sstevel@tonic-gate	membar	#Sync							;\
1270Sstevel@tonic-gate5:									\
1280Sstevel@tonic-gate	cmp	%g0, arg2						;\
1290Sstevel@tonic-gate	bne,pt	%icc, 4b		/* branch if not done */	;\
1300Sstevel@tonic-gate	sub	arg2, tmp1, arg2					;\
1310Sstevel@tonic-gate1:
1320Sstevel@tonic-gate
1337393SDonghai.Qiao@Sun.COM/*
1347393SDonghai.Qiao@Sun.COM * macro that flushes the entire dcache color
1357393SDonghai.Qiao@Sun.COM * dcache size = 64K, one way 16K
136*10724SEthindra.Ramamurthy@Sun.COM *
137*10724SEthindra.Ramamurthy@Sun.COM * In:
138*10724SEthindra.Ramamurthy@Sun.COM *    arg = virtual color register (not clobbered)
139*10724SEthindra.Ramamurthy@Sun.COM *    way = way#, can either be a constant or a register (not clobbered)
140*10724SEthindra.Ramamurthy@Sun.COM *    tmp1, tmp2, tmp3 = scratch registers
141*10724SEthindra.Ramamurthy@Sun.COM *
1427393SDonghai.Qiao@Sun.COM */
1437393SDonghai.Qiao@Sun.COM#define DCACHE_FLUSHCOLOR(arg, way, tmp1, tmp2, tmp3)			\
1447393SDonghai.Qiao@Sun.COM	ldxa	[%g0]ASI_DCU, tmp1;					\
1457393SDonghai.Qiao@Sun.COM	btst	DCU_DC, tmp1;		/* is dcache enabled? */	\
1467393SDonghai.Qiao@Sun.COM	bz,pn	%icc, 1f;						\
1477393SDonghai.Qiao@Sun.COM	ASM_LD(tmp1, dcache_linesize)					\
1487393SDonghai.Qiao@Sun.COM	/*								\
1497393SDonghai.Qiao@Sun.COM	 * arg = virtual color						\
1507393SDonghai.Qiao@Sun.COM	 * tmp1 = cache line size					\
1517393SDonghai.Qiao@Sun.COM	 */								\
152*10724SEthindra.Ramamurthy@Sun.COM	sllx	arg, MMU_PAGESHIFT, tmp2; /* color to dcache page */	\
1537393SDonghai.Qiao@Sun.COM	mov	way, tmp3;						\
154*10724SEthindra.Ramamurthy@Sun.COM	sllx	tmp3, 14, tmp3;		  /* One way 16K */		\
155*10724SEthindra.Ramamurthy@Sun.COM	or	tmp2, tmp3, tmp3;					\
156*10724SEthindra.Ramamurthy@Sun.COM	set	MMU_PAGESIZE, tmp2;					\
157*10724SEthindra.Ramamurthy@Sun.COM	/*								\
158*10724SEthindra.Ramamurthy@Sun.COM	 * tmp2 = page size						\
159*10724SEthindra.Ramamurthy@Sun.COM	 * tmp3 =  cached page in dcache				\
160*10724SEthindra.Ramamurthy@Sun.COM	 */								\
1617393SDonghai.Qiao@Sun.COM	sub	tmp2, tmp1, tmp2;					\
1627393SDonghai.Qiao@Sun.COM2:									\
163*10724SEthindra.Ramamurthy@Sun.COM	stxa	%g0, [tmp3 + tmp2]ASI_DC_TAG;				\
1647393SDonghai.Qiao@Sun.COM	membar	#Sync;							\
1657393SDonghai.Qiao@Sun.COM	cmp	%g0, tmp2;						\
1667393SDonghai.Qiao@Sun.COM	bne,pt	%icc, 2b;						\
167*10724SEthindra.Ramamurthy@Sun.COM	sub	tmp2, tmp1, tmp2;					\
1687393SDonghai.Qiao@Sun.COM1:
1690Sstevel@tonic-gate
1700Sstevel@tonic-gate/* END CSTYLED */
1710Sstevel@tonic-gate
1720Sstevel@tonic-gate#endif	/* !lint */
1730Sstevel@tonic-gate
1740Sstevel@tonic-gate/*
1750Sstevel@tonic-gate * Cheetah MMU and Cache operations.
1760Sstevel@tonic-gate */
1770Sstevel@tonic-gate
1780Sstevel@tonic-gate#if defined(lint)
1790Sstevel@tonic-gate
1800Sstevel@tonic-gate/* ARGSUSED */
1810Sstevel@tonic-gatevoid
1822241Shuahvtag_flushpage(caddr_t vaddr, uint64_t sfmmup)
1830Sstevel@tonic-gate{}
1840Sstevel@tonic-gate
1850Sstevel@tonic-gate#else	/* lint */
1860Sstevel@tonic-gate
1870Sstevel@tonic-gate	ENTRY_NP(vtag_flushpage)
1880Sstevel@tonic-gate	/*
1890Sstevel@tonic-gate	 * flush page from the tlb
1900Sstevel@tonic-gate	 *
1910Sstevel@tonic-gate	 * %o0 = vaddr
1922241Shuah	 * %o1 = sfmmup
1930Sstevel@tonic-gate	 */
1940Sstevel@tonic-gate	rdpr	%pstate, %o5
1950Sstevel@tonic-gate#ifdef DEBUG
1962241Shuah	PANIC_IF_INTR_DISABLED_PSTR(%o5, u3_di_label0, %g1)
1970Sstevel@tonic-gate#endif /* DEBUG */
1980Sstevel@tonic-gate	/*
1990Sstevel@tonic-gate	 * disable ints
2000Sstevel@tonic-gate	 */
2010Sstevel@tonic-gate	andn	%o5, PSTATE_IE, %o4
2020Sstevel@tonic-gate	wrpr	%o4, 0, %pstate
2030Sstevel@tonic-gate
2040Sstevel@tonic-gate	/*
2050Sstevel@tonic-gate	 * Then, blow out the tlb
2060Sstevel@tonic-gate	 * Interrupts are disabled to prevent the primary ctx register
2070Sstevel@tonic-gate	 * from changing underneath us.
2080Sstevel@tonic-gate	 */
2092241Shuah	sethi   %hi(ksfmmup), %o3
2102241Shuah        ldx     [%o3 + %lo(ksfmmup)], %o3
2112241Shuah        cmp     %o3, %o1
2122241Shuah        bne,pt   %xcc, 1f			! if not kernel as, go to 1
2132241Shuah	  sethi	%hi(FLUSH_ADDR), %o3
2140Sstevel@tonic-gate	/*
2152241Shuah	 * For Kernel demaps use primary. type = page implicitly
2160Sstevel@tonic-gate	 */
2170Sstevel@tonic-gate	stxa	%g0, [%o0]ASI_DTLB_DEMAP	/* dmmu flush for KCONTEXT */
2180Sstevel@tonic-gate	stxa	%g0, [%o0]ASI_ITLB_DEMAP	/* immu flush for KCONTEXT */
2190Sstevel@tonic-gate	flush	%o3
2202241Shuah	retl
2212241Shuah	  wrpr	%g0, %o5, %pstate		/* enable interrupts */
2220Sstevel@tonic-gate1:
2230Sstevel@tonic-gate	/*
2240Sstevel@tonic-gate	 * User demap.  We need to set the primary context properly.
2250Sstevel@tonic-gate	 * Secondary context cannot be used for Cheetah IMMU.
2260Sstevel@tonic-gate	 * %o0 = vaddr
2272241Shuah	 * %o1 = sfmmup
2280Sstevel@tonic-gate	 * %o3 = FLUSH_ADDR
2290Sstevel@tonic-gate	 */
2302241Shuah	SFMMU_CPU_CNUM(%o1, %g1, %g2)		! %g1 = sfmmu cnum on this CPU
2312241Shuah
2322241Shuah	ldub	[%o1 + SFMMU_CEXT], %o4		! %o4 = sfmmup->sfmmu_cext
2330Sstevel@tonic-gate	sll	%o4, CTXREG_EXT_SHIFT, %o4
2345584Sjimand	or	%g1, %o4, %g1			! %g1 = primary pgsz | cnum
2352241Shuah
2360Sstevel@tonic-gate	wrpr	%g0, 1, %tl
2370Sstevel@tonic-gate	set	MMU_PCONTEXT, %o4
2380Sstevel@tonic-gate	or	DEMAP_PRIMARY | DEMAP_PAGE_TYPE, %o0, %o0
2392241Shuah	ldxa	[%o4]ASI_DMMU, %o2		! %o2 = save old ctxnum
2405584Sjimand	srlx	%o2, CTXREG_NEXT_SHIFT, %o1	! need to preserve nucleus pgsz
2415584Sjimand	sllx	%o1, CTXREG_NEXT_SHIFT, %o1	! %o1 = nucleus pgsz
2425584Sjimand	or	%g1, %o1, %g1			! %g1 = nucleus pgsz | primary pgsz | cnum
2432241Shuah	stxa	%g1, [%o4]ASI_DMMU		! wr new ctxum
2442241Shuah
2450Sstevel@tonic-gate	stxa	%g0, [%o0]ASI_DTLB_DEMAP
2460Sstevel@tonic-gate	stxa	%g0, [%o0]ASI_ITLB_DEMAP
2470Sstevel@tonic-gate	stxa	%o2, [%o4]ASI_DMMU		/* restore old ctxnum */
2480Sstevel@tonic-gate	flush	%o3
2490Sstevel@tonic-gate	wrpr	%g0, 0, %tl
2502241Shuah
2510Sstevel@tonic-gate	retl
2520Sstevel@tonic-gate	wrpr	%g0, %o5, %pstate		/* enable interrupts */
2530Sstevel@tonic-gate	SET_SIZE(vtag_flushpage)
2540Sstevel@tonic-gate
2550Sstevel@tonic-gate#endif	/* lint */
2560Sstevel@tonic-gate
2570Sstevel@tonic-gate#if defined(lint)
2580Sstevel@tonic-gate
2590Sstevel@tonic-gatevoid
2600Sstevel@tonic-gatevtag_flushall(void)
2610Sstevel@tonic-gate{}
2620Sstevel@tonic-gate
2630Sstevel@tonic-gate#else	/* lint */
2640Sstevel@tonic-gate
2650Sstevel@tonic-gate	ENTRY_NP2(vtag_flushall, demap_all)
2660Sstevel@tonic-gate	/*
2670Sstevel@tonic-gate	 * flush the tlb
2680Sstevel@tonic-gate	 */
2690Sstevel@tonic-gate	sethi	%hi(FLUSH_ADDR), %o3
2700Sstevel@tonic-gate	set	DEMAP_ALL_TYPE, %g1
2710Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_DTLB_DEMAP
2720Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_ITLB_DEMAP
2730Sstevel@tonic-gate	flush	%o3
2740Sstevel@tonic-gate	retl
2750Sstevel@tonic-gate	nop
2760Sstevel@tonic-gate	SET_SIZE(demap_all)
2770Sstevel@tonic-gate	SET_SIZE(vtag_flushall)
2780Sstevel@tonic-gate
2790Sstevel@tonic-gate#endif	/* lint */
2800Sstevel@tonic-gate
2810Sstevel@tonic-gate
2820Sstevel@tonic-gate#if defined(lint)
2830Sstevel@tonic-gate
2840Sstevel@tonic-gate/* ARGSUSED */
2850Sstevel@tonic-gatevoid
2862241Shuahvtag_flushpage_tl1(uint64_t vaddr, uint64_t sfmmup)
2870Sstevel@tonic-gate{}
2880Sstevel@tonic-gate
2890Sstevel@tonic-gate#else	/* lint */
2900Sstevel@tonic-gate
2910Sstevel@tonic-gate	ENTRY_NP(vtag_flushpage_tl1)
2920Sstevel@tonic-gate	/*
2930Sstevel@tonic-gate	 * x-trap to flush page from tlb and tsb
2940Sstevel@tonic-gate	 *
2950Sstevel@tonic-gate	 * %g1 = vaddr, zero-extended on 32-bit kernel
2962241Shuah	 * %g2 = sfmmup
2970Sstevel@tonic-gate	 *
2980Sstevel@tonic-gate	 * assumes TSBE_TAG = 0
2990Sstevel@tonic-gate	 */
3000Sstevel@tonic-gate	srln	%g1, MMU_PAGESHIFT, %g1
3012241Shuah
3022241Shuah	sethi   %hi(ksfmmup), %g3
3032241Shuah        ldx     [%g3 + %lo(ksfmmup)], %g3
3042241Shuah        cmp     %g3, %g2
3052241Shuah        bne,pt	%xcc, 1f                        ! if not kernel as, go to 1
3060Sstevel@tonic-gate	  slln	%g1, MMU_PAGESHIFT, %g1		/* g1 = vaddr */
3070Sstevel@tonic-gate
3080Sstevel@tonic-gate	/* We need to demap in the kernel context */
3090Sstevel@tonic-gate	or	DEMAP_NUCLEUS | DEMAP_PAGE_TYPE, %g1, %g1
3100Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_DTLB_DEMAP
3110Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_ITLB_DEMAP
3120Sstevel@tonic-gate	retry
3130Sstevel@tonic-gate1:
3140Sstevel@tonic-gate	/* We need to demap in a user context */
3150Sstevel@tonic-gate	or	DEMAP_PRIMARY | DEMAP_PAGE_TYPE, %g1, %g1
3162241Shuah
3172241Shuah	SFMMU_CPU_CNUM(%g2, %g6, %g3)	! %g6 = sfmmu cnum on this CPU
3182241Shuah
3192241Shuah	ldub	[%g2 + SFMMU_CEXT], %g4		! %g4 = sfmmup->cext
3200Sstevel@tonic-gate	sll	%g4, CTXREG_EXT_SHIFT, %g4
3212241Shuah	or	%g6, %g4, %g6			! %g6 = pgsz | cnum
3222241Shuah
3230Sstevel@tonic-gate	set	MMU_PCONTEXT, %g4
3240Sstevel@tonic-gate	ldxa	[%g4]ASI_DMMU, %g5		/* rd old ctxnum */
3255584Sjimand	srlx	%g5, CTXREG_NEXT_SHIFT, %g2	/* %g2 = nucleus pgsz */
3265584Sjimand	sllx	%g2, CTXREG_NEXT_SHIFT, %g2	/* preserve nucleus pgsz */
3275584Sjimand	or	%g6, %g2, %g6			/* %g6 = nucleus pgsz | primary pgsz | cnum */
3282241Shuah	stxa	%g6, [%g4]ASI_DMMU		/* wr new ctxum */
3290Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_DTLB_DEMAP
3300Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_ITLB_DEMAP
3310Sstevel@tonic-gate	stxa	%g5, [%g4]ASI_DMMU		/* restore old ctxnum */
3320Sstevel@tonic-gate	retry
3330Sstevel@tonic-gate	SET_SIZE(vtag_flushpage_tl1)
3340Sstevel@tonic-gate
3350Sstevel@tonic-gate#endif	/* lint */
3360Sstevel@tonic-gate
3370Sstevel@tonic-gate
3380Sstevel@tonic-gate#if defined(lint)
3390Sstevel@tonic-gate
3400Sstevel@tonic-gate/* ARGSUSED */
3410Sstevel@tonic-gatevoid
3422241Shuahvtag_flush_pgcnt_tl1(uint64_t vaddr, uint64_t sfmmup_pgcnt)
3430Sstevel@tonic-gate{}
3440Sstevel@tonic-gate
3450Sstevel@tonic-gate#else	/* lint */
3460Sstevel@tonic-gate
3470Sstevel@tonic-gate	ENTRY_NP(vtag_flush_pgcnt_tl1)
3480Sstevel@tonic-gate	/*
3490Sstevel@tonic-gate	 * x-trap to flush pgcnt MMU_PAGESIZE pages from tlb
3500Sstevel@tonic-gate	 *
3510Sstevel@tonic-gate	 * %g1 = vaddr, zero-extended on 32-bit kernel
3522241Shuah	 * %g2 = <sfmmup58|pgcnt6>, (pgcnt - 1) is pass'ed in via pgcnt6 bits.
3530Sstevel@tonic-gate	 *
3540Sstevel@tonic-gate	 * NOTE: this handler relies on the fact that no
3550Sstevel@tonic-gate	 *	interrupts or traps can occur during the loop
3560Sstevel@tonic-gate	 *	issuing the TLB_DEMAP operations. It is assumed
3570Sstevel@tonic-gate	 *	that interrupts are disabled and this code is
3580Sstevel@tonic-gate	 *	fetching from the kernel locked text address.
3590Sstevel@tonic-gate	 *
3600Sstevel@tonic-gate	 * assumes TSBE_TAG = 0
3610Sstevel@tonic-gate	 */
3622241Shuah	set	SFMMU_PGCNT_MASK, %g4
3632241Shuah	and	%g4, %g2, %g3			/* g3 = pgcnt - 1 */
3642241Shuah	add	%g3, 1, %g3			/* g3 = pgcnt */
3652241Shuah
3662241Shuah	andn	%g2, SFMMU_PGCNT_MASK, %g2	/* g2 = sfmmup */
3670Sstevel@tonic-gate	srln	%g1, MMU_PAGESHIFT, %g1
3682241Shuah
3692241Shuah	sethi   %hi(ksfmmup), %g4
3702241Shuah        ldx     [%g4 + %lo(ksfmmup)], %g4
3712241Shuah        cmp     %g4, %g2
3722241Shuah        bne,pn   %xcc, 1f			/* if not kernel as, go to 1 */
3730Sstevel@tonic-gate	  slln	%g1, MMU_PAGESHIFT, %g1		/* g1 = vaddr */
3740Sstevel@tonic-gate
3750Sstevel@tonic-gate	/* We need to demap in the kernel context */
3760Sstevel@tonic-gate	or	DEMAP_NUCLEUS | DEMAP_PAGE_TYPE, %g1, %g1
3770Sstevel@tonic-gate	set	MMU_PAGESIZE, %g2		/* g2 = pgsize */
3782241Shuah	sethi   %hi(FLUSH_ADDR), %g5
3790Sstevel@tonic-gate4:
3800Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_DTLB_DEMAP
3810Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_ITLB_DEMAP
3822241Shuah	flush	%g5				! flush required by immu
3832241Shuah
3840Sstevel@tonic-gate	deccc	%g3				/* decr pgcnt */
3850Sstevel@tonic-gate	bnz,pt	%icc,4b
3860Sstevel@tonic-gate	  add	%g1, %g2, %g1			/* next page */
3870Sstevel@tonic-gate	retry
3880Sstevel@tonic-gate1:
3892241Shuah	/*
3902241Shuah	 * We need to demap in a user context
3912241Shuah	 *
3922241Shuah	 * g2 = sfmmup
3932241Shuah	 * g3 = pgcnt
3942241Shuah	 */
3952241Shuah	SFMMU_CPU_CNUM(%g2, %g5, %g6)		! %g5 = sfmmu cnum on this CPU
3962241Shuah
3972241Shuah	or	DEMAP_PRIMARY | DEMAP_PAGE_TYPE, %g1, %g1
3982241Shuah
3992241Shuah	ldub	[%g2 + SFMMU_CEXT], %g4		! %g4 = sfmmup->cext
4000Sstevel@tonic-gate	sll	%g4, CTXREG_EXT_SHIFT, %g4
4012241Shuah	or	%g5, %g4, %g5
4022241Shuah
4030Sstevel@tonic-gate	set	MMU_PCONTEXT, %g4
4042241Shuah	ldxa	[%g4]ASI_DMMU, %g6		/* rd old ctxnum */
4055584Sjimand	srlx	%g6, CTXREG_NEXT_SHIFT, %g2	/* %g2 = nucleus pgsz */
4065584Sjimand	sllx	%g2, CTXREG_NEXT_SHIFT, %g2	/* preserve nucleus pgsz */
4075584Sjimand	or	%g5, %g2, %g5			/* %g5 = nucleus pgsz | primary pgsz | cnum */
4082241Shuah	stxa	%g5, [%g4]ASI_DMMU		/* wr new ctxum */
4090Sstevel@tonic-gate
4100Sstevel@tonic-gate	set	MMU_PAGESIZE, %g2		/* g2 = pgsize */
4112241Shuah	sethi   %hi(FLUSH_ADDR), %g5
4120Sstevel@tonic-gate3:
4130Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_DTLB_DEMAP
4140Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_ITLB_DEMAP
4152241Shuah	flush	%g5				! flush required by immu
4162241Shuah
4170Sstevel@tonic-gate	deccc	%g3				/* decr pgcnt */
4180Sstevel@tonic-gate	bnz,pt	%icc,3b
4190Sstevel@tonic-gate	  add	%g1, %g2, %g1			/* next page */
4200Sstevel@tonic-gate
4212241Shuah	stxa	%g6, [%g4]ASI_DMMU		/* restore old ctxnum */
4220Sstevel@tonic-gate	retry
4230Sstevel@tonic-gate	SET_SIZE(vtag_flush_pgcnt_tl1)
4240Sstevel@tonic-gate
4250Sstevel@tonic-gate#endif	/* lint */
4260Sstevel@tonic-gate
4270Sstevel@tonic-gate#if defined(lint)
4280Sstevel@tonic-gate
4290Sstevel@tonic-gate/*ARGSUSED*/
4300Sstevel@tonic-gatevoid
4310Sstevel@tonic-gatevtag_flushall_tl1(uint64_t dummy1, uint64_t dummy2)
4320Sstevel@tonic-gate{}
4330Sstevel@tonic-gate
4340Sstevel@tonic-gate#else	/* lint */
4350Sstevel@tonic-gate
4360Sstevel@tonic-gate	ENTRY_NP(vtag_flushall_tl1)
4370Sstevel@tonic-gate	/*
4380Sstevel@tonic-gate	 * x-trap to flush tlb
4390Sstevel@tonic-gate	 */
4400Sstevel@tonic-gate	set	DEMAP_ALL_TYPE, %g4
4410Sstevel@tonic-gate	stxa	%g0, [%g4]ASI_DTLB_DEMAP
4420Sstevel@tonic-gate	stxa	%g0, [%g4]ASI_ITLB_DEMAP
4430Sstevel@tonic-gate	retry
4440Sstevel@tonic-gate	SET_SIZE(vtag_flushall_tl1)
4450Sstevel@tonic-gate
4460Sstevel@tonic-gate#endif	/* lint */
4470Sstevel@tonic-gate
4480Sstevel@tonic-gate
4490Sstevel@tonic-gate#if defined(lint)
4500Sstevel@tonic-gate
4510Sstevel@tonic-gate/* ARGSUSED */
4520Sstevel@tonic-gatevoid
4530Sstevel@tonic-gatevac_flushpage(pfn_t pfnum, int vcolor)
4540Sstevel@tonic-gate{}
4550Sstevel@tonic-gate
4560Sstevel@tonic-gate#else	/* lint */
4570Sstevel@tonic-gate
4580Sstevel@tonic-gate/*
4590Sstevel@tonic-gate * vac_flushpage(pfnum, color)
4600Sstevel@tonic-gate *	Flush 1 8k page of the D-$ with physical page = pfnum
4610Sstevel@tonic-gate *	Algorithm:
4620Sstevel@tonic-gate *		The cheetah dcache is a 64k psuedo 4 way accaociative cache.
4630Sstevel@tonic-gate *		It is virtual indexed, physically tagged cache.
4640Sstevel@tonic-gate */
4650Sstevel@tonic-gate	.seg	".data"
4660Sstevel@tonic-gate	.align	8
4670Sstevel@tonic-gate	.global	dflush_type
4680Sstevel@tonic-gatedflush_type:
4690Sstevel@tonic-gate	.word	FLUSHPAGE_TYPE
4700Sstevel@tonic-gate
4710Sstevel@tonic-gate	ENTRY(vac_flushpage)
4720Sstevel@tonic-gate	/*
4730Sstevel@tonic-gate	 * flush page from the d$
4740Sstevel@tonic-gate	 *
4750Sstevel@tonic-gate	 * %o0 = pfnum, %o1 = color
4760Sstevel@tonic-gate	 */
4770Sstevel@tonic-gate	DCACHE_FLUSHPAGE(%o0, %o1, %o2, %o3, %o4)
4780Sstevel@tonic-gate	retl
4790Sstevel@tonic-gate	  nop
4800Sstevel@tonic-gate	SET_SIZE(vac_flushpage)
4810Sstevel@tonic-gate
4820Sstevel@tonic-gate#endif	/* lint */
4830Sstevel@tonic-gate
4840Sstevel@tonic-gate
4850Sstevel@tonic-gate#if defined(lint)
4860Sstevel@tonic-gate
4870Sstevel@tonic-gate/* ARGSUSED */
4880Sstevel@tonic-gatevoid
4890Sstevel@tonic-gatevac_flushpage_tl1(uint64_t pfnum, uint64_t vcolor)
4900Sstevel@tonic-gate{}
4910Sstevel@tonic-gate
4920Sstevel@tonic-gate#else	/* lint */
4930Sstevel@tonic-gate
4940Sstevel@tonic-gate	ENTRY_NP(vac_flushpage_tl1)
4950Sstevel@tonic-gate	/*
4960Sstevel@tonic-gate	 * x-trap to flush page from the d$
4970Sstevel@tonic-gate	 *
4980Sstevel@tonic-gate	 * %g1 = pfnum, %g2 = color
4990Sstevel@tonic-gate	 */
5000Sstevel@tonic-gate	DCACHE_FLUSHPAGE(%g1, %g2, %g3, %g4, %g5)
5010Sstevel@tonic-gate	retry
5020Sstevel@tonic-gate	SET_SIZE(vac_flushpage_tl1)
5030Sstevel@tonic-gate
5040Sstevel@tonic-gate#endif	/* lint */
5050Sstevel@tonic-gate
5060Sstevel@tonic-gate
5070Sstevel@tonic-gate#if defined(lint)
5080Sstevel@tonic-gate
5090Sstevel@tonic-gate/* ARGSUSED */
5100Sstevel@tonic-gatevoid
5110Sstevel@tonic-gatevac_flushcolor(int vcolor, pfn_t pfnum)
5120Sstevel@tonic-gate{}
5130Sstevel@tonic-gate
5140Sstevel@tonic-gate#else	/* lint */
5150Sstevel@tonic-gate
5160Sstevel@tonic-gate	ENTRY(vac_flushcolor)
5170Sstevel@tonic-gate	/*
5187393SDonghai.Qiao@Sun.COM	 * %o0 = vcolor
5190Sstevel@tonic-gate	 */
5207393SDonghai.Qiao@Sun.COM	DCACHE_FLUSHCOLOR(%o0, 0, %o1, %o2, %o3)
5217393SDonghai.Qiao@Sun.COM	DCACHE_FLUSHCOLOR(%o0, 1, %o1, %o2, %o3)
5227393SDonghai.Qiao@Sun.COM	DCACHE_FLUSHCOLOR(%o0, 2, %o1, %o2, %o3)
5237393SDonghai.Qiao@Sun.COM	DCACHE_FLUSHCOLOR(%o0, 3, %o1, %o2, %o3)
5240Sstevel@tonic-gate	retl
5250Sstevel@tonic-gate	  nop
5260Sstevel@tonic-gate	SET_SIZE(vac_flushcolor)
5270Sstevel@tonic-gate
5280Sstevel@tonic-gate#endif	/* lint */
5290Sstevel@tonic-gate
5300Sstevel@tonic-gate
5310Sstevel@tonic-gate#if defined(lint)
5320Sstevel@tonic-gate
5330Sstevel@tonic-gate/* ARGSUSED */
5340Sstevel@tonic-gatevoid
5350Sstevel@tonic-gatevac_flushcolor_tl1(uint64_t vcolor, uint64_t pfnum)
5360Sstevel@tonic-gate{}
5370Sstevel@tonic-gate
5380Sstevel@tonic-gate#else	/* lint */
5390Sstevel@tonic-gate
5400Sstevel@tonic-gate	ENTRY(vac_flushcolor_tl1)
5410Sstevel@tonic-gate	/*
5420Sstevel@tonic-gate	 * %g1 = vcolor
5430Sstevel@tonic-gate	 */
5447393SDonghai.Qiao@Sun.COM	DCACHE_FLUSHCOLOR(%g1, 0, %g2, %g3, %g4)
5457393SDonghai.Qiao@Sun.COM	DCACHE_FLUSHCOLOR(%g1, 1, %g2, %g3, %g4)
5467393SDonghai.Qiao@Sun.COM	DCACHE_FLUSHCOLOR(%g1, 2, %g2, %g3, %g4)
5477393SDonghai.Qiao@Sun.COM	DCACHE_FLUSHCOLOR(%g1, 3, %g2, %g3, %g4)
5480Sstevel@tonic-gate	retry
5490Sstevel@tonic-gate	SET_SIZE(vac_flushcolor_tl1)
5500Sstevel@tonic-gate
5510Sstevel@tonic-gate#endif	/* lint */
5520Sstevel@tonic-gate
5530Sstevel@tonic-gate#if defined(lint)
5540Sstevel@tonic-gate
5550Sstevel@tonic-gateint
5560Sstevel@tonic-gateidsr_busy(void)
5570Sstevel@tonic-gate{
5580Sstevel@tonic-gate	return (0);
5590Sstevel@tonic-gate}
5600Sstevel@tonic-gate
5610Sstevel@tonic-gate#else	/* lint */
5620Sstevel@tonic-gate
5630Sstevel@tonic-gate/*
5640Sstevel@tonic-gate * Determine whether or not the IDSR is busy.
5650Sstevel@tonic-gate * Entry: no arguments
5660Sstevel@tonic-gate * Returns: 1 if busy, 0 otherwise
5670Sstevel@tonic-gate */
5680Sstevel@tonic-gate	ENTRY(idsr_busy)
5690Sstevel@tonic-gate	ldxa	[%g0]ASI_INTR_DISPATCH_STATUS, %g1
5700Sstevel@tonic-gate	clr	%o0
5710Sstevel@tonic-gate	btst	IDSR_BUSY, %g1
5720Sstevel@tonic-gate	bz,a,pt	%xcc, 1f
5730Sstevel@tonic-gate	mov	1, %o0
5740Sstevel@tonic-gate1:
5750Sstevel@tonic-gate	retl
5760Sstevel@tonic-gate	nop
5770Sstevel@tonic-gate	SET_SIZE(idsr_busy)
5780Sstevel@tonic-gate
5790Sstevel@tonic-gate#endif	/* lint */
5800Sstevel@tonic-gate
5810Sstevel@tonic-gate#if defined(lint)
5820Sstevel@tonic-gate
5830Sstevel@tonic-gate/* ARGSUSED */
5840Sstevel@tonic-gatevoid
5850Sstevel@tonic-gateinit_mondo(xcfunc_t *func, uint64_t arg1, uint64_t arg2)
5860Sstevel@tonic-gate{}
5870Sstevel@tonic-gate
5880Sstevel@tonic-gate/* ARGSUSED */
5890Sstevel@tonic-gatevoid
5900Sstevel@tonic-gateinit_mondo_nocheck(xcfunc_t *func, uint64_t arg1, uint64_t arg2)
5910Sstevel@tonic-gate{}
5920Sstevel@tonic-gate
5930Sstevel@tonic-gate#else	/* lint */
5940Sstevel@tonic-gate
5950Sstevel@tonic-gate	.global _dispatch_status_busy
5960Sstevel@tonic-gate_dispatch_status_busy:
5970Sstevel@tonic-gate	.asciz	"ASI_INTR_DISPATCH_STATUS error: busy"
5980Sstevel@tonic-gate	.align	4
5990Sstevel@tonic-gate
6000Sstevel@tonic-gate/*
6010Sstevel@tonic-gate * Setup interrupt dispatch data registers
6020Sstevel@tonic-gate * Entry:
6030Sstevel@tonic-gate *	%o0 - function or inumber to call
6040Sstevel@tonic-gate *	%o1, %o2 - arguments (2 uint64_t's)
6050Sstevel@tonic-gate */
6060Sstevel@tonic-gate	.seg "text"
6070Sstevel@tonic-gate
6080Sstevel@tonic-gate	ENTRY(init_mondo)
6090Sstevel@tonic-gate#ifdef DEBUG
6100Sstevel@tonic-gate	!
6110Sstevel@tonic-gate	! IDSR should not be busy at the moment
6120Sstevel@tonic-gate	!
6130Sstevel@tonic-gate	ldxa	[%g0]ASI_INTR_DISPATCH_STATUS, %g1
6140Sstevel@tonic-gate	btst	IDSR_BUSY, %g1
6150Sstevel@tonic-gate	bz,pt	%xcc, 1f
6160Sstevel@tonic-gate	nop
6170Sstevel@tonic-gate	sethi	%hi(_dispatch_status_busy), %o0
6180Sstevel@tonic-gate	call	panic
6190Sstevel@tonic-gate	or	%o0, %lo(_dispatch_status_busy), %o0
6200Sstevel@tonic-gate#endif /* DEBUG */
6210Sstevel@tonic-gate
6220Sstevel@tonic-gate	ALTENTRY(init_mondo_nocheck)
6230Sstevel@tonic-gate	!
6240Sstevel@tonic-gate	! interrupt vector dispatch data reg 0
6250Sstevel@tonic-gate	!
6260Sstevel@tonic-gate1:
6270Sstevel@tonic-gate	mov	IDDR_0, %g1
6280Sstevel@tonic-gate	mov	IDDR_1, %g2
6290Sstevel@tonic-gate	mov	IDDR_2, %g3
6300Sstevel@tonic-gate	stxa	%o0, [%g1]ASI_INTR_DISPATCH
6310Sstevel@tonic-gate
6320Sstevel@tonic-gate	!
6330Sstevel@tonic-gate	! interrupt vector dispatch data reg 1
6340Sstevel@tonic-gate	!
6350Sstevel@tonic-gate	stxa	%o1, [%g2]ASI_INTR_DISPATCH
6360Sstevel@tonic-gate
6370Sstevel@tonic-gate	!
6380Sstevel@tonic-gate	! interrupt vector dispatch data reg 2
6390Sstevel@tonic-gate	!
6400Sstevel@tonic-gate	stxa	%o2, [%g3]ASI_INTR_DISPATCH
6410Sstevel@tonic-gate
6420Sstevel@tonic-gate	membar	#Sync
6430Sstevel@tonic-gate	retl
6440Sstevel@tonic-gate	nop
6450Sstevel@tonic-gate	SET_SIZE(init_mondo_nocheck)
6460Sstevel@tonic-gate	SET_SIZE(init_mondo)
6470Sstevel@tonic-gate
6480Sstevel@tonic-gate#endif	/* lint */
6490Sstevel@tonic-gate
6500Sstevel@tonic-gate
6510Sstevel@tonic-gate#if !(defined(JALAPENO) || defined(SERRANO))
6520Sstevel@tonic-gate
6530Sstevel@tonic-gate#if defined(lint)
6540Sstevel@tonic-gate
6550Sstevel@tonic-gate/* ARGSUSED */
6560Sstevel@tonic-gatevoid
6570Sstevel@tonic-gateshipit(int upaid, int bn)
6580Sstevel@tonic-gate{ return; }
6590Sstevel@tonic-gate
6600Sstevel@tonic-gate#else	/* lint */
6610Sstevel@tonic-gate
6620Sstevel@tonic-gate/*
6630Sstevel@tonic-gate * Ship mondo to aid using busy/nack pair bn
6640Sstevel@tonic-gate */
6650Sstevel@tonic-gate	ENTRY_NP(shipit)
6660Sstevel@tonic-gate	sll	%o0, IDCR_PID_SHIFT, %g1	! IDCR<18:14> = agent id
6670Sstevel@tonic-gate	sll	%o1, IDCR_BN_SHIFT, %g2		! IDCR<28:24> = b/n pair
6680Sstevel@tonic-gate	or	%g1, IDCR_OFFSET, %g1		! IDCR<13:0> = 0x70
6690Sstevel@tonic-gate	or	%g1, %g2, %g1
6700Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_INTR_DISPATCH	! interrupt vector dispatch
6710Sstevel@tonic-gate	membar	#Sync
6720Sstevel@tonic-gate	retl
6730Sstevel@tonic-gate	nop
6740Sstevel@tonic-gate	SET_SIZE(shipit)
6750Sstevel@tonic-gate
6760Sstevel@tonic-gate#endif	/* lint */
6770Sstevel@tonic-gate
6780Sstevel@tonic-gate#endif	/* !(JALAPENO || SERRANO) */
6790Sstevel@tonic-gate
6800Sstevel@tonic-gate
6810Sstevel@tonic-gate#if defined(lint)
6820Sstevel@tonic-gate
6830Sstevel@tonic-gate/* ARGSUSED */
6840Sstevel@tonic-gatevoid
6850Sstevel@tonic-gateflush_instr_mem(caddr_t vaddr, size_t len)
6860Sstevel@tonic-gate{}
6870Sstevel@tonic-gate
6880Sstevel@tonic-gate#else	/* lint */
6890Sstevel@tonic-gate
6900Sstevel@tonic-gate/*
6910Sstevel@tonic-gate * flush_instr_mem:
6920Sstevel@tonic-gate *	Flush 1 page of the I-$ starting at vaddr
6930Sstevel@tonic-gate * 	%o0 vaddr
6940Sstevel@tonic-gate *	%o1 bytes to be flushed
6950Sstevel@tonic-gate * UltraSPARC-III maintains consistency of the on-chip Instruction Cache with
6960Sstevel@tonic-gate * the stores from all processors so that a FLUSH instruction is only needed
6970Sstevel@tonic-gate * to ensure pipeline is consistent. This means a single flush is sufficient at
6980Sstevel@tonic-gate * the end of a sequence of stores that updates the instruction stream to
6990Sstevel@tonic-gate * ensure correct operation.
7000Sstevel@tonic-gate */
7010Sstevel@tonic-gate
7020Sstevel@tonic-gate	ENTRY(flush_instr_mem)
7033517Smp204432	flush	%o0			! address irrelevant
7040Sstevel@tonic-gate	retl
7050Sstevel@tonic-gate	nop
7060Sstevel@tonic-gate	SET_SIZE(flush_instr_mem)
7070Sstevel@tonic-gate
7080Sstevel@tonic-gate#endif	/* lint */
7090Sstevel@tonic-gate
7100Sstevel@tonic-gate
7110Sstevel@tonic-gate#if defined(CPU_IMP_ECACHE_ASSOC)
7120Sstevel@tonic-gate
7130Sstevel@tonic-gate#if defined(lint)
7140Sstevel@tonic-gate
7150Sstevel@tonic-gate/* ARGSUSED */
7160Sstevel@tonic-gateuint64_t
7170Sstevel@tonic-gateget_ecache_ctrl(void)
7180Sstevel@tonic-gate{ return (0); }
7190Sstevel@tonic-gate
7200Sstevel@tonic-gate#else	/* lint */
7210Sstevel@tonic-gate
7220Sstevel@tonic-gate	ENTRY(get_ecache_ctrl)
7230Sstevel@tonic-gate	GET_CPU_IMPL(%o0)
7240Sstevel@tonic-gate	cmp	%o0, JAGUAR_IMPL
7250Sstevel@tonic-gate	!
7260Sstevel@tonic-gate	! Putting an ASI access in the delay slot may
7270Sstevel@tonic-gate	! cause it to be accessed, even when annulled.
7280Sstevel@tonic-gate	!
7290Sstevel@tonic-gate	bne	1f
7300Sstevel@tonic-gate	  nop
7310Sstevel@tonic-gate	ldxa	[%g0]ASI_EC_CFG_TIMING, %o0	! read Jaguar shared E$ ctrl reg
7320Sstevel@tonic-gate	b	2f
7330Sstevel@tonic-gate	  nop
7340Sstevel@tonic-gate1:
7350Sstevel@tonic-gate	ldxa	[%g0]ASI_EC_CTRL, %o0		! read Ch/Ch+ E$ control reg
7360Sstevel@tonic-gate2:
7370Sstevel@tonic-gate	retl
7380Sstevel@tonic-gate	  nop
7390Sstevel@tonic-gate	SET_SIZE(get_ecache_ctrl)
7400Sstevel@tonic-gate
7410Sstevel@tonic-gate#endif	/* lint */
7420Sstevel@tonic-gate
7430Sstevel@tonic-gate#endif	/* CPU_IMP_ECACHE_ASSOC */
7440Sstevel@tonic-gate
7450Sstevel@tonic-gate
7460Sstevel@tonic-gate#if !(defined(JALAPENO) || defined(SERRANO))
7470Sstevel@tonic-gate
7480Sstevel@tonic-gate/*
7490Sstevel@tonic-gate * flush_ecache:
7500Sstevel@tonic-gate *	%o0 - 64 bit physical address
7510Sstevel@tonic-gate *	%o1 - ecache size
7520Sstevel@tonic-gate *	%o2 - ecache linesize
7530Sstevel@tonic-gate */
7540Sstevel@tonic-gate#if defined(lint)
7550Sstevel@tonic-gate
7560Sstevel@tonic-gate/*ARGSUSED*/
7570Sstevel@tonic-gatevoid
7580Sstevel@tonic-gateflush_ecache(uint64_t physaddr, size_t ecache_size, size_t ecache_linesize)
7590Sstevel@tonic-gate{}
7600Sstevel@tonic-gate
7610Sstevel@tonic-gate#else /* !lint */
7620Sstevel@tonic-gate
7630Sstevel@tonic-gate	ENTRY(flush_ecache)
7640Sstevel@tonic-gate
7650Sstevel@tonic-gate	/*
7660Sstevel@tonic-gate	 * For certain CPU implementations, we have to flush the L2 cache
7670Sstevel@tonic-gate	 * before flushing the ecache.
7680Sstevel@tonic-gate	 */
7690Sstevel@tonic-gate	PN_L2_FLUSHALL(%g3, %g4, %g5)
7700Sstevel@tonic-gate
7710Sstevel@tonic-gate	/*
7720Sstevel@tonic-gate	 * Flush the entire Ecache using displacement flush.
7730Sstevel@tonic-gate	 */
7740Sstevel@tonic-gate	ECACHE_FLUSHALL(%o1, %o2, %o0, %o4)
7750Sstevel@tonic-gate
7760Sstevel@tonic-gate	retl
7770Sstevel@tonic-gate	nop
7780Sstevel@tonic-gate	SET_SIZE(flush_ecache)
7790Sstevel@tonic-gate
7800Sstevel@tonic-gate#endif /* lint */
7810Sstevel@tonic-gate
7820Sstevel@tonic-gate#endif	/* !(JALAPENO || SERRANO) */
7830Sstevel@tonic-gate
7840Sstevel@tonic-gate
7850Sstevel@tonic-gate#if defined(lint)
7860Sstevel@tonic-gate
7870Sstevel@tonic-gatevoid
7880Sstevel@tonic-gateflush_dcache(void)
7890Sstevel@tonic-gate{}
7900Sstevel@tonic-gate
7910Sstevel@tonic-gate#else	/* lint */
7920Sstevel@tonic-gate
7930Sstevel@tonic-gate	ENTRY(flush_dcache)
7940Sstevel@tonic-gate	ASM_LD(%o0, dcache_size)
7950Sstevel@tonic-gate	ASM_LD(%o1, dcache_linesize)
7960Sstevel@tonic-gate	CH_DCACHE_FLUSHALL(%o0, %o1, %o2)
7970Sstevel@tonic-gate	retl
7980Sstevel@tonic-gate	nop
7990Sstevel@tonic-gate	SET_SIZE(flush_dcache)
8000Sstevel@tonic-gate
8010Sstevel@tonic-gate#endif	/* lint */
8020Sstevel@tonic-gate
8030Sstevel@tonic-gate
8040Sstevel@tonic-gate#if defined(lint)
8050Sstevel@tonic-gate
8060Sstevel@tonic-gatevoid
8070Sstevel@tonic-gateflush_icache(void)
8080Sstevel@tonic-gate{}
8090Sstevel@tonic-gate
8100Sstevel@tonic-gate#else	/* lint */
8110Sstevel@tonic-gate
8120Sstevel@tonic-gate	ENTRY(flush_icache)
8130Sstevel@tonic-gate	GET_CPU_PRIVATE_PTR(%g0, %o0, %o2, flush_icache_1);
8140Sstevel@tonic-gate	ld	[%o0 + CHPR_ICACHE_LINESIZE], %o1
8150Sstevel@tonic-gate	ba,pt	%icc, 2f
8160Sstevel@tonic-gate	  ld	[%o0 + CHPR_ICACHE_SIZE], %o0
8170Sstevel@tonic-gateflush_icache_1:
8180Sstevel@tonic-gate	ASM_LD(%o0, icache_size)
8190Sstevel@tonic-gate	ASM_LD(%o1, icache_linesize)
8200Sstevel@tonic-gate2:
8210Sstevel@tonic-gate	CH_ICACHE_FLUSHALL(%o0, %o1, %o2, %o4)
8220Sstevel@tonic-gate	retl
8230Sstevel@tonic-gate	nop
8240Sstevel@tonic-gate	SET_SIZE(flush_icache)
8250Sstevel@tonic-gate
8260Sstevel@tonic-gate#endif	/* lint */
8270Sstevel@tonic-gate
8280Sstevel@tonic-gate#if defined(lint)
8290Sstevel@tonic-gate
8300Sstevel@tonic-gate/*ARGSUSED*/
8310Sstevel@tonic-gatevoid
8320Sstevel@tonic-gatekdi_flush_idcache(int dcache_size, int dcache_lsize, int icache_size,
8330Sstevel@tonic-gate    int icache_lsize)
8340Sstevel@tonic-gate{
8350Sstevel@tonic-gate}
8360Sstevel@tonic-gate
8370Sstevel@tonic-gate#else	/* lint */
8380Sstevel@tonic-gate
8390Sstevel@tonic-gate	ENTRY(kdi_flush_idcache)
8400Sstevel@tonic-gate	CH_DCACHE_FLUSHALL(%o0, %o1, %g1)
8410Sstevel@tonic-gate	CH_ICACHE_FLUSHALL(%o2, %o3, %g1, %g2)
8420Sstevel@tonic-gate	membar	#Sync
8430Sstevel@tonic-gate	retl
8440Sstevel@tonic-gate	nop
8450Sstevel@tonic-gate	SET_SIZE(kdi_flush_idcache)
8460Sstevel@tonic-gate
8470Sstevel@tonic-gate#endif	/* lint */
8480Sstevel@tonic-gate
8490Sstevel@tonic-gate#if defined(lint)
8500Sstevel@tonic-gate
8510Sstevel@tonic-gatevoid
8520Sstevel@tonic-gateflush_pcache(void)
8530Sstevel@tonic-gate{}
8540Sstevel@tonic-gate
8550Sstevel@tonic-gate#else	/* lint */
8560Sstevel@tonic-gate
8570Sstevel@tonic-gate	ENTRY(flush_pcache)
8580Sstevel@tonic-gate	PCACHE_FLUSHALL(%o0, %o1, %o2)
8590Sstevel@tonic-gate	retl
8600Sstevel@tonic-gate	nop
8610Sstevel@tonic-gate	SET_SIZE(flush_pcache)
8620Sstevel@tonic-gate
8630Sstevel@tonic-gate#endif	/* lint */
8640Sstevel@tonic-gate
8650Sstevel@tonic-gate
8660Sstevel@tonic-gate#if defined(CPU_IMP_L1_CACHE_PARITY)
8670Sstevel@tonic-gate
8680Sstevel@tonic-gate#if defined(lint)
8690Sstevel@tonic-gate
8700Sstevel@tonic-gate/* ARGSUSED */
8710Sstevel@tonic-gatevoid
8720Sstevel@tonic-gateget_dcache_dtag(uint32_t dcache_idx, uint64_t *data)
8730Sstevel@tonic-gate{}
8740Sstevel@tonic-gate
8750Sstevel@tonic-gate#else	/* lint */
8760Sstevel@tonic-gate
8770Sstevel@tonic-gate/*
8780Sstevel@tonic-gate * Get dcache data and tag.  The Dcache data is a pointer to a ch_dc_data_t
8790Sstevel@tonic-gate * structure (see cheetahregs.h):
8800Sstevel@tonic-gate * The Dcache *should* be turned off when this code is executed.
8810Sstevel@tonic-gate */
8820Sstevel@tonic-gate	.align	128
8830Sstevel@tonic-gate	ENTRY(get_dcache_dtag)
8840Sstevel@tonic-gate	rdpr	%pstate, %o5
8850Sstevel@tonic-gate	andn    %o5, PSTATE_IE | PSTATE_AM, %o3
8860Sstevel@tonic-gate	wrpr	%g0, %o3, %pstate
8870Sstevel@tonic-gate	b	1f
8880Sstevel@tonic-gate	  stx	%o0, [%o1 + CH_DC_IDX]
8890Sstevel@tonic-gate
8900Sstevel@tonic-gate	.align	128
8910Sstevel@tonic-gate1:
8920Sstevel@tonic-gate	ldxa	[%o0]ASI_DC_TAG, %o2
8930Sstevel@tonic-gate	stx	%o2, [%o1 + CH_DC_TAG]
8940Sstevel@tonic-gate	membar	#Sync
8950Sstevel@tonic-gate	ldxa	[%o0]ASI_DC_UTAG, %o2
8960Sstevel@tonic-gate	membar	#Sync
8970Sstevel@tonic-gate	stx	%o2, [%o1 + CH_DC_UTAG]
8980Sstevel@tonic-gate	ldxa	[%o0]ASI_DC_SNP_TAG, %o2
8990Sstevel@tonic-gate	stx	%o2, [%o1 + CH_DC_SNTAG]
9000Sstevel@tonic-gate	add	%o1, CH_DC_DATA, %o1
9010Sstevel@tonic-gate	clr	%o3
9020Sstevel@tonic-gate2:
9030Sstevel@tonic-gate	membar	#Sync				! required before ASI_DC_DATA
9040Sstevel@tonic-gate	ldxa	[%o0 + %o3]ASI_DC_DATA, %o2
9050Sstevel@tonic-gate	membar	#Sync				! required after ASI_DC_DATA
9060Sstevel@tonic-gate	stx	%o2, [%o1 + %o3]
9070Sstevel@tonic-gate	cmp	%o3, CH_DC_DATA_REG_SIZE - 8
9080Sstevel@tonic-gate	blt	2b
9090Sstevel@tonic-gate	  add	%o3, 8, %o3
9100Sstevel@tonic-gate
9110Sstevel@tonic-gate	/*
9120Sstevel@tonic-gate	 * Unlike other CPUs in the family, D$ data parity bits for Panther
9130Sstevel@tonic-gate	 * do not reside in the microtag. Instead, we have to read them
9140Sstevel@tonic-gate	 * using the DC_data_parity bit of ASI_DCACHE_DATA. Also, instead
9150Sstevel@tonic-gate	 * of just having 8 parity bits to protect all 32 bytes of data
9160Sstevel@tonic-gate	 * per line, we now have 32 bits of parity.
9170Sstevel@tonic-gate	 */
9180Sstevel@tonic-gate	GET_CPU_IMPL(%o3)
9190Sstevel@tonic-gate	cmp	%o3, PANTHER_IMPL
9200Sstevel@tonic-gate	bne	4f
9210Sstevel@tonic-gate	  clr	%o3
9220Sstevel@tonic-gate
9230Sstevel@tonic-gate	/*
9240Sstevel@tonic-gate	 * move our pointer to the next field where we store parity bits
9250Sstevel@tonic-gate	 * and add the offset of the last parity byte since we will be
9260Sstevel@tonic-gate	 * storing all 4 parity bytes within one 64 bit field like this:
9270Sstevel@tonic-gate	 *
9280Sstevel@tonic-gate	 * +------+------------+------------+------------+------------+
9290Sstevel@tonic-gate	 * |  -   | DC_parity  | DC_parity  | DC_parity  | DC_parity  |
9300Sstevel@tonic-gate	 * |  -   | for word 3 | for word 2 | for word 1 | for word 0 |
9310Sstevel@tonic-gate	 * +------+------------+------------+------------+------------+
9320Sstevel@tonic-gate	 *  63:32     31:24        23:16         15:8          7:0
9330Sstevel@tonic-gate	 */
9340Sstevel@tonic-gate	add	%o1, CH_DC_PN_DATA_PARITY - CH_DC_DATA + 7, %o1
9350Sstevel@tonic-gate
9360Sstevel@tonic-gate	/* add the DC_data_parity bit into our working index */
9370Sstevel@tonic-gate	mov	1, %o2
9380Sstevel@tonic-gate	sll	%o2, PN_DC_DATA_PARITY_BIT_SHIFT, %o2
9390Sstevel@tonic-gate	or	%o0, %o2, %o0
9400Sstevel@tonic-gate3:
9410Sstevel@tonic-gate	membar	#Sync				! required before ASI_DC_DATA
9420Sstevel@tonic-gate	ldxa	[%o0 + %o3]ASI_DC_DATA, %o2
9430Sstevel@tonic-gate	membar	#Sync				! required after ASI_DC_DATA
9440Sstevel@tonic-gate	stb	%o2, [%o1]
9450Sstevel@tonic-gate	dec	%o1
9460Sstevel@tonic-gate	cmp	%o3, CH_DC_DATA_REG_SIZE - 8
9470Sstevel@tonic-gate	blt	3b
9480Sstevel@tonic-gate	  add	%o3, 8, %o3
9490Sstevel@tonic-gate4:
9500Sstevel@tonic-gate	retl
9510Sstevel@tonic-gate	  wrpr	%g0, %o5, %pstate
9520Sstevel@tonic-gate	SET_SIZE(get_dcache_dtag)
9530Sstevel@tonic-gate
9540Sstevel@tonic-gate#endif	/* lint */
9550Sstevel@tonic-gate
9560Sstevel@tonic-gate
9570Sstevel@tonic-gate#if defined(lint)
9580Sstevel@tonic-gate
9590Sstevel@tonic-gate/* ARGSUSED */
9600Sstevel@tonic-gatevoid
9610Sstevel@tonic-gateget_icache_dtag(uint32_t ecache_idx, uint64_t *data)
9620Sstevel@tonic-gate{}
9630Sstevel@tonic-gate
9640Sstevel@tonic-gate#else	/* lint */
9650Sstevel@tonic-gate
9660Sstevel@tonic-gate/*
9670Sstevel@tonic-gate * Get icache data and tag.  The data argument is a pointer to a ch_ic_data_t
9680Sstevel@tonic-gate * structure (see cheetahregs.h):
9690Sstevel@tonic-gate * The Icache *Must* be turned off when this function is called.
9700Sstevel@tonic-gate * This is because diagnostic accesses to the Icache interfere with cache
9710Sstevel@tonic-gate * consistency.
9720Sstevel@tonic-gate */
9730Sstevel@tonic-gate	.align	128
9740Sstevel@tonic-gate	ENTRY(get_icache_dtag)
9750Sstevel@tonic-gate	rdpr	%pstate, %o5
9760Sstevel@tonic-gate	andn    %o5, PSTATE_IE | PSTATE_AM, %o3
9770Sstevel@tonic-gate	wrpr	%g0, %o3, %pstate
9780Sstevel@tonic-gate
9790Sstevel@tonic-gate	stx	%o0, [%o1 + CH_IC_IDX]
9800Sstevel@tonic-gate	ldxa	[%o0]ASI_IC_TAG, %o2
9810Sstevel@tonic-gate	stx	%o2, [%o1 + CH_IC_PATAG]
9820Sstevel@tonic-gate	add	%o0, CH_ICTAG_UTAG, %o0
9830Sstevel@tonic-gate	ldxa	[%o0]ASI_IC_TAG, %o2
9840Sstevel@tonic-gate	add	%o0, (CH_ICTAG_UPPER - CH_ICTAG_UTAG), %o0
9850Sstevel@tonic-gate	stx	%o2, [%o1 + CH_IC_UTAG]
9860Sstevel@tonic-gate	ldxa	[%o0]ASI_IC_TAG, %o2
9870Sstevel@tonic-gate	add	%o0, (CH_ICTAG_LOWER - CH_ICTAG_UPPER), %o0
9880Sstevel@tonic-gate	stx	%o2, [%o1 + CH_IC_UPPER]
9890Sstevel@tonic-gate	ldxa	[%o0]ASI_IC_TAG, %o2
9900Sstevel@tonic-gate	andn	%o0, CH_ICTAG_TMASK, %o0
9910Sstevel@tonic-gate	stx	%o2, [%o1 + CH_IC_LOWER]
9920Sstevel@tonic-gate	ldxa	[%o0]ASI_IC_SNP_TAG, %o2
9930Sstevel@tonic-gate	stx	%o2, [%o1 + CH_IC_SNTAG]
9940Sstevel@tonic-gate	add	%o1, CH_IC_DATA, %o1
9950Sstevel@tonic-gate	clr	%o3
9960Sstevel@tonic-gate2:
9970Sstevel@tonic-gate	ldxa	[%o0 + %o3]ASI_IC_DATA, %o2
9980Sstevel@tonic-gate	stx	%o2, [%o1 + %o3]
9990Sstevel@tonic-gate	cmp	%o3, PN_IC_DATA_REG_SIZE - 8
10000Sstevel@tonic-gate	blt	2b
10010Sstevel@tonic-gate	  add	%o3, 8, %o3
10020Sstevel@tonic-gate
10030Sstevel@tonic-gate	retl
10040Sstevel@tonic-gate	  wrpr	%g0, %o5, %pstate
10050Sstevel@tonic-gate	SET_SIZE(get_icache_dtag)
10060Sstevel@tonic-gate
10070Sstevel@tonic-gate#endif	/* lint */
10080Sstevel@tonic-gate
10090Sstevel@tonic-gate#if defined(lint)
10100Sstevel@tonic-gate
10110Sstevel@tonic-gate/* ARGSUSED */
10120Sstevel@tonic-gatevoid
10130Sstevel@tonic-gateget_pcache_dtag(uint32_t pcache_idx, uint64_t *data)
10140Sstevel@tonic-gate{}
10150Sstevel@tonic-gate
10160Sstevel@tonic-gate#else	/* lint */
10170Sstevel@tonic-gate
10180Sstevel@tonic-gate/*
10190Sstevel@tonic-gate * Get pcache data and tags.
10200Sstevel@tonic-gate * inputs:
10210Sstevel@tonic-gate *   pcache_idx	- fully constructed VA for for accessing P$ diagnostic
10220Sstevel@tonic-gate *		  registers. Contains PC_way and PC_addr shifted into
10230Sstevel@tonic-gate *		  the correct bit positions. See the PRM for more details.
10240Sstevel@tonic-gate *   data	- pointer to a ch_pc_data_t
10250Sstevel@tonic-gate * structure (see cheetahregs.h):
10260Sstevel@tonic-gate */
10270Sstevel@tonic-gate	.align	128
10280Sstevel@tonic-gate	ENTRY(get_pcache_dtag)
10290Sstevel@tonic-gate	rdpr	%pstate, %o5
10300Sstevel@tonic-gate	andn    %o5, PSTATE_IE | PSTATE_AM, %o3
10310Sstevel@tonic-gate	wrpr	%g0, %o3, %pstate
10320Sstevel@tonic-gate
10330Sstevel@tonic-gate	stx	%o0, [%o1 + CH_PC_IDX]
10340Sstevel@tonic-gate	ldxa	[%o0]ASI_PC_STATUS_DATA, %o2
10350Sstevel@tonic-gate	stx	%o2, [%o1 + CH_PC_STATUS]
10360Sstevel@tonic-gate	ldxa	[%o0]ASI_PC_TAG, %o2
10370Sstevel@tonic-gate	stx	%o2, [%o1 + CH_PC_TAG]
10380Sstevel@tonic-gate	ldxa	[%o0]ASI_PC_SNP_TAG, %o2
10390Sstevel@tonic-gate	stx	%o2, [%o1 + CH_PC_SNTAG]
10400Sstevel@tonic-gate	add	%o1, CH_PC_DATA, %o1
10410Sstevel@tonic-gate	clr	%o3
10420Sstevel@tonic-gate2:
10430Sstevel@tonic-gate	ldxa	[%o0 + %o3]ASI_PC_DATA, %o2
10440Sstevel@tonic-gate	stx	%o2, [%o1 + %o3]
10450Sstevel@tonic-gate	cmp	%o3, CH_PC_DATA_REG_SIZE - 8
10460Sstevel@tonic-gate	blt	2b
10470Sstevel@tonic-gate	  add	%o3, 8, %o3
10480Sstevel@tonic-gate
10490Sstevel@tonic-gate	retl
10500Sstevel@tonic-gate	  wrpr	%g0, %o5, %pstate
10510Sstevel@tonic-gate	SET_SIZE(get_pcache_dtag)
10520Sstevel@tonic-gate
10530Sstevel@tonic-gate#endif	/* lint */
10540Sstevel@tonic-gate
10550Sstevel@tonic-gate#endif	/* CPU_IMP_L1_CACHE_PARITY */
10560Sstevel@tonic-gate
10570Sstevel@tonic-gate#if defined(lint)
10580Sstevel@tonic-gate
10590Sstevel@tonic-gate/* ARGSUSED */
10600Sstevel@tonic-gatevoid
10610Sstevel@tonic-gateset_dcu(uint64_t dcu)
10620Sstevel@tonic-gate{}
10630Sstevel@tonic-gate
10640Sstevel@tonic-gate#else	/* lint */
10650Sstevel@tonic-gate
10660Sstevel@tonic-gate/*
10670Sstevel@tonic-gate * re-enable the i$, d$, w$, and p$ according to bootup cache state.
10680Sstevel@tonic-gate * Turn on WE, HPE, SPE, PE, IC, and DC bits defined as DCU_CACHE.
10690Sstevel@tonic-gate *   %o0 - 64 bit constant
10700Sstevel@tonic-gate */
10710Sstevel@tonic-gate	ENTRY(set_dcu)
10720Sstevel@tonic-gate	stxa	%o0, [%g0]ASI_DCU	! Store to DCU
10730Sstevel@tonic-gate	flush	%g0	/* flush required after changing the IC bit */
10740Sstevel@tonic-gate	retl
10750Sstevel@tonic-gate	nop
10760Sstevel@tonic-gate	SET_SIZE(set_dcu)
10770Sstevel@tonic-gate
10780Sstevel@tonic-gate#endif	/* lint */
10790Sstevel@tonic-gate
10800Sstevel@tonic-gate
10810Sstevel@tonic-gate#if defined(lint)
10820Sstevel@tonic-gate
10830Sstevel@tonic-gateuint64_t
10840Sstevel@tonic-gateget_dcu(void)
10850Sstevel@tonic-gate{
10860Sstevel@tonic-gate	return ((uint64_t)0);
10870Sstevel@tonic-gate}
10880Sstevel@tonic-gate
10890Sstevel@tonic-gate#else	/* lint */
10900Sstevel@tonic-gate
10910Sstevel@tonic-gate/*
10920Sstevel@tonic-gate * Return DCU register.
10930Sstevel@tonic-gate */
10940Sstevel@tonic-gate	ENTRY(get_dcu)
10950Sstevel@tonic-gate	ldxa	[%g0]ASI_DCU, %o0		/* DCU control register */
10960Sstevel@tonic-gate	retl
10970Sstevel@tonic-gate	nop
10980Sstevel@tonic-gate	SET_SIZE(get_dcu)
10990Sstevel@tonic-gate
11000Sstevel@tonic-gate#endif	/* lint */
11010Sstevel@tonic-gate
11020Sstevel@tonic-gate/*
11030Sstevel@tonic-gate * Cheetah/Cheetah+ level 15 interrupt handler trap table entry.
11040Sstevel@tonic-gate *
11050Sstevel@tonic-gate * This handler is used to check for softints generated by error trap
11060Sstevel@tonic-gate * handlers to report errors.  On Cheetah, this mechanism is used by the
11070Sstevel@tonic-gate * Fast ECC at TL>0 error trap handler and, on Cheetah+, by both the Fast
11080Sstevel@tonic-gate * ECC at TL>0 error and the I$/D$ parity error at TL>0 trap handlers.
11090Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must
11100Sstevel@tonic-gate *     be relocatable.
11110Sstevel@tonic-gate */
11120Sstevel@tonic-gate#if defined(lint)
11130Sstevel@tonic-gate
11140Sstevel@tonic-gatevoid
11150Sstevel@tonic-gatech_pil15_interrupt_instr(void)
11160Sstevel@tonic-gate{}
11170Sstevel@tonic-gate
11180Sstevel@tonic-gate#else	/* lint */
11190Sstevel@tonic-gate
11200Sstevel@tonic-gate	ENTRY_NP(ch_pil15_interrupt_instr)
11210Sstevel@tonic-gate	ASM_JMP(%g1, ch_pil15_interrupt)
11220Sstevel@tonic-gate	SET_SIZE(ch_pil15_interrupt_instr)
11230Sstevel@tonic-gate
11240Sstevel@tonic-gate#endif
11250Sstevel@tonic-gate
11260Sstevel@tonic-gate
11270Sstevel@tonic-gate#if defined(lint)
11280Sstevel@tonic-gate
11290Sstevel@tonic-gatevoid
11300Sstevel@tonic-gatech_pil15_interrupt(void)
11310Sstevel@tonic-gate{}
11320Sstevel@tonic-gate
11330Sstevel@tonic-gate#else	/* lint */
11340Sstevel@tonic-gate
11350Sstevel@tonic-gate	ENTRY_NP(ch_pil15_interrupt)
11360Sstevel@tonic-gate
11370Sstevel@tonic-gate	/*
11380Sstevel@tonic-gate	 * Since pil_interrupt is hacked to assume that every level 15
11390Sstevel@tonic-gate	 * interrupt is generated by the CPU to indicate a performance
11400Sstevel@tonic-gate	 * counter overflow this gets ugly.  Before calling pil_interrupt
11410Sstevel@tonic-gate	 * the Error at TL>0 pending status is inspected.  If it is
11420Sstevel@tonic-gate	 * non-zero, then an error has occurred and it is handled.
11430Sstevel@tonic-gate	 * Otherwise control is transfered to pil_interrupt.  Note that if
11440Sstevel@tonic-gate	 * an error is detected pil_interrupt will not be called and
11450Sstevel@tonic-gate	 * overflow interrupts may be lost causing erroneous performance
11460Sstevel@tonic-gate	 * measurements.  However, error-recovery will have a detrimental
11470Sstevel@tonic-gate	 * effect on performance anyway.
11480Sstevel@tonic-gate	 */
11490Sstevel@tonic-gate	CPU_INDEX(%g1, %g4)
11500Sstevel@tonic-gate	set	ch_err_tl1_pending, %g4
11510Sstevel@tonic-gate	ldub	[%g1 + %g4], %g2
11520Sstevel@tonic-gate	brz	%g2, 1f
11530Sstevel@tonic-gate	  nop
11540Sstevel@tonic-gate
11550Sstevel@tonic-gate	/*
11560Sstevel@tonic-gate	 * We have a pending TL>0 error, clear the TL>0 pending status.
11570Sstevel@tonic-gate	 */
11580Sstevel@tonic-gate	stb	%g0, [%g1 + %g4]
11590Sstevel@tonic-gate
11600Sstevel@tonic-gate	/*
11610Sstevel@tonic-gate	 * Clear the softint.
11620Sstevel@tonic-gate	 */
11630Sstevel@tonic-gate	mov	1, %g5
11640Sstevel@tonic-gate	sll	%g5, PIL_15, %g5
11650Sstevel@tonic-gate	wr	%g5, CLEAR_SOFTINT
11660Sstevel@tonic-gate
11670Sstevel@tonic-gate	/*
11680Sstevel@tonic-gate	 * For Cheetah*, call cpu_tl1_error via systrap at PIL 15
11690Sstevel@tonic-gate	 * to process the Fast ECC/Cache Parity at TL>0 error.  Clear
11700Sstevel@tonic-gate	 * panic flag (%g2).
11710Sstevel@tonic-gate	 */
11720Sstevel@tonic-gate	set	cpu_tl1_error, %g1
11730Sstevel@tonic-gate	clr	%g2
11740Sstevel@tonic-gate	ba	sys_trap
11750Sstevel@tonic-gate	  mov	PIL_15, %g4
11760Sstevel@tonic-gate
11770Sstevel@tonic-gate1:
11780Sstevel@tonic-gate	/*
11790Sstevel@tonic-gate	 * The logout is invalid.
11800Sstevel@tonic-gate	 *
11810Sstevel@tonic-gate	 * Call the default interrupt handler.
11820Sstevel@tonic-gate	 */
11830Sstevel@tonic-gate	sethi	%hi(pil_interrupt), %g1
11840Sstevel@tonic-gate	jmp	%g1 + %lo(pil_interrupt)
11850Sstevel@tonic-gate	  mov	PIL_15, %g4
11860Sstevel@tonic-gate
11870Sstevel@tonic-gate	SET_SIZE(ch_pil15_interrupt)
11880Sstevel@tonic-gate#endif
11890Sstevel@tonic-gate
11900Sstevel@tonic-gate
11910Sstevel@tonic-gate/*
11920Sstevel@tonic-gate * Error Handling
11930Sstevel@tonic-gate *
11940Sstevel@tonic-gate * Cheetah provides error checking for all memory access paths between
11950Sstevel@tonic-gate * the CPU, External Cache, Cheetah Data Switch and system bus. Error
11960Sstevel@tonic-gate * information is logged in the AFSR, (also AFSR_EXT for Panther) and
11970Sstevel@tonic-gate * AFAR and one of the following traps is generated (provided that it
11980Sstevel@tonic-gate * is enabled in External Cache Error Enable Register) to handle that
11990Sstevel@tonic-gate * error:
12000Sstevel@tonic-gate * 1. trap 0x70: Precise trap
12010Sstevel@tonic-gate *    tt0_fecc for errors at trap level(TL)>=0
12020Sstevel@tonic-gate * 2. trap 0x0A and 0x32: Deferred trap
12030Sstevel@tonic-gate *    async_err for errors at TL>=0
12040Sstevel@tonic-gate * 3. trap 0x63: Disrupting trap
12050Sstevel@tonic-gate *    ce_err for errors at TL=0
12060Sstevel@tonic-gate *    (Note that trap 0x63 cannot happen at trap level > 0)
12070Sstevel@tonic-gate *
12080Sstevel@tonic-gate * Trap level one handlers panic the system except for the fast ecc
12090Sstevel@tonic-gate * error handler which tries to recover from certain errors.
12100Sstevel@tonic-gate */
12110Sstevel@tonic-gate
12120Sstevel@tonic-gate/*
12130Sstevel@tonic-gate * FAST ECC TRAP STRATEGY:
12140Sstevel@tonic-gate *
12150Sstevel@tonic-gate * Software must handle single and multi bit errors which occur due to data
12160Sstevel@tonic-gate * or instruction cache reads from the external cache. A single or multi bit
12170Sstevel@tonic-gate * error occuring in one of these situations results in a precise trap.
12180Sstevel@tonic-gate *
12190Sstevel@tonic-gate * The basic flow of this trap handler is as follows:
12200Sstevel@tonic-gate *
12210Sstevel@tonic-gate * 1) Record the state and then turn off the Dcache and Icache.  The Dcache
12220Sstevel@tonic-gate *    is disabled because bad data could have been installed.  The Icache is
12230Sstevel@tonic-gate *    turned off because we want to capture the Icache line related to the
12240Sstevel@tonic-gate *    AFAR.
12250Sstevel@tonic-gate * 2) Disable trapping on CEEN/NCCEN errors during TL=0 processing.
12260Sstevel@tonic-gate * 3) Park sibling core if caches are shared (to avoid race condition while
12270Sstevel@tonic-gate *    accessing shared resources such as L3 data staging register during
12280Sstevel@tonic-gate *    CPU logout.
12290Sstevel@tonic-gate * 4) Read the AFAR and AFSR.
12300Sstevel@tonic-gate * 5) If CPU logout structure is not being used, then:
12310Sstevel@tonic-gate *    6) Clear all errors from the AFSR.
12320Sstevel@tonic-gate *    7) Capture Ecache, Dcache and Icache lines in "CPU log out" structure.
12330Sstevel@tonic-gate *    8) Flush Ecache then Flush Dcache and Icache and restore to previous
12340Sstevel@tonic-gate *       state.
12350Sstevel@tonic-gate *    9) Unpark sibling core if we parked it earlier.
12360Sstevel@tonic-gate *    10) call cpu_fast_ecc_error via systrap at PIL 14 unless we're already
12370Sstevel@tonic-gate *        running at PIL 15.
12380Sstevel@tonic-gate * 6) Otherwise, if CPU logout structure is being used:
12390Sstevel@tonic-gate *    7) Incriment the "logout busy count".
12400Sstevel@tonic-gate *    8) Flush Ecache then Flush Dcache and Icache and restore to previous
12410Sstevel@tonic-gate *       state.
12420Sstevel@tonic-gate *    9) Unpark sibling core if we parked it earlier.
12430Sstevel@tonic-gate *    10) Issue a retry since the other CPU error logging code will end up
12440Sstevel@tonic-gate *       finding this error bit and logging information about it later.
12450Sstevel@tonic-gate * 7) Alternatively (to 5 and 6 above), if the cpu_private struct is not
12460Sstevel@tonic-gate *    yet initialized such that we can't even check the logout struct, then
12470Sstevel@tonic-gate *    we place the clo_flags data into %g2 (sys_trap->have_win arg #1) and
12480Sstevel@tonic-gate *    call cpu_fast_ecc_error via systrap. The clo_flags parameter is used
1249815Sdilpreet *    to determine information such as TL, TT, CEEN and NCEEN settings, etc
1250815Sdilpreet *    in the high level trap handler since we don't have access to detailed
1251815Sdilpreet *    logout information in cases where the cpu_private struct is not yet
12520Sstevel@tonic-gate *    initialized.
12530Sstevel@tonic-gate *
12540Sstevel@tonic-gate * We flush the E$ and D$ here on TL=1 code to prevent getting nested
12550Sstevel@tonic-gate * Fast ECC traps in the TL=0 code.  If we get a Fast ECC event here in
12560Sstevel@tonic-gate * the TL=1 code, we will go to the Fast ECC at TL>0 handler which,
12570Sstevel@tonic-gate * since it is uses different code/data from this handler, has a better
12580Sstevel@tonic-gate * chance of fixing things up than simply recursing through this code
12590Sstevel@tonic-gate * again (this would probably cause an eventual kernel stack overflow).
12600Sstevel@tonic-gate * If the Fast ECC at TL>0 handler encounters a Fast ECC error before it
12610Sstevel@tonic-gate * can flush the E$ (or the error is a stuck-at bit), we will recurse in
12620Sstevel@tonic-gate * the Fast ECC at TL>0 handler and eventually Red Mode.
12630Sstevel@tonic-gate *
12640Sstevel@tonic-gate * Note that for Cheetah (and only Cheetah), we use alias addresses for
12650Sstevel@tonic-gate * flushing rather than ASI accesses (which don't exist on Cheetah).
12660Sstevel@tonic-gate * Should we encounter a Fast ECC error within this handler on Cheetah,
12670Sstevel@tonic-gate * there's a good chance it's within the ecache_flushaddr buffer (since
12680Sstevel@tonic-gate * it's the largest piece of memory we touch in the handler and it is
12690Sstevel@tonic-gate * usually kernel text/data).  For that reason the Fast ECC at TL>0
12700Sstevel@tonic-gate * handler for Cheetah uses an alternate buffer: ecache_tl1_flushaddr.
12710Sstevel@tonic-gate */
12720Sstevel@tonic-gate
12730Sstevel@tonic-gate/*
12740Sstevel@tonic-gate * Cheetah ecc-protected E$ trap (Trap 70) at TL=0
12750Sstevel@tonic-gate * tt0_fecc is replaced by fecc_err_instr in cpu_init_trap of the various
12760Sstevel@tonic-gate * architecture-specific files.
12770Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must
12780Sstevel@tonic-gate *     be relocatable.
12790Sstevel@tonic-gate */
12800Sstevel@tonic-gate
12810Sstevel@tonic-gate#if defined(lint)
12820Sstevel@tonic-gate
12830Sstevel@tonic-gatevoid
12840Sstevel@tonic-gatefecc_err_instr(void)
12850Sstevel@tonic-gate{}
12860Sstevel@tonic-gate
12870Sstevel@tonic-gate#else	/* lint */
12880Sstevel@tonic-gate
12890Sstevel@tonic-gate	ENTRY_NP(fecc_err_instr)
12900Sstevel@tonic-gate	membar	#Sync			! Cheetah requires membar #Sync
12910Sstevel@tonic-gate
12920Sstevel@tonic-gate	/*
12930Sstevel@tonic-gate	 * Save current DCU state.  Turn off the Dcache and Icache.
12940Sstevel@tonic-gate	 */
12950Sstevel@tonic-gate	ldxa	[%g0]ASI_DCU, %g1	! save DCU in %g1
12960Sstevel@tonic-gate	andn	%g1, DCU_DC + DCU_IC, %g4
12970Sstevel@tonic-gate	stxa	%g4, [%g0]ASI_DCU
12980Sstevel@tonic-gate	flush	%g0	/* flush required after changing the IC bit */
12990Sstevel@tonic-gate
13000Sstevel@tonic-gate	ASM_JMP(%g4, fast_ecc_err)
13010Sstevel@tonic-gate	SET_SIZE(fecc_err_instr)
13020Sstevel@tonic-gate
13030Sstevel@tonic-gate#endif	/* lint */
13040Sstevel@tonic-gate
13050Sstevel@tonic-gate
13060Sstevel@tonic-gate#if !(defined(JALAPENO) || defined(SERRANO))
13070Sstevel@tonic-gate
13080Sstevel@tonic-gate#if defined(lint)
13090Sstevel@tonic-gate
13100Sstevel@tonic-gatevoid
13110Sstevel@tonic-gatefast_ecc_err(void)
13120Sstevel@tonic-gate{}
13130Sstevel@tonic-gate
13140Sstevel@tonic-gate#else	/* lint */
13150Sstevel@tonic-gate
13160Sstevel@tonic-gate	.section ".text"
13170Sstevel@tonic-gate	.align	64
13180Sstevel@tonic-gate	ENTRY_NP(fast_ecc_err)
13190Sstevel@tonic-gate
13200Sstevel@tonic-gate	/*
13210Sstevel@tonic-gate	 * Turn off CEEN and NCEEN.
13220Sstevel@tonic-gate	 */
13230Sstevel@tonic-gate	ldxa	[%g0]ASI_ESTATE_ERR, %g3
13240Sstevel@tonic-gate	andn	%g3, EN_REG_NCEEN + EN_REG_CEEN, %g4
13250Sstevel@tonic-gate	stxa	%g4, [%g0]ASI_ESTATE_ERR
13260Sstevel@tonic-gate	membar	#Sync			! membar sync required
13270Sstevel@tonic-gate
13280Sstevel@tonic-gate	/*
13290Sstevel@tonic-gate	 * Check to see whether we need to park our sibling core
13300Sstevel@tonic-gate	 * before recording diagnostic information from caches
13310Sstevel@tonic-gate	 * which may be shared by both cores.
13320Sstevel@tonic-gate	 * We use %g1 to store information about whether or not
13330Sstevel@tonic-gate	 * we had to park the core (%g1 holds our DCUCR value and
13340Sstevel@tonic-gate	 * we only use bits from that register which are "reserved"
13350Sstevel@tonic-gate	 * to keep track of core parking) so that we know whether
13360Sstevel@tonic-gate	 * or not to unpark later. %g5 and %g4 are scratch registers.
13370Sstevel@tonic-gate	 */
13380Sstevel@tonic-gate	PARK_SIBLING_CORE(%g1, %g5, %g4)
13390Sstevel@tonic-gate
13400Sstevel@tonic-gate	/*
13410Sstevel@tonic-gate	 * Do the CPU log out capture.
13420Sstevel@tonic-gate	 *   %g3 = "failed?" return value.
13430Sstevel@tonic-gate	 *   %g2 = Input = AFAR. Output the clo_flags info which is passed
13440Sstevel@tonic-gate	 *         into this macro via %g4. Output only valid if cpu_private
13450Sstevel@tonic-gate	 *         struct has not been initialized.
13460Sstevel@tonic-gate	 *   CHPR_FECCTL0_LOGOUT = cpu logout structure offset input
13470Sstevel@tonic-gate	 *   %g4 = Trap information stored in the cpu logout flags field
13480Sstevel@tonic-gate	 *   %g5 = scr1
13490Sstevel@tonic-gate	 *   %g6 = scr2
13500Sstevel@tonic-gate	 *   %g3 = scr3
13510Sstevel@tonic-gate	 *   %g4 = scr4
13520Sstevel@tonic-gate	 */
1353815Sdilpreet	 /* store the CEEN and NCEEN values, TL=0 */
1354815Sdilpreet	and	%g3, EN_REG_CEEN + EN_REG_NCEEN, %g4
13550Sstevel@tonic-gate	set	CHPR_FECCTL0_LOGOUT, %g6
13560Sstevel@tonic-gate	DO_CPU_LOGOUT(%g3, %g2, %g6, %g4, %g5, %g6, %g3, %g4)
13570Sstevel@tonic-gate
13580Sstevel@tonic-gate	/*
13590Sstevel@tonic-gate	 * Flush the Ecache (and L2 cache for Panther) to get the error out
13600Sstevel@tonic-gate	 * of the Ecache.  If the UCC or UCU is on a dirty line, then the
13610Sstevel@tonic-gate	 * following flush will turn that into a WDC or WDU, respectively.
13620Sstevel@tonic-gate	 */
13630Sstevel@tonic-gate	PN_L2_FLUSHALL(%g4, %g5, %g6)
13640Sstevel@tonic-gate
13650Sstevel@tonic-gate	CPU_INDEX(%g4, %g5)
13660Sstevel@tonic-gate	mulx	%g4, CPU_NODE_SIZE, %g4
13670Sstevel@tonic-gate	set	cpunodes, %g5
13680Sstevel@tonic-gate	add	%g4, %g5, %g4
13690Sstevel@tonic-gate	ld	[%g4 + ECACHE_LINESIZE], %g5
13700Sstevel@tonic-gate	ld	[%g4 + ECACHE_SIZE], %g4
13710Sstevel@tonic-gate
13720Sstevel@tonic-gate	ASM_LDX(%g6, ecache_flushaddr)
13730Sstevel@tonic-gate	ECACHE_FLUSHALL(%g4, %g5, %g6, %g7)
13740Sstevel@tonic-gate
13750Sstevel@tonic-gate	/*
13760Sstevel@tonic-gate	 * Flush the Dcache.  Since bad data could have been installed in
13770Sstevel@tonic-gate	 * the Dcache we must flush it before re-enabling it.
13780Sstevel@tonic-gate	 */
13790Sstevel@tonic-gate	ASM_LD(%g5, dcache_size)
13800Sstevel@tonic-gate	ASM_LD(%g6, dcache_linesize)
13810Sstevel@tonic-gate	CH_DCACHE_FLUSHALL(%g5, %g6, %g7)
13820Sstevel@tonic-gate
13830Sstevel@tonic-gate	/*
13840Sstevel@tonic-gate	 * Flush the Icache.  Since we turned off the Icache to capture the
13850Sstevel@tonic-gate	 * Icache line it is now stale or corrupted and we must flush it
13860Sstevel@tonic-gate	 * before re-enabling it.
13870Sstevel@tonic-gate	 */
13880Sstevel@tonic-gate	GET_CPU_PRIVATE_PTR(%g0, %g5, %g7, fast_ecc_err_5);
13890Sstevel@tonic-gate	ld	[%g5 + CHPR_ICACHE_LINESIZE], %g6
13900Sstevel@tonic-gate	ba,pt	%icc, 6f
13910Sstevel@tonic-gate	  ld	[%g5 + CHPR_ICACHE_SIZE], %g5
13920Sstevel@tonic-gatefast_ecc_err_5:
13930Sstevel@tonic-gate	ASM_LD(%g5, icache_size)
13940Sstevel@tonic-gate	ASM_LD(%g6, icache_linesize)
13950Sstevel@tonic-gate6:
13960Sstevel@tonic-gate	CH_ICACHE_FLUSHALL(%g5, %g6, %g7, %g4)
13970Sstevel@tonic-gate
13980Sstevel@tonic-gate	/*
13990Sstevel@tonic-gate	 * check to see whether we parked our sibling core at the start
14000Sstevel@tonic-gate	 * of this handler. If so, we need to unpark it here.
14010Sstevel@tonic-gate	 * We use DCUCR reserved bits (stored in %g1) to keep track of
14020Sstevel@tonic-gate	 * whether or not we need to unpark. %g5 and %g4 are scratch registers.
14030Sstevel@tonic-gate	 */
14040Sstevel@tonic-gate	UNPARK_SIBLING_CORE(%g1, %g5, %g4)
14050Sstevel@tonic-gate
14060Sstevel@tonic-gate	/*
14070Sstevel@tonic-gate	 * Restore the Dcache and Icache to the previous state.
14080Sstevel@tonic-gate	 */
14090Sstevel@tonic-gate	stxa	%g1, [%g0]ASI_DCU
14100Sstevel@tonic-gate	flush	%g0	/* flush required after changing the IC bit */
14110Sstevel@tonic-gate
14120Sstevel@tonic-gate	/*
14130Sstevel@tonic-gate	 * Make sure our CPU logout operation was successful.
14140Sstevel@tonic-gate	 */
14150Sstevel@tonic-gate	cmp	%g3, %g0
14160Sstevel@tonic-gate	be	8f
14170Sstevel@tonic-gate	  nop
14180Sstevel@tonic-gate
14190Sstevel@tonic-gate	/*
14200Sstevel@tonic-gate	 * If the logout structure had been busy, how many times have
14210Sstevel@tonic-gate	 * we tried to use it and failed (nesting count)? If we have
14220Sstevel@tonic-gate	 * already recursed a substantial number of times, then we can
14230Sstevel@tonic-gate	 * assume things are not going to get better by themselves and
14240Sstevel@tonic-gate	 * so it would be best to panic.
14250Sstevel@tonic-gate	 */
14260Sstevel@tonic-gate	cmp	%g3, CLO_NESTING_MAX
14270Sstevel@tonic-gate	blt	7f
14280Sstevel@tonic-gate	  nop
14290Sstevel@tonic-gate
14300Sstevel@tonic-gate        call ptl1_panic
14310Sstevel@tonic-gate          mov   PTL1_BAD_ECC, %g1
14320Sstevel@tonic-gate
14330Sstevel@tonic-gate7:
14340Sstevel@tonic-gate	/*
14350Sstevel@tonic-gate	 * Otherwise, if the logout structure was busy but we have not
14360Sstevel@tonic-gate	 * nested more times than our maximum value, then we simply
14370Sstevel@tonic-gate	 * issue a retry. Our TL=0 trap handler code will check and
14380Sstevel@tonic-gate	 * clear the AFSR after it is done logging what is currently
14390Sstevel@tonic-gate	 * in the logout struct and handle this event at that time.
14400Sstevel@tonic-gate	 */
14410Sstevel@tonic-gate	retry
14420Sstevel@tonic-gate8:
14430Sstevel@tonic-gate	/*
14440Sstevel@tonic-gate	 * Call cpu_fast_ecc_error via systrap at PIL 14 unless we're
14450Sstevel@tonic-gate	 * already at PIL 15.
14460Sstevel@tonic-gate	 */
14470Sstevel@tonic-gate	set	cpu_fast_ecc_error, %g1
14480Sstevel@tonic-gate	rdpr	%pil, %g4
14490Sstevel@tonic-gate	cmp	%g4, PIL_14
14500Sstevel@tonic-gate	ba	sys_trap
14510Sstevel@tonic-gate	  movl	%icc, PIL_14, %g4
14520Sstevel@tonic-gate
14530Sstevel@tonic-gate	SET_SIZE(fast_ecc_err)
14540Sstevel@tonic-gate
14550Sstevel@tonic-gate#endif	/* lint */
14560Sstevel@tonic-gate
14570Sstevel@tonic-gate#endif	/* !(JALAPENO || SERRANO) */
14580Sstevel@tonic-gate
14590Sstevel@tonic-gate
14600Sstevel@tonic-gate/*
14610Sstevel@tonic-gate * Cheetah/Cheetah+ Fast ECC at TL>0 trap strategy:
14620Sstevel@tonic-gate *
14630Sstevel@tonic-gate * The basic flow of this trap handler is as follows:
14640Sstevel@tonic-gate *
14650Sstevel@tonic-gate * 1) In the "trap 70" trap table code (fecc_err_tl1_instr), generate a
14660Sstevel@tonic-gate *    software trap 0 ("ta 0") to buy an extra set of %tpc, etc. which we
14670Sstevel@tonic-gate *    will use to save %g1 and %g2.
14680Sstevel@tonic-gate * 2) At the software trap 0 at TL>0 trap table code (fecc_err_tl1_cont_instr),
14690Sstevel@tonic-gate *    we save %g1+%g2 using %tpc, %tnpc + %tstate and jump to the fast ecc
14700Sstevel@tonic-gate *    handler (using the just saved %g1).
14710Sstevel@tonic-gate * 3) Turn off the Dcache if it was on and save the state of the Dcache
14720Sstevel@tonic-gate *    (whether on or off) in Bit2 (CH_ERR_TSTATE_DC_ON) of %tstate.
14730Sstevel@tonic-gate *    NB: we don't turn off the Icache because bad data is not installed nor
14740Sstevel@tonic-gate *        will we be doing any diagnostic accesses.
14750Sstevel@tonic-gate * 4) compute physical address of the per-cpu/per-tl save area using %g1+%g2
14760Sstevel@tonic-gate * 5) Save %g1-%g7 into the per-cpu/per-tl save area (%g1 + %g2 from the
14770Sstevel@tonic-gate *    %tpc, %tnpc, %tstate values previously saved).
14780Sstevel@tonic-gate * 6) set %tl to %tl - 1.
14790Sstevel@tonic-gate * 7) Save the appropriate flags and TPC in the ch_err_tl1_data structure.
14800Sstevel@tonic-gate * 8) Save the value of CH_ERR_TSTATE_DC_ON in the ch_err_tl1_tmp field.
14810Sstevel@tonic-gate * 9) For Cheetah and Jalapeno, read the AFAR and AFSR and clear.  For
14820Sstevel@tonic-gate *    Cheetah+ (and later), read the shadow AFAR and AFSR but don't clear.
14830Sstevel@tonic-gate *    Save the values in ch_err_tl1_data.  For Panther, read the shadow
14840Sstevel@tonic-gate *    AFSR_EXT and save the value in ch_err_tl1_data.
14850Sstevel@tonic-gate * 10) Disable CEEN/NCEEN to prevent any disrupting/deferred errors from
14860Sstevel@tonic-gate *    being queued.  We'll report them via the AFSR/AFAR capture in step 13.
14870Sstevel@tonic-gate * 11) Flush the Ecache.
14880Sstevel@tonic-gate *    NB: the Ecache is flushed assuming the largest possible size with
14890Sstevel@tonic-gate *        the smallest possible line size since access to the cpu_nodes may
14900Sstevel@tonic-gate *        cause an unrecoverable DTLB miss.
14910Sstevel@tonic-gate * 12) Reenable CEEN/NCEEN with the value saved from step 10.
14920Sstevel@tonic-gate * 13) For Cheetah and Jalapeno, read the AFAR and AFSR and clear again.
14930Sstevel@tonic-gate *    For Cheetah+ (and later), read the primary AFAR and AFSR and now clear.
14940Sstevel@tonic-gate *    Save the read AFSR/AFAR values in ch_err_tl1_data.  For Panther,
14950Sstevel@tonic-gate *    read and clear the primary AFSR_EXT and save it in ch_err_tl1_data.
14960Sstevel@tonic-gate * 14) Flush and re-enable the Dcache if it was on at step 3.
14970Sstevel@tonic-gate * 15) Do TRAPTRACE if enabled.
14980Sstevel@tonic-gate * 16) Check if a UCU->WDU (or L3_UCU->WDU for Panther) happened, panic if so.
14990Sstevel@tonic-gate * 17) Set the event pending flag in ch_err_tl1_pending[CPU]
15000Sstevel@tonic-gate * 18) Cause a softint 15.  The pil15_interrupt handler will inspect the
15010Sstevel@tonic-gate *    event pending flag and call cpu_tl1_error via systrap if set.
15020Sstevel@tonic-gate * 19) Restore the registers from step 5 and issue retry.
15030Sstevel@tonic-gate */
15040Sstevel@tonic-gate
15050Sstevel@tonic-gate/*
15060Sstevel@tonic-gate * Cheetah ecc-protected E$ trap (Trap 70) at TL>0
15070Sstevel@tonic-gate * tt1_fecc is replaced by fecc_err_tl1_instr in cpu_init_trap of the various
15080Sstevel@tonic-gate * architecture-specific files.  This generates a "Software Trap 0" at TL>0,
15090Sstevel@tonic-gate * which goes to fecc_err_tl1_cont_instr, and we continue the handling there.
15100Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must
15110Sstevel@tonic-gate *     be relocatable.
15120Sstevel@tonic-gate */
15130Sstevel@tonic-gate
15140Sstevel@tonic-gate#if defined(lint)
15150Sstevel@tonic-gate
15160Sstevel@tonic-gatevoid
15170Sstevel@tonic-gatefecc_err_tl1_instr(void)
15180Sstevel@tonic-gate{}
15190Sstevel@tonic-gate
15200Sstevel@tonic-gate#else	/* lint */
15210Sstevel@tonic-gate
15220Sstevel@tonic-gate	ENTRY_NP(fecc_err_tl1_instr)
15230Sstevel@tonic-gate	CH_ERR_TL1_TRAPENTRY(SWTRAP_0);
15240Sstevel@tonic-gate	SET_SIZE(fecc_err_tl1_instr)
15250Sstevel@tonic-gate
15260Sstevel@tonic-gate#endif	/* lint */
15270Sstevel@tonic-gate
15280Sstevel@tonic-gate/*
15290Sstevel@tonic-gate * Software trap 0 at TL>0.
15300Sstevel@tonic-gate * tt1_swtrap0 is replaced by fecc_err_tl1_cont_instr in cpu_init_trap of
15310Sstevel@tonic-gate * the various architecture-specific files.  This is used as a continuation
15320Sstevel@tonic-gate * of the fast ecc handling where we've bought an extra TL level, so we can
15330Sstevel@tonic-gate * use %tpc, %tnpc, %tstate to temporarily save the value of registers %g1
15340Sstevel@tonic-gate * and %g2.  Note that %tstate has bits 0-2 and then bits 8-19 as r/w,
15350Sstevel@tonic-gate * there's a reserved hole from 3-7.  We only use bits 0-1 and 8-9 (the low
15360Sstevel@tonic-gate * order two bits from %g1 and %g2 respectively).
15370Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must
15380Sstevel@tonic-gate *     be relocatable.
15390Sstevel@tonic-gate */
15400Sstevel@tonic-gate#if defined(lint)
15410Sstevel@tonic-gate
15420Sstevel@tonic-gatevoid
15430Sstevel@tonic-gatefecc_err_tl1_cont_instr(void)
15440Sstevel@tonic-gate{}
15450Sstevel@tonic-gate
15460Sstevel@tonic-gate#else	/* lint */
15470Sstevel@tonic-gate
15480Sstevel@tonic-gate	ENTRY_NP(fecc_err_tl1_cont_instr)
15490Sstevel@tonic-gate	CH_ERR_TL1_SWTRAPENTRY(fast_ecc_tl1_err)
15500Sstevel@tonic-gate	SET_SIZE(fecc_err_tl1_cont_instr)
15510Sstevel@tonic-gate
15520Sstevel@tonic-gate#endif	/* lint */
15530Sstevel@tonic-gate
15540Sstevel@tonic-gate
15550Sstevel@tonic-gate#if defined(lint)
15560Sstevel@tonic-gate
15570Sstevel@tonic-gatevoid
15580Sstevel@tonic-gatece_err(void)
15590Sstevel@tonic-gate{}
15600Sstevel@tonic-gate
15610Sstevel@tonic-gate#else	/* lint */
15620Sstevel@tonic-gate
15630Sstevel@tonic-gate/*
15640Sstevel@tonic-gate * The ce_err function handles disrupting trap type 0x63 at TL=0.
15650Sstevel@tonic-gate *
15660Sstevel@tonic-gate * AFSR errors bits which cause this trap are:
15670Sstevel@tonic-gate *	CE, EMC, EDU:ST, EDC, WDU, WDC, CPU, CPC, IVU, IVC
15680Sstevel@tonic-gate *
15690Sstevel@tonic-gate * NCEEN Bit of Cheetah External Cache Error Enable Register enables
15700Sstevel@tonic-gate * the following AFSR disrupting traps: EDU:ST, WDU, CPU, IVU
15710Sstevel@tonic-gate *
15720Sstevel@tonic-gate * CEEN Bit of Cheetah External Cache Error Enable Register enables
15730Sstevel@tonic-gate * the following AFSR disrupting traps: CE, EMC, EDC, WDC, CPC, IVC
15740Sstevel@tonic-gate *
15750Sstevel@tonic-gate * Cheetah+ also handles (No additional processing required):
15760Sstevel@tonic-gate *    DUE, DTO, DBERR	(NCEEN controlled)
15770Sstevel@tonic-gate *    THCE		(CEEN and ET_ECC_en controlled)
15780Sstevel@tonic-gate *    TUE		(ET_ECC_en controlled)
15790Sstevel@tonic-gate *
15800Sstevel@tonic-gate * Panther further adds:
15810Sstevel@tonic-gate *    IMU, L3_EDU, L3_WDU, L3_CPU		(NCEEN controlled)
15820Sstevel@tonic-gate *    IMC, L3_EDC, L3_WDC, L3_CPC, L3_THCE	(CEEN controlled)
15830Sstevel@tonic-gate *    TUE_SH, TUE		(NCEEN and L2_tag_ECC_en controlled)
15840Sstevel@tonic-gate *    L3_TUE, L3_TUE_SH		(NCEEN and ET_ECC_en controlled)
15850Sstevel@tonic-gate *    THCE			(CEEN and L2_tag_ECC_en controlled)
15860Sstevel@tonic-gate *    L3_THCE			(CEEN and ET_ECC_en controlled)
15870Sstevel@tonic-gate *
15880Sstevel@tonic-gate * Steps:
15890Sstevel@tonic-gate *	1. Disable hardware corrected disrupting errors only (CEEN)
15900Sstevel@tonic-gate *	2. Park sibling core if caches are shared (to avoid race
15910Sstevel@tonic-gate *	   condition while accessing shared resources such as L3
15920Sstevel@tonic-gate *	   data staging register during CPU logout.
15930Sstevel@tonic-gate *	3. If the CPU logout structure is not currently being used:
15940Sstevel@tonic-gate *		4. Clear AFSR error bits
15950Sstevel@tonic-gate *		5. Capture Ecache, Dcache and Icache lines associated
15960Sstevel@tonic-gate *		   with AFAR.
15970Sstevel@tonic-gate *		6. Unpark sibling core if we parked it earlier.
15980Sstevel@tonic-gate *		7. call cpu_disrupting_error via sys_trap at PIL 14
15990Sstevel@tonic-gate *		   unless we're already running at PIL 15.
16000Sstevel@tonic-gate *	4. Otherwise, if the CPU logout structure is busy:
16010Sstevel@tonic-gate *		5. Incriment "logout busy count" and place into %g3
16020Sstevel@tonic-gate *		6. Unpark sibling core if we parked it earlier.
16030Sstevel@tonic-gate *		7. Issue a retry since the other CPU error logging
16040Sstevel@tonic-gate *		   code will end up finding this error bit and logging
16050Sstevel@tonic-gate *		   information about it later.
16060Sstevel@tonic-gate *	5. Alternatively (to 3 and 4 above), if the cpu_private struct is
16070Sstevel@tonic-gate *         not yet initialized such that we can't even check the logout
16080Sstevel@tonic-gate *         struct, then we place the clo_flags data into %g2
16090Sstevel@tonic-gate *         (sys_trap->have_win arg #1) and call cpu_disrupting_error via
16100Sstevel@tonic-gate *         systrap. The clo_flags parameter is used to determine information
16110Sstevel@tonic-gate *         such as TL, TT, CEEN settings, etc in the high level trap
16120Sstevel@tonic-gate *         handler since we don't have access to detailed logout information
16130Sstevel@tonic-gate *         in cases where the cpu_private struct is not yet initialized.
16140Sstevel@tonic-gate *
16150Sstevel@tonic-gate * %g3: [ logout busy count ] - arg #2
16160Sstevel@tonic-gate * %g2: [ clo_flags if cpu_private unavailable ] - sys_trap->have_win: arg #1
16170Sstevel@tonic-gate */
16180Sstevel@tonic-gate
16190Sstevel@tonic-gate	.align	128
16200Sstevel@tonic-gate	ENTRY_NP(ce_err)
16210Sstevel@tonic-gate	membar	#Sync			! Cheetah requires membar #Sync
16220Sstevel@tonic-gate
16230Sstevel@tonic-gate	/*
16240Sstevel@tonic-gate	 * Disable trap on hardware corrected errors (CEEN) while at TL=0
16250Sstevel@tonic-gate	 * to prevent recursion.
16260Sstevel@tonic-gate	 */
16270Sstevel@tonic-gate	ldxa	[%g0]ASI_ESTATE_ERR, %g1
16280Sstevel@tonic-gate	bclr	EN_REG_CEEN, %g1
16290Sstevel@tonic-gate	stxa	%g1, [%g0]ASI_ESTATE_ERR
16300Sstevel@tonic-gate	membar	#Sync			! membar sync required
16310Sstevel@tonic-gate
16320Sstevel@tonic-gate	/*
16330Sstevel@tonic-gate	 * Save current DCU state.  Turn off Icache to allow capture of
16340Sstevel@tonic-gate	 * Icache data by DO_CPU_LOGOUT.
16350Sstevel@tonic-gate	 */
16360Sstevel@tonic-gate	ldxa	[%g0]ASI_DCU, %g1	! save DCU in %g1
16370Sstevel@tonic-gate	andn	%g1, DCU_IC, %g4
16380Sstevel@tonic-gate	stxa	%g4, [%g0]ASI_DCU
16390Sstevel@tonic-gate	flush	%g0	/* flush required after changing the IC bit */
16400Sstevel@tonic-gate
16410Sstevel@tonic-gate	/*
16420Sstevel@tonic-gate	 * Check to see whether we need to park our sibling core
16430Sstevel@tonic-gate	 * before recording diagnostic information from caches
16440Sstevel@tonic-gate	 * which may be shared by both cores.
16450Sstevel@tonic-gate	 * We use %g1 to store information about whether or not
16460Sstevel@tonic-gate	 * we had to park the core (%g1 holds our DCUCR value and
16470Sstevel@tonic-gate	 * we only use bits from that register which are "reserved"
16480Sstevel@tonic-gate	 * to keep track of core parking) so that we know whether
16490Sstevel@tonic-gate	 * or not to unpark later. %g5 and %g4 are scratch registers.
16500Sstevel@tonic-gate	 */
16510Sstevel@tonic-gate	PARK_SIBLING_CORE(%g1, %g5, %g4)
16520Sstevel@tonic-gate
16530Sstevel@tonic-gate	/*
16540Sstevel@tonic-gate	 * Do the CPU log out capture.
16550Sstevel@tonic-gate	 *   %g3 = "failed?" return value.
16560Sstevel@tonic-gate	 *   %g2 = Input = AFAR. Output the clo_flags info which is passed
16570Sstevel@tonic-gate	 *         into this macro via %g4. Output only valid if cpu_private
16580Sstevel@tonic-gate	 *         struct has not been initialized.
16590Sstevel@tonic-gate	 *   CHPR_CECC_LOGOUT = cpu logout structure offset input
16600Sstevel@tonic-gate	 *   %g4 = Trap information stored in the cpu logout flags field
16610Sstevel@tonic-gate	 *   %g5 = scr1
16620Sstevel@tonic-gate	 *   %g6 = scr2
16630Sstevel@tonic-gate	 *   %g3 = scr3
16640Sstevel@tonic-gate	 *   %g4 = scr4
16650Sstevel@tonic-gate	 */
16660Sstevel@tonic-gate	clr	%g4			! TL=0 bit in afsr
16670Sstevel@tonic-gate	set	CHPR_CECC_LOGOUT, %g6
16680Sstevel@tonic-gate	DO_CPU_LOGOUT(%g3, %g2, %g6, %g4, %g5, %g6, %g3, %g4)
16690Sstevel@tonic-gate
16700Sstevel@tonic-gate	/*
16710Sstevel@tonic-gate	 * Flush the Icache.  Since we turned off the Icache to capture the
16720Sstevel@tonic-gate	 * Icache line it is now stale or corrupted and we must flush it
16730Sstevel@tonic-gate	 * before re-enabling it.
16740Sstevel@tonic-gate	 */
16750Sstevel@tonic-gate	GET_CPU_PRIVATE_PTR(%g0, %g5, %g7, ce_err_1);
16760Sstevel@tonic-gate	ld	[%g5 + CHPR_ICACHE_LINESIZE], %g6
16770Sstevel@tonic-gate	ba,pt	%icc, 2f
16780Sstevel@tonic-gate	  ld	[%g5 + CHPR_ICACHE_SIZE], %g5
16790Sstevel@tonic-gatece_err_1:
16800Sstevel@tonic-gate	ASM_LD(%g5, icache_size)
16810Sstevel@tonic-gate	ASM_LD(%g6, icache_linesize)
16820Sstevel@tonic-gate2:
16830Sstevel@tonic-gate	CH_ICACHE_FLUSHALL(%g5, %g6, %g7, %g4)
16840Sstevel@tonic-gate
16850Sstevel@tonic-gate	/*
16860Sstevel@tonic-gate	 * check to see whether we parked our sibling core at the start
16870Sstevel@tonic-gate	 * of this handler. If so, we need to unpark it here.
16880Sstevel@tonic-gate	 * We use DCUCR reserved bits (stored in %g1) to keep track of
16890Sstevel@tonic-gate	 * whether or not we need to unpark. %g5 and %g4 are scratch registers.
16900Sstevel@tonic-gate	 */
16910Sstevel@tonic-gate	UNPARK_SIBLING_CORE(%g1, %g5, %g4)
16920Sstevel@tonic-gate
16930Sstevel@tonic-gate	/*
16940Sstevel@tonic-gate	 * Restore Icache to previous state.
16950Sstevel@tonic-gate	 */
16960Sstevel@tonic-gate	stxa	%g1, [%g0]ASI_DCU
16970Sstevel@tonic-gate	flush	%g0	/* flush required after changing the IC bit */
16980Sstevel@tonic-gate
16990Sstevel@tonic-gate	/*
17000Sstevel@tonic-gate	 * Make sure our CPU logout operation was successful.
17010Sstevel@tonic-gate	 */
17020Sstevel@tonic-gate	cmp	%g3, %g0
17030Sstevel@tonic-gate	be	4f
17040Sstevel@tonic-gate	  nop
17050Sstevel@tonic-gate
17060Sstevel@tonic-gate	/*
17070Sstevel@tonic-gate	 * If the logout structure had been busy, how many times have
17080Sstevel@tonic-gate	 * we tried to use it and failed (nesting count)? If we have
17090Sstevel@tonic-gate	 * already recursed a substantial number of times, then we can
17100Sstevel@tonic-gate	 * assume things are not going to get better by themselves and
17110Sstevel@tonic-gate	 * so it would be best to panic.
17120Sstevel@tonic-gate	 */
17130Sstevel@tonic-gate	cmp	%g3, CLO_NESTING_MAX
17140Sstevel@tonic-gate	blt	3f
17150Sstevel@tonic-gate	  nop
17160Sstevel@tonic-gate
17170Sstevel@tonic-gate        call ptl1_panic
17180Sstevel@tonic-gate          mov   PTL1_BAD_ECC, %g1
17190Sstevel@tonic-gate
17200Sstevel@tonic-gate3:
17210Sstevel@tonic-gate	/*
17220Sstevel@tonic-gate	 * Otherwise, if the logout structure was busy but we have not
17230Sstevel@tonic-gate	 * nested more times than our maximum value, then we simply
17240Sstevel@tonic-gate	 * issue a retry. Our TL=0 trap handler code will check and
17250Sstevel@tonic-gate	 * clear the AFSR after it is done logging what is currently
17260Sstevel@tonic-gate	 * in the logout struct and handle this event at that time.
17270Sstevel@tonic-gate	 */
17280Sstevel@tonic-gate	retry
17290Sstevel@tonic-gate4:
17300Sstevel@tonic-gate	/*
17310Sstevel@tonic-gate	 * Call cpu_disrupting_error via systrap at PIL 14 unless we're
17320Sstevel@tonic-gate	 * already at PIL 15.
17330Sstevel@tonic-gate	 */
17340Sstevel@tonic-gate	set	cpu_disrupting_error, %g1
17350Sstevel@tonic-gate	rdpr	%pil, %g4
17360Sstevel@tonic-gate	cmp	%g4, PIL_14
17370Sstevel@tonic-gate	ba	sys_trap
17380Sstevel@tonic-gate	  movl	%icc, PIL_14, %g4
17390Sstevel@tonic-gate	SET_SIZE(ce_err)
17400Sstevel@tonic-gate
17410Sstevel@tonic-gate#endif	/* lint */
17420Sstevel@tonic-gate
17430Sstevel@tonic-gate
17440Sstevel@tonic-gate#if defined(lint)
17450Sstevel@tonic-gate
17460Sstevel@tonic-gate/*
17470Sstevel@tonic-gate * This trap cannot happen at TL>0 which means this routine will never
17480Sstevel@tonic-gate * actually be called and so we treat this like a BAD TRAP panic.
17490Sstevel@tonic-gate */
17500Sstevel@tonic-gatevoid
17510Sstevel@tonic-gatece_err_tl1(void)
17520Sstevel@tonic-gate{}
17530Sstevel@tonic-gate
17540Sstevel@tonic-gate#else	/* lint */
17550Sstevel@tonic-gate
17560Sstevel@tonic-gate	.align	64
17570Sstevel@tonic-gate	ENTRY_NP(ce_err_tl1)
17580Sstevel@tonic-gate
17590Sstevel@tonic-gate        call ptl1_panic
17600Sstevel@tonic-gate          mov   PTL1_BAD_TRAP, %g1
17610Sstevel@tonic-gate
17620Sstevel@tonic-gate	SET_SIZE(ce_err_tl1)
17630Sstevel@tonic-gate
17640Sstevel@tonic-gate#endif	/* lint */
17650Sstevel@tonic-gate
17660Sstevel@tonic-gate
17670Sstevel@tonic-gate#if defined(lint)
17680Sstevel@tonic-gate
17690Sstevel@tonic-gatevoid
17700Sstevel@tonic-gateasync_err(void)
17710Sstevel@tonic-gate{}
17720Sstevel@tonic-gate
17730Sstevel@tonic-gate#else	/* lint */
17740Sstevel@tonic-gate
17750Sstevel@tonic-gate/*
17760Sstevel@tonic-gate * The async_err function handles deferred trap types 0xA
17770Sstevel@tonic-gate * (instruction_access_error) and 0x32 (data_access_error) at TL>=0.
17780Sstevel@tonic-gate *
17790Sstevel@tonic-gate * AFSR errors bits which cause this trap are:
17800Sstevel@tonic-gate *	UE, EMU, EDU:BLD, L3_EDU:BLD, TO, BERR
17810Sstevel@tonic-gate * On some platforms, EMU may causes cheetah to pull the error pin
17820Sstevel@tonic-gate * never giving Solaris a chance to take a trap.
17830Sstevel@tonic-gate *
17840Sstevel@tonic-gate * NCEEN Bit of Cheetah External Cache Error Enable Register enables
17850Sstevel@tonic-gate * the following AFSR deferred traps: UE, EMU, EDU:BLD, TO, BERR
17860Sstevel@tonic-gate *
17870Sstevel@tonic-gate * Steps:
17880Sstevel@tonic-gate *	1. Disable CEEN and NCEEN errors to prevent recursive errors.
17890Sstevel@tonic-gate *	2. Turn D$ off per Cheetah PRM P.5 Note 6, turn I$ off to capture
17900Sstevel@tonic-gate *         I$ line in DO_CPU_LOGOUT.
17910Sstevel@tonic-gate *	3. Park sibling core if caches are shared (to avoid race
17920Sstevel@tonic-gate *	   condition while accessing shared resources such as L3
17930Sstevel@tonic-gate *	   data staging register during CPU logout.
17940Sstevel@tonic-gate *	4. If the CPU logout structure is not currently being used:
17950Sstevel@tonic-gate *		5. Clear AFSR error bits
17960Sstevel@tonic-gate *		6. Capture Ecache, Dcache and Icache lines associated
17970Sstevel@tonic-gate *		   with AFAR.
17980Sstevel@tonic-gate *		7. Unpark sibling core if we parked it earlier.
17990Sstevel@tonic-gate *		8. call cpu_deferred_error via sys_trap.
18000Sstevel@tonic-gate *	5. Otherwise, if the CPU logout structure is busy:
18010Sstevel@tonic-gate *		6. Incriment "logout busy count"
18020Sstevel@tonic-gate *		7. Unpark sibling core if we parked it earlier.
18030Sstevel@tonic-gate *		8) Issue a retry since the other CPU error logging
18040Sstevel@tonic-gate *		   code will end up finding this error bit and logging
18050Sstevel@tonic-gate *		   information about it later.
18060Sstevel@tonic-gate *      6. Alternatively (to 4 and 5 above), if the cpu_private struct is
18070Sstevel@tonic-gate *         not yet initialized such that we can't even check the logout
18080Sstevel@tonic-gate *         struct, then we place the clo_flags data into %g2
18090Sstevel@tonic-gate *         (sys_trap->have_win arg #1) and call cpu_deferred_error via
18100Sstevel@tonic-gate *         systrap. The clo_flags parameter is used to determine information
18110Sstevel@tonic-gate *         such as TL, TT, CEEN settings, etc in the high level trap handler
18120Sstevel@tonic-gate *         since we don't have access to detailed logout information in cases
18130Sstevel@tonic-gate *         where the cpu_private struct is not yet initialized.
18140Sstevel@tonic-gate *
18150Sstevel@tonic-gate * %g2: [ clo_flags if cpu_private unavailable ] - sys_trap->have_win: arg #1
18160Sstevel@tonic-gate * %g3: [ logout busy count ] - arg #2
18170Sstevel@tonic-gate */
18180Sstevel@tonic-gate
18190Sstevel@tonic-gate	ENTRY_NP(async_err)
18200Sstevel@tonic-gate	membar	#Sync			! Cheetah requires membar #Sync
18210Sstevel@tonic-gate
18220Sstevel@tonic-gate	/*
18230Sstevel@tonic-gate	 * Disable CEEN and NCEEN.
18240Sstevel@tonic-gate	 */
18250Sstevel@tonic-gate	ldxa	[%g0]ASI_ESTATE_ERR, %g3
18260Sstevel@tonic-gate	andn	%g3, EN_REG_NCEEN + EN_REG_CEEN, %g4
18270Sstevel@tonic-gate	stxa	%g4, [%g0]ASI_ESTATE_ERR
18280Sstevel@tonic-gate	membar	#Sync			! membar sync required
18290Sstevel@tonic-gate
18300Sstevel@tonic-gate	/*
18310Sstevel@tonic-gate	 * Save current DCU state.
18320Sstevel@tonic-gate	 * Disable Icache to allow capture of Icache data by DO_CPU_LOGOUT.
18330Sstevel@tonic-gate	 * Do this regardless of whether this is a Data Access Error or
18340Sstevel@tonic-gate	 * Instruction Access Error Trap.
18350Sstevel@tonic-gate	 * Disable Dcache for both Data Access Error and Instruction Access
18360Sstevel@tonic-gate	 * Error per Cheetah PRM P.5 Note 6.
18370Sstevel@tonic-gate	 */
18380Sstevel@tonic-gate	ldxa	[%g0]ASI_DCU, %g1	! save DCU in %g1
18390Sstevel@tonic-gate	andn	%g1, DCU_IC + DCU_DC, %g4
18400Sstevel@tonic-gate	stxa	%g4, [%g0]ASI_DCU
18410Sstevel@tonic-gate	flush	%g0	/* flush required after changing the IC bit */
18420Sstevel@tonic-gate
18430Sstevel@tonic-gate	/*
18440Sstevel@tonic-gate	 * Check to see whether we need to park our sibling core
18450Sstevel@tonic-gate	 * before recording diagnostic information from caches
18460Sstevel@tonic-gate	 * which may be shared by both cores.
18470Sstevel@tonic-gate	 * We use %g1 to store information about whether or not
18480Sstevel@tonic-gate	 * we had to park the core (%g1 holds our DCUCR value and
18490Sstevel@tonic-gate	 * we only use bits from that register which are "reserved"
18500Sstevel@tonic-gate	 * to keep track of core parking) so that we know whether
18510Sstevel@tonic-gate	 * or not to unpark later. %g6 and %g4 are scratch registers.
18520Sstevel@tonic-gate	 */
18530Sstevel@tonic-gate	PARK_SIBLING_CORE(%g1, %g6, %g4)
18540Sstevel@tonic-gate
18550Sstevel@tonic-gate	/*
18560Sstevel@tonic-gate	 * Do the CPU logout capture.
18570Sstevel@tonic-gate	 *
18580Sstevel@tonic-gate	 *   %g3 = "failed?" return value.
18590Sstevel@tonic-gate	 *   %g2 = Input = AFAR. Output the clo_flags info which is passed
18600Sstevel@tonic-gate	 *         into this macro via %g4. Output only valid if cpu_private
18610Sstevel@tonic-gate	 *         struct has not been initialized.
18620Sstevel@tonic-gate	 *   CHPR_ASYNC_LOGOUT = cpu logout structure offset input
18630Sstevel@tonic-gate	 *   %g4 = Trap information stored in the cpu logout flags field
18640Sstevel@tonic-gate	 *   %g5 = scr1
18650Sstevel@tonic-gate	 *   %g6 = scr2
18660Sstevel@tonic-gate	 *   %g3 = scr3
18670Sstevel@tonic-gate	 *   %g4 = scr4
18680Sstevel@tonic-gate	 */
18690Sstevel@tonic-gate	andcc	%g5, T_TL1, %g0
18700Sstevel@tonic-gate	clr	%g6
18710Sstevel@tonic-gate	movnz	%xcc, 1, %g6			! set %g6 if T_TL1 set
18720Sstevel@tonic-gate	sllx	%g6, CLO_FLAGS_TL_SHIFT, %g6
18730Sstevel@tonic-gate	sllx	%g5, CLO_FLAGS_TT_SHIFT, %g4
18740Sstevel@tonic-gate	set	CLO_FLAGS_TT_MASK, %g2
18750Sstevel@tonic-gate	and	%g4, %g2, %g4			! ttype
18760Sstevel@tonic-gate	or	%g6, %g4, %g4			! TT and TL
18770Sstevel@tonic-gate	and	%g3, EN_REG_CEEN, %g3		! CEEN value
18780Sstevel@tonic-gate	or	%g3, %g4, %g4			! TT and TL and CEEN
18790Sstevel@tonic-gate	set	CHPR_ASYNC_LOGOUT, %g6
18800Sstevel@tonic-gate	DO_CPU_LOGOUT(%g3, %g2, %g6, %g4, %g5, %g6, %g3, %g4)
18810Sstevel@tonic-gate
18820Sstevel@tonic-gate	/*
18830Sstevel@tonic-gate	 * If the logout struct was busy, we may need to pass the
18840Sstevel@tonic-gate	 * TT, TL, and CEEN information to the TL=0 handler via
18850Sstevel@tonic-gate	 * systrap parameter so save it off here.
18860Sstevel@tonic-gate	 */
18870Sstevel@tonic-gate	cmp	%g3, %g0
18880Sstevel@tonic-gate	be	1f
18890Sstevel@tonic-gate	  nop
18900Sstevel@tonic-gate	sllx	%g4, 32, %g4
18910Sstevel@tonic-gate	or	%g4, %g3, %g3
18920Sstevel@tonic-gate1:
18930Sstevel@tonic-gate	/*
18940Sstevel@tonic-gate	 * Flush the Icache.  Since we turned off the Icache to capture the
18950Sstevel@tonic-gate	 * Icache line it is now stale or corrupted and we must flush it
18960Sstevel@tonic-gate	 * before re-enabling it.
18970Sstevel@tonic-gate	 */
18980Sstevel@tonic-gate	GET_CPU_PRIVATE_PTR(%g0, %g5, %g7, async_err_1);
18990Sstevel@tonic-gate	ld	[%g5 + CHPR_ICACHE_LINESIZE], %g6
19000Sstevel@tonic-gate	ba,pt	%icc, 2f
19010Sstevel@tonic-gate	  ld	[%g5 + CHPR_ICACHE_SIZE], %g5
19020Sstevel@tonic-gateasync_err_1:
19030Sstevel@tonic-gate	ASM_LD(%g5, icache_size)
19040Sstevel@tonic-gate	ASM_LD(%g6, icache_linesize)
19050Sstevel@tonic-gate2:
19060Sstevel@tonic-gate	CH_ICACHE_FLUSHALL(%g5, %g6, %g7, %g4)
19070Sstevel@tonic-gate
19080Sstevel@tonic-gate	/*
19090Sstevel@tonic-gate	 * XXX - Don't we need to flush the Dcache before turning it back
19100Sstevel@tonic-gate	 *       on to avoid stale or corrupt data? Was this broken?
19110Sstevel@tonic-gate	 */
19120Sstevel@tonic-gate	/*
19130Sstevel@tonic-gate	 * Flush the Dcache before turning it back on since it may now
19140Sstevel@tonic-gate	 * contain stale or corrupt data.
19150Sstevel@tonic-gate	 */
19160Sstevel@tonic-gate	ASM_LD(%g5, dcache_size)
19170Sstevel@tonic-gate	ASM_LD(%g6, dcache_linesize)
19180Sstevel@tonic-gate	CH_DCACHE_FLUSHALL(%g5, %g6, %g7)
19190Sstevel@tonic-gate
19200Sstevel@tonic-gate	/*
19210Sstevel@tonic-gate	 * check to see whether we parked our sibling core at the start
19220Sstevel@tonic-gate	 * of this handler. If so, we need to unpark it here.
19230Sstevel@tonic-gate	 * We use DCUCR reserved bits (stored in %g1) to keep track of
19240Sstevel@tonic-gate	 * whether or not we need to unpark. %g5 and %g7 are scratch registers.
19250Sstevel@tonic-gate	 */
19260Sstevel@tonic-gate	UNPARK_SIBLING_CORE(%g1, %g5, %g7)
19270Sstevel@tonic-gate
19280Sstevel@tonic-gate	/*
19290Sstevel@tonic-gate	 * Restore Icache and Dcache to previous state.
19300Sstevel@tonic-gate	 */
19310Sstevel@tonic-gate	stxa	%g1, [%g0]ASI_DCU
19320Sstevel@tonic-gate	flush	%g0	/* flush required after changing the IC bit */
19330Sstevel@tonic-gate
19340Sstevel@tonic-gate	/*
19350Sstevel@tonic-gate	 * Make sure our CPU logout operation was successful.
19360Sstevel@tonic-gate	 */
19370Sstevel@tonic-gate	cmp	%g3, %g0
19380Sstevel@tonic-gate	be	4f
19390Sstevel@tonic-gate	  nop
19400Sstevel@tonic-gate
19410Sstevel@tonic-gate	/*
19420Sstevel@tonic-gate	 * If the logout structure had been busy, how many times have
19430Sstevel@tonic-gate	 * we tried to use it and failed (nesting count)? If we have
19440Sstevel@tonic-gate	 * already recursed a substantial number of times, then we can
19450Sstevel@tonic-gate	 * assume things are not going to get better by themselves and
19460Sstevel@tonic-gate	 * so it would be best to panic.
19470Sstevel@tonic-gate	 */
19480Sstevel@tonic-gate	cmp	%g3, CLO_NESTING_MAX
19490Sstevel@tonic-gate	blt	3f
19500Sstevel@tonic-gate	  nop
19510Sstevel@tonic-gate
19520Sstevel@tonic-gate        call ptl1_panic
19530Sstevel@tonic-gate          mov   PTL1_BAD_ECC, %g1
19540Sstevel@tonic-gate
19550Sstevel@tonic-gate3:
19560Sstevel@tonic-gate	/*
19570Sstevel@tonic-gate	 * Otherwise, if the logout structure was busy but we have not
19580Sstevel@tonic-gate	 * nested more times than our maximum value, then we simply
19590Sstevel@tonic-gate	 * issue a retry. Our TL=0 trap handler code will check and
19600Sstevel@tonic-gate	 * clear the AFSR after it is done logging what is currently
19610Sstevel@tonic-gate	 * in the logout struct and handle this event at that time.
19620Sstevel@tonic-gate	 */
19630Sstevel@tonic-gate	retry
19640Sstevel@tonic-gate4:
19656553Sjimand	RESET_USER_RTT_REGS(%g4, %g5, async_err_resetskip)
19666553Sjimandasync_err_resetskip:
19670Sstevel@tonic-gate	set	cpu_deferred_error, %g1
19680Sstevel@tonic-gate	ba	sys_trap
19690Sstevel@tonic-gate	  mov	PIL_15, %g4		! run at pil 15
19700Sstevel@tonic-gate	SET_SIZE(async_err)
19710Sstevel@tonic-gate
19720Sstevel@tonic-gate#endif	/* lint */
19730Sstevel@tonic-gate
19740Sstevel@tonic-gate#if defined(CPU_IMP_L1_CACHE_PARITY)
19750Sstevel@tonic-gate
19760Sstevel@tonic-gate/*
19770Sstevel@tonic-gate * D$ parity error trap (trap 71) at TL=0.
19780Sstevel@tonic-gate * tt0_dperr is replaced by dcache_parity_instr in cpu_init_trap of
19790Sstevel@tonic-gate * the various architecture-specific files.  This merely sets up the
19800Sstevel@tonic-gate * arguments for cpu_parity_error and calls it via sys_trap.
19810Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must
19820Sstevel@tonic-gate *     be relocatable.
19830Sstevel@tonic-gate */
19840Sstevel@tonic-gate#if defined(lint)
19850Sstevel@tonic-gate
19860Sstevel@tonic-gatevoid
19870Sstevel@tonic-gatedcache_parity_instr(void)
19880Sstevel@tonic-gate{}
19890Sstevel@tonic-gate
19900Sstevel@tonic-gate#else	/* lint */
19910Sstevel@tonic-gate	ENTRY_NP(dcache_parity_instr)
19920Sstevel@tonic-gate	membar	#Sync			! Cheetah+ requires membar #Sync
19930Sstevel@tonic-gate	set	cpu_parity_error, %g1
19940Sstevel@tonic-gate	or	%g0, CH_ERR_DPE, %g2
19950Sstevel@tonic-gate	rdpr	%tpc, %g3
19960Sstevel@tonic-gate	sethi	%hi(sys_trap), %g7
19970Sstevel@tonic-gate	jmp	%g7 + %lo(sys_trap)
19980Sstevel@tonic-gate	  mov	PIL_15, %g4		! run at pil 15
19990Sstevel@tonic-gate	SET_SIZE(dcache_parity_instr)
20000Sstevel@tonic-gate
20010Sstevel@tonic-gate#endif	/* lint */
20020Sstevel@tonic-gate
20030Sstevel@tonic-gate
20040Sstevel@tonic-gate/*
20050Sstevel@tonic-gate * D$ parity error trap (trap 71) at TL>0.
20060Sstevel@tonic-gate * tt1_dperr is replaced by dcache_parity_tl1_instr in cpu_init_trap of
20070Sstevel@tonic-gate * the various architecture-specific files.  This generates a "Software
20080Sstevel@tonic-gate * Trap 1" at TL>0, which goes to dcache_parity_tl1_cont_instr, and we
20090Sstevel@tonic-gate * continue the handling there.
20100Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must
20110Sstevel@tonic-gate *     be relocatable.
20120Sstevel@tonic-gate */
20130Sstevel@tonic-gate#if defined(lint)
20140Sstevel@tonic-gate
20150Sstevel@tonic-gatevoid
20160Sstevel@tonic-gatedcache_parity_tl1_instr(void)
20170Sstevel@tonic-gate{}
20180Sstevel@tonic-gate
20190Sstevel@tonic-gate#else	/* lint */
20200Sstevel@tonic-gate	ENTRY_NP(dcache_parity_tl1_instr)
20210Sstevel@tonic-gate	CH_ERR_TL1_TRAPENTRY(SWTRAP_1);
20220Sstevel@tonic-gate	SET_SIZE(dcache_parity_tl1_instr)
20230Sstevel@tonic-gate
20240Sstevel@tonic-gate#endif	/* lint */
20250Sstevel@tonic-gate
20260Sstevel@tonic-gate
20270Sstevel@tonic-gate/*
20280Sstevel@tonic-gate * Software trap 1 at TL>0.
20290Sstevel@tonic-gate * tt1_swtrap1 is replaced by dcache_parity_tl1_cont_instr in cpu_init_trap
20300Sstevel@tonic-gate * of the various architecture-specific files.  This is used as a continuation
20310Sstevel@tonic-gate * of the dcache parity handling where we've bought an extra TL level, so we
20320Sstevel@tonic-gate * can use %tpc, %tnpc, %tstate to temporarily save the value of registers %g1
20330Sstevel@tonic-gate * and %g2.  Note that %tstate has bits 0-2 and then bits 8-19 as r/w,
20340Sstevel@tonic-gate * there's a reserved hole from 3-7.  We only use bits 0-1 and 8-9 (the low
20350Sstevel@tonic-gate * order two bits from %g1 and %g2 respectively).
20360Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must
20370Sstevel@tonic-gate *     be relocatable.
20380Sstevel@tonic-gate */
20390Sstevel@tonic-gate#if defined(lint)
20400Sstevel@tonic-gate
20410Sstevel@tonic-gatevoid
20420Sstevel@tonic-gatedcache_parity_tl1_cont_instr(void)
20430Sstevel@tonic-gate{}
20440Sstevel@tonic-gate
20450Sstevel@tonic-gate#else	/* lint */
20460Sstevel@tonic-gate	ENTRY_NP(dcache_parity_tl1_cont_instr)
20470Sstevel@tonic-gate	CH_ERR_TL1_SWTRAPENTRY(dcache_parity_tl1_err);
20480Sstevel@tonic-gate	SET_SIZE(dcache_parity_tl1_cont_instr)
20490Sstevel@tonic-gate
20500Sstevel@tonic-gate#endif	/* lint */
20510Sstevel@tonic-gate
20520Sstevel@tonic-gate/*
20530Sstevel@tonic-gate * D$ parity error at TL>0 handler
20540Sstevel@tonic-gate * We get here via trap 71 at TL>0->Software trap 1 at TL>0.  We enter
20550Sstevel@tonic-gate * this routine with %g1 and %g2 already saved in %tpc, %tnpc and %tstate.
20560Sstevel@tonic-gate */
20570Sstevel@tonic-gate#if defined(lint)
20580Sstevel@tonic-gate
20590Sstevel@tonic-gatevoid
20600Sstevel@tonic-gatedcache_parity_tl1_err(void)
20610Sstevel@tonic-gate{}
20620Sstevel@tonic-gate
20630Sstevel@tonic-gate#else	/* lint */
20640Sstevel@tonic-gate
20650Sstevel@tonic-gate	ENTRY_NP(dcache_parity_tl1_err)
20660Sstevel@tonic-gate
20670Sstevel@tonic-gate	/*
20680Sstevel@tonic-gate	 * This macro saves all the %g registers in the ch_err_tl1_data
20690Sstevel@tonic-gate	 * structure, updates the ch_err_tl1_flags and saves the %tpc in
20700Sstevel@tonic-gate	 * ch_err_tl1_tpc.  At the end of this macro, %g1 will point to
20710Sstevel@tonic-gate	 * the ch_err_tl1_data structure and %g2 will have the original
20720Sstevel@tonic-gate	 * flags in the ch_err_tl1_data structure.  All %g registers
20730Sstevel@tonic-gate	 * except for %g1 and %g2 will be available.
20740Sstevel@tonic-gate	 */
20750Sstevel@tonic-gate	CH_ERR_TL1_ENTER(CH_ERR_DPE);
20760Sstevel@tonic-gate
20770Sstevel@tonic-gate#ifdef TRAPTRACE
20780Sstevel@tonic-gate	/*
20790Sstevel@tonic-gate	 * Get current trap trace entry physical pointer.
20800Sstevel@tonic-gate	 */
20810Sstevel@tonic-gate	CPU_INDEX(%g6, %g5)
20820Sstevel@tonic-gate	sll	%g6, TRAPTR_SIZE_SHIFT, %g6
20830Sstevel@tonic-gate	set	trap_trace_ctl, %g5
20840Sstevel@tonic-gate	add	%g6, %g5, %g6
20850Sstevel@tonic-gate	ld	[%g6 + TRAPTR_LIMIT], %g5
20860Sstevel@tonic-gate	tst	%g5
20870Sstevel@tonic-gate	be	%icc, dpe_tl1_skip_tt
20880Sstevel@tonic-gate	  nop
20890Sstevel@tonic-gate	ldx	[%g6 + TRAPTR_PBASE], %g5
20900Sstevel@tonic-gate	ld	[%g6 + TRAPTR_OFFSET], %g4
20910Sstevel@tonic-gate	add	%g5, %g4, %g5
20920Sstevel@tonic-gate
20930Sstevel@tonic-gate	/*
20940Sstevel@tonic-gate	 * Create trap trace entry.
20950Sstevel@tonic-gate	 */
20960Sstevel@tonic-gate	rd	%asi, %g7
20970Sstevel@tonic-gate	wr	%g0, TRAPTR_ASI, %asi
20980Sstevel@tonic-gate	rd	STICK, %g4
20990Sstevel@tonic-gate	stxa	%g4, [%g5 + TRAP_ENT_TICK]%asi
21000Sstevel@tonic-gate	rdpr	%tl, %g4
21010Sstevel@tonic-gate	stha	%g4, [%g5 + TRAP_ENT_TL]%asi
21020Sstevel@tonic-gate	rdpr	%tt, %g4
21030Sstevel@tonic-gate	stha	%g4, [%g5 + TRAP_ENT_TT]%asi
21040Sstevel@tonic-gate	rdpr	%tpc, %g4
21050Sstevel@tonic-gate	stna	%g4, [%g5 + TRAP_ENT_TPC]%asi
21060Sstevel@tonic-gate	rdpr	%tstate, %g4
21070Sstevel@tonic-gate	stxa	%g4, [%g5 + TRAP_ENT_TSTATE]%asi
21080Sstevel@tonic-gate	stna	%sp, [%g5 + TRAP_ENT_SP]%asi
21090Sstevel@tonic-gate	stna	%g0, [%g5 + TRAP_ENT_TR]%asi
21100Sstevel@tonic-gate	stna	%g0, [%g5 + TRAP_ENT_F1]%asi
21110Sstevel@tonic-gate	stna	%g0, [%g5 + TRAP_ENT_F2]%asi
21120Sstevel@tonic-gate	stna	%g0, [%g5 + TRAP_ENT_F3]%asi
21130Sstevel@tonic-gate	stna	%g0, [%g5 + TRAP_ENT_F4]%asi
21140Sstevel@tonic-gate	wr	%g0, %g7, %asi
21150Sstevel@tonic-gate
21160Sstevel@tonic-gate	/*
21170Sstevel@tonic-gate	 * Advance trap trace pointer.
21180Sstevel@tonic-gate	 */
21190Sstevel@tonic-gate	ld	[%g6 + TRAPTR_OFFSET], %g5
21200Sstevel@tonic-gate	ld	[%g6 + TRAPTR_LIMIT], %g4
21210Sstevel@tonic-gate	st	%g5, [%g6 + TRAPTR_LAST_OFFSET]
21220Sstevel@tonic-gate	add	%g5, TRAP_ENT_SIZE, %g5
21230Sstevel@tonic-gate	sub	%g4, TRAP_ENT_SIZE, %g4
21240Sstevel@tonic-gate	cmp	%g5, %g4
21250Sstevel@tonic-gate	movge	%icc, 0, %g5
21260Sstevel@tonic-gate	st	%g5, [%g6 + TRAPTR_OFFSET]
21270Sstevel@tonic-gatedpe_tl1_skip_tt:
21280Sstevel@tonic-gate#endif	/* TRAPTRACE */
21290Sstevel@tonic-gate
21300Sstevel@tonic-gate	/*
21310Sstevel@tonic-gate	 * I$ and D$ are automatically turned off by HW when the CPU hits
21320Sstevel@tonic-gate	 * a dcache or icache parity error so we will just leave those two
21330Sstevel@tonic-gate	 * off for now to avoid repeating this trap.
21340Sstevel@tonic-gate	 * For Panther, however, since we trap on P$ data parity errors
21350Sstevel@tonic-gate	 * and HW does not automatically disable P$, we need to disable it
21360Sstevel@tonic-gate	 * here so that we don't encounter any recursive traps when we
21370Sstevel@tonic-gate	 * issue the retry.
21380Sstevel@tonic-gate	 */
21390Sstevel@tonic-gate	ldxa	[%g0]ASI_DCU, %g3
21400Sstevel@tonic-gate	mov	1, %g4
21410Sstevel@tonic-gate	sllx	%g4, DCU_PE_SHIFT, %g4
21420Sstevel@tonic-gate	andn	%g3, %g4, %g3
21430Sstevel@tonic-gate	stxa	%g3, [%g0]ASI_DCU
21440Sstevel@tonic-gate	membar	#Sync
21450Sstevel@tonic-gate
21460Sstevel@tonic-gate	/*
21470Sstevel@tonic-gate	 * We fall into this macro if we've successfully logged the error in
21480Sstevel@tonic-gate	 * the ch_err_tl1_data structure and want the PIL15 softint to pick
21490Sstevel@tonic-gate	 * it up and log it.  %g1 must point to the ch_err_tl1_data structure.
21500Sstevel@tonic-gate	 * Restores the %g registers and issues retry.
21510Sstevel@tonic-gate	 */
21520Sstevel@tonic-gate	CH_ERR_TL1_EXIT;
21530Sstevel@tonic-gate	SET_SIZE(dcache_parity_tl1_err)
21540Sstevel@tonic-gate
21550Sstevel@tonic-gate#endif	/* lint */
21560Sstevel@tonic-gate
21570Sstevel@tonic-gate/*
21580Sstevel@tonic-gate * I$ parity error trap (trap 72) at TL=0.
21590Sstevel@tonic-gate * tt0_iperr is replaced by icache_parity_instr in cpu_init_trap of
21600Sstevel@tonic-gate * the various architecture-specific files.  This merely sets up the
21610Sstevel@tonic-gate * arguments for cpu_parity_error and calls it via sys_trap.
21620Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must
21630Sstevel@tonic-gate *     be relocatable.
21640Sstevel@tonic-gate */
21650Sstevel@tonic-gate#if defined(lint)
21660Sstevel@tonic-gate
21670Sstevel@tonic-gatevoid
21680Sstevel@tonic-gateicache_parity_instr(void)
21690Sstevel@tonic-gate{}
21700Sstevel@tonic-gate
21710Sstevel@tonic-gate#else	/* lint */
21720Sstevel@tonic-gate
21730Sstevel@tonic-gate	ENTRY_NP(icache_parity_instr)
21740Sstevel@tonic-gate	membar	#Sync			! Cheetah+ requires membar #Sync
21750Sstevel@tonic-gate	set	cpu_parity_error, %g1
21760Sstevel@tonic-gate	or	%g0, CH_ERR_IPE, %g2
21770Sstevel@tonic-gate	rdpr	%tpc, %g3
21780Sstevel@tonic-gate	sethi	%hi(sys_trap), %g7
21790Sstevel@tonic-gate	jmp	%g7 + %lo(sys_trap)
21800Sstevel@tonic-gate	  mov	PIL_15, %g4		! run at pil 15
21810Sstevel@tonic-gate	SET_SIZE(icache_parity_instr)
21820Sstevel@tonic-gate
21830Sstevel@tonic-gate#endif	/* lint */
21840Sstevel@tonic-gate
21850Sstevel@tonic-gate/*
21860Sstevel@tonic-gate * I$ parity error trap (trap 72) at TL>0.
21870Sstevel@tonic-gate * tt1_iperr is replaced by icache_parity_tl1_instr in cpu_init_trap of
21880Sstevel@tonic-gate * the various architecture-specific files.  This generates a "Software
21890Sstevel@tonic-gate * Trap 2" at TL>0, which goes to icache_parity_tl1_cont_instr, and we
21900Sstevel@tonic-gate * continue the handling there.
21910Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must
21920Sstevel@tonic-gate *     be relocatable.
21930Sstevel@tonic-gate */
21940Sstevel@tonic-gate#if defined(lint)
21950Sstevel@tonic-gate
21960Sstevel@tonic-gatevoid
21970Sstevel@tonic-gateicache_parity_tl1_instr(void)
21980Sstevel@tonic-gate{}
21990Sstevel@tonic-gate
22000Sstevel@tonic-gate#else	/* lint */
22010Sstevel@tonic-gate	ENTRY_NP(icache_parity_tl1_instr)
22020Sstevel@tonic-gate	CH_ERR_TL1_TRAPENTRY(SWTRAP_2);
22030Sstevel@tonic-gate	SET_SIZE(icache_parity_tl1_instr)
22040Sstevel@tonic-gate
22050Sstevel@tonic-gate#endif	/* lint */
22060Sstevel@tonic-gate
22070Sstevel@tonic-gate/*
22080Sstevel@tonic-gate * Software trap 2 at TL>0.
22090Sstevel@tonic-gate * tt1_swtrap2 is replaced by icache_parity_tl1_cont_instr in cpu_init_trap
22100Sstevel@tonic-gate * of the various architecture-specific files.  This is used as a continuation
22110Sstevel@tonic-gate * of the icache parity handling where we've bought an extra TL level, so we
22120Sstevel@tonic-gate * can use %tpc, %tnpc, %tstate to temporarily save the value of registers %g1
22130Sstevel@tonic-gate * and %g2.  Note that %tstate has bits 0-2 and then bits 8-19 as r/w,
22140Sstevel@tonic-gate * there's a reserved hole from 3-7.  We only use bits 0-1 and 8-9 (the low
22150Sstevel@tonic-gate * order two bits from %g1 and %g2 respectively).
22160Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must
22170Sstevel@tonic-gate *     be relocatable.
22180Sstevel@tonic-gate */
22190Sstevel@tonic-gate#if defined(lint)
22200Sstevel@tonic-gate
22210Sstevel@tonic-gatevoid
22220Sstevel@tonic-gateicache_parity_tl1_cont_instr(void)
22230Sstevel@tonic-gate{}
22240Sstevel@tonic-gate
22250Sstevel@tonic-gate#else	/* lint */
22260Sstevel@tonic-gate	ENTRY_NP(icache_parity_tl1_cont_instr)
22270Sstevel@tonic-gate	CH_ERR_TL1_SWTRAPENTRY(icache_parity_tl1_err);
22280Sstevel@tonic-gate	SET_SIZE(icache_parity_tl1_cont_instr)
22290Sstevel@tonic-gate
22300Sstevel@tonic-gate#endif	/* lint */
22310Sstevel@tonic-gate
22320Sstevel@tonic-gate
22330Sstevel@tonic-gate/*
22340Sstevel@tonic-gate * I$ parity error at TL>0 handler
22350Sstevel@tonic-gate * We get here via trap 72 at TL>0->Software trap 2 at TL>0.  We enter
22360Sstevel@tonic-gate * this routine with %g1 and %g2 already saved in %tpc, %tnpc and %tstate.
22370Sstevel@tonic-gate */
22380Sstevel@tonic-gate#if defined(lint)
22390Sstevel@tonic-gate
22400Sstevel@tonic-gatevoid
22410Sstevel@tonic-gateicache_parity_tl1_err(void)
22420Sstevel@tonic-gate{}
22430Sstevel@tonic-gate
22440Sstevel@tonic-gate#else	/* lint */
22450Sstevel@tonic-gate
22460Sstevel@tonic-gate	ENTRY_NP(icache_parity_tl1_err)
22470Sstevel@tonic-gate
22480Sstevel@tonic-gate	/*
22490Sstevel@tonic-gate	 * This macro saves all the %g registers in the ch_err_tl1_data
22500Sstevel@tonic-gate	 * structure, updates the ch_err_tl1_flags and saves the %tpc in
22510Sstevel@tonic-gate	 * ch_err_tl1_tpc.  At the end of this macro, %g1 will point to
22520Sstevel@tonic-gate	 * the ch_err_tl1_data structure and %g2 will have the original
22530Sstevel@tonic-gate	 * flags in the ch_err_tl1_data structure.  All %g registers
22540Sstevel@tonic-gate	 * except for %g1 and %g2 will be available.
22550Sstevel@tonic-gate	 */
22560Sstevel@tonic-gate	CH_ERR_TL1_ENTER(CH_ERR_IPE);
22570Sstevel@tonic-gate
22580Sstevel@tonic-gate#ifdef TRAPTRACE
22590Sstevel@tonic-gate	/*
22600Sstevel@tonic-gate	 * Get current trap trace entry physical pointer.
22610Sstevel@tonic-gate	 */
22620Sstevel@tonic-gate	CPU_INDEX(%g6, %g5)
22630Sstevel@tonic-gate	sll	%g6, TRAPTR_SIZE_SHIFT, %g6
22640Sstevel@tonic-gate	set	trap_trace_ctl, %g5
22650Sstevel@tonic-gate	add	%g6, %g5, %g6
22660Sstevel@tonic-gate	ld	[%g6 + TRAPTR_LIMIT], %g5
22670Sstevel@tonic-gate	tst	%g5
22680Sstevel@tonic-gate	be	%icc, ipe_tl1_skip_tt
22690Sstevel@tonic-gate	  nop
22700Sstevel@tonic-gate	ldx	[%g6 + TRAPTR_PBASE], %g5
22710Sstevel@tonic-gate	ld	[%g6 + TRAPTR_OFFSET], %g4
22720Sstevel@tonic-gate	add	%g5, %g4, %g5
22730Sstevel@tonic-gate
22740Sstevel@tonic-gate	/*
22750Sstevel@tonic-gate	 * Create trap trace entry.
22760Sstevel@tonic-gate	 */
22770Sstevel@tonic-gate	rd	%asi, %g7
22780Sstevel@tonic-gate	wr	%g0, TRAPTR_ASI, %asi
22790Sstevel@tonic-gate	rd	STICK, %g4
22800Sstevel@tonic-gate	stxa	%g4, [%g5 + TRAP_ENT_TICK]%asi
22810Sstevel@tonic-gate	rdpr	%tl, %g4
22820Sstevel@tonic-gate	stha	%g4, [%g5 + TRAP_ENT_TL]%asi
22830Sstevel@tonic-gate	rdpr	%tt, %g4
22840Sstevel@tonic-gate	stha	%g4, [%g5 + TRAP_ENT_TT]%asi
22850Sstevel@tonic-gate	rdpr	%tpc, %g4
22860Sstevel@tonic-gate	stna	%g4, [%g5 + TRAP_ENT_TPC]%asi
22870Sstevel@tonic-gate	rdpr	%tstate, %g4
22880Sstevel@tonic-gate	stxa	%g4, [%g5 + TRAP_ENT_TSTATE]%asi
22890Sstevel@tonic-gate	stna	%sp, [%g5 + TRAP_ENT_SP]%asi
22900Sstevel@tonic-gate	stna	%g0, [%g5 + TRAP_ENT_TR]%asi
22910Sstevel@tonic-gate	stna	%g0, [%g5 + TRAP_ENT_F1]%asi
22920Sstevel@tonic-gate	stna	%g0, [%g5 + TRAP_ENT_F2]%asi
22930Sstevel@tonic-gate	stna	%g0, [%g5 + TRAP_ENT_F3]%asi
22940Sstevel@tonic-gate	stna	%g0, [%g5 + TRAP_ENT_F4]%asi
22950Sstevel@tonic-gate	wr	%g0, %g7, %asi
22960Sstevel@tonic-gate
22970Sstevel@tonic-gate	/*
22980Sstevel@tonic-gate	 * Advance trap trace pointer.
22990Sstevel@tonic-gate	 */
23000Sstevel@tonic-gate	ld	[%g6 + TRAPTR_OFFSET], %g5
23010Sstevel@tonic-gate	ld	[%g6 + TRAPTR_LIMIT], %g4
23020Sstevel@tonic-gate	st	%g5, [%g6 + TRAPTR_LAST_OFFSET]
23030Sstevel@tonic-gate	add	%g5, TRAP_ENT_SIZE, %g5
23040Sstevel@tonic-gate	sub	%g4, TRAP_ENT_SIZE, %g4
23050Sstevel@tonic-gate	cmp	%g5, %g4
23060Sstevel@tonic-gate	movge	%icc, 0, %g5
23070Sstevel@tonic-gate	st	%g5, [%g6 + TRAPTR_OFFSET]
23080Sstevel@tonic-gateipe_tl1_skip_tt:
23090Sstevel@tonic-gate#endif	/* TRAPTRACE */
23100Sstevel@tonic-gate
23110Sstevel@tonic-gate	/*
23120Sstevel@tonic-gate	 * We fall into this macro if we've successfully logged the error in
23130Sstevel@tonic-gate	 * the ch_err_tl1_data structure and want the PIL15 softint to pick
23140Sstevel@tonic-gate	 * it up and log it.  %g1 must point to the ch_err_tl1_data structure.
23150Sstevel@tonic-gate	 * Restores the %g registers and issues retry.
23160Sstevel@tonic-gate	 */
23170Sstevel@tonic-gate	CH_ERR_TL1_EXIT;
23180Sstevel@tonic-gate
23190Sstevel@tonic-gate	SET_SIZE(icache_parity_tl1_err)
23200Sstevel@tonic-gate
23210Sstevel@tonic-gate#endif	/* lint */
23220Sstevel@tonic-gate
23230Sstevel@tonic-gate#endif	/* CPU_IMP_L1_CACHE_PARITY */
23240Sstevel@tonic-gate
23250Sstevel@tonic-gate
23260Sstevel@tonic-gate/*
23270Sstevel@tonic-gate * The itlb_rd_entry and dtlb_rd_entry functions return the tag portion of the
23280Sstevel@tonic-gate * tte, the virtual address, and the ctxnum of the specified tlb entry.  They
23290Sstevel@tonic-gate * should only be used in places where you have no choice but to look at the
23300Sstevel@tonic-gate * tlb itself.
23310Sstevel@tonic-gate *
23320Sstevel@tonic-gate * Note: These two routines are required by the Estar "cpr" loadable module.
23330Sstevel@tonic-gate */
23340Sstevel@tonic-gate
23350Sstevel@tonic-gate#if defined(lint)
23360Sstevel@tonic-gate
23370Sstevel@tonic-gate/* ARGSUSED */
23380Sstevel@tonic-gatevoid
23390Sstevel@tonic-gateitlb_rd_entry(uint_t entry, tte_t *tte, uint64_t *va_tag)
23400Sstevel@tonic-gate{}
23410Sstevel@tonic-gate
23420Sstevel@tonic-gate#else	/* lint */
23430Sstevel@tonic-gate
23440Sstevel@tonic-gate	ENTRY_NP(itlb_rd_entry)
23450Sstevel@tonic-gate	sllx	%o0, 3, %o0
23460Sstevel@tonic-gate	ldxa	[%o0]ASI_ITLB_ACCESS, %g1
23470Sstevel@tonic-gate	stx	%g1, [%o1]
23480Sstevel@tonic-gate	ldxa	[%o0]ASI_ITLB_TAGREAD, %g2
23490Sstevel@tonic-gate	set	TAGREAD_CTX_MASK, %o4
23500Sstevel@tonic-gate	andn	%g2, %o4, %o5
23510Sstevel@tonic-gate	retl
23520Sstevel@tonic-gate	  stx	%o5, [%o2]
23530Sstevel@tonic-gate	SET_SIZE(itlb_rd_entry)
23540Sstevel@tonic-gate
23550Sstevel@tonic-gate#endif	/* lint */
23560Sstevel@tonic-gate
23570Sstevel@tonic-gate
23580Sstevel@tonic-gate#if defined(lint)
23590Sstevel@tonic-gate
23600Sstevel@tonic-gate/* ARGSUSED */
23610Sstevel@tonic-gatevoid
23620Sstevel@tonic-gatedtlb_rd_entry(uint_t entry, tte_t *tte, uint64_t *va_tag)
23630Sstevel@tonic-gate{}
23640Sstevel@tonic-gate
23650Sstevel@tonic-gate#else	/* lint */
23660Sstevel@tonic-gate
23670Sstevel@tonic-gate	ENTRY_NP(dtlb_rd_entry)
23680Sstevel@tonic-gate	sllx	%o0, 3, %o0
23690Sstevel@tonic-gate	ldxa	[%o0]ASI_DTLB_ACCESS, %g1
23700Sstevel@tonic-gate	stx	%g1, [%o1]
23710Sstevel@tonic-gate	ldxa	[%o0]ASI_DTLB_TAGREAD, %g2
23720Sstevel@tonic-gate	set	TAGREAD_CTX_MASK, %o4
23730Sstevel@tonic-gate	andn	%g2, %o4, %o5
23740Sstevel@tonic-gate	retl
23750Sstevel@tonic-gate	  stx	%o5, [%o2]
23760Sstevel@tonic-gate	SET_SIZE(dtlb_rd_entry)
23770Sstevel@tonic-gate#endif	/* lint */
23780Sstevel@tonic-gate
23790Sstevel@tonic-gate
23800Sstevel@tonic-gate#if !(defined(JALAPENO) || defined(SERRANO))
23810Sstevel@tonic-gate
23820Sstevel@tonic-gate#if defined(lint)
23830Sstevel@tonic-gate
23840Sstevel@tonic-gateuint64_t
23850Sstevel@tonic-gateget_safari_config(void)
23860Sstevel@tonic-gate{ return (0); }
23870Sstevel@tonic-gate
23880Sstevel@tonic-gate#else	/* lint */
23890Sstevel@tonic-gate
23900Sstevel@tonic-gate	ENTRY(get_safari_config)
23910Sstevel@tonic-gate	ldxa	[%g0]ASI_SAFARI_CONFIG, %o0
23920Sstevel@tonic-gate	retl
23930Sstevel@tonic-gate	nop
23940Sstevel@tonic-gate	SET_SIZE(get_safari_config)
23950Sstevel@tonic-gate
23960Sstevel@tonic-gate#endif	/* lint */
23970Sstevel@tonic-gate
23980Sstevel@tonic-gate
23990Sstevel@tonic-gate#if defined(lint)
24000Sstevel@tonic-gate
24010Sstevel@tonic-gate/* ARGSUSED */
24020Sstevel@tonic-gatevoid
24030Sstevel@tonic-gateset_safari_config(uint64_t safari_config)
24040Sstevel@tonic-gate{}
24050Sstevel@tonic-gate
24060Sstevel@tonic-gate#else	/* lint */
24070Sstevel@tonic-gate
24080Sstevel@tonic-gate	ENTRY(set_safari_config)
24090Sstevel@tonic-gate	stxa	%o0, [%g0]ASI_SAFARI_CONFIG
24100Sstevel@tonic-gate	membar	#Sync
24110Sstevel@tonic-gate	retl
24120Sstevel@tonic-gate	nop
24130Sstevel@tonic-gate	SET_SIZE(set_safari_config)
24140Sstevel@tonic-gate
24150Sstevel@tonic-gate#endif	/* lint */
24160Sstevel@tonic-gate
24170Sstevel@tonic-gate#endif	/* !(JALAPENO || SERRANO) */
24180Sstevel@tonic-gate
24190Sstevel@tonic-gate
24200Sstevel@tonic-gate#if defined(lint)
24210Sstevel@tonic-gate
24220Sstevel@tonic-gatevoid
24230Sstevel@tonic-gatecpu_cleartickpnt(void)
24240Sstevel@tonic-gate{}
24250Sstevel@tonic-gate
24260Sstevel@tonic-gate#else	/* lint */
24270Sstevel@tonic-gate	/*
24280Sstevel@tonic-gate	 * Clear the NPT (non-privileged trap) bit in the %tick/%stick
24290Sstevel@tonic-gate	 * registers. In an effort to make the change in the
24300Sstevel@tonic-gate	 * tick/stick counter as consistent as possible, we disable
24310Sstevel@tonic-gate	 * all interrupts while we're changing the registers. We also
24320Sstevel@tonic-gate	 * ensure that the read and write instructions are in the same
24330Sstevel@tonic-gate	 * line in the instruction cache.
24340Sstevel@tonic-gate	 */
24350Sstevel@tonic-gate	ENTRY_NP(cpu_clearticknpt)
24360Sstevel@tonic-gate	rdpr	%pstate, %g1		/* save processor state */
24370Sstevel@tonic-gate	andn	%g1, PSTATE_IE, %g3	/* turn off */
24380Sstevel@tonic-gate	wrpr	%g0, %g3, %pstate	/*   interrupts */
24390Sstevel@tonic-gate	rdpr	%tick, %g2		/* get tick register */
24400Sstevel@tonic-gate	brgez,pn %g2, 1f		/* if NPT bit off, we're done */
24410Sstevel@tonic-gate	mov	1, %g3			/* create mask */
24420Sstevel@tonic-gate	sllx	%g3, 63, %g3		/*   for NPT bit */
24430Sstevel@tonic-gate	ba,a,pt	%xcc, 2f
24440Sstevel@tonic-gate	.align	8			/* Ensure rd/wr in same i$ line */
24450Sstevel@tonic-gate2:
24460Sstevel@tonic-gate	rdpr	%tick, %g2		/* get tick register */
24470Sstevel@tonic-gate	wrpr	%g3, %g2, %tick		/* write tick register, */
24480Sstevel@tonic-gate					/*   clearing NPT bit   */
24490Sstevel@tonic-gate1:
24500Sstevel@tonic-gate	rd	STICK, %g2		/* get stick register */
24510Sstevel@tonic-gate	brgez,pn %g2, 3f		/* if NPT bit off, we're done */
24520Sstevel@tonic-gate	mov	1, %g3			/* create mask */
24530Sstevel@tonic-gate	sllx	%g3, 63, %g3		/*   for NPT bit */
24540Sstevel@tonic-gate	ba,a,pt	%xcc, 4f
24550Sstevel@tonic-gate	.align	8			/* Ensure rd/wr in same i$ line */
24560Sstevel@tonic-gate4:
24570Sstevel@tonic-gate	rd	STICK, %g2		/* get stick register */
24580Sstevel@tonic-gate	wr	%g3, %g2, STICK		/* write stick register, */
24590Sstevel@tonic-gate					/*   clearing NPT bit   */
24600Sstevel@tonic-gate3:
24610Sstevel@tonic-gate	jmp	%g4 + 4
24620Sstevel@tonic-gate	wrpr	%g0, %g1, %pstate	/* restore processor state */
24630Sstevel@tonic-gate
24640Sstevel@tonic-gate	SET_SIZE(cpu_clearticknpt)
24650Sstevel@tonic-gate
24660Sstevel@tonic-gate#endif	/* lint */
24670Sstevel@tonic-gate
24680Sstevel@tonic-gate
24690Sstevel@tonic-gate#if defined(CPU_IMP_L1_CACHE_PARITY)
24700Sstevel@tonic-gate
24710Sstevel@tonic-gate#if defined(lint)
24720Sstevel@tonic-gate/*
24730Sstevel@tonic-gate * correct_dcache_parity(size_t size, size_t linesize)
24740Sstevel@tonic-gate *
24750Sstevel@tonic-gate * Correct D$ data parity by zeroing the data and initializing microtag
24760Sstevel@tonic-gate * for all indexes and all ways of the D$.
24770Sstevel@tonic-gate *
24780Sstevel@tonic-gate */
24790Sstevel@tonic-gate/* ARGSUSED */
24800Sstevel@tonic-gatevoid
24810Sstevel@tonic-gatecorrect_dcache_parity(size_t size, size_t linesize)
24820Sstevel@tonic-gate{}
24830Sstevel@tonic-gate
24840Sstevel@tonic-gate#else	/* lint */
24850Sstevel@tonic-gate
24860Sstevel@tonic-gate	ENTRY(correct_dcache_parity)
24870Sstevel@tonic-gate	/*
24880Sstevel@tonic-gate	 * Register Usage:
24890Sstevel@tonic-gate	 *
24900Sstevel@tonic-gate	 * %o0 = input D$ size
24910Sstevel@tonic-gate	 * %o1 = input D$ line size
24920Sstevel@tonic-gate	 * %o2 = scratch
24930Sstevel@tonic-gate	 * %o3 = scratch
24940Sstevel@tonic-gate	 * %o4 = scratch
24950Sstevel@tonic-gate	 */
24960Sstevel@tonic-gate
24970Sstevel@tonic-gate	sub	%o0, %o1, %o0			! init cache line address
24980Sstevel@tonic-gate
24990Sstevel@tonic-gate	/*
25000Sstevel@tonic-gate	 * For Panther CPUs, we also need to clear the data parity bits
25010Sstevel@tonic-gate	 * using DC_data_parity bit of the ASI_DCACHE_DATA register.
25020Sstevel@tonic-gate	 */
25030Sstevel@tonic-gate	GET_CPU_IMPL(%o3)
25040Sstevel@tonic-gate	cmp	%o3, PANTHER_IMPL
25050Sstevel@tonic-gate	bne	1f
25060Sstevel@tonic-gate	  clr	%o3				! zero for non-Panther
25070Sstevel@tonic-gate	mov	1, %o3
25080Sstevel@tonic-gate	sll	%o3, PN_DC_DATA_PARITY_BIT_SHIFT, %o3
25090Sstevel@tonic-gate
25100Sstevel@tonic-gate1:
25110Sstevel@tonic-gate	/*
25120Sstevel@tonic-gate	 * Set utag = way since it must be unique within an index.
25130Sstevel@tonic-gate	 */
25140Sstevel@tonic-gate	srl	%o0, 14, %o2			! get cache way (DC_way)
25150Sstevel@tonic-gate	membar	#Sync				! required before ASI_DC_UTAG
25160Sstevel@tonic-gate	stxa	%o2, [%o0]ASI_DC_UTAG		! set D$ utag = cache way
25170Sstevel@tonic-gate	membar	#Sync				! required after ASI_DC_UTAG
25180Sstevel@tonic-gate
25190Sstevel@tonic-gate	/*
25200Sstevel@tonic-gate	 * Zero line of D$ data (and data parity bits for Panther)
25210Sstevel@tonic-gate	 */
25220Sstevel@tonic-gate	sub	%o1, 8, %o2
25230Sstevel@tonic-gate	or	%o0, %o3, %o4			! same address + DC_data_parity
25240Sstevel@tonic-gate2:
25250Sstevel@tonic-gate	membar	#Sync				! required before ASI_DC_DATA
25260Sstevel@tonic-gate	stxa	%g0, [%o0 + %o2]ASI_DC_DATA	! zero 8 bytes of D$ data
25270Sstevel@tonic-gate	membar	#Sync				! required after ASI_DC_DATA
25280Sstevel@tonic-gate	/*
25290Sstevel@tonic-gate	 * We also clear the parity bits if this is a panther. For non-Panther
25300Sstevel@tonic-gate	 * CPUs, we simply end up clearing the $data register twice.
25310Sstevel@tonic-gate	 */
25320Sstevel@tonic-gate	stxa	%g0, [%o4 + %o2]ASI_DC_DATA
25330Sstevel@tonic-gate	membar	#Sync
25340Sstevel@tonic-gate
25350Sstevel@tonic-gate	subcc	%o2, 8, %o2
25360Sstevel@tonic-gate	bge	2b
25370Sstevel@tonic-gate	nop
25380Sstevel@tonic-gate
25390Sstevel@tonic-gate	subcc	%o0, %o1, %o0
25400Sstevel@tonic-gate	bge	1b
25410Sstevel@tonic-gate	nop
25420Sstevel@tonic-gate
25430Sstevel@tonic-gate	retl
25440Sstevel@tonic-gate	  nop
25450Sstevel@tonic-gate	SET_SIZE(correct_dcache_parity)
25460Sstevel@tonic-gate
25470Sstevel@tonic-gate#endif	/* lint */
25480Sstevel@tonic-gate
25490Sstevel@tonic-gate#endif	/* CPU_IMP_L1_CACHE_PARITY */
25500Sstevel@tonic-gate
25510Sstevel@tonic-gate
25520Sstevel@tonic-gate#if defined(lint)
25530Sstevel@tonic-gate/*
25540Sstevel@tonic-gate *  Get timestamp (stick).
25550Sstevel@tonic-gate */
25560Sstevel@tonic-gate/* ARGSUSED */
25570Sstevel@tonic-gatevoid
25580Sstevel@tonic-gatestick_timestamp(int64_t *ts)
25590Sstevel@tonic-gate{
25600Sstevel@tonic-gate}
25610Sstevel@tonic-gate
25620Sstevel@tonic-gate#else	/* lint */
25630Sstevel@tonic-gate
25640Sstevel@tonic-gate	ENTRY_NP(stick_timestamp)
25650Sstevel@tonic-gate	rd	STICK, %g1	! read stick reg
25660Sstevel@tonic-gate	sllx	%g1, 1, %g1
25670Sstevel@tonic-gate	srlx	%g1, 1, %g1	! clear npt bit
25680Sstevel@tonic-gate
25690Sstevel@tonic-gate	retl
25700Sstevel@tonic-gate	stx     %g1, [%o0]	! store the timestamp
25710Sstevel@tonic-gate	SET_SIZE(stick_timestamp)
25720Sstevel@tonic-gate
25730Sstevel@tonic-gate#endif	/* lint */
25740Sstevel@tonic-gate
25750Sstevel@tonic-gate
25760Sstevel@tonic-gate#if defined(lint)
25770Sstevel@tonic-gate/*
25780Sstevel@tonic-gate * Set STICK adjusted by skew.
25790Sstevel@tonic-gate */
25800Sstevel@tonic-gate/* ARGSUSED */
25810Sstevel@tonic-gatevoid
25820Sstevel@tonic-gatestick_adj(int64_t skew)
25830Sstevel@tonic-gate{
25840Sstevel@tonic-gate}
25850Sstevel@tonic-gate
25860Sstevel@tonic-gate#else	/* lint */
25870Sstevel@tonic-gate
25880Sstevel@tonic-gate	ENTRY_NP(stick_adj)
25890Sstevel@tonic-gate	rdpr	%pstate, %g1		! save processor state
25900Sstevel@tonic-gate	andn	%g1, PSTATE_IE, %g3
25910Sstevel@tonic-gate	ba	1f			! cache align stick adj
25920Sstevel@tonic-gate	wrpr	%g0, %g3, %pstate	! turn off interrupts
25930Sstevel@tonic-gate
25940Sstevel@tonic-gate	.align	16
25950Sstevel@tonic-gate1:	nop
25960Sstevel@tonic-gate
25970Sstevel@tonic-gate	rd	STICK, %g4		! read stick reg
25980Sstevel@tonic-gate	add	%g4, %o0, %o1		! adjust stick with skew
25990Sstevel@tonic-gate	wr	%o1, %g0, STICK		! write stick reg
26000Sstevel@tonic-gate
26010Sstevel@tonic-gate	retl
26020Sstevel@tonic-gate	wrpr	%g1, %pstate		! restore processor state
26030Sstevel@tonic-gate	SET_SIZE(stick_adj)
26040Sstevel@tonic-gate
26050Sstevel@tonic-gate#endif	/* lint */
26060Sstevel@tonic-gate
26070Sstevel@tonic-gate#if defined(lint)
26080Sstevel@tonic-gate/*
26090Sstevel@tonic-gate * Debugger-specific stick retrieval
26100Sstevel@tonic-gate */
26110Sstevel@tonic-gate/*ARGSUSED*/
26120Sstevel@tonic-gateint
26130Sstevel@tonic-gatekdi_get_stick(uint64_t *stickp)
26140Sstevel@tonic-gate{
26150Sstevel@tonic-gate	return (0);
26160Sstevel@tonic-gate}
26170Sstevel@tonic-gate
26180Sstevel@tonic-gate#else	/* lint */
26190Sstevel@tonic-gate
26200Sstevel@tonic-gate	ENTRY_NP(kdi_get_stick)
26210Sstevel@tonic-gate	rd	STICK, %g1
26220Sstevel@tonic-gate	stx	%g1, [%o0]
26230Sstevel@tonic-gate	retl
26240Sstevel@tonic-gate	mov	%g0, %o0
26250Sstevel@tonic-gate	SET_SIZE(kdi_get_stick)
26260Sstevel@tonic-gate
26270Sstevel@tonic-gate#endif	/* lint */
26280Sstevel@tonic-gate
26290Sstevel@tonic-gate#if defined(lint)
26300Sstevel@tonic-gate/*
26310Sstevel@tonic-gate * Invalidate the specified line from the D$.
26320Sstevel@tonic-gate *
26330Sstevel@tonic-gate * Register usage:
26340Sstevel@tonic-gate *	%o0 - index for the invalidation, specifies DC_way and DC_addr
26350Sstevel@tonic-gate *
26360Sstevel@tonic-gate * ASI_DC_TAG, 0x47, is used in the following manner. A 64-bit value is
26370Sstevel@tonic-gate * stored to a particular DC_way and DC_addr in ASI_DC_TAG.
26380Sstevel@tonic-gate *
26390Sstevel@tonic-gate * The format of the stored 64-bit value is:
26400Sstevel@tonic-gate *
26410Sstevel@tonic-gate *	+----------+--------+----------+
26420Sstevel@tonic-gate *	| Reserved | DC_tag | DC_valid |
26430Sstevel@tonic-gate *	+----------+--------+----------+
26440Sstevel@tonic-gate *       63      31 30     1	      0
26450Sstevel@tonic-gate *
26460Sstevel@tonic-gate * DC_tag is the 30-bit physical tag of the associated line.
26470Sstevel@tonic-gate * DC_valid is the 1-bit valid field for both the physical and snoop tags.
26480Sstevel@tonic-gate *
26490Sstevel@tonic-gate * The format of the 64-bit DC_way and DC_addr into ASI_DC_TAG is:
26500Sstevel@tonic-gate *
26510Sstevel@tonic-gate *	+----------+--------+----------+----------+
26520Sstevel@tonic-gate *	| Reserved | DC_way | DC_addr  | Reserved |
26530Sstevel@tonic-gate *	+----------+--------+----------+----------+
26540Sstevel@tonic-gate *       63      16 15    14 13       5 4        0
26550Sstevel@tonic-gate *
26560Sstevel@tonic-gate * DC_way is a 2-bit index that selects one of the 4 ways.
26570Sstevel@tonic-gate * DC_addr is a 9-bit index that selects one of 512 tag/valid fields.
26580Sstevel@tonic-gate *
26590Sstevel@tonic-gate * Setting the DC_valid bit to zero for the specified DC_way and
26600Sstevel@tonic-gate * DC_addr index into the D$ results in an invalidation of a D$ line.
26610Sstevel@tonic-gate */
26620Sstevel@tonic-gate/*ARGSUSED*/
26630Sstevel@tonic-gatevoid
26640Sstevel@tonic-gatedcache_inval_line(int index)
26650Sstevel@tonic-gate{
26660Sstevel@tonic-gate}
26670Sstevel@tonic-gate#else	/* lint */
26680Sstevel@tonic-gate	ENTRY(dcache_inval_line)
26690Sstevel@tonic-gate	sll	%o0, 5, %o0		! shift index into DC_way and DC_addr
26700Sstevel@tonic-gate	stxa	%g0, [%o0]ASI_DC_TAG	! zero the DC_valid and DC_tag bits
26710Sstevel@tonic-gate	membar	#Sync
26720Sstevel@tonic-gate	retl
26730Sstevel@tonic-gate	nop
26740Sstevel@tonic-gate	SET_SIZE(dcache_inval_line)
26750Sstevel@tonic-gate#endif	/* lint */
26760Sstevel@tonic-gate
26770Sstevel@tonic-gate#if defined(lint)
26780Sstevel@tonic-gate/*
26790Sstevel@tonic-gate * Invalidate the entire I$
26800Sstevel@tonic-gate *
26810Sstevel@tonic-gate * Register usage:
26820Sstevel@tonic-gate *	%o0 - specifies IC_way, IC_addr, IC_tag
26830Sstevel@tonic-gate *	%o1 - scratch
26840Sstevel@tonic-gate *	%o2 - used to save and restore DCU value
26850Sstevel@tonic-gate *	%o3 - scratch
26860Sstevel@tonic-gate *	%o5 - used to save and restore PSTATE
26870Sstevel@tonic-gate *
26880Sstevel@tonic-gate * Due to the behavior of the I$ control logic when accessing ASI_IC_TAG,
26890Sstevel@tonic-gate * the I$ should be turned off. Accesses to ASI_IC_TAG may collide and
26900Sstevel@tonic-gate * block out snoops and invalidates to the I$, causing I$ consistency
26910Sstevel@tonic-gate * to be broken. Before turning on the I$, all I$ lines must be invalidated.
26920Sstevel@tonic-gate *
26930Sstevel@tonic-gate * ASI_IC_TAG, 0x67, is used in the following manner. A 64-bit value is
26940Sstevel@tonic-gate * stored to a particular IC_way, IC_addr, IC_tag in ASI_IC_TAG. The
26950Sstevel@tonic-gate * info below describes store (write) use of ASI_IC_TAG. Note that read
26960Sstevel@tonic-gate * use of ASI_IC_TAG behaves differently.
26970Sstevel@tonic-gate *
26980Sstevel@tonic-gate * The format of the stored 64-bit value is:
26990Sstevel@tonic-gate *
27000Sstevel@tonic-gate *	+----------+--------+---------------+-----------+
27010Sstevel@tonic-gate *	| Reserved | Valid  | IC_vpred<7:0> | Undefined |
27020Sstevel@tonic-gate *	+----------+--------+---------------+-----------+
27030Sstevel@tonic-gate *       63      55    54    53           46 45        0
27040Sstevel@tonic-gate *
27050Sstevel@tonic-gate * Valid is the 1-bit valid field for both the physical and snoop tags.
27060Sstevel@tonic-gate * IC_vpred is the 8-bit LPB bits for 8 instructions starting at
27070Sstevel@tonic-gate *	the 32-byte boundary aligned address specified by IC_addr.
27080Sstevel@tonic-gate *
27090Sstevel@tonic-gate * The format of the 64-bit IC_way, IC_addr, IC_tag into ASI_IC_TAG is:
27100Sstevel@tonic-gate *
27110Sstevel@tonic-gate *	+----------+--------+---------+--------+---------+
27120Sstevel@tonic-gate *	| Reserved | IC_way | IC_addr | IC_tag |Reserved |
27130Sstevel@tonic-gate *	+----------+--------+---------+--------+---------+
27140Sstevel@tonic-gate *       63      16 15    14 13      5 4      3 2       0
27150Sstevel@tonic-gate *
27160Sstevel@tonic-gate * IC_way is a 2-bit index that selects one of the 4 ways.
27170Sstevel@tonic-gate * IC_addr[13:6] is an 8-bit index that selects one of 256 valid fields.
27180Sstevel@tonic-gate * IC_addr[5] is a "don't care" for a store.
27190Sstevel@tonic-gate * IC_tag set to 2 specifies that the stored value is to be interpreted
27200Sstevel@tonic-gate *	as containing Valid and IC_vpred as described above.
27210Sstevel@tonic-gate *
27220Sstevel@tonic-gate * Setting the Valid bit to zero for the specified IC_way and
27230Sstevel@tonic-gate * IC_addr index into the I$ results in an invalidation of an I$ line.
27240Sstevel@tonic-gate */
27250Sstevel@tonic-gate/*ARGSUSED*/
27260Sstevel@tonic-gatevoid
27270Sstevel@tonic-gateicache_inval_all(void)
27280Sstevel@tonic-gate{
27290Sstevel@tonic-gate}
27300Sstevel@tonic-gate#else	/* lint */
27310Sstevel@tonic-gate	ENTRY(icache_inval_all)
27320Sstevel@tonic-gate	rdpr	%pstate, %o5
27330Sstevel@tonic-gate	andn	%o5, PSTATE_IE, %o3
27340Sstevel@tonic-gate	wrpr	%g0, %o3, %pstate	! clear IE bit
27350Sstevel@tonic-gate
27360Sstevel@tonic-gate	GET_CPU_PRIVATE_PTR(%g0, %o0, %o2, icache_inval_all_1);
27370Sstevel@tonic-gate	ld	[%o0 + CHPR_ICACHE_LINESIZE], %o1
27380Sstevel@tonic-gate	ba,pt	%icc, 2f
27390Sstevel@tonic-gate	  ld	[%o0 + CHPR_ICACHE_SIZE], %o0
27400Sstevel@tonic-gateicache_inval_all_1:
27410Sstevel@tonic-gate	ASM_LD(%o0, icache_size)
27420Sstevel@tonic-gate	ASM_LD(%o1, icache_linesize)
27430Sstevel@tonic-gate2:
27440Sstevel@tonic-gate	CH_ICACHE_FLUSHALL(%o0, %o1, %o2, %o4)
27450Sstevel@tonic-gate
27460Sstevel@tonic-gate	retl
27470Sstevel@tonic-gate	wrpr	%g0, %o5, %pstate	! restore earlier pstate
27480Sstevel@tonic-gate	SET_SIZE(icache_inval_all)
27490Sstevel@tonic-gate#endif	/* lint */
27500Sstevel@tonic-gate
27510Sstevel@tonic-gate
27520Sstevel@tonic-gate#if defined(lint)
27530Sstevel@tonic-gate/* ARGSUSED */
27540Sstevel@tonic-gatevoid
27550Sstevel@tonic-gatecache_scrubreq_tl1(uint64_t inum, uint64_t index)
27560Sstevel@tonic-gate{
27570Sstevel@tonic-gate}
27580Sstevel@tonic-gate
27590Sstevel@tonic-gate#else	/* lint */
27600Sstevel@tonic-gate/*
27610Sstevel@tonic-gate * cache_scrubreq_tl1 is the crosstrap handler called on offlined cpus via a
27620Sstevel@tonic-gate * crosstrap.  It atomically increments the outstanding request counter and,
27630Sstevel@tonic-gate * if there was not already an outstanding request, branches to setsoftint_tl1
27642973Sgovinda * to enqueue an intr_vec for the given inum.
27650Sstevel@tonic-gate */
27660Sstevel@tonic-gate
27670Sstevel@tonic-gate	! Register usage:
27680Sstevel@tonic-gate	!
27690Sstevel@tonic-gate	! Arguments:
27700Sstevel@tonic-gate	! %g1 - inum
27710Sstevel@tonic-gate	! %g2 - index into chsm_outstanding array
27720Sstevel@tonic-gate	!
27730Sstevel@tonic-gate	! Internal:
27740Sstevel@tonic-gate	! %g2, %g3, %g5 - scratch
27750Sstevel@tonic-gate	! %g4 - ptr. to scrub_misc chsm_outstanding[index].
27760Sstevel@tonic-gate	! %g6 - setsoftint_tl1 address
27770Sstevel@tonic-gate
27780Sstevel@tonic-gate	ENTRY_NP(cache_scrubreq_tl1)
27790Sstevel@tonic-gate	mulx	%g2, CHSM_OUTSTANDING_INCR, %g2
27800Sstevel@tonic-gate	set	CHPR_SCRUB_MISC + CHSM_OUTSTANDING, %g3
27810Sstevel@tonic-gate	add	%g2, %g3, %g2
27820Sstevel@tonic-gate	GET_CPU_PRIVATE_PTR(%g2, %g4, %g5, 1f);
27830Sstevel@tonic-gate	ld	[%g4], %g2		! cpu's chsm_outstanding[index]
27840Sstevel@tonic-gate	!
27850Sstevel@tonic-gate	! no need to use atomic instructions for the following
27860Sstevel@tonic-gate	! increment - we're at tl1
27870Sstevel@tonic-gate	!
27880Sstevel@tonic-gate	add	%g2, 0x1, %g3
27892973Sgovinda	brnz,pn	%g2, 1f			! no need to enqueue more intr_vec
27900Sstevel@tonic-gate	  st	%g3, [%g4]		! delay - store incremented counter
27910Sstevel@tonic-gate	ASM_JMP(%g6, setsoftint_tl1)
27920Sstevel@tonic-gate	! not reached
27930Sstevel@tonic-gate1:
27940Sstevel@tonic-gate	retry
27950Sstevel@tonic-gate	SET_SIZE(cache_scrubreq_tl1)
27960Sstevel@tonic-gate
27970Sstevel@tonic-gate#endif	/* lint */
27980Sstevel@tonic-gate
27990Sstevel@tonic-gate
28000Sstevel@tonic-gate#if defined(lint)
28010Sstevel@tonic-gate
28020Sstevel@tonic-gate/* ARGSUSED */
28030Sstevel@tonic-gatevoid
28040Sstevel@tonic-gateget_cpu_error_state(ch_cpu_errors_t *cpu_error_regs)
28050Sstevel@tonic-gate{}
28060Sstevel@tonic-gate
28070Sstevel@tonic-gate#else	/* lint */
28080Sstevel@tonic-gate
28090Sstevel@tonic-gate/*
28100Sstevel@tonic-gate * Get the error state for the processor.
28110Sstevel@tonic-gate * Note that this must not be used at TL>0
28120Sstevel@tonic-gate */
28130Sstevel@tonic-gate	ENTRY(get_cpu_error_state)
28140Sstevel@tonic-gate#if defined(CHEETAH_PLUS)
28150Sstevel@tonic-gate	set	ASI_SHADOW_REG_VA, %o2
28160Sstevel@tonic-gate	ldxa	[%o2]ASI_AFSR, %o1		! shadow afsr reg
28170Sstevel@tonic-gate	stx	%o1, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR]
28180Sstevel@tonic-gate	ldxa	[%o2]ASI_AFAR, %o1		! shadow afar reg
28190Sstevel@tonic-gate	stx	%o1, [%o0 + CH_CPU_ERRORS_SHADOW_AFAR]
28200Sstevel@tonic-gate	GET_CPU_IMPL(%o3)	! Only panther has AFSR_EXT registers
28210Sstevel@tonic-gate	cmp	%o3, PANTHER_IMPL
28220Sstevel@tonic-gate	bne,a	1f
28230Sstevel@tonic-gate	  stx	%g0, [%o0 + CH_CPU_ERRORS_AFSR_EXT]	! zero for non-PN
28240Sstevel@tonic-gate	set	ASI_AFSR_EXT_VA, %o2
28250Sstevel@tonic-gate	ldxa	[%o2]ASI_AFSR, %o1		! afsr_ext reg
28260Sstevel@tonic-gate	stx	%o1, [%o0 + CH_CPU_ERRORS_AFSR_EXT]
28270Sstevel@tonic-gate	set	ASI_SHADOW_AFSR_EXT_VA, %o2
28280Sstevel@tonic-gate	ldxa	[%o2]ASI_AFSR, %o1		! shadow afsr_ext reg
28290Sstevel@tonic-gate	stx	%o1, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR_EXT]
28300Sstevel@tonic-gate	b	2f
28310Sstevel@tonic-gate	  nop
28320Sstevel@tonic-gate1:
28330Sstevel@tonic-gate	stx	%g0, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR_EXT] ! zero for non-PN
28340Sstevel@tonic-gate2:
28350Sstevel@tonic-gate#else	/* CHEETAH_PLUS */
28360Sstevel@tonic-gate	stx	%g0, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR]
28370Sstevel@tonic-gate	stx	%g0, [%o0 + CH_CPU_ERRORS_SHADOW_AFAR]
28380Sstevel@tonic-gate	stx	%g0, [%o0 + CH_CPU_ERRORS_AFSR_EXT]
28390Sstevel@tonic-gate	stx	%g0, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR_EXT]
28400Sstevel@tonic-gate#endif	/* CHEETAH_PLUS */
28410Sstevel@tonic-gate#if defined(SERRANO)
28420Sstevel@tonic-gate	/*
28430Sstevel@tonic-gate	 * Serrano has an afar2 which captures the address on FRC/FRU errors.
28440Sstevel@tonic-gate	 * We save this in the afar2 of the register save area.
28450Sstevel@tonic-gate	 */
28460Sstevel@tonic-gate	set	ASI_MCU_AFAR2_VA, %o2
28470Sstevel@tonic-gate	ldxa	[%o2]ASI_MCU_CTRL, %o1
28480Sstevel@tonic-gate	stx	%o1, [%o0 + CH_CPU_ERRORS_AFAR2]
28490Sstevel@tonic-gate#endif	/* SERRANO */
28500Sstevel@tonic-gate	ldxa	[%g0]ASI_AFSR, %o1		! primary afsr reg
28510Sstevel@tonic-gate	stx	%o1, [%o0 + CH_CPU_ERRORS_AFSR]
28520Sstevel@tonic-gate	ldxa	[%g0]ASI_AFAR, %o1		! primary afar reg
28530Sstevel@tonic-gate	retl
28540Sstevel@tonic-gate	stx	%o1, [%o0 + CH_CPU_ERRORS_AFAR]
28550Sstevel@tonic-gate	SET_SIZE(get_cpu_error_state)
28560Sstevel@tonic-gate#endif	/* lint */
28570Sstevel@tonic-gate
28580Sstevel@tonic-gate#if defined(lint)
28590Sstevel@tonic-gate
28600Sstevel@tonic-gate/*
28610Sstevel@tonic-gate * Check a page of memory for errors.
28620Sstevel@tonic-gate *
28630Sstevel@tonic-gate * Load each 64 byte block from physical memory.
28640Sstevel@tonic-gate * Check AFSR after each load to see if an error
28650Sstevel@tonic-gate * was caused. If so, log/scrub that error.
28660Sstevel@tonic-gate *
28670Sstevel@tonic-gate * Used to determine if a page contains
28680Sstevel@tonic-gate * CEs when CEEN is disabled.
28690Sstevel@tonic-gate */
28700Sstevel@tonic-gate/*ARGSUSED*/
28710Sstevel@tonic-gatevoid
28720Sstevel@tonic-gatecpu_check_block(caddr_t va, uint_t psz)
28730Sstevel@tonic-gate{}
28740Sstevel@tonic-gate
28750Sstevel@tonic-gate#else	/* lint */
28760Sstevel@tonic-gate
28770Sstevel@tonic-gate	ENTRY(cpu_check_block)
28780Sstevel@tonic-gate	!
28790Sstevel@tonic-gate	! get a new window with room for the error regs
28800Sstevel@tonic-gate	!
28810Sstevel@tonic-gate	save	%sp, -SA(MINFRAME + CH_CPU_ERROR_SIZE), %sp
28820Sstevel@tonic-gate	srl	%i1, 6, %l4		! clear top bits of psz
28830Sstevel@tonic-gate					! and divide by 64
28840Sstevel@tonic-gate	rd	%fprs, %l2		! store FP
28850Sstevel@tonic-gate	wr	%g0, FPRS_FEF, %fprs	! enable FP
28860Sstevel@tonic-gate1:
28870Sstevel@tonic-gate	ldda	[%i0]ASI_BLK_P, %d0	! load a block
28880Sstevel@tonic-gate	membar	#Sync
28890Sstevel@tonic-gate	ldxa    [%g0]ASI_AFSR, %l3	! read afsr reg
28900Sstevel@tonic-gate	brz,a,pt %l3, 2f		! check for error
28910Sstevel@tonic-gate	nop
28920Sstevel@tonic-gate
28930Sstevel@tonic-gate	!
28940Sstevel@tonic-gate	! if error, read the error regs and log it
28950Sstevel@tonic-gate	!
28960Sstevel@tonic-gate	call	get_cpu_error_state
28970Sstevel@tonic-gate	add	%fp, STACK_BIAS - CH_CPU_ERROR_SIZE, %o0
28980Sstevel@tonic-gate
28990Sstevel@tonic-gate	!
29000Sstevel@tonic-gate	! cpu_ce_detected(ch_cpu_errors_t *, flag)
29010Sstevel@tonic-gate	!
29020Sstevel@tonic-gate	call	cpu_ce_detected		! log the error
29030Sstevel@tonic-gate	mov	CE_CEEN_TIMEOUT, %o1
29040Sstevel@tonic-gate2:
29050Sstevel@tonic-gate	dec	%l4			! next 64-byte block
29060Sstevel@tonic-gate	brnz,a,pt  %l4, 1b
29070Sstevel@tonic-gate	add	%i0, 64, %i0		! increment block addr
29080Sstevel@tonic-gate
29090Sstevel@tonic-gate	wr	%l2, %g0, %fprs		! restore FP
29100Sstevel@tonic-gate	ret
29110Sstevel@tonic-gate	restore
29120Sstevel@tonic-gate
29130Sstevel@tonic-gate	SET_SIZE(cpu_check_block)
29140Sstevel@tonic-gate
29150Sstevel@tonic-gate#endif	/* lint */
29160Sstevel@tonic-gate
29170Sstevel@tonic-gate#if defined(lint)
29180Sstevel@tonic-gate
29190Sstevel@tonic-gate/*
29200Sstevel@tonic-gate * Perform a cpu logout called from C.  This is used where we did not trap
29210Sstevel@tonic-gate * for the error but still want to gather "what we can".  Caller must make
29220Sstevel@tonic-gate * sure cpu private area exists and that the indicated logout area is free
29230Sstevel@tonic-gate * for use, and that we are unable to migrate cpus.
29240Sstevel@tonic-gate */
29250Sstevel@tonic-gate/*ARGSUSED*/
29260Sstevel@tonic-gatevoid
29270Sstevel@tonic-gatecpu_delayed_logout(uint64_t afar, ch_cpu_logout_t *clop)
29280Sstevel@tonic-gate{ }
29290Sstevel@tonic-gate
29300Sstevel@tonic-gate#else
29310Sstevel@tonic-gate	ENTRY(cpu_delayed_logout)
29320Sstevel@tonic-gate	rdpr	%pstate, %o2
29330Sstevel@tonic-gate	andn	%o2, PSTATE_IE, %o2
29340Sstevel@tonic-gate	wrpr	%g0, %o2, %pstate		! disable interrupts
29350Sstevel@tonic-gate	PARK_SIBLING_CORE(%o2, %o3, %o4)	! %o2 has DCU value
29360Sstevel@tonic-gate	add	%o1, CH_CLO_DATA + CH_CHD_EC_DATA, %o1
29370Sstevel@tonic-gate	rd	%asi, %g1
29380Sstevel@tonic-gate	wr	%g0, ASI_P, %asi
29390Sstevel@tonic-gate	GET_ECACHE_DTAGS(%o0, %o1, %o3, %o4, %o5)
29400Sstevel@tonic-gate	wr	%g1, %asi
29410Sstevel@tonic-gate	UNPARK_SIBLING_CORE(%o2, %o3, %o4)	! can use %o2 again
29420Sstevel@tonic-gate	rdpr	%pstate, %o2
29430Sstevel@tonic-gate	or	%o2, PSTATE_IE, %o2
29440Sstevel@tonic-gate	wrpr	%g0, %o2, %pstate
29450Sstevel@tonic-gate	retl
29460Sstevel@tonic-gate	  nop
29470Sstevel@tonic-gate	SET_SIZE(cpu_delayed_logout)
29480Sstevel@tonic-gate
29490Sstevel@tonic-gate#endif	/* lint */
29500Sstevel@tonic-gate
29510Sstevel@tonic-gate#if defined(lint)
29520Sstevel@tonic-gate
29530Sstevel@tonic-gate/*ARGSUSED*/
29540Sstevel@tonic-gateint
29550Sstevel@tonic-gatedtrace_blksuword32(uintptr_t addr, uint32_t *data, int tryagain)
29560Sstevel@tonic-gate{ return (0); }
29570Sstevel@tonic-gate
29580Sstevel@tonic-gate#else
29590Sstevel@tonic-gate
29600Sstevel@tonic-gate	ENTRY(dtrace_blksuword32)
29610Sstevel@tonic-gate	save	%sp, -SA(MINFRAME + 4), %sp
29620Sstevel@tonic-gate
29630Sstevel@tonic-gate	rdpr	%pstate, %l1
29640Sstevel@tonic-gate	andn	%l1, PSTATE_IE, %l2		! disable interrupts to
29650Sstevel@tonic-gate	wrpr	%g0, %l2, %pstate		! protect our FPU diddling
29660Sstevel@tonic-gate
29670Sstevel@tonic-gate	rd	%fprs, %l0
29680Sstevel@tonic-gate	andcc	%l0, FPRS_FEF, %g0
29690Sstevel@tonic-gate	bz,a,pt	%xcc, 1f			! if the fpu is disabled
29700Sstevel@tonic-gate	wr	%g0, FPRS_FEF, %fprs		! ... enable the fpu
29710Sstevel@tonic-gate
29720Sstevel@tonic-gate	st	%f0, [%fp + STACK_BIAS - 4]	! save %f0 to the stack
29730Sstevel@tonic-gate1:
29740Sstevel@tonic-gate	set	0f, %l5
29750Sstevel@tonic-gate        /*
29760Sstevel@tonic-gate         * We're about to write a block full or either total garbage
29770Sstevel@tonic-gate         * (not kernel data, don't worry) or user floating-point data
29780Sstevel@tonic-gate         * (so it only _looks_ like garbage).
29790Sstevel@tonic-gate         */
29800Sstevel@tonic-gate	ld	[%i1], %f0			! modify the block
29810Sstevel@tonic-gate	membar	#Sync
29820Sstevel@tonic-gate	stn	%l5, [THREAD_REG + T_LOFAULT]	! set up the lofault handler
29830Sstevel@tonic-gate	stda	%d0, [%i0]ASI_BLK_COMMIT_S	! store the modified block
29840Sstevel@tonic-gate	membar	#Sync
29850Sstevel@tonic-gate	stn	%g0, [THREAD_REG + T_LOFAULT]	! remove the lofault handler
29860Sstevel@tonic-gate
29870Sstevel@tonic-gate	bz,a,pt	%xcc, 1f
29880Sstevel@tonic-gate	wr	%g0, %l0, %fprs			! restore %fprs
29890Sstevel@tonic-gate
29900Sstevel@tonic-gate	ld	[%fp + STACK_BIAS - 4], %f0	! restore %f0
29910Sstevel@tonic-gate1:
29920Sstevel@tonic-gate
29930Sstevel@tonic-gate	wrpr	%g0, %l1, %pstate		! restore interrupts
29940Sstevel@tonic-gate
29950Sstevel@tonic-gate	ret
29960Sstevel@tonic-gate	restore	%g0, %g0, %o0
29970Sstevel@tonic-gate
29980Sstevel@tonic-gate0:
29990Sstevel@tonic-gate	membar	#Sync
30000Sstevel@tonic-gate	stn	%g0, [THREAD_REG + T_LOFAULT]	! remove the lofault handler
30010Sstevel@tonic-gate
30020Sstevel@tonic-gate	bz,a,pt	%xcc, 1f
30030Sstevel@tonic-gate	wr	%g0, %l0, %fprs			! restore %fprs
30040Sstevel@tonic-gate
30050Sstevel@tonic-gate	ld	[%fp + STACK_BIAS - 4], %f0	! restore %f0
30060Sstevel@tonic-gate1:
30070Sstevel@tonic-gate
30080Sstevel@tonic-gate	wrpr	%g0, %l1, %pstate		! restore interrupts
30090Sstevel@tonic-gate
30100Sstevel@tonic-gate	/*
30110Sstevel@tonic-gate	 * If tryagain is set (%i2) we tail-call dtrace_blksuword32_err()
30120Sstevel@tonic-gate	 * which deals with watchpoints. Otherwise, just return -1.
30130Sstevel@tonic-gate	 */
30140Sstevel@tonic-gate	brnz,pt	%i2, 1f
30150Sstevel@tonic-gate	nop
30160Sstevel@tonic-gate	ret
30170Sstevel@tonic-gate	restore	%g0, -1, %o0
30180Sstevel@tonic-gate1:
30190Sstevel@tonic-gate	call	dtrace_blksuword32_err
30200Sstevel@tonic-gate	restore
30210Sstevel@tonic-gate
30220Sstevel@tonic-gate	SET_SIZE(dtrace_blksuword32)
30230Sstevel@tonic-gate
30240Sstevel@tonic-gate#endif /* lint */
30250Sstevel@tonic-gate
30260Sstevel@tonic-gate#ifdef	CHEETAHPLUS_ERRATUM_25
30270Sstevel@tonic-gate
30280Sstevel@tonic-gate#if	defined(lint)
30290Sstevel@tonic-gate/*
30300Sstevel@tonic-gate * Claim a chunk of physical address space.
30310Sstevel@tonic-gate */
30320Sstevel@tonic-gate/*ARGSUSED*/
30330Sstevel@tonic-gatevoid
30340Sstevel@tonic-gateclaimlines(uint64_t pa, size_t sz, int stride)
30350Sstevel@tonic-gate{}
30360Sstevel@tonic-gate#else	/* lint */
30370Sstevel@tonic-gate	ENTRY(claimlines)
30380Sstevel@tonic-gate1:
30390Sstevel@tonic-gate	subcc	%o1, %o2, %o1
30400Sstevel@tonic-gate	add	%o0, %o1, %o3
30410Sstevel@tonic-gate	bgeu,a,pt	%xcc, 1b
30420Sstevel@tonic-gate	casxa	[%o3]ASI_MEM, %g0, %g0
30430Sstevel@tonic-gate	membar  #Sync
30440Sstevel@tonic-gate	retl
30450Sstevel@tonic-gate	nop
30460Sstevel@tonic-gate	SET_SIZE(claimlines)
30470Sstevel@tonic-gate#endif	/* lint */
30480Sstevel@tonic-gate
30490Sstevel@tonic-gate#if	defined(lint)
30500Sstevel@tonic-gate/*
30510Sstevel@tonic-gate * CPU feature initialization,
30520Sstevel@tonic-gate * turn BPE off,
30530Sstevel@tonic-gate * get device id.
30540Sstevel@tonic-gate */
30550Sstevel@tonic-gate/*ARGSUSED*/
30560Sstevel@tonic-gatevoid
30570Sstevel@tonic-gatecpu_feature_init(void)
30580Sstevel@tonic-gate{}
30590Sstevel@tonic-gate#else	/* lint */
30600Sstevel@tonic-gate	ENTRY(cpu_feature_init)
30610Sstevel@tonic-gate	save	%sp, -SA(MINFRAME), %sp
30620Sstevel@tonic-gate	sethi	%hi(cheetah_bpe_off), %o0
30630Sstevel@tonic-gate	ld	[%o0 + %lo(cheetah_bpe_off)], %o0
30640Sstevel@tonic-gate	brz	%o0, 1f
30650Sstevel@tonic-gate	nop
30660Sstevel@tonic-gate	rd	ASR_DISPATCH_CONTROL, %o0
30670Sstevel@tonic-gate	andn	%o0, ASR_DISPATCH_CONTROL_BPE, %o0
30680Sstevel@tonic-gate	wr	%o0, 0, ASR_DISPATCH_CONTROL
30690Sstevel@tonic-gate1:
30700Sstevel@tonic-gate	!
30710Sstevel@tonic-gate	! get the device_id and store the device_id
30720Sstevel@tonic-gate	! in the appropriate cpunodes structure
30730Sstevel@tonic-gate	! given the cpus index
30740Sstevel@tonic-gate	!
30750Sstevel@tonic-gate	CPU_INDEX(%o0, %o1)
30760Sstevel@tonic-gate	mulx %o0, CPU_NODE_SIZE, %o0
30770Sstevel@tonic-gate	set  cpunodes + DEVICE_ID, %o1
30780Sstevel@tonic-gate	ldxa [%g0] ASI_DEVICE_SERIAL_ID, %o2
30790Sstevel@tonic-gate	stx  %o2, [%o0 + %o1]
30800Sstevel@tonic-gate#ifdef	CHEETAHPLUS_ERRATUM_34
30810Sstevel@tonic-gate	!
30820Sstevel@tonic-gate	! apply Cheetah+ erratum 34 workaround
30830Sstevel@tonic-gate	!
30840Sstevel@tonic-gate	call itlb_erratum34_fixup
30850Sstevel@tonic-gate	  nop
30866674Sjfrank	call dtlb_erratum34_fixup
30876674Sjfrank	  nop
30880Sstevel@tonic-gate#endif	/* CHEETAHPLUS_ERRATUM_34 */
30890Sstevel@tonic-gate	ret
30900Sstevel@tonic-gate	  restore
30910Sstevel@tonic-gate	SET_SIZE(cpu_feature_init)
30920Sstevel@tonic-gate#endif	/* lint */
30930Sstevel@tonic-gate
30940Sstevel@tonic-gate#if	defined(lint)
30950Sstevel@tonic-gate/*
30960Sstevel@tonic-gate * Copy a tsb entry atomically, from src to dest.
30970Sstevel@tonic-gate * src must be 128 bit aligned.
30980Sstevel@tonic-gate */
30990Sstevel@tonic-gate/*ARGSUSED*/
31000Sstevel@tonic-gatevoid
31010Sstevel@tonic-gatecopy_tsb_entry(uintptr_t src, uintptr_t dest)
31020Sstevel@tonic-gate{}
31030Sstevel@tonic-gate#else	/* lint */
31040Sstevel@tonic-gate	ENTRY(copy_tsb_entry)
31050Sstevel@tonic-gate	ldda	[%o0]ASI_NQUAD_LD, %o2		! %o2 = tag, %o3 = data
31060Sstevel@tonic-gate	stx	%o2, [%o1]
31070Sstevel@tonic-gate	stx	%o3, [%o1 + 8 ]
31080Sstevel@tonic-gate	retl
31090Sstevel@tonic-gate	nop
31100Sstevel@tonic-gate	SET_SIZE(copy_tsb_entry)
31110Sstevel@tonic-gate#endif	/* lint */
31120Sstevel@tonic-gate
31130Sstevel@tonic-gate#endif	/* CHEETAHPLUS_ERRATUM_25 */
31140Sstevel@tonic-gate
31150Sstevel@tonic-gate#ifdef	CHEETAHPLUS_ERRATUM_34
31160Sstevel@tonic-gate
31170Sstevel@tonic-gate#if	defined(lint)
31180Sstevel@tonic-gate
31190Sstevel@tonic-gate/*ARGSUSED*/
31200Sstevel@tonic-gatevoid
31210Sstevel@tonic-gateitlb_erratum34_fixup(void)
31220Sstevel@tonic-gate{}
31230Sstevel@tonic-gate
31240Sstevel@tonic-gate#else	/* lint */
31250Sstevel@tonic-gate
31260Sstevel@tonic-gate	!
31270Sstevel@tonic-gate	! In Cheetah+ erratum 34, under certain conditions an ITLB locked
31280Sstevel@tonic-gate	! index 0 TTE will erroneously be displaced when a new TTE is
31290Sstevel@tonic-gate	! loaded via ASI_ITLB_IN.  In order to avoid cheetah+ erratum 34,
31300Sstevel@tonic-gate	! locked index 0 TTEs must be relocated.
31310Sstevel@tonic-gate	!
31320Sstevel@tonic-gate	! NOTE: Care must be taken to avoid an ITLB miss in this routine.
31330Sstevel@tonic-gate	!
31340Sstevel@tonic-gate	ENTRY_NP(itlb_erratum34_fixup)
31350Sstevel@tonic-gate	rdpr	%pstate, %o3
31360Sstevel@tonic-gate#ifdef DEBUG
31372241Shuah	PANIC_IF_INTR_DISABLED_PSTR(%o3, u3_di_label1, %g1)
31380Sstevel@tonic-gate#endif /* DEBUG */
31390Sstevel@tonic-gate	wrpr	%o3, PSTATE_IE, %pstate		! Disable interrupts
31400Sstevel@tonic-gate	ldxa	[%g0]ASI_ITLB_ACCESS, %o1	! %o1 = entry 0 data
31410Sstevel@tonic-gate	ldxa	[%g0]ASI_ITLB_TAGREAD, %o2	! %o2 = entry 0 tag
31420Sstevel@tonic-gate
31430Sstevel@tonic-gate	cmp	%o1, %g0			! Is this entry valid?
31440Sstevel@tonic-gate	bge	%xcc, 1f
31450Sstevel@tonic-gate	  andcc	%o1, TTE_LCK_INT, %g0		! Is this entry locked?
31460Sstevel@tonic-gate	bnz	%icc, 2f
31470Sstevel@tonic-gate	  nop
31480Sstevel@tonic-gate1:
31490Sstevel@tonic-gate	retl					! Nope, outta here...
31500Sstevel@tonic-gate	  wrpr	%g0, %o3, %pstate		! Enable interrupts
31510Sstevel@tonic-gate2:
31520Sstevel@tonic-gate	sethi	%hi(FLUSH_ADDR), %o4
31530Sstevel@tonic-gate	stxa	%g0, [%o2]ASI_ITLB_DEMAP	! Flush this mapping
31540Sstevel@tonic-gate	flush	%o4				! Flush required for I-MMU
31550Sstevel@tonic-gate	!
31560Sstevel@tonic-gate	! Start search from index 1 up.  This is because the kernel force
31570Sstevel@tonic-gate	! loads its text page at index 15 in sfmmu_kernel_remap() and we
31580Sstevel@tonic-gate	! don't want our relocated entry evicted later.
31590Sstevel@tonic-gate	!
31600Sstevel@tonic-gate	! NOTE: We assume that we'll be successful in finding an unlocked
31610Sstevel@tonic-gate	! or invalid entry.  If that isn't the case there are bound to
31620Sstevel@tonic-gate	! bigger problems.
31630Sstevel@tonic-gate	!
31640Sstevel@tonic-gate	set	(1 << 3), %g3
31650Sstevel@tonic-gate3:
31660Sstevel@tonic-gate	ldxa	[%g3]ASI_ITLB_ACCESS, %o4	! Load TTE from t16
31670Sstevel@tonic-gate	!
31680Sstevel@tonic-gate	! If this entry isn't valid, we'll choose to displace it (regardless
31690Sstevel@tonic-gate	! of the lock bit).
31700Sstevel@tonic-gate	!
31710Sstevel@tonic-gate	cmp	%o4, %g0			! TTE is > 0 iff not valid
31720Sstevel@tonic-gate	bge	%xcc, 4f			! If invalid, go displace
31730Sstevel@tonic-gate	  andcc	%o4, TTE_LCK_INT, %g0		! Check for lock bit
31740Sstevel@tonic-gate	bnz,a	%icc, 3b			! If locked, look at next
31750Sstevel@tonic-gate	  add	%g3, (1 << 3), %g3		!  entry
31760Sstevel@tonic-gate4:
31770Sstevel@tonic-gate	!
31780Sstevel@tonic-gate	! We found an unlocked or invalid entry; we'll explicitly load
31790Sstevel@tonic-gate	! the former index 0 entry here.
31800Sstevel@tonic-gate	!
31810Sstevel@tonic-gate	sethi	%hi(FLUSH_ADDR), %o4
31820Sstevel@tonic-gate	set	MMU_TAG_ACCESS, %g4
31830Sstevel@tonic-gate	stxa	%o2, [%g4]ASI_IMMU
31840Sstevel@tonic-gate	stxa	%o1, [%g3]ASI_ITLB_ACCESS
31850Sstevel@tonic-gate	flush	%o4				! Flush required for I-MMU
31860Sstevel@tonic-gate	retl
31870Sstevel@tonic-gate	  wrpr	%g0, %o3, %pstate		! Enable interrupts
31880Sstevel@tonic-gate	SET_SIZE(itlb_erratum34_fixup)
31890Sstevel@tonic-gate
31900Sstevel@tonic-gate#endif	/* lint */
31910Sstevel@tonic-gate
31926674Sjfrank#if	defined(lint)
31936674Sjfrank
31946674Sjfrank/*ARGSUSED*/
31956674Sjfrankvoid
31966674Sjfrankdtlb_erratum34_fixup(void)
31976674Sjfrank{}
31986674Sjfrank
31996674Sjfrank#else	/* lint */
32006674Sjfrank
32016674Sjfrank	!
32026674Sjfrank	! In Cheetah+ erratum 34, under certain conditions a DTLB locked
32036674Sjfrank	! index 0 TTE will erroneously be displaced when a new TTE is
32046674Sjfrank	! loaded.  In order to avoid cheetah+ erratum 34, locked index 0
32056674Sjfrank	! TTEs must be relocated.
32066674Sjfrank	!
32076674Sjfrank	ENTRY_NP(dtlb_erratum34_fixup)
32086674Sjfrank	rdpr	%pstate, %o3
32096674Sjfrank#ifdef DEBUG
32106674Sjfrank	PANIC_IF_INTR_DISABLED_PSTR(%o3, u3_di_label2, %g1)
32116674Sjfrank#endif /* DEBUG */
32126674Sjfrank	wrpr	%o3, PSTATE_IE, %pstate		! Disable interrupts
32136674Sjfrank	ldxa	[%g0]ASI_DTLB_ACCESS, %o1	! %o1 = entry 0 data
32146674Sjfrank	ldxa	[%g0]ASI_DTLB_TAGREAD, %o2	! %o2 = entry 0 tag
32156674Sjfrank
32166674Sjfrank	cmp	%o1, %g0			! Is this entry valid?
32176674Sjfrank	bge	%xcc, 1f
32186674Sjfrank	  andcc	%o1, TTE_LCK_INT, %g0		! Is this entry locked?
32196674Sjfrank	bnz	%icc, 2f
32206674Sjfrank	  nop
32216674Sjfrank1:
32226674Sjfrank	retl					! Nope, outta here...
32236674Sjfrank	  wrpr	%g0, %o3, %pstate		! Enable interrupts
32246674Sjfrank2:
32256674Sjfrank	stxa	%g0, [%o2]ASI_DTLB_DEMAP	! Flush this mapping
32266674Sjfrank	membar	#Sync
32276674Sjfrank	!
32286674Sjfrank	! Start search from index 1 up.
32296674Sjfrank	!
32306674Sjfrank	! NOTE: We assume that we'll be successful in finding an unlocked
32316674Sjfrank	! or invalid entry.  If that isn't the case there are bound to
32326674Sjfrank	! bigger problems.
32336674Sjfrank	!
32346674Sjfrank	set	(1 << 3), %g3
32356674Sjfrank3:
32366674Sjfrank	ldxa	[%g3]ASI_DTLB_ACCESS, %o4	! Load TTE from t16
32376674Sjfrank	!
32386674Sjfrank	! If this entry isn't valid, we'll choose to displace it (regardless
32396674Sjfrank	! of the lock bit).
32406674Sjfrank	!
32416674Sjfrank	cmp	%o4, %g0			! TTE is > 0 iff not valid
32426674Sjfrank	bge	%xcc, 4f			! If invalid, go displace
32436674Sjfrank	  andcc	%o4, TTE_LCK_INT, %g0		! Check for lock bit
32446674Sjfrank	bnz,a	%icc, 3b			! If locked, look at next
32456674Sjfrank	  add	%g3, (1 << 3), %g3		!  entry
32466674Sjfrank4:
32476674Sjfrank	!
32486674Sjfrank	! We found an unlocked or invalid entry; we'll explicitly load
32496674Sjfrank	! the former index 0 entry here.
32506674Sjfrank	!
32516674Sjfrank	set	MMU_TAG_ACCESS, %g4
32526674Sjfrank	stxa	%o2, [%g4]ASI_DMMU
32536674Sjfrank	stxa	%o1, [%g3]ASI_DTLB_ACCESS
32546674Sjfrank	membar	#Sync
32556674Sjfrank	retl
32566674Sjfrank	  wrpr	%g0, %o3, %pstate		! Enable interrupts
32576674Sjfrank	SET_SIZE(dtlb_erratum34_fixup)
32586674Sjfrank
32596674Sjfrank#endif	/* lint */
32606674Sjfrank
32610Sstevel@tonic-gate#endif	/* CHEETAHPLUS_ERRATUM_34 */
32620Sstevel@tonic-gate
3263