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 541f63f87Spetede * Common Development and Distribution License (the "License"). 641f63f87Spetede * 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 */ 21f498645aSahl 227c478bd9Sstevel@tonic-gate/* 23b9e93c10SJonathan Haslam * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate#if !defined(lint) 287c478bd9Sstevel@tonic-gate#include "assym.h" 297c478bd9Sstevel@tonic-gate#endif /* !lint */ 307c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h> 317c478bd9Sstevel@tonic-gate#include <sys/privregs.h> 327c478bd9Sstevel@tonic-gate#include <sys/sun4asi.h> 337c478bd9Sstevel@tonic-gate#include <sys/machasi.h> 347c478bd9Sstevel@tonic-gate#include <sys/hypervisor_api.h> 357c478bd9Sstevel@tonic-gate#include <sys/machtrap.h> 367c478bd9Sstevel@tonic-gate#include <sys/machthread.h> 374a75c0c1Sedp#include <sys/machbrand.h> 387c478bd9Sstevel@tonic-gate#include <sys/pcb.h> 397c478bd9Sstevel@tonic-gate#include <sys/pte.h> 407c478bd9Sstevel@tonic-gate#include <sys/mmu.h> 417c478bd9Sstevel@tonic-gate#include <sys/machpcb.h> 427c478bd9Sstevel@tonic-gate#include <sys/async.h> 437c478bd9Sstevel@tonic-gate#include <sys/intreg.h> 447c478bd9Sstevel@tonic-gate#include <sys/scb.h> 457c478bd9Sstevel@tonic-gate#include <sys/psr_compat.h> 467c478bd9Sstevel@tonic-gate#include <sys/syscall.h> 477c478bd9Sstevel@tonic-gate#include <sys/machparam.h> 487c478bd9Sstevel@tonic-gate#include <sys/traptrace.h> 497c478bd9Sstevel@tonic-gate#include <vm/hat_sfmmu.h> 507c478bd9Sstevel@tonic-gate#include <sys/archsystm.h> 517c478bd9Sstevel@tonic-gate#include <sys/utrap.h> 527c478bd9Sstevel@tonic-gate#include <sys/clock.h> 537c478bd9Sstevel@tonic-gate#include <sys/intr.h> 547c478bd9Sstevel@tonic-gate#include <sys/fpu/fpu_simulator.h> 557c478bd9Sstevel@tonic-gate#include <vm/seg_spt.h> 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate/* 587c478bd9Sstevel@tonic-gate * WARNING: If you add a fast trap handler which can be invoked by a 597c478bd9Sstevel@tonic-gate * non-privileged user, you may have to use the FAST_TRAP_DONE macro 607c478bd9Sstevel@tonic-gate * instead of "done" instruction to return back to the user mode. See 617c478bd9Sstevel@tonic-gate * comments for the "fast_trap_done" entry point for more information. 627c478bd9Sstevel@tonic-gate * 637c478bd9Sstevel@tonic-gate * An alternate FAST_TRAP_DONE_CHK_INTR macro should be used for the 647c478bd9Sstevel@tonic-gate * cases where you always want to process any pending interrupts before 657c478bd9Sstevel@tonic-gate * returning back to the user mode. 667c478bd9Sstevel@tonic-gate */ 677c478bd9Sstevel@tonic-gate#define FAST_TRAP_DONE \ 687c478bd9Sstevel@tonic-gate ba,a fast_trap_done 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate#define FAST_TRAP_DONE_CHK_INTR \ 717c478bd9Sstevel@tonic-gate ba,a fast_trap_done_chk_intr 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate/* 747c478bd9Sstevel@tonic-gate * SPARC V9 Trap Table 757c478bd9Sstevel@tonic-gate * 767c478bd9Sstevel@tonic-gate * Most of the trap handlers are made from common building 777c478bd9Sstevel@tonic-gate * blocks, and some are instantiated multiple times within 787c478bd9Sstevel@tonic-gate * the trap table. So, I build a bunch of macros, then 797c478bd9Sstevel@tonic-gate * populate the table using only the macros. 807c478bd9Sstevel@tonic-gate * 817c478bd9Sstevel@tonic-gate * Many macros branch to sys_trap. Its calling convention is: 827c478bd9Sstevel@tonic-gate * %g1 kernel trap handler 837c478bd9Sstevel@tonic-gate * %g2, %g3 args for above 847c478bd9Sstevel@tonic-gate * %g4 desire %pil 857c478bd9Sstevel@tonic-gate */ 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate/* 907c478bd9Sstevel@tonic-gate * Tracing macro. Adds two instructions if TRAPTRACE is defined. 917c478bd9Sstevel@tonic-gate */ 927c478bd9Sstevel@tonic-gate#define TT_TRACE(label) \ 937c478bd9Sstevel@tonic-gate ba label ;\ 947c478bd9Sstevel@tonic-gate rd %pc, %g7 957c478bd9Sstevel@tonic-gate#define TT_TRACE_INS 2 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate#define TT_TRACE_L(label) \ 987c478bd9Sstevel@tonic-gate ba label ;\ 997c478bd9Sstevel@tonic-gate rd %pc, %l4 ;\ 1007c478bd9Sstevel@tonic-gate clr %l4 1017c478bd9Sstevel@tonic-gate#define TT_TRACE_L_INS 3 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate#else 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate#define TT_TRACE(label) 1067c478bd9Sstevel@tonic-gate#define TT_TRACE_INS 0 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate#define TT_TRACE_L(label) 1097c478bd9Sstevel@tonic-gate#define TT_TRACE_L_INS 0 1107c478bd9Sstevel@tonic-gate 1117c478bd9Sstevel@tonic-gate#endif 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate/* 1147c478bd9Sstevel@tonic-gate * This first set are funneled to trap() with %tt as the type. 1157c478bd9Sstevel@tonic-gate * Trap will then either panic or send the user a signal. 1167c478bd9Sstevel@tonic-gate */ 1177c478bd9Sstevel@tonic-gate/* 1187c478bd9Sstevel@tonic-gate * NOT is used for traps that just shouldn't happen. 1197c478bd9Sstevel@tonic-gate * It comes in both single and quadruple flavors. 1207c478bd9Sstevel@tonic-gate */ 1217c478bd9Sstevel@tonic-gate#if !defined(lint) 1227c478bd9Sstevel@tonic-gate .global trap 1237c478bd9Sstevel@tonic-gate#endif /* !lint */ 1247c478bd9Sstevel@tonic-gate#define NOT \ 1257c478bd9Sstevel@tonic-gate TT_TRACE(trace_gen) ;\ 1267c478bd9Sstevel@tonic-gate set trap, %g1 ;\ 1277c478bd9Sstevel@tonic-gate rdpr %tt, %g3 ;\ 1287c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap ;\ 1297c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 ;\ 1307c478bd9Sstevel@tonic-gate .align 32 1317c478bd9Sstevel@tonic-gate#define NOT4 NOT; NOT; NOT; NOT 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate#define NOTP \ 1347c478bd9Sstevel@tonic-gate TT_TRACE(trace_gen) ;\ 1357c478bd9Sstevel@tonic-gate ba,pt %xcc, ptl1_panic ;\ 1367c478bd9Sstevel@tonic-gate mov PTL1_BAD_TRAP, %g1 ;\ 1377c478bd9Sstevel@tonic-gate .align 32 1387c478bd9Sstevel@tonic-gate#define NOTP4 NOTP; NOTP; NOTP; NOTP 1397c478bd9Sstevel@tonic-gate 1401ae08745Sheppo 1417c478bd9Sstevel@tonic-gate/* 1427c478bd9Sstevel@tonic-gate * BAD is used for trap vectors we don't have a kernel 1437c478bd9Sstevel@tonic-gate * handler for. 1447c478bd9Sstevel@tonic-gate * It also comes in single and quadruple versions. 1457c478bd9Sstevel@tonic-gate */ 1467c478bd9Sstevel@tonic-gate#define BAD NOT 1477c478bd9Sstevel@tonic-gate#define BAD4 NOT4 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate#define DONE \ 1507c478bd9Sstevel@tonic-gate done; \ 1517c478bd9Sstevel@tonic-gate .align 32 1527c478bd9Sstevel@tonic-gate 1537c478bd9Sstevel@tonic-gate/* 1547c478bd9Sstevel@tonic-gate * TRAP vectors to the trap() function. 1557c478bd9Sstevel@tonic-gate * It's main use is for user errors. 1567c478bd9Sstevel@tonic-gate */ 1577c478bd9Sstevel@tonic-gate#if !defined(lint) 1587c478bd9Sstevel@tonic-gate .global trap 1597c478bd9Sstevel@tonic-gate#endif /* !lint */ 1607c478bd9Sstevel@tonic-gate#define TRAP(arg) \ 1617c478bd9Sstevel@tonic-gate TT_TRACE(trace_gen) ;\ 1627c478bd9Sstevel@tonic-gate set trap, %g1 ;\ 1637c478bd9Sstevel@tonic-gate mov arg, %g3 ;\ 1647c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap ;\ 1657c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 ;\ 1667c478bd9Sstevel@tonic-gate .align 32 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate/* 16959f2ff5cSedp * SYSCALL is used for unsupported syscall interfaces (with 'which' 17059f2ff5cSedp * set to 'nosys') and legacy support of old SunOS 4.x syscalls (with 17159f2ff5cSedp * 'which' set to 'syscall_trap32'). 17259f2ff5cSedp * 17359f2ff5cSedp * The SYSCALL_TRAP* macros are used for syscall entry points. 17459f2ff5cSedp * SYSCALL_TRAP is used to support LP64 syscalls and SYSCALL_TRAP32 17559f2ff5cSedp * is used to support ILP32. Each macro can only be used once 17659f2ff5cSedp * since they each define a symbol. The symbols are used as hot patch 17759f2ff5cSedp * points by the brand infrastructure to dynamically enable and disable 17859f2ff5cSedp * brand syscall interposition. See the comments around BRAND_CALLBACK 17959f2ff5cSedp * and brand_plat_interposition_enable() for more information. 1807c478bd9Sstevel@tonic-gate */ 1814a75c0c1Sedp#define SYSCALL_NOTT(which) \ 1827c478bd9Sstevel@tonic-gate set (which), %g1 ;\ 183a417a0e0Sjb145095 ba,pt %xcc, user_trap ;\ 1847c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 ;\ 1857c478bd9Sstevel@tonic-gate .align 32 1867c478bd9Sstevel@tonic-gate 18759f2ff5cSedp#define SYSCALL(which) \ 18859f2ff5cSedp TT_TRACE(trace_gen) ;\ 18959f2ff5cSedp SYSCALL_NOTT(which) 19059f2ff5cSedp 19159f2ff5cSedp#define SYSCALL_TRAP32 \ 19259f2ff5cSedp TT_TRACE(trace_gen) ;\ 19359f2ff5cSedp ALTENTRY(syscall_trap32_patch_point) \ 19459f2ff5cSedp SYSCALL_NOTT(syscall_trap32) 19559f2ff5cSedp 19659f2ff5cSedp#define SYSCALL_TRAP \ 19759f2ff5cSedp TT_TRACE(trace_gen) ;\ 19859f2ff5cSedp ALTENTRY(syscall_trap_patch_point) \ 19959f2ff5cSedp SYSCALL_NOTT(syscall_trap) 20059f2ff5cSedp 2017c478bd9Sstevel@tonic-gate/* 2027c478bd9Sstevel@tonic-gate * GOTO just jumps to a label. 2037c478bd9Sstevel@tonic-gate * It's used for things that can be fixed without going thru sys_trap. 2047c478bd9Sstevel@tonic-gate */ 2057c478bd9Sstevel@tonic-gate#define GOTO(label) \ 2067c478bd9Sstevel@tonic-gate .global label ;\ 2077c478bd9Sstevel@tonic-gate ba,a label ;\ 2087c478bd9Sstevel@tonic-gate .empty ;\ 2097c478bd9Sstevel@tonic-gate .align 32 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate/* 2127c478bd9Sstevel@tonic-gate * GOTO_TT just jumps to a label. 2137c478bd9Sstevel@tonic-gate * correctable ECC error traps at level 0 and 1 will use this macro. 2147c478bd9Sstevel@tonic-gate * It's used for things that can be fixed without going thru sys_trap. 2157c478bd9Sstevel@tonic-gate */ 2167c478bd9Sstevel@tonic-gate#define GOTO_TT(label, ttlabel) \ 2177c478bd9Sstevel@tonic-gate .global label ;\ 2187c478bd9Sstevel@tonic-gate TT_TRACE(ttlabel) ;\ 2197c478bd9Sstevel@tonic-gate ba,a label ;\ 2207c478bd9Sstevel@tonic-gate .empty ;\ 2217c478bd9Sstevel@tonic-gate .align 32 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate/* 2247c478bd9Sstevel@tonic-gate * Privileged traps 2257c478bd9Sstevel@tonic-gate * Takes breakpoint if privileged, calls trap() if not. 2267c478bd9Sstevel@tonic-gate */ 2277c478bd9Sstevel@tonic-gate#define PRIV(label) \ 2287c478bd9Sstevel@tonic-gate rdpr %tstate, %g1 ;\ 2297c478bd9Sstevel@tonic-gate btst TSTATE_PRIV, %g1 ;\ 2307c478bd9Sstevel@tonic-gate bnz label ;\ 2317c478bd9Sstevel@tonic-gate rdpr %tt, %g3 ;\ 2327c478bd9Sstevel@tonic-gate set trap, %g1 ;\ 2337c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap ;\ 2347c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 ;\ 2357c478bd9Sstevel@tonic-gate .align 32 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate/* 2397c478bd9Sstevel@tonic-gate * DTrace traps. 2407c478bd9Sstevel@tonic-gate */ 2417c478bd9Sstevel@tonic-gate#define DTRACE_PID \ 2427c478bd9Sstevel@tonic-gate .global dtrace_pid_probe ;\ 2437c478bd9Sstevel@tonic-gate set dtrace_pid_probe, %g1 ;\ 2447c478bd9Sstevel@tonic-gate ba,pt %xcc, user_trap ;\ 2457c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 ;\ 2467c478bd9Sstevel@tonic-gate .align 32 2477c478bd9Sstevel@tonic-gate 2487c478bd9Sstevel@tonic-gate#define DTRACE_RETURN \ 2497c478bd9Sstevel@tonic-gate .global dtrace_return_probe ;\ 2507c478bd9Sstevel@tonic-gate set dtrace_return_probe, %g1 ;\ 2517c478bd9Sstevel@tonic-gate ba,pt %xcc, user_trap ;\ 2527c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 ;\ 2537c478bd9Sstevel@tonic-gate .align 32 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate/* 2567c478bd9Sstevel@tonic-gate * REGISTER WINDOW MANAGEMENT MACROS 2577c478bd9Sstevel@tonic-gate */ 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate/* 2607c478bd9Sstevel@tonic-gate * various convenient units of padding 2617c478bd9Sstevel@tonic-gate */ 2627c478bd9Sstevel@tonic-gate#define SKIP(n) .skip 4*(n) 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate/* 2657c478bd9Sstevel@tonic-gate * CLEAN_WINDOW is the simple handler for cleaning a register window. 2667c478bd9Sstevel@tonic-gate */ 2677c478bd9Sstevel@tonic-gate#define CLEAN_WINDOW \ 2687c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) ;\ 2697c478bd9Sstevel@tonic-gate rdpr %cleanwin, %l0; inc %l0; wrpr %l0, %cleanwin ;\ 2707c478bd9Sstevel@tonic-gate clr %l0; clr %l1; clr %l2; clr %l3 ;\ 2717c478bd9Sstevel@tonic-gate clr %l4; clr %l5; clr %l6; clr %l7 ;\ 2727c478bd9Sstevel@tonic-gate clr %o0; clr %o1; clr %o2; clr %o3 ;\ 2737c478bd9Sstevel@tonic-gate clr %o4; clr %o5; clr %o6; clr %o7 ;\ 2747c478bd9Sstevel@tonic-gate retry; .align 128 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gate#if !defined(lint) 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate/* 2797c478bd9Sstevel@tonic-gate * If we get an unresolved tlb miss while in a window handler, the fault 2807c478bd9Sstevel@tonic-gate * handler will resume execution at the last instruction of the window 2817c478bd9Sstevel@tonic-gate * hander, instead of delivering the fault to the kernel. Spill handlers 2827c478bd9Sstevel@tonic-gate * use this to spill windows into the wbuf. 2837c478bd9Sstevel@tonic-gate * 2847c478bd9Sstevel@tonic-gate * The mixed handler works by checking %sp, and branching to the correct 2857c478bd9Sstevel@tonic-gate * handler. This is done by branching back to label 1: for 32b frames, 2867c478bd9Sstevel@tonic-gate * or label 2: for 64b frames; which implies the handler order is: 32b, 2877c478bd9Sstevel@tonic-gate * 64b, mixed. The 1: and 2: labels are offset into the routines to 2887c478bd9Sstevel@tonic-gate * allow the branchs' delay slots to contain useful instructions. 2897c478bd9Sstevel@tonic-gate */ 2907c478bd9Sstevel@tonic-gate 2917c478bd9Sstevel@tonic-gate/* 2927c478bd9Sstevel@tonic-gate * SPILL_32bit spills a 32-bit-wide kernel register window. It 2937c478bd9Sstevel@tonic-gate * assumes that the kernel context and the nucleus context are the 2947c478bd9Sstevel@tonic-gate * same. The stack pointer is required to be eight-byte aligned even 2957c478bd9Sstevel@tonic-gate * though this code only needs it to be four-byte aligned. 2967c478bd9Sstevel@tonic-gate */ 2977c478bd9Sstevel@tonic-gate#define SPILL_32bit(tail) \ 2987c478bd9Sstevel@tonic-gate srl %sp, 0, %sp ;\ 2997c478bd9Sstevel@tonic-gate1: st %l0, [%sp + 0] ;\ 3007c478bd9Sstevel@tonic-gate st %l1, [%sp + 4] ;\ 3017c478bd9Sstevel@tonic-gate st %l2, [%sp + 8] ;\ 3027c478bd9Sstevel@tonic-gate st %l3, [%sp + 12] ;\ 3037c478bd9Sstevel@tonic-gate st %l4, [%sp + 16] ;\ 3047c478bd9Sstevel@tonic-gate st %l5, [%sp + 20] ;\ 3057c478bd9Sstevel@tonic-gate st %l6, [%sp + 24] ;\ 3067c478bd9Sstevel@tonic-gate st %l7, [%sp + 28] ;\ 3077c478bd9Sstevel@tonic-gate st %i0, [%sp + 32] ;\ 3087c478bd9Sstevel@tonic-gate st %i1, [%sp + 36] ;\ 3097c478bd9Sstevel@tonic-gate st %i2, [%sp + 40] ;\ 3107c478bd9Sstevel@tonic-gate st %i3, [%sp + 44] ;\ 3117c478bd9Sstevel@tonic-gate st %i4, [%sp + 48] ;\ 3127c478bd9Sstevel@tonic-gate st %i5, [%sp + 52] ;\ 3137c478bd9Sstevel@tonic-gate st %i6, [%sp + 56] ;\ 3147c478bd9Sstevel@tonic-gate st %i7, [%sp + 60] ;\ 3157c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) ;\ 3167c478bd9Sstevel@tonic-gate saved ;\ 3177c478bd9Sstevel@tonic-gate retry ;\ 31807e2e5e8Sgirish SKIP(31-19-TT_TRACE_L_INS) ;\ 3197c478bd9Sstevel@tonic-gate ba,a,pt %xcc, fault_32bit_/**/tail ;\ 3207c478bd9Sstevel@tonic-gate .empty 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate/* 3237c478bd9Sstevel@tonic-gate * SPILL_32bit_asi spills a 32-bit-wide register window into a 32-bit 3247c478bd9Sstevel@tonic-gate * wide address space via the designated asi. It is used to spill 3257c478bd9Sstevel@tonic-gate * non-kernel windows. The stack pointer is required to be eight-byte 3267c478bd9Sstevel@tonic-gate * aligned even though this code only needs it to be four-byte 3277c478bd9Sstevel@tonic-gate * aligned. 3287c478bd9Sstevel@tonic-gate */ 3297c478bd9Sstevel@tonic-gate#define SPILL_32bit_asi(asi_num, tail) \ 3307c478bd9Sstevel@tonic-gate srl %sp, 0, %sp ;\ 3317c478bd9Sstevel@tonic-gate1: sta %l0, [%sp + %g0]asi_num ;\ 3327c478bd9Sstevel@tonic-gate mov 4, %g1 ;\ 3337c478bd9Sstevel@tonic-gate sta %l1, [%sp + %g1]asi_num ;\ 3347c478bd9Sstevel@tonic-gate mov 8, %g2 ;\ 3357c478bd9Sstevel@tonic-gate sta %l2, [%sp + %g2]asi_num ;\ 3367c478bd9Sstevel@tonic-gate mov 12, %g3 ;\ 3377c478bd9Sstevel@tonic-gate sta %l3, [%sp + %g3]asi_num ;\ 3387c478bd9Sstevel@tonic-gate add %sp, 16, %g4 ;\ 3397c478bd9Sstevel@tonic-gate sta %l4, [%g4 + %g0]asi_num ;\ 3407c478bd9Sstevel@tonic-gate sta %l5, [%g4 + %g1]asi_num ;\ 3417c478bd9Sstevel@tonic-gate sta %l6, [%g4 + %g2]asi_num ;\ 3427c478bd9Sstevel@tonic-gate sta %l7, [%g4 + %g3]asi_num ;\ 3437c478bd9Sstevel@tonic-gate add %g4, 16, %g4 ;\ 3447c478bd9Sstevel@tonic-gate sta %i0, [%g4 + %g0]asi_num ;\ 3457c478bd9Sstevel@tonic-gate sta %i1, [%g4 + %g1]asi_num ;\ 3467c478bd9Sstevel@tonic-gate sta %i2, [%g4 + %g2]asi_num ;\ 3477c478bd9Sstevel@tonic-gate sta %i3, [%g4 + %g3]asi_num ;\ 3487c478bd9Sstevel@tonic-gate add %g4, 16, %g4 ;\ 3497c478bd9Sstevel@tonic-gate sta %i4, [%g4 + %g0]asi_num ;\ 3507c478bd9Sstevel@tonic-gate sta %i5, [%g4 + %g1]asi_num ;\ 3517c478bd9Sstevel@tonic-gate sta %i6, [%g4 + %g2]asi_num ;\ 3527c478bd9Sstevel@tonic-gate sta %i7, [%g4 + %g3]asi_num ;\ 3537c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) ;\ 3547c478bd9Sstevel@tonic-gate saved ;\ 3557c478bd9Sstevel@tonic-gate retry ;\ 35607e2e5e8Sgirish SKIP(31-25-TT_TRACE_L_INS) ;\ 3577c478bd9Sstevel@tonic-gate ba,a,pt %xcc, fault_32bit_/**/tail ;\ 3587c478bd9Sstevel@tonic-gate .empty 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate#define SPILL_32bit_tt1(asi_num, tail) \ 3617c478bd9Sstevel@tonic-gate ba,a,pt %xcc, fault_32bit_/**/tail ;\ 3627c478bd9Sstevel@tonic-gate .empty ;\ 3637c478bd9Sstevel@tonic-gate .align 128 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate 3667c478bd9Sstevel@tonic-gate/* 3677c478bd9Sstevel@tonic-gate * FILL_32bit fills a 32-bit-wide kernel register window. It assumes 3687c478bd9Sstevel@tonic-gate * that the kernel context and the nucleus context are the same. The 3697c478bd9Sstevel@tonic-gate * stack pointer is required to be eight-byte aligned even though this 3707c478bd9Sstevel@tonic-gate * code only needs it to be four-byte aligned. 3717c478bd9Sstevel@tonic-gate */ 3727c478bd9Sstevel@tonic-gate#define FILL_32bit(tail) \ 3737c478bd9Sstevel@tonic-gate srl %sp, 0, %sp ;\ 3747c478bd9Sstevel@tonic-gate1: TT_TRACE_L(trace_win) ;\ 3757c478bd9Sstevel@tonic-gate ld [%sp + 0], %l0 ;\ 3767c478bd9Sstevel@tonic-gate ld [%sp + 4], %l1 ;\ 3777c478bd9Sstevel@tonic-gate ld [%sp + 8], %l2 ;\ 3787c478bd9Sstevel@tonic-gate ld [%sp + 12], %l3 ;\ 3797c478bd9Sstevel@tonic-gate ld [%sp + 16], %l4 ;\ 3807c478bd9Sstevel@tonic-gate ld [%sp + 20], %l5 ;\ 3817c478bd9Sstevel@tonic-gate ld [%sp + 24], %l6 ;\ 3827c478bd9Sstevel@tonic-gate ld [%sp + 28], %l7 ;\ 3837c478bd9Sstevel@tonic-gate ld [%sp + 32], %i0 ;\ 3847c478bd9Sstevel@tonic-gate ld [%sp + 36], %i1 ;\ 3857c478bd9Sstevel@tonic-gate ld [%sp + 40], %i2 ;\ 3867c478bd9Sstevel@tonic-gate ld [%sp + 44], %i3 ;\ 3877c478bd9Sstevel@tonic-gate ld [%sp + 48], %i4 ;\ 3887c478bd9Sstevel@tonic-gate ld [%sp + 52], %i5 ;\ 3897c478bd9Sstevel@tonic-gate ld [%sp + 56], %i6 ;\ 3907c478bd9Sstevel@tonic-gate ld [%sp + 60], %i7 ;\ 3917c478bd9Sstevel@tonic-gate restored ;\ 3927c478bd9Sstevel@tonic-gate retry ;\ 3937c478bd9Sstevel@tonic-gate SKIP(31-19-TT_TRACE_L_INS) ;\ 3947c478bd9Sstevel@tonic-gate ba,a,pt %xcc, fault_32bit_/**/tail ;\ 3957c478bd9Sstevel@tonic-gate .empty 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate/* 3987c478bd9Sstevel@tonic-gate * FILL_32bit_asi fills a 32-bit-wide register window from a 32-bit 3997c478bd9Sstevel@tonic-gate * wide address space via the designated asi. It is used to fill 4007c478bd9Sstevel@tonic-gate * non-kernel windows. The stack pointer is required to be eight-byte 4017c478bd9Sstevel@tonic-gate * aligned even though this code only needs it to be four-byte 4027c478bd9Sstevel@tonic-gate * aligned. 4037c478bd9Sstevel@tonic-gate */ 4047c478bd9Sstevel@tonic-gate#define FILL_32bit_asi(asi_num, tail) \ 4057c478bd9Sstevel@tonic-gate srl %sp, 0, %sp ;\ 4067c478bd9Sstevel@tonic-gate1: TT_TRACE_L(trace_win) ;\ 4077c478bd9Sstevel@tonic-gate mov 4, %g1 ;\ 4087c478bd9Sstevel@tonic-gate lda [%sp + %g0]asi_num, %l0 ;\ 4097c478bd9Sstevel@tonic-gate mov 8, %g2 ;\ 4107c478bd9Sstevel@tonic-gate lda [%sp + %g1]asi_num, %l1 ;\ 4117c478bd9Sstevel@tonic-gate mov 12, %g3 ;\ 4127c478bd9Sstevel@tonic-gate lda [%sp + %g2]asi_num, %l2 ;\ 4137c478bd9Sstevel@tonic-gate lda [%sp + %g3]asi_num, %l3 ;\ 4147c478bd9Sstevel@tonic-gate add %sp, 16, %g4 ;\ 4157c478bd9Sstevel@tonic-gate lda [%g4 + %g0]asi_num, %l4 ;\ 4167c478bd9Sstevel@tonic-gate lda [%g4 + %g1]asi_num, %l5 ;\ 4177c478bd9Sstevel@tonic-gate lda [%g4 + %g2]asi_num, %l6 ;\ 4187c478bd9Sstevel@tonic-gate lda [%g4 + %g3]asi_num, %l7 ;\ 4197c478bd9Sstevel@tonic-gate add %g4, 16, %g4 ;\ 4207c478bd9Sstevel@tonic-gate lda [%g4 + %g0]asi_num, %i0 ;\ 4217c478bd9Sstevel@tonic-gate lda [%g4 + %g1]asi_num, %i1 ;\ 4227c478bd9Sstevel@tonic-gate lda [%g4 + %g2]asi_num, %i2 ;\ 4237c478bd9Sstevel@tonic-gate lda [%g4 + %g3]asi_num, %i3 ;\ 4247c478bd9Sstevel@tonic-gate add %g4, 16, %g4 ;\ 4257c478bd9Sstevel@tonic-gate lda [%g4 + %g0]asi_num, %i4 ;\ 4267c478bd9Sstevel@tonic-gate lda [%g4 + %g1]asi_num, %i5 ;\ 4277c478bd9Sstevel@tonic-gate lda [%g4 + %g2]asi_num, %i6 ;\ 4287c478bd9Sstevel@tonic-gate lda [%g4 + %g3]asi_num, %i7 ;\ 4297c478bd9Sstevel@tonic-gate restored ;\ 4307c478bd9Sstevel@tonic-gate retry ;\ 4317c478bd9Sstevel@tonic-gate SKIP(31-25-TT_TRACE_L_INS) ;\ 4327c478bd9Sstevel@tonic-gate ba,a,pt %xcc, fault_32bit_/**/tail ;\ 4337c478bd9Sstevel@tonic-gate .empty 4347c478bd9Sstevel@tonic-gate 4357c478bd9Sstevel@tonic-gate 4367c478bd9Sstevel@tonic-gate/* 4377c478bd9Sstevel@tonic-gate * SPILL_64bit spills a 64-bit-wide kernel register window. It 4387c478bd9Sstevel@tonic-gate * assumes that the kernel context and the nucleus context are the 4397c478bd9Sstevel@tonic-gate * same. The stack pointer is required to be eight-byte aligned. 4407c478bd9Sstevel@tonic-gate */ 4417c478bd9Sstevel@tonic-gate#define SPILL_64bit(tail) \ 4427c478bd9Sstevel@tonic-gate2: stx %l0, [%sp + V9BIAS64 + 0] ;\ 4437c478bd9Sstevel@tonic-gate stx %l1, [%sp + V9BIAS64 + 8] ;\ 4447c478bd9Sstevel@tonic-gate stx %l2, [%sp + V9BIAS64 + 16] ;\ 4457c478bd9Sstevel@tonic-gate stx %l3, [%sp + V9BIAS64 + 24] ;\ 4467c478bd9Sstevel@tonic-gate stx %l4, [%sp + V9BIAS64 + 32] ;\ 4477c478bd9Sstevel@tonic-gate stx %l5, [%sp + V9BIAS64 + 40] ;\ 4487c478bd9Sstevel@tonic-gate stx %l6, [%sp + V9BIAS64 + 48] ;\ 4497c478bd9Sstevel@tonic-gate stx %l7, [%sp + V9BIAS64 + 56] ;\ 4507c478bd9Sstevel@tonic-gate stx %i0, [%sp + V9BIAS64 + 64] ;\ 4517c478bd9Sstevel@tonic-gate stx %i1, [%sp + V9BIAS64 + 72] ;\ 4527c478bd9Sstevel@tonic-gate stx %i2, [%sp + V9BIAS64 + 80] ;\ 4537c478bd9Sstevel@tonic-gate stx %i3, [%sp + V9BIAS64 + 88] ;\ 4547c478bd9Sstevel@tonic-gate stx %i4, [%sp + V9BIAS64 + 96] ;\ 4557c478bd9Sstevel@tonic-gate stx %i5, [%sp + V9BIAS64 + 104] ;\ 4567c478bd9Sstevel@tonic-gate stx %i6, [%sp + V9BIAS64 + 112] ;\ 4577c478bd9Sstevel@tonic-gate stx %i7, [%sp + V9BIAS64 + 120] ;\ 4587c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) ;\ 4597c478bd9Sstevel@tonic-gate saved ;\ 4607c478bd9Sstevel@tonic-gate retry ;\ 46107e2e5e8Sgirish SKIP(31-18-TT_TRACE_L_INS) ;\ 4627c478bd9Sstevel@tonic-gate ba,a,pt %xcc, fault_64bit_/**/tail ;\ 4637c478bd9Sstevel@tonic-gate .empty 4647c478bd9Sstevel@tonic-gate 4657c478bd9Sstevel@tonic-gate#define SPILL_64bit_ktt1(tail) \ 4667c478bd9Sstevel@tonic-gate ba,a,pt %xcc, fault_64bit_/**/tail ;\ 4677c478bd9Sstevel@tonic-gate .empty ;\ 4687c478bd9Sstevel@tonic-gate .align 128 4697c478bd9Sstevel@tonic-gate 4707c478bd9Sstevel@tonic-gate#define SPILL_mixed_ktt1(tail) \ 4717c478bd9Sstevel@tonic-gate btst 1, %sp ;\ 4727c478bd9Sstevel@tonic-gate bz,a,pt %xcc, fault_32bit_/**/tail ;\ 4737c478bd9Sstevel@tonic-gate srl %sp, 0, %sp ;\ 4747c478bd9Sstevel@tonic-gate ba,a,pt %xcc, fault_64bit_/**/tail ;\ 4757c478bd9Sstevel@tonic-gate .empty ;\ 4767c478bd9Sstevel@tonic-gate .align 128 4777c478bd9Sstevel@tonic-gate 4787c478bd9Sstevel@tonic-gate/* 4797c478bd9Sstevel@tonic-gate * SPILL_64bit_asi spills a 64-bit-wide register window into a 64-bit 4807c478bd9Sstevel@tonic-gate * wide address space via the designated asi. It is used to spill 4817c478bd9Sstevel@tonic-gate * non-kernel windows. The stack pointer is required to be eight-byte 4827c478bd9Sstevel@tonic-gate * aligned. 4837c478bd9Sstevel@tonic-gate */ 4847c478bd9Sstevel@tonic-gate#define SPILL_64bit_asi(asi_num, tail) \ 4857c478bd9Sstevel@tonic-gate mov 0 + V9BIAS64, %g1 ;\ 4867c478bd9Sstevel@tonic-gate2: stxa %l0, [%sp + %g1]asi_num ;\ 4877c478bd9Sstevel@tonic-gate mov 8 + V9BIAS64, %g2 ;\ 4887c478bd9Sstevel@tonic-gate stxa %l1, [%sp + %g2]asi_num ;\ 4897c478bd9Sstevel@tonic-gate mov 16 + V9BIAS64, %g3 ;\ 4907c478bd9Sstevel@tonic-gate stxa %l2, [%sp + %g3]asi_num ;\ 4917c478bd9Sstevel@tonic-gate mov 24 + V9BIAS64, %g4 ;\ 4927c478bd9Sstevel@tonic-gate stxa %l3, [%sp + %g4]asi_num ;\ 4937c478bd9Sstevel@tonic-gate add %sp, 32, %g5 ;\ 4947c478bd9Sstevel@tonic-gate stxa %l4, [%g5 + %g1]asi_num ;\ 4957c478bd9Sstevel@tonic-gate stxa %l5, [%g5 + %g2]asi_num ;\ 4967c478bd9Sstevel@tonic-gate stxa %l6, [%g5 + %g3]asi_num ;\ 4977c478bd9Sstevel@tonic-gate stxa %l7, [%g5 + %g4]asi_num ;\ 4987c478bd9Sstevel@tonic-gate add %g5, 32, %g5 ;\ 4997c478bd9Sstevel@tonic-gate stxa %i0, [%g5 + %g1]asi_num ;\ 5007c478bd9Sstevel@tonic-gate stxa %i1, [%g5 + %g2]asi_num ;\ 5017c478bd9Sstevel@tonic-gate stxa %i2, [%g5 + %g3]asi_num ;\ 5027c478bd9Sstevel@tonic-gate stxa %i3, [%g5 + %g4]asi_num ;\ 5037c478bd9Sstevel@tonic-gate add %g5, 32, %g5 ;\ 5047c478bd9Sstevel@tonic-gate stxa %i4, [%g5 + %g1]asi_num ;\ 5057c478bd9Sstevel@tonic-gate stxa %i5, [%g5 + %g2]asi_num ;\ 5067c478bd9Sstevel@tonic-gate stxa %i6, [%g5 + %g3]asi_num ;\ 5077c478bd9Sstevel@tonic-gate stxa %i7, [%g5 + %g4]asi_num ;\ 5087c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) ;\ 5097c478bd9Sstevel@tonic-gate saved ;\ 5107c478bd9Sstevel@tonic-gate retry ;\ 51107e2e5e8Sgirish SKIP(31-25-TT_TRACE_L_INS) ;\ 5127c478bd9Sstevel@tonic-gate ba,a,pt %xcc, fault_64bit_/**/tail ;\ 5137c478bd9Sstevel@tonic-gate .empty 5147c478bd9Sstevel@tonic-gate 5157c478bd9Sstevel@tonic-gate#define SPILL_64bit_tt1(asi_num, tail) \ 5167c478bd9Sstevel@tonic-gate ba,a,pt %xcc, fault_64bit_/**/tail ;\ 5177c478bd9Sstevel@tonic-gate .empty ;\ 5187c478bd9Sstevel@tonic-gate .align 128 5197c478bd9Sstevel@tonic-gate 5207c478bd9Sstevel@tonic-gate/* 5217c478bd9Sstevel@tonic-gate * FILL_64bit fills a 64-bit-wide kernel register window. It assumes 5227c478bd9Sstevel@tonic-gate * that the kernel context and the nucleus context are the same. The 5237c478bd9Sstevel@tonic-gate * stack pointer is required to be eight-byte aligned. 5247c478bd9Sstevel@tonic-gate */ 5257c478bd9Sstevel@tonic-gate#define FILL_64bit(tail) \ 5267c478bd9Sstevel@tonic-gate2: TT_TRACE_L(trace_win) ;\ 5277c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 0], %l0 ;\ 5287c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 8], %l1 ;\ 5297c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 16], %l2 ;\ 5307c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 24], %l3 ;\ 5317c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 32], %l4 ;\ 5327c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 40], %l5 ;\ 5337c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 48], %l6 ;\ 5347c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 56], %l7 ;\ 5357c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 64], %i0 ;\ 5367c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 72], %i1 ;\ 5377c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 80], %i2 ;\ 5387c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 88], %i3 ;\ 5397c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 96], %i4 ;\ 5407c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 104], %i5 ;\ 5417c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 112], %i6 ;\ 5427c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 120], %i7 ;\ 5437c478bd9Sstevel@tonic-gate restored ;\ 5447c478bd9Sstevel@tonic-gate retry ;\ 5457c478bd9Sstevel@tonic-gate SKIP(31-18-TT_TRACE_L_INS) ;\ 5467c478bd9Sstevel@tonic-gate ba,a,pt %xcc, fault_64bit_/**/tail ;\ 5477c478bd9Sstevel@tonic-gate .empty 5487c478bd9Sstevel@tonic-gate 5497c478bd9Sstevel@tonic-gate/* 5507c478bd9Sstevel@tonic-gate * FILL_64bit_asi fills a 64-bit-wide register window from a 64-bit 5517c478bd9Sstevel@tonic-gate * wide address space via the designated asi. It is used to fill 5527c478bd9Sstevel@tonic-gate * non-kernel windows. The stack pointer is required to be eight-byte 5537c478bd9Sstevel@tonic-gate * aligned. 5547c478bd9Sstevel@tonic-gate */ 5557c478bd9Sstevel@tonic-gate#define FILL_64bit_asi(asi_num, tail) \ 5567c478bd9Sstevel@tonic-gate mov V9BIAS64 + 0, %g1 ;\ 5577c478bd9Sstevel@tonic-gate2: TT_TRACE_L(trace_win) ;\ 5587c478bd9Sstevel@tonic-gate ldxa [%sp + %g1]asi_num, %l0 ;\ 5597c478bd9Sstevel@tonic-gate mov V9BIAS64 + 8, %g2 ;\ 5607c478bd9Sstevel@tonic-gate ldxa [%sp + %g2]asi_num, %l1 ;\ 5617c478bd9Sstevel@tonic-gate mov V9BIAS64 + 16, %g3 ;\ 5627c478bd9Sstevel@tonic-gate ldxa [%sp + %g3]asi_num, %l2 ;\ 5637c478bd9Sstevel@tonic-gate mov V9BIAS64 + 24, %g4 ;\ 5647c478bd9Sstevel@tonic-gate ldxa [%sp + %g4]asi_num, %l3 ;\ 5657c478bd9Sstevel@tonic-gate add %sp, 32, %g5 ;\ 5667c478bd9Sstevel@tonic-gate ldxa [%g5 + %g1]asi_num, %l4 ;\ 5677c478bd9Sstevel@tonic-gate ldxa [%g5 + %g2]asi_num, %l5 ;\ 5687c478bd9Sstevel@tonic-gate ldxa [%g5 + %g3]asi_num, %l6 ;\ 5697c478bd9Sstevel@tonic-gate ldxa [%g5 + %g4]asi_num, %l7 ;\ 5707c478bd9Sstevel@tonic-gate add %g5, 32, %g5 ;\ 5717c478bd9Sstevel@tonic-gate ldxa [%g5 + %g1]asi_num, %i0 ;\ 5727c478bd9Sstevel@tonic-gate ldxa [%g5 + %g2]asi_num, %i1 ;\ 5737c478bd9Sstevel@tonic-gate ldxa [%g5 + %g3]asi_num, %i2 ;\ 5747c478bd9Sstevel@tonic-gate ldxa [%g5 + %g4]asi_num, %i3 ;\ 5757c478bd9Sstevel@tonic-gate add %g5, 32, %g5 ;\ 5767c478bd9Sstevel@tonic-gate ldxa [%g5 + %g1]asi_num, %i4 ;\ 5777c478bd9Sstevel@tonic-gate ldxa [%g5 + %g2]asi_num, %i5 ;\ 5787c478bd9Sstevel@tonic-gate ldxa [%g5 + %g3]asi_num, %i6 ;\ 5797c478bd9Sstevel@tonic-gate ldxa [%g5 + %g4]asi_num, %i7 ;\ 5807c478bd9Sstevel@tonic-gate restored ;\ 5817c478bd9Sstevel@tonic-gate retry ;\ 5827c478bd9Sstevel@tonic-gate SKIP(31-25-TT_TRACE_L_INS) ;\ 5837c478bd9Sstevel@tonic-gate ba,a,pt %xcc, fault_64bit_/**/tail ;\ 5847c478bd9Sstevel@tonic-gate .empty 5857c478bd9Sstevel@tonic-gate 5867c478bd9Sstevel@tonic-gate 5877c478bd9Sstevel@tonic-gate#endif /* !lint */ 5887c478bd9Sstevel@tonic-gate 5897c478bd9Sstevel@tonic-gate/* 5907c478bd9Sstevel@tonic-gate * SPILL_mixed spills either size window, depending on 5917c478bd9Sstevel@tonic-gate * whether %sp is even or odd, to a 32-bit address space. 5927c478bd9Sstevel@tonic-gate * This may only be used in conjunction with SPILL_32bit/ 5937c478bd9Sstevel@tonic-gate * FILL_64bit. 5947c478bd9Sstevel@tonic-gate * Clear upper 32 bits of %sp if it is odd. 5957c478bd9Sstevel@tonic-gate * We won't need to clear them in 64 bit kernel. 5967c478bd9Sstevel@tonic-gate */ 5977c478bd9Sstevel@tonic-gate#define SPILL_mixed \ 5987c478bd9Sstevel@tonic-gate btst 1, %sp ;\ 5997c478bd9Sstevel@tonic-gate bz,a,pt %xcc, 1b ;\ 6007c478bd9Sstevel@tonic-gate srl %sp, 0, %sp ;\ 6017c478bd9Sstevel@tonic-gate ba,pt %xcc, 2b ;\ 6027c478bd9Sstevel@tonic-gate nop ;\ 6037c478bd9Sstevel@tonic-gate .align 128 6047c478bd9Sstevel@tonic-gate 6057c478bd9Sstevel@tonic-gate/* 6067c478bd9Sstevel@tonic-gate * FILL_mixed(ASI) fills either size window, depending on 6077c478bd9Sstevel@tonic-gate * whether %sp is even or odd, from a 32-bit address space. 6087c478bd9Sstevel@tonic-gate * This may only be used in conjunction with FILL_32bit/ 6097c478bd9Sstevel@tonic-gate * FILL_64bit. New versions of FILL_mixed_{tt1,asi} would be 6107c478bd9Sstevel@tonic-gate * needed for use with FILL_{32,64}bit_{tt1,asi}. Particular 6117c478bd9Sstevel@tonic-gate * attention should be paid to the instructions that belong 6127c478bd9Sstevel@tonic-gate * in the delay slots of the branches depending on the type 6137c478bd9Sstevel@tonic-gate * of fill handler being branched to. 6147c478bd9Sstevel@tonic-gate * Clear upper 32 bits of %sp if it is odd. 6157c478bd9Sstevel@tonic-gate * We won't need to clear them in 64 bit kernel. 6167c478bd9Sstevel@tonic-gate */ 6177c478bd9Sstevel@tonic-gate#define FILL_mixed \ 6187c478bd9Sstevel@tonic-gate btst 1, %sp ;\ 6197c478bd9Sstevel@tonic-gate bz,a,pt %xcc, 1b ;\ 6207c478bd9Sstevel@tonic-gate srl %sp, 0, %sp ;\ 6217c478bd9Sstevel@tonic-gate ba,pt %xcc, 2b ;\ 6227c478bd9Sstevel@tonic-gate nop ;\ 6237c478bd9Sstevel@tonic-gate .align 128 6247c478bd9Sstevel@tonic-gate 6257c478bd9Sstevel@tonic-gate 6267c478bd9Sstevel@tonic-gate/* 6277c478bd9Sstevel@tonic-gate * SPILL_32clean/SPILL_64clean spill 32-bit and 64-bit register windows, 6287c478bd9Sstevel@tonic-gate * respectively, into the address space via the designated asi. The 6297c478bd9Sstevel@tonic-gate * unbiased stack pointer is required to be eight-byte aligned (even for 6307c478bd9Sstevel@tonic-gate * the 32-bit case even though this code does not require such strict 6317c478bd9Sstevel@tonic-gate * alignment). 6327c478bd9Sstevel@tonic-gate * 6337c478bd9Sstevel@tonic-gate * With SPARC v9 the spill trap takes precedence over the cleanwin trap 6347c478bd9Sstevel@tonic-gate * so when cansave == 0, canrestore == 6, and cleanwin == 6 the next save 6357c478bd9Sstevel@tonic-gate * will cause cwp + 2 to be spilled but will not clean cwp + 1. That 6367c478bd9Sstevel@tonic-gate * window may contain kernel data so in user_rtt we set wstate to call 6377c478bd9Sstevel@tonic-gate * these spill handlers on the first user spill trap. These handler then 6387c478bd9Sstevel@tonic-gate * spill the appropriate window but also back up a window and clean the 6397c478bd9Sstevel@tonic-gate * window that didn't get a cleanwin trap. 6407c478bd9Sstevel@tonic-gate */ 6417c478bd9Sstevel@tonic-gate#define SPILL_32clean(asi_num, tail) \ 6427c478bd9Sstevel@tonic-gate srl %sp, 0, %sp ;\ 6437c478bd9Sstevel@tonic-gate sta %l0, [%sp + %g0]asi_num ;\ 6447c478bd9Sstevel@tonic-gate mov 4, %g1 ;\ 6457c478bd9Sstevel@tonic-gate sta %l1, [%sp + %g1]asi_num ;\ 6467c478bd9Sstevel@tonic-gate mov 8, %g2 ;\ 6477c478bd9Sstevel@tonic-gate sta %l2, [%sp + %g2]asi_num ;\ 6487c478bd9Sstevel@tonic-gate mov 12, %g3 ;\ 6497c478bd9Sstevel@tonic-gate sta %l3, [%sp + %g3]asi_num ;\ 6507c478bd9Sstevel@tonic-gate add %sp, 16, %g4 ;\ 6517c478bd9Sstevel@tonic-gate sta %l4, [%g4 + %g0]asi_num ;\ 6527c478bd9Sstevel@tonic-gate sta %l5, [%g4 + %g1]asi_num ;\ 6537c478bd9Sstevel@tonic-gate sta %l6, [%g4 + %g2]asi_num ;\ 6547c478bd9Sstevel@tonic-gate sta %l7, [%g4 + %g3]asi_num ;\ 6557c478bd9Sstevel@tonic-gate add %g4, 16, %g4 ;\ 6567c478bd9Sstevel@tonic-gate sta %i0, [%g4 + %g0]asi_num ;\ 6577c478bd9Sstevel@tonic-gate sta %i1, [%g4 + %g1]asi_num ;\ 6587c478bd9Sstevel@tonic-gate sta %i2, [%g4 + %g2]asi_num ;\ 6597c478bd9Sstevel@tonic-gate sta %i3, [%g4 + %g3]asi_num ;\ 6607c478bd9Sstevel@tonic-gate add %g4, 16, %g4 ;\ 6617c478bd9Sstevel@tonic-gate sta %i4, [%g4 + %g0]asi_num ;\ 6627c478bd9Sstevel@tonic-gate sta %i5, [%g4 + %g1]asi_num ;\ 6637c478bd9Sstevel@tonic-gate sta %i6, [%g4 + %g2]asi_num ;\ 6647c478bd9Sstevel@tonic-gate sta %i7, [%g4 + %g3]asi_num ;\ 6657c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) ;\ 6667c478bd9Sstevel@tonic-gate b .spill_clean ;\ 6677c478bd9Sstevel@tonic-gate mov WSTATE_USER32, %g7 ;\ 66807e2e5e8Sgirish SKIP(31-25-TT_TRACE_L_INS) ;\ 6697c478bd9Sstevel@tonic-gate ba,a,pt %xcc, fault_32bit_/**/tail ;\ 6707c478bd9Sstevel@tonic-gate .empty 6717c478bd9Sstevel@tonic-gate 6727c478bd9Sstevel@tonic-gate#define SPILL_64clean(asi_num, tail) \ 6737c478bd9Sstevel@tonic-gate mov 0 + V9BIAS64, %g1 ;\ 6747c478bd9Sstevel@tonic-gate stxa %l0, [%sp + %g1]asi_num ;\ 6757c478bd9Sstevel@tonic-gate mov 8 + V9BIAS64, %g2 ;\ 6767c478bd9Sstevel@tonic-gate stxa %l1, [%sp + %g2]asi_num ;\ 6777c478bd9Sstevel@tonic-gate mov 16 + V9BIAS64, %g3 ;\ 6787c478bd9Sstevel@tonic-gate stxa %l2, [%sp + %g3]asi_num ;\ 6797c478bd9Sstevel@tonic-gate mov 24 + V9BIAS64, %g4 ;\ 6807c478bd9Sstevel@tonic-gate stxa %l3, [%sp + %g4]asi_num ;\ 6817c478bd9Sstevel@tonic-gate add %sp, 32, %g5 ;\ 6827c478bd9Sstevel@tonic-gate stxa %l4, [%g5 + %g1]asi_num ;\ 6837c478bd9Sstevel@tonic-gate stxa %l5, [%g5 + %g2]asi_num ;\ 6847c478bd9Sstevel@tonic-gate stxa %l6, [%g5 + %g3]asi_num ;\ 6857c478bd9Sstevel@tonic-gate stxa %l7, [%g5 + %g4]asi_num ;\ 6867c478bd9Sstevel@tonic-gate add %g5, 32, %g5 ;\ 6877c478bd9Sstevel@tonic-gate stxa %i0, [%g5 + %g1]asi_num ;\ 6887c478bd9Sstevel@tonic-gate stxa %i1, [%g5 + %g2]asi_num ;\ 6897c478bd9Sstevel@tonic-gate stxa %i2, [%g5 + %g3]asi_num ;\ 6907c478bd9Sstevel@tonic-gate stxa %i3, [%g5 + %g4]asi_num ;\ 6917c478bd9Sstevel@tonic-gate add %g5, 32, %g5 ;\ 6927c478bd9Sstevel@tonic-gate stxa %i4, [%g5 + %g1]asi_num ;\ 6937c478bd9Sstevel@tonic-gate stxa %i5, [%g5 + %g2]asi_num ;\ 6947c478bd9Sstevel@tonic-gate stxa %i6, [%g5 + %g3]asi_num ;\ 6957c478bd9Sstevel@tonic-gate stxa %i7, [%g5 + %g4]asi_num ;\ 6967c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) ;\ 6977c478bd9Sstevel@tonic-gate b .spill_clean ;\ 6987c478bd9Sstevel@tonic-gate mov WSTATE_USER64, %g7 ;\ 69907e2e5e8Sgirish SKIP(31-25-TT_TRACE_L_INS) ;\ 7007c478bd9Sstevel@tonic-gate ba,a,pt %xcc, fault_64bit_/**/tail ;\ 7017c478bd9Sstevel@tonic-gate .empty 7027c478bd9Sstevel@tonic-gate 7037c478bd9Sstevel@tonic-gate 7047c478bd9Sstevel@tonic-gate/* 7057c478bd9Sstevel@tonic-gate * Floating point disabled. 7067c478bd9Sstevel@tonic-gate */ 7077c478bd9Sstevel@tonic-gate#define FP_DISABLED_TRAP \ 7087c478bd9Sstevel@tonic-gate TT_TRACE(trace_gen) ;\ 7097c478bd9Sstevel@tonic-gate ba,pt %xcc,.fp_disabled ;\ 7107c478bd9Sstevel@tonic-gate nop ;\ 7117c478bd9Sstevel@tonic-gate .align 32 7127c478bd9Sstevel@tonic-gate 7137c478bd9Sstevel@tonic-gate/* 7147c478bd9Sstevel@tonic-gate * Floating point exceptions. 7157c478bd9Sstevel@tonic-gate */ 7167c478bd9Sstevel@tonic-gate#define FP_IEEE_TRAP \ 7177c478bd9Sstevel@tonic-gate TT_TRACE(trace_gen) ;\ 7187c478bd9Sstevel@tonic-gate ba,pt %xcc,.fp_ieee_exception ;\ 7197c478bd9Sstevel@tonic-gate nop ;\ 7207c478bd9Sstevel@tonic-gate .align 32 7217c478bd9Sstevel@tonic-gate 7227c478bd9Sstevel@tonic-gate#define FP_TRAP \ 7237c478bd9Sstevel@tonic-gate TT_TRACE(trace_gen) ;\ 7247c478bd9Sstevel@tonic-gate ba,pt %xcc,.fp_exception ;\ 7257c478bd9Sstevel@tonic-gate nop ;\ 7267c478bd9Sstevel@tonic-gate .align 32 7277c478bd9Sstevel@tonic-gate 7287c478bd9Sstevel@tonic-gate#if !defined(lint) 7297c478bd9Sstevel@tonic-gate 7307c478bd9Sstevel@tonic-gate/* 7317c478bd9Sstevel@tonic-gate * ECACHE_ECC error traps at level 0 and level 1 7327c478bd9Sstevel@tonic-gate */ 7337c478bd9Sstevel@tonic-gate#define ECACHE_ECC(table_name) \ 7347c478bd9Sstevel@tonic-gate .global table_name ;\ 7357c478bd9Sstevel@tonic-gatetable_name: ;\ 7367c478bd9Sstevel@tonic-gate membar #Sync ;\ 7377c478bd9Sstevel@tonic-gate set trap, %g1 ;\ 7387c478bd9Sstevel@tonic-gate rdpr %tt, %g3 ;\ 7397c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap ;\ 7407c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 ;\ 7417c478bd9Sstevel@tonic-gate .align 32 7427c478bd9Sstevel@tonic-gate 7437c478bd9Sstevel@tonic-gate#endif /* !lint */ 7447c478bd9Sstevel@tonic-gate 7457c478bd9Sstevel@tonic-gate/* 7467c478bd9Sstevel@tonic-gate * illegal instruction trap 7477c478bd9Sstevel@tonic-gate */ 7487c478bd9Sstevel@tonic-gate#define ILLTRAP_INSTR \ 7497c478bd9Sstevel@tonic-gate membar #Sync ;\ 7507c478bd9Sstevel@tonic-gate TT_TRACE(trace_gen) ;\ 7517c478bd9Sstevel@tonic-gate or %g0, P_UTRAP4, %g2 ;\ 7527c478bd9Sstevel@tonic-gate or %g0, T_UNIMP_INSTR, %g3 ;\ 7537c478bd9Sstevel@tonic-gate sethi %hi(.check_v9utrap), %g4 ;\ 7547c478bd9Sstevel@tonic-gate jmp %g4 + %lo(.check_v9utrap) ;\ 7557c478bd9Sstevel@tonic-gate nop ;\ 7567c478bd9Sstevel@tonic-gate .align 32 7577c478bd9Sstevel@tonic-gate 7587c478bd9Sstevel@tonic-gate/* 7597c478bd9Sstevel@tonic-gate * tag overflow trap 7607c478bd9Sstevel@tonic-gate */ 7617c478bd9Sstevel@tonic-gate#define TAG_OVERFLOW \ 7627c478bd9Sstevel@tonic-gate TT_TRACE(trace_gen) ;\ 7637c478bd9Sstevel@tonic-gate or %g0, P_UTRAP10, %g2 ;\ 7647c478bd9Sstevel@tonic-gate or %g0, T_TAG_OVERFLOW, %g3 ;\ 7657c478bd9Sstevel@tonic-gate sethi %hi(.check_v9utrap), %g4 ;\ 7667c478bd9Sstevel@tonic-gate jmp %g4 + %lo(.check_v9utrap) ;\ 7677c478bd9Sstevel@tonic-gate nop ;\ 7687c478bd9Sstevel@tonic-gate .align 32 7697c478bd9Sstevel@tonic-gate 7707c478bd9Sstevel@tonic-gate/* 7717c478bd9Sstevel@tonic-gate * divide by zero trap 7727c478bd9Sstevel@tonic-gate */ 7737c478bd9Sstevel@tonic-gate#define DIV_BY_ZERO \ 7747c478bd9Sstevel@tonic-gate TT_TRACE(trace_gen) ;\ 7757c478bd9Sstevel@tonic-gate or %g0, P_UTRAP11, %g2 ;\ 7767c478bd9Sstevel@tonic-gate or %g0, T_IDIV0, %g3 ;\ 7777c478bd9Sstevel@tonic-gate sethi %hi(.check_v9utrap), %g4 ;\ 7787c478bd9Sstevel@tonic-gate jmp %g4 + %lo(.check_v9utrap) ;\ 7797c478bd9Sstevel@tonic-gate nop ;\ 7807c478bd9Sstevel@tonic-gate .align 32 7817c478bd9Sstevel@tonic-gate 7827c478bd9Sstevel@tonic-gate/* 7837c478bd9Sstevel@tonic-gate * trap instruction for V9 user trap handlers 7847c478bd9Sstevel@tonic-gate */ 7857c478bd9Sstevel@tonic-gate#define TRAP_INSTR \ 7867c478bd9Sstevel@tonic-gate TT_TRACE(trace_gen) ;\ 7877c478bd9Sstevel@tonic-gate or %g0, T_SOFTWARE_TRAP, %g3 ;\ 7887c478bd9Sstevel@tonic-gate sethi %hi(.check_v9utrap), %g4 ;\ 7897c478bd9Sstevel@tonic-gate jmp %g4 + %lo(.check_v9utrap) ;\ 7907c478bd9Sstevel@tonic-gate nop ;\ 7917c478bd9Sstevel@tonic-gate .align 32 7927c478bd9Sstevel@tonic-gate#define TRP4 TRAP_INSTR; TRAP_INSTR; TRAP_INSTR; TRAP_INSTR 7937c478bd9Sstevel@tonic-gate 7947c478bd9Sstevel@tonic-gate/* 7957c478bd9Sstevel@tonic-gate * LEVEL_INTERRUPT is for level N interrupts. 7967c478bd9Sstevel@tonic-gate * VECTOR_INTERRUPT is for the vector trap. 7977c478bd9Sstevel@tonic-gate */ 7987c478bd9Sstevel@tonic-gate#define LEVEL_INTERRUPT(level) \ 7997c478bd9Sstevel@tonic-gate .global tt_pil/**/level ;\ 8007c478bd9Sstevel@tonic-gatett_pil/**/level: ;\ 8017c478bd9Sstevel@tonic-gate ba,pt %xcc, pil_interrupt ;\ 8027c478bd9Sstevel@tonic-gate mov level, %g4 ;\ 8037c478bd9Sstevel@tonic-gate .align 32 8047c478bd9Sstevel@tonic-gate 8057c478bd9Sstevel@tonic-gate#define LEVEL14_INTERRUPT \ 8067c478bd9Sstevel@tonic-gate ba pil14_interrupt ;\ 8077c478bd9Sstevel@tonic-gate mov PIL_14, %g4 ;\ 8087c478bd9Sstevel@tonic-gate .align 32 8097c478bd9Sstevel@tonic-gate 810b9e93c10SJonathan Haslam#define LEVEL15_INTERRUPT \ 811b9e93c10SJonathan Haslam ba pil15_interrupt ;\ 812b9e93c10SJonathan Haslam mov PIL_15, %g4 ;\ 813b9e93c10SJonathan Haslam .align 32 814b9e93c10SJonathan Haslam 8157c478bd9Sstevel@tonic-gate#define CPU_MONDO \ 8167c478bd9Sstevel@tonic-gate ba,a,pt %xcc, cpu_mondo ;\ 8177c478bd9Sstevel@tonic-gate .align 32 8187c478bd9Sstevel@tonic-gate 8197c478bd9Sstevel@tonic-gate#define DEV_MONDO \ 8207c478bd9Sstevel@tonic-gate ba,a,pt %xcc, dev_mondo ;\ 8217c478bd9Sstevel@tonic-gate .align 32 8227c478bd9Sstevel@tonic-gate 8237c478bd9Sstevel@tonic-gate/* 8241ae08745Sheppo * We take over the rtba after we set our trap table and 8251ae08745Sheppo * fault status area. The watchdog reset trap is now handled by the OS. 8261ae08745Sheppo */ 8271ae08745Sheppo#define WATCHDOG_RESET \ 8281ae08745Sheppo mov PTL1_BAD_WATCHDOG, %g1 ;\ 8291ae08745Sheppo ba,a,pt %xcc, .watchdog_trap ;\ 8301ae08745Sheppo .align 32 8311ae08745Sheppo 8321ae08745Sheppo/* 8331ae08745Sheppo * RED is for traps that use the red mode handler. 8341ae08745Sheppo * We should never see these either. 8351ae08745Sheppo */ 8361ae08745Sheppo#define RED \ 8371ae08745Sheppo mov PTL1_BAD_RED, %g1 ;\ 8381ae08745Sheppo ba,a,pt %xcc, .watchdog_trap ;\ 8391ae08745Sheppo .align 32 8401ae08745Sheppo 8411ae08745Sheppo 8421ae08745Sheppo/* 8437c478bd9Sstevel@tonic-gate * MMU Trap Handlers. 8447c478bd9Sstevel@tonic-gate */ 8457c478bd9Sstevel@tonic-gate 846efaef81fSarao/* 847efaef81fSarao * synthesize for trap(): SFSR in %g3 848efaef81fSarao */ 8497c478bd9Sstevel@tonic-gate#define IMMU_EXCEPTION \ 850c04efe3fSDavid Plauger MMU_FAULT_STATUS_AREA(%g3) ;\ 851c04efe3fSDavid Plauger rdpr %tpc, %g2 ;\ 852c04efe3fSDavid Plauger ldx [%g3 + MMFSA_I_TYPE], %g1 ;\ 853c04efe3fSDavid Plauger ldx [%g3 + MMFSA_I_CTX], %g3 ;\ 854c04efe3fSDavid Plauger sllx %g3, SFSR_CTX_SHIFT, %g3 ;\ 855c04efe3fSDavid Plauger or %g3, %g1, %g3 ;\ 856c04efe3fSDavid Plauger ba,pt %xcc, .mmu_exception_end ;\ 857c04efe3fSDavid Plauger mov T_INSTR_EXCEPTION, %g1 ;\ 8587c478bd9Sstevel@tonic-gate .align 32 8597c478bd9Sstevel@tonic-gate 860efaef81fSarao/* 861efaef81fSarao * synthesize for trap(): TAG_ACCESS in %g2, SFSR in %g3 862efaef81fSarao */ 8637c478bd9Sstevel@tonic-gate#define DMMU_EXCEPTION \ 864efaef81fSarao ba,a,pt %xcc, .dmmu_exception ;\ 8657c478bd9Sstevel@tonic-gate .align 32 8667c478bd9Sstevel@tonic-gate 867efaef81fSarao/* 868efaef81fSarao * synthesize for trap(): SFAR in %g2, SFSR in %g3 869efaef81fSarao */ 8707c478bd9Sstevel@tonic-gate#define DMMU_EXC_AG_PRIV \ 8717c478bd9Sstevel@tonic-gate MMU_FAULT_STATUS_AREA(%g3) ;\ 8727c478bd9Sstevel@tonic-gate ldx [%g3 + MMFSA_D_ADDR], %g2 ;\ 8737c478bd9Sstevel@tonic-gate /* Fault type not available in MMU fault status area */ ;\ 8747c478bd9Sstevel@tonic-gate mov MMFSA_F_PRVACT, %g1 ;\ 8757c478bd9Sstevel@tonic-gate ldx [%g3 + MMFSA_D_CTX], %g3 ;\ 8767c478bd9Sstevel@tonic-gate sllx %g3, SFSR_CTX_SHIFT, %g3 ;\ 8777c478bd9Sstevel@tonic-gate ba,pt %xcc, .mmu_priv_exception ;\ 8787c478bd9Sstevel@tonic-gate or %g3, %g1, %g3 ;\ 8797c478bd9Sstevel@tonic-gate .align 32 8807c478bd9Sstevel@tonic-gate 881efaef81fSarao/* 882efaef81fSarao * synthesize for trap(): SFAR in %g2, SFSR in %g3 883efaef81fSarao */ 8847c478bd9Sstevel@tonic-gate#define DMMU_EXC_AG_NOT_ALIGNED \ 8857c478bd9Sstevel@tonic-gate MMU_FAULT_STATUS_AREA(%g3) ;\ 8867c478bd9Sstevel@tonic-gate ldx [%g3 + MMFSA_D_ADDR], %g2 ;\ 8877c478bd9Sstevel@tonic-gate /* Fault type not available in MMU fault status area */ ;\ 8887c478bd9Sstevel@tonic-gate mov MMFSA_F_UNALIGN, %g1 ;\ 8897c478bd9Sstevel@tonic-gate ldx [%g3 + MMFSA_D_CTX], %g3 ;\ 8907c478bd9Sstevel@tonic-gate sllx %g3, SFSR_CTX_SHIFT, %g3 ;\ 8917c478bd9Sstevel@tonic-gate ba,pt %xcc, .mmu_exception_not_aligned ;\ 892efaef81fSarao or %g3, %g1, %g3 /* SFSR */ ;\ 8937c478bd9Sstevel@tonic-gate .align 32 8947c478bd9Sstevel@tonic-gate/* 8957c478bd9Sstevel@tonic-gate * SPARC V9 IMPL. DEP. #109(1) and (2) and #110(1) and (2) 8967c478bd9Sstevel@tonic-gate */ 8977c478bd9Sstevel@tonic-gate 898efaef81fSarao/* 899efaef81fSarao * synthesize for trap(): SFAR in %g2, SFSR in %g3 900efaef81fSarao */ 9017c478bd9Sstevel@tonic-gate#define DMMU_EXC_LDDF_NOT_ALIGNED \ 9027c478bd9Sstevel@tonic-gate ba,a,pt %xcc, .dmmu_exc_lddf_not_aligned ;\ 9037c478bd9Sstevel@tonic-gate .align 32 904efaef81fSarao/* 905efaef81fSarao * synthesize for trap(): SFAR in %g2, SFSR in %g3 906efaef81fSarao */ 9077c478bd9Sstevel@tonic-gate#define DMMU_EXC_STDF_NOT_ALIGNED \ 9087c478bd9Sstevel@tonic-gate ba,a,pt %xcc, .dmmu_exc_stdf_not_aligned ;\ 9097c478bd9Sstevel@tonic-gate .align 32 9107c478bd9Sstevel@tonic-gate 9117c478bd9Sstevel@tonic-gate#if defined(cscope) 9127c478bd9Sstevel@tonic-gate/* 9137c478bd9Sstevel@tonic-gate * Define labels to direct cscope quickly to labels that 9147c478bd9Sstevel@tonic-gate * are generated by macro expansion of DTLB_MISS(). 9157c478bd9Sstevel@tonic-gate */ 9167c478bd9Sstevel@tonic-gate .global tt0_dtlbmiss 9177c478bd9Sstevel@tonic-gatett0_dtlbmiss: 9187c478bd9Sstevel@tonic-gate .global tt1_dtlbmiss 9197c478bd9Sstevel@tonic-gatett1_dtlbmiss: 9207c478bd9Sstevel@tonic-gate nop 9217c478bd9Sstevel@tonic-gate#endif 9227c478bd9Sstevel@tonic-gate 9237c478bd9Sstevel@tonic-gate/* 9247c478bd9Sstevel@tonic-gate * Data miss handler (must be exactly 32 instructions) 9257c478bd9Sstevel@tonic-gate * 9267c478bd9Sstevel@tonic-gate * This handler is invoked only if the hypervisor has been instructed 9277c478bd9Sstevel@tonic-gate * not to do any TSB walk. 9287c478bd9Sstevel@tonic-gate * 9297c478bd9Sstevel@tonic-gate * Kernel and invalid context cases are handled by the sfmmu_kdtlb_miss 9307c478bd9Sstevel@tonic-gate * handler. 9317c478bd9Sstevel@tonic-gate * 9327c478bd9Sstevel@tonic-gate * User TLB miss handling depends upon whether a user process has one or 9337c478bd9Sstevel@tonic-gate * two TSBs. User TSB information (physical base and size code) is kept 9347c478bd9Sstevel@tonic-gate * in two dedicated scratchpad registers. Absence of a user TSB (primarily 9357c478bd9Sstevel@tonic-gate * second TSB) is indicated by a negative value (-1) in that register. 9367c478bd9Sstevel@tonic-gate */ 9377c478bd9Sstevel@tonic-gate 938efaef81fSarao/* 93960972f37Sjb145095 * synthesize for miss handler: pseudo-tag access in %g2 (with context "type" 94060972f37Sjb145095 * (0=kernel, 1=invalid, or 2=user) rather than context ID) 941efaef81fSarao */ 9427c478bd9Sstevel@tonic-gate#define DTLB_MISS(table_name) ;\ 9437c478bd9Sstevel@tonic-gate .global table_name/**/_dtlbmiss ;\ 9447c478bd9Sstevel@tonic-gatetable_name/**/_dtlbmiss: ;\ 94560972f37Sjb145095 GET_MMU_D_PTAGACC_CTXTYPE(%g2, %g3) /* 8 instr */ ;\ 9467c478bd9Sstevel@tonic-gate cmp %g3, INVALID_CONTEXT ;\ 9477c478bd9Sstevel@tonic-gate ble,pn %xcc, sfmmu_kdtlb_miss ;\ 9487c478bd9Sstevel@tonic-gate srlx %g2, TAG_VALO_SHIFT, %g7 /* g7 = tsb tag */ ;\ 9497c478bd9Sstevel@tonic-gate mov SCRATCHPAD_UTSBREG2, %g1 ;\ 9507c478bd9Sstevel@tonic-gate ldxa [%g1]ASI_SCRATCHPAD, %g1 /* get 2nd tsbreg */ ;\ 95160972f37Sjb145095 brgez,pn %g1, sfmmu_udtlb_slowpath /* branch if 2 TSBs */ ;\ 9527c478bd9Sstevel@tonic-gate nop ;\ 9537c478bd9Sstevel@tonic-gate GET_1ST_TSBE_PTR(%g2, %g1, %g4, %g5) /* 11 instr */ ;\ 9547c478bd9Sstevel@tonic-gate ba,pt %xcc, sfmmu_udtlb_fastpath /* no 4M TSB, miss */ ;\ 9557c478bd9Sstevel@tonic-gate srlx %g2, TAG_VALO_SHIFT, %g7 /* g7 = tsb tag */ ;\ 9567c478bd9Sstevel@tonic-gate .align 128 9577c478bd9Sstevel@tonic-gate 9587c478bd9Sstevel@tonic-gate 9597c478bd9Sstevel@tonic-gate#if defined(cscope) 9607c478bd9Sstevel@tonic-gate/* 9617c478bd9Sstevel@tonic-gate * Define labels to direct cscope quickly to labels that 9627c478bd9Sstevel@tonic-gate * are generated by macro expansion of ITLB_MISS(). 9637c478bd9Sstevel@tonic-gate */ 9647c478bd9Sstevel@tonic-gate .global tt0_itlbmiss 9657c478bd9Sstevel@tonic-gatett0_itlbmiss: 9667c478bd9Sstevel@tonic-gate .global tt1_itlbmiss 9677c478bd9Sstevel@tonic-gatett1_itlbmiss: 9687c478bd9Sstevel@tonic-gate nop 9697c478bd9Sstevel@tonic-gate#endif 9707c478bd9Sstevel@tonic-gate 9717c478bd9Sstevel@tonic-gate/* 9727c478bd9Sstevel@tonic-gate * Instruction miss handler. 9737c478bd9Sstevel@tonic-gate * 9747c478bd9Sstevel@tonic-gate * This handler is invoked only if the hypervisor has been instructed 9757c478bd9Sstevel@tonic-gate * not to do any TSB walk. 9767c478bd9Sstevel@tonic-gate * 9777c478bd9Sstevel@tonic-gate * ldda instructions will have their ASI patched 9787c478bd9Sstevel@tonic-gate * by sfmmu_patch_ktsb at runtime. 9797c478bd9Sstevel@tonic-gate * MUST be EXACTLY 32 instructions or we'll break. 9807c478bd9Sstevel@tonic-gate */ 9817c478bd9Sstevel@tonic-gate 982efaef81fSarao/* 98360972f37Sjb145095 * synthesize for miss handler: TAG_ACCESS in %g2 (with context "type" 98460972f37Sjb145095 * (0=kernel, 1=invalid, or 2=user) rather than context ID) 985efaef81fSarao */ 9867c478bd9Sstevel@tonic-gate#define ITLB_MISS(table_name) \ 9877c478bd9Sstevel@tonic-gate .global table_name/**/_itlbmiss ;\ 9887c478bd9Sstevel@tonic-gatetable_name/**/_itlbmiss: ;\ 98960972f37Sjb145095 GET_MMU_I_PTAGACC_CTXTYPE(%g2, %g3) /* 8 instr */ ;\ 9907c478bd9Sstevel@tonic-gate cmp %g3, INVALID_CONTEXT ;\ 9917c478bd9Sstevel@tonic-gate ble,pn %xcc, sfmmu_kitlb_miss ;\ 9927c478bd9Sstevel@tonic-gate srlx %g2, TAG_VALO_SHIFT, %g7 /* g7 = tsb tag */ ;\ 9937c478bd9Sstevel@tonic-gate mov SCRATCHPAD_UTSBREG2, %g1 ;\ 9947c478bd9Sstevel@tonic-gate ldxa [%g1]ASI_SCRATCHPAD, %g1 /* get 2nd tsbreg */ ;\ 99560972f37Sjb145095 brgez,pn %g1, sfmmu_uitlb_slowpath /* branch if 2 TSBs */ ;\ 9967c478bd9Sstevel@tonic-gate nop ;\ 9977c478bd9Sstevel@tonic-gate GET_1ST_TSBE_PTR(%g2, %g1, %g4, %g5) /* 11 instr */ ;\ 9987c478bd9Sstevel@tonic-gate ba,pt %xcc, sfmmu_uitlb_fastpath /* no 4M TSB, miss */ ;\ 9997c478bd9Sstevel@tonic-gate srlx %g2, TAG_VALO_SHIFT, %g7 /* g7 = tsb tag */ ;\ 10007c478bd9Sstevel@tonic-gate .align 128 10017c478bd9Sstevel@tonic-gate 10027c478bd9Sstevel@tonic-gate#define DTSB_MISS \ 10037c478bd9Sstevel@tonic-gate GOTO_TT(sfmmu_slow_dmmu_miss,trace_dmmu) 10047c478bd9Sstevel@tonic-gate 10057c478bd9Sstevel@tonic-gate#define ITSB_MISS \ 10067c478bd9Sstevel@tonic-gate GOTO_TT(sfmmu_slow_immu_miss,trace_immu) 10077c478bd9Sstevel@tonic-gate 10087c478bd9Sstevel@tonic-gate/* 10097c478bd9Sstevel@tonic-gate * This macro is the first level handler for fast protection faults. 10107c478bd9Sstevel@tonic-gate * It first demaps the tlb entry which generated the fault and then 10117c478bd9Sstevel@tonic-gate * attempts to set the modify bit on the hash. It needs to be 10127c478bd9Sstevel@tonic-gate * exactly 32 instructions. 10137c478bd9Sstevel@tonic-gate */ 1014efaef81fSarao/* 101560972f37Sjb145095 * synthesize for miss handler: TAG_ACCESS in %g2 (with context "type" 101660972f37Sjb145095 * (0=kernel, 1=invalid, or 2=user) rather than context ID) 1017efaef81fSarao */ 10187c478bd9Sstevel@tonic-gate#define DTLB_PROT \ 101960972f37Sjb145095 GET_MMU_D_PTAGACC_CTXTYPE(%g2, %g3) /* 8 instr */ ;\ 10207c478bd9Sstevel@tonic-gate /* ;\ 102160972f37Sjb145095 * g2 = pseudo-tag access register (ctx type rather than ctx ID) ;\ 102260972f37Sjb145095 * g3 = ctx type (0, 1, or 2) ;\ 10237c478bd9Sstevel@tonic-gate */ ;\ 10247c478bd9Sstevel@tonic-gate TT_TRACE(trace_dataprot) /* 2 instr ifdef TRAPTRACE */ ;\ 10257c478bd9Sstevel@tonic-gate /* clobbers g1 and g6 XXXQ? */ ;\ 10267c478bd9Sstevel@tonic-gate brnz,pt %g3, sfmmu_uprot_trap /* user trap */ ;\ 10277c478bd9Sstevel@tonic-gate nop ;\ 10287c478bd9Sstevel@tonic-gate ba,a,pt %xcc, sfmmu_kprot_trap /* kernel trap */ ;\ 10297c478bd9Sstevel@tonic-gate .align 128 10307c478bd9Sstevel@tonic-gate 10317c478bd9Sstevel@tonic-gate#define DMMU_EXCEPTION_TL1 ;\ 10327c478bd9Sstevel@tonic-gate ba,a,pt %xcc, mmu_trap_tl1 ;\ 10337c478bd9Sstevel@tonic-gate .align 32 10347c478bd9Sstevel@tonic-gate 10357c478bd9Sstevel@tonic-gate#define MISALIGN_ADDR_TL1 ;\ 10367c478bd9Sstevel@tonic-gate ba,a,pt %xcc, mmu_trap_tl1 ;\ 10377c478bd9Sstevel@tonic-gate .align 32 10387c478bd9Sstevel@tonic-gate 10397c478bd9Sstevel@tonic-gate/* 10407c478bd9Sstevel@tonic-gate * Trace a tsb hit 10417c478bd9Sstevel@tonic-gate * g1 = tsbe pointer (in/clobbered) 10427c478bd9Sstevel@tonic-gate * g2 = tag access register (in) 10437c478bd9Sstevel@tonic-gate * g3 - g4 = scratch (clobbered) 10447c478bd9Sstevel@tonic-gate * g5 = tsbe data (in) 10457c478bd9Sstevel@tonic-gate * g6 = scratch (clobbered) 10467c478bd9Sstevel@tonic-gate * g7 = pc we jumped here from (in) 10477c478bd9Sstevel@tonic-gate * ttextra = value to OR in to trap type (%tt) (in) 10487c478bd9Sstevel@tonic-gate */ 10497c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE 10507c478bd9Sstevel@tonic-gate#define TRACE_TSBHIT(ttextra) \ 10517c478bd9Sstevel@tonic-gate membar #Sync ;\ 10527c478bd9Sstevel@tonic-gate sethi %hi(FLUSH_ADDR), %g6 ;\ 10537c478bd9Sstevel@tonic-gate flush %g6 ;\ 10547c478bd9Sstevel@tonic-gate TRACE_PTR(%g3, %g6) ;\ 1055*023e71deSHaik Aftandilian GET_TRACE_TICK(%g6, %g4) ;\ 10567c478bd9Sstevel@tonic-gate stxa %g6, [%g3 + TRAP_ENT_TICK]%asi ;\ 10577c478bd9Sstevel@tonic-gate stna %g2, [%g3 + TRAP_ENT_SP]%asi /* tag access */ ;\ 10587c478bd9Sstevel@tonic-gate stna %g5, [%g3 + TRAP_ENT_F1]%asi /* tsb data */ ;\ 10597c478bd9Sstevel@tonic-gate rdpr %tnpc, %g6 ;\ 10607c478bd9Sstevel@tonic-gate stna %g6, [%g3 + TRAP_ENT_F2]%asi ;\ 10617c478bd9Sstevel@tonic-gate stna %g1, [%g3 + TRAP_ENT_F3]%asi /* tsb pointer */ ;\ 10627c478bd9Sstevel@tonic-gate stna %g0, [%g3 + TRAP_ENT_F4]%asi ;\ 10637c478bd9Sstevel@tonic-gate rdpr %tpc, %g6 ;\ 10647c478bd9Sstevel@tonic-gate stna %g6, [%g3 + TRAP_ENT_TPC]%asi ;\ 10657c478bd9Sstevel@tonic-gate TRACE_SAVE_TL_GL_REGS(%g3, %g6) ;\ 10667c478bd9Sstevel@tonic-gate rdpr %tt, %g6 ;\ 10677c478bd9Sstevel@tonic-gate or %g6, (ttextra), %g1 ;\ 10687c478bd9Sstevel@tonic-gate stha %g1, [%g3 + TRAP_ENT_TT]%asi ;\ 10697c478bd9Sstevel@tonic-gate MMU_FAULT_STATUS_AREA(%g4) ;\ 1070efaef81fSarao mov MMFSA_D_ADDR, %g1 ;\ 10717c478bd9Sstevel@tonic-gate cmp %g6, FAST_IMMU_MISS_TT ;\ 1072efaef81fSarao move %xcc, MMFSA_I_ADDR, %g1 ;\ 10737c478bd9Sstevel@tonic-gate cmp %g6, T_INSTR_MMU_MISS ;\ 1074efaef81fSarao move %xcc, MMFSA_I_ADDR, %g1 ;\ 1075efaef81fSarao ldx [%g4 + %g1], %g1 ;\ 1076efaef81fSarao stxa %g1, [%g3 + TRAP_ENT_TSTATE]%asi /* fault addr */ ;\ 1077efaef81fSarao mov MMFSA_D_CTX, %g1 ;\ 10787c478bd9Sstevel@tonic-gate cmp %g6, FAST_IMMU_MISS_TT ;\ 1079efaef81fSarao move %xcc, MMFSA_I_CTX, %g1 ;\ 10807c478bd9Sstevel@tonic-gate cmp %g6, T_INSTR_MMU_MISS ;\ 1081efaef81fSarao move %xcc, MMFSA_I_CTX, %g1 ;\ 1082efaef81fSarao ldx [%g4 + %g1], %g1 ;\ 1083efaef81fSarao stna %g1, [%g3 + TRAP_ENT_TR]%asi ;\ 10847c478bd9Sstevel@tonic-gate TRACE_NEXT(%g3, %g4, %g6) 10857c478bd9Sstevel@tonic-gate#else 10867c478bd9Sstevel@tonic-gate#define TRACE_TSBHIT(ttextra) 10877c478bd9Sstevel@tonic-gate#endif 10887c478bd9Sstevel@tonic-gate 10897c478bd9Sstevel@tonic-gate 10907c478bd9Sstevel@tonic-gate#if defined(lint) 10917c478bd9Sstevel@tonic-gate 10927c478bd9Sstevel@tonic-gatestruct scb trap_table; 10937c478bd9Sstevel@tonic-gatestruct scb scb; /* trap_table/scb are the same object */ 10947c478bd9Sstevel@tonic-gate 10957c478bd9Sstevel@tonic-gate#else /* lint */ 10967c478bd9Sstevel@tonic-gate 10977c478bd9Sstevel@tonic-gate/* 10987c478bd9Sstevel@tonic-gate * ======================================================================= 10997c478bd9Sstevel@tonic-gate * SPARC V9 TRAP TABLE 11007c478bd9Sstevel@tonic-gate * 11017c478bd9Sstevel@tonic-gate * The trap table is divided into two halves: the first half is used when 11027c478bd9Sstevel@tonic-gate * taking traps when TL=0; the second half is used when taking traps from 11037c478bd9Sstevel@tonic-gate * TL>0. Note that handlers in the second half of the table might not be able 11047c478bd9Sstevel@tonic-gate * to make the same assumptions as handlers in the first half of the table. 11057c478bd9Sstevel@tonic-gate * 11067c478bd9Sstevel@tonic-gate * Worst case trap nesting so far: 11077c478bd9Sstevel@tonic-gate * 11087c478bd9Sstevel@tonic-gate * at TL=0 client issues software trap requesting service 11097c478bd9Sstevel@tonic-gate * at TL=1 nucleus wants a register window 11107c478bd9Sstevel@tonic-gate * at TL=2 register window clean/spill/fill takes a TLB miss 11117c478bd9Sstevel@tonic-gate * at TL=3 processing TLB miss 11127c478bd9Sstevel@tonic-gate * at TL=4 handle asynchronous error 11137c478bd9Sstevel@tonic-gate * 11147c478bd9Sstevel@tonic-gate * Note that a trap from TL=4 to TL=5 places Spitfire in "RED mode". 11157c478bd9Sstevel@tonic-gate * 11167c478bd9Sstevel@tonic-gate * ======================================================================= 11177c478bd9Sstevel@tonic-gate */ 11187c478bd9Sstevel@tonic-gate .section ".text" 11197c478bd9Sstevel@tonic-gate .align 4 11207c478bd9Sstevel@tonic-gate .global trap_table, scb, trap_table0, trap_table1, etrap_table 112141f63f87Spetede .type trap_table, #object 112241f63f87Spetede .type trap_table0, #object 112341f63f87Spetede .type trap_table1, #object 112441f63f87Spetede .type scb, #object 11257c478bd9Sstevel@tonic-gatetrap_table: 11267c478bd9Sstevel@tonic-gatescb: 11277c478bd9Sstevel@tonic-gatetrap_table0: 11287c478bd9Sstevel@tonic-gate /* hardware traps */ 11297c478bd9Sstevel@tonic-gate NOT; /* 000 reserved */ 11307c478bd9Sstevel@tonic-gate RED; /* 001 power on reset */ 11311ae08745Sheppo WATCHDOG_RESET; /* 002 watchdog reset */ 11327c478bd9Sstevel@tonic-gate RED; /* 003 externally initiated reset */ 11337c478bd9Sstevel@tonic-gate RED; /* 004 software initiated reset */ 11347c478bd9Sstevel@tonic-gate RED; /* 005 red mode exception */ 11357c478bd9Sstevel@tonic-gate NOT; NOT; /* 006 - 007 reserved */ 11367c478bd9Sstevel@tonic-gate IMMU_EXCEPTION; /* 008 instruction access exception */ 11377c478bd9Sstevel@tonic-gate ITSB_MISS; /* 009 instruction access MMU miss */ 11387c478bd9Sstevel@tonic-gate NOT; /* 00A reserved */ 11397c478bd9Sstevel@tonic-gate NOT; NOT4; /* 00B - 00F reserved */ 11407c478bd9Sstevel@tonic-gate ILLTRAP_INSTR; /* 010 illegal instruction */ 11417c478bd9Sstevel@tonic-gate TRAP(T_PRIV_INSTR); /* 011 privileged opcode */ 11424e8a0fa6Swsm TRAP(T_UNIMP_LDD); /* 012 unimplemented LDD */ 11434e8a0fa6Swsm TRAP(T_UNIMP_STD); /* 013 unimplemented STD */ 11447c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; /* 014 - 01F reserved */ 11457c478bd9Sstevel@tonic-gate FP_DISABLED_TRAP; /* 020 fp disabled */ 11467c478bd9Sstevel@tonic-gate FP_IEEE_TRAP; /* 021 fp exception ieee 754 */ 11477c478bd9Sstevel@tonic-gate FP_TRAP; /* 022 fp exception other */ 11487c478bd9Sstevel@tonic-gate TAG_OVERFLOW; /* 023 tag overflow */ 11497c478bd9Sstevel@tonic-gate CLEAN_WINDOW; /* 024 - 027 clean window */ 11507c478bd9Sstevel@tonic-gate DIV_BY_ZERO; /* 028 division by zero */ 11517c478bd9Sstevel@tonic-gate NOT; /* 029 internal processor error */ 11527c478bd9Sstevel@tonic-gate NOT; NOT; NOT4; /* 02A - 02F reserved */ 11537c478bd9Sstevel@tonic-gate DMMU_EXCEPTION; /* 030 data access exception */ 11547c478bd9Sstevel@tonic-gate DTSB_MISS; /* 031 data access MMU miss */ 11557c478bd9Sstevel@tonic-gate NOT; /* 032 reserved */ 11567c478bd9Sstevel@tonic-gate NOT; /* 033 data access protection */ 11577c478bd9Sstevel@tonic-gate DMMU_EXC_AG_NOT_ALIGNED; /* 034 mem address not aligned */ 11587c478bd9Sstevel@tonic-gate DMMU_EXC_LDDF_NOT_ALIGNED; /* 035 LDDF mem address not aligned */ 11597c478bd9Sstevel@tonic-gate DMMU_EXC_STDF_NOT_ALIGNED; /* 036 STDF mem address not aligned */ 11607c478bd9Sstevel@tonic-gate DMMU_EXC_AG_PRIV; /* 037 privileged action */ 11617c478bd9Sstevel@tonic-gate NOT; /* 038 LDQF mem address not aligned */ 11627c478bd9Sstevel@tonic-gate NOT; /* 039 STQF mem address not aligned */ 11637c478bd9Sstevel@tonic-gate NOT; NOT; NOT4; /* 03A - 03F reserved */ 11647c478bd9Sstevel@tonic-gate NOT; /* 040 async data error */ 11657c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(1); /* 041 interrupt level 1 */ 11667c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(2); /* 042 interrupt level 2 */ 11677c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(3); /* 043 interrupt level 3 */ 11687c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(4); /* 044 interrupt level 4 */ 11697c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(5); /* 045 interrupt level 5 */ 11707c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(6); /* 046 interrupt level 6 */ 11717c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(7); /* 047 interrupt level 7 */ 11727c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(8); /* 048 interrupt level 8 */ 11737c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(9); /* 049 interrupt level 9 */ 11747c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(10); /* 04A interrupt level 10 */ 11757c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(11); /* 04B interrupt level 11 */ 11767c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(12); /* 04C interrupt level 12 */ 11777c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(13); /* 04D interrupt level 13 */ 11787c478bd9Sstevel@tonic-gate LEVEL14_INTERRUPT; /* 04E interrupt level 14 */ 1179b9e93c10SJonathan Haslam LEVEL15_INTERRUPT; /* 04F interrupt level 15 */ 11807c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 050 - 05F reserved */ 11817c478bd9Sstevel@tonic-gate NOT; /* 060 interrupt vector */ 11827c478bd9Sstevel@tonic-gate GOTO(kmdb_trap); /* 061 PA watchpoint */ 11837c478bd9Sstevel@tonic-gate GOTO(kmdb_trap); /* 062 VA watchpoint */ 11847c478bd9Sstevel@tonic-gate NOT; /* 063 reserved */ 11857c478bd9Sstevel@tonic-gate ITLB_MISS(tt0); /* 064 instruction access MMU miss */ 11867c478bd9Sstevel@tonic-gate DTLB_MISS(tt0); /* 068 data access MMU miss */ 11877c478bd9Sstevel@tonic-gate DTLB_PROT; /* 06C data access protection */ 11887c478bd9Sstevel@tonic-gate NOT; /* 070 reserved */ 11897c478bd9Sstevel@tonic-gate NOT; /* 071 reserved */ 11907c478bd9Sstevel@tonic-gate NOT; /* 072 reserved */ 11917c478bd9Sstevel@tonic-gate NOT; /* 073 reserved */ 11927c478bd9Sstevel@tonic-gate NOT4; NOT4 /* 074 - 07B reserved */ 11937c478bd9Sstevel@tonic-gate CPU_MONDO; /* 07C cpu_mondo */ 11947c478bd9Sstevel@tonic-gate DEV_MONDO; /* 07D dev_mondo */ 11957c478bd9Sstevel@tonic-gate GOTO_TT(resumable_error, trace_gen); /* 07E resumable error */ 11967c478bd9Sstevel@tonic-gate GOTO_TT(nonresumable_error, trace_gen); /* 07F non-reasumable error */ 11977c478bd9Sstevel@tonic-gate NOT4; /* 080 spill 0 normal */ 11987c478bd9Sstevel@tonic-gate SPILL_32bit_asi(ASI_AIUP,sn0); /* 084 spill 1 normal */ 11997c478bd9Sstevel@tonic-gate SPILL_64bit_asi(ASI_AIUP,sn0); /* 088 spill 2 normal */ 12007c478bd9Sstevel@tonic-gate SPILL_32clean(ASI_AIUP,sn0); /* 08C spill 3 normal */ 12017c478bd9Sstevel@tonic-gate SPILL_64clean(ASI_AIUP,sn0); /* 090 spill 4 normal */ 12027c478bd9Sstevel@tonic-gate SPILL_32bit(not); /* 094 spill 5 normal */ 12037c478bd9Sstevel@tonic-gate SPILL_64bit(not); /* 098 spill 6 normal */ 12047c478bd9Sstevel@tonic-gate SPILL_mixed; /* 09C spill 7 normal */ 12057c478bd9Sstevel@tonic-gate NOT4; /* 0A0 spill 0 other */ 12067c478bd9Sstevel@tonic-gate SPILL_32bit_asi(ASI_AIUS,so0); /* 0A4 spill 1 other */ 12077c478bd9Sstevel@tonic-gate SPILL_64bit_asi(ASI_AIUS,so0); /* 0A8 spill 2 other */ 12087c478bd9Sstevel@tonic-gate SPILL_32bit_asi(ASI_AIUS,so0); /* 0AC spill 3 other */ 12097c478bd9Sstevel@tonic-gate SPILL_64bit_asi(ASI_AIUS,so0); /* 0B0 spill 4 other */ 12107c478bd9Sstevel@tonic-gate NOT4; /* 0B4 spill 5 other */ 12117c478bd9Sstevel@tonic-gate NOT4; /* 0B8 spill 6 other */ 12127c478bd9Sstevel@tonic-gate NOT4; /* 0BC spill 7 other */ 12137c478bd9Sstevel@tonic-gate NOT4; /* 0C0 fill 0 normal */ 12147c478bd9Sstevel@tonic-gate FILL_32bit_asi(ASI_AIUP,fn0); /* 0C4 fill 1 normal */ 12157c478bd9Sstevel@tonic-gate FILL_64bit_asi(ASI_AIUP,fn0); /* 0C8 fill 2 normal */ 12167c478bd9Sstevel@tonic-gate FILL_32bit_asi(ASI_AIUP,fn0); /* 0CC fill 3 normal */ 12177c478bd9Sstevel@tonic-gate FILL_64bit_asi(ASI_AIUP,fn0); /* 0D0 fill 4 normal */ 12187c478bd9Sstevel@tonic-gate FILL_32bit(not); /* 0D4 fill 5 normal */ 12197c478bd9Sstevel@tonic-gate FILL_64bit(not); /* 0D8 fill 6 normal */ 12207c478bd9Sstevel@tonic-gate FILL_mixed; /* 0DC fill 7 normal */ 12217c478bd9Sstevel@tonic-gate NOT4; /* 0E0 fill 0 other */ 12227c478bd9Sstevel@tonic-gate NOT4; /* 0E4 fill 1 other */ 12237c478bd9Sstevel@tonic-gate NOT4; /* 0E8 fill 2 other */ 12247c478bd9Sstevel@tonic-gate NOT4; /* 0EC fill 3 other */ 12257c478bd9Sstevel@tonic-gate NOT4; /* 0F0 fill 4 other */ 12267c478bd9Sstevel@tonic-gate NOT4; /* 0F4 fill 5 other */ 12277c478bd9Sstevel@tonic-gate NOT4; /* 0F8 fill 6 other */ 12287c478bd9Sstevel@tonic-gate NOT4; /* 0FC fill 7 other */ 12297c478bd9Sstevel@tonic-gate /* user traps */ 12307c478bd9Sstevel@tonic-gate GOTO(syscall_trap_4x); /* 100 old system call */ 12317c478bd9Sstevel@tonic-gate TRAP(T_BREAKPOINT); /* 101 user breakpoint */ 12327c478bd9Sstevel@tonic-gate TRAP(T_DIV0); /* 102 user divide by zero */ 12337c478bd9Sstevel@tonic-gate GOTO(.flushw); /* 103 flush windows */ 12347c478bd9Sstevel@tonic-gate GOTO(.clean_windows); /* 104 clean windows */ 12357c478bd9Sstevel@tonic-gate BAD; /* 105 range check ?? */ 12367c478bd9Sstevel@tonic-gate GOTO(.fix_alignment); /* 106 do unaligned references */ 12377c478bd9Sstevel@tonic-gate BAD; /* 107 unused */ 123859f2ff5cSedp SYSCALL_TRAP32; /* 108 ILP32 system call on LP64 */ 12397c478bd9Sstevel@tonic-gate GOTO(set_trap0_addr); /* 109 set trap0 address */ 12407c478bd9Sstevel@tonic-gate BAD; BAD; BAD4; /* 10A - 10F unused */ 12417c478bd9Sstevel@tonic-gate TRP4; TRP4; TRP4; TRP4; /* 110 - 11F V9 user trap handlers */ 12427c478bd9Sstevel@tonic-gate GOTO(.getcc); /* 120 get condition codes */ 12437c478bd9Sstevel@tonic-gate GOTO(.setcc); /* 121 set condition codes */ 12447c478bd9Sstevel@tonic-gate GOTO(.getpsr); /* 122 get psr */ 12457c478bd9Sstevel@tonic-gate GOTO(.setpsr); /* 123 set psr (some fields) */ 12467c478bd9Sstevel@tonic-gate GOTO(get_timestamp); /* 124 get timestamp */ 12477c478bd9Sstevel@tonic-gate GOTO(get_virtime); /* 125 get lwp virtual time */ 12487c478bd9Sstevel@tonic-gate PRIV(self_xcall); /* 126 self xcall */ 12497c478bd9Sstevel@tonic-gate GOTO(get_hrestime); /* 127 get hrestime */ 12507c478bd9Sstevel@tonic-gate BAD; /* 128 ST_SETV9STACK */ 12517c478bd9Sstevel@tonic-gate GOTO(.getlgrp); /* 129 get lgrpid */ 12527c478bd9Sstevel@tonic-gate BAD; BAD; BAD4; /* 12A - 12F unused */ 12537c478bd9Sstevel@tonic-gate BAD4; BAD4; /* 130 - 137 unused */ 12547c478bd9Sstevel@tonic-gate DTRACE_PID; /* 138 dtrace pid tracing provider */ 1255f498645aSahl BAD; /* 139 unused */ 12567c478bd9Sstevel@tonic-gate DTRACE_RETURN; /* 13A dtrace pid return probe */ 12577c478bd9Sstevel@tonic-gate BAD; BAD4; /* 13B - 13F unused */ 125859f2ff5cSedp SYSCALL_TRAP; /* 140 LP64 system call */ 1259af3c157aSrscott SYSCALL(nosys); /* 141 unused system call trap */ 12607c478bd9Sstevel@tonic-gate#ifdef DEBUG_USER_TRAPTRACECTL 12617c478bd9Sstevel@tonic-gate GOTO(.traptrace_freeze); /* 142 freeze traptrace */ 12627c478bd9Sstevel@tonic-gate GOTO(.traptrace_unfreeze); /* 143 unfreeze traptrace */ 12637c478bd9Sstevel@tonic-gate#else 1264af3c157aSrscott SYSCALL(nosys); /* 142 unused system call trap */ 1265af3c157aSrscott SYSCALL(nosys); /* 143 unused system call trap */ 12667c478bd9Sstevel@tonic-gate#endif 12677c478bd9Sstevel@tonic-gate BAD4; BAD4; BAD4; /* 144 - 14F unused */ 12687c478bd9Sstevel@tonic-gate BAD4; BAD4; BAD4; BAD4; /* 150 - 15F unused */ 12697c478bd9Sstevel@tonic-gate BAD4; BAD4; BAD4; BAD4; /* 160 - 16F unused */ 12707c478bd9Sstevel@tonic-gate BAD; /* 170 - unused */ 12717c478bd9Sstevel@tonic-gate BAD; /* 171 - unused */ 12727c478bd9Sstevel@tonic-gate BAD; BAD; /* 172 - 173 unused */ 12737c478bd9Sstevel@tonic-gate BAD4; BAD4; /* 174 - 17B unused */ 12747c478bd9Sstevel@tonic-gate#ifdef PTL1_PANIC_DEBUG 12757c478bd9Sstevel@tonic-gate mov PTL1_BAD_DEBUG, %g1; GOTO(ptl1_panic); 12767c478bd9Sstevel@tonic-gate /* 17C test ptl1_panic */ 12777c478bd9Sstevel@tonic-gate#else 12787c478bd9Sstevel@tonic-gate BAD; /* 17C unused */ 12797c478bd9Sstevel@tonic-gate#endif /* PTL1_PANIC_DEBUG */ 12807c478bd9Sstevel@tonic-gate PRIV(kmdb_trap); /* 17D kmdb enter (L1-A) */ 12817c478bd9Sstevel@tonic-gate PRIV(kmdb_trap); /* 17E kmdb breakpoint */ 12827c478bd9Sstevel@tonic-gate PRIV(obp_bpt); /* 17F obp breakpoint */ 12837c478bd9Sstevel@tonic-gate /* reserved */ 12847c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 180 - 18F reserved */ 12857c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 190 - 19F reserved */ 12867c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 1A0 - 1AF reserved */ 12877c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 1B0 - 1BF reserved */ 12887c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 1C0 - 1CF reserved */ 12897c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 1D0 - 1DF reserved */ 12907c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 1E0 - 1EF reserved */ 12917c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 1F0 - 1FF reserved */ 12927c478bd9Sstevel@tonic-gate .size trap_table0, (.-trap_table0) 12937c478bd9Sstevel@tonic-gatetrap_table1: 12947c478bd9Sstevel@tonic-gate NOT4; NOT4; /* 000 - 007 unused */ 12957c478bd9Sstevel@tonic-gate NOT; /* 008 instruction access exception */ 12967c478bd9Sstevel@tonic-gate ITSB_MISS; /* 009 instruction access MMU miss */ 12977c478bd9Sstevel@tonic-gate NOT; /* 00A reserved */ 12987c478bd9Sstevel@tonic-gate NOT; NOT4; /* 00B - 00F unused */ 12997c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 010 - 01F unused */ 13007c478bd9Sstevel@tonic-gate NOT4; /* 020 - 023 unused */ 13017c478bd9Sstevel@tonic-gate CLEAN_WINDOW; /* 024 - 027 clean window */ 13027c478bd9Sstevel@tonic-gate NOT4; NOT4; /* 028 - 02F unused */ 13037c478bd9Sstevel@tonic-gate DMMU_EXCEPTION_TL1; /* 030 data access exception */ 13047c478bd9Sstevel@tonic-gate DTSB_MISS; /* 031 data access MMU miss */ 13057c478bd9Sstevel@tonic-gate NOT; /* 032 reserved */ 13067c478bd9Sstevel@tonic-gate NOT; /* 033 unused */ 13077c478bd9Sstevel@tonic-gate MISALIGN_ADDR_TL1; /* 034 mem address not aligned */ 13087c478bd9Sstevel@tonic-gate NOT; NOT; NOT; NOT4; NOT4 /* 035 - 03F unused */ 13097c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 040 - 04F unused */ 13107c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 050 - 05F unused */ 13117c478bd9Sstevel@tonic-gate NOT; /* 060 unused */ 13127c478bd9Sstevel@tonic-gate GOTO(kmdb_trap_tl1); /* 061 PA watchpoint */ 13137c478bd9Sstevel@tonic-gate GOTO(kmdb_trap_tl1); /* 062 VA watchpoint */ 13147c478bd9Sstevel@tonic-gate NOT; /* 063 reserved */ 13157c478bd9Sstevel@tonic-gate ITLB_MISS(tt1); /* 064 instruction access MMU miss */ 13167c478bd9Sstevel@tonic-gate DTLB_MISS(tt1); /* 068 data access MMU miss */ 13177c478bd9Sstevel@tonic-gate DTLB_PROT; /* 06C data access protection */ 13187c478bd9Sstevel@tonic-gate NOT; /* 070 reserved */ 13197c478bd9Sstevel@tonic-gate NOT; /* 071 reserved */ 13207c478bd9Sstevel@tonic-gate NOT; /* 072 reserved */ 13217c478bd9Sstevel@tonic-gate NOT; /* 073 reserved */ 132218aea0b1Swh94709 NOT4; NOT4; /* 074 - 07B reserved */ 132318aea0b1Swh94709 NOT; /* 07C reserved */ 132418aea0b1Swh94709 NOT; /* 07D reserved */ 132518aea0b1Swh94709 NOT; /* 07E resumable error */ 132618aea0b1Swh94709 GOTO_TT(nonresumable_error, trace_gen); /* 07F nonresumable error */ 13277c478bd9Sstevel@tonic-gate NOTP4; /* 080 spill 0 normal */ 13287c478bd9Sstevel@tonic-gate SPILL_32bit_tt1(ASI_AIUP,sn1); /* 084 spill 1 normal */ 13297c478bd9Sstevel@tonic-gate SPILL_64bit_tt1(ASI_AIUP,sn1); /* 088 spill 2 normal */ 13307c478bd9Sstevel@tonic-gate SPILL_32bit_tt1(ASI_AIUP,sn1); /* 08C spill 3 normal */ 13317c478bd9Sstevel@tonic-gate SPILL_64bit_tt1(ASI_AIUP,sn1); /* 090 spill 4 normal */ 13327c478bd9Sstevel@tonic-gate NOTP4; /* 094 spill 5 normal */ 13337c478bd9Sstevel@tonic-gate SPILL_64bit_ktt1(sk); /* 098 spill 6 normal */ 13347c478bd9Sstevel@tonic-gate SPILL_mixed_ktt1(sk); /* 09C spill 7 normal */ 13357c478bd9Sstevel@tonic-gate NOTP4; /* 0A0 spill 0 other */ 13367c478bd9Sstevel@tonic-gate SPILL_32bit_tt1(ASI_AIUS,so1); /* 0A4 spill 1 other */ 13377c478bd9Sstevel@tonic-gate SPILL_64bit_tt1(ASI_AIUS,so1); /* 0A8 spill 2 other */ 13387c478bd9Sstevel@tonic-gate SPILL_32bit_tt1(ASI_AIUS,so1); /* 0AC spill 3 other */ 13397c478bd9Sstevel@tonic-gate SPILL_64bit_tt1(ASI_AIUS,so1); /* 0B0 spill 4 other */ 13407c478bd9Sstevel@tonic-gate NOTP4; /* 0B4 spill 5 other */ 13417c478bd9Sstevel@tonic-gate NOTP4; /* 0B8 spill 6 other */ 13427c478bd9Sstevel@tonic-gate NOTP4; /* 0BC spill 7 other */ 13437c478bd9Sstevel@tonic-gate NOT4; /* 0C0 fill 0 normal */ 13447c478bd9Sstevel@tonic-gate NOT4; /* 0C4 fill 1 normal */ 13457c478bd9Sstevel@tonic-gate NOT4; /* 0C8 fill 2 normal */ 13467c478bd9Sstevel@tonic-gate NOT4; /* 0CC fill 3 normal */ 13477c478bd9Sstevel@tonic-gate NOT4; /* 0D0 fill 4 normal */ 13487c478bd9Sstevel@tonic-gate NOT4; /* 0D4 fill 5 normal */ 13497c478bd9Sstevel@tonic-gate NOT4; /* 0D8 fill 6 normal */ 13507c478bd9Sstevel@tonic-gate NOT4; /* 0DC fill 7 normal */ 13517c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 0E0 - 0EF unused */ 13527c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 0F0 - 0FF unused */ 13537c478bd9Sstevel@tonic-gate/* 13547c478bd9Sstevel@tonic-gate * Code running at TL>0 does not use soft traps, so 13557c478bd9Sstevel@tonic-gate * we can truncate the table here. 13567c478bd9Sstevel@tonic-gate * However: 13577c478bd9Sstevel@tonic-gate * sun4v uses (hypervisor) ta instructions at TL > 0, so 13587c478bd9Sstevel@tonic-gate * provide a safety net for now. 13597c478bd9Sstevel@tonic-gate */ 13607c478bd9Sstevel@tonic-gate /* soft traps */ 13617c478bd9Sstevel@tonic-gate BAD4; BAD4; BAD4; BAD4; /* 100 - 10F unused */ 13627c478bd9Sstevel@tonic-gate BAD4; BAD4; BAD4; BAD4; /* 110 - 11F unused */ 13637c478bd9Sstevel@tonic-gate BAD4; BAD4; BAD4; BAD4; /* 120 - 12F unused */ 13647c478bd9Sstevel@tonic-gate BAD4; BAD4; BAD4; BAD4; /* 130 - 13F unused */ 13657c478bd9Sstevel@tonic-gate BAD4; BAD4; BAD4; BAD4; /* 140 - 14F unused */ 13667c478bd9Sstevel@tonic-gate BAD4; BAD4; BAD4; BAD4; /* 150 - 15F unused */ 13677c478bd9Sstevel@tonic-gate BAD4; BAD4; BAD4; BAD4; /* 160 - 16F unused */ 13687c478bd9Sstevel@tonic-gate BAD4; BAD4; BAD4; BAD4; /* 170 - 17F unused */ 13697c478bd9Sstevel@tonic-gate /* reserved */ 13707c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 180 - 18F reserved */ 13717c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 190 - 19F reserved */ 13727c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 1A0 - 1AF reserved */ 13737c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 1B0 - 1BF reserved */ 13747c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 1C0 - 1CF reserved */ 13757c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 1D0 - 1DF reserved */ 13767c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 1E0 - 1EF reserved */ 13777c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 1F0 - 1FF reserved */ 13787c478bd9Sstevel@tonic-gateetrap_table: 13797c478bd9Sstevel@tonic-gate .size trap_table1, (.-trap_table1) 13807c478bd9Sstevel@tonic-gate .size trap_table, (.-trap_table) 13817c478bd9Sstevel@tonic-gate .size scb, (.-scb) 13827c478bd9Sstevel@tonic-gate 13837c478bd9Sstevel@tonic-gate/* 13847c478bd9Sstevel@tonic-gate * We get to exec_fault in the case of an instruction miss and tte 13857c478bd9Sstevel@tonic-gate * has no execute bit set. We go to tl0 to handle it. 13867c478bd9Sstevel@tonic-gate * 13877c478bd9Sstevel@tonic-gate * g1 = tsbe pointer (in/clobbered) 13887c478bd9Sstevel@tonic-gate * g2 = tag access register (in) 13897c478bd9Sstevel@tonic-gate * g3 - g4 = scratch (clobbered) 13907c478bd9Sstevel@tonic-gate * g5 = tsbe data (in) 13917c478bd9Sstevel@tonic-gate * g6 = scratch (clobbered) 13927c478bd9Sstevel@tonic-gate * g7 = pc we jumped here from (in) 13937c478bd9Sstevel@tonic-gate */ 1394efaef81fSarao/* 139560972f37Sjb145095 * synthesize for miss handler: TAG_ACCESS in %g2 (with context "type" 139660972f37Sjb145095 * (0=kernel, 1=invalid, or 2=user) rather than context ID) 1397efaef81fSarao */ 13987c478bd9Sstevel@tonic-gate ALTENTRY(exec_fault) 13997c478bd9Sstevel@tonic-gate TRACE_TSBHIT(TT_MMU_EXEC) 14007c478bd9Sstevel@tonic-gate MMU_FAULT_STATUS_AREA(%g4) 14017c478bd9Sstevel@tonic-gate ldx [%g4 + MMFSA_I_ADDR], %g2 /* g2 = address */ 14027c478bd9Sstevel@tonic-gate ldx [%g4 + MMFSA_I_CTX], %g3 /* g3 = ctx */ 14037c478bd9Sstevel@tonic-gate srlx %g2, MMU_PAGESHIFT, %g2 ! align address to page boundry 140460972f37Sjb145095 cmp %g3, USER_CONTEXT_TYPE 14057c478bd9Sstevel@tonic-gate sllx %g2, MMU_PAGESHIFT, %g2 140660972f37Sjb145095 movgu %icc, USER_CONTEXT_TYPE, %g3 1407efaef81fSarao or %g2, %g3, %g2 /* TAG_ACCESS */ 14087c478bd9Sstevel@tonic-gate mov T_INSTR_MMU_MISS, %g3 ! arg2 = traptype 14097c478bd9Sstevel@tonic-gate set trap, %g1 14107c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap 14117c478bd9Sstevel@tonic-gate mov -1, %g4 14127c478bd9Sstevel@tonic-gate 14137c478bd9Sstevel@tonic-gate.mmu_exception_not_aligned: 14147c478bd9Sstevel@tonic-gate /* %g2 = sfar, %g3 = sfsr */ 14157c478bd9Sstevel@tonic-gate rdpr %tstate, %g1 14167c478bd9Sstevel@tonic-gate btst TSTATE_PRIV, %g1 14177c478bd9Sstevel@tonic-gate bnz,pn %icc, 2f 14187c478bd9Sstevel@tonic-gate nop 14197c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) ! load CPU struct addr 14207c478bd9Sstevel@tonic-gate ldn [%g1 + CPU_THREAD], %g1 ! load thread pointer 14217c478bd9Sstevel@tonic-gate ldn [%g1 + T_PROCP], %g1 ! load proc pointer 14227c478bd9Sstevel@tonic-gate ldn [%g1 + P_UTRAPS], %g5 ! are there utraps? 14237c478bd9Sstevel@tonic-gate brz,pt %g5, 2f 14247c478bd9Sstevel@tonic-gate nop 14257c478bd9Sstevel@tonic-gate ldn [%g5 + P_UTRAP15], %g5 ! unaligned utrap? 14267c478bd9Sstevel@tonic-gate brz,pn %g5, 2f 14277c478bd9Sstevel@tonic-gate nop 14287c478bd9Sstevel@tonic-gate btst 1, %sp 14297c478bd9Sstevel@tonic-gate bz,pt %xcc, 1f ! 32 bit user program 14307c478bd9Sstevel@tonic-gate nop 14317c478bd9Sstevel@tonic-gate ba,pt %xcc, .setup_v9utrap ! 64 bit user program 14327c478bd9Sstevel@tonic-gate nop 14337c478bd9Sstevel@tonic-gate1: 14347c478bd9Sstevel@tonic-gate ba,pt %xcc, .setup_utrap 14357c478bd9Sstevel@tonic-gate or %g2, %g0, %g7 14367c478bd9Sstevel@tonic-gate2: 14377c478bd9Sstevel@tonic-gate ba,pt %xcc, .mmu_exception_end 14387c478bd9Sstevel@tonic-gate mov T_ALIGNMENT, %g1 14397c478bd9Sstevel@tonic-gate 14407c478bd9Sstevel@tonic-gate.mmu_priv_exception: 14417c478bd9Sstevel@tonic-gate rdpr %tstate, %g1 14427c478bd9Sstevel@tonic-gate btst TSTATE_PRIV, %g1 14437c478bd9Sstevel@tonic-gate bnz,pn %icc, 1f 14447c478bd9Sstevel@tonic-gate nop 14457c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) ! load CPU struct addr 14467c478bd9Sstevel@tonic-gate ldn [%g1 + CPU_THREAD], %g1 ! load thread pointer 14477c478bd9Sstevel@tonic-gate ldn [%g1 + T_PROCP], %g1 ! load proc pointer 14487c478bd9Sstevel@tonic-gate ldn [%g1 + P_UTRAPS], %g5 ! are there utraps? 14497c478bd9Sstevel@tonic-gate brz,pt %g5, 1f 14507c478bd9Sstevel@tonic-gate nop 14517c478bd9Sstevel@tonic-gate ldn [%g5 + P_UTRAP16], %g5 14527c478bd9Sstevel@tonic-gate brnz,pt %g5, .setup_v9utrap 14537c478bd9Sstevel@tonic-gate nop 14547c478bd9Sstevel@tonic-gate1: 14557c478bd9Sstevel@tonic-gate mov T_PRIV_INSTR, %g1 14567c478bd9Sstevel@tonic-gate 14577c478bd9Sstevel@tonic-gate.mmu_exception_end: 14587c478bd9Sstevel@tonic-gate CPU_INDEX(%g4, %g5) 14597c478bd9Sstevel@tonic-gate set cpu_core, %g5 14607c478bd9Sstevel@tonic-gate sllx %g4, CPU_CORE_SHIFT, %g4 14617c478bd9Sstevel@tonic-gate add %g4, %g5, %g4 14627c478bd9Sstevel@tonic-gate lduh [%g4 + CPUC_DTRACE_FLAGS], %g5 14637c478bd9Sstevel@tonic-gate andcc %g5, CPU_DTRACE_NOFAULT, %g0 14647c478bd9Sstevel@tonic-gate bz 1f 14657c478bd9Sstevel@tonic-gate or %g5, CPU_DTRACE_BADADDR, %g5 14667c478bd9Sstevel@tonic-gate stuh %g5, [%g4 + CPUC_DTRACE_FLAGS] 14677c478bd9Sstevel@tonic-gate done 14687c478bd9Sstevel@tonic-gate 14697c478bd9Sstevel@tonic-gate1: 14707c478bd9Sstevel@tonic-gate sllx %g3, 32, %g3 14717c478bd9Sstevel@tonic-gate or %g3, %g1, %g3 14727c478bd9Sstevel@tonic-gate set trap, %g1 14737c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap 14747c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 14757c478bd9Sstevel@tonic-gate 14767c478bd9Sstevel@tonic-gate.fp_disabled: 14777c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) ! load CPU struct addr 14787c478bd9Sstevel@tonic-gate ldn [%g1 + CPU_THREAD], %g1 ! load thread pointer 14797c478bd9Sstevel@tonic-gate rdpr %tstate, %g4 14807c478bd9Sstevel@tonic-gate btst TSTATE_PRIV, %g4 14817c478bd9Sstevel@tonic-gate bnz,a,pn %icc, ptl1_panic 14827c478bd9Sstevel@tonic-gate mov PTL1_BAD_FPTRAP, %g1 14837c478bd9Sstevel@tonic-gate 14847c478bd9Sstevel@tonic-gate ldn [%g1 + T_PROCP], %g1 ! load proc pointer 14857c478bd9Sstevel@tonic-gate ldn [%g1 + P_UTRAPS], %g5 ! are there utraps? 14867c478bd9Sstevel@tonic-gate brz,a,pt %g5, 2f 14877c478bd9Sstevel@tonic-gate nop 14887c478bd9Sstevel@tonic-gate ldn [%g5 + P_UTRAP7], %g5 ! fp_disabled utrap? 14897c478bd9Sstevel@tonic-gate brz,a,pn %g5, 2f 14907c478bd9Sstevel@tonic-gate nop 14917c478bd9Sstevel@tonic-gate btst 1, %sp 14927c478bd9Sstevel@tonic-gate bz,a,pt %xcc, 1f ! 32 bit user program 14937c478bd9Sstevel@tonic-gate nop 14947c478bd9Sstevel@tonic-gate ba,a,pt %xcc, .setup_v9utrap ! 64 bit user program 14957c478bd9Sstevel@tonic-gate nop 14967c478bd9Sstevel@tonic-gate1: 14977c478bd9Sstevel@tonic-gate ba,pt %xcc, .setup_utrap 14987c478bd9Sstevel@tonic-gate or %g0, %g0, %g7 14997c478bd9Sstevel@tonic-gate2: 15007c478bd9Sstevel@tonic-gate set fp_disabled, %g1 15017c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap 15027c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 15037c478bd9Sstevel@tonic-gate 15047c478bd9Sstevel@tonic-gate.fp_ieee_exception: 15057c478bd9Sstevel@tonic-gate rdpr %tstate, %g1 15067c478bd9Sstevel@tonic-gate btst TSTATE_PRIV, %g1 15077c478bd9Sstevel@tonic-gate bnz,a,pn %icc, ptl1_panic 15087c478bd9Sstevel@tonic-gate mov PTL1_BAD_FPTRAP, %g1 15097c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) ! load CPU struct addr 15107c478bd9Sstevel@tonic-gate stx %fsr, [%g1 + CPU_TMP1] 15117c478bd9Sstevel@tonic-gate ldx [%g1 + CPU_TMP1], %g2 15127c478bd9Sstevel@tonic-gate ldn [%g1 + CPU_THREAD], %g1 ! load thread pointer 15137c478bd9Sstevel@tonic-gate ldn [%g1 + T_PROCP], %g1 ! load proc pointer 15147c478bd9Sstevel@tonic-gate ldn [%g1 + P_UTRAPS], %g5 ! are there utraps? 15157c478bd9Sstevel@tonic-gate brz,a,pt %g5, 1f 15167c478bd9Sstevel@tonic-gate nop 15177c478bd9Sstevel@tonic-gate ldn [%g5 + P_UTRAP8], %g5 15187c478bd9Sstevel@tonic-gate brnz,a,pt %g5, .setup_v9utrap 15197c478bd9Sstevel@tonic-gate nop 15207c478bd9Sstevel@tonic-gate1: 15217c478bd9Sstevel@tonic-gate set _fp_ieee_exception, %g1 15227c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap 15237c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 15247c478bd9Sstevel@tonic-gate 15257c478bd9Sstevel@tonic-gate/* 15267c478bd9Sstevel@tonic-gate * Register Inputs: 15277c478bd9Sstevel@tonic-gate * %g5 user trap handler 15287c478bd9Sstevel@tonic-gate * %g7 misaligned addr - for alignment traps only 15297c478bd9Sstevel@tonic-gate */ 15307c478bd9Sstevel@tonic-gate.setup_utrap: 15317c478bd9Sstevel@tonic-gate set trap, %g1 ! setup in case we go 15327c478bd9Sstevel@tonic-gate mov T_FLUSH_PCB, %g3 ! through sys_trap on 15337c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 ! the save instruction below 15347c478bd9Sstevel@tonic-gate 15357c478bd9Sstevel@tonic-gate /* 15367c478bd9Sstevel@tonic-gate * If the DTrace pid provider is single stepping a copied-out 15377c478bd9Sstevel@tonic-gate * instruction, t->t_dtrace_step will be set. In that case we need 15387c478bd9Sstevel@tonic-gate * to abort the single-stepping (since execution of the instruction 15397c478bd9Sstevel@tonic-gate * was interrupted) and use the value of t->t_dtrace_npc as the %npc. 15407c478bd9Sstevel@tonic-gate */ 15417c478bd9Sstevel@tonic-gate save %sp, -SA(MINFRAME32), %sp ! window for trap handler 15427c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) ! load CPU struct addr 15437c478bd9Sstevel@tonic-gate ldn [%g1 + CPU_THREAD], %g1 ! load thread pointer 15447c478bd9Sstevel@tonic-gate ldub [%g1 + T_DTRACE_STEP], %g2 ! load t->t_dtrace_step 15457c478bd9Sstevel@tonic-gate rdpr %tnpc, %l2 ! arg1 == tnpc 15467c478bd9Sstevel@tonic-gate brz,pt %g2, 1f 15477c478bd9Sstevel@tonic-gate rdpr %tpc, %l1 ! arg0 == tpc 15487c478bd9Sstevel@tonic-gate 15497c478bd9Sstevel@tonic-gate ldub [%g1 + T_DTRACE_AST], %g2 ! load t->t_dtrace_ast 15507c478bd9Sstevel@tonic-gate ldn [%g1 + T_DTRACE_NPC], %l2 ! arg1 = t->t_dtrace_npc (step) 15517c478bd9Sstevel@tonic-gate brz,pt %g2, 1f 15527c478bd9Sstevel@tonic-gate st %g0, [%g1 + T_DTRACE_FT] ! zero all pid provider flags 15537c478bd9Sstevel@tonic-gate stub %g2, [%g1 + T_ASTFLAG] ! aston(t) if t->t_dtrace_ast 15547c478bd9Sstevel@tonic-gate1: 15557c478bd9Sstevel@tonic-gate mov %g7, %l3 ! arg2 == misaligned address 15567c478bd9Sstevel@tonic-gate 15577c478bd9Sstevel@tonic-gate rdpr %tstate, %g1 ! cwp for trap handler 15587c478bd9Sstevel@tonic-gate rdpr %cwp, %g4 15597c478bd9Sstevel@tonic-gate bclr TSTATE_CWP_MASK, %g1 15607c478bd9Sstevel@tonic-gate wrpr %g1, %g4, %tstate 15617c478bd9Sstevel@tonic-gate wrpr %g0, %g5, %tnpc ! trap handler address 15627c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 15637c478bd9Sstevel@tonic-gate /* NOTREACHED */ 15647c478bd9Sstevel@tonic-gate 15657c478bd9Sstevel@tonic-gate.check_v9utrap: 15667c478bd9Sstevel@tonic-gate rdpr %tstate, %g1 15677c478bd9Sstevel@tonic-gate btst TSTATE_PRIV, %g1 15687c478bd9Sstevel@tonic-gate bnz,a,pn %icc, 3f 15697c478bd9Sstevel@tonic-gate nop 15707c478bd9Sstevel@tonic-gate CPU_ADDR(%g4, %g1) ! load CPU struct addr 15717c478bd9Sstevel@tonic-gate ldn [%g4 + CPU_THREAD], %g5 ! load thread pointer 15727c478bd9Sstevel@tonic-gate ldn [%g5 + T_PROCP], %g5 ! load proc pointer 15737c478bd9Sstevel@tonic-gate ldn [%g5 + P_UTRAPS], %g5 ! are there utraps? 15747c478bd9Sstevel@tonic-gate 15757c478bd9Sstevel@tonic-gate cmp %g3, T_SOFTWARE_TRAP 15767c478bd9Sstevel@tonic-gate bne,a,pt %icc, 1f 15777c478bd9Sstevel@tonic-gate nop 15787c478bd9Sstevel@tonic-gate 15797c478bd9Sstevel@tonic-gate brz,pt %g5, 3f ! if p_utraps == NULL goto trap() 15807c478bd9Sstevel@tonic-gate rdpr %tt, %g3 ! delay - get actual hw trap type 15817c478bd9Sstevel@tonic-gate 15827c478bd9Sstevel@tonic-gate sub %g3, 254, %g1 ! UT_TRAP_INSTRUCTION_16 = p_utraps[18] 15837c478bd9Sstevel@tonic-gate ba,pt %icc, 2f 15847c478bd9Sstevel@tonic-gate smul %g1, CPTRSIZE, %g2 15857c478bd9Sstevel@tonic-gate1: 15867c478bd9Sstevel@tonic-gate brz,a,pt %g5, 3f ! if p_utraps == NULL goto trap() 15877c478bd9Sstevel@tonic-gate nop 15887c478bd9Sstevel@tonic-gate 15897c478bd9Sstevel@tonic-gate cmp %g3, T_UNIMP_INSTR 15907c478bd9Sstevel@tonic-gate bne,a,pt %icc, 2f 15917c478bd9Sstevel@tonic-gate nop 15927c478bd9Sstevel@tonic-gate 15937c478bd9Sstevel@tonic-gate mov 1, %g1 15947c478bd9Sstevel@tonic-gate st %g1, [%g4 + CPU_TL1_HDLR] ! set CPU_TL1_HDLR 15957c478bd9Sstevel@tonic-gate rdpr %tpc, %g1 ! ld trapping instruction using 15967c478bd9Sstevel@tonic-gate lduwa [%g1]ASI_AIUP, %g1 ! "AS IF USER" ASI which could fault 15977c478bd9Sstevel@tonic-gate st %g0, [%g4 + CPU_TL1_HDLR] ! clr CPU_TL1_HDLR 15987c478bd9Sstevel@tonic-gate 15997c478bd9Sstevel@tonic-gate sethi %hi(0xc1c00000), %g4 ! setup mask for illtrap instruction 16007c478bd9Sstevel@tonic-gate andcc %g1, %g4, %g4 ! and instruction with mask 16017c478bd9Sstevel@tonic-gate bnz,a,pt %icc, 3f ! if %g4 == zero, %g1 is an ILLTRAP 16027c478bd9Sstevel@tonic-gate nop ! fall thru to setup 16037c478bd9Sstevel@tonic-gate2: 16047c478bd9Sstevel@tonic-gate ldn [%g5 + %g2], %g5 16057c478bd9Sstevel@tonic-gate brnz,a,pt %g5, .setup_v9utrap 16067c478bd9Sstevel@tonic-gate nop 16077c478bd9Sstevel@tonic-gate3: 16087c478bd9Sstevel@tonic-gate set trap, %g1 16097c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap 16107c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 16117c478bd9Sstevel@tonic-gate /* NOTREACHED */ 16127c478bd9Sstevel@tonic-gate 16137c478bd9Sstevel@tonic-gate/* 16147c478bd9Sstevel@tonic-gate * Register Inputs: 16157c478bd9Sstevel@tonic-gate * %g5 user trap handler 16167c478bd9Sstevel@tonic-gate */ 16177c478bd9Sstevel@tonic-gate.setup_v9utrap: 16187c478bd9Sstevel@tonic-gate set trap, %g1 ! setup in case we go 16197c478bd9Sstevel@tonic-gate mov T_FLUSH_PCB, %g3 ! through sys_trap on 16207c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 ! the save instruction below 16217c478bd9Sstevel@tonic-gate 16227c478bd9Sstevel@tonic-gate /* 16237c478bd9Sstevel@tonic-gate * If the DTrace pid provider is single stepping a copied-out 16247c478bd9Sstevel@tonic-gate * instruction, t->t_dtrace_step will be set. In that case we need 16257c478bd9Sstevel@tonic-gate * to abort the single-stepping (since execution of the instruction 16267c478bd9Sstevel@tonic-gate * was interrupted) and use the value of t->t_dtrace_npc as the %npc. 16277c478bd9Sstevel@tonic-gate */ 16287c478bd9Sstevel@tonic-gate save %sp, -SA(MINFRAME64), %sp ! window for trap handler 16297c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) ! load CPU struct addr 16307c478bd9Sstevel@tonic-gate ldn [%g1 + CPU_THREAD], %g1 ! load thread pointer 16317c478bd9Sstevel@tonic-gate ldub [%g1 + T_DTRACE_STEP], %g2 ! load t->t_dtrace_step 16327c478bd9Sstevel@tonic-gate rdpr %tnpc, %l7 ! arg1 == tnpc 16337c478bd9Sstevel@tonic-gate brz,pt %g2, 1f 16347c478bd9Sstevel@tonic-gate rdpr %tpc, %l6 ! arg0 == tpc 16357c478bd9Sstevel@tonic-gate 16367c478bd9Sstevel@tonic-gate ldub [%g1 + T_DTRACE_AST], %g2 ! load t->t_dtrace_ast 16377c478bd9Sstevel@tonic-gate ldn [%g1 + T_DTRACE_NPC], %l7 ! arg1 == t->t_dtrace_npc (step) 16387c478bd9Sstevel@tonic-gate brz,pt %g2, 1f 16397c478bd9Sstevel@tonic-gate st %g0, [%g1 + T_DTRACE_FT] ! zero all pid provider flags 16407c478bd9Sstevel@tonic-gate stub %g2, [%g1 + T_ASTFLAG] ! aston(t) if t->t_dtrace_ast 16417c478bd9Sstevel@tonic-gate1: 16427c478bd9Sstevel@tonic-gate rdpr %tstate, %g2 ! cwp for trap handler 16437c478bd9Sstevel@tonic-gate rdpr %cwp, %g4 16447c478bd9Sstevel@tonic-gate bclr TSTATE_CWP_MASK, %g2 16457c478bd9Sstevel@tonic-gate wrpr %g2, %g4, %tstate 16467c478bd9Sstevel@tonic-gate 16477c478bd9Sstevel@tonic-gate ldn [%g1 + T_PROCP], %g4 ! load proc pointer 16487c478bd9Sstevel@tonic-gate ldn [%g4 + P_AS], %g4 ! load as pointer 16497c478bd9Sstevel@tonic-gate ldn [%g4 + A_USERLIMIT], %g4 ! load as userlimit 16507c478bd9Sstevel@tonic-gate cmp %l7, %g4 ! check for single-step set 16517c478bd9Sstevel@tonic-gate bne,pt %xcc, 4f 16527c478bd9Sstevel@tonic-gate nop 16537c478bd9Sstevel@tonic-gate ldn [%g1 + T_LWP], %g1 ! load klwp pointer 16547c478bd9Sstevel@tonic-gate ld [%g1 + PCB_STEP], %g4 ! load single-step flag 16557c478bd9Sstevel@tonic-gate cmp %g4, STEP_ACTIVE ! step flags set in pcb? 16567c478bd9Sstevel@tonic-gate bne,pt %icc, 4f 16577c478bd9Sstevel@tonic-gate nop 16587c478bd9Sstevel@tonic-gate stn %g5, [%g1 + PCB_TRACEPC] ! save trap handler addr in pcb 16597c478bd9Sstevel@tonic-gate mov %l7, %g4 ! on entry to precise user trap 16607c478bd9Sstevel@tonic-gate add %l6, 4, %l7 ! handler, %l6 == pc, %l7 == npc 16617c478bd9Sstevel@tonic-gate ! at time of trap 16627c478bd9Sstevel@tonic-gate wrpr %g0, %g4, %tnpc ! generate FLTBOUNDS, 16637c478bd9Sstevel@tonic-gate ! %g4 == userlimit 16647c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 16657c478bd9Sstevel@tonic-gate /* NOTREACHED */ 16667c478bd9Sstevel@tonic-gate4: 16677c478bd9Sstevel@tonic-gate wrpr %g0, %g5, %tnpc ! trap handler address 16687c478bd9Sstevel@tonic-gate FAST_TRAP_DONE_CHK_INTR 16697c478bd9Sstevel@tonic-gate /* NOTREACHED */ 16707c478bd9Sstevel@tonic-gate 16717c478bd9Sstevel@tonic-gate.fp_exception: 16727c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) 16737c478bd9Sstevel@tonic-gate stx %fsr, [%g1 + CPU_TMP1] 16747c478bd9Sstevel@tonic-gate ldx [%g1 + CPU_TMP1], %g2 16757c478bd9Sstevel@tonic-gate 16767c478bd9Sstevel@tonic-gate /* 16777c478bd9Sstevel@tonic-gate * Cheetah takes unfinished_FPop trap for certain range of operands 16787c478bd9Sstevel@tonic-gate * to the "fitos" instruction. Instead of going through the slow 16797c478bd9Sstevel@tonic-gate * software emulation path, we try to simulate the "fitos" instruction 16807c478bd9Sstevel@tonic-gate * via "fitod" and "fdtos" provided the following conditions are met: 16817c478bd9Sstevel@tonic-gate * 16827c478bd9Sstevel@tonic-gate * fpu_exists is set (if DEBUG) 16837c478bd9Sstevel@tonic-gate * not in privileged mode 16847c478bd9Sstevel@tonic-gate * ftt is unfinished_FPop 16857c478bd9Sstevel@tonic-gate * NXM IEEE trap is not enabled 16867c478bd9Sstevel@tonic-gate * instruction at %tpc is "fitos" 16877c478bd9Sstevel@tonic-gate * 16887c478bd9Sstevel@tonic-gate * Usage: 16897c478bd9Sstevel@tonic-gate * %g1 per cpu address 16907c478bd9Sstevel@tonic-gate * %g2 %fsr 16917c478bd9Sstevel@tonic-gate * %g6 user instruction 16927c478bd9Sstevel@tonic-gate * 16937c478bd9Sstevel@tonic-gate * Note that we can take a memory access related trap while trying 16947c478bd9Sstevel@tonic-gate * to fetch the user instruction. Therefore, we set CPU_TL1_HDLR 16957c478bd9Sstevel@tonic-gate * flag to catch those traps and let the SFMMU code deal with page 16967c478bd9Sstevel@tonic-gate * fault and data access exception. 16977c478bd9Sstevel@tonic-gate */ 16987c478bd9Sstevel@tonic-gate#if defined(DEBUG) || defined(NEED_FPU_EXISTS) 16997c478bd9Sstevel@tonic-gate sethi %hi(fpu_exists), %g7 17007c478bd9Sstevel@tonic-gate ld [%g7 + %lo(fpu_exists)], %g7 17017c478bd9Sstevel@tonic-gate brz,pn %g7, .fp_exception_cont 17027c478bd9Sstevel@tonic-gate nop 17037c478bd9Sstevel@tonic-gate#endif 17047c478bd9Sstevel@tonic-gate rdpr %tstate, %g7 ! branch if in privileged mode 17057c478bd9Sstevel@tonic-gate btst TSTATE_PRIV, %g7 17067c478bd9Sstevel@tonic-gate bnz,pn %xcc, .fp_exception_cont 17077c478bd9Sstevel@tonic-gate srl %g2, FSR_FTT_SHIFT, %g7 ! extract ftt from %fsr 17087c478bd9Sstevel@tonic-gate and %g7, (FSR_FTT>>FSR_FTT_SHIFT), %g7 17097c478bd9Sstevel@tonic-gate cmp %g7, FTT_UNFIN 17107c478bd9Sstevel@tonic-gate set FSR_TEM_NX, %g5 17117c478bd9Sstevel@tonic-gate bne,pn %xcc, .fp_exception_cont ! branch if NOT unfinished_FPop 17127c478bd9Sstevel@tonic-gate andcc %g2, %g5, %g0 17137c478bd9Sstevel@tonic-gate bne,pn %xcc, .fp_exception_cont ! branch if FSR_TEM_NX enabled 17147c478bd9Sstevel@tonic-gate rdpr %tpc, %g5 ! get faulting PC 17157c478bd9Sstevel@tonic-gate 17167c478bd9Sstevel@tonic-gate or %g0, 1, %g7 17177c478bd9Sstevel@tonic-gate st %g7, [%g1 + CPU_TL1_HDLR] ! set tl1_hdlr flag 17187c478bd9Sstevel@tonic-gate lda [%g5]ASI_USER, %g6 ! get user's instruction 17197c478bd9Sstevel@tonic-gate st %g0, [%g1 + CPU_TL1_HDLR] ! clear tl1_hdlr flag 17207c478bd9Sstevel@tonic-gate 17217c478bd9Sstevel@tonic-gate set FITOS_INSTR_MASK, %g7 17227c478bd9Sstevel@tonic-gate and %g6, %g7, %g7 17237c478bd9Sstevel@tonic-gate set FITOS_INSTR, %g5 17247c478bd9Sstevel@tonic-gate cmp %g7, %g5 17257c478bd9Sstevel@tonic-gate bne,pn %xcc, .fp_exception_cont ! branch if not FITOS_INSTR 17267c478bd9Sstevel@tonic-gate nop 17277c478bd9Sstevel@tonic-gate 17287c478bd9Sstevel@tonic-gate /* 17297c478bd9Sstevel@tonic-gate * This is unfinished FPops trap for "fitos" instruction. We 17307c478bd9Sstevel@tonic-gate * need to simulate "fitos" via "fitod" and "fdtos" instruction 17317c478bd9Sstevel@tonic-gate * sequence. 17327c478bd9Sstevel@tonic-gate * 17337c478bd9Sstevel@tonic-gate * We need a temporary FP register to do the conversion. Since 17347c478bd9Sstevel@tonic-gate * both source and destination operands for the "fitos" instruction 17357c478bd9Sstevel@tonic-gate * have to be within %f0-%f31, we use an FP register from the upper 17367c478bd9Sstevel@tonic-gate * half to guarantee that it won't collide with the source or the 17377c478bd9Sstevel@tonic-gate * dest operand. However, we do have to save and restore its value. 17387c478bd9Sstevel@tonic-gate * 17397c478bd9Sstevel@tonic-gate * We use %d62 as a temporary FP register for the conversion and 17407c478bd9Sstevel@tonic-gate * branch to appropriate instruction within the conversion tables 17417c478bd9Sstevel@tonic-gate * based upon the rs2 and rd values. 17427c478bd9Sstevel@tonic-gate */ 17437c478bd9Sstevel@tonic-gate 17447c478bd9Sstevel@tonic-gate std %d62, [%g1 + CPU_TMP1] ! save original value 17457c478bd9Sstevel@tonic-gate 17467c478bd9Sstevel@tonic-gate srl %g6, FITOS_RS2_SHIFT, %g7 17477c478bd9Sstevel@tonic-gate and %g7, FITOS_REG_MASK, %g7 17487c478bd9Sstevel@tonic-gate set _fitos_fitod_table, %g4 17497c478bd9Sstevel@tonic-gate sllx %g7, 2, %g7 17507c478bd9Sstevel@tonic-gate jmp %g4 + %g7 17517c478bd9Sstevel@tonic-gate ba,pt %xcc, _fitos_fitod_done 17527c478bd9Sstevel@tonic-gate .empty 17537c478bd9Sstevel@tonic-gate 17547c478bd9Sstevel@tonic-gate_fitos_fitod_table: 17557c478bd9Sstevel@tonic-gate fitod %f0, %d62 17567c478bd9Sstevel@tonic-gate fitod %f1, %d62 17577c478bd9Sstevel@tonic-gate fitod %f2, %d62 17587c478bd9Sstevel@tonic-gate fitod %f3, %d62 17597c478bd9Sstevel@tonic-gate fitod %f4, %d62 17607c478bd9Sstevel@tonic-gate fitod %f5, %d62 17617c478bd9Sstevel@tonic-gate fitod %f6, %d62 17627c478bd9Sstevel@tonic-gate fitod %f7, %d62 17637c478bd9Sstevel@tonic-gate fitod %f8, %d62 17647c478bd9Sstevel@tonic-gate fitod %f9, %d62 17657c478bd9Sstevel@tonic-gate fitod %f10, %d62 17667c478bd9Sstevel@tonic-gate fitod %f11, %d62 17677c478bd9Sstevel@tonic-gate fitod %f12, %d62 17687c478bd9Sstevel@tonic-gate fitod %f13, %d62 17697c478bd9Sstevel@tonic-gate fitod %f14, %d62 17707c478bd9Sstevel@tonic-gate fitod %f15, %d62 17717c478bd9Sstevel@tonic-gate fitod %f16, %d62 17727c478bd9Sstevel@tonic-gate fitod %f17, %d62 17737c478bd9Sstevel@tonic-gate fitod %f18, %d62 17747c478bd9Sstevel@tonic-gate fitod %f19, %d62 17757c478bd9Sstevel@tonic-gate fitod %f20, %d62 17767c478bd9Sstevel@tonic-gate fitod %f21, %d62 17777c478bd9Sstevel@tonic-gate fitod %f22, %d62 17787c478bd9Sstevel@tonic-gate fitod %f23, %d62 17797c478bd9Sstevel@tonic-gate fitod %f24, %d62 17807c478bd9Sstevel@tonic-gate fitod %f25, %d62 17817c478bd9Sstevel@tonic-gate fitod %f26, %d62 17827c478bd9Sstevel@tonic-gate fitod %f27, %d62 17837c478bd9Sstevel@tonic-gate fitod %f28, %d62 17847c478bd9Sstevel@tonic-gate fitod %f29, %d62 17857c478bd9Sstevel@tonic-gate fitod %f30, %d62 17867c478bd9Sstevel@tonic-gate fitod %f31, %d62 17877c478bd9Sstevel@tonic-gate_fitos_fitod_done: 17887c478bd9Sstevel@tonic-gate 17897c478bd9Sstevel@tonic-gate /* 17907c478bd9Sstevel@tonic-gate * Now convert data back into single precision 17917c478bd9Sstevel@tonic-gate */ 17927c478bd9Sstevel@tonic-gate srl %g6, FITOS_RD_SHIFT, %g7 17937c478bd9Sstevel@tonic-gate and %g7, FITOS_REG_MASK, %g7 17947c478bd9Sstevel@tonic-gate set _fitos_fdtos_table, %g4 17957c478bd9Sstevel@tonic-gate sllx %g7, 2, %g7 17967c478bd9Sstevel@tonic-gate jmp %g4 + %g7 17977c478bd9Sstevel@tonic-gate ba,pt %xcc, _fitos_fdtos_done 17987c478bd9Sstevel@tonic-gate .empty 17997c478bd9Sstevel@tonic-gate 18007c478bd9Sstevel@tonic-gate_fitos_fdtos_table: 18017c478bd9Sstevel@tonic-gate fdtos %d62, %f0 18027c478bd9Sstevel@tonic-gate fdtos %d62, %f1 18037c478bd9Sstevel@tonic-gate fdtos %d62, %f2 18047c478bd9Sstevel@tonic-gate fdtos %d62, %f3 18057c478bd9Sstevel@tonic-gate fdtos %d62, %f4 18067c478bd9Sstevel@tonic-gate fdtos %d62, %f5 18077c478bd9Sstevel@tonic-gate fdtos %d62, %f6 18087c478bd9Sstevel@tonic-gate fdtos %d62, %f7 18097c478bd9Sstevel@tonic-gate fdtos %d62, %f8 18107c478bd9Sstevel@tonic-gate fdtos %d62, %f9 18117c478bd9Sstevel@tonic-gate fdtos %d62, %f10 18127c478bd9Sstevel@tonic-gate fdtos %d62, %f11 18137c478bd9Sstevel@tonic-gate fdtos %d62, %f12 18147c478bd9Sstevel@tonic-gate fdtos %d62, %f13 18157c478bd9Sstevel@tonic-gate fdtos %d62, %f14 18167c478bd9Sstevel@tonic-gate fdtos %d62, %f15 18177c478bd9Sstevel@tonic-gate fdtos %d62, %f16 18187c478bd9Sstevel@tonic-gate fdtos %d62, %f17 18197c478bd9Sstevel@tonic-gate fdtos %d62, %f18 18207c478bd9Sstevel@tonic-gate fdtos %d62, %f19 18217c478bd9Sstevel@tonic-gate fdtos %d62, %f20 18227c478bd9Sstevel@tonic-gate fdtos %d62, %f21 18237c478bd9Sstevel@tonic-gate fdtos %d62, %f22 18247c478bd9Sstevel@tonic-gate fdtos %d62, %f23 18257c478bd9Sstevel@tonic-gate fdtos %d62, %f24 18267c478bd9Sstevel@tonic-gate fdtos %d62, %f25 18277c478bd9Sstevel@tonic-gate fdtos %d62, %f26 18287c478bd9Sstevel@tonic-gate fdtos %d62, %f27 18297c478bd9Sstevel@tonic-gate fdtos %d62, %f28 18307c478bd9Sstevel@tonic-gate fdtos %d62, %f29 18317c478bd9Sstevel@tonic-gate fdtos %d62, %f30 18327c478bd9Sstevel@tonic-gate fdtos %d62, %f31 18337c478bd9Sstevel@tonic-gate_fitos_fdtos_done: 18347c478bd9Sstevel@tonic-gate 18357c478bd9Sstevel@tonic-gate ldd [%g1 + CPU_TMP1], %d62 ! restore %d62 18367c478bd9Sstevel@tonic-gate 18377c478bd9Sstevel@tonic-gate#if DEBUG 18387c478bd9Sstevel@tonic-gate /* 18397c478bd9Sstevel@tonic-gate * Update FPop_unfinished trap kstat 18407c478bd9Sstevel@tonic-gate */ 18417c478bd9Sstevel@tonic-gate set fpustat+FPUSTAT_UNFIN_KSTAT, %g7 18427c478bd9Sstevel@tonic-gate ldx [%g7], %g5 18437c478bd9Sstevel@tonic-gate1: 18447c478bd9Sstevel@tonic-gate add %g5, 1, %g6 18457c478bd9Sstevel@tonic-gate 18467c478bd9Sstevel@tonic-gate casxa [%g7] ASI_N, %g5, %g6 18477c478bd9Sstevel@tonic-gate cmp %g5, %g6 18487c478bd9Sstevel@tonic-gate bne,a,pn %xcc, 1b 18497c478bd9Sstevel@tonic-gate or %g0, %g6, %g5 18507c478bd9Sstevel@tonic-gate 18517c478bd9Sstevel@tonic-gate /* 18527c478bd9Sstevel@tonic-gate * Update fpu_sim_fitos kstat 18537c478bd9Sstevel@tonic-gate */ 18547c478bd9Sstevel@tonic-gate set fpuinfo+FPUINFO_FITOS_KSTAT, %g7 18557c478bd9Sstevel@tonic-gate ldx [%g7], %g5 18567c478bd9Sstevel@tonic-gate1: 18577c478bd9Sstevel@tonic-gate add %g5, 1, %g6 18587c478bd9Sstevel@tonic-gate 18597c478bd9Sstevel@tonic-gate casxa [%g7] ASI_N, %g5, %g6 18607c478bd9Sstevel@tonic-gate cmp %g5, %g6 18617c478bd9Sstevel@tonic-gate bne,a,pn %xcc, 1b 18627c478bd9Sstevel@tonic-gate or %g0, %g6, %g5 18637c478bd9Sstevel@tonic-gate#endif /* DEBUG */ 18647c478bd9Sstevel@tonic-gate 18657c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 18667c478bd9Sstevel@tonic-gate 18677c478bd9Sstevel@tonic-gate.fp_exception_cont: 18687c478bd9Sstevel@tonic-gate /* 18697c478bd9Sstevel@tonic-gate * Let _fp_exception deal with simulating FPop instruction. 18707c478bd9Sstevel@tonic-gate * Note that we need to pass %fsr in %g2 (already read above). 18717c478bd9Sstevel@tonic-gate */ 18727c478bd9Sstevel@tonic-gate 18737c478bd9Sstevel@tonic-gate set _fp_exception, %g1 18747c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap 18757c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 18767c478bd9Sstevel@tonic-gate 18777c478bd9Sstevel@tonic-gate 18787c478bd9Sstevel@tonic-gate/* 18797c478bd9Sstevel@tonic-gate * Register windows 18807c478bd9Sstevel@tonic-gate */ 18817c478bd9Sstevel@tonic-gate.flushw: 18824b418d96Smb158278.clean_windows: 18837c478bd9Sstevel@tonic-gate rdpr %tnpc, %g1 18847c478bd9Sstevel@tonic-gate wrpr %g1, %tpc 18857c478bd9Sstevel@tonic-gate add %g1, 4, %g1 18867c478bd9Sstevel@tonic-gate wrpr %g1, %tnpc 18877c478bd9Sstevel@tonic-gate set trap, %g1 18887c478bd9Sstevel@tonic-gate mov T_FLUSH_PCB, %g3 18897c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap 18907c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 18917c478bd9Sstevel@tonic-gate 18927c478bd9Sstevel@tonic-gate/* 18937c478bd9Sstevel@tonic-gate * .spill_clean: clean the previous window, restore the wstate, and 18947c478bd9Sstevel@tonic-gate * "done". 18957c478bd9Sstevel@tonic-gate * 18967c478bd9Sstevel@tonic-gate * Entry: %g7 contains new wstate 18977c478bd9Sstevel@tonic-gate */ 18987c478bd9Sstevel@tonic-gate.spill_clean: 18997c478bd9Sstevel@tonic-gate sethi %hi(nwin_minus_one), %g5 19007c478bd9Sstevel@tonic-gate ld [%g5 + %lo(nwin_minus_one)], %g5 ! %g5 = nwin - 1 19017c478bd9Sstevel@tonic-gate rdpr %cwp, %g6 ! %g6 = %cwp 19027c478bd9Sstevel@tonic-gate deccc %g6 ! %g6-- 19037c478bd9Sstevel@tonic-gate movneg %xcc, %g5, %g6 ! if (%g6<0) %g6 = nwin-1 19047c478bd9Sstevel@tonic-gate wrpr %g6, %cwp 19057c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) 19067c478bd9Sstevel@tonic-gate clr %l0 19077c478bd9Sstevel@tonic-gate clr %l1 19087c478bd9Sstevel@tonic-gate clr %l2 19097c478bd9Sstevel@tonic-gate clr %l3 19107c478bd9Sstevel@tonic-gate clr %l4 19117c478bd9Sstevel@tonic-gate clr %l5 19127c478bd9Sstevel@tonic-gate clr %l6 19137c478bd9Sstevel@tonic-gate clr %l7 19147c478bd9Sstevel@tonic-gate wrpr %g0, %g7, %wstate 19157c478bd9Sstevel@tonic-gate saved 19167c478bd9Sstevel@tonic-gate retry ! restores correct %cwp 19177c478bd9Sstevel@tonic-gate 19187c478bd9Sstevel@tonic-gate.fix_alignment: 19197c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g2) ! load CPU struct addr to %g1 using %g2 19207c478bd9Sstevel@tonic-gate ldn [%g1 + CPU_THREAD], %g1 ! load thread pointer 19217c478bd9Sstevel@tonic-gate ldn [%g1 + T_PROCP], %g1 19227c478bd9Sstevel@tonic-gate mov 1, %g2 19237c478bd9Sstevel@tonic-gate stb %g2, [%g1 + P_FIXALIGNMENT] 19247c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 19257c478bd9Sstevel@tonic-gate 19267c478bd9Sstevel@tonic-gate#define STDF_REG(REG, ADDR, TMP) \ 19277c478bd9Sstevel@tonic-gate sll REG, 3, REG ;\ 19287c478bd9Sstevel@tonic-gatemark1: set start1, TMP ;\ 19297c478bd9Sstevel@tonic-gate jmp REG + TMP ;\ 19307c478bd9Sstevel@tonic-gate nop ;\ 19317c478bd9Sstevel@tonic-gatestart1: ba,pt %xcc, done1 ;\ 19327c478bd9Sstevel@tonic-gate std %f0, [ADDR + CPU_TMP1] ;\ 19337c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19347c478bd9Sstevel@tonic-gate std %f32, [ADDR + CPU_TMP1] ;\ 19357c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19367c478bd9Sstevel@tonic-gate std %f2, [ADDR + CPU_TMP1] ;\ 19377c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19387c478bd9Sstevel@tonic-gate std %f34, [ADDR + CPU_TMP1] ;\ 19397c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19407c478bd9Sstevel@tonic-gate std %f4, [ADDR + CPU_TMP1] ;\ 19417c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19427c478bd9Sstevel@tonic-gate std %f36, [ADDR + CPU_TMP1] ;\ 19437c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19447c478bd9Sstevel@tonic-gate std %f6, [ADDR + CPU_TMP1] ;\ 19457c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19467c478bd9Sstevel@tonic-gate std %f38, [ADDR + CPU_TMP1] ;\ 19477c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19487c478bd9Sstevel@tonic-gate std %f8, [ADDR + CPU_TMP1] ;\ 19497c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19507c478bd9Sstevel@tonic-gate std %f40, [ADDR + CPU_TMP1] ;\ 19517c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19527c478bd9Sstevel@tonic-gate std %f10, [ADDR + CPU_TMP1] ;\ 19537c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19547c478bd9Sstevel@tonic-gate std %f42, [ADDR + CPU_TMP1] ;\ 19557c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19567c478bd9Sstevel@tonic-gate std %f12, [ADDR + CPU_TMP1] ;\ 19577c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19587c478bd9Sstevel@tonic-gate std %f44, [ADDR + CPU_TMP1] ;\ 19597c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19607c478bd9Sstevel@tonic-gate std %f14, [ADDR + CPU_TMP1] ;\ 19617c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19627c478bd9Sstevel@tonic-gate std %f46, [ADDR + CPU_TMP1] ;\ 19637c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19647c478bd9Sstevel@tonic-gate std %f16, [ADDR + CPU_TMP1] ;\ 19657c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19667c478bd9Sstevel@tonic-gate std %f48, [ADDR + CPU_TMP1] ;\ 19677c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19687c478bd9Sstevel@tonic-gate std %f18, [ADDR + CPU_TMP1] ;\ 19697c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19707c478bd9Sstevel@tonic-gate std %f50, [ADDR + CPU_TMP1] ;\ 19717c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19727c478bd9Sstevel@tonic-gate std %f20, [ADDR + CPU_TMP1] ;\ 19737c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19747c478bd9Sstevel@tonic-gate std %f52, [ADDR + CPU_TMP1] ;\ 19757c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19767c478bd9Sstevel@tonic-gate std %f22, [ADDR + CPU_TMP1] ;\ 19777c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19787c478bd9Sstevel@tonic-gate std %f54, [ADDR + CPU_TMP1] ;\ 19797c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19807c478bd9Sstevel@tonic-gate std %f24, [ADDR + CPU_TMP1] ;\ 19817c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19827c478bd9Sstevel@tonic-gate std %f56, [ADDR + CPU_TMP1] ;\ 19837c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19847c478bd9Sstevel@tonic-gate std %f26, [ADDR + CPU_TMP1] ;\ 19857c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19867c478bd9Sstevel@tonic-gate std %f58, [ADDR + CPU_TMP1] ;\ 19877c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19887c478bd9Sstevel@tonic-gate std %f28, [ADDR + CPU_TMP1] ;\ 19897c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19907c478bd9Sstevel@tonic-gate std %f60, [ADDR + CPU_TMP1] ;\ 19917c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19927c478bd9Sstevel@tonic-gate std %f30, [ADDR + CPU_TMP1] ;\ 19937c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 19947c478bd9Sstevel@tonic-gate std %f62, [ADDR + CPU_TMP1] ;\ 19957c478bd9Sstevel@tonic-gatedone1: 19967c478bd9Sstevel@tonic-gate 19977c478bd9Sstevel@tonic-gate#define LDDF_REG(REG, ADDR, TMP) \ 19987c478bd9Sstevel@tonic-gate sll REG, 3, REG ;\ 19997c478bd9Sstevel@tonic-gatemark2: set start2, TMP ;\ 20007c478bd9Sstevel@tonic-gate jmp REG + TMP ;\ 20017c478bd9Sstevel@tonic-gate nop ;\ 20027c478bd9Sstevel@tonic-gatestart2: ba,pt %xcc, done2 ;\ 20037c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f0 ;\ 20047c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20057c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f32 ;\ 20067c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20077c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f2 ;\ 20087c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20097c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f34 ;\ 20107c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20117c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f4 ;\ 20127c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20137c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f36 ;\ 20147c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20157c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f6 ;\ 20167c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20177c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f38 ;\ 20187c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20197c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f8 ;\ 20207c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20217c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f40 ;\ 20227c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20237c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f10 ;\ 20247c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20257c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f42 ;\ 20267c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20277c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f12 ;\ 20287c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20297c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f44 ;\ 20307c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20317c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f14 ;\ 20327c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20337c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f46 ;\ 20347c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20357c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f16 ;\ 20367c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20377c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f48 ;\ 20387c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20397c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f18 ;\ 20407c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20417c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f50 ;\ 20427c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20437c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f20 ;\ 20447c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20457c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f52 ;\ 20467c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20477c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f22 ;\ 20487c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20497c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f54 ;\ 20507c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20517c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f24 ;\ 20527c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20537c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f56 ;\ 20547c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20557c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f26 ;\ 20567c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20577c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f58 ;\ 20587c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20597c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f28 ;\ 20607c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20617c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f60 ;\ 20627c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20637c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f30 ;\ 20647c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 20657c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f62 ;\ 20667c478bd9Sstevel@tonic-gatedone2: 20677c478bd9Sstevel@tonic-gate 20687c478bd9Sstevel@tonic-gate.lddf_exception_not_aligned: 20697c478bd9Sstevel@tonic-gate /* %g2 = sfar, %g3 = sfsr */ 20707c478bd9Sstevel@tonic-gate mov %g2, %g5 ! stash sfar 20717c478bd9Sstevel@tonic-gate#if defined(DEBUG) || defined(NEED_FPU_EXISTS) 20727c478bd9Sstevel@tonic-gate sethi %hi(fpu_exists), %g2 ! check fpu_exists 20737c478bd9Sstevel@tonic-gate ld [%g2 + %lo(fpu_exists)], %g2 20747c478bd9Sstevel@tonic-gate brz,a,pn %g2, 4f 20757c478bd9Sstevel@tonic-gate nop 20767c478bd9Sstevel@tonic-gate#endif 20777c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) 20787c478bd9Sstevel@tonic-gate or %g0, 1, %g4 20797c478bd9Sstevel@tonic-gate st %g4, [%g1 + CPU_TL1_HDLR] ! set tl1_hdlr flag 20807c478bd9Sstevel@tonic-gate 20817c478bd9Sstevel@tonic-gate rdpr %tpc, %g2 20827c478bd9Sstevel@tonic-gate lda [%g2]ASI_AIUP, %g6 ! get the user's lddf instruction 20837c478bd9Sstevel@tonic-gate srl %g6, 23, %g1 ! using ldda or not? 20847c478bd9Sstevel@tonic-gate and %g1, 1, %g1 20857c478bd9Sstevel@tonic-gate brz,a,pt %g1, 2f ! check for ldda instruction 20867c478bd9Sstevel@tonic-gate nop 20877c478bd9Sstevel@tonic-gate srl %g6, 13, %g1 ! check immflag 20887c478bd9Sstevel@tonic-gate and %g1, 1, %g1 20897c478bd9Sstevel@tonic-gate rdpr %tstate, %g2 ! %tstate in %g2 20907c478bd9Sstevel@tonic-gate brnz,a,pn %g1, 1f 20917c478bd9Sstevel@tonic-gate srl %g2, 31, %g1 ! get asi from %tstate 20927c478bd9Sstevel@tonic-gate srl %g6, 5, %g1 ! get asi from instruction 20937c478bd9Sstevel@tonic-gate and %g1, 0xFF, %g1 ! imm_asi field 20947c478bd9Sstevel@tonic-gate1: 20957c478bd9Sstevel@tonic-gate cmp %g1, ASI_P ! primary address space 20967c478bd9Sstevel@tonic-gate be,a,pt %icc, 2f 20977c478bd9Sstevel@tonic-gate nop 20987c478bd9Sstevel@tonic-gate cmp %g1, ASI_PNF ! primary no fault address space 20997c478bd9Sstevel@tonic-gate be,a,pt %icc, 2f 21007c478bd9Sstevel@tonic-gate nop 21017c478bd9Sstevel@tonic-gate cmp %g1, ASI_S ! secondary address space 21027c478bd9Sstevel@tonic-gate be,a,pt %icc, 2f 21037c478bd9Sstevel@tonic-gate nop 21047c478bd9Sstevel@tonic-gate cmp %g1, ASI_SNF ! secondary no fault address space 21057c478bd9Sstevel@tonic-gate bne,a,pn %icc, 3f 21067c478bd9Sstevel@tonic-gate nop 21077c478bd9Sstevel@tonic-gate2: 21087c478bd9Sstevel@tonic-gate lduwa [%g5]ASI_USER, %g7 ! get first half of misaligned data 21097c478bd9Sstevel@tonic-gate add %g5, 4, %g5 ! increment misaligned data address 21107c478bd9Sstevel@tonic-gate lduwa [%g5]ASI_USER, %g5 ! get second half of misaligned data 21117c478bd9Sstevel@tonic-gate 21127c478bd9Sstevel@tonic-gate sllx %g7, 32, %g7 21137c478bd9Sstevel@tonic-gate or %g5, %g7, %g5 ! combine data 21147c478bd9Sstevel@tonic-gate CPU_ADDR(%g7, %g1) ! save data on a per-cpu basis 21157c478bd9Sstevel@tonic-gate stx %g5, [%g7 + CPU_TMP1] ! save in cpu_tmp1 21167c478bd9Sstevel@tonic-gate 21177c478bd9Sstevel@tonic-gate srl %g6, 25, %g3 ! %g6 has the instruction 21187c478bd9Sstevel@tonic-gate and %g3, 0x1F, %g3 ! %g3 has rd 21197c478bd9Sstevel@tonic-gate LDDF_REG(%g3, %g7, %g4) 21207c478bd9Sstevel@tonic-gate 21217c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) 21227c478bd9Sstevel@tonic-gate st %g0, [%g1 + CPU_TL1_HDLR] ! clear tl1_hdlr flag 21237c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 21247c478bd9Sstevel@tonic-gate3: 21257c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) 21267c478bd9Sstevel@tonic-gate st %g0, [%g1 + CPU_TL1_HDLR] ! clear tl1_hdlr flag 21277c478bd9Sstevel@tonic-gate4: 21287c478bd9Sstevel@tonic-gate set T_USER, %g3 ! trap type in %g3 21297c478bd9Sstevel@tonic-gate or %g3, T_LDDF_ALIGN, %g3 21307c478bd9Sstevel@tonic-gate mov %g5, %g2 ! misaligned vaddr in %g2 21317c478bd9Sstevel@tonic-gate set fpu_trap, %g1 ! goto C for the little and 21327c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap ! no fault little asi's 21337c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 21347c478bd9Sstevel@tonic-gate 21357c478bd9Sstevel@tonic-gate.stdf_exception_not_aligned: 21367c478bd9Sstevel@tonic-gate /* %g2 = sfar, %g3 = sfsr */ 21377c478bd9Sstevel@tonic-gate mov %g2, %g5 21387c478bd9Sstevel@tonic-gate 21397c478bd9Sstevel@tonic-gate#if defined(DEBUG) || defined(NEED_FPU_EXISTS) 21407c478bd9Sstevel@tonic-gate sethi %hi(fpu_exists), %g7 ! check fpu_exists 21417c478bd9Sstevel@tonic-gate ld [%g7 + %lo(fpu_exists)], %g3 21427c478bd9Sstevel@tonic-gate brz,a,pn %g3, 4f 21437c478bd9Sstevel@tonic-gate nop 21447c478bd9Sstevel@tonic-gate#endif 21457c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) 21467c478bd9Sstevel@tonic-gate or %g0, 1, %g4 21477c478bd9Sstevel@tonic-gate st %g4, [%g1 + CPU_TL1_HDLR] ! set tl1_hdlr flag 21487c478bd9Sstevel@tonic-gate 21497c478bd9Sstevel@tonic-gate rdpr %tpc, %g2 21507c478bd9Sstevel@tonic-gate lda [%g2]ASI_AIUP, %g6 ! get the user's stdf instruction 21517c478bd9Sstevel@tonic-gate 21527c478bd9Sstevel@tonic-gate srl %g6, 23, %g1 ! using stda or not? 21537c478bd9Sstevel@tonic-gate and %g1, 1, %g1 21547c478bd9Sstevel@tonic-gate brz,a,pt %g1, 2f ! check for stda instruction 21557c478bd9Sstevel@tonic-gate nop 21567c478bd9Sstevel@tonic-gate srl %g6, 13, %g1 ! check immflag 21577c478bd9Sstevel@tonic-gate and %g1, 1, %g1 21587c478bd9Sstevel@tonic-gate rdpr %tstate, %g2 ! %tstate in %g2 21597c478bd9Sstevel@tonic-gate brnz,a,pn %g1, 1f 21607c478bd9Sstevel@tonic-gate srl %g2, 31, %g1 ! get asi from %tstate 21617c478bd9Sstevel@tonic-gate srl %g6, 5, %g1 ! get asi from instruction 21627c478bd9Sstevel@tonic-gate and %g1, 0xff, %g1 ! imm_asi field 21637c478bd9Sstevel@tonic-gate1: 21647c478bd9Sstevel@tonic-gate cmp %g1, ASI_P ! primary address space 21657c478bd9Sstevel@tonic-gate be,a,pt %icc, 2f 21667c478bd9Sstevel@tonic-gate nop 21677c478bd9Sstevel@tonic-gate cmp %g1, ASI_S ! secondary address space 21687c478bd9Sstevel@tonic-gate bne,a,pn %icc, 3f 21697c478bd9Sstevel@tonic-gate nop 21707c478bd9Sstevel@tonic-gate2: 21717c478bd9Sstevel@tonic-gate srl %g6, 25, %g6 21727c478bd9Sstevel@tonic-gate and %g6, 0x1F, %g6 ! %g6 has rd 21737c478bd9Sstevel@tonic-gate CPU_ADDR(%g7, %g1) 21747c478bd9Sstevel@tonic-gate STDF_REG(%g6, %g7, %g4) ! STDF_REG(REG, ADDR, TMP) 21757c478bd9Sstevel@tonic-gate 21767c478bd9Sstevel@tonic-gate ldx [%g7 + CPU_TMP1], %g6 21777c478bd9Sstevel@tonic-gate srlx %g6, 32, %g7 21787c478bd9Sstevel@tonic-gate stuwa %g7, [%g5]ASI_USER ! first half 21797c478bd9Sstevel@tonic-gate add %g5, 4, %g5 ! increment misaligned data address 21807c478bd9Sstevel@tonic-gate stuwa %g6, [%g5]ASI_USER ! second half 21817c478bd9Sstevel@tonic-gate 21827c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) 21837c478bd9Sstevel@tonic-gate st %g0, [%g1 + CPU_TL1_HDLR] ! clear tl1_hdlr flag 21847c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 21857c478bd9Sstevel@tonic-gate3: 21867c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) 21877c478bd9Sstevel@tonic-gate st %g0, [%g1 + CPU_TL1_HDLR] ! clear tl1_hdlr flag 21887c478bd9Sstevel@tonic-gate4: 21897c478bd9Sstevel@tonic-gate set T_USER, %g3 ! trap type in %g3 21907c478bd9Sstevel@tonic-gate or %g3, T_STDF_ALIGN, %g3 21917c478bd9Sstevel@tonic-gate mov %g5, %g2 ! misaligned vaddr in %g2 21927c478bd9Sstevel@tonic-gate set fpu_trap, %g1 ! goto C for the little and 21937c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap ! nofault little asi's 21947c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 21957c478bd9Sstevel@tonic-gate 21967c478bd9Sstevel@tonic-gate#ifdef DEBUG_USER_TRAPTRACECTL 21977c478bd9Sstevel@tonic-gate 21987c478bd9Sstevel@tonic-gate.traptrace_freeze: 21997c478bd9Sstevel@tonic-gate mov %l0, %g1 ; mov %l1, %g2 ; mov %l2, %g3 ; mov %l4, %g4 22007c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) 22017c478bd9Sstevel@tonic-gate mov %g4, %l4 ; mov %g3, %l2 ; mov %g2, %l1 ; mov %g1, %l0 22027c478bd9Sstevel@tonic-gate set trap_freeze, %g1 22037c478bd9Sstevel@tonic-gate mov 1, %g2 22047c478bd9Sstevel@tonic-gate st %g2, [%g1] 22057c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 22067c478bd9Sstevel@tonic-gate 22077c478bd9Sstevel@tonic-gate.traptrace_unfreeze: 22087c478bd9Sstevel@tonic-gate set trap_freeze, %g1 22097c478bd9Sstevel@tonic-gate st %g0, [%g1] 22107c478bd9Sstevel@tonic-gate mov %l0, %g1 ; mov %l1, %g2 ; mov %l2, %g3 ; mov %l4, %g4 22117c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) 22127c478bd9Sstevel@tonic-gate mov %g4, %l4 ; mov %g3, %l2 ; mov %g2, %l1 ; mov %g1, %l0 22137c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 22147c478bd9Sstevel@tonic-gate 22157c478bd9Sstevel@tonic-gate#endif /* DEBUG_USER_TRAPTRACECTL */ 22167c478bd9Sstevel@tonic-gate 22177c478bd9Sstevel@tonic-gate.getcc: 22187c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g2) 22197c478bd9Sstevel@tonic-gate stx %o0, [%g1 + CPU_TMP1] ! save %o0 22207c478bd9Sstevel@tonic-gate rdpr %tstate, %g3 ! get tstate 22217c478bd9Sstevel@tonic-gate srlx %g3, PSR_TSTATE_CC_SHIFT, %o0 ! shift ccr to V8 psr 22227c478bd9Sstevel@tonic-gate set PSR_ICC, %g2 22237c478bd9Sstevel@tonic-gate and %o0, %g2, %o0 ! mask out the rest 22247c478bd9Sstevel@tonic-gate srl %o0, PSR_ICC_SHIFT, %o0 ! right justify 22257c478bd9Sstevel@tonic-gate wrpr %g0, 0, %gl 22267c478bd9Sstevel@tonic-gate mov %o0, %g1 ! move ccr to normal %g1 22277c478bd9Sstevel@tonic-gate wrpr %g0, 1, %gl 22287c478bd9Sstevel@tonic-gate ! cannot assume globals retained their values after increasing %gl 22297c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g2) 22307c478bd9Sstevel@tonic-gate ldx [%g1 + CPU_TMP1], %o0 ! restore %o0 22317c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 22327c478bd9Sstevel@tonic-gate 22337c478bd9Sstevel@tonic-gate.setcc: 22347c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g2) 22357c478bd9Sstevel@tonic-gate stx %o0, [%g1 + CPU_TMP1] ! save %o0 22367c478bd9Sstevel@tonic-gate wrpr %g0, 0, %gl 22377c478bd9Sstevel@tonic-gate mov %g1, %o0 22387c478bd9Sstevel@tonic-gate wrpr %g0, 1, %gl 22397c478bd9Sstevel@tonic-gate ! cannot assume globals retained their values after increasing %gl 22407c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g2) 22417c478bd9Sstevel@tonic-gate sll %o0, PSR_ICC_SHIFT, %g2 22427c478bd9Sstevel@tonic-gate set PSR_ICC, %g3 22437c478bd9Sstevel@tonic-gate and %g2, %g3, %g2 ! mask out rest 22447c478bd9Sstevel@tonic-gate sllx %g2, PSR_TSTATE_CC_SHIFT, %g2 22457c478bd9Sstevel@tonic-gate rdpr %tstate, %g3 ! get tstate 22467c478bd9Sstevel@tonic-gate srl %g3, 0, %g3 ! clear upper word 22477c478bd9Sstevel@tonic-gate or %g3, %g2, %g3 ! or in new bits 22487c478bd9Sstevel@tonic-gate wrpr %g3, %tstate 22497c478bd9Sstevel@tonic-gate ldx [%g1 + CPU_TMP1], %o0 ! restore %o0 22507c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 22517c478bd9Sstevel@tonic-gate 22527c478bd9Sstevel@tonic-gate/* 22537c478bd9Sstevel@tonic-gate * getpsr(void) 22547c478bd9Sstevel@tonic-gate * Note that the xcc part of the ccr is not provided. 22557c478bd9Sstevel@tonic-gate * The V8 code shows why the V9 trap is not faster: 22567c478bd9Sstevel@tonic-gate * #define GETPSR_TRAP() \ 22577c478bd9Sstevel@tonic-gate * mov %psr, %i0; jmp %l2; rett %l2+4; nop; 22587c478bd9Sstevel@tonic-gate */ 22597c478bd9Sstevel@tonic-gate 22607c478bd9Sstevel@tonic-gate .type .getpsr, #function 22617c478bd9Sstevel@tonic-gate.getpsr: 22627c478bd9Sstevel@tonic-gate rdpr %tstate, %g1 ! get tstate 22637c478bd9Sstevel@tonic-gate srlx %g1, PSR_TSTATE_CC_SHIFT, %o0 ! shift ccr to V8 psr 22647c478bd9Sstevel@tonic-gate set PSR_ICC, %g2 22657c478bd9Sstevel@tonic-gate and %o0, %g2, %o0 ! mask out the rest 22667c478bd9Sstevel@tonic-gate 22677c478bd9Sstevel@tonic-gate rd %fprs, %g1 ! get fprs 22687c478bd9Sstevel@tonic-gate and %g1, FPRS_FEF, %g2 ! mask out dirty upper/lower 22697c478bd9Sstevel@tonic-gate sllx %g2, PSR_FPRS_FEF_SHIFT, %g2 ! shift fef to V8 psr.ef 22707c478bd9Sstevel@tonic-gate or %o0, %g2, %o0 ! or result into psr.ef 22717c478bd9Sstevel@tonic-gate 22727c478bd9Sstevel@tonic-gate set V9_PSR_IMPLVER, %g2 ! SI assigned impl/ver: 0xef 22737c478bd9Sstevel@tonic-gate or %o0, %g2, %o0 ! or psr.impl/ver 22747c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 22757c478bd9Sstevel@tonic-gate SET_SIZE(.getpsr) 22767c478bd9Sstevel@tonic-gate 22777c478bd9Sstevel@tonic-gate/* 22787c478bd9Sstevel@tonic-gate * setpsr(newpsr) 22797c478bd9Sstevel@tonic-gate * Note that there is no support for ccr.xcc in the V9 code. 22807c478bd9Sstevel@tonic-gate */ 22817c478bd9Sstevel@tonic-gate 22827c478bd9Sstevel@tonic-gate .type .setpsr, #function 22837c478bd9Sstevel@tonic-gate.setpsr: 22847c478bd9Sstevel@tonic-gate rdpr %tstate, %g1 ! get tstate 22857c478bd9Sstevel@tonic-gate! setx TSTATE_V8_UBITS, %g2 22867c478bd9Sstevel@tonic-gate or %g0, CCR_ICC, %g3 22877c478bd9Sstevel@tonic-gate sllx %g3, TSTATE_CCR_SHIFT, %g2 22887c478bd9Sstevel@tonic-gate 22897c478bd9Sstevel@tonic-gate andn %g1, %g2, %g1 ! zero current user bits 22907c478bd9Sstevel@tonic-gate set PSR_ICC, %g2 22917c478bd9Sstevel@tonic-gate and %g2, %o0, %g2 ! clear all but psr.icc bits 22927c478bd9Sstevel@tonic-gate sllx %g2, PSR_TSTATE_CC_SHIFT, %g3 ! shift to tstate.ccr.icc 22937c478bd9Sstevel@tonic-gate wrpr %g1, %g3, %tstate ! write tstate 22947c478bd9Sstevel@tonic-gate 22957c478bd9Sstevel@tonic-gate set PSR_EF, %g2 22967c478bd9Sstevel@tonic-gate and %g2, %o0, %g2 ! clear all but fp enable bit 22977c478bd9Sstevel@tonic-gate srlx %g2, PSR_FPRS_FEF_SHIFT, %g4 ! shift ef to V9 fprs.fef 22987c478bd9Sstevel@tonic-gate wr %g0, %g4, %fprs ! write fprs 22997c478bd9Sstevel@tonic-gate 23007c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g2) ! load CPU struct addr to %g1 23017c478bd9Sstevel@tonic-gate ldn [%g1 + CPU_THREAD], %g2 ! load thread pointer 23027c478bd9Sstevel@tonic-gate ldn [%g2 + T_LWP], %g3 ! load klwp pointer 23037c478bd9Sstevel@tonic-gate ldn [%g3 + LWP_FPU], %g2 ! get lwp_fpu pointer 23047c478bd9Sstevel@tonic-gate stuw %g4, [%g2 + FPU_FPRS] ! write fef value to fpu_fprs 23057c478bd9Sstevel@tonic-gate srlx %g4, 2, %g4 ! shift fef value to bit 0 23067c478bd9Sstevel@tonic-gate stub %g4, [%g2 + FPU_EN] ! write fef value to fpu_en 23077c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 23087c478bd9Sstevel@tonic-gate SET_SIZE(.setpsr) 23097c478bd9Sstevel@tonic-gate 23107c478bd9Sstevel@tonic-gate/* 23117c478bd9Sstevel@tonic-gate * getlgrp 23127c478bd9Sstevel@tonic-gate * get home lgrpid on which the calling thread is currently executing. 23137c478bd9Sstevel@tonic-gate */ 23147c478bd9Sstevel@tonic-gate .type .getlgrp, #function 23157c478bd9Sstevel@tonic-gate.getlgrp: 23167c478bd9Sstevel@tonic-gate ! Thanks for the incredibly helpful comments 23177c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g2) ! load CPU struct addr to %g1 using %g2 23187c478bd9Sstevel@tonic-gate ld [%g1 + CPU_ID], %o0 ! load cpu_id 23197c478bd9Sstevel@tonic-gate ldn [%g1 + CPU_THREAD], %g2 ! load thread pointer 23207c478bd9Sstevel@tonic-gate ldn [%g2 + T_LPL], %g2 ! load lpl pointer 23217c478bd9Sstevel@tonic-gate ld [%g2 + LPL_LGRPID], %g1 ! load lpl_lgrpid 23227c478bd9Sstevel@tonic-gate sra %g1, 0, %o1 23237c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 23247c478bd9Sstevel@tonic-gate SET_SIZE(.getlgrp) 23257c478bd9Sstevel@tonic-gate 23267c478bd9Sstevel@tonic-gate/* 23277c478bd9Sstevel@tonic-gate * Entry for old 4.x trap (trap 0). 23287c478bd9Sstevel@tonic-gate */ 23297c478bd9Sstevel@tonic-gate ENTRY_NP(syscall_trap_4x) 23307c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g2) ! load CPU struct addr to %g1 using %g2 23317c478bd9Sstevel@tonic-gate ldn [%g1 + CPU_THREAD], %g2 ! load thread pointer 23327c478bd9Sstevel@tonic-gate ldn [%g2 + T_LWP], %g2 ! load klwp pointer 23337c478bd9Sstevel@tonic-gate ld [%g2 + PCB_TRAP0], %g2 ! lwp->lwp_pcb.pcb_trap0addr 23347c478bd9Sstevel@tonic-gate brz,pn %g2, 1f ! has it been set? 23357c478bd9Sstevel@tonic-gate st %l0, [%g1 + CPU_TMP1] ! delay - save some locals 23367c478bd9Sstevel@tonic-gate st %l1, [%g1 + CPU_TMP2] 23377c478bd9Sstevel@tonic-gate rdpr %tnpc, %l1 ! save old tnpc 23387c478bd9Sstevel@tonic-gate wrpr %g0, %g2, %tnpc ! setup tnpc 23397c478bd9Sstevel@tonic-gate 23407c478bd9Sstevel@tonic-gate mov %g1, %l0 ! save CPU struct addr 23417c478bd9Sstevel@tonic-gate wrpr %g0, 0, %gl 23427c478bd9Sstevel@tonic-gate mov %l1, %g6 ! pass tnpc to user code in %g6 23437c478bd9Sstevel@tonic-gate wrpr %g0, 1, %gl 23447c478bd9Sstevel@tonic-gate ld [%l0 + CPU_TMP2], %l1 ! restore locals 23457c478bd9Sstevel@tonic-gate ld [%l0 + CPU_TMP1], %l0 23467c478bd9Sstevel@tonic-gate FAST_TRAP_DONE_CHK_INTR 23477c478bd9Sstevel@tonic-gate1: 23487c478bd9Sstevel@tonic-gate ! 23497c478bd9Sstevel@tonic-gate ! check for old syscall mmap which is the only different one which 23507c478bd9Sstevel@tonic-gate ! must be the same. Others are handled in the compatibility library. 23517c478bd9Sstevel@tonic-gate ! 23527c478bd9Sstevel@tonic-gate mov %g1, %l0 ! save CPU struct addr 23537c478bd9Sstevel@tonic-gate wrpr %g0, 0, %gl 23547c478bd9Sstevel@tonic-gate cmp %g1, OSYS_mmap ! compare to old 4.x mmap 23557c478bd9Sstevel@tonic-gate movz %icc, SYS_mmap, %g1 23567c478bd9Sstevel@tonic-gate wrpr %g0, 1, %gl 23577c478bd9Sstevel@tonic-gate ld [%l0 + CPU_TMP1], %l0 23587c478bd9Sstevel@tonic-gate SYSCALL(syscall_trap32) 23597c478bd9Sstevel@tonic-gate SET_SIZE(syscall_trap_4x) 23607c478bd9Sstevel@tonic-gate 23617c478bd9Sstevel@tonic-gate/* 23627c478bd9Sstevel@tonic-gate * Handler for software trap 9. 23637c478bd9Sstevel@tonic-gate * Set trap0 emulation address for old 4.x system call trap. 23647c478bd9Sstevel@tonic-gate * XXX - this should be a system call. 23657c478bd9Sstevel@tonic-gate */ 23667c478bd9Sstevel@tonic-gate ENTRY_NP(set_trap0_addr) 23677c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g2) ! load CPU struct addr to %g1 using %g2 23687c478bd9Sstevel@tonic-gate st %l0, [%g1 + CPU_TMP1] ! save some locals 23697c478bd9Sstevel@tonic-gate st %l1, [%g1 + CPU_TMP2] 23707c478bd9Sstevel@tonic-gate mov %g1, %l0 ! preserve CPU addr 23717c478bd9Sstevel@tonic-gate wrpr %g0, 0, %gl 23727c478bd9Sstevel@tonic-gate mov %g1, %l1 23737c478bd9Sstevel@tonic-gate wrpr %g0, 1, %gl 23747c478bd9Sstevel@tonic-gate ! cannot assume globals retained their values after increasing %gl 23757c478bd9Sstevel@tonic-gate ldn [%l0 + CPU_THREAD], %g2 ! load thread pointer 23767c478bd9Sstevel@tonic-gate ldn [%g2 + T_LWP], %g2 ! load klwp pointer 23777c478bd9Sstevel@tonic-gate andn %l1, 3, %l1 ! force alignment 23787c478bd9Sstevel@tonic-gate st %l1, [%g2 + PCB_TRAP0] ! lwp->lwp_pcb.pcb_trap0addr 23797c478bd9Sstevel@tonic-gate ld [%l0 + CPU_TMP2], %l1 ! restore locals 23807c478bd9Sstevel@tonic-gate ld [%l0 + CPU_TMP1], %l0 23817c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 23827c478bd9Sstevel@tonic-gate SET_SIZE(set_trap0_addr) 23837c478bd9Sstevel@tonic-gate 23847c478bd9Sstevel@tonic-gate/* 23857c478bd9Sstevel@tonic-gate * mmu_trap_tl1 23867c478bd9Sstevel@tonic-gate * trap handler for unexpected mmu traps. 23877c478bd9Sstevel@tonic-gate * simply checks if the trap was a user lddf/stdf alignment trap, in which 23887c478bd9Sstevel@tonic-gate * case we go to fpu_trap or a user trap from the window handler, in which 23897c478bd9Sstevel@tonic-gate * case we go save the state on the pcb. Otherwise, we go to ptl1_panic. 23907c478bd9Sstevel@tonic-gate */ 23917c478bd9Sstevel@tonic-gate .type mmu_trap_tl1, #function 23927c478bd9Sstevel@tonic-gatemmu_trap_tl1: 23937c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE 23947c478bd9Sstevel@tonic-gate TRACE_PTR(%g5, %g6) 2395*023e71deSHaik Aftandilian GET_TRACE_TICK(%g6, %g7) 23967c478bd9Sstevel@tonic-gate stxa %g6, [%g5 + TRAP_ENT_TICK]%asi 23977c478bd9Sstevel@tonic-gate TRACE_SAVE_TL_GL_REGS(%g5, %g6) 23987c478bd9Sstevel@tonic-gate rdpr %tt, %g6 23997c478bd9Sstevel@tonic-gate stha %g6, [%g5 + TRAP_ENT_TT]%asi 24007c478bd9Sstevel@tonic-gate rdpr %tstate, %g6 24017c478bd9Sstevel@tonic-gate stxa %g6, [%g5 + TRAP_ENT_TSTATE]%asi 24027c478bd9Sstevel@tonic-gate stna %sp, [%g5 + TRAP_ENT_SP]%asi 24037c478bd9Sstevel@tonic-gate stna %g0, [%g5 + TRAP_ENT_TR]%asi 24047c478bd9Sstevel@tonic-gate rdpr %tpc, %g6 24057c478bd9Sstevel@tonic-gate stna %g6, [%g5 + TRAP_ENT_TPC]%asi 24067c478bd9Sstevel@tonic-gate MMU_FAULT_STATUS_AREA(%g6) 24077c478bd9Sstevel@tonic-gate ldx [%g6 + MMFSA_D_ADDR], %g6 24087c478bd9Sstevel@tonic-gate stna %g6, [%g5 + TRAP_ENT_F1]%asi ! MMU fault address 24097c478bd9Sstevel@tonic-gate CPU_PADDR(%g7, %g6); 24107c478bd9Sstevel@tonic-gate add %g7, CPU_TL1_HDLR, %g7 24117c478bd9Sstevel@tonic-gate lda [%g7]ASI_MEM, %g6 24127c478bd9Sstevel@tonic-gate stna %g6, [%g5 + TRAP_ENT_F2]%asi 24137c478bd9Sstevel@tonic-gate MMU_FAULT_STATUS_AREA(%g6) 24147c478bd9Sstevel@tonic-gate ldx [%g6 + MMFSA_D_TYPE], %g7 ! XXXQ should be a MMFSA_F_ constant? 24157c478bd9Sstevel@tonic-gate ldx [%g6 + MMFSA_D_CTX], %g6 24167c478bd9Sstevel@tonic-gate sllx %g6, SFSR_CTX_SHIFT, %g6 24177c478bd9Sstevel@tonic-gate or %g6, %g7, %g6 24187c478bd9Sstevel@tonic-gate stna %g6, [%g5 + TRAP_ENT_F3]%asi ! MMU context/type 24197c478bd9Sstevel@tonic-gate set 0xdeadbeef, %g6 24207c478bd9Sstevel@tonic-gate stna %g6, [%g5 + TRAP_ENT_F4]%asi 24217c478bd9Sstevel@tonic-gate TRACE_NEXT(%g5, %g6, %g7) 24227c478bd9Sstevel@tonic-gate#endif /* TRAPTRACE */ 24237c478bd9Sstevel@tonic-gate CPU_PADDR(%g7, %g6); 24247c478bd9Sstevel@tonic-gate add %g7, CPU_TL1_HDLR, %g7 ! %g7 = &cpu_m.tl1_hdlr (PA) 24257c478bd9Sstevel@tonic-gate lda [%g7]ASI_MEM, %g6 24267c478bd9Sstevel@tonic-gate brz,a,pt %g6, 1f 24277c478bd9Sstevel@tonic-gate nop 24287c478bd9Sstevel@tonic-gate sta %g0, [%g7]ASI_MEM 24297c478bd9Sstevel@tonic-gate ! XXXQ need to setup registers for sfmmu_mmu_trap? 24307c478bd9Sstevel@tonic-gate ba,a,pt %xcc, sfmmu_mmu_trap ! handle page faults 24317c478bd9Sstevel@tonic-gate1: 24327c478bd9Sstevel@tonic-gate rdpr %tpc, %g7 24337c478bd9Sstevel@tonic-gate /* in user_rtt? */ 24347c478bd9Sstevel@tonic-gate set rtt_fill_start, %g6 24357c478bd9Sstevel@tonic-gate cmp %g7, %g6 24367c478bd9Sstevel@tonic-gate blu,pn %xcc, 6f 24377c478bd9Sstevel@tonic-gate .empty 24387c478bd9Sstevel@tonic-gate set rtt_fill_end, %g6 24397c478bd9Sstevel@tonic-gate cmp %g7, %g6 24407c478bd9Sstevel@tonic-gate bgeu,pn %xcc, 6f 24417c478bd9Sstevel@tonic-gate nop 24427c478bd9Sstevel@tonic-gate set fault_rtt_fn1, %g7 24437c478bd9Sstevel@tonic-gate ba,a 7f 24447c478bd9Sstevel@tonic-gate6: 24457c478bd9Sstevel@tonic-gate ! check to see if the trap pc is in a window spill/fill handling 24467c478bd9Sstevel@tonic-gate rdpr %tpc, %g7 24477c478bd9Sstevel@tonic-gate /* tpc should be in the trap table */ 24487c478bd9Sstevel@tonic-gate set trap_table, %g6 24497c478bd9Sstevel@tonic-gate cmp %g7, %g6 24507c478bd9Sstevel@tonic-gate blu,a,pn %xcc, ptl1_panic 24517c478bd9Sstevel@tonic-gate mov PTL1_BAD_MMUTRAP, %g1 24527c478bd9Sstevel@tonic-gate set etrap_table, %g6 24537c478bd9Sstevel@tonic-gate cmp %g7, %g6 24547c478bd9Sstevel@tonic-gate bgeu,a,pn %xcc, ptl1_panic 24557c478bd9Sstevel@tonic-gate mov PTL1_BAD_MMUTRAP, %g1 24567c478bd9Sstevel@tonic-gate ! pc is inside the trap table, convert to trap type 24577c478bd9Sstevel@tonic-gate srl %g7, 5, %g6 ! XXXQ need #define 24587c478bd9Sstevel@tonic-gate and %g6, 0x1ff, %g6 ! XXXQ need #define 24597c478bd9Sstevel@tonic-gate ! and check for a window trap type 24607c478bd9Sstevel@tonic-gate and %g6, WTRAP_TTMASK, %g6 24617c478bd9Sstevel@tonic-gate cmp %g6, WTRAP_TYPE 24627c478bd9Sstevel@tonic-gate bne,a,pn %xcc, ptl1_panic 24637c478bd9Sstevel@tonic-gate mov PTL1_BAD_MMUTRAP, %g1 24647c478bd9Sstevel@tonic-gate andn %g7, WTRAP_ALIGN, %g7 /* 128 byte aligned */ 24657c478bd9Sstevel@tonic-gate add %g7, WTRAP_FAULTOFF, %g7 24667c478bd9Sstevel@tonic-gate 24677c478bd9Sstevel@tonic-gate7: 24687c478bd9Sstevel@tonic-gate ! Arguments are passed in the global set active after the 24697c478bd9Sstevel@tonic-gate ! 'done' instruction. Before switching sets, must save 24707c478bd9Sstevel@tonic-gate ! the calculated next pc 24717c478bd9Sstevel@tonic-gate wrpr %g0, %g7, %tnpc 24727c478bd9Sstevel@tonic-gate wrpr %g0, 1, %gl 24737c478bd9Sstevel@tonic-gate rdpr %tt, %g5 2474efaef81fSarao MMU_FAULT_STATUS_AREA(%g7) 24757c478bd9Sstevel@tonic-gate cmp %g5, T_ALIGNMENT 2476efaef81fSarao be,pn %xcc, 1f 2477efaef81fSarao ldx [%g7 + MMFSA_D_ADDR], %g6 2478efaef81fSarao ldx [%g7 + MMFSA_D_CTX], %g7 2479efaef81fSarao srlx %g6, MMU_PAGESHIFT, %g6 /* align address */ 248060972f37Sjb145095 cmp %g7, USER_CONTEXT_TYPE 2481efaef81fSarao sllx %g6, MMU_PAGESHIFT, %g6 248260972f37Sjb145095 movgu %icc, USER_CONTEXT_TYPE, %g7 2483efaef81fSarao or %g6, %g7, %g6 /* TAG_ACCESS */ 2484efaef81fSarao1: 24857c478bd9Sstevel@tonic-gate done 24867c478bd9Sstevel@tonic-gate SET_SIZE(mmu_trap_tl1) 24877c478bd9Sstevel@tonic-gate 24887c478bd9Sstevel@tonic-gate/* 24897c478bd9Sstevel@tonic-gate * Several traps use kmdb_trap and kmdb_trap_tl1 as their handlers. These 24907c478bd9Sstevel@tonic-gate * traps are valid only when kmdb is loaded. When the debugger is active, 24917c478bd9Sstevel@tonic-gate * the code below is rewritten to transfer control to the appropriate 24927c478bd9Sstevel@tonic-gate * debugger entry points. 24937c478bd9Sstevel@tonic-gate */ 24947c478bd9Sstevel@tonic-gate .global kmdb_trap 24957c478bd9Sstevel@tonic-gate .align 8 24967c478bd9Sstevel@tonic-gatekmdb_trap: 24977c478bd9Sstevel@tonic-gate ba,a trap_table0 24987c478bd9Sstevel@tonic-gate jmp %g1 + 0 24997c478bd9Sstevel@tonic-gate nop 25007c478bd9Sstevel@tonic-gate 25017c478bd9Sstevel@tonic-gate .global kmdb_trap_tl1 25027c478bd9Sstevel@tonic-gate .align 8 25037c478bd9Sstevel@tonic-gatekmdb_trap_tl1: 25047c478bd9Sstevel@tonic-gate ba,a trap_table0 25057c478bd9Sstevel@tonic-gate jmp %g1 + 0 25067c478bd9Sstevel@tonic-gate nop 25077c478bd9Sstevel@tonic-gate 25087c478bd9Sstevel@tonic-gate/* 25097c478bd9Sstevel@tonic-gate * This entry is copied from OBP's trap table during boot. 25107c478bd9Sstevel@tonic-gate */ 25117c478bd9Sstevel@tonic-gate .global obp_bpt 25127c478bd9Sstevel@tonic-gate .align 8 25137c478bd9Sstevel@tonic-gateobp_bpt: 25147c478bd9Sstevel@tonic-gate NOT 25157c478bd9Sstevel@tonic-gate 25167c478bd9Sstevel@tonic-gate 25177c478bd9Sstevel@tonic-gate 25187c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE 25197c478bd9Sstevel@tonic-gate/* 25207c478bd9Sstevel@tonic-gate * TRAPTRACE support. 25217c478bd9Sstevel@tonic-gate * labels here are branched to with "rd %pc, %g7" in the delay slot. 25227c478bd9Sstevel@tonic-gate * Return is done by "jmp %g7 + 4". 25237c478bd9Sstevel@tonic-gate */ 25247c478bd9Sstevel@tonic-gate 25257c478bd9Sstevel@tonic-gatetrace_dmmu: 25267c478bd9Sstevel@tonic-gate TRACE_PTR(%g3, %g6) 2527*023e71deSHaik Aftandilian GET_TRACE_TICK(%g6, %g5) 25287c478bd9Sstevel@tonic-gate stxa %g6, [%g3 + TRAP_ENT_TICK]%asi 25297c478bd9Sstevel@tonic-gate TRACE_SAVE_TL_GL_REGS(%g3, %g6) 25307c478bd9Sstevel@tonic-gate rdpr %tt, %g6 25317c478bd9Sstevel@tonic-gate stha %g6, [%g3 + TRAP_ENT_TT]%asi 25327c478bd9Sstevel@tonic-gate rdpr %tstate, %g6 25337c478bd9Sstevel@tonic-gate stxa %g6, [%g3 + TRAP_ENT_TSTATE]%asi 25347c478bd9Sstevel@tonic-gate stna %sp, [%g3 + TRAP_ENT_SP]%asi 25357c478bd9Sstevel@tonic-gate rdpr %tpc, %g6 25367c478bd9Sstevel@tonic-gate stna %g6, [%g3 + TRAP_ENT_TPC]%asi 25377c478bd9Sstevel@tonic-gate MMU_FAULT_STATUS_AREA(%g6) 25387c478bd9Sstevel@tonic-gate ldx [%g6 + MMFSA_D_ADDR], %g4 25397c478bd9Sstevel@tonic-gate stxa %g4, [%g3 + TRAP_ENT_TR]%asi 25407c478bd9Sstevel@tonic-gate ldx [%g6 + MMFSA_D_CTX], %g4 25417c478bd9Sstevel@tonic-gate stxa %g4, [%g3 + TRAP_ENT_F1]%asi 25427c478bd9Sstevel@tonic-gate ldx [%g6 + MMFSA_D_TYPE], %g4 25437c478bd9Sstevel@tonic-gate stxa %g4, [%g3 + TRAP_ENT_F2]%asi 25447c478bd9Sstevel@tonic-gate stxa %g6, [%g3 + TRAP_ENT_F3]%asi 25457c478bd9Sstevel@tonic-gate stna %g0, [%g3 + TRAP_ENT_F4]%asi 25467c478bd9Sstevel@tonic-gate TRACE_NEXT(%g3, %g4, %g5) 25477c478bd9Sstevel@tonic-gate jmp %g7 + 4 25487c478bd9Sstevel@tonic-gate nop 25497c478bd9Sstevel@tonic-gate 25507c478bd9Sstevel@tonic-gatetrace_immu: 25517c478bd9Sstevel@tonic-gate TRACE_PTR(%g3, %g6) 2552*023e71deSHaik Aftandilian GET_TRACE_TICK(%g6, %g5) 25537c478bd9Sstevel@tonic-gate stxa %g6, [%g3 + TRAP_ENT_TICK]%asi 25547c478bd9Sstevel@tonic-gate TRACE_SAVE_TL_GL_REGS(%g3, %g6) 25557c478bd9Sstevel@tonic-gate rdpr %tt, %g6 25567c478bd9Sstevel@tonic-gate stha %g6, [%g3 + TRAP_ENT_TT]%asi 25577c478bd9Sstevel@tonic-gate rdpr %tstate, %g6 25587c478bd9Sstevel@tonic-gate stxa %g6, [%g3 + TRAP_ENT_TSTATE]%asi 25597c478bd9Sstevel@tonic-gate stna %sp, [%g3 + TRAP_ENT_SP]%asi 25607c478bd9Sstevel@tonic-gate rdpr %tpc, %g6 25617c478bd9Sstevel@tonic-gate stna %g6, [%g3 + TRAP_ENT_TPC]%asi 25627c478bd9Sstevel@tonic-gate MMU_FAULT_STATUS_AREA(%g6) 25637c478bd9Sstevel@tonic-gate ldx [%g6 + MMFSA_I_ADDR], %g4 25647c478bd9Sstevel@tonic-gate stxa %g4, [%g3 + TRAP_ENT_TR]%asi 25657c478bd9Sstevel@tonic-gate ldx [%g6 + MMFSA_I_CTX], %g4 25667c478bd9Sstevel@tonic-gate stxa %g4, [%g3 + TRAP_ENT_F1]%asi 25677c478bd9Sstevel@tonic-gate ldx [%g6 + MMFSA_I_TYPE], %g4 25687c478bd9Sstevel@tonic-gate stxa %g4, [%g3 + TRAP_ENT_F2]%asi 25697c478bd9Sstevel@tonic-gate stxa %g6, [%g3 + TRAP_ENT_F3]%asi 25707c478bd9Sstevel@tonic-gate stna %g0, [%g3 + TRAP_ENT_F4]%asi 25717c478bd9Sstevel@tonic-gate TRACE_NEXT(%g3, %g4, %g5) 25727c478bd9Sstevel@tonic-gate jmp %g7 + 4 25737c478bd9Sstevel@tonic-gate nop 25747c478bd9Sstevel@tonic-gate 25757c478bd9Sstevel@tonic-gatetrace_gen: 25767c478bd9Sstevel@tonic-gate TRACE_PTR(%g3, %g6) 2577*023e71deSHaik Aftandilian GET_TRACE_TICK(%g6, %g5) 25787c478bd9Sstevel@tonic-gate stxa %g6, [%g3 + TRAP_ENT_TICK]%asi 25797c478bd9Sstevel@tonic-gate TRACE_SAVE_TL_GL_REGS(%g3, %g6) 25807c478bd9Sstevel@tonic-gate rdpr %tt, %g6 25817c478bd9Sstevel@tonic-gate stha %g6, [%g3 + TRAP_ENT_TT]%asi 25827c478bd9Sstevel@tonic-gate rdpr %tstate, %g6 25837c478bd9Sstevel@tonic-gate stxa %g6, [%g3 + TRAP_ENT_TSTATE]%asi 25847c478bd9Sstevel@tonic-gate stna %sp, [%g3 + TRAP_ENT_SP]%asi 25857c478bd9Sstevel@tonic-gate rdpr %tpc, %g6 25867c478bd9Sstevel@tonic-gate stna %g6, [%g3 + TRAP_ENT_TPC]%asi 25877c478bd9Sstevel@tonic-gate stna %g0, [%g3 + TRAP_ENT_TR]%asi 25887c478bd9Sstevel@tonic-gate stna %g0, [%g3 + TRAP_ENT_F1]%asi 25897c478bd9Sstevel@tonic-gate stna %g0, [%g3 + TRAP_ENT_F2]%asi 25907c478bd9Sstevel@tonic-gate stna %g0, [%g3 + TRAP_ENT_F3]%asi 25917c478bd9Sstevel@tonic-gate stna %g0, [%g3 + TRAP_ENT_F4]%asi 25927c478bd9Sstevel@tonic-gate TRACE_NEXT(%g3, %g4, %g5) 25937c478bd9Sstevel@tonic-gate jmp %g7 + 4 25947c478bd9Sstevel@tonic-gate nop 25957c478bd9Sstevel@tonic-gate 25967c478bd9Sstevel@tonic-gatetrace_win: 25977c478bd9Sstevel@tonic-gate TRACE_WIN_INFO(0, %l0, %l1, %l2) 25987c478bd9Sstevel@tonic-gate ! Keep the locals as clean as possible, caller cleans %l4 25997c478bd9Sstevel@tonic-gate clr %l2 26007c478bd9Sstevel@tonic-gate clr %l1 26017c478bd9Sstevel@tonic-gate jmp %l4 + 4 26027c478bd9Sstevel@tonic-gate clr %l0 26037c478bd9Sstevel@tonic-gate 26047c478bd9Sstevel@tonic-gate/* 26057c478bd9Sstevel@tonic-gate * Trace a tsb hit 26067c478bd9Sstevel@tonic-gate * g1 = tsbe pointer (in/clobbered) 26077c478bd9Sstevel@tonic-gate * g2 = tag access register (in) 26087c478bd9Sstevel@tonic-gate * g3 - g4 = scratch (clobbered) 26097c478bd9Sstevel@tonic-gate * g5 = tsbe data (in) 26107c478bd9Sstevel@tonic-gate * g6 = scratch (clobbered) 26117c478bd9Sstevel@tonic-gate * g7 = pc we jumped here from (in) 26127c478bd9Sstevel@tonic-gate */ 26137c478bd9Sstevel@tonic-gate 26147c478bd9Sstevel@tonic-gate ! Do not disturb %g5, it will be used after the trace 26157c478bd9Sstevel@tonic-gate ALTENTRY(trace_tsbhit) 26167c478bd9Sstevel@tonic-gate TRACE_TSBHIT(0) 26177c478bd9Sstevel@tonic-gate jmp %g7 + 4 26187c478bd9Sstevel@tonic-gate nop 26197c478bd9Sstevel@tonic-gate 26207c478bd9Sstevel@tonic-gate/* 26217c478bd9Sstevel@tonic-gate * Trace a TSB miss 26227c478bd9Sstevel@tonic-gate * 26237c478bd9Sstevel@tonic-gate * g1 = tsb8k pointer (in) 26247c478bd9Sstevel@tonic-gate * g2 = tag access register (in) 26257c478bd9Sstevel@tonic-gate * g3 = tsb4m pointer (in) 26267c478bd9Sstevel@tonic-gate * g4 = tsbe tag (in/clobbered) 26277c478bd9Sstevel@tonic-gate * g5 - g6 = scratch (clobbered) 26287c478bd9Sstevel@tonic-gate * g7 = pc we jumped here from (in) 26297c478bd9Sstevel@tonic-gate */ 26307c478bd9Sstevel@tonic-gate .global trace_tsbmiss 26317c478bd9Sstevel@tonic-gatetrace_tsbmiss: 26327c478bd9Sstevel@tonic-gate membar #Sync 26337c478bd9Sstevel@tonic-gate sethi %hi(FLUSH_ADDR), %g6 26347c478bd9Sstevel@tonic-gate flush %g6 26357c478bd9Sstevel@tonic-gate TRACE_PTR(%g5, %g6) 26367c478bd9Sstevel@tonic-gate stna %g2, [%g5 + TRAP_ENT_SP]%asi ! tag access 26377c478bd9Sstevel@tonic-gate stna %g4, [%g5 + TRAP_ENT_F1]%asi ! XXX? tsb tag 2638*023e71deSHaik Aftandilian GET_TRACE_TICK(%g6, %g4) 2639*023e71deSHaik Aftandilian stxa %g6, [%g5 + TRAP_ENT_TICK]%asi 26407c478bd9Sstevel@tonic-gate rdpr %tnpc, %g6 26417c478bd9Sstevel@tonic-gate stna %g6, [%g5 + TRAP_ENT_F2]%asi 26427c478bd9Sstevel@tonic-gate stna %g1, [%g5 + TRAP_ENT_F3]%asi ! tsb8k pointer 26437c478bd9Sstevel@tonic-gate rdpr %tpc, %g6 26447c478bd9Sstevel@tonic-gate stna %g6, [%g5 + TRAP_ENT_TPC]%asi 26457c478bd9Sstevel@tonic-gate TRACE_SAVE_TL_GL_REGS(%g5, %g6) 26467c478bd9Sstevel@tonic-gate rdpr %tt, %g6 26477c478bd9Sstevel@tonic-gate or %g6, TT_MMU_MISS, %g4 26487c478bd9Sstevel@tonic-gate stha %g4, [%g5 + TRAP_ENT_TT]%asi 2649efaef81fSarao mov MMFSA_D_ADDR, %g4 26507c478bd9Sstevel@tonic-gate cmp %g6, FAST_IMMU_MISS_TT 2651efaef81fSarao move %xcc, MMFSA_I_ADDR, %g4 26527c478bd9Sstevel@tonic-gate cmp %g6, T_INSTR_MMU_MISS 2653efaef81fSarao move %xcc, MMFSA_I_ADDR, %g4 2654efaef81fSarao MMU_FAULT_STATUS_AREA(%g6) 2655efaef81fSarao ldx [%g6 + %g4], %g6 2656efaef81fSarao stxa %g6, [%g5 + TRAP_ENT_TSTATE]%asi ! tag target 265760972f37Sjb145095 cmp %g4, MMFSA_D_ADDR 265860972f37Sjb145095 move %xcc, MMFSA_D_CTX, %g4 265960972f37Sjb145095 movne %xcc, MMFSA_I_CTX, %g4 266060972f37Sjb145095 MMU_FAULT_STATUS_AREA(%g6) 266160972f37Sjb145095 ldx [%g6 + %g4], %g6 266260972f37Sjb145095 stxa %g6, [%g5 + TRAP_ENT_F4]%asi ! context ID 26637c478bd9Sstevel@tonic-gate stna %g3, [%g5 + TRAP_ENT_TR]%asi ! tsb4m pointer 26647c478bd9Sstevel@tonic-gate TRACE_NEXT(%g5, %g4, %g6) 26657c478bd9Sstevel@tonic-gate jmp %g7 + 4 26667c478bd9Sstevel@tonic-gate nop 26677c478bd9Sstevel@tonic-gate 26687c478bd9Sstevel@tonic-gate/* 26697c478bd9Sstevel@tonic-gate * g2 = tag access register (in) 267060972f37Sjb145095 * g3 = ctx type (0, 1 or 2) (in) (not used) 26717c478bd9Sstevel@tonic-gate */ 26727c478bd9Sstevel@tonic-gatetrace_dataprot: 26737c478bd9Sstevel@tonic-gate membar #Sync 26747c478bd9Sstevel@tonic-gate sethi %hi(FLUSH_ADDR), %g6 26757c478bd9Sstevel@tonic-gate flush %g6 26767c478bd9Sstevel@tonic-gate TRACE_PTR(%g1, %g6) 2677*023e71deSHaik Aftandilian GET_TRACE_TICK(%g6, %g4) 26787c478bd9Sstevel@tonic-gate stxa %g6, [%g1 + TRAP_ENT_TICK]%asi 26797c478bd9Sstevel@tonic-gate rdpr %tpc, %g6 26807c478bd9Sstevel@tonic-gate stna %g6, [%g1 + TRAP_ENT_TPC]%asi 26817c478bd9Sstevel@tonic-gate rdpr %tstate, %g6 26827c478bd9Sstevel@tonic-gate stxa %g6, [%g1 + TRAP_ENT_TSTATE]%asi 26837c478bd9Sstevel@tonic-gate stna %g2, [%g1 + TRAP_ENT_SP]%asi ! tag access reg 26847c478bd9Sstevel@tonic-gate stna %g0, [%g1 + TRAP_ENT_F1]%asi 26857c478bd9Sstevel@tonic-gate stna %g0, [%g1 + TRAP_ENT_F2]%asi 26867c478bd9Sstevel@tonic-gate stna %g0, [%g1 + TRAP_ENT_F3]%asi 26877c478bd9Sstevel@tonic-gate stna %g0, [%g1 + TRAP_ENT_F4]%asi 26887c478bd9Sstevel@tonic-gate TRACE_SAVE_TL_GL_REGS(%g1, %g6) 26897c478bd9Sstevel@tonic-gate rdpr %tt, %g6 26907c478bd9Sstevel@tonic-gate stha %g6, [%g1 + TRAP_ENT_TT]%asi 269160972f37Sjb145095 mov MMFSA_D_CTX, %g4 269260972f37Sjb145095 cmp %g6, FAST_IMMU_MISS_TT 269360972f37Sjb145095 move %xcc, MMFSA_I_CTX, %g4 269460972f37Sjb145095 cmp %g6, T_INSTR_MMU_MISS 269560972f37Sjb145095 move %xcc, MMFSA_I_CTX, %g4 269660972f37Sjb145095 MMU_FAULT_STATUS_AREA(%g6) 269760972f37Sjb145095 ldx [%g6 + %g4], %g6 269860972f37Sjb145095 stxa %g6, [%g1 + TRAP_ENT_TR]%asi ! context ID 26997c478bd9Sstevel@tonic-gate TRACE_NEXT(%g1, %g4, %g5) 27007c478bd9Sstevel@tonic-gate jmp %g7 + 4 27017c478bd9Sstevel@tonic-gate nop 27027c478bd9Sstevel@tonic-gate 27037c478bd9Sstevel@tonic-gate#endif /* TRAPTRACE */ 27047c478bd9Sstevel@tonic-gate 2705efaef81fSarao/* 27061ae08745Sheppo * Handle watchdog reset trap. Enable the MMU using the MMU_ENABLE 27071ae08745Sheppo * HV service, which requires the return target to be specified as a VA 27081ae08745Sheppo * since we are enabling the MMU. We set the target to ptl1_panic. 27091ae08745Sheppo */ 27101ae08745Sheppo 27111ae08745Sheppo .type .watchdog_trap, #function 27121ae08745Sheppo.watchdog_trap: 27131ae08745Sheppo mov 1, %o0 27141ae08745Sheppo setx ptl1_panic, %g2, %o1 27151ae08745Sheppo mov MMU_ENABLE, %o5 27161ae08745Sheppo ta FAST_TRAP 27171ae08745Sheppo done 27181ae08745Sheppo SET_SIZE(.watchdog_trap) 27191ae08745Sheppo/* 2720efaef81fSarao * synthesize for trap(): SFAR in %g2, SFSR in %g3 2721efaef81fSarao */ 2722efaef81fSarao .type .dmmu_exc_lddf_not_aligned, #function 27237c478bd9Sstevel@tonic-gate.dmmu_exc_lddf_not_aligned: 27247c478bd9Sstevel@tonic-gate MMU_FAULT_STATUS_AREA(%g3) 27257c478bd9Sstevel@tonic-gate ldx [%g3 + MMFSA_D_ADDR], %g2 27267c478bd9Sstevel@tonic-gate /* Fault type not available in MMU fault status area */ 27277c478bd9Sstevel@tonic-gate mov MMFSA_F_UNALIGN, %g1 27287c478bd9Sstevel@tonic-gate ldx [%g3 + MMFSA_D_CTX], %g3 27297c478bd9Sstevel@tonic-gate sllx %g3, SFSR_CTX_SHIFT, %g3 27307c478bd9Sstevel@tonic-gate btst 1, %sp 27317c478bd9Sstevel@tonic-gate bnz,pt %xcc, .lddf_exception_not_aligned 2732efaef81fSarao or %g3, %g1, %g3 /* SFSR */ 27337c478bd9Sstevel@tonic-gate ba,a,pt %xcc, .mmu_exception_not_aligned 2734efaef81fSarao SET_SIZE(.dmmu_exc_lddf_not_aligned) 27357c478bd9Sstevel@tonic-gate 2736efaef81fSarao/* 2737efaef81fSarao * synthesize for trap(): SFAR in %g2, SFSR in %g3 2738efaef81fSarao */ 2739efaef81fSarao .type .dmmu_exc_stdf_not_aligned, #function 27407c478bd9Sstevel@tonic-gate.dmmu_exc_stdf_not_aligned: 27417c478bd9Sstevel@tonic-gate MMU_FAULT_STATUS_AREA(%g3) 27427c478bd9Sstevel@tonic-gate ldx [%g3 + MMFSA_D_ADDR], %g2 27437c478bd9Sstevel@tonic-gate /* Fault type not available in MMU fault status area */ 27447c478bd9Sstevel@tonic-gate mov MMFSA_F_UNALIGN, %g1 27457c478bd9Sstevel@tonic-gate ldx [%g3 + MMFSA_D_CTX], %g3 27467c478bd9Sstevel@tonic-gate sllx %g3, SFSR_CTX_SHIFT, %g3 27477c478bd9Sstevel@tonic-gate btst 1, %sp 27487c478bd9Sstevel@tonic-gate bnz,pt %xcc, .stdf_exception_not_aligned 2749efaef81fSarao or %g3, %g1, %g3 /* SFSR */ 27507c478bd9Sstevel@tonic-gate ba,a,pt %xcc, .mmu_exception_not_aligned 2751efaef81fSarao SET_SIZE(.dmmu_exc_stdf_not_aligned) 27527c478bd9Sstevel@tonic-gate 2753efaef81fSarao .type .dmmu_exception, #function 2754efaef81fSarao.dmmu_exception: 2755efaef81fSarao MMU_FAULT_STATUS_AREA(%g3) 2756efaef81fSarao ldx [%g3 + MMFSA_D_ADDR], %g2 2757efaef81fSarao ldx [%g3 + MMFSA_D_TYPE], %g1 275860972f37Sjb145095 ldx [%g3 + MMFSA_D_CTX], %g4 2759efaef81fSarao srlx %g2, MMU_PAGESHIFT, %g2 /* align address */ 2760efaef81fSarao sllx %g2, MMU_PAGESHIFT, %g2 276160972f37Sjb145095 sllx %g4, SFSR_CTX_SHIFT, %g3 2762efaef81fSarao or %g3, %g1, %g3 /* SFSR */ 276360972f37Sjb145095 cmp %g4, USER_CONTEXT_TYPE 276460972f37Sjb145095 movgeu %icc, USER_CONTEXT_TYPE, %g4 276560972f37Sjb145095 or %g2, %g4, %g2 /* TAG_ACCESS */ 2766efaef81fSarao ba,pt %xcc, .mmu_exception_end 2767efaef81fSarao mov T_DATA_EXCEPTION, %g1 2768efaef81fSarao SET_SIZE(.dmmu_exception) 27697c478bd9Sstevel@tonic-gate 2770b9e93c10SJonathan Haslam .align 32 2771b9e93c10SJonathan Haslam .global pil15_epilogue 2772b9e93c10SJonathan Haslampil15_epilogue: 2773b9e93c10SJonathan Haslam ba pil_interrupt_common 2774b9e93c10SJonathan Haslam nop 2775b9e93c10SJonathan Haslam .align 32 2776b9e93c10SJonathan Haslam 27777c478bd9Sstevel@tonic-gate/* 27787c478bd9Sstevel@tonic-gate * fast_trap_done, fast_trap_done_chk_intr: 27797c478bd9Sstevel@tonic-gate * 27807c478bd9Sstevel@tonic-gate * Due to the design of UltraSPARC pipeline, pending interrupts are not 27817c478bd9Sstevel@tonic-gate * taken immediately after a RETRY or DONE instruction which causes IE to 27827c478bd9Sstevel@tonic-gate * go from 0 to 1. Instead, the instruction at %tpc or %tnpc is allowed 27837c478bd9Sstevel@tonic-gate * to execute first before taking any interrupts. If that instruction 27847c478bd9Sstevel@tonic-gate * results in other traps, and if the corresponding trap handler runs 27857c478bd9Sstevel@tonic-gate * entirely at TL=1 with interrupts disabled, then pending interrupts 27867c478bd9Sstevel@tonic-gate * won't be taken until after yet another instruction following the %tpc 27877c478bd9Sstevel@tonic-gate * or %tnpc. 27887c478bd9Sstevel@tonic-gate * 27897c478bd9Sstevel@tonic-gate * A malicious user program can use this feature to block out interrupts 27907c478bd9Sstevel@tonic-gate * for extended durations, which can result in send_mondo_timeout kernel 27917c478bd9Sstevel@tonic-gate * panic. 27927c478bd9Sstevel@tonic-gate * 27937c478bd9Sstevel@tonic-gate * This problem is addressed by servicing any pending interrupts via 27947c478bd9Sstevel@tonic-gate * sys_trap before returning back to the user mode from a fast trap 27957c478bd9Sstevel@tonic-gate * handler. The "done" instruction within a fast trap handler, which 27967c478bd9Sstevel@tonic-gate * runs entirely at TL=1 with interrupts disabled, is replaced with the 27977c478bd9Sstevel@tonic-gate * FAST_TRAP_DONE macro, which branches control to this fast_trap_done 27987c478bd9Sstevel@tonic-gate * entry point. 27997c478bd9Sstevel@tonic-gate * 28007c478bd9Sstevel@tonic-gate * We check for any pending interrupts here and force a sys_trap to 28017c478bd9Sstevel@tonic-gate * service those interrupts, if any. To minimize overhead, pending 28027c478bd9Sstevel@tonic-gate * interrupts are checked if the %tpc happens to be at 16K boundary, 28037c478bd9Sstevel@tonic-gate * which allows a malicious program to execute at most 4K consecutive 28047c478bd9Sstevel@tonic-gate * instructions before we service any pending interrupts. If a worst 28057c478bd9Sstevel@tonic-gate * case fast trap handler takes about 2 usec, then interrupts will be 28067c478bd9Sstevel@tonic-gate * blocked for at most 8 msec, less than a clock tick. 28077c478bd9Sstevel@tonic-gate * 28087c478bd9Sstevel@tonic-gate * For the cases where we don't know if the %tpc will cross a 16K 28097c478bd9Sstevel@tonic-gate * boundary, we can't use the above optimization and always process 28107c478bd9Sstevel@tonic-gate * any pending interrupts via fast_frap_done_chk_intr entry point. 28117c478bd9Sstevel@tonic-gate * 28127c478bd9Sstevel@tonic-gate * Entry Conditions: 28137c478bd9Sstevel@tonic-gate * %pstate am:0 priv:1 ie:0 28147c478bd9Sstevel@tonic-gate * globals are AG (not normal globals) 28157c478bd9Sstevel@tonic-gate */ 28167c478bd9Sstevel@tonic-gate 28177c478bd9Sstevel@tonic-gate .global fast_trap_done, fast_trap_done_chk_intr 28187c478bd9Sstevel@tonic-gatefast_trap_done: 28197c478bd9Sstevel@tonic-gate rdpr %tpc, %g5 28207c478bd9Sstevel@tonic-gate sethi %hi(0xffffc000), %g6 ! 1's complement of 0x3fff 28217c478bd9Sstevel@tonic-gate andncc %g5, %g6, %g0 ! check lower 14 bits of %tpc 28227c478bd9Sstevel@tonic-gate bz,pn %icc, 1f ! branch if zero (lower 32 bits only) 28237c478bd9Sstevel@tonic-gate nop 28247c478bd9Sstevel@tonic-gate done 28257c478bd9Sstevel@tonic-gate 28267c478bd9Sstevel@tonic-gatefast_trap_done_chk_intr: 28277c478bd9Sstevel@tonic-gate1: rd SOFTINT, %g6 28287c478bd9Sstevel@tonic-gate brnz,pn %g6, 2f ! branch if any pending intr 28297c478bd9Sstevel@tonic-gate nop 28307c478bd9Sstevel@tonic-gate done 28317c478bd9Sstevel@tonic-gate 28327c478bd9Sstevel@tonic-gate2: 28337c478bd9Sstevel@tonic-gate /* 28347c478bd9Sstevel@tonic-gate * We get here if there are any pending interrupts. 28357c478bd9Sstevel@tonic-gate * Adjust %tpc/%tnpc as we'll be resuming via "retry" 28367c478bd9Sstevel@tonic-gate * instruction. 28377c478bd9Sstevel@tonic-gate */ 28387c478bd9Sstevel@tonic-gate rdpr %tnpc, %g5 28397c478bd9Sstevel@tonic-gate wrpr %g0, %g5, %tpc 28407c478bd9Sstevel@tonic-gate add %g5, 4, %g5 28417c478bd9Sstevel@tonic-gate wrpr %g0, %g5, %tnpc 28427c478bd9Sstevel@tonic-gate 28437c478bd9Sstevel@tonic-gate /* 28447c478bd9Sstevel@tonic-gate * Force a dummy sys_trap call so that interrupts can be serviced. 28457c478bd9Sstevel@tonic-gate */ 28467c478bd9Sstevel@tonic-gate set fast_trap_dummy_call, %g1 28477c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap 28487c478bd9Sstevel@tonic-gate mov -1, %g4 28497c478bd9Sstevel@tonic-gate 28507c478bd9Sstevel@tonic-gatefast_trap_dummy_call: 28517c478bd9Sstevel@tonic-gate retl 28527c478bd9Sstevel@tonic-gate nop 28537c478bd9Sstevel@tonic-gate 28544a75c0c1Sedp/* 285559f2ff5cSedp * Currently the brand syscall interposition code is not enabled by 285659f2ff5cSedp * default. Instead, when a branded zone is first booted the brand 285759f2ff5cSedp * infrastructure will patch the trap table so that the syscall 285859f2ff5cSedp * entry points are redirected to syscall_wrapper32 and syscall_wrapper 285959f2ff5cSedp * for ILP32 and LP64 syscalls respectively. this is done in 286059f2ff5cSedp * brand_plat_interposition_enable(). Note that the syscall wrappers 286159f2ff5cSedp * below do not collect any trap trace data since the syscall hot patch 286259f2ff5cSedp * points are reached after trap trace data has already been collected. 28634a75c0c1Sedp */ 28644a75c0c1Sedp#define BRAND_CALLBACK(callback_id) \ 28654a75c0c1Sedp CPU_ADDR(%g2, %g1) /* load CPU struct addr to %g2 */ ;\ 28664a75c0c1Sedp ldn [%g2 + CPU_THREAD], %g3 /* load thread pointer */ ;\ 28674a75c0c1Sedp ldn [%g3 + T_PROCP], %g3 /* get proc pointer */ ;\ 28684a75c0c1Sedp ldn [%g3 + P_BRAND], %g3 /* get brand pointer */ ;\ 28694a75c0c1Sedp brz %g3, 1f /* No brand? No callback. */ ;\ 28704a75c0c1Sedp nop ;\ 28714a75c0c1Sedp ldn [%g3 + B_MACHOPS], %g3 /* get machops list */ ;\ 28724a75c0c1Sedp ldn [%g3 + (callback_id << 3)], %g3 ;\ 28734a75c0c1Sedp brz %g3, 1f ;\ 28744a75c0c1Sedp /* \ 28754a75c0c1Sedp * This isn't pretty. We want a low-latency way for the callback \ 28764a75c0c1Sedp * routine to decline to do anything. We just pass in an address \ 28774a75c0c1Sedp * the routine can directly jmp back to, pretending that nothing \ 28784a75c0c1Sedp * has happened. \ 28794a75c0c1Sedp * \ 28804a75c0c1Sedp * %g1: return address (where the brand handler jumps back to) \ 28814a75c0c1Sedp * %g2: address of CPU structure \ 28824a75c0c1Sedp * %g3: address of brand handler (where we will jump to) \ 28834a75c0c1Sedp */ \ 28844a75c0c1Sedp mov %pc, %g1 ;\ 28854a75c0c1Sedp add %g1, 16, %g1 ;\ 28864a75c0c1Sedp jmp %g3 ;\ 28874a75c0c1Sedp nop ;\ 28884a75c0c1Sedp1: 28894a75c0c1Sedp 28904a75c0c1Sedp ENTRY_NP(syscall_wrapper32) 28914a75c0c1Sedp BRAND_CALLBACK(BRAND_CB_SYSCALL32) 28924a75c0c1Sedp SYSCALL_NOTT(syscall_trap32) 28934a75c0c1Sedp SET_SIZE(syscall_wrapper32) 28944a75c0c1Sedp 28954a75c0c1Sedp ENTRY_NP(syscall_wrapper) 28964a75c0c1Sedp BRAND_CALLBACK(BRAND_CB_SYSCALL) 28974a75c0c1Sedp SYSCALL_NOTT(syscall_trap) 28984a75c0c1Sedp SET_SIZE(syscall_wrapper) 28994a75c0c1Sedp 29007c478bd9Sstevel@tonic-gate#endif /* lint */ 2901