xref: /xnu-8020.121.3/bsd/sys/kdebug_private.h (revision fdd8201d7b966f0c3ea610489d29bd841d358941)
1 /*
2  * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 
29 #ifndef BSD_KDEBUG_PRIVATE_H
30 #define BSD_KDEBUG_PRIVATE_H
31 
32 #include <stdint.h>
33 #include <stdbool.h>
34 #include <sys/cdefs.h>
35 #include <sys/kdebug.h>
36 
37 __BEGIN_DECLS
38 
39 #if !KERNEL
40 
41 #include <Availability.h>
42 
43 #pragma mark - user space SPI
44 
45 /*
46  * OS components can use the full precision of the "code" field
47  * (Class, SubClass, Code) to inject events using kdebug_trace() by
48  * using:
49  *
50  * kdebug_trace(KDBG_CODE(DBG_XPC, 15, 1) | DBG_FUNC_NONE, 1, 2, 3, 4);
51  *
52  * These trace points can be included in production code, since they
53  * use reserved, non-overlapping ranges.  The performance impact when
54  * kernel tracing is not enabled is minimal.  However, when tracing is enabled,
55  * each tracepoint becomes a syscall.  For this reason, os_signpost(3) is
56  * recommended instead of kdebug_trace(2).
57  *
58  * Classes can be reserved by filing a Radar in xnu | ktrace.
59  *
60  * 64-bit arguments may be truncated if the system is using a 32-bit
61  * kernel.
62  *
63  * On error, -1 will be returned and errno will indicate the error.
64  */
65 int kdebug_trace(uint32_t code, uint64_t arg1, uint64_t arg2, uint64_t arg3,
66     uint64_t arg4)
67 __OSX_AVAILABLE(10.10) __IOS_AVAILABLE(8.2);
68 
69 /*!
70  * @function kdebug_trace_string
71  *
72  * @discussion
73  * This function emits strings to kdebug trace along with an ID and allows
74  * for previously-traced strings to be overwritten and invalidated.
75  *
76  * To start tracing a string and generate an ID to use to refer to it:
77  *
78  *      string_id = kdebug_trace_string(debugid, 0, "string");
79  *
80  * To replace a string previously traced:
81  *
82  *      string_id = kdebug_trace_string(debugid, string_id, "new string");
83  *
84  * To invalidate a string ID:
85  *
86  *      string_id = kdebug_trace_string(debugid, string_id, NULL);
87  *
88  * To check for errors:
89  *
90  *      if ((int64_t)string_id == -1) { perror("string error") }
91  *
92  * @param debugid
93  * The `debugid` to check if its enabled before tracing and include as
94  * an argument in the event containing the string.
95  *
96  * Some classes or subclasses are reserved for specific uses and are not
97  * allowed to be used with this function.  No function qualifiers are
98  * allowed on `debugid`.
99  *
100  * @param str_id
101  * When 0, a new ID will be generated and returned if tracing is
102  * enabled.
103  *
104  * Otherwise `str_id` must contain an ID that was previously generated
105  * with this function.  Clents should pass NULL in `str` if `str_id`
106  * is no longer in use.  Otherwise, the string previously mapped to
107  * `str_id` will be overwritten with the contents of `str`.
108  *
109  * @param str
110  * A NUL-terminated 'C' string containing the characters that should be
111  * traced alongside `str_id`.
112  *
113  * If necessary, the string will be truncated at an
114  * implementation-defined length of at least PATH_MAX characters.  The string
115  * must not be the empty string, but can be NULL if a valid `str_id` is
116  * provided.
117  *
118  * @return
119  * 0 if tracing is disabled or `debugid` is being filtered out of trace.
120  * It can also return (int64_t)-1 if an error occured. Otherwise,
121  * it returns the ID to use to refer to the string in future
122  * kdebug_trace(2) calls.
123  *
124  * The errors that can occur are:
125  *
126  * EINVAL
127  *      There are function qualifiers on `debugid`, `str` is empty, or
128  *      `str_id` was not generated by this function.
129  * EPERM
130  *      The `debugid`'s class or subclass is reserved for internal use.
131  * EFAULT
132  *      `str` is an invalid address or NULL when `str_id` is 0.
133  */
134 extern uint64_t kdebug_trace_string(uint32_t debugid, uint64_t str_id,
135     const char *str)
136 __OSX_AVAILABLE(10.11) __IOS_AVAILABLE(9.0);
137 
138 /*
139  * Although the performance impact of kdebug_trace() when kernel
140  * tracing is not enabled is minimal, it may require the caller to
141  * perform an expensive calculation/summarization. This cost can be
142  * skipped by checking the kdebug_is_enabled() predicate:
143  *
144  * if (kdebug_is_enabled(KDBG_CODE(DBG_XPC, 15, 1))) {
145  *     uint64_t arg1 = ...;
146  *     uint64_t arg2 = ...;
147  *     kdebug_trace(KDBG_CODE(DBG_XPC, 15, 1) | DBG_FUNC_NONE, arg1, arg2, 0, 0);
148  * }
149  *
150  * If tracing is enabled for the code at the time of the check, 1
151  * will be returned. Otherwise, 0 will be returned.
152  */
153 extern bool kdebug_is_enabled(uint32_t code)
154 __API_AVAILABLE(macos(10.12), ios(10), watchos(3), tvos(10));
155 
156 /*
157  * Returns a pointer to the userspace typefilter, if one is available.
158  * May return NULL.
159  */
160 extern void *kdebug_typefilter(void)
161 __API_AVAILABLE(macos(10.12), ios(10), watchos(3), tvos(10));
162 
163 /*
164  * Returns true if kdebug is using continuous time for its events, and false
165  * otherwise.
166  */
167 extern bool kdebug_using_continuous_time(void)
168 __API_AVAILABLE(macos(10.15), ios(13), tvos(13), watchos(6));
169 
170 /*
171  * Convert an absolute time to a kdebug timestamp.
172  */
173 extern uint64_t kdebug_timestamp_from_absolute(uint64_t abstime)
174 __API_AVAILABLE(macos(12), ios(15), tvos(15), watchos(8));
175 
176 /*
177  * Convert a continuous time to a kdebug timestamp.
178  */
179 extern uint64_t kdebug_timestamp_from_continuous(uint64_t conttime)
180 __API_AVAILABLE(macos(12), ios(15), tvos(15), watchos(8));
181 
182 /*
183  * Capture a kdebug timestamp for the current time.
184  */
185 extern uint64_t kdebug_timestamp(void)
186 __API_AVAILABLE(macos(12), ios(15), tvos(15), watchos(8));
187 
188 #endif /* !KERNEL */
189 
190 #pragma mark - private debugids
191 
192 #define DBG_PPT         36
193 #define DBG_PERFCTRL    39
194 #define DBG_CLPC        50
195 #define DBG_MUSE        52
196 
197 /* **** 128 to 139 are reserved for IOP tracing **** */
198 #define DBG_ANS         128
199 #define DBG_SIO         129
200 #define DBG_SEP         130
201 #define DBG_ISP         131
202 #define DBG_OSCAR       132
203 #define DBG_EMBEDDEDGFX 133
204 #define DBG_PMP         134
205 #define DBG_RTKIT       135
206 
207 #define MACH_BRIDGE_RCV_TS      0x1     /* receive timestamp pair from interrupt handler */
208 #define MACH_BRIDGE_REMOTE_TIME 0x2     /* calculate remote timestamp */
209 #define MACH_BRIDGE_RESET_TS    0x3     /* reset timestamp conversion parameters */
210 #define MACH_BRIDGE_TS_PARAMS   0x4     /* recompute timestamp conversion parameters */
211 #define MACH_BRIDGE_SKIP_TS     0x5     /* skip timestamp */
212 #define MACH_BRIDGE_TS_MISMATCH 0x6     /* mismatch between predicted and received remote timestamp */
213 #define MACH_BRIDGE_OBSV_RATE   0x7     /* out of range observed rates */
214 
215 /* DBG_SKYWALK has same toplevel code as DBG_DLIL, so don't reuse subcodes */
216 #define DBG_SKYWALK_ALWAYSON    0x10
217 #define DBG_SKYWALK_FLOWSWITCH  0x11
218 #define DBG_SKYWALK_NETIF       0x12
219 #define DBG_SKYWALK_CHANNEL     0x13
220 #define DBG_SKYWALK_PACKET      0x14
221 
222 #define PPT_TEST            0x01
223 #define PPT_JETSAM_HIWAT    0x02
224 #define PPT_JETSAM_TOPPROC  0x03
225 
226 #define SKYWALKDBG_CODE(SubClass, code) KDBG_CODE(DBG_DLIL, SubClass, code)
227 #define PPTDBG_CODE(SubClass, code) KDBG_CODE(DBG_PPT, SubClass, code)
228 #define PERFCTRL_CODE(SubClass, code) KDBG_CODE(DBG_PERFCTRL, SubClass, code)
229 
230 #if !defined(DRIVERKIT)
231 
232 extern unsigned int kdebug_enable;
233 
234 /*
235  * Bits used by kdebug_enable.  These used to control which events are traced at
236  * runtime.
237  */
238 #define KDEBUG_ENABLE_TRACE     0x001U
239 /*
240  * If set, the timestamps in events are expected to be continuous times.
241  * Otherwise, the timestamps are absolute times.  IOPs should observe this bit
242  * in order to log events that can be merged cleanly with other event streams.
243  */
244 #define KDEBUG_ENABLE_CONT_TIME 0x020U
245 
246 #define KDEBUG_TRACE (KDEBUG_ENABLE_TRACE)
247 
248 /* obsolete kdebug_enable bits */
249 #define KDEBUG_ENABLE_ENTROPY   0x002U
250 #define KDEBUG_ENABLE_CHUD      0x004U
251 #define KDEBUG_ENABLE_PPT       0x008U
252 #define KDEBUG_ENABLE_SERIAL    0x010U
253 #define KDEBUG_PPT    (KDEBUG_ENABLE_PPT)
254 #define KDEBUG_COMMON (KDEBUG_ENABLE_TRACE | KDEBUG_ENABLE_PPT)
255 
256 /*
257  * The kernel debug configuration level.  These values control which events are
258  * compiled in under different build configurations.
259  *
260  * Infer the supported kernel debug event level from config option.  Use
261  * (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD) as a guard to protect unaudited debug
262  * code.
263  */
264 #define KDEBUG_LEVEL_NONE     0
265 #define KDEBUG_LEVEL_IST      1
266 #define KDEBUG_LEVEL_STANDARD 2
267 #define KDEBUG_LEVEL_FULL     3
268 
269 #if NO_KDEBUG
270 #define KDEBUG_LEVEL KDEBUG_LEVEL_NONE
271 #elif IST_KDEBUG
272 #define KDEBUG_LEVEL KDEBUG_LEVEL_IST
273 #elif KDEBUG
274 #define KDEBUG_LEVEL KDEBUG_LEVEL_FULL
275 #else
276 #define KDEBUG_LEVEL KDEBUG_LEVEL_STANDARD
277 /*
278  * Currently, all other kernel configurations (development, etc) build with
279  * KDEBUG_LEVEL_STANDARD.
280  */
281 #endif
282 
283 /*
284  * Some Apple internal clients try to use the kernel macros in user space.
285  */
286 #ifndef KERNEL_DEBUG
287 #define KERNEL_DEBUG(...) do { } while (0)
288 #endif /* !defined(KERNEL_DEBUG) */
289 
290 #pragma mark - private definitions
291 
292 /*
293  * Ensure that both LP32 and LP64 variants of arm64 use the same kd_buf
294  * structure.
295  */
296 #if defined(__arm64__)
297 typedef uint64_t kd_buf_argtype;
298 #else
299 typedef uintptr_t kd_buf_argtype;
300 #endif
301 
302 /*
303  * The main event ABI as recorded in the kernel.
304  */
305 
306 typedef struct {
307 	uint64_t timestamp;
308 	kd_buf_argtype arg1;
309 	kd_buf_argtype arg2;
310 	kd_buf_argtype arg3;
311 	kd_buf_argtype arg4;
312 	kd_buf_argtype arg5; /* the thread ID */
313 	uint32_t debugid;
314 /*
315  * Ensure that both LP32 and LP64 variants of arm64 use the same kd_buf
316  * structure.
317  */
318 #if defined(__LP64__) || defined(__arm64__)
319 	uint32_t cpuid;
320 	kd_buf_argtype unused;
321 #endif
322 } kd_buf;
323 
324 #if defined(__LP64__) || defined(__arm64__)
325 #define KDBG_TIMESTAMP_MASK 0xffffffffffffffffULL
326 static inline void
kdbg_set_cpu(kd_buf * kp,int cpu)327 kdbg_set_cpu(kd_buf *kp, int cpu)
328 {
329 	kp->cpuid = (unsigned int)cpu;
330 }
331 static inline int
kdbg_get_cpu(kd_buf * kp)332 kdbg_get_cpu(kd_buf *kp)
333 {
334 	return (int)kp->cpuid;
335 }
336 static inline void
kdbg_set_timestamp(kd_buf * kp,uint64_t thetime)337 kdbg_set_timestamp(kd_buf *kp, uint64_t thetime)
338 {
339 	kp->timestamp = thetime;
340 }
341 static inline uint64_t
kdbg_get_timestamp(kd_buf * kp)342 kdbg_get_timestamp(kd_buf *kp)
343 {
344 	return kp->timestamp;
345 }
346 static inline void
kdbg_set_timestamp_and_cpu(kd_buf * kp,uint64_t thetime,int cpu)347 kdbg_set_timestamp_and_cpu(kd_buf *kp, uint64_t thetime, int cpu)
348 {
349 	kdbg_set_timestamp(kp, thetime);
350 	kdbg_set_cpu(kp, cpu);
351 }
352 #else
353 #define KDBG_TIMESTAMP_MASK 0x00ffffffffffffffULL
354 #define KDBG_CPU_MASK       0xff00000000000000ULL
355 #define KDBG_CPU_SHIFT      56
356 static inline void
kdbg_set_cpu(kd_buf * kp,int cpu)357 kdbg_set_cpu(kd_buf *kp, int cpu)
358 {
359 	kp->timestamp = (kp->timestamp & KDBG_TIMESTAMP_MASK) |
360 	    (((uint64_t) cpu) << KDBG_CPU_SHIFT);
361 }
362 static inline int
kdbg_get_cpu(kd_buf * kp)363 kdbg_get_cpu(kd_buf *kp)
364 {
365 	return (int) (((kp)->timestamp & KDBG_CPU_MASK) >> KDBG_CPU_SHIFT);
366 }
367 static inline void
kdbg_set_timestamp(kd_buf * kp,uint64_t thetime)368 kdbg_set_timestamp(kd_buf *kp, uint64_t thetime)
369 {
370 	kp->timestamp = thetime & KDBG_TIMESTAMP_MASK;
371 }
372 static inline uint64_t
kdbg_get_timestamp(kd_buf * kp)373 kdbg_get_timestamp(kd_buf *kp)
374 {
375 	return kp->timestamp & KDBG_TIMESTAMP_MASK;
376 }
377 static inline void
kdbg_set_timestamp_and_cpu(kd_buf * kp,uint64_t thetime,int cpu)378 kdbg_set_timestamp_and_cpu(kd_buf *kp, uint64_t thetime, int cpu)
379 {
380 	kp->timestamp = (thetime & KDBG_TIMESTAMP_MASK) |
381 	    (((uint64_t) cpu) << KDBG_CPU_SHIFT);
382 }
383 #endif
384 
385 /*
386  * 2^16 bits (8 kilobytes), one for each possible class/subclass combination
387  */
388 #define KDBG_TYPEFILTER_BITMAP_SIZE ((256 * 256) / 8)
389 
390 /*
391  * Bits for kd_ctrl_page.flags, KERN_KD{D,E}FLAGS.
392  */
393 /* disable tracing when buffers are full */
394 #define KDBG_NOWRAP          0x0002
395 /* buffer has wrapped */
396 #define KDBG_WRAPPED         0x0008
397 /* only include processes with kdebug bit set in proc */
398 #define KDBG_PIDCHECK        0x0010
399 /* thread map is initialized */
400 #define KDBG_MAPINIT         0x0020
401 /* exclude processes based on kdebug bit in proc */
402 #define KDBG_PIDEXCLUDE      0x0040
403 /* whether the kdebug locks are intialized */
404 #define KDBG_LOCKINIT        0x0080
405 /* word size of the kernel */
406 #define KDBG_LP64            0x0100
407 /* whether timestamps are in continuous time */
408 #define KDBG_CONTINUOUS_TIME 0x0200
409 /* coprocessor tracing is disabled */
410 #define KDBG_DISABLE_COPROCS 0x0400
411 /* check each event against matcher to disable tracing */
412 #define KDBG_MATCH_DISABLE   0x0800
413 
414 /* flags that are allowed to be set by user space */
415 #define KDBG_USERFLAGS  (KDBG_NOWRAP | KDBG_CONTINUOUS_TIME | KDBG_DISABLE_COPROCS | KDBG_MATCH_DISABLE)
416 
417 /* bits for kd_ctrl_page.flags and kbufinfo_t.flags */
418 
419 /* only trace events within a range */
420 #define KDBG_RANGECHECK       0x00100000U
421 /* only trace at most 4 types of events, at the code granularity */
422 #define KDBG_VALCHECK         0x00200000U
423 /* check class and subclass against the typefilter */
424 #define KDBG_TYPEFILTER_CHECK 0x00400000U
425 /* we are going to use 64-bit debugid in arg4 */
426 #define KDBG_DEBUGID_64       0x00800000U
427 /* kdebug trace buffers are initialized */
428 #define KDBG_BUFINIT          0x80000000U
429 
430 /* bits for the type field of kd_regtype */
431 #define KDBG_CLASSTYPE  0x10000
432 #define KDBG_SUBCLSTYPE 0x20000
433 #define KDBG_RANGETYPE  0x40000
434 #define KDBG_TYPENONE   0x80000
435 #define KDBG_CKTYPES    0xF0000
436 
437 typedef struct {
438 	unsigned int type;
439 	unsigned int value1;
440 	unsigned int value2;
441 	unsigned int value3;
442 	unsigned int value4;
443 } kd_regtype;
444 
445 typedef struct {
446 	/* number of events that can fit in the buffers */
447 	int nkdbufs;
448 	/* set if trace is disabled */
449 	int nolog;
450 	/* kd_ctrl_page.flags */
451 	unsigned int flags;
452 	/* number of threads in thread map */
453 	int nkdthreads;
454 	/* the owning pid */
455 	int bufid;
456 } kbufinfo_t;
457 
458 typedef struct {
459 	/* the thread ID */
460 #if defined(__arm64__)
461 	uint64_t thread;
462 #else
463 	uintptr_t thread __kernel_data_semantics;
464 #endif
465 	/* 0 for invalid, otherwise the PID (or 1 for kernel_task) */
466 	int valid;
467 	/* the name of the process owning the thread */
468 	char command[20];
469 } kd_threadmap;
470 
471 typedef struct {
472 	uint32_t version_no;
473 	uint32_t cpu_count;
474 } kd_cpumap_header;
475 
476 /* cpumap flags */
477 #define KDBG_CPUMAP_IS_IOP      0x1
478 
479 typedef struct {
480 	uint32_t cpu_id;
481 	uint32_t flags;
482 	char name[8];
483 } kd_cpumap;
484 
485 typedef struct {
486 	uint32_t cpu_id;
487 	uint32_t flags;
488 	char name[32];
489 } kd_cpumap_ext;
490 
491 typedef struct {
492 	int             version_no;
493 	int             thread_count;
494 	uint64_t        TOD_secs;
495 	uint32_t        TOD_usecs;
496 } RAW_header;
497 
498 typedef struct {
499 	uint32_t kem_debugid;
500 	uint32_t kem_padding;
501 	uint64_t kem_args[4];
502 } kd_event_matcher;
503 
504 /*
505  * Bits set in the comm page for kdebug.
506  */
507 #define KDEBUG_COMMPAGE_ENABLE_TRACE      0x1
508 #define KDEBUG_COMMPAGE_ENABLE_TYPEFILTER 0x2 /* Forced to false if ENABLE_TRACE is 0 */
509 #define KDEBUG_COMMPAGE_CONTINUOUS        0x4 /* Forced to false if ENABLE_TRACE is 0 */
510 
511 #pragma mark - Tests
512 
513 enum kdebug_test {
514 	KDTEST_KERNEL_MACROS = 1,
515 	KDTEST_OLD_TIMESTAMP = 2,
516 	KDTEST_FUTURE_TIMESTAMP = 3,
517 	KDTEST_SETUP_IOP = 4,
518 	KDTEST_SETUP_COPROCESSOR = 5,
519 	KDTEST_CONTINUOUS_TIMESTAMP = 6,
520 	KDTEST_ABSOLUTE_TIMESTAMP = 7,
521 };
522 
523 #pragma mark - Obsolete interfaces
524 
525 /* obsolete KERN_KD[DE]FLAGS flags */
526 #define KDBG_INIT              0x01
527 #define KDBG_FREERUN           0x04
528 
529 /* Obsolete IDs for trace files. */
530 #define RAW_VERSION0    0x55aa0000
531 #define RAW_VERSION1    0x55aa0101
532 #define RAW_VERSION2    0x55aa0200
533 
534 /* for EnergyTracing user space & clients */
535 #define kEnTrCompKernel     2
536 
537 /*
538  * EnergyTracing opcodes
539  *
540  * Activations use DBG_FUNC_START/END.
541  * Events are DBG_FUNC_NONE.
542  */
543 
544 /* Socket reads and writes are uniquely identified by the (sanitized)
545  *  pointer to the socket struct in question.  To associate this address
546  *  with the user space file descriptor, we have a socket activation with
547  *  the FD as its identifier and the socket struct pointer as its value.
548  */
549 #define kEnTrActKernSocket      1
550 #define kEnTrActKernSockRead    2
551 #define kEnTrActKernSockWrite   3
552 
553 #define kEnTrActKernPoll        10
554 #define kEnTrActKernSelect      11
555 #define kEnTrActKernKQWait      12
556 
557 #define kEnTrEvUnblocked        256
558 
559 /* Lower 16-bits of quality. */
560 #define kEnTrFlagNonBlocking    1 << 0
561 #define kEnTrFlagNoWork         1 << 1
562 
563 /*
564  * EnergyTracing macros.
565  */
566 
567 #if (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST)
568 #define ENTR_SHOULDTRACE kdebug_enable
569 #define ENTR_KDTRACE(component, opcode, lifespan, id, quality, value)   \
570 do {                                                                    \
571     uint32_t kdcode__;                                                  \
572     uintptr_t highval__, lowval__, mask__ = 0xffffffff;                 \
573     kdcode__ = KDBG_CODE(DBG_ENERGYTRACE,component,opcode)|(lifespan);  \
574     highval__ = ((value) >> 32) & mask__;                               \
575     lowval__ = (value) & mask__;                                        \
576     ENTR_KDTRACEFUNC(kdcode__, id, quality, highval__, lowval__);       \
577 } while(0)
578 
579 /*
580  *   Trace the association of two existing activations.
581  *
582  *   An association is traced as a modification to the parent activation.
583  *   In order to fit the sub-activation's component, activation code, and
584  *   activation ID into a kdebug tracepoint, the arguments that would hold
585  *   the value are left separate, and one stores the component and opcode
586  *   of the sub-activation, while the other stores the pointer-sized
587  *   activation ID.
588  *
589  *           arg2                   arg3               arg4
590  +-----------------+  +~+----+----+--------+   +----------+
591  |kEnTrModAssociate|  | |    |    |        |   |          |
592  +-----------------+  +~+----+----+--------+   +----------+
593  *                           8-bits unused       sub-activation ID
594  *                                8-bit sub-component
595  *                                     16-bit sub-opcode
596  *
597  */
598 #define kEnTrModAssociate (1 << 28)
599 #define ENTR_KDASSOCIATE(par_comp, par_opcode, par_act_id,              \
600 	    sub_comp, sub_opcode, sub_act_id)              \
601 do {                                                                    \
602     unsigned sub_compcode = ((unsigned)sub_comp << 16) | sub_opcode;    \
603     ENTR_KDTRACEFUNC(KDBG_CODE(DBG_ENERGYTRACE,par_comp,par_opcode),    \
604 	             par_act_id, kEnTrModAssociate, sub_compcode,       \
605 	             sub_act_id);                                       \
606 } while(0)
607 
608 #else /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST) */
609 
610 #define ENTR_SHOULDTRACE FALSE
611 #define ENTR_KDTRACE(component, opcode, lifespan, id, quality, value)   \
612 	                            do {} while (0)
613 #define ENTR_KDASSOCIATE(par_comp, par_opcode, par_act_id,              \
614 	    sub_comp, sub_opcode, sub_act_id)              \
615 	                            do {} while (0)
616 
617 #endif /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST) */
618 
619 #endif /* !defined(DRIVERKIT) */
620 
621 __END_DECLS
622 
623 #endif /* !defined(BSD_KDEBUG_PRIVATE_H) */
624