1*5d9d9091SRichard Lowe/* 2*5d9d9091SRichard Lowe * CDDL HEADER START 3*5d9d9091SRichard Lowe * 4*5d9d9091SRichard Lowe * The contents of this file are subject to the terms of the 5*5d9d9091SRichard Lowe * Common Development and Distribution License (the "License"). 6*5d9d9091SRichard Lowe * You may not use this file except in compliance with the License. 7*5d9d9091SRichard Lowe * 8*5d9d9091SRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5d9d9091SRichard Lowe * or http://www.opensolaris.org/os/licensing. 10*5d9d9091SRichard Lowe * See the License for the specific language governing permissions 11*5d9d9091SRichard Lowe * and limitations under the License. 12*5d9d9091SRichard Lowe * 13*5d9d9091SRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each 14*5d9d9091SRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5d9d9091SRichard Lowe * If applicable, add the following below this CDDL HEADER, with the 16*5d9d9091SRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying 17*5d9d9091SRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner] 18*5d9d9091SRichard Lowe * 19*5d9d9091SRichard Lowe * CDDL HEADER END 20*5d9d9091SRichard Lowe */ 21*5d9d9091SRichard Lowe/* 22*5d9d9091SRichard Lowe * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23*5d9d9091SRichard Lowe * Use is subject to license terms. 24*5d9d9091SRichard Lowe */ 25*5d9d9091SRichard Lowe 26*5d9d9091SRichard Lowe#include <sys/asm_linkage.h> 27*5d9d9091SRichard Lowe#include <sys/machthread.h> 28*5d9d9091SRichard Lowe#include <sys/privregs.h> 29*5d9d9091SRichard Lowe#include <sys/machasi.h> 30*5d9d9091SRichard Lowe#include <sys/trap.h> 31*5d9d9091SRichard Lowe#include <sys/mmu.h> 32*5d9d9091SRichard Lowe#include <sys/machparam.h> 33*5d9d9091SRichard Lowe#include <sys/machtrap.h> 34*5d9d9091SRichard Lowe#include <sys/traptrace.h> 35*5d9d9091SRichard Lowe 36*5d9d9091SRichard Lowe#include "assym.h" 37*5d9d9091SRichard Lowe 38*5d9d9091SRichard Lowe /* 39*5d9d9091SRichard Lowe * Spill fault handlers 40*5d9d9091SRichard Lowe * sn0 - spill normal tl 0 41*5d9d9091SRichard Lowe * sn1 - spill normal tl >0 42*5d9d9091SRichard Lowe * so0 - spill other tl 0 43*5d9d9091SRichard Lowe * so1 - spill other tl >0 44*5d9d9091SRichard Lowe */ 45*5d9d9091SRichard Lowe 46*5d9d9091SRichard Lowe ENTRY_NP(fault_32bit_sn0) 47*5d9d9091SRichard Lowe ! 48*5d9d9091SRichard Lowe FAULT_WINTRACE(%g1, %g2, %g3, TT_F32_SN0) 49*5d9d9091SRichard Lowe ! 50*5d9d9091SRichard Lowe ! Spill normal tl0 fault. 51*5d9d9091SRichard Lowe ! This happens when a user tries to spill to an unmapped or 52*5d9d9091SRichard Lowe ! misaligned stack. We handle an unmapped stack by simulating 53*5d9d9091SRichard Lowe ! a pagefault at the trap pc and a misaligned stack by generating 54*5d9d9091SRichard Lowe ! a user alignment trap. 55*5d9d9091SRichard Lowe ! 56*5d9d9091SRichard Lowe ! spill the window into wbuf slot 0 57*5d9d9091SRichard Lowe ! (we know wbuf is empty since we came from user mode) 58*5d9d9091SRichard Lowe ! 59*5d9d9091SRichard Lowe ! g5 = mmu trap type, g6 = tag access reg (g5 != T_ALIGNMENT) or 60*5d9d9091SRichard Lowe ! sfar (g5 == T_ALIGNMENT) 61*5d9d9091SRichard Lowe ! 62*5d9d9091SRichard Lowe CPU_ADDR(%g4, %g1) 63*5d9d9091SRichard Lowe ldn [%g4 + CPU_MPCB], %g1 64*5d9d9091SRichard Lowe stn %sp, [%g1 + MPCB_SPBUF] 65*5d9d9091SRichard Lowe ldn [%g1 + MPCB_WBUF], %g2 66*5d9d9091SRichard Lowe SAVE_V8WINDOW(%g2) 67*5d9d9091SRichard Lowe mov 1, %g2 68*5d9d9091SRichard Lowe st %g2, [%g1 + MPCB_WBCNT] 69*5d9d9091SRichard Lowe saved 70*5d9d9091SRichard Lowe ! 71*5d9d9091SRichard Lowe ! setup user_trap args 72*5d9d9091SRichard Lowe ! 73*5d9d9091SRichard Lowe set sfmmu_tsbmiss_exception, %g1 74*5d9d9091SRichard Lowe mov %g6, %g2 ! arg2 = tagaccess 75*5d9d9091SRichard Lowe mov T_WIN_OVERFLOW, %g3 ! arg3 = traptype 76*5d9d9091SRichard Lowe cmp %g5, T_ALIGNMENT 77*5d9d9091SRichard Lowe bne %icc, 1f 78*5d9d9091SRichard Lowe nop 79*5d9d9091SRichard Lowe set trap, %g1 80*5d9d9091SRichard Lowe mov T_ALIGNMENT, %g3 81*5d9d9091SRichard Lowe1: 82*5d9d9091SRichard Lowe sub %g0, 1, %g4 83*5d9d9091SRichard Lowe ! 84*5d9d9091SRichard Lowe ! spill traps increment %cwp by 2, 85*5d9d9091SRichard Lowe ! but user_trap wants the trap %cwp 86*5d9d9091SRichard Lowe ! 87*5d9d9091SRichard Lowe rdpr %tstate, %g5 88*5d9d9091SRichard Lowe and %g5, TSTATE_CWP, %g5 89*5d9d9091SRichard Lowe ba,pt %xcc, user_trap 90*5d9d9091SRichard Lowe wrpr %g0, %g5, %cwp 91*5d9d9091SRichard Lowe SET_SIZE(fault_32bit_sn0) 92*5d9d9091SRichard Lowe 93*5d9d9091SRichard Lowe ! 94*5d9d9091SRichard Lowe ! Spill normal tl1 fault. 95*5d9d9091SRichard Lowe ! This happens when sys_trap's save spills to an unmapped stack. 96*5d9d9091SRichard Lowe ! We handle it by spilling the window to the wbuf and trying 97*5d9d9091SRichard Lowe ! sys_trap again. 98*5d9d9091SRichard Lowe ! 99*5d9d9091SRichard Lowe ! spill the window into wbuf slot 0 100*5d9d9091SRichard Lowe ! (we know wbuf is empty since we came from user mode) 101*5d9d9091SRichard Lowe ! 102*5d9d9091SRichard Lowe ENTRY_NP(fault_32bit_sn1) 103*5d9d9091SRichard Lowe FAULT_WINTRACE(%g5, %g6, %g7, TT_F32_SN1) 104*5d9d9091SRichard Lowe CPU_ADDR(%g5, %g6) 105*5d9d9091SRichard Lowe ldn [%g5 + CPU_MPCB], %g6 106*5d9d9091SRichard Lowe stn %sp, [%g6 + MPCB_SPBUF] 107*5d9d9091SRichard Lowe ldn [%g6 + MPCB_WBUF], %g5 108*5d9d9091SRichard Lowe SAVE_V8WINDOW(%g5) 109*5d9d9091SRichard Lowe mov 1, %g5 110*5d9d9091SRichard Lowe st %g5, [%g6 + MPCB_WBCNT] 111*5d9d9091SRichard Lowe saved 112*5d9d9091SRichard Lowe set sys_trap, %g5 113*5d9d9091SRichard Lowe wrpr %g5, %tnpc 114*5d9d9091SRichard Lowe done 115*5d9d9091SRichard Lowe SET_SIZE(fault_32bit_sn1) 116*5d9d9091SRichard Lowe 117*5d9d9091SRichard Lowe ENTRY_NP(fault_32bit_so0) 118*5d9d9091SRichard Lowe ! 119*5d9d9091SRichard Lowe FAULT_WINTRACE(%g5, %g6, %g1, TT_F32_SO0) 120*5d9d9091SRichard Lowe ! 121*5d9d9091SRichard Lowe ! Spill other tl0 fault. 122*5d9d9091SRichard Lowe ! This happens when the kernel spills a user window and that 123*5d9d9091SRichard Lowe ! user's stack has been unmapped. 124*5d9d9091SRichard Lowe ! We handle it by spilling the window into the user's wbuf. 125*5d9d9091SRichard Lowe ! 126*5d9d9091SRichard Lowe ! find lwp & increment wbcnt 127*5d9d9091SRichard Lowe ! 128*5d9d9091SRichard Lowe CPU_ADDR(%g5, %g6) 129*5d9d9091SRichard Lowe ldn [%g5 + CPU_MPCB], %g1 130*5d9d9091SRichard Lowe ld [%g1 + MPCB_WBCNT], %g2 131*5d9d9091SRichard Lowe add %g2, 1, %g3 132*5d9d9091SRichard Lowe st %g3, [%g1 + MPCB_WBCNT] 133*5d9d9091SRichard Lowe ! 134*5d9d9091SRichard Lowe ! use previous wbcnt to spill new spbuf & wbuf 135*5d9d9091SRichard Lowe ! 136*5d9d9091SRichard Lowe sll %g2, CPTRSHIFT, %g4 ! spbuf size is sizeof (caddr_t) 137*5d9d9091SRichard Lowe add %g1, MPCB_SPBUF, %g3 138*5d9d9091SRichard Lowe stn %sp, [%g3 + %g4] 139*5d9d9091SRichard Lowe sll %g2, RWIN32SHIFT, %g4 140*5d9d9091SRichard Lowe ldn [%g1 + MPCB_WBUF], %g3 141*5d9d9091SRichard Lowe add %g3, %g4, %g3 142*5d9d9091SRichard Lowe SAVE_V8WINDOW(%g3) 143*5d9d9091SRichard Lowe saved 144*5d9d9091SRichard Lowe retry 145*5d9d9091SRichard Lowe SET_SIZE(fault_32bit_so0) 146*5d9d9091SRichard Lowe 147*5d9d9091SRichard Lowe ! 148*5d9d9091SRichard Lowe ! Spill other tl1 fault. 149*5d9d9091SRichard Lowe ! This happens when priv_trap spills a user window and that 150*5d9d9091SRichard Lowe ! user's stack has been unmapped. 151*5d9d9091SRichard Lowe ! We handle it by spilling the window to the wbuf and retrying 152*5d9d9091SRichard Lowe ! the save. 153*5d9d9091SRichard Lowe ! 154*5d9d9091SRichard Lowe ENTRY_NP(fault_32bit_so1) 155*5d9d9091SRichard Lowe FAULT_WINTRACE(%g5, %g6, %g7, TT_F32_SO1) 156*5d9d9091SRichard Lowe CPU_ADDR(%g5, %g6) 157*5d9d9091SRichard Lowe ! 158*5d9d9091SRichard Lowe ! find lwp & increment wbcnt 159*5d9d9091SRichard Lowe ! 160*5d9d9091SRichard Lowe ldn [%g5 + CPU_MPCB], %g6 161*5d9d9091SRichard Lowe ld [%g6 + MPCB_WBCNT], %g5 162*5d9d9091SRichard Lowe add %g5, 1, %g7 163*5d9d9091SRichard Lowe st %g7, [%g6 + MPCB_WBCNT] 164*5d9d9091SRichard Lowe ! 165*5d9d9091SRichard Lowe ! use previous wbcnt to spill new spbuf & wbuf 166*5d9d9091SRichard Lowe ! 167*5d9d9091SRichard Lowe sll %g5, CPTRSHIFT, %g7 ! spbuf size is sizeof (caddr_t) 168*5d9d9091SRichard Lowe add %g6, %g7, %g7 169*5d9d9091SRichard Lowe stn %sp, [%g7 + MPCB_SPBUF] 170*5d9d9091SRichard Lowe sll %g5, RWIN32SHIFT, %g7 171*5d9d9091SRichard Lowe ldn [%g6 + MPCB_WBUF], %g5 172*5d9d9091SRichard Lowe add %g5, %g7, %g7 173*5d9d9091SRichard Lowe SAVE_V8WINDOW(%g7) 174*5d9d9091SRichard Lowe saved 175*5d9d9091SRichard Lowe set sys_trap, %g5 176*5d9d9091SRichard Lowe wrpr %g5, %tnpc 177*5d9d9091SRichard Lowe done 178*5d9d9091SRichard Lowe SET_SIZE(fault_32bit_so1) 179*5d9d9091SRichard Lowe 180*5d9d9091SRichard Lowe ENTRY_NP(fault_64bit_sn0) 181*5d9d9091SRichard Lowe ! 182*5d9d9091SRichard Lowe FAULT_WINTRACE(%g1, %g2, %g3, TT_F64_SN0) 183*5d9d9091SRichard Lowe ! 184*5d9d9091SRichard Lowe ! Spill normal tl0 fault. 185*5d9d9091SRichard Lowe ! This happens when a user tries to spill to an unmapped or 186*5d9d9091SRichard Lowe ! misaligned stack. We handle an unmapped stack by simulating 187*5d9d9091SRichard Lowe ! a pagefault at the trap pc and a misaligned stack by generating 188*5d9d9091SRichard Lowe ! a user alignment trap. 189*5d9d9091SRichard Lowe ! 190*5d9d9091SRichard Lowe ! spill the window into wbuf slot 0 191*5d9d9091SRichard Lowe ! (we know wbuf is empty since we came from user mode) 192*5d9d9091SRichard Lowe ! 193*5d9d9091SRichard Lowe ! g5 = mmu trap type, g6 = tag access reg (g5 != T_ALIGNMENT) or 194*5d9d9091SRichard Lowe ! sfar (g5 == T_ALIGNMENT) 195*5d9d9091SRichard Lowe ! 196*5d9d9091SRichard Lowe CPU_ADDR(%g4, %g1) 197*5d9d9091SRichard Lowe ldn [%g4 + CPU_MPCB], %g1 198*5d9d9091SRichard Lowe stn %sp, [%g1 + MPCB_SPBUF] 199*5d9d9091SRichard Lowe ldn [%g1 + MPCB_WBUF], %g2 200*5d9d9091SRichard Lowe SAVE_V9WINDOW(%g2) 201*5d9d9091SRichard Lowe mov 1, %g2 202*5d9d9091SRichard Lowe st %g2, [%g1 + MPCB_WBCNT] 203*5d9d9091SRichard Lowe saved 204*5d9d9091SRichard Lowe ! 205*5d9d9091SRichard Lowe ! setup user_trap args 206*5d9d9091SRichard Lowe ! 207*5d9d9091SRichard Lowe set sfmmu_tsbmiss_exception, %g1 208*5d9d9091SRichard Lowe mov %g6, %g2 ! arg2 = tagaccess 209*5d9d9091SRichard Lowe mov %g5, %g3 ! arg3 = traptype 210*5d9d9091SRichard Lowe cmp %g5, T_ALIGNMENT 211*5d9d9091SRichard Lowe bne %icc, 1f 212*5d9d9091SRichard Lowe nop 213*5d9d9091SRichard Lowe set trap, %g1 214*5d9d9091SRichard Lowe mov T_ALIGNMENT, %g3 215*5d9d9091SRichard Lowe1: 216*5d9d9091SRichard Lowe sub %g0, 1, %g4 217*5d9d9091SRichard Lowe ! 218*5d9d9091SRichard Lowe ! spill traps increment %cwp by 2, 219*5d9d9091SRichard Lowe ! but user_trap wants the trap %cwp 220*5d9d9091SRichard Lowe ! 221*5d9d9091SRichard Lowe rdpr %tstate, %g5 222*5d9d9091SRichard Lowe and %g5, TSTATE_CWP, %g5 223*5d9d9091SRichard Lowe ba,pt %xcc, user_trap 224*5d9d9091SRichard Lowe wrpr %g0, %g5, %cwp 225*5d9d9091SRichard Lowe SET_SIZE(fault_64bit_sn0) 226*5d9d9091SRichard Lowe 227*5d9d9091SRichard Lowe ! 228*5d9d9091SRichard Lowe ! Spill normal tl1 fault. 229*5d9d9091SRichard Lowe ! This happens when sys_trap's save spills to an unmapped stack. 230*5d9d9091SRichard Lowe ! We handle it by spilling the window to the wbuf and trying 231*5d9d9091SRichard Lowe ! sys_trap again. 232*5d9d9091SRichard Lowe ! 233*5d9d9091SRichard Lowe ! spill the window into wbuf slot 0 234*5d9d9091SRichard Lowe ! (we know wbuf is empty since we came from user mode) 235*5d9d9091SRichard Lowe ! 236*5d9d9091SRichard Lowe ENTRY_NP(fault_64bit_sn1) 237*5d9d9091SRichard Lowe FAULT_WINTRACE(%g5, %g6, %g7, TT_F64_SN1) 238*5d9d9091SRichard Lowe CPU_ADDR(%g5, %g6) 239*5d9d9091SRichard Lowe ldn [%g5 + CPU_MPCB], %g6 240*5d9d9091SRichard Lowe stn %sp, [%g6 + MPCB_SPBUF] 241*5d9d9091SRichard Lowe ldn [%g6 + MPCB_WBUF], %g5 242*5d9d9091SRichard Lowe SAVE_V9WINDOW(%g5) 243*5d9d9091SRichard Lowe mov 1, %g5 244*5d9d9091SRichard Lowe st %g5, [%g6 + MPCB_WBCNT] 245*5d9d9091SRichard Lowe saved 246*5d9d9091SRichard Lowe set sys_trap, %g5 247*5d9d9091SRichard Lowe wrpr %g5, %tnpc 248*5d9d9091SRichard Lowe done 249*5d9d9091SRichard Lowe SET_SIZE(fault_64bit_sn1) 250*5d9d9091SRichard Lowe 251*5d9d9091SRichard Lowe ENTRY_NP(fault_64bit_so0) 252*5d9d9091SRichard Lowe ! 253*5d9d9091SRichard Lowe FAULT_WINTRACE(%g5, %g6, %g1, TT_F64_SO0) 254*5d9d9091SRichard Lowe ! 255*5d9d9091SRichard Lowe ! Spill other tl0 fault. 256*5d9d9091SRichard Lowe ! This happens when the kernel spills a user window and that 257*5d9d9091SRichard Lowe ! user's stack has been unmapped. 258*5d9d9091SRichard Lowe ! We handle it by spilling the window into the user's wbuf. 259*5d9d9091SRichard Lowe ! 260*5d9d9091SRichard Lowe ! find lwp & increment wbcnt 261*5d9d9091SRichard Lowe ! 262*5d9d9091SRichard Lowe CPU_ADDR(%g5, %g6) 263*5d9d9091SRichard Lowe ldn [%g5 + CPU_MPCB], %g1 264*5d9d9091SRichard Lowe ld [%g1 + MPCB_WBCNT], %g2 265*5d9d9091SRichard Lowe add %g2, 1, %g3 266*5d9d9091SRichard Lowe st %g3, [%g1 + MPCB_WBCNT] 267*5d9d9091SRichard Lowe ! 268*5d9d9091SRichard Lowe ! use previous wbcnt to spill new spbuf & wbuf 269*5d9d9091SRichard Lowe ! 270*5d9d9091SRichard Lowe sll %g2, CPTRSHIFT, %g4 ! spbuf size is sizeof (caddr_t) 271*5d9d9091SRichard Lowe add %g1, MPCB_SPBUF, %g3 272*5d9d9091SRichard Lowe stn %sp, [%g3 + %g4] 273*5d9d9091SRichard Lowe sll %g2, RWIN64SHIFT, %g4 274*5d9d9091SRichard Lowe ldn [%g1 + MPCB_WBUF], %g3 275*5d9d9091SRichard Lowe add %g3, %g4, %g3 276*5d9d9091SRichard Lowe SAVE_V9WINDOW(%g3) 277*5d9d9091SRichard Lowe saved 278*5d9d9091SRichard Lowe retry 279*5d9d9091SRichard Lowe SET_SIZE(fault_64bit_so0) 280*5d9d9091SRichard Lowe 281*5d9d9091SRichard Lowe ! 282*5d9d9091SRichard Lowe ! Spill other tl1 fault. 283*5d9d9091SRichard Lowe ! This happens when priv_trap spills a user window and that 284*5d9d9091SRichard Lowe ! user's stack has been unmapped. 285*5d9d9091SRichard Lowe ! We handle it by spilling the window to the wbuf and retrying 286*5d9d9091SRichard Lowe ! the save. 287*5d9d9091SRichard Lowe ! 288*5d9d9091SRichard Lowe ENTRY_NP(fault_64bit_so1) 289*5d9d9091SRichard Lowe FAULT_WINTRACE(%g5, %g6, %g7, TT_F64_SO1) 290*5d9d9091SRichard Lowe CPU_ADDR(%g5, %g6) 291*5d9d9091SRichard Lowe ! 292*5d9d9091SRichard Lowe ! find lwp & increment wbcnt 293*5d9d9091SRichard Lowe ! 294*5d9d9091SRichard Lowe ldn [%g5 + CPU_MPCB], %g6 295*5d9d9091SRichard Lowe ld [%g6 + MPCB_WBCNT], %g5 296*5d9d9091SRichard Lowe add %g5, 1, %g7 297*5d9d9091SRichard Lowe st %g7, [%g6 + MPCB_WBCNT] 298*5d9d9091SRichard Lowe ! 299*5d9d9091SRichard Lowe ! use previous wbcnt to spill new spbuf & wbuf 300*5d9d9091SRichard Lowe ! 301*5d9d9091SRichard Lowe sll %g5, CPTRSHIFT, %g7 ! spbuf size is sizeof (caddr_t) 302*5d9d9091SRichard Lowe add %g6, %g7, %g7 303*5d9d9091SRichard Lowe stn %sp, [%g7 + MPCB_SPBUF] 304*5d9d9091SRichard Lowe sll %g5, RWIN64SHIFT, %g7 305*5d9d9091SRichard Lowe ldn [%g6 + MPCB_WBUF], %g5 306*5d9d9091SRichard Lowe add %g5, %g7, %g7 307*5d9d9091SRichard Lowe SAVE_V9WINDOW(%g7) 308*5d9d9091SRichard Lowe saved 309*5d9d9091SRichard Lowe set sys_trap, %g5 310*5d9d9091SRichard Lowe wrpr %g5, %tnpc 311*5d9d9091SRichard Lowe done 312*5d9d9091SRichard Lowe SET_SIZE(fault_64bit_so1) 313*5d9d9091SRichard Lowe 314*5d9d9091SRichard Lowe /* 315*5d9d9091SRichard Lowe * Fill fault handlers 316*5d9d9091SRichard Lowe * fn0 - fill normal tl 0 317*5d9d9091SRichard Lowe * fn1 - fill normal tl 1 318*5d9d9091SRichard Lowe */ 319*5d9d9091SRichard Lowe 320*5d9d9091SRichard Lowe ENTRY_NP(fault_32bit_fn0) 321*5d9d9091SRichard Lowe ! 322*5d9d9091SRichard Lowe FAULT_WINTRACE(%g1, %g2, %g3, TT_F32_FN0) 323*5d9d9091SRichard Lowe ! 324*5d9d9091SRichard Lowe.fault_fn0_common: 325*5d9d9091SRichard Lowe ! 326*5d9d9091SRichard Lowe ! Fill normal tl0 fault. 327*5d9d9091SRichard Lowe ! This happens when a user tries to fill to an unmapped or 328*5d9d9091SRichard Lowe ! misaligned stack. We handle an unmapped stack by simulating 329*5d9d9091SRichard Lowe ! a pagefault at the trap pc and a misaligned stack by generating 330*5d9d9091SRichard Lowe ! a user alignment trap. 331*5d9d9091SRichard Lowe ! 332*5d9d9091SRichard Lowe ! setup user_trap args 333*5d9d9091SRichard Lowe ! 334*5d9d9091SRichard Lowe ! g5 = mmu trap type, g6 = tag access reg (g5 != T_ALIGNMENT) or 335*5d9d9091SRichard Lowe ! sfar (g5 == T_ALIGNMENT) 336*5d9d9091SRichard Lowe ! 337*5d9d9091SRichard Lowe set sfmmu_tsbmiss_exception, %g1 338*5d9d9091SRichard Lowe mov %g6, %g2 ! arg2 = tagaccess 339*5d9d9091SRichard Lowe mov T_WIN_UNDERFLOW, %g3 340*5d9d9091SRichard Lowe cmp %g5, T_ALIGNMENT 341*5d9d9091SRichard Lowe bne %icc, 1f 342*5d9d9091SRichard Lowe nop 343*5d9d9091SRichard Lowe set trap, %g1 344*5d9d9091SRichard Lowe mov T_ALIGNMENT, %g3 345*5d9d9091SRichard Lowe1: 346*5d9d9091SRichard Lowe sub %g0, 1, %g4 347*5d9d9091SRichard Lowe ! 348*5d9d9091SRichard Lowe ! sys_trap wants %cwp to be the same as when the trap occured, 349*5d9d9091SRichard Lowe ! so set it from %tstate 350*5d9d9091SRichard Lowe ! 351*5d9d9091SRichard Lowe rdpr %tstate, %g5 352*5d9d9091SRichard Lowe and %g5, TSTATE_CWP, %g5 353*5d9d9091SRichard Lowe ba,pt %xcc, user_trap 354*5d9d9091SRichard Lowe wrpr %g0, %g5, %cwp 355*5d9d9091SRichard Lowe SET_SIZE(fault_32bit_fn0) 356*5d9d9091SRichard Lowe 357*5d9d9091SRichard Lowe ENTRY_NP(fault_32bit_fn1) 358*5d9d9091SRichard Lowe ! 359*5d9d9091SRichard Lowe FAULT_WINTRACE(%g1, %g2, %g3, TT_F32_FN1) 360*5d9d9091SRichard Lowe ! 361*5d9d9091SRichard Lowe.fault_fn1_common: 362*5d9d9091SRichard Lowe ! 363*5d9d9091SRichard Lowe ! Fill normal tl1 fault. 364*5d9d9091SRichard Lowe ! This happens when user_rtt's restore fills from an unmapped or 365*5d9d9091SRichard Lowe ! misaligned stack. We handle an unmapped stack by simulating 366*5d9d9091SRichard Lowe ! a pagefault at user_rtt and a misaligned stack by generating 367*5d9d9091SRichard Lowe ! a RTT alignment trap. 368*5d9d9091SRichard Lowe ! 369*5d9d9091SRichard Lowe ! save fault addr & fix %cwp 370*5d9d9091SRichard Lowe ! 371*5d9d9091SRichard Lowe rdpr %tstate, %g1 372*5d9d9091SRichard Lowe and %g1, TSTATE_CWP, %g1 373*5d9d9091SRichard Lowe wrpr %g0, %g1, %cwp 374*5d9d9091SRichard Lowe ! 375*5d9d9091SRichard Lowe ! fake tl1 traps regs so that after pagefault runs, we 376*5d9d9091SRichard Lowe ! re-execute at user_rtt. 377*5d9d9091SRichard Lowe ! 378*5d9d9091SRichard Lowe wrpr %g0, 1, %tl 379*5d9d9091SRichard Lowe set TSTATE_KERN | TSTATE_IE, %g1 380*5d9d9091SRichard Lowe wrpr %g0, %g1, %tstate 381*5d9d9091SRichard Lowe set user_rtt, %g1 382*5d9d9091SRichard Lowe wrpr %g0, %g1, %tpc 383*5d9d9091SRichard Lowe add %g1, 4, %g1 384*5d9d9091SRichard Lowe wrpr %g0, %g1, %tnpc 385*5d9d9091SRichard Lowe ! 386*5d9d9091SRichard Lowe ! setup sys_trap args 387*5d9d9091SRichard Lowe ! 388*5d9d9091SRichard Lowe ! g5 = mmu trap type, g6 = tag access reg (g5 != T_ALIGNMENT) or 389*5d9d9091SRichard Lowe ! sfar (g5 == T_ALIGNMENT) 390*5d9d9091SRichard Lowe ! 391*5d9d9091SRichard Lowe set sfmmu_tsbmiss_exception, %g1 392*5d9d9091SRichard Lowe mov %g6, %g2 ! arg2 = tagaccess 393*5d9d9091SRichard Lowe set T_USER | T_SYS_RTT_PAGE, %g3 ! arg3 = traptype 394*5d9d9091SRichard Lowe cmp %g5, T_ALIGNMENT 395*5d9d9091SRichard Lowe bne %icc, 1f 396*5d9d9091SRichard Lowe nop 397*5d9d9091SRichard Lowe set trap, %g1 398*5d9d9091SRichard Lowe set T_USER | T_SYS_RTT_ALIGN, %g3 399*5d9d9091SRichard Lowe1: 400*5d9d9091SRichard Lowe sub %g0, 1, %g4 401*5d9d9091SRichard Lowe ! 402*5d9d9091SRichard Lowe ! setup to run kernel again by setting THREAD_REG, %wstate 403*5d9d9091SRichard Lowe ! and the mmu to their kernel values. 404*5d9d9091SRichard Lowe ! 405*5d9d9091SRichard Lowe rdpr %pstate, %l1 406*5d9d9091SRichard Lowe wrpr %l1, PSTATE_AG, %pstate 407*5d9d9091SRichard Lowe mov %l6, THREAD_REG ! %l6 is user_rtt's thread 408*5d9d9091SRichard Lowe wrpr %g0, %l1, %pstate 409*5d9d9091SRichard Lowe rdpr %wstate, %l1 410*5d9d9091SRichard Lowe sllx %l1, WSTATE_SHIFT, %l1 411*5d9d9091SRichard Lowe wrpr %l1, WSTATE_K64, %wstate 412*5d9d9091SRichard Lowe sethi %hi(kcontextreg), %g5 ! mov KCONTEXT, %g5 413*5d9d9091SRichard Lowe ldx [%g5 + %lo(kcontextreg)], %g5 414*5d9d9091SRichard Lowe mov MMU_PCONTEXT, %g6 415*5d9d9091SRichard Lowe ldxa [%g6]ASI_MMU_CTX, %g7 416*5d9d9091SRichard Lowe xor %g5, %g7, %g7 417*5d9d9091SRichard Lowe srlx %g7, CTXREG_NEXT_SHIFT, %g7 418*5d9d9091SRichard Lowe brz %g7, 1f ! if N_pgsz0/1 changed, need demap 419*5d9d9091SRichard Lowe nop 420*5d9d9091SRichard Lowe mov DEMAP_ALL_TYPE, %g7 421*5d9d9091SRichard Lowe stxa %g0, [%g7]ASI_DTLB_DEMAP 422*5d9d9091SRichard Lowe stxa %g0, [%g7]ASI_ITLB_DEMAP 423*5d9d9091SRichard Lowe1: 424*5d9d9091SRichard Lowe stxa %g5, [%g6]ASI_MMU_CTX 425*5d9d9091SRichard Lowe sethi %hi(FLUSH_ADDR), %g5 426*5d9d9091SRichard Lowe flush %g5 427*5d9d9091SRichard Lowe 428*5d9d9091SRichard Lowe ba,pt %xcc, priv_trap 429*5d9d9091SRichard Lowe nop 430*5d9d9091SRichard Lowe SET_SIZE(fault_32bit_fn1) 431*5d9d9091SRichard Lowe 432*5d9d9091SRichard Lowe ENTRY_NP(fault_64bit_fn0) 433*5d9d9091SRichard Lowe FAULT_WINTRACE(%g1, %g2, %g3, TT_F64_FN0) 434*5d9d9091SRichard Lowe b .fault_fn0_common 435*5d9d9091SRichard Lowe nop 436*5d9d9091SRichard Lowe SET_SIZE(fault_64bit_fn0) 437*5d9d9091SRichard Lowe 438*5d9d9091SRichard Lowe ENTRY_NP(fault_64bit_fn1) 439*5d9d9091SRichard Lowe FAULT_WINTRACE(%g1, %g2, %g3, TT_F64_FN1) 440*5d9d9091SRichard Lowe b .fault_fn1_common 441*5d9d9091SRichard Lowe nop 442*5d9d9091SRichard Lowe SET_SIZE(fault_64bit_fn1) 443*5d9d9091SRichard Lowe 444*5d9d9091SRichard Lowe /* 445*5d9d9091SRichard Lowe * Kernel fault handlers 446*5d9d9091SRichard Lowe */ 447*5d9d9091SRichard Lowe ENTRY_NP(fault_32bit_not) 448*5d9d9091SRichard Lowe ENTRY_NP(fault_64bit_not) 449*5d9d9091SRichard Lowe ba,pt %xcc, ptl1_panic 450*5d9d9091SRichard Lowe mov PTL1_BAD_WTRAP, %g1 451*5d9d9091SRichard Lowe SET_SIZE(fault_32bit_not) 452*5d9d9091SRichard Lowe SET_SIZE(fault_64bit_not) 453