xref: /onnv-gate/usr/src/uts/sun4v/vm/mach_sfmmu.h (revision 10271:7c80b70bb8de)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
53687Sjb145095  * Common Development and Distribution License (the "License").
63687Sjb145095  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*8819SJason.Beloro@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate /*
270Sstevel@tonic-gate  * VM - Hardware Address Translation management.
280Sstevel@tonic-gate  *
290Sstevel@tonic-gate  * This file describes the contents of the sun reference mmu (sfmmu)
300Sstevel@tonic-gate  * specific hat data structures and the sfmmu specific hat procedures.
310Sstevel@tonic-gate  * The machine independent interface is described in <vm/hat.h>.
320Sstevel@tonic-gate  */
330Sstevel@tonic-gate 
340Sstevel@tonic-gate #ifndef _VM_MACH_SFMMU_H
350Sstevel@tonic-gate #define	_VM_MACH_SFMMU_H
360Sstevel@tonic-gate 
370Sstevel@tonic-gate #include <sys/x_call.h>
380Sstevel@tonic-gate #include <sys/hypervisor_api.h>
390Sstevel@tonic-gate 
400Sstevel@tonic-gate #ifdef	__cplusplus
410Sstevel@tonic-gate extern "C" {
420Sstevel@tonic-gate #endif
430Sstevel@tonic-gate 
440Sstevel@tonic-gate /*
450Sstevel@tonic-gate  * Define UTSB_PHYS if user TSB is always accessed via physical address.
460Sstevel@tonic-gate  * On sun4v platform, user TSB is accessed via physical address.
470Sstevel@tonic-gate  */
480Sstevel@tonic-gate #define	UTSB_PHYS	1
490Sstevel@tonic-gate 
500Sstevel@tonic-gate /*
510Sstevel@tonic-gate  * Hypervisor TSB info
520Sstevel@tonic-gate  */
534528Spaulsan #define	NHV_TSB_INFO	4
540Sstevel@tonic-gate 
550Sstevel@tonic-gate #ifndef _ASM
560Sstevel@tonic-gate 
570Sstevel@tonic-gate struct hv_tsb_block {
580Sstevel@tonic-gate 	uint64_t	hv_tsb_info_pa;	/* hypervisor TSB info PA */
590Sstevel@tonic-gate 	uint64_t	hv_tsb_info_cnt; /* hypervisor TSB info count */
600Sstevel@tonic-gate 	hv_tsb_info_t	hv_tsb_info[NHV_TSB_INFO]; /* hypervisor TSB info */
610Sstevel@tonic-gate };
620Sstevel@tonic-gate 
630Sstevel@tonic-gate #endif /* _ASM */
640Sstevel@tonic-gate 
650Sstevel@tonic-gate #ifdef _ASM
660Sstevel@tonic-gate 
670Sstevel@tonic-gate /*
684528Spaulsan  * This macro is used to set private/shared secondary context register in
694528Spaulsan  * sfmmu_alloc_ctx().
704528Spaulsan  * Input:
714528Spaulsan  * cnum     = cnum
724528Spaulsan  * is_shctx = sfmmu private/shared flag (0: private, 1: shared)
737718SJason.Beloro@Sun.COM  * tmp2 is only used in the sun4u version of this macro
744528Spaulsan  */
756127Ssm142603 #define	SET_SECCTX(cnum, is_shctx, tmp1, tmp2, label)			\
764528Spaulsan 	mov	MMU_SCONTEXT, tmp1;					\
774528Spaulsan 	movrnz	is_shctx, MMU_SCONTEXT1, tmp1;				\
784528Spaulsan 	stxa    cnum, [tmp1]ASI_MMU_CTX;  /* set 2nd ctx reg. */	\
797718SJason.Beloro@Sun.COM 	membar  #Sync;							\
804528Spaulsan 
814528Spaulsan /*
820Sstevel@tonic-gate  * This macro is used in the MMU code to check if TL should be lowered from
830Sstevel@tonic-gate  * 2 to 1 to pop trapstat's state.  See the block comment in trapstat.c
840Sstevel@tonic-gate  * for details.
850Sstevel@tonic-gate  */
860Sstevel@tonic-gate 
870Sstevel@tonic-gate #define	TSTAT_CHECK_TL1(label, scr1, scr2)			\
880Sstevel@tonic-gate 	rdpr	%tpc, scr1;					\
890Sstevel@tonic-gate 	sethi	%hi(KERNELBASE), scr2;				\
900Sstevel@tonic-gate 	or	scr2, %lo(KERNELBASE), scr2; 			\
910Sstevel@tonic-gate 	cmp	scr1, scr2; 					\
920Sstevel@tonic-gate 	bgeu	%xcc, 9f;					\
930Sstevel@tonic-gate 	nop;							\
940Sstevel@tonic-gate 	wrpr	%g0, 1, %gl;					\
950Sstevel@tonic-gate 	ba	label;						\
960Sstevel@tonic-gate 	wrpr	%g0, 1, %tl;					\
970Sstevel@tonic-gate 9:
980Sstevel@tonic-gate 
990Sstevel@tonic-gate /*
1000Sstevel@tonic-gate  * The following macros allow us to share majority of the
1010Sstevel@tonic-gate  * SFMMU code between sun4u and sun4v platforms.
1020Sstevel@tonic-gate  */
1030Sstevel@tonic-gate 
1040Sstevel@tonic-gate #define	SETUP_TSB_ASI(qlp, tmp)
1050Sstevel@tonic-gate 
1060Sstevel@tonic-gate #define	SETUP_UTSB_ATOMIC_ASI(tmp1, tmp2)
1070Sstevel@tonic-gate 
1080Sstevel@tonic-gate /*
1090Sstevel@tonic-gate  * Macro to swtich to alternate global register on sun4u platforms
1100Sstevel@tonic-gate  * (not applicable to sun4v platforms)
1110Sstevel@tonic-gate  */
1120Sstevel@tonic-gate #define	USE_ALTERNATE_GLOBALS(scr)
1130Sstevel@tonic-gate 
1140Sstevel@tonic-gate /*
1150Sstevel@tonic-gate  * Macro to set %gl register value on sun4v platforms
1160Sstevel@tonic-gate  * (not applicable to sun4u platforms)
1170Sstevel@tonic-gate  */
1180Sstevel@tonic-gate #define	SET_GL_REG(val)						\
1190Sstevel@tonic-gate 	wrpr	%g0, val, %gl
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate /*
1223687Sjb145095  * Get pseudo-tagacc value and context from the MMU fault area.  Pseudo-tagacc
1233687Sjb145095  * is the faulting virtual address OR'd with 0 for KCONTEXT, INVALID_CONTEXT
1243687Sjb145095  * (1) for invalid context, and USER_CONTEXT (2) for user context.
1250Sstevel@tonic-gate  *
1260Sstevel@tonic-gate  * In:
1273687Sjb145095  *   tagacc, ctxtype = scratch registers
1280Sstevel@tonic-gate  * Out:
1290Sstevel@tonic-gate  *   tagacc = MMU data tag access register value
1303687Sjb145095  *   ctx = context type (KCONTEXT, INVALID_CONTEXT or USER_CONTEXT)
1310Sstevel@tonic-gate  */
1323687Sjb145095 #define	GET_MMU_D_PTAGACC_CTXTYPE(ptagacc, ctxtype)			\
1333687Sjb145095 	MMU_FAULT_STATUS_AREA(ctxtype);					\
1343687Sjb145095 	ldx	[ctxtype + MMFSA_D_ADDR], ptagacc;			\
1353687Sjb145095 	ldx	[ctxtype + MMFSA_D_CTX], ctxtype;			\
1363687Sjb145095 	srlx	ptagacc, MMU_PAGESHIFT, ptagacc; /* align to page boundary */ \
1373687Sjb145095 	cmp	ctxtype, USER_CONTEXT_TYPE;				\
1383687Sjb145095 	sllx	ptagacc, MMU_PAGESHIFT, ptagacc;			\
1393687Sjb145095 	movgu	%icc, USER_CONTEXT_TYPE, ctxtype;			\
1403687Sjb145095 	or	ptagacc, ctxtype, ptagacc
1410Sstevel@tonic-gate 
1420Sstevel@tonic-gate /*
1430Sstevel@tonic-gate  * Synthesize/get data tag access register value from the MMU fault area
1440Sstevel@tonic-gate  *
1450Sstevel@tonic-gate  * In:
1460Sstevel@tonic-gate  *   tagacc, scr1 = scratch registers
1470Sstevel@tonic-gate  * Out:
1480Sstevel@tonic-gate  *   tagacc = MMU data tag access register value
1490Sstevel@tonic-gate  */
1500Sstevel@tonic-gate #define	GET_MMU_D_TAGACC(tagacc, scr1)				\
1513687Sjb145095 	GET_MMU_D_PTAGACC_CTXTYPE(tagacc, scr1)
1520Sstevel@tonic-gate 
1530Sstevel@tonic-gate /*
1540Sstevel@tonic-gate  * Synthesize/get data tag target register value from the MMU fault area
1550Sstevel@tonic-gate  *
1560Sstevel@tonic-gate  * In:
1570Sstevel@tonic-gate  *   ttarget, scr1 = scratch registers
1580Sstevel@tonic-gate  * Out:
1590Sstevel@tonic-gate  *   ttarget = MMU data tag target register value
1600Sstevel@tonic-gate  */
1610Sstevel@tonic-gate #define	GET_MMU_D_TTARGET(ttarget, scr1)			\
1620Sstevel@tonic-gate 	MMU_FAULT_STATUS_AREA(ttarget);				\
1630Sstevel@tonic-gate 	ldx	[ttarget + MMFSA_D_CTX], scr1;			\
1640Sstevel@tonic-gate 	sllx	scr1, TTARGET_CTX_SHIFT, scr1;			\
1650Sstevel@tonic-gate 	ldx	[ttarget + MMFSA_D_ADDR], ttarget;		\
1660Sstevel@tonic-gate 	srlx	ttarget, TTARGET_VA_SHIFT, ttarget;		\
1670Sstevel@tonic-gate 	or	ttarget, scr1, ttarget
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate /*
1703687Sjb145095  * Synthesize/get data/instruction psuedo tag access register values
1713687Sjb145095  * from the MMU fault area (context is 0 for kernel, 1 for invalid, 2 for user)
1720Sstevel@tonic-gate  *
1730Sstevel@tonic-gate  * In:
1740Sstevel@tonic-gate  *   dtagacc, itagacc, scr1, scr2 = scratch registers
1750Sstevel@tonic-gate  * Out:
1763687Sjb145095  *   dtagacc = MMU data tag access register value w/psuedo-context
1773687Sjb145095  *   itagacc = MMU instruction tag access register value w/pseudo-context
1780Sstevel@tonic-gate  */
1790Sstevel@tonic-gate #define	GET_MMU_BOTH_TAGACC(dtagacc, itagacc, scr1, scr2)	\
1800Sstevel@tonic-gate 	MMU_FAULT_STATUS_AREA(scr1);				\
1810Sstevel@tonic-gate 	ldx	[scr1 + MMFSA_D_ADDR], scr2;			\
1820Sstevel@tonic-gate 	ldx	[scr1 + MMFSA_D_CTX], dtagacc;			\
1833687Sjb145095 	srlx	scr2, MMU_PAGESHIFT, scr2;	/* align to page boundary */ \
1843687Sjb145095 	cmp	dtagacc, USER_CONTEXT_TYPE;			\
1850Sstevel@tonic-gate 	sllx	scr2, MMU_PAGESHIFT, scr2;			\
1863687Sjb145095 	movgu	%icc, USER_CONTEXT_TYPE, dtagacc;		\
1870Sstevel@tonic-gate 	or	scr2, dtagacc, dtagacc;				\
1880Sstevel@tonic-gate 	ldx	[scr1 + MMFSA_I_ADDR], scr2;			\
1890Sstevel@tonic-gate 	ldx	[scr1 + MMFSA_I_CTX], itagacc;			\
1900Sstevel@tonic-gate 	srlx	scr2, MMU_PAGESHIFT, scr2;	/* align to page boundry */ \
1913687Sjb145095 	cmp	itagacc, USER_CONTEXT_TYPE;			\
1920Sstevel@tonic-gate 	sllx	scr2, MMU_PAGESHIFT, scr2;			\
1933687Sjb145095 	movgu	%icc, USER_CONTEXT_TYPE, itagacc;		\
1940Sstevel@tonic-gate 	or	scr2, itagacc, itagacc
1950Sstevel@tonic-gate 
1960Sstevel@tonic-gate /*
1970Sstevel@tonic-gate  * Synthesize/get MMU data fault address from the MMU fault area
1980Sstevel@tonic-gate  *
1990Sstevel@tonic-gate  * In:
2000Sstevel@tonic-gate  *   daddr, scr1 = scratch registers
2010Sstevel@tonic-gate  * Out:
2020Sstevel@tonic-gate  *   daddr = MMU data fault address
2030Sstevel@tonic-gate  */
2040Sstevel@tonic-gate #define	GET_MMU_D_ADDR(daddr, scr1)				\
2050Sstevel@tonic-gate 	MMU_FAULT_STATUS_AREA(scr1);				\
2060Sstevel@tonic-gate 	ldx	[scr1 + MMFSA_D_ADDR], daddr
2070Sstevel@tonic-gate 
2080Sstevel@tonic-gate /*
2093687Sjb145095  * Get pseudo-tagacc value and context from the MMU fault area.  Pseudo-tagacc
2103687Sjb145095  * is the faulting virtual address OR'd with 0 for KCONTEXT, INVALID_CONTEXT
2113687Sjb145095  * (1) for invalid context, and USER_CONTEXT (2) for user context.
2123687Sjb145095  *
2133687Sjb145095  * In:
2143687Sjb145095  *   tagacc, ctxtype = scratch registers
2153687Sjb145095  * Out:
2163687Sjb145095  *   tagacc = MMU instruction tag access register value
2173687Sjb145095  *   ctxtype = context type (KCONTEXT, INVALID_CONTEXT or USER_CONTEXT)
2183687Sjb145095  */
2193687Sjb145095 #define	GET_MMU_I_PTAGACC_CTXTYPE(ptagacc, ctxtype)			\
2203687Sjb145095 	MMU_FAULT_STATUS_AREA(ctxtype);					\
2213687Sjb145095 	ldx	[ctxtype + MMFSA_I_ADDR], ptagacc;			\
2223687Sjb145095 	ldx	[ctxtype + MMFSA_I_CTX], ctxtype;			\
2233687Sjb145095 	srlx	ptagacc, MMU_PAGESHIFT, ptagacc; /* align to page boundary */ \
2243687Sjb145095 	cmp	ctxtype, USER_CONTEXT_TYPE;				\
2253687Sjb145095 	sllx	ptagacc, MMU_PAGESHIFT, ptagacc;			\
2263687Sjb145095 	movgu	%icc, USER_CONTEXT_TYPE, ctxtype;			\
2273687Sjb145095 	or	ptagacc, ctxtype, ptagacc
2283687Sjb145095 
2293687Sjb145095 /*
2300Sstevel@tonic-gate  * Load ITLB entry
2310Sstevel@tonic-gate  *
2320Sstevel@tonic-gate  * In:
2330Sstevel@tonic-gate  *   tte = reg containing tte
2340Sstevel@tonic-gate  *   scr1, scr2, scr3, scr4 = scratch registers
2350Sstevel@tonic-gate  */
2360Sstevel@tonic-gate #define	ITLB_STUFF(tte, scr1, scr2, scr3, scr4)		\
2370Sstevel@tonic-gate 	mov	%o0, scr1;				\
2380Sstevel@tonic-gate 	mov	%o1, scr2;				\
2390Sstevel@tonic-gate 	mov	%o2, scr3;				\
2400Sstevel@tonic-gate 	mov	%o3, scr4;				\
2410Sstevel@tonic-gate 	MMU_FAULT_STATUS_AREA(%o2);			\
2420Sstevel@tonic-gate 	ldx	[%o2 + MMFSA_I_ADDR], %o0;		\
2430Sstevel@tonic-gate 	ldx	[%o2 + MMFSA_I_CTX], %o1;		\
2440Sstevel@tonic-gate 	mov	tte, %o2;				\
2450Sstevel@tonic-gate 	mov	MAP_ITLB, %o3;				\
2460Sstevel@tonic-gate 	ta	MMU_MAP_ADDR;				\
2470Sstevel@tonic-gate 	/* BEGIN CSTYLED */				\
2480Sstevel@tonic-gate 	brnz,a,pn %o0, ptl1_panic;			\
2490Sstevel@tonic-gate 	  mov	PTL1_BAD_HCALL, %g1;			\
2500Sstevel@tonic-gate 	/* END CSTYLED */				\
2510Sstevel@tonic-gate 	mov	scr1, %o0;				\
2520Sstevel@tonic-gate 	mov	scr2, %o1;				\
2530Sstevel@tonic-gate 	mov	scr3, %o2;				\
2540Sstevel@tonic-gate 	mov	scr4, %o3
2550Sstevel@tonic-gate 
2560Sstevel@tonic-gate /*
2570Sstevel@tonic-gate  * Load DTLB entry
2580Sstevel@tonic-gate  *
2590Sstevel@tonic-gate  * In:
2600Sstevel@tonic-gate  *   tte = reg containing tte
2610Sstevel@tonic-gate  *   scr1, scr2, scr3, scr4 = scratch registers
2620Sstevel@tonic-gate  */
2630Sstevel@tonic-gate #define	DTLB_STUFF(tte, scr1, scr2, scr3, scr4)		\
2640Sstevel@tonic-gate 	mov	%o0, scr1;				\
2650Sstevel@tonic-gate 	mov	%o1, scr2;				\
2660Sstevel@tonic-gate 	mov	%o2, scr3;				\
2670Sstevel@tonic-gate 	mov	%o3, scr4;				\
2680Sstevel@tonic-gate 	MMU_FAULT_STATUS_AREA(%o2);			\
2690Sstevel@tonic-gate 	ldx	[%o2 + MMFSA_D_ADDR], %o0;		\
2700Sstevel@tonic-gate 	ldx	[%o2 + MMFSA_D_CTX], %o1;		\
2710Sstevel@tonic-gate 	mov	tte, %o2;				\
2720Sstevel@tonic-gate 	mov	MAP_DTLB, %o3;				\
2730Sstevel@tonic-gate 	ta	MMU_MAP_ADDR;				\
2740Sstevel@tonic-gate 	/* BEGIN CSTYLED */				\
2750Sstevel@tonic-gate 	brnz,a,pn %o0, ptl1_panic;			\
2760Sstevel@tonic-gate 	  mov	PTL1_BAD_HCALL, %g1;			\
2770Sstevel@tonic-gate 	/* END CSTYLED */				\
2780Sstevel@tonic-gate 	mov	scr1, %o0;				\
2790Sstevel@tonic-gate 	mov	scr2, %o1;				\
2800Sstevel@tonic-gate 	mov	scr3, %o2;				\
2810Sstevel@tonic-gate 	mov	scr4, %o3
2820Sstevel@tonic-gate 
2830Sstevel@tonic-gate /*
2840Sstevel@tonic-gate  * Returns PFN given the TTE and vaddr
2850Sstevel@tonic-gate  *
2860Sstevel@tonic-gate  * In:
2870Sstevel@tonic-gate  *   tte = reg containing tte
2880Sstevel@tonic-gate  *   vaddr = reg containing vaddr
2890Sstevel@tonic-gate  *   scr1, scr2, scr3 = scratch registers
2900Sstevel@tonic-gate  * Out:
2910Sstevel@tonic-gate  *   tte = PFN value
2920Sstevel@tonic-gate  */
2930Sstevel@tonic-gate #define	TTETOPFN(tte, vaddr, label, scr1, scr2, scr3)			\
2940Sstevel@tonic-gate 	and	tte, TTE_SZ_BITS, scr1;		/* scr1 = ttesz */	\
2950Sstevel@tonic-gate 	sllx	tte, TTE_PA_LSHIFT, tte;				\
2960Sstevel@tonic-gate 	sllx	scr1, 1, scr2;						\
2970Sstevel@tonic-gate 	add	scr2, scr1, scr2;		/* mulx 3 */		\
2980Sstevel@tonic-gate 	add	scr2, MMU_PAGESHIFT + TTE_PA_LSHIFT, scr3;		\
2990Sstevel@tonic-gate 	/* CSTYLED */							\
3000Sstevel@tonic-gate 	brz,pt	scr2, label/**/1;					\
3010Sstevel@tonic-gate 	srlx	tte, scr3, tte;						\
3020Sstevel@tonic-gate 	sllx	tte, scr2, tte;						\
3030Sstevel@tonic-gate 	set	1, scr1;						\
3040Sstevel@tonic-gate 	add	scr2, MMU_PAGESHIFT, scr3;				\
3050Sstevel@tonic-gate 	sllx	scr1, scr3, scr1;					\
3060Sstevel@tonic-gate 	sub	scr1, 1, scr1;	/* scr1=TTE_PAGE_OFFSET(ttesz) */	\
3070Sstevel@tonic-gate 	and	vaddr, scr1, scr2;					\
3080Sstevel@tonic-gate 	srln	scr2, MMU_PAGESHIFT, scr2;				\
3090Sstevel@tonic-gate 	or	tte, scr2, tte;						\
3100Sstevel@tonic-gate 	/* CSTYLED */							\
3110Sstevel@tonic-gate label/**/1:
3120Sstevel@tonic-gate 
3130Sstevel@tonic-gate /*
3140Sstevel@tonic-gate  * TTE_SET_REF_ML is a macro that updates the reference bit if it is
3150Sstevel@tonic-gate  * not already set.
3160Sstevel@tonic-gate  *
3170Sstevel@tonic-gate  * Parameters:
3180Sstevel@tonic-gate  * tte      = reg containing tte
3190Sstevel@tonic-gate  * ttepa    = physical pointer to tte
3200Sstevel@tonic-gate  * tsbarea  = tsb miss area
3210Sstevel@tonic-gate  * tmp1     = tmp reg
3228187SPaul.Sandhu@Sun.COM  * tmp2     = tmp reg
3230Sstevel@tonic-gate  * label    = temporary label
3240Sstevel@tonic-gate  */
3250Sstevel@tonic-gate 
3268187SPaul.Sandhu@Sun.COM #define	TTE_SET_REF_ML(tte, ttepa, tsbarea, tmp1, tmp2, label)		\
3270Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
3280Sstevel@tonic-gate 	/* check reference bit */					\
3290Sstevel@tonic-gate 	btst	TTE_REF_INT, tte;					\
3300Sstevel@tonic-gate 	bnz,pt	%xcc, label/**/2;	/* if ref bit set-skip ahead */	\
3310Sstevel@tonic-gate 	nop;								\
3320Sstevel@tonic-gate 	/* update reference bit */					\
3330Sstevel@tonic-gate label/**/1:								\
3340Sstevel@tonic-gate 	or	tte, TTE_REF_INT, tmp1;					\
3350Sstevel@tonic-gate 	casxa	[ttepa]ASI_MEM, tte, tmp1; 	/* update ref bit */	\
3360Sstevel@tonic-gate 	cmp	tte, tmp1;						\
3370Sstevel@tonic-gate 	bne,a,pn %xcc, label/**/1;					\
3380Sstevel@tonic-gate 	ldxa	[ttepa]ASI_MEM, tte;	/* MMU_READTTE through pa */	\
3390Sstevel@tonic-gate 	or	tte, TTE_REF_INT, tte;					\
3400Sstevel@tonic-gate label/**/2:								\
3410Sstevel@tonic-gate 	/* END CSTYLED */
3420Sstevel@tonic-gate 
3430Sstevel@tonic-gate 
3440Sstevel@tonic-gate /*
3450Sstevel@tonic-gate  * TTE_SET_REFMOD_ML is a macro that updates the reference and modify bits
3460Sstevel@tonic-gate  * if not already set.
3470Sstevel@tonic-gate  *
3480Sstevel@tonic-gate  * Parameters:
3490Sstevel@tonic-gate  * tte      = reg containing tte
3500Sstevel@tonic-gate  * ttepa    = physical pointer to tte
3510Sstevel@tonic-gate  * tsbarea  = tsb miss area
3520Sstevel@tonic-gate  * tmp1     = tmp reg
3538187SPaul.Sandhu@Sun.COM  * tmp2     = tmp reg
3540Sstevel@tonic-gate  * label    = temporary label
3550Sstevel@tonic-gate  * exitlabel = label where to jump to if write perm bit not set.
3560Sstevel@tonic-gate  */
3570Sstevel@tonic-gate 
3588187SPaul.Sandhu@Sun.COM #define	TTE_SET_REFMOD_ML(tte, ttepa, tsbarea, tmp1, tmp2, label,	\
3590Sstevel@tonic-gate 	exitlabel)							\
3600Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
3610Sstevel@tonic-gate 	/* check reference bit */					\
3620Sstevel@tonic-gate 	btst	TTE_WRPRM_INT, tte;					\
3630Sstevel@tonic-gate 	bz,pn	%xcc, exitlabel;	/* exit if wr_perm no set */	\
3640Sstevel@tonic-gate 	  btst	TTE_HWWR_INT, tte;					\
3650Sstevel@tonic-gate 	bnz,pn	%xcc, label/**/2;	/* nothing to do */		\
3660Sstevel@tonic-gate 	  nop;								\
3670Sstevel@tonic-gate 	/* update reference bit */					\
3680Sstevel@tonic-gate label/**/1:								\
3690Sstevel@tonic-gate 	or	tte, TTE_HWWR_INT | TTE_REF_INT, tmp1;			\
3700Sstevel@tonic-gate 	casxa	[ttepa]ASI_MEM, tte, tmp1; /* update ref/mod bit */	\
3710Sstevel@tonic-gate 	cmp	tte, tmp1;						\
3720Sstevel@tonic-gate 	bne,a,pn %xcc, label/**/1;					\
3730Sstevel@tonic-gate 	  ldxa	[ttepa]ASI_MEM, tte;	/* MMU_READTTE through pa */	\
3740Sstevel@tonic-gate 	or	tte, TTE_HWWR_INT | TTE_REF_INT, tte;			\
3750Sstevel@tonic-gate label/**/2:								\
3760Sstevel@tonic-gate 	/* END CSTYLED */
3774528Spaulsan /*
3784528Spaulsan  * Get TSB base register from the scratchpad for
3794528Spaulsan  * shared contexts
3804528Spaulsan  *
3814528Spaulsan  * In:
3824528Spaulsan  *   tsbmiss = pointer to tsbmiss area
3834528Spaulsan  *   tsbmissoffset = offset to right tsb pointer
3844528Spaulsan  *   tsbreg = scratch
3854528Spaulsan  * Out:
3864528Spaulsan  *   tsbreg = tsbreg from the specified scratchpad register
3874528Spaulsan  */
3884528Spaulsan #define	GET_UTSBREG_SHCTX(tsbmiss, tsbmissoffset, tsbreg)		\
3894528Spaulsan 	ldx	[tsbmiss + tsbmissoffset], tsbreg
3904528Spaulsan 
3910Sstevel@tonic-gate 
3920Sstevel@tonic-gate /*
3930Sstevel@tonic-gate  * Get the location of the TSB entry in the first TSB to probe
3940Sstevel@tonic-gate  *
3950Sstevel@tonic-gate  * In:
3960Sstevel@tonic-gate  *   tagacc = tag access register (not clobbered)
3970Sstevel@tonic-gate  *   tsbe, tmp1, tmp2 = scratch registers
3980Sstevel@tonic-gate  * Out:
3990Sstevel@tonic-gate  *   tsbe = pointer to the tsbe in the 1st TSB
4000Sstevel@tonic-gate  */
4010Sstevel@tonic-gate 
4020Sstevel@tonic-gate #define	GET_1ST_TSBE_PTR(tagacc, tsbe, tmp1, tmp2)			\
4030Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
4040Sstevel@tonic-gate 	mov	SCRATCHPAD_UTSBREG1, tmp1				;\
4050Sstevel@tonic-gate 	ldxa	[tmp1]ASI_SCRATCHPAD, tsbe	/* get tsbreg */	;\
4060Sstevel@tonic-gate 	and	tsbe, TSB_SOFTSZ_MASK, tmp2	/* tmp2=szc */		;\
4070Sstevel@tonic-gate 	andn	tsbe, TSB_SOFTSZ_MASK, tsbe	/* tsbbase */		;\
4080Sstevel@tonic-gate 	mov	TSB_ENTRIES(0), tmp1	/* nentries in TSB size 0 */	;\
4090Sstevel@tonic-gate 	sllx	tmp1, tmp2, tmp1	/* tmp1 = nentries in TSB */	;\
4100Sstevel@tonic-gate 	sub	tmp1, 1, tmp1		/* mask = nentries - 1 */	;\
4110Sstevel@tonic-gate 	srlx	tagacc, MMU_PAGESHIFT, tmp2 				;\
4120Sstevel@tonic-gate 	and	tmp2, tmp1, tmp1	/* tsbent = virtpage & mask */	;\
4130Sstevel@tonic-gate 	sllx	tmp1, TSB_ENTRY_SHIFT, tmp1	/* entry num --> ptr */	;\
4140Sstevel@tonic-gate 	add	tsbe, tmp1, tsbe	/* add entry offset to TSB base */ ;\
4150Sstevel@tonic-gate 	/* END CSTYLED */
4160Sstevel@tonic-gate 
4170Sstevel@tonic-gate 
4180Sstevel@tonic-gate /*
4190Sstevel@tonic-gate  * Will probe the first TSB, and if it finds a match, will insert it
4200Sstevel@tonic-gate  * into the TLB and retry.
4210Sstevel@tonic-gate  *
4220Sstevel@tonic-gate  * tsbe_ptr = precomputed first TSB entry pointer (in, ro)
4230Sstevel@tonic-gate  * vpg_4m = 4M virtual page number for tag matching  (in, ro)
4240Sstevel@tonic-gate  * label = where to branch to if this is a miss (text)
4250Sstevel@tonic-gate  * %asi = atomic ASI to use for the TSB access
4260Sstevel@tonic-gate  *
4270Sstevel@tonic-gate  * For trapstat, we have to explicily use these registers.
4280Sstevel@tonic-gate  * g4 = location tag will be retrieved into from TSB (out)
4290Sstevel@tonic-gate  * g5 = location data(tte) will be retrieved into from TSB (out)
4300Sstevel@tonic-gate  */
4310Sstevel@tonic-gate #define	PROBE_1ST_DTSB(tsbe_ptr, vpg_4m, label)	/* g4/g5 clobbered */	\
4320Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
4330Sstevel@tonic-gate 	ldda	[tsbe_ptr]ASI_QUAD_LDD_PHYS, %g4 /* g4 = tag, g5 = data */ ;\
4340Sstevel@tonic-gate 	cmp	%g4, vpg_4m		/* compare tag w/ TSB */	;\
4350Sstevel@tonic-gate 	bne,pn	%xcc, label/**/1	/* branch if !match */		;\
4360Sstevel@tonic-gate 	  nop								;\
4370Sstevel@tonic-gate 	brgez,pn %g5, label/**/1					;\
4380Sstevel@tonic-gate 	  nop								;\
4390Sstevel@tonic-gate 	TT_TRACE(trace_tsbhit)						;\
4400Sstevel@tonic-gate 	DTLB_STUFF(%g5, %g1, %g2, %g3, %g4)				;\
4410Sstevel@tonic-gate 	/* trapstat expects tte in %g5 */				;\
4420Sstevel@tonic-gate 	retry				/* retry faulted instruction */	;\
4430Sstevel@tonic-gate label/**/1:								\
4440Sstevel@tonic-gate 	/* END CSTYLED */
4450Sstevel@tonic-gate 
4460Sstevel@tonic-gate 
4470Sstevel@tonic-gate /*
4480Sstevel@tonic-gate  * Same as above, only if the TTE doesn't have the execute
4490Sstevel@tonic-gate  * bit set, will branch to exec_fault directly.
4500Sstevel@tonic-gate  */
4510Sstevel@tonic-gate #define	PROBE_1ST_ITSB(tsbe_ptr, vpg_4m, label)				\
4520Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
4530Sstevel@tonic-gate 	ldda	[tsbe_ptr]ASI_QUAD_LDD_PHYS, %g4 /* g4 = tag, g5 = data */ ;\
4540Sstevel@tonic-gate 	cmp	%g4, vpg_4m		/* compare tag w/ TSB */	;\
4550Sstevel@tonic-gate 	bne,pn	%xcc, label/**/1	/* branch if !match */		;\
4560Sstevel@tonic-gate 	  nop								;\
4570Sstevel@tonic-gate 	brgez,pn %g5, label/**/1					;\
4580Sstevel@tonic-gate 	  nop								;\
4590Sstevel@tonic-gate 	andcc	%g5, TTE_EXECPRM_INT, %g0  /* check execute bit */	;\
4600Sstevel@tonic-gate 	bz,pn	%icc, exec_fault					;\
4610Sstevel@tonic-gate 	  nop								;\
4620Sstevel@tonic-gate 	TT_TRACE(trace_tsbhit)						;\
4630Sstevel@tonic-gate 	ITLB_STUFF(%g5, %g1, %g2, %g3, %g4)				;\
4640Sstevel@tonic-gate 	retry				/* retry faulted instruction */	;\
4650Sstevel@tonic-gate label/**/1:								\
4660Sstevel@tonic-gate 	/* END CSTYLED */
4670Sstevel@tonic-gate 
4680Sstevel@tonic-gate /*
4690Sstevel@tonic-gate  * vpg_4m = 4M virtual page number for tag matching (in)
4700Sstevel@tonic-gate  * tsbe_ptr = precomputed second TSB entry pointer (in)
4710Sstevel@tonic-gate  * label = label to use to make branch targets unique (text)
4720Sstevel@tonic-gate  *
4730Sstevel@tonic-gate  * For trapstat, we have to explicity use these registers.
4740Sstevel@tonic-gate  * g4 = tag portion of TSBE (out)
4750Sstevel@tonic-gate  * g5 = data portion of TSBE (out)
4760Sstevel@tonic-gate  */
4770Sstevel@tonic-gate #define	PROBE_2ND_DTSB(tsbe_ptr, vpg_4m, label)				\
4780Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
4790Sstevel@tonic-gate 	ldda	[tsbe_ptr]ASI_QUAD_LDD_PHYS, %g4  /* g4 = tag, g5 = data */ ;\
4800Sstevel@tonic-gate 	/* since we are looking at 2nd tsb, if it's valid, it must be 4M */ ;\
4810Sstevel@tonic-gate 	cmp	%g4, vpg_4m						;\
4820Sstevel@tonic-gate 	bne,pn	%xcc, label/**/1					;\
4830Sstevel@tonic-gate 	  nop								;\
4840Sstevel@tonic-gate 	brgez,pn %g5, label/**/1					;\
4850Sstevel@tonic-gate 	  nop								;\
4860Sstevel@tonic-gate 	mov	tsbe_ptr, %g1		/* trace_tsbhit wants ptr in %g1 */ ;\
4870Sstevel@tonic-gate 	TT_TRACE(trace_tsbhit)						;\
4880Sstevel@tonic-gate 	DTLB_STUFF(%g5, %g1, %g2, %g3, %g4)				;\
4890Sstevel@tonic-gate 	/* trapstat expects tte in %g5 */				;\
4900Sstevel@tonic-gate 	retry				/* retry faulted instruction */	;\
4910Sstevel@tonic-gate label/**/1:								\
4920Sstevel@tonic-gate 	/* END CSTYLED */
4930Sstevel@tonic-gate 
4940Sstevel@tonic-gate 
4950Sstevel@tonic-gate /*
4960Sstevel@tonic-gate  * Same as above, with the following additions:
4970Sstevel@tonic-gate  * If the TTE found is not executable, branch directly
4980Sstevel@tonic-gate  * to exec_fault.  If a TSB miss, branch to TSB miss handler.
4990Sstevel@tonic-gate  */
5000Sstevel@tonic-gate #define	PROBE_2ND_ITSB(tsbe_ptr, vpg_4m)				\
5010Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
5020Sstevel@tonic-gate 	ldda	[tsbe_ptr]ASI_QUAD_LDD_PHYS, %g4 /* g4 = tag, g5 = data */ ;\
5030Sstevel@tonic-gate 	cmp	%g4, vpg_4m		/* compare tag w/ TSB */	;\
5040Sstevel@tonic-gate 	bne,pn	%xcc, sfmmu_tsb_miss_tt	/* branch if !match */		;\
5050Sstevel@tonic-gate 	  nop								;\
5060Sstevel@tonic-gate 	brgez,pn %g5, sfmmu_tsb_miss_tt					;\
5070Sstevel@tonic-gate 	  nop								;\
5080Sstevel@tonic-gate 	andcc	%g5, TTE_EXECPRM_INT, %g0  /* check execute bit */	;\
5090Sstevel@tonic-gate 	bz,pn	%icc, exec_fault					;\
5100Sstevel@tonic-gate 	  mov	tsbe_ptr, %g1		/* trap trace wants ptr in %g1 */ ;\
5110Sstevel@tonic-gate 	TT_TRACE(trace_tsbhit)						;\
5120Sstevel@tonic-gate 	ITLB_STUFF(%g5, %g1, %g2, %g3, %g4)				;\
5130Sstevel@tonic-gate 	retry				/* retry faulted instruction */	\
5140Sstevel@tonic-gate 	/* END CSTYLED */
5150Sstevel@tonic-gate 
5164528Spaulsan /*
5174528Spaulsan  * 1. Get ctx1. The traptype is supplied by caller.
5184528Spaulsan  * 2. If iTSB miss, store in MMFSA_I_CTX
5194528Spaulsan  * 3. if dTSB miss, store in MMFSA_D_CTX
5204528Spaulsan  * 4. Thus the [D|I]TLB_STUFF will work as expected.
5214528Spaulsan  */
5224528Spaulsan #define	SAVE_CTX1(traptype, ctx1, tmp, label)				\
5234528Spaulsan 	/* BEGIN CSTYLED */						\
5244528Spaulsan 	mov	MMU_SCONTEXT1, tmp					;\
5254528Spaulsan 	ldxa	[tmp]ASI_MMU_CTX, ctx1					;\
5264528Spaulsan 	MMU_FAULT_STATUS_AREA(tmp)					;\
5274528Spaulsan 	cmp     traptype, FAST_IMMU_MISS_TT				;\
5284528Spaulsan 	be,a,pn %icc, label						;\
5294528Spaulsan 	  stx	ctx1, [tmp + MMFSA_I_CTX] 				;\
5304528Spaulsan 	cmp     traptype, T_INSTR_MMU_MISS				;\
5314528Spaulsan 	be,a,pn %icc, label						;\
5324528Spaulsan 	  stx	ctx1, [tmp + MMFSA_I_CTX]				;\
5334528Spaulsan 	stx	ctx1, [tmp + MMFSA_D_CTX]				;\
5344528Spaulsan label:
5354528Spaulsan 	/* END CSTYLED */
5364528Spaulsan 
5370Sstevel@tonic-gate #endif /* _ASM */
5380Sstevel@tonic-gate 
5390Sstevel@tonic-gate #ifdef	__cplusplus
5400Sstevel@tonic-gate }
5410Sstevel@tonic-gate #endif
5420Sstevel@tonic-gate 
5430Sstevel@tonic-gate #endif	/* _VM_MACH_SFMMU_H */
544