]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IOPlatformExpert.cpp
xnu-3248.30.4.tar.gz
[apple/xnu.git] / iokit / Kernel / IOPlatformExpert.cpp
index bbbea1e39ad4465fcc4f6be222080e653909b5ba..31ab8b7007f457778c98580577fb745fac7e3ca3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998-2010 Apple Inc. All rights reserved.
+ * Copyright (c) 1998-2014 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -39,6 +39,7 @@
 #include <IOKit/IOKitKeys.h>
 #include <IOKit/IOTimeStamp.h>
 #include <IOKit/IOUserClient.h>
+#include <IOKit/IOKitDiagnosticsUserClient.h>
 
 #include <IOKit/system.h>
 
@@ -62,11 +63,11 @@ static void getCStringForObject(OSObject *inObj, char *outStr, size_t outStrLen)
 OSDefineMetaClassAndStructors(IOPlatformExpert, IOService)
 
 OSMetaClassDefineReservedUsed(IOPlatformExpert,  0);
-
 OSMetaClassDefineReservedUsed(IOPlatformExpert,  1);
-OSMetaClassDefineReservedUnused(IOPlatformExpert,  2);
-OSMetaClassDefineReservedUnused(IOPlatformExpert,  3);
-OSMetaClassDefineReservedUnused(IOPlatformExpert,  4);
+OSMetaClassDefineReservedUsed(IOPlatformExpert,  2);
+OSMetaClassDefineReservedUsed(IOPlatformExpert,  3);
+OSMetaClassDefineReservedUsed(IOPlatformExpert,  4);
+
 OSMetaClassDefineReservedUnused(IOPlatformExpert,  5);
 OSMetaClassDefineReservedUnused(IOPlatformExpert,  6);
 OSMetaClassDefineReservedUnused(IOPlatformExpert,  7);
@@ -324,6 +325,17 @@ IOReturn IOPlatformExpert::registerInterruptController(OSSymbol *name, IOInterru
   return kIOReturnSuccess;
 }
 
+IOReturn IOPlatformExpert::deregisterInterruptController(OSSymbol *name)
+{
+  IOLockLock(gIOInterruptControllersLock);
+  
+  gIOInterruptControllers->removeObject(name);
+  
+  IOLockUnlock(gIOInterruptControllersLock);
+  
+  return kIOReturnSuccess;
+}
+
 IOInterruptController *IOPlatformExpert::lookUpInterruptController(OSSymbol *name)
 {
   OSObject              *object;
@@ -363,6 +375,17 @@ bool IOPlatformExpert::platformAdjustService(IOService */*service*/)
   return true;
 }
 
+void IOPlatformExpert::getUTCTimeOfDay(clock_sec_t * secs, clock_nsec_t * nsecs)
+{
+  *secs = getGMTTimeOfDay();
+  *nsecs = 0;
+}
+
+void IOPlatformExpert::setUTCTimeOfDay(clock_sec_t secs, __unused clock_nsec_t nsecs)
+{
+  setGMTTimeOfDay(secs);
+}
+
 
 //*********************************************************************************
 // PMLog
@@ -379,8 +402,8 @@ PMLog(const char *who, unsigned long event,
        nowus += (nows % 1000) * 1000000;
 
     kprintf("pm%u %p %.30s %d %lx %lx\n",
-               nowus, current_thread(), who,   // Identity
-               (int) event, (long) param1, (long) param2);                     // Args
+               nowus, OBFUSCATE(current_thread()), who,        // Identity
+               (int) event, (long)OBFUSCATE(param1), (long)OBFUSCATE(param2));                 // Args
 }
 
 
@@ -757,6 +780,9 @@ int PEHaltRestart(unsigned int type)
   IOPMrootDomain    *pmRootDomain;
   AbsoluteTime      deadline;
   thread_call_t     shutdown_hang;
+  IORegistryEntry   *node;
+  OSData            *data;
+  uint32_t          timeout = 30;
   
   if(type == kPEHaltCPU || type == kPERestartCPU || type == kPEUPSDelayHaltCPU)
   {
@@ -768,11 +794,20 @@ int PEHaltRestart(unsigned int type)
     
     /* Spawn a thread that will panic in 30 seconds. 
        If all goes well the machine will be off by the time
-       the timer expires.
+       the timer expires. If the device wants a different
+       timeout, use that value instead of 30 seconds.
      */
+#define RESTART_NODE_PATH    "/chosen"
+    node = IORegistryEntry::fromPath( RESTART_NODE_PATH, gIODTPlane );
+    if ( node ) {
+      data = OSDynamicCast( OSData, node->getProperty( "halt-restart-timeout" ) );
+      if ( data && data->getLength() == 4 )
+        timeout = *((uint32_t *) data->getBytesNoCopy());
+    }
+
     shutdown_hang = thread_call_allocate( &IOShutdownNotificationsTimedOut, 
                         (thread_call_param_t)(uintptr_t) type);
-    clock_interval_to_deadline( 30, kSecondScale, &deadline );
+    clock_interval_to_deadline( timeout, kSecondScale, &deadline );
     thread_call_enter1_delayed( shutdown_hang, 0, deadline );
 
     pmRootDomain->handlePlatformHaltRestart(type); 
@@ -785,6 +820,10 @@ int PEHaltRestart(unsigned int type)
        replies.
      */
    }
