X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/4a2492630c73add3c3aa8a805ba4ff343d4a58ea..89b3af67bb32e691275bf6fa803d1834b2284115:/iokit/Kernel/IOPlatformExpert.cpp diff --git a/iokit/Kernel/IOPlatformExpert.cpp b/iokit/Kernel/IOPlatformExpert.cpp index 239fab5e5..d5b9f7f5b 100644 --- a/iokit/Kernel/IOPlatformExpert.cpp +++ b/iokit/Kernel/IOPlatformExpert.cpp @@ -1,16 +1,19 @@ /* * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * * 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. + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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 @@ -20,7 +23,7 @@ * Please see the License for the specific language governing rights and * limitations under the License. * - * @APPLE_LICENSE_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * HISTORY @@ -37,17 +40,20 @@ #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); @@ -92,25 +98,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); @@ -251,20 +249,18 @@ int (*PE_halt_restart)(unsigned int type) = 0; int IOPlatformExpert::haltRestart(unsigned int type) { - IOPMrootDomain *rd = getPMRootDomain(); - OSBoolean *b = 0; - - if(rd) b = (OSBoolean *)OSDynamicCast(OSBoolean, rd->getProperty(OSString::withCString("StallSystemAtHalt"))); - if (type == kPEHangCPU) while (1); - if (kOSBooleanTrue == b) { - // Stall shutdown for 5 minutes, and if no outside force has removed our power, continue with - // a reboot. - IOSleep(1000*60*5); + 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; } - + kprintf("platform halt restart\n"); if (PE_halt_restart) return (*PE_halt_restart)(type); else return -1; } @@ -371,11 +367,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); + } } } @@ -702,15 +731,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); } @@ -750,8 +781,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 @@ -762,11 +794,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. @@ -790,16 +830,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" */ @@ -911,7 +953,7 @@ bool IODTPlatformExpert::createNubs( IOService * parent, OSIterator * iter ) return( ok ); } -void IODTPlatformExpert::processTopLevel( IORegistryEntry * root ) +void IODTPlatformExpert::processTopLevel( IORegistryEntry * rootEntry ) { OSIterator * kids; IORegistryEntry * next; @@ -919,7 +961,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); @@ -928,7 +970,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) { @@ -943,12 +985,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 ) @@ -1100,14 +1142,14 @@ IOByteCount IODTPlatformExpert::savePanicInfo(UInt8 *buffer, IOByteCount length) OSString* IODTPlatformExpert::createSystemSerialNumberString(OSData* myProperty) { UInt8* serialNumber; unsigned int serialNumberSize; - short pos = 0; + unsigned short pos = 0; char* temp; char SerialNo[30]; if (myProperty != NULL) { serialNumberSize = myProperty->getLength(); serialNumber = (UInt8*)(myProperty->getBytesNoCopy()); - temp = serialNumber; + temp = (char*)serialNumber; if (serialNumberSize > 0) { // check to see if this is a CTO serial number... while (pos < serialNumberSize && temp[pos] != '-') pos++; @@ -1192,6 +1234,12 @@ void IOPlatformExpertDevice::free() workLoop->release(); } +bool IOPlatformExpertDevice::attachToChild( IORegistryEntry * child, + const IORegistryPlane * plane ) +{ + return IOService::attachToChild( child, plane ); +} + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #undef super