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