Loading...
--- 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;
+}