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*10271SJason.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/cheetahregs.h> 390Sstevel@tonic-gate #include <sys/spitregs.h> 401772Sjl139090 #include <sys/opl_olympus_regs.h> 416127Ssm142603 #include <sys/mmu.h> 421772Sjl139090 430Sstevel@tonic-gate #ifdef __cplusplus 440Sstevel@tonic-gate extern "C" { 450Sstevel@tonic-gate #endif 460Sstevel@tonic-gate 470Sstevel@tonic-gate /* 481772Sjl139090 * On sun4u platforms, user TSBs are accessed via virtual address by default. 491772Sjl139090 * Platforms that support ASI_SCRATCHPAD registers can define UTSB_PHYS in the 501772Sjl139090 * platform Makefile to access user TSBs via physical address but must also 511772Sjl139090 * designate one ASI_SCRATCHPAD register to hold the second user TSB. To 521772Sjl139090 * designate the user TSB scratchpad register, platforms must provide a 536127Ssm142603 * definition for SCRATCHPAD_UTSBREG2 below. 541772Sjl139090 * 551772Sjl139090 * Platforms that use UTSB_PHYS do not allocate 2 locked TLB entries to access 561772Sjl139090 * the user TSBs. 570Sstevel@tonic-gate */ 581772Sjl139090 #if defined(UTSB_PHYS) 591772Sjl139090 601772Sjl139090 #if defined(_OPL) 616127Ssm142603 #define SCRATCHPAD_UTSBREG2 OPL_SCRATCHPAD_UTSBREG4 /* 4M-256M pages */ 626127Ssm142603 #define SCRATCHPAD_UTSBREG3 OPL_SCRATCHPAD_UTSBREG5 /* 8K-512K pages */ 636127Ssm142603 #define SCRATCHPAD_UTSBREG4 OPL_SCRATCHPAD_UTSBREG6 /* 4M-256M pages */ 641772Sjl139090 #else 656127Ssm142603 #error "Compiling UTSB_PHYS but no SCRATCHPAD_UTSBREG2 specified" 666127Ssm142603 #endif /* _OPL */ 671772Sjl139090 681772Sjl139090 #endif /* UTSB_PHYS */ 691772Sjl139090 700Sstevel@tonic-gate 710Sstevel@tonic-gate #ifdef _ASM 720Sstevel@tonic-gate 730Sstevel@tonic-gate /* 746127Ssm142603 * This macro is used to set private/shared secondary context register in 754528Spaulsan * sfmmu_alloc_ctx(). 766127Ssm142603 * if is_shctx = 0 then we set the SCONTEXT to cnum and invalidate the 776127Ssm142603 * SHARED_CONTEXT register. If is_shctx = 1 then only the SHARED_CONTEXT 786127Ssm142603 * register is set. 796127Ssm142603 * (See additional comments in sfmmu_alloc_ctx) 804528Spaulsan * Input: 816127Ssm142603 * cnum = cnum 826127Ssm142603 * is_shctx = sfmmu private/shared flag (0: private, 1: shared) 836127Ssm142603 * tmp1 : %o4 scratch 846127Ssm142603 * tmp2 : %o5 scratch 856127Ssm142603 * label: used as local branch targets 864528Spaulsan */ 876127Ssm142603 #define SET_SECCTX(cnum, is_shctx, tmp1, tmp2, label) \ 886127Ssm142603 /* BEGIN CSTYLED */ \ 896127Ssm142603 brnz,pn is_shctx, label/**/1 ;\ 906127Ssm142603 sethi %hi(FLUSH_ADDR), tmp2 ;\ 916127Ssm142603 mov MMU_SCONTEXT, tmp1 ;\ 926127Ssm142603 stxa cnum, [tmp1]ASI_MMU_CTX ;\ 936127Ssm142603 flush tmp2 ;\ 946127Ssm142603 sethi %hi(shctx_on), tmp1 ;\ 956127Ssm142603 ld [tmp1 + %lo(shctx_on)], tmp1 ;\ 966127Ssm142603 brz,pt tmp1, label/**/3 ;\ 976127Ssm142603 mov %g0, cnum ;\ 986127Ssm142603 ba,pt %xcc, label/**/2 ;\ 996127Ssm142603 label/**/1: ;\ 1006127Ssm142603 set SHCTXREG_VALID_BIT, tmp1 ;\ 1016127Ssm142603 sllx cnum, CTXREG_CTX_SHIFT, cnum ;\ 1026127Ssm142603 srlx cnum, CTXREG_CTX_SHIFT, cnum ;\ 1036127Ssm142603 or cnum, tmp1, cnum ;\ 1046127Ssm142603 mov cnum, tmp1 ;\ 1056127Ssm142603 sllx cnum, 32, cnum ;\ 1066127Ssm142603 or cnum, tmp1, cnum ;\ 1076127Ssm142603 label/**/2: ;\ 1086127Ssm142603 mov MMU_SHARED_CONTEXT, tmp1 ;\ 1096127Ssm142603 stxa cnum, [tmp1]ASI_MMU_CTX ;\ 1106127Ssm142603 flush tmp2 ;\ 1116127Ssm142603 label/**/3: 1126127Ssm142603 /* END CSTYLED */ 1134528Spaulsan 1144528Spaulsan /* 1150Sstevel@tonic-gate * This macro is used in the MMU code to check if TL should be lowered from 1160Sstevel@tonic-gate * 2 to 1 to pop trapstat's state. See the block comment in trapstat.c 1170Sstevel@tonic-gate * for details. 1180Sstevel@tonic-gate */ 1190Sstevel@tonic-gate 1200Sstevel@tonic-gate #define TSTAT_CHECK_TL1(label, scr1, scr2) \ 1210Sstevel@tonic-gate rdpr %tpc, scr1; \ 1220Sstevel@tonic-gate sethi %hi(KERNELBASE), scr2; \ 1230Sstevel@tonic-gate or scr2, %lo(KERNELBASE), scr2; \ 1240Sstevel@tonic-gate cmp scr1, scr2; \ 1250Sstevel@tonic-gate bgeu %xcc, 9f; \ 1266127Ssm142603 nop; \ 1270Sstevel@tonic-gate ba label; \ 1280Sstevel@tonic-gate wrpr %g0, 1, %tl; \ 1290Sstevel@tonic-gate 9: 1300Sstevel@tonic-gate 1310Sstevel@tonic-gate 1320Sstevel@tonic-gate /* 1330Sstevel@tonic-gate * The following macros allow us to share majority of the 1340Sstevel@tonic-gate * SFMMU code between sun4u and sun4v platforms. 1350Sstevel@tonic-gate */ 1360Sstevel@tonic-gate 1370Sstevel@tonic-gate #define SETUP_TSB_ASI(qlp, tmp) \ 1380Sstevel@tonic-gate movrz qlp, ASI_N, tmp; \ 1390Sstevel@tonic-gate movrnz qlp, ASI_MEM, tmp; \ 1400Sstevel@tonic-gate mov tmp, %asi 1410Sstevel@tonic-gate 1420Sstevel@tonic-gate /* 1430Sstevel@tonic-gate * Macro to swtich to alternate global register on sun4u platforms 1440Sstevel@tonic-gate * (not applicable to sun4v platforms) 1450Sstevel@tonic-gate */ 1460Sstevel@tonic-gate #define USE_ALTERNATE_GLOBALS(scr) \ 1470Sstevel@tonic-gate rdpr %pstate, scr; \ 1480Sstevel@tonic-gate wrpr scr, PSTATE_MG | PSTATE_AG, %pstate 1490Sstevel@tonic-gate 1500Sstevel@tonic-gate /* 1510Sstevel@tonic-gate * Macro to set %gl register value on sun4v platforms 1520Sstevel@tonic-gate * (not applicable to sun4u platforms) 1530Sstevel@tonic-gate */ 1540Sstevel@tonic-gate #define SET_GL_REG(val) 1550Sstevel@tonic-gate 1560Sstevel@tonic-gate /* 1570Sstevel@tonic-gate * Get MMU data tag access register value 1580Sstevel@tonic-gate * 1590Sstevel@tonic-gate * In: 1600Sstevel@tonic-gate * tagacc, scr1 = scratch registers 1610Sstevel@tonic-gate * Out: 1620Sstevel@tonic-gate * tagacc = MMU data tag access register value 1630Sstevel@tonic-gate */ 1640Sstevel@tonic-gate #define GET_MMU_D_TAGACC(tagacc, scr1) \ 1650Sstevel@tonic-gate mov MMU_TAG_ACCESS, scr1; \ 1660Sstevel@tonic-gate ldxa [scr1]ASI_DMMU, tagacc 1670Sstevel@tonic-gate 1680Sstevel@tonic-gate /* 1690Sstevel@tonic-gate * Get MMU data tag target register 1700Sstevel@tonic-gate * 1710Sstevel@tonic-gate * In: 1720Sstevel@tonic-gate * ttarget, scr1 = scratch registers 1730Sstevel@tonic-gate * Out: 1740Sstevel@tonic-gate * ttarget = MMU data tag target register value 1750Sstevel@tonic-gate */ 1760Sstevel@tonic-gate #define GET_MMU_D_TTARGET(ttarget, scr1) \ 1770Sstevel@tonic-gate ldxa [%g0]ASI_DMMU, ttarget 1780Sstevel@tonic-gate 1790Sstevel@tonic-gate /* 1800Sstevel@tonic-gate * Get MMU data/instruction tag access register values 1810Sstevel@tonic-gate * 1820Sstevel@tonic-gate * In: 1830Sstevel@tonic-gate * dtagacc, itagacc, scr1, scr2 = scratch registers 1840Sstevel@tonic-gate * Out: 1850Sstevel@tonic-gate * dtagacc = MMU data tag access register value 1860Sstevel@tonic-gate * itagacc = MMU instruction tag access register value 1870Sstevel@tonic-gate */ 1880Sstevel@tonic-gate #define GET_MMU_BOTH_TAGACC(dtagacc, itagacc, scr1, scr2) \ 1890Sstevel@tonic-gate mov MMU_TAG_ACCESS, scr1; \ 1900Sstevel@tonic-gate ldxa [scr1]ASI_DMMU, dtagacc; \ 1910Sstevel@tonic-gate ldxa [scr1]ASI_IMMU, itagacc 1920Sstevel@tonic-gate 1930Sstevel@tonic-gate /* 1940Sstevel@tonic-gate * Get MMU data fault address from the tag access register 1950Sstevel@tonic-gate * 1960Sstevel@tonic-gate * In: 1970Sstevel@tonic-gate * daddr, scr1 = scratch registers 1980Sstevel@tonic-gate * Out: 1990Sstevel@tonic-gate * daddr = MMU data fault address 2000Sstevel@tonic-gate */ 2010Sstevel@tonic-gate #define GET_MMU_D_ADDR(daddr, scr1) \ 2020Sstevel@tonic-gate mov MMU_TAG_ACCESS, scr1; \ 2030Sstevel@tonic-gate ldxa [scr1]ASI_DMMU, daddr; \ 2040Sstevel@tonic-gate set TAGACC_CTX_MASK, scr1; \ 2050Sstevel@tonic-gate andn daddr, scr1, daddr 2060Sstevel@tonic-gate 2070Sstevel@tonic-gate 2080Sstevel@tonic-gate /* 2090Sstevel@tonic-gate * Load ITLB entry 2100Sstevel@tonic-gate * 2110Sstevel@tonic-gate * In: 2120Sstevel@tonic-gate * tte = reg containing tte 2130Sstevel@tonic-gate * scr1, scr2, scr3, scr4 = scratch registers (not used) 2140Sstevel@tonic-gate */ 2150Sstevel@tonic-gate #define ITLB_STUFF(tte, scr1, scr2, scr3, scr4) \ 2160Sstevel@tonic-gate stxa tte, [%g0]ASI_ITLB_IN 2170Sstevel@tonic-gate 2180Sstevel@tonic-gate /* 2190Sstevel@tonic-gate * Load DTLB entry 2200Sstevel@tonic-gate * 2210Sstevel@tonic-gate * In: 2220Sstevel@tonic-gate * tte = reg containing tte 2230Sstevel@tonic-gate * scr1, scr2, scr3, scr4 = scratch register (not used) 2240Sstevel@tonic-gate */ 2250Sstevel@tonic-gate #define DTLB_STUFF(tte, scr1, scr2, scr3, scr4) \ 2260Sstevel@tonic-gate stxa tte, [%g0]ASI_DTLB_IN 2270Sstevel@tonic-gate 2280Sstevel@tonic-gate 2290Sstevel@tonic-gate /* 2300Sstevel@tonic-gate * Returns PFN given the TTE and vaddr 2310Sstevel@tonic-gate * 2320Sstevel@tonic-gate * In: 2330Sstevel@tonic-gate * tte = reg containing tte 2340Sstevel@tonic-gate * vaddr = reg containing vaddr 2350Sstevel@tonic-gate * scr1, scr2, scr3 = scratch registers 2360Sstevel@tonic-gate * Out: 2370Sstevel@tonic-gate * tte = PFN value 2380Sstevel@tonic-gate */ 2390Sstevel@tonic-gate #define TTETOPFN(tte, vaddr, label, scr1, scr2, scr3) \ 2400Sstevel@tonic-gate srlx tte, TTE_SZ_SHFT, scr1; \ 2410Sstevel@tonic-gate and scr1, TTE_SZ_BITS, scr1; /* scr1 = tte_size */ \ 2420Sstevel@tonic-gate srlx tte, TTE_SZ2_SHFT, scr3; \ 2430Sstevel@tonic-gate and scr3, TTE_SZ2_BITS, scr3; /* scr3 = tte_size2 */ \ 2440Sstevel@tonic-gate or scr1, scr3, scr1; \ 2450Sstevel@tonic-gate sllx scr1, 1, scr2; \ 2460Sstevel@tonic-gate add scr2, scr1, scr2; /* mulx 3 */ \ 2470Sstevel@tonic-gate sllx tte, TTE_PA_LSHIFT, tte; \ 2480Sstevel@tonic-gate add scr2, MMU_PAGESHIFT + TTE_PA_LSHIFT, scr3; \ 2490Sstevel@tonic-gate /* BEGIN CSTYLED */ \ 2500Sstevel@tonic-gate brz,pt scr2, label/**/1; \ 2510Sstevel@tonic-gate srlx tte, scr3, tte; \ 2520Sstevel@tonic-gate /* END CSTYLED */ \ 2530Sstevel@tonic-gate sllx tte, scr2, tte; \ 2540Sstevel@tonic-gate set 1, scr1; \ 2550Sstevel@tonic-gate add scr2, MMU_PAGESHIFT, scr3; \ 2560Sstevel@tonic-gate sllx scr1, scr3, scr1; \ 2570Sstevel@tonic-gate sub scr1, 1, scr1; /* g2=TTE_PAGE_OFFSET(ttesz) */ \ 2580Sstevel@tonic-gate and vaddr, scr1, scr2; \ 2590Sstevel@tonic-gate srln scr2, MMU_PAGESHIFT, scr2; \ 2600Sstevel@tonic-gate or tte, scr2, tte; \ 2610Sstevel@tonic-gate /* CSTYLED */ \ 2620Sstevel@tonic-gate label/**/1: 2630Sstevel@tonic-gate 2640Sstevel@tonic-gate 2650Sstevel@tonic-gate /* 2660Sstevel@tonic-gate * TTE_SET_REF_ML is a macro that updates the reference bit if it is 2678187SPaul.Sandhu@Sun.COM * not already set. Older sun4u platform use the virtual address to 2688187SPaul.Sandhu@Sun.COM * flush entries from dcache, this is not available here but there are 2698187SPaul.Sandhu@Sun.COM * only two positions in the 64K dcache where the cache line can reside 2708187SPaul.Sandhu@Sun.COM * so we need to flush both of them. 2710Sstevel@tonic-gate * 2720Sstevel@tonic-gate * Parameters: 2730Sstevel@tonic-gate * tte = reg containing tte 2740Sstevel@tonic-gate * ttepa = physical pointer to tte 2750Sstevel@tonic-gate * tsbarea = tsb miss area 2760Sstevel@tonic-gate * tmp1 = tmp reg 2778187SPaul.Sandhu@Sun.COM * tmp2 = tmp reg 2780Sstevel@tonic-gate * label = temporary label 2790Sstevel@tonic-gate */ 2800Sstevel@tonic-gate 2818187SPaul.Sandhu@Sun.COM #define TTE_SET_REF_ML(tte, ttepa, tsbarea, tmp1, tmp2, label) \ 2820Sstevel@tonic-gate /* BEGIN CSTYLED */ \ 2830Sstevel@tonic-gate /* check reference bit */ \ 2840Sstevel@tonic-gate andcc tte, TTE_REF_INT, %g0; \ 2850Sstevel@tonic-gate bnz,pt %xcc, label/**/4; /* if ref bit set-skip ahead */ \ 2860Sstevel@tonic-gate nop; \ 2870Sstevel@tonic-gate GET_CPU_IMPL(tmp1); \ 2881772Sjl139090 cmp tmp1, SPITFIRE_IMPL; \ 2891772Sjl139090 blt %icc, label/**/2; /* skip flush if FJ-OPL cpus */ \ 2900Sstevel@tonic-gate cmp tmp1, CHEETAH_IMPL; \ 2910Sstevel@tonic-gate bl,a %icc, label/**/1; \ 2920Sstevel@tonic-gate /* update reference bit */ \ 2930Sstevel@tonic-gate lduh [tsbarea + TSBMISS_DMASK], tmp1; \ 2940Sstevel@tonic-gate stxa %g0, [ttepa]ASI_DC_INVAL; /* flush line from dcache */ \ 2950Sstevel@tonic-gate membar #Sync; \ 2960Sstevel@tonic-gate ba label/**/2; \ 2970Sstevel@tonic-gate label/**/1: \ 2988187SPaul.Sandhu@Sun.COM and ttepa, tmp1, tmp1; \ 2998187SPaul.Sandhu@Sun.COM stxa %g0, [tmp1]ASI_DC_TAG; /* flush line1 from dcache */ \ 3008187SPaul.Sandhu@Sun.COM or %g0, 1, tmp2; \ 3018187SPaul.Sandhu@Sun.COM sllx tmp2, MMU_PAGESHIFT, tmp2; \ 3028187SPaul.Sandhu@Sun.COM xor tmp1, tmp2, tmp1; \ 3038187SPaul.Sandhu@Sun.COM stxa %g0, [tmp1]ASI_DC_TAG; /* flush line2 from dcache */ \ 3040Sstevel@tonic-gate membar #Sync; \ 3050Sstevel@tonic-gate label/**/2: \ 3060Sstevel@tonic-gate or tte, TTE_REF_INT, tmp1; \ 3070Sstevel@tonic-gate casxa [ttepa]ASI_MEM, tte, tmp1; /* update ref bit */ \ 3080Sstevel@tonic-gate cmp tte, tmp1; \ 3090Sstevel@tonic-gate bne,a,pn %xcc, label/**/2; \ 3100Sstevel@tonic-gate ldxa [ttepa]ASI_MEM, tte; /* MMU_READTTE through pa */ \ 3110Sstevel@tonic-gate or tte, TTE_REF_INT, tte; \ 3120Sstevel@tonic-gate label/**/4: \ 3130Sstevel@tonic-gate /* END CSTYLED */ 3140Sstevel@tonic-gate 3150Sstevel@tonic-gate 3160Sstevel@tonic-gate /* 3170Sstevel@tonic-gate * TTE_SET_REFMOD_ML is a macro that updates the reference and modify bits 3180Sstevel@tonic-gate * if not already set. 3190Sstevel@tonic-gate * 3200Sstevel@tonic-gate * Parameters: 3210Sstevel@tonic-gate * tte = reg containing tte 3220Sstevel@tonic-gate * ttepa = physical pointer to tte 3230Sstevel@tonic-gate * tsbarea = tsb miss area 3240Sstevel@tonic-gate * tmp1 = tmp reg 3258187SPaul.Sandhu@Sun.COM * tmp2 = tmp reg 3260Sstevel@tonic-gate * label = temporary label 3270Sstevel@tonic-gate * exitlabel = label where to jump to if write perm bit not set. 3280Sstevel@tonic-gate */ 3290Sstevel@tonic-gate 3308187SPaul.Sandhu@Sun.COM #define TTE_SET_REFMOD_ML(tte, ttepa, tsbarea, tmp1, tmp2, label, \ 3318187SPaul.Sandhu@Sun.COM exitlabel) \ 3320Sstevel@tonic-gate /* BEGIN CSTYLED */ \ 3330Sstevel@tonic-gate /* check reference bit */ \ 3340Sstevel@tonic-gate andcc tte, TTE_WRPRM_INT, %g0; \ 3350Sstevel@tonic-gate bz,pn %xcc, exitlabel; /* exit if wr_perm not set */ \ 3360Sstevel@tonic-gate nop; \ 3370Sstevel@tonic-gate andcc tte, TTE_HWWR_INT, %g0; \ 3380Sstevel@tonic-gate bnz,pn %xcc, label/**/4; /* nothing to do */ \ 3390Sstevel@tonic-gate nop; \ 3400Sstevel@tonic-gate GET_CPU_IMPL(tmp1); \ 3411772Sjl139090 cmp tmp1, SPITFIRE_IMPL; \ 3421772Sjl139090 blt %icc, label/**/2; /* skip flush if FJ-OPL cpus */ \ 3430Sstevel@tonic-gate cmp tmp1, CHEETAH_IMPL; \ 3440Sstevel@tonic-gate bl,a %icc, label/**/1; \ 3450Sstevel@tonic-gate /* update reference bit */ \ 3460Sstevel@tonic-gate lduh [tsbarea + TSBMISS_DMASK], tmp1; \ 3470Sstevel@tonic-gate stxa %g0, [ttepa]ASI_DC_INVAL; /* flush line from dcache */ \ 3480Sstevel@tonic-gate membar #Sync; \ 3490Sstevel@tonic-gate ba label/**/2; \ 3500Sstevel@tonic-gate label/**/1: \ 3518187SPaul.Sandhu@Sun.COM and ttepa, tmp1, tmp1; \ 3528187SPaul.Sandhu@Sun.COM stxa %g0, [tmp1]ASI_DC_TAG; /* flush line1 from dcache */ \ 3538187SPaul.Sandhu@Sun.COM or %g0, 1, tmp2; \ 3548187SPaul.Sandhu@Sun.COM sllx tmp2, MMU_PAGESHIFT, tmp2; \ 3558187SPaul.Sandhu@Sun.COM xor tmp1, tmp2, tmp1; \ 3568187SPaul.Sandhu@Sun.COM stxa %g0, [tmp1]ASI_DC_TAG; /* flush line2 from dcache */ \ 3570Sstevel@tonic-gate membar #Sync; \ 3580Sstevel@tonic-gate label/**/2: \ 3590Sstevel@tonic-gate or tte, TTE_HWWR_INT | TTE_REF_INT, tmp1; \ 3600Sstevel@tonic-gate casxa [ttepa]ASI_MEM, tte, tmp1; /* update ref/mod bit */ \ 3610Sstevel@tonic-gate cmp tte, tmp1; \ 3620Sstevel@tonic-gate bne,a,pn %xcc, label/**/2; \ 3630Sstevel@tonic-gate ldxa [ttepa]ASI_MEM, tte; /* MMU_READTTE through pa */ \ 3640Sstevel@tonic-gate or tte, TTE_HWWR_INT | TTE_REF_INT, tte; \ 3650Sstevel@tonic-gate label/**/4: \ 3660Sstevel@tonic-gate /* END CSTYLED */ 3670Sstevel@tonic-gate 3680Sstevel@tonic-gate 3691772Sjl139090 #ifndef UTSB_PHYS 3701772Sjl139090 3710Sstevel@tonic-gate /* 3720Sstevel@tonic-gate * Synthesize TSB base register contents for a process with 3730Sstevel@tonic-gate * a single TSB. 3740Sstevel@tonic-gate * 3750Sstevel@tonic-gate * We patch the virtual address mask in at runtime since the 3760Sstevel@tonic-gate * number of significant virtual address bits in the TSB VA 3770Sstevel@tonic-gate * can vary depending upon the TSB slab size being used on the 3780Sstevel@tonic-gate * machine. 3790Sstevel@tonic-gate * 3800Sstevel@tonic-gate * In: 3810Sstevel@tonic-gate * tsbinfo = TSB info pointer (ro) 3820Sstevel@tonic-gate * vabase = value of utsb_vabase (ro) 3830Sstevel@tonic-gate * Out: 3840Sstevel@tonic-gate * tsbreg = value to program into TSB base register 3850Sstevel@tonic-gate */ 3860Sstevel@tonic-gate 3870Sstevel@tonic-gate #define MAKE_TSBREG(tsbreg, tsbinfo, vabase, tmp1, tmp2, label) \ 3880Sstevel@tonic-gate /* BEGIN CSTYLED */ \ 3890Sstevel@tonic-gate ldx [tsbinfo + TSBINFO_VADDR], tmp1; \ 3900Sstevel@tonic-gate .global label/**/_tsbreg_vamask ;\ 3910Sstevel@tonic-gate label/**/_tsbreg_vamask: \ 3920Sstevel@tonic-gate or %g0, RUNTIME_PATCH, tsbreg; \ 3930Sstevel@tonic-gate lduh [tsbinfo + TSBINFO_SZCODE], tmp2; \ 3940Sstevel@tonic-gate sllx tsbreg, TSBREG_VAMASK_SHIFT, tsbreg; \ 3950Sstevel@tonic-gate or vabase, tmp2, tmp2; \ 3960Sstevel@tonic-gate and tmp1, tsbreg, tsbreg; \ 3970Sstevel@tonic-gate or tsbreg, tmp2, tsbreg; \ 3980Sstevel@tonic-gate /* END CSTYLED */ 3990Sstevel@tonic-gate 4000Sstevel@tonic-gate 4010Sstevel@tonic-gate /* 4020Sstevel@tonic-gate * Synthesize TSB base register contents for a process with 4030Sstevel@tonic-gate * two TSBs. See hat_sfmmu.h for the layout of the TSB base 4040Sstevel@tonic-gate * register in this case. 4050Sstevel@tonic-gate * 4060Sstevel@tonic-gate * In: 4070Sstevel@tonic-gate * tsb1 = pointer to first TSB info (ro) 4080Sstevel@tonic-gate * tsb2 = pointer to second TSB info (ro) 4090Sstevel@tonic-gate * Out: 4100Sstevel@tonic-gate * tsbreg = value to program into TSB base register 4110Sstevel@tonic-gate */ 4120Sstevel@tonic-gate #define MAKE_TSBREG_SECTSB(tsbreg, tsb1, tsb2, tmp1, tmp2, tmp3, label) \ 4130Sstevel@tonic-gate /* BEGIN CSTYLED */ \ 4140Sstevel@tonic-gate set TSBREG_MSB_CONST, tmp3 ;\ 4150Sstevel@tonic-gate sllx tmp3, TSBREG_MSB_SHIFT, tsbreg ;\ 4160Sstevel@tonic-gate .global label/**/_tsbreg_vamask ;\ 4170Sstevel@tonic-gate label/**/_tsbreg_vamask: ;\ 4180Sstevel@tonic-gate or %g0, RUNTIME_PATCH, tmp3 ;\ 4190Sstevel@tonic-gate sll tmp3, TSBREG_VAMASK_SHIFT, tmp3 ;\ 4200Sstevel@tonic-gate ldx [tsb1 + TSBINFO_VADDR], tmp1 ;\ 4210Sstevel@tonic-gate ldx [tsb2 + TSBINFO_VADDR], tmp2 ;\ 4220Sstevel@tonic-gate and tmp1, tmp3, tmp1 ;\ 4230Sstevel@tonic-gate and tmp2, tmp3, tmp2 ;\ 4240Sstevel@tonic-gate sllx tmp2, TSBREG_SECTSB_MKSHIFT, tmp2 ;\ 4250Sstevel@tonic-gate or tmp1, tmp2, tmp3 ;\ 4260Sstevel@tonic-gate or tsbreg, tmp3, tsbreg ;\ 4270Sstevel@tonic-gate lduh [tsb1 + TSBINFO_SZCODE], tmp1 ;\ 4280Sstevel@tonic-gate lduh [tsb2 + TSBINFO_SZCODE], tmp2 ;\ 4290Sstevel@tonic-gate and tmp1, TSB_SOFTSZ_MASK, tmp1 ;\ 4300Sstevel@tonic-gate and tmp2, TSB_SOFTSZ_MASK, tmp2 ;\ 4310Sstevel@tonic-gate sllx tmp2, TSBREG_SECSZ_SHIFT, tmp2 ;\ 4320Sstevel@tonic-gate or tmp1, tmp2, tmp3 ;\ 4330Sstevel@tonic-gate or tsbreg, tmp3, tsbreg ;\ 4340Sstevel@tonic-gate /* END CSTYLED */ 4350Sstevel@tonic-gate 4360Sstevel@tonic-gate 4370Sstevel@tonic-gate /* 4380Sstevel@tonic-gate * Load the locked TSB TLB entry. 4390Sstevel@tonic-gate * 4400Sstevel@tonic-gate * In: 4410Sstevel@tonic-gate * tsbinfo = tsb_info pointer as va (ro) 4420Sstevel@tonic-gate * tteidx = shifted index into TLB to load the locked entry (ro) 4430Sstevel@tonic-gate * va = virtual address at which to load the locked TSB entry (ro) 4440Sstevel@tonic-gate * Out: 4450Sstevel@tonic-gate * Scratch: 4460Sstevel@tonic-gate * tmp 4470Sstevel@tonic-gate */ 4480Sstevel@tonic-gate #define LOAD_TSBTTE(tsbinfo, tteidx, va, tmp) \ 4490Sstevel@tonic-gate mov MMU_TAG_ACCESS, tmp; \ 4500Sstevel@tonic-gate stxa va, [tmp]ASI_DMMU; /* set tag access */ \ 4510Sstevel@tonic-gate membar #Sync; \ 4520Sstevel@tonic-gate ldx [tsbinfo + TSBINFO_TTE], tmp; /* fetch locked tte */ \ 4530Sstevel@tonic-gate stxa tmp, [tteidx]ASI_DTLB_ACCESS; /* load locked tte */ \ 4540Sstevel@tonic-gate membar #Sync 4550Sstevel@tonic-gate 4560Sstevel@tonic-gate 4570Sstevel@tonic-gate /* 4580Sstevel@tonic-gate * In the current implementation, TSBs usually come from physically 4590Sstevel@tonic-gate * contiguous chunks of memory up to 4MB in size, but 8K TSBs may be 4600Sstevel@tonic-gate * allocated from 8K chunks of memory under certain conditions. To 4610Sstevel@tonic-gate * prevent aliasing in the virtual address cache when the TSB slab is 4620Sstevel@tonic-gate * 8K in size we must align the reserved (TL>0) TSB virtual address to 4630Sstevel@tonic-gate * have the same low-order bits as the kernel (TL=0) TSB virtual address, 4640Sstevel@tonic-gate * and map 8K TSBs with an 8K TTE. In cases where the TSB reserved VA 4650Sstevel@tonic-gate * range is smaller than the assumed 4M we will patch the shift at 4660Sstevel@tonic-gate * runtime; otherwise we leave it alone (which is why RUNTIME_PATCH 4670Sstevel@tonic-gate * constant doesn't appear below). 4680Sstevel@tonic-gate * 4690Sstevel@tonic-gate * In: 4700Sstevel@tonic-gate * tsbinfo (ro) 4710Sstevel@tonic-gate * resva: reserved VA base for this TSB 4720Sstevel@tonic-gate * Out: 4730Sstevel@tonic-gate * resva: corrected VA for this TSB 4740Sstevel@tonic-gate */ 4750Sstevel@tonic-gate #define RESV_OFFSET(tsbinfo, resva, tmp1, label) \ 4760Sstevel@tonic-gate /* BEGIN CSTYLED */ \ 4770Sstevel@tonic-gate lduh [tsbinfo + TSBINFO_SZCODE], tmp1 ;\ 4785861Sjimand brgz,pn tmp1, label/**/9 ;\ 4790Sstevel@tonic-gate nop ;\ 4800Sstevel@tonic-gate ldx [tsbinfo + TSBINFO_VADDR], tmp1 ;\ 4810Sstevel@tonic-gate .global label/**/_resv_offset ;\ 4820Sstevel@tonic-gate label/**/_resv_offset: ;\ 4830Sstevel@tonic-gate sllx tmp1, (64 - MMU_PAGESHIFT4M), tmp1 ;\ 4840Sstevel@tonic-gate srlx tmp1, (64 - MMU_PAGESHIFT4M), tmp1 ;\ 4850Sstevel@tonic-gate or tmp1, resva, resva ;\ 4865861Sjimand label/**/9: \ 4875861Sjimand /* END CSTYLED */ 4880Sstevel@tonic-gate 4890Sstevel@tonic-gate /* 4900Sstevel@tonic-gate * Determine the pointer of the entry in the first TSB to probe given 4910Sstevel@tonic-gate * the 8K TSB pointer register contents. 4920Sstevel@tonic-gate * 4930Sstevel@tonic-gate * In: 4940Sstevel@tonic-gate * tsbp8k = 8K TSB pointer register (ro) 4950Sstevel@tonic-gate * tmp = scratch register 4960Sstevel@tonic-gate * label = label for hot patching of utsb_vabase 4970Sstevel@tonic-gate * 4980Sstevel@tonic-gate * Out: tsbe_ptr = TSB entry address 4990Sstevel@tonic-gate * 5000Sstevel@tonic-gate * Note: This function is patched at runtime for performance reasons. 5011772Sjl139090 * Any changes here require sfmmu_patch_utsb fixed. 5020Sstevel@tonic-gate */ 5030Sstevel@tonic-gate 5040Sstevel@tonic-gate #define GET_1ST_TSBE_PTR(tsbp8k, tsbe_ptr, tmp, label) \ 5050Sstevel@tonic-gate /* BEGIN CSTYLED */ \ 5060Sstevel@tonic-gate label/**/_get_1st_tsbe_ptr: ;\ 5070Sstevel@tonic-gate RUNTIME_PATCH_SETX(tsbe_ptr, tmp) ;\ 5080Sstevel@tonic-gate /* tsbeptr = contents of utsb_vabase */ ;\ 5090Sstevel@tonic-gate /* clear upper bits leaving just bits 21:0 of TSB ptr. */ ;\ 5100Sstevel@tonic-gate sllx tsbp8k, TSBREG_FIRTSB_SHIFT, tmp ;\ 5110Sstevel@tonic-gate /* finish clear */ ;\ 5120Sstevel@tonic-gate srlx tmp, TSBREG_FIRTSB_SHIFT, tmp ;\ 5130Sstevel@tonic-gate /* or-in bits 41:22 of the VA to form the real pointer. */ ;\ 5140Sstevel@tonic-gate or tsbe_ptr, tmp, tsbe_ptr \ 5150Sstevel@tonic-gate /* END CSTYLED */ 5160Sstevel@tonic-gate 5170Sstevel@tonic-gate /* 5180Sstevel@tonic-gate * Determine the base address of the second TSB given the 8K TSB 5190Sstevel@tonic-gate * pointer register contents. 5200Sstevel@tonic-gate * 5210Sstevel@tonic-gate * In: 5220Sstevel@tonic-gate * tsbp8k = 8K TSB pointer register (ro) 5230Sstevel@tonic-gate * tmp = scratch register 5240Sstevel@tonic-gate * label = label for hot patching of utsb_vabase 5250Sstevel@tonic-gate * 5260Sstevel@tonic-gate * Out: 5270Sstevel@tonic-gate * tsbbase = TSB base address 5280Sstevel@tonic-gate * 5290Sstevel@tonic-gate * Note: This function is patched at runtime for performance reasons. 5300Sstevel@tonic-gate * Any changes here require sfmmu_patch_utsb fixed. 5310Sstevel@tonic-gate */ 5320Sstevel@tonic-gate 5330Sstevel@tonic-gate #define GET_2ND_TSB_BASE(tsbp8k, tsbbase, tmp, label) \ 5340Sstevel@tonic-gate /* BEGIN CSTYLED */ \ 5350Sstevel@tonic-gate label/**/_get_2nd_tsb_base: ;\ 5360Sstevel@tonic-gate RUNTIME_PATCH_SETX(tsbbase, tmp) ;\ 5370Sstevel@tonic-gate /* tsbbase = contents of utsb4m_vabase */ ;\ 5380Sstevel@tonic-gate /* clear upper bits leaving just bits 21:xx of TSB addr. */ ;\ 5390Sstevel@tonic-gate sllx tsbp8k, TSBREG_SECTSB_LSHIFT, tmp ;\ 5400Sstevel@tonic-gate /* clear lower bits leaving just 21:13 in 8:0 */ ;\ 5410Sstevel@tonic-gate srlx tmp, (TSBREG_SECTSB_RSHIFT + MMU_PAGESHIFT), tmp ;\ 5420Sstevel@tonic-gate /* adjust TSB offset to bits 21:13 */ ;\ 5430Sstevel@tonic-gate sllx tmp, MMU_PAGESHIFT, tmp ;\ 5440Sstevel@tonic-gate or tsbbase, tmp, tsbbase ;\ 5450Sstevel@tonic-gate /* END CSTYLED */ 5460Sstevel@tonic-gate 5470Sstevel@tonic-gate /* 5480Sstevel@tonic-gate * Determine the size code of the second TSB given the 8K TSB 5490Sstevel@tonic-gate * pointer register contents. 5500Sstevel@tonic-gate * 5510Sstevel@tonic-gate * In: 5520Sstevel@tonic-gate * tsbp8k = 8K TSB pointer register (ro) 5530Sstevel@tonic-gate * Out: 5540Sstevel@tonic-gate * size = TSB size code 5550Sstevel@tonic-gate */ 5560Sstevel@tonic-gate 5570Sstevel@tonic-gate #define GET_2ND_TSB_SIZE(tsbp8k, size) \ 5580Sstevel@tonic-gate srlx tsbp8k, TSBREG_SECSZ_SHIFT, size; \ 5590Sstevel@tonic-gate and size, TSB_SOFTSZ_MASK, size 5600Sstevel@tonic-gate 5610Sstevel@tonic-gate /* 5620Sstevel@tonic-gate * Get the location in the 2nd TSB of the tsbe for this fault. 5630Sstevel@tonic-gate * Assumes that the second TSB only contains 4M mappings. 5640Sstevel@tonic-gate * 5650Sstevel@tonic-gate * In: 5660Sstevel@tonic-gate * tagacc = tag access register (clobbered) 5670Sstevel@tonic-gate * tsbp8k = contents of TSB8K pointer register (ro) 5680Sstevel@tonic-gate * tmp1, tmp2 = scratch registers 5690Sstevel@tonic-gate * label = label at which to patch in reserved TSB 4M VA range 5700Sstevel@tonic-gate * Out: 5710Sstevel@tonic-gate * tsbe_ptr = pointer to the tsbe in the 2nd TSB 5720Sstevel@tonic-gate */ 5730Sstevel@tonic-gate #define GET_2ND_TSBE_PTR(tagacc, tsbp8k, tsbe_ptr, tmp1, tmp2, label) \ 5740Sstevel@tonic-gate GET_2ND_TSB_BASE(tsbp8k, tsbe_ptr, tmp2, label); \ 5750Sstevel@tonic-gate /* tsbe_ptr = TSB base address, tmp2 = junk */ \ 5760Sstevel@tonic-gate GET_2ND_TSB_SIZE(tsbp8k, tmp1); \ 5770Sstevel@tonic-gate /* tmp1 = TSB size code */ \ 5780Sstevel@tonic-gate GET_TSBE_POINTER(MMU_PAGESHIFT4M, tsbe_ptr, tagacc, tmp1, tmp2) 5790Sstevel@tonic-gate 5801772Sjl139090 5816127Ssm142603 #else /* !UTSB_PHYS */ 5821772Sjl139090 5831772Sjl139090 5841772Sjl139090 /* 5851772Sjl139090 * Determine the pointer of the entry in the first TSB to probe given 5861772Sjl139090 * the 8K TSB pointer register contents. 5871772Sjl139090 * 5881772Sjl139090 * In: 5891772Sjl139090 * tagacc = tag access register 5901772Sjl139090 * tsbe_ptr = 8K TSB pointer register 5911772Sjl139090 * tmp = scratch registers 5921772Sjl139090 * 5931772Sjl139090 * Out: tsbe_ptr = TSB entry address 5941772Sjl139090 * 5951772Sjl139090 * Note: This macro is a nop since the 8K TSB pointer register 5961772Sjl139090 * is the entry pointer and does not need to be decoded. 5971772Sjl139090 * It is defined to allow for code sharing with sun4v. 5981772Sjl139090 */ 5991772Sjl139090 6001772Sjl139090 #define GET_1ST_TSBE_PTR(tagacc, tsbe_ptr, tmp1, tmp2) 6011772Sjl139090 6026127Ssm142603 #endif /* !UTSB_PHYS */ 6031772Sjl139090 6041772Sjl139090 6051772Sjl139090 /* 6061772Sjl139090 * Load TSB base register. In the single TSB case this register 6071772Sjl139090 * contains utsb_vabase, bits 21:13 of tsbinfo->tsb_va, and the 6081772Sjl139090 * TSB size code in bits 2:0. See hat_sfmmu.h for the layout in 6091772Sjl139090 * the case where we have multiple TSBs per process. 6101772Sjl139090 * 6111772Sjl139090 * In: 6121772Sjl139090 * tsbreg = value to load (ro) 6131772Sjl139090 */ 6141772Sjl139090 #define LOAD_TSBREG(tsbreg, tmp1, tmp2) \ 6151772Sjl139090 mov MMU_TSB, tmp1; \ 6161772Sjl139090 sethi %hi(FLUSH_ADDR), tmp2; \ 6171772Sjl139090 stxa tsbreg, [tmp1]ASI_DMMU; /* dtsb reg */ \ 6181772Sjl139090 stxa tsbreg, [tmp1]ASI_IMMU; /* itsb reg */ \ 6191772Sjl139090 flush tmp2 6201772Sjl139090 6211772Sjl139090 #ifdef UTSB_PHYS 6221772Sjl139090 #define UTSB_PROBE_ASI ASI_QUAD_LDD_PHYS 6231772Sjl139090 #else 6241772Sjl139090 #define UTSB_PROBE_ASI ASI_NQUAD_LD 6251772Sjl139090 #endif 6266127Ssm142603 #define PROBE_TSB(tsbe_ptr, tag, tsbtag, label) \ 6276127Ssm142603 /* BEGIN CSTYLED */ \ 6286127Ssm142603 ldda [tsbe_ptr]UTSB_PROBE_ASI, tsbtag ;\ 6296127Ssm142603 cmp tsbtag, tag /* compare tag w/ TSB */ ;\ 6306127Ssm142603 bne,pn %xcc, label/**/1 /* branch if !match */ ;\ 6316127Ssm142603 nop \ 6326127Ssm142603 /* END CSTYLED */ 6331772Sjl139090 /* 6346127Ssm142603 * Probe a TSB. If miss continue from the end of the macro for most probes 6356127Ssm142603 * except jump to TSB miss for 3rd ITSB probe. If hit retry faulted 6366127Ssm142603 * instruction for DTSB probes. For ITSB probes in case of TSB hit check 6376127Ssm142603 * execute bit and branch to exec_fault if the bit is not set otherwise retry 6386127Ssm142603 * faulted instruction. Do ITLB synthesis in case of hit in second ITSB if 6396127Ssm142603 * synthesis bit is set. 6401772Sjl139090 * 6416127Ssm142603 * tsbe_ptr = precomputed TSB entry pointer (in, ro) 6421772Sjl139090 * vpg_4m = 4M virtual page number for tag matching (in, ro) 6431772Sjl139090 * label = where to branch to if this is a miss (text) 6441772Sjl139090 * 6451772Sjl139090 * For trapstat, we have to explicily use these registers. 6461772Sjl139090 * g4 = location tag will be retrieved into from TSB (out) 6471772Sjl139090 * g5 = location data(tte) will be retrieved into from TSB (out) 6486127Ssm142603 * 6496127Ssm142603 * In case of first tsb probe tsbe_ptr is %g1. For other tsb probes 6506127Ssm142603 * move tsbe_ptr into %g1 in case of hit for traptrace. 6516127Ssm142603 * 6526127Ssm142603 * If the probe fails and we continue from call site %g4-%g5 are clobbered. 6536127Ssm142603 * 2nd ITSB probe macro will also clobber %g6 in this case. 6541772Sjl139090 */ 6556127Ssm142603 #define PROBE_1ST_DTSB(tsbe_ptr, vpg_4m, label) \ 6566127Ssm142603 /* BEGIN CSTYLED */ \ 6576127Ssm142603 PROBE_TSB(tsbe_ptr, vpg_4m, %g4, label) ;\ 6586127Ssm142603 TT_TRACE(trace_tsbhit) ;\ 6596127Ssm142603 DTLB_STUFF(%g5, %g1, %g2, %g3, %g4) ;\ 6606127Ssm142603 retry /* retry faulted instruction */ ;\ 6616127Ssm142603 label/**/1: \ 6626127Ssm142603 /* END CSTYLED */ 6636127Ssm142603 6646127Ssm142603 #define PROBE_2ND_DTSB(tsbe_ptr, vpg_4m, label) \ 6656127Ssm142603 /* BEGIN CSTYLED */ \ 6666127Ssm142603 PROBE_TSB(tsbe_ptr, vpg_4m, %g4, label) ;\ 6676127Ssm142603 mov tsbe_ptr, %g1 /* trace_tsbhit wants ptr in %g1 */ ;\ 6686127Ssm142603 TT_TRACE(trace_tsbhit) ;\ 6696127Ssm142603 DTLB_STUFF(%g5, %g1, %g2, %g3, %g4) ;\ 6706127Ssm142603 retry /* retry faulted instruction */ ;\ 6716127Ssm142603 label/**/1: \ 6721772Sjl139090 /* END CSTYLED */ 6731772Sjl139090 6746127Ssm142603 #define PROBE_1ST_ITSB(tsbe_ptr, vpg_4m, label) \ 6756127Ssm142603 /* BEGIN CSTYLED */ \ 6766127Ssm142603 PROBE_TSB(tsbe_ptr, vpg_4m, %g4, label) ;\ 6776127Ssm142603 andcc %g5, TTE_EXECPRM_INT, %g0 /* check execute bit */ ;\ 6786127Ssm142603 bz,pn %icc, exec_fault ;\ 6796127Ssm142603 nop ;\ 6806127Ssm142603 TT_TRACE(trace_tsbhit) ;\ 6816127Ssm142603 ITLB_STUFF(%g5, %g1, %g2, %g3, %g4) ;\ 6826127Ssm142603 retry /* retry faulted instruction */ ;\ 6836127Ssm142603 label/**/1: \ 6846127Ssm142603 /* END CSTYLED */ 6856127Ssm142603 6866127Ssm142603 #define PROBE_2ND_ITSB(tsbe_ptr, vpg_4m, label) \ 6876127Ssm142603 /* BEGIN CSTYLED */ \ 6886127Ssm142603 ldda [tsbe_ptr]UTSB_PROBE_ASI, %g4 /* g4 = tag, g5 = data */ ;\ 6896127Ssm142603 cmp %g4, vpg_4m /* compare tag w/ TSB */ ;\ 6906127Ssm142603 bne,pn %xcc, label/**/2 /* branch if !match */ ;\ 6916127Ssm142603 or %g0, TTE4M, %g6 ;\ 6926127Ssm142603 andcc %g5, TTE_EXECPRM_INT, %g0 /* check execute bit */ ;\ 6936127Ssm142603 bz,a,pn %icc, label/**/1 ;\ 6946127Ssm142603 sllx %g6, TTE_SZ_SHFT, %g6 ;\ 6956127Ssm142603 mov tsbe_ptr, %g1 /* trap trace wants ptr in %g1 */ ;\ 6966127Ssm142603 TT_TRACE(trace_tsbhit) ;\ 6976127Ssm142603 ITLB_STUFF(%g5, %g1, %g2, %g3, %g4) ;\ 6986127Ssm142603 retry /* retry faulted instruction */ ;\ 6996127Ssm142603 label/**/1: ;\ 7006127Ssm142603 andcc %g5, TTE_E_SYNTH_INT, %g0 ;\ 7016127Ssm142603 bz,pn %icc, exec_fault ;\ 7026127Ssm142603 mov tsbe_ptr, %g1 /* trap trace wants ptr in %g1 */ ;\ 7036127Ssm142603 or %g5, %g6, %g5 ;\ 7046127Ssm142603 TT_TRACE(trace_tsbhit) ;\ 7056127Ssm142603 ITLB_STUFF(%g5, %g1, %g2, %g3, %g4) ;\ 7066127Ssm142603 retry /* retry faulted instruction */ ;\ 7076127Ssm142603 label/**/2: 7086127Ssm142603 /* END CSTYLED */ 7096127Ssm142603 7106127Ssm142603 #ifdef UTSB_PHYS 7116127Ssm142603 7121772Sjl139090 /* 7136127Ssm142603 * Updates the context filed in the tagaccess register with the shared 7146127Ssm142603 * context to force the next i/DTLB_STUFF() to load this mapping into 7156127Ssm142603 * the TLB with the shared context. 7161772Sjl139090 */ 7176127Ssm142603 #define SET_SHCTX_TAGACC(tmp1, tmp2, asi) \ 7186127Ssm142603 /* BEGIN CSTYLED */ \ 7196127Ssm142603 mov MMU_TAG_ACCESS, tmp2 ;\ 7206127Ssm142603 ldxa [tmp2]asi, tmp2 /* tmp2 = VA|CTX */ ;\ 7216127Ssm142603 srlx tmp2, TAGACC_SHIFT, tmp2 ;\ 7226127Ssm142603 sllx tmp2, TAGACC_SHIFT, tmp2 /* tmp2 = VA */ ;\ 7236127Ssm142603 mov MMU_SHARED_CONTEXT, tmp1 /* clobber tsbe_ptr */ ;\ 7246127Ssm142603 ldxa [tmp1]ASI_MMU_CTX, tmp1 /* tmp2 = shctx reg */ ;\ 7256127Ssm142603 sllx tmp1, SHCTXREG_CTX_LSHIFT, tmp1 ;\ 7266127Ssm142603 srlx tmp1, SHCTXREG_CTX_LSHIFT, tmp1 /* tmp1 = SHCTX */ ;\ 7276127Ssm142603 or tmp1, tmp2, tmp1 /* tmp1 = VA|SHCTX */ ;\ 7286127Ssm142603 mov MMU_TAG_ACCESS, tmp2 ;\ 7296127Ssm142603 stxa tmp1, [tmp2]asi /* asi = VA|SHCTX */ 7306127Ssm142603 /* END CSTYLED */ 7316127Ssm142603 7326127Ssm142603 #define PROBE_SHCTX_DTSB(tsbe_ptr, vpg_4m, label) \ 7336127Ssm142603 /* BEGIN CSTYLED */ \ 7346127Ssm142603 PROBE_TSB(tsbe_ptr, vpg_4m, %g4, label) ;\ 7356127Ssm142603 mov tsbe_ptr, %g1 /* trace_tsbhit wants ptr in %g1 */ ;\ 7366127Ssm142603 TT_TRACE(trace_tsbhit) ;\ 7376127Ssm142603 SET_SHCTX_TAGACC(%g3, %g4, ASI_DMMU) ;\ 7386127Ssm142603 DTLB_STUFF(%g5, %g1, %g2, %g3, %g4) ;\ 7396127Ssm142603 retry /* retry faulted instruction */ ;\ 7406127Ssm142603 label/**/1: \ 7411772Sjl139090 /* END CSTYLED */ 7420Sstevel@tonic-gate 7436127Ssm142603 #define PROBE_3RD_DTSB(tsbe_ptr, vpg_4m, label) \ 7446127Ssm142603 /* BEGIN CSTYLED */ \ 7456127Ssm142603 PROBE_SHCTX_DTSB(tsbe_ptr, vpg_4m, label) ;\ 7466127Ssm142603 /* END CSTYLED */ 7476127Ssm142603 7486127Ssm142603 #define PROBE_4TH_DTSB(tsbe_ptr, vpg_4m, label) \ 7496127Ssm142603 /* BEGIN CSTYLED */ \ 7506127Ssm142603 PROBE_SHCTX_DTSB(tsbe_ptr, vpg_4m, label) ;\ 7516127Ssm142603 /* END CSTYLED */ 7526127Ssm142603 7536127Ssm142603 #define PROBE_SHCTX_ITSB(tsbe_ptr, vpg_4m, label) \ 7546127Ssm142603 /* BEGIN CSTYLED */ \ 7556127Ssm142603 PROBE_TSB(tsbe_ptr, vpg_4m, %g4, label) ;\ 7566127Ssm142603 andcc %g5, TTE_EXECPRM_INT, %g0 /* check execute bit */ ;\ 7576127Ssm142603 bz,pn %icc, exec_fault ;\ 7586127Ssm142603 mov tsbe_ptr, %g1 /* for traptrace sake */ ;\ 7596127Ssm142603 TT_TRACE(trace_tsbhit) ;\ 7606127Ssm142603 SET_SHCTX_TAGACC(%g3, %g4, ASI_IMMU) ;\ 7616127Ssm142603 ITLB_STUFF(%g5, %g1, %g2, %g3, %g4) ;\ 7626127Ssm142603 retry /* retry faulted instruction */ ;\ 7636127Ssm142603 label/**/1: 7646127Ssm142603 /* END CSTYLED */ 7656127Ssm142603 7666127Ssm142603 #define PROBE_3RD_ITSB(tsbe_ptr, vpg_4m, label) \ 7676127Ssm142603 /* BEGIN CSTYLED */ \ 7686127Ssm142603 PROBE_SHCTX_ITSB(tsbe_ptr, vpg_4m, sfmmu_tsb_miss_tt) ;\ 7696127Ssm142603 /* END CSTYLED */ 7706127Ssm142603 7716127Ssm142603 #define PROBE_4TH_ITSB(tsbe_ptr, vpg_4m, label) \ 7726127Ssm142603 /* BEGIN CSTYLED */ \ 7736127Ssm142603 PROBE_SHCTX_ITSB(tsbe_ptr, vpg_4m, label) ;\ 7740Sstevel@tonic-gate /* END CSTYLED */ 7750Sstevel@tonic-gate 7764528Spaulsan /* 7776127Ssm142603 * The traptype is supplied by caller. 7786127Ssm142603 * 7796127Ssm142603 * If iTSB miss, store shctx into IMMU TAG ACCESS REG 7806127Ssm142603 * If dTSB miss, store shctx into DMMU TAG ACCESS REG 7816127Ssm142603 * Thus the [D|I]TLB_STUFF will work as expected. 7820Sstevel@tonic-gate */ 7836127Ssm142603 #define SAVE_CTX1(traptype, tmp1, tmp2, label) \ 7846127Ssm142603 /* BEGIN CSTYLED */ \ 7856127Ssm142603 cmp traptype, FAST_IMMU_MISS_TT ;\ 7866127Ssm142603 be,pn %icc, label/**/1 ;\ 7876127Ssm142603 nop ;\ 7886127Ssm142603 SET_SHCTX_TAGACC(tmp1, tmp2, ASI_DMMU) ;\ 7896127Ssm142603 membar #Sync ;\ 7906127Ssm142603 ba,a label/**/2 ;\ 7916127Ssm142603 label/**/1: ;\ 7926127Ssm142603 SET_SHCTX_TAGACC(tmp1, tmp2, ASI_IMMU) ;\ 7936127Ssm142603 sethi %hi(FLUSH_ADDR), tmp1 ;\ 7946127Ssm142603 flush tmp1 ;\ 7956127Ssm142603 label/**/2: 7960Sstevel@tonic-gate /* END CSTYLED */ 7970Sstevel@tonic-gate 7986127Ssm142603 #endif /* UTSB_PHYS */ 7996127Ssm142603 8000Sstevel@tonic-gate #endif /* _ASM */ 8010Sstevel@tonic-gate 8020Sstevel@tonic-gate #ifdef __cplusplus 8030Sstevel@tonic-gate } 8040Sstevel@tonic-gate #endif 8050Sstevel@tonic-gate 8060Sstevel@tonic-gate #endif /* _VM_MACH_SFMMU_H */ 807