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
191static uint64_t gIOWorkLoopTestDeadline;
192
193static void
194TESAction(OSObject * owner, IOTimerEventSource * tes)
195{
196 if (mach_absolute_time() < gIOWorkLoopTestDeadline) tes->setTimeout(1, kMicrosecondScale);
197}
198
199static int
200IOWorkLoopTest(int newValue)
201{
202 IOReturn err;
203 uint32_t idx;
204 IOWorkLoop * wl;
205 IOTimerEventSource * tes;
206 IOInterruptEventSource * ies;
207
208 wl = IOWorkLoop::workLoop();
209 assert(wl);
210 tes = IOTimerEventSource::timerEventSource(kIOTimerEventSourceOptionsPriorityWorkLoop, wl, &TESAction);
211 assert(tes);
212 err = wl->addEventSource(tes);
213 assert(kIOReturnSuccess == err);
214 clock_interval_to_deadline(100, kMillisecondScale, &gIOWorkLoopTestDeadline);
215 for (idx = 0; mach_absolute_time() < gIOWorkLoopTestDeadline; idx++)
216 {
217 tes->setTimeout(idx & 1023, kNanosecondScale);
218 }
219 tes->cancelTimeout();
220 wl->removeEventSource(tes);
221 tes->release();
222
223 int value = 3;
224
225 tes = IOTimerEventSource::timerEventSource(kIOTimerEventSourceOptionsDefault, wl, ^(IOTimerEventSource * tes){
226 kprintf("wl %p, value %d\n", wl, value);
227 });
228 err = wl->addEventSource(tes);
229 assert(kIOReturnSuccess == err);
230
231 value = 2;
232 tes->setTimeout(1, kNanosecondScale);
233 IOSleep(1);
234 wl->removeEventSource(tes);
235 tes->release();
236
237 ies = IOInterruptEventSource::interruptEventSource(wl, NULL, 0, ^void(IOInterruptEventSource *sender, int count){
238 kprintf("ies block %p, %d\n", sender, count);
239 });
240
241 assert(ies);
242 kprintf("ies %p\n", ies);
243 err = wl->addEventSource(ies);
244 assert(kIOReturnSuccess == err);
245 ies->interruptOccurred(NULL, NULL, 0);
246 IOSleep(1);
247 ies->interruptOccurred(NULL, NULL, 0);
248 IOSleep(1);
249 wl->removeEventSource(ies);
250 ies->release();
251
252 wl->release();
253
254 return (0);
255}
256
257static int
258OSCollectionTest(int newValue)
259{
260 OSArray * array = OSArray::withCapacity(8);
261 array->setObject(kOSBooleanTrue);
262 array->setObject(kOSBooleanFalse);
263 array->setObject(kOSBooleanFalse);
264 array->setObject(kOSBooleanTrue);
265 array->setObject(kOSBooleanFalse);
266 array->setObject(kOSBooleanTrue);
267
268 __block unsigned int index;
269 index = 0;
270 array->iterateObjects(^bool(OSObject * obj) {
271 kprintf("%d:%d ", index, (obj == kOSBooleanTrue) ? 1 : (obj == kOSBooleanFalse) ? 0 : 2);
272 index++;
273 return (false);
274 });
275 kprintf("\n");
276 array->release();
277
278 OSDictionary * dict = IOService::resourceMatching("hello");
279 assert(dict);
280 index = 0;
281 dict->iterateObjects(^bool(const OSSymbol * sym, OSObject * obj) {
282 OSString * str = OSDynamicCast(OSString, obj);
283 assert(str);
284 kprintf("%d:%s=%s\n", index, sym->getCStringNoCopy(), str->getCStringNoCopy());
285 index++;
286 return (false);
287 });
288 dict->release();
289
290 OSSerializer * serializer = OSSerializer::withBlock(^bool(OSSerialize * s){
291 return (gIOBSDUnitKey->serialize(s));
292 });
293 assert(serializer);
294 IOService::getPlatform()->setProperty("OSSerializer_withBlock", serializer);
295 serializer->release();
296
297 return (0);
298}
299
300#if 0
301#include <IOKit/IOUserClient.h>
302class TestUserClient : public IOUserClient
303{
304 OSDeclareDefaultStructors(TestUserClient);
305 virtual void stop( IOService *provider) APPLE_KEXT_OVERRIDE;
306 virtual bool finalize(IOOptionBits options) APPLE_KEXT_OVERRIDE;
307 virtual IOReturn externalMethod( uint32_t selector,
308 IOExternalMethodArguments * arguments,
309 IOExternalMethodDispatch * dispatch,
310 OSObject * target,
311 void * reference ) APPLE_KEXT_OVERRIDE;
312};
313
314void TestUserClient::stop( IOService *provider)
315{
316 kprintf("TestUserClient::stop\n");
317}
318bool TestUserClient::finalize(IOOptionBits options)
319{
320 kprintf("TestUserClient::finalize\n");
321 return(true);
322}
323IOReturn TestUserClient::externalMethod( uint32_t selector,
324 IOExternalMethodArguments * arguments,
325 IOExternalMethodDispatch * dispatch,
326 OSObject * target,
327 void * reference )
328{
329 getProvider()->terminate();
330 IOSleep(500);
331 return (0);
332}
333OSDefineMetaClassAndStructors(TestUserClient, IOUserClient);
334#endif
335
336static int
337IOServiceTest(int newValue)
338{
339 OSDictionary * matching;
340 IONotifier * note;
341 __block IOService * found;
342
343#if 0
344 found = new IOService;
345 found->init();
346 found->setName("IOTestUserClientProvider");
347 found->attach(IOService::getPlatform());
348 found->setProperty("IOUserClientClass", "TestUserClient");
349 found->registerService();
350#endif
351
352 matching = IOService::serviceMatching("IOPlatformExpert");
353 assert(matching);
354 found = nullptr;
355 note = IOService::addMatchingNotification(gIOMatchedNotification, matching, 0,
356 ^bool(IOService * newService, IONotifier * notifier) {
357 kprintf("found %s, %d\n", newService->getName(), newService->getRetainCount());
358 found = newService;
359 found->retain();
360 return (true);
361 }
362 );
363 assert(note);
364 assert(found);
365 matching->release();
366 note->remove();
367
368 note = found->registerInterest(gIOBusyInterest,
369 ^IOReturn(uint32_t messageType, IOService * provider,
370 void * messageArgument, size_t argSize) {
371 kprintf("%p messageType 0x%08x %p\n", provider, messageType, messageArgument);
372 return (kIOReturnSuccess);
373 });
374 assert(note);
375 IOSleep(1*1000);
376 note->remove();
377 found->release();
378
379 return (0);
380}
381
382#endif /* DEVELOPMENT || DEBUG */
383
384static int
385sysctl_iokittest(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
386{
387 int error;
388 int newValue, changed;
389
390 error = sysctl_io_number(req, 0, sizeof(int), &newValue, &changed);
391 if (error) return (error);
392
393#if DEVELOPMENT || DEBUG
394 if (changed && (66==newValue))
395 {
396 IOReturn ret;
397 IOWorkLoop * wl = IOWorkLoop::workLoop();
398 IOCommandGate * cg = IOCommandGate::commandGate(wl);
399 ret = wl->addEventSource(cg);
400
401 struct x
402 {
403 uint64_t h;
404 uint64_t l;
405 };
406 struct x y;
407
408 y.h = 0x1111111122222222;
409 y.l = 0x3333333344444444;
410
411 kprintf("ret1 %d\n", ret);
412 ret = cg->runActionBlock(^(){
413 printf("hello %d 0x%qx\n", wl->inGate(), y.h);
414 return 99;
415 });
416 kprintf("ret %d\n", ret);
417 }
418
419 if (changed && (999==newValue))
420 {
421 OSData * data = OSData::withCapacity(16);
422 data->release();
423 data->release();
424 }
425
426
427 if (changed && newValue)
428 {
429 error = IOWorkLoopTest(newValue);
430 assert(KERN_SUCCESS == error);
431 error = IOServiceTest(newValue);
432 assert(KERN_SUCCESS == error);
433 error = OSCollectionTest(newValue);
434 assert(KERN_SUCCESS == error);
435 error = IOMemoryDescriptorTest(newValue);
436 assert(KERN_SUCCESS == error);
437 }
438#endif /* DEVELOPMENT || DEBUG */
439
440 return (error);
441}
442
443SYSCTL_PROC(_kern, OID_AUTO, iokittest,
444 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NOAUTO | CTLFLAG_KERN | CTLFLAG_LOCKED,
445 0, 0, sysctl_iokittest, "I", "");
446
447
448