Exemple #1
0
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;
}
UInt32 ACPIBacklightPanel::queryACPICurentBrightnessLevel()
{
    //DbgLog("%s::%s()\n", this->getName(),__FUNCTION__);

    if (_backlightHandler)
        return _backlightHandler->getBacklightLevel();
    
    UInt32 level = minAC;
    const char* method = _extended ? "XBQC" : "_BQC";
	if (kIOReturnSuccess == backLightDevice->evaluateInteger(method, &level))
	{
		//DbgLog("%s: queryACPICurentBrightnessLevel %s = %d\n", this->getName(), method, level);
        
        OSBoolean * useIdx = OSDynamicCast(OSBoolean, getProperty("BQC use index"));
        if (useIdx && useIdx->isTrue())
        {
            OSArray * levels = queryACPISupportedBrightnessLevels();
            if (levels)
            {
                OSNumber *num = OSDynamicCast(OSNumber, levels->getObject(level));
                if (num)
                    level = num->unsigned32BitValue();
                levels->release();
            }
        }
        //DbgLog("%s: queryACPICurentBrightnessLevel returning %d\n", this->getName(), level);
	}
	else {
		IOLog("ACPIBacklight: Error in queryACPICurentBrightnessLevel %s\n", method);
	}
    //some laptops didn't return anything on startup, return then max value (first entry in _BCL):
	return level;
}
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 CompareDeviceUsagePairs( IOService * owner, OSDictionary * matching, SInt32 * score, SInt32 increment)
{
    // We return success if we match the key in the dictionary with the key in
    // the property table, or if the prop isn't present
    //
    OSArray *		pairArray;
    OSDictionary * 	pair;
    bool		matches = true;
    int			count;
    
    pairArray = OSDynamicCast(OSArray, matching->getObject( kIOHIDDeviceUsagePairsKey ));
    
    if (pairArray)
    {
        count = pairArray->getCount();
        
        for (int i=0; i<count; i++)
        {
            if ( !(pair = OSDynamicCast(OSDictionary,pairArray->getObject(i))) )
                continue;
        
            if ( !(matches = CompareDeviceUsage(owner, pair, score, increment)) )
                continue;

            break;
        }
    }
    
    return matches;
}
bool CompareNumberPropertyArray( IOService * owner, OSDictionary * matching, const char * arrayName, const char * key, SInt32 * score, SInt32 increment)
{
	OSNumber    *registryProperty = (OSNumber *)owner->copyProperty(key);
    OSArray     *propertyArray = (OSArray *)matching->getObject(arrayName);
    CONVERT_TO_STACK_RETAIN(registryProperty);
	
    // If the property in the matching doesn't exist return true
	if ( OSDynamicCast(OSArray, propertyArray) )
    {
        if ( OSDynamicCast(OSNumber, registryProperty ) )
        {
            OSNumber *propertyFromArray;
            int i = 0;
            
            for ( i = 0; i < propertyArray->getCount(); i ++ )
            {
                propertyFromArray = OSDynamicCast(OSNumber, propertyArray->getObject(i));
                if ( propertyFromArray && propertyFromArray->isEqualTo(registryProperty) )
                {
                    if ( score )
                        *score += increment;
                    return true;
                }
            }
        }
    }
    else
        return true;
    
	return false;
}
Exemple #6
0
void SuperIO::LoadConfiguration(IOService* provider) {
	m_Service = provider;
	
	OSBoolean* fanControl = OSDynamicCast(OSBoolean, provider->getProperty("Enable Fan Control"));	
	m_FanControl = fanControl->getValue();
	
	OSBoolean* alternateRegisters = OSDynamicCast(OSBoolean, provider->getProperty("Register number alternative variant"));
	m_AlternateRegisters = alternateRegisters->getValue();
		
	OSArray* fanIDs = OSDynamicCast(OSArray, provider->getProperty("Fan Names"));	
	if (fanIDs) fanIDs = OSArray::withArray(fanIDs);	
    if (fanIDs)  {
		UInt32 count = fanIDs->getCount();
		
		if(count > 5)
			count = 5;
		
		for (UInt32 i = 0; i < count; i++) {
			OSString* name = OSDynamicCast(OSString, fanIDs->getObject(i)); 
			FanName[i] = name->getCStringNoCopy();
		}
		
		fanIDs->release();
    }
}
//====================================================================================================
// IOHIDEventOverrideDriver::dispatchKeyboardEvent
//====================================================================================================
bool IOHIDEventOverrideDriver::handleStart( IOService * provider )
{
    OSArray * maps = NULL;
    
    if ( !super::handleStart(provider) )
        return false;
    
    maps = OSDynamicCast(OSArray, getProperty("ButtonMaps"));
    if ( maps ) {
        int index;
        
        for ( index=0; index<maps->getCount(); index++ ) {
            OSDictionary *  map;
            OSNumber *      number;
            uint32_t        button;
            uint32_t        usagePage;
            uint32_t        usage;
            uint32_t        eventType;
            
            map = OSDynamicCast(OSDictionary, maps->getObject(index));
            if ( !map )
                continue;
            
            number = OSDynamicCast(OSNumber, map->getObject("ButtonNumber"));
            if ( !number )
                continue;
            
            button = number->unsigned32BitValue();
            if ( !button || button>32 )
                continue;
            
            number = OSDynamicCast(OSNumber, map->getObject("EventType"));
            if ( !number )
                continue;
            
            eventType = number->unsigned32BitValue();
            
            number = OSDynamicCast(OSNumber, map->getObject("UsagePage"));
            if ( !number )
                continue;
            
            usagePage = number->unsigned32BitValue();

            number = OSDynamicCast(OSNumber, map->getObject("Usage"));
            if ( !number )
                continue;
            
            usage = number->unsigned32BitValue();
            
            _buttonMap[button-1].eventType  = eventType;
            _buttonMap[button-1].usagePage  = usagePage;
            _buttonMap[button-1].usage      = usage;
        }
    }
    
    return true;
}
void loadPStateOverride(OSArray* dict) {
	
  //return;
  // autodetect
  
  /* Here we load the override pstate table from the given array */
	NumberOfPStates = dict->getCount();
	for (int i = 0; i < NumberOfPStates; i++) {
		OSArray* onePstate		= (OSArray*) dict->getObject(i);
		PStates[i].AcpiFreq		= ((OSNumber*) onePstate->getObject(0))->unsigned16BitValue();
		PStates[i].Frequency		= MHz_to_FID(PStates[i].AcpiFreq); // this accounts for N/2 automatically
		PStates[i].OriginalVoltage	= mV_to_VID(((OSNumber*) onePstate->getObject(1))->unsigned16BitValue());
		PStates[i].Voltage		= PStates[i].OriginalVoltage;
		PStates[i].TimesChosen		= 0;
		info("P-State %d: %d MHz Fr: %d at %d mV\n", i, PStates[i].AcpiFreq, PStates[i].Frequency, VID_to_mV(PStates[i].OriginalVoltage));
	}
	info("Loaded %d PStates from Info.plist\n", NumberOfPStates);
}
UInt32 ACPIBacklightPanel::setupIndexedLevels()
{
    DbgLog("%s::%s()\n", this->getName(),__FUNCTION__);
    
	OSNumber * num;
	OSArray * levels = queryACPISupportedBrightnessLevels();
	if (levels)
	{
		BCLlevelsCount = levels->getCount();
		
		if (BCLlevelsCount < 3)
			return 0;
		
		//verify the types of objects is good once for all
		for (int i = 0; i< BCLlevelsCount; i++) {
			if (!OSDynamicCast(OSNumber, levels->getObject(i)))
				return 0;
		}
		
        //TODO : manage the case when the list has no order! Linux do that
		//test the order of the list
		UInt32 min, max;
		num = OSDynamicCast(OSNumber, levels->getObject(2));
		min = num->unsigned32BitValue();
		num = OSDynamicCast(OSNumber, levels->getObject(BCLlevelsCount-1));
		max = num->unsigned32BitValue();
		
		if (max < min) //list is reverted !
		{
			BCLlevels = new UInt32[BCLlevelsCount];
			for (int i = 0; i< BCLlevelsCount; i++) {
				num = OSDynamicCast(OSNumber, levels->getObject(BCLlevelsCount -1 -i));
				BCLlevels[i] = num->unsigned32BitValue();
			}
		}
		else
		{
			BCLlevelsCount = BCLlevelsCount -2;
			BCLlevels = new UInt32[BCLlevelsCount];
			for (int i = 0; i< BCLlevelsCount; i++) {
				num = OSDynamicCast(OSNumber, levels->getObject(i+2));
				BCLlevels[i] = num->unsigned32BitValue();
			}
		}

		//2 first items are min on ac and max on bat
		num = OSDynamicCast(OSNumber, levels->getObject(0));
		minAC = findIndexForLevel(num->unsigned32BitValue());
		setDebugProperty("BCL: Min on AC", num);
		num = OSDynamicCast(OSNumber, levels->getObject(1));
		maxBat = findIndexForLevel(num->unsigned32BitValue());
		setDebugProperty("BCL: Max on Bat", num);
		setDebugProperty("Brightness Control Levels", levels);
        levels->release();
		
		return BCLlevelsCount-1;
	}
	return 0;
}
Exemple #10
0
/*********************************************************************
* Remove drivers from the catalog which match the
* properties in the matching dictionary.
*********************************************************************/
bool
IOCatalogue::removeDrivers(
    OSDictionary * matching,
    bool doNubMatching)
{
    OSOrderedSet         * set;
    OSCollectionIterator * iter;
    OSDictionary         * dict;
    OSArray              * array;
    const OSSymbol       * key;
    unsigned int           idx;

    if ( !matching )
        return false;
    
    set = OSOrderedSet::withCapacity(10,
                                     IOServiceOrdering,
                                     (void *)gIOProbeScoreKey);
    if ( !set )
        return false;
    iter = OSCollectionIterator::withCollection(personalities);
    if (!iter) 
    {
    	set->release();
    	return (false);
    }

    IORWLockWrite(lock);
    while ((key = (const OSSymbol *) iter->getNextObject()))
    {
        array = (OSArray *) personalities->getObject(key);
        if (array) for (idx = 0; (dict = (OSDictionary *) array->getObject(idx)); idx++)
        {
           /* This comparison must be done with only the keys in the
            * "matching" dict to enable general searches.
            */
            if ( dict->isEqualTo(matching, matching) ) {
                set->setObject(dict);        
                array->removeObject(idx);
                idx--;
            }
        }
        // Start device matching.
        if ( doNubMatching && (set->getCount() > 0) ) {
            IOService::catalogNewDrivers(set);
            generation++;
        }
    }
    IORWLockUnlock(lock);
   
    set->release();
    iter->release();
    
    return true;
}
bool CompareDeviceUsage( IOService * owner, OSDictionary * matching, SInt32 * score, SInt32 increment)
{
    // We return success if we match the key in the dictionary with the key in
    // the property table, or if the prop isn't present
    //
    OSObject * 		usage;
    OSObject *		usagePage;
    OSArray *		functions;
    OSDictionary * 	pair;
    bool		matches = true;
    int			count;
    
    usage = matching->getObject( kIOHIDDeviceUsageKey );
    usagePage = matching->getObject( kIOHIDDeviceUsagePageKey );
    functions = OSDynamicCast(OSArray, owner->copyProperty( kIOHIDDeviceUsagePairsKey ));
    
    if ( functions )
    {
        if ( usagePage || usage )
        {
            count = functions->getCount();
            
            for (int i=0; i<count; i++)
            {
                if ( !(pair = (OSDictionary *)functions->getObject(i)) )
                    continue;
            
                if ( !usagePage || 
                    !(matches = usagePage->isEqualTo(pair->getObject(kIOHIDDeviceUsagePageKey))) )
                    continue;

                if ( score && !usage ) 
                {
                    *score += increment / 2;
                    break;
                }
                    
                if ( !usage || 
                    !(matches = usage->isEqualTo(pair->getObject(kIOHIDDeviceUsageKey))) )            
                    continue;
        
                if ( score ) 
                    *score += increment;
                
                break;
            }
        }
        
        functions->release();
    } else {
		matches = false;
	}
    
    return matches;
}
void AppleACPIPS2Nub::mergeInterruptProperties(IOService *pnpProvider, long)
{
    /* Make sure we're called from within start() where these i-vars are valid */
    if(m_interruptControllers == NULL || m_interruptSpecifiers == NULL)
        return;

    /*  Get the interrupt controllers/specifiers arrays from the provider, and make sure they
     *  exist and contain at least one entry.  We assume they contain exactly one entry.
     */
    OSArray *controllers = OSDynamicCast(OSArray,pnpProvider->getProperty(gIOInterruptControllersKey));
    OSArray *specifiers = OSDynamicCast(OSArray,pnpProvider->getProperty(gIOInterruptSpecifiersKey));
    if(controllers == NULL || specifiers == NULL)
        return;
    if(controllers->getCount() == 0 || specifiers->getCount() == 0)
        return;

    /* Append the first object of each array into our own respective array */
    m_interruptControllers->setObject(controllers->getObject(0));
    m_interruptSpecifiers->setObject(specifiers->getObject(0));
}
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;
}
Exemple #14
0
//  This routine will look to see if the OSArray contains any matching keys.  The OSArray has to contain a list of OSNumbers.
bool 
IOUSBNub::USBComparePropertyInArray( OSDictionary *matching, const char * arrayName, const char * key, UInt32 * theProductIDThatMatched )
{
    // We return success iff we match any entry in the array with the key 
	OSArray *		propertyIDArray = NULL;
	OSNumber *		registryProperty = NULL;
	OSNumber *		propertyFromArrayItem = NULL;
    bool			matches = false;
	unsigned int	index;
	
	*theProductIDThatMatched = 0;
	
	// Get our nub's value for the key
	registryProperty = OSDynamicCast(OSNumber, getProperty(key));
	propertyIDArray = OSDynamicCast(OSArray, matching->getObject(arrayName));
	
	// Iterate over the array looking for the entries
	if (propertyIDArray && registryProperty)
	{
		USBLog(7, "%s[%p]::USBComparePropertyInArray - found array with capacity of %d", getName(), this, propertyIDArray->getCount());
		
		for (index = 0; index < propertyIDArray->getCount(); index++)
		{
			propertyFromArrayItem = OSDynamicCast(OSNumber, propertyIDArray->getObject(index));
			if (propertyFromArrayItem)
			{
				// See if this item has the same value as the one in our registry for this key
				matches = propertyFromArrayItem->isEqualTo( registryProperty);
				if (matches)
				{
					*theProductIDThatMatched = propertyFromArrayItem->unsigned32BitValue();
					USBLog(7, "%s[%p]::USBComparePropertyInArray - item %d matched:  id = 0x%x", getName(), this, index, (uint32_t) *theProductIDThatMatched);
					break;
				}
				else 
				{
					USBLog(7, "%s[%p]::USBComparePropertyInArray - item %d did not match", getName(), this, index);
				}
			}
		}
	}
	
    return matches;
}
Exemple #15
0
//  This routine will look to see if the OSArray contains any matching keys.  The OSArray has to contain a list of OSNumbers.
bool 
IOUSBNub::USBComparePropertyInArrayWithMask( OSDictionary *matching, const char * arrayName, const char * key, const char * maskKey, UInt32 * theProductIDThatMatched )
{
    // We return success iff we match any entry in the array with the key 
	OSArray *		propertyIDArray = NULL;
	OSNumber *		registryProperty = NULL;
	OSNumber *		propertyFromArrayItem = NULL;
    OSNumber *		dictionaryMask = NULL;
    bool			matches = false;
	unsigned int	index;
	
	*theProductIDThatMatched = 0;
	
	// Get our nub's value for the key
	registryProperty = OSDynamicCast(OSNumber, getProperty(key));
	propertyIDArray = OSDynamicCast(OSArray, matching->getObject(arrayName));
    dictionaryMask = OSDynamicCast(OSNumber, matching->getObject(maskKey));
	
	// Iterate over the array looking for the entries
	if (propertyIDArray && registryProperty && dictionaryMask)
	{
		USBLog(7, "%s[%p]::USBComparePropertyInArrayWithMask - found array with capacity of %d", getName(), this, propertyIDArray->getCount());
		
		for (index = 0; index < propertyIDArray->getCount(); index++)
		{
			propertyFromArrayItem = OSDynamicCast(OSNumber, propertyIDArray->getObject(index));
			if (propertyFromArrayItem)
			{
				UInt32  registryValue = registryProperty->unsigned32BitValue();
				UInt32  arrayValue = propertyFromArrayItem->unsigned32BitValue();
				UInt32  mask = dictionaryMask->unsigned32BitValue();
				
				if ( (registryValue & mask) == (arrayValue & mask) )
				{
					USBLog(7, "%s[%p]::USBComparePropertyInArrayWithMask - 0x%x, 0x%x, mask 0x%x matched", getName(), this, (uint32_t)arrayValue, (uint32_t)registryValue, (uint32_t)mask);
					*theProductIDThatMatched = registryValue;
					matches = true;
				}
			}
		}
	}
	
    return matches;
}
Exemple #16
0
/*********************************************************************
* Is personality already in the catalog?
*********************************************************************/
OSOrderedSet *
IOCatalogue::findDrivers(
    OSDictionary * matching,
    SInt32 * generationCount)
{
    OSCollectionIterator * iter;
    OSDictionary         * dict;
    OSOrderedSet         * set;
    OSArray              * array;
    const OSSymbol       * key;
    unsigned int           idx;

    OSKext::uniquePersonalityProperties(matching);

    set = OSOrderedSet::withCapacity( 1, IOServiceOrdering,
                                      (void *)gIOProbeScoreKey );
    if (!set) return (0);
    iter = OSCollectionIterator::withCollection(personalities);
    if (!iter) 
    {
    	set->release();
    	return (0);
    }

    IORWLockRead(lock);
    while ((key = (const OSSymbol *) iter->getNextObject()))
    {
        array = (OSArray *) personalities->getObject(key);
        if (array) for (idx = 0; (dict = (OSDictionary *) array->getObject(idx)); idx++)
        {
	   /* This comparison must be done with only the keys in the
	    * "matching" dict to enable general searches.
	    */
	    if ( dict->isEqualTo(matching, matching) )
		set->setObject(dict);
	}
    }
    *generationCount = getGenerationCount();
    IORWLockUnlock(lock);

    iter->release();
    return set;
}
bool CompareNumberPropertyArrayWithMask( IOService * owner, OSDictionary * matching, const char * arrayName, const char * key, const char * maskKey, SInt32 * score, SInt32 increment)
{
	OSNumber    *registryProperty = (OSNumber *)owner->copyProperty(key);
    OSArray     *propertyArray = (OSArray *)matching->getObject(arrayName);
	OSNumber    *valueMask = (OSNumber *)matching->getObject(maskKey);
    CONVERT_TO_STACK_RETAIN(registryProperty);

    // If the property array or the value mask doesn't exist then return true
    if( OSDynamicCast(OSArray, propertyArray) && OSDynamicCast(OSNumber, valueMask) )
    {
        if ( OSDynamicCast(OSNumber, registryProperty) )
        {
            OSNumber *propertyFromArray;
            UInt32  registryValue = registryProperty->unsigned32BitValue();
            UInt32  mask = valueMask->unsigned32BitValue();
            
            int i = 0;
            
            for ( i = 0; i < propertyArray->getCount(); i ++ )
            {
                propertyFromArray = OSDynamicCast(OSNumber, propertyArray->getObject(i));
                if ( propertyFromArray )
                {
                    UInt32 propertyFromArrayValue = propertyFromArray->unsigned32BitValue();
                    if( (registryValue & mask) == (propertyFromArrayValue & mask ) )
                    {
                        if ( score )
                            *score += increment;
                        return true;
                        
                    }
                }
            }
        }
	}
    else
        return true;
    
	return false;
}
Exemple #18
0
IOReturn IOCatalogue::_removeDrivers(OSDictionary * matching)
{
    IOReturn               ret = kIOReturnSuccess;
    OSCollectionIterator * iter;
    OSDictionary         * dict;
    OSArray              * array;
    const OSSymbol       * key;
    unsigned int           idx;

    // remove configs from catalog.

    iter = OSCollectionIterator::withCollection(personalities);
    if (!iter) return (kIOReturnNoMemory);

    while ((key = (const OSSymbol *) iter->getNextObject()))
    {
        array = (OSArray *) personalities->getObject(key);
        if (array) for (idx = 0; (dict = (OSDictionary *) array->getObject(idx)); idx++)
        {

	    /* Remove from the catalogue's array any personalities
	     * that match the matching dictionary.
	     * This comparison must be done with only the keys in the
	     * "matching" dict to enable general matching.
	     */
            if (dict->isEqualTo(matching, matching))
            {
                array->removeObject(idx);
                idx--;
            }
        }
    }
    iter->release();

    return ret;
}
Exemple #19
0
OSOrderedSet *
IOCatalogue::findDrivers(
    IOService * service,
    SInt32 * generationCount)
{
    OSDictionary         * nextTable;
    OSOrderedSet         * set;
    OSArray              * array;
    const OSMetaClass    * meta;
    unsigned int           idx;

    set = OSOrderedSet::withCapacity( 1, IOServiceOrdering,
                                      (void *)gIOProbeScoreKey );
    if( !set )
	return( 0 );

    IORWLockRead(lock);

    meta = service->getMetaClass();
    while (meta)
    {
    	array = (OSArray *) personalities->getObject(meta->getClassNameSymbol());
	if (array) for (idx = 0; (nextTable = (OSDictionary *) array->getObject(idx)); idx++)
	{
            set->setObject(nextTable);
	}
	if (meta == &IOService::gMetaClass) break;
	meta = meta->getSuperClass();
    }

    *generationCount = getGenerationCount();

    IORWLockUnlock(lock);

    return( set );
}
Exemple #20
0
void
KLDBootstrap::readPrelinkedExtensions(
    kernel_section_t * prelinkInfoSect)
{
    OSArray                   * infoDictArray           = NULL;  // do not release
    OSObject                  * parsedXML       = NULL;  // must release
    OSDictionary              * prelinkInfoDict         = NULL;  // do not release
    OSString                  * errorString             = NULL;  // must release
    OSKext                    * theKernel               = NULL;  // must release

    kernel_segment_command_t  * prelinkTextSegment      = NULL;  // see code
    kernel_segment_command_t  * prelinkInfoSegment      = NULL;  // see code

   /* We make some copies of data, but if anything fails we're basically
    * going to fail the boot, so these won't be cleaned up on error.
    */
    void                      * prelinkData             = NULL;  // see code
    vm_size_t                   prelinkLength           = 0;


    OSDictionary              * infoDict                = NULL;  // do not release

    IORegistryEntry           * registryRoot            = NULL;  // do not release
    OSNumber                  * prelinkCountObj         = NULL;  // must release

    u_int                       i = 0;
#if NO_KEXTD
    bool                        ramDiskBoot;
    bool                        developerDevice;
    bool                        dontLoad;
#endif
    OSData                     * kaslrOffsets = NULL;
    unsigned long               plk_segSizes[PLK_SEGMENTS];
    vm_offset_t                 plk_segAddrs[PLK_SEGMENTS];

    OSKextLog(/* kext */ NULL,
        kOSKextLogProgressLevel |
        kOSKextLogDirectoryScanFlag | kOSKextLogArchiveFlag,
        "Starting from prelinked kernel.");

    prelinkTextSegment = getsegbyname(kPrelinkTextSegment);
    if (!prelinkTextSegment) {
        OSKextLog(/* kext */ NULL,
            kOSKextLogErrorLevel |
            kOSKextLogDirectoryScanFlag | kOSKextLogArchiveFlag,
            "Can't find prelinked kexts' text segment.");
        goto finish;
    }

#if KASLR_KEXT_DEBUG
    unsigned long   scratchSize;
    vm_offset_t     scratchAddr;
    
    IOLog("kaslr: prelinked kernel address info: \n");
    
    scratchAddr = (vm_offset_t) getsegdatafromheader(&_mh_execute_header, "__TEXT", &scratchSize);
    IOLog("kaslr: start 0x%lx end 0x%lx length %lu for __TEXT \n", 
          (unsigned long)scratchAddr, 
          (unsigned long)(scratchAddr + scratchSize),
          scratchSize);
    
    scratchAddr = (vm_offset_t) getsegdatafromheader(&_mh_execute_header, "__DATA", &scratchSize);
    IOLog("kaslr: start 0x%lx end 0x%lx length %lu for __DATA \n", 
          (unsigned long)scratchAddr, 
          (unsigned long)(scratchAddr + scratchSize),
          scratchSize);
    
    scratchAddr = (vm_offset_t) getsegdatafromheader(&_mh_execute_header, "__LINKEDIT", &scratchSize);
    IOLog("kaslr: start 0x%lx end 0x%lx length %lu for __LINKEDIT \n", 
          (unsigned long)scratchAddr, 
          (unsigned long)(scratchAddr + scratchSize),
          scratchSize);
    
    scratchAddr = (vm_offset_t) getsegdatafromheader(&_mh_execute_header, "__KLD", &scratchSize);
    IOLog("kaslr: start 0x%lx end 0x%lx length %lu for __KLD \n", 
          (unsigned long)scratchAddr, 
          (unsigned long)(scratchAddr + scratchSize),
          scratchSize);
    
    scratchAddr = (vm_offset_t) getsegdatafromheader(&_mh_execute_header, "__PRELINK_TEXT", &scratchSize);
    IOLog("kaslr: start 0x%lx end 0x%lx length %lu for __PRELINK_TEXT \n", 
          (unsigned long)scratchAddr, 
          (unsigned long)(scratchAddr + scratchSize),
          scratchSize);
    
    scratchAddr = (vm_offset_t) getsegdatafromheader(&_mh_execute_header, "__PRELINK_INFO", &scratchSize);
    IOLog("kaslr: start 0x%lx end 0x%lx length %lu for __PRELINK_INFO \n", 
          (unsigned long)scratchAddr, 
          (unsigned long)(scratchAddr + scratchSize),
          scratchSize);
#endif

    prelinkData = (void *) prelinkTextSegment->vmaddr;
    prelinkLength = prelinkTextSegment->vmsize;

    /* build arrays of plk info for later use */
    const char ** segNamePtr;

    for (segNamePtr = &plk_segNames[0], i = 0; *segNamePtr && i < PLK_SEGMENTS; segNamePtr++, i++) {
        plk_segSizes[i] = 0;
        plk_segAddrs[i] = (vm_offset_t)getsegdatafromheader(&_mh_execute_header, *segNamePtr, &plk_segSizes[i]);
    }


   /* Unserialize the info dictionary from the prelink info section.
    */
    parsedXML = OSUnserializeXML((const char *)prelinkInfoSect->addr,
        &errorString);
    if (parsedXML) {
        prelinkInfoDict = OSDynamicCast(OSDictionary, parsedXML);
    }
    if (!prelinkInfoDict) {
        const char * errorCString = "(unknown error)";
        
        if (errorString && errorString->getCStringNoCopy()) {
            errorCString = errorString->getCStringNoCopy();
        } else if (parsedXML) {
            errorCString = "not a dictionary";
        }
        OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogArchiveFlag,
            "Error unserializing prelink plist: %s.", errorCString);
        goto finish;
    }

