1 /* 2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * The contents of this file constitute Original Code as defined in and 7 * are subject to the Apple Public Source License Version 1.1 (the 8 * "License"). You may not use this file except in compliance with the 9 * License. Please obtain a copy of the License at 10 * http://www.apple.com/publicsource and read it before using this file. 11 * 12 * This Original Code and all software distributed under the License are 13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 * License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * @APPLE_LICENSE_HEADER_END@ 21 */ 22 /* 23 * Copyright (c) 1998,1999 Apple Computer, Inc. All rights reserved. 24 * 25 * HISTORY 26 * 27 */ 28 29 #include <libkern/c++/OSUnserialize.h> 30 #include <IOKit/IORegistryEntry.h> 31 #include <IOKit/IODeviceTreeSupport.h> 32 #include <IOKit/IOCatalogue.h> 33 #include <IOKit/IOUserClient.h> 34 #include <IOKit/IOMemoryDescriptor.h> 35 #include <IOKit/IOPlatformExpert.h> 36 #include <IOKit/IOLib.h> 37 #include <IOKit/IOKitKeys.h> 38 #include <IOKit/IOKitDebug.h> 39 40 #include <IOKit/assert.h> 41 42 extern "C" { 43 44 extern void OSlibkernInit (void); 45 extern void IOLibInit(void); 46 47 #include <kern/clock.h> 48 49 /*XXX power management hacks XXX*/ 50 #include <IOKit/IOReturn.h> 51 #include <IOKit/IOMessage.h> 52 53 extern void *registerSleepWakeInterest( 54 void *callback, 55 void *target, 56 void *refCon); 57 /*XXX power management hacks XXX*/ 58 59 static void 60 calend_wakeup_resynch( 61 thread_call_param_t p0, 62 thread_call_param_t p1) 63 { 64 void IOKitResetTime(void); 65 66 IOKitResetTime(); 67 } 68 69 static thread_call_t calend_sleep_wake_call; 70 71 static IOReturn 72 calend_sleep_wake_notif( 73 void *target, 74 void *refCon, 75 unsigned int messageType, 76 void *provider, 77 void *messageArg, 78 vm_size_t argSize) 79 { 80 if (messageType != kIOMessageSystemHasPoweredOn) 81 return (kIOReturnUnsupported); 82 83 if (calend_sleep_wake_call != NULL) 84 thread_call_enter(calend_sleep_wake_call); 85 86 return (kIOReturnSuccess); 87 } 88 89 void IOKitResetTime( void ) 90 { 91 mach_timespec_t t; 92 93 t.tv_sec = 30; 94 t.tv_nsec = 0; 95 IOService::waitForService( 96 IOService::resourceMatching("IORTC"), &t ); 97 #ifndef i386 98 IOService::waitForService( 99 IOService::resourceMatching("IONVRAM"), &t ); 100 #endif 101 102 if (calend_sleep_wake_call == NULL) { 103 calend_sleep_wake_call = thread_call_allocate( 104 calend_wakeup_resynch, NULL); 105 106 registerSleepWakeInterest(calend_sleep_wake_notif, NULL, NULL); 107 } 108 109 clock_initialize_calendar(); 110 } 111 112 113 void StartIOKit( void * p1, void * p2, void * p3, void * p4 ) 114 { 115 IOPlatformExpertDevice * rootNub; 116 int debugFlags; 117 IORegistryEntry * root; 118 OSObject * obj; 119 extern const char * gIOKernelKmods; 120 OSString * errorString = NULL; // must release 121 OSDictionary * fakeKmods; // must release 122 OSCollectionIterator * kmodIter; // must release 123 OSString * kmodName; // don't release 124 125 IOLog( iokit_version ); 126 127 if( PE_parse_boot_arg( "io", &debugFlags )) 128 gIOKitDebug = debugFlags; 129 // 130 // Have to start IOKit environment before we attempt to start 131 // the C++ runtime environment. At some stage we have to clean up 132 // the initialisation path so that OS C++ can initialise independantly 133 // of iokit basic service initialisation, or better we have IOLib stuff 134 // initialise as basic OS services. 135 // 136 IOLibInit(); 137 OSlibkernInit(); 138 139 IOLog("_cppInit done\n"); 140 141 142 /***** 143 * Declare the fake kmod_info structs for built-in components 144 * that must be tracked as independent units for dependencies. 145 */ 146 fakeKmods = OSDynamicCast(OSDictionary, 147 OSUnserialize(gIOKernelKmods, &errorString)); 148 149 if (!fakeKmods) { 150 if (errorString) { 151 panic("Kernel kmod list syntax error: %s\n", 152 errorString->getCStringNoCopy()); 153 errorString->release(); 154 } else { 155 panic("Error loading kernel kmod list.\n"); 156 } 157 } 158 159 kmodIter = OSCollectionIterator::withCollection(fakeKmods); 160 if (!kmodIter) { 161 panic("Can't declare in-kernel kmods.\n"); 162 } 163 while ((kmodName = OSDynamicCast(OSString, kmodIter->getNextObject()))) { 164 165 OSString * kmodVersion = OSDynamicCast(OSString, 166 fakeKmods->getObject(kmodName)); 167 if (!kmodVersion) { 168 panic("Can't declare in-kernel kmod; \"%s\" has " 169 "an invalid version.\n", 170 kmodName->getCStringNoCopy()); 171 } 172 if (KERN_SUCCESS != kmod_create_fake(kmodName->getCStringNoCopy(), 173 kmodVersion->getCStringNoCopy())) { 174 panic("Failure declaring in-kernel kmod \"%s\".\n", 175 kmodName->getCStringNoCopy()); 176 } 177 } 178 179 kmodIter->release(); 180 fakeKmods->release(); 181 182 183 184 root = IORegistryEntry::initialize(); 185 assert( root ); 186 IOService::initialize(); 187 IOCatalogue::initialize(); 188 IOUserClient::initialize(); 189 IOMemoryDescriptor::initialize(); 190 191 obj = OSString::withCString( iokit_version ); 192 assert( obj ); 193 if( obj ) { 194 root->setProperty( kIOKitBuildVersionKey, obj ); 195 obj->release(); 196 } 197 obj = IOKitDiagnostics::diagnostics(); 198 if( obj ) { 199 root->setProperty( kIOKitDiagnosticsKey, obj ); 200 obj->release(); 201 } 202 203 rootNub = new IOPlatformExpertDevice; 204 205 if( rootNub && rootNub->initWithArgs( p1, p2, p3, p4)) { 206 rootNub->attach( 0 ); 207 208 /* Enter into the catalogue the drivers 209 * provided by BootX. 210 */ 211 gIOCatalogue->recordStartupExtensions(); 212 213 rootNub->registerService(); 214 } 215 } 216 217 }; /* extern "C" */ 218