1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
|
/*
* 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 */
|