#if NO_KEXTD
    /* Check if we should keep developer kexts around.
     * TODO: Check DeviceTree instead of a boot-arg <rdar://problem/10604201>
     */
    developerDevice = true;
    PE_parse_boot_argn("developer", &developerDevice, sizeof(developerDevice));

    ramDiskBoot = IORamDiskBSDRoot();
#endif /* NO_KEXTD */


    infoDictArray = OSDynamicCast(OSArray, 
        prelinkInfoDict->getObject(kPrelinkInfoDictionaryKey));
    if (!infoDictArray) {
        OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogArchiveFlag,
            "The prelinked kernel has no kext info dictionaries");
        goto finish;
    }
    
    /* kaslrOffsets are available use them to slide local relocations */
    kaslrOffsets = OSDynamicCast(OSData,
                                 prelinkInfoDict->getObject(kPrelinkLinkKASLROffsetsKey));
        
    /* Create dictionary of excluded kexts
     */
    OSKext::createExcludeListFromPrelinkInfo(infoDictArray);
    /* Create OSKext objects for each info dictionary. 
     */
    for (i = 0; i < infoDictArray->getCount(); ++i) {
        infoDict = OSDynamicCast(OSDictionary, infoDictArray->getObject(i));
        if (!infoDict) {
            OSKextLog(/* kext */ NULL,
                kOSKextLogErrorLevel |
                kOSKextLogDirectoryScanFlag | kOSKextLogArchiveFlag,
                "Can't find info dictionary for prelinked kext #%d.", i);
            continue;
        }

#if NO_KEXTD
        dontLoad = false;

        /* If we're not on a developer device, skip and free developer kexts.
         */
        if (developerDevice == false) {
            OSBoolean *devOnlyBool = OSDynamicCast(OSBoolean,
                infoDict->getObject(kOSBundleDeveloperOnlyKey));
            if (devOnlyBool == kOSBooleanTrue) {
                dontLoad = true;
            }
        }

        /* Skip and free kexts that are only needed when booted from a ram disk.
         */
        if (ramDiskBoot == false) {
            OSBoolean *ramDiskOnlyBool = OSDynamicCast(OSBoolean,
                infoDict->getObject(kOSBundleRamDiskOnlyKey));
            if (ramDiskOnlyBool == kOSBooleanTrue) {
                dontLoad = true;
            }
        }

        if (dontLoad == true) {
            OSString *bundleID = OSDynamicCast(OSString,
                infoDict->getObject(kCFBundleIdentifierKey));
            if (bundleID) {
                OSKextLog(NULL, kOSKextLogWarningLevel | kOSKextLogGeneralFlag,
                    "Kext %s not loading.", bundleID->getCStringNoCopy());
            }
            
            OSNumber *addressNum = OSDynamicCast(OSNumber,
                infoDict->getObject(kPrelinkExecutableLoadKey));
            OSNumber *lengthNum = OSDynamicCast(OSNumber,
                infoDict->getObject(kPrelinkExecutableSizeKey));
            if (addressNum && lengthNum) {
#error Pick the right way to free prelinked data on this arch
            }

            infoDictArray->removeObject(i--);
            continue;
        }
#endif /* NO_KEXTD */

       /* Create the kext for the entry, then release it, because the
        * kext system keeps them around until explicitly removed.
        * Any creation/registration failures are already logged for us.
        */
        OSKext * newKext = OSKext::withPrelinkedInfoDict(infoDict, (kaslrOffsets ? TRUE : FALSE));
        OSSafeReleaseNULL(newKext);
    }

    /* slide kxld relocations */
    if (kaslrOffsets && vm_kernel_slide > 0) {
	    int slidKextAddrCount = 0;
	    int badSlideAddr = 0;
	    int badSlideTarget = 0;

        kaslrPackedOffsets * myOffsets = NULL;
	    myOffsets = (kaslrPackedOffsets *) kaslrOffsets->getBytesNoCopy();

	    for (uint32_t j = 0; j < myOffsets->count; j++) {

		    uint64_t        slideOffset = (uint64_t) myOffsets->offsetsArray[j];
		    uintptr_t *     slideAddr = (uintptr_t *) ((uint64_t)prelinkData + slideOffset);
		    int             slideAddrSegIndex = -1;
		    int             addrToSlideSegIndex = -1;

		    slideAddrSegIndex = __whereIsAddr( (vm_offset_t)slideAddr, &plk_segSizes[0], &plk_segAddrs[0], PLK_SEGMENTS );
		    if (slideAddrSegIndex >= 0) {
			    addrToSlideSegIndex = __whereIsAddr( (vm_offset_t)(*slideAddr + vm_kernel_slide), &plk_segSizes[0], &plk_segAddrs[0], PLK_SEGMENTS );
			    if (addrToSlideSegIndex < 0) {
				    badSlideTarget++;
				    continue;
			    }
		    }
		    else {
			    badSlideAddr++;
			    continue;
		    }

		    slidKextAddrCount++;
		    *(slideAddr) += vm_kernel_slide;
	    } // for ...

	    /* All kexts are now slid, set VM protections for them */
	    OSKext::setAllVMAttributes();
    }

   /* Store the number of prelinked kexts in the registry so we can tell
    * when the system has been started from a prelinked kernel.
    */
    registryRoot = IORegistryEntry::getRegistryRoot();
    assert(registryRoot);

    prelinkCountObj = OSNumber::withNumber(
        (unsigned long long)infoDictArray->getCount(),
        8 * sizeof(uint32_t));
    assert(prelinkCountObj);
    if (prelinkCountObj) {
        registryRoot->setProperty(kOSPrelinkKextCountKey, prelinkCountObj);
    }
    
    OSKextLog(/* kext */ NULL,
        kOSKextLogProgressLevel |
        kOSKextLogGeneralFlag | kOSKextLogKextBookkeepingFlag |
        kOSKextLogDirectoryScanFlag | kOSKextLogArchiveFlag,
        "%u prelinked kexts", 
        infoDictArray->getCount());

