1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #ifndef _SYS_TRAPTRACE_H 28*7c478bd9Sstevel@tonic-gate #define _SYS_TRAPTRACE_H 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus 33*7c478bd9Sstevel@tonic-gate extern "C" { 34*7c478bd9Sstevel@tonic-gate #endif 35*7c478bd9Sstevel@tonic-gate 36*7c478bd9Sstevel@tonic-gate #define TRAP_TENABLE_ALL -1 /* enable all hv traptracing */ 37*7c478bd9Sstevel@tonic-gate #define TRAP_TDISABLE_ALL 0 /* disable all hv traptracing */ 38*7c478bd9Sstevel@tonic-gate #define TRAP_TFREEZE_ALL -1 /* freeze all hv traptracing */ 39*7c478bd9Sstevel@tonic-gate #define TRAP_TUNFREEZE_ALL 0 /* unfreeze all hv traptracing */ 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate /* 42*7c478bd9Sstevel@tonic-gate * Trap tracing. If TRAPTRACE is defined, every trap records info 43*7c478bd9Sstevel@tonic-gate * in a circular buffer. Define TRAPTRACE in Makefile.$ARCH. 44*7c478bd9Sstevel@tonic-gate * 45*7c478bd9Sstevel@tonic-gate * Trap trace records are TRAP_ENT_SIZE bytes, consisting of the 46*7c478bd9Sstevel@tonic-gate * %tick, %tl, %tt, %tpc, %tstate, %sp, and a few other words: 47*7c478bd9Sstevel@tonic-gate * 48*7c478bd9Sstevel@tonic-gate * struct trap_trace_record { 49*7c478bd9Sstevel@tonic-gate * ushort_t tl, tt; 50*7c478bd9Sstevel@tonic-gate * long pc; 51*7c478bd9Sstevel@tonic-gate * int64_t tstate, tick; 52*7c478bd9Sstevel@tonic-gate * long sp, tr, f1, f2, f3, f4; 53*7c478bd9Sstevel@tonic-gate * }; 54*7c478bd9Sstevel@tonic-gate * 55*7c478bd9Sstevel@tonic-gate * Note that for UltraSparc III and beyond %stick is used in place of %tick 56*7c478bd9Sstevel@tonic-gate * unless compiled with TRAPTRACE_FORCE_TICK. 57*7c478bd9Sstevel@tonic-gate * 58*7c478bd9Sstevel@tonic-gate * Auxilliary entries (not of just a trap), have obvious non-%tt values in 59*7c478bd9Sstevel@tonic-gate * the TRAP_ENT_TT field 60*7c478bd9Sstevel@tonic-gate */ 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate #define TRAP_TBUF (2 * PAGESIZE) /* default size is two pages */ 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate #ifndef _ASM 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate /* 67*7c478bd9Sstevel@tonic-gate * HV Trap trace header 68*7c478bd9Sstevel@tonic-gate */ 69*7c478bd9Sstevel@tonic-gate typedef struct htrap_trace_hdr { 70*7c478bd9Sstevel@tonic-gate uint64_t last_offset; /* most recently completed entry */ 71*7c478bd9Sstevel@tonic-gate uint64_t offset; /* next entry to be written */ 72*7c478bd9Sstevel@tonic-gate uint64_t dummy1; 73*7c478bd9Sstevel@tonic-gate uint64_t dummy2; 74*7c478bd9Sstevel@tonic-gate uint64_t dummy3; 75*7c478bd9Sstevel@tonic-gate uint64_t dummy4; 76*7c478bd9Sstevel@tonic-gate uint64_t dummy5; 77*7c478bd9Sstevel@tonic-gate uint64_t dummy6; 78*7c478bd9Sstevel@tonic-gate } htrap_trace_hdr_t; 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate /* 81*7c478bd9Sstevel@tonic-gate * HV Trap trace record 82*7c478bd9Sstevel@tonic-gate */ 83*7c478bd9Sstevel@tonic-gate struct htrap_trace_record { 84*7c478bd9Sstevel@tonic-gate uint8_t tt_ty; /* Indicates HV or Guest entry */ 85*7c478bd9Sstevel@tonic-gate uint8_t tt_hpstate; /* Hyper-privilege State */ 86*7c478bd9Sstevel@tonic-gate uint8_t tt_tl; /* Trap level */ 87*7c478bd9Sstevel@tonic-gate uint8_t tt_gl; /* Global register level */ 88*7c478bd9Sstevel@tonic-gate uint16_t tt_tt; /* Trap type */ 89*7c478bd9Sstevel@tonic-gate uint16_t tt_tag; /* Extended Trap Indentifier */ 90*7c478bd9Sstevel@tonic-gate uint64_t tt_tstate; /* Trap state */ 91*7c478bd9Sstevel@tonic-gate uint64_t tt_tick; /* Tick */ 92*7c478bd9Sstevel@tonic-gate uint64_t tt_tpc; /* Trap PC */ 93*7c478bd9Sstevel@tonic-gate uint64_t tt_f1; /* Entry specific */ 94*7c478bd9Sstevel@tonic-gate uint64_t tt_f2; /* Entry specific */ 95*7c478bd9Sstevel@tonic-gate uint64_t tt_f3; /* Entry specific */ 96*7c478bd9Sstevel@tonic-gate uint64_t tt_f4; /* Entry specific */ 97*7c478bd9Sstevel@tonic-gate }; 98*7c478bd9Sstevel@tonic-gate 99*7c478bd9Sstevel@tonic-gate /* 100*7c478bd9Sstevel@tonic-gate * Kernel Trap trace record 101*7c478bd9Sstevel@tonic-gate */ 102*7c478bd9Sstevel@tonic-gate struct trap_trace_record { 103*7c478bd9Sstevel@tonic-gate uint8_t tt_tl; 104*7c478bd9Sstevel@tonic-gate uint8_t tt_gl; 105*7c478bd9Sstevel@tonic-gate uint16_t tt_tt; 106*7c478bd9Sstevel@tonic-gate uintptr_t tt_tpc; 107*7c478bd9Sstevel@tonic-gate uint64_t tt_tstate; 108*7c478bd9Sstevel@tonic-gate uint64_t tt_tick; 109*7c478bd9Sstevel@tonic-gate uintptr_t tt_sp; 110*7c478bd9Sstevel@tonic-gate uintptr_t tt_tr; 111*7c478bd9Sstevel@tonic-gate uintptr_t tt_f1; 112*7c478bd9Sstevel@tonic-gate uintptr_t tt_f2; 113*7c478bd9Sstevel@tonic-gate uintptr_t tt_f3; 114*7c478bd9Sstevel@tonic-gate uintptr_t tt_f4; 115*7c478bd9Sstevel@tonic-gate }; 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate #define TRAP_TSIZE ((TRAP_TBUF / sizeof (struct trap_trace_record)) * \ 118*7c478bd9Sstevel@tonic-gate sizeof (struct trap_trace_record)) 119*7c478bd9Sstevel@tonic-gate 120*7c478bd9Sstevel@tonic-gate /* Rounding not needed, done for consistency */ 121*7c478bd9Sstevel@tonic-gate #define HTRAP_TSIZE ((TRAP_TBUF / sizeof (struct htrap_trace_record)) * \ 122*7c478bd9Sstevel@tonic-gate sizeof (struct htrap_trace_record)) 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate #else 125*7c478bd9Sstevel@tonic-gate 126*7c478bd9Sstevel@tonic-gate #define TRAP_TSIZE ((TRAP_TBUF / TRAP_ENT_SIZE) * TRAP_ENT_SIZE) 127*7c478bd9Sstevel@tonic-gate /* Rounding not needed, done for consistency */ 128*7c478bd9Sstevel@tonic-gate #define HTRAP_TSIZE ((TRAP_TBUF / HTRAP_ENT_SIZE) * HTRAP_ENT_SIZE) 129*7c478bd9Sstevel@tonic-gate 130*7c478bd9Sstevel@tonic-gate #endif 131*7c478bd9Sstevel@tonic-gate 132*7c478bd9Sstevel@tonic-gate #define TRAP_TBUF_SIZE (TRAP_TSIZE + HTRAP_TSIZE) 133*7c478bd9Sstevel@tonic-gate 134*7c478bd9Sstevel@tonic-gate /* 135*7c478bd9Sstevel@tonic-gate * Trap tracing buffer header. 136*7c478bd9Sstevel@tonic-gate */ 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate #ifndef _ASM 139*7c478bd9Sstevel@tonic-gate 140*7c478bd9Sstevel@tonic-gate /* 141*7c478bd9Sstevel@tonic-gate * Example buffer header stored in locore.s: 142*7c478bd9Sstevel@tonic-gate * 143*7c478bd9Sstevel@tonic-gate * (the actual implementation could be .skip TRAPTR_SIZE*NCPU) 144*7c478bd9Sstevel@tonic-gate */ 145*7c478bd9Sstevel@tonic-gate typedef union { 146*7c478bd9Sstevel@tonic-gate struct { 147*7c478bd9Sstevel@tonic-gate caddr_t vaddr_base; /* virtual address of top of buffer */ 148*7c478bd9Sstevel@tonic-gate uint64_t paddr_base; /* physical address of buffer */ 149*7c478bd9Sstevel@tonic-gate uint_t last_offset; /* to "know" what trace completed */ 150*7c478bd9Sstevel@tonic-gate uint_t offset; /* current index into buffer (bytes) */ 151*7c478bd9Sstevel@tonic-gate uint_t limit; /* upper limit on index */ 152*7c478bd9Sstevel@tonic-gate uchar_t asi; /* cache for real asi */ 153*7c478bd9Sstevel@tonic-gate caddr_t hvaddr_base; /* HV virtual addr of top of buffer */ 154*7c478bd9Sstevel@tonic-gate uint64_t hpaddr_base; /* HV physical addr of buffer */ 155*7c478bd9Sstevel@tonic-gate uint_t hlimit; /* HV upper limit on index */ 156*7c478bd9Sstevel@tonic-gate } d; 157*7c478bd9Sstevel@tonic-gate char cache_linesize[64]; 158*7c478bd9Sstevel@tonic-gate } TRAP_TRACE_CTL; 159*7c478bd9Sstevel@tonic-gate 160*7c478bd9Sstevel@tonic-gate #ifdef _KERNEL 161*7c478bd9Sstevel@tonic-gate 162*7c478bd9Sstevel@tonic-gate extern TRAP_TRACE_CTL trap_trace_ctl[]; /* allocated in locore.s */ 163*7c478bd9Sstevel@tonic-gate extern int trap_trace_bufsize; /* default buffer size */ 164*7c478bd9Sstevel@tonic-gate extern char trap_tr0[]; /* prealloc buf for boot cpu */ 165*7c478bd9Sstevel@tonic-gate extern int trap_freeze; /* freeze the trap trace */ 166*7c478bd9Sstevel@tonic-gate extern caddr_t ttrace_buf; /* buffer bop alloced */ 167*7c478bd9Sstevel@tonic-gate extern int ttrace_index; /* index used */ 168*7c478bd9Sstevel@tonic-gate extern caddr_t trap_trace_alloc(caddr_t); 169*7c478bd9Sstevel@tonic-gate 170*7c478bd9Sstevel@tonic-gate extern int htrap_trace_bufsize; /* default hv buffer size */ 171*7c478bd9Sstevel@tonic-gate extern void htrap_trace_setup(caddr_t, int); 172*7c478bd9Sstevel@tonic-gate extern void htrap_trace_register(int); 173*7c478bd9Sstevel@tonic-gate 174*7c478bd9Sstevel@tonic-gate #endif 175*7c478bd9Sstevel@tonic-gate 176*7c478bd9Sstevel@tonic-gate /* 177*7c478bd9Sstevel@tonic-gate * freeze the trap trace 178*7c478bd9Sstevel@tonic-gate */ 179*7c478bd9Sstevel@tonic-gate #define TRAPTRACE_FREEZE trap_freeze = 1; 180*7c478bd9Sstevel@tonic-gate #define TRAPTRACE_UNFREEZE trap_freeze = 0; 181*7c478bd9Sstevel@tonic-gate 182*7c478bd9Sstevel@tonic-gate #else /* _ASM */ 183*7c478bd9Sstevel@tonic-gate 184*7c478bd9Sstevel@tonic-gate #include <sys/machthread.h> 185*7c478bd9Sstevel@tonic-gate 186*7c478bd9Sstevel@tonic-gate /* 187*7c478bd9Sstevel@tonic-gate * Offsets of words in trap_trace_ctl: 188*7c478bd9Sstevel@tonic-gate */ 189*7c478bd9Sstevel@tonic-gate /* 190*7c478bd9Sstevel@tonic-gate * XXX This should be done with genassym 191*7c478bd9Sstevel@tonic-gate */ 192*7c478bd9Sstevel@tonic-gate #define TRAPTR_VBASE 0 /* virtual address of buffer */ 193*7c478bd9Sstevel@tonic-gate #define TRAPTR_LAST_OFFSET 16 /* last completed trace entry */ 194*7c478bd9Sstevel@tonic-gate #define TRAPTR_OFFSET 20 /* next trace entry pointer */ 195*7c478bd9Sstevel@tonic-gate #define TRAPTR_LIMIT 24 /* pointer past end of buffer */ 196*7c478bd9Sstevel@tonic-gate #define TRAPTR_PBASE 8 /* start of buffer */ 197*7c478bd9Sstevel@tonic-gate #define TRAPTR_ASIBUF 28 /* cache of current asi */ 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate #define TRAPTR_HVBASE 32 /* HV virtual address of buffer */ 200*7c478bd9Sstevel@tonic-gate #define TRAPTR_HPBASE 40 /* HV start of buffer */ 201*7c478bd9Sstevel@tonic-gate #define TRAPTR_HLIMIT 48 /* HV pointer past end of buffer */ 202*7c478bd9Sstevel@tonic-gate 203*7c478bd9Sstevel@tonic-gate #define TRAPTR_SIZE_SHIFT 6 /* shift count -- per CPU indexing */ 204*7c478bd9Sstevel@tonic-gate #define TRAPTR_SIZE (1<<TRAPTR_SIZE_SHIFT) 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate #define TRAPTR_ASI ASI_MEM /* ASI to use for TRAPTR access */ 207*7c478bd9Sstevel@tonic-gate 208*7c478bd9Sstevel@tonic-gate /* 209*7c478bd9Sstevel@tonic-gate * Use new %stick register for UltraSparc III and beyond for 210*7c478bd9Sstevel@tonic-gate * sane debugging of mixed speed CPU systems. Use TRAPTRACE_FORCE_TICK 211*7c478bd9Sstevel@tonic-gate * for finer granularity on same speed systems. 212*7c478bd9Sstevel@tonic-gate * 213*7c478bd9Sstevel@tonic-gate * Note the label-less branches used due to contraints of where 214*7c478bd9Sstevel@tonic-gate * and when trap trace macros are used. 215*7c478bd9Sstevel@tonic-gate */ 216*7c478bd9Sstevel@tonic-gate #ifdef TRAPTRACE_FORCE_TICK 217*7c478bd9Sstevel@tonic-gate #define GET_TRACE_TICK(reg) \ 218*7c478bd9Sstevel@tonic-gate rdpr %tick, reg; 219*7c478bd9Sstevel@tonic-gate #else 220*7c478bd9Sstevel@tonic-gate #define GET_TRACE_TICK(reg) \ 221*7c478bd9Sstevel@tonic-gate sethi %hi(traptrace_use_stick), reg; \ 222*7c478bd9Sstevel@tonic-gate lduw [reg + %lo(traptrace_use_stick)], reg; \ 223*7c478bd9Sstevel@tonic-gate /* CSTYLED */ \ 224*7c478bd9Sstevel@tonic-gate brz,a reg, .+12; \ 225*7c478bd9Sstevel@tonic-gate rdpr %tick, reg; \ 226*7c478bd9Sstevel@tonic-gate rd %asr24, reg; 227*7c478bd9Sstevel@tonic-gate #endif 228*7c478bd9Sstevel@tonic-gate 229*7c478bd9Sstevel@tonic-gate /* 230*7c478bd9Sstevel@tonic-gate * TRACE_PTR(ptr, scr1) - get trap trace entry physical pointer. 231*7c478bd9Sstevel@tonic-gate * ptr is the register to receive the trace pointer. 232*7c478bd9Sstevel@tonic-gate * scr1 is a different register to be used as scratch. 233*7c478bd9Sstevel@tonic-gate * TRACING now needs a known processor state. Hence the assertion. 234*7c478bd9Sstevel@tonic-gate * NOTE: this caches and resets %asi 235*7c478bd9Sstevel@tonic-gate */ 236*7c478bd9Sstevel@tonic-gate #define TRACE_PTR(ptr, scr1) \ 237*7c478bd9Sstevel@tonic-gate sethi %hi(trap_freeze), ptr; \ 238*7c478bd9Sstevel@tonic-gate ld [ptr + %lo(trap_freeze)], ptr; \ 239*7c478bd9Sstevel@tonic-gate /* CSTYLED */ \ 240*7c478bd9Sstevel@tonic-gate brnz,pn ptr, .+20; /* skip assertion */ \ 241*7c478bd9Sstevel@tonic-gate rdpr %pstate, scr1; \ 242*7c478bd9Sstevel@tonic-gate andcc scr1, PSTATE_IE | PSTATE_AM, scr1; \ 243*7c478bd9Sstevel@tonic-gate /* CSTYLED */ \ 244*7c478bd9Sstevel@tonic-gate bne,a,pn %icc, trace_ptr_panic; \ 245*7c478bd9Sstevel@tonic-gate rd %pc, %g1; \ 246*7c478bd9Sstevel@tonic-gate CPU_INDEX(scr1, ptr); \ 247*7c478bd9Sstevel@tonic-gate sll scr1, TRAPTR_SIZE_SHIFT, scr1; \ 248*7c478bd9Sstevel@tonic-gate set trap_trace_ctl, ptr; \ 249*7c478bd9Sstevel@tonic-gate add ptr, scr1, scr1; \ 250*7c478bd9Sstevel@tonic-gate rd %asi, ptr; \ 251*7c478bd9Sstevel@tonic-gate stb ptr, [scr1 + TRAPTR_ASIBUF]; \ 252*7c478bd9Sstevel@tonic-gate sethi %hi(trap_freeze), ptr; \ 253*7c478bd9Sstevel@tonic-gate ld [ptr + %lo(trap_freeze)], ptr; \ 254*7c478bd9Sstevel@tonic-gate /* CSTYLED */ \ 255*7c478bd9Sstevel@tonic-gate brnz,pn ptr, .+20; /* skip assertion */ \ 256*7c478bd9Sstevel@tonic-gate ld [scr1 + TRAPTR_LIMIT], ptr; \ 257*7c478bd9Sstevel@tonic-gate tst ptr; \ 258*7c478bd9Sstevel@tonic-gate /* CSTYLED */ \ 259*7c478bd9Sstevel@tonic-gate be,a,pn %icc, trace_ptr_panic; \ 260*7c478bd9Sstevel@tonic-gate rd %pc, %g1; \ 261*7c478bd9Sstevel@tonic-gate ldx [scr1 + TRAPTR_PBASE], ptr; \ 262*7c478bd9Sstevel@tonic-gate ld [scr1 + TRAPTR_OFFSET], scr1; \ 263*7c478bd9Sstevel@tonic-gate wr %g0, TRAPTR_ASI, %asi; \ 264*7c478bd9Sstevel@tonic-gate add ptr, scr1, ptr; 265*7c478bd9Sstevel@tonic-gate 266*7c478bd9Sstevel@tonic-gate /* 267*7c478bd9Sstevel@tonic-gate * TRACE_NEXT(scr1, scr2, scr3) - advance the trap trace pointer. 268*7c478bd9Sstevel@tonic-gate * scr1, scr2, scr3 are scratch registers. 269*7c478bd9Sstevel@tonic-gate * This routine will skip updating the trap pointers if the 270*7c478bd9Sstevel@tonic-gate * global freeze register is set (e.g. in panic). 271*7c478bd9Sstevel@tonic-gate * (we also restore the asi register) 272*7c478bd9Sstevel@tonic-gate */ 273*7c478bd9Sstevel@tonic-gate #define TRACE_NEXT(scr1, scr2, scr3) \ 274*7c478bd9Sstevel@tonic-gate CPU_INDEX(scr2, scr1); \ 275*7c478bd9Sstevel@tonic-gate sll scr2, TRAPTR_SIZE_SHIFT, scr2; \ 276*7c478bd9Sstevel@tonic-gate set trap_trace_ctl, scr1; \ 277*7c478bd9Sstevel@tonic-gate add scr1, scr2, scr2; \ 278*7c478bd9Sstevel@tonic-gate ldub [scr2 + TRAPTR_ASIBUF], scr1; \ 279*7c478bd9Sstevel@tonic-gate wr %g0, scr1, %asi; \ 280*7c478bd9Sstevel@tonic-gate sethi %hi(trap_freeze), scr1; \ 281*7c478bd9Sstevel@tonic-gate ld [scr1 + %lo(trap_freeze)], scr1; \ 282*7c478bd9Sstevel@tonic-gate /* CSTYLED */ \ 283*7c478bd9Sstevel@tonic-gate brnz scr1, .+36; /* skip update on freeze */ \ 284*7c478bd9Sstevel@tonic-gate ld [scr2 + TRAPTR_OFFSET], scr1; \ 285*7c478bd9Sstevel@tonic-gate ld [scr2 + TRAPTR_LIMIT], scr3; \ 286*7c478bd9Sstevel@tonic-gate st scr1, [scr2 + TRAPTR_LAST_OFFSET]; \ 287*7c478bd9Sstevel@tonic-gate add scr1, TRAP_ENT_SIZE, scr1; \ 288*7c478bd9Sstevel@tonic-gate sub scr3, TRAP_ENT_SIZE, scr3; \ 289*7c478bd9Sstevel@tonic-gate cmp scr1, scr3; \ 290*7c478bd9Sstevel@tonic-gate movge %icc, 0, scr1; \ 291*7c478bd9Sstevel@tonic-gate st scr1, [scr2 + TRAPTR_OFFSET]; 292*7c478bd9Sstevel@tonic-gate 293*7c478bd9Sstevel@tonic-gate /* 294*7c478bd9Sstevel@tonic-gate * macro to save %tl, %gl to trap trace record at addr 295*7c478bd9Sstevel@tonic-gate */ 296*7c478bd9Sstevel@tonic-gate #define TRACE_SAVE_TL_GL_REGS(addr, scr1) \ 297*7c478bd9Sstevel@tonic-gate rdpr %tl, scr1; \ 298*7c478bd9Sstevel@tonic-gate stba scr1, [addr + TRAP_ENT_TL]%asi; \ 299*7c478bd9Sstevel@tonic-gate rdpr %gl, scr1; \ 300*7c478bd9Sstevel@tonic-gate stba scr1, [addr + TRAP_ENT_GL]%asi 301*7c478bd9Sstevel@tonic-gate 302*7c478bd9Sstevel@tonic-gate /* 303*7c478bd9Sstevel@tonic-gate * macro to save tl to trap trace record at addr 304*7c478bd9Sstevel@tonic-gate */ 305*7c478bd9Sstevel@tonic-gate #define TRACE_SAVE_TL_VAL(addr, tl) \ 306*7c478bd9Sstevel@tonic-gate stba tl, [addr + TRAP_ENT_TL]%asi 307*7c478bd9Sstevel@tonic-gate 308*7c478bd9Sstevel@tonic-gate /* 309*7c478bd9Sstevel@tonic-gate * macro to save gl to trap trace record at addr 310*7c478bd9Sstevel@tonic-gate */ 311*7c478bd9Sstevel@tonic-gate #define TRACE_SAVE_GL_VAL(addr, gl) \ 312*7c478bd9Sstevel@tonic-gate stba gl, [addr + TRAP_ENT_GL]%asi 313*7c478bd9Sstevel@tonic-gate 314*7c478bd9Sstevel@tonic-gate 315*7c478bd9Sstevel@tonic-gate /* 316*7c478bd9Sstevel@tonic-gate * Trace macro for sys_trap return entries: 317*7c478bd9Sstevel@tonic-gate * prom_rtt, priv_rtt, and user_rtt 318*7c478bd9Sstevel@tonic-gate * %l7 - regs 319*7c478bd9Sstevel@tonic-gate * %l6 - trap %pil for prom_rtt and priv_rtt; THREAD_REG for user_rtt 320*7c478bd9Sstevel@tonic-gate */ 321*7c478bd9Sstevel@tonic-gate #define TRACE_RTT(code, scr1, scr2, scr3, scr4) \ 322*7c478bd9Sstevel@tonic-gate rdpr %pstate, scr4; \ 323*7c478bd9Sstevel@tonic-gate andn scr4, PSTATE_IE | PSTATE_AM, scr3; \ 324*7c478bd9Sstevel@tonic-gate wrpr %g0, scr3, %pstate; \ 325*7c478bd9Sstevel@tonic-gate TRACE_PTR(scr1, scr2); \ 326*7c478bd9Sstevel@tonic-gate GET_TRACE_TICK(scr2); \ 327*7c478bd9Sstevel@tonic-gate stxa scr2, [scr1 + TRAP_ENT_TICK]%asi; \ 328*7c478bd9Sstevel@tonic-gate TRACE_SAVE_TL_GL_REGS(scr1, scr2); \ 329*7c478bd9Sstevel@tonic-gate set code, scr2; \ 330*7c478bd9Sstevel@tonic-gate stha scr2, [scr1 + TRAP_ENT_TT]%asi; \ 331*7c478bd9Sstevel@tonic-gate ldn [%l7 + PC_OFF], scr2; \ 332*7c478bd9Sstevel@tonic-gate stna scr2, [scr1 + TRAP_ENT_TPC]%asi; \ 333*7c478bd9Sstevel@tonic-gate ldx [%l7 + TSTATE_OFF], scr2; \ 334*7c478bd9Sstevel@tonic-gate stxa scr2, [scr1 + TRAP_ENT_TSTATE]%asi; \ 335*7c478bd9Sstevel@tonic-gate stna %sp, [scr1 + TRAP_ENT_SP]%asi; \ 336*7c478bd9Sstevel@tonic-gate stna %l6, [scr1 + TRAP_ENT_TR]%asi; \ 337*7c478bd9Sstevel@tonic-gate stna %l7, [scr1 + TRAP_ENT_F1]%asi; \ 338*7c478bd9Sstevel@tonic-gate ldn [THREAD_REG + T_CPU], scr2; \ 339*7c478bd9Sstevel@tonic-gate ld [scr2 + CPU_BASE_SPL], scr2; \ 340*7c478bd9Sstevel@tonic-gate stna scr2, [scr1 + TRAP_ENT_F2]%asi; \ 341*7c478bd9Sstevel@tonic-gate stna %g0, [scr1 + TRAP_ENT_F3]%asi; \ 342*7c478bd9Sstevel@tonic-gate rdpr %cwp, scr2; \ 343*7c478bd9Sstevel@tonic-gate stna scr2, [scr1 + TRAP_ENT_F4]%asi; \ 344*7c478bd9Sstevel@tonic-gate TRACE_NEXT(scr1, scr2, scr3); \ 345*7c478bd9Sstevel@tonic-gate wrpr %g0, scr4, %pstate 346*7c478bd9Sstevel@tonic-gate 347*7c478bd9Sstevel@tonic-gate /* 348*7c478bd9Sstevel@tonic-gate * Trace macro for spill and fill trap handlers 349*7c478bd9Sstevel@tonic-gate * tl and tt fields indicate which spill handler is entered 350*7c478bd9Sstevel@tonic-gate */ 351*7c478bd9Sstevel@tonic-gate #define TRACE_WIN_INFO(code, scr1, scr2, scr3) \ 352*7c478bd9Sstevel@tonic-gate TRACE_PTR(scr1, scr2); \ 353*7c478bd9Sstevel@tonic-gate GET_TRACE_TICK(scr2); \ 354*7c478bd9Sstevel@tonic-gate stxa scr2, [scr1 + TRAP_ENT_TICK]%asi; \ 355*7c478bd9Sstevel@tonic-gate TRACE_SAVE_TL_GL_REGS(scr1, scr2); \ 356*7c478bd9Sstevel@tonic-gate rdpr %tt, scr2; \ 357*7c478bd9Sstevel@tonic-gate set code, scr3; \ 358*7c478bd9Sstevel@tonic-gate or scr2, scr3, scr2; \ 359*7c478bd9Sstevel@tonic-gate stha scr2, [scr1 + TRAP_ENT_TT]%asi; \ 360*7c478bd9Sstevel@tonic-gate rdpr %tstate, scr2; \ 361*7c478bd9Sstevel@tonic-gate stxa scr2, [scr1 + TRAP_ENT_TSTATE]%asi; \ 362*7c478bd9Sstevel@tonic-gate stna %sp, [scr1 + TRAP_ENT_SP]%asi; \ 363*7c478bd9Sstevel@tonic-gate rdpr %tpc, scr2; \ 364*7c478bd9Sstevel@tonic-gate stna scr2, [scr1 + TRAP_ENT_TPC]%asi; \ 365*7c478bd9Sstevel@tonic-gate set TT_FSPILL_DEBUG, scr2; \ 366*7c478bd9Sstevel@tonic-gate stna scr2, [scr1 + TRAP_ENT_TR]%asi; \ 367*7c478bd9Sstevel@tonic-gate rdpr %pstate, scr2; \ 368*7c478bd9Sstevel@tonic-gate stna scr2, [scr1 + TRAP_ENT_F1]%asi; \ 369*7c478bd9Sstevel@tonic-gate rdpr %cwp, scr2; \ 370*7c478bd9Sstevel@tonic-gate sll scr2, 24, scr2; \ 371*7c478bd9Sstevel@tonic-gate rdpr %cansave, scr3; \ 372*7c478bd9Sstevel@tonic-gate sll scr3, 16, scr3; \ 373*7c478bd9Sstevel@tonic-gate or scr2, scr3, scr2; \ 374*7c478bd9Sstevel@tonic-gate rdpr %canrestore, scr3; \ 375*7c478bd9Sstevel@tonic-gate or scr2, scr3, scr2; \ 376*7c478bd9Sstevel@tonic-gate stna scr2, [scr1 + TRAP_ENT_F2]%asi; \ 377*7c478bd9Sstevel@tonic-gate rdpr %otherwin, scr2; \ 378*7c478bd9Sstevel@tonic-gate sll scr2, 24, scr2; \ 379*7c478bd9Sstevel@tonic-gate rdpr %cleanwin, scr3; \ 380*7c478bd9Sstevel@tonic-gate sll scr3, 16, scr3; \ 381*7c478bd9Sstevel@tonic-gate or scr2, scr3, scr2; \ 382*7c478bd9Sstevel@tonic-gate rdpr %wstate, scr3; \ 383*7c478bd9Sstevel@tonic-gate or scr2, scr3, scr2; \ 384*7c478bd9Sstevel@tonic-gate stna scr2, [scr1 + TRAP_ENT_F3]%asi; \ 385*7c478bd9Sstevel@tonic-gate stna %o7, [scr1 + TRAP_ENT_F4]%asi; \ 386*7c478bd9Sstevel@tonic-gate TRACE_NEXT(scr1, scr2, scr3) 387*7c478bd9Sstevel@tonic-gate 388*7c478bd9Sstevel@tonic-gate #ifdef TRAPTRACE 389*7c478bd9Sstevel@tonic-gate 390*7c478bd9Sstevel@tonic-gate #define FAULT_WINTRACE(scr1, scr2, scr3, type) \ 391*7c478bd9Sstevel@tonic-gate TRACE_PTR(scr1, scr2); \ 392*7c478bd9Sstevel@tonic-gate GET_TRACE_TICK(scr2); \ 393*7c478bd9Sstevel@tonic-gate stxa scr2, [scr1 + TRAP_ENT_TICK]%asi; \ 394*7c478bd9Sstevel@tonic-gate TRACE_SAVE_TL_GL_REGS(scr1, scr2); \ 395*7c478bd9Sstevel@tonic-gate set type, scr2; \ 396*7c478bd9Sstevel@tonic-gate stha scr2, [scr1 + TRAP_ENT_TT]%asi; \ 397*7c478bd9Sstevel@tonic-gate rdpr %tpc, scr2; \ 398*7c478bd9Sstevel@tonic-gate stna scr2, [scr1 + TRAP_ENT_TPC]%asi; \ 399*7c478bd9Sstevel@tonic-gate rdpr %tstate, scr2; \ 400*7c478bd9Sstevel@tonic-gate stxa scr2, [scr1 + TRAP_ENT_TSTATE]%asi; \ 401*7c478bd9Sstevel@tonic-gate stna %sp, [scr1 + TRAP_ENT_SP]%asi; \ 402*7c478bd9Sstevel@tonic-gate stna %g0, [scr1 + TRAP_ENT_TR]%asi; \ 403*7c478bd9Sstevel@tonic-gate stna %g0, [scr1 + TRAP_ENT_F1]%asi; \ 404*7c478bd9Sstevel@tonic-gate stna %g4, [scr1 + TRAP_ENT_F2]%asi; \ 405*7c478bd9Sstevel@tonic-gate rdpr %pil, scr2; \ 406*7c478bd9Sstevel@tonic-gate stna scr2, [scr1 + TRAP_ENT_F3]%asi; \ 407*7c478bd9Sstevel@tonic-gate stna %g0, [scr1 + TRAP_ENT_F4]%asi; \ 408*7c478bd9Sstevel@tonic-gate TRACE_NEXT(scr1, scr2, scr3) 409*7c478bd9Sstevel@tonic-gate 410*7c478bd9Sstevel@tonic-gate #define SYSTRAP_TT 0x1300 411*7c478bd9Sstevel@tonic-gate 412*7c478bd9Sstevel@tonic-gate #define SYSTRAP_TRACE(scr1, scr2, scr3) \ 413*7c478bd9Sstevel@tonic-gate TRACE_PTR(scr1, scr2); \ 414*7c478bd9Sstevel@tonic-gate GET_TRACE_TICK(scr2); \ 415*7c478bd9Sstevel@tonic-gate stxa scr2, [scr1 + TRAP_ENT_TICK]%asi; \ 416*7c478bd9Sstevel@tonic-gate TRACE_SAVE_TL_GL_REGS(scr1, scr2); \ 417*7c478bd9Sstevel@tonic-gate set SYSTRAP_TT, scr3; \ 418*7c478bd9Sstevel@tonic-gate rdpr %tt, scr2; \ 419*7c478bd9Sstevel@tonic-gate or scr3, scr2, scr2; \ 420*7c478bd9Sstevel@tonic-gate stha scr2, [scr1 + TRAP_ENT_TT]%asi; \ 421*7c478bd9Sstevel@tonic-gate rdpr %tpc, scr2; \ 422*7c478bd9Sstevel@tonic-gate stna scr2, [scr1 + TRAP_ENT_TPC]%asi; \ 423*7c478bd9Sstevel@tonic-gate rdpr %tstate, scr2; \ 424*7c478bd9Sstevel@tonic-gate stxa scr2, [scr1 + TRAP_ENT_TSTATE]%asi; \ 425*7c478bd9Sstevel@tonic-gate stna %g1, [scr1 + TRAP_ENT_SP]%asi; \ 426*7c478bd9Sstevel@tonic-gate stna %g2, [scr1 + TRAP_ENT_TR]%asi; \ 427*7c478bd9Sstevel@tonic-gate stna %g3, [scr1 + TRAP_ENT_F1]%asi; \ 428*7c478bd9Sstevel@tonic-gate stna %g4, [scr1 + TRAP_ENT_F2]%asi; \ 429*7c478bd9Sstevel@tonic-gate rdpr %pil, scr2; \ 430*7c478bd9Sstevel@tonic-gate stna scr2, [scr1 + TRAP_ENT_F3]%asi; \ 431*7c478bd9Sstevel@tonic-gate rdpr %cwp, scr2; \ 432*7c478bd9Sstevel@tonic-gate stna scr2, [scr1 + TRAP_ENT_F4]%asi; \ 433*7c478bd9Sstevel@tonic-gate TRACE_NEXT(scr1, scr2, scr3) 434*7c478bd9Sstevel@tonic-gate 435*7c478bd9Sstevel@tonic-gate #else /* TRAPTRACE */ 436*7c478bd9Sstevel@tonic-gate 437*7c478bd9Sstevel@tonic-gate #define FAULT_WINTRACE(scr1, scr2, scr3, type) 438*7c478bd9Sstevel@tonic-gate #define SYSTRAP_TRACE(scr1, scr2, scr3) 439*7c478bd9Sstevel@tonic-gate 440*7c478bd9Sstevel@tonic-gate #endif /* TRAPTRACE */ 441*7c478bd9Sstevel@tonic-gate 442*7c478bd9Sstevel@tonic-gate #endif /* _ASM */ 443*7c478bd9Sstevel@tonic-gate 444*7c478bd9Sstevel@tonic-gate /* 445*7c478bd9Sstevel@tonic-gate * Trap trace codes used in place of a %tbr value when more than one 446*7c478bd9Sstevel@tonic-gate * entry is made by a trap. The general scheme is that the trap-type is 447*7c478bd9Sstevel@tonic-gate * in the same position as in the TT, and the low-order bits indicate 448*7c478bd9Sstevel@tonic-gate * which precise entry is being made. 449*7c478bd9Sstevel@tonic-gate */ 450*7c478bd9Sstevel@tonic-gate 451*7c478bd9Sstevel@tonic-gate #define TT_F32_SN0 0x1084 452*7c478bd9Sstevel@tonic-gate #define TT_F64_SN0 0x1088 453*7c478bd9Sstevel@tonic-gate #define TT_F32_NT0 0x1094 454*7c478bd9Sstevel@tonic-gate #define TT_F64_NT0 0x1098 455*7c478bd9Sstevel@tonic-gate #define TT_F32_SO0 0x10A4 456*7c478bd9Sstevel@tonic-gate #define TT_F64_SO0 0x10A8 457*7c478bd9Sstevel@tonic-gate #define TT_F32_FN0 0x10C4 458*7c478bd9Sstevel@tonic-gate #define TT_F64_FN0 0x10C8 459*7c478bd9Sstevel@tonic-gate #define TT_F32_SN1 0x1284 460*7c478bd9Sstevel@tonic-gate #define TT_F64_SN1 0x1288 461*7c478bd9Sstevel@tonic-gate #define TT_F32_NT1 0x1294 462*7c478bd9Sstevel@tonic-gate #define TT_F64_NT1 0x1298 463*7c478bd9Sstevel@tonic-gate #define TT_F32_SO1 0x12A4 464*7c478bd9Sstevel@tonic-gate #define TT_F64_SO1 0x12A8 465*7c478bd9Sstevel@tonic-gate #define TT_F32_FN1 0x12C4 466*7c478bd9Sstevel@tonic-gate #define TT_F64_FN1 0x12C8 467*7c478bd9Sstevel@tonic-gate #define TT_RTT_FN1 0x12DD 468*7c478bd9Sstevel@tonic-gate 469*7c478bd9Sstevel@tonic-gate #define TT_SC_ENTR 0x880 /* enter system call */ 470*7c478bd9Sstevel@tonic-gate #define TT_SC_RET 0x881 /* system call normal return */ 471*7c478bd9Sstevel@tonic-gate 472*7c478bd9Sstevel@tonic-gate #define TT_SYS_RTT_PROM 0x5555 /* return from trap to prom */ 473*7c478bd9Sstevel@tonic-gate #define TT_SYS_RTT_PRIV 0x6666 /* return from trap to privilege */ 474*7c478bd9Sstevel@tonic-gate #define TT_SYS_RTT_USER 0x7777 /* return from trap to user */ 475*7c478bd9Sstevel@tonic-gate 476*7c478bd9Sstevel@tonic-gate #define TT_INTR_EXIT 0x8888 /* interrupt thread exit (no pinned thread) */ 477*7c478bd9Sstevel@tonic-gate #define TT_FSPILL_DEBUG 0x9999 /* fill/spill debugging */ 478*7c478bd9Sstevel@tonic-gate 479*7c478bd9Sstevel@tonic-gate #define TT_SERVE_INTR 0x6000 /* SERVE_INTR */ 480*7c478bd9Sstevel@tonic-gate #define TT_XCALL 0xd000 /* xcall/xtrap */ 481*7c478bd9Sstevel@tonic-gate #define TT_XCALL_CONT 0xdc00 /* continuation of an xcall/xtrap record */ 482*7c478bd9Sstevel@tonic-gate 483*7c478bd9Sstevel@tonic-gate #define TT_MMU_MISS 0x200 /* or'd into %tt to indicate a miss */ 484*7c478bd9Sstevel@tonic-gate #define TT_MMU_EXEC 0x400 /* or'd into %tt to indicate exec_fault */ 485*7c478bd9Sstevel@tonic-gate 486*7c478bd9Sstevel@tonic-gate 487*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus 488*7c478bd9Sstevel@tonic-gate } 489*7c478bd9Sstevel@tonic-gate #endif 490*7c478bd9Sstevel@tonic-gate 491*7c478bd9Sstevel@tonic-gate #endif /* _SYS_TRAPTRACE_H */ 492