xref: /illumos-gate/usr/src/uts/sparc/v7/sys/traptrace.h (revision 3299f39fdcbdab4be7a9c70daa3873f2b78a398d)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright (c) 1990-2001 by Sun Microsystems, Inc.
24  * All rights reserved.
25  */
26 
27 #ifndef _SYS_TRAPTRACE_H
28 #define	_SYS_TRAPTRACE_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #ifdef	__cplusplus
33 extern "C" {
34 #endif
35 
36 /*
37  * Trap tracing. If TRAPTRACE is defined, every trap records info
38  * in a circular buffer.  Define TRAPTRACE in Makefile.sun4m.
39  *
40  * Trap trace records are 8 words, consisting of the %tbr, %psr, %pc, %sp,
41  * %g7 (THREAD_REG), and up to three other words.
42  *
43  * Auxilliary entries (not of just a trap), have obvious non-%tbr values in
44  * the first word.
45  */
46 #define	TRAP_ENT_TBR	0x00
47 #define	TRAP_ENT_PSR	0x04
48 #define	TRAP_ENT_PC	0x08
49 #define	TRAP_ENT_SP	0x0c
50 #define	TRAP_ENT_G7	0x10
51 #define	TRAP_ENT_TR	0x14
52 #define	TRAP_ENT_F1	0x18
53 #define	TRAP_ENT_F2	0x1c
54 
55 #define	TRAP_ENT_SIZE	32
56 #define	TRAP_TSIZE	(TRAP_ENT_SIZE*256)
57 
58 /*
59  * Trap tracing buffer header.
60  */
61 
62 /*
63  * Example buffer header in locore.s:
64  *
65  * trap_trace_ctl:
66  * 	.word	trap_tr0		! next	CPU 0
67  * 	.word	trap_tr0		! first
68  * 	.word	trap_tr0 + TRAP_TSIZE	! limit
69  * 	.word	0			! junk for alignment of prom dump
70  *
71  * 	.word	trap_tr1		! next	CPU 1
72  * 	.word	trap_tr1		! first
73  * 	.word	trap_tr1 + TRAP_TSIZE	! limit
74  * 	.word	0			! junk for alignment of prom dump
75  *
76  * 	.word	trap_tr2		! next	CPU 2
77  * 	.word	trap_tr2		! first
78  * 	.word	trap_tr2 + TRAP_TSIZE	! limit
79  * 	.word	0			! junk for alignment of prom dump
80  *
81  * 	.word	trap_tr3		! next	CPU 3
82  * 	.word	trap_tr3		! first
83  * 	.word	trap_tr3 + TRAP_TSIZE	! limit
84  * 	.word	0			! junk for alignment of prom dump
85  * 	.align	16
86  *
87  * Offsets of words in trap_trace_ctl:
88  */
89 #define	TRAPTR_NEXT	0		/* next trace entry pointer */
90 #define	TRAPTR_FIRST	4		/* start of buffer */
91 #define	TRAPTR_LIMIT	8		/* pointer past end of buffer */
92 
93 #define	TRAPTR_SIZE_SHIFT	4	/* shift count for CPU indexing */
94 
95 #ifdef	_ASM
96 
97 /*
98  * TRACE_PTR(ptr, scr1) - get trap trace entry pointer.
99  *	ptr is the register to receive the trace pointer.
100  *	reg is a different register to be used as scratch.
101  */
102 #define	TRACE_PTR(ptr, scr1)			\
103 	CPU_INDEX(scr1);			\
104 	sll	scr1, TRAPTR_SIZE_SHIFT, scr1;	\
105 	set	trap_trace_ctl, ptr; 		\
106 	ld	[ptr + scr1], ptr;		\
107 	set	panicstr, scr1;			\
108 	ld	[scr1], scr1;			\
109 	tst	scr1;				\
110 	bz	.+0xc;				\
111 	sethi	%hi(trap_tr_panic), scr1;	\
112 	or	scr1, %lo(trap_tr_panic), ptr
113 
114 /*
115  * TRACE_NEXT(ptr, scr1, scr2) - advance the trap trace pointer.
116  *	ptr is the register holding the current trace pointer (from TRACE_PTR).
117  *	scr1, and scr2 are scratch registers (different from ptr).
118  */
119 #define	TRACE_NEXT(ptr, scr1, scr2)		\
120 	CPU_INDEX(scr2);			\
121 	sll	scr2, TRAPTR_SIZE_SHIFT, scr2;	\
122 	set	trap_trace_ctl, scr1;		\
123 	add	scr2, scr1, scr1;		\
124 	add	ptr, TRAP_ENT_SIZE, ptr;	\
125 	ld	[scr1 + TRAPTR_LIMIT], scr2;	\
126 	cmp	ptr, scr2;			\
127 	/* CSTYLED */				\
128 	bgeu,a	.+8;				\
129 	ld	[scr1 + TRAPTR_FIRST], ptr;	\
130 	set	panicstr, scr2;			\
131 	ld	[scr2], scr2;			\
132 	tst	scr2;				\
133 	/* CSTYLED */				\
134 	bz,a	.+8;				\
135 	st	ptr, [scr1]
136 
137 /*
138  * Macro to restore the %psr (thus enabling traps) while preserving
139  * cpu_base_spl.  Note that the actual write to the %psr is broken into
140  * two writes to avoid the IU bug (one cannot raise PIL and enable traps
141  * in a single write to the %psr).
142  */
143 #define	TRACE_RESTORE_PSR(old, scr1, scr2)	\
144 	andn	old, PSR_ET, old;		\
145 	ld	[THREAD_REG + T_CPU], scr1;	\
146 	ld	[scr1 + CPU_BASE_SPL], scr1;	\
147 	and	old, PSR_PIL, scr2;		\
148 	subcc	scr1, scr2, scr1;		\
149 	/* CSTYLED */				\
150 	bg,a	9f;				\
151 	add	old, scr1, old;			\
152 9:	mov	old, %psr;			\
153 	wr	old, PSR_ET, %psr;		\
154 	nop;					\
155 	nop;					\
156 	nop
157 
158 /*
159  * Trace macro for underflow or overflow trap handler
160  */
161 #ifdef TRAPTRACE
162 
163 #define	TRACE_UNFL(code, addr, scr1, scr2, scr3) \
164 	TRACE_PTR(scr1, scr2);			\
165 	set	code, scr2;			\
166 	st	scr2, [scr1 + TRAP_ENT_TBR];	\
167 	mov	%psr, scr2;			\
168 	st	scr2, [scr1 + TRAP_ENT_PSR];	\
169 	st	%g0, [scr1 + TRAP_ENT_PC];	\
170 	st	addr, [scr1 + TRAP_ENT_SP];	\
171 	st	%g0, [scr1 + TRAP_ENT_G7];	\
172 	TRACE_NEXT(scr1, scr2, scr3)
173 
174 #else	/* TRAPTRACE */
175 
176 #define	TRACE_UNFL(code, addr, scr1, scr2, scr3)
177 
178 #endif	/* TRAPTRACE */
179 
180 #define	TRACE_OVFL	TRACE_UNFL	/* overflow trace is the same */
181 
182 #endif	/* _ASM */
183 
184 /*
185  * Trap trace codes used in place of a %tbr value when more than one
186  * entry is made by a trap.  The general scheme is that the trap-type is
187  * in the same position as in the TBR, and the low-order bits indicate
188  * which precise entry is being made.
189  */
190 #define	TT_OV_USR	0x051	/* overflow to user address in %sp */
191 #define	TT_OV_SYS	0x052	/* overflow to system address in %sp */
192 #define	TT_OV_SHR	0x053	/* overflow of shared window to user */
193 #define	TT_OV_SHRK	0x054	/* overflow of shared window to system */
194 #define	TT_OV_BUF	0x055	/* overflow from user of user window to PCB */
195 #define	TT_OV_BUFK	0x056	/* overflow from kernel of user window to PCB */
196 
197 #define	TT_UF_USR	0x061	/* underflow of user window */
198 #define	TT_UF_SYS	0x062	/* underflow of kernel window */
199 #define	TT_UF_FAULT	0x063	/* underflow of user window had fault */
200 
201 #define	TT_SC_RET	0x881	/* system call normal return */
202 #define	TT_SC_POST	0x882	/* system call return after post_syscall */
203 #define	TT_SC_TRAP	0x883	/* system call return calling trap */
204 
205 #define	TT_SYS_RTT	0x6666	/* return from trap */
206 #define	TT_SYS_RTTU	0x7777	/* return from trap to user */
207 
208 #define	TT_INTR_ENT	-1	/* interrupt entry */
209 #define	TT_INTR_RET	-2	/* interrupt return */
210 #define	TT_INTR_RET2	-3	/* interrupt return */
211 #define	TT_INTR_EXIT	0x8888	/* interrupt thread exit (no pinned thread) */
212 
213 #ifdef	__cplusplus
214 }
215 #endif
216 
217 #endif	/* _SYS_TRAPTRACE_H */
218