2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License, Version 1.0 only 2N/A * (the "License"). You may not use this file except in compliance 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 2N/A * Use is subject to license terms. 2N/A#
pragma ident "%Z%%M% %I% %E% SMI" 2N/A * Spill fault handlers 2N/A * sn0 - spill normal tl 0 2N/A * sn1 - spill normal tl >0 2N/A * so0 - spill other tl 0 2N/A * so1 - spill other tl >0 ! We handle it by spilling the window to the wbuf and trying ! spill the window into wbuf slot 0 ! (we know wbuf is empty since we came from user mode) ENTRY_NP(fault_32bit_sn1) FAULT_WINTRACE(%g5, %g6, %g7, TT_F32_SN1) ldxa [%g5 + CPU_MPCB_PA]%asi, %g6 ldxa [%g6 + MPCB_WBUF_PA]%asi, %g5 stna %sp, [%g6 + MPCB_SPBUF]%asi sta %g5, [%g6 + MPCB_WBCNT]%asi SET_SIZE(fault_32bit_sn1) ENTRY_NP(fault_32bit_so0) FAULT_WINTRACE(%g5, %g6, %g1, TT_F32_SO0) ! This happens when the kernel spills a user window and that ! find lwp & increment wbcnt ldn [%g5 + CPU_MPCB], %g1 ld [%g1 + MPCB_WBCNT], %g2 st %g3, [%g1 + MPCB_WBCNT] ! use previous wbcnt to spill new spbuf & wbuf sll %g2, CPTRSHIFT, %g4 ! spbuf size is sizeof (caddr_t) sll %g2, RWIN32SHIFT, %g4 ldn [%g1 + MPCB_WBUF], %g3 SET_SIZE(fault_32bit_so0) ! This happens when priv_trap spills a user window and that ! We handle it by spilling the window to the wbuf and trying ! spill the window into wbuf slot 0 ! (we know wbuf is empty since we came from user mode) ENTRY_NP(fault_64bit_sn1) FAULT_WINTRACE(%g5, %g6, %g7, TT_F64_SN1) ldxa [%g5 + CPU_MPCB_PA]%asi, %g6 ldxa [%g6 + MPCB_WBUF_PA]%asi, %g5 stna %sp, [%g6 + MPCB_SPBUF]%asi sta %g5, [%g6 + MPCB_WBCNT]%asi SET_SIZE(fault_64bit_sn1) ! Spill normal kernel tl1. ! spill the kernel window into kwbuf FAULT_WINTRACE(%g5, %g6, %g7, TT_F32_NT1) lda [%g5 + MCPU_KWBUF_FULL]%asi, %g7 bnz,a,pn %icc, ptl1_panic sta %g6, [%g5 + MCPU_KWBUF_FULL]%asi ! Spill normal kernel tl1. ! spill the kernel window into kwbuf FAULT_WINTRACE(%g5, %g6, %g7, TT_F64_NT1) lda [%g5 + MCPU_KWBUF_FULL]%asi, %g7 bnz,a,pn %icc, ptl1_panic sta %g6, [%g5 + MCPU_KWBUF_FULL]%asi ENTRY_NP(fault_64bit_so0) FAULT_WINTRACE(%g5, %g6, %g1, TT_F64_SO0) ! This happens when the kernel spills a user window and that ! find lwp & increment wbcnt ldn [%g5 + CPU_MPCB], %g1 ld [%g1 + MPCB_WBCNT], %g2 st %g3, [%g1 + MPCB_WBCNT] ! use previous wbcnt to spill new spbuf & wbuf sll %g2, CPTRSHIFT, %g4 ! spbuf size is sizeof (caddr_t) sll %g2, RWIN64SHIFT, %g4 ldn [%g1 + MPCB_WBUF], %g3 SET_SIZE(fault_64bit_so0) ! This happens when priv_trap spills a user window and that ! misaligned stack. We handle an unmapped stack by simulating ! a pagefault at user_rtt and a misaligned stack by generating ! save fault addr & fix %cwp ! fake tl1 traps regs so that after pagefault runs, we ! re-execute at user_rtt. set TSTATE_KERN | TSTATE_IE, %g1 ! g5 = mmu trap type, g6 = tag access reg (g5 != T_ALIGNMENT) or ! sfar (g5 == T_ALIGNMENT) set sfmmu_tsbmiss_exception, %g1 mov %g6, %g2 ! arg2 = tagaccess set T_USER | T_SYS_RTT_PAGE, %g3 ! arg3 = traptype set T_USER | T_SYS_RTT_ALIGN, %g3 ! setup to run kernel again by setting THREAD_REG, %wstate ! and the mmu to their kernel values. ! sun4v cannot safely lower %gl then raise it again ! so ktl0 must restore THREAD_REG sllx %l1, WSTATE_SHIFT, %l1 wrpr %l1, WSTATE_K64, %wstate stxa %g5, [%g6]ASI_MMU_CTX SET_SIZE(fault_32bit_fn1) ENTRY_NP(fault_64bit_fn0) FAULT_WINTRACE(%g1, %g2, %g3, TT_F64_FN0) SET_SIZE(fault_64bit_fn0) ENTRY_NP(fault_64bit_fn1) FAULT_WINTRACE(%g1, %g2, %g3, TT_F64_FN1) SET_SIZE(fault_64bit_fn1) FAULT_WINTRACE(%g1, %g2, %g3, TT_RTT_FN1) ENTRY_NP(fault_32bit_not) ENTRY_NP(fault_64bit_not) SET_SIZE(fault_32bit_not) SET_SIZE(fault_64bit_not)