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 */ 217c478bd9Sstevel@tonic-gate/* 22b9e93c10SJonathan Haslam * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 25*5d9d9091SRichard Lowe 267c478bd9Sstevel@tonic-gate#include "assym.h" 277c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h> 287c478bd9Sstevel@tonic-gate#include <sys/privregs.h> 297c478bd9Sstevel@tonic-gate#include <sys/sun4asi.h> 3025cf1a30Sjl#include <sys/spitregs.h> 317c478bd9Sstevel@tonic-gate#include <sys/cheetahregs.h> 327c478bd9Sstevel@tonic-gate#include <sys/machtrap.h> 337c478bd9Sstevel@tonic-gate#include <sys/machthread.h> 349acbbeafSnn#include <sys/machbrand.h> 357c478bd9Sstevel@tonic-gate#include <sys/pcb.h> 367c478bd9Sstevel@tonic-gate#include <sys/pte.h> 377c478bd9Sstevel@tonic-gate#include <sys/mmu.h> 387c478bd9Sstevel@tonic-gate#include <sys/machpcb.h> 397c478bd9Sstevel@tonic-gate#include <sys/async.h> 407c478bd9Sstevel@tonic-gate#include <sys/intreg.h> 417c478bd9Sstevel@tonic-gate#include <sys/scb.h> 427c478bd9Sstevel@tonic-gate#include <sys/psr_compat.h> 437c478bd9Sstevel@tonic-gate#include <sys/syscall.h> 447c478bd9Sstevel@tonic-gate#include <sys/machparam.h> 457c478bd9Sstevel@tonic-gate#include <sys/traptrace.h> 467c478bd9Sstevel@tonic-gate#include <vm/hat_sfmmu.h> 477c478bd9Sstevel@tonic-gate#include <sys/archsystm.h> 487c478bd9Sstevel@tonic-gate#include <sys/utrap.h> 497c478bd9Sstevel@tonic-gate#include <sys/clock.h> 507c478bd9Sstevel@tonic-gate#include <sys/intr.h> 517c478bd9Sstevel@tonic-gate#include <sys/fpu/fpu_simulator.h> 527c478bd9Sstevel@tonic-gate#include <vm/seg_spt.h> 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate/* 557c478bd9Sstevel@tonic-gate * WARNING: If you add a fast trap handler which can be invoked by a 567c478bd9Sstevel@tonic-gate * non-privileged user, you may have to use the FAST_TRAP_DONE macro 577c478bd9Sstevel@tonic-gate * instead of "done" instruction to return back to the user mode. See 587c478bd9Sstevel@tonic-gate * comments for the "fast_trap_done" entry point for more information. 597c478bd9Sstevel@tonic-gate * 607c478bd9Sstevel@tonic-gate * An alternate FAST_TRAP_DONE_CHK_INTR macro should be used for the 617c478bd9Sstevel@tonic-gate * cases where you always want to process any pending interrupts before 627c478bd9Sstevel@tonic-gate * returning back to the user mode. 637c478bd9Sstevel@tonic-gate */ 647c478bd9Sstevel@tonic-gate#define FAST_TRAP_DONE \ 657c478bd9Sstevel@tonic-gate ba,a fast_trap_done 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate#define FAST_TRAP_DONE_CHK_INTR \ 687c478bd9Sstevel@tonic-gate ba,a fast_trap_done_chk_intr 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate/* 717c478bd9Sstevel@tonic-gate * SPARC V9 Trap Table 727c478bd9Sstevel@tonic-gate * 737c478bd9Sstevel@tonic-gate * Most of the trap handlers are made from common building 747c478bd9Sstevel@tonic-gate * blocks, and some are instantiated multiple times within 757c478bd9Sstevel@tonic-gate * the trap table. So, I build a bunch of macros, then 767c478bd9Sstevel@tonic-gate * populate the table using only the macros. 777c478bd9Sstevel@tonic-gate * 787c478bd9Sstevel@tonic-gate * Many macros branch to sys_trap. Its calling convention is: 797c478bd9Sstevel@tonic-gate * %g1 kernel trap handler 807c478bd9Sstevel@tonic-gate * %g2, %g3 args for above 817c478bd9Sstevel@tonic-gate * %g4 desire %pil 827c478bd9Sstevel@tonic-gate */ 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate/* 877c478bd9Sstevel@tonic-gate * Tracing macro. Adds two instructions if TRAPTRACE is defined. 887c478bd9Sstevel@tonic-gate */ 897c478bd9Sstevel@tonic-gate#define TT_TRACE(label) \ 907c478bd9Sstevel@tonic-gate ba label ;\ 917c478bd9Sstevel@tonic-gate rd %pc, %g7 927c478bd9Sstevel@tonic-gate#define TT_TRACE_INS 2 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate#define TT_TRACE_L(label) \ 957c478bd9Sstevel@tonic-gate ba label ;\ 967c478bd9Sstevel@tonic-gate rd %pc, %l4 ;\ 977c478bd9Sstevel@tonic-gate clr %l4 987c478bd9Sstevel@tonic-gate#define TT_TRACE_L_INS 3 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate#else 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate#define TT_TRACE(label) 1037c478bd9Sstevel@tonic-gate#define TT_TRACE_INS 0 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate#define TT_TRACE_L(label) 1067c478bd9Sstevel@tonic-gate#define TT_TRACE_L_INS 0 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate#endif 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate/* 1117c478bd9Sstevel@tonic-gate * This first set are funneled to trap() with %tt as the type. 1127c478bd9Sstevel@tonic-gate * Trap will then either panic or send the user a signal. 1137c478bd9Sstevel@tonic-gate */ 1147c478bd9Sstevel@tonic-gate/* 1157c478bd9Sstevel@tonic-gate * NOT is used for traps that just shouldn't happen. 1167c478bd9Sstevel@tonic-gate * It comes in both single and quadruple flavors. 1177c478bd9Sstevel@tonic-gate */ 1187c478bd9Sstevel@tonic-gate .global trap 1197c478bd9Sstevel@tonic-gate#define NOT \ 1207c478bd9Sstevel@tonic-gate TT_TRACE(trace_gen) ;\ 1217c478bd9Sstevel@tonic-gate set trap, %g1 ;\ 1227c478bd9Sstevel@tonic-gate rdpr %tt, %g3 ;\ 1237c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap ;\ 1247c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 ;\ 1257c478bd9Sstevel@tonic-gate .align 32 1267c478bd9Sstevel@tonic-gate#define NOT4 NOT; NOT; NOT; NOT 1277c478bd9Sstevel@tonic-gate/* 1287c478bd9Sstevel@tonic-gate * RED is for traps that use the red mode handler. 1297c478bd9Sstevel@tonic-gate * We should never see these either. 1307c478bd9Sstevel@tonic-gate */ 1317c478bd9Sstevel@tonic-gate#define RED NOT 1327c478bd9Sstevel@tonic-gate/* 1337c478bd9Sstevel@tonic-gate * BAD is used for trap vectors we don't have a kernel 1347c478bd9Sstevel@tonic-gate * handler for. 1357c478bd9Sstevel@tonic-gate * It also comes in single and quadruple versions. 1367c478bd9Sstevel@tonic-gate */ 1377c478bd9Sstevel@tonic-gate#define BAD NOT 1387c478bd9Sstevel@tonic-gate#define BAD4 NOT4 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate#define DONE \ 1417c478bd9Sstevel@tonic-gate done; \ 1427c478bd9Sstevel@tonic-gate .align 32 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate/* 1457c478bd9Sstevel@tonic-gate * TRAP vectors to the trap() function. 1467c478bd9Sstevel@tonic-gate * It's main use is for user errors. 1477c478bd9Sstevel@tonic-gate */ 1487c478bd9Sstevel@tonic-gate .global trap 1497c478bd9Sstevel@tonic-gate#define TRAP(arg) \ 1507c478bd9Sstevel@tonic-gate TT_TRACE(trace_gen) ;\ 1517c478bd9Sstevel@tonic-gate set trap, %g1 ;\ 1527c478bd9Sstevel@tonic-gate mov arg, %g3 ;\ 1537c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap ;\ 1547c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 ;\ 1557c478bd9Sstevel@tonic-gate .align 32 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate/* 15859f2ff5cSedp * SYSCALL is used for unsupported syscall interfaces (with 'which' 15959f2ff5cSedp * set to 'nosys') and legacy support of old SunOS 4.x syscalls (with 16059f2ff5cSedp * 'which' set to 'syscall_trap32'). 16159f2ff5cSedp * 16259f2ff5cSedp * The SYSCALL_TRAP* macros are used for syscall entry points. 16359f2ff5cSedp * SYSCALL_TRAP is used to support LP64 syscalls and SYSCALL_TRAP32 16459f2ff5cSedp * is used to support ILP32. Each macro can only be used once 16559f2ff5cSedp * since they each define a symbol. The symbols are used as hot patch 16659f2ff5cSedp * points by the brand infrastructure to dynamically enable and disable 16759f2ff5cSedp * brand syscall interposition. See the comments around BRAND_CALLBACK 16859f2ff5cSedp * and brand_plat_interposition_enable() for more information. 1697c478bd9Sstevel@tonic-gate */ 1704a75c0c1Sedp#define SYSCALL_NOTT(which) \ 1717c478bd9Sstevel@tonic-gate set (which), %g1 ;\ 1727c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap ;\ 1737c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 ;\ 1747c478bd9Sstevel@tonic-gate .align 32 1757c478bd9Sstevel@tonic-gate 17659f2ff5cSedp#define SYSCALL(which) \ 17759f2ff5cSedp TT_TRACE(trace_gen) ;\ 17859f2ff5cSedp SYSCALL_NOTT(which) 17959f2ff5cSedp 18059f2ff5cSedp#define SYSCALL_TRAP32 \ 18159f2ff5cSedp TT_TRACE(trace_gen) ;\ 18259f2ff5cSedp ALTENTRY(syscall_trap32_patch_point) \ 18359f2ff5cSedp SYSCALL_NOTT(syscall_trap32) 18459f2ff5cSedp 18559f2ff5cSedp#define SYSCALL_TRAP \ 18659f2ff5cSedp TT_TRACE(trace_gen) ;\ 18759f2ff5cSedp ALTENTRY(syscall_trap_patch_point) \ 18859f2ff5cSedp SYSCALL_NOTT(syscall_trap) 18959f2ff5cSedp 19050eff769Smb#define FLUSHW(h_name) \ 19150eff769Smb .global h_name ;\ 19250eff769Smbh_name: ;\ 1937c478bd9Sstevel@tonic-gate set trap, %g1 ;\ 1947c478bd9Sstevel@tonic-gate mov T_FLUSHW, %g3 ;\ 1957c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 ;\ 1967c478bd9Sstevel@tonic-gate save ;\ 1977c478bd9Sstevel@tonic-gate flushw ;\ 1987c478bd9Sstevel@tonic-gate restore ;\ 1997c478bd9Sstevel@tonic-gate FAST_TRAP_DONE ;\ 2007c478bd9Sstevel@tonic-gate .align 32 2017c478bd9Sstevel@tonic-gate 2027c478bd9Sstevel@tonic-gate/* 2037c478bd9Sstevel@tonic-gate * GOTO just jumps to a label. 2047c478bd9Sstevel@tonic-gate * It's used for things that can be fixed without going thru sys_trap. 2057c478bd9Sstevel@tonic-gate */ 2067c478bd9Sstevel@tonic-gate#define GOTO(label) \ 2077c478bd9Sstevel@tonic-gate .global label ;\ 2087c478bd9Sstevel@tonic-gate ba,a label ;\ 2097c478bd9Sstevel@tonic-gate .empty ;\ 2107c478bd9Sstevel@tonic-gate .align 32 2117c478bd9Sstevel@tonic-gate 2127c478bd9Sstevel@tonic-gate/* 2137c478bd9Sstevel@tonic-gate * GOTO_TT just jumps to a label. 2147c478bd9Sstevel@tonic-gate * correctable ECC error traps at level 0 and 1 will use this macro. 2157c478bd9Sstevel@tonic-gate * It's used for things that can be fixed without going thru sys_trap. 2167c478bd9Sstevel@tonic-gate */ 2177c478bd9Sstevel@tonic-gate#define GOTO_TT(label, ttlabel) \ 2187c478bd9Sstevel@tonic-gate .global label ;\ 2197c478bd9Sstevel@tonic-gate TT_TRACE(ttlabel) ;\ 2207c478bd9Sstevel@tonic-gate ba,a label ;\ 2217c478bd9Sstevel@tonic-gate .empty ;\ 2227c478bd9Sstevel@tonic-gate .align 32 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate/* 2257c478bd9Sstevel@tonic-gate * Privileged traps 2267c478bd9Sstevel@tonic-gate * Takes breakpoint if privileged, calls trap() if not. 2277c478bd9Sstevel@tonic-gate */ 2287c478bd9Sstevel@tonic-gate#define PRIV(label) \ 2297c478bd9Sstevel@tonic-gate rdpr %tstate, %g1 ;\ 2307c478bd9Sstevel@tonic-gate btst TSTATE_PRIV, %g1 ;\ 2317c478bd9Sstevel@tonic-gate bnz label ;\ 2327c478bd9Sstevel@tonic-gate rdpr %tt, %g3 ;\ 2337c478bd9Sstevel@tonic-gate set trap, %g1 ;\ 2347c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap ;\ 2357c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 ;\ 2367c478bd9Sstevel@tonic-gate .align 32 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate/* 2407c478bd9Sstevel@tonic-gate * DTrace traps. 2417c478bd9Sstevel@tonic-gate */ 2427c478bd9Sstevel@tonic-gate#define DTRACE_PID \ 2437c478bd9Sstevel@tonic-gate .global dtrace_pid_probe ;\ 2447c478bd9Sstevel@tonic-gate set dtrace_pid_probe, %g1 ;\ 2457c478bd9Sstevel@tonic-gate ba,pt %xcc, user_trap ;\ 2467c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 ;\ 2477c478bd9Sstevel@tonic-gate .align 32 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate#define DTRACE_RETURN \ 2507c478bd9Sstevel@tonic-gate .global dtrace_return_probe ;\ 2517c478bd9Sstevel@tonic-gate set dtrace_return_probe, %g1 ;\ 2527c478bd9Sstevel@tonic-gate ba,pt %xcc, user_trap ;\ 2537c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 ;\ 2547c478bd9Sstevel@tonic-gate .align 32 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate/* 2577c478bd9Sstevel@tonic-gate * REGISTER WINDOW MANAGEMENT MACROS 2587c478bd9Sstevel@tonic-gate */ 2597c478bd9Sstevel@tonic-gate 2607c478bd9Sstevel@tonic-gate/* 2617c478bd9Sstevel@tonic-gate * various convenient units of padding 2627c478bd9Sstevel@tonic-gate */ 2637c478bd9Sstevel@tonic-gate#define SKIP(n) .skip 4*(n) 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate/* 2667c478bd9Sstevel@tonic-gate * CLEAN_WINDOW is the simple handler for cleaning a register window. 2677c478bd9Sstevel@tonic-gate */ 2687c478bd9Sstevel@tonic-gate#define CLEAN_WINDOW \ 2697c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) ;\ 2707c478bd9Sstevel@tonic-gate rdpr %cleanwin, %l0; inc %l0; wrpr %l0, %cleanwin ;\ 2717c478bd9Sstevel@tonic-gate clr %l0; clr %l1; clr %l2; clr %l3 ;\ 2727c478bd9Sstevel@tonic-gate clr %l4; clr %l5; clr %l6; clr %l7 ;\ 2737c478bd9Sstevel@tonic-gate clr %o0; clr %o1; clr %o2; clr %o3 ;\ 2747c478bd9Sstevel@tonic-gate clr %o4; clr %o5; clr %o6; clr %o7 ;\ 2757c478bd9Sstevel@tonic-gate retry; .align 128 2767c478bd9Sstevel@tonic-gate 2777c478bd9Sstevel@tonic-gate/* 2787c478bd9Sstevel@tonic-gate * If we get an unresolved tlb miss while in a window handler, the fault 2797c478bd9Sstevel@tonic-gate * handler will resume execution at the last instruction of the window 2807c478bd9Sstevel@tonic-gate * hander, instead of delivering the fault to the kernel. Spill handlers 2817c478bd9Sstevel@tonic-gate * use this to spill windows into the wbuf. 2827c478bd9Sstevel@tonic-gate * 2837c478bd9Sstevel@tonic-gate * The mixed handler works by checking %sp, and branching to the correct 2847c478bd9Sstevel@tonic-gate * handler. This is done by branching back to label 1: for 32b frames, 2857c478bd9Sstevel@tonic-gate * or label 2: for 64b frames; which implies the handler order is: 32b, 2867c478bd9Sstevel@tonic-gate * 64b, mixed. The 1: and 2: labels are offset into the routines to 2877c478bd9Sstevel@tonic-gate * allow the branchs' delay slots to contain useful instructions. 2887c478bd9Sstevel@tonic-gate */ 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate/* 2917c478bd9Sstevel@tonic-gate * SPILL_32bit spills a 32-bit-wide kernel register window. It 2927c478bd9Sstevel@tonic-gate * assumes that the kernel context and the nucleus context are the 2937c478bd9Sstevel@tonic-gate * same. The stack pointer is required to be eight-byte aligned even 2947c478bd9Sstevel@tonic-gate * though this code only needs it to be four-byte aligned. 2957c478bd9Sstevel@tonic-gate */ 2967c478bd9Sstevel@tonic-gate#define SPILL_32bit(tail) \ 2977c478bd9Sstevel@tonic-gate srl %sp, 0, %sp ;\ 2987c478bd9Sstevel@tonic-gate1: st %l0, [%sp + 0] ;\ 2997c478bd9Sstevel@tonic-gate st %l1, [%sp + 4] ;\ 3007c478bd9Sstevel@tonic-gate st %l2, [%sp + 8] ;\ 3017c478bd9Sstevel@tonic-gate st %l3, [%sp + 12] ;\ 3027c478bd9Sstevel@tonic-gate st %l4, [%sp + 16] ;\ 3037c478bd9Sstevel@tonic-gate st %l5, [%sp + 20] ;\ 3047c478bd9Sstevel@tonic-gate st %l6, [%sp + 24] ;\ 3057c478bd9Sstevel@tonic-gate st %l7, [%sp + 28] ;\ 3067c478bd9Sstevel@tonic-gate st %i0, [%sp + 32] ;\ 3077c478bd9Sstevel@tonic-gate st %i1, [%sp + 36] ;\ 3087c478bd9Sstevel@tonic-gate st %i2, [%sp + 40] ;\ 3097c478bd9Sstevel@tonic-gate st %i3, [%sp + 44] ;\ 3107c478bd9Sstevel@tonic-gate st %i4, [%sp + 48] ;\ 3117c478bd9Sstevel@tonic-gate st %i5, [%sp + 52] ;\ 3127c478bd9Sstevel@tonic-gate st %i6, [%sp + 56] ;\ 3137c478bd9Sstevel@tonic-gate st %i7, [%sp + 60] ;\ 3147c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) ;\ 3157c478bd9Sstevel@tonic-gate saved ;\ 3167c478bd9Sstevel@tonic-gate retry ;\ 3177c478bd9Sstevel@tonic-gate SKIP(31-19-TT_TRACE_L_INS) ;\ 318*5d9d9091SRichard Lowe ba,a,pt %xcc, fault_32bit_##tail ;\ 3197c478bd9Sstevel@tonic-gate .empty 3207c478bd9Sstevel@tonic-gate 3217c478bd9Sstevel@tonic-gate/* 3227c478bd9Sstevel@tonic-gate * SPILL_32bit_asi spills a 32-bit-wide register window into a 32-bit 3237c478bd9Sstevel@tonic-gate * wide address space via the designated asi. It is used to spill 3247c478bd9Sstevel@tonic-gate * non-kernel windows. The stack pointer is required to be eight-byte 3257c478bd9Sstevel@tonic-gate * aligned even though this code only needs it to be four-byte 3267c478bd9Sstevel@tonic-gate * aligned. 3277c478bd9Sstevel@tonic-gate */ 3287c478bd9Sstevel@tonic-gate#define SPILL_32bit_asi(asi_num, tail) \ 3297c478bd9Sstevel@tonic-gate srl %sp, 0, %sp ;\ 3307c478bd9Sstevel@tonic-gate1: sta %l0, [%sp + %g0]asi_num ;\ 3317c478bd9Sstevel@tonic-gate mov 4, %g1 ;\ 3327c478bd9Sstevel@tonic-gate sta %l1, [%sp + %g1]asi_num ;\ 3337c478bd9Sstevel@tonic-gate mov 8, %g2 ;\ 3347c478bd9Sstevel@tonic-gate sta %l2, [%sp + %g2]asi_num ;\ 3357c478bd9Sstevel@tonic-gate mov 12, %g3 ;\ 3367c478bd9Sstevel@tonic-gate sta %l3, [%sp + %g3]asi_num ;\ 3377c478bd9Sstevel@tonic-gate add %sp, 16, %g4 ;\ 3387c478bd9Sstevel@tonic-gate sta %l4, [%g4 + %g0]asi_num ;\ 3397c478bd9Sstevel@tonic-gate sta %l5, [%g4 + %g1]asi_num ;\ 3407c478bd9Sstevel@tonic-gate sta %l6, [%g4 + %g2]asi_num ;\ 3417c478bd9Sstevel@tonic-gate sta %l7, [%g4 + %g3]asi_num ;\ 3427c478bd9Sstevel@tonic-gate add %g4, 16, %g4 ;\ 3437c478bd9Sstevel@tonic-gate sta %i0, [%g4 + %g0]asi_num ;\ 3447c478bd9Sstevel@tonic-gate sta %i1, [%g4 + %g1]asi_num ;\ 3457c478bd9Sstevel@tonic-gate sta %i2, [%g4 + %g2]asi_num ;\ 3467c478bd9Sstevel@tonic-gate sta %i3, [%g4 + %g3]asi_num ;\ 3477c478bd9Sstevel@tonic-gate add %g4, 16, %g4 ;\ 3487c478bd9Sstevel@tonic-gate sta %i4, [%g4 + %g0]asi_num ;\ 3497c478bd9Sstevel@tonic-gate sta %i5, [%g4 + %g1]asi_num ;\ 3507c478bd9Sstevel@tonic-gate sta %i6, [%g4 + %g2]asi_num ;\ 3517c478bd9Sstevel@tonic-gate sta %i7, [%g4 + %g3]asi_num ;\ 3527c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) ;\ 3537c478bd9Sstevel@tonic-gate saved ;\ 3547c478bd9Sstevel@tonic-gate retry ;\ 3557c478bd9Sstevel@tonic-gate SKIP(31-25-TT_TRACE_L_INS) ;\ 356*5d9d9091SRichard Lowe ba,a,pt %xcc, fault_32bit_##tail ;\ 3577c478bd9Sstevel@tonic-gate .empty 3587c478bd9Sstevel@tonic-gate 3597c478bd9Sstevel@tonic-gate/* 3607c478bd9Sstevel@tonic-gate * SPILL_32bit_tt1 spills a 32-bit-wide register window into a 32-bit 3617c478bd9Sstevel@tonic-gate * wide address space via the designated asi. It is used to spill 3627c478bd9Sstevel@tonic-gate * windows at tl>1 where performance isn't the primary concern and 3637c478bd9Sstevel@tonic-gate * where we don't want to use unnecessary registers. The stack 3647c478bd9Sstevel@tonic-gate * pointer is required to be eight-byte aligned even though this code 3657c478bd9Sstevel@tonic-gate * only needs it to be four-byte aligned. 3667c478bd9Sstevel@tonic-gate */ 3677c478bd9Sstevel@tonic-gate#define SPILL_32bit_tt1(asi_num, tail) \ 3687c478bd9Sstevel@tonic-gate mov asi_num, %asi ;\ 3697c478bd9Sstevel@tonic-gate1: srl %sp, 0, %sp ;\ 3707c478bd9Sstevel@tonic-gate sta %l0, [%sp + 0]%asi ;\ 3717c478bd9Sstevel@tonic-gate sta %l1, [%sp + 4]%asi ;\ 3727c478bd9Sstevel@tonic-gate sta %l2, [%sp + 8]%asi ;\ 3737c478bd9Sstevel@tonic-gate sta %l3, [%sp + 12]%asi ;\ 3747c478bd9Sstevel@tonic-gate sta %l4, [%sp + 16]%asi ;\ 3757c478bd9Sstevel@tonic-gate sta %l5, [%sp + 20]%asi ;\ 3767c478bd9Sstevel@tonic-gate sta %l6, [%sp + 24]%asi ;\ 3777c478bd9Sstevel@tonic-gate sta %l7, [%sp + 28]%asi ;\ 3787c478bd9Sstevel@tonic-gate sta %i0, [%sp + 32]%asi ;\ 3797c478bd9Sstevel@tonic-gate sta %i1, [%sp + 36]%asi ;\ 3807c478bd9Sstevel@tonic-gate sta %i2, [%sp + 40]%asi ;\ 3817c478bd9Sstevel@tonic-gate sta %i3, [%sp + 44]%asi ;\ 3827c478bd9Sstevel@tonic-gate sta %i4, [%sp + 48]%asi ;\ 3837c478bd9Sstevel@tonic-gate sta %i5, [%sp + 52]%asi ;\ 3847c478bd9Sstevel@tonic-gate sta %i6, [%sp + 56]%asi ;\ 3857c478bd9Sstevel@tonic-gate sta %i7, [%sp + 60]%asi ;\ 3867c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) ;\ 3877c478bd9Sstevel@tonic-gate saved ;\ 3887c478bd9Sstevel@tonic-gate retry ;\ 3897c478bd9Sstevel@tonic-gate SKIP(31-20-TT_TRACE_L_INS) ;\ 390*5d9d9091SRichard Lowe ba,a,pt %xcc, fault_32bit_##tail ;\ 3917c478bd9Sstevel@tonic-gate .empty 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate 3947c478bd9Sstevel@tonic-gate/* 3957c478bd9Sstevel@tonic-gate * FILL_32bit fills a 32-bit-wide kernel register window. It assumes 3967c478bd9Sstevel@tonic-gate * that the kernel context and the nucleus context are the same. The 3977c478bd9Sstevel@tonic-gate * stack pointer is required to be eight-byte aligned even though this 3987c478bd9Sstevel@tonic-gate * code only needs it to be four-byte aligned. 3997c478bd9Sstevel@tonic-gate */ 4007c478bd9Sstevel@tonic-gate#define FILL_32bit(tail) \ 4017c478bd9Sstevel@tonic-gate srl %sp, 0, %sp ;\ 4027c478bd9Sstevel@tonic-gate1: TT_TRACE_L(trace_win) ;\ 4037c478bd9Sstevel@tonic-gate ld [%sp + 0], %l0 ;\ 4047c478bd9Sstevel@tonic-gate ld [%sp + 4], %l1 ;\ 4057c478bd9Sstevel@tonic-gate ld [%sp + 8], %l2 ;\ 4067c478bd9Sstevel@tonic-gate ld [%sp + 12], %l3 ;\ 4077c478bd9Sstevel@tonic-gate ld [%sp + 16], %l4 ;\ 4087c478bd9Sstevel@tonic-gate ld [%sp + 20], %l5 ;\ 4097c478bd9Sstevel@tonic-gate ld [%sp + 24], %l6 ;\ 4107c478bd9Sstevel@tonic-gate ld [%sp + 28], %l7 ;\ 4117c478bd9Sstevel@tonic-gate ld [%sp + 32], %i0 ;\ 4127c478bd9Sstevel@tonic-gate ld [%sp + 36], %i1 ;\ 4137c478bd9Sstevel@tonic-gate ld [%sp + 40], %i2 ;\ 4147c478bd9Sstevel@tonic-gate ld [%sp + 44], %i3 ;\ 4157c478bd9Sstevel@tonic-gate ld [%sp + 48], %i4 ;\ 4167c478bd9Sstevel@tonic-gate ld [%sp + 52], %i5 ;\ 4177c478bd9Sstevel@tonic-gate ld [%sp + 56], %i6 ;\ 4187c478bd9Sstevel@tonic-gate ld [%sp + 60], %i7 ;\ 4197c478bd9Sstevel@tonic-gate restored ;\ 4207c478bd9Sstevel@tonic-gate retry ;\ 4217c478bd9Sstevel@tonic-gate SKIP(31-19-TT_TRACE_L_INS) ;\ 422*5d9d9091SRichard Lowe ba,a,pt %xcc, fault_32bit_##tail ;\ 4237c478bd9Sstevel@tonic-gate .empty 4247c478bd9Sstevel@tonic-gate 4257c478bd9Sstevel@tonic-gate/* 4267c478bd9Sstevel@tonic-gate * FILL_32bit_asi fills a 32-bit-wide register window from a 32-bit 4277c478bd9Sstevel@tonic-gate * wide address space via the designated asi. It is used to fill 4287c478bd9Sstevel@tonic-gate * non-kernel windows. The stack pointer is required to be eight-byte 4297c478bd9Sstevel@tonic-gate * aligned even though this code only needs it to be four-byte 4307c478bd9Sstevel@tonic-gate * aligned. 4317c478bd9Sstevel@tonic-gate */ 4327c478bd9Sstevel@tonic-gate#define FILL_32bit_asi(asi_num, tail) \ 4337c478bd9Sstevel@tonic-gate srl %sp, 0, %sp ;\ 4347c478bd9Sstevel@tonic-gate1: TT_TRACE_L(trace_win) ;\ 4357c478bd9Sstevel@tonic-gate mov 4, %g1 ;\ 4367c478bd9Sstevel@tonic-gate lda [%sp + %g0]asi_num, %l0 ;\ 4377c478bd9Sstevel@tonic-gate mov 8, %g2 ;\ 4387c478bd9Sstevel@tonic-gate lda [%sp + %g1]asi_num, %l1 ;\ 4397c478bd9Sstevel@tonic-gate mov 12, %g3 ;\ 4407c478bd9Sstevel@tonic-gate lda [%sp + %g2]asi_num, %l2 ;\ 4417c478bd9Sstevel@tonic-gate lda [%sp + %g3]asi_num, %l3 ;\ 4427c478bd9Sstevel@tonic-gate add %sp, 16, %g4 ;\ 4437c478bd9Sstevel@tonic-gate lda [%g4 + %g0]asi_num, %l4 ;\ 4447c478bd9Sstevel@tonic-gate lda [%g4 + %g1]asi_num, %l5 ;\ 4457c478bd9Sstevel@tonic-gate lda [%g4 + %g2]asi_num, %l6 ;\ 4467c478bd9Sstevel@tonic-gate lda [%g4 + %g3]asi_num, %l7 ;\ 4477c478bd9Sstevel@tonic-gate add %g4, 16, %g4 ;\ 4487c478bd9Sstevel@tonic-gate lda [%g4 + %g0]asi_num, %i0 ;\ 4497c478bd9Sstevel@tonic-gate lda [%g4 + %g1]asi_num, %i1 ;\ 4507c478bd9Sstevel@tonic-gate lda [%g4 + %g2]asi_num, %i2 ;\ 4517c478bd9Sstevel@tonic-gate lda [%g4 + %g3]asi_num, %i3 ;\ 4527c478bd9Sstevel@tonic-gate add %g4, 16, %g4 ;\ 4537c478bd9Sstevel@tonic-gate lda [%g4 + %g0]asi_num, %i4 ;\ 4547c478bd9Sstevel@tonic-gate lda [%g4 + %g1]asi_num, %i5 ;\ 4557c478bd9Sstevel@tonic-gate lda [%g4 + %g2]asi_num, %i6 ;\ 4567c478bd9Sstevel@tonic-gate lda [%g4 + %g3]asi_num, %i7 ;\ 4577c478bd9Sstevel@tonic-gate restored ;\ 4587c478bd9Sstevel@tonic-gate retry ;\ 4597c478bd9Sstevel@tonic-gate SKIP(31-25-TT_TRACE_L_INS) ;\ 460*5d9d9091SRichard Lowe ba,a,pt %xcc, fault_32bit_##tail ;\ 4617c478bd9Sstevel@tonic-gate .empty 4627c478bd9Sstevel@tonic-gate 4637c478bd9Sstevel@tonic-gate/* 4647c478bd9Sstevel@tonic-gate * FILL_32bit_tt1 fills a 32-bit-wide register window from a 32-bit 4657c478bd9Sstevel@tonic-gate * wide address space via the designated asi. It is used to fill 4667c478bd9Sstevel@tonic-gate * windows at tl>1 where performance isn't the primary concern and 4677c478bd9Sstevel@tonic-gate * where we don't want to use unnecessary registers. The stack 4687c478bd9Sstevel@tonic-gate * pointer is required to be eight-byte aligned even though this code 4697c478bd9Sstevel@tonic-gate * only needs it to be four-byte aligned. 4707c478bd9Sstevel@tonic-gate */ 4717c478bd9Sstevel@tonic-gate#define FILL_32bit_tt1(asi_num, tail) \ 4727c478bd9Sstevel@tonic-gate mov asi_num, %asi ;\ 4737c478bd9Sstevel@tonic-gate1: srl %sp, 0, %sp ;\ 4747c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) ;\ 4757c478bd9Sstevel@tonic-gate lda [%sp + 0]%asi, %l0 ;\ 4767c478bd9Sstevel@tonic-gate lda [%sp + 4]%asi, %l1 ;\ 4777c478bd9Sstevel@tonic-gate lda [%sp + 8]%asi, %l2 ;\ 4787c478bd9Sstevel@tonic-gate lda [%sp + 12]%asi, %l3 ;\ 4797c478bd9Sstevel@tonic-gate lda [%sp + 16]%asi, %l4 ;\ 4807c478bd9Sstevel@tonic-gate lda [%sp + 20]%asi, %l5 ;\ 4817c478bd9Sstevel@tonic-gate lda [%sp + 24]%asi, %l6 ;\ 4827c478bd9Sstevel@tonic-gate lda [%sp + 28]%asi, %l7 ;\ 4837c478bd9Sstevel@tonic-gate lda [%sp + 32]%asi, %i0 ;\ 4847c478bd9Sstevel@tonic-gate lda [%sp + 36]%asi, %i1 ;\ 4857c478bd9Sstevel@tonic-gate lda [%sp + 40]%asi, %i2 ;\ 4867c478bd9Sstevel@tonic-gate lda [%sp + 44]%asi, %i3 ;\ 4877c478bd9Sstevel@tonic-gate lda [%sp + 48]%asi, %i4 ;\ 4887c478bd9Sstevel@tonic-gate lda [%sp + 52]%asi, %i5 ;\ 4897c478bd9Sstevel@tonic-gate lda [%sp + 56]%asi, %i6 ;\ 4907c478bd9Sstevel@tonic-gate lda [%sp + 60]%asi, %i7 ;\ 4917c478bd9Sstevel@tonic-gate restored ;\ 4927c478bd9Sstevel@tonic-gate retry ;\ 4937c478bd9Sstevel@tonic-gate SKIP(31-20-TT_TRACE_L_INS) ;\ 494*5d9d9091SRichard Lowe ba,a,pt %xcc, fault_32bit_##tail ;\ 4957c478bd9Sstevel@tonic-gate .empty 4967c478bd9Sstevel@tonic-gate 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate/* 4997c478bd9Sstevel@tonic-gate * SPILL_64bit spills a 64-bit-wide kernel register window. It 5007c478bd9Sstevel@tonic-gate * assumes that the kernel context and the nucleus context are the 5017c478bd9Sstevel@tonic-gate * same. The stack pointer is required to be eight-byte aligned. 5027c478bd9Sstevel@tonic-gate */ 5037c478bd9Sstevel@tonic-gate#define SPILL_64bit(tail) \ 5047c478bd9Sstevel@tonic-gate2: stx %l0, [%sp + V9BIAS64 + 0] ;\ 5057c478bd9Sstevel@tonic-gate stx %l1, [%sp + V9BIAS64 + 8] ;\ 5067c478bd9Sstevel@tonic-gate stx %l2, [%sp + V9BIAS64 + 16] ;\ 5077c478bd9Sstevel@tonic-gate stx %l3, [%sp + V9BIAS64 + 24] ;\ 5087c478bd9Sstevel@tonic-gate stx %l4, [%sp + V9BIAS64 + 32] ;\ 5097c478bd9Sstevel@tonic-gate stx %l5, [%sp + V9BIAS64 + 40] ;\ 5107c478bd9Sstevel@tonic-gate stx %l6, [%sp + V9BIAS64 + 48] ;\ 5117c478bd9Sstevel@tonic-gate stx %l7, [%sp + V9BIAS64 + 56] ;\ 5127c478bd9Sstevel@tonic-gate stx %i0, [%sp + V9BIAS64 + 64] ;\ 5137c478bd9Sstevel@tonic-gate stx %i1, [%sp + V9BIAS64 + 72] ;\ 5147c478bd9Sstevel@tonic-gate stx %i2, [%sp + V9BIAS64 + 80] ;\ 5157c478bd9Sstevel@tonic-gate stx %i3, [%sp + V9BIAS64 + 88] ;\ 5167c478bd9Sstevel@tonic-gate stx %i4, [%sp + V9BIAS64 + 96] ;\ 5177c478bd9Sstevel@tonic-gate stx %i5, [%sp + V9BIAS64 + 104] ;\ 5187c478bd9Sstevel@tonic-gate stx %i6, [%sp + V9BIAS64 + 112] ;\ 5197c478bd9Sstevel@tonic-gate stx %i7, [%sp + V9BIAS64 + 120] ;\ 5207c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) ;\ 5217c478bd9Sstevel@tonic-gate saved ;\ 5227c478bd9Sstevel@tonic-gate retry ;\ 5237c478bd9Sstevel@tonic-gate SKIP(31-18-TT_TRACE_L_INS) ;\ 524*5d9d9091SRichard Lowe ba,a,pt %xcc, fault_64bit_##tail ;\ 5257c478bd9Sstevel@tonic-gate .empty 5267c478bd9Sstevel@tonic-gate 5277c478bd9Sstevel@tonic-gate/* 5287c478bd9Sstevel@tonic-gate * SPILL_64bit_asi spills a 64-bit-wide register window into a 64-bit 5297c478bd9Sstevel@tonic-gate * wide address space via the designated asi. It is used to spill 5307c478bd9Sstevel@tonic-gate * non-kernel windows. The stack pointer is required to be eight-byte 5317c478bd9Sstevel@tonic-gate * aligned. 5327c478bd9Sstevel@tonic-gate */ 5337c478bd9Sstevel@tonic-gate#define SPILL_64bit_asi(asi_num, tail) \ 5347c478bd9Sstevel@tonic-gate mov 0 + V9BIAS64, %g1 ;\ 5357c478bd9Sstevel@tonic-gate2: stxa %l0, [%sp + %g1]asi_num ;\ 5367c478bd9Sstevel@tonic-gate mov 8 + V9BIAS64, %g2 ;\ 5377c478bd9Sstevel@tonic-gate stxa %l1, [%sp + %g2]asi_num ;\ 5387c478bd9Sstevel@tonic-gate mov 16 + V9BIAS64, %g3 ;\ 5397c478bd9Sstevel@tonic-gate stxa %l2, [%sp + %g3]asi_num ;\ 5407c478bd9Sstevel@tonic-gate mov 24 + V9BIAS64, %g4 ;\ 5417c478bd9Sstevel@tonic-gate stxa %l3, [%sp + %g4]asi_num ;\ 5427c478bd9Sstevel@tonic-gate add %sp, 32, %g5 ;\ 5437c478bd9Sstevel@tonic-gate stxa %l4, [%g5 + %g1]asi_num ;\ 5447c478bd9Sstevel@tonic-gate stxa %l5, [%g5 + %g2]asi_num ;\ 5457c478bd9Sstevel@tonic-gate stxa %l6, [%g5 + %g3]asi_num ;\ 5467c478bd9Sstevel@tonic-gate stxa %l7, [%g5 + %g4]asi_num ;\ 5477c478bd9Sstevel@tonic-gate add %g5, 32, %g5 ;\ 5487c478bd9Sstevel@tonic-gate stxa %i0, [%g5 + %g1]asi_num ;\ 5497c478bd9Sstevel@tonic-gate stxa %i1, [%g5 + %g2]asi_num ;\ 5507c478bd9Sstevel@tonic-gate stxa %i2, [%g5 + %g3]asi_num ;\ 5517c478bd9Sstevel@tonic-gate stxa %i3, [%g5 + %g4]asi_num ;\ 5527c478bd9Sstevel@tonic-gate add %g5, 32, %g5 ;\ 5537c478bd9Sstevel@tonic-gate stxa %i4, [%g5 + %g1]asi_num ;\ 5547c478bd9Sstevel@tonic-gate stxa %i5, [%g5 + %g2]asi_num ;\ 5557c478bd9Sstevel@tonic-gate stxa %i6, [%g5 + %g3]asi_num ;\ 5567c478bd9Sstevel@tonic-gate stxa %i7, [%g5 + %g4]asi_num ;\ 5577c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) ;\ 5587c478bd9Sstevel@tonic-gate saved ;\ 5597c478bd9Sstevel@tonic-gate retry ;\ 5607c478bd9Sstevel@tonic-gate SKIP(31-25-TT_TRACE_L_INS) ;\ 561*5d9d9091SRichard Lowe ba,a,pt %xcc, fault_64bit_##tail ;\ 5627c478bd9Sstevel@tonic-gate .empty 5637c478bd9Sstevel@tonic-gate 5647c478bd9Sstevel@tonic-gate/* 5657c478bd9Sstevel@tonic-gate * SPILL_64bit_tt1 spills a 64-bit-wide register window into a 64-bit 5667c478bd9Sstevel@tonic-gate * wide address space via the designated asi. It is used to spill 5677c478bd9Sstevel@tonic-gate * windows at tl>1 where performance isn't the primary concern and 5687c478bd9Sstevel@tonic-gate * where we don't want to use unnecessary registers. The stack 5697c478bd9Sstevel@tonic-gate * pointer is required to be eight-byte aligned. 5707c478bd9Sstevel@tonic-gate */ 5717c478bd9Sstevel@tonic-gate#define SPILL_64bit_tt1(asi_num, tail) \ 5727c478bd9Sstevel@tonic-gate mov asi_num, %asi ;\ 5737c478bd9Sstevel@tonic-gate2: stxa %l0, [%sp + V9BIAS64 + 0]%asi ;\ 5747c478bd9Sstevel@tonic-gate stxa %l1, [%sp + V9BIAS64 + 8]%asi ;\ 5757c478bd9Sstevel@tonic-gate stxa %l2, [%sp + V9BIAS64 + 16]%asi ;\ 5767c478bd9Sstevel@tonic-gate stxa %l3, [%sp + V9BIAS64 + 24]%asi ;\ 5777c478bd9Sstevel@tonic-gate stxa %l4, [%sp + V9BIAS64 + 32]%asi ;\ 5787c478bd9Sstevel@tonic-gate stxa %l5, [%sp + V9BIAS64 + 40]%asi ;\ 5797c478bd9Sstevel@tonic-gate stxa %l6, [%sp + V9BIAS64 + 48]%asi ;\ 5807c478bd9Sstevel@tonic-gate stxa %l7, [%sp + V9BIAS64 + 56]%asi ;\ 5817c478bd9Sstevel@tonic-gate stxa %i0, [%sp + V9BIAS64 + 64]%asi ;\ 5827c478bd9Sstevel@tonic-gate stxa %i1, [%sp + V9BIAS64 + 72]%asi ;\ 5837c478bd9Sstevel@tonic-gate stxa %i2, [%sp + V9BIAS64 + 80]%asi ;\ 5847c478bd9Sstevel@tonic-gate stxa %i3, [%sp + V9BIAS64 + 88]%asi ;\ 5857c478bd9Sstevel@tonic-gate stxa %i4, [%sp + V9BIAS64 + 96]%asi ;\ 5867c478bd9Sstevel@tonic-gate stxa %i5, [%sp + V9BIAS64 + 104]%asi ;\ 5877c478bd9Sstevel@tonic-gate stxa %i6, [%sp + V9BIAS64 + 112]%asi ;\ 5887c478bd9Sstevel@tonic-gate stxa %i7, [%sp + V9BIAS64 + 120]%asi ;\ 5897c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) ;\ 5907c478bd9Sstevel@tonic-gate saved ;\ 5917c478bd9Sstevel@tonic-gate retry ;\ 5927c478bd9Sstevel@tonic-gate SKIP(31-19-TT_TRACE_L_INS) ;\ 593*5d9d9091SRichard Lowe ba,a,pt %xcc, fault_64bit_##tail ;\ 5947c478bd9Sstevel@tonic-gate .empty 5957c478bd9Sstevel@tonic-gate 5967c478bd9Sstevel@tonic-gate 5977c478bd9Sstevel@tonic-gate/* 5987c478bd9Sstevel@tonic-gate * FILL_64bit fills a 64-bit-wide kernel register window. It assumes 5997c478bd9Sstevel@tonic-gate * that the kernel context and the nucleus context are the same. The 6007c478bd9Sstevel@tonic-gate * stack pointer is required to be eight-byte aligned. 6017c478bd9Sstevel@tonic-gate */ 6027c478bd9Sstevel@tonic-gate#define FILL_64bit(tail) \ 6037c478bd9Sstevel@tonic-gate2: TT_TRACE_L(trace_win) ;\ 6047c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 0], %l0 ;\ 6057c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 8], %l1 ;\ 6067c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 16], %l2 ;\ 6077c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 24], %l3 ;\ 6087c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 32], %l4 ;\ 6097c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 40], %l5 ;\ 6107c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 48], %l6 ;\ 6117c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 56], %l7 ;\ 6127c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 64], %i0 ;\ 6137c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 72], %i1 ;\ 6147c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 80], %i2 ;\ 6157c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 88], %i3 ;\ 6167c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 96], %i4 ;\ 6177c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 104], %i5 ;\ 6187c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 112], %i6 ;\ 6197c478bd9Sstevel@tonic-gate ldx [%sp + V9BIAS64 + 120], %i7 ;\ 6207c478bd9Sstevel@tonic-gate restored ;\ 6217c478bd9Sstevel@tonic-gate retry ;\ 6227c478bd9Sstevel@tonic-gate SKIP(31-18-TT_TRACE_L_INS) ;\ 623*5d9d9091SRichard Lowe ba,a,pt %xcc, fault_64bit_##tail ;\ 6247c478bd9Sstevel@tonic-gate .empty 6257c478bd9Sstevel@tonic-gate 6267c478bd9Sstevel@tonic-gate/* 6277c478bd9Sstevel@tonic-gate * FILL_64bit_asi fills a 64-bit-wide register window from a 64-bit 6287c478bd9Sstevel@tonic-gate * wide address space via the designated asi. It is used to fill 6297c478bd9Sstevel@tonic-gate * non-kernel windows. The stack pointer is required to be eight-byte 6304a75c0c1Sedp * aligned. 6317c478bd9Sstevel@tonic-gate */ 6327c478bd9Sstevel@tonic-gate#define FILL_64bit_asi(asi_num, tail) \ 6337c478bd9Sstevel@tonic-gate mov V9BIAS64 + 0, %g1 ;\ 6347c478bd9Sstevel@tonic-gate2: TT_TRACE_L(trace_win) ;\ 6357c478bd9Sstevel@tonic-gate ldxa [%sp + %g1]asi_num, %l0 ;\ 6367c478bd9Sstevel@tonic-gate mov V9BIAS64 + 8, %g2 ;\ 6377c478bd9Sstevel@tonic-gate ldxa [%sp + %g2]asi_num, %l1 ;\ 6387c478bd9Sstevel@tonic-gate mov V9BIAS64 + 16, %g3 ;\ 6397c478bd9Sstevel@tonic-gate ldxa [%sp + %g3]asi_num, %l2 ;\ 6407c478bd9Sstevel@tonic-gate mov V9BIAS64 + 24, %g4 ;\ 6417c478bd9Sstevel@tonic-gate ldxa [%sp + %g4]asi_num, %l3 ;\ 6427c478bd9Sstevel@tonic-gate add %sp, 32, %g5 ;\ 6437c478bd9Sstevel@tonic-gate ldxa [%g5 + %g1]asi_num, %l4 ;\ 6447c478bd9Sstevel@tonic-gate ldxa [%g5 + %g2]asi_num, %l5 ;\ 6457c478bd9Sstevel@tonic-gate ldxa [%g5 + %g3]asi_num, %l6 ;\ 6467c478bd9Sstevel@tonic-gate ldxa [%g5 + %g4]asi_num, %l7 ;\ 6477c478bd9Sstevel@tonic-gate add %g5, 32, %g5 ;\ 6487c478bd9Sstevel@tonic-gate ldxa [%g5 + %g1]asi_num, %i0 ;\ 6497c478bd9Sstevel@tonic-gate ldxa [%g5 + %g2]asi_num, %i1 ;\ 6507c478bd9Sstevel@tonic-gate ldxa [%g5 + %g3]asi_num, %i2 ;\ 6517c478bd9Sstevel@tonic-gate ldxa [%g5 + %g4]asi_num, %i3 ;\ 6527c478bd9Sstevel@tonic-gate add %g5, 32, %g5 ;\ 6537c478bd9Sstevel@tonic-gate ldxa [%g5 + %g1]asi_num, %i4 ;\ 6547c478bd9Sstevel@tonic-gate ldxa [%g5 + %g2]asi_num, %i5 ;\ 6557c478bd9Sstevel@tonic-gate ldxa [%g5 + %g3]asi_num, %i6 ;\ 6567c478bd9Sstevel@tonic-gate ldxa [%g5 + %g4]asi_num, %i7 ;\ 6577c478bd9Sstevel@tonic-gate restored ;\ 6587c478bd9Sstevel@tonic-gate retry ;\ 6597c478bd9Sstevel@tonic-gate SKIP(31-25-TT_TRACE_L_INS) ;\ 660*5d9d9091SRichard Lowe ba,a,pt %xcc, fault_64bit_##tail ;\ 6617c478bd9Sstevel@tonic-gate .empty 6627c478bd9Sstevel@tonic-gate 6637c478bd9Sstevel@tonic-gate/* 6647c478bd9Sstevel@tonic-gate * FILL_64bit_tt1 fills a 64-bit-wide register window from a 64-bit 6657c478bd9Sstevel@tonic-gate * wide address space via the designated asi. It is used to fill 6667c478bd9Sstevel@tonic-gate * windows at tl>1 where performance isn't the primary concern and 6677c478bd9Sstevel@tonic-gate * where we don't want to use unnecessary registers. The stack 6687c478bd9Sstevel@tonic-gate * pointer is required to be eight-byte aligned. 6697c478bd9Sstevel@tonic-gate */ 6707c478bd9Sstevel@tonic-gate#define FILL_64bit_tt1(asi_num, tail) \ 6717c478bd9Sstevel@tonic-gate mov asi_num, %asi ;\ 6727c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) ;\ 6737c478bd9Sstevel@tonic-gate ldxa [%sp + V9BIAS64 + 0]%asi, %l0 ;\ 6747c478bd9Sstevel@tonic-gate ldxa [%sp + V9BIAS64 + 8]%asi, %l1 ;\ 6757c478bd9Sstevel@tonic-gate ldxa [%sp + V9BIAS64 + 16]%asi, %l2 ;\ 6767c478bd9Sstevel@tonic-gate ldxa [%sp + V9BIAS64 + 24]%asi, %l3 ;\ 6777c478bd9Sstevel@tonic-gate ldxa [%sp + V9BIAS64 + 32]%asi, %l4 ;\ 6787c478bd9Sstevel@tonic-gate ldxa [%sp + V9BIAS64 + 40]%asi, %l5 ;\ 6797c478bd9Sstevel@tonic-gate ldxa [%sp + V9BIAS64 + 48]%asi, %l6 ;\ 6807c478bd9Sstevel@tonic-gate ldxa [%sp + V9BIAS64 + 56]%asi, %l7 ;\ 6817c478bd9Sstevel@tonic-gate ldxa [%sp + V9BIAS64 + 64]%asi, %i0 ;\ 6827c478bd9Sstevel@tonic-gate ldxa [%sp + V9BIAS64 + 72]%asi, %i1 ;\ 6837c478bd9Sstevel@tonic-gate ldxa [%sp + V9BIAS64 + 80]%asi, %i2 ;\ 6847c478bd9Sstevel@tonic-gate ldxa [%sp + V9BIAS64 + 88]%asi, %i3 ;\ 6857c478bd9Sstevel@tonic-gate ldxa [%sp + V9BIAS64 + 96]%asi, %i4 ;\ 6867c478bd9Sstevel@tonic-gate ldxa [%sp + V9BIAS64 + 104]%asi, %i5 ;\ 6877c478bd9Sstevel@tonic-gate ldxa [%sp + V9BIAS64 + 112]%asi, %i6 ;\ 6887c478bd9Sstevel@tonic-gate ldxa [%sp + V9BIAS64 + 120]%asi, %i7 ;\ 6897c478bd9Sstevel@tonic-gate restored ;\ 6907c478bd9Sstevel@tonic-gate retry ;\ 6917c478bd9Sstevel@tonic-gate SKIP(31-19-TT_TRACE_L_INS) ;\ 692*5d9d9091SRichard Lowe ba,a,pt %xcc, fault_64bit_##tail ;\ 6937c478bd9Sstevel@tonic-gate .empty 6947c478bd9Sstevel@tonic-gate 6957c478bd9Sstevel@tonic-gate/* 6967c478bd9Sstevel@tonic-gate * SPILL_mixed spills either size window, depending on 6977c478bd9Sstevel@tonic-gate * whether %sp is even or odd, to a 32-bit address space. 6987c478bd9Sstevel@tonic-gate * This may only be used in conjunction with SPILL_32bit/ 6997c478bd9Sstevel@tonic-gate * SPILL_64bit. New versions of SPILL_mixed_{tt1,asi} would be 7007c478bd9Sstevel@tonic-gate * needed for use with SPILL_{32,64}bit_{tt1,asi}. Particular 7017c478bd9Sstevel@tonic-gate * attention should be paid to the instructions that belong 7027c478bd9Sstevel@tonic-gate * in the delay slots of the branches depending on the type 7037c478bd9Sstevel@tonic-gate * of spill handler being branched to. 7047c478bd9Sstevel@tonic-gate * Clear upper 32 bits of %sp if it is odd. 7057c478bd9Sstevel@tonic-gate * We won't need to clear them in 64 bit kernel. 7067c478bd9Sstevel@tonic-gate */ 7077c478bd9Sstevel@tonic-gate#define SPILL_mixed \ 7087c478bd9Sstevel@tonic-gate btst 1, %sp ;\ 7097c478bd9Sstevel@tonic-gate bz,a,pt %xcc, 1b ;\ 7107c478bd9Sstevel@tonic-gate srl %sp, 0, %sp ;\ 7117c478bd9Sstevel@tonic-gate ba,pt %xcc, 2b ;\ 7127c478bd9Sstevel@tonic-gate nop ;\ 7137c478bd9Sstevel@tonic-gate .align 128 7147c478bd9Sstevel@tonic-gate 7157c478bd9Sstevel@tonic-gate/* 7167c478bd9Sstevel@tonic-gate * FILL_mixed(ASI) fills either size window, depending on 7177c478bd9Sstevel@tonic-gate * whether %sp is even or odd, from a 32-bit address space. 7187c478bd9Sstevel@tonic-gate * This may only be used in conjunction with FILL_32bit/ 7197c478bd9Sstevel@tonic-gate * FILL_64bit. New versions of FILL_mixed_{tt1,asi} would be 7207c478bd9Sstevel@tonic-gate * needed for use with FILL_{32,64}bit_{tt1,asi}. Particular 7217c478bd9Sstevel@tonic-gate * attention should be paid to the instructions that belong 7227c478bd9Sstevel@tonic-gate * in the delay slots of the branches depending on the type 7237c478bd9Sstevel@tonic-gate * of fill handler being branched to. 7247c478bd9Sstevel@tonic-gate * Clear upper 32 bits of %sp if it is odd. 7257c478bd9Sstevel@tonic-gate * We won't need to clear them in 64 bit kernel. 7267c478bd9Sstevel@tonic-gate */ 7277c478bd9Sstevel@tonic-gate#define FILL_mixed \ 7287c478bd9Sstevel@tonic-gate btst 1, %sp ;\ 7297c478bd9Sstevel@tonic-gate bz,a,pt %xcc, 1b ;\ 7307c478bd9Sstevel@tonic-gate srl %sp, 0, %sp ;\ 7317c478bd9Sstevel@tonic-gate ba,pt %xcc, 2b ;\ 7327c478bd9Sstevel@tonic-gate nop ;\ 7337c478bd9Sstevel@tonic-gate .align 128 7347c478bd9Sstevel@tonic-gate 7357c478bd9Sstevel@tonic-gate 7367c478bd9Sstevel@tonic-gate/* 7377c478bd9Sstevel@tonic-gate * SPILL_32clean/SPILL_64clean spill 32-bit and 64-bit register windows, 7387c478bd9Sstevel@tonic-gate * respectively, into the address space via the designated asi. The 7397c478bd9Sstevel@tonic-gate * unbiased stack pointer is required to be eight-byte aligned (even for 7407c478bd9Sstevel@tonic-gate * the 32-bit case even though this code does not require such strict 7417c478bd9Sstevel@tonic-gate * alignment). 7427c478bd9Sstevel@tonic-gate * 7437c478bd9Sstevel@tonic-gate * With SPARC v9 the spill trap takes precedence over the cleanwin trap 7447c478bd9Sstevel@tonic-gate * so when cansave == 0, canrestore == 6, and cleanwin == 6 the next save 7457c478bd9Sstevel@tonic-gate * will cause cwp + 2 to be spilled but will not clean cwp + 1. That 7467c478bd9Sstevel@tonic-gate * window may contain kernel data so in user_rtt we set wstate to call 7477c478bd9Sstevel@tonic-gate * these spill handlers on the first user spill trap. These handler then 7487c478bd9Sstevel@tonic-gate * spill the appropriate window but also back up a window and clean the 7497c478bd9Sstevel@tonic-gate * window that didn't get a cleanwin trap. 7507c478bd9Sstevel@tonic-gate */ 7517c478bd9Sstevel@tonic-gate#define SPILL_32clean(asi_num, tail) \ 7527c478bd9Sstevel@tonic-gate srl %sp, 0, %sp ;\ 7537c478bd9Sstevel@tonic-gate sta %l0, [%sp + %g0]asi_num ;\ 7547c478bd9Sstevel@tonic-gate mov 4, %g1 ;\ 7557c478bd9Sstevel@tonic-gate sta %l1, [%sp + %g1]asi_num ;\ 7567c478bd9Sstevel@tonic-gate mov 8, %g2 ;\ 7577c478bd9Sstevel@tonic-gate sta %l2, [%sp + %g2]asi_num ;\ 7587c478bd9Sstevel@tonic-gate mov 12, %g3 ;\ 7597c478bd9Sstevel@tonic-gate sta %l3, [%sp + %g3]asi_num ;\ 7607c478bd9Sstevel@tonic-gate add %sp, 16, %g4 ;\ 7617c478bd9Sstevel@tonic-gate sta %l4, [%g4 + %g0]asi_num ;\ 7627c478bd9Sstevel@tonic-gate sta %l5, [%g4 + %g1]asi_num ;\ 7637c478bd9Sstevel@tonic-gate sta %l6, [%g4 + %g2]asi_num ;\ 7647c478bd9Sstevel@tonic-gate sta %l7, [%g4 + %g3]asi_num ;\ 7657c478bd9Sstevel@tonic-gate add %g4, 16, %g4 ;\ 7667c478bd9Sstevel@tonic-gate sta %i0, [%g4 + %g0]asi_num ;\ 7677c478bd9Sstevel@tonic-gate sta %i1, [%g4 + %g1]asi_num ;\ 7687c478bd9Sstevel@tonic-gate sta %i2, [%g4 + %g2]asi_num ;\ 7697c478bd9Sstevel@tonic-gate sta %i3, [%g4 + %g3]asi_num ;\ 7707c478bd9Sstevel@tonic-gate add %g4, 16, %g4 ;\ 7717c478bd9Sstevel@tonic-gate sta %i4, [%g4 + %g0]asi_num ;\ 7727c478bd9Sstevel@tonic-gate sta %i5, [%g4 + %g1]asi_num ;\ 7737c478bd9Sstevel@tonic-gate sta %i6, [%g4 + %g2]asi_num ;\ 7747c478bd9Sstevel@tonic-gate sta %i7, [%g4 + %g3]asi_num ;\ 7757c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) ;\ 7767c478bd9Sstevel@tonic-gate b .spill_clean ;\ 7777c478bd9Sstevel@tonic-gate mov WSTATE_USER32, %g7 ;\ 7787c478bd9Sstevel@tonic-gate SKIP(31-25-TT_TRACE_L_INS) ;\ 779*5d9d9091SRichard Lowe ba,a,pt %xcc, fault_32bit_##tail ;\ 7807c478bd9Sstevel@tonic-gate .empty 7817c478bd9Sstevel@tonic-gate 7827c478bd9Sstevel@tonic-gate#define SPILL_64clean(asi_num, tail) \ 7837c478bd9Sstevel@tonic-gate mov 0 + V9BIAS64, %g1 ;\ 7847c478bd9Sstevel@tonic-gate stxa %l0, [%sp + %g1]asi_num ;\ 7857c478bd9Sstevel@tonic-gate mov 8 + V9BIAS64, %g2 ;\ 7867c478bd9Sstevel@tonic-gate stxa %l1, [%sp + %g2]asi_num ;\ 7877c478bd9Sstevel@tonic-gate mov 16 + V9BIAS64, %g3 ;\ 7887c478bd9Sstevel@tonic-gate stxa %l2, [%sp + %g3]asi_num ;\ 7897c478bd9Sstevel@tonic-gate mov 24 + V9BIAS64, %g4 ;\ 7907c478bd9Sstevel@tonic-gate stxa %l3, [%sp + %g4]asi_num ;\ 7917c478bd9Sstevel@tonic-gate add %sp, 32, %g5 ;\ 7927c478bd9Sstevel@tonic-gate stxa %l4, [%g5 + %g1]asi_num ;\ 7937c478bd9Sstevel@tonic-gate stxa %l5, [%g5 + %g2]asi_num ;\ 7947c478bd9Sstevel@tonic-gate stxa %l6, [%g5 + %g3]asi_num ;\ 7957c478bd9Sstevel@tonic-gate stxa %l7, [%g5 + %g4]asi_num ;\ 7967c478bd9Sstevel@tonic-gate add %g5, 32, %g5 ;\ 7977c478bd9Sstevel@tonic-gate stxa %i0, [%g5 + %g1]asi_num ;\ 7987c478bd9Sstevel@tonic-gate stxa %i1, [%g5 + %g2]asi_num ;\ 7997c478bd9Sstevel@tonic-gate stxa %i2, [%g5 + %g3]asi_num ;\ 8007c478bd9Sstevel@tonic-gate stxa %i3, [%g5 + %g4]asi_num ;\ 8017c478bd9Sstevel@tonic-gate add %g5, 32, %g5 ;\ 8027c478bd9Sstevel@tonic-gate stxa %i4, [%g5 + %g1]asi_num ;\ 8037c478bd9Sstevel@tonic-gate stxa %i5, [%g5 + %g2]asi_num ;\ 8047c478bd9Sstevel@tonic-gate stxa %i6, [%g5 + %g3]asi_num ;\ 8057c478bd9Sstevel@tonic-gate stxa %i7, [%g5 + %g4]asi_num ;\ 8067c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) ;\ 8077c478bd9Sstevel@tonic-gate b .spill_clean ;\ 8087c478bd9Sstevel@tonic-gate mov WSTATE_USER64, %g7 ;\ 8097c478bd9Sstevel@tonic-gate SKIP(31-25-TT_TRACE_L_INS) ;\ 810*5d9d9091SRichard Lowe ba,a,pt %xcc, fault_64bit_##tail ;\ 8117c478bd9Sstevel@tonic-gate .empty 8127c478bd9Sstevel@tonic-gate 8137c478bd9Sstevel@tonic-gate 8147c478bd9Sstevel@tonic-gate/* 8157c478bd9Sstevel@tonic-gate * Floating point disabled. 8167c478bd9Sstevel@tonic-gate */ 8177c478bd9Sstevel@tonic-gate#define FP_DISABLED_TRAP \ 8187c478bd9Sstevel@tonic-gate TT_TRACE(trace_gen) ;\ 8197c478bd9Sstevel@tonic-gate ba,pt %xcc,.fp_disabled ;\ 8207c478bd9Sstevel@tonic-gate nop ;\ 8217c478bd9Sstevel@tonic-gate .align 32 8227c478bd9Sstevel@tonic-gate 8237c478bd9Sstevel@tonic-gate/* 8247c478bd9Sstevel@tonic-gate * Floating point exceptions. 8257c478bd9Sstevel@tonic-gate */ 8267c478bd9Sstevel@tonic-gate#define FP_IEEE_TRAP \ 8277c478bd9Sstevel@tonic-gate TT_TRACE(trace_gen) ;\ 8287c478bd9Sstevel@tonic-gate ba,pt %xcc,.fp_ieee_exception ;\ 8297c478bd9Sstevel@tonic-gate nop ;\ 8307c478bd9Sstevel@tonic-gate .align 32 8317c478bd9Sstevel@tonic-gate 8327c478bd9Sstevel@tonic-gate#define FP_TRAP \ 8337c478bd9Sstevel@tonic-gate TT_TRACE(trace_gen) ;\ 8347c478bd9Sstevel@tonic-gate ba,pt %xcc,.fp_exception ;\ 8357c478bd9Sstevel@tonic-gate nop ;\ 8367c478bd9Sstevel@tonic-gate .align 32 8377c478bd9Sstevel@tonic-gate 8387c478bd9Sstevel@tonic-gate/* 8397c478bd9Sstevel@tonic-gate * asynchronous traps at level 0 and level 1 8407c478bd9Sstevel@tonic-gate * 8417c478bd9Sstevel@tonic-gate * The first instruction must be a membar for UltraSPARC-III 8427c478bd9Sstevel@tonic-gate * to stop RED state entry if the store queue has many 8437c478bd9Sstevel@tonic-gate * pending bad stores (PRM, Chapter 11). 8447c478bd9Sstevel@tonic-gate */ 84525cf1a30Sjl#define ASYNC_TRAP(ttype, ttlabel, table_name)\ 84625cf1a30Sjl .global table_name ;\ 84725cf1a30Sjltable_name: ;\ 8487c478bd9Sstevel@tonic-gate membar #Sync ;\ 8497c478bd9Sstevel@tonic-gate TT_TRACE(ttlabel) ;\ 8507c478bd9Sstevel@tonic-gate ba async_err ;\ 8517c478bd9Sstevel@tonic-gate mov ttype, %g5 ;\ 8527c478bd9Sstevel@tonic-gate .align 32 8537c478bd9Sstevel@tonic-gate 8547c478bd9Sstevel@tonic-gate/* 8557c478bd9Sstevel@tonic-gate * Defaults to BAD entry, but establishes label to be used for 8567c478bd9Sstevel@tonic-gate * architecture-specific overwrite of trap table entry. 8577c478bd9Sstevel@tonic-gate */ 8587c478bd9Sstevel@tonic-gate#define LABELED_BAD(table_name) \ 8597c478bd9Sstevel@tonic-gate .global table_name ;\ 8607c478bd9Sstevel@tonic-gatetable_name: ;\ 8617c478bd9Sstevel@tonic-gate BAD 8627c478bd9Sstevel@tonic-gate 8637c478bd9Sstevel@tonic-gate/* 8647c478bd9Sstevel@tonic-gate * illegal instruction trap 8657c478bd9Sstevel@tonic-gate */ 8667c478bd9Sstevel@tonic-gate#define ILLTRAP_INSTR \ 8677c478bd9Sstevel@tonic-gate membar #Sync ;\ 8687c478bd9Sstevel@tonic-gate TT_TRACE(trace_gen) ;\ 8697c478bd9Sstevel@tonic-gate or %g0, P_UTRAP4, %g2 ;\ 8707c478bd9Sstevel@tonic-gate or %g0, T_UNIMP_INSTR, %g3 ;\ 8717c478bd9Sstevel@tonic-gate sethi %hi(.check_v9utrap), %g4 ;\ 8727c478bd9Sstevel@tonic-gate jmp %g4 + %lo(.check_v9utrap) ;\ 8737c478bd9Sstevel@tonic-gate nop ;\ 8747c478bd9Sstevel@tonic-gate .align 32 8757c478bd9Sstevel@tonic-gate 8767c478bd9Sstevel@tonic-gate/* 8777c478bd9Sstevel@tonic-gate * tag overflow trap 8787c478bd9Sstevel@tonic-gate */ 8797c478bd9Sstevel@tonic-gate#define TAG_OVERFLOW \ 8807c478bd9Sstevel@tonic-gate TT_TRACE(trace_gen) ;\ 8817c478bd9Sstevel@tonic-gate or %g0, P_UTRAP10, %g2 ;\ 8827c478bd9Sstevel@tonic-gate or %g0, T_TAG_OVERFLOW, %g3 ;\ 8837c478bd9Sstevel@tonic-gate sethi %hi(.check_v9utrap), %g4 ;\ 8847c478bd9Sstevel@tonic-gate jmp %g4 + %lo(.check_v9utrap) ;\ 8857c478bd9Sstevel@tonic-gate nop ;\ 8867c478bd9Sstevel@tonic-gate .align 32 8877c478bd9Sstevel@tonic-gate 8887c478bd9Sstevel@tonic-gate/* 8897c478bd9Sstevel@tonic-gate * divide by zero trap 8907c478bd9Sstevel@tonic-gate */ 8917c478bd9Sstevel@tonic-gate#define DIV_BY_ZERO \ 8927c478bd9Sstevel@tonic-gate TT_TRACE(trace_gen) ;\ 8937c478bd9Sstevel@tonic-gate or %g0, P_UTRAP11, %g2 ;\ 8947c478bd9Sstevel@tonic-gate or %g0, T_IDIV0, %g3 ;\ 8957c478bd9Sstevel@tonic-gate sethi %hi(.check_v9utrap), %g4 ;\ 8967c478bd9Sstevel@tonic-gate jmp %g4 + %lo(.check_v9utrap) ;\ 8977c478bd9Sstevel@tonic-gate nop ;\ 8987c478bd9Sstevel@tonic-gate .align 32 8997c478bd9Sstevel@tonic-gate 9007c478bd9Sstevel@tonic-gate/* 9017c478bd9Sstevel@tonic-gate * trap instruction for V9 user trap handlers 9027c478bd9Sstevel@tonic-gate */ 9037c478bd9Sstevel@tonic-gate#define TRAP_INSTR \ 9047c478bd9Sstevel@tonic-gate TT_TRACE(trace_gen) ;\ 9057c478bd9Sstevel@tonic-gate or %g0, T_SOFTWARE_TRAP, %g3 ;\ 9067c478bd9Sstevel@tonic-gate sethi %hi(.check_v9utrap), %g4 ;\ 9077c478bd9Sstevel@tonic-gate jmp %g4 + %lo(.check_v9utrap) ;\ 9087c478bd9Sstevel@tonic-gate nop ;\ 9097c478bd9Sstevel@tonic-gate .align 32 9107c478bd9Sstevel@tonic-gate#define TRP4 TRAP_INSTR; TRAP_INSTR; TRAP_INSTR; TRAP_INSTR 9117c478bd9Sstevel@tonic-gate 9127c478bd9Sstevel@tonic-gate/* 9137c478bd9Sstevel@tonic-gate * LEVEL_INTERRUPT is for level N interrupts. 9147c478bd9Sstevel@tonic-gate * VECTOR_INTERRUPT is for the vector trap. 9157c478bd9Sstevel@tonic-gate */ 9167c478bd9Sstevel@tonic-gate#define LEVEL_INTERRUPT(level) \ 917*5d9d9091SRichard Lowe .global tt_pil##level ;\ 918*5d9d9091SRichard Lowett_pil##level: ;\ 9197c478bd9Sstevel@tonic-gate ba,pt %xcc, pil_interrupt ;\ 9207c478bd9Sstevel@tonic-gate mov level, %g4 ;\ 9217c478bd9Sstevel@tonic-gate .align 32 9227c478bd9Sstevel@tonic-gate 9237c478bd9Sstevel@tonic-gate#define LEVEL14_INTERRUPT \ 9247c478bd9Sstevel@tonic-gate ba pil14_interrupt ;\ 9257c478bd9Sstevel@tonic-gate mov PIL_14, %g4 ;\ 9267c478bd9Sstevel@tonic-gate .align 32 9277c478bd9Sstevel@tonic-gate 928b9e93c10SJonathan Haslam#define LEVEL15_INTERRUPT \ 929b9e93c10SJonathan Haslam ba pil15_interrupt ;\ 930b9e93c10SJonathan Haslam mov PIL_15, %g4 ;\ 931b9e93c10SJonathan Haslam .align 32 932b9e93c10SJonathan Haslam 9337c478bd9Sstevel@tonic-gate#define VECTOR_INTERRUPT \ 9347c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_INTR_RECEIVE_STATUS, %g1 ;\ 9357c478bd9Sstevel@tonic-gate btst IRSR_BUSY, %g1 ;\ 9367c478bd9Sstevel@tonic-gate bnz,pt %xcc, vec_interrupt ;\ 9377c478bd9Sstevel@tonic-gate nop ;\ 9387c478bd9Sstevel@tonic-gate ba,a,pt %xcc, vec_intr_spurious ;\ 9397c478bd9Sstevel@tonic-gate .empty ;\ 9407c478bd9Sstevel@tonic-gate .align 32 9417c478bd9Sstevel@tonic-gate 9427c478bd9Sstevel@tonic-gate/* 9437c478bd9Sstevel@tonic-gate * MMU Trap Handlers. 9447c478bd9Sstevel@tonic-gate */ 9457c478bd9Sstevel@tonic-gate#define SWITCH_GLOBALS /* mmu->alt, alt->mmu */ \ 9467c478bd9Sstevel@tonic-gate rdpr %pstate, %g5 ;\ 9477c478bd9Sstevel@tonic-gate wrpr %g5, PSTATE_MG | PSTATE_AG, %pstate 9487c478bd9Sstevel@tonic-gate 9497c478bd9Sstevel@tonic-gate#define IMMU_EXCEPTION \ 9507c478bd9Sstevel@tonic-gate membar #Sync ;\ 9517c478bd9Sstevel@tonic-gate SWITCH_GLOBALS ;\ 9527c478bd9Sstevel@tonic-gate wr %g0, ASI_IMMU, %asi ;\ 9537c478bd9Sstevel@tonic-gate rdpr %tpc, %g2 ;\ 9547c478bd9Sstevel@tonic-gate ldxa [MMU_SFSR]%asi, %g3 ;\ 9557c478bd9Sstevel@tonic-gate ba,pt %xcc, .mmu_exception_end ;\ 9567c478bd9Sstevel@tonic-gate mov T_INSTR_EXCEPTION, %g1 ;\ 9577c478bd9Sstevel@tonic-gate .align 32 9587c478bd9Sstevel@tonic-gate 9597c478bd9Sstevel@tonic-gate#define DMMU_EXCEPTION \ 9607c478bd9Sstevel@tonic-gate SWITCH_GLOBALS ;\ 9617c478bd9Sstevel@tonic-gate wr %g0, ASI_DMMU, %asi ;\ 9627c478bd9Sstevel@tonic-gate ldxa [MMU_TAG_ACCESS]%asi, %g2 ;\ 9637c478bd9Sstevel@tonic-gate ldxa [MMU_SFSR]%asi, %g3 ;\ 9647c478bd9Sstevel@tonic-gate ba,pt %xcc, .mmu_exception_end ;\ 9657c478bd9Sstevel@tonic-gate mov T_DATA_EXCEPTION, %g1 ;\ 9667c478bd9Sstevel@tonic-gate .align 32 9677c478bd9Sstevel@tonic-gate 9687c478bd9Sstevel@tonic-gate#define DMMU_EXC_AG_PRIV \ 9697c478bd9Sstevel@tonic-gate wr %g0, ASI_DMMU, %asi ;\ 9707c478bd9Sstevel@tonic-gate ldxa [MMU_SFAR]%asi, %g2 ;\ 9717c478bd9Sstevel@tonic-gate ba,pt %xcc, .mmu_priv_exception ;\ 9727c478bd9Sstevel@tonic-gate ldxa [MMU_SFSR]%asi, %g3 ;\ 9737c478bd9Sstevel@tonic-gate .align 32 9747c478bd9Sstevel@tonic-gate 9757c478bd9Sstevel@tonic-gate#define DMMU_EXC_AG_NOT_ALIGNED \ 9767c478bd9Sstevel@tonic-gate wr %g0, ASI_DMMU, %asi ;\ 9777c478bd9Sstevel@tonic-gate ldxa [MMU_SFAR]%asi, %g2 ;\ 9787c478bd9Sstevel@tonic-gate ba,pt %xcc, .mmu_exception_not_aligned ;\ 9797c478bd9Sstevel@tonic-gate ldxa [MMU_SFSR]%asi, %g3 ;\ 9807c478bd9Sstevel@tonic-gate .align 32 9817c478bd9Sstevel@tonic-gate 9827c478bd9Sstevel@tonic-gate/* 9837c478bd9Sstevel@tonic-gate * SPARC V9 IMPL. DEP. #109(1) and (2) and #110(1) and (2) 9847c478bd9Sstevel@tonic-gate */ 9857c478bd9Sstevel@tonic-gate#define DMMU_EXC_LDDF_NOT_ALIGNED \ 9867c478bd9Sstevel@tonic-gate btst 1, %sp ;\ 9877c478bd9Sstevel@tonic-gate bnz,pt %xcc, .lddf_exception_not_aligned ;\ 9887c478bd9Sstevel@tonic-gate wr %g0, ASI_DMMU, %asi ;\ 9897c478bd9Sstevel@tonic-gate ldxa [MMU_SFAR]%asi, %g2 ;\ 9907c478bd9Sstevel@tonic-gate ba,pt %xcc, .mmu_exception_not_aligned ;\ 9917c478bd9Sstevel@tonic-gate ldxa [MMU_SFSR]%asi, %g3 ;\ 9927c478bd9Sstevel@tonic-gate .align 32 9937c478bd9Sstevel@tonic-gate 9947c478bd9Sstevel@tonic-gate#define DMMU_EXC_STDF_NOT_ALIGNED \ 9957c478bd9Sstevel@tonic-gate btst 1, %sp ;\ 9967c478bd9Sstevel@tonic-gate bnz,pt %xcc, .stdf_exception_not_aligned ;\ 9977c478bd9Sstevel@tonic-gate wr %g0, ASI_DMMU, %asi ;\ 9987c478bd9Sstevel@tonic-gate ldxa [MMU_SFAR]%asi, %g2 ;\ 9997c478bd9Sstevel@tonic-gate ba,pt %xcc, .mmu_exception_not_aligned ;\ 10007c478bd9Sstevel@tonic-gate ldxa [MMU_SFSR]%asi, %g3 ;\ 10017c478bd9Sstevel@tonic-gate .align 32 10027c478bd9Sstevel@tonic-gate 10037c478bd9Sstevel@tonic-gate/* 10047c478bd9Sstevel@tonic-gate * Flush the TLB using either the primary, secondary, or nucleus flush 10057c478bd9Sstevel@tonic-gate * operation based on whether the ctx from the tag access register matches 10067c478bd9Sstevel@tonic-gate * the primary or secondary context (flush the nucleus if neither matches). 10077c478bd9Sstevel@tonic-gate * 10087c478bd9Sstevel@tonic-gate * Requires a membar #Sync before next ld/st. 10097c478bd9Sstevel@tonic-gate * exits with: 10107c478bd9Sstevel@tonic-gate * g2 = tag access register 10117c478bd9Sstevel@tonic-gate * g3 = ctx number 10127c478bd9Sstevel@tonic-gate */ 10137c478bd9Sstevel@tonic-gate#if TAGACC_CTX_MASK != CTXREG_CTX_MASK 10147c478bd9Sstevel@tonic-gate#error "TAGACC_CTX_MASK != CTXREG_CTX_MASK" 10157c478bd9Sstevel@tonic-gate#endif 10167c478bd9Sstevel@tonic-gate#define DTLB_DEMAP_ENTRY \ 10177c478bd9Sstevel@tonic-gate mov MMU_TAG_ACCESS, %g1 ;\ 10187c478bd9Sstevel@tonic-gate mov MMU_PCONTEXT, %g5 ;\ 10197c478bd9Sstevel@tonic-gate ldxa [%g1]ASI_DMMU, %g2 ;\ 10207c478bd9Sstevel@tonic-gate sethi %hi(TAGACC_CTX_MASK), %g4 ;\ 10217c478bd9Sstevel@tonic-gate or %g4, %lo(TAGACC_CTX_MASK), %g4 ;\ 10227c478bd9Sstevel@tonic-gate and %g2, %g4, %g3 /* g3 = ctx */ ;\ 10237c478bd9Sstevel@tonic-gate ldxa [%g5]ASI_DMMU, %g6 /* g6 = primary ctx */ ;\ 10247c478bd9Sstevel@tonic-gate and %g6, %g4, %g6 /* &= CTXREG_CTX_MASK */ ;\ 10257c478bd9Sstevel@tonic-gate cmp %g3, %g6 ;\ 10267c478bd9Sstevel@tonic-gate be,pt %xcc, 1f ;\ 10277c478bd9Sstevel@tonic-gate andn %g2, %g4, %g1 /* ctx = primary */ ;\ 10287c478bd9Sstevel@tonic-gate mov MMU_SCONTEXT, %g5 ;\ 10297c478bd9Sstevel@tonic-gate ldxa [%g5]ASI_DMMU, %g6 /* g6 = secondary ctx */ ;\ 10307c478bd9Sstevel@tonic-gate and %g6, %g4, %g6 /* &= CTXREG_CTX_MASK */ ;\ 10317c478bd9Sstevel@tonic-gate cmp %g3, %g6 ;\ 10327c478bd9Sstevel@tonic-gate be,a,pt %xcc, 1f ;\ 10337c478bd9Sstevel@tonic-gate or %g1, DEMAP_SECOND, %g1 ;\ 10347c478bd9Sstevel@tonic-gate or %g1, DEMAP_NUCLEUS, %g1 ;\ 10357c478bd9Sstevel@tonic-gate1: stxa %g0, [%g1]ASI_DTLB_DEMAP /* MMU_DEMAP_PAGE */ ;\ 10367c478bd9Sstevel@tonic-gate membar #Sync 10377c478bd9Sstevel@tonic-gate 10387c478bd9Sstevel@tonic-gate#if defined(cscope) 10397c478bd9Sstevel@tonic-gate/* 10407c478bd9Sstevel@tonic-gate * Define labels to direct cscope quickly to labels that 10417c478bd9Sstevel@tonic-gate * are generated by macro expansion of DTLB_MISS(). 10427c478bd9Sstevel@tonic-gate */ 10437c478bd9Sstevel@tonic-gate .global tt0_dtlbmiss 10447c478bd9Sstevel@tonic-gatett0_dtlbmiss: 10457c478bd9Sstevel@tonic-gate .global tt1_dtlbmiss 10467c478bd9Sstevel@tonic-gatett1_dtlbmiss: 10477c478bd9Sstevel@tonic-gate nop 10487c478bd9Sstevel@tonic-gate#endif 10497c478bd9Sstevel@tonic-gate 10507c478bd9Sstevel@tonic-gate/* 10517c478bd9Sstevel@tonic-gate * Needs to be exactly 32 instructions 10527c478bd9Sstevel@tonic-gate * 10537c478bd9Sstevel@tonic-gate * UTLB NOTE: If we don't hit on the 8k pointer then we branch 10547c478bd9Sstevel@tonic-gate * to a special 4M tsb handler. It would be nice if that handler 10557c478bd9Sstevel@tonic-gate * could live in this file but currently it seems better to allow 10567c478bd9Sstevel@tonic-gate * it to fall thru to sfmmu_tsb_miss. 10577c478bd9Sstevel@tonic-gate */ 105825cf1a30Sjl#ifdef UTSB_PHYS 105925cf1a30Sjl#define DTLB_MISS(table_name) ;\ 1060*5d9d9091SRichard Lowe .global table_name##_dtlbmiss ;\ 1061*5d9d9091SRichard Lowetable_name##_dtlbmiss: ;\ 106225cf1a30Sjl mov MMU_TAG_ACCESS, %g6 /* select tag acc */ ;\ 106325cf1a30Sjl ldxa [%g0]ASI_DMMU_TSB_8K, %g1 /* g1 = tsbe ptr */ ;\ 106425cf1a30Sjl ldxa [%g6]ASI_DMMU, %g2 /* g2 = tag access */ ;\ 106525cf1a30Sjl sllx %g2, TAGACC_CTX_LSHIFT, %g3 ;\ 106625cf1a30Sjl srlx %g3, TAGACC_CTX_LSHIFT, %g3 /* g3 = ctx */ ;\ 106725cf1a30Sjl cmp %g3, INVALID_CONTEXT ;\ 106825cf1a30Sjl ble,pn %xcc, sfmmu_kdtlb_miss ;\ 10691426d65aSsm srax %g2, PREDISM_BASESHIFT, %g6 /* g6 > 0 ISM predicted */ ;\ 10701426d65aSsm brgz,pn %g6, sfmmu_udtlb_slowpath_ismpred ;\ 107125cf1a30Sjl srlx %g2, TAG_VALO_SHIFT, %g7 /* g7 = tsb tag */ ;\ 107225cf1a30Sjl ldda [%g1]ASI_QUAD_LDD_PHYS, %g4 /* g4 = tag, %g5 data */;\ 107325cf1a30Sjl cmp %g4, %g7 ;\ 10741426d65aSsm bne,pn %xcc, sfmmu_udtlb_slowpath_noismpred ;\ 10751426d65aSsm nop ;\ 107625cf1a30Sjl TT_TRACE(trace_tsbhit) /* 2 instr ifdef TRAPTRACE */ ;\ 107725cf1a30Sjl stxa %g5, [%g0]ASI_DTLB_IN /* trapstat expects TTE */ ;\ 107825cf1a30Sjl retry /* in %g5 */ ;\ 107925cf1a30Sjl unimp 0 ;\ 108025cf1a30Sjl unimp 0 ;\ 108125cf1a30Sjl unimp 0 ;\ 108225cf1a30Sjl unimp 0 ;\ 108325cf1a30Sjl unimp 0 ;\ 108425cf1a30Sjl unimp 0 ;\ 108525cf1a30Sjl unimp 0 ;\ 108625cf1a30Sjl unimp 0 ;\ 108725cf1a30Sjl unimp 0 ;\ 10881426d65aSsm unimp 0 ;\ 10891426d65aSsm unimp 0 ;\ 10901426d65aSsm unimp 0 ;\ 10911426d65aSsm unimp 0 ;\ 10921426d65aSsm unimp 0 ;\ 109325cf1a30Sjl .align 128 1094*5d9d9091SRichard Lowe 109525cf1a30Sjl#else /* UTSB_PHYS */ 10967c478bd9Sstevel@tonic-gate#define DTLB_MISS(table_name) ;\ 1097*5d9d9091SRichard Lowe .global table_name##_dtlbmiss ;\ 1098*5d9d9091SRichard Lowetable_name##_dtlbmiss: ;\ 10997c478bd9Sstevel@tonic-gate mov MMU_TAG_ACCESS, %g6 /* select tag acc */ ;\ 11007c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_DMMU_TSB_8K, %g1 /* g1 = tsbe ptr */ ;\ 11017c478bd9Sstevel@tonic-gate ldxa [%g6]ASI_DMMU, %g2 /* g2 = tag access */ ;\ 11027c478bd9Sstevel@tonic-gate sllx %g2, TAGACC_CTX_LSHIFT, %g3 ;\ 11037c478bd9Sstevel@tonic-gate srlx %g3, TAGACC_CTX_LSHIFT, %g3 /* g3 = ctx */ ;\ 11047c478bd9Sstevel@tonic-gate cmp %g3, INVALID_CONTEXT ;\ 11057c478bd9Sstevel@tonic-gate ble,pn %xcc, sfmmu_kdtlb_miss ;\ 11067c478bd9Sstevel@tonic-gate srlx %g2, TAG_VALO_SHIFT, %g7 /* g7 = tsb tag */ ;\ 11077c478bd9Sstevel@tonic-gate brlz,pn %g1, sfmmu_udtlb_slowpath ;\ 11087c478bd9Sstevel@tonic-gate nop ;\ 11097c478bd9Sstevel@tonic-gate ldda [%g1]ASI_NQUAD_LD, %g4 /* g4 = tag, %g5 data */ ;\ 11107c478bd9Sstevel@tonic-gate cmp %g4, %g7 ;\ 11117c478bd9Sstevel@tonic-gate bne,pn %xcc, sfmmu_tsb_miss_tt /* no 4M TSB, miss */ ;\ 111205d3dc4bSpaulsan mov -1, %g3 /* set 4M tsbe ptr to -1 */ ;\ 11137c478bd9Sstevel@tonic-gate TT_TRACE(trace_tsbhit) /* 2 instr ifdef TRAPTRACE */ ;\ 11147c478bd9Sstevel@tonic-gate stxa %g5, [%g0]ASI_DTLB_IN /* trapstat expects TTE */ ;\ 11157c478bd9Sstevel@tonic-gate retry /* in %g5 */ ;\ 11167c478bd9Sstevel@tonic-gate unimp 0 ;\ 11177c478bd9Sstevel@tonic-gate unimp 0 ;\ 11187c478bd9Sstevel@tonic-gate unimp 0 ;\ 11197c478bd9Sstevel@tonic-gate unimp 0 ;\ 11207c478bd9Sstevel@tonic-gate unimp 0 ;\ 112105d3dc4bSpaulsan unimp 0 ;\ 112205d3dc4bSpaulsan unimp 0 ;\ 112305d3dc4bSpaulsan unimp 0 ;\ 112405d3dc4bSpaulsan unimp 0 ;\ 112505d3dc4bSpaulsan unimp 0 ;\ 112605d3dc4bSpaulsan unimp 0 ;\ 112705d3dc4bSpaulsan unimp 0 ;\ 112805d3dc4bSpaulsan unimp 0 ;\ 112905d3dc4bSpaulsan unimp 0 ;\ 11307c478bd9Sstevel@tonic-gate .align 128 113125cf1a30Sjl#endif /* UTSB_PHYS */ 11327c478bd9Sstevel@tonic-gate 11337c478bd9Sstevel@tonic-gate#if defined(cscope) 11347c478bd9Sstevel@tonic-gate/* 11357c478bd9Sstevel@tonic-gate * Define labels to direct cscope quickly to labels that 11367c478bd9Sstevel@tonic-gate * are generated by macro expansion of ITLB_MISS(). 11377c478bd9Sstevel@tonic-gate */ 11387c478bd9Sstevel@tonic-gate .global tt0_itlbmiss 11397c478bd9Sstevel@tonic-gatett0_itlbmiss: 11407c478bd9Sstevel@tonic-gate .global tt1_itlbmiss 11417c478bd9Sstevel@tonic-gatett1_itlbmiss: 11427c478bd9Sstevel@tonic-gate nop 11437c478bd9Sstevel@tonic-gate#endif 11447c478bd9Sstevel@tonic-gate 11457c478bd9Sstevel@tonic-gate/* 11467c478bd9Sstevel@tonic-gate * Instruction miss handler. 11477c478bd9Sstevel@tonic-gate * ldda instructions will have their ASI patched 11487c478bd9Sstevel@tonic-gate * by sfmmu_patch_ktsb at runtime. 11497c478bd9Sstevel@tonic-gate * MUST be EXACTLY 32 instructions or we'll break. 11507c478bd9Sstevel@tonic-gate */ 115125cf1a30Sjl#ifdef UTSB_PHYS 11521426d65aSsm#define ITLB_MISS(table_name) \ 1153*5d9d9091SRichard Lowe .global table_name##_itlbmiss ;\ 1154*5d9d9091SRichard Lowetable_name##_itlbmiss: ;\ 11551426d65aSsm mov MMU_TAG_ACCESS, %g6 /* select tag acc */ ;\ 11561426d65aSsm ldxa [%g0]ASI_IMMU_TSB_8K, %g1 /* g1 = tsbe ptr */ ;\ 11571426d65aSsm ldxa [%g6]ASI_IMMU, %g2 /* g2 = tag access */ ;\ 11581426d65aSsm sllx %g2, TAGACC_CTX_LSHIFT, %g3 ;\ 11591426d65aSsm srlx %g3, TAGACC_CTX_LSHIFT, %g3 /* g3 = ctx */ ;\ 11601426d65aSsm cmp %g3, INVALID_CONTEXT ;\ 11611426d65aSsm ble,pn %xcc, sfmmu_kitlb_miss ;\ 11621426d65aSsm srlx %g2, TAG_VALO_SHIFT, %g7 /* g7 = tsb tag */ ;\ 11631426d65aSsm ldda [%g1]ASI_QUAD_LDD_PHYS, %g4 /* g4 = tag, g5 = data */ ;\ 11641426d65aSsm cmp %g4, %g7 ;\ 11651426d65aSsm bne,pn %xcc, sfmmu_uitlb_slowpath ;\ 11661426d65aSsm andcc %g5, TTE_EXECPRM_INT, %g0 /* check execute bit */ ;\ 11671426d65aSsm bz,pn %icc, exec_fault ;\ 11681426d65aSsm nop ;\ 11691426d65aSsm TT_TRACE(trace_tsbhit) /* 2 instr ifdef TRAPTRACE */ ;\ 11701426d65aSsm stxa %g5, [%g0]ASI_ITLB_IN /* trapstat expects %g5 */ ;\ 11711426d65aSsm retry ;\ 117205d3dc4bSpaulsan unimp 0 ;\ 117305d3dc4bSpaulsan unimp 0 ;\ 117405d3dc4bSpaulsan unimp 0 ;\ 11751426d65aSsm unimp 0 ;\ 11761426d65aSsm unimp 0 ;\ 11771426d65aSsm unimp 0 ;\ 11781426d65aSsm unimp 0 ;\ 11791426d65aSsm unimp 0 ;\ 11801426d65aSsm unimp 0 ;\ 11811426d65aSsm unimp 0 ;\ 11821426d65aSsm unimp 0 ;\ 11831426d65aSsm unimp 0 ;\ 11841426d65aSsm unimp 0 ;\ 11851426d65aSsm unimp 0 ;\ 1186*5d9d9091SRichard Lowe .align 128 11871426d65aSsm 118825cf1a30Sjl#else /* UTSB_PHYS */ 11897c478bd9Sstevel@tonic-gate#define ITLB_MISS(table_name) \ 1190*5d9d9091SRichard Lowe .global table_name##_itlbmiss ;\ 1191*5d9d9091SRichard Lowetable_name##_itlbmiss: ;\ 11927c478bd9Sstevel@tonic-gate mov MMU_TAG_ACCESS, %g6 /* select tag acc */ ;\ 11937c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_IMMU_TSB_8K, %g1 /* g1 = tsbe ptr */ ;\ 11947c478bd9Sstevel@tonic-gate ldxa [%g6]ASI_IMMU, %g2 /* g2 = tag access */ ;\ 11957c478bd9Sstevel@tonic-gate sllx %g2, TAGACC_CTX_LSHIFT, %g3 ;\ 11967c478bd9Sstevel@tonic-gate srlx %g3, TAGACC_CTX_LSHIFT, %g3 /* g3 = ctx */ ;\ 11977c478bd9Sstevel@tonic-gate cmp %g3, INVALID_CONTEXT ;\ 11987c478bd9Sstevel@tonic-gate ble,pn %xcc, sfmmu_kitlb_miss ;\ 11997c478bd9Sstevel@tonic-gate srlx %g2, TAG_VALO_SHIFT, %g7 /* g7 = tsb tag */ ;\ 12007c478bd9Sstevel@tonic-gate brlz,pn %g1, sfmmu_uitlb_slowpath /* if >1 TSB branch */ ;\ 12017c478bd9Sstevel@tonic-gate nop ;\ 12027c478bd9Sstevel@tonic-gate ldda [%g1]ASI_NQUAD_LD, %g4 /* g4 = tag, g5 = data */ ;\ 12037c478bd9Sstevel@tonic-gate cmp %g4, %g7 ;\ 12047c478bd9Sstevel@tonic-gate bne,pn %xcc, sfmmu_tsb_miss_tt /* br if 8k ptr miss */ ;\ 120505d3dc4bSpaulsan mov -1, %g3 /* set 4M TSB ptr to -1 */ ;\ 12067c478bd9Sstevel@tonic-gate andcc %g5, TTE_EXECPRM_INT, %g0 /* check execute bit */ ;\ 12077c478bd9Sstevel@tonic-gate bz,pn %icc, exec_fault ;\ 12087c478bd9Sstevel@tonic-gate nop ;\ 12097c478bd9Sstevel@tonic-gate TT_TRACE(trace_tsbhit) /* 2 instr ifdef TRAPTRACE */ ;\ 12107c478bd9Sstevel@tonic-gate stxa %g5, [%g0]ASI_ITLB_IN /* trapstat expects %g5 */ ;\ 12117c478bd9Sstevel@tonic-gate retry ;\ 12127c478bd9Sstevel@tonic-gate unimp 0 ;\ 12137c478bd9Sstevel@tonic-gate unimp 0 ;\ 12147c478bd9Sstevel@tonic-gate unimp 0 ;\ 12157c478bd9Sstevel@tonic-gate unimp 0 ;\ 12167c478bd9Sstevel@tonic-gate unimp 0 ;\ 121705d3dc4bSpaulsan unimp 0 ;\ 121805d3dc4bSpaulsan unimp 0 ;\ 121905d3dc4bSpaulsan unimp 0 ;\ 122005d3dc4bSpaulsan unimp 0 ;\ 122105d3dc4bSpaulsan unimp 0 ;\ 122205d3dc4bSpaulsan unimp 0 ;\ 12237c478bd9Sstevel@tonic-gate .align 128 122425cf1a30Sjl#endif /* UTSB_PHYS */ 12257c478bd9Sstevel@tonic-gate 12267c478bd9Sstevel@tonic-gate 12277c478bd9Sstevel@tonic-gate/* 12287c478bd9Sstevel@tonic-gate * This macro is the first level handler for fast protection faults. 12297c478bd9Sstevel@tonic-gate * It first demaps the tlb entry which generated the fault and then 12307c478bd9Sstevel@tonic-gate * attempts to set the modify bit on the hash. It needs to be 12317c478bd9Sstevel@tonic-gate * exactly 32 instructions. 12327c478bd9Sstevel@tonic-gate */ 12337c478bd9Sstevel@tonic-gate#define DTLB_PROT \ 12347c478bd9Sstevel@tonic-gate DTLB_DEMAP_ENTRY /* 20 instructions */ ;\ 12357c478bd9Sstevel@tonic-gate /* ;\ 12367c478bd9Sstevel@tonic-gate * At this point: ;\ 12377c478bd9Sstevel@tonic-gate * g1 = ???? ;\ 12387c478bd9Sstevel@tonic-gate * g2 = tag access register ;\ 12397c478bd9Sstevel@tonic-gate * g3 = ctx number ;\ 12407c478bd9Sstevel@tonic-gate * g4 = ???? ;\ 12417c478bd9Sstevel@tonic-gate */ ;\ 12427c478bd9Sstevel@tonic-gate TT_TRACE(trace_dataprot) /* 2 instr ifdef TRAPTRACE */ ;\ 12437c478bd9Sstevel@tonic-gate /* clobbers g1 and g6 */ ;\ 12447c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_DMMU_TSB_8K, %g1 /* g1 = tsbe ptr */ ;\ 12457c478bd9Sstevel@tonic-gate brnz,pt %g3, sfmmu_uprot_trap /* user trap */ ;\ 12467c478bd9Sstevel@tonic-gate nop ;\ 12477c478bd9Sstevel@tonic-gate ba,a,pt %xcc, sfmmu_kprot_trap /* kernel trap */ ;\ 12487c478bd9Sstevel@tonic-gate unimp 0 ;\ 12497c478bd9Sstevel@tonic-gate unimp 0 ;\ 12507c478bd9Sstevel@tonic-gate unimp 0 ;\ 12517c478bd9Sstevel@tonic-gate unimp 0 ;\ 12527c478bd9Sstevel@tonic-gate unimp 0 ;\ 12537c478bd9Sstevel@tonic-gate unimp 0 ;\ 12547c478bd9Sstevel@tonic-gate .align 128 12557c478bd9Sstevel@tonic-gate 12567c478bd9Sstevel@tonic-gate#define DMMU_EXCEPTION_TL1 ;\ 12577c478bd9Sstevel@tonic-gate SWITCH_GLOBALS ;\ 12587c478bd9Sstevel@tonic-gate ba,a,pt %xcc, mmu_trap_tl1 ;\ 12597c478bd9Sstevel@tonic-gate nop ;\ 12607c478bd9Sstevel@tonic-gate .align 32 12617c478bd9Sstevel@tonic-gate 12627c478bd9Sstevel@tonic-gate#define MISALIGN_ADDR_TL1 ;\ 12637c478bd9Sstevel@tonic-gate ba,a,pt %xcc, mmu_trap_tl1 ;\ 12647c478bd9Sstevel@tonic-gate nop ;\ 12657c478bd9Sstevel@tonic-gate .align 32 12667c478bd9Sstevel@tonic-gate 12677c478bd9Sstevel@tonic-gate/* 12687c478bd9Sstevel@tonic-gate * Trace a tsb hit 12697c478bd9Sstevel@tonic-gate * g1 = tsbe pointer (in/clobbered) 12707c478bd9Sstevel@tonic-gate * g2 = tag access register (in) 12717c478bd9Sstevel@tonic-gate * g3 - g4 = scratch (clobbered) 12727c478bd9Sstevel@tonic-gate * g5 = tsbe data (in) 12737c478bd9Sstevel@tonic-gate * g6 = scratch (clobbered) 12747c478bd9Sstevel@tonic-gate * g7 = pc we jumped here from (in) 12757c478bd9Sstevel@tonic-gate * ttextra = value to OR in to trap type (%tt) (in) 12767c478bd9Sstevel@tonic-gate */ 12777c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE 12787c478bd9Sstevel@tonic-gate#define TRACE_TSBHIT(ttextra) \ 12797c478bd9Sstevel@tonic-gate membar #Sync ;\ 12807c478bd9Sstevel@tonic-gate sethi %hi(FLUSH_ADDR), %g6 ;\ 12817c478bd9Sstevel@tonic-gate flush %g6 ;\ 12827c478bd9Sstevel@tonic-gate TRACE_PTR(%g3, %g6) ;\ 1283023e71deSHaik Aftandilian GET_TRACE_TICK(%g6, %g4) ;\ 12847c478bd9Sstevel@tonic-gate stxa %g6, [%g3 + TRAP_ENT_TICK]%asi ;\ 12857c478bd9Sstevel@tonic-gate stxa %g2, [%g3 + TRAP_ENT_SP]%asi /* tag access */ ;\ 12867c478bd9Sstevel@tonic-gate stxa %g5, [%g3 + TRAP_ENT_F1]%asi /* tsb data */ ;\ 12877c478bd9Sstevel@tonic-gate rdpr %tnpc, %g6 ;\ 12887c478bd9Sstevel@tonic-gate stxa %g6, [%g3 + TRAP_ENT_F2]%asi ;\ 12897c478bd9Sstevel@tonic-gate stxa %g1, [%g3 + TRAP_ENT_F3]%asi /* tsb pointer */ ;\ 12907c478bd9Sstevel@tonic-gate stxa %g0, [%g3 + TRAP_ENT_F4]%asi ;\ 12917c478bd9Sstevel@tonic-gate rdpr %tpc, %g6 ;\ 12927c478bd9Sstevel@tonic-gate stxa %g6, [%g3 + TRAP_ENT_TPC]%asi ;\ 12937c478bd9Sstevel@tonic-gate rdpr %tl, %g6 ;\ 12947c478bd9Sstevel@tonic-gate stha %g6, [%g3 + TRAP_ENT_TL]%asi ;\ 12957c478bd9Sstevel@tonic-gate rdpr %tt, %g6 ;\ 12967c478bd9Sstevel@tonic-gate or %g6, (ttextra), %g6 ;\ 12977c478bd9Sstevel@tonic-gate stha %g6, [%g3 + TRAP_ENT_TT]%asi ;\ 12987c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_IMMU, %g1 /* tag target */ ;\ 12997c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_DMMU, %g4 ;\ 13007c478bd9Sstevel@tonic-gate cmp %g6, FAST_IMMU_MISS_TT ;\ 13017c478bd9Sstevel@tonic-gate movne %icc, %g4, %g1 ;\ 13027c478bd9Sstevel@tonic-gate stxa %g1, [%g3 + TRAP_ENT_TSTATE]%asi /* tsb tag */ ;\ 13037c478bd9Sstevel@tonic-gate stxa %g0, [%g3 + TRAP_ENT_TR]%asi ;\ 13047c478bd9Sstevel@tonic-gate TRACE_NEXT(%g3, %g4, %g6) 13057c478bd9Sstevel@tonic-gate#else 13067c478bd9Sstevel@tonic-gate#define TRACE_TSBHIT(ttextra) 13077c478bd9Sstevel@tonic-gate#endif 13087c478bd9Sstevel@tonic-gate 13097c478bd9Sstevel@tonic-gate/* 13107c478bd9Sstevel@tonic-gate * ======================================================================= 13117c478bd9Sstevel@tonic-gate * SPARC V9 TRAP TABLE 13127c478bd9Sstevel@tonic-gate * 13137c478bd9Sstevel@tonic-gate * The trap table is divided into two halves: the first half is used when 13147c478bd9Sstevel@tonic-gate * taking traps when TL=0; the second half is used when taking traps from 13157c478bd9Sstevel@tonic-gate * TL>0. Note that handlers in the second half of the table might not be able 13167c478bd9Sstevel@tonic-gate * to make the same assumptions as handlers in the first half of the table. 13177c478bd9Sstevel@tonic-gate * 13187c478bd9Sstevel@tonic-gate * Worst case trap nesting so far: 13197c478bd9Sstevel@tonic-gate * 13207c478bd9Sstevel@tonic-gate * at TL=0 client issues software trap requesting service 13217c478bd9Sstevel@tonic-gate * at TL=1 nucleus wants a register window 13227c478bd9Sstevel@tonic-gate * at TL=2 register window clean/spill/fill takes a TLB miss 13237c478bd9Sstevel@tonic-gate * at TL=3 processing TLB miss 13247c478bd9Sstevel@tonic-gate * at TL=4 handle asynchronous error 13257c478bd9Sstevel@tonic-gate * 13267c478bd9Sstevel@tonic-gate * Note that a trap from TL=4 to TL=5 places Spitfire in "RED mode". 13277c478bd9Sstevel@tonic-gate * 13287c478bd9Sstevel@tonic-gate * ======================================================================= 13297c478bd9Sstevel@tonic-gate */ 13307c478bd9Sstevel@tonic-gate .section ".text" 13317c478bd9Sstevel@tonic-gate .align 4 13327c478bd9Sstevel@tonic-gate .global trap_table, scb, trap_table0, trap_table1, etrap_table 133341f63f87Spetede .type trap_table, #object 133441f63f87Spetede .type scb, #object 13357c478bd9Sstevel@tonic-gatetrap_table: 13367c478bd9Sstevel@tonic-gatescb: 13377c478bd9Sstevel@tonic-gatetrap_table0: 13387c478bd9Sstevel@tonic-gate /* hardware traps */ 13397c478bd9Sstevel@tonic-gate NOT; /* 000 reserved */ 13407c478bd9Sstevel@tonic-gate RED; /* 001 power on reset */ 13417c478bd9Sstevel@tonic-gate RED; /* 002 watchdog reset */ 13427c478bd9Sstevel@tonic-gate RED; /* 003 externally initiated reset */ 13437c478bd9Sstevel@tonic-gate RED; /* 004 software initiated reset */ 13447c478bd9Sstevel@tonic-gate RED; /* 005 red mode exception */ 13457c478bd9Sstevel@tonic-gate NOT; NOT; /* 006 - 007 reserved */ 13467c478bd9Sstevel@tonic-gate IMMU_EXCEPTION; /* 008 instruction access exception */ 13477c478bd9Sstevel@tonic-gate NOT; /* 009 instruction access MMU miss */ 134825cf1a30Sjl ASYNC_TRAP(T_INSTR_ERROR, trace_gen, tt0_iae); 13497c478bd9Sstevel@tonic-gate /* 00A instruction access error */ 13507c478bd9Sstevel@tonic-gate NOT; NOT4; /* 00B - 00F reserved */ 13517c478bd9Sstevel@tonic-gate ILLTRAP_INSTR; /* 010 illegal instruction */ 13527c478bd9Sstevel@tonic-gate TRAP(T_PRIV_INSTR); /* 011 privileged opcode */ 13537c478bd9Sstevel@tonic-gate NOT; /* 012 unimplemented LDD */ 13547c478bd9Sstevel@tonic-gate NOT; /* 013 unimplemented STD */ 13557c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; /* 014 - 01F reserved */ 13567c478bd9Sstevel@tonic-gate FP_DISABLED_TRAP; /* 020 fp disabled */ 13577c478bd9Sstevel@tonic-gate FP_IEEE_TRAP; /* 021 fp exception ieee 754 */ 13587c478bd9Sstevel@tonic-gate FP_TRAP; /* 022 fp exception other */ 13597c478bd9Sstevel@tonic-gate TAG_OVERFLOW; /* 023 tag overflow */ 13607c478bd9Sstevel@tonic-gate CLEAN_WINDOW; /* 024 - 027 clean window */ 13617c478bd9Sstevel@tonic-gate DIV_BY_ZERO; /* 028 division by zero */ 13627c478bd9Sstevel@tonic-gate NOT; /* 029 internal processor error */ 13637c478bd9Sstevel@tonic-gate NOT; NOT; NOT4; /* 02A - 02F reserved */ 13647c478bd9Sstevel@tonic-gate DMMU_EXCEPTION; /* 030 data access exception */ 13657c478bd9Sstevel@tonic-gate NOT; /* 031 data access MMU miss */ 136625cf1a30Sjl ASYNC_TRAP(T_DATA_ERROR, trace_gen, tt0_dae); 13677c478bd9Sstevel@tonic-gate /* 032 data access error */ 13687c478bd9Sstevel@tonic-gate NOT; /* 033 data access protection */ 13697c478bd9Sstevel@tonic-gate DMMU_EXC_AG_NOT_ALIGNED; /* 034 mem address not aligned */ 13707c478bd9Sstevel@tonic-gate DMMU_EXC_LDDF_NOT_ALIGNED; /* 035 LDDF mem address not aligned */ 13717c478bd9Sstevel@tonic-gate DMMU_EXC_STDF_NOT_ALIGNED; /* 036 STDF mem address not aligned */ 13727c478bd9Sstevel@tonic-gate DMMU_EXC_AG_PRIV; /* 037 privileged action */ 13737c478bd9Sstevel@tonic-gate NOT; /* 038 LDQF mem address not aligned */ 13747c478bd9Sstevel@tonic-gate NOT; /* 039 STQF mem address not aligned */ 13757c478bd9Sstevel@tonic-gate NOT; NOT; NOT4; /* 03A - 03F reserved */ 137625cf1a30Sjl LABELED_BAD(tt0_asdat); /* 040 async data error */ 13777c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(1); /* 041 interrupt level 1 */ 13787c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(2); /* 042 interrupt level 2 */ 13797c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(3); /* 043 interrupt level 3 */ 13807c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(4); /* 044 interrupt level 4 */ 13817c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(5); /* 045 interrupt level 5 */ 13827c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(6); /* 046 interrupt level 6 */ 13837c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(7); /* 047 interrupt level 7 */ 13847c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(8); /* 048 interrupt level 8 */ 13857c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(9); /* 049 interrupt level 9 */ 13867c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(10); /* 04A interrupt level 10 */ 13877c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(11); /* 04B interrupt level 11 */ 13887c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(12); /* 04C interrupt level 12 */ 13897c478bd9Sstevel@tonic-gate LEVEL_INTERRUPT(13); /* 04D interrupt level 13 */ 13907c478bd9Sstevel@tonic-gate LEVEL14_INTERRUPT; /* 04E interrupt level 14 */ 1391b9e93c10SJonathan Haslam LEVEL15_INTERRUPT; /* 04F interrupt level 15 */ 13927c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 050 - 05F reserved */ 13937c478bd9Sstevel@tonic-gate VECTOR_INTERRUPT; /* 060 interrupt vector */ 13947c478bd9Sstevel@tonic-gate GOTO(kmdb_trap); /* 061 PA watchpoint */ 13957c478bd9Sstevel@tonic-gate GOTO(kmdb_trap); /* 062 VA watchpoint */ 13967c478bd9Sstevel@tonic-gate GOTO_TT(ce_err, trace_gen); /* 063 corrected ECC error */ 13977c478bd9Sstevel@tonic-gate ITLB_MISS(tt0); /* 064 instruction access MMU miss */ 13987c478bd9Sstevel@tonic-gate DTLB_MISS(tt0); /* 068 data access MMU miss */ 13997c478bd9Sstevel@tonic-gate DTLB_PROT; /* 06C data access protection */ 14007c478bd9Sstevel@tonic-gate LABELED_BAD(tt0_fecc); /* 070 fast ecache ECC error */ 14017c478bd9Sstevel@tonic-gate LABELED_BAD(tt0_dperr); /* 071 Cheetah+ dcache parity error */ 14027c478bd9Sstevel@tonic-gate LABELED_BAD(tt0_iperr); /* 072 Cheetah+ icache parity error */ 14037c478bd9Sstevel@tonic-gate NOT; /* 073 reserved */ 14047c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; /* 074 - 07F reserved */ 14057c478bd9Sstevel@tonic-gate NOT4; /* 080 spill 0 normal */ 14067c478bd9Sstevel@tonic-gate SPILL_32bit_asi(ASI_AIUP,sn0); /* 084 spill 1 normal */ 14077c478bd9Sstevel@tonic-gate SPILL_64bit_asi(ASI_AIUP,sn0); /* 088 spill 2 normal */ 14087c478bd9Sstevel@tonic-gate SPILL_32clean(ASI_AIUP,sn0); /* 08C spill 3 normal */ 14097c478bd9Sstevel@tonic-gate SPILL_64clean(ASI_AIUP,sn0); /* 090 spill 4 normal */ 14107c478bd9Sstevel@tonic-gate SPILL_32bit(not); /* 094 spill 5 normal */ 14117c478bd9Sstevel@tonic-gate SPILL_64bit(not); /* 098 spill 6 normal */ 14127c478bd9Sstevel@tonic-gate SPILL_mixed; /* 09C spill 7 normal */ 14137c478bd9Sstevel@tonic-gate NOT4; /* 0A0 spill 0 other */ 14147c478bd9Sstevel@tonic-gate SPILL_32bit_asi(ASI_AIUS,so0); /* 0A4 spill 1 other */ 14157c478bd9Sstevel@tonic-gate SPILL_64bit_asi(ASI_AIUS,so0); /* 0A8 spill 2 other */ 14167c478bd9Sstevel@tonic-gate SPILL_32bit_asi(ASI_AIUS,so0); /* 0AC spill 3 other */ 14177c478bd9Sstevel@tonic-gate SPILL_64bit_asi(ASI_AIUS,so0); /* 0B0 spill 4 other */ 14187c478bd9Sstevel@tonic-gate NOT4; /* 0B4 spill 5 other */ 14197c478bd9Sstevel@tonic-gate NOT4; /* 0B8 spill 6 other */ 14207c478bd9Sstevel@tonic-gate NOT4; /* 0BC spill 7 other */ 14217c478bd9Sstevel@tonic-gate NOT4; /* 0C0 fill 0 normal */ 14227c478bd9Sstevel@tonic-gate FILL_32bit_asi(ASI_AIUP,fn0); /* 0C4 fill 1 normal */ 14237c478bd9Sstevel@tonic-gate FILL_64bit_asi(ASI_AIUP,fn0); /* 0C8 fill 2 normal */ 14247c478bd9Sstevel@tonic-gate FILL_32bit_asi(ASI_AIUP,fn0); /* 0CC fill 3 normal */ 14257c478bd9Sstevel@tonic-gate FILL_64bit_asi(ASI_AIUP,fn0); /* 0D0 fill 4 normal */ 14267c478bd9Sstevel@tonic-gate FILL_32bit(not); /* 0D4 fill 5 normal */ 14277c478bd9Sstevel@tonic-gate FILL_64bit(not); /* 0D8 fill 6 normal */ 14287c478bd9Sstevel@tonic-gate FILL_mixed; /* 0DC fill 7 normal */ 14297c478bd9Sstevel@tonic-gate NOT4; /* 0E0 fill 0 other */ 14307c478bd9Sstevel@tonic-gate NOT4; /* 0E4 fill 1 other */ 14317c478bd9Sstevel@tonic-gate NOT4; /* 0E8 fill 2 other */ 14327c478bd9Sstevel@tonic-gate NOT4; /* 0EC fill 3 other */ 14337c478bd9Sstevel@tonic-gate NOT4; /* 0F0 fill 4 other */ 14347c478bd9Sstevel@tonic-gate NOT4; /* 0F4 fill 5 other */ 14357c478bd9Sstevel@tonic-gate NOT4; /* 0F8 fill 6 other */ 14367c478bd9Sstevel@tonic-gate NOT4; /* 0FC fill 7 other */ 14377c478bd9Sstevel@tonic-gate /* user traps */ 14387c478bd9Sstevel@tonic-gate GOTO(syscall_trap_4x); /* 100 old system call */ 14397c478bd9Sstevel@tonic-gate TRAP(T_BREAKPOINT); /* 101 user breakpoint */ 14407c478bd9Sstevel@tonic-gate TRAP(T_DIV0); /* 102 user divide by zero */ 144150eff769Smb FLUSHW(tt0_flushw); /* 103 flush windows */ 14427c478bd9Sstevel@tonic-gate GOTO(.clean_windows); /* 104 clean windows */ 14437c478bd9Sstevel@tonic-gate BAD; /* 105 range check ?? */ 14447c478bd9Sstevel@tonic-gate GOTO(.fix_alignment); /* 106 do unaligned references */ 14457c478bd9Sstevel@tonic-gate BAD; /* 107 unused */ 144659f2ff5cSedp SYSCALL_TRAP32; /* 108 ILP32 system call on LP64 */ 14477c478bd9Sstevel@tonic-gate GOTO(set_trap0_addr); /* 109 set trap0 address */ 14487c478bd9Sstevel@tonic-gate BAD; BAD; BAD4; /* 10A - 10F unused */ 14497c478bd9Sstevel@tonic-gate TRP4; TRP4; TRP4; TRP4; /* 110 - 11F V9 user trap handlers */ 14507c478bd9Sstevel@tonic-gate GOTO(.getcc); /* 120 get condition codes */ 14517c478bd9Sstevel@tonic-gate GOTO(.setcc); /* 121 set condition codes */ 14527c478bd9Sstevel@tonic-gate GOTO(.getpsr); /* 122 get psr */ 14537c478bd9Sstevel@tonic-gate GOTO(.setpsr); /* 123 set psr (some fields) */ 14547c478bd9Sstevel@tonic-gate GOTO(get_timestamp); /* 124 get timestamp */ 14557c478bd9Sstevel@tonic-gate GOTO(get_virtime); /* 125 get lwp virtual time */ 14567c478bd9Sstevel@tonic-gate PRIV(self_xcall); /* 126 self xcall */ 14577c478bd9Sstevel@tonic-gate GOTO(get_hrestime); /* 127 get hrestime */ 14587c478bd9Sstevel@tonic-gate BAD; /* 128 ST_SETV9STACK */ 14597c478bd9Sstevel@tonic-gate GOTO(.getlgrp); /* 129 get lgrpid */ 14607c478bd9Sstevel@tonic-gate BAD; BAD; BAD4; /* 12A - 12F unused */ 14617c478bd9Sstevel@tonic-gate BAD4; BAD4; /* 130 - 137 unused */ 14627c478bd9Sstevel@tonic-gate DTRACE_PID; /* 138 dtrace pid tracing provider */ 1463f498645aSahl BAD; /* 139 unused */ 14647c478bd9Sstevel@tonic-gate DTRACE_RETURN; /* 13A dtrace pid return probe */ 14657c478bd9Sstevel@tonic-gate BAD; BAD4; /* 13B - 13F unused */ 146659f2ff5cSedp SYSCALL_TRAP; /* 140 LP64 system call */ 1467af3c157aSrscott SYSCALL(nosys); /* 141 unused system call trap */ 14687c478bd9Sstevel@tonic-gate#ifdef DEBUG_USER_TRAPTRACECTL 14697c478bd9Sstevel@tonic-gate GOTO(.traptrace_freeze); /* 142 freeze traptrace */ 14707c478bd9Sstevel@tonic-gate GOTO(.traptrace_unfreeze); /* 143 unfreeze traptrace */ 14717c478bd9Sstevel@tonic-gate#else 1472af3c157aSrscott SYSCALL(nosys); /* 142 unused system call trap */ 1473af3c157aSrscott SYSCALL(nosys); /* 143 unused system call trap */ 14747c478bd9Sstevel@tonic-gate#endif 14757c478bd9Sstevel@tonic-gate BAD4; BAD4; BAD4; /* 144 - 14F unused */ 14767c478bd9Sstevel@tonic-gate BAD4; BAD4; BAD4; BAD4; /* 150 - 15F unused */ 14777c478bd9Sstevel@tonic-gate BAD4; BAD4; BAD4; BAD4; /* 160 - 16F unused */ 14787c478bd9Sstevel@tonic-gate BAD; /* 170 - unused */ 14797c478bd9Sstevel@tonic-gate BAD; /* 171 - unused */ 14807c478bd9Sstevel@tonic-gate BAD; BAD; /* 172 - 173 unused */ 14817c478bd9Sstevel@tonic-gate BAD4; BAD4; /* 174 - 17B unused */ 14827c478bd9Sstevel@tonic-gate#ifdef PTL1_PANIC_DEBUG 14837c478bd9Sstevel@tonic-gate mov PTL1_BAD_DEBUG, %g1; GOTO(ptl1_panic); 14847c478bd9Sstevel@tonic-gate /* 17C test ptl1_panic */ 14857c478bd9Sstevel@tonic-gate#else 14867c478bd9Sstevel@tonic-gate BAD; /* 17C unused */ 14877c478bd9Sstevel@tonic-gate#endif /* PTL1_PANIC_DEBUG */ 14887c478bd9Sstevel@tonic-gate PRIV(kmdb_trap); /* 17D kmdb enter (L1-A) */ 14897c478bd9Sstevel@tonic-gate PRIV(kmdb_trap); /* 17E kmdb breakpoint */ 14907c478bd9Sstevel@tonic-gate PRIV(kctx_obp_bpt); /* 17F obp breakpoint */ 14917c478bd9Sstevel@tonic-gate /* reserved */ 14927c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 180 - 18F reserved */ 14937c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 190 - 19F reserved */ 14947c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 1A0 - 1AF reserved */ 14957c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 1B0 - 1BF reserved */ 14967c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 1C0 - 1CF reserved */ 14977c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 1D0 - 1DF reserved */ 14987c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 1E0 - 1EF reserved */ 14997c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 1F0 - 1FF reserved */ 15007c478bd9Sstevel@tonic-gatetrap_table1: 15017c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT; NOT; /* 000 - 009 unused */ 150225cf1a30Sjl ASYNC_TRAP(T_INSTR_ERROR + T_TL1, trace_gen, tt1_iae); 15037c478bd9Sstevel@tonic-gate /* 00A instruction access error */ 15047c478bd9Sstevel@tonic-gate NOT; NOT4; /* 00B - 00F unused */ 15057c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 010 - 01F unused */ 15067c478bd9Sstevel@tonic-gate NOT4; /* 020 - 023 unused */ 15077c478bd9Sstevel@tonic-gate CLEAN_WINDOW; /* 024 - 027 clean window */ 15087c478bd9Sstevel@tonic-gate NOT4; NOT4; /* 028 - 02F unused */ 15097c478bd9Sstevel@tonic-gate DMMU_EXCEPTION_TL1; /* 030 data access exception */ 15107c478bd9Sstevel@tonic-gate NOT; /* 031 unused */ 151125cf1a30Sjl ASYNC_TRAP(T_DATA_ERROR + T_TL1, trace_gen, tt1_dae); 15127c478bd9Sstevel@tonic-gate /* 032 data access error */ 15137c478bd9Sstevel@tonic-gate NOT; /* 033 unused */ 15147c478bd9Sstevel@tonic-gate MISALIGN_ADDR_TL1; /* 034 mem address not aligned */ 15157c478bd9Sstevel@tonic-gate NOT; NOT; NOT; NOT4; NOT4 /* 035 - 03F unused */ 151625cf1a30Sjl LABELED_BAD(tt1_asdat); /* 040 async data error */ 151725cf1a30Sjl NOT; NOT; NOT; /* 041 - 043 unused */ 151825cf1a30Sjl NOT4; NOT4; NOT4; /* 044 - 04F unused */ 15197c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 050 - 05F unused */ 15207c478bd9Sstevel@tonic-gate NOT; /* 060 unused */ 15217c478bd9Sstevel@tonic-gate GOTO(kmdb_trap_tl1); /* 061 PA watchpoint */ 15227c478bd9Sstevel@tonic-gate GOTO(kmdb_trap_tl1); /* 062 VA watchpoint */ 15237c478bd9Sstevel@tonic-gate GOTO_TT(ce_err_tl1, trace_gen); /* 063 corrected ECC error */ 15247c478bd9Sstevel@tonic-gate ITLB_MISS(tt1); /* 064 instruction access MMU miss */ 15257c478bd9Sstevel@tonic-gate DTLB_MISS(tt1); /* 068 data access MMU miss */ 15267c478bd9Sstevel@tonic-gate DTLB_PROT; /* 06C data access protection */ 15277c478bd9Sstevel@tonic-gate LABELED_BAD(tt1_fecc); /* 070 fast ecache ECC error */ 15287c478bd9Sstevel@tonic-gate LABELED_BAD(tt1_dperr); /* 071 Cheetah+ dcache parity error */ 15297c478bd9Sstevel@tonic-gate LABELED_BAD(tt1_iperr); /* 072 Cheetah+ icache parity error */ 15307c478bd9Sstevel@tonic-gate NOT; /* 073 reserved */ 15317c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; /* 074 - 07F reserved */ 15327c478bd9Sstevel@tonic-gate NOT4; /* 080 spill 0 normal */ 15337c478bd9Sstevel@tonic-gate SPILL_32bit_tt1(ASI_AIUP,sn1); /* 084 spill 1 normal */ 15347c478bd9Sstevel@tonic-gate SPILL_64bit_tt1(ASI_AIUP,sn1); /* 088 spill 2 normal */ 15357c478bd9Sstevel@tonic-gate SPILL_32bit_tt1(ASI_AIUP,sn1); /* 08C spill 3 normal */ 15367c478bd9Sstevel@tonic-gate SPILL_64bit_tt1(ASI_AIUP,sn1); /* 090 spill 4 normal */ 15377c478bd9Sstevel@tonic-gate SPILL_32bit(not); /* 094 spill 5 normal */ 15387c478bd9Sstevel@tonic-gate SPILL_64bit(not); /* 098 spill 6 normal */ 15397c478bd9Sstevel@tonic-gate SPILL_mixed; /* 09C spill 7 normal */ 15407c478bd9Sstevel@tonic-gate NOT4; /* 0A0 spill 0 other */ 15417c478bd9Sstevel@tonic-gate SPILL_32bit_tt1(ASI_AIUS,so1); /* 0A4 spill 1 other */ 15427c478bd9Sstevel@tonic-gate SPILL_64bit_tt1(ASI_AIUS,so1); /* 0A8 spill 2 other */ 15437c478bd9Sstevel@tonic-gate SPILL_32bit_tt1(ASI_AIUS,so1); /* 0AC spill 3 other */ 15447c478bd9Sstevel@tonic-gate SPILL_64bit_tt1(ASI_AIUS,so1); /* 0B0 spill 4 other */ 15457c478bd9Sstevel@tonic-gate NOT4; /* 0B4 spill 5 other */ 15467c478bd9Sstevel@tonic-gate NOT4; /* 0B8 spill 6 other */ 15477c478bd9Sstevel@tonic-gate NOT4; /* 0BC spill 7 other */ 15487c478bd9Sstevel@tonic-gate NOT4; /* 0C0 fill 0 normal */ 15497c478bd9Sstevel@tonic-gate FILL_32bit_tt1(ASI_AIUP,fn1); /* 0C4 fill 1 normal */ 15507c478bd9Sstevel@tonic-gate FILL_64bit_tt1(ASI_AIUP,fn1); /* 0C8 fill 2 normal */ 15517c478bd9Sstevel@tonic-gate FILL_32bit_tt1(ASI_AIUP,fn1); /* 0CC fill 3 normal */ 15527c478bd9Sstevel@tonic-gate FILL_64bit_tt1(ASI_AIUP,fn1); /* 0D0 fill 4 normal */ 15537c478bd9Sstevel@tonic-gate FILL_32bit(not); /* 0D4 fill 5 normal */ 15547c478bd9Sstevel@tonic-gate FILL_64bit(not); /* 0D8 fill 6 normal */ 15557c478bd9Sstevel@tonic-gate FILL_mixed; /* 0DC fill 7 normal */ 15567c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 0E0 - 0EF unused */ 15577c478bd9Sstevel@tonic-gate NOT4; NOT4; NOT4; NOT4; /* 0F0 - 0FF unused */ 15587c478bd9Sstevel@tonic-gate LABELED_BAD(tt1_swtrap0); /* 100 fast ecache ECC error (cont) */ 15597c478bd9Sstevel@tonic-gate LABELED_BAD(tt1_swtrap1); /* 101 Ch+ D$ parity error (cont) */ 15607c478bd9Sstevel@tonic-gate LABELED_BAD(tt1_swtrap2); /* 102 Ch+ I$ parity error (cont) */ 15617c478bd9Sstevel@tonic-gate NOT; /* 103 reserved */ 15627c478bd9Sstevel@tonic-gate/* 15637c478bd9Sstevel@tonic-gate * We only reserve the above four special case soft traps for code running 15647c478bd9Sstevel@tonic-gate * at TL>0, so we can truncate the trap table here. 15657c478bd9Sstevel@tonic-gate */ 15667c478bd9Sstevel@tonic-gateetrap_table: 15677c478bd9Sstevel@tonic-gate .size trap_table, (.-trap_table) 15687c478bd9Sstevel@tonic-gate .size scb, (.-scb) 15697c478bd9Sstevel@tonic-gate 15707c478bd9Sstevel@tonic-gate/* 15717c478bd9Sstevel@tonic-gate * We get to exec_fault in the case of an instruction miss and tte 15727c478bd9Sstevel@tonic-gate * has no execute bit set. We go to tl0 to handle it. 15737c478bd9Sstevel@tonic-gate * 15747c478bd9Sstevel@tonic-gate * g1 = tsbe pointer (in/clobbered) 15757c478bd9Sstevel@tonic-gate * g2 = tag access register (in) 15767c478bd9Sstevel@tonic-gate * g3 - g4 = scratch (clobbered) 15777c478bd9Sstevel@tonic-gate * g5 = tsbe data (in) 15787c478bd9Sstevel@tonic-gate * g6 = scratch (clobbered) 15797c478bd9Sstevel@tonic-gate */ 15807c478bd9Sstevel@tonic-gate ALTENTRY(exec_fault) 15817c478bd9Sstevel@tonic-gate TRACE_TSBHIT(0x200) 15827c478bd9Sstevel@tonic-gate SWITCH_GLOBALS 15837c478bd9Sstevel@tonic-gate mov MMU_TAG_ACCESS, %g4 15847c478bd9Sstevel@tonic-gate ldxa [%g4]ASI_IMMU, %g2 ! arg1 = addr 15857c478bd9Sstevel@tonic-gate mov T_INSTR_MMU_MISS, %g3 ! arg2 = traptype 15867c478bd9Sstevel@tonic-gate set trap, %g1 15877c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap 15887c478bd9Sstevel@tonic-gate mov -1, %g4 15897c478bd9Sstevel@tonic-gate 15907c478bd9Sstevel@tonic-gate.mmu_exception_not_aligned: 15917c478bd9Sstevel@tonic-gate rdpr %tstate, %g1 15927c478bd9Sstevel@tonic-gate btst TSTATE_PRIV, %g1 15937c478bd9Sstevel@tonic-gate bnz,pn %icc, 2f 15947c478bd9Sstevel@tonic-gate nop 15957c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) ! load CPU struct addr 15967c478bd9Sstevel@tonic-gate ldn [%g1 + CPU_THREAD], %g1 ! load thread pointer 15977c478bd9Sstevel@tonic-gate ldn [%g1 + T_PROCP], %g1 ! load proc pointer 15987c478bd9Sstevel@tonic-gate ldn [%g1 + P_UTRAPS], %g5 ! are there utraps? 15997c478bd9Sstevel@tonic-gate brz,pt %g5, 2f 16007c478bd9Sstevel@tonic-gate nop 16017c478bd9Sstevel@tonic-gate ldn [%g5 + P_UTRAP15], %g5 ! unaligned utrap? 16027c478bd9Sstevel@tonic-gate brz,pn %g5, 2f 16037c478bd9Sstevel@tonic-gate nop 16047c478bd9Sstevel@tonic-gate btst 1, %sp 16057c478bd9Sstevel@tonic-gate bz,pt %xcc, 1f ! 32 bit user program 16067c478bd9Sstevel@tonic-gate nop 16077c478bd9Sstevel@tonic-gate ba,pt %xcc, .setup_v9utrap ! 64 bit user program 16087c478bd9Sstevel@tonic-gate nop 16097c478bd9Sstevel@tonic-gate1: 16107c478bd9Sstevel@tonic-gate ba,pt %xcc, .setup_utrap 16117c478bd9Sstevel@tonic-gate or %g2, %g0, %g7 16127c478bd9Sstevel@tonic-gate2: 16137c478bd9Sstevel@tonic-gate ba,pt %xcc, .mmu_exception_end 16147c478bd9Sstevel@tonic-gate mov T_ALIGNMENT, %g1 16157c478bd9Sstevel@tonic-gate 16167c478bd9Sstevel@tonic-gate.mmu_priv_exception: 16177c478bd9Sstevel@tonic-gate rdpr %tstate, %g1 16187c478bd9Sstevel@tonic-gate btst TSTATE_PRIV, %g1 16197c478bd9Sstevel@tonic-gate bnz,pn %icc, 1f 16207c478bd9Sstevel@tonic-gate nop 16217c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) ! load CPU struct addr 16227c478bd9Sstevel@tonic-gate ldn [%g1 + CPU_THREAD], %g1 ! load thread pointer 16237c478bd9Sstevel@tonic-gate ldn [%g1 + T_PROCP], %g1 ! load proc pointer 16247c478bd9Sstevel@tonic-gate ldn [%g1 + P_UTRAPS], %g5 ! are there utraps? 16257c478bd9Sstevel@tonic-gate brz,pt %g5, 1f 16267c478bd9Sstevel@tonic-gate nop 16277c478bd9Sstevel@tonic-gate ldn [%g5 + P_UTRAP16], %g5 16287c478bd9Sstevel@tonic-gate brnz,pt %g5, .setup_v9utrap 16297c478bd9Sstevel@tonic-gate nop 16307c478bd9Sstevel@tonic-gate1: 16317c478bd9Sstevel@tonic-gate mov T_PRIV_INSTR, %g1 16327c478bd9Sstevel@tonic-gate 16337c478bd9Sstevel@tonic-gate.mmu_exception_end: 16347c478bd9Sstevel@tonic-gate CPU_INDEX(%g4, %g5) 16357c478bd9Sstevel@tonic-gate set cpu_core, %g5 16367c478bd9Sstevel@tonic-gate sllx %g4, CPU_CORE_SHIFT, %g4 16377c478bd9Sstevel@tonic-gate add %g4, %g5, %g4 16387c478bd9Sstevel@tonic-gate lduh [%g4 + CPUC_DTRACE_FLAGS], %g5 16397c478bd9Sstevel@tonic-gate andcc %g5, CPU_DTRACE_NOFAULT, %g0 16407c478bd9Sstevel@tonic-gate bz %xcc, .mmu_exception_tlb_chk 16417c478bd9Sstevel@tonic-gate or %g5, CPU_DTRACE_BADADDR, %g5 16427c478bd9Sstevel@tonic-gate stuh %g5, [%g4 + CPUC_DTRACE_FLAGS] 16437c478bd9Sstevel@tonic-gate done 16447c478bd9Sstevel@tonic-gate 16457c478bd9Sstevel@tonic-gate.mmu_exception_tlb_chk: 16467c478bd9Sstevel@tonic-gate GET_CPU_IMPL(%g5) ! check SFSR.FT to see if this 16477c478bd9Sstevel@tonic-gate cmp %g5, PANTHER_IMPL ! is a TLB parity error. But 16487c478bd9Sstevel@tonic-gate bne 2f ! we only do this check while 16497c478bd9Sstevel@tonic-gate mov 1, %g4 ! running on Panther CPUs 16507c478bd9Sstevel@tonic-gate sllx %g4, PN_SFSR_PARITY_SHIFT, %g4 ! since US-I/II use the same 16517c478bd9Sstevel@tonic-gate andcc %g3, %g4, %g0 ! bit for something else which 16527c478bd9Sstevel@tonic-gate bz 2f ! will be handled later. 16537c478bd9Sstevel@tonic-gate nop 16547c478bd9Sstevel@tonic-gate.mmu_exception_is_tlb_parity: 16557c478bd9Sstevel@tonic-gate .weak itlb_parity_trap 16567c478bd9Sstevel@tonic-gate .weak dtlb_parity_trap 16577c478bd9Sstevel@tonic-gate set itlb_parity_trap, %g4 16587c478bd9Sstevel@tonic-gate cmp %g1, T_INSTR_EXCEPTION ! branch to the itlb or 16597c478bd9Sstevel@tonic-gate be 3f ! dtlb parity handler 16607c478bd9Sstevel@tonic-gate nop ! if this trap is due 16617c478bd9Sstevel@tonic-gate set dtlb_parity_trap, %g4 16627c478bd9Sstevel@tonic-gate cmp %g1, T_DATA_EXCEPTION ! to a IMMU exception 16637c478bd9Sstevel@tonic-gate be 3f ! or DMMU exception. 16644a75c0c1Sedp nop 16657c478bd9Sstevel@tonic-gate2: 16667c478bd9Sstevel@tonic-gate sllx %g3, 32, %g3 16677c478bd9Sstevel@tonic-gate or %g3, %g1, %g3 16687c478bd9Sstevel@tonic-gate set trap, %g1 16697c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap 16707c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 16717c478bd9Sstevel@tonic-gate3: 16727c478bd9Sstevel@tonic-gate jmp %g4 ! off to the appropriate 16737c478bd9Sstevel@tonic-gate nop ! TLB parity handler 16747c478bd9Sstevel@tonic-gate 16757c478bd9Sstevel@tonic-gate.fp_disabled: 16767c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) ! load CPU struct addr 16777c478bd9Sstevel@tonic-gate ldn [%g1 + CPU_THREAD], %g1 ! load thread pointer 16787c478bd9Sstevel@tonic-gate#ifdef SF_ERRATA_30 /* call causes fp-disabled */ 16797c478bd9Sstevel@tonic-gate brz,a,pn %g1, 2f 16807c478bd9Sstevel@tonic-gate nop 16817c478bd9Sstevel@tonic-gate#endif 16827c478bd9Sstevel@tonic-gate rdpr %tstate, %g4 16837c478bd9Sstevel@tonic-gate btst TSTATE_PRIV, %g4 16847c478bd9Sstevel@tonic-gate#ifdef SF_ERRATA_30 /* call causes fp-disabled */ 16857c478bd9Sstevel@tonic-gate bnz,pn %icc, 2f 16867c478bd9Sstevel@tonic-gate nop 16877c478bd9Sstevel@tonic-gate#else 16887c478bd9Sstevel@tonic-gate bnz,a,pn %icc, ptl1_panic 16897c478bd9Sstevel@tonic-gate mov PTL1_BAD_FPTRAP, %g1 16907c478bd9Sstevel@tonic-gate#endif 16917c478bd9Sstevel@tonic-gate ldn [%g1 + T_PROCP], %g1 ! load proc pointer 16927c478bd9Sstevel@tonic-gate ldn [%g1 + P_UTRAPS], %g5 ! are there utraps? 16937c478bd9Sstevel@tonic-gate brz,a,pt %g5, 2f 16947c478bd9Sstevel@tonic-gate nop 16957c478bd9Sstevel@tonic-gate ldn [%g5 + P_UTRAP7], %g5 ! fp_disabled utrap? 16967c478bd9Sstevel@tonic-gate brz,a,pn %g5, 2f 16977c478bd9Sstevel@tonic-gate nop 16987c478bd9Sstevel@tonic-gate btst 1, %sp 16997c478bd9Sstevel@tonic-gate bz,a,pt %xcc, 1f ! 32 bit user program 17007c478bd9Sstevel@tonic-gate nop 17017c478bd9Sstevel@tonic-gate ba,a,pt %xcc, .setup_v9utrap ! 64 bit user program 17027c478bd9Sstevel@tonic-gate nop 17037c478bd9Sstevel@tonic-gate1: 17047c478bd9Sstevel@tonic-gate ba,pt %xcc, .setup_utrap 17057c478bd9Sstevel@tonic-gate or %g0, %g0, %g7 17067c478bd9Sstevel@tonic-gate2: 17077c478bd9Sstevel@tonic-gate set fp_disabled, %g1 17087c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap 17097c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 17107c478bd9Sstevel@tonic-gate 17117c478bd9Sstevel@tonic-gate.fp_ieee_exception: 17127c478bd9Sstevel@tonic-gate rdpr %tstate, %g1 17137c478bd9Sstevel@tonic-gate btst TSTATE_PRIV, %g1 17147c478bd9Sstevel@tonic-gate bnz,a,pn %icc, ptl1_panic 17157c478bd9Sstevel@tonic-gate mov PTL1_BAD_FPTRAP, %g1 17167c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) ! load CPU struct addr 17177c478bd9Sstevel@tonic-gate stx %fsr, [%g1 + CPU_TMP1] 17187c478bd9Sstevel@tonic-gate ldx [%g1 + CPU_TMP1], %g2 17197c478bd9Sstevel@tonic-gate ldn [%g1 + CPU_THREAD], %g1 ! load thread pointer 17207c478bd9Sstevel@tonic-gate ldn [%g1 + T_PROCP], %g1 ! load proc pointer 17217c478bd9Sstevel@tonic-gate ldn [%g1 + P_UTRAPS], %g5 ! are there utraps? 17227c478bd9Sstevel@tonic-gate brz,a,pt %g5, 1f 17237c478bd9Sstevel@tonic-gate nop 17247c478bd9Sstevel@tonic-gate ldn [%g5 + P_UTRAP8], %g5 17257c478bd9Sstevel@tonic-gate brnz,a,pt %g5, .setup_v9utrap 17267c478bd9Sstevel@tonic-gate nop 17277c478bd9Sstevel@tonic-gate1: 17287c478bd9Sstevel@tonic-gate set _fp_ieee_exception, %g1 17297c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap 17307c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 17317c478bd9Sstevel@tonic-gate 17327c478bd9Sstevel@tonic-gate/* 17337c478bd9Sstevel@tonic-gate * Register Inputs: 17347c478bd9Sstevel@tonic-gate * %g5 user trap handler 17357c478bd9Sstevel@tonic-gate * %g7 misaligned addr - for alignment traps only 17367c478bd9Sstevel@tonic-gate */ 17377c478bd9Sstevel@tonic-gate.setup_utrap: 17387c478bd9Sstevel@tonic-gate set trap, %g1 ! setup in case we go 17397c478bd9Sstevel@tonic-gate mov T_FLUSH_PCB, %g3 ! through sys_trap on 17407c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 ! the save instruction below 17417c478bd9Sstevel@tonic-gate 17427c478bd9Sstevel@tonic-gate /* 17437c478bd9Sstevel@tonic-gate * If the DTrace pid provider is single stepping a copied-out 17447c478bd9Sstevel@tonic-gate * instruction, t->t_dtrace_step will be set. In that case we need 17457c478bd9Sstevel@tonic-gate * to abort the single-stepping (since execution of the instruction 17467c478bd9Sstevel@tonic-gate * was interrupted) and use the value of t->t_dtrace_npc as the %npc. 17477c478bd9Sstevel@tonic-gate */ 17487c478bd9Sstevel@tonic-gate save %sp, -SA(MINFRAME32), %sp ! window for trap handler 17497c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) ! load CPU struct addr 17507c478bd9Sstevel@tonic-gate ldn [%g1 + CPU_THREAD], %g1 ! load thread pointer 17517c478bd9Sstevel@tonic-gate ldub [%g1 + T_DTRACE_STEP], %g2 ! load t->t_dtrace_step 17527c478bd9Sstevel@tonic-gate rdpr %tnpc, %l2 ! arg1 == tnpc 17537c478bd9Sstevel@tonic-gate brz,pt %g2, 1f 17547c478bd9Sstevel@tonic-gate rdpr %tpc, %l1 ! arg0 == tpc 17557c478bd9Sstevel@tonic-gate 17567c478bd9Sstevel@tonic-gate ldub [%g1 + T_DTRACE_AST], %g2 ! load t->t_dtrace_ast 17577c478bd9Sstevel@tonic-gate ldn [%g1 + T_DTRACE_NPC], %l2 ! arg1 = t->t_dtrace_npc (step) 17587c478bd9Sstevel@tonic-gate brz,pt %g2, 1f 17597c478bd9Sstevel@tonic-gate st %g0, [%g1 + T_DTRACE_FT] ! zero all pid provider flags 17607c478bd9Sstevel@tonic-gate stub %g2, [%g1 + T_ASTFLAG] ! aston(t) if t->t_dtrace_ast 17617c478bd9Sstevel@tonic-gate1: 17627c478bd9Sstevel@tonic-gate mov %g7, %l3 ! arg2 == misaligned address 17637c478bd9Sstevel@tonic-gate 17647c478bd9Sstevel@tonic-gate rdpr %tstate, %g1 ! cwp for trap handler 17657c478bd9Sstevel@tonic-gate rdpr %cwp, %g4 17667c478bd9Sstevel@tonic-gate bclr TSTATE_CWP_MASK, %g1 17677c478bd9Sstevel@tonic-gate wrpr %g1, %g4, %tstate 17687c478bd9Sstevel@tonic-gate wrpr %g0, %g5, %tnpc ! trap handler address 17697c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 17707c478bd9Sstevel@tonic-gate /* NOTREACHED */ 17717c478bd9Sstevel@tonic-gate 17727c478bd9Sstevel@tonic-gate.check_v9utrap: 17737c478bd9Sstevel@tonic-gate rdpr %tstate, %g1 17747c478bd9Sstevel@tonic-gate btst TSTATE_PRIV, %g1 17757c478bd9Sstevel@tonic-gate bnz,a,pn %icc, 3f 17767c478bd9Sstevel@tonic-gate nop 17777c478bd9Sstevel@tonic-gate CPU_ADDR(%g4, %g1) ! load CPU struct addr 17787c478bd9Sstevel@tonic-gate ldn [%g4 + CPU_THREAD], %g5 ! load thread pointer 17797c478bd9Sstevel@tonic-gate ldn [%g5 + T_PROCP], %g5 ! load proc pointer 17807c478bd9Sstevel@tonic-gate ldn [%g5 + P_UTRAPS], %g5 ! are there utraps? 17817c478bd9Sstevel@tonic-gate 17827c478bd9Sstevel@tonic-gate cmp %g3, T_SOFTWARE_TRAP 17837c478bd9Sstevel@tonic-gate bne,a,pt %icc, 1f 17847c478bd9Sstevel@tonic-gate nop 17857c478bd9Sstevel@tonic-gate 17867c478bd9Sstevel@tonic-gate brz,pt %g5, 3f ! if p_utraps == NULL goto trap() 17877c478bd9Sstevel@tonic-gate rdpr %tt, %g3 ! delay - get actual hw trap type 17884a75c0c1Sedp 17897c478bd9Sstevel@tonic-gate sub %g3, 254, %g1 ! UT_TRAP_INSTRUCTION_16 = p_utraps[18] 17907c478bd9Sstevel@tonic-gate ba,pt %icc, 2f 17917c478bd9Sstevel@tonic-gate smul %g1, CPTRSIZE, %g2 17927c478bd9Sstevel@tonic-gate1: 17937c478bd9Sstevel@tonic-gate brz,a,pt %g5, 3f ! if p_utraps == NULL goto trap() 17947c478bd9Sstevel@tonic-gate nop 17957c478bd9Sstevel@tonic-gate 17967c478bd9Sstevel@tonic-gate cmp %g3, T_UNIMP_INSTR 17977c478bd9Sstevel@tonic-gate bne,a,pt %icc, 2f 17987c478bd9Sstevel@tonic-gate nop 17997c478bd9Sstevel@tonic-gate 18007c478bd9Sstevel@tonic-gate mov 1, %g1 18017c478bd9Sstevel@tonic-gate st %g1, [%g4 + CPU_TL1_HDLR] ! set CPU_TL1_HDLR 18024a75c0c1Sedp rdpr %tpc, %g1 ! ld trapping instruction using 18037c478bd9Sstevel@tonic-gate lduwa [%g1]ASI_AIUP, %g1 ! "AS IF USER" ASI which could fault 18047c478bd9Sstevel@tonic-gate st %g0, [%g4 + CPU_TL1_HDLR] ! clr CPU_TL1_HDLR 18057c478bd9Sstevel@tonic-gate 18067c478bd9Sstevel@tonic-gate sethi %hi(0xc1c00000), %g4 ! setup mask for illtrap instruction 18077c478bd9Sstevel@tonic-gate andcc %g1, %g4, %g4 ! and instruction with mask 18087c478bd9Sstevel@tonic-gate bnz,a,pt %icc, 3f ! if %g4 == zero, %g1 is an ILLTRAP 18097c478bd9Sstevel@tonic-gate nop ! fall thru to setup 18104a75c0c1Sedp2: 18117c478bd9Sstevel@tonic-gate ldn [%g5 + %g2], %g5 18127c478bd9Sstevel@tonic-gate brnz,a,pt %g5, .setup_v9utrap 18137c478bd9Sstevel@tonic-gate nop 18147c478bd9Sstevel@tonic-gate3: 18157c478bd9Sstevel@tonic-gate set trap, %g1 18167c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap 18177c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 18187c478bd9Sstevel@tonic-gate /* NOTREACHED */ 18197c478bd9Sstevel@tonic-gate 18207c478bd9Sstevel@tonic-gate/* 18217c478bd9Sstevel@tonic-gate * Register Inputs: 18227c478bd9Sstevel@tonic-gate * %g5 user trap handler 18237c478bd9Sstevel@tonic-gate */ 18247c478bd9Sstevel@tonic-gate.setup_v9utrap: 18257c478bd9Sstevel@tonic-gate set trap, %g1 ! setup in case we go 18267c478bd9Sstevel@tonic-gate mov T_FLUSH_PCB, %g3 ! through sys_trap on 18277c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 ! the save instruction below 18287c478bd9Sstevel@tonic-gate 18297c478bd9Sstevel@tonic-gate /* 18307c478bd9Sstevel@tonic-gate * If the DTrace pid provider is single stepping a copied-out 18317c478bd9Sstevel@tonic-gate * instruction, t->t_dtrace_step will be set. In that case we need 18327c478bd9Sstevel@tonic-gate * to abort the single-stepping (since execution of the instruction 18337c478bd9Sstevel@tonic-gate * was interrupted) and use the value of t->t_dtrace_npc as the %npc. 18347c478bd9Sstevel@tonic-gate */ 18357c478bd9Sstevel@tonic-gate save %sp, -SA(MINFRAME64), %sp ! window for trap handler 18367c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) ! load CPU struct addr 18377c478bd9Sstevel@tonic-gate ldn [%g1 + CPU_THREAD], %g1 ! load thread pointer 18387c478bd9Sstevel@tonic-gate ldub [%g1 + T_DTRACE_STEP], %g2 ! load t->t_dtrace_step 18397c478bd9Sstevel@tonic-gate rdpr %tnpc, %l7 ! arg1 == tnpc 18407c478bd9Sstevel@tonic-gate brz,pt %g2, 1f 18417c478bd9Sstevel@tonic-gate rdpr %tpc, %l6 ! arg0 == tpc 18427c478bd9Sstevel@tonic-gate 18437c478bd9Sstevel@tonic-gate ldub [%g1 + T_DTRACE_AST], %g2 ! load t->t_dtrace_ast 18447c478bd9Sstevel@tonic-gate ldn [%g1 + T_DTRACE_NPC], %l7 ! arg1 == t->t_dtrace_npc (step) 18457c478bd9Sstevel@tonic-gate brz,pt %g2, 1f 18467c478bd9Sstevel@tonic-gate st %g0, [%g1 + T_DTRACE_FT] ! zero all pid provider flags 18477c478bd9Sstevel@tonic-gate stub %g2, [%g1 + T_ASTFLAG] ! aston(t) if t->t_dtrace_ast 18487c478bd9Sstevel@tonic-gate1: 18497c478bd9Sstevel@tonic-gate rdpr %tstate, %g2 ! cwp for trap handler 18507c478bd9Sstevel@tonic-gate rdpr %cwp, %g4 18517c478bd9Sstevel@tonic-gate bclr TSTATE_CWP_MASK, %g2 18527c478bd9Sstevel@tonic-gate wrpr %g2, %g4, %tstate 18537c478bd9Sstevel@tonic-gate 18547c478bd9Sstevel@tonic-gate ldn [%g1 + T_PROCP], %g4 ! load proc pointer 18557c478bd9Sstevel@tonic-gate ldn [%g4 + P_AS], %g4 ! load as pointer 18567c478bd9Sstevel@tonic-gate ldn [%g4 + A_USERLIMIT], %g4 ! load as userlimit 18577c478bd9Sstevel@tonic-gate cmp %l7, %g4 ! check for single-step set 18587c478bd9Sstevel@tonic-gate bne,pt %xcc, 4f 18597c478bd9Sstevel@tonic-gate nop 18607c478bd9Sstevel@tonic-gate ldn [%g1 + T_LWP], %g1 ! load klwp pointer 18617c478bd9Sstevel@tonic-gate ld [%g1 + PCB_STEP], %g4 ! load single-step flag 18627c478bd9Sstevel@tonic-gate cmp %g4, STEP_ACTIVE ! step flags set in pcb? 18637c478bd9Sstevel@tonic-gate bne,pt %icc, 4f 18647c478bd9Sstevel@tonic-gate nop 18657c478bd9Sstevel@tonic-gate stn %g5, [%g1 + PCB_TRACEPC] ! save trap handler addr in pcb 18667c478bd9Sstevel@tonic-gate mov %l7, %g4 ! on entry to precise user trap 18677c478bd9Sstevel@tonic-gate add %l6, 4, %l7 ! handler, %l6 == pc, %l7 == npc 18687c478bd9Sstevel@tonic-gate ! at time of trap 18697c478bd9Sstevel@tonic-gate wrpr %g0, %g4, %tnpc ! generate FLTBOUNDS, 18707c478bd9Sstevel@tonic-gate ! %g4 == userlimit 18717c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 18727c478bd9Sstevel@tonic-gate /* NOTREACHED */ 18737c478bd9Sstevel@tonic-gate4: 18747c478bd9Sstevel@tonic-gate wrpr %g0, %g5, %tnpc ! trap handler address 18757c478bd9Sstevel@tonic-gate FAST_TRAP_DONE_CHK_INTR 18767c478bd9Sstevel@tonic-gate /* NOTREACHED */ 18777c478bd9Sstevel@tonic-gate 18787c478bd9Sstevel@tonic-gate.fp_exception: 18797c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) 18807c478bd9Sstevel@tonic-gate stx %fsr, [%g1 + CPU_TMP1] 18817c478bd9Sstevel@tonic-gate ldx [%g1 + CPU_TMP1], %g2 18827c478bd9Sstevel@tonic-gate 18837c478bd9Sstevel@tonic-gate /* 18847c478bd9Sstevel@tonic-gate * Cheetah takes unfinished_FPop trap for certain range of operands 18857c478bd9Sstevel@tonic-gate * to the "fitos" instruction. Instead of going through the slow 18867c478bd9Sstevel@tonic-gate * software emulation path, we try to simulate the "fitos" instruction 18877c478bd9Sstevel@tonic-gate * via "fitod" and "fdtos" provided the following conditions are met: 18887c478bd9Sstevel@tonic-gate * 18897c478bd9Sstevel@tonic-gate * fpu_exists is set (if DEBUG) 18907c478bd9Sstevel@tonic-gate * not in privileged mode 18917c478bd9Sstevel@tonic-gate * ftt is unfinished_FPop 18927c478bd9Sstevel@tonic-gate * NXM IEEE trap is not enabled 18937c478bd9Sstevel@tonic-gate * instruction at %tpc is "fitos" 18947c478bd9Sstevel@tonic-gate * 18957c478bd9Sstevel@tonic-gate * Usage: 18967c478bd9Sstevel@tonic-gate * %g1 per cpu address 18977c478bd9Sstevel@tonic-gate * %g2 %fsr 18987c478bd9Sstevel@tonic-gate * %g6 user instruction 18997c478bd9Sstevel@tonic-gate * 19007c478bd9Sstevel@tonic-gate * Note that we can take a memory access related trap while trying 19017c478bd9Sstevel@tonic-gate * to fetch the user instruction. Therefore, we set CPU_TL1_HDLR 19027c478bd9Sstevel@tonic-gate * flag to catch those traps and let the SFMMU code deal with page 19037c478bd9Sstevel@tonic-gate * fault and data access exception. 19047c478bd9Sstevel@tonic-gate */ 19057c478bd9Sstevel@tonic-gate#if defined(DEBUG) || defined(NEED_FPU_EXISTS) 19067c478bd9Sstevel@tonic-gate sethi %hi(fpu_exists), %g7 19077c478bd9Sstevel@tonic-gate ld [%g7 + %lo(fpu_exists)], %g7 19087c478bd9Sstevel@tonic-gate brz,pn %g7, .fp_exception_cont 19097c478bd9Sstevel@tonic-gate nop 19107c478bd9Sstevel@tonic-gate#endif 19117c478bd9Sstevel@tonic-gate rdpr %tstate, %g7 ! branch if in privileged mode 19127c478bd9Sstevel@tonic-gate btst TSTATE_PRIV, %g7 19137c478bd9Sstevel@tonic-gate bnz,pn %xcc, .fp_exception_cont 19147c478bd9Sstevel@tonic-gate srl %g2, FSR_FTT_SHIFT, %g7 ! extract ftt from %fsr 19157c478bd9Sstevel@tonic-gate and %g7, (FSR_FTT>>FSR_FTT_SHIFT), %g7 19167c478bd9Sstevel@tonic-gate cmp %g7, FTT_UNFIN 19174a75c0c1Sedp set FSR_TEM_NX, %g5 19187c478bd9Sstevel@tonic-gate bne,pn %xcc, .fp_exception_cont ! branch if NOT unfinished_FPop 19197c478bd9Sstevel@tonic-gate andcc %g2, %g5, %g0 19207c478bd9Sstevel@tonic-gate bne,pn %xcc, .fp_exception_cont ! branch if FSR_TEM_NX enabled 19217c478bd9Sstevel@tonic-gate rdpr %tpc, %g5 ! get faulting PC 19227c478bd9Sstevel@tonic-gate 19237c478bd9Sstevel@tonic-gate or %g0, 1, %g7 19247c478bd9Sstevel@tonic-gate st %g7, [%g1 + CPU_TL1_HDLR] ! set tl1_hdlr flag 19257c478bd9Sstevel@tonic-gate lda [%g5]ASI_USER, %g6 ! get user's instruction 19267c478bd9Sstevel@tonic-gate st %g0, [%g1 + CPU_TL1_HDLR] ! clear tl1_hdlr flag 19277c478bd9Sstevel@tonic-gate 19287c478bd9Sstevel@tonic-gate set FITOS_INSTR_MASK, %g7 19297c478bd9Sstevel@tonic-gate and %g6, %g7, %g7 19307c478bd9Sstevel@tonic-gate set FITOS_INSTR, %g5 19317c478bd9Sstevel@tonic-gate cmp %g7, %g5 19327c478bd9Sstevel@tonic-gate bne,pn %xcc, .fp_exception_cont ! branch if not FITOS_INSTR 19337c478bd9Sstevel@tonic-gate nop 19347c478bd9Sstevel@tonic-gate 19357c478bd9Sstevel@tonic-gate /* 19367c478bd9Sstevel@tonic-gate * This is unfinished FPops trap for "fitos" instruction. We 19377c478bd9Sstevel@tonic-gate * need to simulate "fitos" via "fitod" and "fdtos" instruction 19387c478bd9Sstevel@tonic-gate * sequence. 19397c478bd9Sstevel@tonic-gate * 19407c478bd9Sstevel@tonic-gate * We need a temporary FP register to do the conversion. Since 19417c478bd9Sstevel@tonic-gate * both source and destination operands for the "fitos" instruction 19427c478bd9Sstevel@tonic-gate * have to be within %f0-%f31, we use an FP register from the upper 19437c478bd9Sstevel@tonic-gate * half to guarantee that it won't collide with the source or the 19447c478bd9Sstevel@tonic-gate * dest operand. However, we do have to save and restore its value. 19457c478bd9Sstevel@tonic-gate * 19467c478bd9Sstevel@tonic-gate * We use %d62 as a temporary FP register for the conversion and 19477c478bd9Sstevel@tonic-gate * branch to appropriate instruction within the conversion tables 19487c478bd9Sstevel@tonic-gate * based upon the rs2 and rd values. 19497c478bd9Sstevel@tonic-gate */ 19507c478bd9Sstevel@tonic-gate 19517c478bd9Sstevel@tonic-gate std %d62, [%g1 + CPU_TMP1] ! save original value 19527c478bd9Sstevel@tonic-gate 19537c478bd9Sstevel@tonic-gate srl %g6, FITOS_RS2_SHIFT, %g7 19547c478bd9Sstevel@tonic-gate and %g7, FITOS_REG_MASK, %g7 19557c478bd9Sstevel@tonic-gate set _fitos_fitod_table, %g4 19567c478bd9Sstevel@tonic-gate sllx %g7, 2, %g7 19577c478bd9Sstevel@tonic-gate jmp %g4 + %g7 19587c478bd9Sstevel@tonic-gate ba,pt %xcc, _fitos_fitod_done 19597c478bd9Sstevel@tonic-gate .empty 19607c478bd9Sstevel@tonic-gate 19617c478bd9Sstevel@tonic-gate_fitos_fitod_table: 19627c478bd9Sstevel@tonic-gate fitod %f0, %d62 19637c478bd9Sstevel@tonic-gate fitod %f1, %d62 19647c478bd9Sstevel@tonic-gate fitod %f2, %d62 19657c478bd9Sstevel@tonic-gate fitod %f3, %d62 19667c478bd9Sstevel@tonic-gate fitod %f4, %d62 19677c478bd9Sstevel@tonic-gate fitod %f5, %d62 19687c478bd9Sstevel@tonic-gate fitod %f6, %d62 19697c478bd9Sstevel@tonic-gate fitod %f7, %d62 19707c478bd9Sstevel@tonic-gate fitod %f8, %d62 19717c478bd9Sstevel@tonic-gate fitod %f9, %d62 19727c478bd9Sstevel@tonic-gate fitod %f10, %d62 19737c478bd9Sstevel@tonic-gate fitod %f11, %d62 19747c478bd9Sstevel@tonic-gate fitod %f12, %d62 19757c478bd9Sstevel@tonic-gate fitod %f13, %d62 19767c478bd9Sstevel@tonic-gate fitod %f14, %d62 19777c478bd9Sstevel@tonic-gate fitod %f15, %d62 19787c478bd9Sstevel@tonic-gate fitod %f16, %d62 19797c478bd9Sstevel@tonic-gate fitod %f17, %d62 19807c478bd9Sstevel@tonic-gate fitod %f18, %d62 19817c478bd9Sstevel@tonic-gate fitod %f19, %d62 19827c478bd9Sstevel@tonic-gate fitod %f20, %d62 19837c478bd9Sstevel@tonic-gate fitod %f21, %d62 19847c478bd9Sstevel@tonic-gate fitod %f22, %d62 19857c478bd9Sstevel@tonic-gate fitod %f23, %d62 19867c478bd9Sstevel@tonic-gate fitod %f24, %d62 19877c478bd9Sstevel@tonic-gate fitod %f25, %d62 19887c478bd9Sstevel@tonic-gate fitod %f26, %d62 19897c478bd9Sstevel@tonic-gate fitod %f27, %d62 19907c478bd9Sstevel@tonic-gate fitod %f28, %d62 19917c478bd9Sstevel@tonic-gate fitod %f29, %d62 19927c478bd9Sstevel@tonic-gate fitod %f30, %d62 19937c478bd9Sstevel@tonic-gate fitod %f31, %d62 19947c478bd9Sstevel@tonic-gate_fitos_fitod_done: 19957c478bd9Sstevel@tonic-gate 19967c478bd9Sstevel@tonic-gate /* 19977c478bd9Sstevel@tonic-gate * Now convert data back into single precision 19987c478bd9Sstevel@tonic-gate */ 19997c478bd9Sstevel@tonic-gate srl %g6, FITOS_RD_SHIFT, %g7 20007c478bd9Sstevel@tonic-gate and %g7, FITOS_REG_MASK, %g7 20017c478bd9Sstevel@tonic-gate set _fitos_fdtos_table, %g4 20027c478bd9Sstevel@tonic-gate sllx %g7, 2, %g7 20037c478bd9Sstevel@tonic-gate jmp %g4 + %g7 20047c478bd9Sstevel@tonic-gate ba,pt %xcc, _fitos_fdtos_done 20057c478bd9Sstevel@tonic-gate .empty 20067c478bd9Sstevel@tonic-gate 20077c478bd9Sstevel@tonic-gate_fitos_fdtos_table: 20087c478bd9Sstevel@tonic-gate fdtos %d62, %f0 20097c478bd9Sstevel@tonic-gate fdtos %d62, %f1 20107c478bd9Sstevel@tonic-gate fdtos %d62, %f2 20117c478bd9Sstevel@tonic-gate fdtos %d62, %f3 20127c478bd9Sstevel@tonic-gate fdtos %d62, %f4 20137c478bd9Sstevel@tonic-gate fdtos %d62, %f5 20147c478bd9Sstevel@tonic-gate fdtos %d62, %f6 20157c478bd9Sstevel@tonic-gate fdtos %d62, %f7 20167c478bd9Sstevel@tonic-gate fdtos %d62, %f8 20177c478bd9Sstevel@tonic-gate fdtos %d62, %f9 20187c478bd9Sstevel@tonic-gate fdtos %d62, %f10 20197c478bd9Sstevel@tonic-gate fdtos %d62, %f11 20207c478bd9Sstevel@tonic-gate fdtos %d62, %f12 20217c478bd9Sstevel@tonic-gate fdtos %d62, %f13 20227c478bd9Sstevel@tonic-gate fdtos %d62, %f14 20237c478bd9Sstevel@tonic-gate fdtos %d62, %f15 20247c478bd9Sstevel@tonic-gate fdtos %d62, %f16 20257c478bd9Sstevel@tonic-gate fdtos %d62, %f17 20267c478bd9Sstevel@tonic-gate fdtos %d62, %f18 20277c478bd9Sstevel@tonic-gate fdtos %d62, %f19 20287c478bd9Sstevel@tonic-gate fdtos %d62, %f20 20297c478bd9Sstevel@tonic-gate fdtos %d62, %f21 20307c478bd9Sstevel@tonic-gate fdtos %d62, %f22 20317c478bd9Sstevel@tonic-gate fdtos %d62, %f23 20327c478bd9Sstevel@tonic-gate fdtos %d62, %f24 20337c478bd9Sstevel@tonic-gate fdtos %d62, %f25 20347c478bd9Sstevel@tonic-gate fdtos %d62, %f26 20357c478bd9Sstevel@tonic-gate fdtos %d62, %f27 20367c478bd9Sstevel@tonic-gate fdtos %d62, %f28 20377c478bd9Sstevel@tonic-gate fdtos %d62, %f29 20387c478bd9Sstevel@tonic-gate fdtos %d62, %f30 20397c478bd9Sstevel@tonic-gate fdtos %d62, %f31 20407c478bd9Sstevel@tonic-gate_fitos_fdtos_done: 20417c478bd9Sstevel@tonic-gate 20427c478bd9Sstevel@tonic-gate ldd [%g1 + CPU_TMP1], %d62 ! restore %d62 20437c478bd9Sstevel@tonic-gate 20447c478bd9Sstevel@tonic-gate#if DEBUG 20457c478bd9Sstevel@tonic-gate /* 20467c478bd9Sstevel@tonic-gate * Update FPop_unfinished trap kstat 20477c478bd9Sstevel@tonic-gate */ 20487c478bd9Sstevel@tonic-gate set fpustat+FPUSTAT_UNFIN_KSTAT, %g7 20497c478bd9Sstevel@tonic-gate ldx [%g7], %g5 20507c478bd9Sstevel@tonic-gate1: 20517c478bd9Sstevel@tonic-gate add %g5, 1, %g6 20524a75c0c1Sedp 20537c478bd9Sstevel@tonic-gate casxa [%g7] ASI_N, %g5, %g6 20547c478bd9Sstevel@tonic-gate cmp %g5, %g6 20557c478bd9Sstevel@tonic-gate bne,a,pn %xcc, 1b 20567c478bd9Sstevel@tonic-gate or %g0, %g6, %g5 20577c478bd9Sstevel@tonic-gate 20587c478bd9Sstevel@tonic-gate /* 20597c478bd9Sstevel@tonic-gate * Update fpu_sim_fitos kstat 20607c478bd9Sstevel@tonic-gate */ 20617c478bd9Sstevel@tonic-gate set fpuinfo+FPUINFO_FITOS_KSTAT, %g7 20627c478bd9Sstevel@tonic-gate ldx [%g7], %g5 20637c478bd9Sstevel@tonic-gate1: 20647c478bd9Sstevel@tonic-gate add %g5, 1, %g6 20657c478bd9Sstevel@tonic-gate 20667c478bd9Sstevel@tonic-gate casxa [%g7] ASI_N, %g5, %g6 20677c478bd9Sstevel@tonic-gate cmp %g5, %g6 20687c478bd9Sstevel@tonic-gate bne,a,pn %xcc, 1b 20697c478bd9Sstevel@tonic-gate or %g0, %g6, %g5 20707c478bd9Sstevel@tonic-gate#endif /* DEBUG */ 20717c478bd9Sstevel@tonic-gate 20727c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 20737c478bd9Sstevel@tonic-gate 20747c478bd9Sstevel@tonic-gate.fp_exception_cont: 20757c478bd9Sstevel@tonic-gate /* 20767c478bd9Sstevel@tonic-gate * Let _fp_exception deal with simulating FPop instruction. 20777c478bd9Sstevel@tonic-gate * Note that we need to pass %fsr in %g2 (already read above). 20787c478bd9Sstevel@tonic-gate */ 20797c478bd9Sstevel@tonic-gate 20807c478bd9Sstevel@tonic-gate set _fp_exception, %g1 20817c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap 20827c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 20837c478bd9Sstevel@tonic-gate 208450eff769Smb .global opl_cleanw_patch 208550eff769Smbopl_cleanw_patch: 20867c478bd9Sstevel@tonic-gate.clean_windows: 20877c478bd9Sstevel@tonic-gate set trap, %g1 20887c478bd9Sstevel@tonic-gate mov T_FLUSH_PCB, %g3 20897c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 20907c478bd9Sstevel@tonic-gate save 20917c478bd9Sstevel@tonic-gate flushw 20927c478bd9Sstevel@tonic-gate restore 20937c478bd9Sstevel@tonic-gate wrpr %g0, %g0, %cleanwin ! no clean windows 20947c478bd9Sstevel@tonic-gate 20957c478bd9Sstevel@tonic-gate CPU_ADDR(%g4, %g5) 20967c478bd9Sstevel@tonic-gate ldn [%g4 + CPU_MPCB], %g4 20977c478bd9Sstevel@tonic-gate brz,a,pn %g4, 1f 20987c478bd9Sstevel@tonic-gate nop 20997c478bd9Sstevel@tonic-gate ld [%g4 + MPCB_WSTATE], %g5 21007c478bd9Sstevel@tonic-gate add %g5, WSTATE_CLEAN_OFFSET, %g5 21017c478bd9Sstevel@tonic-gate wrpr %g0, %g5, %wstate 21027c478bd9Sstevel@tonic-gate1: FAST_TRAP_DONE 21037c478bd9Sstevel@tonic-gate 21047c478bd9Sstevel@tonic-gate/* 21057c478bd9Sstevel@tonic-gate * .spill_clean: clean the previous window, restore the wstate, and 21067c478bd9Sstevel@tonic-gate * "done". 21077c478bd9Sstevel@tonic-gate * 21087c478bd9Sstevel@tonic-gate * Entry: %g7 contains new wstate 21097c478bd9Sstevel@tonic-gate */ 21107c478bd9Sstevel@tonic-gate.spill_clean: 21117c478bd9Sstevel@tonic-gate sethi %hi(nwin_minus_one), %g5 21127c478bd9Sstevel@tonic-gate ld [%g5 + %lo(nwin_minus_one)], %g5 ! %g5 = nwin - 1 21137c478bd9Sstevel@tonic-gate rdpr %cwp, %g6 ! %g6 = %cwp 21147c478bd9Sstevel@tonic-gate deccc %g6 ! %g6-- 21157c478bd9Sstevel@tonic-gate movneg %xcc, %g5, %g6 ! if (%g6<0) %g6 = nwin-1 21167c478bd9Sstevel@tonic-gate wrpr %g6, %cwp 21177c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) 21187c478bd9Sstevel@tonic-gate clr %l0 21197c478bd9Sstevel@tonic-gate clr %l1 21207c478bd9Sstevel@tonic-gate clr %l2 21217c478bd9Sstevel@tonic-gate clr %l3 21227c478bd9Sstevel@tonic-gate clr %l4 21237c478bd9Sstevel@tonic-gate clr %l5 21247c478bd9Sstevel@tonic-gate clr %l6 21257c478bd9Sstevel@tonic-gate clr %l7 21267c478bd9Sstevel@tonic-gate wrpr %g0, %g7, %wstate 21277c478bd9Sstevel@tonic-gate saved 21287c478bd9Sstevel@tonic-gate retry ! restores correct %cwp 21297c478bd9Sstevel@tonic-gate 21307c478bd9Sstevel@tonic-gate.fix_alignment: 21317c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g2) ! load CPU struct addr to %g1 using %g2 21327c478bd9Sstevel@tonic-gate ldn [%g1 + CPU_THREAD], %g1 ! load thread pointer 21337c478bd9Sstevel@tonic-gate ldn [%g1 + T_PROCP], %g1 21347c478bd9Sstevel@tonic-gate mov 1, %g2 21357c478bd9Sstevel@tonic-gate stb %g2, [%g1 + P_FIXALIGNMENT] 21367c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 21377c478bd9Sstevel@tonic-gate 21387c478bd9Sstevel@tonic-gate#define STDF_REG(REG, ADDR, TMP) \ 21397c478bd9Sstevel@tonic-gate sll REG, 3, REG ;\ 21407c478bd9Sstevel@tonic-gatemark1: set start1, TMP ;\ 21417c478bd9Sstevel@tonic-gate jmp REG + TMP ;\ 21427c478bd9Sstevel@tonic-gate nop ;\ 21437c478bd9Sstevel@tonic-gatestart1: ba,pt %xcc, done1 ;\ 21447c478bd9Sstevel@tonic-gate std %f0, [ADDR + CPU_TMP1] ;\ 21457c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21467c478bd9Sstevel@tonic-gate std %f32, [ADDR + CPU_TMP1] ;\ 21477c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21487c478bd9Sstevel@tonic-gate std %f2, [ADDR + CPU_TMP1] ;\ 21497c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21507c478bd9Sstevel@tonic-gate std %f34, [ADDR + CPU_TMP1] ;\ 21517c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21527c478bd9Sstevel@tonic-gate std %f4, [ADDR + CPU_TMP1] ;\ 21537c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21547c478bd9Sstevel@tonic-gate std %f36, [ADDR + CPU_TMP1] ;\ 21557c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21567c478bd9Sstevel@tonic-gate std %f6, [ADDR + CPU_TMP1] ;\ 21577c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21587c478bd9Sstevel@tonic-gate std %f38, [ADDR + CPU_TMP1] ;\ 21597c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21607c478bd9Sstevel@tonic-gate std %f8, [ADDR + CPU_TMP1] ;\ 21617c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21627c478bd9Sstevel@tonic-gate std %f40, [ADDR + CPU_TMP1] ;\ 21637c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21647c478bd9Sstevel@tonic-gate std %f10, [ADDR + CPU_TMP1] ;\ 21657c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21667c478bd9Sstevel@tonic-gate std %f42, [ADDR + CPU_TMP1] ;\ 21677c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21687c478bd9Sstevel@tonic-gate std %f12, [ADDR + CPU_TMP1] ;\ 21697c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21707c478bd9Sstevel@tonic-gate std %f44, [ADDR + CPU_TMP1] ;\ 21717c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21727c478bd9Sstevel@tonic-gate std %f14, [ADDR + CPU_TMP1] ;\ 21737c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21747c478bd9Sstevel@tonic-gate std %f46, [ADDR + CPU_TMP1] ;\ 21757c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21767c478bd9Sstevel@tonic-gate std %f16, [ADDR + CPU_TMP1] ;\ 21777c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21787c478bd9Sstevel@tonic-gate std %f48, [ADDR + CPU_TMP1] ;\ 21797c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21807c478bd9Sstevel@tonic-gate std %f18, [ADDR + CPU_TMP1] ;\ 21817c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21827c478bd9Sstevel@tonic-gate std %f50, [ADDR + CPU_TMP1] ;\ 21837c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21847c478bd9Sstevel@tonic-gate std %f20, [ADDR + CPU_TMP1] ;\ 21857c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21867c478bd9Sstevel@tonic-gate std %f52, [ADDR + CPU_TMP1] ;\ 21877c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21887c478bd9Sstevel@tonic-gate std %f22, [ADDR + CPU_TMP1] ;\ 21897c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21907c478bd9Sstevel@tonic-gate std %f54, [ADDR + CPU_TMP1] ;\ 21917c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21927c478bd9Sstevel@tonic-gate std %f24, [ADDR + CPU_TMP1] ;\ 21937c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21947c478bd9Sstevel@tonic-gate std %f56, [ADDR + CPU_TMP1] ;\ 21957c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21967c478bd9Sstevel@tonic-gate std %f26, [ADDR + CPU_TMP1] ;\ 21977c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 21987c478bd9Sstevel@tonic-gate std %f58, [ADDR + CPU_TMP1] ;\ 21997c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 22007c478bd9Sstevel@tonic-gate std %f28, [ADDR + CPU_TMP1] ;\ 22017c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 22027c478bd9Sstevel@tonic-gate std %f60, [ADDR + CPU_TMP1] ;\ 22037c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 22047c478bd9Sstevel@tonic-gate std %f30, [ADDR + CPU_TMP1] ;\ 22057c478bd9Sstevel@tonic-gate ba,pt %xcc, done1 ;\ 22067c478bd9Sstevel@tonic-gate std %f62, [ADDR + CPU_TMP1] ;\ 22077c478bd9Sstevel@tonic-gatedone1: 22087c478bd9Sstevel@tonic-gate 22097c478bd9Sstevel@tonic-gate#define LDDF_REG(REG, ADDR, TMP) \ 22107c478bd9Sstevel@tonic-gate sll REG, 3, REG ;\ 22117c478bd9Sstevel@tonic-gatemark2: set start2, TMP ;\ 22127c478bd9Sstevel@tonic-gate jmp REG + TMP ;\ 22137c478bd9Sstevel@tonic-gate nop ;\ 22147c478bd9Sstevel@tonic-gatestart2: ba,pt %xcc, done2 ;\ 22157c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f0 ;\ 22167c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22177c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f32 ;\ 22187c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22197c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f2 ;\ 22207c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22217c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f34 ;\ 22227c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22237c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f4 ;\ 22247c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22257c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f36 ;\ 22267c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22277c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f6 ;\ 22287c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22297c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f38 ;\ 22307c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22317c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f8 ;\ 22327c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22337c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f40 ;\ 22347c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22357c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f10 ;\ 22367c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22377c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f42 ;\ 22387c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22397c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f12 ;\ 22407c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22417c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f44 ;\ 22427c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22437c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f14 ;\ 22447c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22457c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f46 ;\ 22467c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22477c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f16 ;\ 22487c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22497c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f48 ;\ 22507c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22517c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f18 ;\ 22527c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22537c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f50 ;\ 22547c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22557c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f20 ;\ 22567c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22577c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f52 ;\ 22587c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22597c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f22 ;\ 22607c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22617c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f54 ;\ 22627c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22637c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f24 ;\ 22647c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22657c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f56 ;\ 22667c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22677c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f26 ;\ 22687c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22697c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f58 ;\ 22707c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22717c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f28 ;\ 22727c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22737c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f60 ;\ 22747c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22757c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f30 ;\ 22767c478bd9Sstevel@tonic-gate ba,pt %xcc, done2 ;\ 22777c478bd9Sstevel@tonic-gate ldd [ADDR + CPU_TMP1], %f62 ;\ 22787c478bd9Sstevel@tonic-gatedone2: 22797c478bd9Sstevel@tonic-gate 22807c478bd9Sstevel@tonic-gate.lddf_exception_not_aligned: 22817c478bd9Sstevel@tonic-gate /* 22827c478bd9Sstevel@tonic-gate * Cheetah overwrites SFAR on a DTLB miss, hence read it now. 22837c478bd9Sstevel@tonic-gate */ 22847c478bd9Sstevel@tonic-gate ldxa [MMU_SFAR]%asi, %g5 ! misaligned vaddr in %g5 22857c478bd9Sstevel@tonic-gate 22867c478bd9Sstevel@tonic-gate#if defined(DEBUG) || defined(NEED_FPU_EXISTS) 22877c478bd9Sstevel@tonic-gate sethi %hi(fpu_exists), %g2 ! check fpu_exists 22887c478bd9Sstevel@tonic-gate ld [%g2 + %lo(fpu_exists)], %g2 22897c478bd9Sstevel@tonic-gate brz,a,pn %g2, 4f 22907c478bd9Sstevel@tonic-gate nop 22917c478bd9Sstevel@tonic-gate#endif 22927c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) 22937c478bd9Sstevel@tonic-gate or %g0, 1, %g4 22947c478bd9Sstevel@tonic-gate st %g4, [%g1 + CPU_TL1_HDLR] ! set tl1_hdlr flag 22957c478bd9Sstevel@tonic-gate 22967c478bd9Sstevel@tonic-gate rdpr %tpc, %g2 22977c478bd9Sstevel@tonic-gate lda [%g2]ASI_AIUP, %g6 ! get the user's lddf instruction 22987c478bd9Sstevel@tonic-gate srl %g6, 23, %g1 ! using ldda or not? 22997c478bd9Sstevel@tonic-gate and %g1, 1, %g1 23007c478bd9Sstevel@tonic-gate brz,a,pt %g1, 2f ! check for ldda instruction 23017c478bd9Sstevel@tonic-gate nop 23027c478bd9Sstevel@tonic-gate srl %g6, 13, %g1 ! check immflag 23037c478bd9Sstevel@tonic-gate and %g1, 1, %g1 23047c478bd9Sstevel@tonic-gate rdpr %tstate, %g2 ! %tstate in %g2 23057c478bd9Sstevel@tonic-gate brnz,a,pn %g1, 1f 23067c478bd9Sstevel@tonic-gate srl %g2, 31, %g1 ! get asi from %tstate 23077c478bd9Sstevel@tonic-gate srl %g6, 5, %g1 ! get asi from instruction 23087c478bd9Sstevel@tonic-gate and %g1, 0xFF, %g1 ! imm_asi field 23097c478bd9Sstevel@tonic-gate1: 23107c478bd9Sstevel@tonic-gate cmp %g1, ASI_P ! primary address space 23117c478bd9Sstevel@tonic-gate be,a,pt %icc, 2f 23127c478bd9Sstevel@tonic-gate nop 23137c478bd9Sstevel@tonic-gate cmp %g1, ASI_PNF ! primary no fault address space 23147c478bd9Sstevel@tonic-gate be,a,pt %icc, 2f 23157c478bd9Sstevel@tonic-gate nop 23167c478bd9Sstevel@tonic-gate cmp %g1, ASI_S ! secondary address space 23177c478bd9Sstevel@tonic-gate be,a,pt %icc, 2f 23187c478bd9Sstevel@tonic-gate nop 23197c478bd9Sstevel@tonic-gate cmp %g1, ASI_SNF ! secondary no fault address space 23207c478bd9Sstevel@tonic-gate bne,a,pn %icc, 3f 23217c478bd9Sstevel@tonic-gate nop 23227c478bd9Sstevel@tonic-gate2: 23237c478bd9Sstevel@tonic-gate lduwa [%g5]ASI_USER, %g7 ! get first half of misaligned data 23247c478bd9Sstevel@tonic-gate add %g5, 4, %g5 ! increment misaligned data address 23257c478bd9Sstevel@tonic-gate lduwa [%g5]ASI_USER, %g5 ! get second half of misaligned data 23267c478bd9Sstevel@tonic-gate 23277c478bd9Sstevel@tonic-gate sllx %g7, 32, %g7 23287c478bd9Sstevel@tonic-gate or %g5, %g7, %g5 ! combine data 23297c478bd9Sstevel@tonic-gate CPU_ADDR(%g7, %g1) ! save data on a per-cpu basis 23307c478bd9Sstevel@tonic-gate stx %g5, [%g7 + CPU_TMP1] ! save in cpu_tmp1 23317c478bd9Sstevel@tonic-gate 23327c478bd9Sstevel@tonic-gate srl %g6, 25, %g3 ! %g6 has the instruction 23337c478bd9Sstevel@tonic-gate and %g3, 0x1F, %g3 ! %g3 has rd 23347c478bd9Sstevel@tonic-gate LDDF_REG(%g3, %g7, %g4) 23357c478bd9Sstevel@tonic-gate 23367c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) 23377c478bd9Sstevel@tonic-gate st %g0, [%g1 + CPU_TL1_HDLR] ! clear tl1_hdlr flag 23387c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 23397c478bd9Sstevel@tonic-gate3: 23407c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) 23417c478bd9Sstevel@tonic-gate st %g0, [%g1 + CPU_TL1_HDLR] ! clear tl1_hdlr flag 23427c478bd9Sstevel@tonic-gate4: 23437c478bd9Sstevel@tonic-gate set T_USER, %g3 ! trap type in %g3 23447c478bd9Sstevel@tonic-gate or %g3, T_LDDF_ALIGN, %g3 23457c478bd9Sstevel@tonic-gate mov %g5, %g2 ! misaligned vaddr in %g2 23467c478bd9Sstevel@tonic-gate set fpu_trap, %g1 ! goto C for the little and 23477c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap ! no fault little asi's 23487c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 23497c478bd9Sstevel@tonic-gate 23507c478bd9Sstevel@tonic-gate.stdf_exception_not_aligned: 23517c478bd9Sstevel@tonic-gate /* 23527c478bd9Sstevel@tonic-gate * Cheetah overwrites SFAR on a DTLB miss, hence read it now. 23537c478bd9Sstevel@tonic-gate */ 23547c478bd9Sstevel@tonic-gate ldxa [MMU_SFAR]%asi, %g5 ! misaligned vaddr in %g5 23557c478bd9Sstevel@tonic-gate 23567c478bd9Sstevel@tonic-gate#if defined(DEBUG) || defined(NEED_FPU_EXISTS) 23577c478bd9Sstevel@tonic-gate sethi %hi(fpu_exists), %g7 ! check fpu_exists 23587c478bd9Sstevel@tonic-gate ld [%g7 + %lo(fpu_exists)], %g3 23597c478bd9Sstevel@tonic-gate brz,a,pn %g3, 4f 23607c478bd9Sstevel@tonic-gate nop 23617c478bd9Sstevel@tonic-gate#endif 23627c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) 23637c478bd9Sstevel@tonic-gate or %g0, 1, %g4 23647c478bd9Sstevel@tonic-gate st %g4, [%g1 + CPU_TL1_HDLR] ! set tl1_hdlr flag 23657c478bd9Sstevel@tonic-gate 23667c478bd9Sstevel@tonic-gate rdpr %tpc, %g2 23677c478bd9Sstevel@tonic-gate lda [%g2]ASI_AIUP, %g6 ! get the user's stdf instruction 23687c478bd9Sstevel@tonic-gate 23697c478bd9Sstevel@tonic-gate srl %g6, 23, %g1 ! using stda or not? 23707c478bd9Sstevel@tonic-gate and %g1, 1, %g1 23717c478bd9Sstevel@tonic-gate brz,a,pt %g1, 2f ! check for stda instruction 23727c478bd9Sstevel@tonic-gate nop 23737c478bd9Sstevel@tonic-gate srl %g6, 13, %g1 ! check immflag 23747c478bd9Sstevel@tonic-gate and %g1, 1, %g1 23757c478bd9Sstevel@tonic-gate rdpr %tstate, %g2 ! %tstate in %g2 23767c478bd9Sstevel@tonic-gate brnz,a,pn %g1, 1f 23777c478bd9Sstevel@tonic-gate srl %g2, 31, %g1 ! get asi from %tstate 23787c478bd9Sstevel@tonic-gate srl %g6, 5, %g1 ! get asi from instruction 23797c478bd9Sstevel@tonic-gate and %g1, 0xFF, %g1 ! imm_asi field 23807c478bd9Sstevel@tonic-gate1: 23817c478bd9Sstevel@tonic-gate cmp %g1, ASI_P ! primary address space 23827c478bd9Sstevel@tonic-gate be,a,pt %icc, 2f 23837c478bd9Sstevel@tonic-gate nop 23847c478bd9Sstevel@tonic-gate cmp %g1, ASI_S ! secondary address space 23857c478bd9Sstevel@tonic-gate bne,a,pn %icc, 3f 23867c478bd9Sstevel@tonic-gate nop 23877c478bd9Sstevel@tonic-gate2: 23887c478bd9Sstevel@tonic-gate srl %g6, 25, %g6 23897c478bd9Sstevel@tonic-gate and %g6, 0x1F, %g6 ! %g6 has rd 23907c478bd9Sstevel@tonic-gate CPU_ADDR(%g7, %g1) 23917c478bd9Sstevel@tonic-gate STDF_REG(%g6, %g7, %g4) ! STDF_REG(REG, ADDR, TMP) 23927c478bd9Sstevel@tonic-gate 23937c478bd9Sstevel@tonic-gate ldx [%g7 + CPU_TMP1], %g6 23947c478bd9Sstevel@tonic-gate srlx %g6, 32, %g7 23957c478bd9Sstevel@tonic-gate stuwa %g7, [%g5]ASI_USER ! first half 23967c478bd9Sstevel@tonic-gate add %g5, 4, %g5 ! increment misaligned data address 23977c478bd9Sstevel@tonic-gate stuwa %g6, [%g5]ASI_USER ! second half 23987c478bd9Sstevel@tonic-gate 23997c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) 24007c478bd9Sstevel@tonic-gate st %g0, [%g1 + CPU_TL1_HDLR] ! clear tl1_hdlr flag 24017c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 24027c478bd9Sstevel@tonic-gate3: 24037c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) 24047c478bd9Sstevel@tonic-gate st %g0, [%g1 + CPU_TL1_HDLR] ! clear tl1_hdlr flag 24057c478bd9Sstevel@tonic-gate4: 24067c478bd9Sstevel@tonic-gate set T_USER, %g3 ! trap type in %g3 24077c478bd9Sstevel@tonic-gate or %g3, T_STDF_ALIGN, %g3 24087c478bd9Sstevel@tonic-gate mov %g5, %g2 ! misaligned vaddr in %g2 24097c478bd9Sstevel@tonic-gate set fpu_trap, %g1 ! goto C for the little and 24107c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap ! nofault little asi's 24117c478bd9Sstevel@tonic-gate sub %g0, 1, %g4 24127c478bd9Sstevel@tonic-gate 24137c478bd9Sstevel@tonic-gate#ifdef DEBUG_USER_TRAPTRACECTL 24147c478bd9Sstevel@tonic-gate 24157c478bd9Sstevel@tonic-gate.traptrace_freeze: 24167c478bd9Sstevel@tonic-gate mov %l0, %g1 ; mov %l1, %g2 ; mov %l2, %g3 ; mov %l4, %g4 24177c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) 24187c478bd9Sstevel@tonic-gate mov %g4, %l4 ; mov %g3, %l2 ; mov %g2, %l1 ; mov %g1, %l0 24197c478bd9Sstevel@tonic-gate set trap_freeze, %g1 24207c478bd9Sstevel@tonic-gate mov 1, %g2 24217c478bd9Sstevel@tonic-gate st %g2, [%g1] 24227c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 24237c478bd9Sstevel@tonic-gate 24247c478bd9Sstevel@tonic-gate.traptrace_unfreeze: 24257c478bd9Sstevel@tonic-gate set trap_freeze, %g1 24267c478bd9Sstevel@tonic-gate st %g0, [%g1] 24277c478bd9Sstevel@tonic-gate mov %l0, %g1 ; mov %l1, %g2 ; mov %l2, %g3 ; mov %l4, %g4 24287c478bd9Sstevel@tonic-gate TT_TRACE_L(trace_win) 24297c478bd9Sstevel@tonic-gate mov %g4, %l4 ; mov %g3, %l2 ; mov %g2, %l1 ; mov %g1, %l0 24307c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 24317c478bd9Sstevel@tonic-gate 24327c478bd9Sstevel@tonic-gate#endif /* DEBUG_USER_TRAPTRACECTL */ 24337c478bd9Sstevel@tonic-gate 24347c478bd9Sstevel@tonic-gate.getcc: 24357c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g2) 24367c478bd9Sstevel@tonic-gate stx %o0, [%g1 + CPU_TMP1] ! save %o0 24377c478bd9Sstevel@tonic-gate stx %o1, [%g1 + CPU_TMP2] ! save %o1 24387c478bd9Sstevel@tonic-gate rdpr %tstate, %g3 ! get tstate 24397c478bd9Sstevel@tonic-gate srlx %g3, PSR_TSTATE_CC_SHIFT, %o0 ! shift ccr to V8 psr 24407c478bd9Sstevel@tonic-gate set PSR_ICC, %g2 24417c478bd9Sstevel@tonic-gate and %o0, %g2, %o0 ! mask out the rest 24427c478bd9Sstevel@tonic-gate srl %o0, PSR_ICC_SHIFT, %o0 ! right justify 24437c478bd9Sstevel@tonic-gate rdpr %pstate, %o1 24447c478bd9Sstevel@tonic-gate wrpr %o1, PSTATE_AG, %pstate ! get into normal globals 24457c478bd9Sstevel@tonic-gate mov %o0, %g1 ! move ccr to normal %g1 24467c478bd9Sstevel@tonic-gate wrpr %g0, %o1, %pstate ! back into alternate globals 24477c478bd9Sstevel@tonic-gate ldx [%g1 + CPU_TMP1], %o0 ! restore %o0 24487c478bd9Sstevel@tonic-gate ldx [%g1 + CPU_TMP2], %o1 ! restore %o1 24497c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 24507c478bd9Sstevel@tonic-gate 24517c478bd9Sstevel@tonic-gate.setcc: 24527c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g2) 24537c478bd9Sstevel@tonic-gate stx %o0, [%g1 + CPU_TMP1] ! save %o0 24547c478bd9Sstevel@tonic-gate stx %o1, [%g1 + CPU_TMP2] ! save %o1 24557c478bd9Sstevel@tonic-gate rdpr %pstate, %o0 24567c478bd9Sstevel@tonic-gate wrpr %o0, PSTATE_AG, %pstate ! get into normal globals 24577c478bd9Sstevel@tonic-gate mov %g1, %o1 24587c478bd9Sstevel@tonic-gate wrpr %g0, %o0, %pstate ! back to alternates 24597c478bd9Sstevel@tonic-gate sll %o1, PSR_ICC_SHIFT, %g2 24607c478bd9Sstevel@tonic-gate set PSR_ICC, %g3 24617c478bd9Sstevel@tonic-gate and %g2, %g3, %g2 ! mask out rest 24627c478bd9Sstevel@tonic-gate sllx %g2, PSR_TSTATE_CC_SHIFT, %g2 24637c478bd9Sstevel@tonic-gate rdpr %tstate, %g3 ! get tstate 24647c478bd9Sstevel@tonic-gate srl %g3, 0, %g3 ! clear upper word 24657c478bd9Sstevel@tonic-gate or %g3, %g2, %g3 ! or in new bits 24667c478bd9Sstevel@tonic-gate wrpr %g3, %tstate 24677c478bd9Sstevel@tonic-gate ldx [%g1 + CPU_TMP1], %o0 ! restore %o0 24687c478bd9Sstevel@tonic-gate ldx [%g1 + CPU_TMP2], %o1 ! restore %o1 24697c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 24707c478bd9Sstevel@tonic-gate 24717c478bd9Sstevel@tonic-gate/* 24727c478bd9Sstevel@tonic-gate * getpsr(void) 24737c478bd9Sstevel@tonic-gate * Note that the xcc part of the ccr is not provided. 24747c478bd9Sstevel@tonic-gate * The V8 code shows why the V9 trap is not faster: 24757c478bd9Sstevel@tonic-gate * #define GETPSR_TRAP() \ 24767c478bd9Sstevel@tonic-gate * mov %psr, %i0; jmp %l2; rett %l2+4; nop; 24777c478bd9Sstevel@tonic-gate */ 24787c478bd9Sstevel@tonic-gate 24797c478bd9Sstevel@tonic-gate .type .getpsr, #function 24807c478bd9Sstevel@tonic-gate.getpsr: 24817c478bd9Sstevel@tonic-gate rdpr %tstate, %g1 ! get tstate 24827c478bd9Sstevel@tonic-gate srlx %g1, PSR_TSTATE_CC_SHIFT, %o0 ! shift ccr to V8 psr 24837c478bd9Sstevel@tonic-gate set PSR_ICC, %g2 24847c478bd9Sstevel@tonic-gate and %o0, %g2, %o0 ! mask out the rest 24857c478bd9Sstevel@tonic-gate 24867c478bd9Sstevel@tonic-gate rd %fprs, %g1 ! get fprs 24877c478bd9Sstevel@tonic-gate and %g1, FPRS_FEF, %g2 ! mask out dirty upper/lower 24887c478bd9Sstevel@tonic-gate sllx %g2, PSR_FPRS_FEF_SHIFT, %g2 ! shift fef to V8 psr.ef 24897c478bd9Sstevel@tonic-gate or %o0, %g2, %o0 ! or result into psr.ef 24907c478bd9Sstevel@tonic-gate 24917c478bd9Sstevel@tonic-gate set V9_PSR_IMPLVER, %g2 ! SI assigned impl/ver: 0xef 24927c478bd9Sstevel@tonic-gate or %o0, %g2, %o0 ! or psr.impl/ver 24937c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 24947c478bd9Sstevel@tonic-gate SET_SIZE(.getpsr) 24957c478bd9Sstevel@tonic-gate 24967c478bd9Sstevel@tonic-gate/* 24977c478bd9Sstevel@tonic-gate * setpsr(newpsr) 24987c478bd9Sstevel@tonic-gate * Note that there is no support for ccr.xcc in the V9 code. 24997c478bd9Sstevel@tonic-gate */ 25007c478bd9Sstevel@tonic-gate 25017c478bd9Sstevel@tonic-gate .type .setpsr, #function 25027c478bd9Sstevel@tonic-gate.setpsr: 25037c478bd9Sstevel@tonic-gate rdpr %tstate, %g1 ! get tstate 25047c478bd9Sstevel@tonic-gate! setx TSTATE_V8_UBITS, %g2 25057c478bd9Sstevel@tonic-gate or %g0, CCR_ICC, %g3 25067c478bd9Sstevel@tonic-gate sllx %g3, TSTATE_CCR_SHIFT, %g2 25077c478bd9Sstevel@tonic-gate 25087c478bd9Sstevel@tonic-gate andn %g1, %g2, %g1 ! zero current user bits 25097c478bd9Sstevel@tonic-gate set PSR_ICC, %g2 25107c478bd9Sstevel@tonic-gate and %g2, %o0, %g2 ! clear all but psr.icc bits 25117c478bd9Sstevel@tonic-gate sllx %g2, PSR_TSTATE_CC_SHIFT, %g3 ! shift to tstate.ccr.icc 25127c478bd9Sstevel@tonic-gate wrpr %g1, %g3, %tstate ! write tstate 25137c478bd9Sstevel@tonic-gate 25147c478bd9Sstevel@tonic-gate set PSR_EF, %g2 25157c478bd9Sstevel@tonic-gate and %g2, %o0, %g2 ! clear all but fp enable bit 25167c478bd9Sstevel@tonic-gate srlx %g2, PSR_FPRS_FEF_SHIFT, %g4 ! shift ef to V9 fprs.fef 25177c478bd9Sstevel@tonic-gate wr %g0, %g4, %fprs ! write fprs 25187c478bd9Sstevel@tonic-gate 25197c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g2) ! load CPU struct addr to %g1 25207c478bd9Sstevel@tonic-gate ldn [%g1 + CPU_THREAD], %g2 ! load thread pointer 25217c478bd9Sstevel@tonic-gate ldn [%g2 + T_LWP], %g3 ! load klwp pointer 25227c478bd9Sstevel@tonic-gate ldn [%g3 + LWP_FPU], %g2 ! get lwp_fpu pointer 25237c478bd9Sstevel@tonic-gate stuw %g4, [%g2 + FPU_FPRS] ! write fef value to fpu_fprs 25247c478bd9Sstevel@tonic-gate srlx %g4, 2, %g4 ! shift fef value to bit 0 25257c478bd9Sstevel@tonic-gate stub %g4, [%g2 + FPU_EN] ! write fef value to fpu_en 25267c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 25277c478bd9Sstevel@tonic-gate SET_SIZE(.setpsr) 25287c478bd9Sstevel@tonic-gate 25297c478bd9Sstevel@tonic-gate/* 25307c478bd9Sstevel@tonic-gate * getlgrp 25317c478bd9Sstevel@tonic-gate * get home lgrpid on which the calling thread is currently executing. 25327c478bd9Sstevel@tonic-gate */ 25337c478bd9Sstevel@tonic-gate .type .getlgrp, #function 25347c478bd9Sstevel@tonic-gate.getlgrp: 25357c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g2) ! load CPU struct addr to %g1 using %g2 25367c478bd9Sstevel@tonic-gate ld [%g1 + CPU_ID], %o0 ! load cpu_id 25377c478bd9Sstevel@tonic-gate ldn [%g1 + CPU_THREAD], %g2 ! load thread pointer 25387c478bd9Sstevel@tonic-gate ldn [%g2 + T_LPL], %g2 ! load lpl pointer 25397c478bd9Sstevel@tonic-gate ld [%g2 + LPL_LGRPID], %g1 ! load lpl_lgrpid 25407c478bd9Sstevel@tonic-gate sra %g1, 0, %o1 25417c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 25427c478bd9Sstevel@tonic-gate SET_SIZE(.getlgrp) 25437c478bd9Sstevel@tonic-gate 25447c478bd9Sstevel@tonic-gate/* 25457c478bd9Sstevel@tonic-gate * Entry for old 4.x trap (trap 0). 25467c478bd9Sstevel@tonic-gate */ 25477c478bd9Sstevel@tonic-gate ENTRY_NP(syscall_trap_4x) 25487c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g2) ! load CPU struct addr to %g1 using %g2 25497c478bd9Sstevel@tonic-gate ldn [%g1 + CPU_THREAD], %g2 ! load thread pointer 25507c478bd9Sstevel@tonic-gate ldn [%g2 + T_LWP], %g2 ! load klwp pointer 25517c478bd9Sstevel@tonic-gate ld [%g2 + PCB_TRAP0], %g2 ! lwp->lwp_pcb.pcb_trap0addr 25527c478bd9Sstevel@tonic-gate brz,pn %g2, 1f ! has it been set? 25537c478bd9Sstevel@tonic-gate st %l0, [%g1 + CPU_TMP1] ! delay - save some locals 25547c478bd9Sstevel@tonic-gate st %l1, [%g1 + CPU_TMP2] 25557c478bd9Sstevel@tonic-gate rdpr %tnpc, %l1 ! save old tnpc 25567c478bd9Sstevel@tonic-gate wrpr %g0, %g2, %tnpc ! setup tnpc 25577c478bd9Sstevel@tonic-gate 25587c478bd9Sstevel@tonic-gate rdpr %pstate, %l0 25597c478bd9Sstevel@tonic-gate wrpr %l0, PSTATE_AG, %pstate ! switch to normal globals 25607c478bd9Sstevel@tonic-gate mov %l1, %g6 ! pass tnpc to user code in %g6 25617c478bd9Sstevel@tonic-gate wrpr %l0, %g0, %pstate ! switch back to alternate globals 25627c478bd9Sstevel@tonic-gate 25637c478bd9Sstevel@tonic-gate ! Note that %g1 still contains CPU struct addr 25647c478bd9Sstevel@tonic-gate ld [%g1 + CPU_TMP2], %l1 ! restore locals 25657c478bd9Sstevel@tonic-gate ld [%g1 + CPU_TMP1], %l0 25667c478bd9Sstevel@tonic-gate FAST_TRAP_DONE_CHK_INTR 25677c478bd9Sstevel@tonic-gate1: 25687c478bd9Sstevel@tonic-gate mov %g1, %l0 25697c478bd9Sstevel@tonic-gate st %l1, [%g1 + CPU_TMP2] 25707c478bd9Sstevel@tonic-gate rdpr %pstate, %l1 25717c478bd9Sstevel@tonic-gate wrpr %l1, PSTATE_AG, %pstate 25727c478bd9Sstevel@tonic-gate ! 25737c478bd9Sstevel@tonic-gate ! check for old syscall mmap which is the only different one which 25747c478bd9Sstevel@tonic-gate ! must be the same. Others are handled in the compatibility library. 25757c478bd9Sstevel@tonic-gate ! 25767c478bd9Sstevel@tonic-gate cmp %g1, OSYS_mmap ! compare to old 4.x mmap 25777c478bd9Sstevel@tonic-gate movz %icc, SYS_mmap, %g1 25787c478bd9Sstevel@tonic-gate wrpr %g0, %l1, %pstate 25797c478bd9Sstevel@tonic-gate ld [%l0 + CPU_TMP2], %l1 ! restore locals 25807c478bd9Sstevel@tonic-gate ld [%l0 + CPU_TMP1], %l0 25817c478bd9Sstevel@tonic-gate SYSCALL(syscall_trap32) 25827c478bd9Sstevel@tonic-gate SET_SIZE(syscall_trap_4x) 25837c478bd9Sstevel@tonic-gate 25847c478bd9Sstevel@tonic-gate/* 25857c478bd9Sstevel@tonic-gate * Handler for software trap 9. 25867c478bd9Sstevel@tonic-gate * Set trap0 emulation address for old 4.x system call trap. 25877c478bd9Sstevel@tonic-gate * XXX - this should be a system call. 25887c478bd9Sstevel@tonic-gate */ 25897c478bd9Sstevel@tonic-gate ENTRY_NP(set_trap0_addr) 25907c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g2) ! load CPU struct addr to %g1 using %g2 25917c478bd9Sstevel@tonic-gate ldn [%g1 + CPU_THREAD], %g2 ! load thread pointer 25927c478bd9Sstevel@tonic-gate ldn [%g2 + T_LWP], %g2 ! load klwp pointer 25937c478bd9Sstevel@tonic-gate st %l0, [%g1 + CPU_TMP1] ! save some locals 25947c478bd9Sstevel@tonic-gate st %l1, [%g1 + CPU_TMP2] 25957c478bd9Sstevel@tonic-gate rdpr %pstate, %l0 25967c478bd9Sstevel@tonic-gate wrpr %l0, PSTATE_AG, %pstate 25977c478bd9Sstevel@tonic-gate mov %g1, %l1 25987c478bd9Sstevel@tonic-gate wrpr %g0, %l0, %pstate 25997c478bd9Sstevel@tonic-gate andn %l1, 3, %l1 ! force alignment 26007c478bd9Sstevel@tonic-gate st %l1, [%g2 + PCB_TRAP0] ! lwp->lwp_pcb.pcb_trap0addr 26017c478bd9Sstevel@tonic-gate ld [%g1 + CPU_TMP1], %l0 ! restore locals 26027c478bd9Sstevel@tonic-gate ld [%g1 + CPU_TMP2], %l1 26037c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 26047c478bd9Sstevel@tonic-gate SET_SIZE(set_trap0_addr) 26057c478bd9Sstevel@tonic-gate 26067c478bd9Sstevel@tonic-gate/* 26077c478bd9Sstevel@tonic-gate * mmu_trap_tl1 26087c478bd9Sstevel@tonic-gate * trap handler for unexpected mmu traps. 26097c478bd9Sstevel@tonic-gate * simply checks if the trap was a user lddf/stdf alignment trap, in which 26107c478bd9Sstevel@tonic-gate * case we go to fpu_trap or a user trap from the window handler, in which 26117c478bd9Sstevel@tonic-gate * case we go save the state on the pcb. Otherwise, we go to ptl1_panic. 26127c478bd9Sstevel@tonic-gate */ 26137c478bd9Sstevel@tonic-gate .type mmu_trap_tl1, #function 26147c478bd9Sstevel@tonic-gatemmu_trap_tl1: 26157c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE 26167c478bd9Sstevel@tonic-gate TRACE_PTR(%g5, %g6) 2617023e71deSHaik Aftandilian GET_TRACE_TICK(%g6, %g7) 26187c478bd9Sstevel@tonic-gate stxa %g6, [%g5 + TRAP_ENT_TICK]%asi 26197c478bd9Sstevel@tonic-gate rdpr %tl, %g6 26207c478bd9Sstevel@tonic-gate stha %g6, [%g5 + TRAP_ENT_TL]%asi 26217c478bd9Sstevel@tonic-gate rdpr %tt, %g6 26227c478bd9Sstevel@tonic-gate stha %g6, [%g5 + TRAP_ENT_TT]%asi 26237c478bd9Sstevel@tonic-gate rdpr %tstate, %g6 26247c478bd9Sstevel@tonic-gate stxa %g6, [%g5 + TRAP_ENT_TSTATE]%asi 26257c478bd9Sstevel@tonic-gate stna %sp, [%g5 + TRAP_ENT_SP]%asi 26267c478bd9Sstevel@tonic-gate stna %g0, [%g5 + TRAP_ENT_TR]%asi 26277c478bd9Sstevel@tonic-gate rdpr %tpc, %g6 26287c478bd9Sstevel@tonic-gate stna %g6, [%g5 + TRAP_ENT_TPC]%asi 26297c478bd9Sstevel@tonic-gate set MMU_SFAR, %g6 26307c478bd9Sstevel@tonic-gate ldxa [%g6]ASI_DMMU, %g6 26317c478bd9Sstevel@tonic-gate stxa %g6, [%g5 + TRAP_ENT_F1]%asi 26327c478bd9Sstevel@tonic-gate CPU_PADDR(%g7, %g6); 26337c478bd9Sstevel@tonic-gate add %g7, CPU_TL1_HDLR, %g7 26347c478bd9Sstevel@tonic-gate lda [%g7]ASI_MEM, %g6 26357c478bd9Sstevel@tonic-gate stxa %g6, [%g5 + TRAP_ENT_F2]%asi 26367c478bd9Sstevel@tonic-gate set 0xdeadbeef, %g6 26377c478bd9Sstevel@tonic-gate stna %g6, [%g5 + TRAP_ENT_F3]%asi 26387c478bd9Sstevel@tonic-gate stna %g6, [%g5 + TRAP_ENT_F4]%asi 26397c478bd9Sstevel@tonic-gate TRACE_NEXT(%g5, %g6, %g7) 26407c478bd9Sstevel@tonic-gate#endif /* TRAPTRACE */ 26417c478bd9Sstevel@tonic-gate 26427c478bd9Sstevel@tonic-gate GET_CPU_IMPL(%g5) 26437c478bd9Sstevel@tonic-gate cmp %g5, PANTHER_IMPL 26447c478bd9Sstevel@tonic-gate bne mmu_trap_tl1_4 26457c478bd9Sstevel@tonic-gate nop 26467c478bd9Sstevel@tonic-gate rdpr %tt, %g5 26477c478bd9Sstevel@tonic-gate cmp %g5, T_DATA_EXCEPTION 26487c478bd9Sstevel@tonic-gate bne mmu_trap_tl1_4 26497c478bd9Sstevel@tonic-gate nop 26507c478bd9Sstevel@tonic-gate wr %g0, ASI_DMMU, %asi 26517c478bd9Sstevel@tonic-gate ldxa [MMU_SFSR]%asi, %g5 26527c478bd9Sstevel@tonic-gate mov 1, %g6 26537c478bd9Sstevel@tonic-gate sllx %g6, PN_SFSR_PARITY_SHIFT, %g6 26547c478bd9Sstevel@tonic-gate andcc %g5, %g6, %g0 26557c478bd9Sstevel@tonic-gate bz mmu_trap_tl1_4 26567c478bd9Sstevel@tonic-gate 26577c478bd9Sstevel@tonic-gate /* 26587c478bd9Sstevel@tonic-gate * We are running on a Panther and have hit a DTLB parity error. 26597c478bd9Sstevel@tonic-gate */ 26607c478bd9Sstevel@tonic-gate ldxa [MMU_TAG_ACCESS]%asi, %g2 26617c478bd9Sstevel@tonic-gate mov %g5, %g3 26627c478bd9Sstevel@tonic-gate ba,pt %xcc, .mmu_exception_is_tlb_parity 26637c478bd9Sstevel@tonic-gate mov T_DATA_EXCEPTION, %g1 26647c478bd9Sstevel@tonic-gate 26657c478bd9Sstevel@tonic-gatemmu_trap_tl1_4: 26667c478bd9Sstevel@tonic-gate CPU_PADDR(%g7, %g6); 26677c478bd9Sstevel@tonic-gate add %g7, CPU_TL1_HDLR, %g7 ! %g7 = &cpu_m.tl1_hdlr (PA) 26687c478bd9Sstevel@tonic-gate /* 26697c478bd9Sstevel@tonic-gate * AM is cleared on trap, so addresses are 64 bit 26707c478bd9Sstevel@tonic-gate */ 26717c478bd9Sstevel@tonic-gate lda [%g7]ASI_MEM, %g6 26727c478bd9Sstevel@tonic-gate brz,a,pt %g6, 1f 26737c478bd9Sstevel@tonic-gate nop 26747c478bd9Sstevel@tonic-gate /* 26757c478bd9Sstevel@tonic-gate * We are going to update cpu_m.tl1_hdlr using physical address. 26767c478bd9Sstevel@tonic-gate * Flush the D$ line, so that stale data won't be accessed later. 26777c478bd9Sstevel@tonic-gate */ 26787c478bd9Sstevel@tonic-gate CPU_ADDR(%g6, %g5) 26797c478bd9Sstevel@tonic-gate add %g6, CPU_TL1_HDLR, %g6 ! %g6 = &cpu_m.tl1_hdlr (VA) 26807c478bd9Sstevel@tonic-gate GET_CPU_IMPL(%g5) 26817c478bd9Sstevel@tonic-gate cmp %g5, CHEETAH_IMPL 268225cf1a30Sjl bl,pt %icc, 3f 268325cf1a30Sjl cmp %g5, SPITFIRE_IMPL 26847c478bd9Sstevel@tonic-gate stxa %g0, [%g7]ASI_DC_INVAL 26857c478bd9Sstevel@tonic-gate membar #Sync 26867c478bd9Sstevel@tonic-gate ba,pt %xcc, 2f 268725cf1a30Sjl nop 26887c478bd9Sstevel@tonic-gate3: 268925cf1a30Sjl bl,pt %icc, 2f 269025cf1a30Sjl sethi %hi(dcache_line_mask), %g5 26917c478bd9Sstevel@tonic-gate ld [%g5 + %lo(dcache_line_mask)], %g5 26927c478bd9Sstevel@tonic-gate and %g6, %g5, %g5 26937c478bd9Sstevel@tonic-gate stxa %g0, [%g5]ASI_DC_TAG 26947c478bd9Sstevel@tonic-gate membar #Sync 26957c478bd9Sstevel@tonic-gate2: 26967c478bd9Sstevel@tonic-gate sta %g0, [%g7]ASI_MEM 26977c478bd9Sstevel@tonic-gate SWITCH_GLOBALS ! back to mmu globals 26987c478bd9Sstevel@tonic-gate ba,a,pt %xcc, sfmmu_mmu_trap ! handle page faults 26997c478bd9Sstevel@tonic-gate1: 27007c478bd9Sstevel@tonic-gate rdpr %tt, %g5 27017c478bd9Sstevel@tonic-gate rdpr %tl, %g7 27027c478bd9Sstevel@tonic-gate sub %g7, 1, %g6 27037c478bd9Sstevel@tonic-gate wrpr %g6, %tl 27047c478bd9Sstevel@tonic-gate rdpr %tt, %g6 27057c478bd9Sstevel@tonic-gate wrpr %g7, %tl 27067c478bd9Sstevel@tonic-gate and %g6, WTRAP_TTMASK, %g6 27077c478bd9Sstevel@tonic-gate cmp %g6, WTRAP_TYPE 27087c478bd9Sstevel@tonic-gate bne,a,pn %xcc, ptl1_panic 27097c478bd9Sstevel@tonic-gate mov PTL1_BAD_MMUTRAP, %g1 27107c478bd9Sstevel@tonic-gate rdpr %tpc, %g7 27117c478bd9Sstevel@tonic-gate /* tpc should be in the trap table */ 27127c478bd9Sstevel@tonic-gate set trap_table, %g6 27137c478bd9Sstevel@tonic-gate cmp %g7, %g6 27147c478bd9Sstevel@tonic-gate blt,a,pn %xcc, ptl1_panic 27157c478bd9Sstevel@tonic-gate mov PTL1_BAD_MMUTRAP, %g1 27167c478bd9Sstevel@tonic-gate set etrap_table, %g6 27177c478bd9Sstevel@tonic-gate cmp %g7, %g6 27187c478bd9Sstevel@tonic-gate bge,a,pn %xcc, ptl1_panic 27197c478bd9Sstevel@tonic-gate mov PTL1_BAD_MMUTRAP, %g1 27207c478bd9Sstevel@tonic-gate cmp %g5, T_ALIGNMENT 27217c478bd9Sstevel@tonic-gate move %icc, MMU_SFAR, %g6 27227c478bd9Sstevel@tonic-gate movne %icc, MMU_TAG_ACCESS, %g6 27237c478bd9Sstevel@tonic-gate ldxa [%g6]ASI_DMMU, %g6 27247c478bd9Sstevel@tonic-gate andn %g7, WTRAP_ALIGN, %g7 /* 128 byte aligned */ 27257c478bd9Sstevel@tonic-gate add %g7, WTRAP_FAULTOFF, %g7 27267c478bd9Sstevel@tonic-gate wrpr %g0, %g7, %tnpc 27277c478bd9Sstevel@tonic-gate done 27287c478bd9Sstevel@tonic-gate SET_SIZE(mmu_trap_tl1) 27297c478bd9Sstevel@tonic-gate 27307c478bd9Sstevel@tonic-gate/* 27317c478bd9Sstevel@tonic-gate * Several traps use kmdb_trap and kmdb_trap_tl1 as their handlers. These 27327c478bd9Sstevel@tonic-gate * traps are valid only when kmdb is loaded. When the debugger is active, 27337c478bd9Sstevel@tonic-gate * the code below is rewritten to transfer control to the appropriate 27347c478bd9Sstevel@tonic-gate * debugger entry points. 27357c478bd9Sstevel@tonic-gate */ 27367c478bd9Sstevel@tonic-gate .global kmdb_trap 27377c478bd9Sstevel@tonic-gate .align 8 27387c478bd9Sstevel@tonic-gatekmdb_trap: 27397c478bd9Sstevel@tonic-gate ba,a trap_table0 27407c478bd9Sstevel@tonic-gate jmp %g1 + 0 27417c478bd9Sstevel@tonic-gate nop 27427c478bd9Sstevel@tonic-gate 27437c478bd9Sstevel@tonic-gate .global kmdb_trap_tl1 27447c478bd9Sstevel@tonic-gate .align 8 27457c478bd9Sstevel@tonic-gatekmdb_trap_tl1: 27467c478bd9Sstevel@tonic-gate ba,a trap_table0 27477c478bd9Sstevel@tonic-gate jmp %g1 + 0 27487c478bd9Sstevel@tonic-gate nop 27497c478bd9Sstevel@tonic-gate 27507c478bd9Sstevel@tonic-gate/* 27517c478bd9Sstevel@tonic-gate * This entry is copied from OBP's trap table during boot. 27527c478bd9Sstevel@tonic-gate */ 27537c478bd9Sstevel@tonic-gate .global obp_bpt 27547c478bd9Sstevel@tonic-gate .align 8 27557c478bd9Sstevel@tonic-gateobp_bpt: 27567c478bd9Sstevel@tonic-gate NOT 27577c478bd9Sstevel@tonic-gate 27587c478bd9Sstevel@tonic-gate/* 27597c478bd9Sstevel@tonic-gate * if kernel, set PCONTEXT to 0 for debuggers 27607c478bd9Sstevel@tonic-gate * if user, clear nucleus page sizes 27617c478bd9Sstevel@tonic-gate */ 27627c478bd9Sstevel@tonic-gate .global kctx_obp_bpt 27637c478bd9Sstevel@tonic-gatekctx_obp_bpt: 27647c478bd9Sstevel@tonic-gate set obp_bpt, %g2 27657c478bd9Sstevel@tonic-gate1: 2766febcc4a5Sjimand#ifndef _OPL 27677c478bd9Sstevel@tonic-gate mov MMU_PCONTEXT, %g1 27687c478bd9Sstevel@tonic-gate ldxa [%g1]ASI_DMMU, %g1 27697c478bd9Sstevel@tonic-gate srlx %g1, CTXREG_NEXT_SHIFT, %g3 27707c478bd9Sstevel@tonic-gate brz,pt %g3, 3f ! nucleus pgsz is 0, no problem 27717c478bd9Sstevel@tonic-gate sllx %g3, CTXREG_NEXT_SHIFT, %g3 27727c478bd9Sstevel@tonic-gate set CTXREG_CTX_MASK, %g4 ! check Pcontext 27737c478bd9Sstevel@tonic-gate btst %g4, %g1 27747c478bd9Sstevel@tonic-gate bz,a,pt %xcc, 2f 27757c478bd9Sstevel@tonic-gate clr %g3 ! kernel: PCONTEXT=0 27767c478bd9Sstevel@tonic-gate xor %g3, %g1, %g3 ! user: clr N_pgsz0/1 bits 27777c478bd9Sstevel@tonic-gate2: 27787c478bd9Sstevel@tonic-gate set DEMAP_ALL_TYPE, %g1 27797c478bd9Sstevel@tonic-gate stxa %g0, [%g1]ASI_DTLB_DEMAP 27807c478bd9Sstevel@tonic-gate stxa %g0, [%g1]ASI_ITLB_DEMAP 27817c478bd9Sstevel@tonic-gate mov MMU_PCONTEXT, %g1 27827c478bd9Sstevel@tonic-gate stxa %g3, [%g1]ASI_DMMU 27837c478bd9Sstevel@tonic-gate membar #Sync 27847c478bd9Sstevel@tonic-gate sethi %hi(FLUSH_ADDR), %g1 27857c478bd9Sstevel@tonic-gate flush %g1 ! flush required by immu 2786febcc4a5Sjimand#endif /* _OPL */ 27877c478bd9Sstevel@tonic-gate3: 27887c478bd9Sstevel@tonic-gate jmp %g2 27897c478bd9Sstevel@tonic-gate nop 27907c478bd9Sstevel@tonic-gate 27917c478bd9Sstevel@tonic-gate 27927c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE 27937c478bd9Sstevel@tonic-gate/* 27947c478bd9Sstevel@tonic-gate * TRAPTRACE support. 27957c478bd9Sstevel@tonic-gate * labels here are branched to with "rd %pc, %g7" in the delay slot. 27967c478bd9Sstevel@tonic-gate * Return is done by "jmp %g7 + 4". 27977c478bd9Sstevel@tonic-gate */ 27987c478bd9Sstevel@tonic-gate 27997c478bd9Sstevel@tonic-gatetrace_gen: 28007c478bd9Sstevel@tonic-gate TRACE_PTR(%g3, %g6) 2801023e71deSHaik Aftandilian GET_TRACE_TICK(%g6, %g4) 28027c478bd9Sstevel@tonic-gate stxa %g6, [%g3 + TRAP_ENT_TICK]%asi 28037c478bd9Sstevel@tonic-gate rdpr %tl, %g6 28047c478bd9Sstevel@tonic-gate stha %g6, [%g3 + TRAP_ENT_TL]%asi 28057c478bd9Sstevel@tonic-gate rdpr %tt, %g6 28067c478bd9Sstevel@tonic-gate stha %g6, [%g3 + TRAP_ENT_TT]%asi 28077c478bd9Sstevel@tonic-gate rdpr %tstate, %g6 28087c478bd9Sstevel@tonic-gate stxa %g6, [%g3 + TRAP_ENT_TSTATE]%asi 28097c478bd9Sstevel@tonic-gate stna %sp, [%g3 + TRAP_ENT_SP]%asi 28107c478bd9Sstevel@tonic-gate rdpr %tpc, %g6 28117c478bd9Sstevel@tonic-gate stna %g6, [%g3 + TRAP_ENT_TPC]%asi 28127c478bd9Sstevel@tonic-gate TRACE_NEXT(%g3, %g4, %g5) 28137c478bd9Sstevel@tonic-gate jmp %g7 + 4 28147c478bd9Sstevel@tonic-gate nop 28157c478bd9Sstevel@tonic-gate 28167c478bd9Sstevel@tonic-gatetrace_win: 28177c478bd9Sstevel@tonic-gate TRACE_WIN_INFO(0, %l0, %l1, %l2) 28187c478bd9Sstevel@tonic-gate ! Keep the locals as clean as possible, caller cleans %l4 28197c478bd9Sstevel@tonic-gate clr %l2 28207c478bd9Sstevel@tonic-gate clr %l1 28217c478bd9Sstevel@tonic-gate jmp %l4 + 4 28227c478bd9Sstevel@tonic-gate clr %l0 28237c478bd9Sstevel@tonic-gate 28247c478bd9Sstevel@tonic-gate/* 28257c478bd9Sstevel@tonic-gate * Trace a tsb hit 28267c478bd9Sstevel@tonic-gate * g1 = tsbe pointer (in/clobbered) 28277c478bd9Sstevel@tonic-gate * g2 = tag access register (in) 28287c478bd9Sstevel@tonic-gate * g3 - g4 = scratch (clobbered) 28297c478bd9Sstevel@tonic-gate * g5 = tsbe data (in) 28307c478bd9Sstevel@tonic-gate * g6 = scratch (clobbered) 28317c478bd9Sstevel@tonic-gate * g7 = pc we jumped here from (in) 28327c478bd9Sstevel@tonic-gate */ 28337c478bd9Sstevel@tonic-gate 28347c478bd9Sstevel@tonic-gate ! Do not disturb %g5, it will be used after the trace 28357c478bd9Sstevel@tonic-gate ALTENTRY(trace_tsbhit) 28367c478bd9Sstevel@tonic-gate TRACE_TSBHIT(0) 28377c478bd9Sstevel@tonic-gate jmp %g7 + 4 28387c478bd9Sstevel@tonic-gate nop 28397c478bd9Sstevel@tonic-gate 28407c478bd9Sstevel@tonic-gate/* 28417c478bd9Sstevel@tonic-gate * Trace a TSB miss 28427c478bd9Sstevel@tonic-gate * 28437c478bd9Sstevel@tonic-gate * g1 = tsb8k pointer (in) 28447c478bd9Sstevel@tonic-gate * g2 = tag access register (in) 28457c478bd9Sstevel@tonic-gate * g3 = tsb4m pointer (in) 28467c478bd9Sstevel@tonic-gate * g4 = tsbe tag (in/clobbered) 28477c478bd9Sstevel@tonic-gate * g5 - g6 = scratch (clobbered) 28487c478bd9Sstevel@tonic-gate * g7 = pc we jumped here from (in) 28497c478bd9Sstevel@tonic-gate */ 28507c478bd9Sstevel@tonic-gate .global trace_tsbmiss 28517c478bd9Sstevel@tonic-gatetrace_tsbmiss: 28527c478bd9Sstevel@tonic-gate membar #Sync 28537c478bd9Sstevel@tonic-gate sethi %hi(FLUSH_ADDR), %g6 28547c478bd9Sstevel@tonic-gate flush %g6 28557c478bd9Sstevel@tonic-gate TRACE_PTR(%g5, %g6) 28567c478bd9Sstevel@tonic-gate stxa %g2, [%g5 + TRAP_ENT_SP]%asi ! tag access 28577c478bd9Sstevel@tonic-gate stxa %g4, [%g5 + TRAP_ENT_F1]%asi ! tsb tag 2858023e71deSHaik Aftandilian GET_TRACE_TICK(%g6, %g4) 2859023e71deSHaik Aftandilian stxa %g6, [%g5 + TRAP_ENT_TICK]%asi 28607c478bd9Sstevel@tonic-gate rdpr %tnpc, %g6 28617c478bd9Sstevel@tonic-gate stxa %g6, [%g5 + TRAP_ENT_F2]%asi 28627c478bd9Sstevel@tonic-gate stna %g1, [%g5 + TRAP_ENT_F3]%asi ! tsb8k pointer 28637c478bd9Sstevel@tonic-gate srlx %g1, 32, %g6 28647c478bd9Sstevel@tonic-gate stna %g6, [%g5 + TRAP_ENT_F4]%asi ! huh? 28657c478bd9Sstevel@tonic-gate rdpr %tpc, %g6 28667c478bd9Sstevel@tonic-gate stna %g6, [%g5 + TRAP_ENT_TPC]%asi 28677c478bd9Sstevel@tonic-gate rdpr %tl, %g6 28687c478bd9Sstevel@tonic-gate stha %g6, [%g5 + TRAP_ENT_TL]%asi 28697c478bd9Sstevel@tonic-gate rdpr %tt, %g6 28707c478bd9Sstevel@tonic-gate or %g6, TT_MMU_MISS, %g4 28717c478bd9Sstevel@tonic-gate stha %g4, [%g5 + TRAP_ENT_TT]%asi 28727c478bd9Sstevel@tonic-gate cmp %g6, FAST_IMMU_MISS_TT 28737c478bd9Sstevel@tonic-gate be,a %icc, 1f 28747c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_IMMU, %g6 28757c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_DMMU, %g6 28767c478bd9Sstevel@tonic-gate1: stxa %g6, [%g5 + TRAP_ENT_TSTATE]%asi ! tag target 28777c478bd9Sstevel@tonic-gate stxa %g3, [%g5 + TRAP_ENT_TR]%asi ! tsb4m pointer 28787c478bd9Sstevel@tonic-gate TRACE_NEXT(%g5, %g4, %g6) 28797c478bd9Sstevel@tonic-gate jmp %g7 + 4 28807c478bd9Sstevel@tonic-gate nop 28817c478bd9Sstevel@tonic-gate 28827c478bd9Sstevel@tonic-gate/* 28837c478bd9Sstevel@tonic-gate * g2 = tag access register (in) 28847c478bd9Sstevel@tonic-gate * g3 = ctx number (in) 28857c478bd9Sstevel@tonic-gate */ 28867c478bd9Sstevel@tonic-gatetrace_dataprot: 28877c478bd9Sstevel@tonic-gate membar #Sync 28887c478bd9Sstevel@tonic-gate sethi %hi(FLUSH_ADDR), %g6 28897c478bd9Sstevel@tonic-gate flush %g6 28907c478bd9Sstevel@tonic-gate TRACE_PTR(%g1, %g6) 2891023e71deSHaik Aftandilian GET_TRACE_TICK(%g6, %g5) 28927c478bd9Sstevel@tonic-gate stxa %g6, [%g1 + TRAP_ENT_TICK]%asi 28937c478bd9Sstevel@tonic-gate rdpr %tpc, %g6 28947c478bd9Sstevel@tonic-gate stna %g6, [%g1 + TRAP_ENT_TPC]%asi 28957c478bd9Sstevel@tonic-gate rdpr %tstate, %g6 28967c478bd9Sstevel@tonic-gate stxa %g6, [%g1 + TRAP_ENT_TSTATE]%asi 28977c478bd9Sstevel@tonic-gate stxa %g2, [%g1 + TRAP_ENT_SP]%asi ! tag access reg 28987c478bd9Sstevel@tonic-gate stxa %g0, [%g1 + TRAP_ENT_TR]%asi 28997c478bd9Sstevel@tonic-gate stxa %g0, [%g1 + TRAP_ENT_F1]%asi 29007c478bd9Sstevel@tonic-gate stxa %g0, [%g1 + TRAP_ENT_F2]%asi 29017c478bd9Sstevel@tonic-gate stxa %g0, [%g1 + TRAP_ENT_F3]%asi 29027c478bd9Sstevel@tonic-gate stxa %g0, [%g1 + TRAP_ENT_F4]%asi 29037c478bd9Sstevel@tonic-gate rdpr %tl, %g6 29047c478bd9Sstevel@tonic-gate stha %g6, [%g1 + TRAP_ENT_TL]%asi 29057c478bd9Sstevel@tonic-gate rdpr %tt, %g6 29067c478bd9Sstevel@tonic-gate stha %g6, [%g1 + TRAP_ENT_TT]%asi 29077c478bd9Sstevel@tonic-gate TRACE_NEXT(%g1, %g4, %g5) 29087c478bd9Sstevel@tonic-gate jmp %g7 + 4 29097c478bd9Sstevel@tonic-gate nop 29107c478bd9Sstevel@tonic-gate 29117c478bd9Sstevel@tonic-gate#endif /* TRAPTRACE */ 29127c478bd9Sstevel@tonic-gate 2913b9e93c10SJonathan Haslam .align 32 2914b9e93c10SJonathan Haslam .global pil15_epilogue 2915b9e93c10SJonathan Haslampil15_epilogue: 2916b9e93c10SJonathan Haslam ba pil_interrupt_common 2917b9e93c10SJonathan Haslam nop 2918b9e93c10SJonathan Haslam .align 32 2919b9e93c10SJonathan Haslam 29207c478bd9Sstevel@tonic-gate/* 29217c478bd9Sstevel@tonic-gate * fast_trap_done, fast_trap_done_chk_intr: 29227c478bd9Sstevel@tonic-gate * 29237c478bd9Sstevel@tonic-gate * Due to the design of UltraSPARC pipeline, pending interrupts are not 29247c478bd9Sstevel@tonic-gate * taken immediately after a RETRY or DONE instruction which causes IE to 29257c478bd9Sstevel@tonic-gate * go from 0 to 1. Instead, the instruction at %tpc or %tnpc is allowed 29267c478bd9Sstevel@tonic-gate * to execute first before taking any interrupts. If that instruction 29277c478bd9Sstevel@tonic-gate * results in other traps, and if the corresponding trap handler runs 29287c478bd9Sstevel@tonic-gate * entirely at TL=1 with interrupts disabled, then pending interrupts 29297c478bd9Sstevel@tonic-gate * won't be taken until after yet another instruction following the %tpc 29307c478bd9Sstevel@tonic-gate * or %tnpc. 29317c478bd9Sstevel@tonic-gate * 29327c478bd9Sstevel@tonic-gate * A malicious user program can use this feature to block out interrupts 29337c478bd9Sstevel@tonic-gate * for extended durations, which can result in send_mondo_timeout kernel 29347c478bd9Sstevel@tonic-gate * panic. 29357c478bd9Sstevel@tonic-gate * 29367c478bd9Sstevel@tonic-gate * This problem is addressed by servicing any pending interrupts via 29377c478bd9Sstevel@tonic-gate * sys_trap before returning back to the user mode from a fast trap 29387c478bd9Sstevel@tonic-gate * handler. The "done" instruction within a fast trap handler, which 29397c478bd9Sstevel@tonic-gate * runs entirely at TL=1 with interrupts disabled, is replaced with the 29407c478bd9Sstevel@tonic-gate * FAST_TRAP_DONE macro, which branches control to this fast_trap_done 29417c478bd9Sstevel@tonic-gate * entry point. 29427c478bd9Sstevel@tonic-gate * 29437c478bd9Sstevel@tonic-gate * We check for any pending interrupts here and force a sys_trap to 29447c478bd9Sstevel@tonic-gate * service those interrupts, if any. To minimize overhead, pending 29457c478bd9Sstevel@tonic-gate * interrupts are checked if the %tpc happens to be at 16K boundary, 29467c478bd9Sstevel@tonic-gate * which allows a malicious program to execute at most 4K consecutive 29477c478bd9Sstevel@tonic-gate * instructions before we service any pending interrupts. If a worst 29487c478bd9Sstevel@tonic-gate * case fast trap handler takes about 2 usec, then interrupts will be 29497c478bd9Sstevel@tonic-gate * blocked for at most 8 msec, less than a clock tick. 29507c478bd9Sstevel@tonic-gate * 29517c478bd9Sstevel@tonic-gate * For the cases where we don't know if the %tpc will cross a 16K 29527c478bd9Sstevel@tonic-gate * boundary, we can't use the above optimization and always process 29537c478bd9Sstevel@tonic-gate * any pending interrupts via fast_frap_done_chk_intr entry point. 29547c478bd9Sstevel@tonic-gate * 29557c478bd9Sstevel@tonic-gate * Entry Conditions: 29567c478bd9Sstevel@tonic-gate * %pstate am:0 priv:1 ie:0 29577c478bd9Sstevel@tonic-gate * globals are AG (not normal globals) 29587c478bd9Sstevel@tonic-gate */ 29597c478bd9Sstevel@tonic-gate 29607c478bd9Sstevel@tonic-gate .global fast_trap_done, fast_trap_done_chk_intr 29617c478bd9Sstevel@tonic-gatefast_trap_done: 29627c478bd9Sstevel@tonic-gate rdpr %tpc, %g5 29637c478bd9Sstevel@tonic-gate sethi %hi(0xffffc000), %g6 ! 1's complement of 0x3fff 29647c478bd9Sstevel@tonic-gate andncc %g5, %g6, %g0 ! check lower 14 bits of %tpc 29657c478bd9Sstevel@tonic-gate bz,a,pn %icc, 1f ! branch if zero (lower 32 bits only) 29667c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_INTR_RECEIVE_STATUS, %g5 29677c478bd9Sstevel@tonic-gate done 29687c478bd9Sstevel@tonic-gate 29699acbbeafSnn ALTENTRY(fast_trap_done_check_interrupts) 29707c478bd9Sstevel@tonic-gatefast_trap_done_chk_intr: 29717c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_INTR_RECEIVE_STATUS, %g5 29727c478bd9Sstevel@tonic-gate 29737c478bd9Sstevel@tonic-gate1: rd SOFTINT, %g6 29747c478bd9Sstevel@tonic-gate and %g5, IRSR_BUSY, %g5 29757c478bd9Sstevel@tonic-gate orcc %g5, %g6, %g0 29767c478bd9Sstevel@tonic-gate bnz,pn %xcc, 2f ! branch if any pending intr 29777c478bd9Sstevel@tonic-gate nop 29787c478bd9Sstevel@tonic-gate done 29797c478bd9Sstevel@tonic-gate 29807c478bd9Sstevel@tonic-gate2: 29817c478bd9Sstevel@tonic-gate /* 29827c478bd9Sstevel@tonic-gate * We get here if there are any pending interrupts. 29837c478bd9Sstevel@tonic-gate * Adjust %tpc/%tnpc as we'll be resuming via "retry" 29847c478bd9Sstevel@tonic-gate * instruction. 29857c478bd9Sstevel@tonic-gate */ 29867c478bd9Sstevel@tonic-gate rdpr %tnpc, %g5 29877c478bd9Sstevel@tonic-gate wrpr %g0, %g5, %tpc 29887c478bd9Sstevel@tonic-gate add %g5, 4, %g5 29897c478bd9Sstevel@tonic-gate wrpr %g0, %g5, %tnpc 29907c478bd9Sstevel@tonic-gate 29917c478bd9Sstevel@tonic-gate /* 29927c478bd9Sstevel@tonic-gate * Force a dummy sys_trap call so that interrupts can be serviced. 29937c478bd9Sstevel@tonic-gate */ 29947c478bd9Sstevel@tonic-gate set fast_trap_dummy_call, %g1 29957c478bd9Sstevel@tonic-gate ba,pt %xcc, sys_trap 29967c478bd9Sstevel@tonic-gate mov -1, %g4 29977c478bd9Sstevel@tonic-gate 29987c478bd9Sstevel@tonic-gatefast_trap_dummy_call: 29997c478bd9Sstevel@tonic-gate retl 30007c478bd9Sstevel@tonic-gate nop 30017c478bd9Sstevel@tonic-gate 30029acbbeafSnn/* 300359f2ff5cSedp * Currently the brand syscall interposition code is not enabled by 300459f2ff5cSedp * default. Instead, when a branded zone is first booted the brand 300559f2ff5cSedp * infrastructure will patch the trap table so that the syscall 300659f2ff5cSedp * entry points are redirected to syscall_wrapper32 and syscall_wrapper 300759f2ff5cSedp * for ILP32 and LP64 syscalls respectively. this is done in 300859f2ff5cSedp * brand_plat_interposition_enable(). Note that the syscall wrappers 300959f2ff5cSedp * below do not collect any trap trace data since the syscall hot patch 301059f2ff5cSedp * points are reached after trap trace data has already been collected. 30119acbbeafSnn */ 30129acbbeafSnn#define BRAND_CALLBACK(callback_id) \ 30134a75c0c1Sedp CPU_ADDR(%g2, %g1) /* load CPU struct addr to %g2 */ ;\ 30144a75c0c1Sedp ldn [%g2 + CPU_THREAD], %g3 /* load thread pointer */ ;\ 30154a75c0c1Sedp ldn [%g3 + T_PROCP], %g3 /* get proc pointer */ ;\ 30164a75c0c1Sedp ldn [%g3 + P_BRAND], %g3 /* get brand pointer */ ;\ 30174a75c0c1Sedp brz %g3, 1f /* No brand? No callback. */ ;\ 30189acbbeafSnn nop ;\ 30194a75c0c1Sedp ldn [%g3 + B_MACHOPS], %g3 /* get machops list */ ;\ 30204a75c0c1Sedp ldn [%g3 + (callback_id << 3)], %g3 ;\ 30214a75c0c1Sedp brz %g3, 1f ;\ 30229acbbeafSnn /* \ 30239acbbeafSnn * This isn't pretty. We want a low-latency way for the callback \ 30249acbbeafSnn * routine to decline to do anything. We just pass in an address \ 30259acbbeafSnn * the routine can directly jmp back to, pretending that nothing \ 30269acbbeafSnn * has happened. \ 30274a75c0c1Sedp * \ 30284a75c0c1Sedp * %g1: return address (where the brand handler jumps back to) \ 30294a75c0c1Sedp * %g2: address of CPU structure \ 30304a75c0c1Sedp * %g3: address of brand handler (where we will jump to) \ 30319acbbeafSnn */ \ 30329acbbeafSnn mov %pc, %g1 ;\ 30339acbbeafSnn add %g1, 16, %g1 ;\ 30344a75c0c1Sedp jmp %g3 ;\ 30359acbbeafSnn nop ;\ 30369acbbeafSnn1: 30379acbbeafSnn 30389acbbeafSnn ENTRY_NP(syscall_wrapper32) 30399acbbeafSnn BRAND_CALLBACK(BRAND_CB_SYSCALL32) 30404a75c0c1Sedp SYSCALL_NOTT(syscall_trap32) 30419acbbeafSnn SET_SIZE(syscall_wrapper32) 30429acbbeafSnn 30439acbbeafSnn ENTRY_NP(syscall_wrapper) 30449acbbeafSnn BRAND_CALLBACK(BRAND_CB_SYSCALL) 30454a75c0c1Sedp SYSCALL_NOTT(syscall_trap) 30469acbbeafSnn SET_SIZE(syscall_wrapper) 3047