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