+   else if(type == kPEPanicRestartCPU || type == kPEPanicSync)
+   {
+    IOCPURunPlatformPanicActions(type);
+   }
 
   if (gIOPlatform) return gIOPlatform->haltRestart(type);
   else return -1;
@@ -867,6 +906,38 @@ err:
     return FALSE;
 }
 
+boolean_t
+PEWriteNVRAMBooleanProperty(const char *symbol, boolean_t value)
+{
+       const OSSymbol *sym = NULL;
+       OSBoolean *data = NULL;
+       bool ret = false;
+
+       if (symbol == NULL) {
+               goto exit;
+       }
+
+       if (init_gIOOptionsEntry() < 0) {
+               goto exit;
+       }
+
+       if ((sym = OSSymbol::withCStringNoCopy(symbol)) == NULL) {
+               goto exit;
+       }
+
+       data  = value ? kOSBooleanTrue : kOSBooleanFalse;
+       ret = gIOOptionsEntry->setProperty(sym, data);
+
+       sym->release();
+
+       /* success, force the NVRAM to flush writes */
+       if (ret == true) {
+               gIOOptionsEntry->sync();
+       }
+
+exit:
+       return ret;
+}
 
 boolean_t PEWriteNVRAMProperty(const char *symbol, const void *value, 
                                const unsigned int len)
@@ -933,16 +1004,35 @@ err:
 
 long PEGetGMTTimeOfDay(void)
 {
-       long    result = 0;
-
-       if( gIOPlatform)                result = gIOPlatform->getGMTTimeOfDay();
+    clock_sec_t     secs;
+    clock_usec_t    usecs;
 
-       return (result);
+    PEGetUTCTimeOfDay(&secs, &usecs);
+    return secs;
 }
 
 void PESetGMTTimeOfDay(long secs)
 {
-    if( gIOPlatform)           gIOPlatform->setGMTTimeOfDay(secs);
+    PESetUTCTimeOfDay(secs, 0);
+}
+
+void PEGetUTCTimeOfDay(clock_sec_t * secs, clock_usec_t * usecs)
+{
+    clock_nsec_t    nsecs = 0;
+
+    *secs = 0;
+       if (gIOPlatform)
+        gIOPlatform->getUTCTimeOfDay(secs, &nsecs);
+
+    assert(nsecs < NSEC_PER_SEC);
+    *usecs = nsecs / NSEC_PER_USEC;
+}
+
+void PESetUTCTimeOfDay(clock_sec_t secs, clock_usec_t usecs)
+{
+    assert(usecs < USEC_PER_SEC);
+       if (gIOPlatform)
+        gIOPlatform->setUTCTimeOfDay(secs, usecs * NSEC_PER_USEC);
 }
 
 } /* extern "C" */
@@ -1135,6 +1225,7 @@ void IODTPlatformExpert::processTopLevel( IORegistryEntry * rootEntry )
         } else {
          dtNVRAM->attach(this);
          dtNVRAM->registerService();
+         options->release();
        }
       }
     }
@@ -1142,7 +1233,10 @@ void IODTPlatformExpert::processTopLevel( IORegistryEntry * rootEntry )
     // Publish the cpus.
     cpus = rootEntry->childFromPath( "cpus", gIODTPlane);
     if ( cpus)
+    {
       createNubs( this, IODTFindMatchingEntries( cpus, kIODTExclusive, 0));
+      cpus->release();
+    }
 
     // publish top level, minus excludeList
     createNubs( this, IODTFindMatchingEntries( rootEntry, kIODTExclusive, excludeList()));
@@ -1423,6 +1517,40 @@ IOReturn IOPlatformExpertDevice::setProperties( OSObject * properties )
     return kIOReturnUnsupported;
 }
 
+IOReturn IOPlatformExpertDevice::newUserClient( task_t owningTask, void * securityID,
+                                    UInt32 type,  OSDictionary * properties,
+                                    IOUserClient ** handler )
+{
+    IOReturn            err = kIOReturnSuccess;
+    IOUserClient *      newConnect = 0;
+    IOUserClient *      theConnect = 0;
+
+    switch (type)
+    {
+        case kIOKitDiagnosticsClientType:
+           newConnect = IOKitDiagnosticsClient::withTask(owningTask);
+           if (!newConnect) err = kIOReturnNotPermitted;
+            break;
+        default:
+            err = kIOReturnBadArgument;
+    }
+
+    if (newConnect)
+    {
+        if ((false == newConnect->attach(this))
+                || (false == newConnect->start(this)))
+        {
+            newConnect->detach( this );
+            newConnect->release();
+        }
+        else
+            theConnect = newConnect;
+    }
+
+    *handler = theConnect;
+    return (err);
+}
+
 void IOPlatformExpertDevice::free()
 {
     if (workLoop)
@@ -1473,7 +1601,7 @@ class IOPanicPlatform : IOPlatformExpert {
     OSDeclareDefaultStructors(IOPanicPlatform);
 
 public:
-    bool start(IOService * provider);
+    bool start(IOService * provider) APPLE_KEXT_OVERRIDE;
 };