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