xref: /xnu-12377.1.9/iokit/IOKit/IOLib.h (revision f6217f891ac0bb64f3d375211650a4c1ff8ca1ea) !
1 /*
2  * Copyright (c) 1998-2016 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  * Copyright (c) 1998 Apple Computer, Inc.  All rights reserved.
30  *
31  * HISTORY
32  *
33  */
34 
35 #ifndef __IOKIT_IOLIB_H
36 #define __IOKIT_IOLIB_H
37 
38 #ifndef KERNEL
39 #error IOLib.h is for kernel use only
40 #endif
41 
42 #include <stdarg.h>
43 #include <sys/cdefs.h>
44 #include <os/overflow.h>
45 #include <os/alloc_util.h>
46 
47 #include <sys/appleapiopts.h>
48 
49 #include <IOKit/system.h>
50 
51 #include <IOKit/IOReturn.h>
52 #include <IOKit/IOTypes.h>
53 #include <IOKit/IOLocks.h>
54 
55 #include <libkern/OSAtomic.h>
56 
57 __BEGIN_DECLS
58 
59 #include <kern/thread_call.h>
60 #include <kern/clock.h>
61 #ifdef KERNEL_PRIVATE
62 #include <kern/kalloc.h>
63 #include <kern/assert.h>
64 #endif
65 
66 /*
67  * min/max macros.
68  */
69 
70 #define min(a, b) ((a) < (b) ? (a) : (b))
71 #define max(a, b) ((a) > (b) ? (a) : (b))
72 
73 /*
74  * Safe functions to compute array sizes (saturate to a size that can't be
75  * allocated ever and will cause the allocation to return NULL always).
76  */
77 
78 static inline vm_size_t
IOMallocArraySize(vm_size_t hdr_size,vm_size_t elem_size,vm_size_t elem_count)79 IOMallocArraySize(vm_size_t hdr_size, vm_size_t elem_size, vm_size_t elem_count)
80 {
81 	/* IOMalloc() will reject this size before even asking the VM  */
82 	const vm_size_t limit = 1ull << (8 * sizeof(vm_size_t) - 1);
83 	vm_size_t s = hdr_size;
84 
85 	if (os_mul_and_add_overflow(elem_size, elem_count, s, &s) || (s & limit)) {
86 		return limit;
87 	}
88 	return s;
89 }
90 
91 #define IOKIT_TYPE_IS_COMPATIBLE_PTR(ptr, type) \
92 	(__builtin_xnu_types_compatible(os_get_pointee_type(ptr), type) ||   \
93 	    __builtin_xnu_types_compatible(os_get_pointee_type(ptr), void))  \
94 
95 #define IOKIT_TYPE_ASSERT_COMPATIBLE_POINTER(ptr, type) \
96 	_Static_assert(IOKIT_TYPE_IS_COMPATIBLE_PTR(ptr, type), \
97 	    "Pointer type is not compatible with specified type")
98 
99 /*
100  * These are opaque to the user.
101  */
102 typedef thread_t IOThread;
103 typedef void (*IOThreadFunc)(void *argument);
104 
105 /*
106  * Memory allocation functions.
107  */
108 #if XNU_KERNEL_PRIVATE
109 
110 /*
111  * IOMalloc_internal allocates memory from the specifed kalloc heap, which can be:
112  * - KHEAP_DATA_BUFFERS: Should be used for data buffers
113  * - KHEAP_DEFAULT: Should be used for allocations that aren't data buffers.
114  *
115  * For more details on kalloc_heaps see kalloc.h
116  */
117 
118 extern void *
119 IOMalloc_internal(
120 	struct kalloc_heap * kalloc_heap_cfg,
121 	vm_size_t            size,
122 	zalloc_flags_t       flags);
123 
124 __attribute__((alloc_size(2)))
125 static inline void *
__IOMalloc_internal(struct kalloc_heap * kalloc_heap_cfg,vm_size_t size,zalloc_flags_t flags)126 __IOMalloc_internal(
127 	struct kalloc_heap * kalloc_heap_cfg,
128 	vm_size_t            size,
129 	zalloc_flags_t       flags)
130 {
131 	void *addr = (IOMalloc_internal)(kalloc_heap_cfg, size, flags);
132 	if (flags & Z_NOFAIL) {
133 		__builtin_assume(addr != NULL);
134 	}
135 	return addr;
136 }
137 
138 #define IOMalloc(size)     __IOMalloc_internal(KHEAP_DEFAULT, size, Z_WAITOK)
139 #define IOMallocZero(size) __IOMalloc_internal(KHEAP_DEFAULT, size, Z_ZERO)
140 
141 #else /* XNU_KERNEL_PRIVATE */
142 
143 /*! @function IOMalloc
144  *   @abstract Allocates general purpose, wired memory in the kernel map.
145  *   @discussion This is a general purpose utility to allocate memory in the kernel. There are no alignment guarantees given on the returned memory, and alignment may vary depending on the kernel configuration. This function may block and so should not be called from interrupt level or while a simple lock is held.
146  *   @param size Size of the memory requested.
147  *   @result Pointer to the allocated memory, or zero on failure. */
148 
149 void * IOMalloc(vm_size_t size)      __attribute__((alloc_size(1)));
150 void * IOMallocZero(vm_size_t size)  __attribute__((alloc_size(1)));
151 
152 /*! @function IOFree
153  *   @abstract Frees memory allocated with IOMalloc.
154  *   @discussion This function frees memory allocated with IOMalloc, it may block and so should not be called from interrupt level or while a simple lock is held.
155  *   @param address Pointer to the allocated memory. Must be identical to result
156  *   @of a prior IOMalloc.
157  *   @param size Size of the memory allocated. Must be identical to size of
158  *   @the corresponding IOMalloc */
159 
160 #endif /* XNU_KERNEL_PRIVATE */
161 
162 #if XNU_KERNEL_PRIVATE
163 
164 /*
165  * IOFree_internal allows specifying the kalloc heap to free the allocation
166  * to
167  */
168 
169 extern void
170 IOFree_internal(
171 	struct kalloc_heap * kalloc_heap_cfg,
172 	void               * inAddress,
173 	vm_size_t            size);
174 
175 #endif /* XNU_KERNEL_PRIVATE */
176 
177 void   IOFree(void * address, vm_size_t size);
178 
179 /*! @function IOMallocAligned
180  *   @abstract Allocates wired memory in the kernel map, with an alignment restriction.
181  *   @discussion This is a utility to allocate memory in the kernel, with an alignment restriction which is specified as a byte count. This function may block and so should not be called from interrupt level or while a simple lock is held.
182  *   @param size Size of the memory requested.
183  *   @param alignment Byte count of the alignment for the memory. For example, pass 256 to get memory allocated at an address with bit 0-7 zero.
184  *   @result Pointer to the allocated memory, or zero on failure. */
185 
186 #if XNU_KERNEL_PRIVATE
187 
188 extern void *
189 IOMallocAligned_internal(
190 	struct kalloc_heap * kalloc_heap_cfg,
191 	vm_size_t            size,
192 	vm_size_t            alignment,
193 	zalloc_flags_t       flags);
194 
195 __attribute__((alloc_size(2)))
196 static inline void *
__IOMallocAligned_internal(struct kalloc_heap * kalloc_heap_cfg,vm_size_t size,vm_size_t alignment,zalloc_flags_t flags)197 __IOMallocAligned_internal(
198 	struct kalloc_heap * kalloc_heap_cfg,
199 	vm_size_t            size,
200 	vm_size_t            alignment,
201 	zalloc_flags_t       flags)
202 {
203 	void *addr = (IOMallocAligned_internal)(kalloc_heap_cfg, size, alignment, flags);
204 	if (flags & Z_NOFAIL) {
205 		__builtin_assume(addr != NULL);
206 	}
207 	return addr;
208 }
209 
210 #define IOMallocAligned(size, alignment) \
211 	__IOMallocAligned_internal(GET_KEXT_KHEAP_DATA(), size, alignment, Z_WAITOK)
212 
213 #else /* XNU_KERNEL_PRIVATE */
214 
215 void * IOMallocAligned(vm_size_t size, vm_offset_t alignment) __attribute__((alloc_size(1)));
216 
217 #endif /* !XNU_KERNEL_PRIVATE */
218 
219 
220 /*! @function IOFreeAligned
221  *   @abstract Frees memory allocated with IOMallocAligned.
222  *   @discussion This function frees memory allocated with IOMallocAligned, it may block and so should not be called from interrupt level or while a simple lock is held.
223  *   @param address Pointer to the allocated memory.
224  *   @param size Size of the memory allocated. */
225 
226 #if XNU_KERNEL_PRIVATE
227 
228 /*
229  * IOFreeAligned_internal allows specifying the kalloc heap to free the
230  * allocation to
231  */
232 
233 extern void
234 IOFreeAligned_internal(
235 	struct kalloc_heap * kalloc_heap_cfg,
236 	void               * address,
237 	vm_size_t            size);
238 
239 #endif /* XNU_KERNEL_PRIVATE */
240 
241 void   IOFreeAligned(void * address, vm_size_t size);
242 
243 /*! @function IOMallocContiguous
244  *   @abstract Deprecated - use IOBufferMemoryDescriptor. Allocates wired memory in the kernel map, with an alignment restriction and physically contiguous.
245  *   @discussion This is a utility to allocate memory in the kernel, with an alignment restriction which is specified as a byte count, and will allocate only physically contiguous memory. The request may fail if memory is fragmented, and may cause large amounts of paging activity. This function may block and so should not be called from interrupt level or while a simple lock is held.
246  *   @param size Size of the memory requested.
247  *   @param alignment Byte count of the alignment for the memory. For example, pass 256 to get memory allocated at an address with bits 0-7 zero.
248  *   @param physicalAddress IOMallocContiguous returns the physical address of the allocated memory here, if physicalAddress is a non-zero pointer. The physicalAddress argument is deprecated and should be passed as NULL. To obtain the physical address for a memory buffer, use the IODMACommand class in conjunction with the IOMemoryDescriptor or IOBufferMemoryDescriptor classes.
249  *   @result Virtual address of the allocated memory, or zero on failure. */
250 
251 void * IOMallocContiguous(vm_size_t size, vm_size_t alignment,
252     IOPhysicalAddress * physicalAddress) __attribute__((deprecated)) __attribute__((alloc_size(1)));
253 
254 /*! @function IOFreeContiguous
255  *   @abstract Deprecated - use IOBufferMemoryDescriptor. Frees memory allocated with IOMallocContiguous.
256  *   @discussion This function frees memory allocated with IOMallocContiguous, it may block and so should not be called from interrupt level or while a simple lock is held.
257  *   @param address Virtual address of the allocated memory.
258  *   @param size Size of the memory allocated. */
259 
260 void   IOFreeContiguous(void * address, vm_size_t size) __attribute__((deprecated));
261 
262 
263 /*! @function IOMallocPageable
264  *   @abstract Allocates pageable memory in the kernel map.
265  *   @discussion This is a utility to allocate pageable memory in the kernel. This function may block and so should not be called from interrupt level or while a simple lock is held.
266  *   @param size Size of the memory requested.
267  *   @param alignment Byte count of the alignment for the memory. For example, pass 256 to get memory allocated at an address with bits 0-7 zero.
268  *   @result Pointer to the allocated memory, or zero on failure. */
269 
270 void * IOMallocPageable(vm_size_t size, vm_size_t alignment) __attribute__((alloc_size(1)));
271 
272 /*! @function IOMallocPageableZero
273  *   @abstract Allocates pageable, zeroed memory in the kernel map.
274  *   @discussion Same as IOMallocPageable but guarantees the returned memory will be zeroed.
275  *   @param size Size of the memory requested.
276  *   @param alignment Byte count of the alignment for the memory. For example, pass 256 to get memory allocated at an address with bits 0-7 zero.
277  *   @result Pointer to the allocated memory, or zero on failure. */
278 
279 void * IOMallocPageableZero(vm_size_t size, vm_size_t alignment) __attribute__((alloc_size(1)));
280 
281 /*! @function IOFreePageable
282  *   @abstract Frees memory allocated with IOMallocPageable.
283  *   @discussion This function frees memory allocated with IOMallocPageable, it may block and so should not be called from interrupt level or while a simple lock is held.
284  *   @param address Virtual address of the allocated memory.
285  *   @param size Size of the memory allocated. */
286 
287 void IOFreePageable(void * address, vm_size_t size);
288 
289 #if XNU_KERNEL_PRIVATE
290 
291 #define IOMallocData(size) __IOMalloc_internal(GET_KEXT_KHEAP_DATA(), size, Z_WAITOK)
292 #define IOMallocZeroData(size) __IOMalloc_internal(GET_KEXT_KHEAP_DATA(), size, Z_ZERO)
293 
294 #define IOMallocDataSharable(size) __IOMalloc_internal(KHEAP_DATA_SHARED, size, Z_WAITOK)
295 #define IOMallocZeroDataSharable() __IOMalloc_internal(KHEAP_DATA_SHARED, size, Z_ZERO)
296 
297 #else /* XNU_KERNEL_PRIVATE */
298 
299 /*! @function IOMallocData
300  *   @abstract Allocates wired memory in the kernel map, from a separate section meant for pure data.
301  *   @discussion Same as IOMalloc except that this function should be used for allocating pure data.
302  *   @param size Size of the memory requested.
303  *   @result Pointer to the allocated memory, or zero on failure. */
304 void * IOMallocData(vm_size_t size) __attribute__((alloc_size(1)));
305 
306 /*! @function IOMallocZeroData
307  *   @abstract Allocates wired memory in the kernel map, from a separate section meant for pure data bytes that don't contain pointers.
308  *   @discussion Same as IOMallocData except that the memory returned is zeroed.
309  *   @param size Size of the memory requested.
310  *   @result Pointer to the allocated memory, or zero on failure. */
311 void * IOMallocZeroData(vm_size_t size) __attribute__((alloc_size(1)));
312 
313 /*! @function IOMallocDataSharable
314  *   @abstract Allocates wired memory in the kernel map, from a separate section meant for pure data that meant to be shared.
315  *   @discussion Same as IOMalloc except that this function should be used for allocating pure data.
316  *   @param size Size of the memory requested.
317  *   @result Pointer to the allocated memory, or zero on failure. */
318 void * IOMallocDataSharable(vm_size_t size) __attribute__((alloc_size(1)));
319 
320 /*! @function IOMallocZeroDataSharable
321  *   @abstract Allocates wired memory in the kernel map, from a separate section meant for pure data bytes that don't contain pointers and meant to be shared.
322  *   @discussion Same as IOMallocDataSharable except that the memory returned is zeroed.
323  *   @param size Size of the memory requested.
324  *   @result Pointer to the allocated memory, or zero on failure. */
325 void * IOMallocZeroDataSharable(vm_size_t size) __attribute__((alloc_size(1)));
326 
327 #endif /* !XNU_KERNEL_PRIVATE */
328 
329 /*! @function IOFreeData
330  *   @abstract Frees memory allocated with IOMallocData or IOMallocZeroData.
331  *   @discussion This function frees memory allocated with IOMallocData/IOMallocZeroData, it may block and so should not be called from interrupt level or while a simple lock is held.
332  *   @param address Virtual address of the allocated memory. Passing NULL here is acceptable.
333  *   @param size Size of the memory allocated. It is acceptable to pass 0 size for a NULL address. */
334 void IOFreeData(void * address, vm_size_t size);
335 
336 /*! @function IOFreeDataSharable
337  *   @abstract Frees memory allocated with IOMallocDataSharable or IOMallocZeroDataSharable.
338  *   @discussion This function frees memory allocated with IOMallocDataSharable/IOMallocZeroDataSharable, it may block and so should not be called from interrupt level or while a simple lock is held.
339  *   @param address Virtual address of the allocated memory. Passing NULL here is acceptable.
340  *   @param size Size of the memory allocated. It is acceptable to pass 0 size for a NULL address. */
341 void IOFreeDataSharable(void * address, vm_size_t size);
342 
343 #define IONewData(type, count) \
344 	((type *)IOMallocData(IOMallocArraySize(0, sizeof(type), count)))
345 
346 #define IONewZeroData(type, count) \
347 	((type *)IOMallocZeroData(IOMallocArraySize(0, sizeof(type), count)))
348 
349 #define IODeleteData(ptr, type, count) ({ \
350 	vm_size_t  __count = (vm_size_t)(count);             \
351 	IOKIT_TYPE_ASSERT_COMPATIBLE_POINTER(ptr, type);     \
352 	IOFreeData(os_ptr_load_and_erase(ptr),               \
353 	    IOMallocArraySize(0, sizeof(type), __count));    \
354 })
355 
356 #if KERNEL_PRIVATE
357 
358 /*
359  * Typed memory allocation macros. All may block.
360  */
361 
362 /*
363  * Use IOMallocType to allocate a single typed object.
364  *
365  * If you use IONew with count 1, please use IOMallocType
366  * instead. For arrays of typed objects use IONew.
367  *
368  * IOMallocType returns zeroed memory. It will not
369  * fail to allocate memory for sizes less than:
370  * - 16K (macos)
371  * - 8K  (embedded 32-bit)
372  * - 32K (embedded 64-bit)
373  */
374 #define IOMallocType(type) ({                           \
375 	static _KALLOC_TYPE_DEFINE(kt_view_var, type,       \
376 	    KT_SHARED_ACCT);                                \
377 	(type *) IOMallocTypeImpl(kt_view_var);             \
378 })
379 
380 #define IOFreeType(elem, type) ({                       \
381 	static _KALLOC_TYPE_DEFINE(kt_view_var, type,       \
382 	   KT_SHARED_ACCT);                                 \
383 	IOFREETYPE_ASSERT_COMPATIBLE_POINTER(elem, type);   \
384 	IOFreeTypeImpl(kt_view_var,                         \
385 	    os_ptr_load_and_erase(elem));                   \
386 })
387 
388 /*
389  * Versioning macro for the typed allocator APIs.
390  */
391 #define IO_TYPED_ALLOCATOR_VERSION    1
392 
393 #endif /* KERNEL_PRIVATE */
394 
395 /*
396  * IONew/IONewZero/IODelete/IOSafeDeleteNULL
397  *
398  * Those functions come in 2 variants:
399  *
400  * 1. IONew(element_type, count)
401  *    IONewZero(element_type, count)
402  *    IODelete(ptr, element_type, count)
403  *    IOSafeDeleteNULL(ptr, element_type, count)
404  *
405  *    Those allocate/free arrays of `count` elements of type `element_type`.
406  *
407  * 2. IONew(hdr_type, element_type, count)
408  *    IONewZero(hdr_type, element_type, count)
409  *    IODelete(ptr, hdr_type, element_type, count)
410  *    IOSafeDeleteNULL(ptr, hdr_type, element_type, count)
411  *
412  *    Those allocate/free arrays with `count` elements of type `element_type`,
413  *    prefixed with a header of type `hdr_type`, like this:
414  *
415  * Those perform safe math with the sizes, checking for overflow.
416  * An overflow in the sizes will cause the allocation to return NULL.
417  */
418 #define IONew(...)             __IOKIT_DISPATCH(IONew, ##__VA_ARGS__)
419 #define IONewZero(...)         __IOKIT_DISPATCH(IONewZero, ##__VA_ARGS__)
420 #define IODelete(...)          __IOKIT_DISPATCH(IODelete, ##__VA_ARGS__)
421 #if KERNEL_PRIVATE
422 #define IOSafeDeleteNULL(...)  __IOKIT_DISPATCH(IODelete, ##__VA_ARGS__)
423 #else
424 #define IOSafeDeleteNULL(...)  __IOKIT_DISPATCH(IOSafeDeleteNULL, ##__VA_ARGS__)
425 #endif
426 
427 #if KERNEL_PRIVATE
428 #define IONew_2(e_ty, count) ({                                             \
429 	static KALLOC_TYPE_VAR_DEFINE(kt_view_var, e_ty, KT_SHARED_ACCT);       \
430 	(e_ty *) IOMallocTypeVarImpl(kt_view_var,                               \
431 	    IOMallocArraySize(0, sizeof(e_ty), count));                         \
432 })
433 
434 #define IONew_3(h_ty, e_ty, count) ({                                       \
435 	static KALLOC_TYPE_VAR_DEFINE(kt_view_var, h_ty, e_ty, KT_SHARED_ACCT); \
436 	(h_ty *) IOMallocTypeVarImpl(kt_view_var,                               \
437 	    IOMallocArraySize(sizeof(h_ty), sizeof(e_ty), count));              \
438 })
439 
440 #define IONewZero_2(e_ty, count) \
441 	IONew_2(e_ty, count)
442 
443 #define IONewZero_3(h_ty, e_ty, count) \
444 	IONew_3(h_ty, e_ty, count)
445 
446 #else /* KERNEL_PRIVATE */
447 #define IONew_2(e_ty, count) \
448 	((e_ty *)IOMalloc(IOMallocArraySize(0, sizeof(e_ty), count)))
449 
450 #define IONew_3(h_ty, e_ty, count) \
451 	((h_ty *)IOMalloc(IOMallocArraySize(sizeof(h_ty), sizeof(e_ty), count)))
452 
453 #define IONewZero_2(e_ty, count) \
454 	((e_ty *)IOMallocZero(IOMallocArraySize(0, sizeof(e_ty), count)))
455 
456 #define IONewZero_3(h_ty, e_ty, count) \
457 	((h_ty *)IOMallocZero(IOMallocArraySize(sizeof(h_ty), sizeof(e_ty), count)))
458 #endif /* !KERNEL_PRIVATE */
459 
460 #if KERNEL_PRIVATE
461 #define IODelete_3(ptr, e_ty, count) ({                                     \
462 	vm_size_t __s = IOMallocArraySize(0, sizeof(e_ty), count);              \
463 	KALLOC_TYPE_ASSERT_COMPATIBLE_POINTER(ptr, e_ty);                       \
464 	static KALLOC_TYPE_VAR_DEFINE(kt_view_var, e_ty, KT_SHARED_ACCT);       \
465 	IOFreeTypeVarImpl(kt_view_var, os_ptr_load_and_erase(ptr), __s);        \
466 })
467 
468 #define IODelete_4(ptr, h_ty, e_ty, count) ({                               \
469 	vm_size_t __s = IOMallocArraySize(sizeof(h_ty), sizeof(e_ty), count);   \
470 	KALLOC_TYPE_ASSERT_COMPATIBLE_POINTER(ptr, h_ty);                       \
471 	static KALLOC_TYPE_VAR_DEFINE(kt_view_var, h_ty, e_ty, KT_SHARED_ACCT); \
472 	IOFreeTypeVarImpl(kt_view_var, os_ptr_load_and_erase(ptr), __s);        \
473 })
474 
475 #else /* KERNEL_PRIVATE */
476 #define IODelete_3(ptr, e_ty, count) \
477 	IOFree(ptr, IOMallocArraySize(0, sizeof(e_ty), count));
478 
479 #define IODelete_4(ptr, h_ty, e_ty, count) \
480 	IOFree(ptr, IOMallocArraySize(sizeof(h_ty), sizeof(e_ty), count));
481 
482 #define IOSafeDeleteNULL_3(ptr, e_ty, count)  ({                           \
483 	vm_size_t __s = IOMallocArraySize(0, sizeof(e_ty), count);             \
484 	IOFree(os_ptr_load_and_erase(ptr), __s);                               \
485 })
486 
487 #define IOSafeDeleteNULL_4(ptr, h_ty, e_ty, count)  ({                     \
488 	vm_size_t __s = IOMallocArraySize(sizeof(h_ty), sizeof(e_ty), count);  \
489 	IOFree(os_ptr_load_and_erase(ptr), __s);                               \
490 })
491 #endif /* !KERNEL_PRIVATE */
492 
493 /////////////////////////////////////////////////////////////////////////////
494 //
495 //
496 //	These functions are now implemented in IOMapper.cpp
497 //
498 //
499 /////////////////////////////////////////////////////////////////////////////
500 
501 /*! @function IOMappedRead8
502  *   @abstract Read one byte from the desired "Physical" IOSpace address.
503  *   @discussion Read one byte from the desired "Physical" IOSpace address.  This function allows the developer to read an address returned from any memory descriptor's getPhysicalSegment routine.  It can then be used by segmenting a physical page slightly to tag the physical page with its kernel space virtual address.
504  *   @param address The desired address, as returned by IOMemoryDescriptor::getPhysicalSegment.
505  *   @result Data contained at that location */
506 
507 UInt8 IOMappedRead8(IOPhysicalAddress address);
508 
509 /*! @function IOMappedRead16
510  *   @abstract Read two bytes from the desired "Physical" IOSpace address.
511  *   @discussion Read two bytes from the desired "Physical" IOSpace address.  This function allows the developer to read an address returned from any memory descriptor's getPhysicalSegment routine.  It can then be used by segmenting a physical page slightly to tag the physical page with its kernel space virtual address.
512  *   @param address The desired address, as returned by IOMemoryDescriptor::getPhysicalSegment.
513  *   @result Data contained at that location */
514 
515 UInt16 IOMappedRead16(IOPhysicalAddress address);
516 
517 /*! @function IOMappedRead32
518  *   @abstract Read four bytes from the desired "Physical" IOSpace address.
519  *   @discussion Read four bytes from the desired "Physical" IOSpace address.  This function allows the developer to read an address returned from any memory descriptor's getPhysicalSegment routine.  It can then be used by segmenting a physical page slightly to tag the physical page with its kernel space virtual address.
520  *   @param address The desired address, as returned by IOMemoryDescriptor::getPhysicalSegment.
521  *   @result Data contained at that location */
522 
523 UInt32 IOMappedRead32(IOPhysicalAddress address);
524 
525 /*! @function IOMappedRead64
526  *   @abstract Read eight bytes from the desired "Physical" IOSpace address.
527  *   @discussion Read eight bytes from the desired "Physical" IOSpace address.  This function allows the developer to read an address returned from any memory descriptor's getPhysicalSegment routine.  It can then be used by segmenting a physical page slightly to tag the physical page with its kernel space virtual address.
528  *   @param address The desired address, as returned by IOMemoryDescriptor::getPhysicalSegment.
529  *   @result Data contained at that location */
530 
531 UInt64 IOMappedRead64(IOPhysicalAddress address);
532 
533 /*! @function IOMappedWrite8
534  *   @abstract Write one byte to the desired "Physical" IOSpace address.
535  *   @discussion Write one byte to the desired "Physical" IOSpace address.  This function allows the developer to write to an address returned from any memory descriptor's getPhysicalSegment routine.
536  *   @param address The desired address, as returned by IOMemoryDescriptor::getPhysicalSegment.
537  *   @param value Data to be writen to the desired location */
538 
539 void IOMappedWrite8(IOPhysicalAddress address, UInt8 value);
540 
541 /*! @function IOMappedWrite16
542  *   @abstract Write two bytes to the desired "Physical" IOSpace address.
543  *   @discussion Write two bytes to the desired "Physical" IOSpace address.  This function allows the developer to write to an address returned from any memory descriptor's getPhysicalSegment routine.
544  *   @param address The desired address, as returned by IOMemoryDescriptor::getPhysicalSegment.
545  *   @param value Data to be writen to the desired location */
546 
547 void IOMappedWrite16(IOPhysicalAddress address, UInt16 value);
548 
549 /*! @function IOMappedWrite32
550  *   @abstract Write four bytes to the desired "Physical" IOSpace address.
551  *   @discussion Write four bytes to the desired "Physical" IOSpace address.  This function allows the developer to write to an address returned from any memory descriptor's getPhysicalSegment routine.
552  *   @param address The desired address, as returned by IOMemoryDescriptor::getPhysicalSegment.
553  *   @param value Data to be writen to the desired location */
554 
555 void IOMappedWrite32(IOPhysicalAddress address, UInt32 value);
556 
557 /*! @function IOMappedWrite64
558  *   @abstract Write eight bytes to the desired "Physical" IOSpace address.
559  *   @discussion Write eight bytes to the desired "Physical" IOSpace address.  This function allows the developer to write to an address returned from any memory descriptor's getPhysicalSegment routine.
560  *   @param address The desired address, as returned by IOMemoryDescriptor::getPhysicalSegment.
561  *   @param value Data to be writen to the desired location */
562 
563 void IOMappedWrite64(IOPhysicalAddress address, UInt64 value);
564 
565 /* This function is deprecated. Cache settings may be set for allocated memory with the IOBufferMemoryDescriptor api. */
566 
567 IOReturn IOSetProcessorCacheMode( task_t task, IOVirtualAddress address,
568     IOByteCount length, IOOptionBits cacheMode ) __attribute__((deprecated));
569 
570 /*! @function IOFlushProcessorCache
571  *   @abstract Flushes the processor cache for mapped memory.
572  *   @discussion This function flushes the processor cache of an already mapped memory range. Note in most cases it is preferable to use IOMemoryDescriptor::prepare and complete to manage cache coherency since they are aware of the architecture's requirements. Flushing the processor cache is not required for coherency in most situations.
573  *   @param task Task the memory is mapped into.
574  *   @param address Virtual address of the memory.
575  *   @param length Length of the range to set.
576  *   @result An IOReturn code. */
577 
578 IOReturn IOFlushProcessorCache( task_t task, IOVirtualAddress address,
579     IOByteCount length );
580 
581 /*! @function IOThreadSelf
582  *   @abstract Returns the osfmk identifier for the currently running thread.
583  *   @discussion This function returns the current thread (a pointer to the currently active osfmk thread_shuttle). */
584 
585 #define IOThreadSelf() (current_thread())
586 
587 /*! @function IOCreateThread
588  *   @abstract Deprecated function - use kernel_thread_start(). Create a kernel thread.
589  *   @discussion This function creates a kernel thread, and passes the caller supplied argument to the new thread.  Warning: the value returned by this function is not 100% reliable.  There is a race condition where it is possible that the new thread has already terminated before this call returns.  Under that circumstance the IOThread returned will be invalid.  In general there is little that can be done with this value except compare it against 0.  The thread itself can call IOThreadSelf() 100% reliably and that is the prefered mechanism to manipulate the IOThreads state.
590  *   @param function A C-function pointer where the thread will begin execution.
591  *   @param argument Caller specified data to be passed to the new thread.
592  *   @result An IOThread identifier for the new thread, equivalent to an osfmk thread_t. */
593 
594 IOThread IOCreateThread(IOThreadFunc function, void *argument) __attribute__((deprecated));
595 
596 /*! @function IOExitThread
597  *   @abstract Deprecated function - use thread_terminate(). Terminate execution of current thread.
598  *   @discussion This function destroys the currently running thread, and does not return. */
599 
600 void IOExitThread(void) __attribute__((deprecated));
601 
602 /*! @function IOSleep
603  *   @abstract Sleep the calling thread for a number of milliseconds.
604  *   @discussion This function blocks the calling thread for at least the number of specified milliseconds, giving time to other processes.
605  *   @param milliseconds The integer number of milliseconds to wait. */
606 
607 void IOSleep(unsigned milliseconds);
608 
609 /*! @function IOSleepWithLeeway
610  *   @abstract Sleep the calling thread for a number of milliseconds, with a specified leeway the kernel may use for timer coalescing.
611  *   @discussion This function blocks the calling thread for at least the number of specified milliseconds, giving time to other processes.  The kernel may also coalesce any timers involved in the delay, using the leeway given as a guideline.
612  *   @param intervalMilliseconds The integer number of milliseconds to wait.
613  *   @param leewayMilliseconds The integer number of milliseconds to use as a timer coalescing guideline. */
614 
615 void IOSleepWithLeeway(unsigned intervalMilliseconds, unsigned leewayMilliseconds);
616 
617 /*! @function IODelay
618  *   @abstract Spin delay for a number of microseconds.
619  *   @discussion This function spins to delay for at least the number of specified microseconds. Since the CPU is busy spinning no time is made available to other processes; this method of delay should be used only for short periods. Also, the AbsoluteTime based APIs of kern/clock.h provide finer grained and lower cost delays.
620  *   @param microseconds The integer number of microseconds to spin wait. */
621 
622 void IODelay(unsigned microseconds);
623 
624 /*! @function IOPause
625  *   @abstract Spin delay for a number of nanoseconds.
626  *   @discussion This function spins to delay for at least the number of specified nanoseconds. Since the CPU is busy spinning no time is made available to other processes; this method of delay should be used only for short periods.
627  *   @param nanoseconds The integer number of nanoseconds to spin wait. */
628 
629 void IOPause(unsigned nanoseconds);
630 
631 /*! @function IOLog
632  *   @abstract Log a message to console in text mode, and /var/log/system.log.
633  *   @discussion This function allows a driver to log diagnostic information to the screen during verbose boots, and to a log file found at /var/log/system.log. IOLog should not be called from interrupt context.
634  *   @param format A printf() style format string (see printf(3) documentation).
635  */
636 
637 void IOLog(const char *format, ...)
638 __attribute__((format(printf, 1, 2)));
639 
640 /*! @function IOLogv
641  *   @abstract Log a message to console in text mode, and /var/log/system.log.
642  *   @discussion This function allows a driver to log diagnostic information to the screen during verbose boots, and to a log file found at /var/log/system.log. IOLogv should not be called from interrupt context.
643  *   @param format A printf() style format string (see printf(3) documentation).
644  *   @param ap stdarg(3) style variable arguments. */
645 
646 void IOLogv(const char *format, va_list ap)
647 __attribute__((format(printf, 1, 0)));
648 
649 #ifndef _FN_KPRINTF
650 #define _FN_KPRINTF
651 void kprintf(const char *format, ...) __printflike(1, 2);
652 #endif
653 #ifndef _FN_KPRINTF_DECLARED
654 #define _FN_KPRINTF_DECLARED
655 #endif
656 
657 /*
658  * Convert a integer constant (typically a #define or enum) to a string
659  * via an array of IONamedValue.
660  */
661 const char *IOFindNameForValue(int value,
662     const IONamedValue *namedValueArray);
663 
664 /*
665  * Convert a string to an int via an array of IONamedValue. Returns
666  * kIOReturnSuccess of string found, else returns kIOReturnBadArgument.
667  */
668 IOReturn IOFindValueForName(const char *string,
669     const IONamedValue *regValueArray,
670     int *value);                                /* RETURNED */
671 
672 /*! @function Debugger
673  *   @abstract Enter the kernel debugger.
674  *   @discussion This function freezes the kernel and enters the builtin debugger. It may not be possible to exit the debugger without a second machine.
675  *   @param reason A C-string to describe why the debugger is being entered. */
676 
677 void Debugger(const char * reason);
678 #if __LP64__
679 #define IOPanic(reason) panic("%s", reason)
680 #else
681 void IOPanic(const char *reason) __attribute__((deprecated)) __abortlike;
682 #endif
683 
684 #ifdef __cplusplus
685 class OSDictionary;
686 #endif
687 
688 #ifdef __cplusplus
689 OSDictionary *
690 #else
691 struct OSDictionary *
692 #endif
693 IOBSDNameMatching( const char * name );
694 
695 #ifdef __cplusplus
696 OSDictionary *
697 #else
698 struct OSDictionary *
699 #endif
700 IOOFPathMatching( const char * path, char * buf, int maxLen ) __attribute__((deprecated));
701 
702 /*
703  * Convert between size and a power-of-two alignment.
704  */
705 IOAlignment IOSizeToAlignment(unsigned int size);
706 unsigned int IOAlignmentToSize(IOAlignment align);
707 
708 /*
709  * Multiply and divide routines for IOFixed datatype.
710  */
711 
712 static inline IOFixed
IOFixedMultiply(IOFixed a,IOFixed b)713 IOFixedMultiply(IOFixed a, IOFixed b)
714 {
715 	return (IOFixed)((((SInt64) a) * ((SInt64) b)) >> 16);
716 }
717 
718 static inline IOFixed
IOFixedDivide(IOFixed a,IOFixed b)719 IOFixedDivide(IOFixed a, IOFixed b)
720 {
721 	return (IOFixed)((((SInt64) a) << 16) / ((SInt64) b));
722 }
723 
724 /*
725  * IORound and IOTrunc convenience functions, in the spirit
726  * of vm's round_page() and trunc_page().
727  */
728 #define IORound(value, multiple) \
729 	((((value) + (multiple) - 1) / (multiple)) * (multiple))
730 
731 #define IOTrunc(value, multiple) \
732 	(((value) / (multiple)) * (multiple));
733 
734 
735 #if defined(__APPLE_API_OBSOLETE)
736 
737 /* The following API is deprecated */
738 
739 /* The API exported by kern/clock.h
740  *  should be used for high resolution timing. */
741 
742 void IOGetTime( mach_timespec_t * clock_time) __attribute__((deprecated));
743 
744 #if !defined(__LP64__)
745 
746 #undef eieio
747 #define eieio() \
748     OSSynchronizeIO()
749 
750 extern mach_timespec_t IOZeroTvalspec;
751 
752 #endif /* !defined(__LP64__) */
753 
754 #endif /* __APPLE_API_OBSOLETE */
755 
756 #if XNU_KERNEL_PRIVATE
757 vm_tag_t
758 IOMemoryTag(vm_map_t map);
759 
760 vm_size_t
761 log2up(vm_size_t size);
762 #endif
763 
764 /*
765  * Implementation details
766  */
767 #define __IOKIT_COUNT_ARGS1(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, N, ...) N
768 #define __IOKIT_COUNT_ARGS(...) \
769 	__IOKIT_COUNT_ARGS1(, ##__VA_ARGS__, _9, _8, _7, _6, _5, _4, _3, _2, _1, _0)
770 #define __IOKIT_DISPATCH1(base, N, ...) __CONCAT(base, N)(__VA_ARGS__)
771 #define __IOKIT_DISPATCH(base, ...) \
772 	__IOKIT_DISPATCH1(base, __IOKIT_COUNT_ARGS(__VA_ARGS__), ##__VA_ARGS__)
773 
774 
775 #ifdef XNU_KERNEL_PRIVATE
776 
777 #define IOFREETYPE_ASSERT_COMPATIBLE_POINTER(ptr, type) \
778     KALLOC_TYPE_ASSERT_COMPATIBLE_POINTER(ptr, type)
779 
780 #else  /* XNU_KERNEL_PRIVATE */
781 
782 #define IOFREETYPE_ASSERT_COMPATIBLE_POINTER(ptr, type) do {} while (0)
783 
784 #endif /* XNU_KERNEL_PRIVATE */
785 
786 #if KERNEL_PRIVATE
787 /*
788  * Implementation functions for IOMallocType/IOFreeType.
789  * Not intended to be used on their own.
790  */
791 void *
792 IOMallocTypeImpl(kalloc_type_view_t kt_view);
793 
794 void
795 IOFreeTypeImpl(kalloc_type_view_t kt_view, void * address);
796 
797 void *
798 IOMallocTypeVarImpl(kalloc_type_var_view_t kt_view, vm_size_t size);
799 
800 void
801 IOFreeTypeVarImpl(kalloc_type_var_view_t kt_view, void * address, vm_size_t size);
802 #endif
803 
804 #if KERNEL_PRIVATE
805 #if __cplusplus
806 
807 #if __has_feature(cxx_deleted_functions)
808 #define __IODeleteArrayOperators()                         \
809 	_Pragma("clang diagnostic push")                       \
810 	_Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
811 	void *operator new[](size_t) = delete;                 \
812 	void operator delete[](void *) = delete;               \
813 	void operator delete[](void *, size_t) = delete;       \
814 	_Pragma("clang diagnostic pop")
815 #else  /* __has_feature(cxx_deleted_functions) */
816 #define __IODeleteArrayOperators()
817 #endif /* __has_feature(cxx_deleted_functions) */
818 
819 #define __IOAddOperatorsSentinel(name, type) \
820 	static void __CONCAT(name, type) (void) __unused
821 
822 #define __IOAddTypedOperatorsSentinel(type) \
823 	__IOAddOperatorsSentinel(__kt_typed_operators_, type)
824 
825 #define __IOAddTypedArrayOperatorsSentinel(type) \
826 	__IOAddOperatorsSentinel(__kt_typed_array_operators_, type)
827 
828 #define __IODeclareTypedOperators(type)                    \
829 	void *operator new(size_t size __unused);              \
830 	void operator delete(void *mem, size_t size __unused); \
831 	__IOAddTypedOperatorsSentinel(type)
832 
833 #define __IODeclareTypedArrayOperators(type) \
834 	void *operator new[](size_t __unused);   \
835 	void operator delete[](void *ptr);       \
836 	__IOAddTypedArrayOperatorsSentinel(type)
837 
838 
839 #define __IODefineTypedOperators(type)                          \
840 	void *type::operator new(size_t size __unused)              \
841 	{                                                           \
842 	        return IOMallocType(type);                                \
843 	}                                                           \
844 	void type::operator delete(void *mem, size_t size __unused) \
845 	{                                                           \
846 	        IOFreeType(mem, type);                                    \
847 	}
848 
849 
850 extern "C++" {
851 template<typename T>
852 struct __IOTypedOperatorsArrayHeader {
853 	size_t alloc_size;
854 	_Alignas(T) char array[];
855 };
856 
857 #define __IOTypedOperatorNewArrayImpl(type, count)                        \
858 	{                                                                  \
859 	        typedef __IOTypedOperatorsArrayHeader<type> hdr_ty;        \
860 	        static KALLOC_TYPE_VAR_DEFINE(kt_view_var,                 \
861 	            hdr_ty, type, KT_SHARED_ACCT);                         \
862 	        hdr_ty *hdr;                                               \
863 	        const size_t __s = sizeof(hdr_ty) + count;                 \
864 	        hdr = reinterpret_cast<hdr_ty *>(                          \
865 	            IOMallocTypeVarImpl(kt_view_var, __s));                \
866 	        if (hdr) {                                                 \
867 	                hdr->alloc_size = __s;                             \
868 	                return reinterpret_cast<void *>(&hdr->array);      \
869 	        }                                                          \
870 	        _Pragma("clang diagnostic push")                           \
871 	        _Pragma("clang diagnostic ignored \"-Wnew-returns-null\"") \
872 	        return NULL;                                               \
873 	        _Pragma("clang diagnostic pop")                            \
874 	}
875 
876 #define __IOTypedOperatorDeleteArrayImpl(type, ptr)                  \
877 	{                                                             \
878 	        typedef __IOTypedOperatorsArrayHeader<type> hdr_ty;   \
879 	        static KALLOC_TYPE_VAR_DEFINE(kt_view_var,            \
880 	            hdr_ty, type, KT_SHARED_ACCT);                    \
881 	        hdr_ty *hdr = reinterpret_cast<hdr_ty *>(             \
882 	            reinterpret_cast<uintptr_t>(ptr) - sizeof(*hdr)); \
883 	        IOFreeTypeVarImpl(kt_view_var,                        \
884 	        reinterpret_cast<void *>(hdr), hdr->alloc_size);  \
885 	}
886 
887 #define __IODefineTypedArrayOperators(type)        \
888 	void *type::operator new[](size_t count)       \
889 	__IOTypedOperatorNewArrayImpl(type, count)  \
890 	void type::operator delete[](void *ptr)        \
891 	__IOTypedOperatorDeleteArrayImpl(type, ptr)
892 
893 
894 #define __IOOverrideTypedOperators(type)                  \
895 	void *operator new(size_t size __unused)              \
896 	{                                                     \
897 	        return IOMallocType(type);                        \
898 	}                                                     \
899 	void operator delete(void *mem, size_t size __unused) \
900 	{                                                     \
901 	        IOFreeType(mem, type);                            \
902 	} \
903 	__IOAddTypedOperatorsSentinel(type)
904 
905 #define __IOOverrideTypedArrayOperators(type)       \
906 	void *operator new[](size_t count)              \
907 	__IOTypedOperatorNewArrayImpl(type, count)   \
908 	void operator delete[](void *ptr)               \
909 	__IOTypedOperatorDeleteArrayImpl(type, ptr)  \
910 	__IOAddTypedArrayOperatorsSentinel(type)
911 
912 /*!
913  * @macro IODeclareTypedOperators
914  *
915  * @abstract
916  * Declare operator new/delete to adopt the typed allocator
917  * API for a given class/struct. It must be paired with
918  * @c IODefineTypedOperators.
919  *
920  * @discussion
921  * Use this macro within a class/struct declaration to declare
922  * @c operator new and @c operator delete to use the typed
923  * allocator API as the backing storage for this type.
924  *
925  * @note The default variant deletes the declaration of the
926  * array operators. Please see doc/allocators/api-basics.md for
927  * more details regarding their usage.
928  *
929  * @param type The type which the declarations are being provided for.
930  */
931 #define IODeclareTypedOperatorsSupportingArrayOperators(type) \
932 	__IODeclareTypedArrayOperators(type);                     \
933 	__IODeclareTypedOperators(type)
934 #define IODeclareTypedOperators(type) \
935 	__IODeleteArrayOperators()        \
936 	__IODeclareTypedOperators(type)
937 
938 /*!
939  * @macro IODefineTypedOperators
940  *
941  * @abstract
942  * Define (out of line) operator new/delete to adopt the typed
943  * allocator API for a given class/struct. It must be paired
944  * with @c IODeclareTypedOperators.
945  *
946  * @discussion
947  * Use this macro to provide an out of line definition of
948  * @c operator new and @c operator delete for a given type
949  * to use the typed allocator API as its backing storage.
950  *
951  * @param type The type which the overrides are being provided for.
952  */
953 #define IODefineTypedOperatorsSupportingArrayOperators(type) \
954 	__IODefineTypedOperators(type)                           \
955 	__IODefineTypedArrayOperators(type)
956 #define IODefineTypedOperators(type) \
957 	__IODefineTypedOperators(type)
958 
959 /*!
960  * @macro IOOverrideTypedOperators
961  *
962  * @abstract
963  * Override operator new/delete to use @c kalloc_type.
964  *
965  * @discussion
966  * Use this macro within a class/struct declaration to override
967  * @c operator new and @c operator delete to use the typed
968  * allocator API as the backing storage for this type.
969  *
970  * @note The default variant deletes the implementation of the
971  * array operators. Please see doc/allocators/api-basics.md for
972  * more details regarding their usage.
973  *
974  * @param type The type which the overrides are being provided for.
975  */
976 #define IOOverrideTypedOperators(type) \
977 	__IODeleteArrayOperators()         \
978 	__IOOverrideTypedOperators(type)
979 
980 #define IOOverrideTypedOperatorsSupportingArrayOperators(type) \
981 	__IOOverrideTypedArrayOperators(type);                     \
982 	__IOOverrideTypedOperators(type)
983 
984 
985 /*!
986  * @template IOTypedOperatorsMixin
987  *
988  * @abstract
989  * Mixin that implements @c operator new and @c operator delete
990  * using the typed allocator API.
991  *
992  * @discussion
993  * Inherit from this struct in order to adopt the typed allocator
994  * API on a struct/class for @c operator new and @c operator delete.
995  *
996  * The type passed as as a template parameter must be the type
997  * which is inheriting from the struct itself.
998  *
999  * @note See doc/allocators/api-basics.md for more details
1000  * regarding the usage of the mixin.
1001  *
1002  * @example
1003  *
1004  *     class C : public IOTypedOperatorsMixin<C> {
1005  *         ...
1006  *     }
1007  *     C *obj = new C;
1008  *
1009  */
1010 template<class T>
1011 struct IOTypedOperatorsMixin {
1012 	IOOverrideTypedOperators(T);
1013 };
1014 
1015 template<class T>
1016 struct IOTypedOperatorsMixinSupportingArrayOperators {
1017 	IOOverrideTypedOperatorsSupportingArrayOperators(T);
1018 };
1019 } // extern "C++"
1020 
1021 
1022 #endif /* __cplusplus */
1023 #endif /* KERNEL_PRIVATE */
1024 
1025 __END_DECLS
1026 
1027 #endif /* !__IOKIT_IOLIB_H */
1028