xref: /xnu-11215/iokit/Kernel/IOStartIOKit.cpp (revision c1dac77f)
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 #include <IOKit/network/IONetworkController.h>
40 #include <IOKit/graphics/IODisplay.h>
41 
42 #include <IOKit/assert.h>
43 
44 extern "C" {
45 
46 extern void OSlibkernInit (void);
47 extern void IOLibInit(void);
48 
49 #include <kern/clock.h>
50 
51 
52 void IOKitResetTime( void )
53 {
54     mach_timespec_t	t;
55 
56     t.tv_sec = 30;
57     t.tv_nsec = 0;
58     IOService::waitForService(
59         IOService::resourceMatching("IORTC"), &t );
60 #ifndef i386
61     IOService::waitForService(
62         IOService::resourceMatching("IONVRAM"), &t );
63 #endif
64 
65     clock_initialize_calendar();
66 }
67 
68 
69 void StartIOKit( void * p1, void * p2, void * p3, void * p4 )
70 {
71     IOPlatformExpertDevice *	rootNub;
72     int				debugFlags;
73     IORegistryEntry *		root;
74     OSObject *			obj;
75     extern const char *         gIOKernelKmods;
76     OSString *                  errorString = NULL; // must release
77     OSDictionary *              fakeKmods;  // must release
78     OSCollectionIterator *      kmodIter;   // must release
79     OSString *                  kmodName;   // don't release
80 
81     IOLog( iokit_version );
82 
83     if( PE_parse_boot_arg( "io", &debugFlags ))
84 	gIOKitDebug = debugFlags;
85     //
86     // Have to start IOKit environment before we attempt to start
87     // the C++ runtime environment.  At some stage we have to clean up
88     // the initialisation path so that OS C++ can initialise independantly
89     // of iokit basic service initialisation, or better we have IOLib stuff
90     // initialise as basic OS services.
91     //
92     IOLibInit();
93     OSlibkernInit();
94 
95     IOLog("_cppInit done\n");
96 
97 
98    /*****
99     * Declare the fake kmod_info structs for built-in components
100     * that must be tracked as independent units for dependencies.
101     */
102     fakeKmods = OSDynamicCast(OSDictionary,
103         OSUnserialize(gIOKernelKmods, &errorString));
104 
105     if (!fakeKmods) {
106         if (errorString) {
107             panic("Kernel kmod list syntax error: %s\n",
108                     errorString->getCStringNoCopy());
109             errorString->release();
110         } else {
111             panic("Error loading kernel kmod list.\n");
112         }
113     }
114 
115     kmodIter = OSCollectionIterator::withCollection(fakeKmods);
116     if (!kmodIter) {
117         panic("Can't declare in-kernel kmods.\n");
118     }
119     while ((kmodName = OSDynamicCast(OSString, kmodIter->getNextObject()))) {
120 
121         OSString * kmodVersion = OSDynamicCast(OSString,
122             fakeKmods->getObject(kmodName));
123         if (!kmodVersion) {
124             panic("Can't declare in-kernel kmod; \"%s\" has "
125                 "an invalid version.\n",
126                 kmodName->getCStringNoCopy());
127         }
128         if (KERN_SUCCESS != kmod_create_fake(kmodName->getCStringNoCopy(),
129                 kmodVersion->getCStringNoCopy())) {
130             panic("Failure declaring in-kernel kmod \"%s\".\n",
131                 kmodName->getCStringNoCopy());
132         }
133     }
134 
135     kmodIter->release();
136     fakeKmods->release();
137 
138 
139 
140     root = IORegistryEntry::initialize();
141     assert( root );
142     IOService::initialize();
143     IOCatalogue::initialize();
144     IOUserClient::initialize();
145     IOMemoryDescriptor::initialize();
146     IONetworkController::initialize();
147     IODisplay::initialize();
148 
149     obj = OSString::withCString( iokit_version );
150     assert( obj );
151     if( obj ) {
152         root->setProperty( kIOKitBuildVersionKey, obj );
153 	obj->release();
154     }
155     obj = IOKitDiagnostics::diagnostics();
156     if( obj ) {
157         root->setProperty( kIOKitDiagnosticsKey, obj );
158 	obj->release();
159     }
160 
161 #ifdef i386
162     // pretend there's no device-tree for intel
163     p1 = 0;
164 #endif
165 
166     rootNub = new IOPlatformExpertDevice;
167 
168     if( rootNub && rootNub->initWithArgs( p1, p2, p3, p4)) {
169         rootNub->attach( 0 );
170 
171        /* Enter into the catalogue the drivers
172         * provided by BootX.
173         */
174         gIOCatalogue->recordStartupExtensions();
175 
176         rootNub->registerService();
177     }
178 }
179 
180 }; /* extern "C" */
181