]> git.saurik.com Git - apple/xnu.git/blame - iokit/IOKit/IOMemoryCursor.h
xnu-6153.41.3.tar.gz
[apple/xnu.git] / iokit / IOKit / IOMemoryCursor.h
CommitLineData
1c79356b 1/*
cb323159 2 * Copyright (c) 1998-2019 Apple Inc. All rights reserved.
1c79356b 3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
0a7de745 5 *
2d21ac55
A
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.
0a7de745 14 *
2d21ac55
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
0a7de745 17 *
2d21ac55
A
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
8f6c56a5
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
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.
0a7de745 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b
A
27 */
28#ifndef _IOMEMORYCURSOR_H
29#define _IOMEMORYCURSOR_H
30
31#include <libkern/c++/OSObject.h>
32#include <IOKit/IOTypes.h>
33
34class IOMemoryDescriptor;
35
36/**************************** class IOMemoryCursor ***************************/
37
38/*!
0a7de745
A
39 * @class IOMemoryCursor
40 * @abstract A mechanism to convert memory references to physical addresses.
41 * @discussion The IOMemoryCursor declares the super class that all
42 * specific memory cursors must inherit from, but a memory cursor can be created without a specific format subclass by just providing a segment function to the initializers. This class does the difficult stuff of dividing a memory descriptor into a physical scatter/gather list appropriate for the target hardware.
43 * <br><br>
44 * A driver is expected to create a memory cursor and configure it to the limitations of its DMA hardware; for instance the memory cursor used by the FireWire SBP-2 protocol has a maximum physical segment size of 2^16 - 1 but the actual transfer size is unlimited. Thus it would create a cursor with a maxSegmentSize of 65535 and a maxTransfer size of UINT_MAX. It would also provide a SegmentFunction that can output a pagelist entry.
45 * <br><br>
46 * Below is the simplest example of a SegmentFunction:<br>
47 * void IONaturalMemoryCursor::outputSegment(PhysicalSegment segment,<br>
48 * void * outSegments,<br>
49 * UInt32 outSegmentIndex)<br>
50 * {<br>
51 * ((PhysicalSegment *) outSegments)[outSegmentIndex] = segment;<br>
52 * }
53 *
54 */
1c79356b
A
55class IOMemoryCursor : public OSObject
56{
cb323159 57 OSDeclareDefaultStructors(IOMemoryCursor);
1c79356b
A
58
59public:
60/*!
0a7de745
A
61 * @typedef PhysicalSegment
62 * @discussion A physical address/length pair.
63 */
64 struct PhysicalSegment {
65 IOPhysicalAddress location;
66 IOPhysicalLength length;
67 };
1c79356b
A
68
69/*! @defined IOPhysicalSegment
0a7de745
A
70 * @discussion Backward compatibility define for the old non-class scoped type definition. See IOMemoryCursor::PhysicalSegment
71 */
1c79356b
A
72#define IOPhysicalSegment IOMemoryCursor::PhysicalSegment
73
74/*!
0a7de745
A
75 * @typedef SegmentFunction
76 * @discussion Pointer to a C function that outputs a single physical segment to an element in the array as defined by the segments and segmentIndex parameters.
77 * @param segment The physical address and length that is next to be output.
78 * @param segments Base of the output vector of DMA address length pairs.
79 * @param segmentIndex Index to output 'segment' in the 'segments' array.
80 */
81 typedef void (*SegmentFunction)(PhysicalSegment segment,
82 void * segments,
83 UInt32 segmentIndex);
1c79356b
A
84
85/*! @defined OutputSegmentFunc
0a7de745 86 * @discussion Backward compatibility define for the old non-class scoped type definition. See IOMemoryCursor::SegmentFunction */
1c79356b
A
87#define OutputSegmentFunc IOMemoryCursor::SegmentFunction
88
89protected:
90/*! @var outSeg The action method called when an event has been delivered */
0a7de745 91 SegmentFunction outSeg;
1c79356b
A
92
93/*! @var maxSegmentSize Maximum size of one segment in a scatter/gather list */
0a7de745 94 IOPhysicalLength maxSegmentSize;
1c79356b
A
95
96/*! @var maxTransferSize
0a7de745
A
97 * Maximum size of a transfer that this memory cursor is allowed to generate */
98 IOPhysicalLength maxTransferSize;
1c79356b
A
99
100/*! @var alignMask
0a7de745
A
101 * Currently unused. Reserved for automated aligment restriction code. */
102 IOPhysicalLength alignMask;
1c79356b
A
103
104public:
105/*! @function withSpecification
0a7de745
A
106 * @abstract Creates and initializes an IOMemoryCursor in one operation.
107 * @discussion Factory function to create and initialize an IOMemoryCursor in one operation. For more information, see IOMemoryCursor::initWithSpecification.
108 * @param outSegFunc SegmentFunction to call to output one physical segment.
109 * @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0.
110 * @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum.
111 * @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment.
112 * @result Returns a new memory cursor if successfully created and initialized, 0 otherwise.
113 */
114 static IOMemoryCursor *
1c79356b 115 withSpecification(SegmentFunction outSegFunc,
0a7de745
A
116 IOPhysicalLength maxSegmentSize = 0,
117 IOPhysicalLength maxTransferSize = 0,
118 IOPhysicalLength alignment = 1);
1c79356b
A
119
120/*! @function initWithSpecification
0a7de745
A
121 * @abstract Primary initializer for the IOMemoryCursor class.
122 * @param outSegFunc SegmentFunction to call to output one physical segment.
123 * @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0.
124 * @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum.
125 * @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment.
126 * @result Returns true if the inherited classes and this instance initialize
127 * successfully.
128 */
129 virtual bool initWithSpecification(SegmentFunction outSegFunc,
130 IOPhysicalLength maxSegmentSize = 0,
131 IOPhysicalLength maxTransferSize = 0,
132 IOPhysicalLength alignment = 1);
1c79356b
A
133
134/*! @function genPhysicalSegments
0a7de745
A
135 * @abstract Generates a physical scatter/gather list given a memory descriptor.
136 * @discussion Generates a list of physical segments from the given memory descriptor, relative to the current position of the descriptor.
137 * @param descriptor IOMemoryDescriptor that describes the data associated with an I/O request.
138 * @param fromPosition Starting location of the I/O within a memory descriptor.
139 * @param segments Void pointer to base of output physical scatter/gather list. Always passed directly onto the SegmentFunction without interpretation by the cursor.
140 * @param maxSegments Maximum number of segments that can be written to segments array.
141 * @param maxTransferSize Maximum transfer size is limited to that many bytes, otherwise it defaults to the maximum transfer size specified when the memory cursor was initialized.
142 * @param transferSize Pointer to an IOByteCount variable that can contain the total size of the transfer being described. Defaults to 0 indicating that no transfer size need be returned.
143 * @result If the descriptor is exhausted of memory, a zero is returned, otherwise the number of segments that were filled in is returned.
144 */
145 virtual UInt32 genPhysicalSegments(
146 IOMemoryDescriptor *descriptor,
147 IOByteCount fromPosition,
148 void * segments,
149 UInt32 maxSegments,
150 UInt32 maxTransferSize = 0,
cb323159 151 IOByteCount *transferSize = NULL);
1c79356b
A
152};
153
154/************************ class IONaturalMemoryCursor ************************/
155
156
157/*!
0a7de745
A
158 * @class IONaturalMemoryCursor
159 * @abstract An IOMemoryCursor subclass that outputs a vector of PhysicalSegments in the natural byte orientation for the CPU.
160 * @discussion The IONaturalMemoryCursor would be used when it is too difficult to safely describe a SegmentFunction that is more appropriate for your hardware. This cursor just outputs an array of PhysicalSegments.
161 */
1c79356b
A
162class IONaturalMemoryCursor : public IOMemoryCursor
163{
cb323159 164 OSDeclareDefaultStructors(IONaturalMemoryCursor);
1c79356b
A
165
166public:
91447636 167/*! @function outputSegment
0a7de745
A
168 * @abstract Outputs the given segment into the output segments array in natural byte order.
169 * @param segment The physical address and length that is next to be output.
170 * @param segments Base of the output vector of DMA address length pairs.
171 * @param segmentIndex Index to output 'segment' in the 'segments' array.
172 */
173 static void outputSegment(PhysicalSegment segment,
174 void * segments,
175 UInt32 segmentIndex);
1c79356b
A
176
177/*! @defined naturalOutputSegment
0a7de745
A
178 * @discussion Backward compatibility define for the old global function definition. See IONaturalMemoryCursor::outputSegment.
179 */
1c79356b
A
180#define naturalOutputSegment IONaturalMemoryCursor::outputSegment
181
182/*! @function withSpecification
0a7de745
A
183 * @abstract Creates and initializes an IONaturalMemoryCursor in one operation.
184 * @discussion Factory function to create and initialize an IONaturalMemoryCursor in one operation. For more information, see IONaturalMemoryCursor::initWithSpecification.
185 * @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0.
186 * @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum.
187 * @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment.
188 * @result Returns a new memory cursor if successfully created and initialized, 0 otherwise.
189 */
190 static IONaturalMemoryCursor *
1c79356b 191 withSpecification(IOPhysicalLength maxSegmentSize,
0a7de745
A
192 IOPhysicalLength maxTransferSize,
193 IOPhysicalLength alignment = 1);
1c79356b
A
194
195/*! @function initWithSpecification
0a7de745
A
196 * @abstract Primary initializer for the IONaturalMemoryCursor class.
197 * @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0.
198 * @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum.
199 * @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment.
200 * @result Returns true if the inherited classes and this instance initialize successfully.
201 */
202 virtual bool initWithSpecification(IOPhysicalLength maxSegmentSize,
203 IOPhysicalLength maxTransferSize,
204 IOPhysicalLength alignment = 1);
1c79356b
A
205
206
207/*! @function getPhysicalSegments
0a7de745
A
208 * @abstract Generates a CPU natural physical scatter/gather list given a memory descriptor.
209 * @discussion Generates a list of physical segments from the given memory descriptor, relative to the current position of the descriptor. Wraps IOMemoryCursor::genPhysicalSegments.
210 * @param descriptor IOMemoryDescriptor that describes the data associated with an I/O request.
211 * @param fromPosition Starting location of the I/O within a memory descriptor.
212 * @param segments Pointer to an array of IOMemoryCursor::PhysicalSegments for the output physical scatter/gather list.
213 * @param maxSegments Maximum number of segments that can be written to segments array.
214 * @param inMaxTransferSize Maximum transfer size is limited to that many bytes, otherwise it defaults to the maximum transfer size specified when the memory cursor was initialized.
215 * @param transferSize Pointer to an IOByteCount variable that can contain the total size of the transfer being described. Defaults to 0 indicating that no transfer size need be returned.
216 * @result If the descriptor is exhausted of memory, a zero is returned, otherwise the number of segments that were filled in is returned.
217 */
218 virtual UInt32
219 getPhysicalSegments(IOMemoryDescriptor *descriptor,
220 IOByteCount fromPosition,
221 PhysicalSegment *segments,
222 UInt32 maxSegments,
223 UInt32 inMaxTransferSize = 0,
cb323159 224 IOByteCount *transferSize = NULL)
0a7de745
A
225 {
226 return genPhysicalSegments(descriptor, fromPosition, segments,
227 maxSegments, inMaxTransferSize, transferSize);
228 }
1c79356b
A
229};
230
231/************************** class IOBigMemoryCursor **************************/
232
233/*!
0a7de745
A
234 * @class IOBigMemoryCursor
235 * @abstract An IOMemoryCursor subclass that outputs a vector of PhysicalSegments in the big endian byte order.
236 * @discussion The IOBigMemoryCursor would be used when the DMA hardware requires a big endian address and length pair. This cursor outputs an array of PhysicalSegments that are encoded in big-endian format.
237 */
1c79356b
A
238class IOBigMemoryCursor : public IOMemoryCursor
239{
cb323159 240 OSDeclareDefaultStructors(IOBigMemoryCursor);
1c79356b
A
241
242public:
91447636 243/*! @function outputSegment
0a7de745
A
244 * @abstract Outputs the given segment into the output segments array in big endian byte order.
245 * @param segment The physical address and length that is next to be output.
246 * @param segments Base of the output vector of DMA address length pairs.
247 * @param segmentIndex Index to output 'segment' in the 'segments' array.
248 */
249 static void outputSegment(PhysicalSegment segment,
250 void * segments,
251 UInt32 segmentIndex);
1c79356b
A
252
253/*! @defined bigOutputSegment
0a7de745
A
254 * @discussion Backward compatibility define for the old global function definition. See IOBigMemoryCursor::outputSegment
255 */
1c79356b
A
256#define bigOutputSegment IOBigMemoryCursor::outputSegment
257
258/*! @function withSpecification
0a7de745
A
259 * @abstract Creates and initializes an IOBigMemoryCursor in one operation.
260 * @discussion Factory function to create and initialize an IOBigMemoryCursor in one operation. See also IOBigMemoryCursor::initWithSpecification.
261 * @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0.
262 * @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum.
263 * @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment.
264 * @result Returns a new memory cursor if successfully created and initialized, 0 otherwise.
265 */
266 static IOBigMemoryCursor *
1c79356b 267 withSpecification(IOPhysicalLength maxSegmentSize,
0a7de745
A
268 IOPhysicalLength maxTransferSize,
269 IOPhysicalLength alignment = 1);
1c79356b
A
270
271/*! @function initWithSpecification
0a7de745
A
272 * @abstract Primary initializer for the IOBigMemoryCursor class.
273 * @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0.
274 * @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum.
275 * @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment.
276 * @result Returns true if the inherited classes and this instance initialize
277 * successfully.
278 */
279 virtual bool initWithSpecification(IOPhysicalLength maxSegmentSize,
280 IOPhysicalLength maxTransferSize,
281 IOPhysicalLength alignment = 1);
1c79356b
A
282
283
284/*! @function getPhysicalSegments
0a7de745
A
285 * @abstract Generates a big endian physical scatter/gather list given a memory descriptor.
286 * @discussion Generates a list of physical segments from the given memory descriptor, relative to the current position of the descriptor. Wraps IOMemoryCursor::genPhysicalSegments.
287 * @param descriptor IOMemoryDescriptor that describes the data associated with an I/O request.
288 * @param fromPosition Starting location of the I/O within a memory descriptor.
289 * @param segments Pointer to an array of IOMemoryCursor::PhysicalSegments for the output physical scatter/gather list.
290 * @param maxSegments Maximum number of segments that can be written to segments array.
291 * @param inMaxTransferSize Maximum transfer size is limited to that many bytes, otherwise it defaults to the maximum transfer size specified when the memory cursor was initialized.
292 * @param transferSize Pointer to an IOByteCount variable that can contain the total size of the transfer being described. Defaults to 0 indicating that no transfer size need be returned.
293 * @result If the descriptor is exhausted of memory, a zero is returned, otherwise the number of segments that were filled in is returned.
294 */
295 virtual UInt32
296 getPhysicalSegments(IOMemoryDescriptor * descriptor,
297 IOByteCount fromPosition,
298 PhysicalSegment * segments,
299 UInt32 maxSegments,
300 UInt32 inMaxTransferSize = 0,
cb323159 301 IOByteCount * transferSize = NULL)
0a7de745
A
302 {
303 return genPhysicalSegments(descriptor, fromPosition, segments,
304 maxSegments, inMaxTransferSize, transferSize);
305 }
1c79356b
A
306};
307
308/************************* class IOLittleMemoryCursor ************************/
309
310/*!
0a7de745
A
311 * @class IOLittleMemoryCursor
312 * @abstract An IOMemoryCursor subclass that outputs a vector of PhysicalSegments in the little endian byte order.
313 * @discussion The IOLittleMemoryCursor would be used when the DMA hardware requires a little endian address and length pair. This cursor outputs an array of PhysicalSegments that are encoded in little endian format.
314 */
1c79356b
A
315class IOLittleMemoryCursor : public IOMemoryCursor
316{
cb323159 317 OSDeclareDefaultStructors(IOLittleMemoryCursor);
1c79356b
A
318
319public:
91447636 320/*! @function outputSegment
0a7de745
A
321 * @abstract Outputs the given segment into the output segments array in little endian byte order.
322 * @param segment The physical address and length that is next to be output.
323 * @param segments Base of the output vector of DMA address length pairs.
324 * @param segmentIndex Index to output 'segment' in the 'segments' array.
325 */
326 static void outputSegment(PhysicalSegment segment,
327 void * segments,
328 UInt32 segmentIndex);
1c79356b
A
329
330/*! @defined littleOutputSegment
0a7de745 331 * @discussion Backward compatibility define for the old global function definition. See also IOLittleMemoryCursor::outputSegment. */
1c79356b
A
332#define littleOutputSegment IOLittleMemoryCursor::outputSegment
333
334/*! @function withSpecification
0a7de745
A
335 * @abstract Creates and initializes an IOLittleMemoryCursor in one operation.
336 * @discussion Factory function to create and initialize an IOLittleMemoryCursor in one operation. See also IOLittleMemoryCursor::initWithSpecification.
337 * @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0.
338 * @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum.
339 * @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment.
340 * @result Returns a new memory cursor if successfully created and initialized, 0 otherwise.
341 */
342 static IOLittleMemoryCursor *
1c79356b 343 withSpecification(IOPhysicalLength maxSegmentSize,
0a7de745
A
344 IOPhysicalLength maxTransferSize,
345 IOPhysicalLength alignment = 1);
1c79356b
A
346
347/*! @function initWithSpecification
0a7de745
A
348 * @abstract Primary initializer for the IOLittleMemoryCursor class.
349 * @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0.
350 * @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum.
351 * @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment.
352 * @result Returns true if the inherited classes and this instance initialize successfully.
353 */
354 virtual bool initWithSpecification(IOPhysicalLength maxSegmentSize,
355 IOPhysicalLength maxTransferSize,
356 IOPhysicalLength alignment = 1);
1c79356b
A
357
358
359/*! @function getPhysicalSegments
0a7de745
A
360 * @abstract Generates a little endian physical scatter/gather list given a memory descriptor.
361 * @discussion Generates a list of physical segments from the given memory descriptor, relative to the current position of the descriptor. Wraps IOMemoryCursor::genPhysicalSegments.
362 * @param descriptor IOMemoryDescriptor that describes the data associated with an I/O request.
363 * @param fromPosition Starting location of the I/O within a memory descriptor.
364 * @param segments Pointer to an array of IOMemoryCursor::PhysicalSegments for the output physical scatter/gather list.
365 * @param maxSegments Maximum number of segments that can be written to segments array.
366 * @param inMaxTransferSize Maximum transfer size is limited to that many bytes, otherwise it defaults to the maximum transfer size specified when the memory cursor was initialized.
367 * @param transferSize Pointer to an IOByteCount variable that can contain the total size of the transfer being described. Defaults to 0 indicating that no transfer size need be returned.
368 * @result If the descriptor is exhausted of memory, a zero is returned, otherwise the number of segments that were filled in is returned.
369 */
370 virtual UInt32
371 getPhysicalSegments(IOMemoryDescriptor * descriptor,
372 IOByteCount fromPosition,
373 PhysicalSegment * segments,
374 UInt32 maxSegments,
375 UInt32 inMaxTransferSize = 0,
cb323159 376 IOByteCount * transferSize = NULL)
0a7de745
A
377 {
378 return genPhysicalSegments(descriptor, fromPosition, segments,
379 maxSegments, inMaxTransferSize, transferSize);
380 }
1c79356b
A
381};
382
1c79356b 383#endif /* !_IOMEMORYCURSOR_H */