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/* 221426d65aSsm142603 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate#pragma ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate/* 297c478bd9Sstevel@tonic-gate * SFMMU primitives. These primitives should only be used by sfmmu 307c478bd9Sstevel@tonic-gate * routines. 317c478bd9Sstevel@tonic-gate */ 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate#if defined(lint) 347c478bd9Sstevel@tonic-gate#include <sys/types.h> 357c478bd9Sstevel@tonic-gate#else /* lint */ 367c478bd9Sstevel@tonic-gate#include "assym.h" 377c478bd9Sstevel@tonic-gate#endif /* lint */ 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h> 407c478bd9Sstevel@tonic-gate#include <sys/machtrap.h> 417c478bd9Sstevel@tonic-gate#include <sys/machasi.h> 427c478bd9Sstevel@tonic-gate#include <sys/sun4asi.h> 437c478bd9Sstevel@tonic-gate#include <sys/pte.h> 447c478bd9Sstevel@tonic-gate#include <sys/mmu.h> 457c478bd9Sstevel@tonic-gate#include <vm/hat_sfmmu.h> 467c478bd9Sstevel@tonic-gate#include <vm/seg_spt.h> 477c478bd9Sstevel@tonic-gate#include <sys/machparam.h> 487c478bd9Sstevel@tonic-gate#include <sys/privregs.h> 497c478bd9Sstevel@tonic-gate#include <sys/scb.h> 507c478bd9Sstevel@tonic-gate#include <sys/intreg.h> 517c478bd9Sstevel@tonic-gate#include <sys/machthread.h> 527c478bd9Sstevel@tonic-gate#include <sys/clock.h> 537c478bd9Sstevel@tonic-gate#include <sys/trapstat.h> 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate/* 567c478bd9Sstevel@tonic-gate * sfmmu related subroutines 577c478bd9Sstevel@tonic-gate */ 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate#if defined (lint) 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate/* 627c478bd9Sstevel@tonic-gate * sfmmu related subroutines 637c478bd9Sstevel@tonic-gate */ 647c478bd9Sstevel@tonic-gate/* ARGSUSED */ 657c478bd9Sstevel@tonic-gatevoid 661e2e7a75Shuahsfmmu_raise_tsb_exception(uint64_t sfmmup, uint64_t rctx) 677c478bd9Sstevel@tonic-gate{} 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate/* ARGSUSED */ 707c478bd9Sstevel@tonic-gatevoid 711e2e7a75Shuahsfmmu_itlb_ld_kva(caddr_t vaddr, tte_t *tte) 727c478bd9Sstevel@tonic-gate{} 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate/* ARGSUSED */ 757c478bd9Sstevel@tonic-gatevoid 761e2e7a75Shuahsfmmu_dtlb_ld_kva(caddr_t vaddr, tte_t *tte) 777c478bd9Sstevel@tonic-gate{} 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gateint 807c478bd9Sstevel@tonic-gatesfmmu_getctx_pri() 817c478bd9Sstevel@tonic-gate{ return(0); } 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gateint 847c478bd9Sstevel@tonic-gatesfmmu_getctx_sec() 857c478bd9Sstevel@tonic-gate{ return(0); } 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate/* ARGSUSED */ 887c478bd9Sstevel@tonic-gatevoid 8905d3dc4bSpaulsansfmmu_setctx_sec(uint_t ctx) 907c478bd9Sstevel@tonic-gate{} 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate/* ARGSUSED */ 937c478bd9Sstevel@tonic-gatevoid 947c478bd9Sstevel@tonic-gatesfmmu_load_mmustate(sfmmu_t *sfmmup) 957c478bd9Sstevel@tonic-gate{ 967c478bd9Sstevel@tonic-gate} 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate#else /* lint */ 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate/* 1011e2e7a75Shuah * Invalidate either the context of a specific victim or any process 1021e2e7a75Shuah * currently running on this CPU. 1037c478bd9Sstevel@tonic-gate * 1041e2e7a75Shuah * %g1 = sfmmup whose ctx is being invalidated 1051e2e7a75Shuah * when called from sfmmu_wrap_around, %g1 == INVALID_CONTEXT 1061e2e7a75Shuah * Note %g1 is the only input argument used by this xcall handler. 1077c478bd9Sstevel@tonic-gate */ 1081e2e7a75Shuah ENTRY(sfmmu_raise_tsb_exception) 1097c478bd9Sstevel@tonic-gate ! 1101426d65aSsm142603 ! if (victim == INVALID_CONTEXT || 1111426d65aSsm142603 ! current CPU tsbmiss->usfmmup == victim sfmmup) { 1121426d65aSsm142603 ! if (shctx_on) { 1131426d65aSsm142603 ! shctx = INVALID; 1141426d65aSsm142603 ! } 1151e2e7a75Shuah ! if (sec-ctx > INVALID_CONTEXT) { 1161e2e7a75Shuah ! write INVALID_CONTEXT to sec-ctx 1171e2e7a75Shuah ! } 1181e2e7a75Shuah ! if (pri-ctx > INVALID_CONTEXT) { 1191e2e7a75Shuah ! write INVALID_CONTEXT to pri-ctx 1201e2e7a75Shuah ! } 1217c478bd9Sstevel@tonic-gate ! } 1221e2e7a75Shuah 1231e2e7a75Shuah sethi %hi(ksfmmup), %g3 1241e2e7a75Shuah ldx [%g3 + %lo(ksfmmup)], %g3 1251e2e7a75Shuah cmp %g1, %g3 1261e2e7a75Shuah be,a,pn %xcc, ptl1_panic /* can't invalidate kernel ctx */ 1271e2e7a75Shuah mov PTL1_BAD_RAISE_TSBEXCP, %g1 1281e2e7a75Shuah 1291e2e7a75Shuah set INVALID_CONTEXT, %g2 1301e2e7a75Shuah cmp %g1, INVALID_CONTEXT 1311426d65aSsm142603 be,pn %xcc, 0f /* called from wrap_around? */ 1321e2e7a75Shuah mov MMU_SCONTEXT, %g3 1331e2e7a75Shuah 1341426d65aSsm142603 CPU_TSBMISS_AREA(%g5, %g6) /* load cpu tsbmiss area */ 1351426d65aSsm142603 ldx [%g5 + TSBMISS_UHATID], %g5 /* load usfmmup */ 1361426d65aSsm142603 cmp %g5, %g1 /* hat toBe-invalid running? */ 1371426d65aSsm142603 bne,pt %xcc, 3f 1381426d65aSsm142603 nop 1391426d65aSsm142603 1401426d65aSsm1426030: 1411426d65aSsm142603 sethi %hi(shctx_on), %g5 1421426d65aSsm142603 ld [%g5 + %lo(shctx_on)], %g5 1431426d65aSsm142603 brz %g5, 1f 1441426d65aSsm142603 mov MMU_SHARED_CONTEXT, %g5 1451426d65aSsm142603 sethi %hi(FLUSH_ADDR), %g4 1461426d65aSsm142603 stxa %g0, [%g5]ASI_MMU_CTX 1471426d65aSsm142603 flush %g4 1481426d65aSsm142603 1491426d65aSsm1426031: 1501e2e7a75Shuah ldxa [%g3]ASI_MMU_CTX, %g5 /* %g5 = pgsz | sec-ctx */ 1511e2e7a75Shuah set CTXREG_CTX_MASK, %g4 1521e2e7a75Shuah and %g5, %g4, %g5 /* %g5 = sec-ctx */ 1531e2e7a75Shuah cmp %g5, INVALID_CONTEXT /* kernel ctx or invald ctx? */ 1541426d65aSsm142603 ble,pn %xcc, 2f /* yes, no need to change */ 1557c478bd9Sstevel@tonic-gate mov MMU_PCONTEXT, %g7 1561e2e7a75Shuah 1571e2e7a75Shuah stxa %g2, [%g3]ASI_MMU_CTX /* set invalid ctx */ 1587c478bd9Sstevel@tonic-gate membar #Sync 1591e2e7a75Shuah 1601426d65aSsm1426032: 161febcc4a5Sjimand ldxa [%g7]ASI_MMU_CTX, %g3 /* get pgz | pri-ctx */ 162febcc4a5Sjimand and %g3, %g4, %g5 /* %g5 = pri-ctx */ 1631e2e7a75Shuah cmp %g5, INVALID_CONTEXT /* kernel ctx or invald ctx? */ 1641426d65aSsm142603 ble,pn %xcc, 3f /* yes, no need to change */ 165febcc4a5Sjimand srlx %g3, CTXREG_NEXT_SHIFT, %g3 /* %g3 = nucleus pgsz */ 166febcc4a5Sjimand sllx %g3, CTXREG_NEXT_SHIFT, %g3 /* need to preserve nucleus pgsz */ 167febcc4a5Sjimand or %g3, %g2, %g2 /* %g2 = nucleus pgsz | INVALID_CONTEXT */ 1681e2e7a75Shuah 1691e2e7a75Shuah stxa %g2, [%g7]ASI_MMU_CTX /* set pri-ctx to invalid */ 1701426d65aSsm1426033: 1717c478bd9Sstevel@tonic-gate retry 1721e2e7a75Shuah SET_SIZE(sfmmu_raise_tsb_exception) 1737c478bd9Sstevel@tonic-gate 1741426d65aSsm142603 1751426d65aSsm142603 1761e2e7a75Shuah /* 1771e2e7a75Shuah * %o0 = virtual address 1781e2e7a75Shuah * %o1 = address of TTE to be loaded 1791e2e7a75Shuah */ 1801e2e7a75Shuah ENTRY_NP(sfmmu_itlb_ld_kva) 1817c478bd9Sstevel@tonic-gate rdpr %pstate, %o3 1827c478bd9Sstevel@tonic-gate#ifdef DEBUG 1831e2e7a75Shuah PANIC_IF_INTR_DISABLED_PSTR(%o3, msfmmu_di_l1, %g1) 1847c478bd9Sstevel@tonic-gate#endif /* DEBUG */ 1857c478bd9Sstevel@tonic-gate wrpr %o3, PSTATE_IE, %pstate ! Disable interrupts 1867c478bd9Sstevel@tonic-gate srln %o0, MMU_PAGESHIFT, %o0 1877c478bd9Sstevel@tonic-gate slln %o0, MMU_PAGESHIFT, %o0 ! Clear page offset 1881e2e7a75Shuah 1891e2e7a75Shuah ldx [%o1], %g1 1907c478bd9Sstevel@tonic-gate set MMU_TAG_ACCESS, %o5 1917c478bd9Sstevel@tonic-gate#ifdef CHEETAHPLUS_ERRATUM_34 1927c478bd9Sstevel@tonic-gate ! 1937c478bd9Sstevel@tonic-gate ! If this is Cheetah or derivative and the specified TTE is locked 1947c478bd9Sstevel@tonic-gate ! and hence to be loaded into the T16, fully-associative TLB, we 1957c478bd9Sstevel@tonic-gate ! must avoid Cheetah+ erratum 34. In Cheetah+ erratum 34, under 1967c478bd9Sstevel@tonic-gate ! certain conditions an ITLB locked index 0 TTE will erroneously be 1977c478bd9Sstevel@tonic-gate ! displaced when a new TTE is loaded via ASI_ITLB_IN. To avoid 1987c478bd9Sstevel@tonic-gate ! this erratum, we scan the T16 top down for an unlocked TTE and 1997c478bd9Sstevel@tonic-gate ! explicitly load the specified TTE into that index. 2007c478bd9Sstevel@tonic-gate ! 2017c478bd9Sstevel@tonic-gate GET_CPU_IMPL(%g2) 2027c478bd9Sstevel@tonic-gate cmp %g2, CHEETAH_IMPL 2037c478bd9Sstevel@tonic-gate bl,pn %icc, 0f 2047c478bd9Sstevel@tonic-gate nop 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate andcc %g1, TTE_LCK_INT, %g0 2077c478bd9Sstevel@tonic-gate bz %icc, 0f ! Lock bit is not set; 2087c478bd9Sstevel@tonic-gate ! load normally. 2097c478bd9Sstevel@tonic-gate or %g0, (15 << 3), %g3 ! Start searching from the 2107c478bd9Sstevel@tonic-gate ! top down. 2117c478bd9Sstevel@tonic-gate 2127c478bd9Sstevel@tonic-gate1: 2137c478bd9Sstevel@tonic-gate ldxa [%g3]ASI_ITLB_ACCESS, %g4 ! Load TTE from t16 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate ! 2167c478bd9Sstevel@tonic-gate ! If this entry isn't valid, we'll choose to displace it (regardless 2177c478bd9Sstevel@tonic-gate ! of the lock bit). 2187c478bd9Sstevel@tonic-gate ! 2197c478bd9Sstevel@tonic-gate cmp %g4, %g0 2207c478bd9Sstevel@tonic-gate bge %xcc, 2f ! TTE is > 0 iff not valid 2217c478bd9Sstevel@tonic-gate andcc %g4, TTE_LCK_INT, %g0 ! Check for lock bit 2227c478bd9Sstevel@tonic-gate bz %icc, 2f ! If unlocked, go displace 2237c478bd9Sstevel@tonic-gate nop 2247c478bd9Sstevel@tonic-gate sub %g3, (1 << 3), %g3 2257c478bd9Sstevel@tonic-gate brgz %g3, 1b ! Still more TLB entries 2267c478bd9Sstevel@tonic-gate nop ! to search 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate sethi %hi(sfmmu_panic5), %o0 ! We searched all entries and 2297c478bd9Sstevel@tonic-gate call panic ! found no unlocked TTE so 2307c478bd9Sstevel@tonic-gate or %o0, %lo(sfmmu_panic5), %o0 ! give up. 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate2: 2347c478bd9Sstevel@tonic-gate ! 2357c478bd9Sstevel@tonic-gate ! We have found an unlocked or non-valid entry; we'll explicitly load 2367c478bd9Sstevel@tonic-gate ! our locked entry here. 2377c478bd9Sstevel@tonic-gate ! 2387c478bd9Sstevel@tonic-gate sethi %hi(FLUSH_ADDR), %o1 ! Flush addr doesn't matter 2397c478bd9Sstevel@tonic-gate stxa %o0, [%o5]ASI_IMMU 2407c478bd9Sstevel@tonic-gate stxa %g1, [%g3]ASI_ITLB_ACCESS 2417c478bd9Sstevel@tonic-gate flush %o1 ! Flush required for I-MMU 2427c478bd9Sstevel@tonic-gate ba 3f ! Delay slot of ba is empty 2437c478bd9Sstevel@tonic-gate nop ! per Erratum 64 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate0: 2467c478bd9Sstevel@tonic-gate#endif /* CHEETAHPLUS_ERRATUM_34 */ 2477c478bd9Sstevel@tonic-gate sethi %hi(FLUSH_ADDR), %o1 ! Flush addr doesn't matter 2487c478bd9Sstevel@tonic-gate stxa %o0, [%o5]ASI_IMMU 2497c478bd9Sstevel@tonic-gate stxa %g1, [%g0]ASI_ITLB_IN 2507c478bd9Sstevel@tonic-gate flush %o1 ! Flush required for I-MMU 2517c478bd9Sstevel@tonic-gate3: 2527c478bd9Sstevel@tonic-gate retl 2537c478bd9Sstevel@tonic-gate wrpr %g0, %o3, %pstate ! Enable interrupts 2541e2e7a75Shuah SET_SIZE(sfmmu_itlb_ld_kva) 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate /* 2577c478bd9Sstevel@tonic-gate * Load an entry into the DTLB. 2587c478bd9Sstevel@tonic-gate * 2597c478bd9Sstevel@tonic-gate * Special handling is required for locked entries since there 2607c478bd9Sstevel@tonic-gate * are some TLB slots that are reserved for the kernel but not 2617c478bd9Sstevel@tonic-gate * always held locked. We want to avoid loading locked TTEs 2627c478bd9Sstevel@tonic-gate * into those slots since they could be displaced. 2631e2e7a75Shuah * 2641e2e7a75Shuah * %o0 = virtual address 2651e2e7a75Shuah * %o1 = address of TTE to be loaded 2667c478bd9Sstevel@tonic-gate */ 2671e2e7a75Shuah ENTRY_NP(sfmmu_dtlb_ld_kva) 2687c478bd9Sstevel@tonic-gate rdpr %pstate, %o3 2697c478bd9Sstevel@tonic-gate#ifdef DEBUG 2701e2e7a75Shuah PANIC_IF_INTR_DISABLED_PSTR(%o3, msfmmu_di_l2, %g1) 2717c478bd9Sstevel@tonic-gate#endif /* DEBUG */ 2727c478bd9Sstevel@tonic-gate wrpr %o3, PSTATE_IE, %pstate ! disable interrupts 2737c478bd9Sstevel@tonic-gate srln %o0, MMU_PAGESHIFT, %o0 2747c478bd9Sstevel@tonic-gate slln %o0, MMU_PAGESHIFT, %o0 ! clear page offset 2751e2e7a75Shuah 2761e2e7a75Shuah ldx [%o1], %g1 2771e2e7a75Shuah 2787c478bd9Sstevel@tonic-gate set MMU_TAG_ACCESS, %o5 2791e2e7a75Shuah 2801e2e7a75Shuah set cpu_impl_dual_pgsz, %o2 2811e2e7a75Shuah ld [%o2], %o2 2821e2e7a75Shuah brz %o2, 1f 2831e2e7a75Shuah nop 2841e2e7a75Shuah 2851e2e7a75Shuah sethi %hi(ksfmmup), %o2 2861e2e7a75Shuah ldx [%o2 + %lo(ksfmmup)], %o2 2871e2e7a75Shuah ldub [%o2 + SFMMU_CEXT], %o2 2881e2e7a75Shuah sll %o2, TAGACCEXT_SHIFT, %o2 2891e2e7a75Shuah 2907c478bd9Sstevel@tonic-gate set MMU_TAG_ACCESS_EXT, %o4 ! can go into T8 if unlocked 2917c478bd9Sstevel@tonic-gate stxa %o2,[%o4]ASI_DMMU 2927c478bd9Sstevel@tonic-gate membar #Sync 2937c478bd9Sstevel@tonic-gate1: 2947c478bd9Sstevel@tonic-gate andcc %g1, TTE_LCK_INT, %g0 ! Locked entries require 2957c478bd9Sstevel@tonic-gate bnz,pn %icc, 2f ! special handling 2967c478bd9Sstevel@tonic-gate sethi %hi(dtlb_resv_ttenum), %g3 2977c478bd9Sstevel@tonic-gate stxa %o0,[%o5]ASI_DMMU ! Load unlocked TTE 2987c478bd9Sstevel@tonic-gate stxa %g1,[%g0]ASI_DTLB_IN ! via DTLB_IN 2997c478bd9Sstevel@tonic-gate membar #Sync 3007c478bd9Sstevel@tonic-gate retl 3017c478bd9Sstevel@tonic-gate wrpr %g0, %o3, %pstate ! enable interrupts 3027c478bd9Sstevel@tonic-gate2: 303*19f938d5Sjfrank#ifdef CHEETAHPLUS_ERRATUM_34 304*19f938d5Sjfrank GET_CPU_IMPL(%g2) 305*19f938d5Sjfrank#endif 3067c478bd9Sstevel@tonic-gate ld [%g3 + %lo(dtlb_resv_ttenum)], %g3 3077c478bd9Sstevel@tonic-gate sll %g3, 3, %g3 ! First reserved idx in TLB 0 3087c478bd9Sstevel@tonic-gate sub %g3, (1 << 3), %g3 ! Decrement idx 309*19f938d5Sjfrank ! Erratum 15 workaround due to ld [%g3 + %lo(dtlb_resv_ttenum)], %g3 310*19f938d5Sjfrank ldxa [%g3]ASI_DTLB_ACCESS, %g4 ! Load TTE from TLB 0 3117c478bd9Sstevel@tonic-gate3: 3127c478bd9Sstevel@tonic-gate ldxa [%g3]ASI_DTLB_ACCESS, %g4 ! Load TTE from TLB 0 3137c478bd9Sstevel@tonic-gate ! 3147c478bd9Sstevel@tonic-gate ! If this entry isn't valid, we'll choose to displace it (regardless 3157c478bd9Sstevel@tonic-gate ! of the lock bit). 3167c478bd9Sstevel@tonic-gate ! 3177c478bd9Sstevel@tonic-gate brgez,pn %g4, 4f ! TTE is > 0 iff not valid 3187c478bd9Sstevel@tonic-gate nop 3197c478bd9Sstevel@tonic-gate andcc %g4, TTE_LCK_INT, %g0 ! Check for lock bit 3207c478bd9Sstevel@tonic-gate bz,pn %icc, 4f ! If unlocked, go displace 3217c478bd9Sstevel@tonic-gate nop 3227c478bd9Sstevel@tonic-gate sub %g3, (1 << 3), %g3 ! Decrement idx 323*19f938d5Sjfrank#ifdef CHEETAHPLUS_ERRATUM_34 324*19f938d5Sjfrank ! 325*19f938d5Sjfrank ! If this is a Cheetah or derivative, we must work around Erratum 34 326*19f938d5Sjfrank ! for the DTLB. Erratum 34 states that under certain conditions, 327*19f938d5Sjfrank ! a locked entry 0 TTE may be improperly displaced. To avoid this, 328*19f938d5Sjfrank ! we do not place a locked TTE in entry 0. 329*19f938d5Sjfrank ! 330*19f938d5Sjfrank brgz %g3, 3b 331*19f938d5Sjfrank nop 332*19f938d5Sjfrank cmp %g2, CHEETAH_IMPL 333*19f938d5Sjfrank bge,pt %icc, 5f 334*19f938d5Sjfrank nop 335*19f938d5Sjfrank brz %g3, 3b 336*19f938d5Sjfrank nop 337*19f938d5Sjfrank#else /* CHEETAHPLUS_ERRATUM_34 */ 3387c478bd9Sstevel@tonic-gate brgez %g3, 3b 3397c478bd9Sstevel@tonic-gate nop 340*19f938d5Sjfrank#endif /* CHEETAHPLUS_ERRATUM_34 */ 341*19f938d5Sjfrank5: 3427c478bd9Sstevel@tonic-gate sethi %hi(sfmmu_panic5), %o0 ! We searched all entries and 3437c478bd9Sstevel@tonic-gate call panic ! found no unlocked TTE so 3447c478bd9Sstevel@tonic-gate or %o0, %lo(sfmmu_panic5), %o0 ! give up. 3457c478bd9Sstevel@tonic-gate4: 3467c478bd9Sstevel@tonic-gate stxa %o0,[%o5]ASI_DMMU ! Setup tag access 34725cf1a30Sjl139090#ifdef OLYMPUS_SHARED_FTLB 34825cf1a30Sjl139090 stxa %g1,[%g0]ASI_DTLB_IN 34925cf1a30Sjl139090#else 3507c478bd9Sstevel@tonic-gate stxa %g1,[%g3]ASI_DTLB_ACCESS ! Displace entry at idx 35125cf1a30Sjl139090#endif 3527c478bd9Sstevel@tonic-gate membar #Sync 3537c478bd9Sstevel@tonic-gate retl 3547c478bd9Sstevel@tonic-gate wrpr %g0, %o3, %pstate ! enable interrupts 3551e2e7a75Shuah SET_SIZE(sfmmu_dtlb_ld_kva) 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate ENTRY_NP(sfmmu_getctx_pri) 3587c478bd9Sstevel@tonic-gate set MMU_PCONTEXT, %o0 3597c478bd9Sstevel@tonic-gate retl 3607c478bd9Sstevel@tonic-gate ldxa [%o0]ASI_MMU_CTX, %o0 3617c478bd9Sstevel@tonic-gate SET_SIZE(sfmmu_getctx_pri) 3627c478bd9Sstevel@tonic-gate 3637c478bd9Sstevel@tonic-gate ENTRY_NP(sfmmu_getctx_sec) 3647c478bd9Sstevel@tonic-gate set MMU_SCONTEXT, %o0 3657c478bd9Sstevel@tonic-gate set CTXREG_CTX_MASK, %o1 3667c478bd9Sstevel@tonic-gate ldxa [%o0]ASI_MMU_CTX, %o0 3677c478bd9Sstevel@tonic-gate retl 3687c478bd9Sstevel@tonic-gate and %o0, %o1, %o0 3697c478bd9Sstevel@tonic-gate SET_SIZE(sfmmu_getctx_sec) 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate /* 3727c478bd9Sstevel@tonic-gate * Set the secondary context register for this process. 3731e2e7a75Shuah * %o0 = page_size | context number for this process. 3747c478bd9Sstevel@tonic-gate */ 3757c478bd9Sstevel@tonic-gate ENTRY_NP(sfmmu_setctx_sec) 3767c478bd9Sstevel@tonic-gate /* 3777c478bd9Sstevel@tonic-gate * From resume we call sfmmu_setctx_sec with interrupts disabled. 3787c478bd9Sstevel@tonic-gate * But we can also get called from C with interrupts enabled. So, 3791e2e7a75Shuah * we need to check first. 3807c478bd9Sstevel@tonic-gate */ 3817c478bd9Sstevel@tonic-gate 3827c478bd9Sstevel@tonic-gate /* If interrupts are not disabled, then disable them */ 3837c478bd9Sstevel@tonic-gate rdpr %pstate, %g1 3847c478bd9Sstevel@tonic-gate btst PSTATE_IE, %g1 3857c478bd9Sstevel@tonic-gate bnz,a,pt %icc, 1f 3867c478bd9Sstevel@tonic-gate wrpr %g1, PSTATE_IE, %pstate /* disable interrupts */ 3871e2e7a75Shuah 3887c478bd9Sstevel@tonic-gate1: 3897c478bd9Sstevel@tonic-gate mov MMU_SCONTEXT, %o1 3901e2e7a75Shuah 3917c478bd9Sstevel@tonic-gate sethi %hi(FLUSH_ADDR), %o4 3927c478bd9Sstevel@tonic-gate stxa %o0, [%o1]ASI_MMU_CTX /* set 2nd context reg. */ 3937c478bd9Sstevel@tonic-gate flush %o4 3941426d65aSsm142603 sethi %hi(shctx_on), %g3 3951426d65aSsm142603 ld [%g3 + %lo(shctx_on)], %g3 3961426d65aSsm142603 brz %g3, 2f 3971426d65aSsm142603 nop 3981426d65aSsm142603 set CTXREG_CTX_MASK, %o4 3991426d65aSsm142603 and %o0,%o4,%o1 4001426d65aSsm142603 cmp %o1, INVALID_CONTEXT 4011426d65aSsm142603 bne,pn %icc, 2f 4021426d65aSsm142603 mov MMU_SHARED_CONTEXT, %o1 4031426d65aSsm142603 sethi %hi(FLUSH_ADDR), %o4 4041426d65aSsm142603 stxa %g0, [%o1]ASI_MMU_CTX /* set 2nd context reg. */ 4051426d65aSsm142603 flush %o4 4067c478bd9Sstevel@tonic-gate 4071e2e7a75Shuah /* 4081e2e7a75Shuah * if the routine was entered with intr enabled, then enable intr now. 4091e2e7a75Shuah * otherwise, keep intr disabled, return without enabing intr. 4101e2e7a75Shuah * %g1 - old intr state 4111e2e7a75Shuah */ 4121426d65aSsm1426032: btst PSTATE_IE, %g1 4131426d65aSsm142603 bnz,a,pt %icc, 3f 4147c478bd9Sstevel@tonic-gate wrpr %g0, %g1, %pstate /* enable interrupts */ 4151426d65aSsm1426033: retl 4167c478bd9Sstevel@tonic-gate nop 4177c478bd9Sstevel@tonic-gate SET_SIZE(sfmmu_setctx_sec) 4187c478bd9Sstevel@tonic-gate 4197c478bd9Sstevel@tonic-gate /* 4207c478bd9Sstevel@tonic-gate * set ktsb_phys to 1 if the processor supports ASI_QUAD_LDD_PHYS. 4217c478bd9Sstevel@tonic-gate * returns the detection value in %o0. 42225cf1a30Sjl139090 * 42325cf1a30Sjl139090 * Currently ASI_QUAD_LDD_PHYS is supported in processors as follows 42425cf1a30Sjl139090 * - cheetah+ and later (greater or equal to CHEETAH_PLUS_IMPL) 42525cf1a30Sjl139090 * - FJ OPL Olympus-C and later (less than SPITFIRE_IMPL) 42625cf1a30Sjl139090 * 4277c478bd9Sstevel@tonic-gate */ 4287c478bd9Sstevel@tonic-gate ENTRY_NP(sfmmu_setup_4lp) 4297c478bd9Sstevel@tonic-gate GET_CPU_IMPL(%o0); 4307c478bd9Sstevel@tonic-gate cmp %o0, CHEETAH_PLUS_IMPL 43125cf1a30Sjl139090 bge,pt %icc, 4f 4327c478bd9Sstevel@tonic-gate mov 1, %o1 43325cf1a30Sjl139090 cmp %o0, SPITFIRE_IMPL 43425cf1a30Sjl139090 bge,a,pn %icc, 3f 43525cf1a30Sjl139090 clr %o1 43625cf1a30Sjl1390904: 43725cf1a30Sjl139090 set ktsb_phys, %o2 4387c478bd9Sstevel@tonic-gate st %o1, [%o2] 43925cf1a30Sjl1390903: retl 4407c478bd9Sstevel@tonic-gate mov %o1, %o0 4417c478bd9Sstevel@tonic-gate SET_SIZE(sfmmu_setup_4lp) 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate 4447c478bd9Sstevel@tonic-gate /* 4457c478bd9Sstevel@tonic-gate * Called to load MMU registers and tsbmiss area 4467c478bd9Sstevel@tonic-gate * for the active process. This function should 4477c478bd9Sstevel@tonic-gate * only be called from TL=0. 4487c478bd9Sstevel@tonic-gate * 4497c478bd9Sstevel@tonic-gate * %o0 - hat pointer 4501426d65aSsm142603 * 4517c478bd9Sstevel@tonic-gate */ 4527c478bd9Sstevel@tonic-gate ENTRY_NP(sfmmu_load_mmustate) 4531e2e7a75Shuah 4541e2e7a75Shuah#ifdef DEBUG 4551e2e7a75Shuah PANIC_IF_INTR_ENABLED_PSTR(msfmmu_ei_l3, %g1) 4561e2e7a75Shuah#endif /* DEBUG */ 4577c478bd9Sstevel@tonic-gate 4587c478bd9Sstevel@tonic-gate sethi %hi(ksfmmup), %o3 4597c478bd9Sstevel@tonic-gate ldx [%o3 + %lo(ksfmmup)], %o3 4607c478bd9Sstevel@tonic-gate cmp %o3, %o0 4611426d65aSsm142603 be,pn %xcc, 8f ! if kernel as, do nothing 4627c478bd9Sstevel@tonic-gate nop 4637c478bd9Sstevel@tonic-gate /* 4647c478bd9Sstevel@tonic-gate * We need to set up the TSB base register, tsbmiss 4657c478bd9Sstevel@tonic-gate * area, and load locked TTE(s) for the TSB. 4667c478bd9Sstevel@tonic-gate */ 4677c478bd9Sstevel@tonic-gate ldx [%o0 + SFMMU_TSB], %o1 ! %o1 = first tsbinfo 4687c478bd9Sstevel@tonic-gate ldx [%o1 + TSBINFO_NEXTPTR], %g2 ! %g2 = second tsbinfo 46925cf1a30Sjl139090 47025cf1a30Sjl139090#ifdef UTSB_PHYS 47125cf1a30Sjl139090 /* 47225cf1a30Sjl139090 * UTSB_PHYS accesses user TSBs via physical addresses. The first 4731426d65aSsm142603 * TSB is in the MMU I/D TSB Base registers. The 2nd, 3rd and 4741426d65aSsm142603 * 4th TSBs use designated ASI_SCRATCHPAD regs as pseudo TSB base regs. 47525cf1a30Sjl139090 */ 4761426d65aSsm142603 4771426d65aSsm142603 /* create/set first UTSBREG actually loaded into MMU_TSB */ 4781426d65aSsm142603 MAKE_UTSBREG(%o1, %o2, %o3) ! %o2 = first utsbreg 47925cf1a30Sjl139090 LOAD_TSBREG(%o2, %o3, %o4) ! write TSB base register 48025cf1a30Sjl139090 48125cf1a30Sjl139090 brz,a,pt %g2, 2f 48225cf1a30Sjl139090 mov -1, %o2 ! use -1 if no second TSB 48325cf1a30Sjl139090 4841426d65aSsm142603 MAKE_UTSBREG(%g2, %o2, %o3) ! %o2 = second utsbreg 48525cf1a30Sjl1390902: 4861426d65aSsm142603 SET_UTSBREG(SCRATCHPAD_UTSBREG2, %o2, %o3) 4871426d65aSsm142603 4881426d65aSsm142603 /* make 3rd and 4th TSB */ 4891426d65aSsm142603 CPU_TSBMISS_AREA(%o4, %o3) ! %o4 = tsbmiss area 4901426d65aSsm142603 4911426d65aSsm142603 ldx [%o0 + SFMMU_SCDP], %g2 ! %g2 = sfmmu_scd 4921426d65aSsm142603 brz,pt %g2, 3f 4931426d65aSsm142603 mov -1, %o2 ! use -1 if no third TSB 4941426d65aSsm142603 4951426d65aSsm142603 ldx [%g2 + SCD_SFMMUP], %g3 ! %g3 = scdp->scd_sfmmup 4961426d65aSsm142603 ldx [%g3 + SFMMU_TSB], %o1 ! %o1 = first scd tsbinfo 4971426d65aSsm142603 brz,pn %o1, 5f 4981426d65aSsm142603 nop ! panic if no third TSB 4991426d65aSsm142603 5001426d65aSsm142603 /* make 3rd UTSBREG */ 5011426d65aSsm142603 MAKE_UTSBREG(%o1, %o2, %o3) ! %o2 = third utsbreg 5021426d65aSsm1426033: 5031426d65aSsm142603 SET_UTSBREG(SCRATCHPAD_UTSBREG3, %o2, %o3) 5041426d65aSsm142603 stn %o2, [%o4 + TSBMISS_TSBSCDPTR] 5051426d65aSsm142603 5061426d65aSsm142603 brz,pt %g2, 4f 5071426d65aSsm142603 mov -1, %o2 ! use -1 if no 3rd or 4th TSB 5081426d65aSsm142603 5091426d65aSsm142603 ldx [%o1 + TSBINFO_NEXTPTR], %g2 ! %g2 = second scd tsbinfo 5101426d65aSsm142603 brz,pt %g2, 4f 5111426d65aSsm142603 mov -1, %o2 ! use -1 if no 4th TSB 5121426d65aSsm142603 5131426d65aSsm142603 /* make 4th UTSBREG */ 5141426d65aSsm142603 MAKE_UTSBREG(%g2, %o2, %o3) ! %o2 = fourth utsbreg 5151426d65aSsm1426034: 5161426d65aSsm142603 SET_UTSBREG(SCRATCHPAD_UTSBREG4, %o2, %o3) 5171426d65aSsm142603 stn %o2, [%o4 + TSBMISS_TSBSCDPTR4M] 5181426d65aSsm142603 ba,pt %icc, 6f 5191426d65aSsm142603 mov %o4, %o2 ! %o2 = tsbmiss area 5201426d65aSsm1426035: 5211426d65aSsm142603 sethi %hi(panicstr), %g1 ! panic if no 3rd TSB 5221426d65aSsm142603 ldx [%g1 + %lo(panicstr)], %g1 5231426d65aSsm142603 tst %g1 5241426d65aSsm142603 5251426d65aSsm142603 bnz,pn %xcc, 8f 5261426d65aSsm142603 nop 5271426d65aSsm142603 5281426d65aSsm142603 sethi %hi(sfmmu_panic10), %o0 5291426d65aSsm142603 call panic 5301426d65aSsm142603 or %o0, %lo(sfmmu_panic10), %o0 5311426d65aSsm142603 5321426d65aSsm142603#else /* UTSBREG_PHYS */ 5331426d65aSsm142603 5347c478bd9Sstevel@tonic-gate brz,pt %g2, 4f 5357c478bd9Sstevel@tonic-gate nop 5367c478bd9Sstevel@tonic-gate /* 5377c478bd9Sstevel@tonic-gate * We have a second TSB for this process, so we need to 5387c478bd9Sstevel@tonic-gate * encode data for both the first and second TSB in our single 5397c478bd9Sstevel@tonic-gate * TSB base register. See hat_sfmmu.h for details on what bits 5407c478bd9Sstevel@tonic-gate * correspond to which TSB. 5417c478bd9Sstevel@tonic-gate * We also need to load a locked TTE into the TLB for the second TSB 5427c478bd9Sstevel@tonic-gate * in this case. 5437c478bd9Sstevel@tonic-gate */ 5447c478bd9Sstevel@tonic-gate MAKE_TSBREG_SECTSB(%o2, %o1, %g2, %o3, %o4, %g3, sfmmu_tsb_2nd) 5457c478bd9Sstevel@tonic-gate ! %o2 = tsbreg 5467c478bd9Sstevel@tonic-gate sethi %hi(utsb4m_dtlb_ttenum), %o3 5477c478bd9Sstevel@tonic-gate sethi %hi(utsb4m_vabase), %o4 5487c478bd9Sstevel@tonic-gate ld [%o3 + %lo(utsb4m_dtlb_ttenum)], %o3 5497c478bd9Sstevel@tonic-gate ldx [%o4 + %lo(utsb4m_vabase)], %o4 ! %o4 = TLB tag for sec TSB 5507c478bd9Sstevel@tonic-gate sll %o3, DTACC_SHIFT, %o3 ! %o3 = sec TSB TLB index 5517c478bd9Sstevel@tonic-gate RESV_OFFSET(%g2, %o4, %g3, sfmmu_tsb_2nd) ! or-in bits of TSB VA 5527c478bd9Sstevel@tonic-gate LOAD_TSBTTE(%g2, %o3, %o4, %g3) ! load sec TSB locked TTE 5537c478bd9Sstevel@tonic-gate sethi %hi(utsb_vabase), %g3 5547c478bd9Sstevel@tonic-gate ldx [%g3 + %lo(utsb_vabase)], %g3 ! %g3 = TLB tag for first TSB 5557c478bd9Sstevel@tonic-gate ba,pt %xcc, 5f 5567c478bd9Sstevel@tonic-gate nop 5577c478bd9Sstevel@tonic-gate 5587c478bd9Sstevel@tonic-gate4: sethi %hi(utsb_vabase), %g3 5597c478bd9Sstevel@tonic-gate ldx [%g3 + %lo(utsb_vabase)], %g3 ! %g3 = TLB tag for first TSB 5607c478bd9Sstevel@tonic-gate MAKE_TSBREG(%o2, %o1, %g3, %o3, %o4, sfmmu_tsb_1st) ! %o2 = tsbreg 5617c478bd9Sstevel@tonic-gate 5627c478bd9Sstevel@tonic-gate5: LOAD_TSBREG(%o2, %o3, %o4) ! write TSB base register 5637c478bd9Sstevel@tonic-gate 5647c478bd9Sstevel@tonic-gate /* 5657c478bd9Sstevel@tonic-gate * Load the TTE for the first TSB at the appropriate location in 5667c478bd9Sstevel@tonic-gate * the TLB 5677c478bd9Sstevel@tonic-gate */ 5687c478bd9Sstevel@tonic-gate sethi %hi(utsb_dtlb_ttenum), %o2 5697c478bd9Sstevel@tonic-gate ld [%o2 + %lo(utsb_dtlb_ttenum)], %o2 5707c478bd9Sstevel@tonic-gate sll %o2, DTACC_SHIFT, %o2 ! %o1 = first TSB TLB index 5717c478bd9Sstevel@tonic-gate RESV_OFFSET(%o1, %g3, %o3, sfmmu_tsb_1st) ! or-in bits of TSB VA 5727c478bd9Sstevel@tonic-gate LOAD_TSBTTE(%o1, %o2, %g3, %o4) ! load first TSB locked TTE 5731426d65aSsm142603 CPU_TSBMISS_AREA(%o2, %o3) 57425cf1a30Sjl139090#endif /* UTSB_PHYS */ 5751426d65aSsm1426036: 5761426d65aSsm142603 ldx [%o0 + SFMMU_ISMBLKPA], %o1 ! copy members of sfmmu 5771426d65aSsm142603 ! we need to access from 5787c478bd9Sstevel@tonic-gate stx %o1, [%o2 + TSBMISS_ISMBLKPA] ! sfmmu_tsb_miss into the 57905d3dc4bSpaulsan ldub [%o0 + SFMMU_TTEFLAGS], %o3 ! per-CPU tsbmiss area. 5807c478bd9Sstevel@tonic-gate stx %o0, [%o2 + TSBMISS_UHATID] 58105d3dc4bSpaulsan stub %o3, [%o2 + TSBMISS_UTTEFLAGS] 5821426d65aSsm142603#ifdef UTSB_PHYS 5831426d65aSsm142603 ldx [%o0 + SFMMU_SRDP], %o1 5841426d65aSsm142603 ldub [%o0 + SFMMU_RTTEFLAGS], %o4 5851426d65aSsm142603 stub %o4, [%o2 + TSBMISS_URTTEFLAGS] 5861426d65aSsm142603 stx %o1, [%o2 + TSBMISS_SHARED_UHATID] 5871426d65aSsm142603 brz,pn %o1, 8f ! check for sfmmu_srdp 5881426d65aSsm142603 add %o0, SFMMU_HMERMAP, %o1 5891426d65aSsm142603 add %o2, TSBMISS_SHMERMAP, %o2 5901426d65aSsm142603 mov SFMMU_HMERGNMAP_WORDS, %o3 5911426d65aSsm142603 ! set tsbmiss shmermap 5921426d65aSsm142603 SET_REGION_MAP(%o1, %o2, %o3, %o4, load_shme_mmustate) 5937c478bd9Sstevel@tonic-gate 5941426d65aSsm142603 ldx [%o0 + SFMMU_SCDP], %o4 ! %o4 = sfmmu_scd 5951426d65aSsm142603 CPU_TSBMISS_AREA(%o2, %o3) ! %o2 = tsbmiss area 5961426d65aSsm142603 mov SFMMU_HMERGNMAP_WORDS, %o3 5971426d65aSsm142603 brnz,pt %o4, 7f ! check for sfmmu_scdp else 5981426d65aSsm142603 add %o2, TSBMISS_SCDSHMERMAP, %o2 ! zero tsbmiss scd_shmermap 5991426d65aSsm142603 ZERO_REGION_MAP(%o2, %o3, zero_scd_mmustate) 6001426d65aSsm142603 ba 8f 6011426d65aSsm142603 nop 6021426d65aSsm1426037: 6031426d65aSsm142603 add %o4, SCD_HMERMAP, %o1 6041426d65aSsm142603 SET_REGION_MAP(%o1, %o2, %o3, %o4, load_scd_mmustate) 6051426d65aSsm142603#endif /* UTSB_PHYS */ 6061426d65aSsm142603 6071426d65aSsm1426038: 6081426d65aSsm142603 retl 6097c478bd9Sstevel@tonic-gate nop 6107c478bd9Sstevel@tonic-gate SET_SIZE(sfmmu_load_mmustate) 6117c478bd9Sstevel@tonic-gate 6127c478bd9Sstevel@tonic-gate#endif /* lint */ 6137c478bd9Sstevel@tonic-gate 6147c478bd9Sstevel@tonic-gate#if defined (lint) 6157c478bd9Sstevel@tonic-gate/* 6167c478bd9Sstevel@tonic-gate * Invalidate all of the entries within the tsb, by setting the inv bit 6177c478bd9Sstevel@tonic-gate * in the tte_tag field of each tsbe. 6187c478bd9Sstevel@tonic-gate * 6197c478bd9Sstevel@tonic-gate * We take advantage of the fact TSBs are page aligned and a multiple of 6207c478bd9Sstevel@tonic-gate * PAGESIZE to use block stores. 6217c478bd9Sstevel@tonic-gate * 6227c478bd9Sstevel@tonic-gate * See TSB_LOCK_ENTRY and the miss handlers for how this works in practice 6237c478bd9Sstevel@tonic-gate * (in short, we set all bits in the upper word of the tag, and we give the 6247c478bd9Sstevel@tonic-gate * invalid bit precedence over other tag bits in both places). 6257c478bd9Sstevel@tonic-gate */ 6267c478bd9Sstevel@tonic-gate/* ARGSUSED */ 6277c478bd9Sstevel@tonic-gatevoid 6287c478bd9Sstevel@tonic-gatesfmmu_inv_tsb_fast(caddr_t tsb_base, uint_t tsb_bytes) 6297c478bd9Sstevel@tonic-gate{} 6307c478bd9Sstevel@tonic-gate 6317c478bd9Sstevel@tonic-gate#else /* lint */ 6327c478bd9Sstevel@tonic-gate 6337c478bd9Sstevel@tonic-gate#define VIS_BLOCKSIZE 64 6347c478bd9Sstevel@tonic-gate 6357c478bd9Sstevel@tonic-gate ENTRY(sfmmu_inv_tsb_fast) 6367c478bd9Sstevel@tonic-gate 6377c478bd9Sstevel@tonic-gate ! Get space for aligned block of saved fp regs. 6387c478bd9Sstevel@tonic-gate save %sp, -SA(MINFRAME + 2*VIS_BLOCKSIZE), %sp 6397c478bd9Sstevel@tonic-gate 6407c478bd9Sstevel@tonic-gate ! kpreempt_disable(); 6417c478bd9Sstevel@tonic-gate ldsb [THREAD_REG + T_PREEMPT], %l3 6427c478bd9Sstevel@tonic-gate inc %l3 6437c478bd9Sstevel@tonic-gate stb %l3, [THREAD_REG + T_PREEMPT] 6447c478bd9Sstevel@tonic-gate 6457c478bd9Sstevel@tonic-gate ! See if fpu was in use. If it was, we need to save off the 6467c478bd9Sstevel@tonic-gate ! floating point registers to the stack. 6477c478bd9Sstevel@tonic-gate rd %fprs, %l0 ! %l0 = cached copy of fprs 6487c478bd9Sstevel@tonic-gate btst FPRS_FEF, %l0 6497c478bd9Sstevel@tonic-gate bz,pt %icc, 4f 6507c478bd9Sstevel@tonic-gate nop 6517c478bd9Sstevel@tonic-gate 6527c478bd9Sstevel@tonic-gate ! save in-use fpregs on stack 6537c478bd9Sstevel@tonic-gate membar #Sync ! make sure tranx to fp regs 6547c478bd9Sstevel@tonic-gate ! have completed 6557c478bd9Sstevel@tonic-gate add %fp, STACK_BIAS - 65, %l1 ! get stack frame for fp regs 6567c478bd9Sstevel@tonic-gate and %l1, -VIS_BLOCKSIZE, %l1 ! block align frame 6577c478bd9Sstevel@tonic-gate stda %d0, [%l1]ASI_BLK_P ! %l1 = addr of saved fp regs 6587c478bd9Sstevel@tonic-gate 6597c478bd9Sstevel@tonic-gate ! enable fp 6607c478bd9Sstevel@tonic-gate4: membar #StoreStore|#StoreLoad|#LoadStore 6617c478bd9Sstevel@tonic-gate wr %g0, FPRS_FEF, %fprs 6627c478bd9Sstevel@tonic-gate wr %g0, ASI_BLK_P, %asi 6637c478bd9Sstevel@tonic-gate 6647c478bd9Sstevel@tonic-gate ! load up FP registers with invalid TSB tag. 6657c478bd9Sstevel@tonic-gate fone %d0 ! ones in tag 6667c478bd9Sstevel@tonic-gate fzero %d2 ! zeros in TTE 6677c478bd9Sstevel@tonic-gate fone %d4 ! ones in tag 6687c478bd9Sstevel@tonic-gate fzero %d6 ! zeros in TTE 6697c478bd9Sstevel@tonic-gate fone %d8 ! ones in tag 6707c478bd9Sstevel@tonic-gate fzero %d10 ! zeros in TTE 6717c478bd9Sstevel@tonic-gate fone %d12 ! ones in tag 6727c478bd9Sstevel@tonic-gate fzero %d14 ! zeros in TTE 6737c478bd9Sstevel@tonic-gate ba,pt %xcc, .sfmmu_inv_doblock 6747c478bd9Sstevel@tonic-gate mov (4*VIS_BLOCKSIZE), %i4 ! we do 4 stda's each loop below 6757c478bd9Sstevel@tonic-gate 6767c478bd9Sstevel@tonic-gate.sfmmu_inv_blkstart: 6777c478bd9Sstevel@tonic-gate ! stda %d0, [%i0+192]%asi ! in dly slot of branch that got us here 6787c478bd9Sstevel@tonic-gate stda %d0, [%i0+128]%asi 6797c478bd9Sstevel@tonic-gate stda %d0, [%i0+64]%asi 6807c478bd9Sstevel@tonic-gate stda %d0, [%i0]%asi 6817c478bd9Sstevel@tonic-gate 6827c478bd9Sstevel@tonic-gate add %i0, %i4, %i0 6837c478bd9Sstevel@tonic-gate sub %i1, %i4, %i1 6847c478bd9Sstevel@tonic-gate 6857c478bd9Sstevel@tonic-gate.sfmmu_inv_doblock: 6867c478bd9Sstevel@tonic-gate cmp %i1, (4*VIS_BLOCKSIZE) ! check for completion 6877c478bd9Sstevel@tonic-gate bgeu,a %icc, .sfmmu_inv_blkstart 6887c478bd9Sstevel@tonic-gate stda %d0, [%i0+192]%asi 6897c478bd9Sstevel@tonic-gate 6907c478bd9Sstevel@tonic-gate.sfmmu_inv_finish: 6917c478bd9Sstevel@tonic-gate membar #Sync 6927c478bd9Sstevel@tonic-gate btst FPRS_FEF, %l0 ! saved from above 6937c478bd9Sstevel@tonic-gate bz,a .sfmmu_inv_finished 6947c478bd9Sstevel@tonic-gate wr %l0, 0, %fprs ! restore fprs 6957c478bd9Sstevel@tonic-gate 6967c478bd9Sstevel@tonic-gate ! restore fpregs from stack 6977c478bd9Sstevel@tonic-gate ldda [%l1]ASI_BLK_P, %d0 6987c478bd9Sstevel@tonic-gate membar #Sync 6997c478bd9Sstevel@tonic-gate wr %l0, 0, %fprs ! restore fprs 7007c478bd9Sstevel@tonic-gate 7017c478bd9Sstevel@tonic-gate.sfmmu_inv_finished: 7027c478bd9Sstevel@tonic-gate ! kpreempt_enable(); 7037c478bd9Sstevel@tonic-gate ldsb [THREAD_REG + T_PREEMPT], %l3 7047c478bd9Sstevel@tonic-gate dec %l3 7057c478bd9Sstevel@tonic-gate stb %l3, [THREAD_REG + T_PREEMPT] 7067c478bd9Sstevel@tonic-gate ret 7077c478bd9Sstevel@tonic-gate restore 7087c478bd9Sstevel@tonic-gate SET_SIZE(sfmmu_inv_tsb_fast) 7097c478bd9Sstevel@tonic-gate 7107c478bd9Sstevel@tonic-gate#endif /* lint */ 7117c478bd9Sstevel@tonic-gate 7127c478bd9Sstevel@tonic-gate#if defined(lint) 7137c478bd9Sstevel@tonic-gate 7147c478bd9Sstevel@tonic-gate/* 7157c478bd9Sstevel@tonic-gate * Prefetch "struct tsbe" while walking TSBs. 7167c478bd9Sstevel@tonic-gate * prefetch 7 cache lines ahead of where we are at now. 7177c478bd9Sstevel@tonic-gate * #n_reads is being used since #one_read only applies to 7187c478bd9Sstevel@tonic-gate * floating point reads, and we are not doing floating point 7197c478bd9Sstevel@tonic-gate * reads. However, this has the negative side effect of polluting 7207c478bd9Sstevel@tonic-gate * the ecache. 7217c478bd9Sstevel@tonic-gate * The 448 comes from (7 * 64) which is how far ahead of our current 7227c478bd9Sstevel@tonic-gate * address, we want to prefetch. 7237c478bd9Sstevel@tonic-gate */ 7247c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 7257c478bd9Sstevel@tonic-gatevoid 7267c478bd9Sstevel@tonic-gateprefetch_tsbe_read(struct tsbe *tsbep) 7277c478bd9Sstevel@tonic-gate{} 7287c478bd9Sstevel@tonic-gate 7297c478bd9Sstevel@tonic-gate/* Prefetch the tsbe that we are about to write */ 7307c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 7317c478bd9Sstevel@tonic-gatevoid 7327c478bd9Sstevel@tonic-gateprefetch_tsbe_write(struct tsbe *tsbep) 7337c478bd9Sstevel@tonic-gate{} 7347c478bd9Sstevel@tonic-gate 7357c478bd9Sstevel@tonic-gate#else /* lint */ 7367c478bd9Sstevel@tonic-gate 7377c478bd9Sstevel@tonic-gate ENTRY(prefetch_tsbe_read) 7387c478bd9Sstevel@tonic-gate retl 7397c478bd9Sstevel@tonic-gate prefetch [%o0+448], #n_reads 7407c478bd9Sstevel@tonic-gate SET_SIZE(prefetch_tsbe_read) 7417c478bd9Sstevel@tonic-gate 7427c478bd9Sstevel@tonic-gate ENTRY(prefetch_tsbe_write) 7437c478bd9Sstevel@tonic-gate retl 7447c478bd9Sstevel@tonic-gate prefetch [%o0], #n_writes 7457c478bd9Sstevel@tonic-gate SET_SIZE(prefetch_tsbe_write) 7467c478bd9Sstevel@tonic-gate#endif /* lint */ 7477c478bd9Sstevel@tonic-gate 748