]> git.saurik.com Git - apple/xnu.git/blame - iokit/Kernel/IOSubMemoryDescriptor.cpp
xnu-6153.61.1.tar.gz
[apple/xnu.git] / iokit / Kernel / IOSubMemoryDescriptor.cpp
CommitLineData
b0d623f7
A
1/*
2 * Copyright (c) 1998-2007 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
0a7de745 5 *
b0d623f7
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 *
b0d623f7
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 *
b0d623f7
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
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.
0a7de745 25 *
b0d623f7
A
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29#include <IOKit/IOSubMemoryDescriptor.h>
30
31#include "IOKitKernelInternal.h"
32
33#define super IOMemoryDescriptor
34
35OSDefineMetaClassAndStructors(IOSubMemoryDescriptor, IOMemoryDescriptor)
36
0a7de745
A
37IOReturn
38IOSubMemoryDescriptor::redirect( task_t safeTask, bool doRedirect )
b0d623f7
A
39{
40#ifdef __LP64__
0a7de745 41 super::redirect( safeTask, doRedirect );
b0d623f7 42#endif /* __LP64__ */
0a7de745 43 return _parent->redirect( safeTask, doRedirect );
b0d623f7
A
44}
45
46IOSubMemoryDescriptor *
0a7de745
A
47IOSubMemoryDescriptor::withSubRange(IOMemoryDescriptor * of,
48 IOByteCount offset,
49 IOByteCount length,
50 IOOptionBits options)
b0d623f7 51{
0a7de745 52 IOSubMemoryDescriptor *self = new IOSubMemoryDescriptor;
b0d623f7 53
0a7de745
A
54 if (self && !self->initSubRange(of, offset, length, (IODirection) options)) {
55 self->release();
cb323159 56 self = NULL;
0a7de745
A
57 }
58 return self;
b0d623f7
A
59}
60
0a7de745
A
61bool
62IOSubMemoryDescriptor::initSubRange( IOMemoryDescriptor * parent,
63 IOByteCount offset, IOByteCount length,
64 IODirection direction )
b0d623f7 65{
0a7de745
A
66 if (parent && ((offset + length) > parent->getLength())) {
67 return false;
68 }
69
b0d623f7 70 /*
0a7de745
A
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.
b0d623f7
A
74 */
75
0a7de745
A
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;
3e170ce0 100
b0d623f7 101#ifndef __LP64__
0a7de745 102 _direction = (IODirection) (_flags & kIOMemoryDirectionMask);
b0d623f7 103#endif /* !__LP64__ */
b0d623f7 104
0a7de745 105 return true;
b0d623f7
A
106}
107
0a7de745
A
108void
109IOSubMemoryDescriptor::free( void )
b0d623f7 110{
0a7de745
A
111 if (_parent) {
112 _parent->release();
113 }
b0d623f7 114
0a7de745 115 super::free();
b0d623f7
A
116}
117
118addr64_t
119IOSubMemoryDescriptor::getPhysicalSegment(IOByteCount offset, IOByteCount * length, IOOptionBits options)
120{
0a7de745
A
121 addr64_t address;
122 IOByteCount actualLength;
b0d623f7 123
0a7de745 124 assert(offset <= _length);
b0d623f7 125
0a7de745
A
126 if (length) {
127 *length = 0;
128 }
b0d623f7 129
0a7de745
A
130 if (offset >= _length) {
131 return 0;
132 }
b0d623f7 133
0a7de745 134 address = _parent->getPhysicalSegment( offset + _start, &actualLength, options );
b0d623f7 135
0a7de745
A
136 if (address && length) {
137 *length = min( _length - offset, actualLength );
138 }
b0d623f7 139
0a7de745 140 return address;
b0d623f7
A
141}
142
0a7de745
A
143IOReturn
144IOSubMemoryDescriptor::setPurgeable( IOOptionBits newState,
145 IOOptionBits * oldState )
b0d623f7 146{
0a7de745 147 IOReturn err;
b0d623f7 148
0a7de745 149 err = _parent->setPurgeable( newState, oldState );
b0d623f7 150
0a7de745 151 return err;
b0d623f7
A
152}
153
cb323159
A
154IOReturn
155IOSubMemoryDescriptor::setOwnership( task_t newOwner,
156 int newLedgerTag,
157 IOOptionBits newLedgerOptions )
158{
159 IOReturn err;
160
161 if (iokit_iomd_setownership_enabled == FALSE) {
162 return kIOReturnUnsupported;
163 }
164
165 err = _parent->setOwnership( newOwner, newLedgerTag, newLedgerOptions );
166
167 return err;
168}
169
0a7de745
A
170IOReturn
171IOSubMemoryDescriptor::prepare(
172 IODirection forDirection)
b0d623f7 173{
0a7de745 174 IOReturn err;
b0d623f7 175
0a7de745 176 err = _parent->prepare( forDirection);
b0d623f7 177
0a7de745 178 return err;
b0d623f7
A
179}
180
0a7de745
A
181IOReturn
182IOSubMemoryDescriptor::complete(
183 IODirection forDirection)
b0d623f7 184{
0a7de745 185 IOReturn err;
b0d623f7 186
0a7de745 187 err = _parent->complete( forDirection);
b0d623f7 188
0a7de745 189 return err;
b0d623f7
A
190}
191
0a7de745
A
192IOMemoryMap *
193IOSubMemoryDescriptor::makeMapping(
194 IOMemoryDescriptor * owner,
195 task_t intoTask,
196 IOVirtualAddress address,
197 IOOptionBits options,
198 IOByteCount offset,
199 IOByteCount length )
b0d623f7 200{
cb323159 201 IOMemoryMap * mapping = NULL;
b0d623f7
A
202
203#ifndef __LP64__
0a7de745
A
204 if (!(kIOMap64Bit & options)) {
205 panic("IOSubMemoryDescriptor::makeMapping !64bit");
206 }
b0d623f7
A
207#endif /* !__LP64__ */
208
0a7de745
A
209 mapping = (IOMemoryMap *) _parent->makeMapping(
210 owner,
211 intoTask,
212 address,
213 options, _start + offset, length );
b0d623f7 214
0a7de745 215 return mapping;
b0d623f7
A
216}
217
218uint64_t
219IOSubMemoryDescriptor::getPreparationID( void )
220{
0a7de745 221 uint64_t pID;
316670eb 222
0a7de745
A
223 if (!super::getKernelReserved()) {
224 return kIOPreparationIDUnsupported;
225 }
316670eb 226
0a7de745
A
227 pID = _parent->getPreparationID();
228 if (reserved->kernReserved[0] != pID) {
229 reserved->kernReserved[0] = pID;
230 reserved->preparationID = kIOPreparationIDUnprepared;
231 super::setPreparationID();
232 }
316670eb 233
0a7de745 234 return super::getPreparationID();
b0d623f7
A
235}
236
3e170ce0
A
237IOReturn
238IOSubMemoryDescriptor::getPageCounts(IOByteCount * residentPageCount,
0a7de745 239 IOByteCount * dirtyPageCount)
3e170ce0 240{
0a7de745 241 return _parent->getPageCounts(residentPageCount, dirtyPageCount);
3e170ce0 242}