#if CONFIG_KEXT_BASEMENT
        /* On CONFIG_KEXT_BASEMENT systems, kexts are copied to their own 
         * special VM region during OSKext init time, so we can free the whole 
         * segment now.
         */
        ml_static_mfree((vm_offset_t) prelinkData, prelinkLength);
#endif /* __x86_64__ */

   /* Free the prelink info segment, we're done with it.
    */
    prelinkInfoSegment = getsegbyname(kPrelinkInfoSegment);
    if (prelinkInfoSegment) {
        ml_static_mfree((vm_offset_t)prelinkInfoSegment->vmaddr,
            (vm_size_t)prelinkInfoSegment->vmsize);
    }

finish:
    OSSafeReleaseNULL(errorString);
    OSSafeReleaseNULL(parsedXML);
    OSSafeReleaseNULL(theKernel);
    OSSafeReleaseNULL(prelinkCountObj);
    return;
}
bool ACPIMonitor::start(IOService * provider)
{
	if (!super::start(provider)) 
        return false;

	acpiDevice = (IOACPIPlatformDevice *)provider;
	
	if (!acpiDevice) {
        HWSensorsWarningLog("ACPI device not ready");
        return false;
    }
    
    if (OSDictionary *config = OSDynamicCast(OSDictionary, getProperty("Keys Associations"))) {
        // Temperatures
        if ((temperatures = OSDynamicCast(OSDictionary, config->getObject("Temperatures")))) {
            OSCollectionIterator *iterator = OSCollectionIterator::withCollection(temperatures);
            
            iterator->reset();
            
            while (OSString *key = OSDynamicCast(OSString, iterator->getNextObject())) {
                
                OSString *method = OSDynamicCast(OSString, temperatures->getObject(key));
                
                if (method && kIOReturnSuccess == acpiDevice->evaluateObject(method->getCStringNoCopy())) {
                    if (!addSensor(key->getCStringNoCopy(), TYPE_SP78, TYPE_SPXX_SIZE, kFakeSMCTemperatureSensor, 0))
                        HWSensorsWarningLog("can't add temperature sensor for method %s with key %s", method->getCStringNoCopy(), key->getCStringNoCopy());
                }
            };
            
           //HWSensorsInfoLog("%d temperature sensor(s) added", count);
        }
        else return false;
        
        
        // Voltages
        if ((voltages = OSDynamicCast(OSDictionary, config->getObject("Voltages")))) {
            OSCollectionIterator *iterator = OSCollectionIterator::withCollection(voltages);
            
            iterator->reset();
            
            while (OSString *key = OSDynamicCast(OSString, iterator->getNextObject())) {
                
                OSString *method = OSDynamicCast(OSString, voltages->getObject(key));
                
                if (method && kIOReturnSuccess == acpiDevice->evaluateObject(method->getCStringNoCopy())) {
                    if (!addSensor(key->getCStringNoCopy(), TYPE_FP4C, TYPE_FPXX_SIZE, kFakeSMCVoltageSensor, 0))
                        HWSensorsWarningLog("can't add voltage sensor for method %s with key %s", method->getCStringNoCopy(), key->getCStringNoCopy());
                }
            };
            
            //HWSensorsInfoLog("%d voltage sensor(s) added", count);
        }
        else return false;
        
        
        // Tachometers
        if ((tachometers = OSDynamicCast(OSDictionary, config->getObject("Tachometers")))) {
            UInt16 count = 0;
            OSArray* fanNames = OSDynamicCast(OSArray, getProperty("Fan Names"));
            
            OSCollectionIterator *iterator = OSCollectionIterator::withCollection(tachometers);
            
            iterator->reset();
            
            while (OSString *key = OSDynamicCast(OSString, iterator->getNextObject())) {
                
                OSString *method = OSDynamicCast(OSString, tachometers->getObject(key));
                
                if (method && kIOReturnSuccess == acpiDevice->evaluateObject(method->getCStringNoCopy())) {
                    OSString* name = NULL;
                    
                    if (fanNames)
                        name = OSDynamicCast(OSString, fanNames->getObject(count));
                    
                    if (!addTachometer(count, name ? name->getCStringNoCopy() : 0))
                        HWSensorsWarningLog("Failed to register tachometer sensor %d", count);
                    
                    count++;
                }
            };
            
            //HWSensorsInfoLog("%d tachometer sensor(s) added", count);
        }
        else return false;
    }
    
	registerService();

	return true;	
}
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;
    }
    
    methods = OSArray::withCapacity(0);
    OSNumber *interval = NULL;
    OSNumber *timeout = NULL;
    OSBoolean *logging = NULL;
    OSArray *list = NULL;
    
    
    // Try to load configuration from info.plist first
    if (OSDictionary *configuration = getConfigurationNode())
    {
        OSBoolean* disable = OSDynamicCast(OSBoolean, configuration->getObject("DisableDevice"));
        if (disable && disable->isTrue())
            return false;
        
        interval = OSDynamicCast(OSNumber, configuration->getObject("PollingInterval"));
        timeout = OSDynamicCast(OSNumber, configuration->getObject("PollingTimeout"));
        logging = OSDynamicCast(OSBoolean, configuration->getObject("LoggingEnabled"));
        list = OSDynamicCast(OSArray, configuration->getObject("Methods"));
    }
    // Try to load configuration provided by ACPI device
    else {
        OSObject *object = NULL;
        
        if (kIOReturnSuccess == acpiDevice->evaluateObject("INVL", &object) && object)
            interval = OSDynamicCast(OSNumber, object);
        
        if (kIOReturnSuccess == acpiDevice->evaluateObject("TOUT", &object) && object)
            timeout = OSDynamicCast(OSNumber, object);
        
        if (kIOReturnSuccess == acpiDevice->evaluateObject("LOGG", &object) && object) {
            if (OSNumber *number = OSDynamicCast(OSNumber, object)) {
                logging = OSBoolean::withBoolean(number->unsigned8BitValue() == 1);
            }
        }
        
        if (kIOReturnSuccess == acpiDevice->evaluateObject("LIST", &object) && object)
            list = OSDynamicCast(OSArray, object);
        else
            ACPISensorsErrorLog("polling methods table (LIST) not found");
    }
    
    if (interval) {
        pollingInterval = (double)interval->unsigned64BitValue() / (double)1000.0;
        ACPISensorsInfoLog("polling interval %lld ms", interval->unsigned64BitValue());
        
        if (pollingInterval) {
            
            if (timeout) {
                pollingTimeout = (double)timeout->unsigned64BitValue() / 1000.0;
                ACPISensorsInfoLog("polling timeout %lld ms", timeout->unsigned64BitValue());
            }
            
            if (logging) {
                loggingEnabled = logging->isTrue();
                ACPISensorsInfoLog("logging %s", loggingEnabled ? "enabled" : "disabled");
            }
            
            if (list) {
                for (unsigned int i = 0; i < list->getCount(); i++) {
                    if (OSString *method = OSDynamicCast(OSString, list->getObject(i))) {
                        if (method->getLength() && kIOReturnSuccess == acpiDevice->validateObject(method->getCStringNoCopy())) {
                            methods->setObject(method);
                            ACPISensorsInfoLog("method \"%s\" registered", method->getCStringNoCopy());
                        }
                        else ACPISensorsErrorLog("unable to register method \"%s\"", method->getCStringNoCopy());
                    }
                }
            }
        }
        else ACPISensorsWarningLog("polling interval is set to zero, driver will be disabled");
    }
    
