xref: /xnu-12377.1.9/osfmk/kern/socd_client_kern.h (revision f6217f891ac0bb64f3d375211650a4c1ff8ca1ea)
1 /*
2  * Copyright (c) 2021, 2024 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 /* socd_client_kern.h: machine-independent API for interfacing with soc diagnostics data pipeline, kernel mode specific logic */
30 
31 #ifndef _KERN_SOCD_CLIENT_KERN_H_
32 #define _KERN_SOCD_CLIENT_KERN_H_
33 
34 #include <kern/socd_client.h>
35 #include <kern/kern_types.h>
36 #include <mach/vm_param.h>
37 #include <sys/cdefs.h>
38 
39 __BEGIN_DECLS
40 
41 /*
42  * SOCD_TRACE
43  * Trace an event to debug kernel and hardware hangs. Traced on all build variants of kernel.
44  * x - kdebug debugid
45  * a, b, c, d - 64 bit data arguments
46  *
47  * Usage:
48  *    SOCD_TRACE is an expensive operation and must not be used on performance critical paths.
49  *    Each data argument must be wrapped with SOCD_ADDR or SOCD_VAL macro. To enforce this rule,
50  *    SOCD_ is prepended to all data arguments passed to SOCD_TRACE.
51  *    1. Use ADDR when passing a kernel address. The macro verifies kernel address is slid, then it removes the slide.
52  *       When kernel address is not slid, the macro returns 0.
53  *    2. Use VALUE when passing an argument that's not expected to be a kernel address. When the argument
54  *       is a kernel address, the macro returns 0.
55  *    3. Use PACK_2X32 to pack two 32 bit values into one 64 bit argument. PACK_2X32 arguments must be wrapped with ADDR or VALUE macro as well.
56  *    4. Use PACK_LSB to overwrite the least significant bit of a 64 bit value. PACK_LSB arguments must be wrapped with ADDR or VALUE macro as well.
57  *
58  *
59  * Example:
60  *      SOCD_TRACE(KDBG_EVENTID(DBG_DRIVERS, DBG_SOCDIAGS, SOCD_TRACE_EVENTID(SOCD_TRACE_CLASS_KERNEL, SOCD_TRACE_MODE_NONE, SOCD_TRACE_CODE_KERNEL_PANIC)),
61  *                 ADDR(caller_function_ptr), VALUE(panic_options))
62  */
63 #define SOCD_TRACE(x, ...) SOCD_TRACE_(x, ## __VA_ARGS__, 4, 3, 2, 1, 0)
64 #define SOCD_TRACE_(x, a, b, c, d, n, ...) SOCD_TRACE##n(x, a, b, c, d)
65 #define SOCD_TRACE0(x, a, b, c, d)         SOCD_TRACE_IMPL(x,        0,        0,        0,        0)
66 #define SOCD_TRACE1(x, a, b, c, d)         SOCD_TRACE_IMPL(x, SOCD_##a,        0,        0,        0)
67 #define SOCD_TRACE2(x, a, b, c, d)         SOCD_TRACE_IMPL(x, SOCD_##a, SOCD_##b,        0,        0)
68 #define SOCD_TRACE3(x, a, b, c, d)         SOCD_TRACE_IMPL(x, SOCD_##a, SOCD_##b, SOCD_##c,        0)
69 #define SOCD_TRACE4(x, a, b, c, d)         SOCD_TRACE_IMPL(x, SOCD_##a, SOCD_##b, SOCD_##c, SOCD_##d)
70 
71 #if defined(__arm64__)
72 #  define SOCD_TRACE_ENABLED 1
73 #endif
74 
75 #if SOCD_TRACE_ENABLED
76 #define SOCD_TRACE_IMPL(x, a, b, c, d) \
77 do { \
78 	socd_client_trace((x), (socd_client_trace_arg_t)(a), (socd_client_trace_arg_t)(b), \
79 	                        (socd_client_trace_arg_t)(c), (socd_client_trace_arg_t)(d)); \
80 } while (0)
81 #define SOCD_TRACE_REINIT() socd_client_reinit()
82 #else // SOCD_TRACE_ENABLED
83 #define SOCD_TRACE_IMPL(x, a, b, c, d)
84 #define SOCD_TRACE_REINIT()
85 #endif // !SOCD_TRACE_ENABLED
86 
87 #define SOCD_ADDR(_a) (VM_KERNEL_UNSLIDE((vm_offset_t)(_a)))
88 #define SOCD_VALUE(_v) (VM_KERNEL_ADDRESS((vm_offset_t)(_v)) ? (socd_client_trace_arg_t)0 : (socd_client_trace_arg_t)(_v))
89 #define SOCD_PACK_2X32(h, l) ((((uint64_t)(SOCD_##h) & 0xffffffff) << 32) | ((uint64_t)(SOCD_##l) & 0xffffffff))
90 #define SOCD_PACK_LSB(h, lsb) ((((uint64_t)(SOCD_##h)) & 0xfffffffffffffffe) | ((uint64_t)(SOCD_##lsb) & 0x1))
91 
92 /* Test macros for proper functionality locally before nominating. */
93 #if !defined(__arm64__)
94 static_assert(SOCD_PACK_2X32(VALUE(0xffff1000), VALUE(0xffff1200)) == 0xffff1000ffff1200, "PACK_2X32 failed to return expected output.");
95 static_assert(SOCD_PACK_LSB(VALUE(0xffff), VALUE(0x0)) == 0xfffe, "PACK_LSB failed to return expected output.");
96 #endif // !defined(__arm64__)
97 
98 #define _SOCD_TRACE_XNU(cls, mode, func, ...) \
99    SOCD_TRACE(KDBG_EVENTID(DBG_DRIVERS, DBG_SOCDIAGS, SOCD_TRACE_EVENTID(SOCD_TRACE_CLASS_XNU, mode, SOCD_TRACE_CODE_XNU_##cls)) | (func), ## __VA_ARGS__)
100 #define SOCD_TRACE_XNU(c, m, ...) _SOCD_TRACE_XNU(c, m, DBG_FUNC_NONE, ## __VA_ARGS__)
101 #define SOCD_TRACE_XNU_START(c, ...) _SOCD_TRACE_XNU(c, SOCD_TRACE_MODE_NONE, DBG_FUNC_START, ## __VA_ARGS__)
102 #define SOCD_TRACE_XNU_END(c, ...) _SOCD_TRACE_XNU(c, SOCD_TRACE_MODE_NONE, DBG_FUNC_END, ## __VA_ARGS__)
103 
104 extern void socd_client_reinit(void);
105 extern void socd_client_trace(uint32_t debugid, socd_client_trace_arg_t arg1,
106     socd_client_trace_arg_t arg2, socd_client_trace_arg_t arg3, socd_client_trace_arg_t arg4);
107 
108 __END_DECLS
109 
110 #endif /* !defined(_KERN_SOCD_CLIENT_KERN_H_) */
111