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#include "assym.h"
327c478bd9Sstevel@tonic-gate
337c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h>
347c478bd9Sstevel@tonic-gate#include <sys/machtrap.h>
357c478bd9Sstevel@tonic-gate#include <sys/machasi.h>
367c478bd9Sstevel@tonic-gate#include <sys/sun4asi.h>
377c478bd9Sstevel@tonic-gate#include <sys/pte.h>
387c478bd9Sstevel@tonic-gate#include <sys/mmu.h>
397c478bd9Sstevel@tonic-gate#include <vm/hat_sfmmu.h>
407c478bd9Sstevel@tonic-gate#include <vm/seg_spt.h>
417c478bd9Sstevel@tonic-gate#include <sys/machparam.h>
427c478bd9Sstevel@tonic-gate#include <sys/privregs.h>
437c478bd9Sstevel@tonic-gate#include <sys/scb.h>
447c478bd9Sstevel@tonic-gate#include <sys/intreg.h>
457c478bd9Sstevel@tonic-gate#include <sys/machthread.h>
467c478bd9Sstevel@tonic-gate#include <sys/clock.h>
477c478bd9Sstevel@tonic-gate#include <sys/trapstat.h>
487c478bd9Sstevel@tonic-gate
497c478bd9Sstevel@tonic-gate/*
507c478bd9Sstevel@tonic-gate * sfmmu related subroutines
517c478bd9Sstevel@tonic-gate */
527c478bd9Sstevel@tonic-gate
537c478bd9Sstevel@tonic-gate/*
541e2e7a75Shuah * Invalidate either the context of a specific victim or any process
55*55fea89dSDan Cross * currently running on this CPU.
567c478bd9Sstevel@tonic-gate *
571e2e7a75Shuah * %g1 = sfmmup whose ctx is being stolen (victim)
581e2e7a75Shuah *	 when called from sfmmu_wrap_around, %g1 == INVALID_CONTEXT.
591e2e7a75Shuah * Note %g1 is the only input argument used by this xcall handler.
607c478bd9Sstevel@tonic-gate */
617c478bd9Sstevel@tonic-gate
621e2e7a75Shuah	ENTRY(sfmmu_raise_tsb_exception)
631e2e7a75Shuah	!
641e2e7a75Shuah	! if (victim == INVALID_CONTEXT) {
651e2e7a75Shuah	!	if (sec-ctx > INVALID_CONTEXT)
661e2e7a75Shuah	!		write INVALID_CONTEXT to sec-ctx
67*55fea89dSDan Cross	!	if (pri-ctx > INVALID_CONTEXT)
681e2e7a75Shuah	!		write INVALID_CONTEXT to pri-ctx
691e2e7a75Shuah	!
701e2e7a75Shuah	! } else if (current CPU tsbmiss->usfmmup != victim sfmmup) {
711e2e7a75Shuah	!	return
721e2e7a75Shuah	! } else {
731e2e7a75Shuah	!	if (sec-ctx > INVALID_CONTEXT)
741e2e7a75Shuah	!		write INVALID_CONTEXT to sec-ctx
75*55fea89dSDan Cross	!
761e2e7a75Shuah	!	if (pri-ctx > INVALID_CONTEXT)
771e2e7a75Shuah	!		write INVALID_CONTEXT to pri-ctx
781e2e7a75Shuah	! }
791e2e7a75Shuah	!
801e2e7a75Shuah
811e2e7a75Shuah	sethi   %hi(ksfmmup), %g3
821e2e7a75Shuah	ldx	[%g3 + %lo(ksfmmup)], %g3
831e2e7a75Shuah	cmp	%g1, %g3
841e2e7a75Shuah	be,a,pn %xcc, ptl1_panic	/* can't invalidate kernel ctx */
851e2e7a75Shuah	  mov	PTL1_BAD_RAISE_TSBEXCP, %g1
861e2e7a75Shuah
871e2e7a75Shuah	set	INVALID_CONTEXT, %g2
88*55fea89dSDan Cross
891e2e7a75Shuah	cmp	%g1, INVALID_CONTEXT
901e2e7a75Shuah	bne,pt	%xcc, 1f			/* called from wrap_around? */
911e2e7a75Shuah	  mov	MMU_SCONTEXT, %g3
921e2e7a75Shuah
931e2e7a75Shuah	ldxa	[%g3]ASI_MMU_CTX, %g5		/* %g5 = sec-ctx */
941e2e7a75Shuah	cmp	%g5, INVALID_CONTEXT		/* kernel  or invalid ctx ? */
951e2e7a75Shuah	ble,pn	%xcc, 0f			/* yes, no need to change */
961e2e7a75Shuah	  mov	MMU_PCONTEXT, %g7
97*55fea89dSDan Cross
981e2e7a75Shuah	stxa	%g2, [%g3]ASI_MMU_CTX		/* set invalid ctx */
991e2e7a75Shuah	membar	#Sync
1001e2e7a75Shuah
101*55fea89dSDan Cross0:
1021e2e7a75Shuah	ldxa	[%g7]ASI_MMU_CTX, %g5		/* %g5 = pri-ctx */
1031e2e7a75Shuah	cmp	%g5, INVALID_CONTEXT		/* kernel or invalid ctx? */
1041e2e7a75Shuah	ble,pn	%xcc, 6f			/* yes, no need to change */
1051e2e7a75Shuah	  nop
1061e2e7a75Shuah
1071e2e7a75Shuah	stxa	%g2, [%g7]ASI_MMU_CTX		/* set pri-ctx to invalid  */
1081e2e7a75Shuah	membar	#Sync
1091e2e7a75Shuah
1101e2e7a75Shuah6:	/* flushall tlb */
1117c478bd9Sstevel@tonic-gate	mov	%o0, %g3
1127c478bd9Sstevel@tonic-gate	mov	%o1, %g4
113*55fea89dSDan Cross	mov	%o2, %g6
1147c478bd9Sstevel@tonic-gate	mov	%o5, %g7
1157c478bd9Sstevel@tonic-gate
1161e2e7a75Shuah        mov     %g0, %o0        ! XXX no cpu list yet
1171e2e7a75Shuah        mov     %g0, %o1        ! XXX no cpu list yet
1181e2e7a75Shuah        mov     MAP_ITLB | MAP_DTLB, %o2
1191e2e7a75Shuah        mov     MMU_DEMAP_ALL, %o5
1201e2e7a75Shuah        ta      FAST_TRAP
1211e2e7a75Shuah        brz,pt  %o0, 5f
1221e2e7a75Shuah          nop
12305d3dc4bSpaulsan     	ba ptl1_panic		/* bad HV call */
12405d3dc4bSpaulsan	  mov	PTL1_BAD_RAISE_TSBEXCP, %g1
125*55fea89dSDan Cross5:
1267c478bd9Sstevel@tonic-gate	mov	%g3, %o0
1277c478bd9Sstevel@tonic-gate	mov	%g4, %o1
1281e2e7a75Shuah	mov	%g6, %o2
1297c478bd9Sstevel@tonic-gate	mov	%g7, %o5
130*55fea89dSDan Cross
1311e2e7a75Shuah	ba	3f
1321e2e7a75Shuah	  nop
1331e2e7a75Shuah1:
1347c478bd9Sstevel@tonic-gate	/*
1351e2e7a75Shuah	 * %g1 = sfmmup
1361e2e7a75Shuah	 * %g2 = INVALID_CONTEXT
1371e2e7a75Shuah	 * %g3 = MMU_SCONTEXT
1387c478bd9Sstevel@tonic-gate	 */
1391e2e7a75Shuah	CPU_TSBMISS_AREA(%g5, %g6)		/* load cpu tsbmiss area */
1401e2e7a75Shuah	ldx	[%g5 + TSBMISS_UHATID], %g5     /* load usfmmup */
1411e2e7a75Shuah
1427c478bd9Sstevel@tonic-gate	cmp	%g5, %g1			/* is it the victim? */
1431e2e7a75Shuah	bne,pt	%xcc, 2f			/* is our sec-ctx a victim? */
1441e2e7a75Shuah	  nop
1451e2e7a75Shuah
1461e2e7a75Shuah	ldxa    [%g3]ASI_MMU_CTX, %g5           /* %g5 = sec-ctx */
1471e2e7a75Shuah	cmp     %g5, INVALID_CONTEXT            /* kernel  or invalid ctx ? */
1481e2e7a75Shuah	ble,pn  %xcc, 0f                        /* yes, no need to change */
1497c478bd9Sstevel@tonic-gate	  mov	MMU_PCONTEXT, %g7
1501e2e7a75Shuah
1511e2e7a75Shuah	stxa	%g2, [%g3]ASI_MMU_CTX		/* set sec-ctx to invalid */
1527c478bd9Sstevel@tonic-gate	membar	#Sync
1531e2e7a75Shuah
1541e2e7a75Shuah0:
1551e2e7a75Shuah	ldxa	[%g7]ASI_MMU_CTX, %g4		/* %g4 = pri-ctx */
1561e2e7a75Shuah	cmp	%g4, INVALID_CONTEXT		/* is pri-ctx the victim? */
1571e2e7a75Shuah	ble 	%icc, 3f			/* no need to change pri-ctx */
1587c478bd9Sstevel@tonic-gate	  nop
1591e2e7a75Shuah	stxa	%g2, [%g7]ASI_MMU_CTX		/* set pri-ctx to invalid  */
1607c478bd9Sstevel@tonic-gate	membar	#Sync
1611e2e7a75Shuah
1621e2e7a75Shuah3:
1637c478bd9Sstevel@tonic-gate	/* TSB program must be cleared - walkers do not check a context. */
1647c478bd9Sstevel@tonic-gate	mov	%o0, %g3
1657c478bd9Sstevel@tonic-gate	mov	%o1, %g4
1667c478bd9Sstevel@tonic-gate	mov	%o5, %g7
1677c478bd9Sstevel@tonic-gate	clr	%o0
1687c478bd9Sstevel@tonic-gate	clr	%o1
1697c478bd9Sstevel@tonic-gate	mov	MMU_TSB_CTXNON0, %o5
1707c478bd9Sstevel@tonic-gate	ta	FAST_TRAP
1717c478bd9Sstevel@tonic-gate	brnz,a,pn %o0, ptl1_panic
1727c478bd9Sstevel@tonic-gate	  mov	PTL1_BAD_HCALL, %g1
1737c478bd9Sstevel@tonic-gate	mov	%g3, %o0
1747c478bd9Sstevel@tonic-gate	mov	%g4, %o1
1757c478bd9Sstevel@tonic-gate	mov	%g7, %o5
1767c478bd9Sstevel@tonic-gate2:
1777c478bd9Sstevel@tonic-gate	retry
1781e2e7a75Shuah	SET_SIZE(sfmmu_raise_tsb_exception)
1797c478bd9Sstevel@tonic-gate
1807c478bd9Sstevel@tonic-gate	ENTRY_NP(sfmmu_getctx_pri)
1817c478bd9Sstevel@tonic-gate	set	MMU_PCONTEXT, %o0
1827c478bd9Sstevel@tonic-gate	retl
1839c7f0c79Sarutz	ldxa	[%o0]ASI_MMU_CTX, %o0
1847c478bd9Sstevel@tonic-gate	SET_SIZE(sfmmu_getctx_pri)
1857c478bd9Sstevel@tonic-gate
1867c478bd9Sstevel@tonic-gate	ENTRY_NP(sfmmu_getctx_sec)
1877c478bd9Sstevel@tonic-gate	set	MMU_SCONTEXT, %o0
1887c478bd9Sstevel@tonic-gate	retl
1899c7f0c79Sarutz	ldxa	[%o0]ASI_MMU_CTX, %o0
1907c478bd9Sstevel@tonic-gate	SET_SIZE(sfmmu_getctx_sec)
1917c478bd9Sstevel@tonic-gate
1927c478bd9Sstevel@tonic-gate	/*
1937c478bd9Sstevel@tonic-gate	 * Set the secondary context register for this process.
1941e2e7a75Shuah	 * %o0 = context number
1957c478bd9Sstevel@tonic-gate	 */
1967c478bd9Sstevel@tonic-gate	ENTRY_NP(sfmmu_setctx_sec)
1977c478bd9Sstevel@tonic-gate	/*
1987c478bd9Sstevel@tonic-gate	 * From resume we call sfmmu_setctx_sec with interrupts disabled.
1997c478bd9Sstevel@tonic-gate	 * But we can also get called from C with interrupts enabled. So,
2001e2e7a75Shuah	 * we need to check first.
2017c478bd9Sstevel@tonic-gate	 */
2027c478bd9Sstevel@tonic-gate
2037c478bd9Sstevel@tonic-gate	/* If interrupts are not disabled, then disable them */
2047c478bd9Sstevel@tonic-gate	rdpr	%pstate, %g1
2057c478bd9Sstevel@tonic-gate	btst	PSTATE_IE, %g1
2067c478bd9Sstevel@tonic-gate	bnz,a,pt %icc, 1f
2077c478bd9Sstevel@tonic-gate	wrpr	%g1, PSTATE_IE, %pstate		/* disable interrupts */
2087c478bd9Sstevel@tonic-gate1:
2097c478bd9Sstevel@tonic-gate	mov	MMU_SCONTEXT, %o1
2107c478bd9Sstevel@tonic-gate	stxa	%o0, [%o1]ASI_MMU_CTX		/* set 2nd context reg. */
2112f0fcb93SJason Beloro	membar	#Sync
21205d3dc4bSpaulsan        /*
21305d3dc4bSpaulsan         * if the routine is entered with intr enabled, then enable intr now.
21405d3dc4bSpaulsan         * otherwise, keep intr disabled, return without enabing intr.
21505d3dc4bSpaulsan         * %g1 - old intr state
21605d3dc4bSpaulsan         */
21705d3dc4bSpaulsan        btst    PSTATE_IE, %g1
21805d3dc4bSpaulsan        bnz,a,pt %icc, 2f
21905d3dc4bSpaulsan        wrpr    %g0, %g1, %pstate               /* enable interrupts */
22005d3dc4bSpaulsan2:      retl
22105d3dc4bSpaulsan        nop
22205d3dc4bSpaulsan        SET_SIZE(sfmmu_setctx_sec)
2237c478bd9Sstevel@tonic-gate
2247c478bd9Sstevel@tonic-gate	/*
2257c478bd9Sstevel@tonic-gate	 * set ktsb_phys to 1 if the processor supports ASI_QUAD_LDD_PHYS.
2267c478bd9Sstevel@tonic-gate	 * returns the detection value in %o0.
2277c478bd9Sstevel@tonic-gate	 */
2287c478bd9Sstevel@tonic-gate	ENTRY_NP(sfmmu_setup_4lp)
2297c478bd9Sstevel@tonic-gate	set	ktsb_phys, %o2
2307c478bd9Sstevel@tonic-gate	mov	1, %o1
2317c478bd9Sstevel@tonic-gate	st	%o1, [%o2]
2327c478bd9Sstevel@tonic-gate	retl
2337c478bd9Sstevel@tonic-gate	mov	%o1, %o0
2347c478bd9Sstevel@tonic-gate	SET_SIZE(sfmmu_setup_4lp)
2357c478bd9Sstevel@tonic-gate
2367c478bd9Sstevel@tonic-gate	/*
2377c478bd9Sstevel@tonic-gate	 * Called to load MMU registers and tsbmiss area
2387c478bd9Sstevel@tonic-gate	 * for the active process.  This function should
2397c478bd9Sstevel@tonic-gate	 * only be called from TL=0.
2407c478bd9Sstevel@tonic-gate	 *
2417c478bd9Sstevel@tonic-gate	 * %o0 - hat pointer
2427c478bd9Sstevel@tonic-gate	 */
2437c478bd9Sstevel@tonic-gate	ENTRY_NP(sfmmu_load_mmustate)
2441e2e7a75Shuah
2451e2e7a75Shuah#ifdef DEBUG
2461e2e7a75Shuah	PANIC_IF_INTR_ENABLED_PSTR(msfmmu_ei_l1, %g1)
2471e2e7a75Shuah#endif /* DEBUG */
2487c478bd9Sstevel@tonic-gate
2497c478bd9Sstevel@tonic-gate	sethi	%hi(ksfmmup), %o3
2507c478bd9Sstevel@tonic-gate	ldx	[%o3 + %lo(ksfmmup)], %o3
2517c478bd9Sstevel@tonic-gate	cmp	%o3, %o0
2529d0d62adSJason Beloro	be,pn	%xcc, 7f			! if kernel as, do nothing
25305d3dc4bSpaulsan	  nop
254*55fea89dSDan Cross
25505d3dc4bSpaulsan	set     MMU_SCONTEXT, %o3
25605d3dc4bSpaulsan        ldxa    [%o3]ASI_MMU_CTX, %o5
257*55fea89dSDan Cross
25805d3dc4bSpaulsan	cmp	%o5, INVALID_CONTEXT		! ctx is invalid?
25905d3dc4bSpaulsan	bne,pt	%icc, 1f
2607c478bd9Sstevel@tonic-gate	  nop
2617c478bd9Sstevel@tonic-gate
26205d3dc4bSpaulsan	CPU_TSBMISS_AREA(%o2, %o3)		! %o2 = tsbmiss area
26305d3dc4bSpaulsan	stx	%o0, [%o2 + TSBMISS_UHATID]
26405d3dc4bSpaulsan	stx	%g0, [%o2 +  TSBMISS_SHARED_UHATID]
26505d3dc4bSpaulsan#ifdef DEBUG
26605d3dc4bSpaulsan	/* check if hypervisor/hardware should handle user TSB */
26705d3dc4bSpaulsan	sethi	%hi(hv_use_non0_tsb), %o2
26805d3dc4bSpaulsan	ld	[%o2 + %lo(hv_use_non0_tsb)], %o2
26905d3dc4bSpaulsan	brz,pn	%o2, 0f
270125be069SJason Beloro	  nop
27105d3dc4bSpaulsan#endif /* DEBUG */
27205d3dc4bSpaulsan	clr	%o0				! ntsb = 0 for invalid ctx
27305d3dc4bSpaulsan	clr	%o1				! HV_TSB_INFO_PA = 0 if inv ctx
27405d3dc4bSpaulsan	mov	MMU_TSB_CTXNON0, %o5
27505d3dc4bSpaulsan	ta	FAST_TRAP			! set TSB info for user process
27605d3dc4bSpaulsan	brnz,a,pn %o0, panic_bad_hcall
277125be069SJason Beloro	  mov	MMU_TSB_CTXNON0, %o1
27805d3dc4bSpaulsan0:
27905d3dc4bSpaulsan	retl
28005d3dc4bSpaulsan	  nop
281*55fea89dSDan Cross1:
2827c478bd9Sstevel@tonic-gate	/*
2837c478bd9Sstevel@tonic-gate	 * We need to set up the TSB base register, tsbmiss
2847c478bd9Sstevel@tonic-gate	 * area, and pass the TSB information into the hypervisor
2857c478bd9Sstevel@tonic-gate	 */
2867c478bd9Sstevel@tonic-gate	ldx	[%o0 + SFMMU_TSB], %o1		! %o1 = first tsbinfo
2877c478bd9Sstevel@tonic-gate	ldx	[%o1 + TSBINFO_NEXTPTR], %g2	! %g2 = second tsbinfo
2887c478bd9Sstevel@tonic-gate
2897c478bd9Sstevel@tonic-gate	/* create/set first UTSBREG */
2907c478bd9Sstevel@tonic-gate	MAKE_UTSBREG(%o1, %o2, %o3)		! %o2 = user tsbreg
2917c478bd9Sstevel@tonic-gate	SET_UTSBREG(SCRATCHPAD_UTSBREG1, %o2, %o3)
2927c478bd9Sstevel@tonic-gate
2937c478bd9Sstevel@tonic-gate	brz,pt	%g2, 2f
2947c478bd9Sstevel@tonic-gate	  mov	-1, %o2				! use -1 if no second TSB
2957c478bd9Sstevel@tonic-gate
2967c478bd9Sstevel@tonic-gate	/* make 2nd UTSBREG */
2977c478bd9Sstevel@tonic-gate	MAKE_UTSBREG(%g2, %o2, %o3)		! %o2 = user tsbreg
2987c478bd9Sstevel@tonic-gate2:
2997c478bd9Sstevel@tonic-gate	SET_UTSBREG(SCRATCHPAD_UTSBREG2, %o2, %o3)
3007c478bd9Sstevel@tonic-gate
30105d3dc4bSpaulsan        /* make 3rd and 4th TSB */
30205d3dc4bSpaulsan	CPU_TSBMISS_AREA(%o4, %o3)		! %o4 = tsbmiss area
30305d3dc4bSpaulsan
30405d3dc4bSpaulsan	ldx	[%o0 + SFMMU_SCDP], %g2		! %g2 = sfmmu_scd
30505d3dc4bSpaulsan	brz,pt	%g2, 3f
30605d3dc4bSpaulsan	  mov	-1, %o2				! use -1 if no third TSB
30705d3dc4bSpaulsan
30805d3dc4bSpaulsan	ldx	[%g2 + SCD_SFMMUP], %g3		! %g3 = scdp->scd_sfmmup
30905d3dc4bSpaulsan	ldx	[%g3 + SFMMU_TSB], %o1		! %o1 = first scd tsbinfo
3109d0d62adSJason Beloro	brz,pn %o1, 9f
31105d3dc4bSpaulsan	  nop					! panic if no third TSB
31205d3dc4bSpaulsan
31305d3dc4bSpaulsan	/* make 3rd UTSBREG */
31405d3dc4bSpaulsan	MAKE_UTSBREG(%o1, %o2, %o3)		! %o2 = user tsbreg
31505d3dc4bSpaulsan3:
31605d3dc4bSpaulsan	SET_UTSBREG_SHCTX(%o4, TSBMISS_TSBSCDPTR, %o2)
31705d3dc4bSpaulsan
31805d3dc4bSpaulsan	brz,pt	%g2, 4f
31905d3dc4bSpaulsan	  mov	-1, %o2				! use -1 if no 3rd or 4th TSB
32005d3dc4bSpaulsan
32105d3dc4bSpaulsan	brz,pt	%o1, 4f
32205d3dc4bSpaulsan	  mov	-1, %o2				! use -1 if no 3rd or 4th TSB
32305d3dc4bSpaulsan	ldx	[%o1 + TSBINFO_NEXTPTR], %g2	! %g2 = second scd tsbinfo
32405d3dc4bSpaulsan	brz,pt	%g2, 4f
32505d3dc4bSpaulsan	  mov	-1, %o2				! use -1 if no 4th TSB
32605d3dc4bSpaulsan
32705d3dc4bSpaulsan	/* make 4th UTSBREG */
32805d3dc4bSpaulsan	MAKE_UTSBREG(%g2, %o2, %o3)		! %o2 = user tsbreg
32905d3dc4bSpaulsan4:
33005d3dc4bSpaulsan	SET_UTSBREG_SHCTX(%o4, TSBMISS_TSBSCDPTR4M, %o2)
33105d3dc4bSpaulsan
3327c478bd9Sstevel@tonic-gate#ifdef DEBUG
3337c478bd9Sstevel@tonic-gate	/* check if hypervisor/hardware should handle user TSB */
3347c478bd9Sstevel@tonic-gate	sethi	%hi(hv_use_non0_tsb), %o2
3357c478bd9Sstevel@tonic-gate	ld	[%o2 + %lo(hv_use_non0_tsb)], %o2
33605d3dc4bSpaulsan	brz,pn	%o2, 6f
337125be069SJason Beloro	  nop
3387c478bd9Sstevel@tonic-gate#endif /* DEBUG */
3397c478bd9Sstevel@tonic-gate	CPU_ADDR(%o2, %o4)	! load CPU struct addr to %o2 using %o4
3407c478bd9Sstevel@tonic-gate	ldub    [%o2 + CPU_TSTAT_FLAGS], %o1	! load cpu_tstat_flag to %o1
3411e2e7a75Shuah
3427c478bd9Sstevel@tonic-gate	mov	%o0, %o3			! preserve %o0
3437c478bd9Sstevel@tonic-gate	btst	TSTAT_TLB_STATS, %o1
34405d3dc4bSpaulsan	bnz,a,pn %icc, 5f			! ntsb = 0 if TLB stats enabled
3457c478bd9Sstevel@tonic-gate	  clr	%o0
346*55fea89dSDan Cross
3477c478bd9Sstevel@tonic-gate	ldx	[%o3 + SFMMU_HVBLOCK + HV_TSB_INFO_CNT], %o0
34805d3dc4bSpaulsan5:
349*55fea89dSDan Cross	ldx	[%o3 + SFMMU_HVBLOCK + HV_TSB_INFO_PA], %o1
3507c478bd9Sstevel@tonic-gate	mov	MMU_TSB_CTXNON0, %o5
3517c478bd9Sstevel@tonic-gate	ta	FAST_TRAP			! set TSB info for user process
3527c478bd9Sstevel@tonic-gate	brnz,a,pn %o0, panic_bad_hcall
3539d0d62adSJason Beloro	mov	MMU_TSB_CTXNON0, %o1
3549d0d62adSJason Beloro	mov	%o3, %o0			! restore %o0
35505d3dc4bSpaulsan6:
3567c478bd9Sstevel@tonic-gate	ldx	[%o0 + SFMMU_ISMBLKPA], %o1	! copy members of sfmmu
35705d3dc4bSpaulsan	CPU_TSBMISS_AREA(%o2, %o3)		! %o2 = tsbmiss area
3587c478bd9Sstevel@tonic-gate	stx	%o1, [%o2 + TSBMISS_ISMBLKPA]	! sfmmu_tsb_miss into the
35905d3dc4bSpaulsan	ldub	[%o0 + SFMMU_TTEFLAGS], %o3	! per-CPU tsbmiss area.
36005d3dc4bSpaulsan	ldub	[%o0 + SFMMU_RTTEFLAGS], %o4
36105d3dc4bSpaulsan	ldx	[%o0 + SFMMU_SRDP], %o1
3627c478bd9Sstevel@tonic-gate	stx	%o0, [%o2 + TSBMISS_UHATID]
36305d3dc4bSpaulsan	stub	%o3, [%o2 + TSBMISS_UTTEFLAGS]
36405d3dc4bSpaulsan	stub	%o4,  [%o2 + TSBMISS_URTTEFLAGS]
36505d3dc4bSpaulsan	stx	%o1, [%o2 +  TSBMISS_SHARED_UHATID]
3669d0d62adSJason Beloro	brz,pn	%o1, 7f				! check for sfmmu_srdp
36705d3dc4bSpaulsan	  add	%o0, SFMMU_HMERMAP, %o1
36805d3dc4bSpaulsan	add	%o2, TSBMISS_SHMERMAP, %o2
36905d3dc4bSpaulsan	mov	SFMMU_HMERGNMAP_WORDS, %o3
37005d3dc4bSpaulsan						! set tsbmiss shmermap
37105d3dc4bSpaulsan	SET_REGION_MAP(%o1, %o2, %o3, %o4, load_shme_mmustate)
37205d3dc4bSpaulsan
37305d3dc4bSpaulsan	ldx	[%o0 + SFMMU_SCDP], %o4		! %o4 = sfmmu_scd
37405d3dc4bSpaulsan	CPU_TSBMISS_AREA(%o2, %o3)		! %o2 = tsbmiss area
37505d3dc4bSpaulsan	mov	SFMMU_HMERGNMAP_WORDS, %o3
3769d0d62adSJason Beloro	brnz,pt	%o4, 8f				! check for sfmmu_scdp else
3779d0d62adSJason Beloro	  add	%o2, TSBMISS_SCDSHMERMAP, %o2	! zero tsbmiss scd_shmermap
37805d3dc4bSpaulsan	ZERO_REGION_MAP(%o2, %o3, zero_scd_mmustate)
3799d0d62adSJason Beloro7:
38005d3dc4bSpaulsan	retl
3817c478bd9Sstevel@tonic-gate	nop
3829d0d62adSJason Beloro8:						! set tsbmiss scd_shmermap
3839d0d62adSJason Beloro	add	%o4, SCD_HMERMAP, %o1
38405d3dc4bSpaulsan	SET_REGION_MAP(%o1, %o2, %o3, %o4, load_scd_mmustate)
38505d3dc4bSpaulsan	retl
38605d3dc4bSpaulsan	  nop
3879d0d62adSJason Beloro9:
388*55fea89dSDan Cross	sethi   %hi(panicstr), %g1		! panic if no 3rd TSB
389*55fea89dSDan Cross        ldx     [%g1 + %lo(panicstr)], %g1
39005d3dc4bSpaulsan        tst     %g1
391*55fea89dSDan Cross
392*55fea89dSDan Cross        bnz,pn  %xcc, 7b
393*55fea89dSDan Cross          nop
394*55fea89dSDan Cross
395*55fea89dSDan Cross        sethi   %hi(sfmmu_panic10), %o0
396*55fea89dSDan Cross        call    panic
397*55fea89dSDan Cross          or      %o0, %lo(sfmmu_panic10), %o0
398125be069SJason Beloro
3999d0d62adSJason Beloro	SET_SIZE(sfmmu_load_mmustate)
400*55fea89dSDan Cross
4017c478bd9Sstevel@tonic-gate	ENTRY(prefetch_tsbe_read)
4027c478bd9Sstevel@tonic-gate	retl
4037c478bd9Sstevel@tonic-gate	nop
4047c478bd9Sstevel@tonic-gate	SET_SIZE(prefetch_tsbe_read)
4057c478bd9Sstevel@tonic-gate
4067c478bd9Sstevel@tonic-gate	ENTRY(prefetch_tsbe_write)
4077c478bd9Sstevel@tonic-gate	retl
4087c478bd9Sstevel@tonic-gate	nop
4097c478bd9Sstevel@tonic-gate	SET_SIZE(prefetch_tsbe_write)
410