1c1dac77fSApple OSS Distributions /* 2855239e5SApple OSS Distributions * Copyright (c) 1998-2010 Apple Inc. All rights reserved. 3c1dac77fSApple OSS Distributions * 4e13b1fa5SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5c1dac77fSApple OSS Distributions * 6e13b1fa5SApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code 7e13b1fa5SApple OSS Distributions * as defined in and that are subject to the Apple Public Source License 8e13b1fa5SApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in 9e13b1fa5SApple OSS Distributions * compliance with the License. The rights granted to you under the License 10e13b1fa5SApple OSS Distributions * may not be used to create, or enable the creation or redistribution of, 11e13b1fa5SApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to 12e13b1fa5SApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any 13e13b1fa5SApple OSS Distributions * terms of an Apple operating system software license agreement. 14c1dac77fSApple OSS Distributions * 15e13b1fa5SApple OSS Distributions * Please obtain a copy of the License at 16e13b1fa5SApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file. 17e13b1fa5SApple OSS Distributions * 18e13b1fa5SApple OSS Distributions * The Original Code and all software distributed under the License are 19e13b1fa5SApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20c1dac77fSApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21c1dac77fSApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22e13b1fa5SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23e13b1fa5SApple OSS Distributions * Please see the License for the specific language governing rights and 24e13b1fa5SApple OSS Distributions * limitations under the License. 25c1dac77fSApple OSS Distributions * 26e13b1fa5SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27c1dac77fSApple OSS Distributions */ 28c1dac77fSApple OSS Distributions 29c1dac77fSApple OSS Distributions #include <libkern/c++/OSUnserialize.h> 303ca3bd55SApple OSS Distributions #include <libkern/c++/OSKext.h> 31*bb611c8fSApple OSS Distributions #include <libkern/section_keywords.h> 3214e3d835SApple OSS Distributions #include <libkern/version.h> 33c1dac77fSApple OSS Distributions #include <IOKit/IORegistryEntry.h> 34c1dac77fSApple OSS Distributions #include <IOKit/IODeviceTreeSupport.h> 35c1dac77fSApple OSS Distributions #include <IOKit/IOCatalogue.h> 36c1dac77fSApple OSS Distributions #include <IOKit/IOUserClient.h> 37c1dac77fSApple OSS Distributions #include <IOKit/IOMemoryDescriptor.h> 38c1dac77fSApple OSS Distributions #include <IOKit/IOPlatformExpert.h> 39*bb611c8fSApple OSS Distributions #include <IOKit/IOKernelReporters.h> 40c1dac77fSApple OSS Distributions #include <IOKit/IOLib.h> 41c1dac77fSApple OSS Distributions #include <IOKit/IOKitKeys.h> 42c1dac77fSApple OSS Distributions #include <IOKit/IOKitDebug.h> 43855239e5SApple OSS Distributions #include <IOKit/pwr_mgt/RootDomain.h> 44e13b1fa5SApple OSS Distributions #include <IOKit/pwr_mgt/IOPMinformeeList.h> 45855239e5SApple OSS Distributions #include <IOKit/IOStatisticsPrivate.h> 46855239e5SApple OSS Distributions #include <IOKit/IOKitKeysPrivate.h> 47a3bb9fccSApple OSS Distributions #include <IOKit/IOInterruptAccountingPrivate.h> 48c1dac77fSApple OSS Distributions #include <IOKit/assert.h> 4988cc0b97SApple OSS Distributions #include <sys/conf.h> 50c1dac77fSApple OSS Distributions 5114e3d835SApple OSS Distributions #include "IOKitKernelInternal.h" 5214e3d835SApple OSS Distributions 53a3bb9fccSApple OSS Distributions const OSSymbol * gIOProgressBackbufferKey; 54a3bb9fccSApple OSS Distributions OSSet * gIORemoveOnReadProperties; 55a3bb9fccSApple OSS Distributions 56c1dac77fSApple OSS Distributions extern "C" { 57*bb611c8fSApple OSS Distributions void InitIOKit(void *dtTop); 58*bb611c8fSApple OSS Distributions void ConfigureIOKit(void); 59*bb611c8fSApple OSS Distributions void StartIOKitMatching(void); 6088cc0b97SApple OSS Distributions void IORegistrySetOSBuildVersion(char * build_version); 6188cc0b97SApple OSS Distributions void IORecordProgressBackbuffer(void * buffer, size_t size, uint32_t theme); 6288cc0b97SApple OSS Distributions 63c1dac77fSApple OSS Distributions extern void OSlibkernInit(void); 643ca3bd55SApple OSS Distributions 65186b8fceSApple OSS Distributions void iokit_post_constructor_init(void); 66c1dac77fSApple OSS Distributions 67*bb611c8fSApple OSS Distributions SECURITY_READ_ONLY_LATE(static IOPlatformExpertDevice*) gRootNub; 68*bb611c8fSApple OSS Distributions 69c1dac77fSApple OSS Distributions #include <kern/clock.h> 70e13b1fa5SApple OSS Distributions #include <sys/time.h> 71c1dac77fSApple OSS Distributions 72a5e72196SApple OSS Distributions void 73a5e72196SApple OSS Distributions IOKitInitializeTime( void ) 74c1dac77fSApple OSS Distributions { 75c1dac77fSApple OSS Distributions mach_timespec_t t; 76c1dac77fSApple OSS Distributions 77c1dac77fSApple OSS Distributions t.tv_sec = 30; 78c1dac77fSApple OSS Distributions t.tv_nsec = 0; 79a5e72196SApple OSS Distributions 80a5e72196SApple OSS Distributions // RTC is not present on this target 81a5e72196SApple OSS Distributions #ifndef BCM2837 82c1dac77fSApple OSS Distributions IOService::waitForService( 83c1dac77fSApple OSS Distributions IOService::resourceMatching("IORTC"), &t ); 84a5e72196SApple OSS Distributions #endif 85855239e5SApple OSS Distributions #if defined(__i386__) || defined(__x86_64__) 86c1dac77fSApple OSS Distributions IOService::waitForService( 87c1dac77fSApple OSS Distributions IOService::resourceMatching("IONVRAM"), &t ); 88c1dac77fSApple OSS Distributions #endif 89c1dac77fSApple OSS Distributions 90c1dac77fSApple OSS Distributions clock_initialize_calendar(); 91c1dac77fSApple OSS Distributions } 92c1dac77fSApple OSS Distributions 93a5e72196SApple OSS Distributions void 94a5e72196SApple OSS Distributions iokit_post_constructor_init(void) 95c1dac77fSApple OSS Distributions { 96c1dac77fSApple OSS Distributions IORegistryEntry * root; 97c1dac77fSApple OSS Distributions OSObject * obj; 98c1dac77fSApple OSS Distributions 990f3703acSApple OSS Distributions IOCPUInitialize(); 100*bb611c8fSApple OSS Distributions IOPlatformActionsInitialize(); 101c1dac77fSApple OSS Distributions root = IORegistryEntry::initialize(); 102c1dac77fSApple OSS Distributions assert( root ); 103c1dac77fSApple OSS Distributions IOService::initialize(); 104c1dac77fSApple OSS Distributions IOCatalogue::initialize(); 105855239e5SApple OSS Distributions IOStatistics::initialize(); 106855239e5SApple OSS Distributions OSKext::initialize(); 107c1dac77fSApple OSS Distributions IOUserClient::initialize(); 108c1dac77fSApple OSS Distributions IOMemoryDescriptor::initialize(); 109855239e5SApple OSS Distributions IORootParent::initialize(); 110*bb611c8fSApple OSS Distributions IOReporter::initialize(); 111c1dac77fSApple OSS Distributions 112e13b1fa5SApple OSS Distributions // Initializes IOPMinformeeList class-wide shared lock 113e13b1fa5SApple OSS Distributions IOPMinformeeList::getSharedRecursiveLock(); 114e13b1fa5SApple OSS Distributions 11514e3d835SApple OSS Distributions obj = OSString::withCString( version ); 116c1dac77fSApple OSS Distributions assert( obj ); 117c1dac77fSApple OSS Distributions if (obj) { 118c1dac77fSApple OSS Distributions root->setProperty( kIOKitBuildVersionKey, obj ); 119c1dac77fSApple OSS Distributions obj->release(); 120c1dac77fSApple OSS Distributions } 121c1dac77fSApple OSS Distributions obj = IOKitDiagnostics::diagnostics(); 122c1dac77fSApple OSS Distributions if (obj) { 123c1dac77fSApple OSS Distributions root->setProperty( kIOKitDiagnosticsKey, obj ); 124c1dac77fSApple OSS Distributions obj->release(); 125c1dac77fSApple OSS Distributions } 1263ca3bd55SApple OSS Distributions } 1273ca3bd55SApple OSS Distributions 1283ca3bd55SApple OSS Distributions /***** 1293ca3bd55SApple OSS Distributions * Pointer into bootstrap KLD segment for functions never used past startup. 1303ca3bd55SApple OSS Distributions */ 131a5e72196SApple OSS Distributions void (*record_startup_extensions_function)(void) = NULL; 1323ca3bd55SApple OSS Distributions 133a5e72196SApple OSS Distributions void 134*bb611c8fSApple OSS Distributions InitIOKit(void *dtTop) 1353ca3bd55SApple OSS Distributions { 136*bb611c8fSApple OSS Distributions int debugFlags = 0; 1373ca3bd55SApple OSS Distributions 138a5e72196SApple OSS Distributions if (PE_parse_boot_argn( "io", &debugFlags, sizeof(debugFlags))) { 1393ca3bd55SApple OSS Distributions gIOKitDebug = debugFlags; 140a5e72196SApple OSS Distributions } 141*bb611c8fSApple OSS Distributions // Enable IOWaitQuiet panics on arm64 macOS except on KASAN. 142*bb611c8fSApple OSS Distributions // existing 3rd party KEXTs may hold the registry busy on x86 RELEASE kernels. 143*bb611c8fSApple OSS Distributions // Enabling this on other platforms is tracked in rdar://66364108 144*bb611c8fSApple OSS Distributions #if XNU_TARGET_OS_OSX && defined(__arm64__) && !KASAN 145a5e72196SApple OSS Distributions else { 146a5e72196SApple OSS Distributions gIOKitDebug |= kIOWaitQuietPanics; 147a5e72196SApple OSS Distributions } 148*bb611c8fSApple OSS Distributions #endif 1493ca3bd55SApple OSS Distributions 150a5e72196SApple OSS Distributions if (PE_parse_boot_argn( "iotrace", &debugFlags, sizeof(debugFlags))) { 151855239e5SApple OSS Distributions gIOKitTrace = debugFlags; 152a5e72196SApple OSS Distributions } 153855239e5SApple OSS Distributions 154855239e5SApple OSS Distributions // Compat for boot-args 155855239e5SApple OSS Distributions gIOKitTrace |= (gIOKitDebug & kIOTraceCompatBootArgs); 156855239e5SApple OSS Distributions 157a5e72196SApple OSS Distributions if (PE_parse_boot_argn( "pmtimeout", &debugFlags, sizeof(debugFlags))) { 1580f3703acSApple OSS Distributions gCanSleepTimeout = debugFlags; 159a5e72196SApple OSS Distributions } 160a5e72196SApple OSS Distributions 161a5e72196SApple OSS Distributions if (PE_parse_boot_argn( "dk", &debugFlags, sizeof(debugFlags))) { 162a5e72196SApple OSS Distributions gIODKDebug = debugFlags; 163a5e72196SApple OSS Distributions } 164a5e72196SApple OSS Distributions 165a5e72196SApple OSS Distributions 1663ca3bd55SApple OSS Distributions // 1673ca3bd55SApple OSS Distributions // Have to start IOKit environment before we attempt to start 1683ca3bd55SApple OSS Distributions // the C++ runtime environment. At some stage we have to clean up 1693ca3bd55SApple OSS Distributions // the initialisation path so that OS C++ can initialise independantly 1703ca3bd55SApple OSS Distributions // of iokit basic service initialisation, or better we have IOLib stuff 1713ca3bd55SApple OSS Distributions // initialise as basic OS services. 1723ca3bd55SApple OSS Distributions // 1733ca3bd55SApple OSS Distributions IOLibInit(); 1743ca3bd55SApple OSS Distributions OSlibkernInit(); 175a5e72196SApple OSS Distributions IOMachPortInitialize(); 17688cc0b97SApple OSS Distributions devsw_init(); 1773ca3bd55SApple OSS Distributions 178a3bb9fccSApple OSS Distributions gIOProgressBackbufferKey = OSSymbol::withCStringNoCopy(kIOProgressBackbufferKey); 179a3bb9fccSApple OSS Distributions gIORemoveOnReadProperties = OSSet::withObjects((const OSObject **) &gIOProgressBackbufferKey, 1); 180a3bb9fccSApple OSS Distributions 181a3bb9fccSApple OSS Distributions interruptAccountingInit(); 182a3bb9fccSApple OSS Distributions 183*bb611c8fSApple OSS Distributions gRootNub = new IOPlatformExpertDevice; 184*bb611c8fSApple OSS Distributions if (__improbable(gRootNub == NULL)) { 185*bb611c8fSApple OSS Distributions panic("Failed to allocate IOKit root nub"); 186*bb611c8fSApple OSS Distributions } 187*bb611c8fSApple OSS Distributions bool ok = gRootNub->init(dtTop); 188*bb611c8fSApple OSS Distributions if (__improbable(!ok)) { 189*bb611c8fSApple OSS Distributions panic("Failed to initialize IOKit root nub"); 190*bb611c8fSApple OSS Distributions } 191*bb611c8fSApple OSS Distributions gRootNub->attach(NULL); 192c1dac77fSApple OSS Distributions 1933ca3bd55SApple OSS Distributions /* If the bootstrap segment set up a function to record startup 1943ca3bd55SApple OSS Distributions * extensions, call it now. 195c1dac77fSApple OSS Distributions */ 1963ca3bd55SApple OSS Distributions if (record_startup_extensions_function) { 1973ca3bd55SApple OSS Distributions record_startup_extensions_function(); 1983ca3bd55SApple OSS Distributions } 199*bb611c8fSApple OSS Distributions } 200c1dac77fSApple OSS Distributions 201*bb611c8fSApple OSS Distributions void 202*bb611c8fSApple OSS Distributions ConfigureIOKit(void) 203*bb611c8fSApple OSS Distributions { 204*bb611c8fSApple OSS Distributions assert(gRootNub != NULL); 205*bb611c8fSApple OSS Distributions gRootNub->configureDefaults(); 206*bb611c8fSApple OSS Distributions } 207*bb611c8fSApple OSS Distributions 208*bb611c8fSApple OSS Distributions void 209*bb611c8fSApple OSS Distributions StartIOKitMatching(void) 210*bb611c8fSApple OSS Distributions { 211*bb611c8fSApple OSS Distributions assert(gRootNub != NULL); 212*bb611c8fSApple OSS Distributions bool ok = gRootNub->startIOServiceMatching(); 213*bb611c8fSApple OSS Distributions if (__improbable(!ok)) { 214*bb611c8fSApple OSS Distributions panic("Failed to start IOService matching"); 215*bb611c8fSApple OSS Distributions } 216e13b1fa5SApple OSS Distributions 217e13b1fa5SApple OSS Distributions #if !NO_KEXTD 218e13b1fa5SApple OSS Distributions /* Add a busy count to keep the registry busy until kextd has 219e13b1fa5SApple OSS Distributions * completely finished launching. This is decremented when kextd 220e13b1fa5SApple OSS Distributions * messages the kernel after the in-kernel linker has been 221e13b1fa5SApple OSS Distributions * removed and personalities have been sent. 222e13b1fa5SApple OSS Distributions */ 223e13b1fa5SApple OSS Distributions IOService::getServiceRoot()->adjustBusy(1); 224e13b1fa5SApple OSS Distributions #endif 225c1dac77fSApple OSS Distributions } 226c1dac77fSApple OSS Distributions 227e13b1fa5SApple OSS Distributions void 228e13b1fa5SApple OSS Distributions IORegistrySetOSBuildVersion(char * build_version) 229e13b1fa5SApple OSS Distributions { 230e13b1fa5SApple OSS Distributions IORegistryEntry * root = IORegistryEntry::getRegistryRoot(); 231e13b1fa5SApple OSS Distributions 232e13b1fa5SApple OSS Distributions if (root) { 233e13b1fa5SApple OSS Distributions if (build_version) { 234e13b1fa5SApple OSS Distributions root->setProperty(kOSBuildVersionKey, build_version); 235e13b1fa5SApple OSS Distributions } else { 236e13b1fa5SApple OSS Distributions root->removeProperty(kOSBuildVersionKey); 237e13b1fa5SApple OSS Distributions } 238e13b1fa5SApple OSS Distributions } 239e13b1fa5SApple OSS Distributions 240e13b1fa5SApple OSS Distributions return; 241e13b1fa5SApple OSS Distributions } 242e13b1fa5SApple OSS Distributions 243a3bb9fccSApple OSS Distributions void 244a3bb9fccSApple OSS Distributions IORecordProgressBackbuffer(void * buffer, size_t size, uint32_t theme) 245a3bb9fccSApple OSS Distributions { 246a3bb9fccSApple OSS Distributions IORegistryEntry * chosen; 247*bb611c8fSApple OSS Distributions 248*bb611c8fSApple OSS Distributions if (((unsigned int) size) != size) { 249*bb611c8fSApple OSS Distributions return; 250*bb611c8fSApple OSS Distributions } 251a5e72196SApple OSS Distributions if ((chosen = IORegistryEntry::fromPath(kIODeviceTreePlane ":/chosen"))) { 252*bb611c8fSApple OSS Distributions chosen->setProperty(kIOProgressBackbufferKey, buffer, (unsigned int) size); 253a3bb9fccSApple OSS Distributions chosen->setProperty(kIOProgressColorThemeKey, theme, 32); 254a3bb9fccSApple OSS Distributions 255a3bb9fccSApple OSS Distributions chosen->release(); 256a3bb9fccSApple OSS Distributions } 257a3bb9fccSApple OSS Distributions } 258c1dac77fSApple OSS Distributions }; /* extern "C" */ 259