/ duct-tape / xnu / iokit / IOKit / IOBufferMemoryDescriptor.h
IOBufferMemoryDescriptor.h
  1  /*
  2   * Copyright (c) 1998-2016 Apple 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  #ifndef _IOBUFFERMEMORYDESCRIPTOR_H
 29  #define _IOBUFFERMEMORYDESCRIPTOR_H
 30  
 31  #include <libkern/c++/OSPtr.h>
 32  #include <IOKit/IOMemoryDescriptor.h>
 33  #include <DriverKit/IOBufferMemoryDescriptor.h>
 34  
 35  enum {
 36  	kIOMemoryPhysicallyContiguous       = 0x00000010,
 37  	kIOMemoryPageable                   = 0x00000020,
 38  	kIOMemoryPurgeable                  = 0x00000040,
 39  	kIOMemoryHostPhysicallyContiguous   = 0x00000080,
 40  	kIOMemorySharingTypeMask            = 0x000f0000,
 41  	kIOMemoryUnshared                   = 0x00000000,
 42  	kIOMemoryKernelUserShared           = 0x00010000,
 43  	// shared IOMemoryDescriptor options for IOBufferMemoryDescriptor:
 44  	kIOBufferDescriptorMemoryFlags      = kIOMemoryDirectionMask
 45  #ifdef XNU_KERNEL_PRIVATE
 46  	    | kIOMemoryAutoPrepare
 47  #endif
 48  	    | kIOMemoryThreadSafe
 49  	    | kIOMemoryClearEncrypt
 50  	    | kIOMemoryMapperNone
 51  	    | kIOMemoryUseReserve
 52  };
 53  
 54  #define _IOBUFFERMEMORYDESCRIPTOR_INTASKWITHOPTIONS_            1
 55  #define _IOBUFFERMEMORYDESCRIPTOR_HOSTPHYSICALLYCONTIGUOUS_     1
 56  #define IOBUFFERMEMORYDESCRIPTOR_SUPPORTS_INTASKWITHOPTIONS_TAGS        1
 57  /*!
 58   *   @class IOBufferMemoryDescriptor
 59   *   @abstract Provides a simple memory descriptor that allocates its own buffer memory.
 60   */
 61  
 62  class IOBufferMemoryDescriptor : public IOGeneralMemoryDescriptor
 63  {
 64  	OSDeclareDefaultStructorsWithDispatch(IOBufferMemoryDescriptor);
 65  
 66  private:
 67  /*! @struct ExpansionData
 68   *   @discussion This structure will be used to expand the capablilties of this class in the future.
 69   */
 70  	struct ExpansionData {
 71  		IOMemoryMap *   map;
 72  	};
 73  
 74  /*! @var reserved
 75   *   Reserved for future use.  (Internal use only)  */
 76  	APPLE_KEXT_WSHADOW_PUSH;
 77  	ExpansionData * reserved;
 78  
 79  protected:
 80  	void *               _buffer;
 81  	vm_size_t            _capacity;
 82  	vm_offset_t          _alignment;
 83  	IOOptionBits         _options;
 84  private:
 85  	uintptr_t            _internalReserved;
 86  	unsigned             _internalFlags;
 87  	APPLE_KEXT_WSHADOW_POP;
 88  
 89  private:
 90  #ifndef __LP64__
 91  	virtual bool initWithOptions(
 92  		IOOptionBits options,
 93  		vm_size_t    capacity,
 94  		vm_offset_t  alignment,
 95  		task_t       inTask) APPLE_KEXT_DEPRECATED;                /* use withOptions() instead */
 96  #endif /* !__LP64__ */
 97  
 98  public:
 99  	virtual bool initWithPhysicalMask(
100  		task_t            inTask,
101  		IOOptionBits      options,
102  		mach_vm_size_t    capacity,
103  		mach_vm_address_t alignment,
104  		mach_vm_address_t physicalMask);
105  
106  #ifdef __LP64__
107  	OSMetaClassDeclareReservedUnused(IOBufferMemoryDescriptor, 0);
108  	OSMetaClassDeclareReservedUnused(IOBufferMemoryDescriptor, 1);
109  #else /* !__LP64__ */
110  	OSMetaClassDeclareReservedUsedX86(IOBufferMemoryDescriptor, 0);
111  	OSMetaClassDeclareReservedUsedX86(IOBufferMemoryDescriptor, 1);
112  #endif /* !__LP64__ */
113  	OSMetaClassDeclareReservedUnused(IOBufferMemoryDescriptor, 2);
114  	OSMetaClassDeclareReservedUnused(IOBufferMemoryDescriptor, 3);
115  	OSMetaClassDeclareReservedUnused(IOBufferMemoryDescriptor, 4);
116  	OSMetaClassDeclareReservedUnused(IOBufferMemoryDescriptor, 5);
117  	OSMetaClassDeclareReservedUnused(IOBufferMemoryDescriptor, 6);
118  	OSMetaClassDeclareReservedUnused(IOBufferMemoryDescriptor, 7);
119  	OSMetaClassDeclareReservedUnused(IOBufferMemoryDescriptor, 8);
120  	OSMetaClassDeclareReservedUnused(IOBufferMemoryDescriptor, 9);
121  	OSMetaClassDeclareReservedUnused(IOBufferMemoryDescriptor, 10);
122  	OSMetaClassDeclareReservedUnused(IOBufferMemoryDescriptor, 11);
123  	OSMetaClassDeclareReservedUnused(IOBufferMemoryDescriptor, 12);
124  	OSMetaClassDeclareReservedUnused(IOBufferMemoryDescriptor, 13);
125  	OSMetaClassDeclareReservedUnused(IOBufferMemoryDescriptor, 14);
126  	OSMetaClassDeclareReservedUnused(IOBufferMemoryDescriptor, 15);
127  
128  protected:
129  	virtual void free() APPLE_KEXT_OVERRIDE;
130  
131  public:
132  
133  /*
134   * withOptions:
135   *
136   * Returns a new IOBufferMemoryDescriptor with a buffer large enough to
137   * hold capacity bytes.  The descriptor's length is initially set to the
138   * capacity.
139   */
140  #ifndef __LP64__
141  	virtual bool initWithOptions(   IOOptionBits options,
142  	    vm_size_t    capacity,
143  	    vm_offset_t  alignment) APPLE_KEXT_DEPRECATED;                         /* use withOptions() instead */
144  #endif /* !__LP64__ */
145  
146  	static OSPtr<IOBufferMemoryDescriptor> withCopy(
147  		task_t            inTask,
148  		IOOptionBits      options,
149  		vm_map_t          sourceMap,
150  		mach_vm_address_t source,
151  		mach_vm_size_t    size);
152  
153  	static OSPtr<IOBufferMemoryDescriptor> withOptions(  IOOptionBits options,
154  	    vm_size_t    capacity,
155  	    vm_offset_t  alignment = 1);
156  
157  /*! @function inTaskWithOptions
158   *   @abstract Creates a memory buffer with memory descriptor for that buffer.
159   *   @discussion Added in Mac OS X 10.2, this method allocates a memory buffer with a given size and alignment in the task's address space specified, and returns a memory descriptor instance representing the memory. It is recommended that memory allocated for I/O or sharing via mapping be created via IOBufferMemoryDescriptor. Options passed with the request specify the kind of memory to be allocated - pageablity and sharing are specified with option bits. This function may block and so should not be called from interrupt level or while a simple lock is held.
160   *   @param inTask The task the buffer will be allocated in.
161   *   @param options Options for the allocation:<br>
162   *   kIODirectionOut, kIODirectionIn - set the direction of the I/O transfer.<br>
163   *   kIOMemoryPhysicallyContiguous - pass to request memory be physically contiguous. This option is heavily discouraged. The request may fail if memory is fragmented, may cause large amounts of paging activity, and may take a very long time to execute.<br>
164   *   kIOMemoryPageable - pass to request memory be non-wired - the default for kernel allocated memory is wired.<br>
165   *   kIOMemoryPurgeable - pass to request memory that may later have its purgeable state set with IOMemoryDescriptor::setPurgeable. Only supported for kIOMemoryPageable allocations.<br>
166   *   kIOMemoryKernelUserShared - pass to request memory that will be mapped into both the kernel and client applications.<br>
167   *   kIOMapInhibitCache - allocate memory with inhibited cache setting. <br>
168   *   kIOMapWriteThruCache - allocate memory with writethru cache setting. <br>
169   *   kIOMapCopybackCache - allocate memory with copyback cache setting. <br>
170   *   kIOMapWriteCombineCache - allocate memory with writecombined cache setting.
171   *   @param capacity The number of bytes to allocate.
172   *   @param alignment The minimum required alignment of the buffer in bytes - 1 is the default for no required alignment. For example, pass 256 to get memory allocated at an address with bits 0-7 zero.
173   *   @result Returns an instance of class IOBufferMemoryDescriptor to be released by the caller, which will free the memory desriptor and associated buffer. */
174  
175  	static OSPtr<IOBufferMemoryDescriptor> inTaskWithOptions(
176  		task_t       inTask,
177  		IOOptionBits options,
178  		vm_size_t    capacity,
179  		vm_offset_t  alignment = 1);
180  
181  /*! @function inTaskWithOptions
182   *   @abstract Creates a memory buffer with memory descriptor for that buffer.
183   *   @discussion Added in Mac OS X 10.2, this method allocates a memory buffer with a given size and alignment in the task's address space specified, and returns a memory descriptor instance representing the memory. It is recommended that memory allocated for I/O or sharing via mapping be created via IOBufferMemoryDescriptor. Options passed with the request specify the kind of memory to be allocated - pageablity and sharing are specified with option bits. This function may block and so should not be called from interrupt level or while a simple lock is held.
184   *   @param inTask The task the buffer will be allocated in.
185   *   @param options Options for the allocation:<br>
186   *   kIODirectionOut, kIODirectionIn - set the direction of the I/O transfer.<br>
187   *   kIOMemoryPhysicallyContiguous - pass to request memory be physically contiguous. This option is heavily discouraged. The request may fail if memory is fragmented, may cause large amounts of paging activity, and may take a very long time to execute.<br>
188   *   kIOMemoryPageable - pass to request memory be non-wired - the default for kernel allocated memory is wired.<br>
189   *   kIOMemoryPurgeable - pass to request memory that may later have its purgeable state set with IOMemoryDescriptor::setPurgeable. Only supported for kIOMemoryPageable allocations.<br>
190   *   kIOMemoryKernelUserShared - pass to request memory that will be mapped into both the kernel and client applications.<br>
191   *   kIOMapInhibitCache - allocate memory with inhibited cache setting. <br>
192   *   kIOMapWriteThruCache - allocate memory with writethru cache setting. <br>
193   *   kIOMapCopybackCache - allocate memory with copyback cache setting. <br>
194   *   kIOMapWriteCombineCache - allocate memory with writecombined cache setting.
195   *   @param capacity The number of bytes to allocate.
196   *   @param alignment The minimum required alignment of the buffer in bytes - 1 is the default for no required alignment. For example, pass 256 to get memory allocated at an address with bits 0-7 zero.
197   *   @param kernTag The kernel memory tag
198   *   @param userTag The user memory tag
199   *   @result Returns an instance of class IOBufferMemoryDescriptor to be released by the caller, which will free the memory desriptor and associated buffer. */
200  
201  	static OSPtr<IOBufferMemoryDescriptor> inTaskWithOptions(
202  		task_t       inTask,
203  		IOOptionBits options,
204  		vm_size_t    capacity,
205  		vm_offset_t  alignment,
206  		uint32_t     kernTag,
207  		uint32_t     userTag);
208  
209  /*! @function inTaskWithPhysicalMask
210   *   @abstract Creates a memory buffer with memory descriptor for that buffer.
211   *   @discussion Added in Mac OS X 10.5, this method allocates a memory buffer with a given size and alignment in the task's address space specified, and returns a memory descriptor instance representing the memory. It is recommended that memory allocated for I/O or sharing via mapping be created via IOBufferMemoryDescriptor. Options passed with the request specify the kind of memory to be allocated - pageablity and sharing are specified with option bits. This function may block and so should not be called from interrupt level or while a simple lock is held.
212   *   @param inTask The task the buffer will be mapped in. Pass NULL to create memory unmapped in any task (eg. for use as a DMA buffer).
213   *   @param options Options for the allocation:<br>
214   *   kIODirectionOut, kIODirectionIn - set the direction of the I/O transfer.<br>
215   *   kIOMemoryPhysicallyContiguous - pass to request memory be physically contiguous. This option is heavily discouraged. The request may fail if memory is fragmented, may cause large amounts of paging activity, and may take a very long time to execute.<br>
216   *   kIOMemoryKernelUserShared - pass to request memory that will be mapped into both the kernel and client applications.<br>
217   *   kIOMapInhibitCache - allocate memory with inhibited cache setting. <br>
218   *   kIOMapWriteThruCache - allocate memory with writethru cache setting. <br>
219   *   kIOMapCopybackCache - allocate memory with copyback cache setting. <br>
220   *   kIOMapWriteCombineCache - allocate memory with writecombined cache setting.
221   *   @param capacity The number of bytes to allocate.
222   *   @param physicalMask The buffer will be allocated with pages such that physical addresses will only have bits set present in physicalMask. For example, pass 0x00000000FFFFFFFFULL for a buffer to be accessed by hardware that has 32 address bits.
223   *   @result Returns an instance of class IOBufferMemoryDescriptor to be released by the caller, which will free the memory desriptor and associated buffer. */
224  
225  	static OSPtr<IOBufferMemoryDescriptor> inTaskWithPhysicalMask(
226  		task_t            inTask,
227  		IOOptionBits      options,
228  		mach_vm_size_t    capacity,
229  		mach_vm_address_t physicalMask);
230  
231  /*
232   * withCapacity:
233   *
234   * Returns a new IOBufferMemoryDescriptor with a buffer large enough to
235   * hold capacity bytes.  The descriptor's length is initially set to the
236   * capacity.
237   */
238  	static OSPtr<IOBufferMemoryDescriptor> withCapacity(
239  		vm_size_t    capacity,
240  		IODirection  withDirection,
241  		bool         withContiguousMemory = false);
242  #ifndef __LP64__
243  	virtual bool initWithBytes(const void * bytes,
244  	    vm_size_t    withLength,
245  	    IODirection  withDirection,
246  	    bool         withContiguousMemory = false) APPLE_KEXT_DEPRECATED;                    /* use withBytes() instead */
247  #endif /* !__LP64__ */
248  
249  /*
250   * withBytes:
251   *
252   * Returns a new IOBufferMemoryDescriptor preloaded with bytes (copied).
253   * The descriptor's length and capacity are set to the input buffer's size.
254   */
255  	static OSPtr<IOBufferMemoryDescriptor> withBytes(
256  		const void * bytes,
257  		vm_size_t    withLength,
258  		IODirection  withDirection,
259  		bool         withContiguousMemory = false);
260  
261  /*
262   * setLength:
263   *
264   * Change the buffer length of the memory descriptor.  When a new buffer
265   * is created, the initial length of the buffer is set to be the same as
266   * the capacity.  The length can be adjusted via setLength for a shorter
267   * transfer (there is no need to create more buffer descriptors when you
268   * can reuse an existing one, even for different transfer sizes).   Note
269   * that the specified length must not exceed the capacity of the buffer.
270   */
271  	virtual void setLength(vm_size_t length);
272  
273  /*
274   * setDirection:
275   *
276   * Change the direction of the transfer.  This method allows one to redirect
277   * the descriptor's transfer direction.  This eliminates the need to destroy
278   * and create new buffers when different transfer directions are needed.
279   */
280  	virtual void setDirection(IODirection direction);
281  
282  /*
283   * getCapacity:
284   *
285   * Get the buffer capacity
286   */
287  	virtual vm_size_t getCapacity() const;
288  
289  /*
290   * getBytesNoCopy:
291   *
292   * Return the virtual address of the beginning of the buffer
293   */
294  	virtual void *getBytesNoCopy();
295  
296  /*
297   * getBytesNoCopy:
298   *
299   * Return the virtual address of an offset from the beginning of the buffer
300   */
301  	virtual void *getBytesNoCopy(vm_size_t start, vm_size_t withLength);
302  
303  /*
304   * appendBytes:
305   *
306   * Add some data to the end of the buffer.  This method automatically
307   * maintains the memory descriptor buffer length.  Note that appendBytes
308   * will not copy past the end of the memory descriptor's current capacity.
309   */
310  	virtual bool appendBytes(const void *bytes, vm_size_t withLength);
311  
312  #ifndef __LP64__
313  	virtual void * getVirtualSegment(IOByteCount offset,
314  	    IOByteCount * length) APPLE_KEXT_OVERRIDE APPLE_KEXT_DEPRECATED;                             /* use getBytesNoCopy() instead */
315  #endif /* !__LP64__ */
316  };
317  
318  #endif /* !_IOBUFFERMEMORYDESCRIPTOR_H */