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