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