1 | /* |
2 | * Copyright (c) 2000-2021 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 <os/base.h> |
33 | #include <stdint.h> |
34 | #include <stdbool.h> |
35 | #include <sys/cdefs.h> |
36 | #include <sys/kdebug.h> |
37 | |
38 | #if !KERNEL |
39 | |
40 | #include <Availability.h> |
41 | |
42 | __BEGIN_DECLS |
43 | |
44 | #pragma mark - User space SPI |
45 | |
46 | // Internal software can trace events into kdebug, but the os_signpost(3) |
47 | // interfaces in `<os/signpost.h>` are recommended. |
48 | // |
49 | // kdebug_trace(KDBG_EVENTID(DBG_XPC, 15, 1), 1, 2, 3, 4); |
50 | // |
51 | // The performance impact when kernel tracing is not enabled is minimal. |
52 | // However, when tracing is enabled, each event requires a syscall. |
53 | // |
54 | // Classes can be reserved by filing a Radar in xnu | ktrace. |
55 | // |
56 | // 64-bit arguments may be truncated if the system is using a 32-bit kernel. |
57 | // |
58 | // On error, -1 will be returned and errno will indicate the error. |
59 | int kdebug_trace(uint32_t debugid, uint64_t arg1, uint64_t arg2, uint64_t arg3, |
60 | uint64_t arg4) |
61 | __API_AVAILABLE(macos(10.0), ios(8), tvos(8), watchos(1)); |
62 | |
63 | // Although the performance impact of kdebug_trace() when tracing is disabled is |
64 | // minimal, it may require the caller to perform an expensive calculation or |
65 | // summarization. This cost can be skipped by checking the kdebug_is_enabled() |
66 | // predicate: |
67 | // |
68 | // if (kdebug_is_enabled(KDBG_CODE(DBG_XPC, 15, 1))) { |
69 | // uint64_t arg1 = ...; |
70 | // uint64_t arg2 = ...; |
71 | // kdebug_trace(KDBG_EVENTID(DBG_XPC, 15, 1), arg1, arg2, 0, 0); |
72 | // } |
73 | // |
74 | // true is returned iff tracing is enabled for the debug ID at the time of the |
75 | // check. |
76 | extern bool kdebug_is_enabled(uint32_t debugid) |
77 | __API_AVAILABLE(macos(10.12), ios(10), watchos(3), tvos(10)); |
78 | |
79 | // Returns true if kdebug is using continuous time for its events, and false |
80 | // otherwise. |
81 | extern bool kdebug_using_continuous_time(void) |
82 | __API_AVAILABLE(macos(10.15), ios(13), tvos(13), watchos(6)); |
83 | |
84 | // Convert an absolute time to a kdebug timestamp. |
85 | extern uint64_t kdebug_timestamp_from_absolute(uint64_t abstime) |
86 | __API_AVAILABLE(macos(12), ios(15), tvos(15), watchos(8)); |
87 | |
88 | // Convert a continuous time to a kdebug timestamp. |
89 | extern uint64_t kdebug_timestamp_from_continuous(uint64_t conttime) |
90 | __API_AVAILABLE(macos(12), ios(15), tvos(15), watchos(8)); |
91 | |
92 | // Capture a kdebug timestamp for the current time. |
93 | extern uint64_t kdebug_timestamp(void) |
94 | __API_AVAILABLE(macos(12), ios(15), tvos(15), watchos(8)); |
95 | |
96 | /// @function kdebug_trace_string |
97 | /// |
98 | /// @discussion |
99 | /// This function emits strings to kdebug trace along with an ID and allows |
100 | /// for previously-traced strings to be overwritten and invalidated. |
101 | /// |
102 | /// To start tracing a string and generate an ID to use to refer to it: |
103 | /// |
104 | /// string_id = kdebug_trace_string(debugid, 0, "string"); |
105 | /// |
106 | /// To replace a string previously traced: |
107 | /// |
108 | /// string_id = kdebug_trace_string(debugid, string_id, "new string"); |
109 | /// |
110 | /// To invalidate a string ID: |
111 | /// |
112 | /// string_id = kdebug_trace_string(debugid, string_id, NULL); |
113 | /// |
114 | /// To check for errors: |
115 | /// |
116 | /// if ((int64_t)string_id == -1) { perror("string error") } |
117 | /// |
118 | /// @param debugid |
119 | /// The `debugid` to check if its enabled before tracing and include as |
120 | /// an argument in the event containing the string. |
121 | /// |
122 | /// Some classes or subclasses are reserved for specific uses and are not |
123 | /// allowed to be used with this function. No function qualifiers are |
124 | /// allowed on `debugid`. |
125 | /// |
126 | /// @param str_id |
127 | /// When 0, a new ID will be generated and returned if tracing is |
128 | /// enabled. |
129 | /// |
130 | /// Otherwise `str_id` must contain an ID that was previously generated |
131 | /// with this function. Clents should pass NULL in `str` if `str_id` |
132 | /// is no longer in use. Otherwise, the string previously mapped to |
133 | /// `str_id` will be overwritten with the contents of `str`. |
134 | /// |
135 | /// @param str |
136 | /// A NUL-terminated 'C' string containing the characters that should be |
137 | /// traced alongside `str_id`. |
138 | /// |
139 | /// If necessary, the string will be truncated at an |
140 | /// implementation-defined length of at least PATH_MAX characters. The string |
141 | /// must not be the empty string, but can be NULL if a valid `str_id` is |
142 | /// provided. |
143 | /// |
144 | /// @return |
145 | /// 0 if tracing is disabled or `debugid` is being filtered out of trace. |
146 | /// It can also return (int64_t)-1 if an error occured. Otherwise, |
147 | /// it returns the ID to use to refer to the string in future |
148 | /// kdebug_trace(2) calls. |
149 | /// |
150 | /// The errors that can occur are: |
151 | /// |
152 | /// EINVAL |
153 | /// There are function qualifiers on `debugid`, `str` is empty, or |
154 | /// `str_id` was not generated by this function. |
155 | /// EPERM |
156 | /// The `debugid`'s class or subclass is reserved for internal use. |
157 | /// EFAULT |
158 | /// `str` is an invalid address or NULL when `str_id` is 0. |
159 | extern uint64_t kdebug_trace_string(uint32_t debugid, uint64_t str_id, |
160 | const char *str) |
161 | __API_AVAILABLE(macos(10.11), ios(9), watchos(2), tvos(9)); |
162 | |
163 | // Returns a pointer to the userspace typefilter, if one is available. |
164 | // May return NULL. |
165 | extern void *kdebug_typefilter(void) |
166 | __API_AVAILABLE(macos(10.12), ios(10), watchos(3), tvos(10)); |
167 | |
168 | #else |
169 | __BEGIN_DECLS |
170 | #endif /* !KERNEL */ |
171 | |
172 | #pragma mark - Private debug IDs |
173 | |
174 | #define DBG_PPT 36 |
175 | #define DBG_PERFCTRL 39 |
176 | #define DBG_CLPC 50 |
177 | #define DBG_MUSE 52 |
178 | |
179 | #define DBG_ANS 128 |
180 | #define DBG_SIO 129 |
181 | #define DBG_SEP 130 |
182 | #define DBG_ISP 131 |
183 | #define DBG_OSCAR 132 |
184 | #define DBG_EMBEDDEDGFX 133 |
185 | #define DBG_PMP 134 |
186 | #define DBG_RTKIT 135 |
187 | #define DBG_DCP 136 |
188 | #define DBG_KMP 137 |
189 | |
190 | // DBG_SKYWALK is the same as DBG_DLIL, so don't reuse subclasses |
191 | #define DBG_SKYWALK_ALWAYSON 0x10 |
192 | #define DBG_SKYWALK_FLOWSWITCH 0x11 |
193 | #define DBG_SKYWALK_NETIF 0x12 |
194 | #define DBG_SKYWALK_CHANNEL 0x13 |
195 | #define DBG_SKYWALK_PACKET 0x14 |
196 | |
197 | // DBG_AQM is the same as DBG_DLIL and DBG_SKYWALK, so don't reuse subclasses |
198 | #define DBG_AQM_ALWAYSON 0x30 |
199 | #define DBG_AQM_STATS 0x31 |
200 | |
201 | #define PPT_TEST 0x01 |
202 | #define PPT_JETSAM_HIWAT 0x02 |
203 | #define PPT_JETSAM_TOPPROC 0x03 |
204 | |
205 | // DBG_SECURITY private subclasses |
206 | #define DBG_SEC_SSMA 0x02 |
207 | |
208 | #define SKYWALKDBG_CODE(SubClass, code) KDBG_CODE(DBG_DLIL, SubClass, code) |
209 | #define PPTDBG_CODE(SubClass, code) KDBG_CODE(DBG_PPT, SubClass, code) |
210 | #define PERFCTRL_CODE(SubClass, code) KDBG_CODE(DBG_PERFCTRL, SubClass, code) |
211 | #define AQMDBG_CODE(SubClass, code) KDBG_CODE(DBG_DLIL, SubClass, code) |
212 | |
213 | #if !defined(DRIVERKIT) |
214 | |
215 | extern unsigned int kdebug_enable; |
216 | |
217 | // Options for `kdebug_enable`. |
218 | |
219 | // Enable tracing. |
220 | #define KDEBUG_ENABLE_TRACE 0x001U |
221 | // Whether timestamps are continuous times or absolute times. |
222 | #define KDEBUG_ENABLE_CONT_TIME 0x020U |
223 | |
224 | #define KDEBUG_TRACE (KDEBUG_ENABLE_TRACE) |
225 | |
226 | // Control which kernel events are compiled in under different build |
227 | // configurations. |
228 | |
229 | // No kdebug events are emitted with the macros. |
230 | #define KDEBUG_LEVEL_NONE 0 |
231 | // In-System Tracing exposes a limited set of events for release kernels. |
232 | #define KDEBUG_LEVEL_IST 1 |
233 | // The default for development kernels. |
234 | #define KDEBUG_LEVEL_STANDARD 2 |
235 | // Truly verbose, debug-level logging, only set manually. |
236 | #define KDEBUG_LEVEL_FULL 3 |
237 | |
238 | // Use configuration options to set the kdebug level. |
239 | #if NO_KDEBUG |
240 | #define KDEBUG_LEVEL KDEBUG_LEVEL_NONE |
241 | #elif IST_KDEBUG |
242 | #define KDEBUG_LEVEL KDEBUG_LEVEL_IST |
243 | #elif KDEBUG |
244 | #define KDEBUG_LEVEL KDEBUG_LEVEL_FULL |
245 | #else // !NO_KDEBUG && !IST_KDEBUG && !KDEBUG |
246 | #define KDEBUG_LEVEL KDEBUG_LEVEL_STANDARD |
247 | #endif // !NO_KDEBUG && !IST_KDEBUG && !KDEBUG |
248 | |
249 | #pragma mark - Implementation details |
250 | |
251 | // Ensure that LP32 and LP64 variants of arm64 use the same kd_buf structure. |
252 | #if defined(__arm64__) |
253 | typedef uint64_t kd_buf_argtype; |
254 | #else // defined(__arm64__) |
255 | typedef uintptr_t kd_buf_argtype; |
256 | #endif // !defined(__arm64__) |
257 | |
258 | // The main event ABI as recorded in the kernel. |
259 | |
260 | typedef struct { |
261 | uint64_t timestamp; |
262 | kd_buf_argtype arg1; |
263 | kd_buf_argtype arg2; |
264 | kd_buf_argtype arg3; |
265 | kd_buf_argtype arg4; |
266 | kd_buf_argtype arg5; // Always the thread ID. |
267 | uint32_t debugid; |
268 | // Ensure that LP32 and LP64 variants of arm64 use the same kd_buf structure. |
269 | #if defined(__LP64__) || defined(__arm64__) |
270 | uint32_t cpuid; |
271 | kd_buf_argtype unused; |
272 | #endif // defined(__LP64__) || defined(__arm64__) |
273 | } kd_buf; |
274 | |
275 | #if defined(__LP64__) || defined(__arm64__) |
276 | |
277 | #define KDBG_TIMESTAMP_MASK 0xffffffffffffffffULL |
278 | static inline void |
279 | kdbg_set_cpu(kd_buf *kp, int cpu) |
280 | { |
281 | kp->cpuid = (unsigned int)cpu; |
282 | } |
283 | static inline int |
284 | kdbg_get_cpu(kd_buf *kp) |
285 | { |
286 | return (int)kp->cpuid; |
287 | } |
288 | static inline void |
289 | kdbg_set_timestamp(kd_buf *kp, uint64_t thetime) |
290 | { |
291 | kp->timestamp = thetime; |
292 | } |
293 | static inline uint64_t |
294 | kdbg_get_timestamp(kd_buf *kp) |
295 | { |
296 | return kp->timestamp; |
297 | } |
298 | static inline void |
299 | kdbg_set_timestamp_and_cpu(kd_buf *kp, uint64_t thetime, int cpu) |
300 | { |
301 | kdbg_set_timestamp(kp, thetime); |
302 | kdbg_set_cpu(kp, cpu); |
303 | } |
304 | #else // defined(__LP64__) || defined(__arm64__) |
305 | #define KDBG_TIMESTAMP_MASK 0x00ffffffffffffffULL |
306 | #define KDBG_CPU_MASK 0xff00000000000000ULL |
307 | #define KDBG_CPU_SHIFT 56 |
308 | static inline void |
309 | kdbg_set_cpu(kd_buf *kp, int cpu) |
310 | { |
311 | kp->timestamp = (kp->timestamp & KDBG_TIMESTAMP_MASK) | |
312 | (((uint64_t) cpu) << KDBG_CPU_SHIFT); |
313 | } |
314 | static inline int |
315 | kdbg_get_cpu(kd_buf *kp) |
316 | { |
317 | return (int) (((kp)->timestamp & KDBG_CPU_MASK) >> KDBG_CPU_SHIFT); |
318 | } |
319 | static inline void |
320 | kdbg_set_timestamp(kd_buf *kp, uint64_t thetime) |
321 | { |
322 | kp->timestamp = thetime & KDBG_TIMESTAMP_MASK; |
323 | } |
324 | static inline uint64_t |
325 | kdbg_get_timestamp(kd_buf *kp) |
326 | { |
327 | return kp->timestamp & KDBG_TIMESTAMP_MASK; |
328 | } |
329 | static inline void |
330 | kdbg_set_timestamp_and_cpu(kd_buf *kp, uint64_t thetime, int cpu) |
331 | { |
332 | kp->timestamp = (thetime & KDBG_TIMESTAMP_MASK) | |
333 | (((uint64_t) cpu) << KDBG_CPU_SHIFT); |
334 | } |
335 | #endif // !defined(__LP64__) && !defined(__arm64__) |
336 | |
337 | // 8KB, one bit for each possible class/subclass combination. |
338 | #define KDBG_TYPEFILTER_BITMAP_SIZE ((256 * 256) / 8) |
339 | |
340 | // Settings that may need to be changed while tracing, protected by the storage |
341 | // lock or the ktrace lock if tracing is disabled. |
342 | // |
343 | // These flags must not overlap with `kdebug_flags_t`. |
344 | __options_decl(kdebug_live_flags_t, uint32_t, { |
345 | // Disable tracing when events wrap. Set while reading events. |
346 | KDBG_NOWRAP = 0x0002, |
347 | // Events have wrapped. |
348 | KDBG_WRAPPED = 0x0008, |
349 | }); |
350 | |
351 | // Mostly configuration options, protected by the ktrace lock. |
352 | __options_decl(kdebug_flags_t, uint32_t, { |
353 | // Only trace processes with the kdebug bit set. |
354 | KDBG_PIDCHECK = 0x0010, |
355 | // Thread map pointer is valid. |
356 | KDBG_MAPINIT = 0x0020, |
357 | // Exclude events from processes with the kdebug bit set. |
358 | KDBG_PIDEXCLUDE = 0x0040, |
359 | // Events are 64-bit, only for `kbufinfo_t`. |
360 | KDBG_LP64 = 0x0100, |
361 | // Timestamps are continuous time, instead of absolute time. |
362 | KDBG_CONTINUOUS_TIME = 0x0200, |
363 | // Exclude events from coprocessors (IOPs). |
364 | KDBG_DISABLE_COPROCS = 0x0400, |
365 | // Disable tracing on event match. |
366 | KDBG_MATCH_DISABLE = 0x0800, |
367 | // Check the typefilter. |
368 | KDBG_TYPEFILTER_CHECK = 0x00400000, |
369 | // 64-bit debug ID present in arg4 (triage-only). |
370 | KDBG_DEBUGID_64 = 0x00800000, |
371 | // Event storage buffers are initialized. |
372 | KDBG_BUFINIT = 0x80000000U, |
373 | }); |
374 | |
375 | // Obsolete flags. |
376 | #define KDBG_INIT 0x01 |
377 | #define KDBG_FREERUN 0x04 |
378 | |
379 | // Flags in `kdebug_live_flags_t` and `kdebug_flags_t` that can be modified by |
380 | // user space. |
381 | #define KDBG_USERFLAGS (KDBG_NOWRAP | KDBG_CONTINUOUS_TIME | \ |
382 | KDBG_DISABLE_COPROCS | KDBG_MATCH_DISABLE) |
383 | |
384 | // Information about kdebug for user space consumption. |
385 | typedef struct { |
386 | // Size of buffers in number of events (kd_bufs). |
387 | int nkdbufs; |
388 | // True is tracing is disabled, false otherwise. |
389 | int nolog; |
390 | // Combined `kdebug_live_flags_t` and `kdebug_state_t`. |
391 | unsigned int flags; |
392 | // Number of threads in the thread map. |
393 | int nkdthreads; |
394 | // Owning process PID. |
395 | int bufid; |
396 | } kbufinfo_t; |
397 | |
398 | // Header for CPU mapping list. |
399 | typedef struct { |
400 | uint32_t ; |
401 | uint32_t ; |
402 | } ; |
403 | |
404 | // CPU map entry flags. |
405 | #define KDBG_CPUMAP_IS_IOP 0x1 |
406 | |
407 | // CPU map entries to map `cpuid` from events to names. |
408 | typedef struct { |
409 | uint32_t cpu_id; |
410 | uint32_t flags; |
411 | char name[32]; |
412 | } kd_cpumap_ext; |
413 | |
414 | // Match structured data from events. |
415 | typedef struct { |
416 | uint32_t kem_debugid; |
417 | uint32_t kem_padding; |
418 | uint64_t kem_args[4]; |
419 | } kd_event_matcher; |
420 | |
421 | // Options for `kdebug_enable` in the comm-page. |
422 | #define KDEBUG_COMMPAGE_ENABLE_TRACE 0x1 |
423 | #define KDEBUG_COMMPAGE_ENABLE_TYPEFILTER 0x2 |
424 | #define KDEBUG_COMMPAGE_CONTINUOUS 0x4 |
425 | |
426 | #pragma mark - Tests |
427 | |
428 | // Test scenarios. |
429 | __enum_decl(kdebug_test_t, uint32_t, { |
430 | KDTEST_KERNEL_MACROS = 1, |
431 | KDTEST_OLD_TIMESTAMP, |
432 | KDTEST_FUTURE_TIMESTAMP, |
433 | KDTEST_SETUP_IOP, |
434 | KDTEST_SETUP_COPROCESSOR, |
435 | KDTEST_CONTINUOUS_TIMESTAMP, |
436 | KDTEST_ABSOLUTE_TIMESTAMP, |
437 | KDTEST_PAST_EVENT, |
438 | }); |
439 | |
440 | #pragma mark - Obsolete interfaces |
441 | |
442 | // Some Apple-internal clients try to use the kernel macros in user space. |
443 | #ifndef KERNEL_DEBUG |
444 | #define KERNEL_DEBUG(...) do { } while (0) |
445 | #endif // !defined(KERNEL_DEBUG) |
446 | |
447 | // Obsolete options for `kdebug_enable`. |
448 | #define KDEBUG_ENABLE_ENTROPY 0x002U |
449 | #define KDEBUG_ENABLE_CHUD 0x004U |
450 | #define KDEBUG_ENABLE_PPT 0x008U |
451 | #define KDEBUG_ENABLE_SERIAL 0x010U |
452 | #define KDEBUG_PPT (KDEBUG_ENABLE_PPT) |
453 | #define KDEBUG_COMMON (KDEBUG_ENABLE_TRACE | KDEBUG_ENABLE_PPT) |
454 | |
455 | // Obsolete flags. |
456 | #define KDBG_LOCKINIT 0x0080 |
457 | #define KDBG_RANGECHECK 0x00100000U |
458 | #define KDBG_VALCHECK 0x00200000U |
459 | |
460 | // Type values for `kd_regtype`. |
461 | #define KDBG_CLASSTYPE 0x10000 |
462 | #define KDBG_SUBCLSTYPE 0x20000 |
463 | #define KDBG_RANGETYPE 0x40000 |
464 | #define KDBG_TYPENONE 0x80000 |
465 | #define KDBG_CKTYPES 0xF0000 |
466 | |
467 | typedef struct { |
468 | unsigned int type; |
469 | unsigned int value1; |
470 | unsigned int value2; |
471 | unsigned int value3; |
472 | unsigned int value4; |
473 | } kd_regtype; |
474 | |
475 | // Entry for the legacy thread map system (replaced by stackshot). |
476 | typedef struct { |
477 | // A thread's unique ID. |
478 | #if defined(__arm64__) |
479 | uint64_t thread; |
480 | #else |
481 | uintptr_t thread __kernel_data_semantics; |
482 | #endif |
483 | // The process ID (or 1 for `kernproc`). |
484 | int valid; |
485 | // The name of the process owning this thread. |
486 | char command[20]; |
487 | } kd_threadmap; |
488 | |
489 | // Legacy CPU map entry. |
490 | typedef struct { |
491 | uint32_t cpu_id; |
492 | uint32_t flags; |
493 | char name[8]; |
494 | } kd_cpumap; |
495 | |
496 | // File header for legacy trace files. |
497 | typedef struct { |
498 | int ; |
499 | int ; |
500 | uint64_t ; |
501 | uint32_t ; |
502 | } ; |
503 | |
504 | // Obsolete `version_no` for legacy trace files. |
505 | #define RAW_VERSION0 0x55aa0000 |
506 | #define RAW_VERSION1 0x55aa0101 |
507 | #define RAW_VERSION2 0x55aa0200 |
508 | |
509 | // Obsolete EnergyTracing definitions. |
510 | |
511 | #define kEnTrCompKernel 2 |
512 | #define kEnTrActKernSocket 1 |
513 | #define kEnTrActKernSockRead 2 |
514 | #define kEnTrActKernSockWrite 3 |
515 | #define kEnTrActKernPoll 10 |
516 | #define kEnTrActKernSelect 11 |
517 | #define kEnTrActKernKQWait 12 |
518 | #define kEnTrEvUnblocked 256 |
519 | #define kEnTrFlagNonBlocking 0x1 |
520 | #define kEnTrFlagNoWork 0x2 |
521 | |
522 | #if (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST) |
523 | #define ENTR_SHOULDTRACE kdebug_enable |
524 | #define ENTR_KDTRACE(component, opcode, lifespan, id, quality, value) \ |
525 | do { \ |
526 | uint32_t kdcode__; \ |
527 | uintptr_t highval__, lowval__, mask__ = 0xffffffff; \ |
528 | kdcode__ = KDBG_CODE(DBG_ENERGYTRACE,component,opcode)|(lifespan); \ |
529 | highval__ = ((value) >> 32) & mask__; \ |
530 | lowval__ = (value) & mask__; \ |
531 | ENTR_KDTRACEFUNC(kdcode__, id, quality, highval__, lowval__); \ |
532 | } while(0) |
533 | |
534 | #define kEnTrModAssociate (1 << 28) |
535 | #define ENTR_KDASSOCIATE(par_comp, par_opcode, par_act_id, \ |
536 | sub_comp, sub_opcode, sub_act_id) \ |
537 | do { \ |
538 | unsigned sub_compcode = ((unsigned)sub_comp << 16) | sub_opcode; \ |
539 | ENTR_KDTRACEFUNC(KDBG_CODE(DBG_ENERGYTRACE,par_comp,par_opcode), \ |
540 | par_act_id, kEnTrModAssociate, sub_compcode, \ |
541 | sub_act_id); \ |
542 | } while(0) |
543 | |
544 | #else // (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST) |
545 | |
546 | #define ENTR_SHOULDTRACE 0 |
547 | #define ENTR_KDTRACE(component, opcode, lifespan, id, quality, value) do {} while (0) |
548 | #define ENTR_KDASSOCIATE(par_comp, par_opcode, par_act_id, sub_comp, sub_opcode, sub_act_id) do {} while (0) |
549 | |
550 | #endif // (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST) |
551 | |
552 | #endif // !defined(DRIVERKIT) |
553 | |
554 | __END_DECLS |
555 | |
556 | #endif // !defined(BSD_KDEBUG_PRIVATE_H) |
557 | |