xref: /titanic_44/usr/src/uts/sun4u/vm/mach_sfmmu.h (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
525cf1a30Sjl139090  * Common Development and Distribution License (the "License").
625cf1a30Sjl139090  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*9d0d62adSJason 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  * VM - Hardware Address Translation management.
287c478bd9Sstevel@tonic-gate  *
297c478bd9Sstevel@tonic-gate  * This file describes the contents of the sun reference mmu (sfmmu)
307c478bd9Sstevel@tonic-gate  * specific hat data structures and the sfmmu specific hat procedures.
317c478bd9Sstevel@tonic-gate  * The machine independent interface is described in <vm/hat.h>.
327c478bd9Sstevel@tonic-gate  */
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate #ifndef _VM_MACH_SFMMU_H
357c478bd9Sstevel@tonic-gate #define	_VM_MACH_SFMMU_H
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate #include <sys/x_call.h>
387c478bd9Sstevel@tonic-gate #include <sys/cheetahregs.h>
397c478bd9Sstevel@tonic-gate #include <sys/spitregs.h>
4025cf1a30Sjl139090 #include <sys/opl_olympus_regs.h>
411426d65aSsm142603 #include <sys/mmu.h>
4225cf1a30Sjl139090 
437c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
447c478bd9Sstevel@tonic-gate extern "C" {
457c478bd9Sstevel@tonic-gate #endif
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate /*
4825cf1a30Sjl139090  * On sun4u platforms, user TSBs are accessed via virtual address by default.
4925cf1a30Sjl139090  * Platforms that support ASI_SCRATCHPAD registers can define UTSB_PHYS in the
5025cf1a30Sjl139090  * platform Makefile to access user TSBs via physical address but must also
5125cf1a30Sjl139090  * designate one ASI_SCRATCHPAD register to hold the second user TSB.  To
5225cf1a30Sjl139090  * designate the user TSB scratchpad register, platforms must provide a
531426d65aSsm142603  * definition for SCRATCHPAD_UTSBREG2 below.
5425cf1a30Sjl139090  *
5525cf1a30Sjl139090  * Platforms that use UTSB_PHYS do not allocate 2 locked TLB entries to access
5625cf1a30Sjl139090  * the user TSBs.
577c478bd9Sstevel@tonic-gate  */
5825cf1a30Sjl139090 #if defined(UTSB_PHYS)
5925cf1a30Sjl139090 
6025cf1a30Sjl139090 #if defined(_OPL)
611426d65aSsm142603 #define	SCRATCHPAD_UTSBREG2	OPL_SCRATCHPAD_UTSBREG4 /* 4M-256M pages */
621426d65aSsm142603 #define	SCRATCHPAD_UTSBREG3	OPL_SCRATCHPAD_UTSBREG5 /* 8K-512K pages */
631426d65aSsm142603 #define	SCRATCHPAD_UTSBREG4	OPL_SCRATCHPAD_UTSBREG6 /* 4M-256M pages */
6425cf1a30Sjl139090 #else
651426d65aSsm142603 #error "Compiling UTSB_PHYS but no SCRATCHPAD_UTSBREG2 specified"
661426d65aSsm142603 #endif /* _OPL */
6725cf1a30Sjl139090 
6825cf1a30Sjl139090 #endif /* UTSB_PHYS */
6925cf1a30Sjl139090 
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate #ifdef _ASM
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate /*
741426d65aSsm142603  * This macro is used to set private/shared secondary context register in
7505d3dc4bSpaulsan  * sfmmu_alloc_ctx().
761426d65aSsm142603  * if is_shctx = 0 then we set the SCONTEXT to cnum and invalidate the
771426d65aSsm142603  * SHARED_CONTEXT register. If is_shctx = 1 then only the SHARED_CONTEXT
781426d65aSsm142603  * register is set.
791426d65aSsm142603  *  (See additional comments in sfmmu_alloc_ctx)
8005d3dc4bSpaulsan  * Input:
811426d65aSsm142603  * cnum     = cnum
821426d65aSsm142603  * is_shctx = sfmmu private/shared flag (0: private, 1: shared)
831426d65aSsm142603  * tmp1 :    %o4 scratch
841426d65aSsm142603  * tmp2 :    %o5 scratch
851426d65aSsm142603  * label: used as local branch targets
8605d3dc4bSpaulsan  */
871426d65aSsm142603 #define	SET_SECCTX(cnum, is_shctx, tmp1, tmp2, label)	   \
881426d65aSsm142603 	/* BEGIN CSTYLED */				   \
891426d65aSsm142603 	brnz,pn is_shctx, label/**/1			  ;\
9005d3dc4bSpaulsan 	  sethi   %hi(FLUSH_ADDR), tmp2			  ;\
911426d65aSsm142603 	mov     MMU_SCONTEXT, tmp1			  ;\
9205d3dc4bSpaulsan 	stxa    cnum, [tmp1]ASI_MMU_CTX			  ;\
931426d65aSsm142603 	flush   tmp2					  ;\
941426d65aSsm142603 	sethi   %hi(shctx_on), tmp1			  ;\
951426d65aSsm142603 	ld      [tmp1 + %lo(shctx_on)], tmp1		  ;\
961426d65aSsm142603 	brz,pt  tmp1, label/**/3			  ;\
971426d65aSsm142603 	mov    %g0, cnum				  ;\
981426d65aSsm142603 	ba,pt    %xcc, label/**/2			  ;\
991426d65aSsm142603 label/**/1:						  ;\
1001426d65aSsm142603 	set     SHCTXREG_VALID_BIT, tmp1		  ;\
1011426d65aSsm142603 	sllx    cnum, CTXREG_CTX_SHIFT, cnum		  ;\
1021426d65aSsm142603 	srlx    cnum, CTXREG_CTX_SHIFT, cnum		  ;\
1031426d65aSsm142603 	or      cnum, tmp1, cnum			  ;\
1041426d65aSsm142603 	mov     cnum, tmp1				  ;\
1051426d65aSsm142603 	sllx    cnum, 32, cnum				  ;\
1061426d65aSsm142603 	or      cnum, tmp1, cnum			  ;\
1071426d65aSsm142603 label/**/2:					          ;\
1081426d65aSsm142603 	mov     MMU_SHARED_CONTEXT, tmp1		  ;\
1091426d65aSsm142603 	stxa    cnum, [tmp1]ASI_MMU_CTX			  ;\
1101426d65aSsm142603 	flush   tmp2					  ;\
1111426d65aSsm142603 label/**/3:
1121426d65aSsm142603 	/* END CSTYLED */
11305d3dc4bSpaulsan 
11405d3dc4bSpaulsan /*
1157c478bd9Sstevel@tonic-gate  * This macro is used in the MMU code to check if TL should be lowered from
1167c478bd9Sstevel@tonic-gate  * 2 to 1 to pop trapstat's state.  See the block comment in trapstat.c
1177c478bd9Sstevel@tonic-gate  * for details.
1187c478bd9Sstevel@tonic-gate  */
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate #define	TSTAT_CHECK_TL1(label, scr1, scr2)			\
1217c478bd9Sstevel@tonic-gate 	rdpr	%tpc, scr1;					\
1227c478bd9Sstevel@tonic-gate 	sethi	%hi(KERNELBASE), scr2;				\
1237c478bd9Sstevel@tonic-gate 	or	scr2, %lo(KERNELBASE), scr2; 			\
1247c478bd9Sstevel@tonic-gate 	cmp	scr1, scr2; 					\
1257c478bd9Sstevel@tonic-gate 	bgeu	%xcc, 9f;					\
1267c478bd9Sstevel@tonic-gate 	    nop;						\
1277c478bd9Sstevel@tonic-gate 	ba	label;						\
1287c478bd9Sstevel@tonic-gate 	wrpr	%g0, 1, %tl;					\
1297c478bd9Sstevel@tonic-gate 9:
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate /*
1337c478bd9Sstevel@tonic-gate  * The following macros allow us to share majority of the
1347c478bd9Sstevel@tonic-gate  * SFMMU code between sun4u and sun4v platforms.
1357c478bd9Sstevel@tonic-gate  */
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate #define	SETUP_TSB_ASI(qlp, tmp)					\
1387c478bd9Sstevel@tonic-gate 	movrz	qlp, ASI_N, tmp;				\
1397c478bd9Sstevel@tonic-gate 	movrnz	qlp, ASI_MEM, tmp;				\
1407c478bd9Sstevel@tonic-gate 	mov	tmp, %asi
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate /*
1437c478bd9Sstevel@tonic-gate  * Macro to swtich to alternate global register on sun4u platforms
1447c478bd9Sstevel@tonic-gate  * (not applicable to sun4v platforms)
1457c478bd9Sstevel@tonic-gate  */
1467c478bd9Sstevel@tonic-gate #define	USE_ALTERNATE_GLOBALS(scr)				\
1477c478bd9Sstevel@tonic-gate 	rdpr	%pstate, scr;					\
1487c478bd9Sstevel@tonic-gate 	wrpr	scr, PSTATE_MG | PSTATE_AG, %pstate
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate /*
1517c478bd9Sstevel@tonic-gate  * Macro to set %gl register value on sun4v platforms
1527c478bd9Sstevel@tonic-gate  * (not applicable to sun4u platforms)
1537c478bd9Sstevel@tonic-gate  */
1547c478bd9Sstevel@tonic-gate #define	SET_GL_REG(val)
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate /*
1577c478bd9Sstevel@tonic-gate  * Get MMU data tag access register value
1587c478bd9Sstevel@tonic-gate  *
1597c478bd9Sstevel@tonic-gate  * In:
1607c478bd9Sstevel@tonic-gate  *   tagacc, scr1 = scratch registers
1617c478bd9Sstevel@tonic-gate  * Out:
1627c478bd9Sstevel@tonic-gate  *   tagacc = MMU data tag access register value
1637c478bd9Sstevel@tonic-gate  */
1647c478bd9Sstevel@tonic-gate #define	GET_MMU_D_TAGACC(tagacc, scr1)				\
1657c478bd9Sstevel@tonic-gate 	mov	MMU_TAG_ACCESS, scr1;				\
1667c478bd9Sstevel@tonic-gate 	ldxa	[scr1]ASI_DMMU, tagacc
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate /*
1697c478bd9Sstevel@tonic-gate  * Get MMU data tag target register
1707c478bd9Sstevel@tonic-gate  *
1717c478bd9Sstevel@tonic-gate  * In:
1727c478bd9Sstevel@tonic-gate  *   ttarget, scr1 = scratch registers
1737c478bd9Sstevel@tonic-gate  * Out:
1747c478bd9Sstevel@tonic-gate  *   ttarget = MMU data tag target register value
1757c478bd9Sstevel@tonic-gate  */
1767c478bd9Sstevel@tonic-gate #define	GET_MMU_D_TTARGET(ttarget, scr1)			\
1777c478bd9Sstevel@tonic-gate 	ldxa	[%g0]ASI_DMMU, ttarget
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate /*
1807c478bd9Sstevel@tonic-gate  * Get MMU data/instruction tag access register values
1817c478bd9Sstevel@tonic-gate  *
1827c478bd9Sstevel@tonic-gate  * In:
1837c478bd9Sstevel@tonic-gate  *   dtagacc, itagacc, scr1, scr2 = scratch registers
1847c478bd9Sstevel@tonic-gate  * Out:
1857c478bd9Sstevel@tonic-gate  *   dtagacc = MMU data tag access register value
1867c478bd9Sstevel@tonic-gate  *   itagacc = MMU instruction tag access register value
1877c478bd9Sstevel@tonic-gate  */
1887c478bd9Sstevel@tonic-gate #define	GET_MMU_BOTH_TAGACC(dtagacc, itagacc, scr1, scr2)	\
1897c478bd9Sstevel@tonic-gate 	mov	MMU_TAG_ACCESS, scr1;				\
1907c478bd9Sstevel@tonic-gate 	ldxa	[scr1]ASI_DMMU, dtagacc;			\
1917c478bd9Sstevel@tonic-gate 	ldxa	[scr1]ASI_IMMU, itagacc
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate /*
1947c478bd9Sstevel@tonic-gate  * Get MMU data fault address from the tag access register
1957c478bd9Sstevel@tonic-gate  *
1967c478bd9Sstevel@tonic-gate  * In:
1977c478bd9Sstevel@tonic-gate  *   daddr, scr1 = scratch registers
1987c478bd9Sstevel@tonic-gate  * Out:
1997c478bd9Sstevel@tonic-gate  *   daddr = MMU data fault address
2007c478bd9Sstevel@tonic-gate  */
2017c478bd9Sstevel@tonic-gate #define	GET_MMU_D_ADDR(daddr, scr1)				\
2027c478bd9Sstevel@tonic-gate 	mov	MMU_TAG_ACCESS, scr1;				\
2037c478bd9Sstevel@tonic-gate 	ldxa	[scr1]ASI_DMMU, daddr;				\
2047c478bd9Sstevel@tonic-gate 	set	TAGACC_CTX_MASK, scr1;				\
2057c478bd9Sstevel@tonic-gate 	andn	daddr, scr1, daddr
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate /*
2097c478bd9Sstevel@tonic-gate  * Load ITLB entry
2107c478bd9Sstevel@tonic-gate  *
2117c478bd9Sstevel@tonic-gate  * In:
2127c478bd9Sstevel@tonic-gate  *   tte = reg containing tte
2137c478bd9Sstevel@tonic-gate  *   scr1, scr2, scr3, scr4 = scratch registers (not used)
2147c478bd9Sstevel@tonic-gate  */
2157c478bd9Sstevel@tonic-gate #define	ITLB_STUFF(tte, scr1, scr2, scr3, scr4)			\
2167c478bd9Sstevel@tonic-gate 	stxa	tte, [%g0]ASI_ITLB_IN
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate /*
2197c478bd9Sstevel@tonic-gate  * Load DTLB entry
2207c478bd9Sstevel@tonic-gate  *
2217c478bd9Sstevel@tonic-gate  * In:
2227c478bd9Sstevel@tonic-gate  *   tte = reg containing tte
2237c478bd9Sstevel@tonic-gate  *   scr1, scr2, scr3, scr4 = scratch register (not used)
2247c478bd9Sstevel@tonic-gate  */
2257c478bd9Sstevel@tonic-gate #define	DTLB_STUFF(tte, scr1, scr2, scr3, scr4)			\
2267c478bd9Sstevel@tonic-gate 	stxa	tte, [%g0]ASI_DTLB_IN
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate /*
2307c478bd9Sstevel@tonic-gate  * Returns PFN given the TTE and vaddr
2317c478bd9Sstevel@tonic-gate  *
2327c478bd9Sstevel@tonic-gate  * In:
2337c478bd9Sstevel@tonic-gate  *   tte = reg containing tte
2347c478bd9Sstevel@tonic-gate  *   vaddr = reg containing vaddr
2357c478bd9Sstevel@tonic-gate  *   scr1, scr2, scr3 = scratch registers
2367c478bd9Sstevel@tonic-gate  * Out:
2377c478bd9Sstevel@tonic-gate  *   tte = PFN value
2387c478bd9Sstevel@tonic-gate  */
2397c478bd9Sstevel@tonic-gate #define	TTETOPFN(tte, vaddr, label, scr1, scr2, scr3)			\
2407c478bd9Sstevel@tonic-gate 	srlx	tte, TTE_SZ_SHFT, scr1;					\
2417c478bd9Sstevel@tonic-gate 	and	scr1, TTE_SZ_BITS, scr1;	/* scr1 = tte_size */	\
2427c478bd9Sstevel@tonic-gate 	srlx	tte, TTE_SZ2_SHFT, scr3;				\
2437c478bd9Sstevel@tonic-gate 	and	scr3, TTE_SZ2_BITS, scr3;	/* scr3 = tte_size2 */	\
2447c478bd9Sstevel@tonic-gate 	or	scr1, scr3, scr1;					\
2457c478bd9Sstevel@tonic-gate 	sllx	scr1, 1, scr2;						\
2467c478bd9Sstevel@tonic-gate 	add	scr2, scr1, scr2;		/* mulx 3 */		\
2477c478bd9Sstevel@tonic-gate 	sllx	tte, TTE_PA_LSHIFT, tte;				\
2487c478bd9Sstevel@tonic-gate 	add	scr2, MMU_PAGESHIFT + TTE_PA_LSHIFT, scr3;		\
2497c478bd9Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
2507c478bd9Sstevel@tonic-gate 	brz,pt	scr2, label/**/1;					\
2517c478bd9Sstevel@tonic-gate 	  srlx	tte, scr3, tte;						\
2527c478bd9Sstevel@tonic-gate 	/* END CSTYLED */						\
2537c478bd9Sstevel@tonic-gate 	sllx	tte, scr2, tte;						\
2547c478bd9Sstevel@tonic-gate 	set	1, scr1;						\
2557c478bd9Sstevel@tonic-gate 	add	scr2, MMU_PAGESHIFT, scr3;				\
2567c478bd9Sstevel@tonic-gate 	sllx	scr1, scr3, scr1;					\
2577c478bd9Sstevel@tonic-gate 	sub	scr1, 1, scr1;		/* g2=TTE_PAGE_OFFSET(ttesz) */	\
2587c478bd9Sstevel@tonic-gate 	and	vaddr, scr1, scr2;					\
2597c478bd9Sstevel@tonic-gate 	srln	scr2, MMU_PAGESHIFT, scr2;				\
2607c478bd9Sstevel@tonic-gate 	or	tte, scr2, tte;						\
2617c478bd9Sstevel@tonic-gate 	/* CSTYLED */							\
2627c478bd9Sstevel@tonic-gate label/**/1:
2637c478bd9Sstevel@tonic-gate 
2647c478bd9Sstevel@tonic-gate 
2657c478bd9Sstevel@tonic-gate /*
2667c478bd9Sstevel@tonic-gate  * TTE_SET_REF_ML is a macro that updates the reference bit if it is
2670a90a7fdSAmritpal Sandhu  * not already set. Older sun4u platform use the virtual address to
2680a90a7fdSAmritpal Sandhu  * flush entries from dcache, this is not available here but there are
2690a90a7fdSAmritpal Sandhu  * only two positions in the 64K dcache where the cache line can reside
2700a90a7fdSAmritpal Sandhu  * so we need to flush both of them.
2717c478bd9Sstevel@tonic-gate  *
2727c478bd9Sstevel@tonic-gate  * Parameters:
2737c478bd9Sstevel@tonic-gate  * tte      = reg containing tte
2747c478bd9Sstevel@tonic-gate  * ttepa    = physical pointer to tte
2757c478bd9Sstevel@tonic-gate  * tsbarea  = tsb miss area
2767c478bd9Sstevel@tonic-gate  * tmp1     = tmp reg
2770a90a7fdSAmritpal Sandhu  * tmp2     = tmp reg
2787c478bd9Sstevel@tonic-gate  * label    = temporary label
2797c478bd9Sstevel@tonic-gate  */
2807c478bd9Sstevel@tonic-gate 
2810a90a7fdSAmritpal Sandhu #define	TTE_SET_REF_ML(tte, ttepa, tsbarea, tmp1, tmp2, label)	\
2827c478bd9Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
2837c478bd9Sstevel@tonic-gate 	/* check reference bit */					\
2847c478bd9Sstevel@tonic-gate 	andcc	tte, TTE_REF_INT, %g0;					\
2857c478bd9Sstevel@tonic-gate 	bnz,pt	%xcc, label/**/4;	/* if ref bit set-skip ahead */	\
2867c478bd9Sstevel@tonic-gate 	  nop;								\
2877c478bd9Sstevel@tonic-gate 	GET_CPU_IMPL(tmp1);						\
28825cf1a30Sjl139090 	cmp	tmp1, SPITFIRE_IMPL;					\
28925cf1a30Sjl139090 	blt	%icc, label/**/2;	/* skip flush if FJ-OPL cpus */	\
2907c478bd9Sstevel@tonic-gate 	cmp	tmp1, CHEETAH_IMPL;					\
2917c478bd9Sstevel@tonic-gate 	bl,a	%icc, label/**/1;					\
2927c478bd9Sstevel@tonic-gate 	/* update reference bit */					\
2937c478bd9Sstevel@tonic-gate 	lduh	[tsbarea + TSBMISS_DMASK], tmp1;			\
2947c478bd9Sstevel@tonic-gate 	stxa	%g0, [ttepa]ASI_DC_INVAL; /* flush line from dcache */	\
2957c478bd9Sstevel@tonic-gate 	membar	#Sync;							\
2967c478bd9Sstevel@tonic-gate 	ba	label/**/2;						\
2977c478bd9Sstevel@tonic-gate label/**/1:								\
2980a90a7fdSAmritpal Sandhu 	and	ttepa, tmp1, tmp1;					\
2990a90a7fdSAmritpal Sandhu 	stxa	%g0, [tmp1]ASI_DC_TAG; /* flush line1 from dcache */	\
3000a90a7fdSAmritpal Sandhu 	or	%g0, 1, tmp2;						\
3010a90a7fdSAmritpal Sandhu 	sllx	tmp2, MMU_PAGESHIFT, tmp2;				\
3020a90a7fdSAmritpal Sandhu 	xor	tmp1, tmp2, tmp1;					\
3030a90a7fdSAmritpal Sandhu 	stxa	%g0, [tmp1]ASI_DC_TAG; /* flush line2 from dcache */	\
3047c478bd9Sstevel@tonic-gate 	membar	#Sync;							\
3057c478bd9Sstevel@tonic-gate label/**/2:								\
3067c478bd9Sstevel@tonic-gate 	or	tte, TTE_REF_INT, tmp1;					\
3077c478bd9Sstevel@tonic-gate 	casxa	[ttepa]ASI_MEM, tte, tmp1; 	/* update ref bit */	\
3087c478bd9Sstevel@tonic-gate 	cmp	tte, tmp1;						\
3097c478bd9Sstevel@tonic-gate 	bne,a,pn %xcc, label/**/2;					\
3107c478bd9Sstevel@tonic-gate 	ldxa	[ttepa]ASI_MEM, tte;	/* MMU_READTTE through pa */	\
3117c478bd9Sstevel@tonic-gate 	or	tte, TTE_REF_INT, tte;					\
3127c478bd9Sstevel@tonic-gate label/**/4:								\
3137c478bd9Sstevel@tonic-gate 	/* END CSTYLED */
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate /*
3177c478bd9Sstevel@tonic-gate  * TTE_SET_REFMOD_ML is a macro that updates the reference and modify bits
3187c478bd9Sstevel@tonic-gate  * if not already set.
3197c478bd9Sstevel@tonic-gate  *
3207c478bd9Sstevel@tonic-gate  * Parameters:
3217c478bd9Sstevel@tonic-gate  * tte      = reg containing tte
3227c478bd9Sstevel@tonic-gate  * ttepa    = physical pointer to tte
3237c478bd9Sstevel@tonic-gate  * tsbarea  = tsb miss area
3247c478bd9Sstevel@tonic-gate  * tmp1     = tmp reg
3250a90a7fdSAmritpal Sandhu  * tmp2     = tmp reg
3267c478bd9Sstevel@tonic-gate  * label    = temporary label
3277c478bd9Sstevel@tonic-gate  * exitlabel = label where to jump to if write perm bit not set.
3287c478bd9Sstevel@tonic-gate  */
3297c478bd9Sstevel@tonic-gate 
3300a90a7fdSAmritpal Sandhu #define	TTE_SET_REFMOD_ML(tte, ttepa, tsbarea, tmp1, tmp2, label,	\
3317c478bd9Sstevel@tonic-gate     exitlabel)								\
3327c478bd9Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
3337c478bd9Sstevel@tonic-gate 	/* check reference bit */					\
3347c478bd9Sstevel@tonic-gate 	andcc	tte, TTE_WRPRM_INT, %g0;				\
3357c478bd9Sstevel@tonic-gate 	bz,pn	%xcc, exitlabel;	/* exit if wr_perm not set */	\
3367c478bd9Sstevel@tonic-gate 	  nop;								\
3377c478bd9Sstevel@tonic-gate 	andcc	tte, TTE_HWWR_INT, %g0;					\
3387c478bd9Sstevel@tonic-gate 	bnz,pn	%xcc, label/**/4;	/* nothing to do */		\
3397c478bd9Sstevel@tonic-gate 	  nop;								\
3407c478bd9Sstevel@tonic-gate 	GET_CPU_IMPL(tmp1);						\
34125cf1a30Sjl139090 	cmp	tmp1, SPITFIRE_IMPL;					\
34225cf1a30Sjl139090 	blt	%icc, label/**/2;	/* skip flush if FJ-OPL cpus */	\
3437c478bd9Sstevel@tonic-gate 	cmp	tmp1, CHEETAH_IMPL;					\
3447c478bd9Sstevel@tonic-gate 	bl,a	%icc, label/**/1;					\
3457c478bd9Sstevel@tonic-gate 	/* update reference bit */					\
3467c478bd9Sstevel@tonic-gate 	lduh	[tsbarea + TSBMISS_DMASK], tmp1;			\
3477c478bd9Sstevel@tonic-gate 	stxa    %g0, [ttepa]ASI_DC_INVAL; /* flush line from dcache */ 	\
3487c478bd9Sstevel@tonic-gate 	membar	#Sync;							\
3497c478bd9Sstevel@tonic-gate 	ba	label/**/2;						\
3507c478bd9Sstevel@tonic-gate label/**/1:								\
3510a90a7fdSAmritpal Sandhu 	and	ttepa, tmp1, tmp1;					\
3520a90a7fdSAmritpal Sandhu 	stxa	%g0, [tmp1]ASI_DC_TAG; /* flush line1 from dcache */	\
3530a90a7fdSAmritpal Sandhu 	or	%g0, 1, tmp2;						\
3540a90a7fdSAmritpal Sandhu 	sllx	tmp2, MMU_PAGESHIFT, tmp2;				\
3550a90a7fdSAmritpal Sandhu 	xor	tmp1, tmp2, tmp1;					\
3560a90a7fdSAmritpal Sandhu 	stxa	%g0, [tmp1]ASI_DC_TAG; /* flush line2 from dcache */	\
3577c478bd9Sstevel@tonic-gate 	membar	#Sync;							\
3587c478bd9Sstevel@tonic-gate label/**/2:								\
3597c478bd9Sstevel@tonic-gate 	or	tte, TTE_HWWR_INT | TTE_REF_INT, tmp1;			\
3607c478bd9Sstevel@tonic-gate 	casxa	[ttepa]ASI_MEM, tte, tmp1; /* update ref/mod bit */	\
3617c478bd9Sstevel@tonic-gate 	cmp	tte, tmp1;						\
3627c478bd9Sstevel@tonic-gate 	bne,a,pn %xcc, label/**/2;					\
3637c478bd9Sstevel@tonic-gate 	  ldxa	[ttepa]ASI_MEM, tte;	/* MMU_READTTE through pa */	\
3647c478bd9Sstevel@tonic-gate 	or	tte, TTE_HWWR_INT | TTE_REF_INT, tte;			\
3657c478bd9Sstevel@tonic-gate label/**/4:								\
3667c478bd9Sstevel@tonic-gate 	/* END CSTYLED */
3677c478bd9Sstevel@tonic-gate 
3687c478bd9Sstevel@tonic-gate 
36925cf1a30Sjl139090 #ifndef UTSB_PHYS
37025cf1a30Sjl139090 
3717c478bd9Sstevel@tonic-gate /*
3727c478bd9Sstevel@tonic-gate  * Synthesize TSB base register contents for a process with
3737c478bd9Sstevel@tonic-gate  * a single TSB.
3747c478bd9Sstevel@tonic-gate  *
3757c478bd9Sstevel@tonic-gate  * We patch the virtual address mask in at runtime since the
3767c478bd9Sstevel@tonic-gate  * number of significant virtual address bits in the TSB VA
3777c478bd9Sstevel@tonic-gate  * can vary depending upon the TSB slab size being used on the
3787c478bd9Sstevel@tonic-gate  * machine.
3797c478bd9Sstevel@tonic-gate  *
3807c478bd9Sstevel@tonic-gate  * In:
3817c478bd9Sstevel@tonic-gate  *   tsbinfo = TSB info pointer (ro)
3827c478bd9Sstevel@tonic-gate  *   vabase = value of utsb_vabase (ro)
3837c478bd9Sstevel@tonic-gate  * Out:
3847c478bd9Sstevel@tonic-gate  *   tsbreg = value to program into TSB base register
3857c478bd9Sstevel@tonic-gate  */
3867c478bd9Sstevel@tonic-gate 
3877c478bd9Sstevel@tonic-gate #define	MAKE_TSBREG(tsbreg, tsbinfo, vabase, tmp1, tmp2, label)		\
3887c478bd9Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
3897c478bd9Sstevel@tonic-gate 	ldx	[tsbinfo + TSBINFO_VADDR], tmp1;			\
3907c478bd9Sstevel@tonic-gate 	.global	label/**/_tsbreg_vamask					;\
3917c478bd9Sstevel@tonic-gate label/**/_tsbreg_vamask:						\
3927c478bd9Sstevel@tonic-gate 	or	%g0, RUNTIME_PATCH, tsbreg;				\
3937c478bd9Sstevel@tonic-gate 	lduh	[tsbinfo + TSBINFO_SZCODE], tmp2;			\
3947c478bd9Sstevel@tonic-gate 	sllx	tsbreg, TSBREG_VAMASK_SHIFT, tsbreg;			\
3957c478bd9Sstevel@tonic-gate 	or	vabase, tmp2, tmp2;					\
3967c478bd9Sstevel@tonic-gate 	and	tmp1, tsbreg, tsbreg;					\
3977c478bd9Sstevel@tonic-gate 	or	tsbreg, tmp2, tsbreg;					\
3987c478bd9Sstevel@tonic-gate 	/* END CSTYLED */
3997c478bd9Sstevel@tonic-gate 
4007c478bd9Sstevel@tonic-gate 
4017c478bd9Sstevel@tonic-gate /*
4027c478bd9Sstevel@tonic-gate  * Synthesize TSB base register contents for a process with
4037c478bd9Sstevel@tonic-gate  * two TSBs.  See hat_sfmmu.h for the layout of the TSB base
4047c478bd9Sstevel@tonic-gate  * register in this case.
4057c478bd9Sstevel@tonic-gate  *
4067c478bd9Sstevel@tonic-gate  * In:
4077c478bd9Sstevel@tonic-gate  *   tsb1 = pointer to first TSB info (ro)
4087c478bd9Sstevel@tonic-gate  *   tsb2 = pointer to second TSB info (ro)
4097c478bd9Sstevel@tonic-gate  * Out:
4107c478bd9Sstevel@tonic-gate  *   tsbreg = value to program into TSB base register
4117c478bd9Sstevel@tonic-gate  */
4127c478bd9Sstevel@tonic-gate #define	MAKE_TSBREG_SECTSB(tsbreg, tsb1, tsb2, tmp1, tmp2, tmp3, label)	\
4137c478bd9Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
4147c478bd9Sstevel@tonic-gate 	set	TSBREG_MSB_CONST, tmp3					;\
4157c478bd9Sstevel@tonic-gate 	sllx	tmp3, TSBREG_MSB_SHIFT, tsbreg				;\
4167c478bd9Sstevel@tonic-gate 	.global	label/**/_tsbreg_vamask					;\
4177c478bd9Sstevel@tonic-gate label/**/_tsbreg_vamask:						;\
4187c478bd9Sstevel@tonic-gate 	or	%g0, RUNTIME_PATCH, tmp3				;\
4197c478bd9Sstevel@tonic-gate 	sll	tmp3, TSBREG_VAMASK_SHIFT, tmp3				;\
4207c478bd9Sstevel@tonic-gate 	ldx	[tsb1 + TSBINFO_VADDR], tmp1				;\
4217c478bd9Sstevel@tonic-gate 	ldx	[tsb2 + TSBINFO_VADDR], tmp2				;\
4227c478bd9Sstevel@tonic-gate 	and	tmp1, tmp3, tmp1					;\
4237c478bd9Sstevel@tonic-gate 	and	tmp2, tmp3, tmp2					;\
4247c478bd9Sstevel@tonic-gate 	sllx	tmp2, TSBREG_SECTSB_MKSHIFT, tmp2			;\
4257c478bd9Sstevel@tonic-gate 	or	tmp1, tmp2, tmp3					;\
4267c478bd9Sstevel@tonic-gate 	or	tsbreg, tmp3, tsbreg					;\
4277c478bd9Sstevel@tonic-gate 	lduh	[tsb1 + TSBINFO_SZCODE], tmp1				;\
4287c478bd9Sstevel@tonic-gate 	lduh	[tsb2 + TSBINFO_SZCODE], tmp2				;\
4297c478bd9Sstevel@tonic-gate 	and	tmp1, TSB_SOFTSZ_MASK, tmp1				;\
4307c478bd9Sstevel@tonic-gate 	and	tmp2, TSB_SOFTSZ_MASK, tmp2				;\
4317c478bd9Sstevel@tonic-gate 	sllx	tmp2, TSBREG_SECSZ_SHIFT, tmp2				;\
4327c478bd9Sstevel@tonic-gate 	or	tmp1, tmp2, tmp3					;\
4337c478bd9Sstevel@tonic-gate 	or	tsbreg, tmp3, tsbreg					;\
4347c478bd9Sstevel@tonic-gate 	/* END CSTYLED */
4357c478bd9Sstevel@tonic-gate 
4367c478bd9Sstevel@tonic-gate 
4377c478bd9Sstevel@tonic-gate /*
4387c478bd9Sstevel@tonic-gate  * Load the locked TSB TLB entry.
4397c478bd9Sstevel@tonic-gate  *
4407c478bd9Sstevel@tonic-gate  * In:
4417c478bd9Sstevel@tonic-gate  *   tsbinfo = tsb_info pointer as va (ro)
4427c478bd9Sstevel@tonic-gate  *   tteidx = shifted index into TLB to load the locked entry (ro)
4437c478bd9Sstevel@tonic-gate  *   va = virtual address at which to load the locked TSB entry (ro)
4447c478bd9Sstevel@tonic-gate  * Out:
4457c478bd9Sstevel@tonic-gate  * Scratch:
4467c478bd9Sstevel@tonic-gate  *   tmp
4477c478bd9Sstevel@tonic-gate  */
4487c478bd9Sstevel@tonic-gate #define	LOAD_TSBTTE(tsbinfo, tteidx, va, tmp)				\
4497c478bd9Sstevel@tonic-gate 	mov	MMU_TAG_ACCESS, tmp;					\
4507c478bd9Sstevel@tonic-gate 	stxa	va, [tmp]ASI_DMMU;		/* set tag access */	\
4517c478bd9Sstevel@tonic-gate 	membar	#Sync;							\
4527c478bd9Sstevel@tonic-gate 	ldx	[tsbinfo + TSBINFO_TTE], tmp;	/* fetch locked tte */	\
4537c478bd9Sstevel@tonic-gate 	stxa	tmp, [tteidx]ASI_DTLB_ACCESS;	/* load locked tte */	\
4547c478bd9Sstevel@tonic-gate 	membar	#Sync
4557c478bd9Sstevel@tonic-gate 
4567c478bd9Sstevel@tonic-gate 
4577c478bd9Sstevel@tonic-gate /*
4587c478bd9Sstevel@tonic-gate  * In the current implementation, TSBs usually come from physically
4597c478bd9Sstevel@tonic-gate  * contiguous chunks of memory up to 4MB in size, but 8K TSBs may be
4607c478bd9Sstevel@tonic-gate  * allocated from 8K chunks of memory under certain conditions.  To
4617c478bd9Sstevel@tonic-gate  * prevent aliasing in the virtual address cache when the TSB slab is
4627c478bd9Sstevel@tonic-gate  * 8K in size we must align the reserved (TL>0) TSB virtual address to
4637c478bd9Sstevel@tonic-gate  * have the same low-order bits as the kernel (TL=0) TSB virtual address,
4647c478bd9Sstevel@tonic-gate  * and map 8K TSBs with an 8K TTE.  In cases where the TSB reserved VA
4657c478bd9Sstevel@tonic-gate  * range is smaller than the assumed 4M we will patch the shift at
4667c478bd9Sstevel@tonic-gate  * runtime; otherwise we leave it alone (which is why RUNTIME_PATCH
4677c478bd9Sstevel@tonic-gate  * constant doesn't appear below).
4687c478bd9Sstevel@tonic-gate  *
4697c478bd9Sstevel@tonic-gate  * In:
4707c478bd9Sstevel@tonic-gate  *   tsbinfo (ro)
4717c478bd9Sstevel@tonic-gate  *   resva: reserved VA base for this TSB
4727c478bd9Sstevel@tonic-gate  * Out:
4737c478bd9Sstevel@tonic-gate  *   resva: corrected VA for this TSB
4747c478bd9Sstevel@tonic-gate  */
4757c478bd9Sstevel@tonic-gate #define	RESV_OFFSET(tsbinfo, resva, tmp1, label)			\
4767c478bd9Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
4777c478bd9Sstevel@tonic-gate 	lduh	[tsbinfo + TSBINFO_SZCODE], tmp1			;\
478fb73348fSjimand 	brgz,pn	tmp1, label/**/9	 				;\
4797c478bd9Sstevel@tonic-gate 	  nop								;\
4807c478bd9Sstevel@tonic-gate 	ldx	[tsbinfo + TSBINFO_VADDR], tmp1				;\
4817c478bd9Sstevel@tonic-gate 	.global	label/**/_resv_offset					;\
4827c478bd9Sstevel@tonic-gate label/**/_resv_offset:							;\
4837c478bd9Sstevel@tonic-gate 	sllx	tmp1, (64 - MMU_PAGESHIFT4M), tmp1			;\
4847c478bd9Sstevel@tonic-gate 	srlx	tmp1, (64 - MMU_PAGESHIFT4M), tmp1			;\
4857c478bd9Sstevel@tonic-gate 	or	tmp1, resva, resva					;\
486fb73348fSjimand label/**/9:								\
487fb73348fSjimand 	/* END CSTYLED */
4887c478bd9Sstevel@tonic-gate 
4897c478bd9Sstevel@tonic-gate /*
4907c478bd9Sstevel@tonic-gate  * Determine the pointer of the entry in the first TSB to probe given
4917c478bd9Sstevel@tonic-gate  * the 8K TSB pointer register contents.
4927c478bd9Sstevel@tonic-gate  *
4937c478bd9Sstevel@tonic-gate  * In:
4947c478bd9Sstevel@tonic-gate  *   tsbp8k = 8K TSB pointer register (ro)
4957c478bd9Sstevel@tonic-gate  *   tmp = scratch register
4967c478bd9Sstevel@tonic-gate  *   label = label for hot patching of utsb_vabase
4977c478bd9Sstevel@tonic-gate  *
4987c478bd9Sstevel@tonic-gate  * Out: tsbe_ptr = TSB entry address
4997c478bd9Sstevel@tonic-gate  *
5007c478bd9Sstevel@tonic-gate  * Note: This function is patched at runtime for performance reasons.
5017c478bd9Sstevel@tonic-gate  *	 Any changes here require sfmmu_patch_utsb fixed.
5027c478bd9Sstevel@tonic-gate  */
5037c478bd9Sstevel@tonic-gate 
5047c478bd9Sstevel@tonic-gate #define	GET_1ST_TSBE_PTR(tsbp8k, tsbe_ptr, tmp, label)			\
5057c478bd9Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
5067c478bd9Sstevel@tonic-gate label/**/_get_1st_tsbe_ptr:						;\
5077c478bd9Sstevel@tonic-gate 	RUNTIME_PATCH_SETX(tsbe_ptr, tmp)				;\
5087c478bd9Sstevel@tonic-gate 	/* tsbeptr = contents of utsb_vabase */				;\
5097c478bd9Sstevel@tonic-gate 	/* clear upper bits leaving just bits 21:0 of TSB ptr. */	;\
5107c478bd9Sstevel@tonic-gate 	sllx	tsbp8k, TSBREG_FIRTSB_SHIFT, tmp			;\
5117c478bd9Sstevel@tonic-gate 	/* finish clear */						;\
5127c478bd9Sstevel@tonic-gate 	srlx	tmp, TSBREG_FIRTSB_SHIFT, tmp				;\
5137c478bd9Sstevel@tonic-gate 	/* or-in bits 41:22 of the VA to form the real pointer. */	;\
5147c478bd9Sstevel@tonic-gate 	or	tsbe_ptr, tmp, tsbe_ptr					\
5157c478bd9Sstevel@tonic-gate 	/* END CSTYLED */
5167c478bd9Sstevel@tonic-gate 
5177c478bd9Sstevel@tonic-gate /*
5187c478bd9Sstevel@tonic-gate  * Determine the base address of the second TSB given the 8K TSB
5197c478bd9Sstevel@tonic-gate  * pointer register contents.
5207c478bd9Sstevel@tonic-gate  *
5217c478bd9Sstevel@tonic-gate  * In:
5227c478bd9Sstevel@tonic-gate  *   tsbp8k = 8K TSB pointer register (ro)
5237c478bd9Sstevel@tonic-gate  *   tmp = scratch register
5247c478bd9Sstevel@tonic-gate  *   label = label for hot patching of utsb_vabase
5257c478bd9Sstevel@tonic-gate  *
5267c478bd9Sstevel@tonic-gate  * Out:
5277c478bd9Sstevel@tonic-gate  *   tsbbase = TSB base address
5287c478bd9Sstevel@tonic-gate  *
5297c478bd9Sstevel@tonic-gate  * Note: This function is patched at runtime for performance reasons.
5307c478bd9Sstevel@tonic-gate  *	 Any changes here require sfmmu_patch_utsb fixed.
5317c478bd9Sstevel@tonic-gate  */
5327c478bd9Sstevel@tonic-gate 
5337c478bd9Sstevel@tonic-gate #define	GET_2ND_TSB_BASE(tsbp8k, tsbbase, tmp, label)			\
5347c478bd9Sstevel@tonic-gate 	/* BEGIN CSTYLED */						\
5357c478bd9Sstevel@tonic-gate label/**/_get_2nd_tsb_base:						;\
5367c478bd9Sstevel@tonic-gate 	RUNTIME_PATCH_SETX(tsbbase, tmp)				;\
5377c478bd9Sstevel@tonic-gate 	/* tsbbase = contents of utsb4m_vabase */			;\
5387c478bd9Sstevel@tonic-gate 	/* clear upper bits leaving just bits 21:xx of TSB addr. */	;\
5397c478bd9Sstevel@tonic-gate 	sllx	tsbp8k, TSBREG_SECTSB_LSHIFT, tmp			;\
5407c478bd9Sstevel@tonic-gate 	/* clear lower bits leaving just 21:13 in 8:0 */		;\
5417c478bd9Sstevel@tonic-gate 	srlx	tmp, (TSBREG_SECTSB_RSHIFT + MMU_PAGESHIFT), tmp	;\
5427c478bd9Sstevel@tonic-gate 	/* adjust TSB offset to bits 21:13 */				;\
5437c478bd9Sstevel@tonic-gate 	sllx	tmp, MMU_PAGESHIFT, tmp					;\
5447c478bd9Sstevel@tonic-gate 	or	tsbbase, tmp, tsbbase					;\
5457c478bd9Sstevel@tonic-gate 	/* END CSTYLED */
5467c478bd9Sstevel@tonic-gate 
5477c478bd9Sstevel@tonic-gate /*
5487c478bd9Sstevel@tonic-gate  * Determine the size code of the second TSB given the 8K TSB
5497c478bd9Sstevel@tonic-gate  * pointer register contents.
5507c478bd9Sstevel@tonic-gate  *
5517c478bd9Sstevel@tonic-gate  * In:
5527c478bd9Sstevel@tonic-gate  *   tsbp8k = 8K TSB pointer register (ro)
5537c478bd9Sstevel@tonic-gate  * Out:
5547c478bd9Sstevel@tonic-gate  *   size = TSB size code
5557c478bd9Sstevel@tonic-gate  */
5567c478bd9Sstevel@tonic-gate 
5577c478bd9Sstevel@tonic-gate #define	GET_2ND_TSB_SIZE(tsbp8k, size)					\
5587c478bd9Sstevel@tonic-gate 	srlx	tsbp8k, TSBREG_SECSZ_SHIFT, size;			\
5597c478bd9Sstevel@tonic-gate 	and	size, TSB_SOFTSZ_MASK, size
5607c478bd9Sstevel@tonic-gate 
5617c478bd9Sstevel@tonic-gate /*
5627c478bd9Sstevel@tonic-gate  * Get the location in the 2nd TSB of the tsbe for this fault.
5637c478bd9Sstevel@tonic-gate  * Assumes that the second TSB only contains 4M mappings.
5647c478bd9Sstevel@tonic-gate  *
5657c478bd9Sstevel@tonic-gate  * In:
5667c478bd9Sstevel@tonic-gate  *   tagacc = tag access register (clobbered)
5677c478bd9Sstevel@tonic-gate  *   tsbp8k = contents of TSB8K pointer register (ro)
5687c478bd9Sstevel@tonic-gate  *   tmp1, tmp2 = scratch registers
5697c478bd9Sstevel@tonic-gate  *   label = label at which to patch in reserved TSB 4M VA range
5707c478bd9Sstevel@tonic-gate  * Out:
5717c478bd9Sstevel@tonic-gate  *   tsbe_ptr = pointer to the tsbe in the 2nd TSB
5727c478bd9Sstevel@tonic-gate  */
5737c478bd9Sstevel@tonic-gate #define	GET_2ND_TSBE_PTR(tagacc, tsbp8k, tsbe_ptr, tmp1, tmp2, label)	\
5747c478bd9Sstevel@tonic-gate 	GET_2ND_TSB_BASE(tsbp8k, tsbe_ptr, tmp2, label);		\
5757c478bd9Sstevel@tonic-gate 	/* tsbe_ptr = TSB base address, tmp2 = junk */			\
5767c478bd9Sstevel@tonic-gate 	GET_2ND_TSB_SIZE(tsbp8k, tmp1);					\
5777c478bd9Sstevel@tonic-gate 	/* tmp1 = TSB size code */					\
5787c478bd9Sstevel@tonic-gate 	GET_TSBE_POINTER(MMU_PAGESHIFT4M, tsbe_ptr, tagacc, tmp1, tmp2)
5797c478bd9Sstevel@tonic-gate 
58025cf1a30Sjl139090 
5811426d65aSsm142603 #else /* !UTSB_PHYS */
58225cf1a30Sjl139090 
58325cf1a30Sjl139090 
58425cf1a30Sjl139090 /*
58525cf1a30Sjl139090  * Determine the pointer of the entry in the first TSB to probe given
58625cf1a30Sjl139090  * the 8K TSB pointer register contents.
58725cf1a30Sjl139090  *
58825cf1a30Sjl139090  * In:
58925cf1a30Sjl139090  *   tagacc = tag access register
59025cf1a30Sjl139090  *   tsbe_ptr = 8K TSB pointer register
59125cf1a30Sjl139090  *   tmp = scratch registers
59225cf1a30Sjl139090  *
59325cf1a30Sjl139090  * Out: tsbe_ptr = TSB entry address
59425cf1a30Sjl139090  *
59525cf1a30Sjl139090  * Note: This macro is a nop since the 8K TSB pointer register
59625cf1a30Sjl139090  *	 is the entry pointer and does not need to be decoded.
59725cf1a30Sjl139090  *	 It is defined to allow for code sharing with sun4v.
59825cf1a30Sjl139090  */
59925cf1a30Sjl139090 
60025cf1a30Sjl139090 #define	GET_1ST_TSBE_PTR(tagacc, tsbe_ptr, tmp1, tmp2)
60125cf1a30Sjl139090 
6021426d65aSsm142603 #endif /* !UTSB_PHYS */
60325cf1a30Sjl139090 
60425cf1a30Sjl139090 
60525cf1a30Sjl139090 /*
60625cf1a30Sjl139090  * Load TSB base register.  In the single TSB case this register
60725cf1a30Sjl139090  * contains utsb_vabase, bits 21:13 of tsbinfo->tsb_va, and the
60825cf1a30Sjl139090  * TSB size code in bits 2:0.  See hat_sfmmu.h for the layout in
60925cf1a30Sjl139090  * the case where we have multiple TSBs per process.
61025cf1a30Sjl139090  *
61125cf1a30Sjl139090  * In:
61225cf1a30Sjl139090  *   tsbreg = value to load (ro)
61325cf1a30Sjl139090  */
61425cf1a30Sjl139090 #define	LOAD_TSBREG(tsbreg, tmp1, tmp2)					\
61525cf1a30Sjl139090 	mov	MMU_TSB, tmp1;						\
61625cf1a30Sjl139090 	sethi	%hi(FLUSH_ADDR), tmp2;					\
61725cf1a30Sjl139090 	stxa	tsbreg, [tmp1]ASI_DMMU;		/* dtsb reg */		\
61825cf1a30Sjl139090 	stxa	tsbreg, [tmp1]ASI_IMMU;		/* itsb reg */		\
61925cf1a30Sjl139090 	flush	tmp2
62025cf1a30Sjl139090 
62125cf1a30Sjl139090 #ifdef UTSB_PHYS
62225cf1a30Sjl139090 #define	UTSB_PROBE_ASI	ASI_QUAD_LDD_PHYS
62325cf1a30Sjl139090 #else
62425cf1a30Sjl139090 #define	UTSB_PROBE_ASI	ASI_NQUAD_LD
62525cf1a30Sjl139090 #endif
6261426d65aSsm142603 #define	PROBE_TSB(tsbe_ptr, tag, tsbtag, label)                            \
6271426d65aSsm142603 	/* BEGIN CSTYLED */                                             \
6281426d65aSsm142603         ldda    [tsbe_ptr]UTSB_PROBE_ASI, tsbtag                        ;\
6291426d65aSsm142603         cmp     tsbtag, tag             /* compare tag w/ TSB */        ;\
6301426d65aSsm142603         bne,pn  %xcc, label/**/1        /* branch if !match */          ;\
6311426d65aSsm142603           nop                                                           \
6321426d65aSsm142603 	/* END CSTYLED */
63325cf1a30Sjl139090 /*
6341426d65aSsm142603  * Probe a TSB. If miss continue from the end of the macro for most probes
6351426d65aSsm142603  * except jump to TSB miss for 3rd ITSB probe. If hit retry faulted
6361426d65aSsm142603  * instruction for DTSB probes. For ITSB probes in case of TSB hit check
6371426d65aSsm142603  * execute bit and branch to exec_fault if the bit is not set otherwise retry
6381426d65aSsm142603  * faulted instruction. Do ITLB synthesis in case of hit in second ITSB if
6391426d65aSsm142603  * synthesis bit is set.
64025cf1a30Sjl139090  *
6411426d65aSsm142603  * tsbe_ptr = precomputed TSB entry pointer (in, ro)
64225cf1a30Sjl139090  * vpg_4m = 4M virtual page number for tag matching  (in, ro)
64325cf1a30Sjl139090  * label = where to branch to if this is a miss (text)
64425cf1a30Sjl139090  *
64525cf1a30Sjl139090  * For trapstat, we have to explicily use these registers.
64625cf1a30Sjl139090  * g4 = location tag will be retrieved into from TSB (out)
64725cf1a30Sjl139090  * g5 = location data(tte) will be retrieved into from TSB (out)
6481426d65aSsm142603  *
6491426d65aSsm142603  * In case of first tsb probe tsbe_ptr is %g1. For other tsb probes
6501426d65aSsm142603  * move tsbe_ptr into %g1 in case of hit for traptrace.
6511426d65aSsm142603  *
6521426d65aSsm142603  * If the probe fails and we continue from call site %g4-%g5 are clobbered.
6531426d65aSsm142603  * 2nd ITSB probe macro will also clobber %g6 in this case.
65425cf1a30Sjl139090  */
6551426d65aSsm142603 #define	PROBE_1ST_DTSB(tsbe_ptr, vpg_4m, label)                         \
65625cf1a30Sjl139090 	/* BEGIN CSTYLED */                                             \
6571426d65aSsm142603         PROBE_TSB(tsbe_ptr, vpg_4m, %g4, label)                         ;\
65825cf1a30Sjl139090         TT_TRACE(trace_tsbhit)                                          ;\
65925cf1a30Sjl139090         DTLB_STUFF(%g5, %g1, %g2, %g3, %g4)                             ;\
66025cf1a30Sjl139090         retry                      /* retry faulted instruction */      ;\
66125cf1a30Sjl139090 label/**/1:                                                             \
66225cf1a30Sjl139090 	/* END CSTYLED */
66325cf1a30Sjl139090 
6647c478bd9Sstevel@tonic-gate #define	PROBE_2ND_DTSB(tsbe_ptr, vpg_4m, label)                         \
6657c478bd9Sstevel@tonic-gate 	/* BEGIN CSTYLED */                                             \
6661426d65aSsm142603         PROBE_TSB(tsbe_ptr, vpg_4m, %g4, label)                         ;\
6677c478bd9Sstevel@tonic-gate         mov     tsbe_ptr, %g1       /* trace_tsbhit wants ptr in %g1 */ ;\
6687c478bd9Sstevel@tonic-gate         TT_TRACE(trace_tsbhit)                                          ;\
6697c478bd9Sstevel@tonic-gate         DTLB_STUFF(%g5, %g1, %g2, %g3, %g4)                             ;\
6707c478bd9Sstevel@tonic-gate         retry                      /* retry faulted instruction */      ;\
6717c478bd9Sstevel@tonic-gate label/**/1:                                                             \
6727c478bd9Sstevel@tonic-gate 	/* END CSTYLED */
6737c478bd9Sstevel@tonic-gate 
6741426d65aSsm142603 #define	PROBE_1ST_ITSB(tsbe_ptr, vpg_4m, label)                         \
6757c478bd9Sstevel@tonic-gate 	/* BEGIN CSTYLED */                                             \
6761426d65aSsm142603         PROBE_TSB(tsbe_ptr, vpg_4m, %g4, label)                         ;\
6777c478bd9Sstevel@tonic-gate         andcc   %g5, TTE_EXECPRM_INT, %g0  /* check execute bit */      ;\
6781426d65aSsm142603         bz,pn   %icc, exec_fault                                        ;\
6791426d65aSsm142603           nop                                                           ;\
6801426d65aSsm142603         TT_TRACE(trace_tsbhit)                                          ;\
6811bd453f3Ssusans         ITLB_STUFF(%g5, %g1, %g2, %g3, %g4)                             ;\
6821bd453f3Ssusans         retry                           /* retry faulted instruction */ ;\
6831426d65aSsm142603 label/**/1:                                                             \
6841bd453f3Ssusans 	/* END CSTYLED */
6851426d65aSsm142603 
6861bd453f3Ssusans #define	PROBE_2ND_ITSB(tsbe_ptr, vpg_4m, label)                         \
6871bd453f3Ssusans 	/* BEGIN CSTYLED */                                             \
68825cf1a30Sjl139090         ldda    [tsbe_ptr]UTSB_PROBE_ASI, %g4 /* g4 = tag, g5 = data */ ;\
6891bd453f3Ssusans         cmp     %g4, vpg_4m             /* compare tag w/ TSB */        ;\
6901426d65aSsm142603         bne,pn  %xcc, label/**/2        /* branch if !match */          ;\
6911bd453f3Ssusans           or    %g0, TTE4M, %g6                                         ;\
6921bd453f3Ssusans         andcc   %g5, TTE_EXECPRM_INT, %g0  /* check execute bit */      ;\
6931bd453f3Ssusans         bz,a,pn %icc, label/**/1                                        ;\
6941bd453f3Ssusans           sllx  %g6, TTE_SZ_SHFT, %g6                                   ;\
6951bd453f3Ssusans         mov     tsbe_ptr, %g1         /* trap trace wants ptr in %g1 */ ;\
6961bd453f3Ssusans         TT_TRACE(trace_tsbhit)                                          ;\
6971bd453f3Ssusans         ITLB_STUFF(%g5, %g1, %g2, %g3, %g4)                             ;\
6981bd453f3Ssusans         retry                        /* retry faulted instruction */    ;\
6991bd453f3Ssusans label/**/1:                                                             ;\
7001bd453f3Ssusans         andcc %g5, TTE_E_SYNTH_INT, %g0                                 ;\
7017c478bd9Sstevel@tonic-gate         bz,pn   %icc, exec_fault                                        ;\
7027c478bd9Sstevel@tonic-gate           mov   tsbe_ptr, %g1       /* trap trace wants ptr in %g1 */   ;\
7031bd453f3Ssusans         or      %g5, %g6, %g5                                           ;\
7047c478bd9Sstevel@tonic-gate         TT_TRACE(trace_tsbhit)                                          ;\
7057c478bd9Sstevel@tonic-gate         ITLB_STUFF(%g5, %g1, %g2, %g3, %g4)                             ;\
7061426d65aSsm142603         retry                      /* retry faulted instruction */      ;\
7071426d65aSsm142603 label/**/2:
7087c478bd9Sstevel@tonic-gate 	/* END CSTYLED */
7097c478bd9Sstevel@tonic-gate 
7101426d65aSsm142603 #ifdef UTSB_PHYS
7111426d65aSsm142603 
7121426d65aSsm142603 /*
7131426d65aSsm142603  * Updates the context filed in the tagaccess register with the shared
7141426d65aSsm142603  * context to force the next i/DTLB_STUFF() to load this mapping into
7151426d65aSsm142603  * the TLB with the shared context.
7161426d65aSsm142603  */
7171426d65aSsm142603 #define	SET_SHCTX_TAGACC(tmp1, tmp2, asi)                               \
7181426d65aSsm142603 	/* BEGIN CSTYLED */                                             \
7191426d65aSsm142603         mov     MMU_TAG_ACCESS, tmp2                                    ;\
7201426d65aSsm142603         ldxa    [tmp2]asi, tmp2                 /* tmp2 = VA|CTX */     ;\
7211426d65aSsm142603         srlx    tmp2, TAGACC_SHIFT, tmp2                                ;\
7221426d65aSsm142603         sllx    tmp2, TAGACC_SHIFT, tmp2        /* tmp2 = VA */         ;\
7231426d65aSsm142603         mov     MMU_SHARED_CONTEXT, tmp1        /* clobber tsbe_ptr */  ;\
7241426d65aSsm142603         ldxa    [tmp1]ASI_MMU_CTX, tmp1         /* tmp2 = shctx reg */  ;\
7251426d65aSsm142603         sllx    tmp1, SHCTXREG_CTX_LSHIFT, tmp1                         ;\
7261426d65aSsm142603         srlx    tmp1, SHCTXREG_CTX_LSHIFT, tmp1 /* tmp1 = SHCTX */      ;\
7271426d65aSsm142603         or      tmp1, tmp2, tmp1                /* tmp1  = VA|SHCTX */  ;\
7281426d65aSsm142603         mov     MMU_TAG_ACCESS, tmp2                                    ;\
7291426d65aSsm142603         stxa    tmp1, [tmp2]asi                 /* asi = VA|SHCTX */
7301426d65aSsm142603 	/* END CSTYLED */
7311426d65aSsm142603 
7321426d65aSsm142603 #define	PROBE_SHCTX_DTSB(tsbe_ptr, vpg_4m, label)                       \
7331426d65aSsm142603 	/* BEGIN CSTYLED */                                             \
7341426d65aSsm142603         PROBE_TSB(tsbe_ptr, vpg_4m, %g4, label)                         ;\
7351426d65aSsm142603         mov     tsbe_ptr, %g1       /* trace_tsbhit wants ptr in %g1 */ ;\
7361426d65aSsm142603         TT_TRACE(trace_tsbhit)                                          ;\
7371426d65aSsm142603         SET_SHCTX_TAGACC(%g3, %g4, ASI_DMMU)                            ;\
7381426d65aSsm142603         DTLB_STUFF(%g5, %g1, %g2, %g3, %g4)                             ;\
7391426d65aSsm142603         retry                      /* retry faulted instruction */      ;\
7401426d65aSsm142603 label/**/1:                                                             \
7411426d65aSsm142603 	/* END CSTYLED */
7421426d65aSsm142603 
7431426d65aSsm142603 #define	PROBE_3RD_DTSB(tsbe_ptr, vpg_4m, label)                         \
7441426d65aSsm142603 	/* BEGIN CSTYLED */                                             \
7451426d65aSsm142603         PROBE_SHCTX_DTSB(tsbe_ptr, vpg_4m, label)                  ;\
7461426d65aSsm142603 	/* END CSTYLED */
7471426d65aSsm142603 
7481426d65aSsm142603 #define	PROBE_4TH_DTSB(tsbe_ptr, vpg_4m, label)                         \
7491426d65aSsm142603 	/* BEGIN CSTYLED */                                             \
7501426d65aSsm142603         PROBE_SHCTX_DTSB(tsbe_ptr, vpg_4m, label)                  ;\
7511426d65aSsm142603 	/* END CSTYLED */
7521426d65aSsm142603 
7531426d65aSsm142603 #define	PROBE_SHCTX_ITSB(tsbe_ptr, vpg_4m, label)                       \
7541426d65aSsm142603 	/* BEGIN CSTYLED */                                             \
7551426d65aSsm142603         PROBE_TSB(tsbe_ptr, vpg_4m, %g4, label)                         ;\
7561426d65aSsm142603         andcc   %g5, TTE_EXECPRM_INT, %g0  /* check execute bit */      ;\
7571426d65aSsm142603         bz,pn %icc, exec_fault                                          ;\
7581426d65aSsm142603          mov     tsbe_ptr, %g1          /* for traptrace sake */        ;\
7591426d65aSsm142603         TT_TRACE(trace_tsbhit)                                          ;\
7601426d65aSsm142603         SET_SHCTX_TAGACC(%g3, %g4, ASI_IMMU)                            ;\
7611426d65aSsm142603         ITLB_STUFF(%g5, %g1, %g2, %g3, %g4)                             ;\
7621426d65aSsm142603         retry                           /* retry faulted instruction */ ;\
7631426d65aSsm142603 label/**/1:
7641426d65aSsm142603 	/* END CSTYLED */
7651426d65aSsm142603 
7661426d65aSsm142603 #define	PROBE_3RD_ITSB(tsbe_ptr, vpg_4m, label)                         \
7671426d65aSsm142603 	/* BEGIN CSTYLED */                                             \
7681426d65aSsm142603         PROBE_SHCTX_ITSB(tsbe_ptr, vpg_4m, sfmmu_tsb_miss_tt)      ;\
7691426d65aSsm142603 	/* END CSTYLED */
7701426d65aSsm142603 
7711426d65aSsm142603 #define	PROBE_4TH_ITSB(tsbe_ptr, vpg_4m, label)                         \
7721426d65aSsm142603 	/* BEGIN CSTYLED */                                             \
7731426d65aSsm142603         PROBE_SHCTX_ITSB(tsbe_ptr, vpg_4m, label)                  ;\
7741426d65aSsm142603 	/* END CSTYLED */
7751426d65aSsm142603 
7761426d65aSsm142603 /*
7771426d65aSsm142603  * The traptype is supplied by caller.
7781426d65aSsm142603  *
7791426d65aSsm142603  * If iTSB miss, store shctx into IMMU TAG ACCESS REG
7801426d65aSsm142603  * If dTSB miss, store shctx into DMMU TAG ACCESS REG
7811426d65aSsm142603  * Thus the [D|I]TLB_STUFF will work as expected.
7821426d65aSsm142603  */
7831426d65aSsm142603 #define	SAVE_CTX1(traptype, tmp1, tmp2, label)                          \
7841426d65aSsm142603 	/* BEGIN CSTYLED */                                             \
7851426d65aSsm142603         cmp     traptype, FAST_IMMU_MISS_TT                             ;\
7861426d65aSsm142603         be,pn %icc, label/**/1                                          ;\
7871426d65aSsm142603           nop                                                           ;\
7881426d65aSsm142603         SET_SHCTX_TAGACC(tmp1, tmp2, ASI_DMMU)                          ;\
7891426d65aSsm142603         membar  #Sync                                                   ;\
7901426d65aSsm142603         ba,a    label/**/2                                              ;\
7911426d65aSsm142603 label/**/1:                                                             ;\
7921426d65aSsm142603         SET_SHCTX_TAGACC(tmp1, tmp2, ASI_IMMU)                          ;\
7931426d65aSsm142603         sethi   %hi(FLUSH_ADDR), tmp1                                   ;\
7941426d65aSsm142603         flush   tmp1                                                    ;\
7951426d65aSsm142603 label/**/2:
7961426d65aSsm142603 	/* END CSTYLED */
7971426d65aSsm142603 
7981426d65aSsm142603 #endif /* UTSB_PHYS */
7991426d65aSsm142603 
8007c478bd9Sstevel@tonic-gate #endif /* _ASM */
8017c478bd9Sstevel@tonic-gate 
8027c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
8037c478bd9Sstevel@tonic-gate }
8047c478bd9Sstevel@tonic-gate #endif
8057c478bd9Sstevel@tonic-gate 
8067c478bd9Sstevel@tonic-gate #endif	/* _VM_MACH_SFMMU_H */
807