void IOPMPagingPlexus::processChildren ( void )
{
    OSIterator *	childIterator;
    IOPowerConnection *	nextChildNub;
    IORegistryEntry *	nextChild;
    IOService *		child;
    unsigned int	i;
    
    childIterator = getChildIterator(gIOPowerPlane);

    if ( childIterator ) {
        while ( (nextChild = (IORegistryEntry *)(childIterator->getNextObject())) ) {
            if ( (nextChildNub = OSDynamicCast(IOPowerConnection,nextChild)) ) {
                child = (IOService *)nextChild->getChildEntry(gIOPowerPlane);
                if ( child->pm_vars->theControllingDriver ) {
                    for ( i = 1; i < child->pm_vars->theNumberOfPowerStates; i++ ) {
                        child->pm_vars->thePowerStates[i].inputPowerRequirement |= IOPMPagingAvailable;
                    }
                }
                if ( child->pm_vars->myCurrentState ) {
                    nextChildNub->setDesiredDomainState(kIOPlexusPowerStateCount-1);
                }
            }
        }
        childIterator->release();
    }
}
Beispiel #2
0
bool net_lundman_zfs_zvol::start (IOService *provider)
{
    bool res = super::start(provider);


    IOLog("ZFS: Loading module ... \n");

	/*
	 * Initialize /dev/zfs, this calls spa_init->dmu_init->arc_init-> etc
	 */
	zfs_ioctl_osx_init();

	///sysctl_register_oid(&sysctl__debug_maczfs);
	//sysctl_register_oid(&sysctl__debug_maczfs_stalk);

    zfs_vfsops_init();

    /*
     * When is the best time to start the system_taskq? It is strictly
     * speaking not used by SPL, but by ZFS. ZFS should really start it?
     */
    system_taskq_init();


    /*
     * hostid is left as 0 on OSX, and left to be set if developers wish to
     * use it. If it is 0, we will hash the hardware.uuid into a 32 bit
     * value and set the hostid.
     */
    if (!zone_get_hostid(NULL)) {
      uint32_t myhostid = 0;
      IORegistryEntry *ioregroot =  IORegistryEntry::getRegistryRoot();
      if(ioregroot) {
        //IOLog("ioregroot is '%s'\n", ioregroot->getName(gIOServicePlane));
        IORegistryEntry *macmodel = ioregroot->getChildEntry(gIOServicePlane);
        if(macmodel) {
          //IOLog("macmodel is '%s'\n", macmodel->getName(gIOServicePlane));
          OSObject *ioplatformuuidobj;
          //ioplatformuuidobj = ioregroot->getProperty("IOPlatformUUID", gIOServicePlane, kIORegistryIterateRecursively);
          ioplatformuuidobj = macmodel->getProperty(kIOPlatformUUIDKey);
          if(ioplatformuuidobj) {
            OSString *ioplatformuuidstr = OSDynamicCast(OSString, ioplatformuuidobj);
            //IOLog("IOPlatformUUID is '%s'\n", ioplatformuuidstr->getCStringNoCopy());

            myhostid = fnv_32a_str(ioplatformuuidstr->getCStringNoCopy(),
                                   FNV1_32A_INIT);

            sysctlbyname("kern.hostid", NULL, NULL, &myhostid, sizeof(myhostid));
            printf("ZFS: hostid set to %08x from UUID '%s'\n",
                   myhostid, ioplatformuuidstr->getCStringNoCopy());
          }
        }
      }
    }

    return res;
}
void IOPMPagingPlexus::processSiblings ( IOService * aNode )
{
    OSIterator *	parentIterator;
    IORegistryEntry *	nextNub;
    IORegistryEntry *	nextParent;
    OSIterator *	siblingIterator;
    IORegistryEntry *	nextSibling;

    parentIterator = aNode->getParentIterator(gIOPowerPlane);		// iterate parents of this node

    if ( parentIterator ) {
        while ( true ) {
            if ( ! (nextNub = (IORegistryEntry *)(parentIterator->getNextObject())) ) {
                parentIterator->release();
                break;
            }
            if ( OSDynamicCast(IOPowerConnection,nextNub) ) {
                nextParent = nextNub->getParentEntry(gIOPowerPlane);
                if ( nextParent == getPMRootDomain() ) {
                    continue;				// plexus already has root's children
                }
                if ( nextParent == this ) {
                    parentIterator->release();
                    removePowerChild((IOPowerConnection *)nextNub);
                    break;
                }
                siblingIterator = nextParent->getChildIterator(gIOPowerPlane);
                                                                                // iterate children of this parent
                if ( siblingIterator ) {
                    while ( (nextSibling = (IORegistryEntry *)(siblingIterator->getNextObject())) ) {
                        if ( OSDynamicCast(IOPowerConnection,nextSibling) ) {
                            nextSibling = nextSibling->getChildEntry(gIOPowerPlane);
                            if ( nextSibling != aNode ) {			// non-ancestor of driver gets
                                addPowerChild((IOService *)nextSibling);	// plexus as parent
                            }
                        }
                    }
                    siblingIterator->release();
                }
                processSiblings((IOService *)nextParent);			// do the same thing to this parent
            }
   	}
    }
}
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;
}