xref: /onnv-gate/usr/src/uts/sun4u/vm/mach_sfmmu.h (revision 4528:9ad45715d2ab)
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
51772Sjl139090  * Common Development and Distribution License (the "License").
61772Sjl139090  * 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*4528Spaulsan  * Copyright 2007 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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
380Sstevel@tonic-gate 
390Sstevel@tonic-gate #include <sys/x_call.h>
400Sstevel@tonic-gate #include <sys/cheetahregs.h>
410Sstevel@tonic-gate #include <sys/spitregs.h>
421772Sjl139090 #include <sys/opl_olympus_regs.h>
431772Sjl139090 
440Sstevel@tonic-gate #ifdef	__cplusplus
450Sstevel@tonic-gate extern "C" {
460Sstevel@tonic-gate #endif
470Sstevel@tonic-gate 
480Sstevel@tonic-gate /*
491772Sjl139090  * On sun4u platforms, user TSBs are accessed via virtual address by default.
501772Sjl139090  * Platforms that support ASI_SCRATCHPAD registers can define UTSB_PHYS in the
511772Sjl139090  * platform Makefile to access user TSBs via physical address but must also
521772Sjl139090  * designate one ASI_SCRATCHPAD register to hold the second user TSB.  To
531772Sjl139090  * designate the user TSB scratchpad register, platforms must provide a
541772Sjl139090  * definition for SCRATCHPAD_UTSBREG below.
551772Sjl139090  *
561772Sjl139090  * Platforms that use UTSB_PHYS do not allocate 2 locked TLB entries to access
571772Sjl139090  * the user TSBs.
580Sstevel@tonic-gate  */
591772Sjl139090 #if defined(UTSB_PHYS)
601772Sjl139090 
611772Sjl139090 #if defined(_OPL)
621772Sjl139090 #define	SCRATCHPAD_UTSBREG	OPL_SCRATCHPAD_UTSBREG4
631772Sjl139090 #else
641772Sjl139090 #error "Compiling UTSB_PHYS but no SCRATCHPAD_UTSBREG specified"
651772Sjl139090 #endif
661772Sjl139090 
671772Sjl139090 #endif /* UTSB_PHYS */
681772Sjl139090 
690Sstevel@tonic-gate 
700Sstevel@tonic-gate #ifdef _ASM
710Sstevel@tonic-gate 
720Sstevel@tonic-gate /*
73*4528Spaulsan  * This macro is used to set private secondary context register in
74*4528Spaulsan  * sfmmu_alloc_ctx().
75*4528Spaulsan  * Input:
76*4528Spaulsan  * cnum : cnum
77*4528Spaulsan  * arg2 : unused
78*4528Spaulsan  */
79*4528Spaulsan #define	SET_SECCTX(cnum, arg2, tmp1, tmp2)			\
80*4528Spaulsan 	mov	MMU_SCONTEXT, tmp1;				\
81*4528Spaulsan 	sethi	%hi(FLUSH_ADDR), tmp2;				\
82*4528Spaulsan 	stxa	cnum, [tmp1]ASI_MMU_CTX;			\
83*4528Spaulsan 	flush	tmp2
84*4528Spaulsan 
85*4528Spaulsan /*
860Sstevel@tonic-gate  * This macro is used in the MMU code to check if TL should be lowered from
870Sstevel@tonic-gate  * 2 to 1 to pop trapstat's state.  See the block comment in trapstat.c
880Sstevel@tonic-gate  * for details.
890Sstevel@tonic-gate  */
900Sstevel@tonic-gate 
910Sstevel@tonic-gate #define	TSTAT_CHECK_TL1(label, scr1, scr2)			\
920Sstevel@tonic-gate 	rdpr	%tpc, scr1;					\
930Sstevel@tonic-gate 	sethi	%hi(KERNELBASE), scr2;				\
940Sstevel@tonic-gate 	or	scr2, %lo(KERNELBASE), scr2; 			\
950Sstevel@tonic-gate 	cmp	scr1, scr2; 					\
960Sstevel@tonic-gate 	bgeu	%xcc, 9f;					\
970Sstevel@tonic-gate 	nop;							\
980Sstevel@tonic-gate 	ba	label;						\
990Sstevel@tonic-gate 	wrpr	%g0, 1, %tl;					\
1000Sstevel@tonic-gate 9:
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate 
1030Sstevel@tonic-gate /*
1040Sstevel@tonic-gate  * The following macros allow us to share majority of the
1050Sstevel@tonic-gate  * SFMMU code between sun4u and sun4v platforms.
1060Sstevel@tonic-gate  */
1070Sstevel@tonic-gate 
1080Sstevel@tonic-gate #define	SETUP_TSB_ASI(qlp, tmp)					\
1090Sstevel@tonic-gate 	movrz	qlp, ASI_N, tmp;				\
1100Sstevel@tonic-gate 	movrnz	qlp, ASI_MEM, tmp;				\
1110Sstevel@tonic-gate 	mov	tmp, %asi
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate /*
1140Sstevel@tonic-gate  * Macro to swtich to alternate global register on sun4u platforms
1150Sstevel@tonic-gate  * (not applicable to sun4v platforms)
1160Sstevel@tonic-gate  */
1170Sstevel@tonic-gate #define	USE_ALTERNATE_GLOBALS(scr)				\
1180Sstevel@tonic-gate 	rdpr	%pstate, scr;					\
1190Sstevel@tonic-gate 	wrpr	scr, PSTATE_MG | PSTATE_AG, %pstate
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate /*
1220Sstevel@tonic-gate  * Macro to set %gl register value on sun4v platforms
1230Sstevel@tonic-gate  * (not applicable to sun4u platforms)
1240Sstevel@tonic-gate  */
1250Sstevel@tonic-gate #define	SET_GL_REG(val)
1260Sstevel@tonic-gate 
1270Sstevel@tonic-gate /*
1280Sstevel@tonic-gate  * Get MMU data tag access register value
1290Sstevel@tonic-gate  *
1300Sstevel@tonic-gate  * In:
1310Sstevel@tonic-gate  *   tagacc, scr1 = scratch registers
1320Sstevel@tonic-gate  * Out:
1330Sstevel@tonic-gate  *   tagacc = MMU data tag access register value
1340Sstevel@tonic-gate  */
1350Sstevel@tonic-gate #define	GET_MMU_D_TAGACC(tagacc, scr1)				\
1360Sstevel@tonic-gate 	mov	MMU_TAG_ACCESS, scr1;				\
1370Sstevel@tonic-gate 	ldxa	[scr1]ASI_DMMU, tagacc
1380Sstevel@tonic-gate 
1390Sstevel@tonic-gate /*
1400Sstevel@tonic-gate  * Get MMU data tag target register
1410Sstevel@tonic-gate  *
1420Sstevel@tonic-gate  * In:
1430Sstevel@tonic-gate  *   ttarget, scr1 = scratch registers
1440Sstevel@tonic-gate  * Out:
1450Sstevel@tonic-gate  *   ttarget = MMU data tag target register value
1460Sstevel@tonic-gate  */
1470Sstevel@tonic-gate #define	GET_MMU_D_TTARGET(ttarget, scr1)			\
1480Sstevel@tonic-gate 	ldxa	[%g0]ASI_DMMU, ttarget
1490Sstevel@tonic-gate 
1500Sstevel@tonic-gate /*
1510Sstevel@tonic-gate  * Get MMU data/instruction tag access register values
1520Sstevel@tonic-gate  *
1530Sstevel@tonic-gate  * In:
1540Sstevel@tonic-gate  *   dtagacc, itagacc, scr1, scr2 = scratch registers
1550Sstevel@tonic-gate  * Out:
1560Sstevel@tonic-gate  *   dtagacc = MMU data tag access register value
1570Sstevel@tonic-gate  *   itagacc = MMU instruction tag access register value
1580Sstevel@tonic-gate  */
1590Sstevel@tonic-gate #define	GET_MMU_BOTH_TAGACC(dtagacc, itagacc, scr1, scr2)	\
1600Sstevel@tonic-gate 	mov	MMU_TAG_ACCESS, scr1;				\
1610Sstevel@tonic-gate 	ldxa	[scr1]ASI_DMMU, dtagacc;			\
1620Sstevel@tonic-gate 	ldxa	[scr1]ASI_IMMU, itagacc
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate /*
1650Sstevel@tonic-gate  * Get MMU data fault address from the tag access register
1660Sstevel@tonic-gate  *
1670Sstevel@tonic-gate  * In:
1680Sstevel@tonic-gate  *   daddr, scr1 = scratch registers
1690Sstevel@tonic-gate  * Out:
1700Sstevel@tonic-gate  *   daddr = MMU data fault address
1710Sstevel@tonic-gate  */
1720Sstevel@tonic-gate #define	GET_MMU_D_ADDR(daddr, scr1)				\
1730Sstevel@tonic-gate 	mov	MMU_TAG_ACCESS, scr1;				\
1740Sstevel@tonic-gate 	ldxa	[scr1]ASI_DMMU, daddr;				\
1750Sstevel@tonic-gate 	set	TAGACC_CTX_MASK, scr1;				\
1760Sstevel@tonic-gate 	andn	daddr, scr1, daddr
1770Sstevel@tonic-gate 
1780Sstevel@tonic-gate 
1790Sstevel@tonic-gate /*
1800Sstevel@tonic-gate  * Load ITLB entry
1810Sstevel@tonic-gate  *
1820Sstevel@tonic-gate  * In:
1830Sstevel@tonic-gate  *   tte = reg containing tte
1840Sstevel@tonic-gate  *   scr1, scr2, scr3, scr4 = scratch registers (not used)
1850Sstevel@tonic-gate  */
1860Sstevel@tonic-gate #define	ITLB_STUFF(tte, scr1, scr2, scr3, scr4)			\
1870Sstevel@tonic-gate 	stxa	tte, [%g0]ASI_ITLB_IN
1880Sstevel@tonic-gate 
1890Sstevel@tonic-gate /*
1900Sstevel@tonic-gate  * Load DTLB entry
1910Sstevel@tonic-gate  *
1920Sstevel@tonic-gate  * In:
1930Sstevel@tonic-gate  *   tte = reg containing tte
1940Sstevel@tonic-gate  *   scr1, scr2, scr3, scr4 = scratch register (not used)
1950Sstevel@tonic-gate  */
1960Sstevel@tonic-gate #define	DTLB_STUFF(tte, scr1, scr2, scr3, scr4)			\
1970Sstevel@tonic-gate 	stxa	tte, [%g0]ASI_DTLB_IN
1980Sstevel@tonic-gate 
1990Sstevel@tonic-gate 
2000Sstevel@tonic-gate /*
2010Sstevel@tonic-gate  * Returns PFN given the TTE and vaddr
2020Sstevel@tonic-gate  *
2030Sstevel@tonic-gate  * In:
2040Sstevel@tonic-gate  *   tte = reg containing tte
2050Sstevel@tonic-gate  *   vaddr = reg containing vaddr
2060Sstevel@tonic-gate  *   scr1, scr2, scr3 = scratch registers
2070Sstevel@tonic-gate  * Out:
2080Sstevel@tonic-gate  *   tte = PFN value
2090Sstevel@tonic-gate  */
2100Sstevel@tonic-gate #define	TTETOPFN(tte, vaddr, label, scr1, scr2, scr3)			\
2110Sstevel@tonic-gate 	srlx	tte, TTE_SZ_SHFT, scr1;					\
2120Sstevel@tonic-gate 	and	scr1, TTE_SZ_BITS, scr1;	/* scr1 = tte_size */	\
2130Sstevel@tonic-gate 	srlx	tte, TTE_SZ2_SHFT, scr3;				\
2140Sstevel@tonic-gate 	and	scr3, TTE_SZ2_BITS, scr3;	/* scr3 = tte_size2 */	\
2150Sstevel@tonic-gate 	or	scr1, scr3, scr1;					\
2160Sstevel@tonic-gate 	sllx	scr1, 1, scr2;						\
2170Sstevel@tonic-gate 	add	scr2, scr1, scr2;		/* mulx 3 */		\
2180Sstevel@tonic-gate 	sllx	tte, TTE_PA_LSHIFT, tte;				\
2190Sstevel@tonic-gate 	add	scr2, MMU_PAGESHIFT + TTE_PA_LSHIFT, scr3;		\
2200Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
2210Sstevel@tonic-gate 	brz,pt	scr2, label/**/1;					\
2220Sstevel@tonic-gate 	  srlx	tte, scr3, tte;						\
2230Sstevel@tonic-gate 	/* END CSTYLED */						\
2240Sstevel@tonic-gate 	sllx	tte, scr2, tte;						\
2250Sstevel@tonic-gate 	set	1, scr1;						\
2260Sstevel@tonic-gate 	add	scr2, MMU_PAGESHIFT, scr3;				\
2270Sstevel@tonic-gate 	sllx	scr1, scr3, scr1;					\
2280Sstevel@tonic-gate 	sub	scr1, 1, scr1;		/* g2=TTE_PAGE_OFFSET(ttesz) */	\
2290Sstevel@tonic-gate 	and	vaddr, scr1, scr2;					\
2300Sstevel@tonic-gate 	srln	scr2, MMU_PAGESHIFT, scr2;				\
2310Sstevel@tonic-gate 	or	tte, scr2, tte;						\
2320Sstevel@tonic-gate 	/* CSTYLED */							\
2330Sstevel@tonic-gate label/**/1:
2340Sstevel@tonic-gate 
2350Sstevel@tonic-gate 
2360Sstevel@tonic-gate /*
2370Sstevel@tonic-gate  * TTE_SET_REF_ML is a macro that updates the reference bit if it is
2380Sstevel@tonic-gate  * not already set.
2390Sstevel@tonic-gate  *
2400Sstevel@tonic-gate  * Parameters:
2410Sstevel@tonic-gate  * tte      = reg containing tte
2420Sstevel@tonic-gate  * ttepa    = physical pointer to tte
2430Sstevel@tonic-gate  * tteva    = virtual ptr to tte
2440Sstevel@tonic-gate  * tsbarea  = tsb miss area
2450Sstevel@tonic-gate  * tmp1     = tmp reg
2460Sstevel@tonic-gate  * label    = temporary label
2470Sstevel@tonic-gate  */
2480Sstevel@tonic-gate 
2490Sstevel@tonic-gate #define	TTE_SET_REF_ML(tte, ttepa, tteva, tsbarea, tmp1, label)		\
2500Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
2510Sstevel@tonic-gate 	/* check reference bit */					\
2520Sstevel@tonic-gate 	andcc	tte, TTE_REF_INT, %g0;					\
2530Sstevel@tonic-gate 	bnz,pt	%xcc, label/**/4;	/* if ref bit set-skip ahead */	\
2540Sstevel@tonic-gate 	  nop;								\
2550Sstevel@tonic-gate 	GET_CPU_IMPL(tmp1);						\
2561772Sjl139090 	cmp	tmp1, SPITFIRE_IMPL;					\
2571772Sjl139090 	blt	%icc, label/**/2;	/* skip flush if FJ-OPL cpus */	\
2580Sstevel@tonic-gate 	cmp	tmp1, CHEETAH_IMPL;					\
2590Sstevel@tonic-gate 	bl,a	%icc, label/**/1;					\
2600Sstevel@tonic-gate 	/* update reference bit */					\
2610Sstevel@tonic-gate 	lduh	[tsbarea + TSBMISS_DMASK], tmp1;			\
2620Sstevel@tonic-gate 	stxa	%g0, [ttepa]ASI_DC_INVAL; /* flush line from dcache */	\
2630Sstevel@tonic-gate 	membar	#Sync;							\
2640Sstevel@tonic-gate 	ba	label/**/2;						\
2650Sstevel@tonic-gate label/**/1:								\
2660Sstevel@tonic-gate 	and	tteva, tmp1, tmp1;					\
2670Sstevel@tonic-gate 	stxa	%g0, [tmp1]ASI_DC_TAG; /* flush line from dcache */	\
2680Sstevel@tonic-gate 	membar	#Sync;							\
2690Sstevel@tonic-gate label/**/2:								\
2700Sstevel@tonic-gate 	or	tte, TTE_REF_INT, tmp1;					\
2710Sstevel@tonic-gate 	casxa	[ttepa]ASI_MEM, tte, tmp1; 	/* update ref bit */	\
2720Sstevel@tonic-gate 	cmp	tte, tmp1;						\
2730Sstevel@tonic-gate 	bne,a,pn %xcc, label/**/2;					\
2740Sstevel@tonic-gate 	ldxa	[ttepa]ASI_MEM, tte;	/* MMU_READTTE through pa */	\
2750Sstevel@tonic-gate 	or	tte, TTE_REF_INT, tte;					\
2760Sstevel@tonic-gate label/**/4:								\
2770Sstevel@tonic-gate 	/* END CSTYLED */
2780Sstevel@tonic-gate 
2790Sstevel@tonic-gate 
2800Sstevel@tonic-gate /*
2810Sstevel@tonic-gate  * TTE_SET_REFMOD_ML is a macro that updates the reference and modify bits
2820Sstevel@tonic-gate  * if not already set.
2830Sstevel@tonic-gate  *
2840Sstevel@tonic-gate  * Parameters:
2850Sstevel@tonic-gate  * tte      = reg containing tte
2860Sstevel@tonic-gate  * ttepa    = physical pointer to tte
2870Sstevel@tonic-gate  * tteva    = virtual ptr to tte
2880Sstevel@tonic-gate  * tsbarea  = tsb miss area
2890Sstevel@tonic-gate  * tmp1     = tmp reg
2900Sstevel@tonic-gate  * label    = temporary label
2910Sstevel@tonic-gate  * exitlabel = label where to jump to if write perm bit not set.
2920Sstevel@tonic-gate  */
2930Sstevel@tonic-gate 
2940Sstevel@tonic-gate #define	TTE_SET_REFMOD_ML(tte, ttepa, tteva, tsbarea, tmp1, label,	\
2950Sstevel@tonic-gate 	exitlabel)							\
2960Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
2970Sstevel@tonic-gate 	/* check reference bit */					\
2980Sstevel@tonic-gate 	andcc	tte, TTE_WRPRM_INT, %g0;				\
2990Sstevel@tonic-gate 	bz,pn	%xcc, exitlabel;	/* exit if wr_perm not set */	\
3000Sstevel@tonic-gate 	  nop;								\
3010Sstevel@tonic-gate 	andcc	tte, TTE_HWWR_INT, %g0;					\
3020Sstevel@tonic-gate 	bnz,pn	%xcc, label/**/4;	/* nothing to do */		\
3030Sstevel@tonic-gate 	  nop;								\
3040Sstevel@tonic-gate 	GET_CPU_IMPL(tmp1);						\
3051772Sjl139090 	cmp	tmp1, SPITFIRE_IMPL;					\
3061772Sjl139090 	blt	%icc, label/**/2;	/* skip flush if FJ-OPL cpus */	\
3070Sstevel@tonic-gate 	cmp	tmp1, CHEETAH_IMPL;					\
3080Sstevel@tonic-gate 	bl,a	%icc, label/**/1;					\
3090Sstevel@tonic-gate 	/* update reference bit */					\
3100Sstevel@tonic-gate 	lduh	[tsbarea + TSBMISS_DMASK], tmp1;			\
3110Sstevel@tonic-gate 	stxa    %g0, [ttepa]ASI_DC_INVAL; /* flush line from dcache */ 	\
3120Sstevel@tonic-gate 	membar	#Sync;							\
3130Sstevel@tonic-gate 	ba	label/**/2;						\
3140Sstevel@tonic-gate label/**/1:								\
3150Sstevel@tonic-gate 	and	tteva, tmp1, tmp1;					\
3160Sstevel@tonic-gate 	stxa	%g0, [tmp1]ASI_DC_TAG; /* flush line from dcache */	\
3170Sstevel@tonic-gate 	membar	#Sync;							\
3180Sstevel@tonic-gate label/**/2:								\
3190Sstevel@tonic-gate 	or	tte, TTE_HWWR_INT | TTE_REF_INT, tmp1;			\
3200Sstevel@tonic-gate 	casxa	[ttepa]ASI_MEM, tte, tmp1; /* update ref/mod bit */	\
3210Sstevel@tonic-gate 	cmp	tte, tmp1;						\
3220Sstevel@tonic-gate 	bne,a,pn %xcc, label/**/2;					\
3230Sstevel@tonic-gate 	  ldxa	[ttepa]ASI_MEM, tte;	/* MMU_READTTE through pa */	\
3240Sstevel@tonic-gate 	or	tte, TTE_HWWR_INT | TTE_REF_INT, tte;			\
3250Sstevel@tonic-gate label/**/4:								\
3260Sstevel@tonic-gate 	/* END CSTYLED */
3270Sstevel@tonic-gate 
3280Sstevel@tonic-gate 
3291772Sjl139090 #ifndef UTSB_PHYS
3301772Sjl139090 
3310Sstevel@tonic-gate /*
3320Sstevel@tonic-gate  * Synthesize TSB base register contents for a process with
3330Sstevel@tonic-gate  * a single TSB.
3340Sstevel@tonic-gate  *
3350Sstevel@tonic-gate  * We patch the virtual address mask in at runtime since the
3360Sstevel@tonic-gate  * number of significant virtual address bits in the TSB VA
3370Sstevel@tonic-gate  * can vary depending upon the TSB slab size being used on the
3380Sstevel@tonic-gate  * machine.
3390Sstevel@tonic-gate  *
3400Sstevel@tonic-gate  * In:
3410Sstevel@tonic-gate  *   tsbinfo = TSB info pointer (ro)
3420Sstevel@tonic-gate  *   vabase = value of utsb_vabase (ro)
3430Sstevel@tonic-gate  * Out:
3440Sstevel@tonic-gate  *   tsbreg = value to program into TSB base register
3450Sstevel@tonic-gate  */
3460Sstevel@tonic-gate 
3470Sstevel@tonic-gate #define	MAKE_TSBREG(tsbreg, tsbinfo, vabase, tmp1, tmp2, label)		\
3480Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
3490Sstevel@tonic-gate 	ldx	[tsbinfo + TSBINFO_VADDR], tmp1;			\
3500Sstevel@tonic-gate 	.global	label/**/_tsbreg_vamask					;\
3510Sstevel@tonic-gate label/**/_tsbreg_vamask:						\
3520Sstevel@tonic-gate 	or	%g0, RUNTIME_PATCH, tsbreg;				\
3530Sstevel@tonic-gate 	lduh	[tsbinfo + TSBINFO_SZCODE], tmp2;			\
3540Sstevel@tonic-gate 	sllx	tsbreg, TSBREG_VAMASK_SHIFT, tsbreg;			\
3550Sstevel@tonic-gate 	or	vabase, tmp2, tmp2;					\
3560Sstevel@tonic-gate 	and	tmp1, tsbreg, tsbreg;					\
3570Sstevel@tonic-gate 	or	tsbreg, tmp2, tsbreg;					\
3580Sstevel@tonic-gate 	/* END CSTYLED */
3590Sstevel@tonic-gate 
3600Sstevel@tonic-gate 
3610Sstevel@tonic-gate /*
3620Sstevel@tonic-gate  * Synthesize TSB base register contents for a process with
3630Sstevel@tonic-gate  * two TSBs.  See hat_sfmmu.h for the layout of the TSB base
3640Sstevel@tonic-gate  * register in this case.
3650Sstevel@tonic-gate  *
3660Sstevel@tonic-gate  * In:
3670Sstevel@tonic-gate  *   tsb1 = pointer to first TSB info (ro)
3680Sstevel@tonic-gate  *   tsb2 = pointer to second TSB info (ro)
3690Sstevel@tonic-gate  * Out:
3700Sstevel@tonic-gate  *   tsbreg = value to program into TSB base register
3710Sstevel@tonic-gate  */
3720Sstevel@tonic-gate #define	MAKE_TSBREG_SECTSB(tsbreg, tsb1, tsb2, tmp1, tmp2, tmp3, label)	\
3730Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
3740Sstevel@tonic-gate 	set	TSBREG_MSB_CONST, tmp3					;\
3750Sstevel@tonic-gate 	sllx	tmp3, TSBREG_MSB_SHIFT, tsbreg				;\
3760Sstevel@tonic-gate 	.global	label/**/_tsbreg_vamask					;\
3770Sstevel@tonic-gate label/**/_tsbreg_vamask:						;\
3780Sstevel@tonic-gate 	or	%g0, RUNTIME_PATCH, tmp3				;\
3790Sstevel@tonic-gate 	sll	tmp3, TSBREG_VAMASK_SHIFT, tmp3				;\
3800Sstevel@tonic-gate 	ldx	[tsb1 + TSBINFO_VADDR], tmp1				;\
3810Sstevel@tonic-gate 	ldx	[tsb2 + TSBINFO_VADDR], tmp2				;\
3820Sstevel@tonic-gate 	and	tmp1, tmp3, tmp1					;\
3830Sstevel@tonic-gate 	and	tmp2, tmp3, tmp2					;\
3840Sstevel@tonic-gate 	sllx	tmp2, TSBREG_SECTSB_MKSHIFT, tmp2			;\
3850Sstevel@tonic-gate 	or	tmp1, tmp2, tmp3					;\
3860Sstevel@tonic-gate 	or	tsbreg, tmp3, tsbreg					;\
3870Sstevel@tonic-gate 	lduh	[tsb1 + TSBINFO_SZCODE], tmp1				;\
3880Sstevel@tonic-gate 	lduh	[tsb2 + TSBINFO_SZCODE], tmp2				;\
3890Sstevel@tonic-gate 	and	tmp1, TSB_SOFTSZ_MASK, tmp1				;\
3900Sstevel@tonic-gate 	and	tmp2, TSB_SOFTSZ_MASK, tmp2				;\
3910Sstevel@tonic-gate 	sllx	tmp2, TSBREG_SECSZ_SHIFT, tmp2				;\
3920Sstevel@tonic-gate 	or	tmp1, tmp2, tmp3					;\
3930Sstevel@tonic-gate 	or	tsbreg, tmp3, tsbreg					;\
3940Sstevel@tonic-gate 	/* END CSTYLED */
3950Sstevel@tonic-gate 
3960Sstevel@tonic-gate 
3970Sstevel@tonic-gate /*
3980Sstevel@tonic-gate  * Load the locked TSB TLB entry.
3990Sstevel@tonic-gate  *
4000Sstevel@tonic-gate  * In:
4010Sstevel@tonic-gate  *   tsbinfo = tsb_info pointer as va (ro)
4020Sstevel@tonic-gate  *   tteidx = shifted index into TLB to load the locked entry (ro)
4030Sstevel@tonic-gate  *   va = virtual address at which to load the locked TSB entry (ro)
4040Sstevel@tonic-gate  * Out:
4050Sstevel@tonic-gate  * Scratch:
4060Sstevel@tonic-gate  *   tmp
4070Sstevel@tonic-gate  */
4080Sstevel@tonic-gate #define	LOAD_TSBTTE(tsbinfo, tteidx, va, tmp)				\
4090Sstevel@tonic-gate 	mov	MMU_TAG_ACCESS, tmp;					\
4100Sstevel@tonic-gate 	stxa	va, [tmp]ASI_DMMU;		/* set tag access */	\
4110Sstevel@tonic-gate 	membar	#Sync;							\
4120Sstevel@tonic-gate 	ldx	[tsbinfo + TSBINFO_TTE], tmp;	/* fetch locked tte */	\
4130Sstevel@tonic-gate 	stxa	tmp, [tteidx]ASI_DTLB_ACCESS;	/* load locked tte */	\
4140Sstevel@tonic-gate 	membar	#Sync
4150Sstevel@tonic-gate 
4160Sstevel@tonic-gate 
4170Sstevel@tonic-gate /*
4180Sstevel@tonic-gate  * In the current implementation, TSBs usually come from physically
4190Sstevel@tonic-gate  * contiguous chunks of memory up to 4MB in size, but 8K TSBs may be
4200Sstevel@tonic-gate  * allocated from 8K chunks of memory under certain conditions.  To
4210Sstevel@tonic-gate  * prevent aliasing in the virtual address cache when the TSB slab is
4220Sstevel@tonic-gate  * 8K in size we must align the reserved (TL>0) TSB virtual address to
4230Sstevel@tonic-gate  * have the same low-order bits as the kernel (TL=0) TSB virtual address,
4240Sstevel@tonic-gate  * and map 8K TSBs with an 8K TTE.  In cases where the TSB reserved VA
4250Sstevel@tonic-gate  * range is smaller than the assumed 4M we will patch the shift at
4260Sstevel@tonic-gate  * runtime; otherwise we leave it alone (which is why RUNTIME_PATCH
4270Sstevel@tonic-gate  * constant doesn't appear below).
4280Sstevel@tonic-gate  *
4290Sstevel@tonic-gate  * In:
4300Sstevel@tonic-gate  *   tsbinfo (ro)
4310Sstevel@tonic-gate  *   resva: reserved VA base for this TSB
4320Sstevel@tonic-gate  * Out:
4330Sstevel@tonic-gate  *   resva: corrected VA for this TSB
4340Sstevel@tonic-gate  */
4350Sstevel@tonic-gate #define	RESV_OFFSET(tsbinfo, resva, tmp1, label)			\
4360Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
4370Sstevel@tonic-gate 	lduh	[tsbinfo + TSBINFO_SZCODE], tmp1			;\
4380Sstevel@tonic-gate 	brgz,pn	tmp1, 9f						;\
4390Sstevel@tonic-gate 	  nop								;\
4400Sstevel@tonic-gate 	ldx	[tsbinfo + TSBINFO_VADDR], tmp1				;\
4410Sstevel@tonic-gate 	.global	label/**/_resv_offset					;\
4420Sstevel@tonic-gate label/**/_resv_offset:							;\
4430Sstevel@tonic-gate 	sllx	tmp1, (64 - MMU_PAGESHIFT4M), tmp1			;\
4440Sstevel@tonic-gate 	srlx	tmp1, (64 - MMU_PAGESHIFT4M), tmp1			;\
4450Sstevel@tonic-gate 	or	tmp1, resva, resva					;\
4461772Sjl139090 9:	/* END CSTYLED */
4470Sstevel@tonic-gate 
4480Sstevel@tonic-gate /*
4490Sstevel@tonic-gate  * Determine the pointer of the entry in the first TSB to probe given
4500Sstevel@tonic-gate  * the 8K TSB pointer register contents.
4510Sstevel@tonic-gate  *
4520Sstevel@tonic-gate  * In:
4530Sstevel@tonic-gate  *   tsbp8k = 8K TSB pointer register (ro)
4540Sstevel@tonic-gate  *   tmp = scratch register
4550Sstevel@tonic-gate  *   label = label for hot patching of utsb_vabase
4560Sstevel@tonic-gate  *
4570Sstevel@tonic-gate  * Out: tsbe_ptr = TSB entry address
4580Sstevel@tonic-gate  *
4590Sstevel@tonic-gate  * Note: This function is patched at runtime for performance reasons.
4601772Sjl139090  *	 Any changes here require sfmmu_patch_utsb fixed.
4610Sstevel@tonic-gate  */
4620Sstevel@tonic-gate 
4630Sstevel@tonic-gate #define	GET_1ST_TSBE_PTR(tsbp8k, tsbe_ptr, tmp, label)			\
4640Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
4650Sstevel@tonic-gate label/**/_get_1st_tsbe_ptr:						;\
4660Sstevel@tonic-gate 	RUNTIME_PATCH_SETX(tsbe_ptr, tmp)				;\
4670Sstevel@tonic-gate 	/* tsbeptr = contents of utsb_vabase */				;\
4680Sstevel@tonic-gate 	/* clear upper bits leaving just bits 21:0 of TSB ptr. */	;\
4690Sstevel@tonic-gate 	sllx	tsbp8k, TSBREG_FIRTSB_SHIFT, tmp			;\
4700Sstevel@tonic-gate 	/* finish clear */						;\
4710Sstevel@tonic-gate 	srlx	tmp, TSBREG_FIRTSB_SHIFT, tmp				;\
4720Sstevel@tonic-gate 	/* or-in bits 41:22 of the VA to form the real pointer. */	;\
4730Sstevel@tonic-gate 	or	tsbe_ptr, tmp, tsbe_ptr					\
4740Sstevel@tonic-gate 	/* END CSTYLED */
4750Sstevel@tonic-gate 
4760Sstevel@tonic-gate /*
4770Sstevel@tonic-gate  * Determine the base address of the second TSB given the 8K TSB
4780Sstevel@tonic-gate  * pointer register contents.
4790Sstevel@tonic-gate  *
4800Sstevel@tonic-gate  * In:
4810Sstevel@tonic-gate  *   tsbp8k = 8K TSB pointer register (ro)
4820Sstevel@tonic-gate  *   tmp = scratch register
4830Sstevel@tonic-gate  *   label = label for hot patching of utsb_vabase
4840Sstevel@tonic-gate  *
4850Sstevel@tonic-gate  * Out:
4860Sstevel@tonic-gate  *   tsbbase = TSB base address
4870Sstevel@tonic-gate  *
4880Sstevel@tonic-gate  * Note: This function is patched at runtime for performance reasons.
4890Sstevel@tonic-gate  *	 Any changes here require sfmmu_patch_utsb fixed.
4900Sstevel@tonic-gate  */
4910Sstevel@tonic-gate 
4920Sstevel@tonic-gate #define	GET_2ND_TSB_BASE(tsbp8k, tsbbase, tmp, label)			\
4930Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
4940Sstevel@tonic-gate label/**/_get_2nd_tsb_base:						;\
4950Sstevel@tonic-gate 	RUNTIME_PATCH_SETX(tsbbase, tmp)				;\
4960Sstevel@tonic-gate 	/* tsbbase = contents of utsb4m_vabase */			;\
4970Sstevel@tonic-gate 	/* clear upper bits leaving just bits 21:xx of TSB addr. */	;\
4980Sstevel@tonic-gate 	sllx	tsbp8k, TSBREG_SECTSB_LSHIFT, tmp			;\
4990Sstevel@tonic-gate 	/* clear lower bits leaving just 21:13 in 8:0 */		;\
5000Sstevel@tonic-gate 	srlx	tmp, (TSBREG_SECTSB_RSHIFT + MMU_PAGESHIFT), tmp	;\
5010Sstevel@tonic-gate 	/* adjust TSB offset to bits 21:13 */				;\
5020Sstevel@tonic-gate 	sllx	tmp, MMU_PAGESHIFT, tmp					;\
5030Sstevel@tonic-gate 	or	tsbbase, tmp, tsbbase					;\
5040Sstevel@tonic-gate 	/* END CSTYLED */
5050Sstevel@tonic-gate 
5060Sstevel@tonic-gate /*
5070Sstevel@tonic-gate  * Determine the size code of the second TSB given the 8K TSB
5080Sstevel@tonic-gate  * pointer register contents.
5090Sstevel@tonic-gate  *
5100Sstevel@tonic-gate  * In:
5110Sstevel@tonic-gate  *   tsbp8k = 8K TSB pointer register (ro)
5120Sstevel@tonic-gate  * Out:
5130Sstevel@tonic-gate  *   size = TSB size code
5140Sstevel@tonic-gate  */
5150Sstevel@tonic-gate 
5160Sstevel@tonic-gate #define	GET_2ND_TSB_SIZE(tsbp8k, size)					\
5170Sstevel@tonic-gate 	srlx	tsbp8k, TSBREG_SECSZ_SHIFT, size;			\
5180Sstevel@tonic-gate 	and	size, TSB_SOFTSZ_MASK, size
5190Sstevel@tonic-gate 
5200Sstevel@tonic-gate /*
5210Sstevel@tonic-gate  * Get the location in the 2nd TSB of the tsbe for this fault.
5220Sstevel@tonic-gate  * Assumes that the second TSB only contains 4M mappings.
5230Sstevel@tonic-gate  *
5240Sstevel@tonic-gate  * In:
5250Sstevel@tonic-gate  *   tagacc = tag access register (clobbered)
5260Sstevel@tonic-gate  *   tsbp8k = contents of TSB8K pointer register (ro)
5270Sstevel@tonic-gate  *   tmp1, tmp2 = scratch registers
5280Sstevel@tonic-gate  *   label = label at which to patch in reserved TSB 4M VA range
5290Sstevel@tonic-gate  * Out:
5300Sstevel@tonic-gate  *   tsbe_ptr = pointer to the tsbe in the 2nd TSB
5310Sstevel@tonic-gate  */
5320Sstevel@tonic-gate #define	GET_2ND_TSBE_PTR(tagacc, tsbp8k, tsbe_ptr, tmp1, tmp2, label)	\
5330Sstevel@tonic-gate 	GET_2ND_TSB_BASE(tsbp8k, tsbe_ptr, tmp2, label);		\
5340Sstevel@tonic-gate 	/* tsbe_ptr = TSB base address, tmp2 = junk */			\
5350Sstevel@tonic-gate 	GET_2ND_TSB_SIZE(tsbp8k, tmp1);					\
5360Sstevel@tonic-gate 	/* tmp1 = TSB size code */					\
5370Sstevel@tonic-gate 	GET_TSBE_POINTER(MMU_PAGESHIFT4M, tsbe_ptr, tagacc, tmp1, tmp2)
5380Sstevel@tonic-gate 
5391772Sjl139090 #endif /* UTSB_PHYS */
5401772Sjl139090 
5411772Sjl139090 
5421772Sjl139090 #ifdef UTSB_PHYS
5431772Sjl139090 
5441772Sjl139090 /*
5451772Sjl139090  * Synthesize a TSB base register contents for a process.
5461772Sjl139090  *
5471772Sjl139090  * In:
5481772Sjl139090  *   tsbinfo = TSB info pointer (ro)
5491772Sjl139090  *   tsbreg, tmp1 = scratch registers
5501772Sjl139090  * Out:
5511772Sjl139090  *   tsbreg = value to program into TSB base register
5521772Sjl139090  */
5531772Sjl139090 
5541772Sjl139090 #define	MAKE_UTSBREG_PHYS(tsbinfo, tsbreg, tmp1)			\
5551772Sjl139090 	ldx	[tsbinfo + TSBINFO_PADDR], tsbreg;		\
5561772Sjl139090 	lduh	[tsbinfo + TSBINFO_SZCODE], tmp1;		\
5571772Sjl139090 	and	tmp1, TSB_SOFTSZ_MASK, tmp1;			\
5581772Sjl139090 	or	tsbreg, tmp1, tsbreg;				\
5591772Sjl139090 
5601772Sjl139090 /*
5611772Sjl139090  * Load TSB base register into a dedicated scratchpad register.
5621772Sjl139090  * This register contains utsb_pabase in bits 63:13, and TSB size
5631772Sjl139090  * code in bits 2:0.
5641772Sjl139090  *
5651772Sjl139090  * In:
5661772Sjl139090  *   tsbreg = value to load (ro)
5671772Sjl139090  *   regnum = constant or register
5681772Sjl139090  *   tmp1 = scratch register
5691772Sjl139090  * Out:
5701772Sjl139090  *   Specified scratchpad register updated
5711772Sjl139090  *
5721772Sjl139090  * Note: If this is enabled on Panther, a membar #Sync is required
5731772Sjl139090  *	 following an ASI store to the scratchpad registers.
5741772Sjl139090  */
5751772Sjl139090 
5761772Sjl139090 #define	SET_UTSBREG(regnum, tsbreg, tmp1)				\
5771772Sjl139090 	mov	regnum, tmp1;						\
5781772Sjl139090 	stxa	tsbreg, [tmp1]ASI_SCRATCHPAD;	/* save tsbreg */	\
5791772Sjl139090 
5801772Sjl139090 /*
5811772Sjl139090  * Get TSB base register from the scratchpad
5821772Sjl139090  *
5831772Sjl139090  * In:
5841772Sjl139090  *   regnum = constant or register
5851772Sjl139090  *   tsbreg = scratch
5861772Sjl139090  * Out:
5871772Sjl139090  *   tsbreg = tsbreg from the specified scratchpad register
5881772Sjl139090  */
5891772Sjl139090 
5901772Sjl139090 #define	GET_UTSBREG(regnum, tsbreg)					\
5911772Sjl139090 	mov	regnum, tsbreg;						\
5921772Sjl139090 	ldxa	[tsbreg]ASI_SCRATCHPAD, tsbreg
5931772Sjl139090 
5941772Sjl139090 /*
5951772Sjl139090  * Determine the pointer of the entry in the first TSB to probe given
5961772Sjl139090  * the 8K TSB pointer register contents.
5971772Sjl139090  *
5981772Sjl139090  * In:
5991772Sjl139090  *   tagacc = tag access register
6001772Sjl139090  *   tsbe_ptr = 8K TSB pointer register
6011772Sjl139090  *   tmp = scratch registers
6021772Sjl139090  *
6031772Sjl139090  * Out: tsbe_ptr = TSB entry address
6041772Sjl139090  *
6051772Sjl139090  * Note: This macro is a nop since the 8K TSB pointer register
6061772Sjl139090  *	 is the entry pointer and does not need to be decoded.
6071772Sjl139090  *	 It is defined to allow for code sharing with sun4v.
6081772Sjl139090  */
6091772Sjl139090 
6101772Sjl139090 #define	GET_1ST_TSBE_PTR(tagacc, tsbe_ptr, tmp1, tmp2)
6111772Sjl139090 
6121772Sjl139090 /*
6131772Sjl139090  * Get the location in the 2nd TSB of the tsbe for this fault.
6141772Sjl139090  * Assumes that the second TSB only contains 4M mappings.
6151772Sjl139090  *
6161772Sjl139090  * In:
6171772Sjl139090  *   tagacc = tag access register (not clobbered)
6181772Sjl139090  *   tsbe = 2nd TSB base register
6191772Sjl139090  *   tmp1, tmp2 = scratch registers
6201772Sjl139090  * Out:
6211772Sjl139090  *   tsbe = pointer to the tsbe in the 2nd TSB
6221772Sjl139090  */
6231772Sjl139090 
6241772Sjl139090 #define	GET_2ND_TSBE_PTR(tagacc, tsbe, tmp1, tmp2)			\
6251772Sjl139090 	and	tsbe, TSB_SOFTSZ_MASK, tmp2;	/* tmp2=szc */		\
6261772Sjl139090 	andn	tsbe, TSB_SOFTSZ_MASK, tsbe;	/* tsbbase */		\
6271772Sjl139090 	mov	TSB_ENTRIES(0), tmp1;	/* nentries in TSB size 0 */	\
6281772Sjl139090 	sllx	tmp1, tmp2, tmp1;	/* tmp1 = nentries in TSB */	\
6291772Sjl139090 	sub	tmp1, 1, tmp1;		/* mask = nentries - 1 */	\
6301772Sjl139090 	srlx	tagacc, MMU_PAGESHIFT4M, tmp2; 				\
6311772Sjl139090 	and	tmp2, tmp1, tmp1;	/* tsbent = virtpage & mask */	\
6321772Sjl139090 	sllx	tmp1, TSB_ENTRY_SHIFT, tmp1;	/* entry num --> ptr */	\
6331772Sjl139090 	add	tsbe, tmp1, tsbe	/* add entry offset to TSB base */
6341772Sjl139090 
6351772Sjl139090 /*
6361772Sjl139090  * Read the 2nd TSB base register.  This is not done in GET_2ND_TSBE_PTR as
6371772Sjl139090  * an optimization since the TLB miss trap handler entries have potentially
6381772Sjl139090  * already loaded the 2nd TSB base reg when we invoke GET_2ND_TSBE_PTR.
6391772Sjl139090  *
6401772Sjl139090  * Out:
6411772Sjl139090  *   tsbreg = contents of the 2nd TSB base register
6421772Sjl139090  */
6431772Sjl139090 #define	GET_2ND_TSBREG(tsbreg)						\
6441772Sjl139090 	GET_UTSBREG(SCRATCHPAD_UTSBREG, tsbreg);
6451772Sjl139090 
6461772Sjl139090 /*
6471772Sjl139090  * Load the 2nd TSB base into a dedicated scratchpad register which
6481772Sjl139090  * is used as a pseudo TSB base register.
6491772Sjl139090  *
6501772Sjl139090  * In:
6511772Sjl139090  *   tsbreg = value to load (ro)
6521772Sjl139090  *   regnum = constant or register
6531772Sjl139090  *   tmp1 = scratch register
6541772Sjl139090  * Out:
6551772Sjl139090  *   Specified scratchpad register updated
6561772Sjl139090  */
6571772Sjl139090 #define	LOAD_2ND_TSBREG(tsbreg, tmp1)					\
6581772Sjl139090 	SET_UTSBREG(SCRATCHPAD_UTSBREG, tsbreg, tmp1);
6591772Sjl139090 
6601772Sjl139090 #endif /* UTSB_PHYS */
6611772Sjl139090 
6621772Sjl139090 
6631772Sjl139090 /*
6641772Sjl139090  * Load TSB base register.  In the single TSB case this register
6651772Sjl139090  * contains utsb_vabase, bits 21:13 of tsbinfo->tsb_va, and the
6661772Sjl139090  * TSB size code in bits 2:0.  See hat_sfmmu.h for the layout in
6671772Sjl139090  * the case where we have multiple TSBs per process.
6681772Sjl139090  *
6691772Sjl139090  * In:
6701772Sjl139090  *   tsbreg = value to load (ro)
6711772Sjl139090  */
6721772Sjl139090 #define	LOAD_TSBREG(tsbreg, tmp1, tmp2)					\
6731772Sjl139090 	mov	MMU_TSB, tmp1;						\
6741772Sjl139090 	sethi	%hi(FLUSH_ADDR), tmp2;					\
6751772Sjl139090 	stxa	tsbreg, [tmp1]ASI_DMMU;		/* dtsb reg */		\
6761772Sjl139090 	stxa	tsbreg, [tmp1]ASI_IMMU;		/* itsb reg */		\
6771772Sjl139090 	flush	tmp2
6781772Sjl139090 
6791772Sjl139090 #ifdef UTSB_PHYS
6801772Sjl139090 #define	UTSB_PROBE_ASI	ASI_QUAD_LDD_PHYS
6811772Sjl139090 #else
6821772Sjl139090 #define	UTSB_PROBE_ASI	ASI_NQUAD_LD
6831772Sjl139090 #endif
6841772Sjl139090 
6851772Sjl139090 /*
6861772Sjl139090  * Will probe the first TSB, and if it finds a match, will insert it
6871772Sjl139090  * into the TLB and retry.
6881772Sjl139090  *
6891772Sjl139090  * tsbe_ptr = precomputed first TSB entry pointer (in, ro)
6901772Sjl139090  * vpg_4m = 4M virtual page number for tag matching  (in, ro)
6911772Sjl139090  * label = where to branch to if this is a miss (text)
6921772Sjl139090  * %asi = atomic ASI to use for the TSB access
6931772Sjl139090  *
6941772Sjl139090  * For trapstat, we have to explicily use these registers.
6951772Sjl139090  * g4 = location tag will be retrieved into from TSB (out)
6961772Sjl139090  * g5 = location data(tte) will be retrieved into from TSB (out)
6971772Sjl139090  */
6981772Sjl139090 #define	PROBE_1ST_DTSB(tsbe_ptr, vpg_4m, label)	/* g4/g5 clobbered */	\
6991772Sjl139090 	/* BEGIN CSTYLED */						\
7001772Sjl139090 	ldda	[tsbe_ptr]UTSB_PROBE_ASI, %g4 /* g4 = tag, g5 = data */	;\
7011772Sjl139090 	cmp	%g4, vpg_4m		/* compare tag w/ TSB */	;\
7021772Sjl139090 	bne,pn	%xcc, label/**/1	/* branch if !match */		;\
7031772Sjl139090 	  nop								;\
7041772Sjl139090 	TT_TRACE(trace_tsbhit)						;\
7051772Sjl139090 	DTLB_STUFF(%g5, %g1, %g2, %g3, %g4)				;\
7061772Sjl139090 	/* trapstat expects tte in %g5 */				;\
7071772Sjl139090 	retry				/* retry faulted instruction */	;\
7081772Sjl139090 label/**/1:								\
7091772Sjl139090 	/* END CSTYLED */
7101772Sjl139090 
7111772Sjl139090 /*
7121772Sjl139090  * Same as above, only if the TTE doesn't have the execute
7131772Sjl139090  * bit set, will branch to exec_fault directly.
7141772Sjl139090  */
7151772Sjl139090 #define	PROBE_1ST_ITSB(tsbe_ptr, vpg_4m, label)				\
7161772Sjl139090 	/* BEGIN CSTYLED */						\
7171772Sjl139090 	ldda	[tsbe_ptr]UTSB_PROBE_ASI, %g4 /* g4 = tag, g5 = data */	;\
7181772Sjl139090 	cmp	%g4, vpg_4m		/* compare tag w/ TSB */	;\
7191772Sjl139090 	bne,pn	%xcc, label/**/1	/* branch if !match */		;\
7201772Sjl139090 	  nop								;\
7211772Sjl139090 	andcc	%g5, TTE_EXECPRM_INT, %g0  /* check execute bit */	;\
7221772Sjl139090 	bz,pn	%icc, exec_fault					;\
7231772Sjl139090 	  nop								;\
7241772Sjl139090 	TT_TRACE(trace_tsbhit)						;\
7251772Sjl139090 	ITLB_STUFF(%g5, %g1, %g2, %g3, %g4)				;\
7261772Sjl139090 	retry				/* retry faulted instruction */	;\
7271772Sjl139090 label/**/1:								\
7281772Sjl139090 	/* END CSTYLED */
7290Sstevel@tonic-gate 
7300Sstevel@tonic-gate /*
7310Sstevel@tonic-gate  * vpg_4m = 4M virtual page number for tag matching (in)
7320Sstevel@tonic-gate  * tsbe_ptr = precomputed second TSB entry pointer (in)
7330Sstevel@tonic-gate  * label = label to use to make branch targets unique (text)
7340Sstevel@tonic-gate  *
7350Sstevel@tonic-gate  * For trapstat, we have to explicity use these registers.
7360Sstevel@tonic-gate  * g4 = tag portion of TSBE (out)
7370Sstevel@tonic-gate  * g5 = data portion of TSBE (out)
7380Sstevel@tonic-gate  */
7390Sstevel@tonic-gate #define	PROBE_2ND_DTSB(tsbe_ptr, vpg_4m, label)				\
7400Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
7411772Sjl139090 	ldda	[tsbe_ptr]UTSB_PROBE_ASI, %g4 /* g4 = tag, g5 = data */	;\
7420Sstevel@tonic-gate 	/* since we are looking at 2nd tsb, if it's valid, it must be 4M */ ;\
7430Sstevel@tonic-gate 	cmp	%g4, vpg_4m						;\
7440Sstevel@tonic-gate 	bne,pn	%xcc, label/**/1					;\
7450Sstevel@tonic-gate 	  nop								;\
7460Sstevel@tonic-gate 	mov	tsbe_ptr, %g1		/* trace_tsbhit wants ptr in %g1 */ ;\
7470Sstevel@tonic-gate 	TT_TRACE(trace_tsbhit)						;\
7480Sstevel@tonic-gate 	DTLB_STUFF(%g5, %g1, %g2, %g3, %g4)				;\
7490Sstevel@tonic-gate 	/* trapstat expects tte in %g5 */				;\
7500Sstevel@tonic-gate 	retry				/* retry faulted instruction */	;\
7510Sstevel@tonic-gate label/**/1:								\
7520Sstevel@tonic-gate 	/* END CSTYLED */
7530Sstevel@tonic-gate 
754*4528Spaulsan /*
755*4528Spaulsan  * Macro to get SCD shared hme map on sun4v platforms
756*4528Spaulsan  * (not applicable to sun4u platforms)
757*4528Spaulsan  */
758*4528Spaulsan #define	GET_SCDSHMERMAP(tsbarea, hmeblkpa, hatid, hmemisc)
759*4528Spaulsan 
760490Ssusans #ifndef TRAPTRACE
7610Sstevel@tonic-gate /*
7620Sstevel@tonic-gate  * Same as above, with the following additions:
7630Sstevel@tonic-gate  * If the TTE found is not executable, branch directly
764490Ssusans  * to exec_fault after checking for ITLB synthesis.
765490Ssusans  * If a TSB miss, branch to TSB miss handler.
7660Sstevel@tonic-gate  */
767490Ssusans #define	PROBE_2ND_ITSB(tsbe_ptr, vpg_4m, label)				\
7680Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
7691772Sjl139090 	ldda	[tsbe_ptr]UTSB_PROBE_ASI, %g4 /* g4 = tag, g5 = data */	;\
7700Sstevel@tonic-gate 	cmp	%g4, vpg_4m		/* compare tag w/ TSB */	;\
7710Sstevel@tonic-gate 	bne,pn	%xcc, sfmmu_tsb_miss_tt	/* branch if !match */		;\
772490Ssusans 	  or	%g0, TTE4M, %g6						;\
7730Sstevel@tonic-gate 	andcc	%g5, TTE_EXECPRM_INT, %g0  /* check execute bit */	;\
774490Ssusans 	bz,a,pn	%icc, label/**/1					;\
775490Ssusans 	  sllx	%g6, TTE_SZ_SHFT, %g6					;\
776490Ssusans 	ITLB_STUFF(%g5, %g1, %g2, %g3, %g4)				;\
777490Ssusans 	retry				/* retry faulted instruction */ ;\
778490Ssusans label/**/1:								;\
779490Ssusans 	andcc %g5, TTE_E_SYNTH_INT, %g0					;\
780490Ssusans 	bz,pn	%icc, exec_fault					;\
781490Ssusans 	  or	%g5, %g6, %g5						;\
782490Ssusans 	ITLB_STUFF(%g5, %g1, %g2, %g3, %g4)				;\
783490Ssusans 	retry				/* retry faulted instruction */	\
784490Ssusans 	/* END CSTYLED */
785490Ssusans #else /* TRAPTRACE */
786490Ssusans /*
787490Ssusans  * Same as above, with the TT_TRACE and mov tsbe_ptr, %g1 additions.
788490Ssusans  */
789490Ssusans #define	PROBE_2ND_ITSB(tsbe_ptr, vpg_4m, label)				\
790490Ssusans 	/* BEGIN CSTYLED */						\
7911772Sjl139090 	ldda	[tsbe_ptr]UTSB_PROBE_ASI, %g4 /* g4 = tag, g5 = data */	;\
792490Ssusans 	cmp	%g4, vpg_4m		/* compare tag w/ TSB */	;\
793490Ssusans 	bne,pn	%xcc, sfmmu_tsb_miss_tt	/* branch if !match */		;\
794490Ssusans 	  or	%g0, TTE4M, %g6						;\
795490Ssusans 	andcc	%g5, TTE_EXECPRM_INT, %g0  /* check execute bit */	;\
796490Ssusans 	bz,a,pn	%icc, label/**/1					;\
797490Ssusans 	  sllx	%g6, TTE_SZ_SHFT, %g6					;\
798490Ssusans 	mov	tsbe_ptr, %g1		/* trap trace wants ptr in %g1 */ ;\
799490Ssusans 	TT_TRACE(trace_tsbhit)						;\
800490Ssusans 	ITLB_STUFF(%g5, %g1, %g2, %g3, %g4)				;\
801490Ssusans 	retry				/* retry faulted instruction */ ;\
802490Ssusans label/**/1:								;\
803490Ssusans 	andcc %g5, TTE_E_SYNTH_INT, %g0				;\
8040Sstevel@tonic-gate 	bz,pn	%icc, exec_fault					;\
8050Sstevel@tonic-gate 	  mov	tsbe_ptr, %g1		/* trap trace wants ptr in %g1 */ ;\
806490Ssusans 	or	%g5, %g6, %g5						;\
8070Sstevel@tonic-gate 	TT_TRACE(trace_tsbhit)						;\
8080Sstevel@tonic-gate 	ITLB_STUFF(%g5, %g1, %g2, %g3, %g4)				;\
8090Sstevel@tonic-gate 	retry				/* retry faulted instruction */	\
8100Sstevel@tonic-gate 	/* END CSTYLED */
8110Sstevel@tonic-gate 
812490Ssusans #endif /* TRAPTRACE */
8130Sstevel@tonic-gate #endif /* _ASM */
8140Sstevel@tonic-gate 
8150Sstevel@tonic-gate #ifdef	__cplusplus
8160Sstevel@tonic-gate }
8170Sstevel@tonic-gate #endif
8180Sstevel@tonic-gate 
8190Sstevel@tonic-gate #endif	/* _VM_MACH_SFMMU_H */
820