Loading...
iokit/Kernel/IOPlatformExpert.cpp xnu-12377.101.15 xnu-792
--- xnu/xnu-12377.101.15/iokit/Kernel/IOPlatformExpert.cpp
+++ xnu/xnu-792/iokit/Kernel/IOPlatformExpert.cpp
@@ -1,33 +1,29 @@
 /*
- * Copyright (c) 1998-2022 Apple Inc. All rights reserved.
+ * Copyright (c) 1998-2000 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. 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
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * 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 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.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ * 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@
  */
-
+/*
+ * HISTORY
+ */
+ 
 #include <IOKit/IOCPU.h>
-#include <IOKit/IOPlatformActions.h>
 #include <IOKit/IODeviceTreeSupport.h>
 #include <IOKit/IOKitDebug.h>
 #include <IOKit/IOMapper.h>
@@ -39,52 +35,18 @@
 #include <IOKit/pwr_mgt/RootDomain.h>
 #include <IOKit/IOKitKeys.h>
 #include <IOKit/IOTimeStamp.h>
-#include <IOKit/IOUserClient.h>
-#include <IOKit/IOKitDiagnosticsUserClient.h>
-#include <IOKit/IOUserServer.h>
-
-#include "IOKitKernelInternal.h"
 
 #include <IOKit/system.h>
-#include <sys/csr.h>
 
 #include <libkern/c++/OSContainers.h>
-#include <libkern/c++/OSSharedPtr.h>
-#include <libkern/crypto/sha1.h>
-#include <libkern/OSAtomic.h>
-
-#if defined(__arm64__)
-#include <arm64/tlb.h>
-#endif
 
 extern "C" {
 #include <machine/machine_routines.h>
 #include <pexpert/pexpert.h>
-#include <uuid/uuid.h>
-#include <sys/sysctl.h>
-}
-
-#define kShutdownTimeout    30 //in secs
-
-#if defined(XNU_TARGET_OS_OSX)
-
-boolean_t coprocessor_cross_panic_enabled = TRUE;
-#define APPLE_VENDOR_VARIABLE_GUID "4d1ede05-38c7-4a6a-9cc6-4bcca8b38c14"
-#endif /* defined(XNU_TARGET_OS_OSX) */
-
-void printDictionaryKeys(OSDictionary * inDictionary, char * inMsg);
-static void getCStringForObject(OSObject *inObj, char *outStr, size_t outStrLen);
-
-/*
- * There are drivers which take mutexes in the quiesce callout or pass
- * the quiesce/active action to super.  Even though it sometimes panics,
- * because it doesn't *always* panic, they get away with it.
- * We need a chicken bit to diagnose and fix them all before this
- * can be enabled by default.
- *
- * <rdar://problem/33831837> tracks turning this on by default.
- */
-uint32_t gEnforcePlatformActionSafety = 0;
+}
+
+void printDictionaryKeys (OSDictionary * inDictionary, char * inMsg);
+static void getCStringForObject (OSObject * inObj, char * outStr);
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
@@ -92,415 +54,312 @@
 
 OSDefineMetaClassAndStructors(IOPlatformExpert, IOService)
 
-OSMetaClassDefineReservedUsedX86(IOPlatformExpert, 0);
-OSMetaClassDefineReservedUsedX86(IOPlatformExpert, 1);
-OSMetaClassDefineReservedUsedX86(IOPlatformExpert, 2);
-OSMetaClassDefineReservedUsedX86(IOPlatformExpert, 3);
-OSMetaClassDefineReservedUsedX86(IOPlatformExpert, 4);
-OSMetaClassDefineReservedUsedX86(IOPlatformExpert, 5);
-OSMetaClassDefineReservedUsedX86(IOPlatformExpert, 6);
-
-OSMetaClassDefineReservedUnused(IOPlatformExpert, 7);
-OSMetaClassDefineReservedUnused(IOPlatformExpert, 8);
-OSMetaClassDefineReservedUnused(IOPlatformExpert, 9);
+OSMetaClassDefineReservedUsed(IOPlatformExpert,  0);
+
+OSMetaClassDefineReservedUsed(IOPlatformExpert,  1);
+OSMetaClassDefineReservedUnused(IOPlatformExpert,  2);
+OSMetaClassDefineReservedUnused(IOPlatformExpert,  3);
+OSMetaClassDefineReservedUnused(IOPlatformExpert,  4);
+OSMetaClassDefineReservedUnused(IOPlatformExpert,  5);
+OSMetaClassDefineReservedUnused(IOPlatformExpert,  6);
+OSMetaClassDefineReservedUnused(IOPlatformExpert,  7);
+OSMetaClassDefineReservedUnused(IOPlatformExpert,  8);
+OSMetaClassDefineReservedUnused(IOPlatformExpert,  9);
 OSMetaClassDefineReservedUnused(IOPlatformExpert, 10);
 OSMetaClassDefineReservedUnused(IOPlatformExpert, 11);
 
 static IOPlatformExpert * gIOPlatform;
 static OSDictionary * gIOInterruptControllers;
 static IOLock * gIOInterruptControllersLock;
-static IODTNVRAM *gIOOptionsEntry;
 
 OSSymbol * gPlatformInterruptControllerName;
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
-bool
-IOPlatformExpert::attach( IOService * provider )
-{
-	if (!super::attach( provider )) {
-		return false;
+bool IOPlatformExpert::attach( IOService * provider )
+{
+
+    if( !super::attach( provider ))
+	return( false);
+
+    return( true);
+}
+
+bool IOPlatformExpert::start( IOService * provider )
+{
+    IORangeAllocator *	physicalRanges;
+    OSData *		busFrequency;
+    
+    if (!super::start(provider))
+      return false;
+
+    // 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);
+    gIOInterruptControllersLock = IOLockAlloc();
+    
+    // Correct the bus frequency in the device tree.
+    busFrequency = OSData::withBytesNoCopy((void *)&gPEClockFrequencyInfo.bus_clock_rate_hz, 4);
+    provider->setProperty("clock-frequency", busFrequency);
+    busFrequency->release();
+    
+    gPlatformInterruptControllerName = (OSSymbol *)OSSymbol::withCStringNoCopy("IOPlatformInterruptController");
+    
+    physicalRanges = IORangeAllocator::withRange(0xffffffff, 1, 16,
+						 IORangeAllocator::kLocking);
+    assert(physicalRanges);
+    setProperty("Platform Memory Ranges", physicalRanges);
+    
+    setPlatform( this );
+    gIOPlatform = this;
+    
+    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) );
+}
+
+bool IOPlatformExpert::configure( IOService * provider )
+{
+    OSSet *		topLevel;
+    OSDictionary *	dict;
+    IOService * 	nub;
+
+    topLevel = OSDynamicCast( OSSet, getProperty("top-level"));
+
+    if( topLevel) {
+        while( (dict = OSDynamicCast( OSDictionary,
+				topLevel->getAnyObject()))) {
+            dict->retain();
+            topLevel->removeObject( dict );
+            nub = createNub( dict );
+            if( 0 == nub)
+                continue;
+            dict->release();
+            nub->attach( this );
+            nub->registerService();
+        }
+    }
+
+    return( true );
+}
+
+IOService * IOPlatformExpert::createNub( OSDictionary * from )
+{
+    IOService *		nub;
+
+    nub = new IOPlatformDevice;
+    if(nub) {
+	if( !nub->init( from )) {
+	    nub->release();
+	    nub = 0;
 	}
-
-	return true;
-}
-
-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 SIP disabled.
-#if CONFIG_CSR
-	if (csr_check(CSR_ALLOW_UNRESTRICTED_FS) == 0)
-#endif /* CONFIG_CSR */
-	{
-		if (PE_parse_boot_argn("dart", &debugFlags, sizeof(debugFlags)) && (debugFlags == 0)) {
-			removeProperty(kIOPlatformMapperPresentKey);
-		}
-#if DEBUG || DEVELOPMENT
-		if (PE_parse_boot_argn("-x", &debugFlags, sizeof(debugFlags))) {
-			removeProperty(kIOPlatformMapperPresentKey);
-		}
-#endif /* DEBUG || DEVELOPMENT */
-	}
-
-	// Register the presence or lack thereof a system
-	// PCI address mapper with the IOMapper class
-	IOMapper::setMapperRequired(NULL != getProperty(kIOPlatformMapperPresentKey));
-
-	gIOInterruptControllers = OSDictionary::withCapacity(1);
-	gIOInterruptControllersLock = IOLockAlloc();
-
-	// Correct the bus frequency in the device tree.
-	busFrequency = OSData::withBytesNoCopy((void *)&gPEClockFrequencyInfo.bus_clock_rate_hz, 4);
-	provider->setProperty("clock-frequency", busFrequency);
-	busFrequency->release();
-
-	gPlatformInterruptControllerName = (OSSymbol *)OSSymbol::withCStringNoCopy("IOPlatformInterruptController");
-
-	physicalRanges = IORangeAllocator::withRange(0xffffffff, 1, 16,
-	    IORangeAllocator::kLocking);
-	assert(physicalRanges);
-	setProperty("Platform Memory Ranges", physicalRanges);
-	OSSafeReleaseNULL(physicalRanges);
-
-	setPlatform( this );
-	gIOPlatform = this;
-
-	PMInstantiatePowerDomains();
-
-#if !defined(__x86_64__)
-	publishPlatformUUIDAndSerial();
-#endif /* !defined(__x86_64__) */
-
-#if defined (__x86_64__)
-	if (PEGetCoprocessorVersion() >= kCoprocessorVersion2) {
-		coprocessor_paniclog_flush = TRUE;
-		extended_debug_log_init();
-	}
-#endif
-
-	PE_parse_boot_argn("enforce_platform_action_safety", &gEnforcePlatformActionSafety,
-	    sizeof(gEnforcePlatformActionSafety));
-
-	return configure(provider);
-}
-
-bool
-IOPlatformExpert::configure( IOService * provider )
-{
-	OSSet *             topLevel;
-	OSDictionary *      dict;
-	IOService *         nub = NULL;
-
-	topLevel = OSDynamicCast( OSSet, getProperty("top-level"));
-
-	if (topLevel) {
-		while ((dict = OSDynamicCast( OSDictionary,
-		    topLevel->getAnyObject()))) {
-			dict->retain();
-			topLevel->removeObject( dict );
-			OSSafeReleaseNULL(nub);
-			nub = createNub( dict );
-			dict->release();
-			if (NULL == nub) {
-				continue;
-			}
-			nub->attach( this );
-			nub->registerService();
-		}
-	}
-	OSSafeReleaseNULL(nub);
-	return true;
-}
-
-IOService *
-IOPlatformExpert::createNub( OSDictionary * from )
-{
-	IOService *         nub;
-
-	nub = new IOPlatformDevice;
-	if (nub) {
-		if (!nub->init( from )) {
-			nub->release();
-			nub = NULL;
-		}
-	}
-	return nub;
-}
-
-bool
-IOPlatformExpert::compareNubName( const IOService * nub,
-    OSString * name, OSString ** matched ) const
-{
-	return nub->IORegistryEntry::compareName( name, matched );
-}
-
-bool
-IOPlatformExpert::compareNubName( const IOService * nub,
-    OSString * name, OSSharedPtr<OSString>& matched ) const
-{
-	OSString* matchedRaw = NULL;
-	bool result = compareNubName(nub, name, &matchedRaw);
-	matched.reset(matchedRaw, OSNoRetain);
-	return result;
-}
-
-IOReturn
-IOPlatformExpert::getNubResources( IOService * nub )
-{
-	return kIOReturnSuccess;
-}
-
-long
-IOPlatformExpert::getBootROMType(void)
-{
-	return _peBootROMType;
-}
-
-long
-IOPlatformExpert::getChipSetType(void)
-{
-	return _peChipSetType;
-}
-
-long
-IOPlatformExpert::getMachineType(void)
-{
-	return _peMachineType;
-}
-
-void
-IOPlatformExpert::setBootROMType(long peBootROMType)
-{
-	_peBootROMType = peBootROMType;
-}
-
-void
-IOPlatformExpert::setChipSetType(long peChipSetType)
-{
-	_peChipSetType = peChipSetType;
-}
-
-void
-IOPlatformExpert::setMachineType(long peMachineType)
-{
-	_peMachineType = peMachineType;
-}
-
-bool
-IOPlatformExpert::getMachineName( char * /*name*/, int /*maxLength*/)
-{
-	return false;
-}
-
-bool
-IOPlatformExpert::getModelName( char * /*name*/, int /*maxLength*/)
-{
-	return false;
-}
-
-bool
-IOPlatformExpert::getTargetName( char * /*name*/, int /*maxLength*/)
-{
-	return false;
-}
-
-bool
-IOPlatformExpert::getProductName( char * /*name*/, int /*maxLength*/)
-{
-	return false;
-}
-
-OSString*
-IOPlatformExpert::createSystemSerialNumberString(OSData* myProperty)
-{
-	return NULL;
-}
-
-IORangeAllocator *
-IOPlatformExpert::getPhysicalRangeAllocator(void)
-{
-	return OSDynamicCast(IORangeAllocator,
-	           getProperty("Platform Memory Ranges"));
-}
-
-int (*PE_halt_restart)(unsigned int type) = NULL;
-
-int
-IOPlatformExpert::haltRestart(unsigned int type)
-{
-	if (type == kPEPanicSync) {
-		return 0;
-	}
-
-	if (type == kPEHangCPU) {
-		while (true) {
-			asm volatile ("");
-		}
-	}
-
-	if (type == kPEUPSDelayHaltCPU) {
-		// RestartOnPowerLoss feature was turned on, proceed with shutdown.
-		type = kPEHaltCPU;
-	}
-
-#if defined (__x86_64__)
-	// On ARM kPEPanicRestartCPU is supported in the drivers
-	if (type == kPEPanicRestartCPU) {
-		type = kPERestartCPU;
-	}
-#endif
-
-	if (PE_halt_restart) {
-		return (*PE_halt_restart)(type);
-	} else {
-		return -1;
-	}
-}
-
-void
-IOPlatformExpert::sleepKernel(void)
+    }
+    return( nub);
+}
+
+bool IOPlatformExpert::compareNubName( const IOService * nub,
+				OSString * name, OSString ** matched ) const
+{
+    return( nub->IORegistryEntry::compareName( name, matched ));
+}
+
+IOReturn IOPlatformExpert::getNubResources( IOService * nub )
+{
+    return( kIOReturnSuccess );
+}
+
+long IOPlatformExpert::getBootROMType(void)
+{
+  return _peBootROMType;
+}
+
+long IOPlatformExpert::getChipSetType(void)
+{
+  return _peChipSetType;
+}
+
+long IOPlatformExpert::getMachineType(void)
+{
+  return _peMachineType;
+}
+
+void IOPlatformExpert::setBootROMType(long peBootROMType)
+{
+  _peBootROMType = peBootROMType;
+}
+
+void IOPlatformExpert::setChipSetType(long peChipSetType)
+{
+  _peChipSetType = peChipSetType;
+}
+
+void IOPlatformExpert::setMachineType(long peMachineType)
+{
+  _peMachineType = peMachineType;
+}
+
+bool IOPlatformExpert::getMachineName( char * /*name*/, int /*maxLength*/)
+{
+    return( false );
+}
+
+bool IOPlatformExpert::getModelName( char * /*name*/, int /*maxLength*/)
+{
+    return( false );
+}
+
+OSString* IOPlatformExpert::createSystemSerialNumberString(OSData* myProperty)
+{
+    return NULL;
+}
+
+IORangeAllocator * IOPlatformExpert::getPhysicalRangeAllocator(void)
+{
+    return(OSDynamicCast(IORangeAllocator,
+			getProperty("Platform Memory Ranges")));
+}
+
+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);
+    type = kPERestartCPU;
+  }
+  
+  if (PE_halt_restart) return (*PE_halt_restart)(type);
+  else return -1;
+}
+
+void IOPlatformExpert::sleepKernel(void)
 {
 #if 0
-	long cnt;
-	boolean_t intState;
-
-	intState = ml_set_interrupts_enabled(false);
-
-	for (cnt = 0; cnt < 10000; cnt++) {
-		IODelay(1000);
-	}
-
-	ml_set_interrupts_enabled(intState);
+  long cnt;
+  boolean_t intState;
+  
+  intState = ml_set_interrupts_enabled(false);
+  
+  for (cnt = 0; cnt < 10000; cnt++) {
+    IODelay(1000);
+  }
+  
+  ml_set_interrupts_enabled(intState);
 #else
 //  PE_initialize_console(0, kPEDisableScreen);
-
-	IOCPUSleepKernel();
-
+  
+  IOCPUSleepKernel();
+  
 //  PE_initialize_console(0, kPEEnableScreen);
 #endif
 }
 
