traptrace.h revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 (c) 1990-2001 by Sun Microsystems, Inc.
* All rights reserved.
*/
#ifndef _SYS_TRAPTRACE_H
#define _SYS_TRAPTRACE_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Trap tracing. If TRAPTRACE is defined, every trap records info
* in a circular buffer. Define TRAPTRACE in Makefile.sun4m.
*
* Trap trace records are 8 words, consisting of the %tbr, %psr, %pc, %sp,
* %g7 (THREAD_REG), and up to three other words.
*
* Auxilliary entries (not of just a trap), have obvious non-%tbr values in
* the first word.
*/
#define TRAP_ENT_TBR 0x00
#define TRAP_ENT_PSR 0x04
#define TRAP_ENT_PC 0x08
#define TRAP_ENT_SP 0x0c
#define TRAP_ENT_G7 0x10
#define TRAP_ENT_TR 0x14
#define TRAP_ENT_F1 0x18
#define TRAP_ENT_F2 0x1c
#define TRAP_ENT_SIZE 32
#define TRAP_TSIZE (TRAP_ENT_SIZE*256)
/*
* Trap tracing buffer header.
*/
/*
* Example buffer header in locore.s:
*
* trap_trace_ctl:
* .word trap_tr0 ! next CPU 0
* .word trap_tr0 ! first
* .word trap_tr0 + TRAP_TSIZE ! limit
* .word 0 ! junk for alignment of prom dump
*
* .word trap_tr1 ! next CPU 1
* .word trap_tr1 ! first
* .word trap_tr1 + TRAP_TSIZE ! limit
* .word 0 ! junk for alignment of prom dump
*
* .word trap_tr2 ! next CPU 2
* .word trap_tr2 ! first
* .word trap_tr2 + TRAP_TSIZE ! limit
* .word 0 ! junk for alignment of prom dump
*
* .word trap_tr3 ! next CPU 3
* .word trap_tr3 ! first
* .word trap_tr3 + TRAP_TSIZE ! limit
* .word 0 ! junk for alignment of prom dump
* .align 16
*
* Offsets of words in trap_trace_ctl:
*/
#define TRAPTR_NEXT 0 /* next trace entry pointer */
#define TRAPTR_FIRST 4 /* start of buffer */
#define TRAPTR_LIMIT 8 /* pointer past end of buffer */
#define TRAPTR_SIZE_SHIFT 4 /* shift count for CPU indexing */
#ifdef _ASM
/*
* TRACE_PTR(ptr, scr1) - get trap trace entry pointer.
* ptr is the register to receive the trace pointer.
* reg is a different register to be used as scratch.
*/
#define TRACE_PTR(ptr, scr1) \
CPU_INDEX(scr1); \
sll scr1, TRAPTR_SIZE_SHIFT, scr1; \
set trap_trace_ctl, ptr; \
ld [ptr + scr1], ptr; \
set panicstr, scr1; \
ld [scr1], scr1; \
tst scr1; \
bz .+0xc; \
sethi %hi(trap_tr_panic), scr1; \
or scr1, %lo(trap_tr_panic), ptr
/*
* TRACE_NEXT(ptr, scr1, scr2) - advance the trap trace pointer.
* ptr is the register holding the current trace pointer (from TRACE_PTR).
* scr1, and scr2 are scratch registers (different from ptr).
*/
#define TRACE_NEXT(ptr, scr1, scr2) \
CPU_INDEX(scr2); \
sll scr2, TRAPTR_SIZE_SHIFT, scr2; \
set trap_trace_ctl, scr1; \
add scr2, scr1, scr1; \
add ptr, TRAP_ENT_SIZE, ptr; \
ld [scr1 + TRAPTR_LIMIT], scr2; \
cmp ptr, scr2; \
/* CSTYLED */ \
bgeu,a .+8; \
ld [scr1 + TRAPTR_FIRST], ptr; \
set panicstr, scr2; \
ld [scr2], scr2; \
tst scr2; \
/* CSTYLED */ \
bz,a .+8; \
st ptr, [scr1]
/*
* Macro to restore the %psr (thus enabling traps) while preserving
* cpu_base_spl. Note that the actual write to the %psr is broken into
* two writes to avoid the IU bug (one cannot raise PIL and enable traps
* in a single write to the %psr).
*/
#define TRACE_RESTORE_PSR(old, scr1, scr2) \
andn old, PSR_ET, old; \
ld [THREAD_REG + T_CPU], scr1; \
ld [scr1 + CPU_BASE_SPL], scr1; \
and old, PSR_PIL, scr2; \
subcc scr1, scr2, scr1; \
/* CSTYLED */ \
bg,a 9f; \
add old, scr1, old; \
9: mov old, %psr; \
wr old, PSR_ET, %psr; \
nop; \
nop; \
nop
/*
* Trace macro for underflow or overflow trap handler
*/
#ifdef TRAPTRACE
#define TRACE_UNFL(code, addr, scr1, scr2, scr3) \
TRACE_PTR(scr1, scr2); \
set code, scr2; \
st scr2, [scr1 + TRAP_ENT_TBR]; \
mov %psr, scr2; \
st scr2, [scr1 + TRAP_ENT_PSR]; \
st %g0, [scr1 + TRAP_ENT_PC]; \
st addr, [scr1 + TRAP_ENT_SP]; \
st %g0, [scr1 + TRAP_ENT_G7]; \
TRACE_NEXT(scr1, scr2, scr3)
#else /* TRAPTRACE */
#define TRACE_UNFL(code, addr, scr1, scr2, scr3)
#endif /* TRAPTRACE */
#define TRACE_OVFL TRACE_UNFL /* overflow trace is the same */
#endif /* _ASM */
/*
* Trap trace codes used in place of a %tbr value when more than one
* entry is made by a trap. The general scheme is that the trap-type is
* in the same position as in the TBR, and the low-order bits indicate
* which precise entry is being made.
*/
#define TT_OV_USR 0x051 /* overflow to user address in %sp */
#define TT_OV_SYS 0x052 /* overflow to system address in %sp */
#define TT_OV_SHR 0x053 /* overflow of shared window to user */
#define TT_OV_SHRK 0x054 /* overflow of shared window to system */
#define TT_OV_BUF 0x055 /* overflow from user of user window to PCB */
#define TT_OV_BUFK 0x056 /* overflow from kernel of user window to PCB */
#define TT_UF_USR 0x061 /* underflow of user window */
#define TT_UF_SYS 0x062 /* underflow of kernel window */
#define TT_UF_FAULT 0x063 /* underflow of user window had fault */
#define TT_SC_RET 0x881 /* system call normal return */
#define TT_SC_POST 0x882 /* system call return after post_syscall */
#define TT_SC_TRAP 0x883 /* system call return calling trap */
#define TT_SYS_RTT 0x6666 /* return from trap */
#define TT_SYS_RTTU 0x7777 /* return from trap to user */
#define TT_INTR_ENT -1 /* interrupt entry */
#define TT_INTR_RET -2 /* interrupt return */
#define TT_INTR_RET2 -3 /* interrupt return */
#define TT_INTR_EXIT 0x8888 /* interrupt thread exit (no pinned thread) */
#ifdef __cplusplus
}
#endif
#endif /* _SYS_TRAPTRACE_H */