OSString * ACPIBacklightPanel::getACPIPath(IOACPIPlatformDevice * acpiDevice) { OSString * separator = OSString::withCStringNoCopy("."); OSArray * array = OSArray::withCapacity(10); char devicePath[512]; bzero(devicePath, sizeof(devicePath)); IOACPIPlatformDevice * parent = acpiDevice; IORegistryIterator * iter = IORegistryIterator::iterateOver(acpiDevice, gIOACPIPlane, kIORegistryIterateParents | kIORegistryIterateRecursively); if (iter) { do { array->setObject(parent->copyName(gIOACPIPlane)); array->setObject(separator); parent = OSDynamicCast(IOACPIPlatformDevice, iter->getNextObject()); } while (parent); iter->release(); int offset = 0; OSString * str = OSDynamicCast(OSString, array->getLastObject()); for (int i = array->getCount()-2; ((i>=0) || ((offset + str->getLength()) > sizeof(devicePath))) ; i--) { str = OSDynamicCast(OSString, array->getObject(i)); strncpy(devicePath + offset, str->getCStringNoCopy(), str->getLength()); offset += str->getLength(); } } return OSString::withCString(devicePath); }
bool IORangeAllocator::serialize(OSSerialize *s) const { OSArray * array = OSArray::withCapacity( numElements * 2 ); OSNumber * num; UInt32 index; bool ret; if( !array) return( false ); LOCK(); for( index = 0; index < numElements; index++) { if( (num = OSNumber::withNumber( elements[index].start, 8 * sizeof(IORangeScalar) ))) { array->setObject(num); num->release(); } if( (num = OSNumber::withNumber( elements[index].end, 8 * sizeof(IORangeScalar) ))) { array->setObject(num); num->release(); } } UNLOCK(); ret = array->serialize(s); array->release(); return( ret ); }
IOReturn FakeSMCDevice::setProperties(OSObject * properties) { KEYSLOCK; IOReturn result = kIOReturnUnsupported; if (OSDictionary * msg = OSDynamicCast(OSDictionary, properties)) { if (OSString * name = OSDynamicCast(OSString, msg->getObject(kFakeSMCDeviceUpdateKeyValue))) { if (FakeSMCKey * key = getKey(name->getCStringNoCopy())) { OSArray *info = OSArray::withCapacity(2); info->setObject(OSString::withCString(key->getType())); info->setObject(OSData::withBytes(key->getValue(), key->getSize())); exposedValues->setObject(key->getKey(), info); OSDictionary *values = OSDictionary::withDictionary(exposedValues); this->setProperty(kFakeSMCDeviceValues, values); OSSafeRelease(values); result = kIOReturnSuccess; } } else if (OSArray* array = OSDynamicCast(OSArray, msg->getObject(kFakeSMCDevicePopulateValues))) { if (OSIterator* iterator = OSCollectionIterator::withCollection(array)) { while (OSString *keyName = OSDynamicCast(OSString, iterator->getNextObject())) if (FakeSMCKey * key = getKey(keyName->getCStringNoCopy())) { OSArray *info = OSArray::withCapacity(2); info->setObject(OSString::withCString(key->getType())); info->setObject(OSData::withBytes(key->getValue(), key->getSize())); exposedValues->setObject(key->getKey(), info); IOSleep(10); //REVIEW: what is this for? } OSDictionary *values = OSDictionary::withDictionary(exposedValues); this->setProperty(kFakeSMCDeviceValues, values); OSSafeRelease(values); OSSafeRelease(iterator); result = kIOReturnSuccess; } } } KEYSUNLOCK; return result; }
void AppleUSBDiagnostics::serializePort(OSDictionary *dictionary, int port, UIMPortDiagnostics *counts, IOService *controller) const { #pragma unused(controller, port) UpdateNumberEntry( dictionary, counts->errorCount, "Port errors"); if( (gUSBStackDebugFlags & kUSBEnableErrorLogMask) != 0) { UpdateNumberEntry( dictionary, counts->totalBytes, "Bytes"); UpdateNumberEntry( dictionary, counts->totalBytes-counts->prevBytes, "Bytes (New)"); counts->prevBytes = counts->totalBytes; UpdateNumberEntry( dictionary, counts->timeouts, "Timeouts"); UpdateNumberEntry( dictionary, counts->timeouts-counts->prevTimeouts, "Timeouts (New)"); counts->prevTimeouts = counts->timeouts; } UpdateNumberEntry( dictionary, counts->resets, "Resets"); UpdateNumberEntry( dictionary, counts->resets-counts->prevResets, "Resets (New)"); counts->prevResets = counts->resets; UpdateNumberEntry( dictionary, counts->enable, "enable"); UpdateNumberEntry( dictionary, counts->suspend, "suspend"); UpdateNumberEntry( dictionary, counts->resume, "resume"); UpdateNumberEntry( dictionary, counts->warmReset, "warmReset"); UpdateNumberEntry( dictionary, counts->power, "power"); UpdateNumberEntry( dictionary, counts->u1Timeout, "u1Timeout"); UpdateNumberEntry( dictionary, counts->u2Timeout, "u2Timeout"); UpdateNumberEntry( dictionary, counts->remoteWakeMask, "remoteWakeMask"); OSArray * errorArray = OSArray::withCapacity(kXHCIMaxCompletionCodes); for(int i=0; i<kXHCIMaxCompletionCodes; i++) { OSNumber * number = OSNumber::withNumber( counts->xhciErrorCode[i], 32 ); errorArray->setObject( i, number ); number->release(); } dictionary->setObject( "XHCI Completion Codes", errorArray ); errorArray->release(); OSArray * linkStateArray = OSArray::withCapacity(kXHCILinkStates); for(int i=0; i<kXHCILinkStates; i++) { OSNumber * number = OSNumber::withNumber( counts->linkState[i], 32 ); linkStateArray->setObject( i, number ); number->release(); } dictionary->setObject( "LinkStates", linkStateArray ); linkStateArray->release(); }
OSArray * IOHIDInterface::createMatchingElements ( OSDictionary * matching, IOOptionBits options __unused) { UInt32 count = _elementArray->getCount(); IOHIDElementPrivate * element = NULL; OSArray * elements = NULL; if ( count ) { if ( matching ) { elements = OSArray::withCapacity(count); for ( UInt32 i = 0; i < count; i ++) { // Compare properties. if (( element = (IOHIDElementPrivate *)_elementArray->getObject(i) ) && element->matchProperties(matching)) { elements->setObject(element); } } } else elements = OSArray::withArray(_elementArray); } return elements; }
OSArray * IODeviceMemory::arrayFromList( InitElement list[], IOItemCount count ) { OSArray * array; IODeviceMemory * range; IOItemCount i; array = OSArray::withCapacity( count ); if( 0 == array ) return( 0); for( i = 0; i < count; i++) { range = IODeviceMemory::withRange( list[i].start, list[i].length ); if( range) { range->setTag( list[i].tag ); array->setObject( range); range->release(); } else { array->release(); array = 0; break; } } return( array ); }
volatile int kmod_start(void) { libkern_init0(); OSString* one = OSString::withCString("Anal sex"); OSString* two = OSString::withCString("Cunnilingus"); OSArray* sexthings = OSArray::withCapacity(2); sexthings->setObject(one); sexthings->setObject(two); printk("Hello from IOKit!\n"); printk("Put: %p %p\n", one, two); printk("OSArray: %p\n", sexthings); printk("Get: %p %p\n", sexthings->getObject(0), sexthings->getObject(1)); OSSerialize* ser = OSSerialize::withCapacity(1024); sexthings->serialize(ser); printk("Serialized: %s \n", ser->text()); return 0; }
/*--------------------------------------------------------------------------- * Update all the registry properties associated with an interface ---------------------------------------------------------------------------*/ void EInterfaces::update_interface_property(void) { int n; debug("update_interface_property - m_nInterfacesInUse=%d\n", m_nInterfacesInUse); if ( m_pProvider ) { m_pProvider->removeProperty(ENABLED_INTERFACES_PROPERTY); if ( m_nInterfacesInUse ) { OSArray* pInterfaces = OSArray::withCapacity(m_nInterfacesInUse); if ( pInterfaces ) { for(n=0; n<numberof(m_aInterfaces); n++) if ( m_aInterfaces[n].m_fEnabled ) { OSNumber* pNumber = OSNumber::withNumber(n, 32); if ( pNumber ) { pInterfaces->setObject(pNumber); pNumber->release(); } } m_pProvider->setProperty(ENABLED_INTERFACES_PROPERTY, (OSObject* )pInterfaces); pInterfaces->release(); } } } }
OSCollection * OSSet::copyCollection(OSDictionary *cycleDict) { bool allocDict = !cycleDict; OSCollection *ret = 0; OSSet *newSet = 0; if (allocDict) { cycleDict = OSDictionary::withCapacity(16); if (!cycleDict) return 0; } do { // Check for a cycle ret = super::copyCollection(cycleDict); if (ret) continue; // Found it newSet = OSSet::withCapacity(members->capacity); if (!newSet) continue; // Couldn't create new set abort // Insert object into cycle Dictionary cycleDict->setObject((const OSSymbol *) this, newSet); OSArray *newMembers = newSet->members; newMembers->capacityIncrement = members->capacityIncrement; // Now copy over the contents into the new duplicate for (unsigned int i = 0; i < members->count; i++) { OSObject *obj = EXT_CAST(members->array[i]); OSCollection *coll = OSDynamicCast(OSCollection, obj); if (coll) { OSCollection *newColl = coll->copyCollection(cycleDict); if (newColl) { obj = newColl; // Rely on cycleDict ref for a bit newColl->release(); } else goto abortCopy; }; newMembers->setObject(obj); }; ret = newSet; newSet = 0; } while(false); abortCopy: if (newSet) newSet->release(); if (allocDict) cycleDict->release(); return ret; }
// <rdar://8202424> IOReturn IOAudioSelectorControl::addAvailableSelection(SInt32 selectionValue, OSString *selectionDescription, const char* tagName, OSObject* tag) { OSArray *newSelections; OSArray *oldAvailableSelections; IOReturn result = kIOReturnSuccess; oldAvailableSelections = availableSelections; newSelections = OSArray::withArray(availableSelections); if (!newSelections) return kIOReturnNoMemory; if (selectionDescription == NULL) { result = kIOReturnBadArgument; } else { if (valueExists(selectionValue)) { result = kIOReturnError; } else { OSDictionary *newSelection; newSelection = OSDictionary::withCapacity(2); if (newSelection) { OSNumber *number; number = OSNumber::withNumber(selectionValue, sizeof(SInt32)*8); if (number) { newSelection->setObject(kIOAudioSelectorControlSelectionValueKey, number); newSelection->setObject(kIOAudioSelectorControlSelectionDescriptionKey, selectionDescription); newSelections->setObject(newSelection); number->release(); } else { result = kIOReturnError; } if ( tagName && tag ) { newSelection->setObject(tagName, tag); } availableSelections = newSelections; setProperty(kIOAudioSelectorControlAvailableSelectionsKey, availableSelections); oldAvailableSelections->release(); newSelection->release(); } else { result = kIOReturnError; } } } if (kIOReturnSuccess == result) { sendChangeNotification(kIOAudioControlRangeChangeNotification); } return result; }
void IOCatalogue::addPersonality(OSDictionary * dict) { const OSSymbol * sym; OSArray * arr; sym = OSDynamicCast(OSSymbol, dict->getObject(gIOProviderClassKey)); if (!sym) return; arr = (OSArray *) personalities->getObject(sym); if (arr) arr->setObject(dict); else { arr = OSArray::withObjects((const OSObject **)&dict, 1, 2); personalities->setObject(sym, arr); arr->release(); } }
OSArray * OSDictionary::copyKeys(void) { OSArray * array; array = OSArray::withCapacity(count); if (!array) return (0); for (unsigned int i = 0; i < count; i++) { if (!array->setObject(i, dictionary[i].key)) { array->release(); array = 0; break; } } return (array); }
bool FakeSMCDevice::initAndStart(IOService *platform, IOService *provider) { if (!provider || !super::init(platform, 0, 0)) return false; OSDictionary *properties = OSDynamicCast(OSDictionary, provider->getProperty("Configuration")); if (!properties) return false; status = (ApleSMCStatus *) IOMalloc(sizeof(struct AppleSMCStatus)); bzero((void*)status, sizeof(struct AppleSMCStatus)); interrupt_handler = 0; keys = OSArray::withCapacity(1); types = OSDictionary::withCapacity(0); exposedValues = OSDictionary::withCapacity(0); // Add fist key - counter key keyCounterKey = FakeSMCKey::withValue(KEY_COUNTER, TYPE_UI32, TYPE_UI32_SIZE, "\0\0\0\1"); keys->setObject(keyCounterKey); fanCounterKey = FakeSMCKey::withValue(KEY_FAN_NUMBER, TYPE_UI8, TYPE_UI8_SIZE, "\0"); keys->setObject(fanCounterKey); if (!gKeysLock) gKeysLock = IORecursiveLockAlloc(); // Load preconfigured keys FakeSMCDebugLog("loading keys..."); if (OSDictionary *dictionary = OSDynamicCast(OSDictionary, properties->getObject("Keys"))) { if (OSIterator *iterator = OSCollectionIterator::withCollection(dictionary)) { while (const OSSymbol *key = (const OSSymbol *)iterator->getNextObject()) { if (OSArray *array = OSDynamicCast(OSArray, dictionary->getObject(key))) { if (OSIterator *aiterator = OSCollectionIterator::withCollection(array)) { OSString *type = OSDynamicCast(OSString, aiterator->getNextObject()); OSData *value = OSDynamicCast(OSData, aiterator->getNextObject()); if (type && value) addKeyWithValue(key->getCStringNoCopy(), type->getCStringNoCopy(), value->getLength(), value->getBytesNoCopy()); OSSafeRelease(aiterator); } } key = 0; } OSSafeRelease(iterator); } HWSensorsInfoLog("%d preconfigured key%s added", keys->getCount(), keys->getCount() == 1 ? "" : "s"); } else { HWSensorsWarningLog("no preconfigured keys found"); } // Load wellknown type names FakeSMCDebugLog("loading types..."); if (OSDictionary *dictionary = OSDynamicCast(OSDictionary, properties->getObject("Types"))) { if (OSIterator *iterator = OSCollectionIterator::withCollection(dictionary)) { while (OSString *key = OSDynamicCast(OSString, iterator->getNextObject())) { if (OSString *value = OSDynamicCast(OSString, dictionary->getObject(key))) { types->setObject(key, value); } } OSSafeRelease(iterator); } } // Set Clover platform keys if (OSDictionary *dictionary = OSDynamicCast(OSDictionary, properties->getObject("Clover"))) { UInt32 count = 0; if (IORegistryEntry* cloverPlatformNode = fromPath("/efi/platform", gIODTPlane)) { if (OSIterator *iterator = OSCollectionIterator::withCollection(dictionary)) { while (OSString *name = OSDynamicCast(OSString, iterator->getNextObject())) { if (OSData *data = OSDynamicCast(OSData, cloverPlatformNode->getProperty(name))) { if (OSArray *items = OSDynamicCast(OSArray, dictionary->getObject(name))) { OSString *key = OSDynamicCast(OSString, items->getObject(0)); OSString *type = OSDynamicCast(OSString, items->getObject(1)); if (addKeyWithValue(key->getCStringNoCopy(), type->getCStringNoCopy(), data->getLength(), data->getBytesNoCopy())) count++; } } } OSSafeRelease(iterator); } } if (count) HWSensorsInfoLog("%d key%s exported by Clover EFI", count, count == 1 ? "" : "s"); } // Start SMC device if (!super::start(platform)) return false; this->setName("SMC"); FakeSMCSetProperty("name", "APP0001"); if (OSString *compatibleKey = OSDynamicCast(OSString, properties->getObject("smc-compatible"))) FakeSMCSetProperty("compatible", (const char *)compatibleKey->getCStringNoCopy()); else FakeSMCSetProperty("compatible", "smc-napa"); if (!this->setProperty("_STA", (unsigned long long)0x0000000b, 32)) { HWSensorsErrorLog("failed to set '_STA' property"); return false; } if (OSBoolean *debugKey = OSDynamicCast(OSBoolean, properties->getObject("debug"))) debug = debugKey->getValue(); else debug = false; if (OSBoolean *traceKey = OSDynamicCast(OSBoolean, properties->getObject("trace"))) trace = traceKey->getValue(); else trace = false; IODeviceMemory::InitElement rangeList[1]; rangeList[0].start = 0x300; rangeList[0].length = 0x20; // rangeList[1].start = 0xfef00000; // rangeList[1].length = 0x10000; if(OSArray *array = IODeviceMemory::arrayFromList(rangeList, 1)) { this->setDeviceMemory(array); OSSafeRelease(array); } else { HWSensorsFatalLog("failed to create Device memory array"); return false; } OSArray *controllers = OSArray::withCapacity(1); if(!controllers) { HWSensorsFatalLog("failed to create controllers array"); return false; } controllers->setObject((OSSymbol *)OSSymbol::withCStringNoCopy("io-apic-0")); OSArray *specifiers = OSArray::withCapacity(1); if(!specifiers) { HWSensorsFatalLog("failed to create specifiers array"); return false; } UInt64 line = 0x06; OSData *tmpData = OSData::withBytes(&line, sizeof(line)); if (!tmpData) { HWSensorsFatalLog("failed to create specifiers data"); return false; } specifiers->setObject(tmpData); this->setProperty(gIOInterruptControllersKey, controllers) && this->setProperty(gIOInterruptSpecifiersKey, specifiers); this->attachToParent(platform, gIOServicePlane); registerService(); HWSensorsInfoLog("successfully initialized"); return true; }
IORegistryEntry * IODeviceTreeAlloc( void * dtTop ) { IORegistryEntry * parent; IORegistryEntry * child; IORegistryIterator * regIter; DTEntryIterator iter; DTEntry dtChild; DTEntry mapEntry; OSArray * stack; OSData * prop; OSDictionary * allInts; vm_offset_t * dtMap; unsigned int propSize; bool intMap; bool freeDT; gIODTPlane = IORegistryEntry::makePlane( kIODeviceTreePlane ); gIODTNameKey = OSSymbol::withCStringNoCopy( "name" ); gIODTUnitKey = OSSymbol::withCStringNoCopy( "AAPL,unit-string" ); gIODTCompatibleKey = OSSymbol::withCStringNoCopy( "compatible" ); gIODTTypeKey = OSSymbol::withCStringNoCopy( "device_type" ); gIODTModelKey = OSSymbol::withCStringNoCopy( "model" ); gIODTSizeCellKey = OSSymbol::withCStringNoCopy( "#size-cells" ); gIODTAddressCellKey = OSSymbol::withCStringNoCopy( "#address-cells" ); gIODTRangeKey = OSSymbol::withCStringNoCopy( "ranges" ); gIODTPersistKey = OSSymbol::withCStringNoCopy( "IODTPersist" ); assert( gIODTPlane && gIODTCompatibleKey && gIODTTypeKey && gIODTModelKey && gIODTSizeCellKey && gIODTAddressCellKey && gIODTRangeKey && gIODTPersistKey ); gIODTDefaultInterruptController = OSSymbol::withCStringNoCopy("IOPrimaryInterruptController"); gIODTNWInterruptMappingKey = OSSymbol::withCStringNoCopy("IONWInterrupts"); gIODTAAPLInterruptsKey = OSSymbol::withCStringNoCopy("AAPL,interrupts"); gIODTPHandleKey = OSSymbol::withCStringNoCopy("AAPL,phandle"); gIODTInterruptParentKey = OSSymbol::withCStringNoCopy("interrupt-parent"); gIODTPHandles = OSArray::withCapacity( 1 ); gIODTPHandleMap = OSArray::withCapacity( 1 ); gIODTInterruptCellKey = OSSymbol::withCStringNoCopy("#interrupt-cells"); assert( gIODTDefaultInterruptController && gIODTNWInterruptMappingKey && gIODTAAPLInterruptsKey && gIODTPHandleKey && gIODTInterruptParentKey && gIODTPHandles && gIODTPHandleMap && gIODTInterruptCellKey ); freeDT = (kSuccess == DTLookupEntry( 0, "/chosen/memory-map", &mapEntry )) && (kSuccess == DTGetProperty( mapEntry, "DeviceTree", (void **) &dtMap, &propSize )) && ((2 * sizeof(uint32_t)) == propSize); parent = MakeReferenceTable( (DTEntry)dtTop, freeDT ); stack = OSArray::withObjects( (const OSObject **) &parent, 1, 10 ); DTCreateEntryIterator( (DTEntry)dtTop, &iter ); do { parent = (IORegistryEntry *)stack->getObject( stack->getCount() - 1); //parent->release(); stack->removeObject( stack->getCount() - 1); while( kSuccess == DTIterateEntries( iter, &dtChild) ) { child = MakeReferenceTable( dtChild, freeDT ); child->attachToParent( parent, gIODTPlane); AddPHandle( child ); if( kSuccess == DTEnterEntry( iter, dtChild)) { stack->setObject( parent); parent = child; } // only registry holds retain child->release(); } } while( stack->getCount() && (kSuccess == DTExitEntry( iter, &dtChild))); stack->release(); DTDisposeEntryIterator( iter); // parent is now root of the created tree // make root name first compatible entry (purely cosmetic) if( (prop = (OSData *) parent->getProperty( gIODTCompatibleKey))) { parent->setName( parent->getName(), gIODTPlane ); parent->setName( (const char *) prop->getBytesNoCopy() ); } // attach tree to meta root parent->attachToParent( IORegistryEntry::getRegistryRoot(), gIODTPlane); parent->release(); if( freeDT ) { // free original device tree DTInit(0); IODTFreeLoaderInfo( "DeviceTree", (void *)dtMap[0], (int) round_page(dtMap[1]) ); } // adjust tree gIODTSharedInterrupts = OSDictionary::withCapacity(4); allInts = OSDictionary::withCapacity(4); intMap = false; regIter = IORegistryIterator::iterateOver( gIODTPlane, kIORegistryIterateRecursively ); assert( regIter && allInts && gIODTSharedInterrupts ); if( regIter && allInts && gIODTSharedInterrupts ) { while( (child = regIter->getNextObject())) { IODTMapInterruptsSharing( child, allInts ); if( !intMap && child->getProperty( gIODTInterruptParentKey)) intMap = true; } regIter->release(); } #if IODTSUPPORTDEBUG parent->setProperty("allInts", allInts); parent->setProperty("sharedInts", gIODTSharedInterrupts); regIter = IORegistryIterator::iterateOver( gIODTPlane, kIORegistryIterateRecursively ); if (regIter) { while( (child = regIter->getNextObject())) { OSArray * array = OSDynamicCast(OSArray, child->getProperty( gIOInterruptSpecifiersKey )); for( UInt32 i = 0; array && (i < array->getCount()); i++) { IOOptionBits options; IOReturn ret = IODTGetInterruptOptions( child, i, &options ); if( (ret != kIOReturnSuccess) || options) IOLog("%s[%ld] %ld (%x)\n", child->getName(), i, options, ret); } } regIter->release(); } #endif allInts->release(); if( intMap) // set a key in the root to indicate we found NW interrupt mapping parent->setProperty( gIODTNWInterruptMappingKey, (OSObject *) gIODTNWInterruptMappingKey ); return( parent); }
/********************************************************************* * This function builds a uniqued, in-order list of modules that need * to be loaded in order for kmod_name to be successfully loaded. This * list ends with kmod_name itself. *********************************************************************/ static OSArray * getDependencyListForKmod(const char * kmod_name) { int error = 0; OSDictionary * extensionsDict; // don't release OSDictionary * extDict; // don't release OSDictionary * extPlist; // don't release OSString * extName; // don't release OSArray * dependencyList = NULL; // return value, caller releases unsigned int i; /* These are used to remove duplicates from the dependency list. */ OSArray * originalList = NULL; // must be released OSDictionary * encounteredNames = NULL; // must be release /* Get the dictionary of startup extensions. * This is keyed by module name. */ extensionsDict = getStartupExtensions(); if (!extensionsDict) { IOLog("getDependencyListForKmod(): No extensions dictionary.\n"); LOG_DELAY(); error = 1; goto finish; } /* Get the requested extension's dictionary entry and its property * list, containing module dependencies. */ extDict = OSDynamicCast(OSDictionary, extensionsDict->getObject(kmod_name)); if (!extDict) { IOLog("getDependencyListForKmod(): " "Extension \"%s\" cannot be found.\n", kmod_name); LOG_DELAY(); error = 1; goto finish; } extPlist = OSDynamicCast(OSDictionary, extDict->getObject("plist")); if (!extPlist) { IOLog("getDependencyListForKmod(): " "Extension \"%s\" has no property list.\n", kmod_name); LOG_DELAY(); error = 1; goto finish; } /* Verify that the retrieved entry's "CFBundleIdentifier" property exists. * This will be added to the dependency list. */ extName = OSDynamicCast(OSString, extPlist->getObject("CFBundleIdentifier")); if (!extName) { IOLog("getDependencyListForKmod(): " "Extension \"%s\" has no \"CFBundleIdentifier\" property.\n", kmod_name); LOG_DELAY(); error = 1; goto finish; } dependencyList = OSArray::withCapacity(10); if (!dependencyList) { IOLog("getDependencyListForKmod(): " "Couldn't allocate dependency array for extension \"%s\".\n", kmod_name); LOG_DELAY(); error = 1; goto finish; } /* Okay, let's get started. */ dependencyList->setObject(extName); /* Here's a slightly tricky bit. This loop iterates through * the dependency list until it runs off the end. Each time * through, however, any number of dependencies can be added * to the end of the list. Eventually some extensions won't * have any more dependencies, no more names will be added * to the list, and this loop will terminate. */ for (i = 0; i < dependencyList->getCount(); i++) { // None of these needs to be released, as they're all from plists. OSString * curName; OSDictionary * curExtDict; OSDictionary * curExtDepDict; OSDictionary * curExtPlist; OSString * curDepName; /* An arbitrary limit to prevent infinite loops. */ if (i > 255) { IOLog("getDependencyListForKmod(): " "max dependency list length exceeded for " "extension \"%s\".\n", kmod_name); LOG_DELAY(); error = 1; goto finish; } curName = OSDynamicCast(OSString, dependencyList->getObject(i)); curExtDict = OSDynamicCast(OSDictionary, extensionsDict->getObject(curName)); if (!curExtDict) { IOLog("getDependencyListForKmod(): " "Extension \"%s\", required for extension \"%s\", " "is not available.\n", curName->getCStringNoCopy(), kmod_name); LOG_DELAY(); error = 1; goto finish; } curExtPlist = OSDynamicCast(OSDictionary, curExtDict->getObject("plist")); if (!curExtPlist) { IOLog("getDependencyListForKmod(): " "Extension \"%s\", required for extension \"%s\", " "has no property list.\n", curName->getCStringNoCopy(), kmod_name); LOG_DELAY(); error = 1; goto finish; } curExtDepDict = OSDynamicCast(OSDictionary, curExtPlist->getObject("OSBundleLibraries")); if (curExtDepDict) { OSCollectionIterator * keyIterator = OSCollectionIterator::withCollection(curExtDepDict); if (!keyIterator) { IOLog("getDependencyListForKmod(): " "Couldn't allocate iterator for extension " "\"%s\".\n", kmod_name); LOG_DELAY(); error = 1; goto finish; } while ( (curDepName = OSDynamicCast(OSString, keyIterator->getNextObject())) ) { OSString * requiredVersion = OSDynamicCast(OSString, curExtDepDict->getObject(curDepName)); if (!verifyCompatibility(curDepName, requiredVersion)) { IOLog("getDependencyListForKmod(): " "Dependency %s of %s is not compatible or is unavailable.\n", curDepName->getCStringNoCopy(), curName->getCStringNoCopy()); LOG_DELAY(); error = 1; goto finish; } dependencyList->setObject(curDepName); } keyIterator->release(); } } /***** * The dependency list now exists in the reverse order of required loads, * and may have duplicates. Now we turn the list around and remove * duplicates. */ originalList = dependencyList; dependencyList = OSArray::withCapacity(originalList->getCount()); if (!dependencyList) { IOLog("getDependenciesForKmod(): " "Couldn't allocate reversal dependency list for extension " "\"%s\".\n", kmod_name); LOG_DELAY(); error = 1; goto finish; } encounteredNames = OSDictionary::withCapacity(originalList->getCount()); if (!encounteredNames) { IOLog("getDependenciesForKmod(): " "Couldn't allocate list of encountered names for extension " "\"%s\".\n", kmod_name); LOG_DELAY(); error = 1; goto finish; } /* Go backward through the original list, using the encounteredNames * dictionary to check for duplicates. We put originalList in as the * value because we need some non-NULL value. Here we also drop any * extensions that aren't proper dependencies (that is, any that are * nonkernel kexts without code). */ i = originalList->getCount(); if (i > 0) { do { i--; OSString * item = OSDynamicCast(OSString, originalList->getObject(i)); if ( (!encounteredNames->getObject(item)) && kextIsADependency(item)) { encounteredNames->setObject(item, originalList); dependencyList->setObject(item); } } while (i > 0); } finish: if (originalList) { originalList->release(); } if (encounteredNames) { encounteredNames->release(); } if (error) { if (dependencyList) { dependencyList->release(); dependencyList = NULL; } } return dependencyList; }
bool MacRISC2CPU::start(IOService *provider) { kern_return_t result; IORegistryEntry *cpusRegEntry, *uniNRegEntry, *mpicRegEntry, *devicetreeRegEntry; OSIterator *cpusIterator; OSData *tmpData; IOService *service; const OSSymbol *interruptControllerName; OSData *interruptData; OSArray *tmpArray; UInt32 maxCPUs, uniNVersion, physCPU; ml_processor_info_t processor_info; #if enableUserClientInterface DFScontMode = 0; fWorkLoop = 0; DFS_Status = false; GPU_Status = kGPUHigh; vStepped = false; #endif // callPlatformFunction symbols mpic_getProvider = OSSymbol::withCString("mpic_getProvider"); mpic_getIPIVector= OSSymbol::withCString("mpic_getIPIVector"); mpic_setCurrentTaskPriority = OSSymbol::withCString("mpic_setCurrentTaskPriority"); mpic_setUpForSleep = OSSymbol::withCString("mpic_setUpForSleep"); mpic_dispatchIPI = OSSymbol::withCString("mpic_dispatchIPI"); keyLargo_restoreRegisterState = OSSymbol::withCString("keyLargo_restoreRegisterState"); keyLargo_syncTimeBase = OSSymbol::withCString("keyLargo_syncTimeBase"); keyLargo_saveRegisterState = OSSymbol::withCString("keyLargo_saveRegisterState"); keyLargo_turnOffIO = OSSymbol::withCString("keyLargo_turnOffIO"); keyLargo_writeRegUInt8 = OSSymbol::withCString("keyLargo_writeRegUInt8"); keyLargo_getHostKeyLargo = OSSymbol::withCString("keyLargo_getHostKeyLargo"); keyLargo_setPowerSupply = OSSymbol::withCString("setPowerSupply"); uniN_setPowerState = OSSymbol::withCString(kUniNSetPowerState); uniN_setAACKDelay = OSSymbol::withCString(kUniNSetAACKDelay); pmu_cpuReset = OSSymbol::withCString("cpuReset"); ati_prepareDMATransaction = OSSymbol::withCString(kIOFBPrepareDMAValueKey); ati_performDMATransaction = OSSymbol::withCString(kIOFBPerformDMAValueKey); macRISC2PE = OSDynamicCast(MacRISC2PE, getPlatform()); if (macRISC2PE == 0) return false; if (!super::start(provider)) return false; // Get the Uni-N Version. uniNRegEntry = fromPath("/uni-n", gIODTPlane); if (uniNRegEntry == 0) return false; tmpData = OSDynamicCast(OSData, uniNRegEntry->getProperty("device-rev")); if (tmpData == 0) return false; uniNVersion = *(long *)tmpData->getBytesNoCopy(); // Find out if this is the boot CPU. bootCPU = false; tmpData = OSDynamicCast(OSData, provider->getProperty("state")); if (tmpData == 0) return false; if (!strcmp((char *)tmpData->getBytesNoCopy(), "running")) bootCPU = true; // Count the CPUs. numCPUs = 0; cpusRegEntry = fromPath("/cpus", gIODTPlane); if (cpusRegEntry == 0) return false; cpusIterator = cpusRegEntry->getChildIterator(gIODTPlane); while (cpusIterator->getNextObject()) numCPUs++; cpusIterator->release(); // [3830950] - The bootCPU driver inits globals for all instances (like gCPUIC) so if we're not the // boot CPU driver we wait here for that driver to finish its initialization if ((numCPUs > 1) && !bootCPU) // Wait for bootCPU driver to say it's up and running (void) waitForService (resourceMatching ("BootCPU")); // Limit the number of CPUs to one if uniNVersion is 1.0.7 or less. if (uniNVersion < kUniNVersion107) numCPUs = 1; // Limit the number of CPUs by the cpu=# boot arg. if (PE_parse_boot_arg("cpus", &maxCPUs)) { if (numCPUs > maxCPUs) numCPUs = maxCPUs; } ignoreSpeedChange = false; doSleep = false; topLevelPCIBridgeCount = 0; // Get the "flush-on-lock" property from the first cpu node. flushOnLock = false; cpusRegEntry = fromPath("/cpus/@0", gIODTPlane); if (cpusRegEntry == 0) return false; if (cpusRegEntry->getProperty("flush-on-lock") != 0) flushOnLock = true; // Set flushOnLock when numCPUs is not one. if (numCPUs != 1) flushOnLock = true; // If system is PowerMac3,5 (TowerG4), then set flushOnLock to disable nap devicetreeRegEntry = fromPath("/", gIODTPlane); tmpData = OSDynamicCast(OSData, devicetreeRegEntry->getProperty("model")); if (tmpData == 0) return false; #if 0 if(!strcmp((char *)tmpData->getBytesNoCopy(), "PowerMac3,5")) flushOnLock = true; #endif // Get the physical CPU number from the "reg" property. tmpData = OSDynamicCast(OSData, provider->getProperty("reg")); if (tmpData == 0) return false; physCPU = *(long *)tmpData->getBytesNoCopy(); setCPUNumber(physCPU); // Get the gpio offset for soft reset from the "soft-reset" property. tmpData = OSDynamicCast(OSData, provider->getProperty("soft-reset")); if (tmpData == 0) { if (physCPU == 0) soft_reset_offset = 0x5B; else soft_reset_offset = 0x5C; } else soft_reset_offset = *(long *)tmpData->getBytesNoCopy(); // Get the gpio offset for timebase enable from the "timebase-enable" property. tmpData = OSDynamicCast(OSData, provider->getProperty("timebase-enable")); if (tmpData == 0) timebase_enable_offset = 0x73; else timebase_enable_offset = *(long *)tmpData->getBytesNoCopy(); // See if reset is needed on wake resetOnWake = (provider->getProperty ("reset-on-wake") != NULL); if (resetOnWake) { vm_address_t reserveMem; reserveMem = (vm_address_t)IOMallocAligned (PAGE_SIZE, PAGE_SIZE); // Get one page (which we keep forever) if (reserveMem) { // map it reserveMemDesc = IOMemoryDescriptor::withAddress (reserveMem, PAGE_SIZE, kIODirectionNone, NULL); if (reserveMemDesc) { // get the physical address reserveMemPhys = reserveMemDesc->getPhysicalAddress(); } } } // On machines with a 'vmin' property in the CPU Node we need to make sure to tell the kernel to // ml_set_processor_voltage on needed processors. needVSetting = (provider->getProperty( "vmin" ) != 0); // While techincally the Apollo7PM machines do need AACK delay, it is already set in the bootROM // since we boot slow. We don't want the machine to switch AACKdelay off when we run DFS high so // setting this to false will take care of the issue. needAACKDelay = false; if (bootCPU) { gCPUIC = new IOCPUInterruptController; if (gCPUIC == 0) return false; if (gCPUIC->initCPUInterruptController(numCPUs) != kIOReturnSuccess) return false; gCPUIC->attach(this); gCPUIC->registerCPUInterruptController(); } // Get the l2cr value from the property list. tmpData = OSDynamicCast(OSData, provider->getProperty("l2cr")); if (tmpData != 0) { l2crValue = *(long *)tmpData->getBytesNoCopy() & 0x7FFFFFFF; } else { l2crValue = mfl2cr() & 0x7FFFFFFF; } // Wait for KeyLargo to show up. keyLargo = waitForService(serviceMatching("KeyLargo")); if (keyLargo == 0) return false; keyLargo->callPlatformFunction (keyLargo_getHostKeyLargo, false, &keyLargo, 0, 0, 0); if (keyLargo == 0) { kprintf ("MacRISC2CPU::start - getHostKeyLargo returned nil\n"); return false; } // Wait for MPIC to show up. mpic = waitForService(serviceMatching("AppleMPICInterruptController")); if (mpic == 0) return false; // Set the Interrupt Properties for this cpu. mpic->callPlatformFunction(mpic_getProvider, false, (void *)&mpicRegEntry, 0, 0, 0); interruptControllerName = IODTInterruptControllerName(mpicRegEntry); mpic->callPlatformFunction(mpic_getIPIVector, false, (void *)&physCPU, (void *)&interruptData, 0, 0); if ((interruptControllerName == 0) || (interruptData == 0)) return false; tmpArray = OSArray::withCapacity(1); tmpArray->setObject(interruptControllerName); cpuNub->setProperty(gIOInterruptControllersKey, tmpArray); tmpArray->release(); tmpArray = OSArray::withCapacity(1); tmpArray->setObject(interruptData); cpuNub->setProperty(gIOInterruptSpecifiersKey, tmpArray); tmpArray->release(); setCPUState(kIOCPUStateUninitalized); // necessary bootCPU initialization is done, so release other CPU drivers to do their thing // other drivers need to be unblocked *before* we call processor_start otherwise we deadlock if (bootCPU) publishResource ("BootCPU", this); if (physCPU < numCPUs) { processor_info.cpu_id = (cpu_id_t)this; processor_info.boot_cpu = bootCPU; processor_info.start_paddr = 0x0100; processor_info.l2cr_value = l2crValue; processor_info.supports_nap = !flushOnLock; processor_info.time_base_enable = OSMemberFunctionCast(time_base_enable_t, this, &MacRISC2CPU::enableCPUTimeBase); // [4091924] // Register this CPU with mach. result = ml_processor_register(&processor_info, &machProcessor, &ipi_handler); if (result == KERN_FAILURE) return false; processor_start(machProcessor); } // Before to go to sleep we wish to disable the napping mode so that the PMU // will not shutdown the system while going to sleep: service = waitForService(serviceMatching("IOPMrootDomain")); pmRootDomain = OSDynamicCast(IOPMrootDomain, service); if (pmRootDomain != 0) { kprintf("Register MacRISC2CPU %ld to acknowledge power changes\n", getCPUNumber()); pmRootDomain->registerInterestedDriver(this); // Join the Power Management Tree to receive setAggressiveness calls. PMinit(); provider->joinPMtree(this); } // Finds PMU and UniN so in quiesce we can put the machine to sleep. // I can not put these calls there because quiesce runs in interrupt // context and waitForService may block. pmu = waitForService(serviceMatching("ApplePMU")); uniN = waitForService(serviceMatching("AppleUniN")); if ((pmu == 0) || (uniN == 0)) return false; if (macRISC2PE->hasPMon) { // Find the platform monitor, if present service = waitForService(resourceMatching("IOPlatformMonitor")); ioPMon = OSDynamicCast (IOPlatformMonitor, service->getProperty("IOPlatformMonitor")); if (!ioPMon) return false; ioPMonDict = OSDictionary::withCapacity(2); if (!ioPMonDict) { ioPMon = NULL; } else { ioPMonDict->setObject (kIOPMonTypeKey, OSSymbol::withCString (kIOPMonTypeCPUCon)); ioPMonDict->setObject (kIOPMonCPUIDKey, OSNumber::withNumber ((long long)getCPUNumber(), 32)); if (messageClient (kIOPMonMessageRegister, ioPMon, (void *)ioPMonDict) != kIOReturnSuccess) { // IOPMon doesn't need to know about us, so don't bother with it IOLog ("MacRISC2CPU::start - failed to register cpu with IOPlatformMonitor\n"); ioPMonDict->release(); ioPMon = NULL; } } } if (macRISC2PE->hasPPlugin) { IOService *ioPPlugin; OSDictionary *ioPPluginDict; // Find the platform plugin, if present service = waitForService(resourceMatching("IOPlatformPlugin")); ioPPlugin = OSDynamicCast (IOService, service->getProperty("IOPlatformPlugin")); if (!ioPPlugin) return false; ioPPluginDict = OSDictionary::withCapacity(2); if (ioPPluginDict) { ioPPluginDict->setObject ("cpu-id", OSNumber::withNumber ((long long)getCPUNumber(), 32)); // Register with the plugin - same API as for platform monitor if (messageClient (kIOPMonMessageRegister, ioPPlugin, (void *)ioPPluginDict) != kIOReturnSuccess) { // ioPPlugin doesn't need to know about us, so don't bother with it IOLog ("MacRISC2CPU::start - failed to register cpu with IOPlatformPlugin\n"); } ioPPluginDict->release(); // Not needed any more } } #if enableUserClientInterface // // UserClient stuff... // fWorkLoop = getWorkLoop(); if(!fWorkLoop) { IOLog("MacRISC2CPU::start ERROR: failed to find a fWorkLoop\n"); } if(!initTimers()) { IOLog("MacRISC2CPU::start ERROR: failed to init the timers\n"); } #endif registerService(); return true; }
void testSet() { bool res = true; void *spaceCheck, *spaceCheck2 , *spaceCheck3; int i, count, count2; OSObject *cache[numStrCache], *str, *sym; OSSet *set1, *set2; OSArray *array; // Do first test without memory leak tests to initialise the metaclass set1 = OSSet::withCapacity(1); TEST_ASSERT('S', "0a", set1); if (set1) set1->release(); // Grow the symbol pool to maximum for (i = 0; i < numStrCache; i++) cache[i] = (OSObject *) OSSymbol::withCStringNoCopy(strCache[i]); for (i = 0; i < numStrCache; i++) cache[i]->release(); // Create and destroy an set spaceCheck = checkPointSpace(); set1 = OSSet::withCapacity(1); TEST_ASSERT('S', "1a", set1); if (set1) { TEST_ASSERT('S', "1b", !set1->getCount()); TEST_ASSERT('S', "1c", 1 == set1->getCapacity()); TEST_ASSERT('S', "1d", 1 == set1->getCapacityIncrement()); TEST_ASSERT('S', "1e", 4 == set1->setCapacityIncrement(4)); TEST_ASSERT('S', "1f", 4 == set1->getCapacityIncrement()); TEST_ASSERT('S', "1g", 8 == set1->ensureCapacity(5)); spaceCheck2 = checkPointSpace(); cache[0] = IOString::withCStringNoCopy(strCache[0]); spaceCheck3 = checkPointSpace(); TEST_ASSERT('S', "1h", set1->setObject(cache[0])); TEST_ASSERT('S', "1i", set1->containsObject(cache[0])); TEST_ASSERT('S', "1j", cache[0] == set1->getAnyObject()); cache[0]->release(); res = res && checkSpace("(S)1k", spaceCheck3, 0); TEST_ASSERT('S', "1l", 1 == set1->getCount()); set1->flushCollection(); TEST_ASSERT('S', "1m", !set1->getCount()); res = res && checkSpace("(S)1n", spaceCheck2, 0); set1->release(); } res = res && checkSpace("(S)1", spaceCheck, 0); // Check the creation of a sizable OSSet from an set of IOObjects // Also check member test of set. spaceCheck = checkPointSpace(); for (i = 0; i < numStrCache; i++) cache[i] = OSString::withCStringNoCopy(strCache[i]); set1 = OSSet::withObjects(cache, numStrCache, numStrCache); TEST_ASSERT('S', "2a", set1); for (i = 0; i < numStrCache; i++) cache[i]->release(); if (set1) { TEST_ASSERT('S', "2b", numStrCache == (int) set1->getCount()); TEST_ASSERT('S', "2c", numStrCache == (int) set1->getCapacity()); TEST_ASSERT('S', "2d", numStrCache == (int) set1->getCapacityIncrement()); count = 0; for (i = set1->getCount(); --i >= 0; ) count += set1->member(cache[i]); TEST_ASSERT('S', "2e", numStrCache == count); set1->release(); } res = res && checkSpace("(S)2", spaceCheck, 0); // Test set creation from another set by both the setObject method // and the withArray factory. And test __takeObject code first // with tail removal then with head removal spaceCheck = checkPointSpace(); for (i = 0; i < numStrCache; i++) cache[i] = OSString::withCStringNoCopy(strCache[i]); set1 = OSSet::withObjects(cache, numStrCache, numStrCache); TEST_ASSERT('S', "3a", set1); for (i = 0; i < numStrCache; i++) cache[i]->release(); set2 = 0; if (set1) { set2 = OSSet::withCapacity(set1->getCount()); TEST_ASSERT('S', "3b", set2); TEST_ASSERT('S', "3c", !set2->getCount()); TEST_ASSERT('S', "3d", set2->setObject(set1)); TEST_ASSERT('S', "3e", set1->getCount() == set2->getCount()); } if (set2) { TEST_ASSERT('S', "3f", numStrCache == (int) set2->getCount()); count = count2 = 0; while ( (str = set2->getAnyObject()) ) { count += set2->__takeObject(str); count2 += set1->member(str); str->release(); } TEST_ASSERT('S', "3g", !set2->getCount()); TEST_ASSERT('S', "3h", numStrCache == count); TEST_ASSERT('S', "3i", numStrCache == count2); spaceCheck2 = checkPointSpace(); set2->flushCollection(); res = res && checkSpace("(S)3j", spaceCheck2, 0); set2->release(); set2 = 0; } if (set1) { set2 = OSSet::withSet(set1, numStrCache - 1); TEST_ASSERT('S', "3k", !set2); set2 = OSSet::withSet(set1, set1->getCount()); TEST_ASSERT('S', "3l", set2); set1->release(); } if (set2) { TEST_ASSERT('S', "3m", numStrCache == (int) set2->getCount()); i = count = count2 = 0; while ( (str = set2->getAnyObject()) ) { count += set2->__takeObject(str); count2 += (cache[i++] == str); str->release(); } TEST_ASSERT('S', "3n", !set2->getCount()); TEST_ASSERT('S', "3o", numStrCache == count); TEST_ASSERT('S', "3p", numStrCache == count2); set2->release(); set2 = 0; } res = res && checkSpace("(S)3", spaceCheck, 0); // Test duplicate removal spaceCheck = checkPointSpace(); set2 = 0; set1 = OSSet::withCapacity(numStrCache); TEST_ASSERT('S', "4a", set1); if (set1) { count = 0; for (i = 0; i < numStrCache; i++) { sym = (OSObject *) OSSymbol::withCStringNoCopy(strCache[i]); count += set1->setObject(sym); sym->release(); } TEST_ASSERT('S', "4b", numStrCache != (int) set1->getCount()); TEST_ASSERT('S', "4c", count == (int) set1->getCount()); count = count2 = 0; for (i = 0; i < numStrCache; i++) { sym = (OSObject *) OSSymbol::withCStringNoCopy(strCache[i]); count += set1->member(sym); count2 += sym->getRetainCount(); sym->release(); } TEST_ASSERT('S', "4d", count == numStrCache); TEST_ASSERT('S', "4e", count2 == numStrCache * 2); set2 = OSSet::withSet(set1, 2 * set1->getCount()); } TEST_ASSERT('S', "4f", set2); if (set2) { set2->setObject(set1); TEST_ASSERT('S', "4g", set1->getCount() == set2->getCount()); set1->release(); set2->release(); } res = res && checkSpace("(S)4", spaceCheck, 0); // Test array duplicate removal spaceCheck = checkPointSpace(); array = OSArray::withCapacity(numStrCache); for (i = 0; i < numStrCache; i++) { sym = (OSObject *) OSSymbol::withCStringNoCopy(strCache[i]); count += array->setObject(sym); sym->release(); } set1 = OSSet::withArray(array, numStrCache); TEST_ASSERT('S', "5a", set1); if (set1) { TEST_ASSERT('S', "5b", array->getCount() != set1->getCount()); array->release(); count = count2 = set1->getCount(); while ( (sym = set1->getAnyObject()) ) { count -= set1->__takeObject(sym); count2 -= sym->getRetainCount(); sym->release(); } TEST_ASSERT('S', "5c", !count); TEST_ASSERT('S', "5d", !count2); set1->release(); } res = res && checkSpace("(S)5", spaceCheck, 0); if (res) verPrintf(("testSet: All OSSet Tests passed\n")); else logPrintf(("testSet: Some OSSet Tests failed\n")); }
bool IOCatalogue::addDrivers( OSArray * drivers, bool doNubMatching) { bool result = false; OSCollectionIterator * iter = NULL; // must release OSOrderedSet * set = NULL; // must release OSObject * object = NULL; // do not release OSArray * persons = NULL; // do not release persons = OSDynamicCast(OSArray, drivers); if (!persons) { goto finish; } set = OSOrderedSet::withCapacity( 10, IOServiceOrdering, (void *)gIOProbeScoreKey ); if (!set) { goto finish; } iter = OSCollectionIterator::withCollection(persons); if (!iter) { goto finish; } /* Start with success; clear it on an error. */ result = true; IORWLockWrite(lock); while ( (object = iter->getNextObject()) ) { // xxx Deleted OSBundleModuleDemand check; will handle in other ways for SL OSDictionary * personality = OSDynamicCast(OSDictionary, object); SInt count; if (!personality) { IOLog("IOCatalogue::addDrivers() encountered non-dictionary; bailing.\n"); result = false; break; } OSKext::uniquePersonalityProperties(personality); // Add driver personality to catalogue. OSArray * array = arrayForPersonality(personality); if (!array) addPersonality(personality); else { count = array->getCount(); while (count--) { OSDictionary * driver; // Be sure not to double up on personalities. driver = (OSDictionary *)array->getObject(count); /* Unlike in other functions, this comparison must be exact! * The catalogue must be able to contain personalities that * are proper supersets of others. * Do not compare just the properties present in one driver * pesonality or the other. */ if (personality->isEqualTo(driver)) { break; } } if (count >= 0) { // its a dup continue; } result = array->setObject(personality); if (!result) { break; } } set->setObject(personality); } // Start device matching. if (result && doNubMatching && (set->getCount() > 0)) { IOService::catalogNewDrivers(set); generation++; } IORWLockUnlock(lock); finish: if (set) set->release(); if (iter) iter->release(); return result; }
// Class start bool VoodooPState::start(IOService * provider) { if (!IOService::start(provider)) return false; // Printout banner InfoLog("%s %s (%s) %s %s [%s]", KextProductName, KextVersion, KextConfig, KextBuildDate, KextBuildTime, KextOSX); InfoLog("based on VoodooPower 1.2.3."); // Setup workloop and timer IOWorkLoop* WorkLoop = getWorkLoop(); if (!WorkLoop) return false; TimerEventSource = IOTimerEventSource::timerEventSource(this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &VoodooPState::LoopTimerEvent)); if (!TimerEventSource) return false; if (kIOReturnSuccess != WorkLoop->addEventSource(TimerEventSource)) { return false; } // Get a SimpleLock SimpleLock = IOSimpleLockAlloc(); if (!SimpleLock) return false; // Publish the static characteristics OSDictionary * dictionary = OSDictionary::withCapacity(13); if (!dictionary) return false; OSArray * array = OSArray::withCapacity(PStateCount); if (!array) return false; setDictionaryNumber(keyCpuCoreTech, CpuCoreTech, dictionary); setDictionaryNumber(keyFrontSideBus, CpuFSB, dictionary); for (int i = 0; i < PStateCount; i++) { OSDictionary * pdictionary = OSDictionary::withCapacity(3); if (!pdictionary) return false; setDictionaryNumber(keyCurrentFrequency, PState[i].frequency, pdictionary); setDictionaryNumber(keyCurrentVoltage, PState[i].voltage, pdictionary); setDictionaryNumber(keyFid, PState[i].fid, pdictionary); setDictionaryNumber(keyDid, PState[i].did, pdictionary); setDictionaryNumber(keyVid, PState[i].vid, pdictionary); array->setObject(i, pdictionary); pdictionary->release(); } setDictionaryArray(keyPStates, array, dictionary); setDictionaryString(keyProductName, KextProductName, dictionary); setDictionaryString(keyProductVersion, KextVersion, dictionary); setDictionaryString(keyBuildConfig, KextConfig, dictionary); setDictionaryString(keyBuildDate, KextBuildDate, dictionary); setDictionaryString(keyBuildTime, KextBuildTime, dictionary); setDictionaryNumber(keyTimerInterval, TimerInterval, dictionary); setProperty(keyCharacteristics, dictionary); array->release(); dictionary->release(); // set initial pstate Request = ColdStart ? (PStateCount-1) : 0; // hot/cold start gPEClockFrequencyInfo.cpu_frequency_max_hz = VoodooFrequencyProc(this,&PState[0]) * Mega; gPEClockFrequencyInfo.cpu_frequency_min_hz = VoodooFrequencyProc(this,&PState[PStateCount-1]) * Mega; LoopTimerEvent(); // Finalize and kick off the loop this->registerService(0); Ready = true; return true; }
bool ACPIBacklightPanel::findDevices(IOService * provider) { DbgLog("%s::%s()\n", this->getName(),__FUNCTION__); if (!gpuDevice || !backLightDevice) { IOACPIPlatformDevice * dev = OSDynamicCast(IOACPIPlatformDevice, provider); if (hasBacklightMethods(dev)) { DbgLog("%s: PNLF has backlight Methods\n", this->getName()); backLightDevice = dev; gpuDevice = dev; gpuDevice->retain(); backLightDevice->retain(); } else { gpuDevice = getGPU(); if (NULL == gpuDevice) return false; gpuDevice->retain(); if (hasBacklightMethods(gpuDevice)) { backLightDevice = gpuDevice; } else { backLightDevice = getChildWithBacklightMethods(gpuDevice); } if (backLightDevice == NULL) return false; backLightDevice->retain(); } #ifdef DEBUG if (gpuDevice != backLightDevice) { OSArray * devicePaths = OSArray::withCapacity(2); OSString* path = getACPIPath(gpuDevice); IOLog("ACPIBacklight: ACPI Method _DOS found. Device path: %s\n", path->getCStringNoCopy()); devicePaths->setObject(path); path->release(); path = getACPIPath(backLightDevice); IOLog("ACPIBacklight: ACPI Methods _BCL _BCM _BQC found. Device path: %s\n", path->getCStringNoCopy()); devicePaths->setObject(path); path->release(); setProperty("ACPI Devices Paths", devicePaths); devicePaths->release(); } else { OSString* path = getACPIPath(backLightDevice); IOLog("ACPIBacklight: ACPI Methods _DOS _BCL _BCM _BQC found. Device path: %s\n", path->getCStringNoCopy()); setProperty("ACPI Device Path", path); path->release(); } #endif } return true; }
// Should only be done during init time - this is not thread safe IOReturn IOAudioLevelControl::addRange(SInt32 minRangeValue, SInt32 maxRangeValue, IOFixed minRangeDB, IOFixed maxRangeDB) { IOReturn result = kIOReturnSuccess; // We should verify the new range doesn't overlap any others here if (ranges == NULL) { ranges = OSArray::withCapacity(1); if (ranges) { setProperty(kIOAudioLevelControlRangesKey, ranges); } } if (ranges) { OSDictionary *newRange; OSArray *newRanges; OSArray *oldRanges; oldRanges = ranges; newRanges = OSArray::withArray(ranges); if (!newRanges) return kIOReturnNoMemory; newRange = OSDictionary::withCapacity(4); if (newRange) { OSNumber *number; number = OSNumber::withNumber(minRangeValue, sizeof(SInt32)*8); newRange->setObject(kIOAudioLevelControlMinValueKey, number); number->release(); number = OSNumber::withNumber(maxRangeValue, sizeof(SInt32)*8); newRange->setObject(kIOAudioLevelControlMaxValueKey, number); number->release(); number = OSNumber::withNumber(minRangeDB, sizeof(IOFixed)*8); newRange->setObject(kIOAudioLevelControlMinDBKey, number); number->release(); number = OSNumber::withNumber(maxRangeDB, sizeof(IOFixed)*8); newRange->setObject(kIOAudioLevelControlMaxDBKey, number); number->release(); newRanges->setObject(newRange); setProperty(kIOAudioLevelControlRangesKey, newRanges); ranges = newRanges; oldRanges->release(); newRange->release(); } else { result = kIOReturnError; } } else { result = kIOReturnError; } return result; }
static void createNubs(IOService *provider) { const char nameID[2][8] = {"@0,name", "@1,name"}; const char name[11] = "Aty,Radeon"; const char typeID[2][15] = {"@0,device_type", "@1,device_type"}; const char type[] = "display"; OSObject *tempObj; int i; if (provider->getProperty(kIONDRVIgnoreKey)) return; provider->setProperty(kIONDRVIgnoreKey, kOSBooleanTrue); //prevent IONDRVFramebuffer from match LOG("createNubs\n"); if (!provider->getProperty("@0,name") && !provider->getProperty("@1,name")) { for (i = 0;i < 2;i++) { // Debug tempObj = OSData::withBytes(name, 11); provider->setProperty(nameID[i], tempObj); tempObj->release(); tempObj = OSData::withBytes(type, 8); provider->setProperty(typeID[i], tempObj); tempObj->release(); } } // have to move below part from IONDRVFramebuffer to make it work IORegistryIterator * iter; IORegistryEntry * next; IOService * newNub; OSArray * toDo = 0; bool firstLevel; OSData * data; if (provider->getProperty("@0,name")) { OSDictionary * dict; OSCollectionIterator * keys; const OSSymbol * key; char buffer[80]; const char * keyChrs; size_t len; char c; dict = provider->dictionaryWithProperties(); keys = OSCollectionIterator::withCollection(dict); if (dict) dict->release(); if (keys) { while ((key = OSDynamicCast(OSSymbol, keys->getNextObject()))) { keyChrs = key->getCStringNoCopy(); if ('@' != keyChrs[0]) continue; len = 0; do { c = keyChrs[len]; if (!c || (c == ',')) break; buffer[len] = c; len++; } while (len < (sizeof(buffer) - 1)); if (!c) continue; buffer[len] = 0; keyChrs += len + 1; next = provider->childFromPath(buffer, gIODTPlane); if (!next) { next = new IOService; if (next && !next->init()) { next->release(); next = 0; } if (!next) continue; next->setLocation(&buffer[1]); if (!next->attachToParent(provider, gIODTPlane)) continue; } OSObject * obj = dict->getObject(key); next->setProperty(keyChrs, dict->getObject(key)); if (!strcmp(keyChrs, "name")) { OSData * data = OSDynamicCast(OSData, obj); if (data) next->setName((const char *) data->getBytesNoCopy()); } next->release(); provider->removeProperty(key); } keys->release(); } } iter = IORegistryIterator::iterateOver( provider, gIODTPlane, 0 ); toDo = OSArray::withCapacity(2); if (iter && toDo) { bool haveDoneLibInit = false; UInt32 index = 0; do { while ((next = (IORegistryEntry *) iter->getNextObject())) { firstLevel = (provider == next->getParentEntry(gIODTPlane)); if (firstLevel) { data = OSDynamicCast( OSData, next->getProperty("device_type")); if (!data || (0 != strcmp("display", (char *) data->getBytesNoCopy()))) continue; if (!haveDoneLibInit) { haveDoneLibInit = (kIOReturnSuccess == _IONDRVLibrariesInitialize(provider)); if (!haveDoneLibInit) continue; } next->setProperty( kIOFBDependentIDKey, (uintptr_t) provider, 64 ); next->setProperty( kIOFBDependentIndexKey, index, 32 ); next->setProperty( kIONDRVIgnoreKey, kOSBooleanTrue ); index++; } toDo->setObject( next ); iter->enterEntry(); } } while (iter->exitEntry()); } if (iter) iter->release(); if (toDo) { OSObject * obj; OSArray * deviceMemory; obj = provider->copyProperty(gIODeviceMemoryKey); deviceMemory = OSDynamicCast(OSArray, obj); for (unsigned int i = 0; (next = (IORegistryEntry *) toDo->getObject(i)); i++) { newNub = new IONDRVDevice; if (!newNub) continue; if (!newNub->init(next, gIODTPlane)) { newNub->free(); newNub = 0; continue; } if (deviceMemory) newNub->setDeviceMemory(deviceMemory); newNub->attach(provider); newNub->registerService(kIOServiceSynchronous); } if (obj) obj->release(); toDo->release(); } }
void KLDBootstrap::readBuiltinPersonalities(void) { OSObject * parsedXML = NULL; // must release OSArray * builtinExtensions = NULL; // do not release OSArray * allPersonalities = NULL; // must release OSString * errorString = NULL; // must release kernel_section_t * infosect = NULL; // do not free OSCollectionIterator * personalitiesIterator = NULL; // must release unsigned int count, i; OSKextLog(/* kext */ NULL, kOSKextLogStepLevel | kOSKextLogLoadFlag, "Reading built-in kernel personalities for I/O Kit drivers."); /* Look in the __BUILTIN __info segment for an array of Info.plist * entries. For each one, extract the personalities dictionary, add * it to our array, then push them all (without matching) to * the IOCatalogue. This can be used to augment the personalities * in gIOKernelConfigTables, especially when linking entire kexts into * the mach_kernel image. */ infosect = getsectbyname("__BUILTIN", "__info"); if (!infosect) { // this isn't fatal goto finish; } parsedXML = OSUnserializeXML((const char *) (uintptr_t)infosect->addr, &errorString); if (parsedXML) { builtinExtensions = OSDynamicCast(OSArray, parsedXML); } if (!builtinExtensions) { const char * errorCString = "(unknown error)"; if (errorString && errorString->getCStringNoCopy()) { errorCString = errorString->getCStringNoCopy(); } else if (parsedXML) { errorCString = "not an array"; } OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogLoadFlag, "Error unserializing built-in personalities: %s.", errorCString); goto finish; } // estimate 3 personalities per Info.plist/kext count = builtinExtensions->getCount(); allPersonalities = OSArray::withCapacity(count * 3); for (i = 0; i < count; i++) { OSDictionary * infoDict = NULL; // do not release OSString * moduleName = NULL; // do not release OSDictionary * personalities; // do not release OSString * personalityName; // do not release OSSafeReleaseNULL(personalitiesIterator); infoDict = OSDynamicCast(OSDictionary, builtinExtensions->getObject(i)); if (!infoDict) { continue; } moduleName = OSDynamicCast(OSString, infoDict->getObject(kCFBundleIdentifierKey)); if (!moduleName) { continue; } OSKextLog(/* kext */ NULL, kOSKextLogStepLevel | kOSKextLogLoadFlag, "Adding personalities for built-in driver %s:", moduleName->getCStringNoCopy()); personalities = OSDynamicCast(OSDictionary, infoDict->getObject("IOKitPersonalities")); if (!personalities) { continue; } personalitiesIterator = OSCollectionIterator::withCollection(personalities); if (!personalitiesIterator) { continue; // xxx - well really, what can we do? should we panic? } while ((personalityName = OSDynamicCast(OSString, personalitiesIterator->getNextObject()))) { OSDictionary * personality = OSDynamicCast(OSDictionary, personalities->getObject(personalityName)); OSKextLog(/* kext */ NULL, kOSKextLogDetailLevel | kOSKextLogLoadFlag, "Adding built-in driver personality %s.", personalityName->getCStringNoCopy()); if (personality && !personality->getObject(kCFBundleIdentifierKey)) { personality->setObject(kCFBundleIdentifierKey, moduleName); } allPersonalities->setObject(personality); } } gIOCatalogue->addDrivers(allPersonalities, false); finish: OSSafeReleaseNULL(parsedXML); OSSafeReleaseNULL(allPersonalities); OSSafeReleaseNULL(errorString); OSSafeReleaseNULL(personalitiesIterator); return; }
OSObject * OSUnserializeBinary(const char *buffer, size_t bufferSize, OSString **errorString) { OSObject ** objsArray; uint32_t objsCapacity; enum { objsCapacityMax = 16*1024*1024 }; uint32_t objsIdx; OSObject ** stackArray; uint32_t stackCapacity; enum { stackCapacityMax = 64 }; uint32_t stackIdx; OSObject * result; OSObject * parent; OSDictionary * dict; OSArray * array; OSSet * set; OSDictionary * newDict; OSArray * newArray; OSSet * newSet; OSObject * o; OSSymbol * sym; OSString * str; size_t bufferPos; const uint32_t * next; uint32_t key, len, wordLen; bool end, newCollect, isRef; unsigned long long value; bool ok; if (errorString) *errorString = 0; if (bufferSize < sizeof(kOSSerializeBinarySignature)) return (NULL); if (0 != strcmp(kOSSerializeBinarySignature, buffer)) return (NULL); if (3 & ((uintptr_t) buffer)) return (NULL); bufferPos = sizeof(kOSSerializeBinarySignature); next = (typeof(next)) (((uintptr_t) buffer) + bufferPos); DEBG("---------OSUnserializeBinary(%p)\n", buffer); objsArray = stackArray = NULL; objsIdx = objsCapacity = 0; stackIdx = stackCapacity = 0; result = 0; parent = 0; dict = 0; array = 0; set = 0; sym = 0; ok = true; while (ok) { bufferPos += sizeof(*next); if (!(ok = (bufferPos <= bufferSize))) break; key = *next++; len = (key & kOSSerializeDataMask); wordLen = (len + 3) >> 2; end = (0 != (kOSSerializeEndCollecton & key)); DEBG("key 0x%08x: 0x%04x, %d\n", key, len, end); newCollect = isRef = false; o = 0; newDict = 0; newArray = 0; newSet = 0; switch (kOSSerializeTypeMask & key) { case kOSSerializeDictionary: o = newDict = OSDictionary::withCapacity(len); newCollect = (len != 0); break; case kOSSerializeArray: o = newArray = OSArray::withCapacity(len); newCollect = (len != 0); break; case kOSSerializeSet: o = newSet = OSSet::withCapacity(len); newCollect = (len != 0); break; case kOSSerializeObject: if (len >= objsIdx) break; o = objsArray[len]; isRef = true; break; case kOSSerializeNumber: bufferPos += sizeof(long long); if (bufferPos > bufferSize) break; if ((len != 32) && (len != 64) && (len != 16) && (len != 8)) break; value = next[1]; value <<= 32; value |= next[0]; o = OSNumber::withNumber(value, len); next += 2; break; case kOSSerializeSymbol: bufferPos += (wordLen * sizeof(uint32_t)); if (bufferPos > bufferSize) break; if (len < 2) break; if (0 != ((const char *)next)[len-1]) break; o = (OSObject *) OSSymbol::withCString((const char *) next); next += wordLen; break; case kOSSerializeString: bufferPos += (wordLen * sizeof(uint32_t)); if (bufferPos > bufferSize) break; o = OSString::withStringOfLength((const char *) next, len); next += wordLen; break; case kOSSerializeData: bufferPos += (wordLen * sizeof(uint32_t)); if (bufferPos > bufferSize) break; o = OSData::withBytes(next, len); next += wordLen; break; case kOSSerializeBoolean: o = (len ? kOSBooleanTrue : kOSBooleanFalse); break; default: break; } if (!(ok = (o != 0))) break; if (!isRef) { setAtIndex(objs, objsIdx, o); if (!ok) { o->release(); break; } objsIdx++; } if (dict) { if (!sym) sym = (OSSymbol *) o; else { str = sym; sym = OSDynamicCast(OSSymbol, sym); if (!sym && (str = OSDynamicCast(OSString, str))) { sym = const_cast<OSSymbol *>(OSSymbol::withString(str)); ok = (sym != 0); if (!ok) break; } DEBG("%s = %s\n", sym->getCStringNoCopy(), o->getMetaClass()->getClassName()); if (o != dict) ok = dict->setObject(sym, o); if (sym && (sym != str)) sym->release(); sym = 0; } } else if (array) ok = array->setObject(o); else if (set) ok = set->setObject(o); else if (result) ok = false; else { assert(!parent); result = o; } if (!ok) break; if (end) parent = 0; if (newCollect) { stackIdx++; setAtIndex(stack, stackIdx, parent); if (!ok) break; DEBG("++stack[%d] %p\n", stackIdx, parent); parent = o; dict = newDict; array = newArray; set = newSet; end = false; } if (end) { while (stackIdx) { parent = stackArray[stackIdx]; DEBG("--stack[%d] %p\n", stackIdx, parent); stackIdx--; if (parent) break; } if (!parent) break; set = 0; dict = 0; array = 0; if (!(dict = OSDynamicCast(OSDictionary, parent))) { if (!(array = OSDynamicCast(OSArray, parent))) ok = (0 != (set = OSDynamicCast(OSSet, parent))); } } } DEBG("ret %p\n", result); if (!ok) result = 0; if (objsCapacity) { for (len = (result != 0); len < objsIdx; len++) objsArray[len]->release(); kfree(objsArray, objsCapacity * sizeof(*objsArray)); } if (stackCapacity) kfree(stackArray, stackCapacity * sizeof(*stackArray)); return (result); }
bool ACPIProbe::start(IOService * provider) { ACPISensorsDebugLog("starting..."); if (!super::start(provider)) return false; if (!(acpiDevice = OSDynamicCast(IOACPIPlatformDevice, provider))) { ACPISensorsFatalLog("ACPI device not ready"); return false; } profiles = OSDictionary::withCapacity(0); profileList = OSArray::withCapacity(0); OSObject *object = NULL; // Try to load configuration provided by ACPI device if (kIOReturnSuccess == acpiDevice->evaluateObject("LIST", &object) && object) { if (OSArray *list = OSDynamicCast(OSArray, object)) { for (unsigned int i = 0; i < list->getCount(); i++) { if (OSString *method = OSDynamicCast(OSString, list->getObject(i))) { if (kIOReturnSuccess == acpiDevice->evaluateObject(method->getCStringNoCopy(), &object) && object) { if (OSArray *config = OSDynamicCast(OSArray, object)) { if (config->getCount() > 4) { OSString *pName = OSDynamicCast(OSString, config->getObject(0)); OSNumber *pInterval = OSDynamicCast(OSNumber, config->getObject(1)); OSNumber *pTimeout = OSDynamicCast(OSNumber, config->getObject(2)); OSNumber *pVerbose = OSDynamicCast(OSNumber, config->getObject(3)); OSArray *pMethods = OSArray::withCapacity(config->getCount() - 4); for (unsigned int offset = 4; offset < config->getCount(); offset++) { if (OSString *methodName = OSDynamicCast(OSString, config->getObject(offset))) { pMethods->setObject(methodName); } } addProfile(pName, pMethods, pInterval, pTimeout, pVerbose); } } OSSafeRelease(object); } } } OSSafeRelease(list); } } else { ACPISensorsErrorLog("profile definition table (LIST) not found"); } // Try to load configuration from info.plist if (profiles->getCount() == 0) { if (OSDictionary *configuration = getConfigurationNode()) { OSString *pName = OSDynamicCast(OSString, configuration->getObject("ProfileName")); OSNumber *pInterval = OSDynamicCast(OSNumber, configuration->getObject("PollingInterval")); OSNumber *pTimeout = OSDynamicCast(OSNumber, configuration->getObject("PollingTimeout")); OSBoolean *pVerboseBool = OSDynamicCast(OSBoolean, configuration->getObject("VerboseLog")); OSNumber *pVerbose = OSNumber::withNumber(pVerboseBool->getValue() ? 1 : 0, 8); OSArray *pMethods = OSDynamicCast(OSArray, configuration->getObject("MethodsToPoll")); addProfile(pName, pMethods, pInterval, pTimeout, pVerbose); } } if (this->profiles->getCount()) { // Parse active profile if (kIOReturnSuccess == acpiDevice->evaluateObject("ACTV", &object) && object) { if (OSString *method = OSDynamicCast(OSString, object)) { if (kIOReturnSuccess == acpiDevice->evaluateObject(method->getCStringNoCopy(), &object) && object) { if (OSArray *config = OSDynamicCast(OSArray, object)) { if (config->getCount() > 4) { if (OSString *profile = OSDynamicCast(OSString, config->getObject(0))) { if (!(activeProfile = (ACPIProbeProfile *)profiles->getObject(profile))) { activeProfile = (ACPIProbeProfile *)profileList->getObject(0); } } } } OSSafeRelease(object); } OSSafeRelease(method); } } // woorkloop if (!(workloop = getWorkLoop())) { HWSensorsFatalLog("Failed to obtain workloop"); return false; } if (!(timerEventSource = IOTimerEventSource::timerEventSource( this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &ACPIProbe::woorkloopTimerEvent)))) { ACPISensorsFatalLog("failed to initialize timer event source"); return false; } if (kIOReturnSuccess != workloop->addEventSource(timerEventSource)) { ACPISensorsFatalLog("failed to add timer event source into workloop"); return false; } timerEventSource->setTimeoutMS(100); //ACPISensorsInfoLog("%d method%s registered", methods->getCount(), methods->getCount() > 1 ? "s" : ""); } // two power states - off and on static const IOPMPowerState powerStates[2] = { { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, IOPMDeviceUsable, IOPMPowerOn, IOPMPowerOn, 0, 0, 0, 0, 0, 0, 0, 0 } }; // register interest in power state changes PMinit(); provider->joinPMtree(this); registerPowerDriver(this, (IOPMPowerState *)powerStates, 2); registerService(); ACPISensorsInfoLog("started"); return true; }