xref: /titanic_51/usr/src/uts/sun4u/cpu/us3_common_asm.s (revision bd963cb9a079e6b9cd23645670bf4b0185cbfe4c)
17c478bd9Sstevel@tonic-gate/*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
51e2e7a75Shuah * Common Development and Distribution License (the "License").
61e2e7a75Shuah * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate/*
22*bd963cb9SEthindra Ramamurthy * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate *
257c478bd9Sstevel@tonic-gate * Assembly code support for Cheetah/Cheetah+ modules
267c478bd9Sstevel@tonic-gate */
277c478bd9Sstevel@tonic-gate
287c478bd9Sstevel@tonic-gate#if !defined(lint)
297c478bd9Sstevel@tonic-gate#include "assym.h"
307c478bd9Sstevel@tonic-gate#endif	/* !lint */
317c478bd9Sstevel@tonic-gate
327c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h>
337c478bd9Sstevel@tonic-gate#include <sys/mmu.h>
347c478bd9Sstevel@tonic-gate#include <vm/hat_sfmmu.h>
357c478bd9Sstevel@tonic-gate#include <sys/machparam.h>
367c478bd9Sstevel@tonic-gate#include <sys/machcpuvar.h>
377c478bd9Sstevel@tonic-gate#include <sys/machthread.h>
387c478bd9Sstevel@tonic-gate#include <sys/machtrap.h>
397c478bd9Sstevel@tonic-gate#include <sys/privregs.h>
407c478bd9Sstevel@tonic-gate#include <sys/trap.h>
417c478bd9Sstevel@tonic-gate#include <sys/cheetahregs.h>
427c478bd9Sstevel@tonic-gate#include <sys/us3_module.h>
437c478bd9Sstevel@tonic-gate#include <sys/xc_impl.h>
447c478bd9Sstevel@tonic-gate#include <sys/intreg.h>
457c478bd9Sstevel@tonic-gate#include <sys/async.h>
467c478bd9Sstevel@tonic-gate#include <sys/clock.h>
477c478bd9Sstevel@tonic-gate#include <sys/cheetahasm.h>
487c478bd9Sstevel@tonic-gate#include <sys/cmpregs.h>
497c478bd9Sstevel@tonic-gate
507c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE
517c478bd9Sstevel@tonic-gate#include <sys/traptrace.h>
527c478bd9Sstevel@tonic-gate#endif /* TRAPTRACE */
537c478bd9Sstevel@tonic-gate
547c478bd9Sstevel@tonic-gate#if !defined(lint)
557c478bd9Sstevel@tonic-gate
567c478bd9Sstevel@tonic-gate/* BEGIN CSTYLED */
577c478bd9Sstevel@tonic-gate
587c478bd9Sstevel@tonic-gate#define	DCACHE_FLUSHPAGE(arg1, arg2, tmp1, tmp2, tmp3)			\
597c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_DCU, tmp1					;\
607c478bd9Sstevel@tonic-gate	btst	DCU_DC, tmp1		/* is dcache enabled? */	;\
617c478bd9Sstevel@tonic-gate	bz,pn	%icc, 1f						;\
627c478bd9Sstevel@tonic-gate	ASM_LD(tmp1, dcache_linesize)					;\
637c478bd9Sstevel@tonic-gate	ASM_LD(tmp2, dflush_type)					;\
647c478bd9Sstevel@tonic-gate	cmp	tmp2, FLUSHPAGE_TYPE					;\
657c478bd9Sstevel@tonic-gate	be,pt	%icc, 2f						;\
667c478bd9Sstevel@tonic-gate	nop								;\
677c478bd9Sstevel@tonic-gate	sllx	arg1, CHEETAH_DC_VBIT_SHIFT, arg1/* tag to compare */	;\
687c478bd9Sstevel@tonic-gate	ASM_LD(tmp3, dcache_size)					;\
697c478bd9Sstevel@tonic-gate	cmp	tmp2, FLUSHMATCH_TYPE					;\
707c478bd9Sstevel@tonic-gate	be,pt	%icc, 3f						;\
717c478bd9Sstevel@tonic-gate	nop								;\
727c478bd9Sstevel@tonic-gate	/*								\
737c478bd9Sstevel@tonic-gate	 * flushtype = FLUSHALL_TYPE, flush the whole thing		\
747c478bd9Sstevel@tonic-gate	 * tmp3 = cache size						\
757c478bd9Sstevel@tonic-gate	 * tmp1 = cache line size					\
767c478bd9Sstevel@tonic-gate	 */								\
777c478bd9Sstevel@tonic-gate	sub	tmp3, tmp1, tmp2					;\
787c478bd9Sstevel@tonic-gate4:									\
797c478bd9Sstevel@tonic-gate	stxa	%g0, [tmp2]ASI_DC_TAG					;\
807c478bd9Sstevel@tonic-gate	membar	#Sync							;\
817c478bd9Sstevel@tonic-gate	cmp	%g0, tmp2						;\
827c478bd9Sstevel@tonic-gate	bne,pt	%icc, 4b						;\
837c478bd9Sstevel@tonic-gate	sub	tmp2, tmp1, tmp2					;\
847c478bd9Sstevel@tonic-gate	ba,pt	%icc, 1f						;\
857c478bd9Sstevel@tonic-gate	nop								;\
867c478bd9Sstevel@tonic-gate	/*								\
877c478bd9Sstevel@tonic-gate	 * flushtype = FLUSHPAGE_TYPE					\
887c478bd9Sstevel@tonic-gate	 * arg1 = pfn							\
897c478bd9Sstevel@tonic-gate	 * arg2 = virtual color						\
907c478bd9Sstevel@tonic-gate	 * tmp1 = cache line size					\
917c478bd9Sstevel@tonic-gate	 * tmp2 = tag from cache					\
927c478bd9Sstevel@tonic-gate	 * tmp3 = counter						\
937c478bd9Sstevel@tonic-gate	 */								\
947c478bd9Sstevel@tonic-gate2:									\
957c478bd9Sstevel@tonic-gate	set	MMU_PAGESIZE, tmp3					;\
967c478bd9Sstevel@tonic-gate        sllx    arg1, MMU_PAGESHIFT, arg1  /* pfn to 43 bit PA	   */   ;\
977c478bd9Sstevel@tonic-gate	sub	tmp3, tmp1, tmp3					;\
987c478bd9Sstevel@tonic-gate4:									\
997c478bd9Sstevel@tonic-gate	stxa	%g0, [arg1 + tmp3]ASI_DC_INVAL				;\
1007c478bd9Sstevel@tonic-gate	membar	#Sync							;\
1017c478bd9Sstevel@tonic-gate5:									\
1027c478bd9Sstevel@tonic-gate	cmp	%g0, tmp3						;\
1037c478bd9Sstevel@tonic-gate	bnz,pt	%icc, 4b		/* branch if not done */	;\
1047c478bd9Sstevel@tonic-gate	sub	tmp3, tmp1, tmp3					;\
1057c478bd9Sstevel@tonic-gate	ba,pt	%icc, 1f						;\
1067c478bd9Sstevel@tonic-gate	nop								;\
1077c478bd9Sstevel@tonic-gate	/*								\
1087c478bd9Sstevel@tonic-gate	 * flushtype = FLUSHMATCH_TYPE					\
1097c478bd9Sstevel@tonic-gate	 * arg1 = tag to compare against				\
1107c478bd9Sstevel@tonic-gate	 * tmp1 = cache line size					\
1117c478bd9Sstevel@tonic-gate	 * tmp3 = cache size						\
1127c478bd9Sstevel@tonic-gate	 * arg2 = counter						\
1137c478bd9Sstevel@tonic-gate	 * tmp2 = cache tag						\
1147c478bd9Sstevel@tonic-gate	 */								\
1157c478bd9Sstevel@tonic-gate3:									\
1167c478bd9Sstevel@tonic-gate	sub	tmp3, tmp1, arg2					;\
1177c478bd9Sstevel@tonic-gate4:									\
1187c478bd9Sstevel@tonic-gate	ldxa	[arg2]ASI_DC_TAG, tmp2		/* read tag */		;\
1197c478bd9Sstevel@tonic-gate	btst	CHEETAH_DC_VBIT_MASK, tmp2				;\
1207c478bd9Sstevel@tonic-gate	bz,pn	%icc, 5f		/* br if no valid sub-blocks */	;\
1217c478bd9Sstevel@tonic-gate	andn	tmp2, CHEETAH_DC_VBIT_MASK, tmp2 /* clear out v bits */	;\
1227c478bd9Sstevel@tonic-gate	cmp	tmp2, arg1						;\
1237c478bd9Sstevel@tonic-gate	bne,pn	%icc, 5f		/* branch if tag miss */	;\
1247c478bd9Sstevel@tonic-gate	nop								;\
1257c478bd9Sstevel@tonic-gate	stxa	%g0, [arg2]ASI_DC_TAG					;\
1267c478bd9Sstevel@tonic-gate	membar	#Sync							;\
1277c478bd9Sstevel@tonic-gate5:									\
1287c478bd9Sstevel@tonic-gate	cmp	%g0, arg2						;\
1297c478bd9Sstevel@tonic-gate	bne,pt	%icc, 4b		/* branch if not done */	;\
1307c478bd9Sstevel@tonic-gate	sub	arg2, tmp1, arg2					;\
1317c478bd9Sstevel@tonic-gate1:
1327c478bd9Sstevel@tonic-gate
133444ce08eSDonghai Qiao/*
134444ce08eSDonghai Qiao * macro that flushes the entire dcache color
135444ce08eSDonghai Qiao * dcache size = 64K, one way 16K
136*bd963cb9SEthindra Ramamurthy *
137*bd963cb9SEthindra Ramamurthy * In:
138*bd963cb9SEthindra Ramamurthy *    arg = virtual color register (not clobbered)
139*bd963cb9SEthindra Ramamurthy *    way = way#, can either be a constant or a register (not clobbered)
140*bd963cb9SEthindra Ramamurthy *    tmp1, tmp2, tmp3 = scratch registers
141*bd963cb9SEthindra Ramamurthy *
142444ce08eSDonghai Qiao */
143444ce08eSDonghai Qiao#define DCACHE_FLUSHCOLOR(arg, way, tmp1, tmp2, tmp3)			\
144444ce08eSDonghai Qiao	ldxa	[%g0]ASI_DCU, tmp1;					\
145444ce08eSDonghai Qiao	btst	DCU_DC, tmp1;		/* is dcache enabled? */	\
146444ce08eSDonghai Qiao	bz,pn	%icc, 1f;						\
147444ce08eSDonghai Qiao	ASM_LD(tmp1, dcache_linesize)					\
148444ce08eSDonghai Qiao	/*								\
149444ce08eSDonghai Qiao	 * arg = virtual color						\
150444ce08eSDonghai Qiao	 * tmp1 = cache line size					\
151444ce08eSDonghai Qiao	 */								\
152*bd963cb9SEthindra Ramamurthy	sllx	arg, MMU_PAGESHIFT, tmp2; /* color to dcache page */	\
153444ce08eSDonghai Qiao	mov	way, tmp3;						\
154444ce08eSDonghai Qiao	sllx	tmp3, 14, tmp3;		  /* One way 16K */		\
155*bd963cb9SEthindra Ramamurthy	or	tmp2, tmp3, tmp3;					\
156*bd963cb9SEthindra Ramamurthy	set	MMU_PAGESIZE, tmp2;					\
157*bd963cb9SEthindra Ramamurthy	/*								\
158*bd963cb9SEthindra Ramamurthy	 * tmp2 = page size						\
159*bd963cb9SEthindra Ramamurthy	 * tmp3 =  cached page in dcache				\
160*bd963cb9SEthindra Ramamurthy	 */								\
161444ce08eSDonghai Qiao	sub	tmp2, tmp1, tmp2;					\
162444ce08eSDonghai Qiao2:									\
163*bd963cb9SEthindra Ramamurthy	stxa	%g0, [tmp3 + tmp2]ASI_DC_TAG;				\
164444ce08eSDonghai Qiao	membar	#Sync;							\
165444ce08eSDonghai Qiao	cmp	%g0, tmp2;						\
166444ce08eSDonghai Qiao	bne,pt	%icc, 2b;						\
167444ce08eSDonghai Qiao	sub	tmp2, tmp1, tmp2;					\
168444ce08eSDonghai Qiao1:
1697c478bd9Sstevel@tonic-gate
1707c478bd9Sstevel@tonic-gate/* END CSTYLED */
1717c478bd9Sstevel@tonic-gate
1727c478bd9Sstevel@tonic-gate#endif	/* !lint */
1737c478bd9Sstevel@tonic-gate
1747c478bd9Sstevel@tonic-gate/*
1757c478bd9Sstevel@tonic-gate * Cheetah MMU and Cache operations.
1767c478bd9Sstevel@tonic-gate */
1777c478bd9Sstevel@tonic-gate
1787c478bd9Sstevel@tonic-gate#if defined(lint)
1797c478bd9Sstevel@tonic-gate
1807c478bd9Sstevel@tonic-gate/* ARGSUSED */
1817c478bd9Sstevel@tonic-gatevoid
1821e2e7a75Shuahvtag_flushpage(caddr_t vaddr, uint64_t sfmmup)
1837c478bd9Sstevel@tonic-gate{}
1847c478bd9Sstevel@tonic-gate
1857c478bd9Sstevel@tonic-gate#else	/* lint */
1867c478bd9Sstevel@tonic-gate
1877c478bd9Sstevel@tonic-gate	ENTRY_NP(vtag_flushpage)
1887c478bd9Sstevel@tonic-gate	/*
1897c478bd9Sstevel@tonic-gate	 * flush page from the tlb
1907c478bd9Sstevel@tonic-gate	 *
1917c478bd9Sstevel@tonic-gate	 * %o0 = vaddr
1921e2e7a75Shuah	 * %o1 = sfmmup
1937c478bd9Sstevel@tonic-gate	 */
1947c478bd9Sstevel@tonic-gate	rdpr	%pstate, %o5
1957c478bd9Sstevel@tonic-gate#ifdef DEBUG
1961e2e7a75Shuah	PANIC_IF_INTR_DISABLED_PSTR(%o5, u3_di_label0, %g1)
1977c478bd9Sstevel@tonic-gate#endif /* DEBUG */
1987c478bd9Sstevel@tonic-gate	/*
1997c478bd9Sstevel@tonic-gate	 * disable ints
2007c478bd9Sstevel@tonic-gate	 */
2017c478bd9Sstevel@tonic-gate	andn	%o5, PSTATE_IE, %o4
2027c478bd9Sstevel@tonic-gate	wrpr	%o4, 0, %pstate
2037c478bd9Sstevel@tonic-gate
2047c478bd9Sstevel@tonic-gate	/*
2057c478bd9Sstevel@tonic-gate	 * Then, blow out the tlb
2067c478bd9Sstevel@tonic-gate	 * Interrupts are disabled to prevent the primary ctx register
2077c478bd9Sstevel@tonic-gate	 * from changing underneath us.
2087c478bd9Sstevel@tonic-gate	 */
2091e2e7a75Shuah	sethi   %hi(ksfmmup), %o3
2101e2e7a75Shuah        ldx     [%o3 + %lo(ksfmmup)], %o3
2111e2e7a75Shuah        cmp     %o3, %o1
2121e2e7a75Shuah        bne,pt   %xcc, 1f			! if not kernel as, go to 1
2137c478bd9Sstevel@tonic-gate	  sethi	%hi(FLUSH_ADDR), %o3
2147c478bd9Sstevel@tonic-gate	/*
2151e2e7a75Shuah	 * For Kernel demaps use primary. type = page implicitly
2167c478bd9Sstevel@tonic-gate	 */
2177c478bd9Sstevel@tonic-gate	stxa	%g0, [%o0]ASI_DTLB_DEMAP	/* dmmu flush for KCONTEXT */
2187c478bd9Sstevel@tonic-gate	stxa	%g0, [%o0]ASI_ITLB_DEMAP	/* immu flush for KCONTEXT */
2197c478bd9Sstevel@tonic-gate	flush	%o3
2201e2e7a75Shuah	retl
2211e2e7a75Shuah	  wrpr	%g0, %o5, %pstate		/* enable interrupts */
2227c478bd9Sstevel@tonic-gate1:
2237c478bd9Sstevel@tonic-gate	/*
2247c478bd9Sstevel@tonic-gate	 * User demap.  We need to set the primary context properly.
2257c478bd9Sstevel@tonic-gate	 * Secondary context cannot be used for Cheetah IMMU.
2267c478bd9Sstevel@tonic-gate	 * %o0 = vaddr
2271e2e7a75Shuah	 * %o1 = sfmmup
2287c478bd9Sstevel@tonic-gate	 * %o3 = FLUSH_ADDR
2297c478bd9Sstevel@tonic-gate	 */
2301e2e7a75Shuah	SFMMU_CPU_CNUM(%o1, %g1, %g2)		! %g1 = sfmmu cnum on this CPU
2311e2e7a75Shuah
2321e2e7a75Shuah	ldub	[%o1 + SFMMU_CEXT], %o4		! %o4 = sfmmup->sfmmu_cext
2337c478bd9Sstevel@tonic-gate	sll	%o4, CTXREG_EXT_SHIFT, %o4
234febcc4a5Sjimand	or	%g1, %o4, %g1			! %g1 = primary pgsz | cnum
2351e2e7a75Shuah
2367c478bd9Sstevel@tonic-gate	wrpr	%g0, 1, %tl
2377c478bd9Sstevel@tonic-gate	set	MMU_PCONTEXT, %o4
2387c478bd9Sstevel@tonic-gate	or	DEMAP_PRIMARY | DEMAP_PAGE_TYPE, %o0, %o0
2391e2e7a75Shuah	ldxa	[%o4]ASI_DMMU, %o2		! %o2 = save old ctxnum
240febcc4a5Sjimand	srlx	%o2, CTXREG_NEXT_SHIFT, %o1	! need to preserve nucleus pgsz
241febcc4a5Sjimand	sllx	%o1, CTXREG_NEXT_SHIFT, %o1	! %o1 = nucleus pgsz
242febcc4a5Sjimand	or	%g1, %o1, %g1			! %g1 = nucleus pgsz | primary pgsz | cnum
2431e2e7a75Shuah	stxa	%g1, [%o4]ASI_DMMU		! wr new ctxum
2441e2e7a75Shuah
2457c478bd9Sstevel@tonic-gate	stxa	%g0, [%o0]ASI_DTLB_DEMAP
2467c478bd9Sstevel@tonic-gate	stxa	%g0, [%o0]ASI_ITLB_DEMAP
2477c478bd9Sstevel@tonic-gate	stxa	%o2, [%o4]ASI_DMMU		/* restore old ctxnum */
2487c478bd9Sstevel@tonic-gate	flush	%o3
2497c478bd9Sstevel@tonic-gate	wrpr	%g0, 0, %tl
2501e2e7a75Shuah
2517c478bd9Sstevel@tonic-gate	retl
2527c478bd9Sstevel@tonic-gate	wrpr	%g0, %o5, %pstate		/* enable interrupts */
2537c478bd9Sstevel@tonic-gate	SET_SIZE(vtag_flushpage)
2547c478bd9Sstevel@tonic-gate
2557c478bd9Sstevel@tonic-gate#endif	/* lint */
2567c478bd9Sstevel@tonic-gate
2577c478bd9Sstevel@tonic-gate#if defined(lint)
2587c478bd9Sstevel@tonic-gate
2597c478bd9Sstevel@tonic-gatevoid
2607c478bd9Sstevel@tonic-gatevtag_flushall(void)
2617c478bd9Sstevel@tonic-gate{}
2627c478bd9Sstevel@tonic-gate
2637c478bd9Sstevel@tonic-gate#else	/* lint */
2647c478bd9Sstevel@tonic-gate
2657c478bd9Sstevel@tonic-gate	ENTRY_NP2(vtag_flushall, demap_all)
2667c478bd9Sstevel@tonic-gate	/*
2677c478bd9Sstevel@tonic-gate	 * flush the tlb
2687c478bd9Sstevel@tonic-gate	 */
2697c478bd9Sstevel@tonic-gate	sethi	%hi(FLUSH_ADDR), %o3
2707c478bd9Sstevel@tonic-gate	set	DEMAP_ALL_TYPE, %g1
2717c478bd9Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_DTLB_DEMAP
2727c478bd9Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_ITLB_DEMAP
2737c478bd9Sstevel@tonic-gate	flush	%o3
2747c478bd9Sstevel@tonic-gate	retl
2757c478bd9Sstevel@tonic-gate	nop
2767c478bd9Sstevel@tonic-gate	SET_SIZE(demap_all)
2777c478bd9Sstevel@tonic-gate	SET_SIZE(vtag_flushall)
2787c478bd9Sstevel@tonic-gate
2797c478bd9Sstevel@tonic-gate#endif	/* lint */
2807c478bd9Sstevel@tonic-gate
2817c478bd9Sstevel@tonic-gate
2827c478bd9Sstevel@tonic-gate#if defined(lint)
2837c478bd9Sstevel@tonic-gate
2847c478bd9Sstevel@tonic-gate/* ARGSUSED */
2857c478bd9Sstevel@tonic-gatevoid
2861e2e7a75Shuahvtag_flushpage_tl1(uint64_t vaddr, uint64_t sfmmup)
2877c478bd9Sstevel@tonic-gate{}
2887c478bd9Sstevel@tonic-gate
2897c478bd9Sstevel@tonic-gate#else	/* lint */
2907c478bd9Sstevel@tonic-gate
2917c478bd9Sstevel@tonic-gate	ENTRY_NP(vtag_flushpage_tl1)
2927c478bd9Sstevel@tonic-gate	/*
2937c478bd9Sstevel@tonic-gate	 * x-trap to flush page from tlb and tsb
2947c478bd9Sstevel@tonic-gate	 *
2957c478bd9Sstevel@tonic-gate	 * %g1 = vaddr, zero-extended on 32-bit kernel
2961e2e7a75Shuah	 * %g2 = sfmmup
2977c478bd9Sstevel@tonic-gate	 *
2987c478bd9Sstevel@tonic-gate	 * assumes TSBE_TAG = 0
2997c478bd9Sstevel@tonic-gate	 */
3007c478bd9Sstevel@tonic-gate	srln	%g1, MMU_PAGESHIFT, %g1
3011e2e7a75Shuah
3021e2e7a75Shuah	sethi   %hi(ksfmmup), %g3
3031e2e7a75Shuah        ldx     [%g3 + %lo(ksfmmup)], %g3
3041e2e7a75Shuah        cmp     %g3, %g2
3051e2e7a75Shuah        bne,pt	%xcc, 1f                        ! if not kernel as, go to 1
3067c478bd9Sstevel@tonic-gate	  slln	%g1, MMU_PAGESHIFT, %g1		/* g1 = vaddr */
3077c478bd9Sstevel@tonic-gate
3087c478bd9Sstevel@tonic-gate	/* We need to demap in the kernel context */
3097c478bd9Sstevel@tonic-gate	or	DEMAP_NUCLEUS | DEMAP_PAGE_TYPE, %g1, %g1
3107c478bd9Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_DTLB_DEMAP
3117c478bd9Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_ITLB_DEMAP
3127c478bd9Sstevel@tonic-gate	retry
3137c478bd9Sstevel@tonic-gate1:
3147c478bd9Sstevel@tonic-gate	/* We need to demap in a user context */
3157c478bd9Sstevel@tonic-gate	or	DEMAP_PRIMARY | DEMAP_PAGE_TYPE, %g1, %g1
3161e2e7a75Shuah
3171e2e7a75Shuah	SFMMU_CPU_CNUM(%g2, %g6, %g3)	! %g6 = sfmmu cnum on this CPU
3181e2e7a75Shuah
3191e2e7a75Shuah	ldub	[%g2 + SFMMU_CEXT], %g4		! %g4 = sfmmup->cext
3207c478bd9Sstevel@tonic-gate	sll	%g4, CTXREG_EXT_SHIFT, %g4
3211e2e7a75Shuah	or	%g6, %g4, %g6			! %g6 = pgsz | cnum
3221e2e7a75Shuah
3237c478bd9Sstevel@tonic-gate	set	MMU_PCONTEXT, %g4
3247c478bd9Sstevel@tonic-gate	ldxa	[%g4]ASI_DMMU, %g5		/* rd old ctxnum */
325febcc4a5Sjimand	srlx	%g5, CTXREG_NEXT_SHIFT, %g2	/* %g2 = nucleus pgsz */
326febcc4a5Sjimand	sllx	%g2, CTXREG_NEXT_SHIFT, %g2	/* preserve nucleus pgsz */
327febcc4a5Sjimand	or	%g6, %g2, %g6			/* %g6 = nucleus pgsz | primary pgsz | cnum */
3281e2e7a75Shuah	stxa	%g6, [%g4]ASI_DMMU		/* wr new ctxum */
3297c478bd9Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_DTLB_DEMAP
3307c478bd9Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_ITLB_DEMAP
3317c478bd9Sstevel@tonic-gate	stxa	%g5, [%g4]ASI_DMMU		/* restore old ctxnum */
3327c478bd9Sstevel@tonic-gate	retry
3337c478bd9Sstevel@tonic-gate	SET_SIZE(vtag_flushpage_tl1)
3347c478bd9Sstevel@tonic-gate
3357c478bd9Sstevel@tonic-gate#endif	/* lint */
3367c478bd9Sstevel@tonic-gate
3377c478bd9Sstevel@tonic-gate
3387c478bd9Sstevel@tonic-gate#if defined(lint)
3397c478bd9Sstevel@tonic-gate
3407c478bd9Sstevel@tonic-gate/* ARGSUSED */
3417c478bd9Sstevel@tonic-gatevoid
3421e2e7a75Shuahvtag_flush_pgcnt_tl1(uint64_t vaddr, uint64_t sfmmup_pgcnt)
3437c478bd9Sstevel@tonic-gate{}
3447c478bd9Sstevel@tonic-gate
3457c478bd9Sstevel@tonic-gate#else	/* lint */
3467c478bd9Sstevel@tonic-gate
3477c478bd9Sstevel@tonic-gate	ENTRY_NP(vtag_flush_pgcnt_tl1)
3487c478bd9Sstevel@tonic-gate	/*
3497c478bd9Sstevel@tonic-gate	 * x-trap to flush pgcnt MMU_PAGESIZE pages from tlb
3507c478bd9Sstevel@tonic-gate	 *
3517c478bd9Sstevel@tonic-gate	 * %g1 = vaddr, zero-extended on 32-bit kernel
3521e2e7a75Shuah	 * %g2 = <sfmmup58|pgcnt6>, (pgcnt - 1) is pass'ed in via pgcnt6 bits.
3537c478bd9Sstevel@tonic-gate	 *
3547c478bd9Sstevel@tonic-gate	 * NOTE: this handler relies on the fact that no
3557c478bd9Sstevel@tonic-gate	 *	interrupts or traps can occur during the loop
3567c478bd9Sstevel@tonic-gate	 *	issuing the TLB_DEMAP operations. It is assumed
3577c478bd9Sstevel@tonic-gate	 *	that interrupts are disabled and this code is
3587c478bd9Sstevel@tonic-gate	 *	fetching from the kernel locked text address.
3597c478bd9Sstevel@tonic-gate	 *
3607c478bd9Sstevel@tonic-gate	 * assumes TSBE_TAG = 0
3617c478bd9Sstevel@tonic-gate	 */
3621e2e7a75Shuah	set	SFMMU_PGCNT_MASK, %g4
3631e2e7a75Shuah	and	%g4, %g2, %g3			/* g3 = pgcnt - 1 */
3641e2e7a75Shuah	add	%g3, 1, %g3			/* g3 = pgcnt */
3651e2e7a75Shuah
3661e2e7a75Shuah	andn	%g2, SFMMU_PGCNT_MASK, %g2	/* g2 = sfmmup */
3677c478bd9Sstevel@tonic-gate	srln	%g1, MMU_PAGESHIFT, %g1
3681e2e7a75Shuah
3691e2e7a75Shuah	sethi   %hi(ksfmmup), %g4
3701e2e7a75Shuah        ldx     [%g4 + %lo(ksfmmup)], %g4
3711e2e7a75Shuah        cmp     %g4, %g2
3721e2e7a75Shuah        bne,pn   %xcc, 1f			/* if not kernel as, go to 1 */
3737c478bd9Sstevel@tonic-gate	  slln	%g1, MMU_PAGESHIFT, %g1		/* g1 = vaddr */
3747c478bd9Sstevel@tonic-gate
3757c478bd9Sstevel@tonic-gate	/* We need to demap in the kernel context */
3767c478bd9Sstevel@tonic-gate	or	DEMAP_NUCLEUS | DEMAP_PAGE_TYPE, %g1, %g1
3777c478bd9Sstevel@tonic-gate	set	MMU_PAGESIZE, %g2		/* g2 = pgsize */
3781e2e7a75Shuah	sethi   %hi(FLUSH_ADDR), %g5
3797c478bd9Sstevel@tonic-gate4:
3807c478bd9Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_DTLB_DEMAP
3817c478bd9Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_ITLB_DEMAP
3821e2e7a75Shuah	flush	%g5				! flush required by immu
3831e2e7a75Shuah
3847c478bd9Sstevel@tonic-gate	deccc	%g3				/* decr pgcnt */
3857c478bd9Sstevel@tonic-gate	bnz,pt	%icc,4b
3867c478bd9Sstevel@tonic-gate	  add	%g1, %g2, %g1			/* next page */
3877c478bd9Sstevel@tonic-gate	retry
3887c478bd9Sstevel@tonic-gate1:
3891e2e7a75Shuah	/*
3901e2e7a75Shuah	 * We need to demap in a user context
3911e2e7a75Shuah	 *
3921e2e7a75Shuah	 * g2 = sfmmup
3931e2e7a75Shuah	 * g3 = pgcnt
3941e2e7a75Shuah	 */
3951e2e7a75Shuah	SFMMU_CPU_CNUM(%g2, %g5, %g6)		! %g5 = sfmmu cnum on this CPU
3961e2e7a75Shuah
3977c478bd9Sstevel@tonic-gate	or	DEMAP_PRIMARY | DEMAP_PAGE_TYPE, %g1, %g1
3981e2e7a75Shuah
3991e2e7a75Shuah	ldub	[%g2 + SFMMU_CEXT], %g4		! %g4 = sfmmup->cext
4007c478bd9Sstevel@tonic-gate	sll	%g4, CTXREG_EXT_SHIFT, %g4
4011e2e7a75Shuah	or	%g5, %g4, %g5
4021e2e7a75Shuah
4037c478bd9Sstevel@tonic-gate	set	MMU_PCONTEXT, %g4
4041e2e7a75Shuah	ldxa	[%g4]ASI_DMMU, %g6		/* rd old ctxnum */
405febcc4a5Sjimand	srlx	%g6, CTXREG_NEXT_SHIFT, %g2	/* %g2 = nucleus pgsz */
406febcc4a5Sjimand	sllx	%g2, CTXREG_NEXT_SHIFT, %g2	/* preserve nucleus pgsz */
407febcc4a5Sjimand	or	%g5, %g2, %g5			/* %g5 = nucleus pgsz | primary pgsz | cnum */
4081e2e7a75Shuah	stxa	%g5, [%g4]ASI_DMMU		/* wr new ctxum */
4097c478bd9Sstevel@tonic-gate
4107c478bd9Sstevel@tonic-gate	set	MMU_PAGESIZE, %g2		/* g2 = pgsize */
4111e2e7a75Shuah	sethi   %hi(FLUSH_ADDR), %g5
4127c478bd9Sstevel@tonic-gate3:
4137c478bd9Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_DTLB_DEMAP
4147c478bd9Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_ITLB_DEMAP
4151e2e7a75Shuah	flush	%g5				! flush required by immu
4161e2e7a75Shuah
4177c478bd9Sstevel@tonic-gate	deccc	%g3				/* decr pgcnt */
4187c478bd9Sstevel@tonic-gate	bnz,pt	%icc,3b
4197c478bd9Sstevel@tonic-gate	  add	%g1, %g2, %g1			/* next page */
4207c478bd9Sstevel@tonic-gate
4211e2e7a75Shuah	stxa	%g6, [%g4]ASI_DMMU		/* restore old ctxnum */
4227c478bd9Sstevel@tonic-gate	retry
4237c478bd9Sstevel@tonic-gate	SET_SIZE(vtag_flush_pgcnt_tl1)
4247c478bd9Sstevel@tonic-gate
4257c478bd9Sstevel@tonic-gate#endif	/* lint */
4267c478bd9Sstevel@tonic-gate
4277c478bd9Sstevel@tonic-gate#if defined(lint)
4287c478bd9Sstevel@tonic-gate
4297c478bd9Sstevel@tonic-gate/*ARGSUSED*/
4307c478bd9Sstevel@tonic-gatevoid
4317c478bd9Sstevel@tonic-gatevtag_flushall_tl1(uint64_t dummy1, uint64_t dummy2)
4327c478bd9Sstevel@tonic-gate{}
4337c478bd9Sstevel@tonic-gate
4347c478bd9Sstevel@tonic-gate#else	/* lint */
4357c478bd9Sstevel@tonic-gate
4367c478bd9Sstevel@tonic-gate	ENTRY_NP(vtag_flushall_tl1)
4377c478bd9Sstevel@tonic-gate	/*
4387c478bd9Sstevel@tonic-gate	 * x-trap to flush tlb
4397c478bd9Sstevel@tonic-gate	 */
4407c478bd9Sstevel@tonic-gate	set	DEMAP_ALL_TYPE, %g4
4417c478bd9Sstevel@tonic-gate	stxa	%g0, [%g4]ASI_DTLB_DEMAP
4427c478bd9Sstevel@tonic-gate	stxa	%g0, [%g4]ASI_ITLB_DEMAP
4437c478bd9Sstevel@tonic-gate	retry
4447c478bd9Sstevel@tonic-gate	SET_SIZE(vtag_flushall_tl1)
4457c478bd9Sstevel@tonic-gate
4467c478bd9Sstevel@tonic-gate#endif	/* lint */
4477c478bd9Sstevel@tonic-gate
4487c478bd9Sstevel@tonic-gate
4497c478bd9Sstevel@tonic-gate#if defined(lint)
4507c478bd9Sstevel@tonic-gate
4517c478bd9Sstevel@tonic-gate/* ARGSUSED */
4527c478bd9Sstevel@tonic-gatevoid
4537c478bd9Sstevel@tonic-gatevac_flushpage(pfn_t pfnum, int vcolor)
4547c478bd9Sstevel@tonic-gate{}
4557c478bd9Sstevel@tonic-gate
4567c478bd9Sstevel@tonic-gate#else	/* lint */
4577c478bd9Sstevel@tonic-gate
4587c478bd9Sstevel@tonic-gate/*
4597c478bd9Sstevel@tonic-gate * vac_flushpage(pfnum, color)
4607c478bd9Sstevel@tonic-gate *	Flush 1 8k page of the D-$ with physical page = pfnum
4617c478bd9Sstevel@tonic-gate *	Algorithm:
4627c478bd9Sstevel@tonic-gate *		The cheetah dcache is a 64k psuedo 4 way accaociative cache.
4637c478bd9Sstevel@tonic-gate *		It is virtual indexed, physically tagged cache.
4647c478bd9Sstevel@tonic-gate */
4657c478bd9Sstevel@tonic-gate	.seg	".data"
4667c478bd9Sstevel@tonic-gate	.align	8
4677c478bd9Sstevel@tonic-gate	.global	dflush_type
4687c478bd9Sstevel@tonic-gatedflush_type:
4697c478bd9Sstevel@tonic-gate	.word	FLUSHPAGE_TYPE
4707c478bd9Sstevel@tonic-gate
4717c478bd9Sstevel@tonic-gate	ENTRY(vac_flushpage)
4727c478bd9Sstevel@tonic-gate	/*
4737c478bd9Sstevel@tonic-gate	 * flush page from the d$
4747c478bd9Sstevel@tonic-gate	 *
4757c478bd9Sstevel@tonic-gate	 * %o0 = pfnum, %o1 = color
4767c478bd9Sstevel@tonic-gate	 */
4777c478bd9Sstevel@tonic-gate	DCACHE_FLUSHPAGE(%o0, %o1, %o2, %o3, %o4)
4787c478bd9Sstevel@tonic-gate	retl
4797c478bd9Sstevel@tonic-gate	  nop
4807c478bd9Sstevel@tonic-gate	SET_SIZE(vac_flushpage)
4817c478bd9Sstevel@tonic-gate
4827c478bd9Sstevel@tonic-gate#endif	/* lint */
4837c478bd9Sstevel@tonic-gate
4847c478bd9Sstevel@tonic-gate
4857c478bd9Sstevel@tonic-gate#if defined(lint)
4867c478bd9Sstevel@tonic-gate
4877c478bd9Sstevel@tonic-gate/* ARGSUSED */
4887c478bd9Sstevel@tonic-gatevoid
4897c478bd9Sstevel@tonic-gatevac_flushpage_tl1(uint64_t pfnum, uint64_t vcolor)
4907c478bd9Sstevel@tonic-gate{}
4917c478bd9Sstevel@tonic-gate
4927c478bd9Sstevel@tonic-gate#else	/* lint */
4937c478bd9Sstevel@tonic-gate
4947c478bd9Sstevel@tonic-gate	ENTRY_NP(vac_flushpage_tl1)
4957c478bd9Sstevel@tonic-gate	/*
4967c478bd9Sstevel@tonic-gate	 * x-trap to flush page from the d$
4977c478bd9Sstevel@tonic-gate	 *
4987c478bd9Sstevel@tonic-gate	 * %g1 = pfnum, %g2 = color
4997c478bd9Sstevel@tonic-gate	 */
5007c478bd9Sstevel@tonic-gate	DCACHE_FLUSHPAGE(%g1, %g2, %g3, %g4, %g5)
5017c478bd9Sstevel@tonic-gate	retry
5027c478bd9Sstevel@tonic-gate	SET_SIZE(vac_flushpage_tl1)
5037c478bd9Sstevel@tonic-gate
5047c478bd9Sstevel@tonic-gate#endif	/* lint */
5057c478bd9Sstevel@tonic-gate
5067c478bd9Sstevel@tonic-gate
5077c478bd9Sstevel@tonic-gate#if defined(lint)
5087c478bd9Sstevel@tonic-gate
5097c478bd9Sstevel@tonic-gate/* ARGSUSED */
5107c478bd9Sstevel@tonic-gatevoid
5117c478bd9Sstevel@tonic-gatevac_flushcolor(int vcolor, pfn_t pfnum)
5127c478bd9Sstevel@tonic-gate{}
5137c478bd9Sstevel@tonic-gate
5147c478bd9Sstevel@tonic-gate#else	/* lint */
5157c478bd9Sstevel@tonic-gate
5167c478bd9Sstevel@tonic-gate	ENTRY(vac_flushcolor)
5177c478bd9Sstevel@tonic-gate	/*
518444ce08eSDonghai Qiao	 * %o0 = vcolor
5197c478bd9Sstevel@tonic-gate	 */
520444ce08eSDonghai Qiao	DCACHE_FLUSHCOLOR(%o0, 0, %o1, %o2, %o3)
521444ce08eSDonghai Qiao	DCACHE_FLUSHCOLOR(%o0, 1, %o1, %o2, %o3)
522444ce08eSDonghai Qiao	DCACHE_FLUSHCOLOR(%o0, 2, %o1, %o2, %o3)
523444ce08eSDonghai Qiao	DCACHE_FLUSHCOLOR(%o0, 3, %o1, %o2, %o3)
5247c478bd9Sstevel@tonic-gate	retl
5257c478bd9Sstevel@tonic-gate	  nop
5267c478bd9Sstevel@tonic-gate	SET_SIZE(vac_flushcolor)
5277c478bd9Sstevel@tonic-gate
5287c478bd9Sstevel@tonic-gate#endif	/* lint */
5297c478bd9Sstevel@tonic-gate
5307c478bd9Sstevel@tonic-gate
5317c478bd9Sstevel@tonic-gate#if defined(lint)
5327c478bd9Sstevel@tonic-gate
5337c478bd9Sstevel@tonic-gate/* ARGSUSED */
5347c478bd9Sstevel@tonic-gatevoid
5357c478bd9Sstevel@tonic-gatevac_flushcolor_tl1(uint64_t vcolor, uint64_t pfnum)
5367c478bd9Sstevel@tonic-gate{}
5377c478bd9Sstevel@tonic-gate
5387c478bd9Sstevel@tonic-gate#else	/* lint */
5397c478bd9Sstevel@tonic-gate
5407c478bd9Sstevel@tonic-gate	ENTRY(vac_flushcolor_tl1)
5417c478bd9Sstevel@tonic-gate	/*
5427c478bd9Sstevel@tonic-gate	 * %g1 = vcolor
5437c478bd9Sstevel@tonic-gate	 */
544444ce08eSDonghai Qiao	DCACHE_FLUSHCOLOR(%g1, 0, %g2, %g3, %g4)
545444ce08eSDonghai Qiao	DCACHE_FLUSHCOLOR(%g1, 1, %g2, %g3, %g4)
546444ce08eSDonghai Qiao	DCACHE_FLUSHCOLOR(%g1, 2, %g2, %g3, %g4)
547444ce08eSDonghai Qiao	DCACHE_FLUSHCOLOR(%g1, 3, %g2, %g3, %g4)
5487c478bd9Sstevel@tonic-gate	retry
5497c478bd9Sstevel@tonic-gate	SET_SIZE(vac_flushcolor_tl1)
5507c478bd9Sstevel@tonic-gate
5517c478bd9Sstevel@tonic-gate#endif	/* lint */
5527c478bd9Sstevel@tonic-gate
5537c478bd9Sstevel@tonic-gate#if defined(lint)
5547c478bd9Sstevel@tonic-gate
5557c478bd9Sstevel@tonic-gateint
5567c478bd9Sstevel@tonic-gateidsr_busy(void)
5577c478bd9Sstevel@tonic-gate{
5587c478bd9Sstevel@tonic-gate	return (0);
5597c478bd9Sstevel@tonic-gate}
5607c478bd9Sstevel@tonic-gate
5617c478bd9Sstevel@tonic-gate#else	/* lint */
5627c478bd9Sstevel@tonic-gate
5637c478bd9Sstevel@tonic-gate/*
5647c478bd9Sstevel@tonic-gate * Determine whether or not the IDSR is busy.
5657c478bd9Sstevel@tonic-gate * Entry: no arguments
5667c478bd9Sstevel@tonic-gate * Returns: 1 if busy, 0 otherwise
5677c478bd9Sstevel@tonic-gate */
5687c478bd9Sstevel@tonic-gate	ENTRY(idsr_busy)
5697c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_INTR_DISPATCH_STATUS, %g1
5707c478bd9Sstevel@tonic-gate	clr	%o0
5717c478bd9Sstevel@tonic-gate	btst	IDSR_BUSY, %g1
5727c478bd9Sstevel@tonic-gate	bz,a,pt	%xcc, 1f
5737c478bd9Sstevel@tonic-gate	mov	1, %o0
5747c478bd9Sstevel@tonic-gate1:
5757c478bd9Sstevel@tonic-gate	retl
5767c478bd9Sstevel@tonic-gate	nop
5777c478bd9Sstevel@tonic-gate	SET_SIZE(idsr_busy)
5787c478bd9Sstevel@tonic-gate
5797c478bd9Sstevel@tonic-gate#endif	/* lint */
5807c478bd9Sstevel@tonic-gate
5817c478bd9Sstevel@tonic-gate#if defined(lint)
5827c478bd9Sstevel@tonic-gate
5837c478bd9Sstevel@tonic-gate/* ARGSUSED */
5847c478bd9Sstevel@tonic-gatevoid
5857c478bd9Sstevel@tonic-gateinit_mondo(xcfunc_t *func, uint64_t arg1, uint64_t arg2)
5867c478bd9Sstevel@tonic-gate{}
5877c478bd9Sstevel@tonic-gate
5887c478bd9Sstevel@tonic-gate/* ARGSUSED */
5897c478bd9Sstevel@tonic-gatevoid
5907c478bd9Sstevel@tonic-gateinit_mondo_nocheck(xcfunc_t *func, uint64_t arg1, uint64_t arg2)
5917c478bd9Sstevel@tonic-gate{}
5927c478bd9Sstevel@tonic-gate
5937c478bd9Sstevel@tonic-gate#else	/* lint */
5947c478bd9Sstevel@tonic-gate
5957c478bd9Sstevel@tonic-gate	.global _dispatch_status_busy
5967c478bd9Sstevel@tonic-gate_dispatch_status_busy:
5977c478bd9Sstevel@tonic-gate	.asciz	"ASI_INTR_DISPATCH_STATUS error: busy"
5987c478bd9Sstevel@tonic-gate	.align	4
5997c478bd9Sstevel@tonic-gate
6007c478bd9Sstevel@tonic-gate/*
6017c478bd9Sstevel@tonic-gate * Setup interrupt dispatch data registers
6027c478bd9Sstevel@tonic-gate * Entry:
6037c478bd9Sstevel@tonic-gate *	%o0 - function or inumber to call
6047c478bd9Sstevel@tonic-gate *	%o1, %o2 - arguments (2 uint64_t's)
6057c478bd9Sstevel@tonic-gate */
6067c478bd9Sstevel@tonic-gate	.seg "text"
6077c478bd9Sstevel@tonic-gate
6087c478bd9Sstevel@tonic-gate	ENTRY(init_mondo)
6097c478bd9Sstevel@tonic-gate#ifdef DEBUG
6107c478bd9Sstevel@tonic-gate	!
6117c478bd9Sstevel@tonic-gate	! IDSR should not be busy at the moment
6127c478bd9Sstevel@tonic-gate	!
6137c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_INTR_DISPATCH_STATUS, %g1
6147c478bd9Sstevel@tonic-gate	btst	IDSR_BUSY, %g1
6157c478bd9Sstevel@tonic-gate	bz,pt	%xcc, 1f
6167c478bd9Sstevel@tonic-gate	nop
6177c478bd9Sstevel@tonic-gate	sethi	%hi(_dispatch_status_busy), %o0
6187c478bd9Sstevel@tonic-gate	call	panic
6197c478bd9Sstevel@tonic-gate	or	%o0, %lo(_dispatch_status_busy), %o0
6207c478bd9Sstevel@tonic-gate#endif /* DEBUG */
6217c478bd9Sstevel@tonic-gate
6227c478bd9Sstevel@tonic-gate	ALTENTRY(init_mondo_nocheck)
6237c478bd9Sstevel@tonic-gate	!
6247c478bd9Sstevel@tonic-gate	! interrupt vector dispatch data reg 0
6257c478bd9Sstevel@tonic-gate	!
6267c478bd9Sstevel@tonic-gate1:
6277c478bd9Sstevel@tonic-gate	mov	IDDR_0, %g1
6287c478bd9Sstevel@tonic-gate	mov	IDDR_1, %g2
6297c478bd9Sstevel@tonic-gate	mov	IDDR_2, %g3
6307c478bd9Sstevel@tonic-gate	stxa	%o0, [%g1]ASI_INTR_DISPATCH
6317c478bd9Sstevel@tonic-gate
6327c478bd9Sstevel@tonic-gate	!
6337c478bd9Sstevel@tonic-gate	! interrupt vector dispatch data reg 1
6347c478bd9Sstevel@tonic-gate	!
6357c478bd9Sstevel@tonic-gate	stxa	%o1, [%g2]ASI_INTR_DISPATCH
6367c478bd9Sstevel@tonic-gate
6377c478bd9Sstevel@tonic-gate	!
6387c478bd9Sstevel@tonic-gate	! interrupt vector dispatch data reg 2
6397c478bd9Sstevel@tonic-gate	!
6407c478bd9Sstevel@tonic-gate	stxa	%o2, [%g3]ASI_INTR_DISPATCH
6417c478bd9Sstevel@tonic-gate
6427c478bd9Sstevel@tonic-gate	membar	#Sync
6437c478bd9Sstevel@tonic-gate	retl
6447c478bd9Sstevel@tonic-gate	nop
6457c478bd9Sstevel@tonic-gate	SET_SIZE(init_mondo_nocheck)
6467c478bd9Sstevel@tonic-gate	SET_SIZE(init_mondo)
6477c478bd9Sstevel@tonic-gate
6487c478bd9Sstevel@tonic-gate#endif	/* lint */
6497c478bd9Sstevel@tonic-gate
6507c478bd9Sstevel@tonic-gate
6517c478bd9Sstevel@tonic-gate#if !(defined(JALAPENO) || defined(SERRANO))
6527c478bd9Sstevel@tonic-gate
6537c478bd9Sstevel@tonic-gate#if defined(lint)
6547c478bd9Sstevel@tonic-gate
6557c478bd9Sstevel@tonic-gate/* ARGSUSED */
6567c478bd9Sstevel@tonic-gatevoid
6577c478bd9Sstevel@tonic-gateshipit(int upaid, int bn)
6587c478bd9Sstevel@tonic-gate{ return; }
6597c478bd9Sstevel@tonic-gate
6607c478bd9Sstevel@tonic-gate#else	/* lint */
6617c478bd9Sstevel@tonic-gate
6627c478bd9Sstevel@tonic-gate/*
6637c478bd9Sstevel@tonic-gate * Ship mondo to aid using busy/nack pair bn
6647c478bd9Sstevel@tonic-gate */
6657c478bd9Sstevel@tonic-gate	ENTRY_NP(shipit)
6667c478bd9Sstevel@tonic-gate	sll	%o0, IDCR_PID_SHIFT, %g1	! IDCR<18:14> = agent id
6677c478bd9Sstevel@tonic-gate	sll	%o1, IDCR_BN_SHIFT, %g2		! IDCR<28:24> = b/n pair
6687c478bd9Sstevel@tonic-gate	or	%g1, IDCR_OFFSET, %g1		! IDCR<13:0> = 0x70
6697c478bd9Sstevel@tonic-gate	or	%g1, %g2, %g1
6707c478bd9Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_INTR_DISPATCH	! interrupt vector dispatch
6717c478bd9Sstevel@tonic-gate	membar	#Sync
6727c478bd9Sstevel@tonic-gate	retl
6737c478bd9Sstevel@tonic-gate	nop
6747c478bd9Sstevel@tonic-gate	SET_SIZE(shipit)
6757c478bd9Sstevel@tonic-gate
6767c478bd9Sstevel@tonic-gate#endif	/* lint */
6777c478bd9Sstevel@tonic-gate
6787c478bd9Sstevel@tonic-gate#endif	/* !(JALAPENO || SERRANO) */
6797c478bd9Sstevel@tonic-gate
6807c478bd9Sstevel@tonic-gate
6817c478bd9Sstevel@tonic-gate#if defined(lint)
6827c478bd9Sstevel@tonic-gate
6837c478bd9Sstevel@tonic-gate/* ARGSUSED */
6847c478bd9Sstevel@tonic-gatevoid
6857c478bd9Sstevel@tonic-gateflush_instr_mem(caddr_t vaddr, size_t len)
6867c478bd9Sstevel@tonic-gate{}
6877c478bd9Sstevel@tonic-gate
6887c478bd9Sstevel@tonic-gate#else	/* lint */
6897c478bd9Sstevel@tonic-gate
6907c478bd9Sstevel@tonic-gate/*
6917c478bd9Sstevel@tonic-gate * flush_instr_mem:
6927c478bd9Sstevel@tonic-gate *	Flush 1 page of the I-$ starting at vaddr
6937c478bd9Sstevel@tonic-gate * 	%o0 vaddr
6947c478bd9Sstevel@tonic-gate *	%o1 bytes to be flushed
6957c478bd9Sstevel@tonic-gate * UltraSPARC-III maintains consistency of the on-chip Instruction Cache with
6967c478bd9Sstevel@tonic-gate * the stores from all processors so that a FLUSH instruction is only needed
6977c478bd9Sstevel@tonic-gate * to ensure pipeline is consistent. This means a single flush is sufficient at
6987c478bd9Sstevel@tonic-gate * the end of a sequence of stores that updates the instruction stream to
6997c478bd9Sstevel@tonic-gate * ensure correct operation.
7007c478bd9Sstevel@tonic-gate */
7017c478bd9Sstevel@tonic-gate
7027c478bd9Sstevel@tonic-gate	ENTRY(flush_instr_mem)
70363360950Smp204432	flush	%o0			! address irrelevant
7047c478bd9Sstevel@tonic-gate	retl
7057c478bd9Sstevel@tonic-gate	nop
7067c478bd9Sstevel@tonic-gate	SET_SIZE(flush_instr_mem)
7077c478bd9Sstevel@tonic-gate
7087c478bd9Sstevel@tonic-gate#endif	/* lint */
7097c478bd9Sstevel@tonic-gate
7107c478bd9Sstevel@tonic-gate
7117c478bd9Sstevel@tonic-gate#if defined(CPU_IMP_ECACHE_ASSOC)
7127c478bd9Sstevel@tonic-gate
7137c478bd9Sstevel@tonic-gate#if defined(lint)
7147c478bd9Sstevel@tonic-gate
7157c478bd9Sstevel@tonic-gate/* ARGSUSED */
7167c478bd9Sstevel@tonic-gateuint64_t
7177c478bd9Sstevel@tonic-gateget_ecache_ctrl(void)
7187c478bd9Sstevel@tonic-gate{ return (0); }
7197c478bd9Sstevel@tonic-gate
7207c478bd9Sstevel@tonic-gate#else	/* lint */
7217c478bd9Sstevel@tonic-gate
7227c478bd9Sstevel@tonic-gate	ENTRY(get_ecache_ctrl)
7237c478bd9Sstevel@tonic-gate	GET_CPU_IMPL(%o0)
7247c478bd9Sstevel@tonic-gate	cmp	%o0, JAGUAR_IMPL
7257c478bd9Sstevel@tonic-gate	!
7267c478bd9Sstevel@tonic-gate	! Putting an ASI access in the delay slot may
7277c478bd9Sstevel@tonic-gate	! cause it to be accessed, even when annulled.
7287c478bd9Sstevel@tonic-gate	!
7297c478bd9Sstevel@tonic-gate	bne	1f
7307c478bd9Sstevel@tonic-gate	  nop
7317c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_EC_CFG_TIMING, %o0	! read Jaguar shared E$ ctrl reg
7327c478bd9Sstevel@tonic-gate	b	2f
7337c478bd9Sstevel@tonic-gate	  nop
7347c478bd9Sstevel@tonic-gate1:
7357c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_EC_CTRL, %o0		! read Ch/Ch+ E$ control reg
7367c478bd9Sstevel@tonic-gate2:
7377c478bd9Sstevel@tonic-gate	retl
7387c478bd9Sstevel@tonic-gate	  nop
7397c478bd9Sstevel@tonic-gate	SET_SIZE(get_ecache_ctrl)
7407c478bd9Sstevel@tonic-gate
7417c478bd9Sstevel@tonic-gate#endif	/* lint */
7427c478bd9Sstevel@tonic-gate
7437c478bd9Sstevel@tonic-gate#endif	/* CPU_IMP_ECACHE_ASSOC */
7447c478bd9Sstevel@tonic-gate
7457c478bd9Sstevel@tonic-gate
7467c478bd9Sstevel@tonic-gate#if !(defined(JALAPENO) || defined(SERRANO))
7477c478bd9Sstevel@tonic-gate
7487c478bd9Sstevel@tonic-gate/*
7497c478bd9Sstevel@tonic-gate * flush_ecache:
7507c478bd9Sstevel@tonic-gate *	%o0 - 64 bit physical address
7517c478bd9Sstevel@tonic-gate *	%o1 - ecache size
7527c478bd9Sstevel@tonic-gate *	%o2 - ecache linesize
7537c478bd9Sstevel@tonic-gate */
7547c478bd9Sstevel@tonic-gate#if defined(lint)
7557c478bd9Sstevel@tonic-gate
7567c478bd9Sstevel@tonic-gate/*ARGSUSED*/
7577c478bd9Sstevel@tonic-gatevoid
7587c478bd9Sstevel@tonic-gateflush_ecache(uint64_t physaddr, size_t ecache_size, size_t ecache_linesize)
7597c478bd9Sstevel@tonic-gate{}
7607c478bd9Sstevel@tonic-gate
7617c478bd9Sstevel@tonic-gate#else /* !lint */
7627c478bd9Sstevel@tonic-gate
7637c478bd9Sstevel@tonic-gate	ENTRY(flush_ecache)
7647c478bd9Sstevel@tonic-gate
7657c478bd9Sstevel@tonic-gate	/*
7667c478bd9Sstevel@tonic-gate	 * For certain CPU implementations, we have to flush the L2 cache
7677c478bd9Sstevel@tonic-gate	 * before flushing the ecache.
7687c478bd9Sstevel@tonic-gate	 */
7697c478bd9Sstevel@tonic-gate	PN_L2_FLUSHALL(%g3, %g4, %g5)
7707c478bd9Sstevel@tonic-gate
7717c478bd9Sstevel@tonic-gate	/*
7727c478bd9Sstevel@tonic-gate	 * Flush the entire Ecache using displacement flush.
7737c478bd9Sstevel@tonic-gate	 */
7747c478bd9Sstevel@tonic-gate	ECACHE_FLUSHALL(%o1, %o2, %o0, %o4)
7757c478bd9Sstevel@tonic-gate
7767c478bd9Sstevel@tonic-gate	retl
7777c478bd9Sstevel@tonic-gate	nop
7787c478bd9Sstevel@tonic-gate	SET_SIZE(flush_ecache)
7797c478bd9Sstevel@tonic-gate
7807c478bd9Sstevel@tonic-gate#endif /* lint */
7817c478bd9Sstevel@tonic-gate
7827c478bd9Sstevel@tonic-gate#endif	/* !(JALAPENO || SERRANO) */
7837c478bd9Sstevel@tonic-gate
7847c478bd9Sstevel@tonic-gate
7857c478bd9Sstevel@tonic-gate#if defined(lint)
7867c478bd9Sstevel@tonic-gate
7877c478bd9Sstevel@tonic-gatevoid
7887c478bd9Sstevel@tonic-gateflush_dcache(void)
7897c478bd9Sstevel@tonic-gate{}
7907c478bd9Sstevel@tonic-gate
7917c478bd9Sstevel@tonic-gate#else	/* lint */
7927c478bd9Sstevel@tonic-gate
7937c478bd9Sstevel@tonic-gate	ENTRY(flush_dcache)
7947c478bd9Sstevel@tonic-gate	ASM_LD(%o0, dcache_size)
7957c478bd9Sstevel@tonic-gate	ASM_LD(%o1, dcache_linesize)
7967c478bd9Sstevel@tonic-gate	CH_DCACHE_FLUSHALL(%o0, %o1, %o2)
7977c478bd9Sstevel@tonic-gate	retl
7987c478bd9Sstevel@tonic-gate	nop
7997c478bd9Sstevel@tonic-gate	SET_SIZE(flush_dcache)
8007c478bd9Sstevel@tonic-gate
8017c478bd9Sstevel@tonic-gate#endif	/* lint */
8027c478bd9Sstevel@tonic-gate
8037c478bd9Sstevel@tonic-gate
8047c478bd9Sstevel@tonic-gate#if defined(lint)
8057c478bd9Sstevel@tonic-gate
8067c478bd9Sstevel@tonic-gatevoid
8077c478bd9Sstevel@tonic-gateflush_icache(void)
8087c478bd9Sstevel@tonic-gate{}
8097c478bd9Sstevel@tonic-gate
8107c478bd9Sstevel@tonic-gate#else	/* lint */
8117c478bd9Sstevel@tonic-gate
8127c478bd9Sstevel@tonic-gate	ENTRY(flush_icache)
8137c478bd9Sstevel@tonic-gate	GET_CPU_PRIVATE_PTR(%g0, %o0, %o2, flush_icache_1);
8147c478bd9Sstevel@tonic-gate	ld	[%o0 + CHPR_ICACHE_LINESIZE], %o1
8157c478bd9Sstevel@tonic-gate	ba,pt	%icc, 2f
8167c478bd9Sstevel@tonic-gate	  ld	[%o0 + CHPR_ICACHE_SIZE], %o0
8177c478bd9Sstevel@tonic-gateflush_icache_1:
8187c478bd9Sstevel@tonic-gate	ASM_LD(%o0, icache_size)
8197c478bd9Sstevel@tonic-gate	ASM_LD(%o1, icache_linesize)
8207c478bd9Sstevel@tonic-gate2:
8217c478bd9Sstevel@tonic-gate	CH_ICACHE_FLUSHALL(%o0, %o1, %o2, %o4)
8227c478bd9Sstevel@tonic-gate	retl
8237c478bd9Sstevel@tonic-gate	nop
8247c478bd9Sstevel@tonic-gate	SET_SIZE(flush_icache)
8257c478bd9Sstevel@tonic-gate
8267c478bd9Sstevel@tonic-gate#endif	/* lint */
8277c478bd9Sstevel@tonic-gate
8287c478bd9Sstevel@tonic-gate#if defined(lint)
8297c478bd9Sstevel@tonic-gate
8307c478bd9Sstevel@tonic-gate/*ARGSUSED*/
8317c478bd9Sstevel@tonic-gatevoid
8327c478bd9Sstevel@tonic-gatekdi_flush_idcache(int dcache_size, int dcache_lsize, int icache_size,
8337c478bd9Sstevel@tonic-gate    int icache_lsize)
8347c478bd9Sstevel@tonic-gate{
8357c478bd9Sstevel@tonic-gate}
8367c478bd9Sstevel@tonic-gate
8377c478bd9Sstevel@tonic-gate#else	/* lint */
8387c478bd9Sstevel@tonic-gate
8397c478bd9Sstevel@tonic-gate	ENTRY(kdi_flush_idcache)
8407c478bd9Sstevel@tonic-gate	CH_DCACHE_FLUSHALL(%o0, %o1, %g1)
8417c478bd9Sstevel@tonic-gate	CH_ICACHE_FLUSHALL(%o2, %o3, %g1, %g2)
8427c478bd9Sstevel@tonic-gate	membar	#Sync
8437c478bd9Sstevel@tonic-gate	retl
8447c478bd9Sstevel@tonic-gate	nop
8457c478bd9Sstevel@tonic-gate	SET_SIZE(kdi_flush_idcache)
8467c478bd9Sstevel@tonic-gate
8477c478bd9Sstevel@tonic-gate#endif	/* lint */
8487c478bd9Sstevel@tonic-gate
8497c478bd9Sstevel@tonic-gate#if defined(lint)
8507c478bd9Sstevel@tonic-gate
8517c478bd9Sstevel@tonic-gatevoid
8527c478bd9Sstevel@tonic-gateflush_pcache(void)
8537c478bd9Sstevel@tonic-gate{}
8547c478bd9Sstevel@tonic-gate
8557c478bd9Sstevel@tonic-gate#else	/* lint */
8567c478bd9Sstevel@tonic-gate
8577c478bd9Sstevel@tonic-gate	ENTRY(flush_pcache)
8587c478bd9Sstevel@tonic-gate	PCACHE_FLUSHALL(%o0, %o1, %o2)
8597c478bd9Sstevel@tonic-gate	retl
8607c478bd9Sstevel@tonic-gate	nop
8617c478bd9Sstevel@tonic-gate	SET_SIZE(flush_pcache)
8627c478bd9Sstevel@tonic-gate
8637c478bd9Sstevel@tonic-gate#endif	/* lint */
8647c478bd9Sstevel@tonic-gate
8657c478bd9Sstevel@tonic-gate
8667c478bd9Sstevel@tonic-gate#if defined(CPU_IMP_L1_CACHE_PARITY)
8677c478bd9Sstevel@tonic-gate
8687c478bd9Sstevel@tonic-gate#if defined(lint)
8697c478bd9Sstevel@tonic-gate
8707c478bd9Sstevel@tonic-gate/* ARGSUSED */
8717c478bd9Sstevel@tonic-gatevoid
8727c478bd9Sstevel@tonic-gateget_dcache_dtag(uint32_t dcache_idx, uint64_t *data)
8737c478bd9Sstevel@tonic-gate{}
8747c478bd9Sstevel@tonic-gate
8757c478bd9Sstevel@tonic-gate#else	/* lint */
8767c478bd9Sstevel@tonic-gate
8777c478bd9Sstevel@tonic-gate/*
8787c478bd9Sstevel@tonic-gate * Get dcache data and tag.  The Dcache data is a pointer to a ch_dc_data_t
8797c478bd9Sstevel@tonic-gate * structure (see cheetahregs.h):
8807c478bd9Sstevel@tonic-gate * The Dcache *should* be turned off when this code is executed.
8817c478bd9Sstevel@tonic-gate */
8827c478bd9Sstevel@tonic-gate	.align	128
8837c478bd9Sstevel@tonic-gate	ENTRY(get_dcache_dtag)
8847c478bd9Sstevel@tonic-gate	rdpr	%pstate, %o5
8857c478bd9Sstevel@tonic-gate	andn    %o5, PSTATE_IE | PSTATE_AM, %o3
8867c478bd9Sstevel@tonic-gate	wrpr	%g0, %o3, %pstate
8877c478bd9Sstevel@tonic-gate	b	1f
8887c478bd9Sstevel@tonic-gate	  stx	%o0, [%o1 + CH_DC_IDX]
8897c478bd9Sstevel@tonic-gate
8907c478bd9Sstevel@tonic-gate	.align	128
8917c478bd9Sstevel@tonic-gate1:
8927c478bd9Sstevel@tonic-gate	ldxa	[%o0]ASI_DC_TAG, %o2
8937c478bd9Sstevel@tonic-gate	stx	%o2, [%o1 + CH_DC_TAG]
8947c478bd9Sstevel@tonic-gate	membar	#Sync
8957c478bd9Sstevel@tonic-gate	ldxa	[%o0]ASI_DC_UTAG, %o2
8967c478bd9Sstevel@tonic-gate	membar	#Sync
8977c478bd9Sstevel@tonic-gate	stx	%o2, [%o1 + CH_DC_UTAG]
8987c478bd9Sstevel@tonic-gate	ldxa	[%o0]ASI_DC_SNP_TAG, %o2
8997c478bd9Sstevel@tonic-gate	stx	%o2, [%o1 + CH_DC_SNTAG]
9007c478bd9Sstevel@tonic-gate	add	%o1, CH_DC_DATA, %o1
9017c478bd9Sstevel@tonic-gate	clr	%o3
9027c478bd9Sstevel@tonic-gate2:
9037c478bd9Sstevel@tonic-gate	membar	#Sync				! required before ASI_DC_DATA
9047c478bd9Sstevel@tonic-gate	ldxa	[%o0 + %o3]ASI_DC_DATA, %o2
9057c478bd9Sstevel@tonic-gate	membar	#Sync				! required after ASI_DC_DATA
9067c478bd9Sstevel@tonic-gate	stx	%o2, [%o1 + %o3]
9077c478bd9Sstevel@tonic-gate	cmp	%o3, CH_DC_DATA_REG_SIZE - 8
9087c478bd9Sstevel@tonic-gate	blt	2b
9097c478bd9Sstevel@tonic-gate	  add	%o3, 8, %o3
9107c478bd9Sstevel@tonic-gate
9117c478bd9Sstevel@tonic-gate	/*
9127c478bd9Sstevel@tonic-gate	 * Unlike other CPUs in the family, D$ data parity bits for Panther
9137c478bd9Sstevel@tonic-gate	 * do not reside in the microtag. Instead, we have to read them
9147c478bd9Sstevel@tonic-gate	 * using the DC_data_parity bit of ASI_DCACHE_DATA. Also, instead
9157c478bd9Sstevel@tonic-gate	 * of just having 8 parity bits to protect all 32 bytes of data
9167c478bd9Sstevel@tonic-gate	 * per line, we now have 32 bits of parity.
9177c478bd9Sstevel@tonic-gate	 */
9187c478bd9Sstevel@tonic-gate	GET_CPU_IMPL(%o3)
9197c478bd9Sstevel@tonic-gate	cmp	%o3, PANTHER_IMPL
9207c478bd9Sstevel@tonic-gate	bne	4f
9217c478bd9Sstevel@tonic-gate	  clr	%o3
9227c478bd9Sstevel@tonic-gate
9237c478bd9Sstevel@tonic-gate	/*
9247c478bd9Sstevel@tonic-gate	 * move our pointer to the next field where we store parity bits
9257c478bd9Sstevel@tonic-gate	 * and add the offset of the last parity byte since we will be
9267c478bd9Sstevel@tonic-gate	 * storing all 4 parity bytes within one 64 bit field like this:
9277c478bd9Sstevel@tonic-gate	 *
9287c478bd9Sstevel@tonic-gate	 * +------+------------+------------+------------+------------+
9297c478bd9Sstevel@tonic-gate	 * |  -   | DC_parity  | DC_parity  | DC_parity  | DC_parity  |
9307c478bd9Sstevel@tonic-gate	 * |  -   | for word 3 | for word 2 | for word 1 | for word 0 |
9317c478bd9Sstevel@tonic-gate	 * +------+------------+------------+------------+------------+
9327c478bd9Sstevel@tonic-gate	 *  63:32     31:24        23:16         15:8          7:0
9337c478bd9Sstevel@tonic-gate	 */
9347c478bd9Sstevel@tonic-gate	add	%o1, CH_DC_PN_DATA_PARITY - CH_DC_DATA + 7, %o1
9357c478bd9Sstevel@tonic-gate
9367c478bd9Sstevel@tonic-gate	/* add the DC_data_parity bit into our working index */
9377c478bd9Sstevel@tonic-gate	mov	1, %o2
9387c478bd9Sstevel@tonic-gate	sll	%o2, PN_DC_DATA_PARITY_BIT_SHIFT, %o2
9397c478bd9Sstevel@tonic-gate	or	%o0, %o2, %o0
9407c478bd9Sstevel@tonic-gate3:
9417c478bd9Sstevel@tonic-gate	membar	#Sync				! required before ASI_DC_DATA
9427c478bd9Sstevel@tonic-gate	ldxa	[%o0 + %o3]ASI_DC_DATA, %o2
9437c478bd9Sstevel@tonic-gate	membar	#Sync				! required after ASI_DC_DATA
9447c478bd9Sstevel@tonic-gate	stb	%o2, [%o1]
9457c478bd9Sstevel@tonic-gate	dec	%o1
9467c478bd9Sstevel@tonic-gate	cmp	%o3, CH_DC_DATA_REG_SIZE - 8
9477c478bd9Sstevel@tonic-gate	blt	3b
9487c478bd9Sstevel@tonic-gate	  add	%o3, 8, %o3
9497c478bd9Sstevel@tonic-gate4:
9507c478bd9Sstevel@tonic-gate	retl
9517c478bd9Sstevel@tonic-gate	  wrpr	%g0, %o5, %pstate
9527c478bd9Sstevel@tonic-gate	SET_SIZE(get_dcache_dtag)
9537c478bd9Sstevel@tonic-gate
9547c478bd9Sstevel@tonic-gate#endif	/* lint */
9557c478bd9Sstevel@tonic-gate
9567c478bd9Sstevel@tonic-gate
9577c478bd9Sstevel@tonic-gate#if defined(lint)
9587c478bd9Sstevel@tonic-gate
9597c478bd9Sstevel@tonic-gate/* ARGSUSED */
9607c478bd9Sstevel@tonic-gatevoid
9617c478bd9Sstevel@tonic-gateget_icache_dtag(uint32_t ecache_idx, uint64_t *data)
9627c478bd9Sstevel@tonic-gate{}
9637c478bd9Sstevel@tonic-gate
9647c478bd9Sstevel@tonic-gate#else	/* lint */
9657c478bd9Sstevel@tonic-gate
9667c478bd9Sstevel@tonic-gate/*
9677c478bd9Sstevel@tonic-gate * Get icache data and tag.  The data argument is a pointer to a ch_ic_data_t
9687c478bd9Sstevel@tonic-gate * structure (see cheetahregs.h):
9697c478bd9Sstevel@tonic-gate * The Icache *Must* be turned off when this function is called.
9707c478bd9Sstevel@tonic-gate * This is because diagnostic accesses to the Icache interfere with cache
9717c478bd9Sstevel@tonic-gate * consistency.
9727c478bd9Sstevel@tonic-gate */
9737c478bd9Sstevel@tonic-gate	.align	128
9747c478bd9Sstevel@tonic-gate	ENTRY(get_icache_dtag)
9757c478bd9Sstevel@tonic-gate	rdpr	%pstate, %o5
9767c478bd9Sstevel@tonic-gate	andn    %o5, PSTATE_IE | PSTATE_AM, %o3
9777c478bd9Sstevel@tonic-gate	wrpr	%g0, %o3, %pstate
9787c478bd9Sstevel@tonic-gate
9797c478bd9Sstevel@tonic-gate	stx	%o0, [%o1 + CH_IC_IDX]
9807c478bd9Sstevel@tonic-gate	ldxa	[%o0]ASI_IC_TAG, %o2
9817c478bd9Sstevel@tonic-gate	stx	%o2, [%o1 + CH_IC_PATAG]
9827c478bd9Sstevel@tonic-gate	add	%o0, CH_ICTAG_UTAG, %o0
9837c478bd9Sstevel@tonic-gate	ldxa	[%o0]ASI_IC_TAG, %o2
9847c478bd9Sstevel@tonic-gate	add	%o0, (CH_ICTAG_UPPER - CH_ICTAG_UTAG), %o0
9857c478bd9Sstevel@tonic-gate	stx	%o2, [%o1 + CH_IC_UTAG]
9867c478bd9Sstevel@tonic-gate	ldxa	[%o0]ASI_IC_TAG, %o2
9877c478bd9Sstevel@tonic-gate	add	%o0, (CH_ICTAG_LOWER - CH_ICTAG_UPPER), %o0
9887c478bd9Sstevel@tonic-gate	stx	%o2, [%o1 + CH_IC_UPPER]
9897c478bd9Sstevel@tonic-gate	ldxa	[%o0]ASI_IC_TAG, %o2
9907c478bd9Sstevel@tonic-gate	andn	%o0, CH_ICTAG_TMASK, %o0
9917c478bd9Sstevel@tonic-gate	stx	%o2, [%o1 + CH_IC_LOWER]
9927c478bd9Sstevel@tonic-gate	ldxa	[%o0]ASI_IC_SNP_TAG, %o2
9937c478bd9Sstevel@tonic-gate	stx	%o2, [%o1 + CH_IC_SNTAG]
9947c478bd9Sstevel@tonic-gate	add	%o1, CH_IC_DATA, %o1
9957c478bd9Sstevel@tonic-gate	clr	%o3
9967c478bd9Sstevel@tonic-gate2:
9977c478bd9Sstevel@tonic-gate	ldxa	[%o0 + %o3]ASI_IC_DATA, %o2
9987c478bd9Sstevel@tonic-gate	stx	%o2, [%o1 + %o3]
9997c478bd9Sstevel@tonic-gate	cmp	%o3, PN_IC_DATA_REG_SIZE - 8
10007c478bd9Sstevel@tonic-gate	blt	2b
10017c478bd9Sstevel@tonic-gate	  add	%o3, 8, %o3
10027c478bd9Sstevel@tonic-gate
10037c478bd9Sstevel@tonic-gate	retl
10047c478bd9Sstevel@tonic-gate	  wrpr	%g0, %o5, %pstate
10057c478bd9Sstevel@tonic-gate	SET_SIZE(get_icache_dtag)
10067c478bd9Sstevel@tonic-gate
10077c478bd9Sstevel@tonic-gate#endif	/* lint */
10087c478bd9Sstevel@tonic-gate
10097c478bd9Sstevel@tonic-gate#if defined(lint)
10107c478bd9Sstevel@tonic-gate
10117c478bd9Sstevel@tonic-gate/* ARGSUSED */
10127c478bd9Sstevel@tonic-gatevoid
10137c478bd9Sstevel@tonic-gateget_pcache_dtag(uint32_t pcache_idx, uint64_t *data)
10147c478bd9Sstevel@tonic-gate{}
10157c478bd9Sstevel@tonic-gate
10167c478bd9Sstevel@tonic-gate#else	/* lint */
10177c478bd9Sstevel@tonic-gate
10187c478bd9Sstevel@tonic-gate/*
10197c478bd9Sstevel@tonic-gate * Get pcache data and tags.
10207c478bd9Sstevel@tonic-gate * inputs:
10217c478bd9Sstevel@tonic-gate *   pcache_idx	- fully constructed VA for for accessing P$ diagnostic
10227c478bd9Sstevel@tonic-gate *		  registers. Contains PC_way and PC_addr shifted into
10237c478bd9Sstevel@tonic-gate *		  the correct bit positions. See the PRM for more details.
10247c478bd9Sstevel@tonic-gate *   data	- pointer to a ch_pc_data_t
10257c478bd9Sstevel@tonic-gate * structure (see cheetahregs.h):
10267c478bd9Sstevel@tonic-gate */
10277c478bd9Sstevel@tonic-gate	.align	128
10287c478bd9Sstevel@tonic-gate	ENTRY(get_pcache_dtag)
10297c478bd9Sstevel@tonic-gate	rdpr	%pstate, %o5
10307c478bd9Sstevel@tonic-gate	andn    %o5, PSTATE_IE | PSTATE_AM, %o3
10317c478bd9Sstevel@tonic-gate	wrpr	%g0, %o3, %pstate
10327c478bd9Sstevel@tonic-gate
10337c478bd9Sstevel@tonic-gate	stx	%o0, [%o1 + CH_PC_IDX]
10347c478bd9Sstevel@tonic-gate	ldxa	[%o0]ASI_PC_STATUS_DATA, %o2
10357c478bd9Sstevel@tonic-gate	stx	%o2, [%o1 + CH_PC_STATUS]
10367c478bd9Sstevel@tonic-gate	ldxa	[%o0]ASI_PC_TAG, %o2
10377c478bd9Sstevel@tonic-gate	stx	%o2, [%o1 + CH_PC_TAG]
10387c478bd9Sstevel@tonic-gate	ldxa	[%o0]ASI_PC_SNP_TAG, %o2
10397c478bd9Sstevel@tonic-gate	stx	%o2, [%o1 + CH_PC_SNTAG]
10407c478bd9Sstevel@tonic-gate	add	%o1, CH_PC_DATA, %o1
10417c478bd9Sstevel@tonic-gate	clr	%o3
10427c478bd9Sstevel@tonic-gate2:
10437c478bd9Sstevel@tonic-gate	ldxa	[%o0 + %o3]ASI_PC_DATA, %o2
10447c478bd9Sstevel@tonic-gate	stx	%o2, [%o1 + %o3]
10457c478bd9Sstevel@tonic-gate	cmp	%o3, CH_PC_DATA_REG_SIZE - 8
10467c478bd9Sstevel@tonic-gate	blt	2b
10477c478bd9Sstevel@tonic-gate	  add	%o3, 8, %o3
10487c478bd9Sstevel@tonic-gate
10497c478bd9Sstevel@tonic-gate	retl
10507c478bd9Sstevel@tonic-gate	  wrpr	%g0, %o5, %pstate
10517c478bd9Sstevel@tonic-gate	SET_SIZE(get_pcache_dtag)
10527c478bd9Sstevel@tonic-gate
10537c478bd9Sstevel@tonic-gate#endif	/* lint */
10547c478bd9Sstevel@tonic-gate
10557c478bd9Sstevel@tonic-gate#endif	/* CPU_IMP_L1_CACHE_PARITY */
10567c478bd9Sstevel@tonic-gate
10577c478bd9Sstevel@tonic-gate#if defined(lint)
10587c478bd9Sstevel@tonic-gate
10597c478bd9Sstevel@tonic-gate/* ARGSUSED */
10607c478bd9Sstevel@tonic-gatevoid
10617c478bd9Sstevel@tonic-gateset_dcu(uint64_t dcu)
10627c478bd9Sstevel@tonic-gate{}
10637c478bd9Sstevel@tonic-gate
10647c478bd9Sstevel@tonic-gate#else	/* lint */
10657c478bd9Sstevel@tonic-gate
10667c478bd9Sstevel@tonic-gate/*
10677c478bd9Sstevel@tonic-gate * re-enable the i$, d$, w$, and p$ according to bootup cache state.
10687c478bd9Sstevel@tonic-gate * Turn on WE, HPE, SPE, PE, IC, and DC bits defined as DCU_CACHE.
10697c478bd9Sstevel@tonic-gate *   %o0 - 64 bit constant
10707c478bd9Sstevel@tonic-gate */
10717c478bd9Sstevel@tonic-gate	ENTRY(set_dcu)
10727c478bd9Sstevel@tonic-gate	stxa	%o0, [%g0]ASI_DCU	! Store to DCU
10737c478bd9Sstevel@tonic-gate	flush	%g0	/* flush required after changing the IC bit */
10747c478bd9Sstevel@tonic-gate	retl
10757c478bd9Sstevel@tonic-gate	nop
10767c478bd9Sstevel@tonic-gate	SET_SIZE(set_dcu)
10777c478bd9Sstevel@tonic-gate
10787c478bd9Sstevel@tonic-gate#endif	/* lint */
10797c478bd9Sstevel@tonic-gate
10807c478bd9Sstevel@tonic-gate
10817c478bd9Sstevel@tonic-gate#if defined(lint)
10827c478bd9Sstevel@tonic-gate
10837c478bd9Sstevel@tonic-gateuint64_t
10847c478bd9Sstevel@tonic-gateget_dcu(void)
10857c478bd9Sstevel@tonic-gate{
10867c478bd9Sstevel@tonic-gate	return ((uint64_t)0);
10877c478bd9Sstevel@tonic-gate}
10887c478bd9Sstevel@tonic-gate
10897c478bd9Sstevel@tonic-gate#else	/* lint */
10907c478bd9Sstevel@tonic-gate
10917c478bd9Sstevel@tonic-gate/*
10927c478bd9Sstevel@tonic-gate * Return DCU register.
10937c478bd9Sstevel@tonic-gate */
10947c478bd9Sstevel@tonic-gate	ENTRY(get_dcu)
10957c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_DCU, %o0		/* DCU control register */
10967c478bd9Sstevel@tonic-gate	retl
10977c478bd9Sstevel@tonic-gate	nop
10987c478bd9Sstevel@tonic-gate	SET_SIZE(get_dcu)
10997c478bd9Sstevel@tonic-gate
11007c478bd9Sstevel@tonic-gate#endif	/* lint */
11017c478bd9Sstevel@tonic-gate
11027c478bd9Sstevel@tonic-gate/*
11037c478bd9Sstevel@tonic-gate * Cheetah/Cheetah+ level 15 interrupt handler trap table entry.
11047c478bd9Sstevel@tonic-gate *
11057c478bd9Sstevel@tonic-gate * This handler is used to check for softints generated by error trap
11067c478bd9Sstevel@tonic-gate * handlers to report errors.  On Cheetah, this mechanism is used by the
11077c478bd9Sstevel@tonic-gate * Fast ECC at TL>0 error trap handler and, on Cheetah+, by both the Fast
11087c478bd9Sstevel@tonic-gate * ECC at TL>0 error and the I$/D$ parity error at TL>0 trap handlers.
11097c478bd9Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must
11107c478bd9Sstevel@tonic-gate *     be relocatable.
11117c478bd9Sstevel@tonic-gate */
11127c478bd9Sstevel@tonic-gate#if defined(lint)
11137c478bd9Sstevel@tonic-gate
11147c478bd9Sstevel@tonic-gatevoid
11157c478bd9Sstevel@tonic-gatech_pil15_interrupt_instr(void)
11167c478bd9Sstevel@tonic-gate{}
11177c478bd9Sstevel@tonic-gate
11187c478bd9Sstevel@tonic-gate#else	/* lint */
11197c478bd9Sstevel@tonic-gate
11207c478bd9Sstevel@tonic-gate	ENTRY_NP(ch_pil15_interrupt_instr)
11217c478bd9Sstevel@tonic-gate	ASM_JMP(%g1, ch_pil15_interrupt)
11227c478bd9Sstevel@tonic-gate	SET_SIZE(ch_pil15_interrupt_instr)
11237c478bd9Sstevel@tonic-gate
11247c478bd9Sstevel@tonic-gate#endif
11257c478bd9Sstevel@tonic-gate
11267c478bd9Sstevel@tonic-gate
11277c478bd9Sstevel@tonic-gate#if defined(lint)
11287c478bd9Sstevel@tonic-gate
11297c478bd9Sstevel@tonic-gatevoid
11307c478bd9Sstevel@tonic-gatech_pil15_interrupt(void)
11317c478bd9Sstevel@tonic-gate{}
11327c478bd9Sstevel@tonic-gate
11337c478bd9Sstevel@tonic-gate#else	/* lint */
11347c478bd9Sstevel@tonic-gate
11357c478bd9Sstevel@tonic-gate	ENTRY_NP(ch_pil15_interrupt)
11367c478bd9Sstevel@tonic-gate
11377c478bd9Sstevel@tonic-gate	/*
11387c478bd9Sstevel@tonic-gate	 * Since pil_interrupt is hacked to assume that every level 15
11397c478bd9Sstevel@tonic-gate	 * interrupt is generated by the CPU to indicate a performance
11407c478bd9Sstevel@tonic-gate	 * counter overflow this gets ugly.  Before calling pil_interrupt
11417c478bd9Sstevel@tonic-gate	 * the Error at TL>0 pending status is inspected.  If it is
11427c478bd9Sstevel@tonic-gate	 * non-zero, then an error has occurred and it is handled.
11437c478bd9Sstevel@tonic-gate	 * Otherwise control is transfered to pil_interrupt.  Note that if
11447c478bd9Sstevel@tonic-gate	 * an error is detected pil_interrupt will not be called and
11457c478bd9Sstevel@tonic-gate	 * overflow interrupts may be lost causing erroneous performance
11467c478bd9Sstevel@tonic-gate	 * measurements.  However, error-recovery will have a detrimental
11477c478bd9Sstevel@tonic-gate	 * effect on performance anyway.
11487c478bd9Sstevel@tonic-gate	 */
11497c478bd9Sstevel@tonic-gate	CPU_INDEX(%g1, %g4)
11507c478bd9Sstevel@tonic-gate	set	ch_err_tl1_pending, %g4
11517c478bd9Sstevel@tonic-gate	ldub	[%g1 + %g4], %g2
11527c478bd9Sstevel@tonic-gate	brz	%g2, 1f
11537c478bd9Sstevel@tonic-gate	  nop
11547c478bd9Sstevel@tonic-gate
11557c478bd9Sstevel@tonic-gate	/*
11567c478bd9Sstevel@tonic-gate	 * We have a pending TL>0 error, clear the TL>0 pending status.
11577c478bd9Sstevel@tonic-gate	 */
11587c478bd9Sstevel@tonic-gate	stb	%g0, [%g1 + %g4]
11597c478bd9Sstevel@tonic-gate
11607c478bd9Sstevel@tonic-gate	/*
11617c478bd9Sstevel@tonic-gate	 * Clear the softint.
11627c478bd9Sstevel@tonic-gate	 */
11637c478bd9Sstevel@tonic-gate	mov	1, %g5
11647c478bd9Sstevel@tonic-gate	sll	%g5, PIL_15, %g5
11657c478bd9Sstevel@tonic-gate	wr	%g5, CLEAR_SOFTINT
11667c478bd9Sstevel@tonic-gate
11677c478bd9Sstevel@tonic-gate	/*
11687c478bd9Sstevel@tonic-gate	 * For Cheetah*, call cpu_tl1_error via systrap at PIL 15
11697c478bd9Sstevel@tonic-gate	 * to process the Fast ECC/Cache Parity at TL>0 error.  Clear
11707c478bd9Sstevel@tonic-gate	 * panic flag (%g2).
11717c478bd9Sstevel@tonic-gate	 */
11727c478bd9Sstevel@tonic-gate	set	cpu_tl1_error, %g1
11737c478bd9Sstevel@tonic-gate	clr	%g2
11747c478bd9Sstevel@tonic-gate	ba	sys_trap
11757c478bd9Sstevel@tonic-gate	  mov	PIL_15, %g4
11767c478bd9Sstevel@tonic-gate
11777c478bd9Sstevel@tonic-gate1:
11787c478bd9Sstevel@tonic-gate	/*
11797c478bd9Sstevel@tonic-gate	 * The logout is invalid.
11807c478bd9Sstevel@tonic-gate	 *
11817c478bd9Sstevel@tonic-gate	 * Call the default interrupt handler.
11827c478bd9Sstevel@tonic-gate	 */
11837c478bd9Sstevel@tonic-gate	sethi	%hi(pil_interrupt), %g1
11847c478bd9Sstevel@tonic-gate	jmp	%g1 + %lo(pil_interrupt)
11857c478bd9Sstevel@tonic-gate	  mov	PIL_15, %g4
11867c478bd9Sstevel@tonic-gate
11877c478bd9Sstevel@tonic-gate	SET_SIZE(ch_pil15_interrupt)
11887c478bd9Sstevel@tonic-gate#endif
11897c478bd9Sstevel@tonic-gate
11907c478bd9Sstevel@tonic-gate
11917c478bd9Sstevel@tonic-gate/*
11927c478bd9Sstevel@tonic-gate * Error Handling
11937c478bd9Sstevel@tonic-gate *
11947c478bd9Sstevel@tonic-gate * Cheetah provides error checking for all memory access paths between
11957c478bd9Sstevel@tonic-gate * the CPU, External Cache, Cheetah Data Switch and system bus. Error
11967c478bd9Sstevel@tonic-gate * information is logged in the AFSR, (also AFSR_EXT for Panther) and
11977c478bd9Sstevel@tonic-gate * AFAR and one of the following traps is generated (provided that it
11987c478bd9Sstevel@tonic-gate * is enabled in External Cache Error Enable Register) to handle that
11997c478bd9Sstevel@tonic-gate * error:
12007c478bd9Sstevel@tonic-gate * 1. trap 0x70: Precise trap
12017c478bd9Sstevel@tonic-gate *    tt0_fecc for errors at trap level(TL)>=0
12027c478bd9Sstevel@tonic-gate * 2. trap 0x0A and 0x32: Deferred trap
12037c478bd9Sstevel@tonic-gate *    async_err for errors at TL>=0
12047c478bd9Sstevel@tonic-gate * 3. trap 0x63: Disrupting trap
12057c478bd9Sstevel@tonic-gate *    ce_err for errors at TL=0
12067c478bd9Sstevel@tonic-gate *    (Note that trap 0x63 cannot happen at trap level > 0)
12077c478bd9Sstevel@tonic-gate *
12087c478bd9Sstevel@tonic-gate * Trap level one handlers panic the system except for the fast ecc
12097c478bd9Sstevel@tonic-gate * error handler which tries to recover from certain errors.
12107c478bd9Sstevel@tonic-gate */
12117c478bd9Sstevel@tonic-gate
12127c478bd9Sstevel@tonic-gate/*
12137c478bd9Sstevel@tonic-gate * FAST ECC TRAP STRATEGY:
12147c478bd9Sstevel@tonic-gate *
12157c478bd9Sstevel@tonic-gate * Software must handle single and multi bit errors which occur due to data
12167c478bd9Sstevel@tonic-gate * or instruction cache reads from the external cache. A single or multi bit
12177c478bd9Sstevel@tonic-gate * error occuring in one of these situations results in a precise trap.
12187c478bd9Sstevel@tonic-gate *
12197c478bd9Sstevel@tonic-gate * The basic flow of this trap handler is as follows:
12207c478bd9Sstevel@tonic-gate *
12217c478bd9Sstevel@tonic-gate * 1) Record the state and then turn off the Dcache and Icache.  The Dcache
12227c478bd9Sstevel@tonic-gate *    is disabled because bad data could have been installed.  The Icache is
12237c478bd9Sstevel@tonic-gate *    turned off because we want to capture the Icache line related to the
12247c478bd9Sstevel@tonic-gate *    AFAR.
12257c478bd9Sstevel@tonic-gate * 2) Disable trapping on CEEN/NCCEN errors during TL=0 processing.
12267c478bd9Sstevel@tonic-gate * 3) Park sibling core if caches are shared (to avoid race condition while
12277c478bd9Sstevel@tonic-gate *    accessing shared resources such as L3 data staging register during
12287c478bd9Sstevel@tonic-gate *    CPU logout.
12297c478bd9Sstevel@tonic-gate * 4) Read the AFAR and AFSR.
12307c478bd9Sstevel@tonic-gate * 5) If CPU logout structure is not being used, then:
12317c478bd9Sstevel@tonic-gate *    6) Clear all errors from the AFSR.
12327c478bd9Sstevel@tonic-gate *    7) Capture Ecache, Dcache and Icache lines in "CPU log out" structure.
12337c478bd9Sstevel@tonic-gate *    8) Flush Ecache then Flush Dcache and Icache and restore to previous
12347c478bd9Sstevel@tonic-gate *       state.
12357c478bd9Sstevel@tonic-gate *    9) Unpark sibling core if we parked it earlier.
12367c478bd9Sstevel@tonic-gate *    10) call cpu_fast_ecc_error via systrap at PIL 14 unless we're already
12377c478bd9Sstevel@tonic-gate *        running at PIL 15.
12387c478bd9Sstevel@tonic-gate * 6) Otherwise, if CPU logout structure is being used:
12397c478bd9Sstevel@tonic-gate *    7) Incriment the "logout busy count".
12407c478bd9Sstevel@tonic-gate *    8) Flush Ecache then Flush Dcache and Icache and restore to previous
12417c478bd9Sstevel@tonic-gate *       state.
12427c478bd9Sstevel@tonic-gate *    9) Unpark sibling core if we parked it earlier.
12437c478bd9Sstevel@tonic-gate *    10) Issue a retry since the other CPU error logging code will end up
12447c478bd9Sstevel@tonic-gate *       finding this error bit and logging information about it later.
12457c478bd9Sstevel@tonic-gate * 7) Alternatively (to 5 and 6 above), if the cpu_private struct is not
12467c478bd9Sstevel@tonic-gate *    yet initialized such that we can't even check the logout struct, then
12477c478bd9Sstevel@tonic-gate *    we place the clo_flags data into %g2 (sys_trap->have_win arg #1) and
12487c478bd9Sstevel@tonic-gate *    call cpu_fast_ecc_error via systrap. The clo_flags parameter is used
12494fd7ecabSdilpreet *    to determine information such as TL, TT, CEEN and NCEEN settings, etc
12504fd7ecabSdilpreet *    in the high level trap handler since we don't have access to detailed
12514fd7ecabSdilpreet *    logout information in cases where the cpu_private struct is not yet
12527c478bd9Sstevel@tonic-gate *    initialized.
12537c478bd9Sstevel@tonic-gate *
12547c478bd9Sstevel@tonic-gate * We flush the E$ and D$ here on TL=1 code to prevent getting nested
12557c478bd9Sstevel@tonic-gate * Fast ECC traps in the TL=0 code.  If we get a Fast ECC event here in
12567c478bd9Sstevel@tonic-gate * the TL=1 code, we will go to the Fast ECC at TL>0 handler which,
12577c478bd9Sstevel@tonic-gate * since it is uses different code/data from this handler, has a better
12587c478bd9Sstevel@tonic-gate * chance of fixing things up than simply recursing through this code
12597c478bd9Sstevel@tonic-gate * again (this would probably cause an eventual kernel stack overflow).
12607c478bd9Sstevel@tonic-gate * If the Fast ECC at TL>0 handler encounters a Fast ECC error before it
12617c478bd9Sstevel@tonic-gate * can flush the E$ (or the error is a stuck-at bit), we will recurse in
12627c478bd9Sstevel@tonic-gate * the Fast ECC at TL>0 handler and eventually Red Mode.
12637c478bd9Sstevel@tonic-gate *
12647c478bd9Sstevel@tonic-gate * Note that for Cheetah (and only Cheetah), we use alias addresses for
12657c478bd9Sstevel@tonic-gate * flushing rather than ASI accesses (which don't exist on Cheetah).
12667c478bd9Sstevel@tonic-gate * Should we encounter a Fast ECC error within this handler on Cheetah,
12677c478bd9Sstevel@tonic-gate * there's a good chance it's within the ecache_flushaddr buffer (since
12687c478bd9Sstevel@tonic-gate * it's the largest piece of memory we touch in the handler and it is
12697c478bd9Sstevel@tonic-gate * usually kernel text/data).  For that reason the Fast ECC at TL>0
12707c478bd9Sstevel@tonic-gate * handler for Cheetah uses an alternate buffer: ecache_tl1_flushaddr.
12717c478bd9Sstevel@tonic-gate */
12727c478bd9Sstevel@tonic-gate
12737c478bd9Sstevel@tonic-gate/*
12747c478bd9Sstevel@tonic-gate * Cheetah ecc-protected E$ trap (Trap 70) at TL=0
12757c478bd9Sstevel@tonic-gate * tt0_fecc is replaced by fecc_err_instr in cpu_init_trap of the various
12767c478bd9Sstevel@tonic-gate * architecture-specific files.
12777c478bd9Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must
12787c478bd9Sstevel@tonic-gate *     be relocatable.
12797c478bd9Sstevel@tonic-gate */
12807c478bd9Sstevel@tonic-gate
12817c478bd9Sstevel@tonic-gate#if defined(lint)
12827c478bd9Sstevel@tonic-gate
12837c478bd9Sstevel@tonic-gatevoid
12847c478bd9Sstevel@tonic-gatefecc_err_instr(void)
12857c478bd9Sstevel@tonic-gate{}
12867c478bd9Sstevel@tonic-gate
12877c478bd9Sstevel@tonic-gate#else	/* lint */
12887c478bd9Sstevel@tonic-gate
12897c478bd9Sstevel@tonic-gate	ENTRY_NP(fecc_err_instr)
12907c478bd9Sstevel@tonic-gate	membar	#Sync			! Cheetah requires membar #Sync
12917c478bd9Sstevel@tonic-gate
12927c478bd9Sstevel@tonic-gate	/*
12937c478bd9Sstevel@tonic-gate	 * Save current DCU state.  Turn off the Dcache and Icache.
12947c478bd9Sstevel@tonic-gate	 */
12957c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_DCU, %g1	! save DCU in %g1
12967c478bd9Sstevel@tonic-gate	andn	%g1, DCU_DC + DCU_IC, %g4
12977c478bd9Sstevel@tonic-gate	stxa	%g4, [%g0]ASI_DCU
12987c478bd9Sstevel@tonic-gate	flush	%g0	/* flush required after changing the IC bit */
12997c478bd9Sstevel@tonic-gate
13007c478bd9Sstevel@tonic-gate	ASM_JMP(%g4, fast_ecc_err)
13017c478bd9Sstevel@tonic-gate	SET_SIZE(fecc_err_instr)
13027c478bd9Sstevel@tonic-gate
13037c478bd9Sstevel@tonic-gate#endif	/* lint */
13047c478bd9Sstevel@tonic-gate
13057c478bd9Sstevel@tonic-gate
13067c478bd9Sstevel@tonic-gate#if !(defined(JALAPENO) || defined(SERRANO))
13077c478bd9Sstevel@tonic-gate
13087c478bd9Sstevel@tonic-gate#if defined(lint)
13097c478bd9Sstevel@tonic-gate
13107c478bd9Sstevel@tonic-gatevoid
13117c478bd9Sstevel@tonic-gatefast_ecc_err(void)
13127c478bd9Sstevel@tonic-gate{}
13137c478bd9Sstevel@tonic-gate
13147c478bd9Sstevel@tonic-gate#else	/* lint */
13157c478bd9Sstevel@tonic-gate
13167c478bd9Sstevel@tonic-gate	.section ".text"
13177c478bd9Sstevel@tonic-gate	.align	64
13187c478bd9Sstevel@tonic-gate	ENTRY_NP(fast_ecc_err)
13197c478bd9Sstevel@tonic-gate
13207c478bd9Sstevel@tonic-gate	/*
13217c478bd9Sstevel@tonic-gate	 * Turn off CEEN and NCEEN.
13227c478bd9Sstevel@tonic-gate	 */
13237c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_ESTATE_ERR, %g3
13247c478bd9Sstevel@tonic-gate	andn	%g3, EN_REG_NCEEN + EN_REG_CEEN, %g4
13257c478bd9Sstevel@tonic-gate	stxa	%g4, [%g0]ASI_ESTATE_ERR
13267c478bd9Sstevel@tonic-gate	membar	#Sync			! membar sync required
13277c478bd9Sstevel@tonic-gate
13287c478bd9Sstevel@tonic-gate	/*
13297c478bd9Sstevel@tonic-gate	 * Check to see whether we need to park our sibling core
13307c478bd9Sstevel@tonic-gate	 * before recording diagnostic information from caches
13317c478bd9Sstevel@tonic-gate	 * which may be shared by both cores.
13327c478bd9Sstevel@tonic-gate	 * We use %g1 to store information about whether or not
13337c478bd9Sstevel@tonic-gate	 * we had to park the core (%g1 holds our DCUCR value and
13347c478bd9Sstevel@tonic-gate	 * we only use bits from that register which are "reserved"
13357c478bd9Sstevel@tonic-gate	 * to keep track of core parking) so that we know whether
13367c478bd9Sstevel@tonic-gate	 * or not to unpark later. %g5 and %g4 are scratch registers.
13377c478bd9Sstevel@tonic-gate	 */
13387c478bd9Sstevel@tonic-gate	PARK_SIBLING_CORE(%g1, %g5, %g4)
13397c478bd9Sstevel@tonic-gate
13407c478bd9Sstevel@tonic-gate	/*
13417c478bd9Sstevel@tonic-gate	 * Do the CPU log out capture.
13427c478bd9Sstevel@tonic-gate	 *   %g3 = "failed?" return value.
13437c478bd9Sstevel@tonic-gate	 *   %g2 = Input = AFAR. Output the clo_flags info which is passed
13447c478bd9Sstevel@tonic-gate	 *         into this macro via %g4. Output only valid if cpu_private
13457c478bd9Sstevel@tonic-gate	 *         struct has not been initialized.
13467c478bd9Sstevel@tonic-gate	 *   CHPR_FECCTL0_LOGOUT = cpu logout structure offset input
13477c478bd9Sstevel@tonic-gate	 *   %g4 = Trap information stored in the cpu logout flags field
13487c478bd9Sstevel@tonic-gate	 *   %g5 = scr1
13497c478bd9Sstevel@tonic-gate	 *   %g6 = scr2
13507c478bd9Sstevel@tonic-gate	 *   %g3 = scr3
13517c478bd9Sstevel@tonic-gate	 *   %g4 = scr4
13527c478bd9Sstevel@tonic-gate	 */
13534fd7ecabSdilpreet	 /* store the CEEN and NCEEN values, TL=0 */
13544fd7ecabSdilpreet	and	%g3, EN_REG_CEEN + EN_REG_NCEEN, %g4
13557c478bd9Sstevel@tonic-gate	set	CHPR_FECCTL0_LOGOUT, %g6
13567c478bd9Sstevel@tonic-gate	DO_CPU_LOGOUT(%g3, %g2, %g6, %g4, %g5, %g6, %g3, %g4)
13577c478bd9Sstevel@tonic-gate
13587c478bd9Sstevel@tonic-gate	/*
13597c478bd9Sstevel@tonic-gate	 * Flush the Ecache (and L2 cache for Panther) to get the error out
13607c478bd9Sstevel@tonic-gate	 * of the Ecache.  If the UCC or UCU is on a dirty line, then the
13617c478bd9Sstevel@tonic-gate	 * following flush will turn that into a WDC or WDU, respectively.
13627c478bd9Sstevel@tonic-gate	 */
13637c478bd9Sstevel@tonic-gate	PN_L2_FLUSHALL(%g4, %g5, %g6)
13647c478bd9Sstevel@tonic-gate
13657c478bd9Sstevel@tonic-gate	CPU_INDEX(%g4, %g5)
13667c478bd9Sstevel@tonic-gate	mulx	%g4, CPU_NODE_SIZE, %g4
13677c478bd9Sstevel@tonic-gate	set	cpunodes, %g5
13687c478bd9Sstevel@tonic-gate	add	%g4, %g5, %g4
13697c478bd9Sstevel@tonic-gate	ld	[%g4 + ECACHE_LINESIZE], %g5
13707c478bd9Sstevel@tonic-gate	ld	[%g4 + ECACHE_SIZE], %g4
13717c478bd9Sstevel@tonic-gate
13727c478bd9Sstevel@tonic-gate	ASM_LDX(%g6, ecache_flushaddr)
13737c478bd9Sstevel@tonic-gate	ECACHE_FLUSHALL(%g4, %g5, %g6, %g7)
13747c478bd9Sstevel@tonic-gate
13757c478bd9Sstevel@tonic-gate	/*
13767c478bd9Sstevel@tonic-gate	 * Flush the Dcache.  Since bad data could have been installed in
13777c478bd9Sstevel@tonic-gate	 * the Dcache we must flush it before re-enabling it.
13787c478bd9Sstevel@tonic-gate	 */
13797c478bd9Sstevel@tonic-gate	ASM_LD(%g5, dcache_size)
13807c478bd9Sstevel@tonic-gate	ASM_LD(%g6, dcache_linesize)
13817c478bd9Sstevel@tonic-gate	CH_DCACHE_FLUSHALL(%g5, %g6, %g7)
13827c478bd9Sstevel@tonic-gate
13837c478bd9Sstevel@tonic-gate	/*
13847c478bd9Sstevel@tonic-gate	 * Flush the Icache.  Since we turned off the Icache to capture the
13857c478bd9Sstevel@tonic-gate	 * Icache line it is now stale or corrupted and we must flush it
13867c478bd9Sstevel@tonic-gate	 * before re-enabling it.
13877c478bd9Sstevel@tonic-gate	 */
13887c478bd9Sstevel@tonic-gate	GET_CPU_PRIVATE_PTR(%g0, %g5, %g7, fast_ecc_err_5);
13897c478bd9Sstevel@tonic-gate	ld	[%g5 + CHPR_ICACHE_LINESIZE], %g6
13907c478bd9Sstevel@tonic-gate	ba,pt	%icc, 6f
13917c478bd9Sstevel@tonic-gate	  ld	[%g5 + CHPR_ICACHE_SIZE], %g5
13927c478bd9Sstevel@tonic-gatefast_ecc_err_5:
13937c478bd9Sstevel@tonic-gate	ASM_LD(%g5, icache_size)
13947c478bd9Sstevel@tonic-gate	ASM_LD(%g6, icache_linesize)
13957c478bd9Sstevel@tonic-gate6:
13967c478bd9Sstevel@tonic-gate	CH_ICACHE_FLUSHALL(%g5, %g6, %g7, %g4)
13977c478bd9Sstevel@tonic-gate
13987c478bd9Sstevel@tonic-gate	/*
13997c478bd9Sstevel@tonic-gate	 * check to see whether we parked our sibling core at the start
14007c478bd9Sstevel@tonic-gate	 * of this handler. If so, we need to unpark it here.
14017c478bd9Sstevel@tonic-gate	 * We use DCUCR reserved bits (stored in %g1) to keep track of
14027c478bd9Sstevel@tonic-gate	 * whether or not we need to unpark. %g5 and %g4 are scratch registers.
14037c478bd9Sstevel@tonic-gate	 */
14047c478bd9Sstevel@tonic-gate	UNPARK_SIBLING_CORE(%g1, %g5, %g4)
14057c478bd9Sstevel@tonic-gate
14067c478bd9Sstevel@tonic-gate	/*
14077c478bd9Sstevel@tonic-gate	 * Restore the Dcache and Icache to the previous state.
14087c478bd9Sstevel@tonic-gate	 */
14097c478bd9Sstevel@tonic-gate	stxa	%g1, [%g0]ASI_DCU
14107c478bd9Sstevel@tonic-gate	flush	%g0	/* flush required after changing the IC bit */
14117c478bd9Sstevel@tonic-gate
14127c478bd9Sstevel@tonic-gate	/*
14137c478bd9Sstevel@tonic-gate	 * Make sure our CPU logout operation was successful.
14147c478bd9Sstevel@tonic-gate	 */
14157c478bd9Sstevel@tonic-gate	cmp	%g3, %g0
14167c478bd9Sstevel@tonic-gate	be	8f
14177c478bd9Sstevel@tonic-gate	  nop
14187c478bd9Sstevel@tonic-gate
14197c478bd9Sstevel@tonic-gate	/*
14207c478bd9Sstevel@tonic-gate	 * If the logout structure had been busy, how many times have
14217c478bd9Sstevel@tonic-gate	 * we tried to use it and failed (nesting count)? If we have
14227c478bd9Sstevel@tonic-gate	 * already recursed a substantial number of times, then we can
14237c478bd9Sstevel@tonic-gate	 * assume things are not going to get better by themselves and
14247c478bd9Sstevel@tonic-gate	 * so it would be best to panic.
14257c478bd9Sstevel@tonic-gate	 */
14267c478bd9Sstevel@tonic-gate	cmp	%g3, CLO_NESTING_MAX
14277c478bd9Sstevel@tonic-gate	blt	7f
14287c478bd9Sstevel@tonic-gate	  nop
14297c478bd9Sstevel@tonic-gate
14307c478bd9Sstevel@tonic-gate        call ptl1_panic
14317c478bd9Sstevel@tonic-gate          mov   PTL1_BAD_ECC, %g1
14327c478bd9Sstevel@tonic-gate
14337c478bd9Sstevel@tonic-gate7:
14347c478bd9Sstevel@tonic-gate	/*
14357c478bd9Sstevel@tonic-gate	 * Otherwise, if the logout structure was busy but we have not
14367c478bd9Sstevel@tonic-gate	 * nested more times than our maximum value, then we simply
14377c478bd9Sstevel@tonic-gate	 * issue a retry. Our TL=0 trap handler code will check and
14387c478bd9Sstevel@tonic-gate	 * clear the AFSR after it is done logging what is currently
14397c478bd9Sstevel@tonic-gate	 * in the logout struct and handle this event at that time.
14407c478bd9Sstevel@tonic-gate	 */
14417c478bd9Sstevel@tonic-gate	retry
14427c478bd9Sstevel@tonic-gate8:
14437c478bd9Sstevel@tonic-gate	/*
14447c478bd9Sstevel@tonic-gate	 * Call cpu_fast_ecc_error via systrap at PIL 14 unless we're
14457c478bd9Sstevel@tonic-gate	 * already at PIL 15.
14467c478bd9Sstevel@tonic-gate	 */
14477c478bd9Sstevel@tonic-gate	set	cpu_fast_ecc_error, %g1
14487c478bd9Sstevel@tonic-gate	rdpr	%pil, %g4
14497c478bd9Sstevel@tonic-gate	cmp	%g4, PIL_14
14507c478bd9Sstevel@tonic-gate	ba	sys_trap
14517c478bd9Sstevel@tonic-gate	  movl	%icc, PIL_14, %g4
14527c478bd9Sstevel@tonic-gate
14537c478bd9Sstevel@tonic-gate	SET_SIZE(fast_ecc_err)
14547c478bd9Sstevel@tonic-gate
14557c478bd9Sstevel@tonic-gate#endif	/* lint */
14567c478bd9Sstevel@tonic-gate
14577c478bd9Sstevel@tonic-gate#endif	/* !(JALAPENO || SERRANO) */
14587c478bd9Sstevel@tonic-gate
14597c478bd9Sstevel@tonic-gate
14607c478bd9Sstevel@tonic-gate/*
14617c478bd9Sstevel@tonic-gate * Cheetah/Cheetah+ Fast ECC at TL>0 trap strategy:
14627c478bd9Sstevel@tonic-gate *
14637c478bd9Sstevel@tonic-gate * The basic flow of this trap handler is as follows:
14647c478bd9Sstevel@tonic-gate *
14657c478bd9Sstevel@tonic-gate * 1) In the "trap 70" trap table code (fecc_err_tl1_instr), generate a
14667c478bd9Sstevel@tonic-gate *    software trap 0 ("ta 0") to buy an extra set of %tpc, etc. which we
14677c478bd9Sstevel@tonic-gate *    will use to save %g1 and %g2.
14687c478bd9Sstevel@tonic-gate * 2) At the software trap 0 at TL>0 trap table code (fecc_err_tl1_cont_instr),
14697c478bd9Sstevel@tonic-gate *    we save %g1+%g2 using %tpc, %tnpc + %tstate and jump to the fast ecc
14707c478bd9Sstevel@tonic-gate *    handler (using the just saved %g1).
14717c478bd9Sstevel@tonic-gate * 3) Turn off the Dcache if it was on and save the state of the Dcache
14727c478bd9Sstevel@tonic-gate *    (whether on or off) in Bit2 (CH_ERR_TSTATE_DC_ON) of %tstate.
14737c478bd9Sstevel@tonic-gate *    NB: we don't turn off the Icache because bad data is not installed nor
14747c478bd9Sstevel@tonic-gate *        will we be doing any diagnostic accesses.
14757c478bd9Sstevel@tonic-gate * 4) compute physical address of the per-cpu/per-tl save area using %g1+%g2
14767c478bd9Sstevel@tonic-gate * 5) Save %g1-%g7 into the per-cpu/per-tl save area (%g1 + %g2 from the
14777c478bd9Sstevel@tonic-gate *    %tpc, %tnpc, %tstate values previously saved).
14787c478bd9Sstevel@tonic-gate * 6) set %tl to %tl - 1.
14797c478bd9Sstevel@tonic-gate * 7) Save the appropriate flags and TPC in the ch_err_tl1_data structure.
14807c478bd9Sstevel@tonic-gate * 8) Save the value of CH_ERR_TSTATE_DC_ON in the ch_err_tl1_tmp field.
14817c478bd9Sstevel@tonic-gate * 9) For Cheetah and Jalapeno, read the AFAR and AFSR and clear.  For
14827c478bd9Sstevel@tonic-gate *    Cheetah+ (and later), read the shadow AFAR and AFSR but don't clear.
14837c478bd9Sstevel@tonic-gate *    Save the values in ch_err_tl1_data.  For Panther, read the shadow
14847c478bd9Sstevel@tonic-gate *    AFSR_EXT and save the value in ch_err_tl1_data.
14857c478bd9Sstevel@tonic-gate * 10) Disable CEEN/NCEEN to prevent any disrupting/deferred errors from
14867c478bd9Sstevel@tonic-gate *    being queued.  We'll report them via the AFSR/AFAR capture in step 13.
14877c478bd9Sstevel@tonic-gate * 11) Flush the Ecache.
14887c478bd9Sstevel@tonic-gate *    NB: the Ecache is flushed assuming the largest possible size with
14897c478bd9Sstevel@tonic-gate *        the smallest possible line size since access to the cpu_nodes may
14907c478bd9Sstevel@tonic-gate *        cause an unrecoverable DTLB miss.
14917c478bd9Sstevel@tonic-gate * 12) Reenable CEEN/NCEEN with the value saved from step 10.
14927c478bd9Sstevel@tonic-gate * 13) For Cheetah and Jalapeno, read the AFAR and AFSR and clear again.
14937c478bd9Sstevel@tonic-gate *    For Cheetah+ (and later), read the primary AFAR and AFSR and now clear.
14947c478bd9Sstevel@tonic-gate *    Save the read AFSR/AFAR values in ch_err_tl1_data.  For Panther,
14957c478bd9Sstevel@tonic-gate *    read and clear the primary AFSR_EXT and save it in ch_err_tl1_data.
14967c478bd9Sstevel@tonic-gate * 14) Flush and re-enable the Dcache if it was on at step 3.
14977c478bd9Sstevel@tonic-gate * 15) Do TRAPTRACE if enabled.
14987c478bd9Sstevel@tonic-gate * 16) Check if a UCU->WDU (or L3_UCU->WDU for Panther) happened, panic if so.
14997c478bd9Sstevel@tonic-gate * 17) Set the event pending flag in ch_err_tl1_pending[CPU]
15007c478bd9Sstevel@tonic-gate * 18) Cause a softint 15.  The pil15_interrupt handler will inspect the
15017c478bd9Sstevel@tonic-gate *    event pending flag and call cpu_tl1_error via systrap if set.
15027c478bd9Sstevel@tonic-gate * 19) Restore the registers from step 5 and issue retry.
15037c478bd9Sstevel@tonic-gate */
15047c478bd9Sstevel@tonic-gate
15057c478bd9Sstevel@tonic-gate/*
15067c478bd9Sstevel@tonic-gate * Cheetah ecc-protected E$ trap (Trap 70) at TL>0
15077c478bd9Sstevel@tonic-gate * tt1_fecc is replaced by fecc_err_tl1_instr in cpu_init_trap of the various
15087c478bd9Sstevel@tonic-gate * architecture-specific files.  This generates a "Software Trap 0" at TL>0,
15097c478bd9Sstevel@tonic-gate * which goes to fecc_err_tl1_cont_instr, and we continue the handling there.
15107c478bd9Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must
15117c478bd9Sstevel@tonic-gate *     be relocatable.
15127c478bd9Sstevel@tonic-gate */
15137c478bd9Sstevel@tonic-gate
15147c478bd9Sstevel@tonic-gate#if defined(lint)
15157c478bd9Sstevel@tonic-gate
15167c478bd9Sstevel@tonic-gatevoid
15177c478bd9Sstevel@tonic-gatefecc_err_tl1_instr(void)
15187c478bd9Sstevel@tonic-gate{}
15197c478bd9Sstevel@tonic-gate
15207c478bd9Sstevel@tonic-gate#else	/* lint */
15217c478bd9Sstevel@tonic-gate
15227c478bd9Sstevel@tonic-gate	ENTRY_NP(fecc_err_tl1_instr)
15237c478bd9Sstevel@tonic-gate	CH_ERR_TL1_TRAPENTRY(SWTRAP_0);
15247c478bd9Sstevel@tonic-gate	SET_SIZE(fecc_err_tl1_instr)
15257c478bd9Sstevel@tonic-gate
15267c478bd9Sstevel@tonic-gate#endif	/* lint */
15277c478bd9Sstevel@tonic-gate
15287c478bd9Sstevel@tonic-gate/*
15297c478bd9Sstevel@tonic-gate * Software trap 0 at TL>0.
15307c478bd9Sstevel@tonic-gate * tt1_swtrap0 is replaced by fecc_err_tl1_cont_instr in cpu_init_trap of
15317c478bd9Sstevel@tonic-gate * the various architecture-specific files.  This is used as a continuation
15327c478bd9Sstevel@tonic-gate * of the fast ecc handling where we've bought an extra TL level, so we can
15337c478bd9Sstevel@tonic-gate * use %tpc, %tnpc, %tstate to temporarily save the value of registers %g1
15347c478bd9Sstevel@tonic-gate * and %g2.  Note that %tstate has bits 0-2 and then bits 8-19 as r/w,
15357c478bd9Sstevel@tonic-gate * there's a reserved hole from 3-7.  We only use bits 0-1 and 8-9 (the low
15367c478bd9Sstevel@tonic-gate * order two bits from %g1 and %g2 respectively).
15377c478bd9Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must
15387c478bd9Sstevel@tonic-gate *     be relocatable.
15397c478bd9Sstevel@tonic-gate */
15407c478bd9Sstevel@tonic-gate#if defined(lint)
15417c478bd9Sstevel@tonic-gate
15427c478bd9Sstevel@tonic-gatevoid
15437c478bd9Sstevel@tonic-gatefecc_err_tl1_cont_instr(void)
15447c478bd9Sstevel@tonic-gate{}
15457c478bd9Sstevel@tonic-gate
15467c478bd9Sstevel@tonic-gate#else	/* lint */
15477c478bd9Sstevel@tonic-gate
15487c478bd9Sstevel@tonic-gate	ENTRY_NP(fecc_err_tl1_cont_instr)
15497c478bd9Sstevel@tonic-gate	CH_ERR_TL1_SWTRAPENTRY(fast_ecc_tl1_err)
15507c478bd9Sstevel@tonic-gate	SET_SIZE(fecc_err_tl1_cont_instr)
15517c478bd9Sstevel@tonic-gate
15527c478bd9Sstevel@tonic-gate#endif	/* lint */
15537c478bd9Sstevel@tonic-gate
15547c478bd9Sstevel@tonic-gate
15557c478bd9Sstevel@tonic-gate#if defined(lint)
15567c478bd9Sstevel@tonic-gate
15577c478bd9Sstevel@tonic-gatevoid
15587c478bd9Sstevel@tonic-gatece_err(void)
15597c478bd9Sstevel@tonic-gate{}
15607c478bd9Sstevel@tonic-gate
15617c478bd9Sstevel@tonic-gate#else	/* lint */
15627c478bd9Sstevel@tonic-gate
15637c478bd9Sstevel@tonic-gate/*
15647c478bd9Sstevel@tonic-gate * The ce_err function handles disrupting trap type 0x63 at TL=0.
15657c478bd9Sstevel@tonic-gate *
15667c478bd9Sstevel@tonic-gate * AFSR errors bits which cause this trap are:
15677c478bd9Sstevel@tonic-gate *	CE, EMC, EDU:ST, EDC, WDU, WDC, CPU, CPC, IVU, IVC
15687c478bd9Sstevel@tonic-gate *
15697c478bd9Sstevel@tonic-gate * NCEEN Bit of Cheetah External Cache Error Enable Register enables
15707c478bd9Sstevel@tonic-gate * the following AFSR disrupting traps: EDU:ST, WDU, CPU, IVU
15717c478bd9Sstevel@tonic-gate *
15727c478bd9Sstevel@tonic-gate * CEEN Bit of Cheetah External Cache Error Enable Register enables
15737c478bd9Sstevel@tonic-gate * the following AFSR disrupting traps: CE, EMC, EDC, WDC, CPC, IVC
15747c478bd9Sstevel@tonic-gate *
15757c478bd9Sstevel@tonic-gate * Cheetah+ also handles (No additional processing required):
15767c478bd9Sstevel@tonic-gate *    DUE, DTO, DBERR	(NCEEN controlled)
15777c478bd9Sstevel@tonic-gate *    THCE		(CEEN and ET_ECC_en controlled)
15787c478bd9Sstevel@tonic-gate *    TUE		(ET_ECC_en controlled)
15797c478bd9Sstevel@tonic-gate *
15807c478bd9Sstevel@tonic-gate * Panther further adds:
15817c478bd9Sstevel@tonic-gate *    IMU, L3_EDU, L3_WDU, L3_CPU		(NCEEN controlled)
15827c478bd9Sstevel@tonic-gate *    IMC, L3_EDC, L3_WDC, L3_CPC, L3_THCE	(CEEN controlled)
15837c478bd9Sstevel@tonic-gate *    TUE_SH, TUE		(NCEEN and L2_tag_ECC_en controlled)
15847c478bd9Sstevel@tonic-gate *    L3_TUE, L3_TUE_SH		(NCEEN and ET_ECC_en controlled)
15857c478bd9Sstevel@tonic-gate *    THCE			(CEEN and L2_tag_ECC_en controlled)
15867c478bd9Sstevel@tonic-gate *    L3_THCE			(CEEN and ET_ECC_en controlled)
15877c478bd9Sstevel@tonic-gate *
15887c478bd9Sstevel@tonic-gate * Steps:
15897c478bd9Sstevel@tonic-gate *	1. Disable hardware corrected disrupting errors only (CEEN)
15907c478bd9Sstevel@tonic-gate *	2. Park sibling core if caches are shared (to avoid race
15917c478bd9Sstevel@tonic-gate *	   condition while accessing shared resources such as L3
15927c478bd9Sstevel@tonic-gate *	   data staging register during CPU logout.
15937c478bd9Sstevel@tonic-gate *	3. If the CPU logout structure is not currently being used:
15947c478bd9Sstevel@tonic-gate *		4. Clear AFSR error bits
15957c478bd9Sstevel@tonic-gate *		5. Capture Ecache, Dcache and Icache lines associated
15967c478bd9Sstevel@tonic-gate *		   with AFAR.
15977c478bd9Sstevel@tonic-gate *		6. Unpark sibling core if we parked it earlier.
15987c478bd9Sstevel@tonic-gate *		7. call cpu_disrupting_error via sys_trap at PIL 14
15997c478bd9Sstevel@tonic-gate *		   unless we're already running at PIL 15.
16007c478bd9Sstevel@tonic-gate *	4. Otherwise, if the CPU logout structure is busy:
16017c478bd9Sstevel@tonic-gate *		5. Incriment "logout busy count" and place into %g3
16027c478bd9Sstevel@tonic-gate *		6. Unpark sibling core if we parked it earlier.
16037c478bd9Sstevel@tonic-gate *		7. Issue a retry since the other CPU error logging
16047c478bd9Sstevel@tonic-gate *		   code will end up finding this error bit and logging
16057c478bd9Sstevel@tonic-gate *		   information about it later.
16067c478bd9Sstevel@tonic-gate *	5. Alternatively (to 3 and 4 above), if the cpu_private struct is
16077c478bd9Sstevel@tonic-gate *         not yet initialized such that we can't even check the logout
16087c478bd9Sstevel@tonic-gate *         struct, then we place the clo_flags data into %g2
16097c478bd9Sstevel@tonic-gate *         (sys_trap->have_win arg #1) and call cpu_disrupting_error via
16107c478bd9Sstevel@tonic-gate *         systrap. The clo_flags parameter is used to determine information
16117c478bd9Sstevel@tonic-gate *         such as TL, TT, CEEN settings, etc in the high level trap
16127c478bd9Sstevel@tonic-gate *         handler since we don't have access to detailed logout information
16137c478bd9Sstevel@tonic-gate *         in cases where the cpu_private struct is not yet initialized.
16147c478bd9Sstevel@tonic-gate *
16157c478bd9Sstevel@tonic-gate * %g3: [ logout busy count ] - arg #2
16167c478bd9Sstevel@tonic-gate * %g2: [ clo_flags if cpu_private unavailable ] - sys_trap->have_win: arg #1
16177c478bd9Sstevel@tonic-gate */
16187c478bd9Sstevel@tonic-gate
16197c478bd9Sstevel@tonic-gate	.align	128
16207c478bd9Sstevel@tonic-gate	ENTRY_NP(ce_err)
16217c478bd9Sstevel@tonic-gate	membar	#Sync			! Cheetah requires membar #Sync
16227c478bd9Sstevel@tonic-gate
16237c478bd9Sstevel@tonic-gate	/*
16247c478bd9Sstevel@tonic-gate	 * Disable trap on hardware corrected errors (CEEN) while at TL=0
16257c478bd9Sstevel@tonic-gate	 * to prevent recursion.
16267c478bd9Sstevel@tonic-gate	 */
16277c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_ESTATE_ERR, %g1
16287c478bd9Sstevel@tonic-gate	bclr	EN_REG_CEEN, %g1
16297c478bd9Sstevel@tonic-gate	stxa	%g1, [%g0]ASI_ESTATE_ERR
16307c478bd9Sstevel@tonic-gate	membar	#Sync			! membar sync required
16317c478bd9Sstevel@tonic-gate
16327c478bd9Sstevel@tonic-gate	/*
16337c478bd9Sstevel@tonic-gate	 * Save current DCU state.  Turn off Icache to allow capture of
16347c478bd9Sstevel@tonic-gate	 * Icache data by DO_CPU_LOGOUT.
16357c478bd9Sstevel@tonic-gate	 */
16367c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_DCU, %g1	! save DCU in %g1
16377c478bd9Sstevel@tonic-gate	andn	%g1, DCU_IC, %g4
16387c478bd9Sstevel@tonic-gate	stxa	%g4, [%g0]ASI_DCU
16397c478bd9Sstevel@tonic-gate	flush	%g0	/* flush required after changing the IC bit */
16407c478bd9Sstevel@tonic-gate
16417c478bd9Sstevel@tonic-gate	/*
16427c478bd9Sstevel@tonic-gate	 * Check to see whether we need to park our sibling core
16437c478bd9Sstevel@tonic-gate	 * before recording diagnostic information from caches
16447c478bd9Sstevel@tonic-gate	 * which may be shared by both cores.
16457c478bd9Sstevel@tonic-gate	 * We use %g1 to store information about whether or not
16467c478bd9Sstevel@tonic-gate	 * we had to park the core (%g1 holds our DCUCR value and
16477c478bd9Sstevel@tonic-gate	 * we only use bits from that register which are "reserved"
16487c478bd9Sstevel@tonic-gate	 * to keep track of core parking) so that we know whether
16497c478bd9Sstevel@tonic-gate	 * or not to unpark later. %g5 and %g4 are scratch registers.
16507c478bd9Sstevel@tonic-gate	 */
16517c478bd9Sstevel@tonic-gate	PARK_SIBLING_CORE(%g1, %g5, %g4)
16527c478bd9Sstevel@tonic-gate
16537c478bd9Sstevel@tonic-gate	/*
16547c478bd9Sstevel@tonic-gate	 * Do the CPU log out capture.
16557c478bd9Sstevel@tonic-gate	 *   %g3 = "failed?" return value.
16567c478bd9Sstevel@tonic-gate	 *   %g2 = Input = AFAR. Output the clo_flags info which is passed
16577c478bd9Sstevel@tonic-gate	 *         into this macro via %g4. Output only valid if cpu_private
16587c478bd9Sstevel@tonic-gate	 *         struct has not been initialized.
16597c478bd9Sstevel@tonic-gate	 *   CHPR_CECC_LOGOUT = cpu logout structure offset input
16607c478bd9Sstevel@tonic-gate	 *   %g4 = Trap information stored in the cpu logout flags field
16617c478bd9Sstevel@tonic-gate	 *   %g5 = scr1
16627c478bd9Sstevel@tonic-gate	 *   %g6 = scr2
16637c478bd9Sstevel@tonic-gate	 *   %g3 = scr3
16647c478bd9Sstevel@tonic-gate	 *   %g4 = scr4
16657c478bd9Sstevel@tonic-gate	 */
16667c478bd9Sstevel@tonic-gate	clr	%g4			! TL=0 bit in afsr
16677c478bd9Sstevel@tonic-gate	set	CHPR_CECC_LOGOUT, %g6
16687c478bd9Sstevel@tonic-gate	DO_CPU_LOGOUT(%g3, %g2, %g6, %g4, %g5, %g6, %g3, %g4)
16697c478bd9Sstevel@tonic-gate
16707c478bd9Sstevel@tonic-gate	/*
16717c478bd9Sstevel@tonic-gate	 * Flush the Icache.  Since we turned off the Icache to capture the
16727c478bd9Sstevel@tonic-gate	 * Icache line it is now stale or corrupted and we must flush it
16737c478bd9Sstevel@tonic-gate	 * before re-enabling it.
16747c478bd9Sstevel@tonic-gate	 */
16757c478bd9Sstevel@tonic-gate	GET_CPU_PRIVATE_PTR(%g0, %g5, %g7, ce_err_1);
16767c478bd9Sstevel@tonic-gate	ld	[%g5 + CHPR_ICACHE_LINESIZE], %g6
16777c478bd9Sstevel@tonic-gate	ba,pt	%icc, 2f
16787c478bd9Sstevel@tonic-gate	  ld	[%g5 + CHPR_ICACHE_SIZE], %g5
16797c478bd9Sstevel@tonic-gatece_err_1:
16807c478bd9Sstevel@tonic-gate	ASM_LD(%g5, icache_size)
16817c478bd9Sstevel@tonic-gate	ASM_LD(%g6, icache_linesize)
16827c478bd9Sstevel@tonic-gate2:
16837c478bd9Sstevel@tonic-gate	CH_ICACHE_FLUSHALL(%g5, %g6, %g7, %g4)
16847c478bd9Sstevel@tonic-gate
16857c478bd9Sstevel@tonic-gate	/*
16867c478bd9Sstevel@tonic-gate	 * check to see whether we parked our sibling core at the start
16877c478bd9Sstevel@tonic-gate	 * of this handler. If so, we need to unpark it here.
16887c478bd9Sstevel@tonic-gate	 * We use DCUCR reserved bits (stored in %g1) to keep track of
16897c478bd9Sstevel@tonic-gate	 * whether or not we need to unpark. %g5 and %g4 are scratch registers.
16907c478bd9Sstevel@tonic-gate	 */
16917c478bd9Sstevel@tonic-gate	UNPARK_SIBLING_CORE(%g1, %g5, %g4)
16927c478bd9Sstevel@tonic-gate
16937c478bd9Sstevel@tonic-gate	/*
16947c478bd9Sstevel@tonic-gate	 * Restore Icache to previous state.
16957c478bd9Sstevel@tonic-gate	 */
16967c478bd9Sstevel@tonic-gate	stxa	%g1, [%g0]ASI_DCU
16977c478bd9Sstevel@tonic-gate	flush	%g0	/* flush required after changing the IC bit */
16987c478bd9Sstevel@tonic-gate
16997c478bd9Sstevel@tonic-gate	/*
17007c478bd9Sstevel@tonic-gate	 * Make sure our CPU logout operation was successful.
17017c478bd9Sstevel@tonic-gate	 */
17027c478bd9Sstevel@tonic-gate	cmp	%g3, %g0
17037c478bd9Sstevel@tonic-gate	be	4f
17047c478bd9Sstevel@tonic-gate	  nop
17057c478bd9Sstevel@tonic-gate
17067c478bd9Sstevel@tonic-gate	/*
17077c478bd9Sstevel@tonic-gate	 * If the logout structure had been busy, how many times have
17087c478bd9Sstevel@tonic-gate	 * we tried to use it and failed (nesting count)? If we have
17097c478bd9Sstevel@tonic-gate	 * already recursed a substantial number of times, then we can
17107c478bd9Sstevel@tonic-gate	 * assume things are not going to get better by themselves and
17117c478bd9Sstevel@tonic-gate	 * so it would be best to panic.
17127c478bd9Sstevel@tonic-gate	 */
17137c478bd9Sstevel@tonic-gate	cmp	%g3, CLO_NESTING_MAX
17147c478bd9Sstevel@tonic-gate	blt	3f
17157c478bd9Sstevel@tonic-gate	  nop
17167c478bd9Sstevel@tonic-gate
17177c478bd9Sstevel@tonic-gate        call ptl1_panic
17187c478bd9Sstevel@tonic-gate          mov   PTL1_BAD_ECC, %g1
17197c478bd9Sstevel@tonic-gate
17207c478bd9Sstevel@tonic-gate3:
17217c478bd9Sstevel@tonic-gate	/*
17227c478bd9Sstevel@tonic-gate	 * Otherwise, if the logout structure was busy but we have not
17237c478bd9Sstevel@tonic-gate	 * nested more times than our maximum value, then we simply
17247c478bd9Sstevel@tonic-gate	 * issue a retry. Our TL=0 trap handler code will check and
17257c478bd9Sstevel@tonic-gate	 * clear the AFSR after it is done logging what is currently
17267c478bd9Sstevel@tonic-gate	 * in the logout struct and handle this event at that time.
17277c478bd9Sstevel@tonic-gate	 */
17287c478bd9Sstevel@tonic-gate	retry
17297c478bd9Sstevel@tonic-gate4:
17307c478bd9Sstevel@tonic-gate	/*
17317c478bd9Sstevel@tonic-gate	 * Call cpu_disrupting_error via systrap at PIL 14 unless we're
17327c478bd9Sstevel@tonic-gate	 * already at PIL 15.
17337c478bd9Sstevel@tonic-gate	 */
17347c478bd9Sstevel@tonic-gate	set	cpu_disrupting_error, %g1
17357c478bd9Sstevel@tonic-gate	rdpr	%pil, %g4
17367c478bd9Sstevel@tonic-gate	cmp	%g4, PIL_14
17377c478bd9Sstevel@tonic-gate	ba	sys_trap
17387c478bd9Sstevel@tonic-gate	  movl	%icc, PIL_14, %g4
17397c478bd9Sstevel@tonic-gate	SET_SIZE(ce_err)
17407c478bd9Sstevel@tonic-gate
17417c478bd9Sstevel@tonic-gate#endif	/* lint */
17427c478bd9Sstevel@tonic-gate
17437c478bd9Sstevel@tonic-gate
17447c478bd9Sstevel@tonic-gate#if defined(lint)
17457c478bd9Sstevel@tonic-gate
17467c478bd9Sstevel@tonic-gate/*
17477c478bd9Sstevel@tonic-gate * This trap cannot happen at TL>0 which means this routine will never
17487c478bd9Sstevel@tonic-gate * actually be called and so we treat this like a BAD TRAP panic.
17497c478bd9Sstevel@tonic-gate */
17507c478bd9Sstevel@tonic-gatevoid
17517c478bd9Sstevel@tonic-gatece_err_tl1(void)
17527c478bd9Sstevel@tonic-gate{}
17537c478bd9Sstevel@tonic-gate
17547c478bd9Sstevel@tonic-gate#else	/* lint */
17557c478bd9Sstevel@tonic-gate
17567c478bd9Sstevel@tonic-gate	.align	64
17577c478bd9Sstevel@tonic-gate	ENTRY_NP(ce_err_tl1)
17587c478bd9Sstevel@tonic-gate
17597c478bd9Sstevel@tonic-gate        call ptl1_panic
17607c478bd9Sstevel@tonic-gate          mov   PTL1_BAD_TRAP, %g1
17617c478bd9Sstevel@tonic-gate
17627c478bd9Sstevel@tonic-gate	SET_SIZE(ce_err_tl1)
17637c478bd9Sstevel@tonic-gate
17647c478bd9Sstevel@tonic-gate#endif	/* lint */
17657c478bd9Sstevel@tonic-gate
17667c478bd9Sstevel@tonic-gate
17677c478bd9Sstevel@tonic-gate#if defined(lint)
17687c478bd9Sstevel@tonic-gate
17697c478bd9Sstevel@tonic-gatevoid
17707c478bd9Sstevel@tonic-gateasync_err(void)
17717c478bd9Sstevel@tonic-gate{}
17727c478bd9Sstevel@tonic-gate
17737c478bd9Sstevel@tonic-gate#else	/* lint */
17747c478bd9Sstevel@tonic-gate
17757c478bd9Sstevel@tonic-gate/*
17767c478bd9Sstevel@tonic-gate * The async_err function handles deferred trap types 0xA
17777c478bd9Sstevel@tonic-gate * (instruction_access_error) and 0x32 (data_access_error) at TL>=0.
17787c478bd9Sstevel@tonic-gate *
17797c478bd9Sstevel@tonic-gate * AFSR errors bits which cause this trap are:
17807c478bd9Sstevel@tonic-gate *	UE, EMU, EDU:BLD, L3_EDU:BLD, TO, BERR
17817c478bd9Sstevel@tonic-gate * On some platforms, EMU may causes cheetah to pull the error pin
17827c478bd9Sstevel@tonic-gate * never giving Solaris a chance to take a trap.
17837c478bd9Sstevel@tonic-gate *
17847c478bd9Sstevel@tonic-gate * NCEEN Bit of Cheetah External Cache Error Enable Register enables
17857c478bd9Sstevel@tonic-gate * the following AFSR deferred traps: UE, EMU, EDU:BLD, TO, BERR
17867c478bd9Sstevel@tonic-gate *
17877c478bd9Sstevel@tonic-gate * Steps:
17887c478bd9Sstevel@tonic-gate *	1. Disable CEEN and NCEEN errors to prevent recursive errors.
17897c478bd9Sstevel@tonic-gate *	2. Turn D$ off per Cheetah PRM P.5 Note 6, turn I$ off to capture
17907c478bd9Sstevel@tonic-gate *         I$ line in DO_CPU_LOGOUT.
17917c478bd9Sstevel@tonic-gate *	3. Park sibling core if caches are shared (to avoid race
17927c478bd9Sstevel@tonic-gate *	   condition while accessing shared resources such as L3
17937c478bd9Sstevel@tonic-gate *	   data staging register during CPU logout.
17947c478bd9Sstevel@tonic-gate *	4. If the CPU logout structure is not currently being used:
17957c478bd9Sstevel@tonic-gate *		5. Clear AFSR error bits
17967c478bd9Sstevel@tonic-gate *		6. Capture Ecache, Dcache and Icache lines associated
17977c478bd9Sstevel@tonic-gate *		   with AFAR.
17987c478bd9Sstevel@tonic-gate *		7. Unpark sibling core if we parked it earlier.
17997c478bd9Sstevel@tonic-gate *		8. call cpu_deferred_error via sys_trap.
18007c478bd9Sstevel@tonic-gate *	5. Otherwise, if the CPU logout structure is busy:
18017c478bd9Sstevel@tonic-gate *		6. Incriment "logout busy count"
18027c478bd9Sstevel@tonic-gate *		7. Unpark sibling core if we parked it earlier.
18037c478bd9Sstevel@tonic-gate *		8) Issue a retry since the other CPU error logging
18047c478bd9Sstevel@tonic-gate *		   code will end up finding this error bit and logging
18057c478bd9Sstevel@tonic-gate *		   information about it later.
18067c478bd9Sstevel@tonic-gate *      6. Alternatively (to 4 and 5 above), if the cpu_private struct is
18077c478bd9Sstevel@tonic-gate *         not yet initialized such that we can't even check the logout
18087c478bd9Sstevel@tonic-gate *         struct, then we place the clo_flags data into %g2
18097c478bd9Sstevel@tonic-gate *         (sys_trap->have_win arg #1) and call cpu_deferred_error via
18107c478bd9Sstevel@tonic-gate *         systrap. The clo_flags parameter is used to determine information
18117c478bd9Sstevel@tonic-gate *         such as TL, TT, CEEN settings, etc in the high level trap handler
18127c478bd9Sstevel@tonic-gate *         since we don't have access to detailed logout information in cases
18137c478bd9Sstevel@tonic-gate *         where the cpu_private struct is not yet initialized.
18147c478bd9Sstevel@tonic-gate *
18157c478bd9Sstevel@tonic-gate * %g2: [ clo_flags if cpu_private unavailable ] - sys_trap->have_win: arg #1
18167c478bd9Sstevel@tonic-gate * %g3: [ logout busy count ] - arg #2
18177c478bd9Sstevel@tonic-gate */
18187c478bd9Sstevel@tonic-gate
18197c478bd9Sstevel@tonic-gate	ENTRY_NP(async_err)
18207c478bd9Sstevel@tonic-gate	membar	#Sync			! Cheetah requires membar #Sync
18217c478bd9Sstevel@tonic-gate
18227c478bd9Sstevel@tonic-gate	/*
18237c478bd9Sstevel@tonic-gate	 * Disable CEEN and NCEEN.
18247c478bd9Sstevel@tonic-gate	 */
18257c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_ESTATE_ERR, %g3
18267c478bd9Sstevel@tonic-gate	andn	%g3, EN_REG_NCEEN + EN_REG_CEEN, %g4
18277c478bd9Sstevel@tonic-gate	stxa	%g4, [%g0]ASI_ESTATE_ERR
18287c478bd9Sstevel@tonic-gate	membar	#Sync			! membar sync required
18297c478bd9Sstevel@tonic-gate
18307c478bd9Sstevel@tonic-gate	/*
18317c478bd9Sstevel@tonic-gate	 * Save current DCU state.
18327c478bd9Sstevel@tonic-gate	 * Disable Icache to allow capture of Icache data by DO_CPU_LOGOUT.
18337c478bd9Sstevel@tonic-gate	 * Do this regardless of whether this is a Data Access Error or
18347c478bd9Sstevel@tonic-gate	 * Instruction Access Error Trap.
18357c478bd9Sstevel@tonic-gate	 * Disable Dcache for both Data Access Error and Instruction Access
18367c478bd9Sstevel@tonic-gate	 * Error per Cheetah PRM P.5 Note 6.
18377c478bd9Sstevel@tonic-gate	 */
18387c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_DCU, %g1	! save DCU in %g1
18397c478bd9Sstevel@tonic-gate	andn	%g1, DCU_IC + DCU_DC, %g4
18407c478bd9Sstevel@tonic-gate	stxa	%g4, [%g0]ASI_DCU
18417c478bd9Sstevel@tonic-gate	flush	%g0	/* flush required after changing the IC bit */
18427c478bd9Sstevel@tonic-gate
18437c478bd9Sstevel@tonic-gate	/*
18447c478bd9Sstevel@tonic-gate	 * Check to see whether we need to park our sibling core
18457c478bd9Sstevel@tonic-gate	 * before recording diagnostic information from caches
18467c478bd9Sstevel@tonic-gate	 * which may be shared by both cores.
18477c478bd9Sstevel@tonic-gate	 * We use %g1 to store information about whether or not
18487c478bd9Sstevel@tonic-gate	 * we had to park the core (%g1 holds our DCUCR value and
18497c478bd9Sstevel@tonic-gate	 * we only use bits from that register which are "reserved"
18507c478bd9Sstevel@tonic-gate	 * to keep track of core parking) so that we know whether
18517c478bd9Sstevel@tonic-gate	 * or not to unpark later. %g6 and %g4 are scratch registers.
18527c478bd9Sstevel@tonic-gate	 */
18537c478bd9Sstevel@tonic-gate	PARK_SIBLING_CORE(%g1, %g6, %g4)
18547c478bd9Sstevel@tonic-gate
18557c478bd9Sstevel@tonic-gate	/*
18567c478bd9Sstevel@tonic-gate	 * Do the CPU logout capture.
18577c478bd9Sstevel@tonic-gate	 *
18587c478bd9Sstevel@tonic-gate	 *   %g3 = "failed?" return value.
18597c478bd9Sstevel@tonic-gate	 *   %g2 = Input = AFAR. Output the clo_flags info which is passed
18607c478bd9Sstevel@tonic-gate	 *         into this macro via %g4. Output only valid if cpu_private
18617c478bd9Sstevel@tonic-gate	 *         struct has not been initialized.
18627c478bd9Sstevel@tonic-gate	 *   CHPR_ASYNC_LOGOUT = cpu logout structure offset input
18637c478bd9Sstevel@tonic-gate	 *   %g4 = Trap information stored in the cpu logout flags field
18647c478bd9Sstevel@tonic-gate	 *   %g5 = scr1
18657c478bd9Sstevel@tonic-gate	 *   %g6 = scr2
18667c478bd9Sstevel@tonic-gate	 *   %g3 = scr3
18677c478bd9Sstevel@tonic-gate	 *   %g4 = scr4
18687c478bd9Sstevel@tonic-gate	 */
18697c478bd9Sstevel@tonic-gate	andcc	%g5, T_TL1, %g0
18707c478bd9Sstevel@tonic-gate	clr	%g6
18717c478bd9Sstevel@tonic-gate	movnz	%xcc, 1, %g6			! set %g6 if T_TL1 set
18727c478bd9Sstevel@tonic-gate	sllx	%g6, CLO_FLAGS_TL_SHIFT, %g6
18737c478bd9Sstevel@tonic-gate	sllx	%g5, CLO_FLAGS_TT_SHIFT, %g4
18747c478bd9Sstevel@tonic-gate	set	CLO_FLAGS_TT_MASK, %g2
18757c478bd9Sstevel@tonic-gate	and	%g4, %g2, %g4			! ttype
18767c478bd9Sstevel@tonic-gate	or	%g6, %g4, %g4			! TT and TL
18777c478bd9Sstevel@tonic-gate	and	%g3, EN_REG_CEEN, %g3		! CEEN value
18787c478bd9Sstevel@tonic-gate	or	%g3, %g4, %g4			! TT and TL and CEEN
18797c478bd9Sstevel@tonic-gate	set	CHPR_ASYNC_LOGOUT, %g6
18807c478bd9Sstevel@tonic-gate	DO_CPU_LOGOUT(%g3, %g2, %g6, %g4, %g5, %g6, %g3, %g4)
18817c478bd9Sstevel@tonic-gate
18827c478bd9Sstevel@tonic-gate	/*
18837c478bd9Sstevel@tonic-gate	 * If the logout struct was busy, we may need to pass the
18847c478bd9Sstevel@tonic-gate	 * TT, TL, and CEEN information to the TL=0 handler via
18857c478bd9Sstevel@tonic-gate	 * systrap parameter so save it off here.
18867c478bd9Sstevel@tonic-gate	 */
18877c478bd9Sstevel@tonic-gate	cmp	%g3, %g0
18887c478bd9Sstevel@tonic-gate	be	1f
18897c478bd9Sstevel@tonic-gate	  nop
18907c478bd9Sstevel@tonic-gate	sllx	%g4, 32, %g4
18917c478bd9Sstevel@tonic-gate	or	%g4, %g3, %g3
18927c478bd9Sstevel@tonic-gate1:
18937c478bd9Sstevel@tonic-gate	/*
18947c478bd9Sstevel@tonic-gate	 * Flush the Icache.  Since we turned off the Icache to capture the
18957c478bd9Sstevel@tonic-gate	 * Icache line it is now stale or corrupted and we must flush it
18967c478bd9Sstevel@tonic-gate	 * before re-enabling it.
18977c478bd9Sstevel@tonic-gate	 */
18987c478bd9Sstevel@tonic-gate	GET_CPU_PRIVATE_PTR(%g0, %g5, %g7, async_err_1);
18997c478bd9Sstevel@tonic-gate	ld	[%g5 + CHPR_ICACHE_LINESIZE], %g6
19007c478bd9Sstevel@tonic-gate	ba,pt	%icc, 2f
19017c478bd9Sstevel@tonic-gate	  ld	[%g5 + CHPR_ICACHE_SIZE], %g5
19027c478bd9Sstevel@tonic-gateasync_err_1:
19037c478bd9Sstevel@tonic-gate	ASM_LD(%g5, icache_size)
19047c478bd9Sstevel@tonic-gate	ASM_LD(%g6, icache_linesize)
19057c478bd9Sstevel@tonic-gate2:
19067c478bd9Sstevel@tonic-gate	CH_ICACHE_FLUSHALL(%g5, %g6, %g7, %g4)
19077c478bd9Sstevel@tonic-gate
19087c478bd9Sstevel@tonic-gate	/*
19097c478bd9Sstevel@tonic-gate	 * XXX - Don't we need to flush the Dcache before turning it back
19107c478bd9Sstevel@tonic-gate	 *       on to avoid stale or corrupt data? Was this broken?
19117c478bd9Sstevel@tonic-gate	 */
19127c478bd9Sstevel@tonic-gate	/*
19137c478bd9Sstevel@tonic-gate	 * Flush the Dcache before turning it back on since it may now
19147c478bd9Sstevel@tonic-gate	 * contain stale or corrupt data.
19157c478bd9Sstevel@tonic-gate	 */
19167c478bd9Sstevel@tonic-gate	ASM_LD(%g5, dcache_size)
19177c478bd9Sstevel@tonic-gate	ASM_LD(%g6, dcache_linesize)
19187c478bd9Sstevel@tonic-gate	CH_DCACHE_FLUSHALL(%g5, %g6, %g7)
19197c478bd9Sstevel@tonic-gate
19207c478bd9Sstevel@tonic-gate	/*
19217c478bd9Sstevel@tonic-gate	 * check to see whether we parked our sibling core at the start
19227c478bd9Sstevel@tonic-gate	 * of this handler. If so, we need to unpark it here.
19237c478bd9Sstevel@tonic-gate	 * We use DCUCR reserved bits (stored in %g1) to keep track of
19247c478bd9Sstevel@tonic-gate	 * whether or not we need to unpark. %g5 and %g7 are scratch registers.
19257c478bd9Sstevel@tonic-gate	 */
19267c478bd9Sstevel@tonic-gate	UNPARK_SIBLING_CORE(%g1, %g5, %g7)
19277c478bd9Sstevel@tonic-gate
19287c478bd9Sstevel@tonic-gate	/*
19297c478bd9Sstevel@tonic-gate	 * Restore Icache and Dcache to previous state.
19307c478bd9Sstevel@tonic-gate	 */
19317c478bd9Sstevel@tonic-gate	stxa	%g1, [%g0]ASI_DCU
19327c478bd9Sstevel@tonic-gate	flush	%g0	/* flush required after changing the IC bit */
19337c478bd9Sstevel@tonic-gate
19347c478bd9Sstevel@tonic-gate	/*
19357c478bd9Sstevel@tonic-gate	 * Make sure our CPU logout operation was successful.
19367c478bd9Sstevel@tonic-gate	 */
19377c478bd9Sstevel@tonic-gate	cmp	%g3, %g0
19387c478bd9Sstevel@tonic-gate	be	4f
19397c478bd9Sstevel@tonic-gate	  nop
19407c478bd9Sstevel@tonic-gate
19417c478bd9Sstevel@tonic-gate	/*
19427c478bd9Sstevel@tonic-gate	 * If the logout structure had been busy, how many times have
19437c478bd9Sstevel@tonic-gate	 * we tried to use it and failed (nesting count)? If we have
19447c478bd9Sstevel@tonic-gate	 * already recursed a substantial number of times, then we can
19457c478bd9Sstevel@tonic-gate	 * assume things are not going to get better by themselves and
19467c478bd9Sstevel@tonic-gate	 * so it would be best to panic.
19477c478bd9Sstevel@tonic-gate	 */
19487c478bd9Sstevel@tonic-gate	cmp	%g3, CLO_NESTING_MAX
19497c478bd9Sstevel@tonic-gate	blt	3f
19507c478bd9Sstevel@tonic-gate	  nop
19517c478bd9Sstevel@tonic-gate
19527c478bd9Sstevel@tonic-gate        call ptl1_panic
19537c478bd9Sstevel@tonic-gate          mov   PTL1_BAD_ECC, %g1
19547c478bd9Sstevel@tonic-gate
19557c478bd9Sstevel@tonic-gate3:
19567c478bd9Sstevel@tonic-gate	/*
19577c478bd9Sstevel@tonic-gate	 * Otherwise, if the logout structure was busy but we have not
19587c478bd9Sstevel@tonic-gate	 * nested more times than our maximum value, then we simply
19597c478bd9Sstevel@tonic-gate	 * issue a retry. Our TL=0 trap handler code will check and
19607c478bd9Sstevel@tonic-gate	 * clear the AFSR after it is done logging what is currently
19617c478bd9Sstevel@tonic-gate	 * in the logout struct and handle this event at that time.
19627c478bd9Sstevel@tonic-gate	 */
19637c478bd9Sstevel@tonic-gate	retry
19647c478bd9Sstevel@tonic-gate4:
19652dd3029aSjimand	RESET_USER_RTT_REGS(%g4, %g5, async_err_resetskip)
19662dd3029aSjimandasync_err_resetskip:
19677c478bd9Sstevel@tonic-gate	set	cpu_deferred_error, %g1
19687c478bd9Sstevel@tonic-gate	ba	sys_trap
19697c478bd9Sstevel@tonic-gate	  mov	PIL_15, %g4		! run at pil 15
19707c478bd9Sstevel@tonic-gate	SET_SIZE(async_err)
19717c478bd9Sstevel@tonic-gate
19727c478bd9Sstevel@tonic-gate#endif	/* lint */
19737c478bd9Sstevel@tonic-gate
19747c478bd9Sstevel@tonic-gate#if defined(CPU_IMP_L1_CACHE_PARITY)
19757c478bd9Sstevel@tonic-gate
19767c478bd9Sstevel@tonic-gate/*
19777c478bd9Sstevel@tonic-gate * D$ parity error trap (trap 71) at TL=0.
19787c478bd9Sstevel@tonic-gate * tt0_dperr is replaced by dcache_parity_instr in cpu_init_trap of
19797c478bd9Sstevel@tonic-gate * the various architecture-specific files.  This merely sets up the
19807c478bd9Sstevel@tonic-gate * arguments for cpu_parity_error and calls it via sys_trap.
19817c478bd9Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must
19827c478bd9Sstevel@tonic-gate *     be relocatable.
19837c478bd9Sstevel@tonic-gate */
19847c478bd9Sstevel@tonic-gate#if defined(lint)
19857c478bd9Sstevel@tonic-gate
19867c478bd9Sstevel@tonic-gatevoid
19877c478bd9Sstevel@tonic-gatedcache_parity_instr(void)
19887c478bd9Sstevel@tonic-gate{}
19897c478bd9Sstevel@tonic-gate
19907c478bd9Sstevel@tonic-gate#else	/* lint */
19917c478bd9Sstevel@tonic-gate	ENTRY_NP(dcache_parity_instr)
19927c478bd9Sstevel@tonic-gate	membar	#Sync			! Cheetah+ requires membar #Sync
19937c478bd9Sstevel@tonic-gate	set	cpu_parity_error, %g1
19947c478bd9Sstevel@tonic-gate	or	%g0, CH_ERR_DPE, %g2
19957c478bd9Sstevel@tonic-gate	rdpr	%tpc, %g3
19967c478bd9Sstevel@tonic-gate	sethi	%hi(sys_trap), %g7
19977c478bd9Sstevel@tonic-gate	jmp	%g7 + %lo(sys_trap)
19987c478bd9Sstevel@tonic-gate	  mov	PIL_15, %g4		! run at pil 15
19997c478bd9Sstevel@tonic-gate	SET_SIZE(dcache_parity_instr)
20007c478bd9Sstevel@tonic-gate
20017c478bd9Sstevel@tonic-gate#endif	/* lint */
20027c478bd9Sstevel@tonic-gate
20037c478bd9Sstevel@tonic-gate
20047c478bd9Sstevel@tonic-gate/*
20057c478bd9Sstevel@tonic-gate * D$ parity error trap (trap 71) at TL>0.
20067c478bd9Sstevel@tonic-gate * tt1_dperr is replaced by dcache_parity_tl1_instr in cpu_init_trap of
20077c478bd9Sstevel@tonic-gate * the various architecture-specific files.  This generates a "Software
20087c478bd9Sstevel@tonic-gate * Trap 1" at TL>0, which goes to dcache_parity_tl1_cont_instr, and we
20097c478bd9Sstevel@tonic-gate * continue the handling there.
20107c478bd9Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must
20117c478bd9Sstevel@tonic-gate *     be relocatable.
20127c478bd9Sstevel@tonic-gate */
20137c478bd9Sstevel@tonic-gate#if defined(lint)
20147c478bd9Sstevel@tonic-gate
20157c478bd9Sstevel@tonic-gatevoid
20167c478bd9Sstevel@tonic-gatedcache_parity_tl1_instr(void)
20177c478bd9Sstevel@tonic-gate{}
20187c478bd9Sstevel@tonic-gate
20197c478bd9Sstevel@tonic-gate#else	/* lint */
20207c478bd9Sstevel@tonic-gate	ENTRY_NP(dcache_parity_tl1_instr)
20217c478bd9Sstevel@tonic-gate	CH_ERR_TL1_TRAPENTRY(SWTRAP_1);
20227c478bd9Sstevel@tonic-gate	SET_SIZE(dcache_parity_tl1_instr)
20237c478bd9Sstevel@tonic-gate
20247c478bd9Sstevel@tonic-gate#endif	/* lint */
20257c478bd9Sstevel@tonic-gate
20267c478bd9Sstevel@tonic-gate
20277c478bd9Sstevel@tonic-gate/*
20287c478bd9Sstevel@tonic-gate * Software trap 1 at TL>0.
20297c478bd9Sstevel@tonic-gate * tt1_swtrap1 is replaced by dcache_parity_tl1_cont_instr in cpu_init_trap
20307c478bd9Sstevel@tonic-gate * of the various architecture-specific files.  This is used as a continuation
20317c478bd9Sstevel@tonic-gate * of the dcache parity handling where we've bought an extra TL level, so we
20327c478bd9Sstevel@tonic-gate * can use %tpc, %tnpc, %tstate to temporarily save the value of registers %g1
20337c478bd9Sstevel@tonic-gate * and %g2.  Note that %tstate has bits 0-2 and then bits 8-19 as r/w,
20347c478bd9Sstevel@tonic-gate * there's a reserved hole from 3-7.  We only use bits 0-1 and 8-9 (the low
20357c478bd9Sstevel@tonic-gate * order two bits from %g1 and %g2 respectively).
20367c478bd9Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must
20377c478bd9Sstevel@tonic-gate *     be relocatable.
20387c478bd9Sstevel@tonic-gate */
20397c478bd9Sstevel@tonic-gate#if defined(lint)
20407c478bd9Sstevel@tonic-gate
20417c478bd9Sstevel@tonic-gatevoid
20427c478bd9Sstevel@tonic-gatedcache_parity_tl1_cont_instr(void)
20437c478bd9Sstevel@tonic-gate{}
20447c478bd9Sstevel@tonic-gate
20457c478bd9Sstevel@tonic-gate#else	/* lint */
20467c478bd9Sstevel@tonic-gate	ENTRY_NP(dcache_parity_tl1_cont_instr)
20477c478bd9Sstevel@tonic-gate	CH_ERR_TL1_SWTRAPENTRY(dcache_parity_tl1_err);
20487c478bd9Sstevel@tonic-gate	SET_SIZE(dcache_parity_tl1_cont_instr)
20497c478bd9Sstevel@tonic-gate
20507c478bd9Sstevel@tonic-gate#endif	/* lint */
20517c478bd9Sstevel@tonic-gate
20527c478bd9Sstevel@tonic-gate/*
20537c478bd9Sstevel@tonic-gate * D$ parity error at TL>0 handler
20547c478bd9Sstevel@tonic-gate * We get here via trap 71 at TL>0->Software trap 1 at TL>0.  We enter
20557c478bd9Sstevel@tonic-gate * this routine with %g1 and %g2 already saved in %tpc, %tnpc and %tstate.
20567c478bd9Sstevel@tonic-gate */
20577c478bd9Sstevel@tonic-gate#if defined(lint)
20587c478bd9Sstevel@tonic-gate
20597c478bd9Sstevel@tonic-gatevoid
20607c478bd9Sstevel@tonic-gatedcache_parity_tl1_err(void)
20617c478bd9Sstevel@tonic-gate{}
20627c478bd9Sstevel@tonic-gate
20637c478bd9Sstevel@tonic-gate#else	/* lint */
20647c478bd9Sstevel@tonic-gate
20657c478bd9Sstevel@tonic-gate	ENTRY_NP(dcache_parity_tl1_err)
20667c478bd9Sstevel@tonic-gate
20677c478bd9Sstevel@tonic-gate	/*
20687c478bd9Sstevel@tonic-gate	 * This macro saves all the %g registers in the ch_err_tl1_data
20697c478bd9Sstevel@tonic-gate	 * structure, updates the ch_err_tl1_flags and saves the %tpc in
20707c478bd9Sstevel@tonic-gate	 * ch_err_tl1_tpc.  At the end of this macro, %g1 will point to
20717c478bd9Sstevel@tonic-gate	 * the ch_err_tl1_data structure and %g2 will have the original
20727c478bd9Sstevel@tonic-gate	 * flags in the ch_err_tl1_data structure.  All %g registers
20737c478bd9Sstevel@tonic-gate	 * except for %g1 and %g2 will be available.
20747c478bd9Sstevel@tonic-gate	 */
20757c478bd9Sstevel@tonic-gate	CH_ERR_TL1_ENTER(CH_ERR_DPE);
20767c478bd9Sstevel@tonic-gate
20777c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE
20787c478bd9Sstevel@tonic-gate	/*
20797c478bd9Sstevel@tonic-gate	 * Get current trap trace entry physical pointer.
20807c478bd9Sstevel@tonic-gate	 */
20817c478bd9Sstevel@tonic-gate	CPU_INDEX(%g6, %g5)
20827c478bd9Sstevel@tonic-gate	sll	%g6, TRAPTR_SIZE_SHIFT, %g6
20837c478bd9Sstevel@tonic-gate	set	trap_trace_ctl, %g5
20847c478bd9Sstevel@tonic-gate	add	%g6, %g5, %g6
20857c478bd9Sstevel@tonic-gate	ld	[%g6 + TRAPTR_LIMIT], %g5
20867c478bd9Sstevel@tonic-gate	tst	%g5
20877c478bd9Sstevel@tonic-gate	be	%icc, dpe_tl1_skip_tt
20887c478bd9Sstevel@tonic-gate	  nop
20897c478bd9Sstevel@tonic-gate	ldx	[%g6 + TRAPTR_PBASE], %g5
20907c478bd9Sstevel@tonic-gate	ld	[%g6 + TRAPTR_OFFSET], %g4
20917c478bd9Sstevel@tonic-gate	add	%g5, %g4, %g5
20927c478bd9Sstevel@tonic-gate
20937c478bd9Sstevel@tonic-gate	/*
20947c478bd9Sstevel@tonic-gate	 * Create trap trace entry.
20957c478bd9Sstevel@tonic-gate	 */
20967c478bd9Sstevel@tonic-gate	rd	%asi, %g7
20977c478bd9Sstevel@tonic-gate	wr	%g0, TRAPTR_ASI, %asi
20987c478bd9Sstevel@tonic-gate	rd	STICK, %g4
20997c478bd9Sstevel@tonic-gate	stxa	%g4, [%g5 + TRAP_ENT_TICK]%asi
21007c478bd9Sstevel@tonic-gate	rdpr	%tl, %g4
21017c478bd9Sstevel@tonic-gate	stha	%g4, [%g5 + TRAP_ENT_TL]%asi
21027c478bd9Sstevel@tonic-gate	rdpr	%tt, %g4
21037c478bd9Sstevel@tonic-gate	stha	%g4, [%g5 + TRAP_ENT_TT]%asi
21047c478bd9Sstevel@tonic-gate	rdpr	%tpc, %g4
21057c478bd9Sstevel@tonic-gate	stna	%g4, [%g5 + TRAP_ENT_TPC]%asi
21067c478bd9Sstevel@tonic-gate	rdpr	%tstate, %g4
21077c478bd9Sstevel@tonic-gate	stxa	%g4, [%g5 + TRAP_ENT_TSTATE]%asi
21087c478bd9Sstevel@tonic-gate	stna	%sp, [%g5 + TRAP_ENT_SP]%asi
21097c478bd9Sstevel@tonic-gate	stna	%g0, [%g5 + TRAP_ENT_TR]%asi
21107c478bd9Sstevel@tonic-gate	stna	%g0, [%g5 + TRAP_ENT_F1]%asi
21117c478bd9Sstevel@tonic-gate	stna	%g0, [%g5 + TRAP_ENT_F2]%asi
21127c478bd9Sstevel@tonic-gate	stna	%g0, [%g5 + TRAP_ENT_F3]%asi
21137c478bd9Sstevel@tonic-gate	stna	%g0, [%g5 + TRAP_ENT_F4]%asi
21147c478bd9Sstevel@tonic-gate	wr	%g0, %g7, %asi
21157c478bd9Sstevel@tonic-gate
21167c478bd9Sstevel@tonic-gate	/*
21177c478bd9Sstevel@tonic-gate	 * Advance trap trace pointer.
21187c478bd9Sstevel@tonic-gate	 */
21197c478bd9Sstevel@tonic-gate	ld	[%g6 + TRAPTR_OFFSET], %g5
21207c478bd9Sstevel@tonic-gate	ld	[%g6 + TRAPTR_LIMIT], %g4
21217c478bd9Sstevel@tonic-gate	st	%g5, [%g6 + TRAPTR_LAST_OFFSET]
21227c478bd9Sstevel@tonic-gate	add	%g5, TRAP_ENT_SIZE, %g5
21237c478bd9Sstevel@tonic-gate	sub	%g4, TRAP_ENT_SIZE, %g4
21247c478bd9Sstevel@tonic-gate	cmp	%g5, %g4
21257c478bd9Sstevel@tonic-gate	movge	%icc, 0, %g5
21267c478bd9Sstevel@tonic-gate	st	%g5, [%g6 + TRAPTR_OFFSET]
21277c478bd9Sstevel@tonic-gatedpe_tl1_skip_tt:
21287c478bd9Sstevel@tonic-gate#endif	/* TRAPTRACE */
21297c478bd9Sstevel@tonic-gate
21307c478bd9Sstevel@tonic-gate	/*
21317c478bd9Sstevel@tonic-gate	 * I$ and D$ are automatically turned off by HW when the CPU hits
21327c478bd9Sstevel@tonic-gate	 * a dcache or icache parity error so we will just leave those two
21337c478bd9Sstevel@tonic-gate	 * off for now to avoid repeating this trap.
21347c478bd9Sstevel@tonic-gate	 * For Panther, however, since we trap on P$ data parity errors
21357c478bd9Sstevel@tonic-gate	 * and HW does not automatically disable P$, we need to disable it
21367c478bd9Sstevel@tonic-gate	 * here so that we don't encounter any recursive traps when we
21377c478bd9Sstevel@tonic-gate	 * issue the retry.
21387c478bd9Sstevel@tonic-gate	 */
21397c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_DCU, %g3
21407c478bd9Sstevel@tonic-gate	mov	1, %g4
21417c478bd9Sstevel@tonic-gate	sllx	%g4, DCU_PE_SHIFT, %g4
21427c478bd9Sstevel@tonic-gate	andn	%g3, %g4, %g3
21437c478bd9Sstevel@tonic-gate	stxa	%g3, [%g0]ASI_DCU
21447c478bd9Sstevel@tonic-gate	membar	#Sync
21457c478bd9Sstevel@tonic-gate
21467c478bd9Sstevel@tonic-gate	/*
21477c478bd9Sstevel@tonic-gate	 * We fall into this macro if we've successfully logged the error in
21487c478bd9Sstevel@tonic-gate	 * the ch_err_tl1_data structure and want the PIL15 softint to pick
21497c478bd9Sstevel@tonic-gate	 * it up and log it.  %g1 must point to the ch_err_tl1_data structure.
21507c478bd9Sstevel@tonic-gate	 * Restores the %g registers and issues retry.
21517c478bd9Sstevel@tonic-gate	 */
21527c478bd9Sstevel@tonic-gate	CH_ERR_TL1_EXIT;
21537c478bd9Sstevel@tonic-gate	SET_SIZE(dcache_parity_tl1_err)
21547c478bd9Sstevel@tonic-gate
21557c478bd9Sstevel@tonic-gate#endif	/* lint */
21567c478bd9Sstevel@tonic-gate
21577c478bd9Sstevel@tonic-gate/*
21587c478bd9Sstevel@tonic-gate * I$ parity error trap (trap 72) at TL=0.
21597c478bd9Sstevel@tonic-gate * tt0_iperr is replaced by icache_parity_instr in cpu_init_trap of
21607c478bd9Sstevel@tonic-gate * the various architecture-specific files.  This merely sets up the
21617c478bd9Sstevel@tonic-gate * arguments for cpu_parity_error and calls it via sys_trap.
21627c478bd9Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must
21637c478bd9Sstevel@tonic-gate *     be relocatable.
21647c478bd9Sstevel@tonic-gate */
21657c478bd9Sstevel@tonic-gate#if defined(lint)
21667c478bd9Sstevel@tonic-gate
21677c478bd9Sstevel@tonic-gatevoid
21687c478bd9Sstevel@tonic-gateicache_parity_instr(void)
21697c478bd9Sstevel@tonic-gate{}
21707c478bd9Sstevel@tonic-gate
21717c478bd9Sstevel@tonic-gate#else	/* lint */
21727c478bd9Sstevel@tonic-gate
21737c478bd9Sstevel@tonic-gate	ENTRY_NP(icache_parity_instr)
21747c478bd9Sstevel@tonic-gate	membar	#Sync			! Cheetah+ requires membar #Sync
21757c478bd9Sstevel@tonic-gate	set	cpu_parity_error, %g1
21767c478bd9Sstevel@tonic-gate	or	%g0, CH_ERR_IPE, %g2
21777c478bd9Sstevel@tonic-gate	rdpr	%tpc, %g3
21787c478bd9Sstevel@tonic-gate	sethi	%hi(sys_trap), %g7
21797c478bd9Sstevel@tonic-gate	jmp	%g7 + %lo(sys_trap)
21807c478bd9Sstevel@tonic-gate	  mov	PIL_15, %g4		! run at pil 15
21817c478bd9Sstevel@tonic-gate	SET_SIZE(icache_parity_instr)
21827c478bd9Sstevel@tonic-gate
21837c478bd9Sstevel@tonic-gate#endif	/* lint */
21847c478bd9Sstevel@tonic-gate
21857c478bd9Sstevel@tonic-gate/*
21867c478bd9Sstevel@tonic-gate * I$ parity error trap (trap 72) at TL>0.
21877c478bd9Sstevel@tonic-gate * tt1_iperr is replaced by icache_parity_tl1_instr in cpu_init_trap of
21887c478bd9Sstevel@tonic-gate * the various architecture-specific files.  This generates a "Software
21897c478bd9Sstevel@tonic-gate * Trap 2" at TL>0, which goes to icache_parity_tl1_cont_instr, and we
21907c478bd9Sstevel@tonic-gate * continue the handling there.
21917c478bd9Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must
21927c478bd9Sstevel@tonic-gate *     be relocatable.
21937c478bd9Sstevel@tonic-gate */
21947c478bd9Sstevel@tonic-gate#if defined(lint)
21957c478bd9Sstevel@tonic-gate
21967c478bd9Sstevel@tonic-gatevoid
21977c478bd9Sstevel@tonic-gateicache_parity_tl1_instr(void)
21987c478bd9Sstevel@tonic-gate{}
21997c478bd9Sstevel@tonic-gate
22007c478bd9Sstevel@tonic-gate#else	/* lint */
22017c478bd9Sstevel@tonic-gate	ENTRY_NP(icache_parity_tl1_instr)
22027c478bd9Sstevel@tonic-gate	CH_ERR_TL1_TRAPENTRY(SWTRAP_2);
22037c478bd9Sstevel@tonic-gate	SET_SIZE(icache_parity_tl1_instr)
22047c478bd9Sstevel@tonic-gate
22057c478bd9Sstevel@tonic-gate#endif	/* lint */
22067c478bd9Sstevel@tonic-gate
22077c478bd9Sstevel@tonic-gate/*
22087c478bd9Sstevel@tonic-gate * Software trap 2 at TL>0.
22097c478bd9Sstevel@tonic-gate * tt1_swtrap2 is replaced by icache_parity_tl1_cont_instr in cpu_init_trap
22107c478bd9Sstevel@tonic-gate * of the various architecture-specific files.  This is used as a continuation
22117c478bd9Sstevel@tonic-gate * of the icache parity handling where we've bought an extra TL level, so we
22127c478bd9Sstevel@tonic-gate * can use %tpc, %tnpc, %tstate to temporarily save the value of registers %g1
22137c478bd9Sstevel@tonic-gate * and %g2.  Note that %tstate has bits 0-2 and then bits 8-19 as r/w,
22147c478bd9Sstevel@tonic-gate * there's a reserved hole from 3-7.  We only use bits 0-1 and 8-9 (the low
22157c478bd9Sstevel@tonic-gate * order two bits from %g1 and %g2 respectively).
22167c478bd9Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must
22177c478bd9Sstevel@tonic-gate *     be relocatable.
22187c478bd9Sstevel@tonic-gate */
22197c478bd9Sstevel@tonic-gate#if defined(lint)
22207c478bd9Sstevel@tonic-gate
22217c478bd9Sstevel@tonic-gatevoid
22227c478bd9Sstevel@tonic-gateicache_parity_tl1_cont_instr(void)
22237c478bd9Sstevel@tonic-gate{}
22247c478bd9Sstevel@tonic-gate
22257c478bd9Sstevel@tonic-gate#else	/* lint */
22267c478bd9Sstevel@tonic-gate	ENTRY_NP(icache_parity_tl1_cont_instr)
22277c478bd9Sstevel@tonic-gate	CH_ERR_TL1_SWTRAPENTRY(icache_parity_tl1_err);
22287c478bd9Sstevel@tonic-gate	SET_SIZE(icache_parity_tl1_cont_instr)
22297c478bd9Sstevel@tonic-gate
22307c478bd9Sstevel@tonic-gate#endif	/* lint */
22317c478bd9Sstevel@tonic-gate
22327c478bd9Sstevel@tonic-gate
22337c478bd9Sstevel@tonic-gate/*
22347c478bd9Sstevel@tonic-gate * I$ parity error at TL>0 handler
22357c478bd9Sstevel@tonic-gate * We get here via trap 72 at TL>0->Software trap 2 at TL>0.  We enter
22367c478bd9Sstevel@tonic-gate * this routine with %g1 and %g2 already saved in %tpc, %tnpc and %tstate.
22377c478bd9Sstevel@tonic-gate */
22387c478bd9Sstevel@tonic-gate#if defined(lint)
22397c478bd9Sstevel@tonic-gate
22407c478bd9Sstevel@tonic-gatevoid
22417c478bd9Sstevel@tonic-gateicache_parity_tl1_err(void)
22427c478bd9Sstevel@tonic-gate{}
22437c478bd9Sstevel@tonic-gate
22447c478bd9Sstevel@tonic-gate#else	/* lint */
22457c478bd9Sstevel@tonic-gate
22467c478bd9Sstevel@tonic-gate	ENTRY_NP(icache_parity_tl1_err)
22477c478bd9Sstevel@tonic-gate
22487c478bd9Sstevel@tonic-gate	/*
22497c478bd9Sstevel@tonic-gate	 * This macro saves all the %g registers in the ch_err_tl1_data
22507c478bd9Sstevel@tonic-gate	 * structure, updates the ch_err_tl1_flags and saves the %tpc in
22517c478bd9Sstevel@tonic-gate	 * ch_err_tl1_tpc.  At the end of this macro, %g1 will point to
22527c478bd9Sstevel@tonic-gate	 * the ch_err_tl1_data structure and %g2 will have the original
22537c478bd9Sstevel@tonic-gate	 * flags in the ch_err_tl1_data structure.  All %g registers
22547c478bd9Sstevel@tonic-gate	 * except for %g1 and %g2 will be available.
22557c478bd9Sstevel@tonic-gate	 */
22567c478bd9Sstevel@tonic-gate	CH_ERR_TL1_ENTER(CH_ERR_IPE);
22577c478bd9Sstevel@tonic-gate
22587c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE
22597c478bd9Sstevel@tonic-gate	/*
22607c478bd9Sstevel@tonic-gate	 * Get current trap trace entry physical pointer.
22617c478bd9Sstevel@tonic-gate	 */
22627c478bd9Sstevel@tonic-gate	CPU_INDEX(%g6, %g5)
22637c478bd9Sstevel@tonic-gate	sll	%g6, TRAPTR_SIZE_SHIFT, %g6
22647c478bd9Sstevel@tonic-gate	set	trap_trace_ctl, %g5
22657c478bd9Sstevel@tonic-gate	add	%g6, %g5, %g6
22667c478bd9Sstevel@tonic-gate	ld	[%g6 + TRAPTR_LIMIT], %g5
22677c478bd9Sstevel@tonic-gate	tst	%g5
22687c478bd9Sstevel@tonic-gate	be	%icc, ipe_tl1_skip_tt
22697c478bd9Sstevel@tonic-gate	  nop
22707c478bd9Sstevel@tonic-gate	ldx	[%g6 + TRAPTR_PBASE], %g5
22717c478bd9Sstevel@tonic-gate	ld	[%g6 + TRAPTR_OFFSET], %g4
22727c478bd9Sstevel@tonic-gate	add	%g5, %g4, %g5
22737c478bd9Sstevel@tonic-gate
22747c478bd9Sstevel@tonic-gate	/*
22757c478bd9Sstevel@tonic-gate	 * Create trap trace entry.
22767c478bd9Sstevel@tonic-gate	 */
22777c478bd9Sstevel@tonic-gate	rd	%asi, %g7
22787c478bd9Sstevel@tonic-gate	wr	%g0, TRAPTR_ASI, %asi
22797c478bd9Sstevel@tonic-gate	rd	STICK, %g4
22807c478bd9Sstevel@tonic-gate	stxa	%g4, [%g5 + TRAP_ENT_TICK]%asi
22817c478bd9Sstevel@tonic-gate	rdpr	%tl, %g4
22827c478bd9Sstevel@tonic-gate	stha	%g4, [%g5 + TRAP_ENT_TL]%asi
22837c478bd9Sstevel@tonic-gate	rdpr	%tt, %g4
22847c478bd9Sstevel@tonic-gate	stha	%g4, [%g5 + TRAP_ENT_TT]%asi
22857c478bd9Sstevel@tonic-gate	rdpr	%tpc, %g4
22867c478bd9Sstevel@tonic-gate	stna	%g4, [%g5 + TRAP_ENT_TPC]%asi
22877c478bd9Sstevel@tonic-gate	rdpr	%tstate, %g4
22887c478bd9Sstevel@tonic-gate	stxa	%g4, [%g5 + TRAP_ENT_TSTATE]%asi
22897c478bd9Sstevel@tonic-gate	stna	%sp, [%g5 + TRAP_ENT_SP]%asi
22907c478bd9Sstevel@tonic-gate	stna	%g0, [%g5 + TRAP_ENT_TR]%asi
22917c478bd9Sstevel@tonic-gate	stna	%g0, [%g5 + TRAP_ENT_F1]%asi
22927c478bd9Sstevel@tonic-gate	stna	%g0, [%g5 + TRAP_ENT_F2]%asi
22937c478bd9Sstevel@tonic-gate	stna	%g0, [%g5 + TRAP_ENT_F3]%asi
22947c478bd9Sstevel@tonic-gate	stna	%g0, [%g5 + TRAP_ENT_F4]%asi
22957c478bd9Sstevel@tonic-gate	wr	%g0, %g7, %asi
22967c478bd9Sstevel@tonic-gate
22977c478bd9Sstevel@tonic-gate	/*
22987c478bd9Sstevel@tonic-gate	 * Advance trap trace pointer.
22997c478bd9Sstevel@tonic-gate	 */
23007c478bd9Sstevel@tonic-gate	ld	[%g6 + TRAPTR_OFFSET], %g5
23017c478bd9Sstevel@tonic-gate	ld	[%g6 + TRAPTR_LIMIT], %g4
23027c478bd9Sstevel@tonic-gate	st	%g5, [%g6 + TRAPTR_LAST_OFFSET]
23037c478bd9Sstevel@tonic-gate	add	%g5, TRAP_ENT_SIZE, %g5
23047c478bd9Sstevel@tonic-gate	sub	%g4, TRAP_ENT_SIZE, %g4
23057c478bd9Sstevel@tonic-gate	cmp	%g5, %g4
23067c478bd9Sstevel@tonic-gate	movge	%icc, 0, %g5
23077c478bd9Sstevel@tonic-gate	st	%g5, [%g6 + TRAPTR_OFFSET]
23087c478bd9Sstevel@tonic-gateipe_tl1_skip_tt:
23097c478bd9Sstevel@tonic-gate#endif	/* TRAPTRACE */
23107c478bd9Sstevel@tonic-gate
23117c478bd9Sstevel@tonic-gate	/*
23127c478bd9Sstevel@tonic-gate	 * We fall into this macro if we've successfully logged the error in
23137c478bd9Sstevel@tonic-gate	 * the ch_err_tl1_data structure and want the PIL15 softint to pick
23147c478bd9Sstevel@tonic-gate	 * it up and log it.  %g1 must point to the ch_err_tl1_data structure.
23157c478bd9Sstevel@tonic-gate	 * Restores the %g registers and issues retry.
23167c478bd9Sstevel@tonic-gate	 */
23177c478bd9Sstevel@tonic-gate	CH_ERR_TL1_EXIT;
23187c478bd9Sstevel@tonic-gate
23197c478bd9Sstevel@tonic-gate	SET_SIZE(icache_parity_tl1_err)
23207c478bd9Sstevel@tonic-gate
23217c478bd9Sstevel@tonic-gate#endif	/* lint */
23227c478bd9Sstevel@tonic-gate
23237c478bd9Sstevel@tonic-gate#endif	/* CPU_IMP_L1_CACHE_PARITY */
23247c478bd9Sstevel@tonic-gate
23257c478bd9Sstevel@tonic-gate
23267c478bd9Sstevel@tonic-gate/*
23277c478bd9Sstevel@tonic-gate * The itlb_rd_entry and dtlb_rd_entry functions return the tag portion of the
23287c478bd9Sstevel@tonic-gate * tte, the virtual address, and the ctxnum of the specified tlb entry.  They
23297c478bd9Sstevel@tonic-gate * should only be used in places where you have no choice but to look at the
23307c478bd9Sstevel@tonic-gate * tlb itself.
23317c478bd9Sstevel@tonic-gate *
23327c478bd9Sstevel@tonic-gate * Note: These two routines are required by the Estar "cpr" loadable module.
23337c478bd9Sstevel@tonic-gate */
23347c478bd9Sstevel@tonic-gate
23357c478bd9Sstevel@tonic-gate#if defined(lint)
23367c478bd9Sstevel@tonic-gate
23377c478bd9Sstevel@tonic-gate/* ARGSUSED */
23387c478bd9Sstevel@tonic-gatevoid
23397c478bd9Sstevel@tonic-gateitlb_rd_entry(uint_t entry, tte_t *tte, uint64_t *va_tag)
23407c478bd9Sstevel@tonic-gate{}
23417c478bd9Sstevel@tonic-gate
23427c478bd9Sstevel@tonic-gate#else	/* lint */
23437c478bd9Sstevel@tonic-gate
23447c478bd9Sstevel@tonic-gate	ENTRY_NP(itlb_rd_entry)
23457c478bd9Sstevel@tonic-gate	sllx	%o0, 3, %o0
23467c478bd9Sstevel@tonic-gate	ldxa	[%o0]ASI_ITLB_ACCESS, %g1
23477c478bd9Sstevel@tonic-gate	stx	%g1, [%o1]
23487c478bd9Sstevel@tonic-gate	ldxa	[%o0]ASI_ITLB_TAGREAD, %g2
23497c478bd9Sstevel@tonic-gate	set	TAGREAD_CTX_MASK, %o4
23507c478bd9Sstevel@tonic-gate	andn	%g2, %o4, %o5
23517c478bd9Sstevel@tonic-gate	retl
23527c478bd9Sstevel@tonic-gate	  stx	%o5, [%o2]
23537c478bd9Sstevel@tonic-gate	SET_SIZE(itlb_rd_entry)
23547c478bd9Sstevel@tonic-gate
23557c478bd9Sstevel@tonic-gate#endif	/* lint */
23567c478bd9Sstevel@tonic-gate
23577c478bd9Sstevel@tonic-gate
23587c478bd9Sstevel@tonic-gate#if defined(lint)
23597c478bd9Sstevel@tonic-gate
23607c478bd9Sstevel@tonic-gate/* ARGSUSED */
23617c478bd9Sstevel@tonic-gatevoid
23627c478bd9Sstevel@tonic-gatedtlb_rd_entry(uint_t entry, tte_t *tte, uint64_t *va_tag)
23637c478bd9Sstevel@tonic-gate{}
23647c478bd9Sstevel@tonic-gate
23657c478bd9Sstevel@tonic-gate#else	/* lint */
23667c478bd9Sstevel@tonic-gate
23677c478bd9Sstevel@tonic-gate	ENTRY_NP(dtlb_rd_entry)
23687c478bd9Sstevel@tonic-gate	sllx	%o0, 3, %o0
23697c478bd9Sstevel@tonic-gate	ldxa	[%o0]ASI_DTLB_ACCESS, %g1
23707c478bd9Sstevel@tonic-gate	stx	%g1, [%o1]
23717c478bd9Sstevel@tonic-gate	ldxa	[%o0]ASI_DTLB_TAGREAD, %g2
23727c478bd9Sstevel@tonic-gate	set	TAGREAD_CTX_MASK, %o4
23737c478bd9Sstevel@tonic-gate	andn	%g2, %o4, %o5
23747c478bd9Sstevel@tonic-gate	retl
23757c478bd9Sstevel@tonic-gate	  stx	%o5, [%o2]
23767c478bd9Sstevel@tonic-gate	SET_SIZE(dtlb_rd_entry)
23777c478bd9Sstevel@tonic-gate#endif	/* lint */
23787c478bd9Sstevel@tonic-gate
23797c478bd9Sstevel@tonic-gate
23807c478bd9Sstevel@tonic-gate#if !(defined(JALAPENO) || defined(SERRANO))
23817c478bd9Sstevel@tonic-gate
23827c478bd9Sstevel@tonic-gate#if defined(lint)
23837c478bd9Sstevel@tonic-gate
23847c478bd9Sstevel@tonic-gateuint64_t
23857c478bd9Sstevel@tonic-gateget_safari_config(void)
23867c478bd9Sstevel@tonic-gate{ return (0); }
23877c478bd9Sstevel@tonic-gate
23887c478bd9Sstevel@tonic-gate#else	/* lint */
23897c478bd9Sstevel@tonic-gate
23907c478bd9Sstevel@tonic-gate	ENTRY(get_safari_config)
23917c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_SAFARI_CONFIG, %o0
23927c478bd9Sstevel@tonic-gate	retl
23937c478bd9Sstevel@tonic-gate	nop
23947c478bd9Sstevel@tonic-gate	SET_SIZE(get_safari_config)
23957c478bd9Sstevel@tonic-gate
23967c478bd9Sstevel@tonic-gate#endif	/* lint */
23977c478bd9Sstevel@tonic-gate
23987c478bd9Sstevel@tonic-gate
23997c478bd9Sstevel@tonic-gate#if defined(lint)
24007c478bd9Sstevel@tonic-gate
24017c478bd9Sstevel@tonic-gate/* ARGSUSED */
24027c478bd9Sstevel@tonic-gatevoid
24037c478bd9Sstevel@tonic-gateset_safari_config(uint64_t safari_config)
24047c478bd9Sstevel@tonic-gate{}
24057c478bd9Sstevel@tonic-gate
24067c478bd9Sstevel@tonic-gate#else	/* lint */
24077c478bd9Sstevel@tonic-gate
24087c478bd9Sstevel@tonic-gate	ENTRY(set_safari_config)
24097c478bd9Sstevel@tonic-gate	stxa	%o0, [%g0]ASI_SAFARI_CONFIG
24107c478bd9Sstevel@tonic-gate	membar	#Sync
24117c478bd9Sstevel@tonic-gate	retl
24127c478bd9Sstevel@tonic-gate	nop
24137c478bd9Sstevel@tonic-gate	SET_SIZE(set_safari_config)
24147c478bd9Sstevel@tonic-gate
24157c478bd9Sstevel@tonic-gate#endif	/* lint */
24167c478bd9Sstevel@tonic-gate
24177c478bd9Sstevel@tonic-gate#endif	/* !(JALAPENO || SERRANO) */
24187c478bd9Sstevel@tonic-gate
24197c478bd9Sstevel@tonic-gate
24207c478bd9Sstevel@tonic-gate#if defined(lint)
24217c478bd9Sstevel@tonic-gate
24227c478bd9Sstevel@tonic-gatevoid
24237c478bd9Sstevel@tonic-gatecpu_cleartickpnt(void)
24247c478bd9Sstevel@tonic-gate{}
24257c478bd9Sstevel@tonic-gate
24267c478bd9Sstevel@tonic-gate#else	/* lint */
24277c478bd9Sstevel@tonic-gate	/*
24287c478bd9Sstevel@tonic-gate	 * Clear the NPT (non-privileged trap) bit in the %tick/%stick
24297c478bd9Sstevel@tonic-gate	 * registers. In an effort to make the change in the
24307c478bd9Sstevel@tonic-gate	 * tick/stick counter as consistent as possible, we disable
24317c478bd9Sstevel@tonic-gate	 * all interrupts while we're changing the registers. We also
24327c478bd9Sstevel@tonic-gate	 * ensure that the read and write instructions are in the same
24337c478bd9Sstevel@tonic-gate	 * line in the instruction cache.
24347c478bd9Sstevel@tonic-gate	 */
24357c478bd9Sstevel@tonic-gate	ENTRY_NP(cpu_clearticknpt)
24367c478bd9Sstevel@tonic-gate	rdpr	%pstate, %g1		/* save processor state */
24377c478bd9Sstevel@tonic-gate	andn	%g1, PSTATE_IE, %g3	/* turn off */
24387c478bd9Sstevel@tonic-gate	wrpr	%g0, %g3, %pstate	/*   interrupts */
24397c478bd9Sstevel@tonic-gate	rdpr	%tick, %g2		/* get tick register */
24407c478bd9Sstevel@tonic-gate	brgez,pn %g2, 1f		/* if NPT bit off, we're done */
24417c478bd9Sstevel@tonic-gate	mov	1, %g3			/* create mask */
24427c478bd9Sstevel@tonic-gate	sllx	%g3, 63, %g3		/*   for NPT bit */
24437c478bd9Sstevel@tonic-gate	ba,a,pt	%xcc, 2f
24447c478bd9Sstevel@tonic-gate	.align	8			/* Ensure rd/wr in same i$ line */
24457c478bd9Sstevel@tonic-gate2:
24467c478bd9Sstevel@tonic-gate	rdpr	%tick, %g2		/* get tick register */
24477c478bd9Sstevel@tonic-gate	wrpr	%g3, %g2, %tick		/* write tick register, */
24487c478bd9Sstevel@tonic-gate					/*   clearing NPT bit   */
24497c478bd9Sstevel@tonic-gate1:
24507c478bd9Sstevel@tonic-gate	rd	STICK, %g2		/* get stick register */
24517c478bd9Sstevel@tonic-gate	brgez,pn %g2, 3f		/* if NPT bit off, we're done */
24527c478bd9Sstevel@tonic-gate	mov	1, %g3			/* create mask */
24537c478bd9Sstevel@tonic-gate	sllx	%g3, 63, %g3		/*   for NPT bit */
24547c478bd9Sstevel@tonic-gate	ba,a,pt	%xcc, 4f
24557c478bd9Sstevel@tonic-gate	.align	8			/* Ensure rd/wr in same i$ line */
24567c478bd9Sstevel@tonic-gate4:
24577c478bd9Sstevel@tonic-gate	rd	STICK, %g2		/* get stick register */
24587c478bd9Sstevel@tonic-gate	wr	%g3, %g2, STICK		/* write stick register, */
24597c478bd9Sstevel@tonic-gate					/*   clearing NPT bit   */
24607c478bd9Sstevel@tonic-gate3:
24617c478bd9Sstevel@tonic-gate	jmp	%g4 + 4
24627c478bd9Sstevel@tonic-gate	wrpr	%g0, %g1, %pstate	/* restore processor state */
24637c478bd9Sstevel@tonic-gate
24647c478bd9Sstevel@tonic-gate	SET_SIZE(cpu_clearticknpt)
24657c478bd9Sstevel@tonic-gate
24667c478bd9Sstevel@tonic-gate#endif	/* lint */
24677c478bd9Sstevel@tonic-gate
24687c478bd9Sstevel@tonic-gate
24697c478bd9Sstevel@tonic-gate#if defined(CPU_IMP_L1_CACHE_PARITY)
24707c478bd9Sstevel@tonic-gate
24717c478bd9Sstevel@tonic-gate#if defined(lint)
24727c478bd9Sstevel@tonic-gate/*
24737c478bd9Sstevel@tonic-gate * correct_dcache_parity(size_t size, size_t linesize)
24747c478bd9Sstevel@tonic-gate *
24757c478bd9Sstevel@tonic-gate * Correct D$ data parity by zeroing the data and initializing microtag
24767c478bd9Sstevel@tonic-gate * for all indexes and all ways of the D$.
24777c478bd9Sstevel@tonic-gate *
24787c478bd9Sstevel@tonic-gate */
24797c478bd9Sstevel@tonic-gate/* ARGSUSED */
24807c478bd9Sstevel@tonic-gatevoid
24817c478bd9Sstevel@tonic-gatecorrect_dcache_parity(size_t size, size_t linesize)
24827c478bd9Sstevel@tonic-gate{}
24837c478bd9Sstevel@tonic-gate
24847c478bd9Sstevel@tonic-gate#else	/* lint */
24857c478bd9Sstevel@tonic-gate
24867c478bd9Sstevel@tonic-gate	ENTRY(correct_dcache_parity)
24877c478bd9Sstevel@tonic-gate	/*
24887c478bd9Sstevel@tonic-gate	 * Register Usage:
24897c478bd9Sstevel@tonic-gate	 *
24907c478bd9Sstevel@tonic-gate	 * %o0 = input D$ size
24917c478bd9Sstevel@tonic-gate	 * %o1 = input D$ line size
24927c478bd9Sstevel@tonic-gate	 * %o2 = scratch
24937c478bd9Sstevel@tonic-gate	 * %o3 = scratch
24947c478bd9Sstevel@tonic-gate	 * %o4 = scratch
24957c478bd9Sstevel@tonic-gate	 */
24967c478bd9Sstevel@tonic-gate
24977c478bd9Sstevel@tonic-gate	sub	%o0, %o1, %o0			! init cache line address
24987c478bd9Sstevel@tonic-gate
24997c478bd9Sstevel@tonic-gate	/*
25007c478bd9Sstevel@tonic-gate	 * For Panther CPUs, we also need to clear the data parity bits
25017c478bd9Sstevel@tonic-gate	 * using DC_data_parity bit of the ASI_DCACHE_DATA register.
25027c478bd9Sstevel@tonic-gate	 */
25037c478bd9Sstevel@tonic-gate	GET_CPU_IMPL(%o3)
25047c478bd9Sstevel@tonic-gate	cmp	%o3, PANTHER_IMPL
25057c478bd9Sstevel@tonic-gate	bne	1f
25067c478bd9Sstevel@tonic-gate	  clr	%o3				! zero for non-Panther
25077c478bd9Sstevel@tonic-gate	mov	1, %o3
25087c478bd9Sstevel@tonic-gate	sll	%o3, PN_DC_DATA_PARITY_BIT_SHIFT, %o3
25097c478bd9Sstevel@tonic-gate
25107c478bd9Sstevel@tonic-gate1:
25117c478bd9Sstevel@tonic-gate	/*
25127c478bd9Sstevel@tonic-gate	 * Set utag = way since it must be unique within an index.
25137c478bd9Sstevel@tonic-gate	 */
25147c478bd9Sstevel@tonic-gate	srl	%o0, 14, %o2			! get cache way (DC_way)
25157c478bd9Sstevel@tonic-gate	membar	#Sync				! required before ASI_DC_UTAG
25167c478bd9Sstevel@tonic-gate	stxa	%o2, [%o0]ASI_DC_UTAG		! set D$ utag = cache way
25177c478bd9Sstevel@tonic-gate	membar	#Sync				! required after ASI_DC_UTAG
25187c478bd9Sstevel@tonic-gate
25197c478bd9Sstevel@tonic-gate	/*
25207c478bd9Sstevel@tonic-gate	 * Zero line of D$ data (and data parity bits for Panther)
25217c478bd9Sstevel@tonic-gate	 */
25227c478bd9Sstevel@tonic-gate	sub	%o1, 8, %o2
25237c478bd9Sstevel@tonic-gate	or	%o0, %o3, %o4			! same address + DC_data_parity
25247c478bd9Sstevel@tonic-gate2:
25257c478bd9Sstevel@tonic-gate	membar	#Sync				! required before ASI_DC_DATA
25267c478bd9Sstevel@tonic-gate	stxa	%g0, [%o0 + %o2]ASI_DC_DATA	! zero 8 bytes of D$ data
25277c478bd9Sstevel@tonic-gate	membar	#Sync				! required after ASI_DC_DATA
25287c478bd9Sstevel@tonic-gate	/*
25297c478bd9Sstevel@tonic-gate	 * We also clear the parity bits if this is a panther. For non-Panther
25307c478bd9Sstevel@tonic-gate	 * CPUs, we simply end up clearing the $data register twice.
25317c478bd9Sstevel@tonic-gate	 */
25327c478bd9Sstevel@tonic-gate	stxa	%g0, [%o4 + %o2]ASI_DC_DATA
25337c478bd9Sstevel@tonic-gate	membar	#Sync
25347c478bd9Sstevel@tonic-gate
25357c478bd9Sstevel@tonic-gate	subcc	%o2, 8, %o2
25367c478bd9Sstevel@tonic-gate	bge	2b
25377c478bd9Sstevel@tonic-gate	nop
25387c478bd9Sstevel@tonic-gate
25397c478bd9Sstevel@tonic-gate	subcc	%o0, %o1, %o0
25407c478bd9Sstevel@tonic-gate	bge	1b
25417c478bd9Sstevel@tonic-gate	nop
25427c478bd9Sstevel@tonic-gate
25437c478bd9Sstevel@tonic-gate	retl
25447c478bd9Sstevel@tonic-gate	  nop
25457c478bd9Sstevel@tonic-gate	SET_SIZE(correct_dcache_parity)
25467c478bd9Sstevel@tonic-gate
25477c478bd9Sstevel@tonic-gate#endif	/* lint */
25487c478bd9Sstevel@tonic-gate
25497c478bd9Sstevel@tonic-gate#endif	/* CPU_IMP_L1_CACHE_PARITY */
25507c478bd9Sstevel@tonic-gate
25517c478bd9Sstevel@tonic-gate
25527c478bd9Sstevel@tonic-gate#if defined(lint)
25537c478bd9Sstevel@tonic-gate/*
25547c478bd9Sstevel@tonic-gate *  Get timestamp (stick).
25557c478bd9Sstevel@tonic-gate */
25567c478bd9Sstevel@tonic-gate/* ARGSUSED */
25577c478bd9Sstevel@tonic-gatevoid
25587c478bd9Sstevel@tonic-gatestick_timestamp(int64_t *ts)
25597c478bd9Sstevel@tonic-gate{
25607c478bd9Sstevel@tonic-gate}
25617c478bd9Sstevel@tonic-gate
25627c478bd9Sstevel@tonic-gate#else	/* lint */
25637c478bd9Sstevel@tonic-gate
25647c478bd9Sstevel@tonic-gate	ENTRY_NP(stick_timestamp)
25657c478bd9Sstevel@tonic-gate	rd	STICK, %g1	! read stick reg
25667c478bd9Sstevel@tonic-gate	sllx	%g1, 1, %g1
25677c478bd9Sstevel@tonic-gate	srlx	%g1, 1, %g1	! clear npt bit
25687c478bd9Sstevel@tonic-gate
25697c478bd9Sstevel@tonic-gate	retl
25707c478bd9Sstevel@tonic-gate	stx     %g1, [%o0]	! store the timestamp
25717c478bd9Sstevel@tonic-gate	SET_SIZE(stick_timestamp)
25727c478bd9Sstevel@tonic-gate
25737c478bd9Sstevel@tonic-gate#endif	/* lint */
25747c478bd9Sstevel@tonic-gate
25757c478bd9Sstevel@tonic-gate
25767c478bd9Sstevel@tonic-gate#if defined(lint)
25777c478bd9Sstevel@tonic-gate/*
25787c478bd9Sstevel@tonic-gate * Set STICK adjusted by skew.
25797c478bd9Sstevel@tonic-gate */
25807c478bd9Sstevel@tonic-gate/* ARGSUSED */
25817c478bd9Sstevel@tonic-gatevoid
25827c478bd9Sstevel@tonic-gatestick_adj(int64_t skew)
25837c478bd9Sstevel@tonic-gate{
25847c478bd9Sstevel@tonic-gate}
25857c478bd9Sstevel@tonic-gate
25867c478bd9Sstevel@tonic-gate#else	/* lint */
25877c478bd9Sstevel@tonic-gate
25887c478bd9Sstevel@tonic-gate	ENTRY_NP(stick_adj)
25897c478bd9Sstevel@tonic-gate	rdpr	%pstate, %g1		! save processor state
25907c478bd9Sstevel@tonic-gate	andn	%g1, PSTATE_IE, %g3
25917c478bd9Sstevel@tonic-gate	ba	1f			! cache align stick adj
25927c478bd9Sstevel@tonic-gate	wrpr	%g0, %g3, %pstate	! turn off interrupts
25937c478bd9Sstevel@tonic-gate
25947c478bd9Sstevel@tonic-gate	.align	16
25957c478bd9Sstevel@tonic-gate1:	nop
25967c478bd9Sstevel@tonic-gate
25977c478bd9Sstevel@tonic-gate	rd	STICK, %g4		! read stick reg
25987c478bd9Sstevel@tonic-gate	add	%g4, %o0, %o1		! adjust stick with skew
25997c478bd9Sstevel@tonic-gate	wr	%o1, %g0, STICK		! write stick reg
26007c478bd9Sstevel@tonic-gate
26017c478bd9Sstevel@tonic-gate	retl
26027c478bd9Sstevel@tonic-gate	wrpr	%g1, %pstate		! restore processor state
26037c478bd9Sstevel@tonic-gate	SET_SIZE(stick_adj)
26047c478bd9Sstevel@tonic-gate
26057c478bd9Sstevel@tonic-gate#endif	/* lint */
26067c478bd9Sstevel@tonic-gate
26077c478bd9Sstevel@tonic-gate#if defined(lint)
26087c478bd9Sstevel@tonic-gate/*
26097c478bd9Sstevel@tonic-gate * Debugger-specific stick retrieval
26107c478bd9Sstevel@tonic-gate */
26117c478bd9Sstevel@tonic-gate/*ARGSUSED*/
26127c478bd9Sstevel@tonic-gateint
26137c478bd9Sstevel@tonic-gatekdi_get_stick(uint64_t *stickp)
26147c478bd9Sstevel@tonic-gate{
26157c478bd9Sstevel@tonic-gate	return (0);
26167c478bd9Sstevel@tonic-gate}
26177c478bd9Sstevel@tonic-gate
26187c478bd9Sstevel@tonic-gate#else	/* lint */
26197c478bd9Sstevel@tonic-gate
26207c478bd9Sstevel@tonic-gate	ENTRY_NP(kdi_get_stick)
26217c478bd9Sstevel@tonic-gate	rd	STICK, %g1
26227c478bd9Sstevel@tonic-gate	stx	%g1, [%o0]
26237c478bd9Sstevel@tonic-gate	retl
26247c478bd9Sstevel@tonic-gate	mov	%g0, %o0
26257c478bd9Sstevel@tonic-gate	SET_SIZE(kdi_get_stick)
26267c478bd9Sstevel@tonic-gate
26277c478bd9Sstevel@tonic-gate#endif	/* lint */
26287c478bd9Sstevel@tonic-gate
26297c478bd9Sstevel@tonic-gate#if defined(lint)
26307c478bd9Sstevel@tonic-gate/*
26317c478bd9Sstevel@tonic-gate * Invalidate the specified line from the D$.
26327c478bd9Sstevel@tonic-gate *
26337c478bd9Sstevel@tonic-gate * Register usage:
26347c478bd9Sstevel@tonic-gate *	%o0 - index for the invalidation, specifies DC_way and DC_addr
26357c478bd9Sstevel@tonic-gate *
26367c478bd9Sstevel@tonic-gate * ASI_DC_TAG, 0x47, is used in the following manner. A 64-bit value is
26377c478bd9Sstevel@tonic-gate * stored to a particular DC_way and DC_addr in ASI_DC_TAG.
26387c478bd9Sstevel@tonic-gate *
26397c478bd9Sstevel@tonic-gate * The format of the stored 64-bit value is:
26407c478bd9Sstevel@tonic-gate *
26417c478bd9Sstevel@tonic-gate *	+----------+--------+----------+
26427c478bd9Sstevel@tonic-gate *	| Reserved | DC_tag | DC_valid |
26437c478bd9Sstevel@tonic-gate *	+----------+--------+----------+
26447c478bd9Sstevel@tonic-gate *       63      31 30     1	      0
26457c478bd9Sstevel@tonic-gate *
26467c478bd9Sstevel@tonic-gate * DC_tag is the 30-bit physical tag of the associated line.
26477c478bd9Sstevel@tonic-gate * DC_valid is the 1-bit valid field for both the physical and snoop tags.
26487c478bd9Sstevel@tonic-gate *
26497c478bd9Sstevel@tonic-gate * The format of the 64-bit DC_way and DC_addr into ASI_DC_TAG is:
26507c478bd9Sstevel@tonic-gate *
26517c478bd9Sstevel@tonic-gate *	+----------+--------+----------+----------+
26527c478bd9Sstevel@tonic-gate *	| Reserved | DC_way | DC_addr  | Reserved |
26537c478bd9Sstevel@tonic-gate *	+----------+--------+----------+----------+
26547c478bd9Sstevel@tonic-gate *       63      16 15    14 13       5 4        0
26557c478bd9Sstevel@tonic-gate *
26567c478bd9Sstevel@tonic-gate * DC_way is a 2-bit index that selects one of the 4 ways.
26577c478bd9Sstevel@tonic-gate * DC_addr is a 9-bit index that selects one of 512 tag/valid fields.
26587c478bd9Sstevel@tonic-gate *
26597c478bd9Sstevel@tonic-gate * Setting the DC_valid bit to zero for the specified DC_way and
26607c478bd9Sstevel@tonic-gate * DC_addr index into the D$ results in an invalidation of a D$ line.
26617c478bd9Sstevel@tonic-gate */
26627c478bd9Sstevel@tonic-gate/*ARGSUSED*/
26637c478bd9Sstevel@tonic-gatevoid
26647c478bd9Sstevel@tonic-gatedcache_inval_line(int index)
26657c478bd9Sstevel@tonic-gate{
26667c478bd9Sstevel@tonic-gate}
26677c478bd9Sstevel@tonic-gate#else	/* lint */
26687c478bd9Sstevel@tonic-gate	ENTRY(dcache_inval_line)
26697c478bd9Sstevel@tonic-gate	sll	%o0, 5, %o0		! shift index into DC_way and DC_addr
26707c478bd9Sstevel@tonic-gate	stxa	%g0, [%o0]ASI_DC_TAG	! zero the DC_valid and DC_tag bits
26717c478bd9Sstevel@tonic-gate	membar	#Sync
26727c478bd9Sstevel@tonic-gate	retl
26737c478bd9Sstevel@tonic-gate	nop
26747c478bd9Sstevel@tonic-gate	SET_SIZE(dcache_inval_line)
26757c478bd9Sstevel@tonic-gate#endif	/* lint */
26767c478bd9Sstevel@tonic-gate
26777c478bd9Sstevel@tonic-gate#if defined(lint)
26787c478bd9Sstevel@tonic-gate/*
26797c478bd9Sstevel@tonic-gate * Invalidate the entire I$
26807c478bd9Sstevel@tonic-gate *
26817c478bd9Sstevel@tonic-gate * Register usage:
26827c478bd9Sstevel@tonic-gate *	%o0 - specifies IC_way, IC_addr, IC_tag
26837c478bd9Sstevel@tonic-gate *	%o1 - scratch
26847c478bd9Sstevel@tonic-gate *	%o2 - used to save and restore DCU value
26857c478bd9Sstevel@tonic-gate *	%o3 - scratch
26867c478bd9Sstevel@tonic-gate *	%o5 - used to save and restore PSTATE
26877c478bd9Sstevel@tonic-gate *
26887c478bd9Sstevel@tonic-gate * Due to the behavior of the I$ control logic when accessing ASI_IC_TAG,
26897c478bd9Sstevel@tonic-gate * the I$ should be turned off. Accesses to ASI_IC_TAG may collide and
26907c478bd9Sstevel@tonic-gate * block out snoops and invalidates to the I$, causing I$ consistency
26917c478bd9Sstevel@tonic-gate * to be broken. Before turning on the I$, all I$ lines must be invalidated.
26927c478bd9Sstevel@tonic-gate *
26937c478bd9Sstevel@tonic-gate * ASI_IC_TAG, 0x67, is used in the following manner. A 64-bit value is
26947c478bd9Sstevel@tonic-gate * stored to a particular IC_way, IC_addr, IC_tag in ASI_IC_TAG. The
26957c478bd9Sstevel@tonic-gate * info below describes store (write) use of ASI_IC_TAG. Note that read
26967c478bd9Sstevel@tonic-gate * use of ASI_IC_TAG behaves differently.
26977c478bd9Sstevel@tonic-gate *
26987c478bd9Sstevel@tonic-gate * The format of the stored 64-bit value is:
26997c478bd9Sstevel@tonic-gate *
27007c478bd9Sstevel@tonic-gate *	+----------+--------+---------------+-----------+
27017c478bd9Sstevel@tonic-gate *	| Reserved | Valid  | IC_vpred<7:0> | Undefined |
27027c478bd9Sstevel@tonic-gate *	+----------+--------+---------------+-----------+
27037c478bd9Sstevel@tonic-gate *       63      55    54    53           46 45        0
27047c478bd9Sstevel@tonic-gate *
27057c478bd9Sstevel@tonic-gate * Valid is the 1-bit valid field for both the physical and snoop tags.
27067c478bd9Sstevel@tonic-gate * IC_vpred is the 8-bit LPB bits for 8 instructions starting at
27077c478bd9Sstevel@tonic-gate *	the 32-byte boundary aligned address specified by IC_addr.
27087c478bd9Sstevel@tonic-gate *
27097c478bd9Sstevel@tonic-gate * The format of the 64-bit IC_way, IC_addr, IC_tag into ASI_IC_TAG is:
27107c478bd9Sstevel@tonic-gate *
27117c478bd9Sstevel@tonic-gate *	+----------+--------+---------+--------+---------+
27127c478bd9Sstevel@tonic-gate *	| Reserved | IC_way | IC_addr | IC_tag |Reserved |
27137c478bd9Sstevel@tonic-gate *	+----------+--------+---------+--------+---------+
27147c478bd9Sstevel@tonic-gate *       63      16 15    14 13      5 4      3 2       0
27157c478bd9Sstevel@tonic-gate *
27167c478bd9Sstevel@tonic-gate * IC_way is a 2-bit index that selects one of the 4 ways.
27177c478bd9Sstevel@tonic-gate * IC_addr[13:6] is an 8-bit index that selects one of 256 valid fields.
27187c478bd9Sstevel@tonic-gate * IC_addr[5] is a "don't care" for a store.
27197c478bd9Sstevel@tonic-gate * IC_tag set to 2 specifies that the stored value is to be interpreted
27207c478bd9Sstevel@tonic-gate *	as containing Valid and IC_vpred as described above.
27217c478bd9Sstevel@tonic-gate *
27227c478bd9Sstevel@tonic-gate * Setting the Valid bit to zero for the specified IC_way and
27237c478bd9Sstevel@tonic-gate * IC_addr index into the I$ results in an invalidation of an I$ line.
27247c478bd9Sstevel@tonic-gate */
27257c478bd9Sstevel@tonic-gate/*ARGSUSED*/
27267c478bd9Sstevel@tonic-gatevoid
27277c478bd9Sstevel@tonic-gateicache_inval_all(void)
27287c478bd9Sstevel@tonic-gate{
27297c478bd9Sstevel@tonic-gate}
27307c478bd9Sstevel@tonic-gate#else	/* lint */
27317c478bd9Sstevel@tonic-gate	ENTRY(icache_inval_all)
27327c478bd9Sstevel@tonic-gate	rdpr	%pstate, %o5
27337c478bd9Sstevel@tonic-gate	andn	%o5, PSTATE_IE, %o3
27347c478bd9Sstevel@tonic-gate	wrpr	%g0, %o3, %pstate	! clear IE bit
27357c478bd9Sstevel@tonic-gate
27367c478bd9Sstevel@tonic-gate	GET_CPU_PRIVATE_PTR(%g0, %o0, %o2, icache_inval_all_1);
27377c478bd9Sstevel@tonic-gate	ld	[%o0 + CHPR_ICACHE_LINESIZE], %o1
27387c478bd9Sstevel@tonic-gate	ba,pt	%icc, 2f
27397c478bd9Sstevel@tonic-gate	  ld	[%o0 + CHPR_ICACHE_SIZE], %o0
27407c478bd9Sstevel@tonic-gateicache_inval_all_1:
27417c478bd9Sstevel@tonic-gate	ASM_LD(%o0, icache_size)
27427c478bd9Sstevel@tonic-gate	ASM_LD(%o1, icache_linesize)
27437c478bd9Sstevel@tonic-gate2:
27447c478bd9Sstevel@tonic-gate	CH_ICACHE_FLUSHALL(%o0, %o1, %o2, %o4)
27457c478bd9Sstevel@tonic-gate
27467c478bd9Sstevel@tonic-gate	retl
27477c478bd9Sstevel@tonic-gate	wrpr	%g0, %o5, %pstate	! restore earlier pstate
27487c478bd9Sstevel@tonic-gate	SET_SIZE(icache_inval_all)
27497c478bd9Sstevel@tonic-gate#endif	/* lint */
27507c478bd9Sstevel@tonic-gate
27517c478bd9Sstevel@tonic-gate
27527c478bd9Sstevel@tonic-gate#if defined(lint)
27537c478bd9Sstevel@tonic-gate/* ARGSUSED */
27547c478bd9Sstevel@tonic-gatevoid
27557c478bd9Sstevel@tonic-gatecache_scrubreq_tl1(uint64_t inum, uint64_t index)
27567c478bd9Sstevel@tonic-gate{
27577c478bd9Sstevel@tonic-gate}
27587c478bd9Sstevel@tonic-gate
27597c478bd9Sstevel@tonic-gate#else	/* lint */
27607c478bd9Sstevel@tonic-gate/*
27617c478bd9Sstevel@tonic-gate * cache_scrubreq_tl1 is the crosstrap handler called on offlined cpus via a
27627c478bd9Sstevel@tonic-gate * crosstrap.  It atomically increments the outstanding request counter and,
27637c478bd9Sstevel@tonic-gate * if there was not already an outstanding request, branches to setsoftint_tl1
2764b0fc0e77Sgovinda * to enqueue an intr_vec for the given inum.
27657c478bd9Sstevel@tonic-gate */
27667c478bd9Sstevel@tonic-gate
27677c478bd9Sstevel@tonic-gate	! Register usage:
27687c478bd9Sstevel@tonic-gate	!
27697c478bd9Sstevel@tonic-gate	! Arguments:
27707c478bd9Sstevel@tonic-gate	! %g1 - inum
27717c478bd9Sstevel@tonic-gate	! %g2 - index into chsm_outstanding array
27727c478bd9Sstevel@tonic-gate	!
27737c478bd9Sstevel@tonic-gate	! Internal:
27747c478bd9Sstevel@tonic-gate	! %g2, %g3, %g5 - scratch
27757c478bd9Sstevel@tonic-gate	! %g4 - ptr. to scrub_misc chsm_outstanding[index].
27767c478bd9Sstevel@tonic-gate	! %g6 - setsoftint_tl1 address
27777c478bd9Sstevel@tonic-gate
27787c478bd9Sstevel@tonic-gate	ENTRY_NP(cache_scrubreq_tl1)
27797c478bd9Sstevel@tonic-gate	mulx	%g2, CHSM_OUTSTANDING_INCR, %g2
27807c478bd9Sstevel@tonic-gate	set	CHPR_SCRUB_MISC + CHSM_OUTSTANDING, %g3
27817c478bd9Sstevel@tonic-gate	add	%g2, %g3, %g2
27827c478bd9Sstevel@tonic-gate	GET_CPU_PRIVATE_PTR(%g2, %g4, %g5, 1f);
27837c478bd9Sstevel@tonic-gate	ld	[%g4], %g2		! cpu's chsm_outstanding[index]
27847c478bd9Sstevel@tonic-gate	!
27857c478bd9Sstevel@tonic-gate	! no need to use atomic instructions for the following
27867c478bd9Sstevel@tonic-gate	! increment - we're at tl1
27877c478bd9Sstevel@tonic-gate	!
27887c478bd9Sstevel@tonic-gate	add	%g2, 0x1, %g3
2789b0fc0e77Sgovinda	brnz,pn	%g2, 1f			! no need to enqueue more intr_vec
27907c478bd9Sstevel@tonic-gate	  st	%g3, [%g4]		! delay - store incremented counter
27917c478bd9Sstevel@tonic-gate	ASM_JMP(%g6, setsoftint_tl1)
27927c478bd9Sstevel@tonic-gate	! not reached
27937c478bd9Sstevel@tonic-gate1:
27947c478bd9Sstevel@tonic-gate	retry
27957c478bd9Sstevel@tonic-gate	SET_SIZE(cache_scrubreq_tl1)
27967c478bd9Sstevel@tonic-gate
27977c478bd9Sstevel@tonic-gate#endif	/* lint */
27987c478bd9Sstevel@tonic-gate
27997c478bd9Sstevel@tonic-gate
28007c478bd9Sstevel@tonic-gate#if defined(lint)
28017c478bd9Sstevel@tonic-gate
28027c478bd9Sstevel@tonic-gate/* ARGSUSED */
28037c478bd9Sstevel@tonic-gatevoid
28047c478bd9Sstevel@tonic-gateget_cpu_error_state(ch_cpu_errors_t *cpu_error_regs)
28057c478bd9Sstevel@tonic-gate{}
28067c478bd9Sstevel@tonic-gate
28077c478bd9Sstevel@tonic-gate#else	/* lint */
28087c478bd9Sstevel@tonic-gate
28097c478bd9Sstevel@tonic-gate/*
28107c478bd9Sstevel@tonic-gate * Get the error state for the processor.
28117c478bd9Sstevel@tonic-gate * Note that this must not be used at TL>0
28127c478bd9Sstevel@tonic-gate */
28137c478bd9Sstevel@tonic-gate	ENTRY(get_cpu_error_state)
28147c478bd9Sstevel@tonic-gate#if defined(CHEETAH_PLUS)
28157c478bd9Sstevel@tonic-gate	set	ASI_SHADOW_REG_VA, %o2
28167c478bd9Sstevel@tonic-gate	ldxa	[%o2]ASI_AFSR, %o1		! shadow afsr reg
28177c478bd9Sstevel@tonic-gate	stx	%o1, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR]
28187c478bd9Sstevel@tonic-gate	ldxa	[%o2]ASI_AFAR, %o1		! shadow afar reg
28197c478bd9Sstevel@tonic-gate	stx	%o1, [%o0 + CH_CPU_ERRORS_SHADOW_AFAR]
28207c478bd9Sstevel@tonic-gate	GET_CPU_IMPL(%o3)	! Only panther has AFSR_EXT registers
28217c478bd9Sstevel@tonic-gate	cmp	%o3, PANTHER_IMPL
28227c478bd9Sstevel@tonic-gate	bne,a	1f
28237c478bd9Sstevel@tonic-gate	  stx	%g0, [%o0 + CH_CPU_ERRORS_AFSR_EXT]	! zero for non-PN
28247c478bd9Sstevel@tonic-gate	set	ASI_AFSR_EXT_VA, %o2
28257c478bd9Sstevel@tonic-gate	ldxa	[%o2]ASI_AFSR, %o1		! afsr_ext reg
28267c478bd9Sstevel@tonic-gate	stx	%o1, [%o0 + CH_CPU_ERRORS_AFSR_EXT]
28277c478bd9Sstevel@tonic-gate	set	ASI_SHADOW_AFSR_EXT_VA, %o2
28287c478bd9Sstevel@tonic-gate	ldxa	[%o2]ASI_AFSR, %o1		! shadow afsr_ext reg
28297c478bd9Sstevel@tonic-gate	stx	%o1, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR_EXT]
28307c478bd9Sstevel@tonic-gate	b	2f
28317c478bd9Sstevel@tonic-gate	  nop
28327c478bd9Sstevel@tonic-gate1:
28337c478bd9Sstevel@tonic-gate	stx	%g0, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR_EXT] ! zero for non-PN
28347c478bd9Sstevel@tonic-gate2:
28357c478bd9Sstevel@tonic-gate#else	/* CHEETAH_PLUS */
28367c478bd9Sstevel@tonic-gate	stx	%g0, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR]
28377c478bd9Sstevel@tonic-gate	stx	%g0, [%o0 + CH_CPU_ERRORS_SHADOW_AFAR]
28387c478bd9Sstevel@tonic-gate	stx	%g0, [%o0 + CH_CPU_ERRORS_AFSR_EXT]
28397c478bd9Sstevel@tonic-gate	stx	%g0, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR_EXT]
28407c478bd9Sstevel@tonic-gate#endif	/* CHEETAH_PLUS */
28417c478bd9Sstevel@tonic-gate#if defined(SERRANO)
28427c478bd9Sstevel@tonic-gate	/*
28437c478bd9Sstevel@tonic-gate	 * Serrano has an afar2 which captures the address on FRC/FRU errors.
28447c478bd9Sstevel@tonic-gate	 * We save this in the afar2 of the register save area.
28457c478bd9Sstevel@tonic-gate	 */
28467c478bd9Sstevel@tonic-gate	set	ASI_MCU_AFAR2_VA, %o2
28477c478bd9Sstevel@tonic-gate	ldxa	[%o2]ASI_MCU_CTRL, %o1
28487c478bd9Sstevel@tonic-gate	stx	%o1, [%o0 + CH_CPU_ERRORS_AFAR2]
28497c478bd9Sstevel@tonic-gate#endif	/* SERRANO */
28507c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_AFSR, %o1		! primary afsr reg
28517c478bd9Sstevel@tonic-gate	stx	%o1, [%o0 + CH_CPU_ERRORS_AFSR]
28527c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_AFAR, %o1		! primary afar reg
28537c478bd9Sstevel@tonic-gate	retl
28547c478bd9Sstevel@tonic-gate	stx	%o1, [%o0 + CH_CPU_ERRORS_AFAR]
28557c478bd9Sstevel@tonic-gate	SET_SIZE(get_cpu_error_state)
28567c478bd9Sstevel@tonic-gate#endif	/* lint */
28577c478bd9Sstevel@tonic-gate
28587c478bd9Sstevel@tonic-gate#if defined(lint)
28597c478bd9Sstevel@tonic-gate
28607c478bd9Sstevel@tonic-gate/*
28617c478bd9Sstevel@tonic-gate * Check a page of memory for errors.
28627c478bd9Sstevel@tonic-gate *
28637c478bd9Sstevel@tonic-gate * Load each 64 byte block from physical memory.
28647c478bd9Sstevel@tonic-gate * Check AFSR after each load to see if an error
28657c478bd9Sstevel@tonic-gate * was caused. If so, log/scrub that error.
28667c478bd9Sstevel@tonic-gate *
28677c478bd9Sstevel@tonic-gate * Used to determine if a page contains
28687c478bd9Sstevel@tonic-gate * CEs when CEEN is disabled.
28697c478bd9Sstevel@tonic-gate */
28707c478bd9Sstevel@tonic-gate/*ARGSUSED*/
28717c478bd9Sstevel@tonic-gatevoid
28727c478bd9Sstevel@tonic-gatecpu_check_block(caddr_t va, uint_t psz)
28737c478bd9Sstevel@tonic-gate{}
28747c478bd9Sstevel@tonic-gate
28757c478bd9Sstevel@tonic-gate#else	/* lint */
28767c478bd9Sstevel@tonic-gate
28777c478bd9Sstevel@tonic-gate	ENTRY(cpu_check_block)
28787c478bd9Sstevel@tonic-gate	!
28797c478bd9Sstevel@tonic-gate	! get a new window with room for the error regs
28807c478bd9Sstevel@tonic-gate	!
28817c478bd9Sstevel@tonic-gate	save	%sp, -SA(MINFRAME + CH_CPU_ERROR_SIZE), %sp
28827c478bd9Sstevel@tonic-gate	srl	%i1, 6, %l4		! clear top bits of psz
28837c478bd9Sstevel@tonic-gate					! and divide by 64
28847c478bd9Sstevel@tonic-gate	rd	%fprs, %l2		! store FP
28857c478bd9Sstevel@tonic-gate	wr	%g0, FPRS_FEF, %fprs	! enable FP
28867c478bd9Sstevel@tonic-gate1:
28877c478bd9Sstevel@tonic-gate	ldda	[%i0]ASI_BLK_P, %d0	! load a block
28887c478bd9Sstevel@tonic-gate	membar	#Sync
28897c478bd9Sstevel@tonic-gate	ldxa    [%g0]ASI_AFSR, %l3	! read afsr reg
28907c478bd9Sstevel@tonic-gate	brz,a,pt %l3, 2f		! check for error
28917c478bd9Sstevel@tonic-gate	nop
28927c478bd9Sstevel@tonic-gate
28937c478bd9Sstevel@tonic-gate	!
28947c478bd9Sstevel@tonic-gate	! if error, read the error regs and log it
28957c478bd9Sstevel@tonic-gate	!
28967c478bd9Sstevel@tonic-gate	call	get_cpu_error_state
28977c478bd9Sstevel@tonic-gate	add	%fp, STACK_BIAS - CH_CPU_ERROR_SIZE, %o0
28987c478bd9Sstevel@tonic-gate
28997c478bd9Sstevel@tonic-gate	!
29007c478bd9Sstevel@tonic-gate	! cpu_ce_detected(ch_cpu_errors_t *, flag)
29017c478bd9Sstevel@tonic-gate	!
29027c478bd9Sstevel@tonic-gate	call	cpu_ce_detected		! log the error
29037c478bd9Sstevel@tonic-gate	mov	CE_CEEN_TIMEOUT, %o1
29047c478bd9Sstevel@tonic-gate2:
29057c478bd9Sstevel@tonic-gate	dec	%l4			! next 64-byte block
29067c478bd9Sstevel@tonic-gate	brnz,a,pt  %l4, 1b
29077c478bd9Sstevel@tonic-gate	add	%i0, 64, %i0		! increment block addr
29087c478bd9Sstevel@tonic-gate
29097c478bd9Sstevel@tonic-gate	wr	%l2, %g0, %fprs		! restore FP
29107c478bd9Sstevel@tonic-gate	ret
29117c478bd9Sstevel@tonic-gate	restore
29127c478bd9Sstevel@tonic-gate
29137c478bd9Sstevel@tonic-gate	SET_SIZE(cpu_check_block)
29147c478bd9Sstevel@tonic-gate
29157c478bd9Sstevel@tonic-gate#endif	/* lint */
29167c478bd9Sstevel@tonic-gate
29177c478bd9Sstevel@tonic-gate#if defined(lint)
29187c478bd9Sstevel@tonic-gate
29197c478bd9Sstevel@tonic-gate/*
29207c478bd9Sstevel@tonic-gate * Perform a cpu logout called from C.  This is used where we did not trap
29217c478bd9Sstevel@tonic-gate * for the error but still want to gather "what we can".  Caller must make
29227c478bd9Sstevel@tonic-gate * sure cpu private area exists and that the indicated logout area is free
29237c478bd9Sstevel@tonic-gate * for use, and that we are unable to migrate cpus.
29247c478bd9Sstevel@tonic-gate */
29257c478bd9Sstevel@tonic-gate/*ARGSUSED*/
29267c478bd9Sstevel@tonic-gatevoid
29277c478bd9Sstevel@tonic-gatecpu_delayed_logout(uint64_t afar, ch_cpu_logout_t *clop)
29287c478bd9Sstevel@tonic-gate{ }
29297c478bd9Sstevel@tonic-gate
29307c478bd9Sstevel@tonic-gate#else
29317c478bd9Sstevel@tonic-gate	ENTRY(cpu_delayed_logout)
29327c478bd9Sstevel@tonic-gate	rdpr	%pstate, %o2
29337c478bd9Sstevel@tonic-gate	andn	%o2, PSTATE_IE, %o2
29347c478bd9Sstevel@tonic-gate	wrpr	%g0, %o2, %pstate		! disable interrupts
29357c478bd9Sstevel@tonic-gate	PARK_SIBLING_CORE(%o2, %o3, %o4)	! %o2 has DCU value
29367c478bd9Sstevel@tonic-gate	add	%o1, CH_CLO_DATA + CH_CHD_EC_DATA, %o1
29377c478bd9Sstevel@tonic-gate	rd	%asi, %g1
29387c478bd9Sstevel@tonic-gate	wr	%g0, ASI_P, %asi
29397c478bd9Sstevel@tonic-gate	GET_ECACHE_DTAGS(%o0, %o1, %o3, %o4, %o5)
29407c478bd9Sstevel@tonic-gate	wr	%g1, %asi
29417c478bd9Sstevel@tonic-gate	UNPARK_SIBLING_CORE(%o2, %o3, %o4)	! can use %o2 again
29427c478bd9Sstevel@tonic-gate	rdpr	%pstate, %o2
29437c478bd9Sstevel@tonic-gate	or	%o2, PSTATE_IE, %o2
29447c478bd9Sstevel@tonic-gate	wrpr	%g0, %o2, %pstate
29457c478bd9Sstevel@tonic-gate	retl
29467c478bd9Sstevel@tonic-gate	  nop
29477c478bd9Sstevel@tonic-gate	SET_SIZE(cpu_delayed_logout)
29487c478bd9Sstevel@tonic-gate
29497c478bd9Sstevel@tonic-gate#endif	/* lint */
29507c478bd9Sstevel@tonic-gate
29517c478bd9Sstevel@tonic-gate#if defined(lint)
29527c478bd9Sstevel@tonic-gate
29537c478bd9Sstevel@tonic-gate/*ARGSUSED*/
29547c478bd9Sstevel@tonic-gateint
29557c478bd9Sstevel@tonic-gatedtrace_blksuword32(uintptr_t addr, uint32_t *data, int tryagain)
29567c478bd9Sstevel@tonic-gate{ return (0); }
29577c478bd9Sstevel@tonic-gate
29587c478bd9Sstevel@tonic-gate#else
29597c478bd9Sstevel@tonic-gate
29607c478bd9Sstevel@tonic-gate	ENTRY(dtrace_blksuword32)
29617c478bd9Sstevel@tonic-gate	save	%sp, -SA(MINFRAME + 4), %sp
29627c478bd9Sstevel@tonic-gate
29637c478bd9Sstevel@tonic-gate	rdpr	%pstate, %l1
29647c478bd9Sstevel@tonic-gate	andn	%l1, PSTATE_IE, %l2		! disable interrupts to
29657c478bd9Sstevel@tonic-gate	wrpr	%g0, %l2, %pstate		! protect our FPU diddling
29667c478bd9Sstevel@tonic-gate
29677c478bd9Sstevel@tonic-gate	rd	%fprs, %l0
29687c478bd9Sstevel@tonic-gate	andcc	%l0, FPRS_FEF, %g0
29697c478bd9Sstevel@tonic-gate	bz,a,pt	%xcc, 1f			! if the fpu is disabled
29707c478bd9Sstevel@tonic-gate	wr	%g0, FPRS_FEF, %fprs		! ... enable the fpu
29717c478bd9Sstevel@tonic-gate
29727c478bd9Sstevel@tonic-gate	st	%f0, [%fp + STACK_BIAS - 4]	! save %f0 to the stack
29737c478bd9Sstevel@tonic-gate1:
29747c478bd9Sstevel@tonic-gate	set	0f, %l5
29757c478bd9Sstevel@tonic-gate        /*
29767c478bd9Sstevel@tonic-gate         * We're about to write a block full or either total garbage
29777c478bd9Sstevel@tonic-gate         * (not kernel data, don't worry) or user floating-point data
29787c478bd9Sstevel@tonic-gate         * (so it only _looks_ like garbage).
29797c478bd9Sstevel@tonic-gate         */
29807c478bd9Sstevel@tonic-gate	ld	[%i1], %f0			! modify the block
29817c478bd9Sstevel@tonic-gate	membar	#Sync
29827c478bd9Sstevel@tonic-gate	stn	%l5, [THREAD_REG + T_LOFAULT]	! set up the lofault handler
29837c478bd9Sstevel@tonic-gate	stda	%d0, [%i0]ASI_BLK_COMMIT_S	! store the modified block
29847c478bd9Sstevel@tonic-gate	membar	#Sync
29857c478bd9Sstevel@tonic-gate	stn	%g0, [THREAD_REG + T_LOFAULT]	! remove the lofault handler
29867c478bd9Sstevel@tonic-gate
29877c478bd9Sstevel@tonic-gate	bz,a,pt	%xcc, 1f
29887c478bd9Sstevel@tonic-gate	wr	%g0, %l0, %fprs			! restore %fprs
29897c478bd9Sstevel@tonic-gate
29907c478bd9Sstevel@tonic-gate	ld	[%fp + STACK_BIAS - 4], %f0	! restore %f0
29917c478bd9Sstevel@tonic-gate1:
29927c478bd9Sstevel@tonic-gate
29937c478bd9Sstevel@tonic-gate	wrpr	%g0, %l1, %pstate		! restore interrupts
29947c478bd9Sstevel@tonic-gate
29957c478bd9Sstevel@tonic-gate	ret
29967c478bd9Sstevel@tonic-gate	restore	%g0, %g0, %o0
29977c478bd9Sstevel@tonic-gate
29987c478bd9Sstevel@tonic-gate0:
29997c478bd9Sstevel@tonic-gate	membar	#Sync
30007c478bd9Sstevel@tonic-gate	stn	%g0, [THREAD_REG + T_LOFAULT]	! remove the lofault handler
30017c478bd9Sstevel@tonic-gate
30027c478bd9Sstevel@tonic-gate	bz,a,pt	%xcc, 1f
30037c478bd9Sstevel@tonic-gate	wr	%g0, %l0, %fprs			! restore %fprs
30047c478bd9Sstevel@tonic-gate
30057c478bd9Sstevel@tonic-gate	ld	[%fp + STACK_BIAS - 4], %f0	! restore %f0
30067c478bd9Sstevel@tonic-gate1:
30077c478bd9Sstevel@tonic-gate
30087c478bd9Sstevel@tonic-gate	wrpr	%g0, %l1, %pstate		! restore interrupts
30097c478bd9Sstevel@tonic-gate
30107c478bd9Sstevel@tonic-gate	/*
30117c478bd9Sstevel@tonic-gate	 * If tryagain is set (%i2) we tail-call dtrace_blksuword32_err()
30127c478bd9Sstevel@tonic-gate	 * which deals with watchpoints. Otherwise, just return -1.
30137c478bd9Sstevel@tonic-gate	 */
30147c478bd9Sstevel@tonic-gate	brnz,pt	%i2, 1f
30157c478bd9Sstevel@tonic-gate	nop
30167c478bd9Sstevel@tonic-gate	ret
30177c478bd9Sstevel@tonic-gate	restore	%g0, -1, %o0
30187c478bd9Sstevel@tonic-gate1:
30197c478bd9Sstevel@tonic-gate	call	dtrace_blksuword32_err
30207c478bd9Sstevel@tonic-gate	restore
30217c478bd9Sstevel@tonic-gate
30227c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_blksuword32)
30237c478bd9Sstevel@tonic-gate
30247c478bd9Sstevel@tonic-gate#endif /* lint */
30257c478bd9Sstevel@tonic-gate
30267c478bd9Sstevel@tonic-gate#ifdef	CHEETAHPLUS_ERRATUM_25
30277c478bd9Sstevel@tonic-gate
30287c478bd9Sstevel@tonic-gate#if	defined(lint)
30297c478bd9Sstevel@tonic-gate/*
30307c478bd9Sstevel@tonic-gate * Claim a chunk of physical address space.
30317c478bd9Sstevel@tonic-gate */
30327c478bd9Sstevel@tonic-gate/*ARGSUSED*/
30337c478bd9Sstevel@tonic-gatevoid
30347c478bd9Sstevel@tonic-gateclaimlines(uint64_t pa, size_t sz, int stride)
30357c478bd9Sstevel@tonic-gate{}
30367c478bd9Sstevel@tonic-gate#else	/* lint */
30377c478bd9Sstevel@tonic-gate	ENTRY(claimlines)
30387c478bd9Sstevel@tonic-gate1:
30397c478bd9Sstevel@tonic-gate	subcc	%o1, %o2, %o1
30407c478bd9Sstevel@tonic-gate	add	%o0, %o1, %o3
30417c478bd9Sstevel@tonic-gate	bgeu,a,pt	%xcc, 1b
30427c478bd9Sstevel@tonic-gate	casxa	[%o3]ASI_MEM, %g0, %g0
30437c478bd9Sstevel@tonic-gate	membar  #Sync
30447c478bd9Sstevel@tonic-gate	retl
30457c478bd9Sstevel@tonic-gate	nop
30467c478bd9Sstevel@tonic-gate	SET_SIZE(claimlines)
30477c478bd9Sstevel@tonic-gate#endif	/* lint */
30487c478bd9Sstevel@tonic-gate
30497c478bd9Sstevel@tonic-gate#if	defined(lint)
30507c478bd9Sstevel@tonic-gate/*
30517c478bd9Sstevel@tonic-gate * CPU feature initialization,
30527c478bd9Sstevel@tonic-gate * turn BPE off,
30537c478bd9Sstevel@tonic-gate * get device id.
30547c478bd9Sstevel@tonic-gate */
30557c478bd9Sstevel@tonic-gate/*ARGSUSED*/
30567c478bd9Sstevel@tonic-gatevoid
30577c478bd9Sstevel@tonic-gatecpu_feature_init(void)
30587c478bd9Sstevel@tonic-gate{}
30597c478bd9Sstevel@tonic-gate#else	/* lint */
30607c478bd9Sstevel@tonic-gate	ENTRY(cpu_feature_init)
30617c478bd9Sstevel@tonic-gate	save	%sp, -SA(MINFRAME), %sp
30627c478bd9Sstevel@tonic-gate	sethi	%hi(cheetah_bpe_off), %o0
30637c478bd9Sstevel@tonic-gate	ld	[%o0 + %lo(cheetah_bpe_off)], %o0
30647c478bd9Sstevel@tonic-gate	brz	%o0, 1f
30657c478bd9Sstevel@tonic-gate	nop
30667c478bd9Sstevel@tonic-gate	rd	ASR_DISPATCH_CONTROL, %o0
30677c478bd9Sstevel@tonic-gate	andn	%o0, ASR_DISPATCH_CONTROL_BPE, %o0
30687c478bd9Sstevel@tonic-gate	wr	%o0, 0, ASR_DISPATCH_CONTROL
30697c478bd9Sstevel@tonic-gate1:
30707c478bd9Sstevel@tonic-gate	!
30717c478bd9Sstevel@tonic-gate	! get the device_id and store the device_id
30727c478bd9Sstevel@tonic-gate	! in the appropriate cpunodes structure
30737c478bd9Sstevel@tonic-gate	! given the cpus index
30747c478bd9Sstevel@tonic-gate	!
30757c478bd9Sstevel@tonic-gate	CPU_INDEX(%o0, %o1)
30767c478bd9Sstevel@tonic-gate	mulx %o0, CPU_NODE_SIZE, %o0
30777c478bd9Sstevel@tonic-gate	set  cpunodes + DEVICE_ID, %o1
30787c478bd9Sstevel@tonic-gate	ldxa [%g0] ASI_DEVICE_SERIAL_ID, %o2
30797c478bd9Sstevel@tonic-gate	stx  %o2, [%o0 + %o1]
30807c478bd9Sstevel@tonic-gate#ifdef	CHEETAHPLUS_ERRATUM_34
30817c478bd9Sstevel@tonic-gate	!
30827c478bd9Sstevel@tonic-gate	! apply Cheetah+ erratum 34 workaround
30837c478bd9Sstevel@tonic-gate	!
30847c478bd9Sstevel@tonic-gate	call itlb_erratum34_fixup
30857c478bd9Sstevel@tonic-gate	  nop
308619f938d5Sjfrank	call dtlb_erratum34_fixup
308719f938d5Sjfrank	  nop
30887c478bd9Sstevel@tonic-gate#endif	/* CHEETAHPLUS_ERRATUM_34 */
30897c478bd9Sstevel@tonic-gate	ret
30907c478bd9Sstevel@tonic-gate	  restore
30917c478bd9Sstevel@tonic-gate	SET_SIZE(cpu_feature_init)
30927c478bd9Sstevel@tonic-gate#endif	/* lint */
30937c478bd9Sstevel@tonic-gate
30947c478bd9Sstevel@tonic-gate#if	defined(lint)
30957c478bd9Sstevel@tonic-gate/*
30967c478bd9Sstevel@tonic-gate * Copy a tsb entry atomically, from src to dest.
30977c478bd9Sstevel@tonic-gate * src must be 128 bit aligned.
30987c478bd9Sstevel@tonic-gate */
30997c478bd9Sstevel@tonic-gate/*ARGSUSED*/
31007c478bd9Sstevel@tonic-gatevoid
31017c478bd9Sstevel@tonic-gatecopy_tsb_entry(uintptr_t src, uintptr_t dest)
31027c478bd9Sstevel@tonic-gate{}
31037c478bd9Sstevel@tonic-gate#else	/* lint */
31047c478bd9Sstevel@tonic-gate	ENTRY(copy_tsb_entry)
31057c478bd9Sstevel@tonic-gate	ldda	[%o0]ASI_NQUAD_LD, %o2		! %o2 = tag, %o3 = data
31067c478bd9Sstevel@tonic-gate	stx	%o2, [%o1]
31077c478bd9Sstevel@tonic-gate	stx	%o3, [%o1 + 8 ]
31087c478bd9Sstevel@tonic-gate	retl
31097c478bd9Sstevel@tonic-gate	nop
31107c478bd9Sstevel@tonic-gate	SET_SIZE(copy_tsb_entry)
31117c478bd9Sstevel@tonic-gate#endif	/* lint */
31127c478bd9Sstevel@tonic-gate
31137c478bd9Sstevel@tonic-gate#endif	/* CHEETAHPLUS_ERRATUM_25 */
31147c478bd9Sstevel@tonic-gate
31157c478bd9Sstevel@tonic-gate#ifdef	CHEETAHPLUS_ERRATUM_34
31167c478bd9Sstevel@tonic-gate
31177c478bd9Sstevel@tonic-gate#if	defined(lint)
31187c478bd9Sstevel@tonic-gate
31197c478bd9Sstevel@tonic-gate/*ARGSUSED*/
31207c478bd9Sstevel@tonic-gatevoid
31217c478bd9Sstevel@tonic-gateitlb_erratum34_fixup(void)
31227c478bd9Sstevel@tonic-gate{}
31237c478bd9Sstevel@tonic-gate
31247c478bd9Sstevel@tonic-gate#else	/* lint */
31257c478bd9Sstevel@tonic-gate
31267c478bd9Sstevel@tonic-gate	!
31277c478bd9Sstevel@tonic-gate	! In Cheetah+ erratum 34, under certain conditions an ITLB locked
31287c478bd9Sstevel@tonic-gate	! index 0 TTE will erroneously be displaced when a new TTE is
31297c478bd9Sstevel@tonic-gate	! loaded via ASI_ITLB_IN.  In order to avoid cheetah+ erratum 34,
31307c478bd9Sstevel@tonic-gate	! locked index 0 TTEs must be relocated.
31317c478bd9Sstevel@tonic-gate	!
31327c478bd9Sstevel@tonic-gate	! NOTE: Care must be taken to avoid an ITLB miss in this routine.
31337c478bd9Sstevel@tonic-gate	!
31347c478bd9Sstevel@tonic-gate	ENTRY_NP(itlb_erratum34_fixup)
31357c478bd9Sstevel@tonic-gate	rdpr	%pstate, %o3
31367c478bd9Sstevel@tonic-gate#ifdef DEBUG
31371e2e7a75Shuah	PANIC_IF_INTR_DISABLED_PSTR(%o3, u3_di_label1, %g1)
31387c478bd9Sstevel@tonic-gate#endif /* DEBUG */
31397c478bd9Sstevel@tonic-gate	wrpr	%o3, PSTATE_IE, %pstate		! Disable interrupts
31407c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_ITLB_ACCESS, %o1	! %o1 = entry 0 data
31417c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_ITLB_TAGREAD, %o2	! %o2 = entry 0 tag
31427c478bd9Sstevel@tonic-gate
31437c478bd9Sstevel@tonic-gate	cmp	%o1, %g0			! Is this entry valid?
31447c478bd9Sstevel@tonic-gate	bge	%xcc, 1f
31457c478bd9Sstevel@tonic-gate	  andcc	%o1, TTE_LCK_INT, %g0		! Is this entry locked?
31467c478bd9Sstevel@tonic-gate	bnz	%icc, 2f
31477c478bd9Sstevel@tonic-gate	  nop
31487c478bd9Sstevel@tonic-gate1:
31497c478bd9Sstevel@tonic-gate	retl					! Nope, outta here...
31507c478bd9Sstevel@tonic-gate	  wrpr	%g0, %o3, %pstate		! Enable interrupts
31517c478bd9Sstevel@tonic-gate2:
31527c478bd9Sstevel@tonic-gate	sethi	%hi(FLUSH_ADDR), %o4
31537c478bd9Sstevel@tonic-gate	stxa	%g0, [%o2]ASI_ITLB_DEMAP	! Flush this mapping
31547c478bd9Sstevel@tonic-gate	flush	%o4				! Flush required for I-MMU
31557c478bd9Sstevel@tonic-gate	!
31567c478bd9Sstevel@tonic-gate	! Start search from index 1 up.  This is because the kernel force
31577c478bd9Sstevel@tonic-gate	! loads its text page at index 15 in sfmmu_kernel_remap() and we
31587c478bd9Sstevel@tonic-gate	! don't want our relocated entry evicted later.
31597c478bd9Sstevel@tonic-gate	!
31607c478bd9Sstevel@tonic-gate	! NOTE: We assume that we'll be successful in finding an unlocked
31617c478bd9Sstevel@tonic-gate	! or invalid entry.  If that isn't the case there are bound to
31627c478bd9Sstevel@tonic-gate	! bigger problems.
31637c478bd9Sstevel@tonic-gate	!
31647c478bd9Sstevel@tonic-gate	set	(1 << 3), %g3
31657c478bd9Sstevel@tonic-gate3:
31667c478bd9Sstevel@tonic-gate	ldxa	[%g3]ASI_ITLB_ACCESS, %o4	! Load TTE from t16
31677c478bd9Sstevel@tonic-gate	!
31687c478bd9Sstevel@tonic-gate	! If this entry isn't valid, we'll choose to displace it (regardless
31697c478bd9Sstevel@tonic-gate	! of the lock bit).
31707c478bd9Sstevel@tonic-gate	!
31717c478bd9Sstevel@tonic-gate	cmp	%o4, %g0			! TTE is > 0 iff not valid
31727c478bd9Sstevel@tonic-gate	bge	%xcc, 4f			! If invalid, go displace
31737c478bd9Sstevel@tonic-gate	  andcc	%o4, TTE_LCK_INT, %g0		! Check for lock bit
31747c478bd9Sstevel@tonic-gate	bnz,a	%icc, 3b			! If locked, look at next
31757c478bd9Sstevel@tonic-gate	  add	%g3, (1 << 3), %g3		!  entry
31767c478bd9Sstevel@tonic-gate4:
31777c478bd9Sstevel@tonic-gate	!
31787c478bd9Sstevel@tonic-gate	! We found an unlocked or invalid entry; we'll explicitly load
31797c478bd9Sstevel@tonic-gate	! the former index 0 entry here.
31807c478bd9Sstevel@tonic-gate	!
31817c478bd9Sstevel@tonic-gate	sethi	%hi(FLUSH_ADDR), %o4
31827c478bd9Sstevel@tonic-gate	set	MMU_TAG_ACCESS, %g4
31837c478bd9Sstevel@tonic-gate	stxa	%o2, [%g4]ASI_IMMU
31847c478bd9Sstevel@tonic-gate	stxa	%o1, [%g3]ASI_ITLB_ACCESS
31857c478bd9Sstevel@tonic-gate	flush	%o4				! Flush required for I-MMU
31867c478bd9Sstevel@tonic-gate	retl
31877c478bd9Sstevel@tonic-gate	  wrpr	%g0, %o3, %pstate		! Enable interrupts
31887c478bd9Sstevel@tonic-gate	SET_SIZE(itlb_erratum34_fixup)
31897c478bd9Sstevel@tonic-gate
31907c478bd9Sstevel@tonic-gate#endif	/* lint */
31917c478bd9Sstevel@tonic-gate
319219f938d5Sjfrank#if	defined(lint)
319319f938d5Sjfrank
319419f938d5Sjfrank/*ARGSUSED*/
319519f938d5Sjfrankvoid
319619f938d5Sjfrankdtlb_erratum34_fixup(void)
319719f938d5Sjfrank{}
319819f938d5Sjfrank
319919f938d5Sjfrank#else	/* lint */
320019f938d5Sjfrank
320119f938d5Sjfrank	!
320219f938d5Sjfrank	! In Cheetah+ erratum 34, under certain conditions a DTLB locked
320319f938d5Sjfrank	! index 0 TTE will erroneously be displaced when a new TTE is
320419f938d5Sjfrank	! loaded.  In order to avoid cheetah+ erratum 34, locked index 0
320519f938d5Sjfrank	! TTEs must be relocated.
320619f938d5Sjfrank	!
320719f938d5Sjfrank	ENTRY_NP(dtlb_erratum34_fixup)
320819f938d5Sjfrank	rdpr	%pstate, %o3
320919f938d5Sjfrank#ifdef DEBUG
321019f938d5Sjfrank	PANIC_IF_INTR_DISABLED_PSTR(%o3, u3_di_label2, %g1)
321119f938d5Sjfrank#endif /* DEBUG */
321219f938d5Sjfrank	wrpr	%o3, PSTATE_IE, %pstate		! Disable interrupts
321319f938d5Sjfrank	ldxa	[%g0]ASI_DTLB_ACCESS, %o1	! %o1 = entry 0 data
321419f938d5Sjfrank	ldxa	[%g0]ASI_DTLB_TAGREAD, %o2	! %o2 = entry 0 tag
321519f938d5Sjfrank
321619f938d5Sjfrank	cmp	%o1, %g0			! Is this entry valid?
321719f938d5Sjfrank	bge	%xcc, 1f
321819f938d5Sjfrank	  andcc	%o1, TTE_LCK_INT, %g0		! Is this entry locked?
321919f938d5Sjfrank	bnz	%icc, 2f
322019f938d5Sjfrank	  nop
322119f938d5Sjfrank1:
322219f938d5Sjfrank	retl					! Nope, outta here...
322319f938d5Sjfrank	  wrpr	%g0, %o3, %pstate		! Enable interrupts
322419f938d5Sjfrank2:
322519f938d5Sjfrank	stxa	%g0, [%o2]ASI_DTLB_DEMAP	! Flush this mapping
322619f938d5Sjfrank	membar	#Sync
322719f938d5Sjfrank	!
322819f938d5Sjfrank	! Start search from index 1 up.
322919f938d5Sjfrank	!
323019f938d5Sjfrank	! NOTE: We assume that we'll be successful in finding an unlocked
323119f938d5Sjfrank	! or invalid entry.  If that isn't the case there are bound to
323219f938d5Sjfrank	! bigger problems.
323319f938d5Sjfrank	!
323419f938d5Sjfrank	set	(1 << 3), %g3
323519f938d5Sjfrank3:
323619f938d5Sjfrank	ldxa	[%g3]ASI_DTLB_ACCESS, %o4	! Load TTE from t16
323719f938d5Sjfrank	!
323819f938d5Sjfrank	! If this entry isn't valid, we'll choose to displace it (regardless
323919f938d5Sjfrank	! of the lock bit).
324019f938d5Sjfrank	!
324119f938d5Sjfrank	cmp	%o4, %g0			! TTE is > 0 iff not valid
324219f938d5Sjfrank	bge	%xcc, 4f			! If invalid, go displace
324319f938d5Sjfrank	  andcc	%o4, TTE_LCK_INT, %g0		! Check for lock bit
324419f938d5Sjfrank	bnz,a	%icc, 3b			! If locked, look at next
324519f938d5Sjfrank	  add	%g3, (1 << 3), %g3		!  entry
324619f938d5Sjfrank4:
324719f938d5Sjfrank	!
324819f938d5Sjfrank	! We found an unlocked or invalid entry; we'll explicitly load
324919f938d5Sjfrank	! the former index 0 entry here.
325019f938d5Sjfrank	!
325119f938d5Sjfrank	set	MMU_TAG_ACCESS, %g4
325219f938d5Sjfrank	stxa	%o2, [%g4]ASI_DMMU
325319f938d5Sjfrank	stxa	%o1, [%g3]ASI_DTLB_ACCESS
325419f938d5Sjfrank	membar	#Sync
325519f938d5Sjfrank	retl
325619f938d5Sjfrank	  wrpr	%g0, %o3, %pstate		! Enable interrupts
325719f938d5Sjfrank	SET_SIZE(dtlb_erratum34_fixup)
325819f938d5Sjfrank
325919f938d5Sjfrank#endif	/* lint */
326019f938d5Sjfrank
32617c478bd9Sstevel@tonic-gate#endif	/* CHEETAHPLUS_ERRATUM_34 */
32627c478bd9Sstevel@tonic-gate
3263