1 /* 2 * Copyright (c) 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 /* 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_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_IMPL(x, a, b, c, d) \ 73 do { \ 74 socd_client_trace((x), (socd_client_trace_arg_t)(a), (socd_client_trace_arg_t)(b), \ 75 (socd_client_trace_arg_t)(c), (socd_client_trace_arg_t)(d)); \ 76 } while (0) 77 #else // defined(__arm64__) 78 #define SOCD_TRACE_IMPL(x, a, b, c, d) 79 #endif // !defined(__arm64__) 80 81 #define SOCD_ADDR(_a) (VM_KERNEL_UNSLIDE((vm_offset_t)(_a))) 82 #define SOCD_VALUE(_v) (VM_KERNEL_ADDRESS((vm_offset_t)(_v)) ? (socd_client_trace_arg_t)0 : (socd_client_trace_arg_t)(_v)) 83 #define SOCD_PACK_2X32(h, l) ((((uint64_t)(SOCD_##h) & 0xffffffff) << 32) | ((uint64_t)(SOCD_##l) & 0xffffffff)) 84 #define SOCD_PACK_LSB(h, lsb) ((((uint64_t)(SOCD_##h)) & 0xfffffffffffffffe) | ((uint64_t)(SOCD_##lsb) & 0x1)) 85 86 /* Test macros for proper functionality locally before nominating. */ 87 #if !defined(__arm64__) 88 static_assert(SOCD_PACK_2X32(VALUE(0xffff1000), VALUE(0xffff1200)) == 0xffff1000ffff1200, "PACK_2X32 failed to return expected output."); 89 static_assert(SOCD_PACK_LSB(VALUE(0xffff), VALUE(0x0)) == 0xfffe, "PACK_LSB failed to return expected output."); 90 #endif // !defined(__arm64__) 91 92 #define _SOCD_TRACE_XNU(c, x, ...) \ 93 SOCD_TRACE(KDBG_EVENTID(DBG_DRIVERS, DBG_SOCDIAGS, SOCD_TRACE_EVENTID(SOCD_TRACE_CLASS_XNU, SOCD_TRACE_CODE_XNU_##c)) | (x), ## __VA_ARGS__) 94 #define SOCD_TRACE_XNU(c, ...) _SOCD_TRACE_XNU(c, DBG_FUNC_NONE, ## __VA_ARGS__) 95 #define SOCD_TRACE_XNU_START(c, ...) _SOCD_TRACE_XNU(c, DBG_FUNC_START, ## __VA_ARGS__) 96 #define SOCD_TRACE_XNU_END(c, ...) _SOCD_TRACE_XNU(c, DBG_FUNC_END, ## __VA_ARGS__) 97 98 extern void socd_client_trace(uint32_t debugid, socd_client_trace_arg_t arg1, 99 socd_client_trace_arg_t arg2, socd_client_trace_arg_t arg3, socd_client_trace_arg_t arg4); 100 101 __END_DECLS 102 103 #endif /* !defined(_KERN_SOCD_CLIENT_KERN_H_) */ 104