1/*
2 * Copyright (c) 2000-2005 Apple Computer, 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 * @OSF_COPYRIGHT@
30 */
31
32#ifndef _KERN_IPC_MIG_H_
33#define _KERN_IPC_MIG_H_
34
35#include <mach/mig.h>
36#include <mach/mach_types.h>
37#include <mach/message.h>
38#include <kern/kern_types.h>
39
40#include <sys/cdefs.h>
41
42#ifdef XNU_KERNEL_PRIVATE
43
44#include <sys/kdebug.h>
45
46/*
47 * Define the trace points for MIG-generated calls. One traces the input parameters
48 * to MIG called things, another traces the outputs, and one traces bad message IDs.
49 */
50#ifdef _MIG_TRACE_PARAMETERS_
51
52#define __BeforeRcvCallTrace(msgid, arg1, arg2, arg3, arg4) \
53 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE, \
54 KDBG_MIGCODE(msgid) | DBG_FUNC_START, \
55 (unsigned int)(arg1), \
56 (unsigned int)(arg2), \
57 (unsigned int)(arg3), \
58 (unsigned int)(arg4), \
59 (unsigned int)(0));
60
61#define __AfterRcvCallTrace(msgid, arg1, arg2, arg3, arg4) \
62 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE, \
63 KDBG_MIGCODE(msgid) | DBG_FUNC_END, \
64 (unsigned int)(arg1), \
65 (unsigned int)(arg2), \
66 (unsigned int)(arg3), \
67 (unsigned int)(arg4), \
68 (unsigned int)(0));
69
70#define __BeforeSimpleCallTrace(msgid, arg1, arg2, arg3, arg4) \
71 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE, \
72 KDBG_MIGCODE(msgid) | DBG_FUNC_START, \
73 (unsigned int)(arg1), \
74 (unsigned int)(arg2), \
75 (unsigned int)(arg3), \
76 (unsigned int)(arg4), \
77 (unsigned int)(0));
78
79#define __AfterSimpleCallTrace(msgid, arg1, arg2, arg3, arg4) \
80 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE, \
81 KDBG_MIGCODE(msgid) | DBG_FUNC_END, \
82 (unsigned int)(arg1), \
83 (unsigned int)(arg2), \
84 (unsigned int)(arg3), \
85 (unsigned int)(arg4), \
86 (unsigned int)(0));
87
88#define __BeforeKobjectServerTrace(msgid) ((void)0)
89#define __AfterKobjectServerTrace(msgid) ((void)0)
90
91#else /* !_MIG_TRACE_PARAMETERS_ */
92
93#define __BeforeKobjectServerTrace(msgid) \
94 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE, \
95 KDBG_MIGCODE(msgid) | DBG_FUNC_START, 0u, 0u, 0u, 0u, 0u)
96
97#define __AfterKobjectServerTrace(msgid) \
98 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE, \
99 KDBG_MIGCODE(msgid) | DBG_FUNC_END, 0u, 0u, 0u, 0u, 0u)
100
101#endif /* !_MIG_TRACE_PARAMETERS_ */
102
103#define _MIG_MSGID_INVALID(msgid) \
104 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE, \
105 MACHDBG_CODE(DBG_MACH_MSGID_INVALID, (msgid)), 0u, 0u, 0u, 0u, 0u)
106
107#endif /* XNU_KERNEL_PRIVATE */
108
109__BEGIN_DECLS
110
111/* Send a message from the kernel */
112
113extern mach_msg_return_t mach_msg_send_from_kernel_proper(
114 mach_msg_header_t *msg,
115 mach_msg_size_t send_size);
116
117#define mach_msg_send_from_kernel mach_msg_send_from_kernel_proper
118
119/*
120 * Allocate kernel message buffer(s) large enough to fit the message,
121 * and accept a block that populates the message content.
122 *
123 * - descriptor_count: Descriptor count in the outgoing message. If non-zero,
124 * kernel expects a complex message, and vice-versa.
125 *
126 * - payload_size: Size of data not processed by kernel (i.e. size of data
127 * following the header, or last descriptor if the message is complex).
128 * This is NOT the total size of the outgoing message.
129 *
130 * For memory safety the kmsg buffers allocated may occupy non-contiguous memory
131 * and it is the caller's responsibility to correctly set up the message
132 * based on content's offset from the mach message header, as follows:
133 *
134 * void (^builder)(mach_msg_header_t *header, mach_msg_descriptor_t *descs, void *payload))
135 *
136 * header* ───────► ┌─────────────────────────┐
137 * │ │
138 * │ mach_msg_header_t │
139 * │ │
140 * ├─────────────────────────┤
141 * │(optional)mach_msg_body_t│
142 * descs* ───────► ├─────────────────────────┤
143 * │ │
144 * │ │
145 * │ │
146 * │ (optional)descriptors │
147 * │ │
148 * │ │
149 * │ │
150 * └─────────────────────────┘
151 * ~~~~~~~~void space~~~~~~~
152 * payload* ───────► ┌─────────────────────────┐
153 * │ │
154 * │ │
155 * │ other data in msg │
156 * │ │
157 * │ │
158 * └─────────────────────────┘
159 *
160 * header: Points to the start of the message, caller should populate this
161 * with the mach message header.
162 *
163 * descs: Pointers to the start of kernel descriptors region, if caller requested
164 * a non-zero descriptor_count. Or NULL if descriptor_count is 0 (meaning
165 * the messsage is not complex). Caller should populate this with descriptors.
166 *
167 * payload: Points to the start of data not processed by kernel, which is after
168 * the last descriptor, if caller requested a non-zero payload_size. Or
169 * NULL if payload_size is 0.
170 *
171 * Mach message body (descriptor count) will be set after the builder accordingly.
172 */
173extern mach_msg_return_t kernel_mach_msg_send_with_builder(
174 mach_msg_size_t descriptor_count,
175 mach_msg_size_t payload_size, /* Warning: NOT total send size */
176 void (^builder)(mach_msg_header_t *header,
177 mach_msg_descriptor_t * __counted_by(descriptor_count)descs, /* Nullable */
178 void * __sized_by(payload_size)payload)); /* Nullable */
179
180extern mach_msg_return_t mach_msg_rpc_from_kernel_proper(
181 mach_msg_header_t *msg,
182 mach_msg_size_t send_size,
183 mach_msg_size_t rcv_size);
184
185#define mach_msg_rpc_from_kernel mach_msg_rpc_from_kernel_proper
186
187extern void mach_msg_destroy_from_kernel_proper(
188 mach_msg_header_t *msg);
189
190#define mach_msg_destroy_from_kernel mach_msg_destroy_from_kernel_proper
191
192#ifdef XNU_KERNEL_PRIVATE
193
194mach_msg_return_t kernel_mach_msg_rpc(
195 mach_msg_header_t *msg,
196 mach_msg_size_t send_size,
197 mach_msg_size_t rcv_size,
198 boolean_t interruptible,
199 boolean_t *message_moved);
200
201extern mach_msg_return_t kernel_mach_msg_send(
202 mach_msg_header_t *msg,
203 mach_msg_size_t send_size,
204 mach_msg_option_t option,
205 mach_msg_timeout_t timeout_val,
206 boolean_t *message_moved);
207
208extern mach_msg_return_t kernel_mach_msg_send_with_builder_internal(
209 mach_msg_size_t desc_count,
210 mach_msg_size_t payload_size, /* Not total send size */
211 mach_msg_option_t option,
212 mach_msg_timeout_t timeout_val,
213 boolean_t *message_moved,
214 void (^builder)(mach_msg_header_t *,
215 mach_msg_descriptor_t *, void *));
216
217extern mach_msg_return_t mach_msg_send_from_kernel_with_options(
218 mach_msg_header_t *msg,
219 mach_msg_size_t send_size,
220 mach_msg_option_t option,
221 mach_msg_timeout_t timeout_val);
222
223#endif /* XNU_KERNEL_PRIVATE */
224#ifdef MACH_KERNEL_PRIVATE
225
226extern void mach_msg_receive_continue(void);
227
228#endif /* MACH_KERNEL_PRIVATE */
229
230__END_DECLS
231
232#endif /* _KERN_IPC_MIG_H_ */
233