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