]> git.saurik.com Git - apple/xnu.git/blob - iokit/Tests/Tests.cpp
7e7fe8f1dd50edc3609a2564d0844440b53f783c
[apple/xnu.git] / iokit / Tests / Tests.cpp
1 /*
2 * Copyright (c) 1998-2000 Apple Computer, 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 *
30 */
31
32 #define TEST_HEADERS 0
33
34 #if TEST_HEADERS
35
36 #include <libkern/OSByteOrder.h>
37 #include <libkern/c++/OSArray.h>
38 #include <libkern/c++/OSBoolean.h>
39 #include <libkern/c++/OSCollection.h>
40 #include <libkern/c++/OSCollectionIterator.h>
41 #include <libkern/c++/OSContainers.h>
42 #include <libkern/c++/OSCPPDebug.h>
43 #include <libkern/c++/OSData.h>
44 #include <libkern/c++/OSDictionary.h>
45 #include <libkern/c++/OSEndianTypes.h>
46 #include <libkern/c++/OSIterator.h>
47 #include <libkern/c++/OSKext.h>
48 #include <libkern/c++/OSLib.h>
49 #include <libkern/c++/OSMetaClass.h>
50 #include <libkern/c++/OSNumber.h>
51 #include <libkern/c++/OSObject.h>
52 #include <libkern/c++/OSOrderedSet.h>
53 #include <libkern/c++/OSSerialize.h>
54 #include <libkern/c++/OSSet.h>
55 #include <libkern/c++/OSString.h>
56 #include <libkern/c++/OSSymbol.h>
57 #include <libkern/c++/OSUnserialize.h>
58 #include <libkern/crypto/aes.h>
59 #include <libkern/crypto/aesxts.h>
60 #include <libkern/crypto/crypto_internal.h>
61 #include <libkern/crypto/des.h>
62 #include <libkern/crypto/md5.h>
63 #include <libkern/crypto/register_crypto.h>
64 #include <libkern/crypto/sha1.h>
65 #include <libkern/crypto/sha2.h>
66 #include <libkern/kernel_mach_header.h>
67 #include <libkern/kext_request_keys.h>
68 #include <libkern/kxld.h>
69 #include <libkern/kxld_types.h>
70 #include <libkern/locks.h>
71 #include <libkern/mkext.h>
72 #include <libkern/OSAtomic.h>
73 #include <libkern/OSBase.h>
74 #include <libkern/OSDebug.h>
75 #include <libkern/OSKextLib.h>
76 #include <libkern/OSKextLibPrivate.h>
77 #include <libkern/OSMalloc.h>
78 #include <libkern/OSReturn.h>
79 #include <libkern/OSSerializeBinary.h>
80 #include <libkern/OSTypes.h>
81 #include <libkern/prelink.h>
82 #include <libkern/stack_protector.h>
83 #include <libkern/sysctl.h>
84 #include <libkern/tree.h>
85 #include <libkern/zconf.h>
86 #include <libkern/zlib.h>
87
88 #include <IOKit/AppleKeyStoreInterface.h>
89 #include <IOKit/assert.h>
90 #include <IOKit/IOBSD.h>
91 #include <IOKit/IOBufferMemoryDescriptor.h>
92 #include <IOKit/IOCatalogue.h>
93 #include <IOKit/IOCommand.h>
94 #include <IOKit/IOCommandGate.h>
95 #include <IOKit/IOCommandPool.h>
96 #include <IOKit/IOCommandQueue.h>
97 #include <IOKit/IOConditionLock.h>
98 #include <IOKit/IOCPU.h>
99 //#include <IOKit/IODataQueue.h>
100 #include <IOKit/IODataQueueShared.h>
101 #include <IOKit/IODeviceMemory.h>
102 #include <IOKit/IODeviceTreeSupport.h>
103 #include <IOKit/IODMACommand.h>
104 #include <IOKit/IODMAController.h>
105 #include <IOKit/IODMAEventSource.h>
106 #include <IOKit/IOEventSource.h>
107 #include <IOKit/IOFilterInterruptEventSource.h>
108 #include <IOKit/IOHibernatePrivate.h>
109 #include <IOKit/IOInterleavedMemoryDescriptor.h>
110 #include <IOKit/IOInterruptAccounting.h>
111 #include <IOKit/IOInterruptAccountingPrivate.h>
112 #include <IOKit/IOInterruptController.h>
113 #include <IOKit/IOInterruptEventSource.h>
114 #include <IOKit/IOInterrupts.h>
115 #include <IOKit/IOKernelReporters.h>
116 #include <IOKit/IOKernelReportStructs.h>
117 #include <IOKit/IOKitDebug.h>
118 #include <IOKit/IOKitDiagnosticsUserClient.h>
119 #include <IOKit/IOKitKeys.h>
120 #include <IOKit/IOKitKeysPrivate.h>
121 #include <IOKit/IOKitServer.h>
122 #include <IOKit/IOLib.h>
123 #include <IOKit/IOLocks.h>
124 #include <IOKit/IOLocksPrivate.h>
125 #include <IOKit/IOMapper.h>
126 #include <IOKit/IOMemoryCursor.h>
127 #include <IOKit/IOMemoryDescriptor.h>
128 #include <IOKit/IOMessage.h>
129 #include <IOKit/IOMultiMemoryDescriptor.h>
130 #include <IOKit/IONotifier.h>
131 #include <IOKit/IONVRAM.h>
132 #include <IOKit/IOPlatformExpert.h>
133 #include <IOKit/IOPolledInterface.h>
134 #include <IOKit/IORangeAllocator.h>
135 #include <IOKit/IORegistryEntry.h>
136 #include <IOKit/IOReportMacros.h>
137 #include <IOKit/IOReportTypes.h>
138 #include <IOKit/IOReturn.h>
139 #include <IOKit/IOService.h>
140 #include <IOKit/IOServicePM.h>
141 #include <IOKit/IOSharedDataQueue.h>
142 #include <IOKit/IOSharedLock.h>
143 #include <IOKit/IOStatistics.h>
144 #include <IOKit/IOStatisticsPrivate.h>
145 #include <IOKit/IOSubMemoryDescriptor.h>
146 #include <IOKit/IOSyncer.h>
147 #include <IOKit/IOTimerEventSource.h>
148 #include <IOKit/IOTimeStamp.h>
149 #include <IOKit/IOTypes.h>
150 #include <IOKit/IOUserClient.h>
151 #include <IOKit/IOWorkLoop.h>
152 #include <IOKit/nvram/IONVRAMController.h>
153 #include <IOKit/OSMessageNotification.h>
154 #include <IOKit/platform/AppleMacIO.h>
155 #include <IOKit/platform/AppleMacIODevice.h>
156 #include <IOKit/platform/AppleNMI.h>
157 #include <IOKit/platform/ApplePlatformExpert.h>
158 #include <IOKit/power/IOPwrController.h>
159 #include <IOKit/pwr_mgt/IOPM.h>
160 #include <IOKit/pwr_mgt/IOPMinformee.h>
161 #include <IOKit/pwr_mgt/IOPMinformeeList.h>
162 #include <IOKit/pwr_mgt/IOPMLibDefs.h>
163 #include <IOKit/pwr_mgt/IOPMlog.h>
164 #include <IOKit/pwr_mgt/IOPMPowerSource.h>
165 #include <IOKit/pwr_mgt/IOPMPowerSourceList.h>
166 #include <IOKit/pwr_mgt/IOPMpowerState.h>
167 #include <IOKit/pwr_mgt/IOPMPrivate.h>
168 #include <IOKit/pwr_mgt/IOPowerConnection.h>
169 #include <IOKit/pwr_mgt/RootDomain.h>
170 #include <IOKit/rtc/IORTCController.h>
171 #include <IOKit/system.h>
172 #include <IOKit/system_management/IOWatchDogTimer.h>
173
174 #endif /* TEST_HEADERS */
175
176 #include <sys/sysctl.h>
177 #include <libkern/c++/OSData.h>
178 #include "Tests.h"
179
180
181 #if DEVELOPMENT || DEBUG
182
183 #include <IOKit/IOWorkLoop.h>
184 #include <IOKit/IOTimerEventSource.h>
185 #include <IOKit/IOInterruptEventSource.h>
186 #include <IOKit/IOCommandGate.h>
187 #include <IOKit/IOPlatformExpert.h>
188 #include <libkern/Block.h>
189 #include <libkern/Block_private.h>
190
191 static uint64_t gIOWorkLoopTestDeadline;
192
193 static void
194 TESAction(OSObject * owner, IOTimerEventSource * tes)
195 {
196 if (mach_absolute_time() < gIOWorkLoopTestDeadline) {
197 tes->setTimeout(1, kMicrosecondScale);
198 }
199 }
200
201 static int
202 IOWorkLoopTest(int newValue)
203 {
204 IOReturn err;
205 uint32_t idx;
206 IOWorkLoop * wl;
207 IOTimerEventSource * tes;
208 IOInterruptEventSource * ies;
209
210 wl = IOWorkLoop::workLoop();
211 assert(wl);
212 tes = IOTimerEventSource::timerEventSource(kIOTimerEventSourceOptionsPriorityWorkLoop, wl, &TESAction);
213 assert(tes);
214 err = wl->addEventSource(tes);
215 assert(kIOReturnSuccess == err);
216 clock_interval_to_deadline(100, kMillisecondScale, &gIOWorkLoopTestDeadline);
217 for (idx = 0; mach_absolute_time() < gIOWorkLoopTestDeadline; idx++) {
218 tes->setTimeout(idx & 1023, kNanosecondScale);
219 }
220 tes->cancelTimeout();
221 wl->removeEventSource(tes);
222 tes->release();
223
224 int value = 3;
225
226 tes = IOTimerEventSource::timerEventSource(kIOTimerEventSourceOptionsDefault, wl, ^(IOTimerEventSource * tes){
227 kprintf("wl %p, value %d\n", wl, value);
228 });
229 err = wl->addEventSource(tes);
230 assert(kIOReturnSuccess == err);
231
232 value = 2;
233 tes->setTimeout(1, kNanosecondScale);
234 IOSleep(1);
235 wl->removeEventSource(tes);
236 tes->release();
237
238 ies = IOInterruptEventSource::interruptEventSource(wl, NULL, 0, ^void (IOInterruptEventSource *sender, int count){
239 kprintf("ies block %p, %d\n", sender, count);
240 });
241
242 assert(ies);
243 kprintf("ies %p\n", ies);
244 err = wl->addEventSource(ies);
245 assert(kIOReturnSuccess == err);
246 ies->interruptOccurred(NULL, NULL, 0);
247 IOSleep(1);
248 ies->interruptOccurred(NULL, NULL, 0);
249 IOSleep(1);
250 wl->removeEventSource(ies);
251 ies->release();
252
253 wl->release();
254
255 return 0;
256 }
257
258 static int
259 OSCollectionTest(int newValue)
260 {
261 OSArray * array = OSArray::withCapacity(8);
262 array->setObject(kOSBooleanTrue);
263 array->setObject(kOSBooleanFalse);
264 array->setObject(kOSBooleanFalse);
265 array->setObject(kOSBooleanTrue);
266 array->setObject(kOSBooleanFalse);
267 array->setObject(kOSBooleanTrue);
268
269 __block unsigned int index;
270 index = 0;
271 array->iterateObjects(^bool (OSObject * obj) {
272 kprintf("%d:%d ", index, (obj == kOSBooleanTrue) ? 1 : (obj == kOSBooleanFalse) ? 0 : 2);
273 index++;
274 return false;
275 });
276 kprintf("\n");
277 array->release();
278
279 OSDictionary * dict = IOService::resourceMatching("hello");
280 assert(dict);
281 index = 0;
282 dict->iterateObjects(^bool (const OSSymbol * sym, OSObject * obj) {
283 OSString * str = OSDynamicCast(OSString, obj);
284 assert(str);
285 kprintf("%d:%s=%s\n", index, sym->getCStringNoCopy(), str->getCStringNoCopy());
286 index++;
287 return false;
288 });
289 dict->release();
290
291 OSSerializer * serializer = OSSerializer::withBlock(^bool (OSSerialize * s){
292 return gIOBSDUnitKey->serialize(s);
293 });
294 assert(serializer);
295 IOService::getPlatform()->setProperty("OSSerializer_withBlock", serializer);
296 serializer->release();
297
298 return 0;
299 }
300
301 #if 0
302 #include <IOKit/IOUserClient.h>
303 class TestUserClient : public IOUserClient
304 {
305 OSDeclareDefaultStructors(TestUserClient);
306 virtual void stop( IOService *provider) APPLE_KEXT_OVERRIDE;
307 virtual bool finalize(IOOptionBits options) APPLE_KEXT_OVERRIDE;
308 virtual IOReturn externalMethod( uint32_t selector,
309 IOExternalMethodArguments * arguments,
310 IOExternalMethodDispatch * dispatch,
311 OSObject * target,
312 void * reference ) APPLE_KEXT_OVERRIDE;
313 };
314
315 void
316 TestUserClient::stop( IOService *provider)
317 {
318 kprintf("TestUserClient::stop\n");
319 }
320 bool
321 TestUserClient::finalize(IOOptionBits options)
322 {
323 kprintf("TestUserClient::finalize\n");
324 return true;
325 }
326 IOReturn
327 TestUserClient::externalMethod( uint32_t selector,
328 IOExternalMethodArguments * arguments,
329 IOExternalMethodDispatch * dispatch,
330 OSObject * target,
331 void * reference )
332 {
333 getProvider()->terminate();
334 IOSleep(500);
335 return 0;
336 }
337 OSDefineMetaClassAndStructors(TestUserClient, IOUserClient);
338 #endif
339
340 static int
341 IOServiceTest(int newValue)
342 {
343 OSDictionary * matching;
344 IONotifier * note;
345 __block IOService * found;
346
347 #if 0
348 found = new IOService;
349 found->init();
350 found->setName("IOTestUserClientProvider");
351 found->attach(IOService::getPlatform());
352 found->setProperty("IOUserClientClass", "TestUserClient");
353 found->registerService();
354 #endif
355
356 matching = IOService::serviceMatching("IOPlatformExpert");
357 assert(matching);
358 found = nullptr;
359 note = IOService::addMatchingNotification(gIOMatchedNotification, matching, 0,
360 ^bool (IOService * newService, IONotifier * notifier) {
361 kprintf("found %s, %d\n", newService->getName(), newService->getRetainCount());
362 found = newService;
363 found->retain();
364 return true;
365 }
366 );
367 assert(note);
368 assert(found);
369 matching->release();
370 note->remove();
371
372 note = found->registerInterest(gIOBusyInterest,
373 ^IOReturn (uint32_t messageType, IOService * provider,
374 void * messageArgument, size_t argSize) {
375 kprintf("%p messageType 0x%08x %p\n", provider, messageType, messageArgument);
376 return kIOReturnSuccess;
377 });
378 assert(note);
379 IOSleep(1 * 1000);
380 note->remove();
381 found->release();
382
383 return 0;
384 }
385
386 #endif /* DEVELOPMENT || DEBUG */
387
388 static int
389 sysctl_iokittest(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
390 {
391 int error;
392 int newValue, changed;
393
394 error = sysctl_io_number(req, 0, sizeof(int), &newValue, &changed);
395 if (error) {
396 return error;
397 }
398
399 #if DEVELOPMENT || DEBUG
400 if (changed && (66 == newValue)) {
401 IOReturn ret;
402 IOWorkLoop * wl = IOWorkLoop::workLoop();
403 IOCommandGate * cg = IOCommandGate::commandGate(wl);
404 ret = wl->addEventSource(cg);
405
406 struct x {
407 uint64_t h;
408 uint64_t l;
409 };
410 struct x y;
411
412 y.h = 0x1111111122222222;
413 y.l = 0x3333333344444444;
414
415 kprintf("ret1 %d\n", ret);
416 ret = cg->runActionBlock(^(){
417 printf("hello %d 0x%qx\n", wl->inGate(), y.h);
418 return 99;
419 });
420 kprintf("ret %d\n", ret);
421 }
422
423 if (changed && (999 == newValue)) {
424 OSData * data = OSData::withCapacity(16);
425 data->release();
426 data->release();
427 }
428
429
430 if (changed && newValue) {
431 error = IOWorkLoopTest(newValue);
432 assert(KERN_SUCCESS == error);
433 error = IOServiceTest(newValue);
434 assert(KERN_SUCCESS == error);
435 error = OSCollectionTest(newValue);
436 assert(KERN_SUCCESS == error);
437 error = IOMemoryDescriptorTest(newValue);
438 assert(KERN_SUCCESS == error);
439 }
440 #endif /* DEVELOPMENT || DEBUG */
441
442 return error;
443 }
444
445 SYSCTL_PROC(_kern, OID_AUTO, iokittest,
446 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NOAUTO | CTLFLAG_KERN | CTLFLAG_LOCKED,
447 0, 0, sysctl_iokittest, "I", "");