//REVIEW_REHABMAN: just bail if no methods to call... no need to stick around...
    if (!methods->getCount())
        return false;

    if (methods->getCount()) {
        // 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" : "");
    }
    
	registerService();
    
    ACPISensorsInfoLog("started");
    
	return true;
}
Exemple #23
0
/*********************************************************************
* This is the function that IOCatalogue calls in order to load a kmod.
* It first checks whether the kmod is already loaded. If the kmod
* isn't loaded, this function builds a dependency list and calls
* load_kmod() repeatedly to guarantee that each dependency is in fact
* loaded.
*********************************************************************/
__private_extern__
kern_return_t load_kernel_extension(char * kmod_name) {
    kern_return_t result = KERN_SUCCESS;
    kmod_info_t * kmod_info = 0;  // must free
    OSArray * dependencyList = NULL;     // must release
    OSArray * curDependencyList = NULL;  // must release

   /* See if the kmod is already loaded.
    */
    kmod_info = kmod_lookupbyname_locked(kmod_name);
    if (kmod_info) {  // NOT checked
        result = KERN_SUCCESS;
        goto finish;
    }

   /* It isn't loaded; build a dependency list and
    * load those.
    */
    unsigned int count;
    unsigned int i;
    dependencyList = getDependencyListForKmod(kmod_name);
    if (!dependencyList) {
        IOLog("load_kernel_extension(): "
            "Can't get dependencies for kernel extension \"%s\".\n",
            kmod_name);
        LOG_DELAY();
        result = KERN_FAILURE;
        goto finish;
    }

    count = dependencyList->getCount();
    for (i = 0; i < count; i++) {
        kern_return_t load_result;
        OSString * curKmodName;  // don't release
        const char * cur_kmod_name;

        curKmodName = OSDynamicCast(OSString,
            dependencyList->getObject(i));
        cur_kmod_name = curKmodName->getCStringNoCopy();
        curDependencyList = getDependencyListForKmod(cur_kmod_name);
        if (!curDependencyList) {
            IOLog("load_kernel_extension(): "
                "Can't get dependencies for kernel extension \"%s\".\n",
                cur_kmod_name);
            LOG_DELAY();
            result = KERN_FAILURE;
            goto finish;
        } else {
            load_result = load_kmod(curDependencyList);
            if (load_result != KERN_SUCCESS) {
                IOLog("load_kernel_extension(): "
                    "load_kmod() failed for kmod \"%s\".\n",
                    cur_kmod_name);
                LOG_DELAY();
                result = load_result;
                goto finish;
            }
            curDependencyList->release();
            curDependencyList = NULL;
        }
    }


finish:

    if (kmod_info) {
        kfree((unsigned int)kmod_info, sizeof(kmod_info_t));
    }

    if (dependencyList) {
        dependencyList->release();
        dependencyList = NULL;
    }
    if (curDependencyList) {
        curDependencyList->release();
        curDependencyList = NULL;
    }

    return result;
}
Exemple #24
0
/*********************************************************************
* 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;
}
Exemple #25
0
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;
}
Exemple #26
0
bool ACPIMonitor::start(IOService * provider)
{
    if (!super::start(provider))
        return false;

    acpiDevice = (IOACPIPlatformDevice *)provider;

    char key[5];

    //Here is Fan in ACPI
    OSArray* fanNames = OSDynamicCast(OSArray, getProperty("FanNames"));

    for (int i=0; i<10; i++)
    {
        snprintf(key, 5, "FAN%X", i);

        if (kIOReturnSuccess == acpiDevice->validateObject(key)) {
            OSString* name = NULL;

            if (fanNames )
                name = OSDynamicCast(OSString, fanNames->getObject(i));

            if (!addTachometer(key, name ? name->getCStringNoCopy() : 0))
                WarningLog("Can't add tachometer sensor, key %s", key);
        }
        else {
            snprintf(key, 5, "FTN%X", i);
            if (kIOReturnSuccess == acpiDevice->validateObject(key)) {
                OSString* name = NULL;

                if (fanNames )
                    name = OSDynamicCast(OSString, fanNames->getObject(i));

                if (!addTachometer(key, name ? name->getCStringNoCopy() : 0))
                    WarningLog("Can't add tachometer sensor, key %s", key);
            }
            else
                break;
        }
    }

    //Next step - temperature keys
    if (kIOReturnSuccess == acpiDevice->validateObject("TCPU"))
        addSensor("TCPU", KEY_CPU_HEATSINK_TEMPERATURE, TYPE_SP78, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("TSYS"))
        addSensor("TSYS", KEY_NORTHBRIDGE_TEMPERATURE, TYPE_SP78, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("TDIM"))
        addSensor("TDIM", KEY_DIMM_TEMPERATURE, TYPE_SP78, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("TAMB"))
        addSensor("TAMB", KEY_AMBIENT_TEMPERATURE, TYPE_SP78, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("TCPP"))
        addSensor("TCPP", KEY_CPU_PROXIMITY_TEMPERATURE, TYPE_SP78, 2);
    // We should add also GPU reading stuff for those who has no supported plug in but have the value on EC registers



    //Voltage
    if (kIOReturnSuccess == acpiDevice->validateObject("VCPU"))
        addSensor("VSN0", KEY_CPU_VOLTAGE, TYPE_FP2E, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("VMEM"))
        addSensor("VSN0", KEY_MEMORY_VOLTAGE, TYPE_FP2E, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("VSN1"))
        addSensor("VSN1", "Vp0C", TYPE_FP2E, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("VSN2"))
        addSensor("VSN2", "Vp1C", TYPE_FP2E, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("VSN3"))
        addSensor("VSN3", "Vp2C", TYPE_FP2E, 2);

    //Amperage
    if (kIOReturnSuccess == acpiDevice->validateObject("ISN0"))
        addSensor("ISN0", "ICAC", TYPE_UI16, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("ISN1"))
        addSensor("ISN1", "Ip0C", TYPE_UI16, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("ISN2"))
        addSensor("ISN2", "Ip1C", TYPE_UI16, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("ISN3"))
        addSensor("ISN3", "Ip2C", TYPE_UI16, 2);

    //Power
    if (kIOReturnSuccess == acpiDevice->validateObject("PSN0"))
        addSensor("PSN0", "PC0C", TYPE_UI16, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("PSN1"))
        addSensor("PSN1", "PC1C", TYPE_UI16, 2);

    // AC Power/Battery
    if (kIOReturnSuccess == acpiDevice->validateObject("ACDC")) // Power Source Read AC/Battery
    {
        addSensor("ACDC", "ACEN", TYPE_UI8, 1);
        addSensor("ACDC", "ACFP", TYPE_FLAG, 1);
        addSensor("ACDC", "ACIN", TYPE_FLAG, 1);
    }
    // TODO real SMC returns ACID only when AC is plugged, if not is zeroed, so hardcoding it in plist is not OK IMHO
    // Same goes for ACIC, but no idea how we can get the AC current value..

    // Here if ACDC returns 0 we need to set the on battery BATP flag

    // Battery stuff, need to implement rest of the keys once i figure those
    if (kIOReturnSuccess == acpiDevice->validateObject("BAK0")) // Battery 0 Current
        addSensor("BAK0", "B0AC", TYPE_SI16, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("BAK1")) // Battery 0 Voltage
        addSensor("BAK1", "B0AV", TYPE_UI16, 2);

    //Keys from info.plist
    OSString *tmpString = 0;
    OSData   *tmpObj = 0;

//	UInt32 tmpUI32;
//	char tmpCString[7];
    char acpiName[5];
    char aKey[5];

    OSIterator *iter = 0;
    const OSSymbol *dictKey = 0;
    OSDictionary *keysToAdd = 0;

    keysToAdd = OSDynamicCast(OSDictionary, getProperty("keysToAdd"));
    if (keysToAdd) {
        iter = OSCollectionIterator::withCollection(keysToAdd);
        if (iter) {
            while ((dictKey = (const OSSymbol *)iter->getNextObject())) {
                tmpObj = 0;
                snprintf(acpiName, 5, "%s", dictKey->getCStringNoCopy());
                //WarningLog(" Found key %s", acpiName);
                tmpString = OSDynamicCast(OSString, keysToAdd->getObject(dictKey));
                if (tmpString) {
                    snprintf(aKey, 5, "%s", tmpString->getCStringNoCopy());
                    InfoLog("Custom name=%s key=%s", acpiName, aKey);
                    if (kIOReturnSuccess == acpiDevice->validateObject(acpiName)) {
                        if (aKey[0] == 'F') {
                            if (!addTachometer(aKey, acpiName))
                                WarningLog("Can't add tachometer sensor, key %s", aKey);

                        } else {
                            addSensor(acpiName, aKey, TYPE_UI16, 2);
                        }
                    }
                }
                else {
                    WarningLog(" no value for key %s", acpiName);
                }

            }

            iter->release();
        } else {
            WarningLog(" can't interate keysToAdd");
        }

    } else {
        WarningLog(" keysToAdd not found");
    }

    registerService(0);

    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);
}
//==============================================================================
// USB Stuff (Mainly...)
//==============================================================================
bool com_milvich_driver_Thrustmaster::init(OSDictionary *properties)
{
    IOLog("%s: init\n", NAME);
    
    if(!super::init(properties))
    {
        return false;
    }
    
    fIface = NULL;
    fPipe = NULL;
    fBuffer = NULL;
    fOutstandingIOOps = 0;
    fNeedToClose = false;
    fFinishedInit = false;
    
    for(unsigned int i = 0; i < sizeof(fControlData); i++)
    {
        fControlData[i] = 0;
    }
    
    OSBoolean		*result;
    int                 count;
    
    // create the buffer for the reports
    fReport = IOBufferMemoryDescriptor::withCapacity(kReportSize, kIODirectionOutIn, true);
    if(!fReport)
    {
        IOLog("%s: Failed to create the MemoryDescriptor for our report\n", NAME);
        return false;
    }
    
    // I need to know this info to create the device descriptor, but I can't
    // dynamicly look this up until I finish initing the iMate, but that blocks...
    // So we be stupid and just read from a config file.
    fHasRudders = false;
    fHasThrottle = true;
    result = OSDynamicCast(OSBoolean, getProperty("HasRudder"));
    if(result)
    {
        fHasRudders = result->getValue();
    }
    result = OSDynamicCast(OSBoolean, getProperty("HasThrottle"));
    if(result)
    {
        fHasThrottle = result->getValue();
    }
    
    // check to see if the rocker switch should act as a modifier
    if(fHasThrottle)
    {
        result = OSDynamicCast(OSBoolean, getProperty("RockerIsModifier"));
        if(!result)
        {
            IOLog("%s: Failed to find an entry for RockerIsModifier, assuming false.\n", NAME);
            fRockerIsModifier = false;
        }
        else
        {
            fRockerIsModifier = result->getValue();
        }
    }
    else
    {
        fRockerIsModifier = false;
    }
    
    // setup buttons
    if(fHasThrottle)
    {
        count = kNumOfButtons;
    }
    else
    {
        count = kNumOfFCSButtons;
    }
    OSArray *buttonArray = OSDynamicCast(OSArray, getProperty("Buttons"));
    if(fRockerIsModifier && buttonArray)
    {
        for(int i = 0; i < count; i++)
        {
            result = OSDynamicCast(OSBoolean, buttonArray->getObject(i));
            if(result && result->getValue())
            {
                for(int j = 0; j < kNumModifiers; j++)
                {
                    fButtonShifts[i * kNumModifiers + j] = fNumButtons;
                    fNumButtons++;
                }
            }
            else
            {
                for(int j = 0; j < kNumModifiers; j++)
                {
                    fButtonShifts[i * kNumModifiers + j] = fNumButtons;
                }
                fNumButtons++;
            }
        }
    }
    else
    {
        // the buttons and hatswitchs are not shifted, so set all 3 shift values
        // to the same thing
        fNumButtons = 0;
        for(int i = 0; i < count; i++)
        {
            for(int j = 0; j < kNumModifiers; j++)
            {
                fButtonShifts[i * kNumModifiers + j] = fNumButtons;
            }
            fNumButtons++;
        }
        // same thing with the hat switch
    }
    
    result = OSDynamicCast(OSBoolean, getProperty("ModifierEffectsHat"));
    fHatIsModified = result && result->getValue();
    if(fHatIsModified && fRockerIsModifier)
    {
        fHatSwitchShifts[0] = 0;
        fHatSwitchShifts[1] = 1;
        fHatSwitchShifts[2] = 2;
    }
    else
    {
        fHatSwitchShifts[0] = fHatSwitchShifts[1] = fHatSwitchShifts[2] = 0;
        fHatIsModified = false;
    }
    
    result = OSDynamicCast(OSBoolean, getProperty("TwistRudder"));
    fTwistRudder = result && result->getValue();
    
    return true;
}
Exemple #29
0
bool PTIDSensors::start(IOService * provider)
{
	if (!super::start(provider))
        return false;
    
	acpiDevice = (IOACPIPlatformDevice *)provider;
	
	if (!acpiDevice) {
        HWSensorsFatalLog("ACPI device not ready");
        return false;
    }
    
    // Update timers
    temperaturesLastUpdated = ptimer_read() - NSEC_PER_SEC;
    tachometersLastUpdated = temperaturesLastUpdated;
    
    acpiDevice->evaluateInteger("IVER", &version);
    
    if (version == 0) {
        OSString *name = OSDynamicCast(OSString, provider->getProperty("name"));
        
        if (name && name->isEqualTo("INT3F0D"))
            version = 0x30000;
        else
            return false;
    }
    
    setProperty("version", version, 64);
    
    // Parse sensors
    switch (version) {
        case 0x30000: {
            OSObject *object = NULL;
            
            // Temperatures
            if(kIOReturnSuccess == acpiDevice->evaluateObject("TSDL", &object) && object) {
                
                OSArray *description = OSDynamicCast(OSArray, object);
                
                HWSensorsDebugLog("Parsing temperatures...");
                
                for (UInt32 index = 1; index < description->getCount(); index += 2) {
                    parseTemperatureName(OSDynamicCast(OSString, description->getObject(index)), (index - 1) / 2);
                }
            }
            else HWSensorsErrorLog("failed to evaluate TSDL table");
            
            // Tachometers
            if(kIOReturnSuccess == acpiDevice->evaluateObject("OSDL", &object) && object) {
                
                OSArray *description = OSDynamicCast(OSArray, object);
                
                HWSensorsDebugLog("Parsing tachometers...");
                
                for (UInt32 index = 2; index < description->getCount(); index += 3) {
                    parseTachometerName(OSDynamicCast(OSString, description->getObject(index)), OSDynamicCast(OSString, description->getObject(index - 1)), (index - 2) / 3);
                }
            }
            else HWSensorsErrorLog("failed to evaluate OSDL table");
            
            break;
        }
            
        case 0x20001: {
            OSObject *object = NULL;
            
            // Temperatures
            if(kIOReturnSuccess == acpiDevice->evaluateObject("TMPV", &object) && object) {
                
                OSArray *description = OSDynamicCast(OSArray, object);
                
                for (UInt32 index = 1; index < description->getCount(); index += 3) {
                    parseTemperatureName(OSDynamicCast(OSString, description->getObject(index)), index + 1);
                }
            }
            else HWSensorsErrorLog("failed to evaluate TMPV table");
            
            // Tachometers
            if(kIOReturnSuccess == acpiDevice->evaluateObject("OSDV", &object) && object) {
                
                OSArray *description = OSDynamicCast(OSArray, object);
                
                for (UInt32 index = 2; index < description->getCount(); index += 4) {
                    parseTachometerName(OSDynamicCast(OSString, description->getObject(index)), OSDynamicCast(OSString, description->getObject(index - 1)), index + 1);
                }
            }
            else HWSensorsErrorLog("failed to evaluate OSDV table");
            
            break;
        }
            
        default:
            HWSensorsFatalLog("usupported interface version: 0x%x", (unsigned int)version);
            return false;
    }
    
    registerService();
    
    HWSensorsInfoLog("started");
    
	return true;
}
bool createPStateTable(PState* pS, unsigned int* numStates) {	
	checkForPenryn(); // early on, so we can display proper mV values
	
	/* If the PState table was specified manually, we dont do the rest. Otherwise autodetect */
	if (NumberOfPStates != 0) {
		dbg("PState table was already created. No autodetection will be performed\n");
		return true;
	}
	
	/* Find CPUs in the IODeviceTree plane */
	IORegistryEntry* ioreg = IORegistryEntry::fromPath("/cpus", IORegistryEntry::getPlane("IODeviceTree"));
	if (ioreg == 0) {
		warn("Holy moly we cannot find your CPU!\n");
		return false;
	}
	
	/* Get the first CPU - we assume all CPUs share the same P-State */
	IOACPIPlatformDevice* cpu = (IOACPIPlatformDevice*) ioreg->getChildEntry(IORegistryEntry::getPlane("IODeviceTree"));
	if (cpu == 0) {
		warn("Um you don't seem to have a CPU o.O\n");
		ioreg = 0;
		return false;
	}
	
	dbg("Using data from %s\n", cpu->getName());
	
	/* Now try to find the performance state table */
	OSObject* PSS;
  cpu->evaluateObject("_PSS", &PSS);
	if(PSS == 0 ) {
		warn("Auto-creating a PState table.\n");
		int maxFID = MHz_to_FID(getCurrentFrequency());
		int maxVID = mV_to_VID(getCurrentVoltage());
		int minVID = mV_to_VID(800); // For now we'll use hardcoded minvolt, later use table
		int minFID = 6; // No LFM right now
		NumberOfPStates = 1 + ((maxFID - minFID) / 2);
		for (int i = 1; i < NumberOfPStates; i++) {
			PStates[i].Frequency		= minFID + (2*(NumberOfPStates - i - 1));
			PStates[i].AcpiFreq		= FID_to_MHz(PStates[i].Frequency);
			PStates[i].OriginalVoltage	= maxVID - (i*((maxVID - minVID) / NumberOfPStates)) ;
			PStates[i].Voltage		= PStates[i].OriginalVoltage;
			PStates[i].Latency		= 110;
			PStates[i].TimesChosen		= 0;
		}
		
		PStates[0].Frequency		= maxFID;
		PStates[0].AcpiFreq		= FID_to_MHz(maxFID);
		PStates[0].OriginalVoltage	= maxVID;
		PStates[0].Voltage		= PStates[0].OriginalVoltage;
		PStates[0].Latency		= 110;
		PStates[0].TimesChosen		= 0;
		MaxLatency			= PStates[0].Latency;
		info("Using %d PStates (auto-created, may not be optimal).\n", NumberOfPStates);
		ioreg = 0; cpu = 0;
		return true;
	}
	
	OSArray* PSSArray = (OSArray*) PSS;
	NumberOfPStates = PSSArray->getCount();
	info("Found %d P-States\n", NumberOfPStates);
	OSArray* onestate; uint16_t ctl, acpifreq; uint32_t power, latency;
	int i = 0, c = 0;
	
	while (c < PSSArray->getCount()) {
		onestate = ( OSArray* )(PSSArray->getObject(c));
		ctl      = ((OSNumber*) onestate->getObject(4))->unsigned32BitValue();
		acpifreq = ((OSNumber*) onestate->getObject(0))->unsigned32BitValue();
		power	 = ((OSNumber*) onestate->getObject(1))->unsigned32BitValue();
		latency	 = ((OSNumber*) onestate->getObject(2))->unsigned32BitValue();
		c++;
		
    
    info("clt: 0x%x , vid: %d , fid: %d \n",  ctl , VID(ctl), FID(ctl) );
    
		if (acpifreq - (10 * (acpifreq / 10)) == 1) {
			// most likely spurious, so skip it
			warn("** Spurious P-State %d: %d MHz at %d mV, consuming %d W, latency %d usec\n", i, acpifreq, VID_to_mV(ctl), power / 1000, latency);
			NumberOfPStates--;
			continue;
		}
	
		if (acpifreq < 1000 && !Below1Ghz) {
			warn("%d MHz disabled because your processor or kernel doesn't support it.\n",acpifreq);
			NumberOfPStates--;
			continue;
		}
		
		PStates[i].AcpiFreq		= acpifreq; // cosmetic only
		PStates[i].Frequency		= FID(ctl);
		PStates[i].OriginalVoltage	= VID(ctl);
		PStates[i].Voltage		= PStates[i].OriginalVoltage *50 / 100; // initially same
		PStates[i].Latency		= latency;
		PStates[i].TimesChosen		= 0;
		
		if (latency > MaxLatency) MaxLatency = latency;
		
		info("Auto: P-State %d: %d MHz at %d mV VID: %d, consuming %d W, latency %d usec\n",
		    i, PStates[i].AcpiFreq, VID_to_mV(PStates[i].Voltage),PStates[i].Voltage,
		    power / 1000, latency);
		i++;
	}
	
	info("Using %d PStates.\n", NumberOfPStates);
	
	ioreg = 0; cpu = 0; PSS = 0; onestate = 0;
	return true;
}