/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_TRAPTRACE_H #define _SYS_TRAPTRACE_H #ifdef __cplusplus extern "C" { #endif #define TRAP_TENABLE_ALL -1 /* enable all hv traptracing */ #define TRAP_TDISABLE_ALL 0 /* disable all hv traptracing */ #define TRAP_TFREEZE_ALL -1 /* freeze all hv traptracing */ #define TRAP_TUNFREEZE_ALL 0 /* unfreeze all hv traptracing */ /* * Trap tracing. If TRAPTRACE is defined, every trap records info * in a circular buffer. Define TRAPTRACE in Makefile.$ARCH. * * Trap trace records are TRAP_ENT_SIZE bytes, consisting of the * %tick, %tl, %tt, %tpc, %tstate, %sp, and a few other words: * * struct trap_trace_record { * ushort_t tl, tt; * long pc; * int64_t tstate, tick; * long sp, tr, f1, f2, f3, f4; * }; * * Note that for UltraSparc III and beyond %stick is used in place of %tick * unless compiled with TRAPTRACE_FORCE_TICK. * * Auxilliary entries (not of just a trap), have obvious non-%tt values in * the TRAP_ENT_TT field */ #define TRAP_TBUF (2 * PAGESIZE) /* default size is two pages */ #ifndef _ASM /* * HV Trap trace header */ typedef struct htrap_trace_hdr { uint64_t last_offset; /* most recently completed entry */ uint64_t offset; /* next entry to be written */ uint64_t dummy1; uint64_t dummy2; uint64_t dummy3; uint64_t dummy4; uint64_t dummy5; uint64_t dummy6; } htrap_trace_hdr_t; /* * HV Trap trace record */ struct htrap_trace_record { uint8_t tt_ty; /* Indicates HV or Guest entry */ uint8_t tt_hpstate; /* Hyper-privilege State */ uint8_t tt_tl; /* Trap level */ uint8_t tt_gl; /* Global register level */ uint16_t tt_tt; /* Trap type */ uint16_t tt_tag; /* Extended Trap Indentifier */ uint64_t tt_tstate; /* Trap state */ uint64_t tt_tick; /* Tick */ uint64_t tt_tpc; /* Trap PC */ uint64_t tt_f1; /* Entry specific */ uint64_t tt_f2; /* Entry specific */ uint64_t tt_f3; /* Entry specific */ uint64_t tt_f4; /* Entry specific */ }; /* * Kernel Trap trace record */ struct trap_trace_record { uint8_t tt_tl; uint8_t tt_gl; uint16_t tt_tt; uintptr_t tt_tpc; uint64_t tt_tstate; uint64_t tt_tick; uintptr_t tt_sp; uintptr_t tt_tr; uintptr_t tt_f1; uintptr_t tt_f2; uintptr_t tt_f3; uintptr_t tt_f4; }; #define TRAP_TSIZE ((TRAP_TBUF / sizeof (struct trap_trace_record)) * \ sizeof (struct trap_trace_record)) /* Rounding not needed, done for consistency */ #define HTRAP_TSIZE ((TRAP_TBUF / sizeof (struct htrap_trace_record)) * \ sizeof (struct htrap_trace_record)) #else #define TRAP_TSIZE ((TRAP_TBUF / TRAP_ENT_SIZE) * TRAP_ENT_SIZE) #define HTRAP_TSIZE ((TRAP_TBUF / HTRAP_ENT_SIZE) * HTRAP_ENT_SIZE) #endif /* * Trap tracing buffer header. */ #ifndef _ASM /* * Example buffer header stored in locore.s: * * (the actual implementation could be .skip TRAPTR_SIZE*NCPU) */ typedef union { struct { caddr_t vaddr_base; /* virtual address of top of buffer */ uint64_t paddr_base; /* physical address of buffer */ uint_t last_offset; /* to "know" what trace completed */ uint_t offset; /* current index into buffer (bytes) */ uint_t limit; /* upper limit on index */ uchar_t asi; /* cache for real asi */ caddr_t hvaddr_base; /* HV virtual addr of top of buffer */ uint64_t hpaddr_base; /* HV physical addr of buffer */ uint_t hlimit; /* HV upper limit on index */ } d; char cache_linesize[64]; } TRAP_TRACE_CTL; #ifdef _KERNEL extern TRAP_TRACE_CTL trap_trace_ctl[]; /* allocated in locore.s */ extern int trap_trace_bufsize; /* default buffer size */ extern char trap_tr0[]; /* prealloc buf for boot cpu */ extern int trap_freeze; /* freeze the trap trace */ extern caddr_t ttrace_buf; /* kmem64 buffer */ extern int ttrace_index; /* index used */ extern size_t calc_traptrace_sz(void); extern int htrap_trace_bufsize; /* default hv buffer size */ extern int mach_htraptrace_enable; extern void mach_htraptrace_setup(int); extern void mach_htraptrace_configure(int); extern void mach_htraptrace_cleanup(int); #endif /* * freeze the trap trace */ #define TRAPTRACE_FREEZE trap_freeze = 1; #define TRAPTRACE_UNFREEZE trap_freeze = 0; #else /* _ASM */ #include #include /* * Offsets of words in trap_trace_ctl: */ /* * XXX This should be done with genassym */ #define TRAPTR_VBASE 0 /* virtual address of buffer */ #define TRAPTR_LAST_OFFSET 16 /* last completed trace entry */ #define TRAPTR_OFFSET 20 /* next trace entry pointer */ #define TRAPTR_LIMIT 24 /* pointer past end of buffer */ #define TRAPTR_PBASE 8 /* start of buffer */ #define TRAPTR_ASIBUF 28 /* cache of current asi */ #define TRAPTR_HVBASE 32 /* HV virtual address of buffer */ #define TRAPTR_HPBASE 40 /* HV start of buffer */ #define TRAPTR_HLIMIT 48 /* HV pointer past end of buffer */ #define TRAPTR_SIZE_SHIFT 6 /* shift count -- per CPU indexing */ #define TRAPTR_SIZE (1<