Beispiel #1
0
/**
 * <pre>
 * Description:
 *   Dump cell inventoy data.
 * Arguments:
 *   *tscb - Test script control block
 * </pre>
 *****************************************************************************/
Byte getEnvironmentStatus(TEST_SCRIPT_CONTROL_BLOCK *tscb)
{
  TEST_SCRIPT_ERROR_BLOCK *tseb = &tscb->testScriptErrorBlock;
  Byte rc = 0;

  ts_printf(__FILE__, __LINE__, "getEnvironmentStatus");

  rc = getCurrentTemperature(MY_CELL_NO + 1, &tscb->wCurrentTempInHundredth);
  if (rc) {
    ts_printf(__FILE__, __LINE__, "error %d", rc);
    tseb->isFatalError = 1;
  }

  rc = getCurrentVoltage(MY_CELL_NO + 1, &tscb->wCurrentV5InMilliVolts, &tscb->wCurrentV12InMilliVolts);
  if (rc) {
    ts_printf(__FILE__, __LINE__, "error %d", rc);
    tseb->isFatalError = 1;
  }

  ts_printf(__FILE__, __LINE__, "cell temp = %d, x_volt = %d, y_volt = %d", tscb->wCurrentTempInHundredth, tscb->wCurrentV5InMilliVolts, tscb->wCurrentV12InMilliVolts);

  return 0;
}
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;
}