-long
-IOPlatformExpert::getGMTTimeOfDay(void)
-{
-	return 0;
-}
-
-void
-IOPlatformExpert::setGMTTimeOfDay(long secs)
-{
-}
-
-
-IOReturn
-IOPlatformExpert::getConsoleInfo( PE_Video * consoleInfo )
-{
-	return PE_current_console( consoleInfo);
-}
-
-IOReturn
-IOPlatformExpert::setConsoleInfo( PE_Video * consoleInfo,
-    unsigned int op)
-{
-	return PE_initialize_console( consoleInfo, op );
-}
-
-IOReturn
-IOPlatformExpert::registerInterruptController(OSSymbol *name, IOInterruptController *interruptController)
-{
-	IOLockLock(gIOInterruptControllersLock);
-
-	gIOInterruptControllers->setObject(name, interruptController);
-
-	IOLockWakeup(gIOInterruptControllersLock,
-	    gIOInterruptControllers, /* one-thread */ false);
-
-	IOLockUnlock(gIOInterruptControllersLock);
-
-	return kIOReturnSuccess;
-}
-
-IOReturn
-IOPlatformExpert::deregisterInterruptController(OSSymbol *name)
-{
-	IOLockLock(gIOInterruptControllersLock);
-
-	gIOInterruptControllers->removeObject(name);
-
-	IOLockUnlock(gIOInterruptControllersLock);
-
-	return kIOReturnSuccess;
-}
-
-IOInterruptController *
-IOPlatformExpert::lookUpInterruptController(OSSymbol *name)
-{
-	OSObject              *object;
-
-	IOLockLock(gIOInterruptControllersLock);
-	while (1) {
-		object = gIOInterruptControllers->getObject(name);
-
-		if (object != NULL) {
-			break;
-		}
-
-		IOLockSleep(gIOInterruptControllersLock,
-		    gIOInterruptControllers, THREAD_UNINT);
-	}
-
-	IOLockUnlock(gIOInterruptControllersLock);
-	return OSDynamicCast(IOInterruptController, object);
-}
-
-
-void
-IOPlatformExpert::setCPUInterruptProperties(IOService *service)
-{
-	IOInterruptController *controller;
-
-	OSDictionary *matching = serviceMatching("IOInterruptController");
-	matching = propertyMatching(gPlatformInterruptControllerName, kOSBooleanTrue, matching);
-
-	controller = OSDynamicCast(IOInterruptController, waitForService(matching));
-	if (controller) {
-		controller->setCPUInterruptProperties(service);
-	}
-}
-
-bool
-IOPlatformExpert::atInterruptLevel(void)
-{
-	return ml_at_interrupt_context();
-}
-
-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);
+long IOPlatformExpert::getGMTTimeOfDay(void)
+{
+    return(0);
+}
+
+void IOPlatformExpert::setGMTTimeOfDay(long secs)
+{
+}
+
+
+IOReturn IOPlatformExpert::getConsoleInfo( PE_Video * consoleInfo )
+{
+    return( PE_current_console( consoleInfo));
+}
+
+IOReturn IOPlatformExpert::setConsoleInfo( PE_Video * consoleInfo,
+						unsigned int op)
+{
+    return( PE_initialize_console( consoleInfo, op ));
+}
+
+IOReturn IOPlatformExpert::registerInterruptController(OSSymbol *name, IOInterruptController *interruptController)
+{
+  IOLockLock(gIOInterruptControllersLock);
+  
+  gIOInterruptControllers->setObject(name, interruptController);
+  
+  IOLockWakeup(gIOInterruptControllersLock,
+		gIOInterruptControllers, /* one-thread */ false);
+
+  IOLockUnlock(gIOInterruptControllersLock);
+  
+  return kIOReturnSuccess;
+}
+
+IOInterruptController *IOPlatformExpert::lookUpInterruptController(OSSymbol *name)
+{
+  OSObject              *object;
+  
+  IOLockLock(gIOInterruptControllersLock);
+  while (1) {
+    
+    object = gIOInterruptControllers->getObject(name);
+    
+    if (object != 0)
+	break;
+    
+    IOLockSleep(gIOInterruptControllersLock,
+		gIOInterruptControllers, THREAD_UNINT);
+  }
+  
+  IOLockUnlock(gIOInterruptControllersLock);
+  return OSDynamicCast(IOInterruptController, object);
+}
+
+
+void IOPlatformExpert::setCPUInterruptProperties(IOService *service)
+{
+  IOCPUInterruptController *controller;
+  
+  controller = OSDynamicCast(IOCPUInterruptController, waitForService(serviceMatching("IOCPUInterruptController")));
+  if (controller) controller->setCPUInterruptProperties(service);
+}
+
+bool IOPlatformExpert::atInterruptLevel(void)
+{
+  return ml_at_interrupt_context();
+}
+
+bool IOPlatformExpert::platformAdjustService(IOService */*service*/)
+{
+  return true;
 }
 
 
@@ -509,19 +368,45 @@
 //
 //*********************************************************************************
 
-void
-IOPlatformExpert::
+void IOPlatformExpert::
 PMLog(const char *who, unsigned long event,
-    unsigned long param1, unsigned long param2)
-{
-	clock_sec_t nows;
-	clock_usec_t nowus;
+      unsigned long param1, unsigned long param2)
+{
+    UInt32 debugFlags = gIOKitDebug;
+
+    if (debugFlags & kIOLogPower) {
+
+	uint32_t nows, nowus;
 	clock_get_system_microtime(&nows, &nowus);
 	nowus += (nows % 1000) * 1000000;
 
-	kprintf("pm%u %p %.30s %d %lx %lx\n",
-	    nowus, OBFUSCATE(current_thread()), who,            // Identity
-	    (int) event, (long)OBFUSCATE(param1), (long)OBFUSCATE(param2));                     // Args
+        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);
+	}
+    }
 }
 
 
@@ -530,17 +415,17 @@
 //
 // In this vanilla implementation, a Root Power Domain is instantiated.
 // All other objects which register will be children of this Root.
-// Where this is inappropriate, PMInstantiatePowerDomains is overridden
+// Where this is inappropriate, PMInstantiatePowerDomains is overridden 
 // in a platform-specific subclass.
 //*********************************************************************************
 
