xref: /titanic_51/usr/src/uts/sun4u/vm/mach_sfmmu_asm.s (revision 19f938d5a97467cae5809ba3cee189b02c8e03b7)
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
525cf1a30Sjl139090 * Common Development and Distribution License (the "License").
625cf1a30Sjl139090 * 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/*
221426d65aSsm142603 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate#pragma ident	"%Z%%M%	%I%	%E% SMI"
277c478bd9Sstevel@tonic-gate
287c478bd9Sstevel@tonic-gate/*
297c478bd9Sstevel@tonic-gate * SFMMU primitives.  These primitives should only be used by sfmmu
307c478bd9Sstevel@tonic-gate * routines.
317c478bd9Sstevel@tonic-gate */
327c478bd9Sstevel@tonic-gate
337c478bd9Sstevel@tonic-gate#if defined(lint)
347c478bd9Sstevel@tonic-gate#include <sys/types.h>
357c478bd9Sstevel@tonic-gate#else	/* lint */
367c478bd9Sstevel@tonic-gate#include "assym.h"
377c478bd9Sstevel@tonic-gate#endif	/* lint */
387c478bd9Sstevel@tonic-gate
397c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h>
407c478bd9Sstevel@tonic-gate#include <sys/machtrap.h>
417c478bd9Sstevel@tonic-gate#include <sys/machasi.h>
427c478bd9Sstevel@tonic-gate#include <sys/sun4asi.h>
437c478bd9Sstevel@tonic-gate#include <sys/pte.h>
447c478bd9Sstevel@tonic-gate#include <sys/mmu.h>
457c478bd9Sstevel@tonic-gate#include <vm/hat_sfmmu.h>
467c478bd9Sstevel@tonic-gate#include <vm/seg_spt.h>
477c478bd9Sstevel@tonic-gate#include <sys/machparam.h>
487c478bd9Sstevel@tonic-gate#include <sys/privregs.h>
497c478bd9Sstevel@tonic-gate#include <sys/scb.h>
507c478bd9Sstevel@tonic-gate#include <sys/intreg.h>
517c478bd9Sstevel@tonic-gate#include <sys/machthread.h>
527c478bd9Sstevel@tonic-gate#include <sys/clock.h>
537c478bd9Sstevel@tonic-gate#include <sys/trapstat.h>
547c478bd9Sstevel@tonic-gate
557c478bd9Sstevel@tonic-gate/*
567c478bd9Sstevel@tonic-gate * sfmmu related subroutines
577c478bd9Sstevel@tonic-gate */
587c478bd9Sstevel@tonic-gate
597c478bd9Sstevel@tonic-gate#if defined (lint)
607c478bd9Sstevel@tonic-gate
617c478bd9Sstevel@tonic-gate/*
627c478bd9Sstevel@tonic-gate * sfmmu related subroutines
637c478bd9Sstevel@tonic-gate */
647c478bd9Sstevel@tonic-gate/* ARGSUSED */
657c478bd9Sstevel@tonic-gatevoid
661e2e7a75Shuahsfmmu_raise_tsb_exception(uint64_t sfmmup, uint64_t rctx)
677c478bd9Sstevel@tonic-gate{}
687c478bd9Sstevel@tonic-gate
697c478bd9Sstevel@tonic-gate/* ARGSUSED */
707c478bd9Sstevel@tonic-gatevoid
711e2e7a75Shuahsfmmu_itlb_ld_kva(caddr_t vaddr, tte_t *tte)
727c478bd9Sstevel@tonic-gate{}
737c478bd9Sstevel@tonic-gate
747c478bd9Sstevel@tonic-gate/* ARGSUSED */
757c478bd9Sstevel@tonic-gatevoid
761e2e7a75Shuahsfmmu_dtlb_ld_kva(caddr_t vaddr, tte_t *tte)
777c478bd9Sstevel@tonic-gate{}
787c478bd9Sstevel@tonic-gate
797c478bd9Sstevel@tonic-gateint
807c478bd9Sstevel@tonic-gatesfmmu_getctx_pri()
817c478bd9Sstevel@tonic-gate{ return(0); }
827c478bd9Sstevel@tonic-gate
837c478bd9Sstevel@tonic-gateint
847c478bd9Sstevel@tonic-gatesfmmu_getctx_sec()
857c478bd9Sstevel@tonic-gate{ return(0); }
867c478bd9Sstevel@tonic-gate
877c478bd9Sstevel@tonic-gate/* ARGSUSED */
887c478bd9Sstevel@tonic-gatevoid
8905d3dc4bSpaulsansfmmu_setctx_sec(uint_t ctx)
907c478bd9Sstevel@tonic-gate{}
917c478bd9Sstevel@tonic-gate
927c478bd9Sstevel@tonic-gate/* ARGSUSED */
937c478bd9Sstevel@tonic-gatevoid
947c478bd9Sstevel@tonic-gatesfmmu_load_mmustate(sfmmu_t *sfmmup)
957c478bd9Sstevel@tonic-gate{
967c478bd9Sstevel@tonic-gate}
977c478bd9Sstevel@tonic-gate
987c478bd9Sstevel@tonic-gate#else	/* lint */
997c478bd9Sstevel@tonic-gate
1007c478bd9Sstevel@tonic-gate/*
1011e2e7a75Shuah * Invalidate either the context of a specific victim or any process
1021e2e7a75Shuah * currently running on this CPU.
1037c478bd9Sstevel@tonic-gate *
1041e2e7a75Shuah * %g1 = sfmmup whose ctx is being invalidated
1051e2e7a75Shuah *	 when called from sfmmu_wrap_around, %g1 == INVALID_CONTEXT
1061e2e7a75Shuah * Note %g1 is the only input argument used by this xcall handler.
1077c478bd9Sstevel@tonic-gate */
1081e2e7a75Shuah	ENTRY(sfmmu_raise_tsb_exception)
1097c478bd9Sstevel@tonic-gate	!
1101426d65aSsm142603	! if (victim == INVALID_CONTEXT ||
1111426d65aSsm142603	!     current CPU tsbmiss->usfmmup == victim sfmmup) {
1121426d65aSsm142603	!       if (shctx_on) {
1131426d65aSsm142603	!               shctx = INVALID;
1141426d65aSsm142603	!       }
1151e2e7a75Shuah	!	if (sec-ctx > INVALID_CONTEXT) {
1161e2e7a75Shuah	!		write INVALID_CONTEXT to sec-ctx
1171e2e7a75Shuah	!	}
1181e2e7a75Shuah	!	if (pri-ctx > INVALID_CONTEXT) {
1191e2e7a75Shuah	!		write INVALID_CONTEXT to pri-ctx
1201e2e7a75Shuah	!	}
1217c478bd9Sstevel@tonic-gate	! }
1221e2e7a75Shuah
1231e2e7a75Shuah	sethi   %hi(ksfmmup), %g3
1241e2e7a75Shuah        ldx     [%g3 + %lo(ksfmmup)], %g3
1251e2e7a75Shuah	cmp	%g1, %g3
1261e2e7a75Shuah	be,a,pn %xcc, ptl1_panic		/* can't invalidate kernel ctx */
1271e2e7a75Shuah	  mov	PTL1_BAD_RAISE_TSBEXCP, %g1
1281e2e7a75Shuah
1291e2e7a75Shuah	set	INVALID_CONTEXT, %g2
1301e2e7a75Shuah	cmp	%g1, INVALID_CONTEXT
1311426d65aSsm142603	be,pn	%xcc, 0f			/* called from wrap_around? */
1321e2e7a75Shuah	  mov	MMU_SCONTEXT, %g3
1331e2e7a75Shuah
1341426d65aSsm142603	CPU_TSBMISS_AREA(%g5, %g6)		/* load cpu tsbmiss area */
1351426d65aSsm142603	ldx	[%g5 + TSBMISS_UHATID], %g5     /* load usfmmup */
1361426d65aSsm142603	cmp	%g5, %g1			/* hat toBe-invalid running? */
1371426d65aSsm142603	bne,pt	%xcc, 3f
1381426d65aSsm142603	  nop
1391426d65aSsm142603
1401426d65aSsm1426030:
1411426d65aSsm142603	sethi   %hi(shctx_on), %g5
1421426d65aSsm142603        ld      [%g5 + %lo(shctx_on)], %g5
1431426d65aSsm142603        brz     %g5, 1f
1441426d65aSsm142603          mov     MMU_SHARED_CONTEXT, %g5
1451426d65aSsm142603        sethi   %hi(FLUSH_ADDR), %g4
1461426d65aSsm142603        stxa    %g0, [%g5]ASI_MMU_CTX
1471426d65aSsm142603        flush   %g4
1481426d65aSsm142603
1491426d65aSsm1426031:
1501e2e7a75Shuah	ldxa	[%g3]ASI_MMU_CTX, %g5		/* %g5 = pgsz | sec-ctx */
1511e2e7a75Shuah	set     CTXREG_CTX_MASK, %g4
1521e2e7a75Shuah	and	%g5, %g4, %g5			/* %g5 = sec-ctx */
1531e2e7a75Shuah	cmp	%g5, INVALID_CONTEXT		/* kernel ctx or invald ctx? */
1541426d65aSsm142603	ble,pn	%xcc, 2f			/* yes, no need to change */
1557c478bd9Sstevel@tonic-gate	  mov   MMU_PCONTEXT, %g7
1561e2e7a75Shuah
1571e2e7a75Shuah	stxa	%g2, [%g3]ASI_MMU_CTX		/* set invalid ctx */
1587c478bd9Sstevel@tonic-gate	membar	#Sync
1591e2e7a75Shuah
1601426d65aSsm1426032:
161febcc4a5Sjimand	ldxa	[%g7]ASI_MMU_CTX, %g3		/* get pgz | pri-ctx */
162febcc4a5Sjimand	and     %g3, %g4, %g5			/* %g5 = pri-ctx */
1631e2e7a75Shuah	cmp	%g5, INVALID_CONTEXT		/* kernel ctx or invald ctx? */
1641426d65aSsm142603	ble,pn	%xcc, 3f			/* yes, no need to change */
165febcc4a5Sjimand	  srlx	%g3, CTXREG_NEXT_SHIFT, %g3	/* %g3 = nucleus pgsz */
166febcc4a5Sjimand	sllx	%g3, CTXREG_NEXT_SHIFT, %g3	/* need to preserve nucleus pgsz */
167febcc4a5Sjimand	or	%g3, %g2, %g2			/* %g2 = nucleus pgsz | INVALID_CONTEXT */
1681e2e7a75Shuah
1691e2e7a75Shuah	stxa	%g2, [%g7]ASI_MMU_CTX		/* set pri-ctx to invalid */
1701426d65aSsm1426033:
1717c478bd9Sstevel@tonic-gate	retry
1721e2e7a75Shuah	SET_SIZE(sfmmu_raise_tsb_exception)
1737c478bd9Sstevel@tonic-gate
1741426d65aSsm142603
1751426d65aSsm142603
1761e2e7a75Shuah	/*
1771e2e7a75Shuah	 * %o0 = virtual address
1781e2e7a75Shuah	 * %o1 = address of TTE to be loaded
1791e2e7a75Shuah	 */
1801e2e7a75Shuah	ENTRY_NP(sfmmu_itlb_ld_kva)
1817c478bd9Sstevel@tonic-gate	rdpr	%pstate, %o3
1827c478bd9Sstevel@tonic-gate#ifdef DEBUG
1831e2e7a75Shuah	PANIC_IF_INTR_DISABLED_PSTR(%o3, msfmmu_di_l1, %g1)
1847c478bd9Sstevel@tonic-gate#endif /* DEBUG */
1857c478bd9Sstevel@tonic-gate	wrpr	%o3, PSTATE_IE, %pstate		! Disable interrupts
1867c478bd9Sstevel@tonic-gate	srln	%o0, MMU_PAGESHIFT, %o0
1877c478bd9Sstevel@tonic-gate	slln	%o0, MMU_PAGESHIFT, %o0		! Clear page offset
1881e2e7a75Shuah
1891e2e7a75Shuah	ldx	[%o1], %g1
1907c478bd9Sstevel@tonic-gate	set	MMU_TAG_ACCESS, %o5
1917c478bd9Sstevel@tonic-gate#ifdef	CHEETAHPLUS_ERRATUM_34
1927c478bd9Sstevel@tonic-gate	!
1937c478bd9Sstevel@tonic-gate	! If this is Cheetah or derivative and the specified TTE is locked
1947c478bd9Sstevel@tonic-gate	! and hence to be loaded into the T16, fully-associative TLB, we
1957c478bd9Sstevel@tonic-gate	! must avoid Cheetah+ erratum 34.  In Cheetah+ erratum 34, under
1967c478bd9Sstevel@tonic-gate	! certain conditions an ITLB locked index 0 TTE will erroneously be
1977c478bd9Sstevel@tonic-gate	! displaced when a new TTE is loaded via ASI_ITLB_IN.  To avoid
1987c478bd9Sstevel@tonic-gate	! this erratum, we scan the T16 top down for an unlocked TTE and
1997c478bd9Sstevel@tonic-gate	! explicitly load the specified TTE into that index.
2007c478bd9Sstevel@tonic-gate	!
2017c478bd9Sstevel@tonic-gate	GET_CPU_IMPL(%g2)
2027c478bd9Sstevel@tonic-gate	cmp	%g2, CHEETAH_IMPL
2037c478bd9Sstevel@tonic-gate	bl,pn	%icc, 0f
2047c478bd9Sstevel@tonic-gate	  nop
2057c478bd9Sstevel@tonic-gate
2067c478bd9Sstevel@tonic-gate	andcc	%g1, TTE_LCK_INT, %g0
2077c478bd9Sstevel@tonic-gate	bz	%icc, 0f			! Lock bit is not set;
2087c478bd9Sstevel@tonic-gate						!   load normally.
2097c478bd9Sstevel@tonic-gate	  or	%g0, (15 << 3), %g3		! Start searching from the
2107c478bd9Sstevel@tonic-gate						!   top down.
2117c478bd9Sstevel@tonic-gate
2127c478bd9Sstevel@tonic-gate1:
2137c478bd9Sstevel@tonic-gate	ldxa	[%g3]ASI_ITLB_ACCESS, %g4	! Load TTE from t16
2147c478bd9Sstevel@tonic-gate
2157c478bd9Sstevel@tonic-gate	!
2167c478bd9Sstevel@tonic-gate	! If this entry isn't valid, we'll choose to displace it (regardless
2177c478bd9Sstevel@tonic-gate	! of the lock bit).
2187c478bd9Sstevel@tonic-gate	!
2197c478bd9Sstevel@tonic-gate	cmp	%g4, %g0
2207c478bd9Sstevel@tonic-gate	bge	%xcc, 2f			! TTE is > 0 iff not valid
2217c478bd9Sstevel@tonic-gate	  andcc	%g4, TTE_LCK_INT, %g0		! Check for lock bit
2227c478bd9Sstevel@tonic-gate	bz	%icc, 2f			! If unlocked, go displace
2237c478bd9Sstevel@tonic-gate	  nop
2247c478bd9Sstevel@tonic-gate	sub	%g3, (1 << 3), %g3
2257c478bd9Sstevel@tonic-gate	brgz	%g3, 1b				! Still more TLB entries
2267c478bd9Sstevel@tonic-gate	  nop					! to search
2277c478bd9Sstevel@tonic-gate
2287c478bd9Sstevel@tonic-gate	sethi   %hi(sfmmu_panic5), %o0          ! We searched all entries and
2297c478bd9Sstevel@tonic-gate	call    panic                           ! found no unlocked TTE so
2307c478bd9Sstevel@tonic-gate	  or    %o0, %lo(sfmmu_panic5), %o0     ! give up.
2317c478bd9Sstevel@tonic-gate
2327c478bd9Sstevel@tonic-gate
2337c478bd9Sstevel@tonic-gate2:
2347c478bd9Sstevel@tonic-gate	!
2357c478bd9Sstevel@tonic-gate	! We have found an unlocked or non-valid entry; we'll explicitly load
2367c478bd9Sstevel@tonic-gate	! our locked entry here.
2377c478bd9Sstevel@tonic-gate	!
2387c478bd9Sstevel@tonic-gate	sethi	%hi(FLUSH_ADDR), %o1		! Flush addr doesn't matter
2397c478bd9Sstevel@tonic-gate	stxa	%o0, [%o5]ASI_IMMU
2407c478bd9Sstevel@tonic-gate	stxa	%g1, [%g3]ASI_ITLB_ACCESS
2417c478bd9Sstevel@tonic-gate	flush	%o1				! Flush required for I-MMU
2427c478bd9Sstevel@tonic-gate	ba	3f				! Delay slot of ba is empty
2437c478bd9Sstevel@tonic-gate	  nop					!   per Erratum 64
2447c478bd9Sstevel@tonic-gate
2457c478bd9Sstevel@tonic-gate0:
2467c478bd9Sstevel@tonic-gate#endif	/* CHEETAHPLUS_ERRATUM_34 */
2477c478bd9Sstevel@tonic-gate	sethi	%hi(FLUSH_ADDR), %o1		! Flush addr doesn't matter
2487c478bd9Sstevel@tonic-gate	stxa	%o0, [%o5]ASI_IMMU
2497c478bd9Sstevel@tonic-gate	stxa	%g1, [%g0]ASI_ITLB_IN
2507c478bd9Sstevel@tonic-gate	flush	%o1				! Flush required for I-MMU
2517c478bd9Sstevel@tonic-gate3:
2527c478bd9Sstevel@tonic-gate	retl
2537c478bd9Sstevel@tonic-gate	  wrpr	%g0, %o3, %pstate		! Enable interrupts
2541e2e7a75Shuah	SET_SIZE(sfmmu_itlb_ld_kva)
2557c478bd9Sstevel@tonic-gate
2567c478bd9Sstevel@tonic-gate	/*
2577c478bd9Sstevel@tonic-gate	 * Load an entry into the DTLB.
2587c478bd9Sstevel@tonic-gate	 *
2597c478bd9Sstevel@tonic-gate	 * Special handling is required for locked entries since there
2607c478bd9Sstevel@tonic-gate	 * are some TLB slots that are reserved for the kernel but not
2617c478bd9Sstevel@tonic-gate	 * always held locked.  We want to avoid loading locked TTEs
2627c478bd9Sstevel@tonic-gate	 * into those slots since they could be displaced.
2631e2e7a75Shuah	 *
2641e2e7a75Shuah	 * %o0 = virtual address
2651e2e7a75Shuah	 * %o1 = address of TTE to be loaded
2667c478bd9Sstevel@tonic-gate	 */
2671e2e7a75Shuah	ENTRY_NP(sfmmu_dtlb_ld_kva)
2687c478bd9Sstevel@tonic-gate	rdpr	%pstate, %o3
2697c478bd9Sstevel@tonic-gate#ifdef DEBUG
2701e2e7a75Shuah	PANIC_IF_INTR_DISABLED_PSTR(%o3, msfmmu_di_l2, %g1)
2717c478bd9Sstevel@tonic-gate#endif /* DEBUG */
2727c478bd9Sstevel@tonic-gate	wrpr	%o3, PSTATE_IE, %pstate		! disable interrupts
2737c478bd9Sstevel@tonic-gate	srln	%o0, MMU_PAGESHIFT, %o0
2747c478bd9Sstevel@tonic-gate	slln	%o0, MMU_PAGESHIFT, %o0		! clear page offset
2751e2e7a75Shuah
2761e2e7a75Shuah	ldx	[%o1], %g1
2771e2e7a75Shuah
2787c478bd9Sstevel@tonic-gate	set	MMU_TAG_ACCESS, %o5
2791e2e7a75Shuah
2801e2e7a75Shuah	set	cpu_impl_dual_pgsz, %o2
2811e2e7a75Shuah	ld	[%o2], %o2
2821e2e7a75Shuah	brz	%o2, 1f
2831e2e7a75Shuah	  nop
2841e2e7a75Shuah
2851e2e7a75Shuah	sethi	%hi(ksfmmup), %o2
2861e2e7a75Shuah	ldx	[%o2 + %lo(ksfmmup)], %o2
2871e2e7a75Shuah	ldub    [%o2 + SFMMU_CEXT], %o2
2881e2e7a75Shuah        sll     %o2, TAGACCEXT_SHIFT, %o2
2891e2e7a75Shuah
2907c478bd9Sstevel@tonic-gate	set	MMU_TAG_ACCESS_EXT, %o4		! can go into T8 if unlocked
2917c478bd9Sstevel@tonic-gate	stxa	%o2,[%o4]ASI_DMMU
2927c478bd9Sstevel@tonic-gate	membar	#Sync
2937c478bd9Sstevel@tonic-gate1:
2947c478bd9Sstevel@tonic-gate	andcc	%g1, TTE_LCK_INT, %g0		! Locked entries require
2957c478bd9Sstevel@tonic-gate	bnz,pn	%icc, 2f			! special handling
2967c478bd9Sstevel@tonic-gate	  sethi	%hi(dtlb_resv_ttenum), %g3
2977c478bd9Sstevel@tonic-gate	stxa	%o0,[%o5]ASI_DMMU		! Load unlocked TTE
2987c478bd9Sstevel@tonic-gate	stxa	%g1,[%g0]ASI_DTLB_IN		! via DTLB_IN
2997c478bd9Sstevel@tonic-gate	membar	#Sync
3007c478bd9Sstevel@tonic-gate	retl
3017c478bd9Sstevel@tonic-gate	  wrpr	%g0, %o3, %pstate		! enable interrupts
3027c478bd9Sstevel@tonic-gate2:
303*19f938d5Sjfrank#ifdef	CHEETAHPLUS_ERRATUM_34
304*19f938d5Sjfrank	GET_CPU_IMPL(%g2)
305*19f938d5Sjfrank#endif
3067c478bd9Sstevel@tonic-gate	ld	[%g3 + %lo(dtlb_resv_ttenum)], %g3
3077c478bd9Sstevel@tonic-gate	sll	%g3, 3, %g3			! First reserved idx in TLB 0
3087c478bd9Sstevel@tonic-gate	sub	%g3, (1 << 3), %g3		! Decrement idx
309*19f938d5Sjfrank	! Erratum 15 workaround due to ld [%g3 + %lo(dtlb_resv_ttenum)], %g3
310*19f938d5Sjfrank	ldxa	[%g3]ASI_DTLB_ACCESS, %g4	! Load TTE from TLB 0
3117c478bd9Sstevel@tonic-gate3:
3127c478bd9Sstevel@tonic-gate	ldxa	[%g3]ASI_DTLB_ACCESS, %g4	! Load TTE from TLB 0
3137c478bd9Sstevel@tonic-gate	!
3147c478bd9Sstevel@tonic-gate	! If this entry isn't valid, we'll choose to displace it (regardless
3157c478bd9Sstevel@tonic-gate	! of the lock bit).
3167c478bd9Sstevel@tonic-gate	!
3177c478bd9Sstevel@tonic-gate	brgez,pn %g4, 4f			! TTE is > 0 iff not valid
3187c478bd9Sstevel@tonic-gate	  nop
3197c478bd9Sstevel@tonic-gate	andcc	%g4, TTE_LCK_INT, %g0		! Check for lock bit
3207c478bd9Sstevel@tonic-gate	bz,pn	%icc, 4f			! If unlocked, go displace
3217c478bd9Sstevel@tonic-gate	  nop
3227c478bd9Sstevel@tonic-gate	sub	%g3, (1 << 3), %g3		! Decrement idx
323*19f938d5Sjfrank#ifdef	CHEETAHPLUS_ERRATUM_34
324*19f938d5Sjfrank	!
325*19f938d5Sjfrank	! If this is a Cheetah or derivative, we must work around Erratum 34
326*19f938d5Sjfrank	! for the DTLB.  Erratum 34 states that under certain conditions,
327*19f938d5Sjfrank	! a locked entry 0 TTE may be improperly displaced.  To avoid this,
328*19f938d5Sjfrank	! we do not place a locked TTE in entry 0.
329*19f938d5Sjfrank	!
330*19f938d5Sjfrank	brgz	%g3, 3b
331*19f938d5Sjfrank	  nop
332*19f938d5Sjfrank	cmp	%g2, CHEETAH_IMPL
333*19f938d5Sjfrank	bge,pt	%icc, 5f
334*19f938d5Sjfrank	  nop
335*19f938d5Sjfrank	brz	%g3, 3b
336*19f938d5Sjfrank	 nop
337*19f938d5Sjfrank#else	/* CHEETAHPLUS_ERRATUM_34 */
3387c478bd9Sstevel@tonic-gate	brgez	%g3, 3b
3397c478bd9Sstevel@tonic-gate	  nop
340*19f938d5Sjfrank#endif	/* CHEETAHPLUS_ERRATUM_34 */
341*19f938d5Sjfrank5:
3427c478bd9Sstevel@tonic-gate	sethi	%hi(sfmmu_panic5), %o0		! We searched all entries and
3437c478bd9Sstevel@tonic-gate	call	panic				! found no unlocked TTE so
3447c478bd9Sstevel@tonic-gate	  or	%o0, %lo(sfmmu_panic5), %o0	! give up.
3457c478bd9Sstevel@tonic-gate4:
3467c478bd9Sstevel@tonic-gate	stxa	%o0,[%o5]ASI_DMMU		! Setup tag access
34725cf1a30Sjl139090#ifdef	OLYMPUS_SHARED_FTLB
34825cf1a30Sjl139090	stxa	%g1,[%g0]ASI_DTLB_IN
34925cf1a30Sjl139090#else
3507c478bd9Sstevel@tonic-gate	stxa	%g1,[%g3]ASI_DTLB_ACCESS	! Displace entry at idx
35125cf1a30Sjl139090#endif
3527c478bd9Sstevel@tonic-gate	membar	#Sync
3537c478bd9Sstevel@tonic-gate	retl
3547c478bd9Sstevel@tonic-gate	  wrpr	%g0, %o3, %pstate		! enable interrupts
3551e2e7a75Shuah	SET_SIZE(sfmmu_dtlb_ld_kva)
3567c478bd9Sstevel@tonic-gate
3577c478bd9Sstevel@tonic-gate	ENTRY_NP(sfmmu_getctx_pri)
3587c478bd9Sstevel@tonic-gate	set	MMU_PCONTEXT, %o0
3597c478bd9Sstevel@tonic-gate	retl
3607c478bd9Sstevel@tonic-gate	  ldxa	[%o0]ASI_MMU_CTX, %o0
3617c478bd9Sstevel@tonic-gate	SET_SIZE(sfmmu_getctx_pri)
3627c478bd9Sstevel@tonic-gate
3637c478bd9Sstevel@tonic-gate	ENTRY_NP(sfmmu_getctx_sec)
3647c478bd9Sstevel@tonic-gate	set	MMU_SCONTEXT, %o0
3657c478bd9Sstevel@tonic-gate	set	CTXREG_CTX_MASK, %o1
3667c478bd9Sstevel@tonic-gate	ldxa	[%o0]ASI_MMU_CTX, %o0
3677c478bd9Sstevel@tonic-gate	retl
3687c478bd9Sstevel@tonic-gate	  and	%o0, %o1, %o0
3697c478bd9Sstevel@tonic-gate	SET_SIZE(sfmmu_getctx_sec)
3707c478bd9Sstevel@tonic-gate
3717c478bd9Sstevel@tonic-gate	/*
3727c478bd9Sstevel@tonic-gate	 * Set the secondary context register for this process.
3731e2e7a75Shuah	 * %o0 = page_size | context number for this process.
3747c478bd9Sstevel@tonic-gate	 */
3757c478bd9Sstevel@tonic-gate	ENTRY_NP(sfmmu_setctx_sec)
3767c478bd9Sstevel@tonic-gate	/*
3777c478bd9Sstevel@tonic-gate	 * From resume we call sfmmu_setctx_sec with interrupts disabled.
3787c478bd9Sstevel@tonic-gate	 * But we can also get called from C with interrupts enabled. So,
3791e2e7a75Shuah	 * we need to check first.
3807c478bd9Sstevel@tonic-gate	 */
3817c478bd9Sstevel@tonic-gate
3827c478bd9Sstevel@tonic-gate	/* If interrupts are not disabled, then disable them */
3837c478bd9Sstevel@tonic-gate	rdpr	%pstate, %g1
3847c478bd9Sstevel@tonic-gate	btst	PSTATE_IE, %g1
3857c478bd9Sstevel@tonic-gate	bnz,a,pt %icc, 1f
3867c478bd9Sstevel@tonic-gate	  wrpr	%g1, PSTATE_IE, %pstate		/* disable interrupts */
3871e2e7a75Shuah
3887c478bd9Sstevel@tonic-gate1:
3897c478bd9Sstevel@tonic-gate	mov	MMU_SCONTEXT, %o1
3901e2e7a75Shuah
3917c478bd9Sstevel@tonic-gate	sethi	%hi(FLUSH_ADDR), %o4
3927c478bd9Sstevel@tonic-gate	stxa	%o0, [%o1]ASI_MMU_CTX		/* set 2nd context reg. */
3937c478bd9Sstevel@tonic-gate	flush	%o4
3941426d65aSsm142603        sethi   %hi(shctx_on), %g3
3951426d65aSsm142603        ld      [%g3 + %lo(shctx_on)], %g3
3961426d65aSsm142603	brz     %g3, 2f
3971426d65aSsm142603	  nop
3981426d65aSsm142603	set	CTXREG_CTX_MASK, %o4
3991426d65aSsm142603	and	%o0,%o4,%o1
4001426d65aSsm142603	cmp	%o1, INVALID_CONTEXT
4011426d65aSsm142603	bne,pn %icc, 2f
4021426d65aSsm142603   	  mov     MMU_SHARED_CONTEXT, %o1
4031426d65aSsm142603        sethi   %hi(FLUSH_ADDR), %o4
4041426d65aSsm142603        stxa    %g0, [%o1]ASI_MMU_CTX           /* set 2nd context reg. */
4051426d65aSsm142603        flush   %o4
4067c478bd9Sstevel@tonic-gate
4071e2e7a75Shuah	/*
4081e2e7a75Shuah	 * if the routine was entered with intr enabled, then enable intr now.
4091e2e7a75Shuah	 * otherwise, keep intr disabled, return without enabing intr.
4101e2e7a75Shuah	 * %g1 - old intr state
4111e2e7a75Shuah	 */
4121426d65aSsm1426032:	btst	PSTATE_IE, %g1
4131426d65aSsm142603	bnz,a,pt %icc, 3f
4147c478bd9Sstevel@tonic-gate	  wrpr	%g0, %g1, %pstate		/* enable interrupts */
4151426d65aSsm1426033:	retl
4167c478bd9Sstevel@tonic-gate	  nop
4177c478bd9Sstevel@tonic-gate	SET_SIZE(sfmmu_setctx_sec)
4187c478bd9Sstevel@tonic-gate
4197c478bd9Sstevel@tonic-gate	/*
4207c478bd9Sstevel@tonic-gate	 * set ktsb_phys to 1 if the processor supports ASI_QUAD_LDD_PHYS.
4217c478bd9Sstevel@tonic-gate	 * returns the detection value in %o0.
42225cf1a30Sjl139090	 *
42325cf1a30Sjl139090	 * Currently ASI_QUAD_LDD_PHYS is supported in processors as follows
42425cf1a30Sjl139090	 *  - cheetah+ and later (greater or equal to CHEETAH_PLUS_IMPL)
42525cf1a30Sjl139090	 *  - FJ OPL Olympus-C and later  (less than SPITFIRE_IMPL)
42625cf1a30Sjl139090	 *
4277c478bd9Sstevel@tonic-gate	 */
4287c478bd9Sstevel@tonic-gate	ENTRY_NP(sfmmu_setup_4lp)
4297c478bd9Sstevel@tonic-gate	GET_CPU_IMPL(%o0);
4307c478bd9Sstevel@tonic-gate	cmp	%o0, CHEETAH_PLUS_IMPL
43125cf1a30Sjl139090	bge,pt	%icc, 4f
4327c478bd9Sstevel@tonic-gate	  mov	1, %o1
43325cf1a30Sjl139090	cmp	%o0, SPITFIRE_IMPL
43425cf1a30Sjl139090	bge,a,pn %icc, 3f
43525cf1a30Sjl139090	  clr	%o1
43625cf1a30Sjl1390904:
43725cf1a30Sjl139090	set	ktsb_phys, %o2
4387c478bd9Sstevel@tonic-gate	st	%o1, [%o2]
43925cf1a30Sjl1390903:	retl
4407c478bd9Sstevel@tonic-gate	mov	%o1, %o0
4417c478bd9Sstevel@tonic-gate	SET_SIZE(sfmmu_setup_4lp)
4427c478bd9Sstevel@tonic-gate
4437c478bd9Sstevel@tonic-gate
4447c478bd9Sstevel@tonic-gate	/*
4457c478bd9Sstevel@tonic-gate	 * Called to load MMU registers and tsbmiss area
4467c478bd9Sstevel@tonic-gate	 * for the active process.  This function should
4477c478bd9Sstevel@tonic-gate	 * only be called from TL=0.
4487c478bd9Sstevel@tonic-gate	 *
4497c478bd9Sstevel@tonic-gate	 * %o0 - hat pointer
4501426d65aSsm142603	 *
4517c478bd9Sstevel@tonic-gate	 */
4527c478bd9Sstevel@tonic-gate	ENTRY_NP(sfmmu_load_mmustate)
4531e2e7a75Shuah
4541e2e7a75Shuah#ifdef DEBUG
4551e2e7a75Shuah        PANIC_IF_INTR_ENABLED_PSTR(msfmmu_ei_l3, %g1)
4561e2e7a75Shuah#endif /* DEBUG */
4577c478bd9Sstevel@tonic-gate
4587c478bd9Sstevel@tonic-gate        sethi   %hi(ksfmmup), %o3
4597c478bd9Sstevel@tonic-gate        ldx     [%o3 + %lo(ksfmmup)], %o3
4607c478bd9Sstevel@tonic-gate        cmp     %o3, %o0
4611426d65aSsm142603        be,pn   %xcc, 8f			! if kernel as, do nothing
4627c478bd9Sstevel@tonic-gate          nop
4637c478bd9Sstevel@tonic-gate        /*
4647c478bd9Sstevel@tonic-gate         * We need to set up the TSB base register, tsbmiss
4657c478bd9Sstevel@tonic-gate         * area, and load locked TTE(s) for the TSB.
4667c478bd9Sstevel@tonic-gate         */
4677c478bd9Sstevel@tonic-gate        ldx     [%o0 + SFMMU_TSB], %o1          ! %o1 = first tsbinfo
4687c478bd9Sstevel@tonic-gate        ldx     [%o1 + TSBINFO_NEXTPTR], %g2    ! %g2 = second tsbinfo
46925cf1a30Sjl139090
47025cf1a30Sjl139090#ifdef UTSB_PHYS
47125cf1a30Sjl139090        /*
47225cf1a30Sjl139090         * UTSB_PHYS accesses user TSBs via physical addresses.  The first
4731426d65aSsm142603         * TSB is in the MMU I/D TSB Base registers.  The 2nd, 3rd and
4741426d65aSsm142603	 * 4th TSBs use designated ASI_SCRATCHPAD regs as pseudo TSB base regs.
47525cf1a30Sjl139090	 */
4761426d65aSsm142603
4771426d65aSsm142603        /* create/set first UTSBREG actually loaded into MMU_TSB  */
4781426d65aSsm142603        MAKE_UTSBREG(%o1, %o2, %o3)             ! %o2 = first utsbreg
47925cf1a30Sjl139090 	LOAD_TSBREG(%o2, %o3, %o4)              ! write TSB base register
48025cf1a30Sjl139090
48125cf1a30Sjl139090        brz,a,pt  %g2, 2f
48225cf1a30Sjl139090          mov   -1, %o2                         ! use -1 if no second TSB
48325cf1a30Sjl139090
4841426d65aSsm142603        MAKE_UTSBREG(%g2, %o2, %o3)             ! %o2 = second utsbreg
48525cf1a30Sjl1390902:
4861426d65aSsm142603        SET_UTSBREG(SCRATCHPAD_UTSBREG2, %o2, %o3)
4871426d65aSsm142603
4881426d65aSsm142603	/* make 3rd and 4th TSB */
4891426d65aSsm142603	CPU_TSBMISS_AREA(%o4, %o3) 		! %o4 = tsbmiss area
4901426d65aSsm142603
4911426d65aSsm142603        ldx     [%o0 + SFMMU_SCDP], %g2         ! %g2 = sfmmu_scd
4921426d65aSsm142603        brz,pt  %g2, 3f
4931426d65aSsm142603          mov   -1, %o2                         ! use -1 if no third TSB
4941426d65aSsm142603
4951426d65aSsm142603        ldx     [%g2 + SCD_SFMMUP], %g3         ! %g3 = scdp->scd_sfmmup
4961426d65aSsm142603        ldx     [%g3 + SFMMU_TSB], %o1          ! %o1 = first scd tsbinfo
4971426d65aSsm142603        brz,pn %o1, 5f
4981426d65aSsm142603          nop                                   ! panic if no third TSB
4991426d65aSsm142603
5001426d65aSsm142603	/* make 3rd UTSBREG */
5011426d65aSsm142603        MAKE_UTSBREG(%o1, %o2, %o3)             ! %o2 = third utsbreg
5021426d65aSsm1426033:
5031426d65aSsm142603        SET_UTSBREG(SCRATCHPAD_UTSBREG3, %o2, %o3)
5041426d65aSsm142603	stn	%o2, [%o4 + TSBMISS_TSBSCDPTR]
5051426d65aSsm142603
5061426d65aSsm142603        brz,pt  %g2, 4f
5071426d65aSsm142603          mov   -1, %o2                         ! use -1 if no 3rd or 4th TSB
5081426d65aSsm142603
5091426d65aSsm142603        ldx     [%o1 + TSBINFO_NEXTPTR], %g2    ! %g2 = second scd tsbinfo
5101426d65aSsm142603        brz,pt  %g2, 4f
5111426d65aSsm142603          mov   -1, %o2                         ! use -1 if no 4th TSB
5121426d65aSsm142603
5131426d65aSsm142603	/* make 4th UTSBREG */
5141426d65aSsm142603        MAKE_UTSBREG(%g2, %o2, %o3)             ! %o2 = fourth utsbreg
5151426d65aSsm1426034:
5161426d65aSsm142603        SET_UTSBREG(SCRATCHPAD_UTSBREG4, %o2, %o3)
5171426d65aSsm142603	stn	%o2, [%o4 + TSBMISS_TSBSCDPTR4M]
5181426d65aSsm142603	ba,pt	%icc, 6f
5191426d65aSsm142603	  mov	%o4, %o2			! %o2 = tsbmiss area
5201426d65aSsm1426035:
5211426d65aSsm142603        sethi   %hi(panicstr), %g1              ! panic if no 3rd TSB
5221426d65aSsm142603        ldx     [%g1 + %lo(panicstr)], %g1
5231426d65aSsm142603        tst     %g1
5241426d65aSsm142603
5251426d65aSsm142603        bnz,pn  %xcc, 8f
5261426d65aSsm142603          nop
5271426d65aSsm142603
5281426d65aSsm142603        sethi   %hi(sfmmu_panic10), %o0
5291426d65aSsm142603        call    panic
5301426d65aSsm142603          or     %o0, %lo(sfmmu_panic10), %o0
5311426d65aSsm142603
5321426d65aSsm142603#else /* UTSBREG_PHYS */
5331426d65aSsm142603
5347c478bd9Sstevel@tonic-gate        brz,pt  %g2, 4f
5357c478bd9Sstevel@tonic-gate          nop
5367c478bd9Sstevel@tonic-gate        /*
5377c478bd9Sstevel@tonic-gate         * We have a second TSB for this process, so we need to
5387c478bd9Sstevel@tonic-gate         * encode data for both the first and second TSB in our single
5397c478bd9Sstevel@tonic-gate         * TSB base register.  See hat_sfmmu.h for details on what bits
5407c478bd9Sstevel@tonic-gate         * correspond to which TSB.
5417c478bd9Sstevel@tonic-gate         * We also need to load a locked TTE into the TLB for the second TSB
5427c478bd9Sstevel@tonic-gate         * in this case.
5437c478bd9Sstevel@tonic-gate         */
5447c478bd9Sstevel@tonic-gate        MAKE_TSBREG_SECTSB(%o2, %o1, %g2, %o3, %o4, %g3, sfmmu_tsb_2nd)
5457c478bd9Sstevel@tonic-gate        ! %o2 = tsbreg
5467c478bd9Sstevel@tonic-gate        sethi   %hi(utsb4m_dtlb_ttenum), %o3
5477c478bd9Sstevel@tonic-gate        sethi   %hi(utsb4m_vabase), %o4
5487c478bd9Sstevel@tonic-gate        ld      [%o3 + %lo(utsb4m_dtlb_ttenum)], %o3
5497c478bd9Sstevel@tonic-gate        ldx     [%o4 + %lo(utsb4m_vabase)], %o4 ! %o4 = TLB tag for sec TSB
5507c478bd9Sstevel@tonic-gate        sll     %o3, DTACC_SHIFT, %o3           ! %o3 = sec TSB TLB index
5517c478bd9Sstevel@tonic-gate        RESV_OFFSET(%g2, %o4, %g3, sfmmu_tsb_2nd)       ! or-in bits of TSB VA
5527c478bd9Sstevel@tonic-gate        LOAD_TSBTTE(%g2, %o3, %o4, %g3)         ! load sec TSB locked TTE
5537c478bd9Sstevel@tonic-gate        sethi   %hi(utsb_vabase), %g3
5547c478bd9Sstevel@tonic-gate        ldx     [%g3 + %lo(utsb_vabase)], %g3   ! %g3 = TLB tag for first TSB
5557c478bd9Sstevel@tonic-gate        ba,pt   %xcc, 5f
5567c478bd9Sstevel@tonic-gate          nop
5577c478bd9Sstevel@tonic-gate
5587c478bd9Sstevel@tonic-gate4:      sethi   %hi(utsb_vabase), %g3
5597c478bd9Sstevel@tonic-gate        ldx     [%g3 + %lo(utsb_vabase)], %g3   ! %g3 = TLB tag for first TSB
5607c478bd9Sstevel@tonic-gate        MAKE_TSBREG(%o2, %o1, %g3, %o3, %o4, sfmmu_tsb_1st)     ! %o2 = tsbreg
5617c478bd9Sstevel@tonic-gate
5627c478bd9Sstevel@tonic-gate5:      LOAD_TSBREG(%o2, %o3, %o4)              ! write TSB base register
5637c478bd9Sstevel@tonic-gate
5647c478bd9Sstevel@tonic-gate        /*
5657c478bd9Sstevel@tonic-gate         * Load the TTE for the first TSB at the appropriate location in
5667c478bd9Sstevel@tonic-gate         * the TLB
5677c478bd9Sstevel@tonic-gate         */
5687c478bd9Sstevel@tonic-gate        sethi   %hi(utsb_dtlb_ttenum), %o2
5697c478bd9Sstevel@tonic-gate        ld      [%o2 + %lo(utsb_dtlb_ttenum)], %o2
5707c478bd9Sstevel@tonic-gate        sll     %o2, DTACC_SHIFT, %o2           ! %o1 = first TSB TLB index
5717c478bd9Sstevel@tonic-gate        RESV_OFFSET(%o1, %g3, %o3, sfmmu_tsb_1st)       ! or-in bits of TSB VA
5727c478bd9Sstevel@tonic-gate        LOAD_TSBTTE(%o1, %o2, %g3, %o4)         ! load first TSB locked TTE
5731426d65aSsm142603	CPU_TSBMISS_AREA(%o2, %o3)
57425cf1a30Sjl139090#endif /* UTSB_PHYS */
5751426d65aSsm1426036:
5761426d65aSsm142603	ldx     [%o0 + SFMMU_ISMBLKPA], %o1     ! copy members of sfmmu
5771426d65aSsm142603	              				! we need to access from
5787c478bd9Sstevel@tonic-gate        stx     %o1, [%o2 + TSBMISS_ISMBLKPA]   ! sfmmu_tsb_miss into the
57905d3dc4bSpaulsan        ldub    [%o0 + SFMMU_TTEFLAGS], %o3     ! per-CPU tsbmiss area.
5807c478bd9Sstevel@tonic-gate        stx     %o0, [%o2 + TSBMISS_UHATID]
58105d3dc4bSpaulsan        stub    %o3, [%o2 + TSBMISS_UTTEFLAGS]
5821426d65aSsm142603#ifdef UTSB_PHYS
5831426d65aSsm142603        ldx     [%o0 + SFMMU_SRDP], %o1
5841426d65aSsm142603        ldub    [%o0 + SFMMU_RTTEFLAGS], %o4
5851426d65aSsm142603        stub    %o4,  [%o2 + TSBMISS_URTTEFLAGS]
5861426d65aSsm142603        stx     %o1, [%o2 +  TSBMISS_SHARED_UHATID]
5871426d65aSsm142603        brz,pn  %o1, 8f				! check for sfmmu_srdp
5881426d65aSsm142603          add   %o0, SFMMU_HMERMAP, %o1
5891426d65aSsm142603        add     %o2, TSBMISS_SHMERMAP, %o2
5901426d65aSsm142603        mov     SFMMU_HMERGNMAP_WORDS, %o3
5911426d65aSsm142603                                                ! set tsbmiss shmermap
5921426d65aSsm142603        SET_REGION_MAP(%o1, %o2, %o3, %o4, load_shme_mmustate)
5937c478bd9Sstevel@tonic-gate
5941426d65aSsm142603	ldx     [%o0 + SFMMU_SCDP], %o4         ! %o4 = sfmmu_scd
5951426d65aSsm142603        CPU_TSBMISS_AREA(%o2, %o3)              ! %o2 = tsbmiss area
5961426d65aSsm142603        mov     SFMMU_HMERGNMAP_WORDS, %o3
5971426d65aSsm142603        brnz,pt %o4, 7f                       ! check for sfmmu_scdp else
5981426d65aSsm142603          add   %o2, TSBMISS_SCDSHMERMAP, %o2 ! zero tsbmiss scd_shmermap
5991426d65aSsm142603        ZERO_REGION_MAP(%o2, %o3, zero_scd_mmustate)
6001426d65aSsm142603	ba 8f
6011426d65aSsm142603	  nop
6021426d65aSsm1426037:
6031426d65aSsm142603        add     %o4, SCD_HMERMAP, %o1
6041426d65aSsm142603        SET_REGION_MAP(%o1, %o2, %o3, %o4, load_scd_mmustate)
6051426d65aSsm142603#endif /* UTSB_PHYS */
6061426d65aSsm142603
6071426d65aSsm1426038:
6081426d65aSsm142603	retl
6097c478bd9Sstevel@tonic-gate          nop
6107c478bd9Sstevel@tonic-gate        SET_SIZE(sfmmu_load_mmustate)
6117c478bd9Sstevel@tonic-gate
6127c478bd9Sstevel@tonic-gate#endif /* lint */
6137c478bd9Sstevel@tonic-gate
6147c478bd9Sstevel@tonic-gate#if defined (lint)
6157c478bd9Sstevel@tonic-gate/*
6167c478bd9Sstevel@tonic-gate * Invalidate all of the entries within the tsb, by setting the inv bit
6177c478bd9Sstevel@tonic-gate * in the tte_tag field of each tsbe.
6187c478bd9Sstevel@tonic-gate *
6197c478bd9Sstevel@tonic-gate * We take advantage of the fact TSBs are page aligned and a multiple of
6207c478bd9Sstevel@tonic-gate * PAGESIZE to use block stores.
6217c478bd9Sstevel@tonic-gate *
6227c478bd9Sstevel@tonic-gate * See TSB_LOCK_ENTRY and the miss handlers for how this works in practice
6237c478bd9Sstevel@tonic-gate * (in short, we set all bits in the upper word of the tag, and we give the
6247c478bd9Sstevel@tonic-gate * invalid bit precedence over other tag bits in both places).
6257c478bd9Sstevel@tonic-gate */
6267c478bd9Sstevel@tonic-gate/* ARGSUSED */
6277c478bd9Sstevel@tonic-gatevoid
6287c478bd9Sstevel@tonic-gatesfmmu_inv_tsb_fast(caddr_t tsb_base, uint_t tsb_bytes)
6297c478bd9Sstevel@tonic-gate{}
6307c478bd9Sstevel@tonic-gate
6317c478bd9Sstevel@tonic-gate#else /* lint */
6327c478bd9Sstevel@tonic-gate
6337c478bd9Sstevel@tonic-gate#define	VIS_BLOCKSIZE	64
6347c478bd9Sstevel@tonic-gate
6357c478bd9Sstevel@tonic-gate	ENTRY(sfmmu_inv_tsb_fast)
6367c478bd9Sstevel@tonic-gate
6377c478bd9Sstevel@tonic-gate	! Get space for aligned block of saved fp regs.
6387c478bd9Sstevel@tonic-gate	save	%sp, -SA(MINFRAME + 2*VIS_BLOCKSIZE), %sp
6397c478bd9Sstevel@tonic-gate
6407c478bd9Sstevel@tonic-gate	! kpreempt_disable();
6417c478bd9Sstevel@tonic-gate	ldsb	[THREAD_REG + T_PREEMPT], %l3
6427c478bd9Sstevel@tonic-gate	inc	%l3
6437c478bd9Sstevel@tonic-gate	stb	%l3, [THREAD_REG + T_PREEMPT]
6447c478bd9Sstevel@tonic-gate
6457c478bd9Sstevel@tonic-gate	! See if fpu was in use.  If it was, we need to save off the
6467c478bd9Sstevel@tonic-gate	! floating point registers to the stack.
6477c478bd9Sstevel@tonic-gate	rd	%fprs, %l0			! %l0 = cached copy of fprs
6487c478bd9Sstevel@tonic-gate	btst	FPRS_FEF, %l0
6497c478bd9Sstevel@tonic-gate	bz,pt	%icc, 4f
6507c478bd9Sstevel@tonic-gate	  nop
6517c478bd9Sstevel@tonic-gate
6527c478bd9Sstevel@tonic-gate	! save in-use fpregs on stack
6537c478bd9Sstevel@tonic-gate	membar	#Sync				! make sure tranx to fp regs
6547c478bd9Sstevel@tonic-gate						! have completed
6557c478bd9Sstevel@tonic-gate	add	%fp, STACK_BIAS - 65, %l1	! get stack frame for fp regs
6567c478bd9Sstevel@tonic-gate	and	%l1, -VIS_BLOCKSIZE, %l1	! block align frame
6577c478bd9Sstevel@tonic-gate	stda	%d0, [%l1]ASI_BLK_P		! %l1 = addr of saved fp regs
6587c478bd9Sstevel@tonic-gate
6597c478bd9Sstevel@tonic-gate	! enable fp
6607c478bd9Sstevel@tonic-gate4:	membar	#StoreStore|#StoreLoad|#LoadStore
6617c478bd9Sstevel@tonic-gate	wr	%g0, FPRS_FEF, %fprs
6627c478bd9Sstevel@tonic-gate	wr	%g0, ASI_BLK_P, %asi
6637c478bd9Sstevel@tonic-gate
6647c478bd9Sstevel@tonic-gate	! load up FP registers with invalid TSB tag.
6657c478bd9Sstevel@tonic-gate	fone	%d0			! ones in tag
6667c478bd9Sstevel@tonic-gate	fzero	%d2			! zeros in TTE
6677c478bd9Sstevel@tonic-gate	fone	%d4			! ones in tag
6687c478bd9Sstevel@tonic-gate	fzero	%d6			! zeros in TTE
6697c478bd9Sstevel@tonic-gate	fone	%d8			! ones in tag
6707c478bd9Sstevel@tonic-gate	fzero	%d10			! zeros in TTE
6717c478bd9Sstevel@tonic-gate	fone	%d12			! ones in tag
6727c478bd9Sstevel@tonic-gate	fzero	%d14			! zeros in TTE
6737c478bd9Sstevel@tonic-gate	ba,pt	%xcc, .sfmmu_inv_doblock
6747c478bd9Sstevel@tonic-gate	  mov	(4*VIS_BLOCKSIZE), %i4	! we do 4 stda's each loop below
6757c478bd9Sstevel@tonic-gate
6767c478bd9Sstevel@tonic-gate.sfmmu_inv_blkstart:
6777c478bd9Sstevel@tonic-gate      ! stda	%d0, [%i0+192]%asi  ! in dly slot of branch that got us here
6787c478bd9Sstevel@tonic-gate	stda	%d0, [%i0+128]%asi
6797c478bd9Sstevel@tonic-gate	stda	%d0, [%i0+64]%asi
6807c478bd9Sstevel@tonic-gate	stda	%d0, [%i0]%asi
6817c478bd9Sstevel@tonic-gate
6827c478bd9Sstevel@tonic-gate	add	%i0, %i4, %i0
6837c478bd9Sstevel@tonic-gate	sub	%i1, %i4, %i1
6847c478bd9Sstevel@tonic-gate
6857c478bd9Sstevel@tonic-gate.sfmmu_inv_doblock:
6867c478bd9Sstevel@tonic-gate	cmp	%i1, (4*VIS_BLOCKSIZE)	! check for completion
6877c478bd9Sstevel@tonic-gate	bgeu,a	%icc, .sfmmu_inv_blkstart
6887c478bd9Sstevel@tonic-gate	  stda	%d0, [%i0+192]%asi
6897c478bd9Sstevel@tonic-gate
6907c478bd9Sstevel@tonic-gate.sfmmu_inv_finish:
6917c478bd9Sstevel@tonic-gate	membar	#Sync
6927c478bd9Sstevel@tonic-gate	btst	FPRS_FEF, %l0		! saved from above
6937c478bd9Sstevel@tonic-gate	bz,a	.sfmmu_inv_finished
6947c478bd9Sstevel@tonic-gate	  wr	%l0, 0, %fprs		! restore fprs
6957c478bd9Sstevel@tonic-gate
6967c478bd9Sstevel@tonic-gate	! restore fpregs from stack
6977c478bd9Sstevel@tonic-gate	ldda    [%l1]ASI_BLK_P, %d0
6987c478bd9Sstevel@tonic-gate	membar	#Sync
6997c478bd9Sstevel@tonic-gate	wr	%l0, 0, %fprs		! restore fprs
7007c478bd9Sstevel@tonic-gate
7017c478bd9Sstevel@tonic-gate.sfmmu_inv_finished:
7027c478bd9Sstevel@tonic-gate	! kpreempt_enable();
7037c478bd9Sstevel@tonic-gate	ldsb	[THREAD_REG + T_PREEMPT], %l3
7047c478bd9Sstevel@tonic-gate	dec	%l3
7057c478bd9Sstevel@tonic-gate	stb	%l3, [THREAD_REG + T_PREEMPT]
7067c478bd9Sstevel@tonic-gate	ret
7077c478bd9Sstevel@tonic-gate	  restore
7087c478bd9Sstevel@tonic-gate	SET_SIZE(sfmmu_inv_tsb_fast)
7097c478bd9Sstevel@tonic-gate
7107c478bd9Sstevel@tonic-gate#endif /* lint */
7117c478bd9Sstevel@tonic-gate
7127c478bd9Sstevel@tonic-gate#if defined(lint)
7137c478bd9Sstevel@tonic-gate
7147c478bd9Sstevel@tonic-gate/*
7157c478bd9Sstevel@tonic-gate * Prefetch "struct tsbe" while walking TSBs.
7167c478bd9Sstevel@tonic-gate * prefetch 7 cache lines ahead of where we are at now.
7177c478bd9Sstevel@tonic-gate * #n_reads is being used since #one_read only applies to
7187c478bd9Sstevel@tonic-gate * floating point reads, and we are not doing floating point
7197c478bd9Sstevel@tonic-gate * reads.  However, this has the negative side effect of polluting
7207c478bd9Sstevel@tonic-gate * the ecache.
7217c478bd9Sstevel@tonic-gate * The 448 comes from (7 * 64) which is how far ahead of our current
7227c478bd9Sstevel@tonic-gate * address, we want to prefetch.
7237c478bd9Sstevel@tonic-gate */
7247c478bd9Sstevel@tonic-gate/*ARGSUSED*/
7257c478bd9Sstevel@tonic-gatevoid
7267c478bd9Sstevel@tonic-gateprefetch_tsbe_read(struct tsbe *tsbep)
7277c478bd9Sstevel@tonic-gate{}
7287c478bd9Sstevel@tonic-gate
7297c478bd9Sstevel@tonic-gate/* Prefetch the tsbe that we are about to write */
7307c478bd9Sstevel@tonic-gate/*ARGSUSED*/
7317c478bd9Sstevel@tonic-gatevoid
7327c478bd9Sstevel@tonic-gateprefetch_tsbe_write(struct tsbe *tsbep)
7337c478bd9Sstevel@tonic-gate{}
7347c478bd9Sstevel@tonic-gate
7357c478bd9Sstevel@tonic-gate#else /* lint */
7367c478bd9Sstevel@tonic-gate
7377c478bd9Sstevel@tonic-gate	ENTRY(prefetch_tsbe_read)
7387c478bd9Sstevel@tonic-gate	retl
7397c478bd9Sstevel@tonic-gate	  prefetch	[%o0+448], #n_reads
7407c478bd9Sstevel@tonic-gate	SET_SIZE(prefetch_tsbe_read)
7417c478bd9Sstevel@tonic-gate
7427c478bd9Sstevel@tonic-gate	ENTRY(prefetch_tsbe_write)
7437c478bd9Sstevel@tonic-gate	retl
7447c478bd9Sstevel@tonic-gate	  prefetch	[%o0], #n_writes
7457c478bd9Sstevel@tonic-gate	SET_SIZE(prefetch_tsbe_write)
7467c478bd9Sstevel@tonic-gate#endif /* lint */
7477c478bd9Sstevel@tonic-gate
748