X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/d7e50217d7adf6e52786a38bcaa4cd698cb9a79e..c0fea4742e91338fffdcf79f86a7c1d5e2b97eb1:/iokit/Kernel/IOPlatformExpert.cpp?ds=sidebyside diff --git a/iokit/Kernel/IOPlatformExpert.cpp b/iokit/Kernel/IOPlatformExpert.cpp index bc3c0e527..6d85f2748 100644 --- a/iokit/Kernel/IOPlatformExpert.cpp +++ b/iokit/Kernel/IOPlatformExpert.cpp @@ -3,22 +3,19 @@ * * @APPLE_LICENSE_HEADER_START@ * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. * * @APPLE_LICENSE_HEADER_END@ */ @@ -36,17 +33,21 @@ #include #include #include +#include +#include #include #include - extern "C" { #include #include } +/* Delay period for UPS halt */ +#define kUPSDelayHaltCPU_msec (1000*60*5) + void printDictionaryKeys (OSDictionary * inDictionary, char * inMsg); static void getCStringForObject (OSObject * inObj, char * outStr); @@ -58,7 +59,7 @@ OSDefineMetaClassAndStructors(IOPlatformExpert, IOService) OSMetaClassDefineReservedUsed(IOPlatformExpert, 0); -OSMetaClassDefineReservedUnused(IOPlatformExpert, 1); +OSMetaClassDefineReservedUsed(IOPlatformExpert, 1); OSMetaClassDefineReservedUnused(IOPlatformExpert, 2); OSMetaClassDefineReservedUnused(IOPlatformExpert, 3); OSMetaClassDefineReservedUnused(IOPlatformExpert, 4); @@ -91,25 +92,17 @@ bool IOPlatformExpert::start( IOService * provider ) { IORangeAllocator * physicalRanges; OSData * busFrequency; + uint32_t debugFlags; if (!super::start(provider)) return false; - + + // Override the mapper present flag is requested by boot arguments. + if (PE_parse_boot_arg("dart", &debugFlags) && (debugFlags == 0)) + removeProperty(kIOPlatformMapperPresentKey); + // Register the presence or lack thereof a system // PCI address mapper with the IOMapper class - -#if 1 - IORegistryEntry * regEntry = IORegistryEntry::fromPath("/u3/dart", gIODTPlane); - if (!regEntry) - regEntry = IORegistryEntry::fromPath("/dart", gIODTPlane); - if (regEntry) { - int debugFlags; - if (!PE_parse_boot_arg("dart", &debugFlags) || debugFlags) - setProperty(kIOPlatformMapperPresentKey, kOSBooleanTrue); - regEntry->release(); - } -#endif - IOMapper::setMapperRequired(0 != getProperty(kIOPlatformMapperPresentKey)); gIOInterruptControllers = OSDictionary::withCapacity(1); @@ -132,6 +125,16 @@ bool IOPlatformExpert::start( IOService * provider ) PMInstantiatePowerDomains(); + // Parse the serial-number data and publish a user-readable string + OSData* mydata = (OSData*) (provider->getProperty("serial-number")); + if (mydata != NULL) { + OSString *serNoString = createSystemSerialNumberString(mydata); + if (serNoString != NULL) { + provider->setProperty(kIOPlatformSerialNumberKey, serNoString); + serNoString->release(); + } + } + return( configure(provider) ); } @@ -175,7 +178,7 @@ IOService * IOPlatformExpert::createNub( OSDictionary * from ) } bool IOPlatformExpert::compareNubName( const IOService * nub, - OSString * name, OSString ** matched) const + OSString * name, OSString ** matched ) const { return( nub->IORegistryEntry::compareName( name, matched )); } @@ -225,6 +228,11 @@ bool IOPlatformExpert::getModelName( char * /*name*/, int /*maxLength*/) return( false ); } +OSString* IOPlatformExpert::createSystemSerialNumberString(OSData* myProperty) +{ + return NULL; +} + IORangeAllocator * IOPlatformExpert::getPhysicalRangeAllocator(void) { return(OSDynamicCast(IORangeAllocator, @@ -236,6 +244,16 @@ int (*PE_halt_restart)(unsigned int type) = 0; int IOPlatformExpert::haltRestart(unsigned int type) { if (type == kPEHangCPU) while (1); + + if (type == kPEUPSDelayHaltCPU) { + // Stall shutdown for 5 minutes, and if no outside force has + // removed our power at that point, proceed with a reboot. + IOSleep( kUPSDelayHaltCPU_msec ); + + // Ideally we never reach this point. + + type = kPERestartCPU; + } if (PE_halt_restart) return (*PE_halt_restart)(type); else return -1; @@ -343,11 +361,44 @@ bool IOPlatformExpert::platformAdjustService(IOService */*service*/) // //********************************************************************************* -void IOPlatformExpert::PMLog(const char * who,unsigned long event,unsigned long param1, unsigned long param2) +void IOPlatformExpert:: +PMLog(const char *who, unsigned long event, + unsigned long param1, unsigned long param2) { - if( gIOKitDebug & kIOLogPower) { - kprintf("%s %02d %08x %08x\n",who,event,param1,param2); -// IOLog("%s %02d %08x %08x\n",who,event,param1,param2); + UInt32 debugFlags = gIOKitDebug; + + if (debugFlags & kIOLogPower) { + + uint32_t nows, nowus; + clock_get_system_microtime(&nows, &nowus); + nowus += (nows % 1000) * 1000000; + + kprintf("pm%u %x %.30s %d %x %x\n", + nowus, (unsigned) current_thread(), who, // Identity + (int) event, param1, param2); // Args + + if (debugFlags & kIOLogTracePower) { + static const UInt32 sStartStopBitField[] = + { 0x00000000, 0x00000040 }; // Only Program Hardware so far + + // Arcane formula from Hacker's Delight by Warren + // abs(x) = ((int) x >> 31) ^ (x + ((int) x >> 31)) + UInt32 sgnevent = ((long) event >> 31); + UInt32 absevent = sgnevent ^ (event + sgnevent); + UInt32 code = IODBG_POWER(absevent); + + UInt32 bit = 1 << (absevent & 0x1f); + if (absevent < sizeof(sStartStopBitField) * 8 + && (sStartStopBitField[absevent >> 5] & bit) ) { + // Or in the START or END bits, Start = 1 & END = 2 + // If sgnevent == 0 then START - 0 => START + // else if sgnevent == -1 then START - -1 => END + code |= DBG_FUNC_START - sgnevent; + } + + // Record the timestamp, wish I had a this pointer + IOTimeStampConstant(code, (UInt32) who, event, param1, param2); + } } } @@ -674,15 +725,17 @@ static void getCStringForObject (OSObject * inObj, char * outStr) } } -/* IOPMPanicOnShutdownHang +/* IOShutdownNotificationsTimedOut * - Called from a timer installed by PEHaltRestart */ -static void IOPMPanicOnShutdownHang(thread_call_param_t p0, thread_call_param_t p1) +static void IOShutdownNotificationsTimedOut( + thread_call_param_t p0, + thread_call_param_t p1) { int type = (int)p0; /* 30 seconds has elapsed - resume shutdown */ - gIOPlatform->haltRestart(type); + if(gIOPlatform) gIOPlatform->haltRestart(type); } @@ -722,8 +775,9 @@ int PEHaltRestart(unsigned int type) bool noWaitForResponses; AbsoluteTime deadline; thread_call_t shutdown_hang; + unsigned int tell_type; - if(type == kPEHaltCPU || type == kPERestartCPU) + if(type == kPEHaltCPU || type == kPERestartCPU || type == kPEUPSDelayHaltCPU) { /* Notify IOKit PM clients of shutdown/restart Clients subscribe to this message with a call to @@ -734,11 +788,19 @@ int PEHaltRestart(unsigned int type) If all goes well the machine will be off by the time the timer expires. */ - shutdown_hang = thread_call_allocate( &IOPMPanicOnShutdownHang, (thread_call_param_t) type); + shutdown_hang = thread_call_allocate( &IOShutdownNotificationsTimedOut, + (thread_call_param_t) type); clock_interval_to_deadline( 30, kSecondScale, &deadline ); thread_call_enter1_delayed( shutdown_hang, 0, deadline ); - noWaitForResponses = pmRootDomain->tellChangeDown2(type); + + if( kPEUPSDelayHaltCPU == type ) { + tell_type = kPEHaltCPU; + } else { + tell_type = type; + } + + noWaitForResponses = pmRootDomain->tellChangeDown2(tell_type); /* This notification should have few clients who all do their work synchronously. @@ -762,16 +824,18 @@ UInt32 PESavePanicInfo(UInt8 *buffer, UInt32 length) long PEGetGMTTimeOfDay(void) { + long result = 0; + if( gIOPlatform) - return( gIOPlatform->getGMTTimeOfDay()); - else - return( 0 ); + result = gIOPlatform->getGMTTimeOfDay(); + + return (result); } void PESetGMTTimeOfDay(long secs) { if( gIOPlatform) - gIOPlatform->setGMTTimeOfDay(secs); + gIOPlatform->setGMTTimeOfDay(secs); } } /* extern "C" */ @@ -883,7 +947,7 @@ bool IODTPlatformExpert::createNubs( IOService * parent, OSIterator * iter ) return( ok ); } -void IODTPlatformExpert::processTopLevel( IORegistryEntry * root ) +void IODTPlatformExpert::processTopLevel( IORegistryEntry * rootEntry ) { OSIterator * kids; IORegistryEntry * next; @@ -891,7 +955,7 @@ void IODTPlatformExpert::processTopLevel( IORegistryEntry * root ) IORegistryEntry * options; // infanticide - kids = IODTFindMatchingEntries( root, 0, deleteList() ); + kids = IODTFindMatchingEntries( rootEntry, 0, deleteList() ); if( kids) { while( (next = (IORegistryEntry *)kids->getNextObject())) { next->detachAll( gIODTPlane); @@ -900,7 +964,7 @@ void IODTPlatformExpert::processTopLevel( IORegistryEntry * root ) } // Publish an IODTNVRAM class on /options. - options = root->childFromPath("options", gIODTPlane); + options = rootEntry->childFromPath("options", gIODTPlane); if (options) { dtNVRAM = new IODTNVRAM; if (dtNVRAM) { @@ -915,12 +979,12 @@ void IODTPlatformExpert::processTopLevel( IORegistryEntry * root ) } // Publish the cpus. - cpus = root->childFromPath( "cpus", gIODTPlane); + cpus = rootEntry->childFromPath( "cpus", gIODTPlane); if ( cpus) createNubs( this, IODTFindMatchingEntries( cpus, kIODTExclusive, 0)); // publish top level, minus excludeList - createNubs( this, IODTFindMatchingEntries( root, kIODTExclusive, excludeList())); + createNubs( this, IODTFindMatchingEntries( rootEntry, kIODTExclusive, excludeList())); } IOReturn IODTPlatformExpert::getNubResources( IOService * nub ) @@ -1069,6 +1133,39 @@ IOByteCount IODTPlatformExpert::savePanicInfo(UInt8 *buffer, IOByteCount length) return lengthSaved; } +OSString* IODTPlatformExpert::createSystemSerialNumberString(OSData* myProperty) { + UInt8* serialNumber; + unsigned int serialNumberSize; + unsigned short pos = 0; + char* temp; + char SerialNo[30]; + + if (myProperty != NULL) { + serialNumberSize = myProperty->getLength(); + serialNumber = (UInt8*)(myProperty->getBytesNoCopy()); + temp = (char*)serialNumber; + if (serialNumberSize > 0) { + // check to see if this is a CTO serial number... + while (pos < serialNumberSize && temp[pos] != '-') pos++; + + if (pos < serialNumberSize) { // there was a hyphen, so it's a CTO serial number + memcpy(SerialNo, serialNumber + 12, 8); + memcpy(&SerialNo[8], serialNumber, 3); + SerialNo[11] = '-'; + memcpy(&SerialNo[12], serialNumber + 3, 8); + SerialNo[20] = 0; + } else { // just a normal serial number + memcpy(SerialNo, serialNumber + 13, 8); + memcpy(&SerialNo[8], serialNumber, 3); + SerialNo[11] = 0; + } + return OSString::withCString(SerialNo); + } + } + return NULL; +} + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #undef super @@ -1084,7 +1181,7 @@ OSMetaClassDefineReservedUnused(IOPlatformExpertDevice, 3); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ bool IOPlatformExpertDevice::compareName( OSString * name, - OSString ** matched) const + OSString ** matched ) const { return( IODTCompareNubName( this, name, matched )); } @@ -1131,6 +1228,12 @@ void IOPlatformExpertDevice::free() workLoop->release(); } +bool IOPlatformExpertDevice::attachToChild( IORegistryEntry * child, + const IORegistryPlane * plane ) +{ + return IOService::attachToChild( child, plane ); +} + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #undef super @@ -1146,7 +1249,7 @@ OSMetaClassDefineReservedUnused(IOPlatformDevice, 3); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ bool IOPlatformDevice::compareName( OSString * name, - OSString ** matched) const + OSString ** matched ) const { return( ((IOPlatformExpert *)getProvider())-> compareNubName( this, name, matched ));