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