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 5*febcc4a5Sjimand * Common Development and Distribution License (the "License"). 6*febcc4a5Sjimand * 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*febcc4a5Sjimand * Copyright 2007 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#include <sys/asm_linkage.h> 297c478bd9Sstevel@tonic-gate#include <sys/machthread.h> 307c478bd9Sstevel@tonic-gate#include <sys/privregs.h> 317c478bd9Sstevel@tonic-gate#include <sys/machasi.h> 327c478bd9Sstevel@tonic-gate#include <sys/trap.h> 337c478bd9Sstevel@tonic-gate#include <sys/mmu.h> 347c478bd9Sstevel@tonic-gate#include <sys/machparam.h> 357c478bd9Sstevel@tonic-gate#include <sys/machtrap.h> 367c478bd9Sstevel@tonic-gate#include <sys/traptrace.h> 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate#if !defined(lint) 397c478bd9Sstevel@tonic-gate#include "assym.h" 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate /* 427c478bd9Sstevel@tonic-gate * Spill fault handlers 437c478bd9Sstevel@tonic-gate * sn0 - spill normal tl 0 447c478bd9Sstevel@tonic-gate * sn1 - spill normal tl >0 457c478bd9Sstevel@tonic-gate * so0 - spill other tl 0 467c478bd9Sstevel@tonic-gate * so1 - spill other tl >0 477c478bd9Sstevel@tonic-gate */ 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate ENTRY_NP(fault_32bit_sn0) 507c478bd9Sstevel@tonic-gate ! 517c478bd9Sstevel@tonic-gate FAULT_WINTRACE(%g1, %g2, %g3, TT_F32_SN0) 527c478bd9Sstevel@tonic-gate ! 537c478bd9Sstevel@tonic-gate ! Spill normal tl0 fault. 547c478bd9Sstevel@tonic-gate ! This happens when a user tries to spill to an unmapped or 557c478bd9Sstevel@tonic-gate ! misaligned stack. We handle an unmapped stack by simulating 567c478bd9Sstevel@tonic-gate ! a pagefault at the trap pc and a misaligned stack by generating 577c478bd9Sstevel@tonic-gate ! a user alignment trap. 587c478bd9Sstevel@tonic-gate ! 597c478bd9Sstevel@tonic-gate ! spill the window into wbuf slot 0 607c478bd9Sstevel@tonic-gate ! (we know wbuf is empty since we came from user mode) 617c478bd9Sstevel@tonic-gate ! 627c478bd9Sstevel@tonic-gate ! g5 = mmu trap type, g6 = tag access reg (g5 != T_ALIGNMENT) or 637c478bd9Sstevel@tonic-gate ! sfar (g5 == T_ALIGNMENT) 647c478bd9Sstevel@tonic-gate ! 657c478bd9Sstevel@tonic-gate CPU_ADDR(%g4, %g1) 667c478bd9Sstevel@tonic-gate ldn [%g4 + CPU_MPCB], %g1 677c478bd9Sstevel@tonic-gate stn %sp, [%g1 + MPCB_SPBUF] 687c478bd9Sstevel@tonic-gate ldn [%g1 + MPCB_WBUF], %g2 697c478bd9Sstevel@tonic-gate SAVE_V8WINDOW(%g2) 707c478bd9Sstevel@tonic-gate mov 1, %g2 717c478bd9Sstevel@tonic-gate st %g2, [%g1 + MPCB_WBCNT] 727c478bd9Sstevel@tonic-gate saved 737c478bd9Sstevel@tonic-gate ! 747c478bd9Sstevel@tonic-gate ! setup user_trap args 757c478bd9Sstevel@tonic-gate ! 767c478bd9Sstevel@tonic-gate set sfmmu_tsbmiss_exception, %g1 777c478bd9Sstevel@tonic-gate mov %g6, %g2 ! arg2 = tagaccess 787c478bd9Sstevel@tonic-gate mov T_WIN_OVERFLOW, %g3 ! arg3 = traptype 797c478bd9Sstevel@tonic-gate cmp %g5, T_ALIGNMENT 807c478bd9Sstevel@tonic-gate bne %icc, 1f 817c478bd9Sstevel@tonic-gate nop 827c478bd9Sstevel@tonic-gate set trap, %g1 837c478bd9Sstevel@tonic-gate mov T_ALIGNMENT, %g3 847c478bd9Sstevel@tonic-gate1: 857c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 867c478bd9Sstevel@tonic-gate ! 877c478bd9Sstevel@tonic-gate ! spill traps increment %cwp by 2, 887c478bd9Sstevel@tonic-gate ! but user_trap wants the trap %cwp 897c478bd9Sstevel@tonic-gate ! 907c478bd9Sstevel@tonic-gate rdpr %tstate, %g5 917c478bd9Sstevel@tonic-gate and %g5, TSTATE_CWP, %g5 927c478bd9Sstevel@tonic-gate ba,pt %xcc, user_trap 937c478bd9Sstevel@tonic-gate wrpr %g0, %g5, %cwp 947c478bd9Sstevel@tonic-gate SET_SIZE(fault_32bit_sn0) 957c478bd9Sstevel@tonic-gate 967c478bd9Sstevel@tonic-gate ! 977c478bd9Sstevel@tonic-gate ! Spill normal tl1 fault. 987c478bd9Sstevel@tonic-gate ! This happens when sys_trap's save spills to an unmapped stack. 997c478bd9Sstevel@tonic-gate ! We handle it by spilling the window to the wbuf and trying 1007c478bd9Sstevel@tonic-gate ! sys_trap again. 1017c478bd9Sstevel@tonic-gate ! 1027c478bd9Sstevel@tonic-gate ! spill the window into wbuf slot 0 1037c478bd9Sstevel@tonic-gate ! (we know wbuf is empty since we came from user mode) 1047c478bd9Sstevel@tonic-gate ! 1057c478bd9Sstevel@tonic-gate ENTRY_NP(fault_32bit_sn1) 1067c478bd9Sstevel@tonic-gate FAULT_WINTRACE(%g5, %g6, %g7, TT_F32_SN1) 1077c478bd9Sstevel@tonic-gate CPU_ADDR(%g5, %g6) 1087c478bd9Sstevel@tonic-gate ldn [%g5 + CPU_MPCB], %g6 1097c478bd9Sstevel@tonic-gate stn %sp, [%g6 + MPCB_SPBUF] 1107c478bd9Sstevel@tonic-gate ldn [%g6 + MPCB_WBUF], %g5 1117c478bd9Sstevel@tonic-gate SAVE_V8WINDOW(%g5) 1127c478bd9Sstevel@tonic-gate mov 1, %g5 1137c478bd9Sstevel@tonic-gate st %g5, [%g6 + MPCB_WBCNT] 1147c478bd9Sstevel@tonic-gate saved 1157c478bd9Sstevel@tonic-gate set sys_trap, %g5 1167c478bd9Sstevel@tonic-gate wrpr %g5, %tnpc 1177c478bd9Sstevel@tonic-gate done 1187c478bd9Sstevel@tonic-gate SET_SIZE(fault_32bit_sn1) 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate ENTRY_NP(fault_32bit_so0) 1217c478bd9Sstevel@tonic-gate ! 1227c478bd9Sstevel@tonic-gate FAULT_WINTRACE(%g5, %g6, %g1, TT_F32_SO0) 1237c478bd9Sstevel@tonic-gate ! 1247c478bd9Sstevel@tonic-gate ! Spill other tl0 fault. 1257c478bd9Sstevel@tonic-gate ! This happens when the kernel spills a user window and that 1267c478bd9Sstevel@tonic-gate ! user's stack has been unmapped. 1277c478bd9Sstevel@tonic-gate ! We handle it by spilling the window into the user's wbuf. 1287c478bd9Sstevel@tonic-gate ! 1297c478bd9Sstevel@tonic-gate ! find lwp & increment wbcnt 1307c478bd9Sstevel@tonic-gate ! 1317c478bd9Sstevel@tonic-gate CPU_ADDR(%g5, %g6) 1327c478bd9Sstevel@tonic-gate ldn [%g5 + CPU_MPCB], %g1 1337c478bd9Sstevel@tonic-gate ld [%g1 + MPCB_WBCNT], %g2 1347c478bd9Sstevel@tonic-gate add %g2, 1, %g3 1357c478bd9Sstevel@tonic-gate st %g3, [%g1 + MPCB_WBCNT] 1367c478bd9Sstevel@tonic-gate ! 1377c478bd9Sstevel@tonic-gate ! use previous wbcnt to spill new spbuf & wbuf 1387c478bd9Sstevel@tonic-gate ! 1397c478bd9Sstevel@tonic-gate sll %g2, CPTRSHIFT, %g4 ! spbuf size is sizeof (caddr_t) 1407c478bd9Sstevel@tonic-gate add %g1, MPCB_SPBUF, %g3 1417c478bd9Sstevel@tonic-gate stn %sp, [%g3 + %g4] 1427c478bd9Sstevel@tonic-gate sll %g2, RWIN32SHIFT, %g4 1437c478bd9Sstevel@tonic-gate ldn [%g1 + MPCB_WBUF], %g3 1447c478bd9Sstevel@tonic-gate add %g3, %g4, %g3 1457c478bd9Sstevel@tonic-gate SAVE_V8WINDOW(%g3) 1467c478bd9Sstevel@tonic-gate saved 1477c478bd9Sstevel@tonic-gate retry 1487c478bd9Sstevel@tonic-gate SET_SIZE(fault_32bit_so0) 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate ! 1517c478bd9Sstevel@tonic-gate ! Spill other tl1 fault. 1527c478bd9Sstevel@tonic-gate ! This happens when priv_trap spills a user window and that 1537c478bd9Sstevel@tonic-gate ! user's stack has been unmapped. 1547c478bd9Sstevel@tonic-gate ! We handle it by spilling the window to the wbuf and retrying 1557c478bd9Sstevel@tonic-gate ! the save. 1567c478bd9Sstevel@tonic-gate ! 1577c478bd9Sstevel@tonic-gate ENTRY_NP(fault_32bit_so1) 1587c478bd9Sstevel@tonic-gate FAULT_WINTRACE(%g5, %g6, %g7, TT_F32_SO1) 1597c478bd9Sstevel@tonic-gate CPU_ADDR(%g5, %g6) 1607c478bd9Sstevel@tonic-gate ! 1617c478bd9Sstevel@tonic-gate ! find lwp & increment wbcnt 1627c478bd9Sstevel@tonic-gate ! 1637c478bd9Sstevel@tonic-gate ldn [%g5 + CPU_MPCB], %g6 1647c478bd9Sstevel@tonic-gate ld [%g6 + MPCB_WBCNT], %g5 1657c478bd9Sstevel@tonic-gate add %g5, 1, %g7 1667c478bd9Sstevel@tonic-gate st %g7, [%g6 + MPCB_WBCNT] 1677c478bd9Sstevel@tonic-gate ! 1687c478bd9Sstevel@tonic-gate ! use previous wbcnt to spill new spbuf & wbuf 1697c478bd9Sstevel@tonic-gate ! 1707c478bd9Sstevel@tonic-gate sll %g5, CPTRSHIFT, %g7 ! spbuf size is sizeof (caddr_t) 1717c478bd9Sstevel@tonic-gate add %g6, %g7, %g7 1727c478bd9Sstevel@tonic-gate stn %sp, [%g7 + MPCB_SPBUF] 1737c478bd9Sstevel@tonic-gate sll %g5, RWIN32SHIFT, %g7 1747c478bd9Sstevel@tonic-gate ldn [%g6 + MPCB_WBUF], %g5 1757c478bd9Sstevel@tonic-gate add %g5, %g7, %g7 1767c478bd9Sstevel@tonic-gate SAVE_V8WINDOW(%g7) 1777c478bd9Sstevel@tonic-gate saved 1787c478bd9Sstevel@tonic-gate set sys_trap, %g5 1797c478bd9Sstevel@tonic-gate wrpr %g5, %tnpc 1807c478bd9Sstevel@tonic-gate done 1817c478bd9Sstevel@tonic-gate SET_SIZE(fault_32bit_so1) 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate ENTRY_NP(fault_64bit_sn0) 1847c478bd9Sstevel@tonic-gate ! 1857c478bd9Sstevel@tonic-gate FAULT_WINTRACE(%g1, %g2, %g3, TT_F64_SN0) 1867c478bd9Sstevel@tonic-gate ! 1877c478bd9Sstevel@tonic-gate ! Spill normal tl0 fault. 1887c478bd9Sstevel@tonic-gate ! This happens when a user tries to spill to an unmapped or 1897c478bd9Sstevel@tonic-gate ! misaligned stack. We handle an unmapped stack by simulating 1907c478bd9Sstevel@tonic-gate ! a pagefault at the trap pc and a misaligned stack by generating 1917c478bd9Sstevel@tonic-gate ! a user alignment trap. 1927c478bd9Sstevel@tonic-gate ! 1937c478bd9Sstevel@tonic-gate ! spill the window into wbuf slot 0 1947c478bd9Sstevel@tonic-gate ! (we know wbuf is empty since we came from user mode) 1957c478bd9Sstevel@tonic-gate ! 1967c478bd9Sstevel@tonic-gate ! g5 = mmu trap type, g6 = tag access reg (g5 != T_ALIGNMENT) or 1977c478bd9Sstevel@tonic-gate ! sfar (g5 == T_ALIGNMENT) 1987c478bd9Sstevel@tonic-gate ! 1997c478bd9Sstevel@tonic-gate CPU_ADDR(%g4, %g1) 2007c478bd9Sstevel@tonic-gate ldn [%g4 + CPU_MPCB], %g1 2017c478bd9Sstevel@tonic-gate stn %sp, [%g1 + MPCB_SPBUF] 2027c478bd9Sstevel@tonic-gate ldn [%g1 + MPCB_WBUF], %g2 2037c478bd9Sstevel@tonic-gate SAVE_V9WINDOW(%g2) 2047c478bd9Sstevel@tonic-gate mov 1, %g2 2057c478bd9Sstevel@tonic-gate st %g2, [%g1 + MPCB_WBCNT] 2067c478bd9Sstevel@tonic-gate saved 2077c478bd9Sstevel@tonic-gate ! 2087c478bd9Sstevel@tonic-gate ! setup user_trap args 2097c478bd9Sstevel@tonic-gate ! 2107c478bd9Sstevel@tonic-gate set sfmmu_tsbmiss_exception, %g1 2117c478bd9Sstevel@tonic-gate mov %g6, %g2 ! arg2 = tagaccess 2127c478bd9Sstevel@tonic-gate mov %g5, %g3 ! arg3 = traptype 2137c478bd9Sstevel@tonic-gate cmp %g5, T_ALIGNMENT 2147c478bd9Sstevel@tonic-gate bne %icc, 1f 2157c478bd9Sstevel@tonic-gate nop 2167c478bd9Sstevel@tonic-gate set trap, %g1 2177c478bd9Sstevel@tonic-gate mov T_ALIGNMENT, %g3 2187c478bd9Sstevel@tonic-gate1: 2197c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 2207c478bd9Sstevel@tonic-gate ! 2217c478bd9Sstevel@tonic-gate ! spill traps increment %cwp by 2, 2227c478bd9Sstevel@tonic-gate ! but user_trap wants the trap %cwp 2237c478bd9Sstevel@tonic-gate ! 2247c478bd9Sstevel@tonic-gate rdpr %tstate, %g5 2257c478bd9Sstevel@tonic-gate and %g5, TSTATE_CWP, %g5 2267c478bd9Sstevel@tonic-gate ba,pt %xcc, user_trap 2277c478bd9Sstevel@tonic-gate wrpr %g0, %g5, %cwp 2287c478bd9Sstevel@tonic-gate SET_SIZE(fault_64bit_sn0) 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate ! 2317c478bd9Sstevel@tonic-gate ! Spill normal tl1 fault. 2327c478bd9Sstevel@tonic-gate ! This happens when sys_trap's save spills to an unmapped stack. 2337c478bd9Sstevel@tonic-gate ! We handle it by spilling the window to the wbuf and trying 2347c478bd9Sstevel@tonic-gate ! sys_trap again. 2357c478bd9Sstevel@tonic-gate ! 2367c478bd9Sstevel@tonic-gate ! spill the window into wbuf slot 0 2377c478bd9Sstevel@tonic-gate ! (we know wbuf is empty since we came from user mode) 2387c478bd9Sstevel@tonic-gate ! 2397c478bd9Sstevel@tonic-gate ENTRY_NP(fault_64bit_sn1) 2407c478bd9Sstevel@tonic-gate FAULT_WINTRACE(%g5, %g6, %g7, TT_F64_SN1) 2417c478bd9Sstevel@tonic-gate CPU_ADDR(%g5, %g6) 2427c478bd9Sstevel@tonic-gate ldn [%g5 + CPU_MPCB], %g6 2437c478bd9Sstevel@tonic-gate stn %sp, [%g6 + MPCB_SPBUF] 2447c478bd9Sstevel@tonic-gate ldn [%g6 + MPCB_WBUF], %g5 2457c478bd9Sstevel@tonic-gate SAVE_V9WINDOW(%g5) 2467c478bd9Sstevel@tonic-gate mov 1, %g5 2477c478bd9Sstevel@tonic-gate st %g5, [%g6 + MPCB_WBCNT] 2487c478bd9Sstevel@tonic-gate saved 2497c478bd9Sstevel@tonic-gate set sys_trap, %g5 2507c478bd9Sstevel@tonic-gate wrpr %g5, %tnpc 2517c478bd9Sstevel@tonic-gate done 2527c478bd9Sstevel@tonic-gate SET_SIZE(fault_64bit_sn1) 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate ENTRY_NP(fault_64bit_so0) 2557c478bd9Sstevel@tonic-gate ! 2567c478bd9Sstevel@tonic-gate FAULT_WINTRACE(%g5, %g6, %g1, TT_F64_SO0) 2577c478bd9Sstevel@tonic-gate ! 2587c478bd9Sstevel@tonic-gate ! Spill other tl0 fault. 2597c478bd9Sstevel@tonic-gate ! This happens when the kernel spills a user window and that 2607c478bd9Sstevel@tonic-gate ! user's stack has been unmapped. 2617c478bd9Sstevel@tonic-gate ! We handle it by spilling the window into the user's wbuf. 2627c478bd9Sstevel@tonic-gate ! 2637c478bd9Sstevel@tonic-gate ! find lwp & increment wbcnt 2647c478bd9Sstevel@tonic-gate ! 2657c478bd9Sstevel@tonic-gate CPU_ADDR(%g5, %g6) 2667c478bd9Sstevel@tonic-gate ldn [%g5 + CPU_MPCB], %g1 2677c478bd9Sstevel@tonic-gate ld [%g1 + MPCB_WBCNT], %g2 2687c478bd9Sstevel@tonic-gate add %g2, 1, %g3 2697c478bd9Sstevel@tonic-gate st %g3, [%g1 + MPCB_WBCNT] 2707c478bd9Sstevel@tonic-gate ! 2717c478bd9Sstevel@tonic-gate ! use previous wbcnt to spill new spbuf & wbuf 2727c478bd9Sstevel@tonic-gate ! 2737c478bd9Sstevel@tonic-gate sll %g2, CPTRSHIFT, %g4 ! spbuf size is sizeof (caddr_t) 2747c478bd9Sstevel@tonic-gate add %g1, MPCB_SPBUF, %g3 2757c478bd9Sstevel@tonic-gate stn %sp, [%g3 + %g4] 2767c478bd9Sstevel@tonic-gate sll %g2, RWIN64SHIFT, %g4 2777c478bd9Sstevel@tonic-gate ldn [%g1 + MPCB_WBUF], %g3 2787c478bd9Sstevel@tonic-gate add %g3, %g4, %g3 2797c478bd9Sstevel@tonic-gate SAVE_V9WINDOW(%g3) 2807c478bd9Sstevel@tonic-gate saved 2817c478bd9Sstevel@tonic-gate retry 2827c478bd9Sstevel@tonic-gate SET_SIZE(fault_64bit_so0) 2837c478bd9Sstevel@tonic-gate 2847c478bd9Sstevel@tonic-gate ! 2857c478bd9Sstevel@tonic-gate ! Spill other tl1 fault. 2867c478bd9Sstevel@tonic-gate ! This happens when priv_trap spills a user window and that 2877c478bd9Sstevel@tonic-gate ! user's stack has been unmapped. 2887c478bd9Sstevel@tonic-gate ! We handle it by spilling the window to the wbuf and retrying 2897c478bd9Sstevel@tonic-gate ! the save. 2907c478bd9Sstevel@tonic-gate ! 2917c478bd9Sstevel@tonic-gate ENTRY_NP(fault_64bit_so1) 2927c478bd9Sstevel@tonic-gate FAULT_WINTRACE(%g5, %g6, %g7, TT_F64_SO1) 2937c478bd9Sstevel@tonic-gate CPU_ADDR(%g5, %g6) 2947c478bd9Sstevel@tonic-gate ! 2957c478bd9Sstevel@tonic-gate ! find lwp & increment wbcnt 2967c478bd9Sstevel@tonic-gate ! 2977c478bd9Sstevel@tonic-gate ldn [%g5 + CPU_MPCB], %g6 2987c478bd9Sstevel@tonic-gate ld [%g6 + MPCB_WBCNT], %g5 2997c478bd9Sstevel@tonic-gate add %g5, 1, %g7 3007c478bd9Sstevel@tonic-gate st %g7, [%g6 + MPCB_WBCNT] 3017c478bd9Sstevel@tonic-gate ! 3027c478bd9Sstevel@tonic-gate ! use previous wbcnt to spill new spbuf & wbuf 3037c478bd9Sstevel@tonic-gate ! 3047c478bd9Sstevel@tonic-gate sll %g5, CPTRSHIFT, %g7 ! spbuf size is sizeof (caddr_t) 3057c478bd9Sstevel@tonic-gate add %g6, %g7, %g7 3067c478bd9Sstevel@tonic-gate stn %sp, [%g7 + MPCB_SPBUF] 3077c478bd9Sstevel@tonic-gate sll %g5, RWIN64SHIFT, %g7 3087c478bd9Sstevel@tonic-gate ldn [%g6 + MPCB_WBUF], %g5 3097c478bd9Sstevel@tonic-gate add %g5, %g7, %g7 3107c478bd9Sstevel@tonic-gate SAVE_V9WINDOW(%g7) 3117c478bd9Sstevel@tonic-gate saved 3127c478bd9Sstevel@tonic-gate set sys_trap, %g5 3137c478bd9Sstevel@tonic-gate wrpr %g5, %tnpc 3147c478bd9Sstevel@tonic-gate done 3157c478bd9Sstevel@tonic-gate SET_SIZE(fault_64bit_so1) 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate /* 3187c478bd9Sstevel@tonic-gate * Fill fault handlers 3197c478bd9Sstevel@tonic-gate * fn0 - fill normal tl 0 3207c478bd9Sstevel@tonic-gate * fn1 - fill normal tl 1 3217c478bd9Sstevel@tonic-gate */ 3227c478bd9Sstevel@tonic-gate 3237c478bd9Sstevel@tonic-gate ENTRY_NP(fault_32bit_fn0) 3247c478bd9Sstevel@tonic-gate ! 3257c478bd9Sstevel@tonic-gate FAULT_WINTRACE(%g1, %g2, %g3, TT_F32_FN0) 3267c478bd9Sstevel@tonic-gate ! 3277c478bd9Sstevel@tonic-gate.fault_fn0_common: 3287c478bd9Sstevel@tonic-gate ! 3297c478bd9Sstevel@tonic-gate ! Fill normal tl0 fault. 3307c478bd9Sstevel@tonic-gate ! This happens when a user tries to fill to an unmapped or 3317c478bd9Sstevel@tonic-gate ! misaligned stack. We handle an unmapped stack by simulating 3327c478bd9Sstevel@tonic-gate ! a pagefault at the trap pc and a misaligned stack by generating 3337c478bd9Sstevel@tonic-gate ! a user alignment trap. 3347c478bd9Sstevel@tonic-gate ! 3357c478bd9Sstevel@tonic-gate ! setup user_trap args 3367c478bd9Sstevel@tonic-gate ! 3377c478bd9Sstevel@tonic-gate ! g5 = mmu trap type, g6 = tag access reg (g5 != T_ALIGNMENT) or 3387c478bd9Sstevel@tonic-gate ! sfar (g5 == T_ALIGNMENT) 3397c478bd9Sstevel@tonic-gate ! 3407c478bd9Sstevel@tonic-gate set sfmmu_tsbmiss_exception, %g1 3417c478bd9Sstevel@tonic-gate mov %g6, %g2 ! arg2 = tagaccess 3427c478bd9Sstevel@tonic-gate mov T_WIN_UNDERFLOW, %g3 3437c478bd9Sstevel@tonic-gate cmp %g5, T_ALIGNMENT 3447c478bd9Sstevel@tonic-gate bne %icc, 1f 3457c478bd9Sstevel@tonic-gate nop 3467c478bd9Sstevel@tonic-gate set trap, %g1 3477c478bd9Sstevel@tonic-gate mov T_ALIGNMENT, %g3 3487c478bd9Sstevel@tonic-gate1: 3497c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 3507c478bd9Sstevel@tonic-gate ! 3517c478bd9Sstevel@tonic-gate ! sys_trap wants %cwp to be the same as when the trap occured, 3527c478bd9Sstevel@tonic-gate ! so set it from %tstate 3537c478bd9Sstevel@tonic-gate ! 3547c478bd9Sstevel@tonic-gate rdpr %tstate, %g5 3557c478bd9Sstevel@tonic-gate and %g5, TSTATE_CWP, %g5 3567c478bd9Sstevel@tonic-gate ba,pt %xcc, user_trap 3577c478bd9Sstevel@tonic-gate wrpr %g0, %g5, %cwp 3587c478bd9Sstevel@tonic-gate SET_SIZE(fault_32bit_fn0) 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate ENTRY_NP(fault_32bit_fn1) 3617c478bd9Sstevel@tonic-gate ! 3627c478bd9Sstevel@tonic-gate FAULT_WINTRACE(%g1, %g2, %g3, TT_F32_FN1) 3637c478bd9Sstevel@tonic-gate ! 3647c478bd9Sstevel@tonic-gate.fault_fn1_common: 3657c478bd9Sstevel@tonic-gate ! 3667c478bd9Sstevel@tonic-gate ! Fill normal tl1 fault. 3677c478bd9Sstevel@tonic-gate ! This happens when user_rtt's restore fills from an unmapped or 3687c478bd9Sstevel@tonic-gate ! misaligned stack. We handle an unmapped stack by simulating 3697c478bd9Sstevel@tonic-gate ! a pagefault at user_rtt and a misaligned stack by generating 3707c478bd9Sstevel@tonic-gate ! a RTT alignment trap. 3717c478bd9Sstevel@tonic-gate ! 3727c478bd9Sstevel@tonic-gate ! save fault addr & fix %cwp 3737c478bd9Sstevel@tonic-gate ! 3747c478bd9Sstevel@tonic-gate rdpr %tstate, %g1 3757c478bd9Sstevel@tonic-gate and %g1, TSTATE_CWP, %g1 3767c478bd9Sstevel@tonic-gate wrpr %g0, %g1, %cwp 3777c478bd9Sstevel@tonic-gate ! 3787c478bd9Sstevel@tonic-gate ! fake tl1 traps regs so that after pagefault runs, we 3797c478bd9Sstevel@tonic-gate ! re-execute at user_rtt. 3807c478bd9Sstevel@tonic-gate ! 3817c478bd9Sstevel@tonic-gate wrpr %g0, 1, %tl 3827c478bd9Sstevel@tonic-gate set TSTATE_KERN | TSTATE_IE, %g1 3837c478bd9Sstevel@tonic-gate wrpr %g0, %g1, %tstate 3847c478bd9Sstevel@tonic-gate set user_rtt, %g1 3857c478bd9Sstevel@tonic-gate wrpr %g0, %g1, %tpc 3867c478bd9Sstevel@tonic-gate add %g1, 4, %g1 3877c478bd9Sstevel@tonic-gate wrpr %g0, %g1, %tnpc 3887c478bd9Sstevel@tonic-gate ! 3897c478bd9Sstevel@tonic-gate ! setup sys_trap args 3907c478bd9Sstevel@tonic-gate ! 3917c478bd9Sstevel@tonic-gate ! g5 = mmu trap type, g6 = tag access reg (g5 != T_ALIGNMENT) or 3927c478bd9Sstevel@tonic-gate ! sfar (g5 == T_ALIGNMENT) 3937c478bd9Sstevel@tonic-gate ! 3947c478bd9Sstevel@tonic-gate set sfmmu_tsbmiss_exception, %g1 3957c478bd9Sstevel@tonic-gate mov %g6, %g2 ! arg2 = tagaccess 3967c478bd9Sstevel@tonic-gate set T_USER | T_SYS_RTT_PAGE, %g3 ! arg3 = traptype 3977c478bd9Sstevel@tonic-gate cmp %g5, T_ALIGNMENT 3987c478bd9Sstevel@tonic-gate bne %icc, 1f 3997c478bd9Sstevel@tonic-gate nop 4007c478bd9Sstevel@tonic-gate set trap, %g1 4017c478bd9Sstevel@tonic-gate set T_USER | T_SYS_RTT_ALIGN, %g3 4027c478bd9Sstevel@tonic-gate1: 4037c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 4047c478bd9Sstevel@tonic-gate ! 4057c478bd9Sstevel@tonic-gate ! setup to run kernel again by setting THREAD_REG, %wstate 4067c478bd9Sstevel@tonic-gate ! and the mmu to their kernel values. 4077c478bd9Sstevel@tonic-gate ! 4087c478bd9Sstevel@tonic-gate rdpr %pstate, %l1 4097c478bd9Sstevel@tonic-gate wrpr %l1, PSTATE_AG, %pstate 4107c478bd9Sstevel@tonic-gate mov %l6, THREAD_REG ! %l6 is user_rtt's thread 4117c478bd9Sstevel@tonic-gate wrpr %g0, %l1, %pstate 4127c478bd9Sstevel@tonic-gate rdpr %wstate, %l1 4137c478bd9Sstevel@tonic-gate sllx %l1, WSTATE_SHIFT, %l1 4147c478bd9Sstevel@tonic-gate wrpr %l1, WSTATE_K64, %wstate 4157c478bd9Sstevel@tonic-gate sethi %hi(kcontextreg), %g5 ! mov KCONTEXT, %g5 4167c478bd9Sstevel@tonic-gate ldx [%g5 + %lo(kcontextreg)], %g5 4177c478bd9Sstevel@tonic-gate mov MMU_PCONTEXT, %g6 418*febcc4a5Sjimand ldxa [%g6]ASI_MMU_CTX, %g7 419*febcc4a5Sjimand xor %g5, %g7, %g7 420*febcc4a5Sjimand srlx %g7, CTXREG_NEXT_SHIFT, %g7 421*febcc4a5Sjimand brz %g7, 1f ! if N_pgsz0/1 changed, need demap 422*febcc4a5Sjimand nop 423*febcc4a5Sjimand mov DEMAP_ALL_TYPE, %g7 424*febcc4a5Sjimand stxa %g0, [%g7]ASI_DTLB_DEMAP 425*febcc4a5Sjimand stxa %g0, [%g7]ASI_ITLB_DEMAP 426*febcc4a5Sjimand1: 4277c478bd9Sstevel@tonic-gate stxa %g5, [%g6]ASI_MMU_CTX 4287c478bd9Sstevel@tonic-gate sethi %hi(FLUSH_ADDR), %g5 4297c478bd9Sstevel@tonic-gate flush %g5 4307c478bd9Sstevel@tonic-gate 4317c478bd9Sstevel@tonic-gate ba,pt %xcc, priv_trap 4327c478bd9Sstevel@tonic-gate nop 4337c478bd9Sstevel@tonic-gate SET_SIZE(fault_32bit_fn1) 4347c478bd9Sstevel@tonic-gate 4357c478bd9Sstevel@tonic-gate ENTRY_NP(fault_64bit_fn0) 4367c478bd9Sstevel@tonic-gate FAULT_WINTRACE(%g1, %g2, %g3, TT_F64_FN0) 4377c478bd9Sstevel@tonic-gate b .fault_fn0_common 4387c478bd9Sstevel@tonic-gate nop 4397c478bd9Sstevel@tonic-gate SET_SIZE(fault_64bit_fn0) 4407c478bd9Sstevel@tonic-gate 4417c478bd9Sstevel@tonic-gate ENTRY_NP(fault_64bit_fn1) 4427c478bd9Sstevel@tonic-gate FAULT_WINTRACE(%g1, %g2, %g3, TT_F64_FN1) 4437c478bd9Sstevel@tonic-gate b .fault_fn1_common 4447c478bd9Sstevel@tonic-gate nop 4457c478bd9Sstevel@tonic-gate SET_SIZE(fault_64bit_fn1) 4467c478bd9Sstevel@tonic-gate 4477c478bd9Sstevel@tonic-gate /* 4487c478bd9Sstevel@tonic-gate * Kernel fault handlers 4497c478bd9Sstevel@tonic-gate */ 4507c478bd9Sstevel@tonic-gate ENTRY_NP(fault_32bit_not) 4517c478bd9Sstevel@tonic-gate ENTRY_NP(fault_64bit_not) 4527c478bd9Sstevel@tonic-gate ba,pt %xcc, ptl1_panic 4537c478bd9Sstevel@tonic-gate mov PTL1_BAD_WTRAP, %g1 4547c478bd9Sstevel@tonic-gate SET_SIZE(fault_32bit_not) 4557c478bd9Sstevel@tonic-gate SET_SIZE(fault_64bit_not) 4567c478bd9Sstevel@tonic-gate#endif /* !lint */ 457