xref: /titanic_50/usr/src/uts/sun4v/vm/mach_sfmmu_asm.s (revision 9d0d62ad2e60e8f742a2e723d06e88352ee6a1f3)
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/*
22125be069SJason Beloro * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate/*
277c478bd9Sstevel@tonic-gate * SFMMU primitives.  These primitives should only be used by sfmmu
287c478bd9Sstevel@tonic-gate * routines.
297c478bd9Sstevel@tonic-gate */
307c478bd9Sstevel@tonic-gate
317c478bd9Sstevel@tonic-gate#if defined(lint)
327c478bd9Sstevel@tonic-gate#include <sys/types.h>
337c478bd9Sstevel@tonic-gate#else	/* lint */
347c478bd9Sstevel@tonic-gate#include "assym.h"
357c478bd9Sstevel@tonic-gate#endif	/* lint */
367c478bd9Sstevel@tonic-gate
377c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h>
387c478bd9Sstevel@tonic-gate#include <sys/machtrap.h>
397c478bd9Sstevel@tonic-gate#include <sys/machasi.h>
407c478bd9Sstevel@tonic-gate#include <sys/sun4asi.h>
417c478bd9Sstevel@tonic-gate#include <sys/pte.h>
427c478bd9Sstevel@tonic-gate#include <sys/mmu.h>
437c478bd9Sstevel@tonic-gate#include <vm/hat_sfmmu.h>
447c478bd9Sstevel@tonic-gate#include <vm/seg_spt.h>
457c478bd9Sstevel@tonic-gate#include <sys/machparam.h>
467c478bd9Sstevel@tonic-gate#include <sys/privregs.h>
477c478bd9Sstevel@tonic-gate#include <sys/scb.h>
487c478bd9Sstevel@tonic-gate#include <sys/intreg.h>
497c478bd9Sstevel@tonic-gate#include <sys/machthread.h>
507c478bd9Sstevel@tonic-gate#include <sys/clock.h>
517c478bd9Sstevel@tonic-gate#include <sys/trapstat.h>
527c478bd9Sstevel@tonic-gate
537c478bd9Sstevel@tonic-gate/*
547c478bd9Sstevel@tonic-gate * sfmmu related subroutines
557c478bd9Sstevel@tonic-gate */
567c478bd9Sstevel@tonic-gate
577c478bd9Sstevel@tonic-gate#if defined (lint)
587c478bd9Sstevel@tonic-gate
597c478bd9Sstevel@tonic-gate/* ARGSUSED */
607c478bd9Sstevel@tonic-gatevoid
611e2e7a75Shuahsfmmu_raise_tsb_exception(uint64_t sfmmup, uint64_t rctx)
627c478bd9Sstevel@tonic-gate{}
637c478bd9Sstevel@tonic-gate
647c478bd9Sstevel@tonic-gateint
657c478bd9Sstevel@tonic-gatesfmmu_getctx_pri()
667c478bd9Sstevel@tonic-gate{ return(0); }
677c478bd9Sstevel@tonic-gate
687c478bd9Sstevel@tonic-gateint
697c478bd9Sstevel@tonic-gatesfmmu_getctx_sec()
707c478bd9Sstevel@tonic-gate{ return(0); }
717c478bd9Sstevel@tonic-gate
727c478bd9Sstevel@tonic-gate/* ARGSUSED */
737c478bd9Sstevel@tonic-gatevoid
7405d3dc4bSpaulsansfmmu_setctx_sec(uint_t ctx)
757c478bd9Sstevel@tonic-gate{}
767c478bd9Sstevel@tonic-gate
777c478bd9Sstevel@tonic-gate/* ARGSUSED */
787c478bd9Sstevel@tonic-gatevoid
797c478bd9Sstevel@tonic-gatesfmmu_load_mmustate(sfmmu_t *sfmmup)
80*9d0d62adSJason Beloro{
81*9d0d62adSJason Beloro}
827c478bd9Sstevel@tonic-gate
837c478bd9Sstevel@tonic-gate#else	/* lint */
847c478bd9Sstevel@tonic-gate
857c478bd9Sstevel@tonic-gate/*
861e2e7a75Shuah * Invalidate either the context of a specific victim or any process
871e2e7a75Shuah * currently running on this CPU.
887c478bd9Sstevel@tonic-gate *
891e2e7a75Shuah * %g1 = sfmmup whose ctx is being stolen (victim)
901e2e7a75Shuah *	 when called from sfmmu_wrap_around, %g1 == INVALID_CONTEXT.
911e2e7a75Shuah * Note %g1 is the only input argument used by this xcall handler.
927c478bd9Sstevel@tonic-gate */
937c478bd9Sstevel@tonic-gate
941e2e7a75Shuah	ENTRY(sfmmu_raise_tsb_exception)
957c478bd9Sstevel@tonic-gate	!
961e2e7a75Shuah	! if (victim == INVALID_CONTEXT) {
971e2e7a75Shuah	!	if (sec-ctx > INVALID_CONTEXT)
981e2e7a75Shuah	!		write INVALID_CONTEXT to sec-ctx
991e2e7a75Shuah	!	if (pri-ctx > INVALID_CONTEXT)
1001e2e7a75Shuah	!		write INVALID_CONTEXT to pri-ctx
1017c478bd9Sstevel@tonic-gate	!
1021e2e7a75Shuah	! } else if (current CPU tsbmiss->usfmmup != victim sfmmup) {
1037c478bd9Sstevel@tonic-gate	!	return
1047c478bd9Sstevel@tonic-gate	! } else {
1051e2e7a75Shuah	!	if (sec-ctx > INVALID_CONTEXT)
1067c478bd9Sstevel@tonic-gate	!		write INVALID_CONTEXT to sec-ctx
1071e2e7a75Shuah	!
1081e2e7a75Shuah	!	if (pri-ctx > INVALID_CONTEXT)
1097c478bd9Sstevel@tonic-gate	!		write INVALID_CONTEXT to pri-ctx
1107c478bd9Sstevel@tonic-gate	! }
1117c478bd9Sstevel@tonic-gate	!
1121e2e7a75Shuah
1131e2e7a75Shuah	sethi   %hi(ksfmmup), %g3
1141e2e7a75Shuah	ldx	[%g3 + %lo(ksfmmup)], %g3
1151e2e7a75Shuah	cmp	%g1, %g3
1161e2e7a75Shuah	be,a,pn %xcc, ptl1_panic	/* can't invalidate kernel ctx */
1171e2e7a75Shuah	  mov	PTL1_BAD_RAISE_TSBEXCP, %g1
1181e2e7a75Shuah
1191e2e7a75Shuah	set	INVALID_CONTEXT, %g2
1201e2e7a75Shuah
1211e2e7a75Shuah	cmp	%g1, INVALID_CONTEXT
1221e2e7a75Shuah	bne,pt	%xcc, 1f			/* called from wrap_around? */
1231e2e7a75Shuah	  mov	MMU_SCONTEXT, %g3
1241e2e7a75Shuah
1251e2e7a75Shuah	ldxa	[%g3]ASI_MMU_CTX, %g5		/* %g5 = sec-ctx */
1261e2e7a75Shuah	cmp	%g5, INVALID_CONTEXT		/* kernel  or invalid ctx ? */
1271e2e7a75Shuah	ble,pn	%xcc, 0f			/* yes, no need to change */
1287c478bd9Sstevel@tonic-gate	  mov	MMU_PCONTEXT, %g7
1291e2e7a75Shuah
1301e2e7a75Shuah	stxa	%g2, [%g3]ASI_MMU_CTX		/* set invalid ctx */
1317c478bd9Sstevel@tonic-gate	membar	#Sync
1321e2e7a75Shuah
1331e2e7a75Shuah0:
1341e2e7a75Shuah	ldxa	[%g7]ASI_MMU_CTX, %g5		/* %g5 = pri-ctx */
1351e2e7a75Shuah	cmp	%g5, INVALID_CONTEXT		/* kernel or invalid ctx? */
1361e2e7a75Shuah	ble,pn	%xcc, 6f			/* yes, no need to change */
1377c478bd9Sstevel@tonic-gate	  nop
1381e2e7a75Shuah
1391e2e7a75Shuah	stxa	%g2, [%g7]ASI_MMU_CTX		/* set pri-ctx to invalid  */
1407c478bd9Sstevel@tonic-gate	membar	#Sync
1411e2e7a75Shuah
1421e2e7a75Shuah6:	/* flushall tlb */
1431e2e7a75Shuah	mov	%o0, %g3
1441e2e7a75Shuah	mov	%o1, %g4
1451e2e7a75Shuah	mov	%o2, %g6
1461e2e7a75Shuah	mov	%o5, %g7
1471e2e7a75Shuah
1481e2e7a75Shuah        mov     %g0, %o0        ! XXX no cpu list yet
1491e2e7a75Shuah        mov     %g0, %o1        ! XXX no cpu list yet
1501e2e7a75Shuah        mov     MAP_ITLB | MAP_DTLB, %o2
1511e2e7a75Shuah        mov     MMU_DEMAP_ALL, %o5
1521e2e7a75Shuah        ta      FAST_TRAP
1531e2e7a75Shuah        brz,pt  %o0, 5f
1541e2e7a75Shuah          nop
15505d3dc4bSpaulsan     	ba ptl1_panic		/* bad HV call */
15605d3dc4bSpaulsan	  mov	PTL1_BAD_RAISE_TSBEXCP, %g1
1571e2e7a75Shuah5:
1581e2e7a75Shuah	mov	%g3, %o0
1591e2e7a75Shuah	mov	%g4, %o1
1601e2e7a75Shuah	mov	%g6, %o2
1611e2e7a75Shuah	mov	%g7, %o5
1621e2e7a75Shuah
1631e2e7a75Shuah	ba	3f
1641e2e7a75Shuah	  nop
1651e2e7a75Shuah1:
1661e2e7a75Shuah	/*
1671e2e7a75Shuah	 * %g1 = sfmmup
1681e2e7a75Shuah	 * %g2 = INVALID_CONTEXT
1691e2e7a75Shuah	 * %g3 = MMU_SCONTEXT
1701e2e7a75Shuah	 */
1711e2e7a75Shuah	CPU_TSBMISS_AREA(%g5, %g6)		/* load cpu tsbmiss area */
1721e2e7a75Shuah	ldx	[%g5 + TSBMISS_UHATID], %g5     /* load usfmmup */
1731e2e7a75Shuah
1741e2e7a75Shuah	cmp	%g5, %g1			/* is it the victim? */
1751e2e7a75Shuah	bne,pt	%xcc, 2f			/* is our sec-ctx a victim? */
1761e2e7a75Shuah	  nop
1771e2e7a75Shuah
1781e2e7a75Shuah	ldxa    [%g3]ASI_MMU_CTX, %g5           /* %g5 = sec-ctx */
1791e2e7a75Shuah	cmp     %g5, INVALID_CONTEXT            /* kernel  or invalid ctx ? */
1801e2e7a75Shuah	ble,pn  %xcc, 0f                        /* yes, no need to change */
1811e2e7a75Shuah	  mov	MMU_PCONTEXT, %g7
1821e2e7a75Shuah
1831e2e7a75Shuah	stxa	%g2, [%g3]ASI_MMU_CTX		/* set sec-ctx to invalid */
1841e2e7a75Shuah	membar	#Sync
1851e2e7a75Shuah
1861e2e7a75Shuah0:
1871e2e7a75Shuah	ldxa	[%g7]ASI_MMU_CTX, %g4		/* %g4 = pri-ctx */
1881e2e7a75Shuah	cmp	%g4, INVALID_CONTEXT		/* is pri-ctx the victim? */
1891e2e7a75Shuah	ble 	%icc, 3f			/* no need to change pri-ctx */
1901e2e7a75Shuah	  nop
1911e2e7a75Shuah	stxa	%g2, [%g7]ASI_MMU_CTX		/* set pri-ctx to invalid  */
1921e2e7a75Shuah	membar	#Sync
1931e2e7a75Shuah
1941e2e7a75Shuah3:
1957c478bd9Sstevel@tonic-gate	/* TSB program must be cleared - walkers do not check a context. */
1967c478bd9Sstevel@tonic-gate	mov	%o0, %g3
1977c478bd9Sstevel@tonic-gate	mov	%o1, %g4
1987c478bd9Sstevel@tonic-gate	mov	%o5, %g7
1997c478bd9Sstevel@tonic-gate	clr	%o0
2007c478bd9Sstevel@tonic-gate	clr	%o1
2017c478bd9Sstevel@tonic-gate	mov	MMU_TSB_CTXNON0, %o5
2027c478bd9Sstevel@tonic-gate	ta	FAST_TRAP
2037c478bd9Sstevel@tonic-gate	brnz,a,pn %o0, ptl1_panic
2047c478bd9Sstevel@tonic-gate	  mov	PTL1_BAD_HCALL, %g1
2057c478bd9Sstevel@tonic-gate	mov	%g3, %o0
2067c478bd9Sstevel@tonic-gate	mov	%g4, %o1
2077c478bd9Sstevel@tonic-gate	mov	%g7, %o5
2087c478bd9Sstevel@tonic-gate2:
2097c478bd9Sstevel@tonic-gate	retry
2101e2e7a75Shuah	SET_SIZE(sfmmu_raise_tsb_exception)
2117c478bd9Sstevel@tonic-gate
2127c478bd9Sstevel@tonic-gate	ENTRY_NP(sfmmu_getctx_pri)
2137c478bd9Sstevel@tonic-gate	set	MMU_PCONTEXT, %o0
2147c478bd9Sstevel@tonic-gate	retl
2159c7f0c79Sarutz	ldxa	[%o0]ASI_MMU_CTX, %o0
2167c478bd9Sstevel@tonic-gate	SET_SIZE(sfmmu_getctx_pri)
2177c478bd9Sstevel@tonic-gate
2187c478bd9Sstevel@tonic-gate	ENTRY_NP(sfmmu_getctx_sec)
2197c478bd9Sstevel@tonic-gate	set	MMU_SCONTEXT, %o0
2207c478bd9Sstevel@tonic-gate	retl
2219c7f0c79Sarutz	ldxa	[%o0]ASI_MMU_CTX, %o0
2227c478bd9Sstevel@tonic-gate	SET_SIZE(sfmmu_getctx_sec)
2237c478bd9Sstevel@tonic-gate
2247c478bd9Sstevel@tonic-gate	/*
2257c478bd9Sstevel@tonic-gate	 * Set the secondary context register for this process.
2261e2e7a75Shuah	 * %o0 = context number
2277c478bd9Sstevel@tonic-gate	 */
2287c478bd9Sstevel@tonic-gate	ENTRY_NP(sfmmu_setctx_sec)
2297c478bd9Sstevel@tonic-gate	/*
2307c478bd9Sstevel@tonic-gate	 * From resume we call sfmmu_setctx_sec with interrupts disabled.
2317c478bd9Sstevel@tonic-gate	 * But we can also get called from C with interrupts enabled. So,
2321e2e7a75Shuah	 * we need to check first.
2337c478bd9Sstevel@tonic-gate	 */
2347c478bd9Sstevel@tonic-gate
2357c478bd9Sstevel@tonic-gate	/* If interrupts are not disabled, then disable them */
2367c478bd9Sstevel@tonic-gate	rdpr	%pstate, %g1
2377c478bd9Sstevel@tonic-gate	btst	PSTATE_IE, %g1
2387c478bd9Sstevel@tonic-gate	bnz,a,pt %icc, 1f
2397c478bd9Sstevel@tonic-gate	wrpr	%g1, PSTATE_IE, %pstate		/* disable interrupts */
2407c478bd9Sstevel@tonic-gate1:
2417c478bd9Sstevel@tonic-gate	mov	MMU_SCONTEXT, %o1
2427c478bd9Sstevel@tonic-gate	stxa	%o0, [%o1]ASI_MMU_CTX		/* set 2nd context reg. */
2432f0fcb93SJason Beloro	membar	#Sync
2441e2e7a75Shuah        /*
2451e2e7a75Shuah         * if the routine is entered with intr enabled, then enable intr now.
2461e2e7a75Shuah         * otherwise, keep intr disabled, return without enabing intr.
2471e2e7a75Shuah         * %g1 - old intr state
2481e2e7a75Shuah         */
2497c478bd9Sstevel@tonic-gate        btst    PSTATE_IE, %g1
2501e2e7a75Shuah        bnz,a,pt %icc, 2f
2517c478bd9Sstevel@tonic-gate        wrpr    %g0, %g1, %pstate               /* enable interrupts */
2521e2e7a75Shuah2:      retl
2537c478bd9Sstevel@tonic-gate        nop
2547c478bd9Sstevel@tonic-gate        SET_SIZE(sfmmu_setctx_sec)
2557c478bd9Sstevel@tonic-gate
2567c478bd9Sstevel@tonic-gate	/*
2577c478bd9Sstevel@tonic-gate	 * set ktsb_phys to 1 if the processor supports ASI_QUAD_LDD_PHYS.
2587c478bd9Sstevel@tonic-gate	 * returns the detection value in %o0.
2597c478bd9Sstevel@tonic-gate	 */
2607c478bd9Sstevel@tonic-gate	ENTRY_NP(sfmmu_setup_4lp)
2617c478bd9Sstevel@tonic-gate	set	ktsb_phys, %o2
2627c478bd9Sstevel@tonic-gate	mov	1, %o1
2637c478bd9Sstevel@tonic-gate	st	%o1, [%o2]
2647c478bd9Sstevel@tonic-gate	retl
2657c478bd9Sstevel@tonic-gate	mov	%o1, %o0
2667c478bd9Sstevel@tonic-gate	SET_SIZE(sfmmu_setup_4lp)
2677c478bd9Sstevel@tonic-gate
2687c478bd9Sstevel@tonic-gate	/*
2697c478bd9Sstevel@tonic-gate	 * Called to load MMU registers and tsbmiss area
2707c478bd9Sstevel@tonic-gate	 * for the active process.  This function should
2717c478bd9Sstevel@tonic-gate	 * only be called from TL=0.
2727c478bd9Sstevel@tonic-gate	 *
2737c478bd9Sstevel@tonic-gate	 * %o0 - hat pointer
2747c478bd9Sstevel@tonic-gate	 */
2757c478bd9Sstevel@tonic-gate	ENTRY_NP(sfmmu_load_mmustate)
2761e2e7a75Shuah
2771e2e7a75Shuah#ifdef DEBUG
2781e2e7a75Shuah	PANIC_IF_INTR_ENABLED_PSTR(msfmmu_ei_l1, %g1)
2791e2e7a75Shuah#endif /* DEBUG */
2807c478bd9Sstevel@tonic-gate
2817c478bd9Sstevel@tonic-gate	sethi	%hi(ksfmmup), %o3
2827c478bd9Sstevel@tonic-gate	ldx	[%o3 + %lo(ksfmmup)], %o3
2837c478bd9Sstevel@tonic-gate	cmp	%o3, %o0
284*9d0d62adSJason Beloro	be,pn	%xcc, 7f			! if kernel as, do nothing
2857c478bd9Sstevel@tonic-gate	  nop
2867c478bd9Sstevel@tonic-gate
28705d3dc4bSpaulsan	set     MMU_SCONTEXT, %o3
28805d3dc4bSpaulsan        ldxa    [%o3]ASI_MMU_CTX, %o5
28905d3dc4bSpaulsan
29005d3dc4bSpaulsan	cmp	%o5, INVALID_CONTEXT		! ctx is invalid?
29105d3dc4bSpaulsan	bne,pt	%icc, 1f
29205d3dc4bSpaulsan	  nop
29305d3dc4bSpaulsan
29405d3dc4bSpaulsan	CPU_TSBMISS_AREA(%o2, %o3)		! %o2 = tsbmiss area
29505d3dc4bSpaulsan	stx	%o0, [%o2 + TSBMISS_UHATID]
29605d3dc4bSpaulsan	stx	%g0, [%o2 +  TSBMISS_SHARED_UHATID]
29705d3dc4bSpaulsan#ifdef DEBUG
29805d3dc4bSpaulsan	/* check if hypervisor/hardware should handle user TSB */
29905d3dc4bSpaulsan	sethi	%hi(hv_use_non0_tsb), %o2
30005d3dc4bSpaulsan	ld	[%o2 + %lo(hv_use_non0_tsb)], %o2
30105d3dc4bSpaulsan	brz,pn	%o2, 0f
30205d3dc4bSpaulsan	  nop
30305d3dc4bSpaulsan#endif /* DEBUG */
30405d3dc4bSpaulsan	clr	%o0				! ntsb = 0 for invalid ctx
30505d3dc4bSpaulsan	clr	%o1				! HV_TSB_INFO_PA = 0 if inv ctx
30605d3dc4bSpaulsan	mov	MMU_TSB_CTXNON0, %o5
30705d3dc4bSpaulsan	ta	FAST_TRAP			! set TSB info for user process
30805d3dc4bSpaulsan	brnz,a,pn %o0, panic_bad_hcall
30905d3dc4bSpaulsan	  mov	MMU_TSB_CTXNON0, %o1
31005d3dc4bSpaulsan0:
31105d3dc4bSpaulsan	retl
31205d3dc4bSpaulsan	  nop
31305d3dc4bSpaulsan1:
3147c478bd9Sstevel@tonic-gate	/*
3157c478bd9Sstevel@tonic-gate	 * We need to set up the TSB base register, tsbmiss
3167c478bd9Sstevel@tonic-gate	 * area, and pass the TSB information into the hypervisor
3177c478bd9Sstevel@tonic-gate	 */
3187c478bd9Sstevel@tonic-gate	ldx	[%o0 + SFMMU_TSB], %o1		! %o1 = first tsbinfo
3197c478bd9Sstevel@tonic-gate	ldx	[%o1 + TSBINFO_NEXTPTR], %g2	! %g2 = second tsbinfo
3207c478bd9Sstevel@tonic-gate
3217c478bd9Sstevel@tonic-gate	/* create/set first UTSBREG */
3227c478bd9Sstevel@tonic-gate	MAKE_UTSBREG(%o1, %o2, %o3)		! %o2 = user tsbreg
3237c478bd9Sstevel@tonic-gate	SET_UTSBREG(SCRATCHPAD_UTSBREG1, %o2, %o3)
3247c478bd9Sstevel@tonic-gate
3257c478bd9Sstevel@tonic-gate	brz,pt	%g2, 2f
3267c478bd9Sstevel@tonic-gate	  mov	-1, %o2				! use -1 if no second TSB
3277c478bd9Sstevel@tonic-gate
3287c478bd9Sstevel@tonic-gate	/* make 2nd UTSBREG */
3297c478bd9Sstevel@tonic-gate	MAKE_UTSBREG(%g2, %o2, %o3)		! %o2 = user tsbreg
3307c478bd9Sstevel@tonic-gate2:
3317c478bd9Sstevel@tonic-gate	SET_UTSBREG(SCRATCHPAD_UTSBREG2, %o2, %o3)
3327c478bd9Sstevel@tonic-gate
33305d3dc4bSpaulsan        /* make 3rd and 4th TSB */
33405d3dc4bSpaulsan	CPU_TSBMISS_AREA(%o4, %o3)		! %o4 = tsbmiss area
33505d3dc4bSpaulsan
33605d3dc4bSpaulsan	ldx	[%o0 + SFMMU_SCDP], %g2		! %g2 = sfmmu_scd
33705d3dc4bSpaulsan	brz,pt	%g2, 3f
33805d3dc4bSpaulsan	  mov	-1, %o2				! use -1 if no third TSB
33905d3dc4bSpaulsan
34005d3dc4bSpaulsan	ldx	[%g2 + SCD_SFMMUP], %g3		! %g3 = scdp->scd_sfmmup
34105d3dc4bSpaulsan	ldx	[%g3 + SFMMU_TSB], %o1		! %o1 = first scd tsbinfo
342*9d0d62adSJason Beloro	brz,pn %o1, 9f
34305d3dc4bSpaulsan	  nop					! panic if no third TSB
34405d3dc4bSpaulsan
34505d3dc4bSpaulsan	/* make 3rd UTSBREG */
34605d3dc4bSpaulsan	MAKE_UTSBREG(%o1, %o2, %o3)		! %o2 = user tsbreg
34705d3dc4bSpaulsan3:
34805d3dc4bSpaulsan	SET_UTSBREG_SHCTX(%o4, TSBMISS_TSBSCDPTR, %o2)
34905d3dc4bSpaulsan
35005d3dc4bSpaulsan	brz,pt	%g2, 4f
35105d3dc4bSpaulsan	  mov	-1, %o2				! use -1 if no 3rd or 4th TSB
35205d3dc4bSpaulsan
35305d3dc4bSpaulsan	brz,pt	%o1, 4f
35405d3dc4bSpaulsan	  mov	-1, %o2				! use -1 if no 3rd or 4th TSB
35505d3dc4bSpaulsan	ldx	[%o1 + TSBINFO_NEXTPTR], %g2	! %g2 = second scd tsbinfo
35605d3dc4bSpaulsan	brz,pt	%g2, 4f
35705d3dc4bSpaulsan	  mov	-1, %o2				! use -1 if no 4th TSB
35805d3dc4bSpaulsan
35905d3dc4bSpaulsan	/* make 4th UTSBREG */
36005d3dc4bSpaulsan	MAKE_UTSBREG(%g2, %o2, %o3)		! %o2 = user tsbreg
36105d3dc4bSpaulsan4:
36205d3dc4bSpaulsan	SET_UTSBREG_SHCTX(%o4, TSBMISS_TSBSCDPTR4M, %o2)
36305d3dc4bSpaulsan
3647c478bd9Sstevel@tonic-gate#ifdef DEBUG
3657c478bd9Sstevel@tonic-gate	/* check if hypervisor/hardware should handle user TSB */
3667c478bd9Sstevel@tonic-gate	sethi	%hi(hv_use_non0_tsb), %o2
3677c478bd9Sstevel@tonic-gate	ld	[%o2 + %lo(hv_use_non0_tsb)], %o2
36805d3dc4bSpaulsan	brz,pn	%o2, 6f
3697c478bd9Sstevel@tonic-gate	  nop
3707c478bd9Sstevel@tonic-gate#endif /* DEBUG */
3717c478bd9Sstevel@tonic-gate	CPU_ADDR(%o2, %o4)	! load CPU struct addr to %o2 using %o4
3727c478bd9Sstevel@tonic-gate	ldub    [%o2 + CPU_TSTAT_FLAGS], %o1	! load cpu_tstat_flag to %o1
3731e2e7a75Shuah
3747c478bd9Sstevel@tonic-gate	mov	%o0, %o3			! preserve %o0
3757c478bd9Sstevel@tonic-gate	btst	TSTAT_TLB_STATS, %o1
37605d3dc4bSpaulsan	bnz,a,pn %icc, 5f			! ntsb = 0 if TLB stats enabled
3777c478bd9Sstevel@tonic-gate	  clr	%o0
37805d3dc4bSpaulsan
3797c478bd9Sstevel@tonic-gate	ldx	[%o3 + SFMMU_HVBLOCK + HV_TSB_INFO_CNT], %o0
38005d3dc4bSpaulsan5:
3817c478bd9Sstevel@tonic-gate	ldx	[%o3 + SFMMU_HVBLOCK + HV_TSB_INFO_PA], %o1
3827c478bd9Sstevel@tonic-gate	mov	MMU_TSB_CTXNON0, %o5
3837c478bd9Sstevel@tonic-gate	ta	FAST_TRAP			! set TSB info for user process
3847c478bd9Sstevel@tonic-gate	brnz,a,pn %o0, panic_bad_hcall
3857c478bd9Sstevel@tonic-gate	mov	MMU_TSB_CTXNON0, %o1
386*9d0d62adSJason Beloro	mov	%o3, %o0			! restore %o0
38705d3dc4bSpaulsan6:
3887c478bd9Sstevel@tonic-gate	ldx	[%o0 + SFMMU_ISMBLKPA], %o1	! copy members of sfmmu
38905d3dc4bSpaulsan	CPU_TSBMISS_AREA(%o2, %o3)		! %o2 = tsbmiss area
3907c478bd9Sstevel@tonic-gate	stx	%o1, [%o2 + TSBMISS_ISMBLKPA]	! sfmmu_tsb_miss into the
39105d3dc4bSpaulsan	ldub	[%o0 + SFMMU_TTEFLAGS], %o3	! per-CPU tsbmiss area.
39205d3dc4bSpaulsan	ldub	[%o0 + SFMMU_RTTEFLAGS], %o4
39305d3dc4bSpaulsan	ldx	[%o0 + SFMMU_SRDP], %o1
3947c478bd9Sstevel@tonic-gate	stx	%o0, [%o2 + TSBMISS_UHATID]
39505d3dc4bSpaulsan	stub	%o3, [%o2 + TSBMISS_UTTEFLAGS]
39605d3dc4bSpaulsan	stub	%o4,  [%o2 + TSBMISS_URTTEFLAGS]
39705d3dc4bSpaulsan	stx	%o1, [%o2 +  TSBMISS_SHARED_UHATID]
398*9d0d62adSJason Beloro	brz,pn	%o1, 7f				! check for sfmmu_srdp
39905d3dc4bSpaulsan	  add	%o0, SFMMU_HMERMAP, %o1
40005d3dc4bSpaulsan	add	%o2, TSBMISS_SHMERMAP, %o2
40105d3dc4bSpaulsan	mov	SFMMU_HMERGNMAP_WORDS, %o3
40205d3dc4bSpaulsan						! set tsbmiss shmermap
40305d3dc4bSpaulsan	SET_REGION_MAP(%o1, %o2, %o3, %o4, load_shme_mmustate)
4047c478bd9Sstevel@tonic-gate
40505d3dc4bSpaulsan	ldx	[%o0 + SFMMU_SCDP], %o4		! %o4 = sfmmu_scd
40605d3dc4bSpaulsan	CPU_TSBMISS_AREA(%o2, %o3)		! %o2 = tsbmiss area
40705d3dc4bSpaulsan	mov	SFMMU_HMERGNMAP_WORDS, %o3
408*9d0d62adSJason Beloro	brnz,pt	%o4, 8f				! check for sfmmu_scdp else
40905d3dc4bSpaulsan	  add	%o2, TSBMISS_SCDSHMERMAP, %o2	! zero tsbmiss scd_shmermap
41005d3dc4bSpaulsan	ZERO_REGION_MAP(%o2, %o3, zero_scd_mmustate)
411*9d0d62adSJason Beloro7:
412*9d0d62adSJason Beloro	retl
413*9d0d62adSJason Beloro	nop
414*9d0d62adSJason Beloro8:						! set tsbmiss scd_shmermap
415*9d0d62adSJason Beloro	add	%o4, SCD_HMERMAP, %o1
416*9d0d62adSJason Beloro	SET_REGION_MAP(%o1, %o2, %o3, %o4, load_scd_mmustate)
41705d3dc4bSpaulsan	retl
41805d3dc4bSpaulsan	  nop
41905d3dc4bSpaulsan9:
42005d3dc4bSpaulsan	sethi   %hi(panicstr), %g1		! panic if no 3rd TSB
42105d3dc4bSpaulsan        ldx     [%g1 + %lo(panicstr)], %g1
42205d3dc4bSpaulsan        tst     %g1
42305d3dc4bSpaulsan
424*9d0d62adSJason Beloro        bnz,pn  %xcc, 7b
42505d3dc4bSpaulsan          nop
42605d3dc4bSpaulsan
42705d3dc4bSpaulsan        sethi   %hi(sfmmu_panic10), %o0
42805d3dc4bSpaulsan        call    panic
42905d3dc4bSpaulsan          or      %o0, %lo(sfmmu_panic10), %o0
430*9d0d62adSJason Beloro
4317c478bd9Sstevel@tonic-gate	SET_SIZE(sfmmu_load_mmustate)
4327c478bd9Sstevel@tonic-gate
4337c478bd9Sstevel@tonic-gate#endif /* lint */
4347c478bd9Sstevel@tonic-gate
4357c478bd9Sstevel@tonic-gate#if defined(lint)
4367c478bd9Sstevel@tonic-gate
4377c478bd9Sstevel@tonic-gate/* Prefetch "struct tsbe" while walking TSBs */
4387c478bd9Sstevel@tonic-gate/*ARGSUSED*/
4397c478bd9Sstevel@tonic-gatevoid
4407c478bd9Sstevel@tonic-gateprefetch_tsbe_read(struct tsbe *tsbep)
4417c478bd9Sstevel@tonic-gate{}
4427c478bd9Sstevel@tonic-gate
4437c478bd9Sstevel@tonic-gate/* Prefetch the tsbe that we are about to write */
4447c478bd9Sstevel@tonic-gate/*ARGSUSED*/
4457c478bd9Sstevel@tonic-gatevoid
4467c478bd9Sstevel@tonic-gateprefetch_tsbe_write(struct tsbe *tsbep)
4477c478bd9Sstevel@tonic-gate{}
4487c478bd9Sstevel@tonic-gate
4497c478bd9Sstevel@tonic-gate#else /* lint */
4507c478bd9Sstevel@tonic-gate
4517c478bd9Sstevel@tonic-gate	ENTRY(prefetch_tsbe_read)
4527c478bd9Sstevel@tonic-gate	retl
4537c478bd9Sstevel@tonic-gate	nop
4547c478bd9Sstevel@tonic-gate	SET_SIZE(prefetch_tsbe_read)
4557c478bd9Sstevel@tonic-gate
4567c478bd9Sstevel@tonic-gate	ENTRY(prefetch_tsbe_write)
4577c478bd9Sstevel@tonic-gate	retl
4587c478bd9Sstevel@tonic-gate	nop
4597c478bd9Sstevel@tonic-gate	SET_SIZE(prefetch_tsbe_write)
4607c478bd9Sstevel@tonic-gate#endif /* lint */
461