]> git.saurik.com Git - apple/xnu.git/blame - iokit/Kernel/IOMemoryCursor.cpp
xnu-6153.81.5.tar.gz
[apple/xnu.git] / iokit / Kernel / IOMemoryCursor.cpp
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
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/* IOMemoryCursor.cpp created by wgulland on 1999-3-02 */
29
30#include <IOKit/assert.h>
31#include <IOKit/IOLib.h>
32#include <IOKit/IOMemoryCursor.h>
33#include <IOKit/IOMemoryDescriptor.h>
34#include <libkern/OSByteOrder.h>
35
36/**************************** class IOMemoryCursor ***************************/
37
38#undef super
39#define super OSObject
40OSDefineMetaClassAndStructors(IOMemoryCursor, OSObject)
41
42IOMemoryCursor *
43IOMemoryCursor::withSpecification(SegmentFunction inSegFunc,
0a7de745
A
44 IOPhysicalLength inMaxSegmentSize,
45 IOPhysicalLength inMaxTransferSize,
46 IOPhysicalLength inAlignment)
1c79356b 47{
0a7de745
A
48 IOMemoryCursor * me = new IOMemoryCursor;
49
50 if (me && !me->initWithSpecification(inSegFunc,
51 inMaxSegmentSize,
52 inMaxTransferSize,
53 inAlignment)) {
54 me->release();
cb323159 55 return NULL;
0a7de745
A
56 }
57
58 return me;
1c79356b
A
59}
60
61/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
62
63bool
64IOMemoryCursor::initWithSpecification(SegmentFunction inSegFunc,
0a7de745
A
65 IOPhysicalLength inMaxSegmentSize,
66 IOPhysicalLength inMaxTransferSize,
67 IOPhysicalLength inAlignment)
1c79356b 68{
55e303ae
A
69// @@@ gvdl: Remove me
70#if 1
0a7de745
A
71 static UInt sMaxDBDMASegment;
72 if (!sMaxDBDMASegment) {
73 sMaxDBDMASegment = (UInt) - 1;
74 if (PE_parse_boot_argn("mseg", &sMaxDBDMASegment, sizeof(sMaxDBDMASegment))) {
75 IOLog("Setting MaxDBDMASegment to %d\n", sMaxDBDMASegment);
76 }
77 }
78
79 if (inMaxSegmentSize > sMaxDBDMASegment) {
80 inMaxSegmentSize = sMaxDBDMASegment;
81 }
55e303ae
A
82#endif
83
0a7de745
A
84 if (!super::init()) {
85 return false;
86 }
87
88 if (!inSegFunc) {
89 return false;
90 }
91
92 outSeg = inSegFunc;
93 maxSegmentSize = inMaxSegmentSize;
94 if (inMaxTransferSize) {
95 maxTransferSize = inMaxTransferSize;
96 } else {
97 maxTransferSize = (IOPhysicalLength) - 1;
98 }
99 alignMask = inAlignment - 1;
100 assert(alignMask == 0); // No alignment code yet!
101
102 return true;
1c79356b
A
103}
104
105/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
106
0a7de745 107UInt32
1c79356b 108IOMemoryCursor::genPhysicalSegments(IOMemoryDescriptor *inDescriptor,
0a7de745
A
109 IOByteCount fromPosition,
110 void * inSegments,
111 UInt32 inMaxSegments,
112 UInt32 inMaxTransferSize,
113 IOByteCount *outTransferSize)
1c79356b 114{
0a7de745
A
115 if (!inDescriptor) {
116 return 0;
117 }
118
119 if (!inMaxSegments) {
120 return 0;
121 }
122
123 if (!inMaxTransferSize) {
124 inMaxTransferSize = maxTransferSize;
125 }
126
127 /*
128 * Iterate over the packet, translating segments where allowed
129 *
130 * If we finished cleanly return number of segments found
131 * and update the position in the descriptor.
132 */
133 PhysicalSegment curSeg = { 0, 0 };
134 UInt curSegIndex = 0;
135 UInt curTransferSize = 0;
136 IOByteCount inDescriptorLength = inDescriptor->getLength();
137 PhysicalSegment seg = { 0, 0 };
138
139 while ((seg.location) || (fromPosition < inDescriptorLength)) {
140 if (!seg.location) {
141 seg.location = inDescriptor->getPhysicalSegment(
142 fromPosition, (IOByteCount*)&seg.length);
143 assert(seg.location);
144 assert(seg.length);
145 fromPosition += seg.length;
146 }
147
148 if (!curSeg.location) {
149 curTransferSize += seg.length;
150 curSeg = seg;
151 seg.location = 0;
152 } else if ((curSeg.location + curSeg.length == seg.location)) {
153 curTransferSize += seg.length;
154 curSeg.length += seg.length;
155 seg.location = 0;
156 }
157
158 if (!seg.location) {
159 if ((curSeg.length > maxSegmentSize)) {
160 seg.location = curSeg.location + maxSegmentSize;
161 seg.length = curSeg.length - maxSegmentSize;
162 curTransferSize -= seg.length;
163 curSeg.length -= seg.length;
164 }
165
166 if ((curTransferSize >= inMaxTransferSize)) {
167 curSeg.length -= curTransferSize - inMaxTransferSize;
168 curTransferSize = inMaxTransferSize;
169 break;
170 }
171 }
172
173 if (seg.location) {
174 if ((curSegIndex + 1 == inMaxSegments)) {
175 break;
176 }
177 (*outSeg)(curSeg, inSegments, curSegIndex++);
178 curSeg.location = 0;
179 }
180 }
181
182 if (curSeg.location) {
183 (*outSeg)(curSeg, inSegments, curSegIndex++);
184 }
185
186 if (outTransferSize) {
187 *outTransferSize = curTransferSize;
188 }
189
190 return curSegIndex;
1c79356b
A
191}
192
193/************************ class IONaturalMemoryCursor ************************/
194
195#undef super
196#define super IOMemoryCursor
197OSDefineMetaClassAndStructors(IONaturalMemoryCursor, IOMemoryCursor)
198
0a7de745
A
199void
200IONaturalMemoryCursor::outputSegment(PhysicalSegment segment,
201 void * outSegments,
202 UInt32 outSegmentIndex)
1c79356b 203{
0a7de745 204 ((PhysicalSegment *) outSegments)[outSegmentIndex] = segment;
1c79356b
A
205}
206
0a7de745 207IONaturalMemoryCursor *
1c79356b 208IONaturalMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize,
0a7de745
A
209 IOPhysicalLength inMaxTransferSize,
210 IOPhysicalLength inAlignment)
1c79356b 211{
0a7de745 212 IONaturalMemoryCursor *me = new IONaturalMemoryCursor;
1c79356b 213
0a7de745
A
214 if (me && !me->initWithSpecification(inMaxSegmentSize,
215 inMaxTransferSize,
216 inAlignment)) {
217 me->release();
cb323159 218 return NULL;
0a7de745 219 }
1c79356b 220
0a7de745 221 return me;
1c79356b
A
222}
223
0a7de745 224bool
1c79356b 225IONaturalMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize,
0a7de745
A
226 IOPhysicalLength inMaxTransferSize,
227 IOPhysicalLength inAlignment)
1c79356b 228{
0a7de745
A
229 return super::initWithSpecification(&IONaturalMemoryCursor::outputSegment,
230 inMaxSegmentSize,
231 inMaxTransferSize,
232 inAlignment);
1c79356b
A
233}
234
235/************************** class IOBigMemoryCursor **************************/
236
237#undef super
238#define super IOMemoryCursor
239OSDefineMetaClassAndStructors(IOBigMemoryCursor, IOMemoryCursor)
240
0a7de745 241void
1c79356b 242IOBigMemoryCursor::outputSegment(PhysicalSegment inSegment,
0a7de745
A
243 void * inSegments,
244 UInt32 inSegmentIndex)
1c79356b 245{
0a7de745 246 IOPhysicalAddress * segment;
1c79356b 247
0a7de745 248 segment = &((PhysicalSegment *) inSegments)[inSegmentIndex].location;
d9a64523 249#if IOPhysSize == 64
0a7de745
A
250 OSWriteBigInt64(segment, 0, inSegment.location);
251 OSWriteBigInt64(segment, sizeof(IOPhysicalAddress), inSegment.length);
d9a64523 252#else
0a7de745
A
253 OSWriteBigInt(segment, 0, inSegment.location);
254 OSWriteBigInt(segment, sizeof(IOPhysicalAddress), inSegment.length);
d9a64523 255#endif
1c79356b
A
256}
257
258IOBigMemoryCursor *
259IOBigMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize,
0a7de745
A
260 IOPhysicalLength inMaxTransferSize,
261 IOPhysicalLength inAlignment)
1c79356b 262{
0a7de745 263 IOBigMemoryCursor * me = new IOBigMemoryCursor;
1c79356b 264
0a7de745
A
265 if (me && !me->initWithSpecification(inMaxSegmentSize,
266 inMaxTransferSize,
267 inAlignment)) {
268 me->release();
cb323159 269 return NULL;
0a7de745 270 }
1c79356b 271
0a7de745 272 return me;
1c79356b
A
273}
274
0a7de745 275bool
1c79356b 276IOBigMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize,
0a7de745
A
277 IOPhysicalLength inMaxTransferSize,
278 IOPhysicalLength inAlignment)
1c79356b 279{
0a7de745
A
280 return super::initWithSpecification(&IOBigMemoryCursor::outputSegment,
281 inMaxSegmentSize,
282 inMaxTransferSize,
283 inAlignment);
1c79356b
A
284}
285
286/************************* class IOLittleMemoryCursor ************************/
287
288#undef super
289#define super IOMemoryCursor
290OSDefineMetaClassAndStructors(IOLittleMemoryCursor, IOMemoryCursor)
291
0a7de745 292void
1c79356b 293IOLittleMemoryCursor::outputSegment(PhysicalSegment inSegment,
0a7de745
A
294 void * inSegments,
295 UInt32 inSegmentIndex)
1c79356b 296{
0a7de745 297 IOPhysicalAddress * segment;
1c79356b 298
0a7de745 299 segment = &((PhysicalSegment *) inSegments)[inSegmentIndex].location;
d9a64523 300#if IOPhysSize == 64
0a7de745
A
301 OSWriteLittleInt64(segment, 0, inSegment.location);
302 OSWriteLittleInt64(segment, sizeof(IOPhysicalAddress), inSegment.length);
d9a64523 303#else
0a7de745
A
304 OSWriteLittleInt(segment, 0, inSegment.location);
305 OSWriteLittleInt(segment, sizeof(IOPhysicalAddress), inSegment.length);
d9a64523 306#endif
1c79356b
A
307}
308
309IOLittleMemoryCursor *
310IOLittleMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize,
0a7de745
A
311 IOPhysicalLength inMaxTransferSize,
312 IOPhysicalLength inAlignment)
1c79356b 313{
0a7de745 314 IOLittleMemoryCursor * me = new IOLittleMemoryCursor;
1c79356b 315
0a7de745
A
316 if (me && !me->initWithSpecification(inMaxSegmentSize,
317 inMaxTransferSize,
318 inAlignment)) {
319 me->release();
cb323159 320 return NULL;
0a7de745 321 }
1c79356b 322
0a7de745 323 return me;
1c79356b
A
324}
325
326/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
327
0a7de745 328bool
1c79356b 329IOLittleMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize,
0a7de745
A
330 IOPhysicalLength inMaxTransferSize,
331 IOPhysicalLength inAlignment)
1c79356b 332{
0a7de745
A
333 return super::initWithSpecification(&IOLittleMemoryCursor::outputSegment,
334 inMaxSegmentSize,
335 inMaxTransferSize,
336 inAlignment);
1c79356b 337}