/*
- * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1998-2010 Apple Inc. All rights reserved.
*
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_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 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.
*
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * 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
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * 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_LICENSE_HEADER_END@
- */
-/*
- * HISTORY
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
-#include <IOKit/system.h>
-#include <IOKit/IOPlatformExpert.h>
#include <IOKit/IOCPU.h>
#include <IOKit/IODeviceTreeSupport.h>
-#include <IOKit/IORangeAllocator.h>
-#include <IOKit/IONVRAM.h>
#include <IOKit/IOKitDebug.h>
+#include <IOKit/IOMapper.h>
+#include <IOKit/IOMessage.h>
+#include <IOKit/IONVRAM.h>
+#include <IOKit/IOPlatformExpert.h>
+#include <IOKit/IORangeAllocator.h>
#include <IOKit/IOWorkLoop.h>
#include <IOKit/pwr_mgt/RootDomain.h>
-#include <IOKit/IOMessage.h>
-#include <libkern/c++/OSContainers.h>
+#include <IOKit/IOKitKeys.h>
+#include <IOKit/IOTimeStamp.h>
+#include <IOKit/IOUserClient.h>
+#include <IOKit/system.h>
+
+#include <libkern/c++/OSContainers.h>
+#include <libkern/crypto/sha1.h>
+#include <libkern/OSAtomic.h>
extern "C" {
#include <machine/machine_routines.h>
#include <pexpert/pexpert.h>
+#include <uuid/uuid.h>
}
void printDictionaryKeys (OSDictionary * inDictionary, char * inMsg);
-static void getCStringForObject (OSObject * inObj, char * outStr);
+static void getCStringForObject(OSObject *inObj, char *outStr, size_t outStrLen);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
OSDefineMetaClassAndStructors(IOPlatformExpert, IOService)
-OSMetaClassDefineReservedUnused(IOPlatformExpert, 0);
-OSMetaClassDefineReservedUnused(IOPlatformExpert, 1);
+OSMetaClassDefineReservedUsed(IOPlatformExpert, 0);
+
+OSMetaClassDefineReservedUsed(IOPlatformExpert, 1);
OSMetaClassDefineReservedUnused(IOPlatformExpert, 2);
OSMetaClassDefineReservedUnused(IOPlatformExpert, 3);
OSMetaClassDefineReservedUnused(IOPlatformExpert, 4);
static IOPlatformExpert * gIOPlatform;
static OSDictionary * gIOInterruptControllers;
static IOLock * gIOInterruptControllersLock;
+static IODTNVRAM *gIOOptionsEntry;
OSSymbol * gPlatformInterruptControllerName;
{
IORangeAllocator * physicalRanges;
OSData * busFrequency;
+ uint32_t debugFlags;
if (!super::start(provider))
return false;
+ // Override the mapper present flag is requested by boot arguments.
+ if (PE_parse_boot_argn("dart", &debugFlags, sizeof (debugFlags)) && (debugFlags == 0))
+ removeProperty(kIOPlatformMapperPresentKey);
+ if (PE_parse_boot_argn("-x", &debugFlags, sizeof (debugFlags)))
+ removeProperty(kIOPlatformMapperPresentKey);
+
+ // Register the presence or lack thereof a system
+ // PCI address mapper with the IOMapper class
+ IOMapper::setMapperRequired(0 != getProperty(kIOPlatformMapperPresentKey));
+
gIOInterruptControllers = OSDictionary::withCapacity(1);
gIOInterruptControllersLock = IOLockAlloc();
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::compareNubName( const IOService * nub,
- OSString * name, OSString ** matched = 0 ) const
+ OSString * name, OSString ** matched ) const
{
return( nub->IORegistryEntry::compareName( name, matched ));
}
return( false );
}
+OSString* IOPlatformExpert::createSystemSerialNumberString(OSData* myProperty)
+{
+ return NULL;
+}
+
IORangeAllocator * IOPlatformExpert::getPhysicalRangeAllocator(void)
{
return(OSDynamicCast(IORangeAllocator,
int IOPlatformExpert::haltRestart(unsigned int type)
{
+ if (type == kPEPanicSync) return 0;
+
+ if (type == kPEHangCPU) while (true) {}
+
+ if (type == kPEUPSDelayHaltCPU) {
+ // RestartOnPowerLoss feature was turned on, proceed with shutdown.
+ type = kPEHaltCPU;
+ }
+
+ // On ARM kPEPanicRestartCPU is supported in the drivers
+ if (type == kPEPanicRestartCPU)
+ type = kPERestartCPU;
+
if (PE_halt_restart) return (*PE_halt_restart)(type);
else return -1;
}
gIOInterruptControllers->setObject(name, interruptController);
- thread_wakeup(gIOInterruptControllers);
-
+ IOLockWakeup(gIOInterruptControllersLock,
+ gIOInterruptControllers, /* one-thread */ false);
+
IOLockUnlock(gIOInterruptControllersLock);
return kIOReturnSuccess;
{
OSObject *object;
+ IOLockLock(gIOInterruptControllersLock);
while (1) {
- IOLockLock(gIOInterruptControllersLock);
object = gIOInterruptControllers->getObject(name);
- if (object == 0) assert_wait(gIOInterruptControllers, THREAD_UNINT);
-
- IOLockUnlock(gIOInterruptControllersLock);
+ if (object != 0)
+ break;
- if (object != 0) break;
-
- thread_block(0);
+ IOLockSleep(gIOInterruptControllersLock,
+ gIOInterruptControllers, THREAD_UNINT);
}
+ IOLockUnlock(gIOInterruptControllersLock);
return OSDynamicCast(IOInterruptController, object);
}
//
//*********************************************************************************
-void IOPlatformExpert::PMLog(const char * who,unsigned long event,unsigned long param1, unsigned long param2)
+void IOPlatformExpert::
+PMLog(const char *who, unsigned long event,
+ unsigned long param1, unsigned long param2)
{
- if( gIOKitDebug & kIOLogPower) {
- kprintf("%s %02d %08x %08x\n",who,event,param1,param2);
-// IOLog("%s %02d %08x %08x\n",who,event,param1,param2);
- }
+ clock_sec_t nows;
+ clock_usec_t nowus;
+ clock_get_system_microtime(&nows, &nowus);
+ nowus += (nows % 1000) * 1000000;
+
+ kprintf("pm%u %p %.30s %d %lx %lx\n",
+ nowus, current_thread(), who, // Identity
+ (int) event, (long) param1, (long) param2); // Args
}
root->init();
root->attach(this);
root->start(this);
- root->youAreRoot();
}
if ( mkey->isEqualTo ("name") ) {
char nameStr[64];
nameStr[0] = 0;
- getCStringForObject (inDictionary->getObject ("name"), nameStr );
+ getCStringForObject(inDictionary->getObject("name"), nameStr,
+ sizeof(nameStr));
if (strlen(nameStr) > 0)
IOLog ("%s name is %s\n", inMsg, nameStr);
}
mcoll->release ();
}
-static void getCStringForObject (OSObject * inObj, char * outStr)
+static void
+getCStringForObject(OSObject *inObj, char *outStr, size_t outStrLen)
{
char * buffer;
unsigned int len, i;
char * objString = (char *) (inObj->getMetaClass())->getClassName();
- if ((0 == strcmp(objString,"OSString")) || (0 == strcmp (objString, "OSSymbol")))
- strcpy (outStr, ((OSString *)inObj)->getCStringNoCopy());
+ if ((0 == strncmp(objString, "OSString", sizeof("OSString"))) ||
+ (0 == strncmp(objString, "OSSymbol", sizeof("OSSymbol"))))
+ strlcpy(outStr, ((OSString *)inObj)->getCStringNoCopy(), outStrLen);
- else if (0 == strcmp(objString,"OSData")) {
+ else if (0 == strncmp(objString, "OSData", sizeof("OSData"))) {
len = ((OSData *)inObj)->getLength();
buffer = (char *)((OSData *)inObj)->getBytesNoCopy();
if (buffer && (len > 0)) {
}
}
-/* IOPMPanicOnShutdownHang
+/* IOShutdownNotificationsTimedOut
* - Called from a timer installed by PEHaltRestart
*/
-static void IOPMPanicOnShutdownHang(thread_call_param_t p0, thread_call_param_t p1)
+static void IOShutdownNotificationsTimedOut(
+ thread_call_param_t p0,
+ thread_call_param_t p1)
{
- int type = (int)p0;
+#ifdef CONFIG_EMBEDDED
+ /* 30 seconds has elapsed - panic */
+ panic("Halt/Restart Timed Out");
+
+#else /* ! CONFIG_EMBEDDED */
+ int type = (int)(long)p0;
/* 30 seconds has elapsed - resume shutdown */
- gIOPlatform->haltRestart(type);
+ if(gIOPlatform) gIOPlatform->haltRestart(type);
+#endif /* CONFIG_EMBEDDED */
}
int PEHaltRestart(unsigned int type)
{
- IOPMrootDomain *pmRootDomain = IOService::getPMRootDomain();
- bool noWaitForResponses;
+ IOPMrootDomain *pmRootDomain;
AbsoluteTime deadline;
thread_call_t shutdown_hang;
- /* 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(type == kPEHaltCPU || type == kPERestartCPU || type == kPEUPSDelayHaltCPU)
+ {
+ pmRootDomain = IOService::getPMRootDomain();
+ /* Notify IOKit PM clients of shutdown/restart
+ Clients subscribe to this message with a call to
+ IOService::registerInterest()
+ */
+
+ /* 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( &IOShutdownNotificationsTimedOut,
+ (thread_call_param_t) type);
+ clock_interval_to_deadline( 30, kSecondScale, &deadline );
+ thread_call_enter1_delayed( shutdown_hang, 0, 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.
+ */
+ }
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;
+}
+
+
+
+inline static int init_gIOOptionsEntry(void)
+{
+ IORegistryEntry *entry;
+ void *nvram_entry;
+ volatile void **options;
+ int ret = -1;
+
+ if (gIOOptionsEntry)
+ return 0;
+
+ entry = IORegistryEntry::fromPath( "/options", gIODTPlane );
+ if (!entry)
+ return -1;
+
+ nvram_entry = (void *) OSDynamicCast(IODTNVRAM, entry);
+ if (!nvram_entry)
+ goto release;
+
+ options = (volatile void **) &gIOOptionsEntry;
+ if (!OSCompareAndSwapPtr(NULL, nvram_entry, options)) {
+ ret = 0;
+ goto release;
+ }
+
+ return 0;
+
+release:
+ entry->release();
+ return ret;
+
+}
+
+/* pass in a NULL value if you just want to figure out the len */
+boolean_t PEReadNVRAMProperty(const char *symbol, void *value,
+ unsigned int *len)
+{
+ OSObject *obj;
+ OSData *data;
+ unsigned int vlen;
+
+ if (!symbol || !len)
+ goto err;
+
+ if (init_gIOOptionsEntry() < 0)
+ goto err;
+
+ vlen = *len;
+ *len = 0;
+
+ obj = gIOOptionsEntry->getProperty(symbol);
+ if (!obj)
+ goto err;
+
+ /* convert to data */
+ data = OSDynamicCast(OSData, obj);
+ if (!data)
+ goto err;
+
+ *len = data->getLength();
+ vlen = min(vlen, *len);
+ if (vlen)
+ memcpy((void *) value, data->getBytesNoCopy(), vlen);
+
+ return TRUE;
+
+err:
+ return FALSE;
+}
+
+
+boolean_t PEWriteNVRAMProperty(const char *symbol, const void *value,
+ const unsigned int len)
+{
+ const OSSymbol *sym;
+ OSData *data;
+ bool ret = false;
+
+ if (!symbol || !value || !len)
+ goto err;
+
+ if (init_gIOOptionsEntry() < 0)
+ goto err;
+
+ sym = OSSymbol::withCStringNoCopy(symbol);
+ if (!sym)
+ goto err;
+
+ data = OSData::withBytes((void *) value, len);
+ if (!data)
+ goto sym_done;
+
+ ret = gIOOptionsEntry->setProperty(sym, data);
+ data->release();
+
+sym_done:
+ sym->release();
+
+ if (ret == true) {
+ gIOOptionsEntry->sync();
+ return TRUE;
+ }
+
+err:
+ return FALSE;
+}
+
+
long PEGetGMTTimeOfDay(void)
{
- if( gIOPlatform)
- return( gIOPlatform->getGMTTimeOfDay());
- else
- return( 0 );
+ long result = 0;
+
+ if( gIOPlatform) result = gIOPlatform->getGMTTimeOfDay();
+
+ return (result);
}
void PESetGMTTimeOfDay(long secs)
{
- if( gIOPlatform)
- gIOPlatform->setGMTTimeOfDay(secs);
+ if( gIOPlatform) gIOPlatform->setGMTTimeOfDay(secs);
}
} /* extern "C" */
void IOPlatformExpert::registerNVRAMController(IONVRAMController * caller)
{
+ OSData * data;
+ IORegistryEntry * entry;
+ OSString * string = 0;
+ uuid_string_t uuid;
+
+#if CONFIG_EMBEDDED
+ entry = IORegistryEntry::fromPath( "/chosen", gIODTPlane );
+ if ( entry )
+ {
+ OSData * data1;
+
+ data1 = OSDynamicCast( OSData, entry->getProperty( "unique-chip-id" ) );
+ if ( data1 && data1->getLength( ) == 8 )
+ {
+ OSData * data2;
+
+ data2 = OSDynamicCast( OSData, entry->getProperty( "chip-id" ) );
+ if ( data2 && data2->getLength( ) == 4 )
+ {
+ SHA1_CTX context;
+ uint8_t digest[ SHA_DIGEST_LENGTH ];
+ const uuid_t space = { 0xA6, 0xDD, 0x4C, 0xCB, 0xB5, 0xE8, 0x4A, 0xF5, 0xAC, 0xDD, 0xB6, 0xDC, 0x6A, 0x05, 0x42, 0xB8 };
+
+ SHA1Init( &context );
+ SHA1Update( &context, space, sizeof( space ) );
+ SHA1Update( &context, data1->getBytesNoCopy( ), data1->getLength( ) );
+ SHA1Update( &context, data2->getBytesNoCopy( ), data2->getLength( ) );
+ SHA1Final( digest, &context );
+
+ digest[ 6 ] = ( digest[ 6 ] & 0x0F ) | 0x50;
+ digest[ 8 ] = ( digest[ 8 ] & 0x3F ) | 0x80;
+
+ uuid_unparse( digest, uuid );
+ string = OSString::withCString( uuid );
+ }
+ }
+
+ entry->release( );
+ }
+#else /* !CONFIG_EMBEDDED */
+ entry = IORegistryEntry::fromPath( "/efi/platform", gIODTPlane );
+ if ( entry )
+ {
+ 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( );
+ }
+#endif /* !CONFIG_EMBEDDED */
+
+ if ( string == 0 )
+ {
+ 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( );
+ }
+ }
+
+ if ( string )
+ {
+ getProvider( )->setProperty( kIOPlatformUUIDKey, string );
+ publishResource( kIOPlatformUUIDKey, string );
+
+ string->release( );
+ }
+
publishResource("IONVRAM");
}
if (waitForFunction) {
_resources = waitForService(resourceMatching(functionName));
} else {
- _resources = resources();
+ _resources = getResourceService();
}
if (_resources == 0) return kIOReturnUnsupported;
param1, param2, param3, param4);
}
+IOByteCount IOPlatformExpert::savePanicInfo(UInt8 *buffer, IOByteCount length)
+{
+ return 0;
+}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
return( ok );
}
-void IODTPlatformExpert::processTopLevel( IORegistryEntry * root )
+void IODTPlatformExpert::processTopLevel( IORegistryEntry * rootEntry )
{
OSIterator * kids;
IORegistryEntry * next;
IORegistryEntry * options;
// infanticide
- kids = IODTFindMatchingEntries( root, 0, deleteList() );
+ kids = IODTFindMatchingEntries( rootEntry, 0, deleteList() );
if( kids) {
while( (next = (IORegistryEntry *)kids->getNextObject())) {
next->detachAll( gIODTPlane);
}
// Publish an IODTNVRAM class on /options.
- options = root->childFromPath("options", gIODTPlane);
+ options = rootEntry->childFromPath("options", gIODTPlane);
if (options) {
dtNVRAM = new IODTNVRAM;
if (dtNVRAM) {
}
// Publish the cpus.
- cpus = root->childFromPath( "cpus", gIODTPlane);
+ cpus = rootEntry->childFromPath( "cpus", gIODTPlane);
if ( cpus)
createNubs( this, IODTFindMatchingEntries( cpus, kIODTExclusive, 0));
// publish top level, minus excludeList
- createNubs( this, IODTFindMatchingEntries( root, kIODTExclusive, excludeList()));
+ createNubs( this, IODTFindMatchingEntries( rootEntry, kIODTExclusive, excludeList()));
}
IOReturn IODTPlatformExpert::getNubResources( IOService * nub )
ok = (0 != prop);
if( ok )
- strncpy( name, (const char *) prop->getBytesNoCopy(), maxLength );
+ strlcpy( name, (const char *) prop->getBytesNoCopy(), maxLength );
return( ok );
}
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;
+}
+
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#undef super
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool IOPlatformExpertDevice::compareName( OSString * name,
- OSString ** matched = 0 ) const
+ OSString ** matched ) const
{
return( IODTCompareNubName( this, name, matched ));
}
argsData[ 2 ] = p3;
argsData[ 3 ] = p4;
- setProperty("IOPlatformArgs", (void *)argsData, sizeof( argsData));
+ setProperty("IOPlatformArgs", (void *)argsData, sizeof(argsData));
return( true);
}
return workLoop;
}
+IOReturn IOPlatformExpertDevice::setProperties( OSObject * properties )
+{
+ OSDictionary * dictionary;
+ OSObject * object;
+ IOReturn status;
+
+ status = super::setProperties( properties );
+ if ( status != kIOReturnUnsupported ) return status;
+
+ status = IOUserClient::clientHasPrivilege( current_task( ), kIOClientPrivilegeAdministrator );
+ if ( status != kIOReturnSuccess ) return status;
+
+ dictionary = OSDynamicCast( OSDictionary, properties );
+ if ( dictionary == 0 ) return kIOReturnBadArgument;
+
+ object = dictionary->getObject( kIOPlatformUUIDKey );
+ if ( object )
+ {
+ IORegistryEntry * entry;
+ OSString * string;
+ uuid_t uuid;
+
+ string = ( OSString * ) getProperty( kIOPlatformUUIDKey );
+ if ( string ) return kIOReturnNotPermitted;
+
+ string = OSDynamicCast( OSString, object );
+ if ( string == 0 ) return kIOReturnBadArgument;
+
+ status = uuid_parse( string->getCStringNoCopy( ), uuid );
+ if ( status != 0 ) return kIOReturnBadArgument;
+
+ entry = IORegistryEntry::fromPath( "/options", gIODTPlane );
+ if ( entry )
+ {
+ entry->setProperty( "platform-uuid", uuid, sizeof( uuid_t ) );
+ entry->release( );
+ }
+
+ setProperty( kIOPlatformUUIDKey, string );
+ publishResource( kIOPlatformUUIDKey, string );
+
+ return kIOReturnSuccess;
+ }
+
+ return kIOReturnUnsupported;
+}
+
void IOPlatformExpertDevice::free()
{
if (workLoop)
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool IOPlatformDevice::compareName( OSString * name,
- OSString ** matched = 0 ) const
+ OSString ** matched ) const
{
return( ((IOPlatformExpert *)getProvider())->
compareNubName( this, name, matched ));
return false;
}
+