2 * Copyright (c) 2014-2016 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #include <sys/cdefs.h>
31 #include <IOKit/assert.h>
32 #include <IOKit/system.h>
33 #include <IOKit/IOLib.h>
34 #include <IOKit/IOMemoryDescriptor.h>
35 #include <IOKit/IOMapper.h>
36 #include <IOKit/IODMACommand.h>
37 #include <IOKit/IOKitKeysPrivate.h>
41 #include <IOKit/IOSubMemoryDescriptor.h>
42 #endif /* !__LP64__ */
43 #include <IOKit/IOSubMemoryDescriptor.h>
44 #include <IOKit/IOMultiMemoryDescriptor.h>
45 #include <IOKit/IOBufferMemoryDescriptor.h>
47 #include <IOKit/IOKitDebug.h>
48 #include <libkern/OSDebug.h>
53 #include <vm/vm_pageout.h>
54 #include <mach/memory_object_types.h>
55 #include <device/device_port.h>
57 #include <mach/vm_prot.h>
58 #include <mach/mach_vm.h>
59 #include <vm/vm_fault.h>
60 #include <vm/vm_protos.h>
64 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
66 #if DEVELOPMENT || DEBUG
68 extern SInt32 gIOMemoryReferenceCount
;
71 IOMultMemoryDescriptorTest(int newValue
)
73 IOMemoryDescriptor
* mds
[3];
74 IOMultiMemoryDescriptor
* mmd
;
79 IOAddressRange ranges
[2];
81 data
= (typeof(data
))IOMallocAligned(ptoa(8), page_size
);
82 for (i
= 0; i
< ptoa(8); i
++) {
83 data
[i
] = atop(i
) | 0xD0;
86 ranges
[0].address
= (IOVirtualAddress
)(data
+ ptoa(4));
87 ranges
[0].length
= ptoa(4);
88 ranges
[1].address
= (IOVirtualAddress
)(data
+ ptoa(0));
89 ranges
[1].length
= ptoa(4);
91 mds
[0] = IOMemoryDescriptor::withAddressRanges(&ranges
[0], 2, kIODirectionOutIn
, kernel_task
);
93 mds
[1] = IOSubMemoryDescriptor::withSubRange(mds
[0], ptoa(3), ptoa(2), kIODirectionOutIn
);
94 mds
[2] = IOSubMemoryDescriptor::withSubRange(mds
[0], ptoa(7), ptoa(1), kIODirectionOutIn
);
96 mmd
= IOMultiMemoryDescriptor::withDescriptors(&mds
[0], sizeof(mds
) / sizeof(mds
[0]), kIODirectionOutIn
, false);
100 map
= mmd
->createMappingInTask(kernel_task
, 0, kIOMapAnywhere
, ptoa(7), mmd
->getLength() - ptoa(7));
104 addr
= (void *) map
->getVirtualAddress();
105 assert(ptoa(4) == map
->getLength());
106 assert(0xd3d3d3d3 == ((uint32_t *)addr
)[ptoa(0) / sizeof(uint32_t)]);
107 assert(0xd7d7d7d7 == ((uint32_t *)addr
)[ptoa(1) / sizeof(uint32_t)]);
108 assert(0xd0d0d0d0 == ((uint32_t *)addr
)[ptoa(2) / sizeof(uint32_t)]);
109 assert(0xd3d3d3d3 == ((uint32_t *)addr
)[ptoa(3) / sizeof(uint32_t)]);
111 IOFreeAligned(data
, ptoa(8));
118 // <rdar://problem/30102458>
120 IODMACommandForceDoubleBufferTest(int newValue
)
123 IOBufferMemoryDescriptor
* bmd
;
126 IODMACommand::SegmentOptions segOptions
=
128 .fStructSize
= sizeof(segOptions
),
129 .fNumAddressBits
= 64,
130 .fMaxSegmentSize
= 0x2000,
131 .fMaxTransferSize
= 128 * 1024,
133 .fAlignmentLength
= 1,
134 .fAlignmentInternalSegments
= 1
136 IODMACommand::Segment64 segments
[1];
141 for (dir
= kIODirectionIn
;; dir
++) {
142 bmd
= IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task
,
143 dir
| kIOMemoryPageable
, ptoa(8));
146 ((uint32_t*) bmd
->getBytesNoCopy())[0] = 0x53535300 | dir
;
148 ret
= bmd
->prepare((IODirection
) dir
);
149 assert(kIOReturnSuccess
== ret
);
151 dma
= IODMACommand::withSpecification(kIODMACommandOutputHost64
, &segOptions
,
152 kIODMAMapOptionMapped
,
155 ret
= dma
->setMemoryDescriptor(bmd
, true);
156 assert(kIOReturnSuccess
== ret
);
158 ret
= dma
->synchronize(IODMACommand::kForceDoubleBuffer
| kIODirectionOut
);
159 assert(kIOReturnSuccess
== ret
);
163 ret
= dma
->gen64IOVMSegments(&dmaOffset
, &segments
[0], &numSegments
);
164 assert(kIOReturnSuccess
== ret
);
165 assert(1 == numSegments
);
167 if (kIODirectionOut
& dir
) {
168 data
= ((uint32_t*) bmd
->getBytesNoCopy())[0];
169 assertf((0x53535300 | dir
) == data
, "mismatch 0x%x", data
);
171 if (kIODirectionIn
& dir
) {
172 IOMappedWrite32(segments
[0].fIOVMAddr
, 0x11223300 | dir
);
175 ret
= dma
->clearMemoryDescriptor(true);
176 assert(kIOReturnSuccess
== ret
);
179 bmd
->complete((IODirection
) dir
);
181 if (kIODirectionIn
& dir
) {
182 data
= ((uint32_t*) bmd
->getBytesNoCopy())[0];
183 assertf((0x11223300 | dir
) == data
, "mismatch 0x%x", data
);
188 if (dir
== kIODirectionInOut
) {
196 // <rdar://problem/34322778>
198 IODMACommandLocalMappedNonContig(int newValue
)
201 IOMemoryDescriptor
* md
;
203 OSDictionary
* matching
;
206 IODMACommand::SegmentOptions segOptions
=
208 .fStructSize
= sizeof(segOptions
),
209 .fNumAddressBits
= 64,
210 .fMaxSegmentSize
= 128 * 1024,
211 .fMaxTransferSize
= 128 * 1024,
213 .fAlignmentLength
= 1,
214 .fAlignmentInternalSegments
= 1
216 IODMACommand::Segment64 segments
[1];
221 vm_size_t bufSize
= ptoa(4);
223 if (!IOMapper::gSystem
) {
228 kr
= vm_allocate_kernel(kernel_map
, &buffer
, bufSize
, VM_FLAGS_ANYWHERE
, VM_KERN_MEMORY_IOKIT
);
229 assert(KERN_SUCCESS
== kr
);
231 // fragment the vmentries
232 kr
= vm_inherit(kernel_map
, buffer
+ ptoa(1), ptoa(1), VM_INHERIT_NONE
);
233 assert(KERN_SUCCESS
== kr
);
235 md
= IOMemoryDescriptor::withAddressRange(
236 buffer
+ 0xa00, 0x2000, kIODirectionOutIn
, kernel_task
);
238 kr
= md
->prepare(kIODirectionOutIn
);
239 assert(kIOReturnSuccess
== kr
);
241 segPhys
= md
->getPhysicalSegment(0, NULL
, 0);
243 matching
= IOService::nameMatching("XHC1");
245 device
= IOService::copyMatchingService(matching
);
247 mapper
= device
? IOMapper::copyMapperForDeviceWithIndex(device
, 0) : NULL
;
249 dma
= IODMACommand::withSpecification(kIODMACommandOutputHost64
, &segOptions
,
250 kIODMAMapOptionMapped
,
253 kr
= dma
->setMemoryDescriptor(md
, true);
254 assert(kIOReturnSuccess
== kr
);
258 kr
= dma
->gen64IOVMSegments(&dmaOffset
, &segments
[0], &numSegments
);
259 assert(kIOReturnSuccess
== kr
);
260 assert(1 == numSegments
);
263 assertf(segments
[0].fIOVMAddr
!= segPhys
, "phys !local 0x%qx, 0x%qx, %p", segments
[0].fIOVMAddr
, segPhys
, dma
);
266 kr
= dma
->clearMemoryDescriptor(true);
267 assert(kIOReturnSuccess
== kr
);
270 kr
= md
->complete(kIODirectionOutIn
);
271 assert(kIOReturnSuccess
== kr
);
274 kr
= vm_deallocate(kernel_map
, buffer
, bufSize
);
275 assert(KERN_SUCCESS
== kr
);
276 OSSafeReleaseNULL(mapper
);
281 // <rdar://problem/30102458>
283 IOMemoryRemoteTest(int newValue
)
286 IOMemoryDescriptor
* md
;
287 IOByteCount offset
, length
;
292 IODMACommand::SegmentOptions segOptions
=
294 .fStructSize
= sizeof(segOptions
),
295 .fNumAddressBits
= 64,
296 .fMaxSegmentSize
= 0x2000,
297 .fMaxTransferSize
= 128 * 1024,
299 .fAlignmentLength
= 1,
300 .fAlignmentInternalSegments
= 1
302 IODMACommand::Segment64 segments
[1];
306 IOAddressRange ranges
[2] = {
307 { 0x1234567890123456ULL
, 0x1000 }, { 0x5432109876543210, 0x2000 },
310 md
= IOMemoryDescriptor::withAddressRanges(&ranges
[0], 2, kIODirectionOutIn
| kIOMemoryRemote
, TASK_NULL
);
314 // md->readBytes(0, &idx, sizeof(idx));
316 ret
= md
->prepare(kIODirectionOutIn
);
317 assert(kIOReturnSuccess
== ret
);
319 printf("remote md flags 0x%qx, r %d\n",
320 md
->getFlags(), (0 != (kIOMemoryRemote
& md
->getFlags())));
322 for (offset
= 0, idx
= 0; true; offset
+= length
, idx
++) {
323 addr
= md
->getPhysicalSegment(offset
, &length
, 0);
328 assert(addr
== ranges
[idx
].address
);
329 assert(length
== ranges
[idx
].length
);
331 assert(offset
== md
->getLength());
333 dma
= IODMACommand::withSpecification(kIODMACommandOutputHost64
, &segOptions
,
334 kIODMAMapOptionUnmapped
| kIODMAMapOptionIterateOnly
,
337 ret
= dma
->setMemoryDescriptor(md
, true);
338 assert(kIOReturnSuccess
== ret
);
340 for (dmaOffset
= 0, idx
= 0; dmaOffset
< md
->getLength(); idx
++) {
342 ret
= dma
->gen64IOVMSegments(&dmaOffset
, &segments
[0], &numSegments
);
343 assert(kIOReturnSuccess
== ret
);
344 assert(1 == numSegments
);
346 assert(segments
[0].fIOVMAddr
== ranges
[idx
].address
);
347 assert(segments
[0].fLength
== ranges
[idx
].length
);
349 assert(dmaOffset
== md
->getLength());
351 ret
= dma
->clearMemoryDescriptor(true);
352 assert(kIOReturnSuccess
== ret
);
354 md
->complete(kIODirectionOutIn
);
361 IOMemoryPrefaultTest(uint32_t options
)
363 IOBufferMemoryDescriptor
* bmd
;
370 lock
= IOSimpleLockAlloc();
373 bmd
= IOBufferMemoryDescriptor::inTaskWithOptions(current_task(),
374 kIODirectionOutIn
| kIOMemoryPageable
, ptoa(8));
377 assert(KERN_SUCCESS
== kr
);
379 map
= bmd
->map(kIOMapPrefault
);
382 p
= (typeof(p
))map
->getVirtualAddress();
383 IOSimpleLockLock(lock
);
385 IOSimpleLockUnlock(lock
);
387 IOLog("IOMemoryPrefaultTest %d\n", data
);
391 IOSimpleLockFree(lock
);
393 return kIOReturnSuccess
;
397 // <rdar://problem/26375234>
399 ZeroLengthTest(int newValue
)
401 IOMemoryDescriptor
* md
;
403 md
= IOMemoryDescriptor::withAddressRange(
404 0, 0, kIODirectionNone
, current_task());
412 // <rdar://problem/27002624>
414 BadFixedAllocTest(int newValue
)
416 IOBufferMemoryDescriptor
* bmd
;
419 bmd
= IOBufferMemoryDescriptor::inTaskWithOptions(NULL
,
420 kIODirectionIn
| kIOMemoryPageable
, ptoa(1));
422 map
= bmd
->createMappingInTask(kernel_task
, 0x2000, 0);
429 // <rdar://problem/26466423>
431 IODirectionPrepareNoZeroFillTest(int newValue
)
433 IOBufferMemoryDescriptor
* bmd
;
435 bmd
= IOBufferMemoryDescriptor::inTaskWithOptions(NULL
,
436 kIODirectionIn
| kIOMemoryPageable
, ptoa(24));
438 bmd
->prepare((IODirection
)(kIODirectionIn
| kIODirectionPrepareNoZeroFill
));
439 bmd
->prepare(kIODirectionIn
);
440 bmd
->complete((IODirection
)(kIODirectionIn
| kIODirectionCompleteWithDataValid
));
441 bmd
->complete(kIODirectionIn
);
446 // <rdar://problem/28190483>
448 IOMemoryMapTest(uint32_t options
)
450 IOBufferMemoryDescriptor
* bmd
;
451 IOMemoryDescriptor
* md
;
459 bmd
= IOBufferMemoryDescriptor::inTaskWithOptions(current_task(),
460 kIODirectionOutIn
| kIOMemoryPageable
, 0x4018 + 0x800);
462 p
= (typeof(p
))bmd
->getBytesNoCopy();
465 r
= copyout(&data
, p
, sizeof(data
));
468 r
= copyout(&data
, p
+ 0x1000, sizeof(data
));
471 r
= copyout(&data
, p
+ 0x2000, sizeof(data
));
474 r
= copyout(&data
, p
+ 0x3000, sizeof(data
));
477 md
= IOMemoryDescriptor::withAddressRange(p
, 0x4018,
478 kIODirectionOut
| options
,
481 time
= mach_absolute_time();
482 map
= md
->map(kIOMapReadOnly
);
483 time
= mach_absolute_time() - time
;
485 absolutetime_to_nanoseconds(time
, &nano
);
487 p2
= (typeof(p2
))map
->getVirtualAddress();
488 assert(0x11 == p2
[0]);
489 assert(0x22 == p2
[0x1000]);
490 assert(0x33 == p2
[0x2000]);
491 assert(0x44 == p2
[0x3000]);
494 r
= copyout(&data
, p
+ 0x2000, sizeof(data
));
497 assert(0x11 == p2
[0]);
498 assert(0x22 == p2
[0x1000]);
499 assert(0x44 == p2
[0x3000]);
500 if (kIOMemoryMapCopyOnWrite
& options
) {
501 assert(0x33 == p2
[0x2000]);
503 assert(0x99 == p2
[0x2000]);
506 IOLog("IOMemoryMapCopyOnWriteTest map(%s) %lld ns\n",
507 kIOMemoryMapCopyOnWrite
& options
? "kIOMemoryMapCopyOnWrite" : "",
514 return kIOReturnSuccess
;
518 IOMemoryMapCopyOnWriteTest(int newValue
)
521 IOMemoryMapTest(kIOMemoryMapCopyOnWrite
);
526 AllocationNameTest(int newValue
)
528 IOMemoryDescriptor
* bmd
;
529 kern_allocation_name_t name
, prior
;
531 name
= kern_allocation_name_allocate("com.apple.iokit.test", 0);
534 prior
= thread_set_allocation_name(name
);
536 bmd
= IOBufferMemoryDescriptor::inTaskWithOptions(TASK_NULL
,
537 kIODirectionOutIn
| kIOMemoryPageable
| kIOMemoryKernelUserShared
,
542 thread_set_allocation_name(prior
);
543 kern_allocation_name_release(name
);
553 IOMemoryDescriptorTest(int newValue
)
557 IOLog("/IOMemoryDescriptorTest %d\n", (int) gIOMemoryReferenceCount
);
561 IOMemoryDescriptor
* sbmds
[3];
562 IOMultiMemoryDescriptor
* smmd
;
563 IOMemoryDescriptor
* mds
[2];
564 IOMultiMemoryDescriptor
* mmd
;
567 sbmds
[0] = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task
, kIODirectionOutIn
| kIOMemoryKernelUserShared
, ptoa(1));
568 sbmds
[1] = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task
, kIODirectionOutIn
| kIOMemoryKernelUserShared
, ptoa(2));
569 sbmds
[2] = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task
, kIODirectionOutIn
| kIOMemoryKernelUserShared
, ptoa(3));
570 smmd
= IOMultiMemoryDescriptor::withDescriptors(&sbmds
[0], sizeof(sbmds
) / sizeof(sbmds
[0]), kIODirectionOutIn
, false);
572 mds
[0] = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task
, kIODirectionOutIn
| kIOMemoryKernelUserShared
, ptoa(1));
574 mmd
= IOMultiMemoryDescriptor::withDescriptors(&mds
[0], sizeof(mds
) / sizeof(mds
[0]), kIODirectionOutIn
, false);
575 map
= mmd
->createMappingInTask(kernel_task
, 0, kIOMapAnywhere
);
586 } else if (5 == newValue
) {
588 IOMemoryDescriptor
* md
;
590 IODMACommand::SegmentOptions segOptions
=
592 .fStructSize
= sizeof(segOptions
),
593 .fNumAddressBits
= 64,
594 .fMaxSegmentSize
= 4096,
595 .fMaxTransferSize
= 128 * 1024,
597 .fAlignmentLength
= 4,
598 .fAlignmentInternalSegments
= 0x1000
601 IOAddressRange ranges
[3][2] =
604 { (uintptr_t) &IOMemoryDescriptorTest
, 0x2ffc },
608 { ranges
[0][0].address
, 0x10 },
609 { 0x3000 + ranges
[0][0].address
, 0xff0 },
612 { ranges
[0][0].address
, 0x2ffc },
613 { trunc_page(ranges
[0][0].address
), 0x800 },
616 static const uint32_t rangesCount
[3] = { 1, 2, 2 };
619 for (test
= 0; test
< 3; test
++) {
620 kprintf("---[%d] address 0x%qx-0x%qx, 0x%qx-0x%qx\n", test
,
621 ranges
[test
][0].address
, ranges
[test
][0].length
,
622 ranges
[test
][1].address
, ranges
[test
][1].length
);
624 md
= IOMemoryDescriptor::withAddressRanges((IOAddressRange
*)&ranges
[test
][0], rangesCount
[test
], kIODirectionOut
, kernel_task
);
627 assert(kIOReturnSuccess
== ret
);
628 dma
= IODMACommand::withSpecification(kIODMACommandOutputHost64
, &segOptions
,
629 IODMACommand::kMapped
, NULL
, NULL
);
631 ret
= dma
->setMemoryDescriptor(md
, true);
632 if (kIOReturnSuccess
== ret
) {
633 IODMACommand::Segment64 segments
[1];
640 ret
= dma
->gen64IOVMSegments(&offset
, &segments
[0], &numSegments
);
641 assert(kIOReturnSuccess
== ret
);
642 assert(1 == numSegments
);
643 kprintf("seg 0x%qx, 0x%qx\n", segments
[0].fIOVMAddr
, segments
[0].fLength
);
644 }while (offset
< md
->getLength());
646 ret
= dma
->clearMemoryDescriptor(true);
647 assert(kIOReturnSuccess
== ret
);
653 return kIOReturnSuccess
;
654 } else if (4 == newValue
) {
657 IOBufferMemoryDescriptor
* md1
;
660 size_t bufSize
= 8192 * 8192 * sizeof(uint32_t);
661 uint64_t start
, time
, nano
;
663 isp
= IOService::copyMatchingService(IOService::nameMatching("isp"));
665 mapper
= IOMapper::copyMapperForDeviceWithIndex(isp
, 0);
668 md1
= IOBufferMemoryDescriptor::inTaskWithOptions(TASK_NULL
,
669 kIODirectionOutIn
| kIOMemoryPersistent
| kIOMemoryPageable
,
672 ret
= md1
->prepare();
673 assert(kIOReturnSuccess
== ret
);
675 IODMAMapSpecification mapSpec
;
676 bzero(&mapSpec
, sizeof(mapSpec
));
678 uint64_t mappedLength
;
680 start
= mach_absolute_time();
682 ret
= md1
->dmaMap(mapper
, NULL
, &mapSpec
, 0, bufSize
, &mapped
, &mappedLength
);
683 assert(kIOReturnSuccess
== ret
);
685 time
= mach_absolute_time() - start
;
687 absolutetime_to_nanoseconds(time
, &nano
);
688 kprintf("time %lld us\n", nano
/ 1000ULL);
689 kprintf("seg0 0x%qx, 0x%qx\n", mapped
, mappedLength
);
693 dma
= IODMACommand::withSpecification(kIODMACommandOutputHost32
,
694 32, 0, IODMACommand::kMapped
, 0, 1, mapper
, NULL
);
698 start
= mach_absolute_time();
699 ret
= dma
->setMemoryDescriptor(md1
, true);
700 assert(kIOReturnSuccess
== ret
);
701 time
= mach_absolute_time() - start
;
703 absolutetime_to_nanoseconds(time
, &nano
);
704 kprintf("time %lld us\n", nano
/ 1000ULL);
707 IODMACommand::Segment32 segments
[1];
708 UInt32 numSegments
= 1;
712 ret
= dma
->gen32IOVMSegments(&offset
, &segments
[0], &numSegments
);
713 assert(kIOReturnSuccess
== ret
);
714 assert(1 == numSegments
);
715 kprintf("seg0 0x%x, 0x%x\n", (int)segments
[0].fIOVMAddr
, (int)segments
[0].fLength
);
717 ret
= dma
->clearMemoryDescriptor(true);
718 assert(kIOReturnSuccess
== ret
);
722 return kIOReturnSuccess
;
726 IOBufferMemoryDescriptor
* md1
;
727 IOBufferMemoryDescriptor
* md2
;
734 md1
= IOBufferMemoryDescriptor::inTaskWithOptions(TASK_NULL
,
735 kIODirectionOutIn
| kIOMemoryPersistent
| kIOMemoryPageable
,
736 64 * 1024, page_size
);
738 map1
= md1
->createMappingInTask(kernel_task
, 0, kIOMapAnywhere
| kIOMapUnique
);
740 buf1
= (uint32_t *) map1
->getVirtualAddress();
742 md2
= IOBufferMemoryDescriptor::inTaskWithOptions(TASK_NULL
,
743 kIODirectionOutIn
| kIOMemoryPersistent
| kIOMemoryPageable
,
744 64 * 1024, page_size
);
746 map2
= md2
->createMappingInTask(kernel_task
, 0, kIOMapAnywhere
| kIOMapUnique
);
748 buf2
= (uint32_t *) map2
->getVirtualAddress();
750 memset(buf1
, 0x11, 64 * 1024L);
751 memset(buf2
, 0x22, 64 * 1024L);
753 kprintf("md1 %p, map1 %p, buf2 %p; md2 %p, map2 %p, buf2 %p\n", md1
, map1
, buf1
, md2
, map2
, buf2
);
755 kprintf("no redir 0x%08x, 0x%08x\n", buf1
[0], buf2
[0]);
756 assert(0x11111111 == buf1
[0]);
757 assert(0x22222222 == buf2
[0]);
758 err
= map1
->redirect(md2
, 0, 0ULL);
759 kprintf("redir md2(0x%x) 0x%08x, 0x%08x\n", err
, buf1
[0], buf2
[0]);
760 assert(0x11111111 == buf2
[0]);
761 assert(0x22222222 == buf1
[0]);
762 err
= map1
->redirect(md1
, 0, 0ULL);
763 kprintf("redir md1(0x%x) 0x%08x, 0x%08x\n", err
, buf1
[0], buf2
[0]);
764 assert(0x11111111 == buf1
[0]);
765 assert(0x22222222 == buf2
[0]);
773 // result = IODMACommandLocalMappedNonContig(newValue);
774 // if (result) return (result);
776 result
= IODMACommandForceDoubleBufferTest(newValue
);
781 result
= AllocationNameTest(newValue
);
786 result
= IOMemoryMapCopyOnWriteTest(newValue
);
791 result
= IOMultMemoryDescriptorTest(newValue
);
796 result
= ZeroLengthTest(newValue
);
801 result
= IODirectionPrepareNoZeroFillTest(newValue
);
806 result
= BadFixedAllocTest(newValue
);
811 result
= IOMemoryRemoteTest(newValue
);
816 result
= IOMemoryPrefaultTest(newValue
);
821 IOGeneralMemoryDescriptor
* md
;
823 vm_size_t bsize
= 16 * 1024 * 1024;
824 vm_size_t srcsize
, srcoffset
, mapoffset
, size
;
827 data
[0] = data
[1] = 0;
828 kr
= vm_allocate_kernel(kernel_map
, &data
[0], bsize
, VM_FLAGS_ANYWHERE
, VM_KERN_MEMORY_IOKIT
);
829 assert(KERN_SUCCESS
== kr
);
831 vm_inherit(kernel_map
, data
[0] + ptoa(1), ptoa(1), VM_INHERIT_NONE
);
832 vm_inherit(kernel_map
, data
[0] + ptoa(16), ptoa(4), VM_INHERIT_NONE
);
834 IOLog("data 0x%lx, 0x%lx\n", (long)data
[0], (long)data
[1]);
836 uint32_t idx
, offidx
;
837 for (idx
= 0; idx
< (bsize
/ sizeof(uint32_t)); idx
++) {
838 ((uint32_t*)data
[0])[idx
] = idx
;
841 for (srcoffset
= 0; srcoffset
< bsize
; srcoffset
= ((srcoffset
<< 2) + 0x40c)) {
842 for (srcsize
= 4; srcsize
< (bsize
- srcoffset
- 1); srcsize
= ((srcsize
<< 2) + 0x3fc)) {
843 IOAddressRange ranges
[3];
844 uint32_t rangeCount
= 1;
846 bzero(&ranges
[0], sizeof(ranges
));
847 ranges
[0].address
= data
[0] + srcoffset
;
848 ranges
[0].length
= srcsize
;
849 ranges
[1].address
= ranges
[2].address
= data
[0];
851 if (srcsize
> ptoa(5)) {
852 ranges
[0].length
= 7634;
853 ranges
[1].length
= 9870;
854 ranges
[2].length
= srcsize
- ranges
[0].length
- ranges
[1].length
;
855 ranges
[1].address
= ranges
[0].address
+ ranges
[0].length
;
856 ranges
[2].address
= ranges
[1].address
+ ranges
[1].length
;
858 } else if ((srcsize
> ptoa(2)) && !(page_mask
& srcoffset
)) {
859 ranges
[0].length
= ptoa(1);
860 ranges
[1].length
= ptoa(1);
861 ranges
[2].length
= srcsize
- ranges
[0].length
- ranges
[1].length
;
862 ranges
[0].address
= data
[0] + srcoffset
+ ptoa(1);
863 ranges
[1].address
= data
[0] + srcoffset
;
864 ranges
[2].address
= ranges
[0].address
+ ranges
[0].length
;
868 md
= OSDynamicCast(IOGeneralMemoryDescriptor
,
869 IOMemoryDescriptor::withAddressRanges(&ranges
[0], rangeCount
, kIODirectionInOut
, kernel_task
));
872 IOLog("IOMemoryDescriptor::withAddressRanges [0x%lx @ 0x%lx]\n[0x%llx, 0x%llx],\n[0x%llx, 0x%llx],\n[0x%llx, 0x%llx]\n",
873 (long) srcsize
, (long) srcoffset
,
874 (long long) ranges
[0].address
- data
[0], (long long) ranges
[0].length
,
875 (long long) ranges
[1].address
- data
[0], (long long) ranges
[1].length
,
876 (long long) ranges
[2].address
- data
[0], (long long) ranges
[2].length
);
878 if (kIOReturnSuccess
== kr
) {
879 for (mapoffset
= 0; mapoffset
< srcsize
; mapoffset
= ((mapoffset
<< 1) + 0xf00)) {
880 for (size
= 4; size
< (srcsize
- mapoffset
- 1); size
= ((size
<< 2) + 0x200)) {
882 mach_vm_address_t addr
= 0;
885 // IOLog("<mapRef [0x%lx @ 0x%lx]\n", (long) size, (long) mapoffset);
887 map
= md
->createMappingInTask(kernel_task
, 0, kIOMapAnywhere
, mapoffset
, size
);
889 addr
= map
->getAddress();
894 // IOLog(">mapRef 0x%x %llx\n", kr, addr);
896 if (kIOReturnSuccess
!= kr
) {
900 if (kIOReturnSuccess
!= kr
) {
901 panic("prepare() fail 0x%x\n", kr
);
904 for (idx
= 0; idx
< size
; idx
+= sizeof(uint32_t)) {
905 offidx
= (idx
+ mapoffset
+ srcoffset
);
906 if ((srcsize
<= ptoa(5)) && (srcsize
> ptoa(2)) && !(page_mask
& srcoffset
)) {
907 if (offidx
< ptoa(2)) {
911 offidx
/= sizeof(uint32_t);
913 if (offidx
!= ((uint32_t*)addr
)[idx
/ sizeof(uint32_t)]) {
914 panic("vm mismatch md %p map %p, @ 0x%x, 0x%lx, 0x%lx, \n", md
, map
, idx
, (long) srcoffset
, (long) mapoffset
);
915 kr
= kIOReturnBadMedia
;
917 if (sizeof(data
) != md
->readBytes(mapoffset
+ idx
, &data
, sizeof(data
))) {
920 if (offidx
!= data
) {
921 panic("phys mismatch md %p map %p, @ 0x%x, 0x%lx, 0x%lx, \n", md
, map
, idx
, (long) srcoffset
, (long) mapoffset
);
922 kr
= kIOReturnBadMedia
;
928 // IOLog("unmapRef %llx\n", addr);
930 if (kIOReturnSuccess
!= kr
) {
936 if (kIOReturnSuccess
!= kr
) {
940 if (kIOReturnSuccess
!= kr
) {
945 if (kIOReturnSuccess
!= kr
) {
946 IOLog("FAIL: src 0x%lx @ 0x%lx, map 0x%lx @ 0x%lx\n",
947 (long) srcsize
, (long) srcoffset
, (long) size
, (long) mapoffset
);
950 assert(kr
== kIOReturnSuccess
);
952 vm_deallocate(kernel_map
, data
[0], bsize
);
953 // vm_deallocate(kernel_map, data[1], size);
955 IOLog("IOMemoryDescriptorTest/ %d\n", (int) gIOMemoryReferenceCount
);
960 #endif /* DEVELOPMENT || DEBUG */