-void
-IOPlatformExpert::PMInstantiatePowerDomains( void )
-{
-	root = new IOPMrootDomain;
-	root->init();
-	root->attach(this);
-	root->start(this);
+void IOPlatformExpert::PMInstantiatePowerDomains ( void )
+{
+    root = new IOPMrootDomain;
+    root->init();
+    root->attach(this);
+    root->start(this);
+    root->youAreRoot();
 }
 
 
@@ -551,10 +436,9 @@
 // Where this is inappropriate, PMRegisterDevice is overridden in a platform-specific subclass.
 //*********************************************************************************
 
-void
-IOPlatformExpert::PMRegisterDevice(IOService * theNub, IOService * theDevice)
-{
-	root->addPowerChild( theDevice );
+void IOPlatformExpert::PMRegisterDevice(IOService * theNub, IOService * theDevice)
+{
+    root->addPowerChild ( theDevice );
 }
 
 //*********************************************************************************
@@ -562,10 +446,9 @@
 //
 //*********************************************************************************
 
-bool
-IOPlatformExpert::hasPMFeature(unsigned long featureMask)
-{
-	return (_pePMFeatures & featureMask) != 0;
+bool IOPlatformExpert::hasPMFeature (unsigned long featureMask)
+{
+  return ((_pePMFeatures & featureMask) != 0);
 }
 
 //*********************************************************************************
@@ -573,10 +456,9 @@
 //
 //*********************************************************************************
 
-bool
-IOPlatformExpert::hasPrivPMFeature(unsigned long privFeatureMask)
-{
-	return (_pePrivPMFeatures & privFeatureMask) != 0;
+bool IOPlatformExpert::hasPrivPMFeature (unsigned long privFeatureMask)
+{
+  return ((_pePrivPMFeatures & privFeatureMask) != 0);
 }
 
 //*********************************************************************************
@@ -584,10 +466,9 @@
 //
 //*********************************************************************************
 
-int
-IOPlatformExpert::numBatteriesSupported(void)
-{
-	return _peNumBatteriesSupported;
+int IOPlatformExpert::numBatteriesSupported (void)
+{
+  return (_peNumBatteriesSupported);
 }
 
 //*********************************************************************************
@@ -601,102 +482,99 @@
 // registered for the given service.
 //*********************************************************************************
 
-bool
-IOPlatformExpert::CheckSubTree(OSArray * inSubTree, IOService * theNub, IOService * theDevice, OSDictionary * theParent)
-{
-	unsigned int    i;
-	unsigned int    numPowerTreeNodes;
-	OSDictionary *  entry;
-	OSDictionary *  matchingDictionary;
-	OSDictionary *  providerDictionary;
-	OSDictionary *  deviceDictionary;
-	OSDictionary *  nubDictionary;
-	OSArray *       children;
-	bool            nodeFound            = false;
-	bool            continueSearch       = false;
-	bool            deviceMatch          = false;
-	bool            providerMatch        = false;
-	bool            multiParentMatch     = false;
-
-	if ((NULL == theDevice) || (NULL == inSubTree)) {
-		return false;
-	}
-
-	numPowerTreeNodes = inSubTree->getCount();
-
-	// iterate through the power tree to find a home for this device
-
-	for (i = 0; i < numPowerTreeNodes; i++) {
-		entry =  (OSDictionary *) inSubTree->getObject(i);
-
-		matchingDictionary = (OSDictionary *) entry->getObject("device");
-		providerDictionary = (OSDictionary *) entry->getObject("provider");
-
-		deviceMatch = true; // if no matching dictionary, this is not a criteria and so must match
-		if (matchingDictionary) {
-			deviceMatch = false;
-			if (NULL != (deviceDictionary = theDevice->dictionaryWithProperties())) {
-				deviceMatch = deviceDictionary->isEqualTo( matchingDictionary, matchingDictionary );
-				deviceDictionary->release();
-			}
-		}
-
-		providerMatch = true; // we indicate a match if there is no nub or provider
-		if (theNub && providerDictionary) {
-			providerMatch = false;
-			if (NULL != (nubDictionary = theNub->dictionaryWithProperties())) {
-				providerMatch = nubDictionary->isEqualTo( providerDictionary, providerDictionary );
-				nubDictionary->release();
-			}
-		}
-
-		multiParentMatch = true; // again we indicate a match if there is no multi-parent node
-		if (deviceMatch && providerMatch) {
-			if (NULL != multipleParentKeyValue) {
-				OSNumber * aNumber = (OSNumber *) entry->getObject("multiple-parent");
-				multiParentMatch   = (NULL != aNumber) ? multipleParentKeyValue->isEqualTo(aNumber) : false;
-			}
-		}
-
-		nodeFound = (deviceMatch && providerMatch && multiParentMatch);
-
-		// if the power tree specifies a provider dictionary but theNub is
-		// NULL then we cannot match with this entry.
-
-		if (theNub == NULL && providerDictionary != NULL) {
-			nodeFound = false;
-		}
-
-		// if this node is THE ONE...then register the device
-
-		if (nodeFound) {
-			if (RegisterServiceInTree(theDevice, entry, theParent, theNub)) {
-				if (kIOLogPower & gIOKitDebug) {
-					IOLog("PMRegisterDevice/CheckSubTree - service registered!\n");
-				}
-
-				numInstancesRegistered++;
-
-				// determine if we need to search for additional nodes for this item
-				multipleParentKeyValue = (OSNumber *) entry->getObject("multiple-parent");
-			} else {
-				nodeFound = false;
-			}
-		}
-
-		continueSearch = ((false == nodeFound) || (NULL != multipleParentKeyValue));
-
-		if (continueSearch && (NULL != (children = (OSArray *) entry->getObject("children")))) {
-			nodeFound = CheckSubTree( children, theNub, theDevice, entry );
-			continueSearch = ((false == nodeFound) || (NULL != multipleParentKeyValue));
-		}
-
-		if (false == continueSearch) {
-			break;
-		}
-	}
-
-	return nodeFound;
+bool IOPlatformExpert::CheckSubTree (OSArray * inSubTree, IOService * theNub, IOService * theDevice, OSDictionary * theParent)
+{
+  unsigned int    i;
+  unsigned int    numPowerTreeNodes;
+  OSDictionary *  entry;
+  OSDictionary *  matchingDictionary;
+  OSDictionary *  providerDictionary;
+  OSDictionary *  deviceDictionary;
+  OSDictionary *  nubDictionary;
+  OSArray *       children;
+  bool            nodeFound            = false;
+  bool            continueSearch       = false;
+  bool            deviceMatch          = false;
+  bool            providerMatch        = false;
+  bool            multiParentMatch     = false;
+
+  if ( (NULL == theDevice) || (NULL == inSubTree) )
+    return false;
+
+  numPowerTreeNodes = inSubTree->getCount ();
+
+  // iterate through the power tree to find a home for this device
+
+  for ( i = 0; i < numPowerTreeNodes; i++ ) {
+
+    entry =  (OSDictionary *) inSubTree->getObject (i);
+
+    matchingDictionary = (OSDictionary *) entry->getObject ("device");
+    providerDictionary = (OSDictionary *) entry->getObject ("provider");
+
+    deviceMatch = true; // if no matching dictionary, this is not a criteria and so must match
+    if ( matchingDictionary ) {
+      deviceMatch = false;
+      if ( NULL != (deviceDictionary = theDevice->dictionaryWithProperties ())) {
+        deviceMatch = deviceDictionary->isEqualTo ( matchingDictionary, matchingDictionary );
+        deviceDictionary->release ();
+      }
+    }
+
+    providerMatch = true; // we indicate a match if there is no nub or provider
+    if ( theNub && providerDictionary ) {
+      providerMatch = false;
+      if ( NULL != (nubDictionary = theNub->dictionaryWithProperties ()) ) {
+        providerMatch = nubDictionary->isEqualTo ( providerDictionary,  providerDictionary );
+        nubDictionary->release ();
+      }
+    }
+
+    multiParentMatch = true; // again we indicate a match if there is no multi-parent node
+    if (deviceMatch && providerMatch) {
+      if (NULL != multipleParentKeyValue) {
+        OSNumber * aNumber = (OSNumber *) entry->getObject ("multiple-parent");
+        multiParentMatch   = (NULL != aNumber) ? multipleParentKeyValue->isEqualTo (aNumber) : false;
+      }
+    }
+
+    nodeFound = (deviceMatch && providerMatch && multiParentMatch);
+
+    // if the power tree specifies a provider dictionary but theNub is
+    // NULL then we cannot match with this entry.
+
+    if ( theNub == NULL && providerDictionary != NULL )
+      nodeFound = false;
+  
+    // if this node is THE ONE...then register the device
+
+    if ( nodeFound ) {
+      if (RegisterServiceInTree (theDevice, entry, theParent, theNub) ) {
+
+        if ( kIOLogPower & gIOKitDebug)
+          IOLog ("PMRegisterDevice/CheckSubTree - service registered!\n");
+
+	numInstancesRegistered++;
+
+	// determine if we need to search for additional nodes for this item
+	multipleParentKeyValue = (OSNumber *) entry->getObject ("multiple-parent");
+      }
+      else
+	nodeFound = false;
+    }
+
+    continueSearch = ( (false == nodeFound) || (NULL != multipleParentKeyValue) );
+
+    if ( continueSearch && (NULL != (children = (OSArray *) entry->getObject ("children"))) ) {
+      nodeFound = CheckSubTree ( children, theNub, theDevice, entry );
+      continueSearch = ( (false == nodeFound) || (NULL != multipleParentKeyValue) );
+    }
+
+    if ( false == continueSearch )
+      break;
+  }
+
+  return ( nodeFound );
 }
 
 //*********************************************************************************
@@ -705,53 +583,51 @@
 // Register a device at the specified node of our power tree.
 //*********************************************************************************
 
-bool
-IOPlatformExpert::RegisterServiceInTree(IOService * theService, OSDictionary * theTreeNode, OSDictionary * theTreeParentNode, IOService * theProvider)
-{
-	IOService *    aService;
-	bool           registered = false;
-	OSArray *      children;
-	unsigned int   numChildren;
-	OSDictionary * child;
-
-	// make sure someone is not already registered here
-
-	if (NULL == theTreeNode->getObject("service")) {
-		if (theTreeNode->setObject("service", OSDynamicCast( OSObject, theService))) {
-			// 1. CHILDREN ------------------
-
-			// we registered the node in the tree...now if the node has children
-			// registered we must tell this service to add them.
-
-			if (NULL != (children = (OSArray *) theTreeNode->getObject("children"))) {
-				numChildren = children->getCount();
-				for (unsigned int i = 0; i < numChildren; i++) {
-					if (NULL != (child = (OSDictionary *) children->getObject(i))) {
-						if (NULL != (aService = (IOService *) child->getObject("service"))) {
-							theService->addPowerChild(aService);
-						}
-					}
-				}
-			}
-
-			// 2. PARENT --------------------
-
-			// also we must notify the parent of this node (if a registered service
-			// exists there) of a new child.
-
-			if (theTreeParentNode) {
-				if (NULL != (aService = (IOService *) theTreeParentNode->getObject("service"))) {
-					if (aService != theProvider) {
-						aService->addPowerChild(theService);
-					}
-				}
-			}
-
-			registered = true;
-		}
-	}
-
-	return registered;
+bool IOPlatformExpert::RegisterServiceInTree (IOService * theService, OSDictionary * theTreeNode, OSDictionary * theTreeParentNode, IOService * theProvider)
+{
+  IOService *    aService;
+  bool           registered = false;
+  OSArray *      children;
+  unsigned int   numChildren;
+  OSDictionary * child;
+
+  // make sure someone is not already registered here
+
+  if ( NULL == theTreeNode->getObject ("service") ) {
+
+    if ( theTreeNode->setObject ("service", OSDynamicCast ( OSObject, theService)) ) {
+
+      // 1. CHILDREN ------------------
+
+      // we registered the node in the tree...now if the node has children
+      // registered we must tell this service to add them.
+
+      if ( NULL != (children = (OSArray *) theTreeNode->getObject ("children")) ) {
+        numChildren = children->getCount ();
+        for ( unsigned int i = 0; i < numChildren; i++ ) {
+          if ( NULL != (child = (OSDictionary *) children->getObject (i)) ) {
+            if ( NULL != (aService = (IOService *) child->getObject ("service")) )
+              theService->addPowerChild (aService);
+          }
+        }
+      }
+
+      // 2. PARENT --------------------
+
+      // also we must notify the parent of this node (if a registered service
+      // exists there) of a new child.
+
+      if ( theTreeParentNode ) {
+        if ( NULL != (aService = (IOService *) theTreeParentNode->getObject ("service")) )
+          if (aService != theProvider)
+            aService->addPowerChild (theService);
+      }
+
+      registered = true;
+    }
+  }
+
+  return registered;
 }
 
 //*********************************************************************************
@@ -759,838 +635,234 @@
 //
 // Print the keys for the given dictionary and selected contents.
 //*********************************************************************************
-void
-printDictionaryKeys(OSDictionary * inDictionary, char * inMsg)
-{
-	OSCollectionIterator * mcoll = OSCollectionIterator::withCollection(inDictionary);
-	OSSymbol * mkey;
-	OSString * ioClass;
-	unsigned int i = 0;
-
-	mcoll->reset();
-
-	mkey = OSDynamicCast(OSSymbol, mcoll->getNextObject());
-
-	while (mkey) {
-		// kprintf ("dictionary key #%d: %s\n", i, mkey->getCStringNoCopy () );
-
-		// if this is the IOClass key, print it's contents
-
-		if (mkey->isEqualTo("IOClass")) {
-			ioClass = (OSString *) inDictionary->getObject("IOClass");
-			if (ioClass) {
-				IOLog("%s IOClass is %s\n", inMsg, ioClass->getCStringNoCopy());
-			}
-		}
-
-		// if this is an IOProviderClass key print it
-
-		if (mkey->isEqualTo("IOProviderClass")) {
-			ioClass = (OSString *) inDictionary->getObject("IOProviderClass");
-			if (ioClass) {
-				IOLog("%s IOProviderClass is %s\n", inMsg, ioClass->getCStringNoCopy());
-			}
-		}
-
-		// also print IONameMatch keys
-		if (mkey->isEqualTo("IONameMatch")) {
-			ioClass = (OSString *) inDictionary->getObject("IONameMatch");
-			if (ioClass) {
-				IOLog("%s IONameMatch is %s\n", inMsg, ioClass->getCStringNoCopy());
-			}
-		}
-
-		// also print IONameMatched keys
-
-		if (mkey->isEqualTo("IONameMatched")) {
-			ioClass = (OSString *) inDictionary->getObject("IONameMatched");
-			if (ioClass) {
-				IOLog("%s IONameMatched is %s\n", inMsg, ioClass->getCStringNoCopy());
-			}
-		}
+void printDictionaryKeys (OSDictionary * inDictionary, char * inMsg)
+{
+  OSCollectionIterator * mcoll = OSCollectionIterator::withCollection (inDictionary);
+  OSSymbol * mkey;
+  OSString * ioClass;
+  unsigned int i = 0;
+ 
+  mcoll->reset ();
+
+  mkey = OSDynamicCast (OSSymbol, mcoll->getNextObject ());
+
+  while (mkey) {
+
+    // kprintf ("dictionary key #%d: %s\n", i, mkey->getCStringNoCopy () );
+
+    // if this is the IOClass key, print it's contents
+
+    if ( mkey->isEqualTo ("IOClass") ) {
+      ioClass = (OSString *) inDictionary->getObject ("IOClass");
+      if ( ioClass ) IOLog ("%s IOClass is %s\n", inMsg, ioClass->getCStringNoCopy () );
+    }
+
+    // if this is an IOProviderClass key print it
+
+    if ( mkey->isEqualTo ("IOProviderClass") ) {
+      ioClass = (OSString *) inDictionary->getObject ("IOProviderClass");
+      if ( ioClass ) IOLog ("%s IOProviderClass is %s\n", inMsg, ioClass->getCStringNoCopy () );
+
+    }
+
+    // also print IONameMatch keys
+    if ( mkey->isEqualTo ("IONameMatch") ) {
+      ioClass = (OSString *) inDictionary->getObject ("IONameMatch");
+      if ( ioClass ) IOLog ("%s IONameMatch is %s\n", inMsg, ioClass->getCStringNoCopy () );
+    }
+
+    // also print IONameMatched keys
+
+    if ( mkey->isEqualTo ("IONameMatched") ) {
+      ioClass = (OSString *) inDictionary->getObject ("IONameMatched");
+      if ( ioClass ) IOLog ("%s IONameMatched is %s\n", inMsg, ioClass->getCStringNoCopy () );
+    }
 
 #if 0
-		// print clock-id
-
-		if (mkey->isEqualTo("AAPL,clock-id")) {
-			char * cstr;
-			cstr = getCStringForObject(inDictionary->getObject("AAPL,clock-id"));
-			if (cstr) {
-				kprintf(" ===> AAPL,clock-id is %s\n", cstr );
-			}
-		}
+    // print clock-id
+
+    if ( mkey->isEqualTo ("AAPL,clock-id") ) {
+      char * cstr;
+      cstr = getCStringForObject (inDictionary->getObject ("AAPL,clock-id"));
+      if (cstr)
+        kprintf (" ===> AAPL,clock-id is %s\n", cstr );
+    }
 #endif
 
-		// print name
-
-		if (mkey->isEqualTo("name")) {
-			char nameStr[64];
-			nameStr[0] = 0;
-			getCStringForObject(inDictionary->getObject("name"), nameStr,
-			    sizeof(nameStr));
-			if (strlen(nameStr) > 0) {
-				IOLog("%s name is %s\n", inMsg, nameStr);
-			}
-		}
-
-		mkey = (OSSymbol *) mcoll->getNextObject();
-
-		i++;
-	}
-
-	mcoll->release();
-}
-
-static void
-getCStringForObject(OSObject *inObj, char *outStr, size_t outStrLen)
-{
-	char * buffer;
-	unsigned int    len, i;
-
-	if ((NULL == inObj) || (NULL == outStr)) {
-		return;
-	}
-
-	char * objString = (char *) (inObj->getMetaClass())->getClassName();
-
-	if ((0 == strncmp(objString, "OSString", sizeof("OSString"))) ||
-	    (0 == strncmp(objString, "OSSymbol", sizeof("OSSymbol")))) {
-		strlcpy(outStr, ((OSString *)inObj)->getCStringNoCopy(), outStrLen);
-	} else if (0 == strncmp(objString, "OSData", sizeof("OSData"))) {
-		len = ((OSData *)inObj)->getLength();
-		buffer = (char *)((OSData *)inObj)->getBytesNoCopy();
-		if (buffer && (len > 0)) {
-			for (i = 0; i < len; i++) {
-				outStr[i] = buffer[i];
-			}
-			outStr[len] = 0;
-		}
-	}
-}
-
-/* IOShutdownNotificationsTimedOut
+    // print name
+
+    if ( mkey->isEqualTo ("name") ) {
+      char nameStr[64];
+      nameStr[0] = 0;
+      getCStringForObject (inDictionary->getObject ("name"), nameStr );
+      if (strlen(nameStr) > 0)
+        IOLog ("%s name is %s\n", inMsg, nameStr);
+    }
+
+    mkey = (OSSymbol *) mcoll->getNextObject ();
+
+    i++;
+  }
+
+  mcoll->release ();
+}
+
+static void getCStringForObject (OSObject * inObj, char * outStr)
+{
+   char * buffer;
+   unsigned int    len, i;
+
+   if ( (NULL == inObj) || (NULL == outStr))
+     return;
+
+   char * objString = (char *) (inObj->getMetaClass())->getClassName();
+
+   if ((0 == strcmp(objString,"OSString")) || (0 == strcmp (objString, "OSSymbol")))
+     strcpy (outStr, ((OSString *)inObj)->getCStringNoCopy());
+
+   else if (0 == strcmp(objString,"OSData")) {
+     len = ((OSData *)inObj)->getLength();
+     buffer = (char *)((OSData *)inObj)->getBytesNoCopy();
+     if (buffer && (len > 0)) {
+       for (i=0; i < len; i++) {
+         outStr[i] = buffer[i];
+       }
+       outStr[len] = 0;
+     }
+   }
+}
+
+/* IOPMPanicOnShutdownHang
  * - Called from a timer installed by PEHaltRestart
  */
-#if !defined(__x86_64)
-__abortlike
-#endif
-static void
-IOShutdownNotificationsTimedOut(
-	thread_call_param_t p0,
-	thread_call_param_t p1)
-{
-#if !defined(__x86_64__)
-	/* 30 seconds has elapsed - panic */
-	panic("Halt/Restart Timed Out");
-
-#else /* !defined(__x86_64__) */
-	int type = (int)(long)p0;
-	uint32_t timeout = (uint32_t)(uintptr_t)p1;
-
-	IOPMrootDomain *pmRootDomain = IOService::getPMRootDomain();
-	if (pmRootDomain) {
-		if ((PEGetCoprocessorVersion() >= kCoprocessorVersion2) || pmRootDomain->checkShutdownTimeout()) {
-			pmRootDomain->panicWithShutdownLog(timeout * 1000);
-		}
-	}
-
-	/* 30 seconds has elapsed - resume shutdown */
-	if (gIOPlatform) {
-		gIOPlatform->haltRestart(type);
-	}
-#endif /* defined(__x86_64__) */
+static void IOPMPanicOnShutdownHang(thread_call_param_t p0, thread_call_param_t p1)
+{
+    int type = (int)p0;
+
+    /* 30 seconds has elapsed - resume shutdown */
+    gIOPlatform->haltRestart(type);
 }
 
 
 extern "C" {
+
 /*
  * Callouts from BSD for machine name & model
- */
-
-/*
- * PEGetMachineName() and PEGetModelName() are inconsistent across
- * architectures, and considered deprecated. Use PEGetTargetName() and
- * PEGetProductName() instead.
- */
-boolean_t
-PEGetMachineName( char * name, int maxLength )
-{
-	if (gIOPlatform) {
-		return gIOPlatform->getMachineName( name, maxLength );
-	} else {
-		return false;
-	}
-}
-
-/*
- * PEGetMachineName() and PEGetModelName() are inconsistent across
- * architectures, and considered deprecated. Use PEGetTargetName() and
- * PEGetProductName() instead.
- */
-boolean_t
-PEGetModelName( char * name, int maxLength )
-{
-	if (gIOPlatform) {
-		return gIOPlatform->getModelName( name, maxLength );
-	} else {
-		return false;
-	}
-}
-
-boolean_t
-PEGetTargetName( char * name, int maxLength )
-{
-	if (gIOPlatform) {
-		return gIOPlatform->getTargetName( name, maxLength );
-	} else {
-		return false;
-	}
-}
-
-boolean_t
-PEGetProductName( char * name, int maxLength )
-{
-	if (gIOPlatform) {
-		return gIOPlatform->getProductName( name, maxLength );
-	} else {
-		return false;
-	}
-}
-
-int
-PEGetPlatformEpoch(void)
-{
-	if (gIOPlatform) {
-		return (int) gIOPlatform->getBootROMType();
-	} else {
-		return -1;
-	}
-}
-
-#if defined(__arm64__)
-__attribute__((noinline))
-static void
-force_hard_hang_if_transaction_pending(void)
-{
-	/*
-	 * Intentionally force a hang if all CPUs cannot complete it
-	 * so that we get an AP watchdog hang *here*  instead of later in the panic flow.
-	 */
-	arm64_sync_tlb(true);
-}
-#endif // defined(__arm64__)
-
-/* Handle necessary platform specific actions prior to panic */
-void
-PEInitiatePanic(void)
-{
-#if defined(__arm64__)
-	/*
-	 * Trigger a TLB flush so any hard hangs exercise the SoC diagnostic
-	 * collection flow rather than hanging late in panic (see rdar://58062030)
-	 */
-	flush_mmu_tlb_entries_async(0, PAGE_SIZE, PAGE_SIZE, true, true);
-	force_hard_hang_if_transaction_pending();
-#endif // defined(__arm64__)
-}
-
-int
-PEHaltRestartInternal(unsigned int type, uint32_t details)
-{
-	IOPMrootDomain    *pmRootDomain;
-	AbsoluteTime      deadline;
-	thread_call_t     shutdown_hang;
-	IORegistryEntry   *node;
-	OSData            *data;
-	uint32_t          timeout = kShutdownTimeout;
-	static boolean_t  panic_begin_called = FALSE;
-
-	if (type == kPEHaltCPU || type == kPERestartCPU || type == kPEUPSDelayHaltCPU) {
-		/* If we're in the panic path, the locks and memory allocations required below
-		 *  could fail. So just try to reboot instead of risking a nested panic.
-		 */
-		if (panic_begin_called) {
-			goto skip_to_haltRestart;
-		}
-
-		pmRootDomain = IOService::getPMRootDomain();
-		/* Notify IOKit PM clients of shutdown/restart
-		 *  Clients subscribe to this message with a call to
-		 *  IOService::registerInterest()
-		 */
-
-		/* Spawn a thread that will panic in 30 seconds.
-		 *  If all goes well the machine will be off by the time
-		 *  the timer expires. If the device wants a different
-		 *  timeout, use that value instead of 30 seconds.
-		 */
-#if  defined(__arm64__)
-#define RESTART_NODE_PATH    "/defaults"
-#else
-#define RESTART_NODE_PATH    "/chosen"
-#endif
-		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());
-			}
-			OSSafeReleaseNULL(node);
-		}
-
-#if (DEVELOPMENT || DEBUG)
-		/* Override the default timeout via a boot-arg */
-		uint32_t boot_arg_val;
-		if (PE_parse_boot_argn("halt_restart_timeout", &boot_arg_val, sizeof(boot_arg_val))) {
-			timeout = boot_arg_val;
-		}
-#endif
-
-		if (timeout) {
-			shutdown_hang = thread_call_allocate( &IOShutdownNotificationsTimedOut,
-			    (thread_call_param_t)(uintptr_t) type);
-			clock_interval_to_deadline( timeout, kSecondScale, &deadline );
-			thread_call_enter1_delayed( shutdown_hang, (thread_call_param_t)(uintptr_t)timeout, deadline );
-		}
-
-		pmRootDomain->handlePlatformHaltRestart(type);
-		/* This notification should have few clients who all do
-		 *  their work synchronously.
-		 *
-		 *  In this "shutdown notification" context we don't give
-		 *  drivers the option of working asynchronously and responding
-		 *  later. PM internals make it very hard to wait for asynchronous
-		 *  replies.
-		 */
-	} else if (type == kPEPanicRestartCPU || type == kPEPanicSync || type == kPEPanicRestartCPUNoCallouts) {
-		if (type == kPEPanicRestartCPU) {
-			// Notify any listeners that we're done collecting
-			// panic data before we call through to do the restart
-#if defined(__x86_64__)
-			if (coprocessor_cross_panic_enabled)
-#endif
-			IOCPURunPlatformPanicActions(kPEPanicEnd, details);
-		} else if (type == kPEPanicRestartCPUNoCallouts) {
-			// We skipped the callouts so now set the type to
-			// the variant that the platform uses for panic restarts.
-			type = kPEPanicRestartCPU;
-		}
-
-
-		// Do an initial sync to flush as much panic data as possible,
-		// in case we have a problem in one of the platorm panic handlers.
-		// After running the platform handlers, do a final sync w/
-		// platform hardware quiesced for the panic.
-		PE_sync_panic_buffers();
-		IOCPURunPlatformPanicActions(type, details);
-		PE_sync_panic_buffers();
-	} else if (type == kPEPanicEnd) {
-#if defined(__x86_64__)
-		if (coprocessor_cross_panic_enabled)
-#endif
-		IOCPURunPlatformPanicActions(type, details);
-	} else if (type == kPEPanicBegin) {
-#if defined(__x86_64__)
-		if (coprocessor_cross_panic_enabled)
-#endif
-		{
-			// Only call the kPEPanicBegin callout once
-			if (!panic_begin_called) {
-				panic_begin_called = TRUE;
-				IOCPURunPlatformPanicActions(type, details);
-			}
-		}
-	} else if (type == kPEPanicDiagnosticsDone || type == kPEPanicDiagnosticsInProgress) {
-		IOCPURunPlatformPanicActions(type, details);
-	}
-
-skip_to_haltRestart:
-	if (gIOPlatform) {
-		// note that this will not necessarily halt or restart the system...
-		// Implementors of this function will check the type and take action accordingly
-		return gIOPlatform->haltRestart(type);
-	} else {
-		return -1;
-	}
-}
-
-int
-PEHaltRestart(unsigned int type)
-{
-	return PEHaltRestartInternal(type, 0);
-}
-
-UInt32
-PESavePanicInfo(UInt8 *buffer, UInt32 length)
-{
-	if (gIOPlatform != NULL) {
-		return (UInt32) gIOPlatform->savePanicInfo(buffer, length);
-	} else {
-		return 0;
-	}
-}
-
-void
-PESavePanicInfoAction(void *buffer, UInt32 offset, UInt32 length)
-{
-	IOCPURunPlatformPanicSyncAction(buffer, offset, length);
-	return;
-}
-
-
-/*
- * Depending on the platform, the /options node may not be created
- * until after IOKit matching has started, by an externally-supplied
- * platform expert subclass.  Therefore, we must check for its presence
- * here and update gIOOptionsEntry for the platform code as necessary.
- */
-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  = IOMin(vlen, *len);
-	if (value && vlen) {
-		memcpy((void *) value, data->getBytesNoCopy(), vlen);
-	}
-
-	return TRUE;
-
-err:
-	return FALSE;
-}
-
-boolean_t
-PEReadNVRAMBooleanProperty(const char *symbol, boolean_t *value)
-{
-	OSObject  *obj;
-	OSBoolean *data;
-
-	if (!symbol || !value) {
-		goto err;
-	}
-
-	if (init_gIOOptionsEntry() < 0) {
-		goto err;
-	}
-
-	obj = gIOOptionsEntry->getProperty(symbol);
-	if (!obj) {
-		return TRUE;
-	}
-
-	/* convert to bool */
-	data = OSDynamicCast(OSBoolean, obj);
-	if (!data) {
-		goto err;
-	}
-
-	*value = data->isTrue() ? TRUE : FALSE;
-
-	return TRUE;
-
-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;
-}
-
-static boolean_t
-PEWriteNVRAMPropertyInternal(const char *symbol, boolean_t copySymbol, 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;
-	}
-
-	if (copySymbol == TRUE) {
-		sym = OSSymbol::withCString(symbol);
-	} else {
-		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;
-}
-
-boolean_t
-PEWriteNVRAMProperty(const char *symbol, const void *value,
-    const unsigned int len)
-{
-	return PEWriteNVRAMPropertyInternal(symbol, FALSE, value, len);
-}
-
-boolean_t
-PEWriteNVRAMPropertyWithCopy(const char *symbol, const void *value,
-    const unsigned int len)
-{
-	return PEWriteNVRAMPropertyInternal(symbol, TRUE, value, len);
-}
-
-boolean_t
-PERemoveNVRAMProperty(const char *symbol)
-{
-	const OSSymbol *sym;
-
-	if (!symbol) {
-		goto err;
-	}
-
-	if (init_gIOOptionsEntry() < 0) {
-		goto err;
-	}
-
-	sym = OSSymbol::withCStringNoCopy(symbol);
-	if (!sym) {
-		goto err;
-	}
-
-	gIOOptionsEntry->removeProperty(sym);
-
-	sym->release();
-
-	gIOOptionsEntry->sync();
-	return TRUE;
-
-err:
-	return FALSE;
-}
-
-boolean_t
-PESyncNVRAM(void)
-{
-	if (gIOOptionsEntry != nullptr) {
-		gIOOptionsEntry->sync();
-	}
-
-	return TRUE;
-}
-
-long
-PEGetGMTTimeOfDay(void)
-{
-	clock_sec_t     secs;
-	clock_usec_t    usecs;
-
-	PEGetUTCTimeOfDay(&secs, &usecs);
-	return secs;
-}
-
-void
-PESetGMTTimeOfDay(long 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);
-	}
-}
-
-coprocessor_type_t
-PEGetCoprocessorVersion( void )
-{
-	coprocessor_type_t coprocessor_version = kCoprocessorVersionNone;
-#if defined(__x86_64__)
-	IORegistryEntry     *platform_entry = NULL;
-	OSData              *coprocessor_version_obj = NULL;
-
-	platform_entry = IORegistryEntry::fromPath(kIODeviceTreePlane ":/efi/platform");
-	if (platform_entry != NULL) {
-		coprocessor_version_obj = OSDynamicCast(OSData, platform_entry->getProperty("apple-coprocessor-version"));
-		if ((coprocessor_version_obj != NULL) && (coprocessor_version_obj->getLength() <= sizeof(uint64_t))) {
-			memcpy(&coprocessor_version, coprocessor_version_obj->getBytesNoCopy(), coprocessor_version_obj->getLength());
-		}
-		platform_entry->release();
-	}
-#endif
-	return coprocessor_version;
-}
+ */ 
+
+boolean_t PEGetMachineName( char * name, int maxLength )
+{
+    if( gIOPlatform)
+	return( gIOPlatform->getMachineName( name, maxLength ));
+    else
+	return( false );
+}
+
+boolean_t PEGetModelName( char * name, int maxLength )
+{
+    if( gIOPlatform)
+	return( gIOPlatform->getModelName( name, maxLength ));
+    else
+	return( false );
+}
+
+int PEGetPlatformEpoch(void)
+{
+    if( gIOPlatform)
+	return( gIOPlatform->getBootROMType());
+    else
+	return( -1 );
+}
+
+int PEHaltRestart(unsigned int type)
+{
+  IOPMrootDomain    *pmRootDomain = IOService::getPMRootDomain();
+  bool              noWaitForResponses;
+  AbsoluteTime      deadline;
+  thread_call_t     shutdown_hang;
+  
+  if(type == kPEHaltCPU || type == kPERestartCPU)
+  {
+    /* Notify IOKit PM clients of shutdown/restart
+       Clients subscribe to this message with a call to
+       IOService::registerInterest()
+    */
+    
+    /* Spawn a thread that will panic in 30 seconds. 
+       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);
+    clock_interval_to_deadline( 30, kSecondScale, &deadline );
+    thread_call_enter1_delayed( shutdown_hang, 0, deadline );
+    
+    noWaitForResponses = pmRootDomain->tellChangeDown2(type); 
+    /* This notification should have few clients who all do 
+       their work synchronously.
+             
+       In this "shutdown notification" context we don't give
+       drivers the option of working asynchronously and responding 
+       later. PM internals make it very hard to wait for asynchronous
+       replies. In fact, it's a bad idea to even be calling
+       tellChangeDown2 from here at all.
+     */
+   }
+
+  if (gIOPlatform) return gIOPlatform->haltRestart(type);
+  else return -1;
+}
+
+UInt32 PESavePanicInfo(UInt8 *buffer, UInt32 length)
+{
+  if (gIOPlatform != 0) return gIOPlatform->savePanicInfo(buffer, length);
+  else return 0;
+}
+
+long PEGetGMTTimeOfDay(void)
+{
+    if( gIOPlatform)
+	return( gIOPlatform->getGMTTimeOfDay());
+    else
+	return( 0 );
+}
+
+void PESetGMTTimeOfDay(long secs)
+{
+    if( gIOPlatform)
+	gIOPlatform->setGMTTimeOfDay(secs);
+}
+
 } /* extern "C" */
 
-bool gIOPlatformUUIDAndSerialDone = false;
-
-void
-IOPlatformExpert::publishPlatformUUIDAndSerial( void )
-{
-	if (!gIOPlatformUUIDAndSerialDone) {
-		// Parse the serial-number data and publish a user-readable string
-		if (NULL == getProvider()->getProperty(kIOPlatformSerialNumberKey)) {
-			OSData* mydata = (OSData*) (getProvider()->getProperty("serial-number"));
-			if (mydata != NULL) {
-				OSString *serNoString = createSystemSerialNumberString(mydata);
-				if (serNoString != NULL) {
-					getProvider()->setProperty(kIOPlatformSerialNumberKey, serNoString);
-					serNoString->release();
-				}
-			}
-		}
-		IOPlatformExpertDevice *provider = OSDynamicCast(IOPlatformExpertDevice, getProvider());
-		assert(provider != NULL);
-		provider->generatePlatformUUID();
-	}
-
-	if (gIOPlatformUUIDAndSerialDone) {
-		publishResource(kIOPlatformUUIDKey, getProvider()->getProperty(kIOPlatformUUIDKey));
-	}
-}
-
-void
-IOPlatformExpert::publishNVRAM( void )
-{
-	if (init_gIOOptionsEntry() < 0) {
-		IOPlatformExpertDevice *provider = OSDynamicCast(IOPlatformExpertDevice, getProvider());
-		assert(provider != NULL);
-		provider->createNVRAM();
-	}
-	if (gIOOptionsEntry != NULL) {
-		gIOOptionsEntry->registerService();
-	}
-}
-
-void
-IOPlatformExpert::registerNVRAMController(IONVRAMController * caller)
-{
-#if defined(__x86_64__)
-	OSData *          data;
-	IORegistryEntry * entry;
-
-	/*
-	 * If we have panic debugging enabled WITHOUT behavior to reboot after any crash (DB_REBOOT_ALWAYS)
-	 * and we are on a co-processor system that has the panic SoC watchdog enabled, disable
-	 * cross panics so that the co-processor doesn't cause the system
-	 * to reset when we enter the debugger or hit a panic on the x86 side.
-	 */
-	if (panicDebugging && !(debug_boot_arg & DB_REBOOT_ALWAYS)) {
-		entry = IORegistryEntry::fromPath( "/options", gIODTPlane );
-		if (entry) {
-			data = OSDynamicCast( OSData, entry->getProperty( APPLE_VENDOR_VARIABLE_GUID":BridgeOSPanicWatchdogEnabled" ));
-			if (data && (data->getLength() == sizeof(UInt8))) {
-				UInt8 *panicWatchdogEnabled = (UInt8 *) data->getBytesNoCopy();
-				UInt32 debug_flags = 0;
-				if (*panicWatchdogEnabled || (PE_i_can_has_debugger(&debug_flags) &&
-				    (debug_flags & DB_DISABLE_CROSS_PANIC))) {
-					coprocessor_cross_panic_enabled = FALSE;
-				}
-			}
-			entry->release();
-		}
-	}
-
-#if (DEVELOPMENT || DEBUG)
-	entry = IORegistryEntry::fromPath( "/options", gIODTPlane );
-	if (entry) {
-		data = OSDynamicCast( OSData, entry->getProperty(nvram_osenvironment));
-		if (data) {
-			sysctl_set_osenvironment(data->getLength(), data->getBytesNoCopy());
-			entry->removeProperty(nvram_osenvironment);
-			IODTNVRAM * nvramOptionsEntry = OSDynamicCast(IODTNVRAM, entry);
-			if (nvramOptionsEntry) {
-				nvramOptionsEntry->sync();
-			}
-		}
-		entry->release();
-	}
-	sysctl_unblock_osenvironment();
-#endif
-	/* on intel the UUID must be published after nvram is available */
-	publishPlatformUUIDAndSerial();
-
-#endif /* defined(__x86_64__) */
-
-	publishResource("IONVRAM");
-}
-
-IOReturn
-IOPlatformExpert::callPlatformFunction(const OSSymbol *functionName,
-    bool waitForFunction,
-    void *param1, void *param2,
-    void *param3, void *param4)
-{
-	IOService *service, *_resources;
-	OSObject  *prop = NULL;
-	IOReturn   ret;
-
-	if (functionName == gIOPlatformQuiesceActionKey ||
-	    functionName == gIOPlatformActiveActionKey ||
-	    functionName == gIOPlatformPanicActionKey) {
-		/*
-		 * Services which register for IOPlatformQuiesceAction / IOPlatformActiveAction / IOPlatformPanicAction
-		 * must consume that event themselves, without passing it up to super/IOPlatformExpert.
-		 */
-		if (gEnforcePlatformActionSafety) {
-			panic("Class %s passed the %s action to IOPlatformExpert",
-			    getMetaClass()->getClassName(), functionName->getCStringNoCopy());
-		}
-	}
-
-	if (waitForFunction) {
-		_resources = waitForService(resourceMatching(functionName));
-	} else {
-		_resources = getResourceService();
-	}
-	if (_resources == NULL) {
-		return kIOReturnUnsupported;
-	}
-
-	prop = _resources->copyProperty(functionName);
-	service = OSDynamicCast(IOService, prop);
-	if (service == NULL) {
-		ret = kIOReturnUnsupported;
-		goto finish;
-	}
-
-	ret = service->callPlatformFunction(functionName, waitForFunction,
-	    param1, param2, param3, param4);
-
-finish:
-	OSSafeReleaseNULL(prop);
-	return ret;
-}
-
-IOByteCount
-IOPlatformExpert::savePanicInfo(UInt8 *buffer, IOByteCount length)
-{
-	return 0;
+void IOPlatformExpert::registerNVRAMController(IONVRAMController * caller)
+{
+    publishResource("IONVRAM");
+}
+
+IOReturn IOPlatformExpert::callPlatformFunction(const OSSymbol *functionName,
+						bool waitForFunction,
+						void *param1, void *param2,
+						void *param3, void *param4)
+{
+  IOService *service, *_resources;
+  
+  if (waitForFunction) {
+    _resources = waitForService(resourceMatching(functionName));
+  } else {
+    _resources = resources();
+  }
+  if (_resources == 0) return kIOReturnUnsupported;
+  
+  service = OSDynamicCast(IOService, _resources->getProperty(functionName));
+  if (service == 0) return kIOReturnUnsupported;
+  
+  return service->callPlatformFunction(functionName, waitForFunction,
+				       param1, param2, param3, param4);
+}
+
+IOByteCount IOPlatformExpert::savePanicInfo(UInt8 *buffer, IOByteCount length)
+{
+  return 0;
 }
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -1600,462 +872,291 @@
 
 OSDefineMetaClassAndAbstractStructors( IODTPlatformExpert, IOPlatformExpert )
 
-OSMetaClassDefineReservedUnused(IODTPlatformExpert, 0);
-OSMetaClassDefineReservedUnused(IODTPlatformExpert, 1);
-OSMetaClassDefineReservedUnused(IODTPlatformExpert, 2);
-OSMetaClassDefineReservedUnused(IODTPlatformExpert, 3);
-OSMetaClassDefineReservedUnused(IODTPlatformExpert, 4);
-OSMetaClassDefineReservedUnused(IODTPlatformExpert, 5);
-OSMetaClassDefineReservedUnused(IODTPlatformExpert, 6);
-OSMetaClassDefineReservedUnused(IODTPlatformExpert, 7);
+OSMetaClassDefineReservedUnused(IODTPlatformExpert,  0);
+OSMetaClassDefineReservedUnused(IODTPlatformExpert,  1);
+OSMetaClassDefineReservedUnused(IODTPlatformExpert,  2);
+OSMetaClassDefineReservedUnused(IODTPlatformExpert,  3);
+OSMetaClassDefineReservedUnused(IODTPlatformExpert,  4);
+OSMetaClassDefineReservedUnused(IODTPlatformExpert,  5);
+OSMetaClassDefineReservedUnused(IODTPlatformExpert,  6);
+OSMetaClassDefineReservedUnused(IODTPlatformExpert,  7);
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
-IOService *
-IODTPlatformExpert::probe( IOService * provider,
-    SInt32 * score )
-{
-	if (!super::probe( provider, score)) {
-		return NULL;
+IOService * IODTPlatformExpert::probe( IOService * provider,
+			       		SInt32 * score )
+{
+    if( !super::probe( provider, score))
+	return( 0 );
+
+    // check machine types
+    if( !provider->compareNames( getProperty( gIONameMatchKey ) ))
+        return( 0 );
+
+    return( this);
+}
+
+bool IODTPlatformExpert::configure( IOService * provider )
+{
+    if( !super::configure( provider))
+	return( false);
+
+    processTopLevel( provider );
+
+    return( true );
+}
+
+IOService * IODTPlatformExpert::createNub( IORegistryEntry * from )
+{
+    IOService *		nub;
+
+    nub = new IOPlatformDevice;
+    if( nub) {
+	if( !nub->init( from, gIODTPlane )) {
+	    nub->free();
+	    nub = 0;
 	}
-
-	// check machine types
-	if (!provider->compareNames( getProperty( gIONameMatchKey ))) {
-		return NULL;
+    }
+    return( nub);
+}
+
+bool IODTPlatformExpert::createNubs( IOService * parent, OSIterator * iter )
+{
+    IORegistryEntry *	next;
+    IOService *		nub;
+    bool		ok = true;
+
+    if( iter) {
+	while( (next = (IORegistryEntry *) iter->getNextObject())) {
+
+            if( 0 == (nub = createNub( next )))
+                continue;
+
+            nub->attach( parent );
+            nub->registerService();
+        }
+	iter->release();
+    }
+
+    return( ok );
+}
+
+void IODTPlatformExpert::processTopLevel( IORegistryEntry * rootEntry )
+{
+    OSIterator * 	kids;
+    IORegistryEntry *	next;
+    IORegistryEntry *	cpus;
+    IORegistryEntry *	options;
+
+    // infanticide
+    kids = IODTFindMatchingEntries( rootEntry, 0, deleteList() );
+    if( kids) {
+	while( (next = (IORegistryEntry *)kids->getNextObject())) {
+	    next->detachAll( gIODTPlane);
 	}
-
-	return this;
-}
-
-bool
-IODTPlatformExpert::configure( IOService * provider )
-{
-	if (!super::configure( provider)) {
-		return false;
+	kids->release();
+    }
+
+    // Publish an IODTNVRAM class on /options.
+    options = rootEntry->childFromPath("options", gIODTPlane);
+    if (options) {
+      dtNVRAM = new IODTNVRAM;
+      if (dtNVRAM) {
+        if (!dtNVRAM->init(options, gIODTPlane)) {
+	  dtNVRAM->release();
+	  dtNVRAM = 0;
+        } else {
+	  dtNVRAM->attach(this);
+	  dtNVRAM->registerService();
 	}
-
-	processTopLevel( provider );
-
-	return true;
-}
-
-IOService *
-IODTPlatformExpert::createNub( IORegistryEntry * from )
-{
-	IOService *         nub;
-
-	nub = new IOPlatformDevice;
-	if (nub) {
-		if (!nub->init( from, gIODTPlane )) {
-			nub->free();
-			nub = NULL;
-		}
+      }
+    }
+
+    // Publish the cpus.
+    cpus = rootEntry->childFromPath( "cpus", gIODTPlane);
+    if ( cpus)
+      createNubs( this, IODTFindMatchingEntries( cpus, kIODTExclusive, 0));
+
+    // publish top level, minus excludeList
+    createNubs( this, IODTFindMatchingEntries( rootEntry, kIODTExclusive, excludeList()));
+}
+
+IOReturn IODTPlatformExpert::getNubResources( IOService * nub )
+{
+  if( nub->getDeviceMemory())
+    return( kIOReturnSuccess );
+
+  IODTResolveAddressing( nub, "reg", 0);
+
+  return( kIOReturnSuccess);
+}
+
+bool IODTPlatformExpert::compareNubName( const IOService * nub,
+				OSString * name, OSString ** matched ) const
+{
+    return( IODTCompareNubName( nub, name, matched )
+	  || super::compareNubName( nub, name, matched) );
+}
+
+bool IODTPlatformExpert::getModelName( char * name, int maxLength )
+{
+    OSData *		prop;
+    const char *	str;
+    int			len;
+    char		c;
+    bool		ok = false;
+
+    maxLength--;
+
+    prop = (OSData *) getProvider()->getProperty( gIODTCompatibleKey );
+    if( prop ) {
+	str = (const char *) prop->getBytesNoCopy();
+
+	if( 0 == strncmp( str, "AAPL,", strlen( "AAPL," ) ))
+	    str += strlen( "AAPL," );
+
+	len = 0;
+	while( (c = *str++)) {
+	    if( (c == '/') || (c == ' '))
+		c = '-';
+
+	    name[ len++ ] = c;
+	    if( len >= maxLength)
+		break;
 	}
-	return nub;
-}
-
-bool
-IODTPlatformExpert::createNubs( IOService * parent, OSIterator * iter )
-{
-	IORegistryEntry *   next;
-	IOService *         nub = NULL;
-	bool                ok = true;
-
-	if (iter) {
-		while ((next = (IORegistryEntry *) iter->getNextObject())) {
-			OSSafeReleaseNULL(nub);
-
-			if (NULL == (nub = createNub( next ))) {
-				continue;
-			}
-
-			nub->attach( parent );
-#if !defined(__x86_64__)
-			OSData *tmpData = (OSData *)next->getProperty("device_type");
-			if (tmpData == NULL) {
-				nub->registerService();
-				continue;
-			}
-
-			char *device_type = (char *)tmpData->getBytesNoCopy();
-			if (strcmp(device_type, "cpu") != 0) {
-				nub->registerService();
-				continue;
-			}
-
-			tmpData = (OSData *)next->getProperty("reg");
-			assert(tmpData != NULL);
-			assert(tmpData->getLength() >= sizeof(UInt32));
-
-			uint32_t phys_id = *(UInt32 *)tmpData->getBytesNoCopy();
-			int logical_cpu_id = ml_get_cpu_number(phys_id);
-			int logical_cluster_id = ml_get_cluster_number(phys_id);
-
-			/*
-			 * If the following condition triggers, it means that a CPU that was present in the DT
-			 * was ignored by XNU at topology parsing time. This can happen currently when using the
-			 * cpus=N boot-arg; for example, cpus=1 will cause XNU to parse and enable a single CPU.
-			 *
-			 * Note that this condition will not trigger for harvested cores because these do not show up
-			 * in the DT/IORegistry in the first place.
-			 */
-			if (logical_cpu_id < 0) {
-				nub->registerService();
-				continue;
-			}
-
-			__assert_only bool logical_id_added_to_ioreg = nub->setProperty("logical-cpu-id", logical_cpu_id, 32U);
-			assert(logical_id_added_to_ioreg == true);
-			logical_id_added_to_ioreg = nub->setProperty("logical-cluster-id", logical_cluster_id, 32U);
-			assert(logical_id_added_to_ioreg == true);
-#endif
-			nub->registerService();
-		}
-		OSSafeReleaseNULL(nub);
-		iter->release();
-	}
-
-	return ok;
-}
-
-void
-IODTPlatformExpert::processTopLevel( IORegistryEntry * rootEntry )
-{
-	OSIterator *        kids;
-	IORegistryEntry *   next;
-	IORegistryEntry *   cpus;
-
-	// infanticide
-	kids = IODTFindMatchingEntries( rootEntry, 0, deleteList());
-	if (kids) {
-		while ((next = (IORegistryEntry *)kids->getNextObject())) {
-			next->detachAll( gIODTPlane);
-		}
-		kids->release();
-	}
-
-	publishNVRAM();
-	assert(gIOOptionsEntry != NULL); // subclasses that do their own NVRAM initialization shouldn't be calling this
-	dtNVRAM = gIOOptionsEntry;
-
-	// Publish the cpus.
-	cpus = rootEntry->childFromPath( "cpus", gIODTPlane);
-	if (cpus) {
-		createNubs( this, IODTFindMatchingEntries( cpus, kIODTExclusive, NULL));
-		cpus->release();
-	}
-
-	// publish top level, minus excludeList
-	createNubs( this, IODTFindMatchingEntries( rootEntry, kIODTExclusive, excludeList()));
-}
-
-IOReturn
-IODTPlatformExpert::getNubResources( IOService * nub )
-{
-	if (nub->getDeviceMemory()) {
-		return kIOReturnSuccess;
-	}
-
-	IODTResolveAddressing( nub, "reg", NULL);
-
-	return kIOReturnSuccess;
-}
-
-bool
-IODTPlatformExpert::compareNubName( const IOService * nub,
-    OSString * name, OSString ** matched ) const
-{
-	return IODTCompareNubName( nub, name, matched )
-	       || super::compareNubName( nub, name, matched);
-}
-
-
-/*
- * Do not use this method directly, it returns inconsistent results
- * across architectures and is considered deprecated.
- *
- * Use getTargetName and getProductName respectively.  For example:
- *
- * targetName: J137AP
- * productName: iMacPro1,1
- *
- * targetName: D331pAP
- * productName: iPhone11,6
- */
-
-bool
-IODTPlatformExpert::getModelName( char * name, int maxLength )
-{
-	OSData *            prop;
-	const char *        str;
-	int                 len;
-	char                c;
-	bool                ok = false;
-
-	maxLength--;
-
-	prop = (OSData *) getProvider()->getProperty( gIODTCompatibleKey );
-	if (prop) {
-		str = (const char *) prop->getBytesNoCopy();
-
-		if (0 == strncmp( str, "AAPL,", strlen( "AAPL," ))) {
-			str += strlen( "AAPL," );
-		}
-
-		len = 0;
-		while ((c = *str++)) {
-			if ((c == '/') || (c == ' ')) {
-				c = '-';
-			}
-
-			name[len++] = c;
-			if (len >= maxLength) {
-				break;
-			}
-		}
-
-		name[len] = 0;
-		ok = true;
-	}
-	return ok;
-}
-
-/*
- * Do not use this method directly, it returns inconsistent results
- * across architectures and is considered deprecated.
- *
- * Use getTargetName and getProductName respectively.  For example:
- *
- * targetName: J137AP
- * productName: iMacPro1,1
- *
- * targetName: D331pAP
- * productName: iPhone11,6
- */
-
-bool
-IODTPlatformExpert::getMachineName( char * name, int maxLength )
-{
-	OSData *            prop;
-	bool                ok = false;
-
-	maxLength--;
-	prop = (OSData *) getProvider()->getProperty( gIODTModelKey );
-	ok = (NULL != prop);
-
-	if (ok) {
-		strlcpy( name, (const char *) prop->getBytesNoCopy(), maxLength );
-	}
-
-	return ok;
-}
-
-/* Examples: J137AP, D331pAP... */
-
-bool
-IODTPlatformExpert::getTargetName( char * name, int maxLength )
-{
-#if __x86_64__
-	OSData *            prop;
-
-	const OSSymbol *        key = gIODTBridgeModelKey;
-
-	maxLength--;
-	prop = (OSData *) getProvider()->getProperty( key );
-
-	if (prop == NULL) {
-		// This happens if there is no bridge.
-		char const * const  unknown = "";
-
-		strlcpy( name, unknown, maxLength );
-	} else {
-		strlcpy( name, (const char *)prop->getBytesNoCopy(), maxLength );
-	}
-
-	return true;
-#else
-	return getModelName( name, maxLength );
-#endif
-}
-
-/* Examples: iMacPro1,1, iPhone11,6... */
-
-bool
-IODTPlatformExpert::getProductName( char * name, int maxLength )
-{
-#if __x86_64__
-	return getModelName( name, maxLength );
-#else
-	return getMachineName( name, maxLength );
-#endif
+
+	name[ len ] = 0;
+	ok = true;
+    }
+    return( ok );
+}
+
+bool IODTPlatformExpert::getMachineName( char * name, int maxLength )
+{
+    OSData *		prop;
+    bool		ok = false;
+
+    maxLength--;
+    prop = (OSData *) getProvider()->getProperty( gIODTModelKey );
+    ok = (0 != prop);
+
+    if( ok )
+	strncpy( name, (const char *) prop->getBytesNoCopy(), maxLength );
+
+    return( ok );
 }
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
-void
-IODTPlatformExpert::registerNVRAMController( IONVRAMController * nvram )
-{
-	if (dtNVRAM) {
-		dtNVRAM->registerNVRAMController(nvram);
-	}
-
-	super::registerNVRAMController(nvram);
-}
-
-int
-IODTPlatformExpert::haltRestart(unsigned int type)
-{
-	return super::haltRestart(type);
-}
-
-IOReturn
-IODTPlatformExpert::readXPRAM(IOByteCount offset, UInt8 * buffer,
-    IOByteCount length)
-{
-	if (dtNVRAM) {
-		return dtNVRAM->readXPRAM(offset, buffer, length);
-	} else {
-		return kIOReturnNotReady;
-	}
-}
-
-IOReturn
-IODTPlatformExpert::writeXPRAM(IOByteCount offset, UInt8 * buffer,
-    IOByteCount length)
-{
-	if (dtNVRAM) {
-		return dtNVRAM->writeXPRAM(offset, buffer, length);
-	} else {
-		return kIOReturnNotReady;
-	}
-}
-
-IOReturn
-IODTPlatformExpert::readNVRAMProperty(
+void IODTPlatformExpert::registerNVRAMController( IONVRAMController * nvram )
+{
+  if (dtNVRAM) dtNVRAM->registerNVRAMController(nvram);
+  
+  super::registerNVRAMController(nvram);
+}
+
+int IODTPlatformExpert::haltRestart(unsigned int type)
+{
+  if (dtNVRAM) dtNVRAM->sync();
+  
+  return super::haltRestart(type);
+}
+
+IOReturn IODTPlatformExpert::readXPRAM(IOByteCount offset, UInt8 * buffer,
+				       IOByteCount length)
+{
+  if (dtNVRAM) return dtNVRAM->readXPRAM(offset, buffer, length);
+  else return kIOReturnNotReady;
+}
+
+IOReturn IODTPlatformExpert::writeXPRAM(IOByteCount offset, UInt8 * buffer,
+					IOByteCount length)
+{
+  if (dtNVRAM) return dtNVRAM->writeXPRAM(offset, buffer, length);
+  else return kIOReturnNotReady;
+}
+
+IOReturn IODTPlatformExpert::readNVRAMProperty(
 	IORegistryEntry * entry,
 	const OSSymbol ** name, OSData ** value )
 {
-	if (dtNVRAM) {
-		return dtNVRAM->readNVRAMProperty(entry, name, value);
-	} else {
-		return kIOReturnNotReady;
-	}
-}
-
-IOReturn
-IODTPlatformExpert::readNVRAMProperty(
-	IORegistryEntry * entry,
-	OSSharedPtr<const OSSymbol>& name, OSSharedPtr<OSData>& value )
-{
-	const OSSymbol* nameRaw = NULL;
-	OSData* valueRaw = NULL;
-
-	IOReturn result = readNVRAMProperty(entry, &nameRaw, &valueRaw);
-
-	name.reset(nameRaw, OSNoRetain);
-	value.reset(valueRaw, OSNoRetain);
-
-	return result;
-}
-
-IOReturn
-IODTPlatformExpert::writeNVRAMProperty(
+  if (dtNVRAM) return dtNVRAM->readNVRAMProperty(entry, name, value);
+  else return kIOReturnNotReady;
+}
+
+IOReturn IODTPlatformExpert::writeNVRAMProperty(
 	IORegistryEntry * entry,
 	const OSSymbol * name, OSData * value )
 {
-	if (dtNVRAM) {
-		return dtNVRAM->writeNVRAMProperty(entry, name, value);
-	} else {
-		return kIOReturnNotReady;
-	}
-}
-
-OSDictionary *
-IODTPlatformExpert::getNVRAMPartitions(void)
-{
-	if (dtNVRAM) {
-		return dtNVRAM->getNVRAMPartitions();
-	} else {
-		return NULL;
-	}
-}
-
-IOReturn
-IODTPlatformExpert::readNVRAMPartition(const OSSymbol * partitionID,
-    IOByteCount offset, UInt8 * buffer,
-    IOByteCount length)
-{
-	if (dtNVRAM) {
-		return dtNVRAM->readNVRAMPartition(partitionID, offset,
-		           buffer, length);
-	} else {
-		return kIOReturnNotReady;
-	}
-}
-
-IOReturn
-IODTPlatformExpert::writeNVRAMPartition(const OSSymbol * partitionID,
-    IOByteCount offset, UInt8 * buffer,
-    IOByteCount length)
-{
-	if (dtNVRAM) {
-		return dtNVRAM->writeNVRAMPartition(partitionID, offset,
-		           buffer, length);
-	} else {
-		return kIOReturnNotReady;
-	}
-}
-
-IOByteCount
-IODTPlatformExpert::savePanicInfo(UInt8 *buffer, IOByteCount length)
-{
-	IOByteCount lengthSaved = 0;
-
-	if (dtNVRAM) {
-		lengthSaved = dtNVRAM->savePanicInfo(buffer, length);
-	}
-
-	if (lengthSaved == 0) {
-		lengthSaved = super::savePanicInfo(buffer, 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;
+  if (dtNVRAM) return dtNVRAM->writeNVRAMProperty(entry, name, value);
+  else return kIOReturnNotReady;
+}
+
+OSDictionary *IODTPlatformExpert::getNVRAMPartitions(void)
+{
+  if (dtNVRAM) return dtNVRAM->getNVRAMPartitions();
+  else return 0;
+}
+
+IOReturn IODTPlatformExpert::readNVRAMPartition(const OSSymbol * partitionID,
+						IOByteCount offset, UInt8 * buffer,
+						IOByteCount length)
+{
+  if (dtNVRAM) return dtNVRAM->readNVRAMPartition(partitionID, offset,
+						  buffer, length);
+  else return kIOReturnNotReady;
+}
+
+IOReturn IODTPlatformExpert::writeNVRAMPartition(const OSSymbol * partitionID,
+						 IOByteCount offset, UInt8 * buffer,
+						 IOByteCount length)
+{
+  if (dtNVRAM) return dtNVRAM->writeNVRAMPartition(partitionID, offset,
+						   buffer, length);
+  else return kIOReturnNotReady;
+}
+
+IOByteCount IODTPlatformExpert::savePanicInfo(UInt8 *buffer, IOByteCount length)
+{
+  IOByteCount lengthSaved = 0;
+  
+  if (dtNVRAM) lengthSaved = dtNVRAM->savePanicInfo(buffer, length);
+  
+  if (lengthSaved == 0) lengthSaved = super::savePanicInfo(buffer, 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;
 }
 
 
@@ -2066,238 +1167,61 @@
 
 OSDefineMetaClassAndStructors(IOPlatformExpertDevice, IOService)
 
-OSMetaClassDefineReservedUnused(IOPlatformExpertDevice, 0);
-OSMetaClassDefineReservedUnused(IOPlatformExpertDevice, 1);
-OSMetaClassDefineReservedUnused(IOPlatformExpertDevice, 2);
-OSMetaClassDefineReservedUnused(IOPlatformExpertDevice, 3);
+OSMetaClassDefineReservedUnused(IOPlatformExpertDevice,  0);
+OSMetaClassDefineReservedUnused(IOPlatformExpertDevice,  1);
+OSMetaClassDefineReservedUnused(IOPlatformExpertDevice,  2);
+OSMetaClassDefineReservedUnused(IOPlatformExpertDevice,  3);
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
+bool IOPlatformExpertDevice::compareName( OSString * name,
+                                        OSString ** matched ) const
+{
+    return( IODTCompareNubName( this, name, matched ));
+}
+
 bool
-IOPlatformExpertDevice::compareName( OSString * name,
-    OSString ** matched ) const
-{
-	return IODTCompareNubName( this, name, matched );
-}
-
-bool
-IOPlatformExpertDevice::init(void *dtRoot)
-{
-	IORegistryEntry *   dt = NULL;
-	bool                ok;
-
-	if ((dtRoot != NULL) && (dt = IODeviceTreeAlloc(dtRoot))) {
-		ok = super::init( dt, gIODTPlane );
-	} else {
-		ok = super::init();
-	}
-
-	if (!ok) {
-		return false;
-	}
-
-	return true;
-}
-
-bool
-IOPlatformExpertDevice::startIOServiceMatching(void)
-{
-	workLoop = IOWorkLoop::workLoop();
-	if (!workLoop) {
-		return false;
-	}
-
-	registerService();
-
-	return true;
-}
-
-IOWorkLoop *
-IOPlatformExpertDevice::getWorkLoop() const
-{
-	return workLoop;
-}
-
-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 = NULL;
-	IOUserClient *      theConnect = NULL;
-
-	switch (type) {
-	case kIOKitDiagnosticsClientType:
-		newConnect = IOKitDiagnosticsClient::withTask(owningTask);
-		if (!newConnect) {
-			err = kIOReturnNotPermitted;
-		}
-		break;
-	case kIOKitUserServerClientType:
-		newConnect = IOUserServer::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();
-			err = kIOReturnNotPermitted;
-		} else {
-			theConnect = newConnect;
-		}
-	}
-
-	*handler = theConnect;
-	return err;
-}
-
-void
-IOPlatformExpertDevice::free()
-{
-	if (workLoop) {
-		workLoop->release();
-	}
-}
-
-void
-IOPlatformExpertDevice::configureDefaults( void )
-{
-	createNVRAM();
-	// Parse the serial-number data and publish a user-readable string
-	OSData* mydata = (OSData*) (getProperty("serial-number"));
-	if (mydata != NULL) {
-		OSString *serNoString = OSString::withCString((const char *)mydata->getBytesNoCopy());
-		if (serNoString != NULL) {
-			setProperty(kIOPlatformSerialNumberKey, serNoString);
-			serNoString->release();
-		}
-	}
-	generatePlatformUUID();
-}
-
-void
-IOPlatformExpertDevice::createNVRAM( void )
-{
-	/*
-	 * Publish an IODTNVRAM class on /options, if present.
-	 * DT-based platforms may need NVRAM access prior to the start
-	 * of IOKit matching, to support security-related operations
-	 * that must happen before machine_lockdown().
-	 */
-	IORegistryEntry *options = IORegistryEntry::fromPath("/options", gIODTPlane);
-	if (options == NULL) {
-		return; // /options may not be present
-	}
-
-	assert(gIOOptionsEntry == NULL);
-	gIOOptionsEntry = new IODTNVRAM;
-
-	assert(gIOOptionsEntry != NULL);
-
-	gIOOptionsEntry->init(options, gIODTPlane);
-	gIOOptionsEntry->attach(this);
-	gIOOptionsEntry->start(this);
-	options->release();
-}
-
-void
-IOPlatformExpertDevice::generatePlatformUUID( void )
-{
-	IORegistryEntry * entry;
-	OSString *        string = NULL;
-	uuid_string_t     uuid;
-
-#if !defined(__x86_64__)
-	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 /* !defined(__x86_64__) */
-	OSData * data;
-
-	entry = IORegistryEntry::fromPath( "/efi/platform", gIODTPlane );
-	if (entry) {
-		data = OSDynamicCast( OSData, entry->getProperty( "system-id" ));
-		if (data && data->getLength() == 16) {
-			SHA1_CTX     context;
-			uint8_t      digest[SHA_DIGEST_LENGTH];
-			const uuid_t space = { 0x2A, 0x06, 0x19, 0x90, 0xD3, 0x8D, 0x44, 0x40, 0xA1, 0x39, 0xC4, 0x97, 0x70, 0x37, 0x65, 0xAC };
-
-			SHA1Init( &context );
-			SHA1Update( &context, space, sizeof(space));
-			SHA1Update( &context, data->getBytesNoCopy(), data->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();
-	}
-	if (!string) {
-		/* vmware still runs this path */
-		entry = IORegistryEntry::fromPath( "/options", gIODTPlane );
-		if (entry) {
-			data = OSDynamicCast( OSData, entry->getProperty( "platform-uuid" ));
-			if (data && data->getLength() == sizeof(uuid_t)) {
-				uuid_unparse((uint8_t *) data->getBytesNoCopy(), uuid );
-				string = OSString::withCString( uuid );
-			}
-			entry->release();
-		}
-	}
-#endif /* defined(__x86_64__) */
-
-	if (string) {
-		setProperty( kIOPlatformUUIDKey, string );
-		gIOPlatformUUIDAndSerialDone = true;
-
-		string->release();
-	}
-}
+IOPlatformExpertDevice::initWithArgs(
+                            void * dtTop, void * p2, void * p3, void * p4 )
+{
+    IORegistryEntry * 	dt = 0;
+    void *		argsData[ 4 ];
+    bool		ok;
+
+    // dtTop may be zero on non- device tree systems
+    if( dtTop && (dt = IODeviceTreeAlloc( dtTop )))
+	ok = super::init( dt, gIODTPlane );
+    else
+	ok = super::init();
+
+    if( !ok)
+	return( false);
+
+    workLoop = IOWorkLoop::workLoop();
+    if (!workLoop)
+        return false;
+
+    argsData[ 0 ] = dtTop;
+    argsData[ 1 ] = p2;
+    argsData[ 2 ] = p3;
+    argsData[ 3 ] = p4;
+
+    setProperty("IOPlatformArgs", (void *)argsData, sizeof( argsData));
+
+    return( true);
+}
+
+IOWorkLoop *IOPlatformExpertDevice::getWorkLoop() const
+{
+    return workLoop;
+}
+
+void IOPlatformExpertDevice::free()
+{
+    if (workLoop)
+        workLoop->release();
+}
+
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 #undef super
@@ -2305,31 +1229,28 @@
 
 OSDefineMetaClassAndStructors(IOPlatformDevice, IOService)
 
-OSMetaClassDefineReservedUnused(IOPlatformDevice, 0);
-OSMetaClassDefineReservedUnused(IOPlatformDevice, 1);
-OSMetaClassDefineReservedUnused(IOPlatformDevice, 2);
-OSMetaClassDefineReservedUnused(IOPlatformDevice, 3);
+OSMetaClassDefineReservedUnused(IOPlatformDevice,  0);
+OSMetaClassDefineReservedUnused(IOPlatformDevice,  1);
+OSMetaClassDefineReservedUnused(IOPlatformDevice,  2);
+OSMetaClassDefineReservedUnused(IOPlatformDevice,  3);
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
-bool
-IOPlatformDevice::compareName( OSString * name,
-    OSString ** matched ) const
-{
-	return ((IOPlatformExpert *)getProvider())->
-	       compareNubName( this, name, matched );
-}
-
-IOService *
-IOPlatformDevice::matchLocation( IOService * /* client */ )
-{
-	return this;
-}
-
-IOReturn
-IOPlatformDevice::getResources( void )
-{
-	return ((IOPlatformExpert *)getProvider())->getNubResources( this );
+bool IOPlatformDevice::compareName( OSString * name,
+					OSString ** matched ) const
+{
+    return( ((IOPlatformExpert *)getProvider())->
+		compareNubName( this, name, matched ));
+}
+
+IOService * IOPlatformDevice::matchLocation( IOService * /* client */ )
+{
+    return( this );
+}
+
+IOReturn IOPlatformDevice::getResources( void )
+{
+    return( ((IOPlatformExpert *)getProvider())->getNubResources( this ));
 }
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -2342,27 +1263,23 @@
 *********************************************************************/
 
 class IOPanicPlatform : IOPlatformExpert {
-	OSDeclareDefaultStructors(IOPanicPlatform);
+    OSDeclareDefaultStructors(IOPanicPlatform);
 
 public:
-	bool start(IOService * provider) APPLE_KEXT_OVERRIDE;
+    bool start(IOService * provider);
 };
 
 
 OSDefineMetaClassAndStructors(IOPanicPlatform, IOPlatformExpert);
 
 
-bool
-IOPanicPlatform::start(IOService * provider)
-{
-	const char * platform_name = "(unknown platform name)";
-
-	if (provider) {
-		platform_name = provider->getName();
-	}
-
-	panic("Unable to find driver for this platform: \"%s\".",
-	    platform_name);
-
-	return false;
-}
+bool IOPanicPlatform::start(IOService * provider) {
+    const char * platform_name = "(unknown platform name)";
+
+    if (provider) platform_name = provider->getName();
+
+    panic("Unable to find driver for this platform: \"%s\".\n",
+        platform_name);
+
+    return false;
+}