]> git.saurik.com Git - apple/xnu.git/blob - iokit/Kernel/IOSubMemoryDescriptor.cpp
xnu-7195.60.75.tar.gz
[apple/xnu.git] / iokit / Kernel / IOSubMemoryDescriptor.cpp
1 /*
2 * Copyright (c) 1998-2007 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
29 #include <IOKit/IOSubMemoryDescriptor.h>
30 #include <IOKit/IOLib.h>
31
32 #include "IOKitKernelInternal.h"
33
34 #define super IOMemoryDescriptor
35
36 OSDefineMetaClassAndStructors(IOSubMemoryDescriptor, IOMemoryDescriptor)
37
38 IOReturn
39 IOSubMemoryDescriptor::redirect( task_t safeTask, bool doRedirect )
40 {
41 #ifdef __LP64__
42 super::redirect( safeTask, doRedirect );
43 #endif /* __LP64__ */
44 return _parent->redirect( safeTask, doRedirect );
45 }
46
47 IOSubMemoryDescriptor *
48 IOSubMemoryDescriptor::withSubRange(IOMemoryDescriptor * of,
49 IOByteCount offset,
50 IOByteCount length,
51 IOOptionBits options)
52 {
53 IOSubMemoryDescriptor *self = new IOSubMemoryDescriptor;
54
55 if (self && !self->initSubRange(of, offset, length, (IODirection) options)) {
56 self->release();
57 self = NULL;
58 }
59 return self;
60 }
61
62 bool
63 IOSubMemoryDescriptor::initSubRange( IOMemoryDescriptor * parent,
64 IOByteCount offset, IOByteCount length,
65 IODirection direction )
66 {
67 if (parent && ((offset + length) > parent->getLength())) {
68 return false;
69 }
70
71 /*
72 * We can check the _parent instance variable before having ever set it
73 * to an initial value because I/O Kit guarantees that all our instance
74 * variables are zeroed on an object's allocation.
75 */
76
77 if (!_parent) {
78 if (!super::init()) {
79 return false;
80 }
81 } else {
82 /*
83 * An existing memory descriptor is being retargeted to
84 * point to somewhere else. Clean up our present state.
85 */
86
87 _parent->release();
88 }
89
90 if (parent) {
91 parent->retain();
92 _tag = parent->getTag();
93 } else {
94 _tag = 0;
95 }
96 _parent = parent;
97 _start = offset;
98 _length = length;
99 _flags = direction;
100 _flags |= kIOMemoryThreadSafe;
101
102 #ifndef __LP64__
103 _direction = (IODirection) (_flags & kIOMemoryDirectionMask);
104 #endif /* !__LP64__ */
105
106 return true;
107 }
108
109 void
110 IOSubMemoryDescriptor::free( void )
111 {
112 if (_parent) {
113 _parent->release();
114 }
115
116 super::free();
117 }
118
119 addr64_t
120 IOSubMemoryDescriptor::getPhysicalSegment(IOByteCount offset, IOByteCount * length, IOOptionBits options)
121 {
122 addr64_t address;
123 IOByteCount actualLength;
124
125 assert(offset <= _length);
126
127 if (length) {
128 *length = 0;
129 }
130
131 if (offset >= _length) {
132 return 0;
133 }
134
135 address = _parent->getPhysicalSegment( offset + _start, &actualLength, options );
136
137 if (address && length) {
138 *length = min( _length - offset, actualLength );
139 }
140
141 return address;
142 }
143
144 IOReturn
145 IOSubMemoryDescriptor::setPurgeable( IOOptionBits newState,
146 IOOptionBits * oldState )
147 {
148 IOReturn err;
149
150 err = _parent->setPurgeable( newState, oldState );
151
152 return err;
153 }
154
155 IOReturn
156 IOSubMemoryDescriptor::setOwnership( task_t newOwner,
157 int newLedgerTag,
158 IOOptionBits newLedgerOptions )
159 {
160 IOReturn err;
161
162 if (iokit_iomd_setownership_enabled == FALSE) {
163 return kIOReturnUnsupported;
164 }
165
166 err = _parent->setOwnership( newOwner, newLedgerTag, newLedgerOptions );
167
168 return err;
169 }
170
171 IOReturn
172 IOSubMemoryDescriptor::prepare(
173 IODirection forDirection)
174 {
175 IOReturn err;
176
177 err = _parent->prepare( forDirection);
178
179 return err;
180 }
181
182 IOReturn
183 IOSubMemoryDescriptor::complete(
184 IODirection forDirection)
185 {
186 IOReturn err;
187
188 err = _parent->complete( forDirection);
189
190 return err;
191 }
192
193 IOMemoryMap *
194 IOSubMemoryDescriptor::makeMapping(
195 IOMemoryDescriptor * owner,
196 task_t intoTask,
197 IOVirtualAddress address,
198 IOOptionBits options,
199 IOByteCount offset,
200 IOByteCount length )
201 {
202 IOMemoryMap * mapping = NULL;
203
204 #ifndef __LP64__
205 if (!(kIOMap64Bit & options)) {
206 panic("IOSubMemoryDescriptor::makeMapping !64bit");
207 }
208 #endif /* !__LP64__ */
209
210 mapping = (IOMemoryMap *) _parent->makeMapping(
211 owner,
212 intoTask,
213 address,
214 options, _start + offset, length );
215
216 return mapping;
217 }
218
219 uint64_t
220 IOSubMemoryDescriptor::getPreparationID( void )
221 {
222 uint64_t pID;
223
224 if (!super::getKernelReserved()) {
225 return kIOPreparationIDUnsupported;
226 }
227
228 pID = _parent->getPreparationID();
229 if (reserved->kernReserved[0] != pID) {
230 reserved->kernReserved[0] = pID;
231 reserved->preparationID = kIOPreparationIDUnprepared;
232 super::setPreparationID();
233 }
234
235 return super::getPreparationID();
236 }
237
238 IOReturn
239 IOSubMemoryDescriptor::getPageCounts(IOByteCount * residentPageCount,
240 IOByteCount * dirtyPageCount)
241 {
242 return _parent->getPageCounts(residentPageCount, dirtyPageCount);
243 }