]>
Commit | Line | Data |
---|---|---|
cb323159 A |
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. The string must not be the empty | |
115 | * string, but can be NULL if a valid `str_id` is provided. | |
116 | * | |
117 | * @return | |
118 | * 0 if tracing is disabled or `debugid` is being filtered out of trace. | |
119 | * It can also return (int64_t)-1 if an error occured. Otherwise, | |
120 | * it returns the ID to use to refer to the string in future | |
121 | * kdebug_trace(2) calls. | |
122 | * | |
123 | * The errors that can occur are: | |
124 | * | |
125 | * EINVAL | |
126 | * There are function qualifiers on `debugid`, `str` is empty, or | |
127 | * `str_id` was not generated by this function. | |
128 | * EPERM | |
129 | * The `debugid`'s class or subclass is reserved for internal use. | |
130 | * EFAULT | |
131 | * `str` is an invalid address or NULL when `str_id` is 0. | |
132 | */ | |
133 | extern uint64_t kdebug_trace_string(uint32_t debugid, uint64_t str_id, | |
134 | const char *str) | |
135 | __OSX_AVAILABLE(10.11) __IOS_AVAILABLE(9.0); | |
136 | ||
137 | /* | |
138 | * Although the performance impact of kdebug_trace() when kernel | |
139 | * tracing is not enabled is minimal, it may require the caller to | |
140 | * perform an expensive calculation/summarization. This cost can be | |
141 | * skipped by checking the kdebug_is_enabled() predicate: | |
142 | * | |
143 | * if (kdebug_is_enabled(KDBG_CODE(DBG_XPC, 15, 1))) { | |
144 | * uint64_t arg1 = ...; | |
145 | * uint64_t arg2 = ...; | |
146 | * kdebug_trace(KDBG_CODE(DBG_XPC, 15, 1) | DBG_FUNC_NONE, arg1, arg2, 0, 0); | |
147 | * } | |
148 | * | |
149 | * If tracing is enabled for the code at the time of the check, 1 | |
150 | * will be returned. Otherwise, 0 will be returned. | |
151 | */ | |
152 | extern bool kdebug_is_enabled(uint32_t code) | |
153 | __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) | |
154 | __WATCHOS_AVAILABLE(3.0) __TVOS_AVAILABLE(10.0); | |
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 | __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) | |
162 | __WATCHOS_AVAILABLE(3.0) __TVOS_AVAILABLE(10.0); | |
163 | ||
164 | /* | |
165 | * Returns true if kdebug is using continuous time for its events, and false | |
166 | * otherwise. | |
167 | */ | |
168 | extern bool kdebug_using_continuous_time(void) | |
169 | __API_AVAILABLE(macos(10.15), ios(13), tvos(13), watchos(6)); | |
170 | ||
171 | #endif /* !KERNEL */ | |
172 | ||
173 | #pragma mark - private debugids | |
174 | ||
175 | #define DBG_PPT 36 | |
176 | #define DBG_PERFCTRL 39 | |
177 | #define DBG_CLPC 50 | |
178 | #define DBG_MUSE 52 | |
179 | ||
180 | /* **** 128 to 139 are reserved for IOP tracing **** */ | |
181 | #define DBG_ANS 128 | |
182 | #define DBG_SIO 129 | |
183 | #define DBG_SEP 130 | |
184 | #define DBG_ISP 131 | |
185 | #define DBG_OSCAR 132 | |
186 | #define DBG_EMBEDDEDGFX 133 | |
187 | #define DBG_PMP 134 | |
188 | #define DBG_RTKIT 135 | |
189 | ||
190 | #define MACH_BRIDGE_RCV_TS 0x1 /* receive timestamp pair from interrupt handler */ | |
191 | #define MACH_BRIDGE_REMOTE_TIME 0x2 /* calculate remote timestamp */ | |
192 | #define MACH_BRIDGE_RESET_TS 0x3 /* reset timestamp conversion parameters */ | |
193 | #define MACH_BRIDGE_TS_PARAMS 0x4 /* recompute timestamp conversion parameters */ | |
194 | #define MACH_BRIDGE_SKIP_TS 0x5 /* skip timestamp */ | |
195 | #define MACH_BRIDGE_TS_MISMATCH 0x6 /* mismatch between predicted and received remote timestamp */ | |
196 | #define MACH_BRIDGE_OBSV_RATE 0x7 /* out of range observed rates */ | |
197 | ||
198 | /* DBG_SKYWALK has same toplevel code as DBG_DLIL, so don't reuse subcodes */ | |
c3c9b80d | 199 | #define DBG_SKYWALK_ALWAYSON 0x10 |
cb323159 A |
200 | #define DBG_SKYWALK_FLOWSWITCH 0x11 |
201 | #define DBG_SKYWALK_NETIF 0x12 | |
202 | #define DBG_SKYWALK_CHANNEL 0x13 | |
c3c9b80d | 203 | #define DBG_SKYWALK_PACKET 0x14 |
cb323159 A |
204 | |
205 | #define PPT_TEST 0x01 | |
206 | #define PPT_JETSAM_HIWAT 0x02 | |
207 | #define PPT_JETSAM_TOPPROC 0x03 | |
208 | ||
209 | #define SKYWALKDBG_CODE(SubClass, code) KDBG_CODE(DBG_DLIL, SubClass, code) | |
210 | #define PPTDBG_CODE(SubClass, code) KDBG_CODE(DBG_PPT, SubClass, code) | |
211 | #define PERFCTRL_CODE(SubClass, code) KDBG_CODE(DBG_PERFCTRL, SubClass, code) | |
212 | ||
213 | #if !defined(DRIVERKIT) | |
214 | ||
215 | extern unsigned int kdebug_enable; | |
216 | ||
217 | /* | |
218 | * Bits used by kdebug_enable. These control which events are traced at | |
219 | * runtime. | |
220 | */ | |
221 | #define KDEBUG_ENABLE_TRACE (1U << 0) | |
222 | #define KDEBUG_ENABLE_ENTROPY (1U << 1) /* obsolete */ | |
223 | #define KDEBUG_ENABLE_CHUD (1U << 2) /* obsolete */ | |
224 | #define KDEBUG_ENABLE_PPT (1U << 3) /* obsolete */ | |
225 | #define KDEBUG_ENABLE_SERIAL (1U << 4) /* obsolete */ | |
226 | ||
227 | /* | |
228 | * If set, the timestamps in events are expected to be continuous times. | |
229 | * Otherwise, the timestamps are absolute times. IOPs should observe this bit | |
230 | * in order to log events that can be merged cleanly with other event streams. | |
231 | */ | |
232 | #define KDEBUG_ENABLE_CONT_TIME 0x20 | |
233 | ||
234 | #define KDEBUG_TRACE (KDEBUG_ENABLE_TRACE) | |
235 | ||
236 | /* | |
237 | * Specify KDEBUG_PPT to indicate that the event belongs to the limited PPT set. | |
238 | * PPT is deprecated -- use a typefilter and the PPTDBG class instead. | |
239 | */ | |
240 | #define KDEBUG_PPT (KDEBUG_ENABLE_PPT) | |
241 | #define KDEBUG_COMMON (KDEBUG_ENABLE_TRACE | KDEBUG_ENABLE_PPT) | |
242 | ||
243 | /* | |
244 | * The kernel debug configuration level. These values control which events are | |
245 | * compiled in under different build configurations. | |
246 | * | |
247 | * Infer the supported kernel debug event level from config option. Use | |
248 | * (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD) as a guard to protect unaudited debug | |
249 | * code. | |
250 | */ | |
251 | #define KDEBUG_LEVEL_NONE 0 | |
252 | #define KDEBUG_LEVEL_IST 1 | |
253 | #define KDEBUG_LEVEL_STANDARD 2 | |
254 | #define KDEBUG_LEVEL_FULL 3 | |
255 | ||
256 | #if NO_KDEBUG | |
257 | #define KDEBUG_LEVEL KDEBUG_LEVEL_NONE | |
258 | #elif IST_KDEBUG | |
259 | #define KDEBUG_LEVEL KDEBUG_LEVEL_IST | |
260 | #elif KDEBUG | |
261 | #define KDEBUG_LEVEL KDEBUG_LEVEL_FULL | |
262 | #else | |
263 | #define KDEBUG_LEVEL KDEBUG_LEVEL_STANDARD | |
264 | /* | |
265 | * Currently, all other kernel configurations (development, etc) build with | |
266 | * KDEBUG_LEVEL_STANDARD. | |
267 | */ | |
268 | #endif | |
269 | ||
270 | /* | |
271 | * Some Apple internal clients try to use the kernel macros in user space. | |
272 | */ | |
273 | #ifndef KERNEL_DEBUG | |
274 | #define KERNEL_DEBUG(...) do { } while (0) | |
275 | #endif /* !defined(KERNEL_DEBUG) */ | |
276 | ||
277 | #pragma mark - private definitions | |
278 | ||
279 | /* | |
280 | * Ensure that both LP32 and LP64 variants of arm64 use the same kd_buf | |
281 | * structure. | |
282 | */ | |
283 | #if defined(__arm64__) | |
284 | typedef uint64_t kd_buf_argtype; | |
285 | #else | |
286 | typedef uintptr_t kd_buf_argtype; | |
287 | #endif | |
288 | ||
289 | typedef struct { | |
290 | uint64_t timestamp; | |
291 | kd_buf_argtype arg1; | |
292 | kd_buf_argtype arg2; | |
293 | kd_buf_argtype arg3; | |
294 | kd_buf_argtype arg4; | |
295 | kd_buf_argtype arg5; /* the thread ID */ | |
296 | uint32_t debugid; | |
297 | /* | |
298 | * Ensure that both LP32 and LP64 variants of arm64 use the same kd_buf | |
299 | * structure. | |
300 | */ | |
301 | #if defined(__LP64__) || defined(__arm64__) | |
302 | uint32_t cpuid; | |
303 | kd_buf_argtype unused; | |
304 | #endif | |
305 | } kd_buf; | |
306 | ||
307 | #if defined(__LP64__) || defined(__arm64__) | |
308 | #define KDBG_TIMESTAMP_MASK 0xffffffffffffffffULL | |
309 | static inline void | |
310 | kdbg_set_cpu(kd_buf *kp, int cpu) | |
311 | { | |
312 | kp->cpuid = (unsigned int)cpu; | |
313 | } | |
314 | static inline int | |
315 | kdbg_get_cpu(kd_buf *kp) | |
316 | { | |
317 | return (int)kp->cpuid; | |
318 | } | |
319 | static inline void | |
320 | kdbg_set_timestamp(kd_buf *kp, uint64_t thetime) | |
321 | { | |
322 | kp->timestamp = thetime; | |
323 | } | |
324 | static inline uint64_t | |
325 | kdbg_get_timestamp(kd_buf *kp) | |
326 | { | |
327 | return kp->timestamp; | |
328 | } | |
329 | static inline void | |
330 | kdbg_set_timestamp_and_cpu(kd_buf *kp, uint64_t thetime, int cpu) | |
331 | { | |
332 | kdbg_set_timestamp(kp, thetime); | |
333 | kdbg_set_cpu(kp, cpu); | |
334 | } | |
335 | #else | |
336 | #define KDBG_TIMESTAMP_MASK 0x00ffffffffffffffULL | |
337 | #define KDBG_CPU_MASK 0xff00000000000000ULL | |
338 | #define KDBG_CPU_SHIFT 56 | |
339 | static inline void | |
340 | kdbg_set_cpu(kd_buf *kp, int cpu) | |
341 | { | |
342 | kp->timestamp = (kp->timestamp & KDBG_TIMESTAMP_MASK) | | |
343 | (((uint64_t) cpu) << KDBG_CPU_SHIFT); | |
344 | } | |
345 | static inline int | |
346 | kdbg_get_cpu(kd_buf *kp) | |
347 | { | |
348 | return (int) (((kp)->timestamp & KDBG_CPU_MASK) >> KDBG_CPU_SHIFT); | |
349 | } | |
350 | static inline void | |
351 | kdbg_set_timestamp(kd_buf *kp, uint64_t thetime) | |
352 | { | |
353 | kp->timestamp = thetime & KDBG_TIMESTAMP_MASK; | |
354 | } | |
355 | static inline uint64_t | |
356 | kdbg_get_timestamp(kd_buf *kp) | |
357 | { | |
358 | return kp->timestamp & KDBG_TIMESTAMP_MASK; | |
359 | } | |
360 | static inline void | |
361 | kdbg_set_timestamp_and_cpu(kd_buf *kp, uint64_t thetime, int cpu) | |
362 | { | |
363 | kp->timestamp = (thetime & KDBG_TIMESTAMP_MASK) | | |
364 | (((uint64_t) cpu) << KDBG_CPU_SHIFT); | |
365 | } | |
366 | #endif | |
367 | ||
368 | /* | |
369 | * 2^16 bits (8 kilobytes), one for each possible class/subclass combination | |
370 | */ | |
371 | #define KDBG_TYPEFILTER_BITMAP_SIZE ((256 * 256) / 8) | |
372 | ||
373 | /* | |
374 | * Bits for kd_ctrl_page.flags, KERN_KD{D,E}FLAGS. | |
375 | */ | |
376 | #define KDBG_INIT (1U << 0) /* obsolete */ | |
377 | /* disable tracing when buffers are full */ | |
378 | #define KDBG_NOWRAP (1U << 1) | |
379 | #define KDBG_FREERUN (1U << 2) /* obsolete */ | |
380 | /* buffer has wrapped */ | |
381 | #define KDBG_WRAPPED (1U << 3) | |
382 | /* flags that are allowed to be set by user space */ | |
383 | #define KDBG_USERFLAGS (KDBG_FREERUN | KDBG_NOWRAP | KDBG_INIT) | |
384 | /* only include processes with kdebug bit set in proc */ | |
385 | #define KDBG_PIDCHECK (1U << 4) | |
386 | /* thread map is initialized */ | |
387 | #define KDBG_MAPINIT (1U << 5) | |
388 | /* exclude processes based on kdebug bit in proc */ | |
389 | #define KDBG_PIDEXCLUDE (1U << 6) | |
390 | /* whether the kdebug locks are intialized */ | |
391 | #define KDBG_LOCKINIT (1U << 7) | |
392 | /* word size of the kernel */ | |
393 | #define KDBG_LP64 (1U << 8) | |
394 | ||
395 | /* bits for kd_ctrl_page.flags and kbufinfo_t.flags */ | |
396 | ||
397 | /* only trace events within a range */ | |
398 | #define KDBG_RANGECHECK 0x00100000U | |
399 | /* only trace at most 4 types of events, at the code granularity */ | |
400 | #define KDBG_VALCHECK 0x00200000U | |
401 | /* check class and subclass against the typefilter */ | |
402 | #define KDBG_TYPEFILTER_CHECK 0x00400000U | |
403 | /* kdebug trace buffers are initialized */ | |
404 | #define KDBG_BUFINIT 0x80000000U | |
405 | ||
406 | /* bits for the type field of kd_regtype */ | |
407 | #define KDBG_CLASSTYPE 0x10000 | |
408 | #define KDBG_SUBCLSTYPE 0x20000 | |
409 | #define KDBG_RANGETYPE 0x40000 | |
410 | #define KDBG_TYPENONE 0x80000 | |
411 | #define KDBG_CKTYPES 0xF0000 | |
412 | ||
413 | typedef struct { | |
414 | unsigned int type; | |
415 | unsigned int value1; | |
416 | unsigned int value2; | |
417 | unsigned int value3; | |
418 | unsigned int value4; | |
419 | } kd_regtype; | |
420 | ||
421 | typedef struct { | |
422 | /* number of events that can fit in the buffers */ | |
423 | int nkdbufs; | |
424 | /* set if trace is disabled */ | |
425 | int nolog; | |
426 | /* kd_ctrl_page.flags */ | |
427 | unsigned int flags; | |
428 | /* number of threads in thread map */ | |
429 | int nkdthreads; | |
430 | /* the owning pid */ | |
431 | int bufid; | |
432 | } kbufinfo_t; | |
433 | ||
434 | typedef struct { | |
435 | /* the thread ID */ | |
436 | #if defined(__arm64__) | |
437 | uint64_t thread; | |
438 | #else | |
439 | uintptr_t thread; | |
440 | #endif | |
441 | /* 0 for invalid, otherwise the PID (or 1 for kernel_task) */ | |
442 | int valid; | |
443 | /* the name of the process owning the thread */ | |
444 | char command[20]; | |
445 | } kd_threadmap; | |
446 | ||
447 | typedef struct { | |
448 | uint32_t version_no; | |
449 | uint32_t cpu_count; | |
450 | } kd_cpumap_header; | |
451 | ||
452 | /* cpumap flags */ | |
453 | #define KDBG_CPUMAP_IS_IOP 0x1 | |
454 | ||
455 | typedef struct { | |
456 | uint32_t cpu_id; | |
457 | uint32_t flags; | |
458 | char name[8]; | |
459 | } kd_cpumap; | |
460 | ||
461 | typedef struct { | |
462 | int version_no; | |
463 | int thread_count; | |
464 | uint64_t TOD_secs; | |
465 | uint32_t TOD_usecs; | |
466 | } RAW_header; | |
467 | ||
468 | #define RAW_VERSION0 0x55aa0000 | |
469 | #define RAW_VERSION1 0x55aa0101 | |
470 | #define RAW_VERSION2 0x55aa0200 /* Only used by kperf and Instruments */ | |
471 | ||
472 | /* | |
473 | * Bits set in the comm page for kdebug. | |
474 | */ | |
475 | #define KDEBUG_COMMPAGE_ENABLE_TRACE 0x1 | |
476 | #define KDEBUG_COMMPAGE_ENABLE_TYPEFILTER 0x2 /* Forced to false if ENABLE_TRACE is 0 */ | |
477 | ||
478 | #pragma mark - EnergyTracing | |
479 | ||
480 | /* for EnergyTracing user space & clients */ | |
481 | #define kEnTrCompKernel 2 | |
482 | ||
483 | /* | |
484 | * EnergyTracing opcodes | |
485 | * | |
486 | * Activations use DBG_FUNC_START/END. | |
487 | * Events are DBG_FUNC_NONE. | |
488 | */ | |
489 | ||
490 | /* Socket reads and writes are uniquely identified by the (sanitized) | |
491 | * pointer to the socket struct in question. To associate this address | |
492 | * with the user space file descriptor, we have a socket activation with | |
493 | * the FD as its identifier and the socket struct pointer as its value. | |
494 | */ | |
495 | #define kEnTrActKernSocket 1 | |
496 | #define kEnTrActKernSockRead 2 | |
497 | #define kEnTrActKernSockWrite 3 | |
498 | ||
499 | #define kEnTrActKernPoll 10 | |
500 | #define kEnTrActKernSelect 11 | |
501 | #define kEnTrActKernKQWait 12 | |
502 | ||
503 | // events | |
504 | #define kEnTrEvUnblocked 256 | |
505 | ||
506 | // EnergyTracing flags (the low-order 16 bits of 'quality') | |
507 | #define kEnTrFlagNonBlocking 1 << 0 | |
508 | #define kEnTrFlagNoWork 1 << 1 | |
509 | ||
510 | /* | |
511 | * EnergyTracing macros. | |
512 | */ | |
513 | ||
514 | #if (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST) | |
515 | // whether to bother calculating EnergyTracing inputs | |
516 | // could change in future to see if DBG_ENERGYTRACE is active | |
517 | #define ENTR_SHOULDTRACE kdebug_enable | |
518 | // encode logical EnergyTracing into 32/64 KDebug trace | |
519 | #define ENTR_KDTRACE(component, opcode, lifespan, id, quality, value) \ | |
520 | do { \ | |
521 | uint32_t kdcode__; \ | |
522 | uintptr_t highval__, lowval__, mask__ = 0xffffffff; \ | |
523 | kdcode__ = KDBG_CODE(DBG_ENERGYTRACE,component,opcode)|(lifespan); \ | |
524 | highval__ = ((value) >> 32) & mask__; \ | |
525 | lowval__ = (value) & mask__; \ | |
526 | ENTR_KDTRACEFUNC(kdcode__, id, quality, highval__, lowval__); \ | |
527 | } while(0) | |
528 | ||
529 | /* | |
530 | * Trace the association of two existing activations. | |
531 | * | |
532 | * An association is traced as a modification to the parent activation. | |
533 | * In order to fit the sub-activation's component, activation code, and | |
534 | * activation ID into a kdebug tracepoint, the arguments that would hold | |
535 | * the value are left separate, and one stores the component and opcode | |
536 | * of the sub-activation, while the other stores the pointer-sized | |
537 | * activation ID. | |
538 | * | |
539 | * arg2 arg3 arg4 | |
540 | +-----------------+ +~+----+----+--------+ +----------+ | |
541 | |kEnTrModAssociate| | | | | | | | | |
542 | +-----------------+ +~+----+----+--------+ +----------+ | |
543 | * 8-bits unused sub-activation ID | |
544 | * 8-bit sub-component | |
545 | * 16-bit sub-opcode | |
546 | * | |
547 | */ | |
548 | #define kEnTrModAssociate (1 << 28) | |
549 | #define ENTR_KDASSOCIATE(par_comp, par_opcode, par_act_id, \ | |
550 | sub_comp, sub_opcode, sub_act_id) \ | |
551 | do { \ | |
552 | unsigned sub_compcode = ((unsigned)sub_comp << 16) | sub_opcode; \ | |
553 | ENTR_KDTRACEFUNC(KDBG_CODE(DBG_ENERGYTRACE,par_comp,par_opcode), \ | |
554 | par_act_id, kEnTrModAssociate, sub_compcode, \ | |
555 | sub_act_id); \ | |
556 | } while(0) | |
557 | ||
558 | #else /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST) */ | |
559 | ||
560 | #define ENTR_SHOULDTRACE FALSE | |
561 | #define ENTR_KDTRACE(component, opcode, lifespan, id, quality, value) \ | |
562 | do {} while (0) | |
563 | #define ENTR_KDASSOCIATE(par_comp, par_opcode, par_act_id, \ | |
564 | sub_comp, sub_opcode, sub_act_id) \ | |
565 | do {} while (0) | |
566 | ||
567 | #endif /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST) */ | |
568 | ||
569 | #endif /* !defined(DRIVERKIT) */ | |
570 | ||
571 | __END_DECLS | |
572 | ||
573 | #endif /* !defined(BSD_KDEBUG_PRIVATE_H) */ |