8354 sync regcomp(3C) with upstream (fix make catalog)
[unleashed/tickless.git] / usr / src / uts / intel / ia32 / sys / traptrace.h
blob038f01715cf3d157f618ca74c7a14e59e48926f0
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
25 #ifndef _IA32_SYS_TRAPTRACE_H
26 #define _IA32_SYS_TRAPTRACE_H
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
32 #include <sys/privregs.h>
35 * Trap tracing. If TRAPTRACE is defined, an entry is recorded every time
36 * the CPU jumps through the Interrupt Descriptor Table (IDT). One exception
37 * is the Double Fault handler, which does not record a traptrace entry.
39 * There are facilities to (conditionally) interleave tracing of related
40 * facilities e.h. x-calls.
44 * Note: non-assembler files that include this file must include
45 * <sys/systm.h> before it, for the typedef of pc_t to be visible.
48 #define TTR_STACK_DEPTH 10
50 #ifndef _ASM
52 #define TTR_PAD1_SIZE (sizeof (long) - 1)
54 typedef struct {
55 uintptr_t ttc_next;
56 uintptr_t ttc_first;
57 uintptr_t ttc_limit;
58 uintptr_t ttc_current;
59 } trap_trace_ctl_t;
61 typedef struct {
62 struct regs ttr_regs;
63 greg_t ttr_cr2;
64 union _ttr_info {
65 struct _idt_entry {
66 int cpuid;
67 short vector;
68 uchar_t ipl;
69 uchar_t spl;
70 uchar_t pri;
71 } idt_entry;
72 struct _gate_entry {
73 int sysnum;
74 } gate_entry;
75 } ttr_info;
76 uintptr_t ttr_curthread;
77 uchar_t ttr_pad[TTR_PAD1_SIZE];
78 uchar_t ttr_marker;
79 hrtime_t ttr_stamp;
80 int ttr_sdepth;
81 pc_t ttr_stack[TTR_STACK_DEPTH];
82 } trap_trace_rec_t;
84 #define ttr_cpuid ttr_info.idt_entry.cpuid
85 #define ttr_vector ttr_info.idt_entry.vector
86 #define ttr_ipl ttr_info.idt_entry.ipl
87 #define ttr_spl ttr_info.idt_entry.spl
88 #define ttr_pri ttr_info.idt_entry.pri
89 #define ttr_sysnum ttr_info.gate_entry.sysnum
91 #define TRAPTR_NENT 128
93 extern trap_trace_ctl_t trap_trace_ctl[NCPU]; /* Allocated in locore.s */
94 extern size_t trap_trace_bufsize;
95 extern int trap_trace_freeze;
96 extern trap_trace_rec_t trap_trace_postmort; /* Entry used after death */
98 #define TRAPTRACE_FREEZE trap_trace_freeze = 1;
99 #define TRAPTRACE_UNFREEZE trap_trace_freeze = 0;
101 #else /* _ASM */
104 * ptr -- will be set to a TRAPTRACE entry.
105 * scr1 -- scratch
106 * scr1_32 -- 32-bit version of scr1
107 * scr2 -- scratch
108 * marker -- register containing byte to store in marker field of entry
110 * Note that this macro defines labels "8" and "9".
112 #ifdef TRAPTRACE
114 #if defined(__amd64)
116 #define TRACE_PTR(ptr, scr1, scr1_32, scr2, marker) \
117 leaq trap_trace_postmort(%rip), ptr; \
118 cmpl $0, trap_trace_freeze(%rip); \
119 jne 9f; \
120 LOADCPU(ptr); \
121 movl CPU_ID(ptr), scr1_32; \
122 shlq $TRAPTR_SIZE_SHIFT, scr1; \
123 leaq trap_trace_ctl(%rip), scr2; \
124 addq scr2, scr1; \
125 movq TRAPTR_NEXT(scr1), ptr; \
126 leaq TRAP_ENT_SIZE(ptr), scr2; \
127 cmpq TRAPTR_LIMIT(scr1), scr2; \
128 jl 8f; \
129 movq TRAPTR_FIRST(scr1), scr2; \
130 8: movq scr2, TRAPTR_NEXT(scr1); \
131 9: movb marker, TTR_MARKER(ptr);
133 #elif defined(__i386)
135 #define TRACE_PTR(ptr, scr1, scr1_32, scr2, marker) \
136 movl $trap_trace_postmort, ptr; \
137 cmpl $0, trap_trace_freeze; \
138 jne 9f; \
139 LOADCPU(ptr); \
140 movl CPU_ID(ptr), scr1_32; \
141 shll $TRAPTR_SIZE_SHIFT, scr1; \
142 addl $trap_trace_ctl, scr1; \
143 movl TRAPTR_NEXT(scr1), ptr; \
144 leal TRAP_ENT_SIZE(ptr), scr2; \
145 cmpl TRAPTR_LIMIT(scr1), scr2; \
146 jl 8f; \
147 movl TRAPTR_FIRST(scr1), scr2; \
148 8: movl scr2, TRAPTR_NEXT(scr1); \
149 9: movb marker, TTR_MARKER(ptr);
151 #endif /* __i386 */
154 * ptr -- pointer to the current TRAPTRACE entry.
155 * reg -- pointer to the stored registers; must be on the stack
156 * scr1 -- scratch used as array index
157 * scr2 -- scratch used as temporary
159 * Note that this macro defines label "9".
160 * Also captures curthread on exit of loop.
162 #if defined(__xpv)
163 #define __GETCR2(_mov, reg) \
164 _mov %gs:CPU_VCPU_INFO, reg; \
165 _mov VCPU_INFO_ARCH_CR2(reg), reg
166 #else
167 #define __GETCR2(_mov, reg) \
168 _mov %cr2, reg
169 #endif
171 #if defined(__amd64)
173 #define TRACE_REGS(ptr, reg, scr1, scr2) \
174 xorq scr1, scr1; \
175 /*CSTYLED*/ \
176 9: movq (reg, scr1, 1), scr2; \
177 movq scr2, (ptr, scr1, 1); \
178 addq $CLONGSIZE, scr1; \
179 cmpq $REGSIZE, scr1; \
180 jl 9b; \
181 movq %gs:CPU_THREAD, scr2; \
182 movq scr2, TTR_CURTHREAD(ptr); \
183 __GETCR2(movq, scr2); \
184 movq scr2, TTR_CR2(ptr)
186 #elif defined(__i386)
188 #define TRACE_REGS(ptr, reg, scr1, scr2) \
189 xorl scr1, scr1; \
190 /*CSTYLED*/ \
191 9: movl (reg, scr1, 1), scr2; \
192 movl scr2, (ptr, scr1, 1); \
193 addl $CLONGSIZE, scr1; \
194 cmpl $REGSIZE, scr1; \
195 jl 9b; \
196 movl %gs:CPU_THREAD, scr2; \
197 movl scr2, TTR_CURTHREAD(ptr); \
198 __GETCR2(movl, scr2); \
199 movl scr2, TTR_CR2(ptr)
201 #endif /* __i386 */
204 * The time stamp macro records a high-resolution time stamp for the
205 * given TRAPTRACE entry. Note that %eax and %edx are plowed by this
206 * macro; if they are to be preserved, it's up to the caller of the macro.
209 #if defined(__amd64)
211 #define TRACE_STAMP(reg) \
212 rdtsc; \
213 movl %eax, TTR_STAMP(reg); \
214 movl %edx, TTR_STAMP+4(reg)
217 * %rbp should be set before invoking this macro.
220 #define TRACE_STACK(tt) \
221 pushq %rdi; \
222 pushq %rsi; \
223 pushq %rdx; \
224 pushq %rcx; \
225 pushq %r8; \
226 pushq %r9; \
227 pushq %rax; \
228 pushq %r12; \
229 movq tt, %r12; \
230 leaq TTR_STACK(%r12), %rdi; \
231 movl $TTR_STACK_DEPTH, %esi; \
232 call getpcstack; \
233 movl %eax, TTR_SDEPTH(%r12); \
234 popq %r12; \
235 popq %rax; \
236 popq %r9; \
237 popq %r8; \
238 popq %rcx; \
239 popq %rdx; \
240 popq %rsi; \
241 popq %rdi
243 #elif defined(__i386)
245 #define TRACE_STAMP(reg) \
246 xorl %eax, %eax; \
247 xorl %edx, %edx; \
248 btl $X86FSET_TSC, x86_featureset; \
249 jnc 9f; \
250 rdtsc; \
251 9: movl %eax, TTR_STAMP(reg); \
252 movl %edx, TTR_STAMP+4(reg)
254 #define TRACE_STACK(tt) \
255 pushl %eax; \
256 pushl %ecx; \
257 pushl %edx; \
258 pushl %ebx; \
259 pushl $TTR_STACK_DEPTH; \
260 movl tt, %ebx; \
261 leal TTR_STACK(%ebx), %eax; \
262 pushl %eax; \
263 call getpcstack; \
264 addl $8, %esp; \
265 movl %eax, TTR_SDEPTH(%ebx); \
266 popl %ebx; \
267 popl %edx; \
268 popl %ecx; \
269 popl %eax
271 #endif /* __i386 */
273 #else
275 #define TRACE_PTR(ptr, scr1, scr1_32, scr2, marker)
276 #define TRACE_REGS(ptr, reg, scr1, scr2)
277 #define TRACE_STAMP(reg)
278 #define TRACE_STACK(reg)
280 #endif /* TRAPTRACE */
282 #endif /* _ASM */
284 #define TT_SYSCALL 0xaa /* system call via lcall */
285 #define TT_SYSENTER 0xab /* system call via sysenter */
286 #define TT_SYSC 0xad /* system call via syscall (32-bit) */
287 #define TT_SYSC64 0xae /* system call via syscall (64-bit) */
288 #define TT_INTERRUPT 0xbb
289 #define TT_TRAP 0xcc
290 #define TT_INTTRAP 0xdd
291 #define TT_EVENT 0xee /* hypervisor event */
293 #ifdef __cplusplus
295 #endif
297 #endif /* _IA32_SYS_TRAPTRACE_H */