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