X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/4a3eedf9ecc9bbe3f3a5c6ce5e53ad199d639d32..4b17d6b6e417f714551ec129064745ea9919780e:/iokit/Kernel/IOPlatformExpert.cpp diff --git a/iokit/Kernel/IOPlatformExpert.cpp b/iokit/Kernel/IOPlatformExpert.cpp index 1b53461ec..29c286ea6 100644 --- a/iokit/Kernel/IOPlatformExpert.cpp +++ b/iokit/Kernel/IOPlatformExpert.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2006 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1998-2010 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -25,9 +25,6 @@ * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ -/* - * HISTORY - */ #include #include @@ -47,6 +44,7 @@ #include #include +#include extern "C" { #include @@ -54,9 +52,6 @@ extern "C" { #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, size_t outStrLen); @@ -83,6 +78,7 @@ OSMetaClassDefineReservedUnused(IOPlatformExpert, 11); static IOPlatformExpert * gIOPlatform; static OSDictionary * gIOInterruptControllers; static IOLock * gIOInterruptControllersLock; +static IODTNVRAM *gIOOptionsEntry; OSSymbol * gPlatformInterruptControllerName; @@ -107,9 +103,11 @@ bool IOPlatformExpert::start( IOService * provider ) return false; // Override the mapper present flag is requested by boot arguments. - if (PE_parse_boot_arg("dart", &debugFlags) && (debugFlags == 0)) + if (PE_parse_boot_argn("dart", &debugFlags, sizeof (debugFlags)) && (debugFlags == 0)) removeProperty(kIOPlatformMapperPresentKey); - + if (PE_parse_boot_argn("-x", &debugFlags, sizeof (debugFlags))) + removeProperty(kIOPlatformMapperPresentKey); + // Register the presence or lack thereof a system // PCI address mapper with the IOMapper class IOMapper::setMapperRequired(0 != getProperty(kIOPlatformMapperPresentKey)); @@ -254,22 +252,17 @@ int IOPlatformExpert::haltRestart(unsigned int type) { if (type == kPEPanicSync) return 0; - if (type == kPEHangCPU) while (1); + if (type == kPEHangCPU) while (true) {} 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; + // RestartOnPowerLoss feature was turned on, proceed with shutdown. + type = kPEHaltCPU; } // On ARM kPEPanicRestartCPU is supported in the drivers if (type == kPEPanicRestartCPU) type = kPERestartCPU; - + if (PE_halt_restart) return (*PE_halt_restart)(type); else return -1; } @@ -380,41 +373,14 @@ void IOPlatformExpert:: PMLog(const char *who, unsigned long event, unsigned long param1, unsigned long param2) { - UInt32 debugFlags = gIOKitDebug; - - if (debugFlags & kIOLogPower) { - - uint32_t nows, nowus; + clock_sec_t nows; + clock_usec_t 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); - } - } + kprintf("pm%u %p %.30s %d %lx %lx\n", + nowus, current_thread(), who, // Identity + (int) event, (long) param1, (long) param2); // Args } @@ -433,7 +399,6 @@ void IOPlatformExpert::PMInstantiatePowerDomains ( void ) root->init(); root->attach(this); root->start(this); - root->youAreRoot(); } @@ -750,10 +715,16 @@ static void IOShutdownNotificationsTimedOut( thread_call_param_t p0, thread_call_param_t p1) { - int type = (int)p0; +#ifdef CONFIG_EMBEDDED + /* 30 seconds has elapsed - panic */ + panic("Halt/Restart Timed Out"); + +#else /* ! CONFIG_EMBEDDED */ + int type = (int)(long)p0; /* 30 seconds has elapsed - resume shutdown */ if(gIOPlatform) gIOPlatform->haltRestart(type); +#endif /* CONFIG_EMBEDDED */ } @@ -789,13 +760,13 @@ int PEGetPlatformEpoch(void) int PEHaltRestart(unsigned int type) { - IOPMrootDomain *pmRootDomain = IOService::getPMRootDomain(); + IOPMrootDomain *pmRootDomain; AbsoluteTime deadline; thread_call_t shutdown_hang; - unsigned int tell_type; if(type == kPEHaltCPU || type == kPERestartCPU || type == kPEUPSDelayHaltCPU) { + pmRootDomain = IOService::getPMRootDomain(); /* Notify IOKit PM clients of shutdown/restart Clients subscribe to this message with a call to IOService::registerInterest() @@ -809,15 +780,8 @@ int PEHaltRestart(unsigned int type) (thread_call_param_t) type); clock_interval_to_deadline( 30, kSecondScale, &deadline ); thread_call_enter1_delayed( shutdown_hang, 0, deadline ); - - - if( kPEUPSDelayHaltCPU == type ) { - tell_type = kPEHaltCPU; - } else { - tell_type = type; - } - pmRootDomain->handlePlatformHaltRestart(tell_type); + pmRootDomain->handlePlatformHaltRestart(type); /* This notification should have few clients who all do their work synchronously. @@ -838,20 +802,127 @@ UInt32 PESavePanicInfo(UInt8 *buffer, UInt32 length) else return 0; } + + +inline static int init_gIOOptionsEntry(void) +{ + IORegistryEntry *entry; + void *nvram_entry; + volatile void **options; + int ret = -1; + + if (gIOOptionsEntry) + return 0; + + entry = IORegistryEntry::fromPath( "/options", gIODTPlane ); + if (!entry) + return -1; + + nvram_entry = (void *) OSDynamicCast(IODTNVRAM, entry); + if (!nvram_entry) + goto release; + + options = (volatile void **) &gIOOptionsEntry; + if (!OSCompareAndSwapPtr(NULL, nvram_entry, options)) { + ret = 0; + goto release; + } + + return 0; + +release: + entry->release(); + return ret; + +} + +/* pass in a NULL value if you just want to figure out the len */ +boolean_t PEReadNVRAMProperty(const char *symbol, void *value, + unsigned int *len) +{ + OSObject *obj; + OSData *data; + unsigned int vlen; + + if (!symbol || !len) + goto err; + + if (init_gIOOptionsEntry() < 0) + goto err; + + vlen = *len; + *len = 0; + + obj = gIOOptionsEntry->getProperty(symbol); + if (!obj) + goto err; + + /* convert to data */ + data = OSDynamicCast(OSData, obj); + if (!data) + goto err; + + *len = data->getLength(); + vlen = min(vlen, *len); + if (vlen) + memcpy((void *) value, data->getBytesNoCopy(), vlen); + + return TRUE; + +err: + return FALSE; +} + + +boolean_t PEWriteNVRAMProperty(const char *symbol, const void *value, + const unsigned int len) +{ + const OSSymbol *sym; + OSData *data; + bool ret = false; + + if (!symbol || !value || !len) + goto err; + + if (init_gIOOptionsEntry() < 0) + goto err; + + sym = OSSymbol::withCStringNoCopy(symbol); + if (!sym) + goto err; + + data = OSData::withBytes((void *) value, len); + if (!data) + goto sym_done; + + ret = gIOOptionsEntry->setProperty(sym, data); + data->release(); + +sym_done: + sym->release(); + + if (ret == true) { + gIOOptionsEntry->sync(); + return TRUE; + } + +err: + return FALSE; +} + + long PEGetGMTTimeOfDay(void) { long result = 0; - if( gIOPlatform) - result = gIOPlatform->getGMTTimeOfDay(); + if( gIOPlatform) result = gIOPlatform->getGMTTimeOfDay(); return (result); } void PESetGMTTimeOfDay(long secs) { - if( gIOPlatform) - gIOPlatform->setGMTTimeOfDay(secs); + if( gIOPlatform) gIOPlatform->setGMTTimeOfDay(secs); } } /* extern "C" */ @@ -861,8 +932,43 @@ void IOPlatformExpert::registerNVRAMController(IONVRAMController * caller) OSData * data; IORegistryEntry * entry; OSString * string = 0; - char uuid[ 36 + 1 ]; + uuid_string_t uuid; + +#if CONFIG_EMBEDDED + entry = IORegistryEntry::fromPath( "/chosen", gIODTPlane ); + if ( entry ) + { + OSData * data1; + + data1 = OSDynamicCast( OSData, entry->getProperty( "unique-chip-id" ) ); + if ( data1 && data1->getLength( ) == 8 ) + { + OSData * data2; + + data2 = OSDynamicCast( OSData, entry->getProperty( "chip-id" ) ); + if ( data2 && data2->getLength( ) == 4 ) + { + SHA1_CTX context; + uint8_t digest[ SHA_DIGEST_LENGTH ]; + const uuid_t space = { 0xA6, 0xDD, 0x4C, 0xCB, 0xB5, 0xE8, 0x4A, 0xF5, 0xAC, 0xDD, 0xB6, 0xDC, 0x6A, 0x05, 0x42, 0xB8 }; + SHA1Init( &context ); + SHA1Update( &context, space, sizeof( space ) ); + SHA1Update( &context, data1->getBytesNoCopy( ), data1->getLength( ) ); + SHA1Update( &context, data2->getBytesNoCopy( ), data2->getLength( ) ); + SHA1Final( digest, &context ); + + digest[ 6 ] = ( digest[ 6 ] & 0x0F ) | 0x50; + digest[ 8 ] = ( digest[ 8 ] & 0x3F ) | 0x80; + + uuid_unparse( digest, uuid ); + string = OSString::withCString( uuid ); + } + } + + entry->release( ); + } +#else /* !CONFIG_EMBEDDED */ entry = IORegistryEntry::fromPath( "/efi/platform", gIODTPlane ); if ( entry ) { @@ -887,6 +993,7 @@ void IOPlatformExpert::registerNVRAMController(IONVRAMController * caller) entry->release( ); } +#endif /* !CONFIG_EMBEDDED */ if ( string == 0 ) { @@ -925,7 +1032,7 @@ IOReturn IOPlatformExpert::callPlatformFunction(const OSSymbol *functionName, if (waitForFunction) { _resources = waitForService(resourceMatching(functionName)); } else { - _resources = resources(); + _resources = getResourceService(); } if (_resources == 0) return kIOReturnUnsupported; @@ -1406,3 +1513,4 @@ bool IOPanicPlatform::start(IOService * provider) { return false; } +