PB5_1_PlatformMonitor.cpp [plain text]
#include "PB5_1_PlatformMonitor.h"
static const OSSymbol *gIOPMonPowerStateKey;
static const OSSymbol *gIOPMonThermalStateKey;
static const OSSymbol *gIOPMonClamshellStateKey;
static const OSSymbol *gIOPMonCPUActionKey;
static const OSSymbol *gIOPMonGPUActionKey;
static const OSSymbol *gIOPMonState0;
static const OSSymbol *gIOPMonState1;
static const OSSymbol *gIOPMonState2;
static const OSSymbol *gIOPMonState3;
static const OSSymbol *gIOPMonFull;
static const OSSymbol *gIOPMonReduced;
static const OSSymbol *gIOPMonSlow;
static IOService *provider;
static bool actionFullPower ();
static bool actionPower1 ();
static bool actionPower1GPU1 ();
static bool actionPower1GPU2 ();
static IOPlatformMonitorAction platformActionGrid[kMaxPowerStates][kMaxThermalStates][kNumClamshellStates] =
{
{
{
actionFullPower, actionPower1 },
{
actionPower1, actionPower1 },
{
actionPower1GPU1, actionPower1GPU1 },
{
actionPower1GPU2, actionPower1GPU2 },
},
{
{
actionPower1, actionPower1 },
{
actionPower1, actionPower1 },
{
actionPower1GPU1, actionPower1GPU1 },
{
actionPower1GPU2, actionPower1GPU2 },
}
};
static ConSensorInfo conSensorArray[kMaxConSensors];
static ConSensorInfo subSensorArray[kMaxSensorIndex];
static OldThresholdInfo thermalThresholdInfoArray[kMaxSensorIndex][kNumClamshellStates][kMaxThermalStates] =
{
{ { { TEMP_SENSOR_FMT(0), kThermalState0, TEMP_SENSOR_FMT(100), kThermalState1 }, { TEMP_SENSOR_FMT(95), kThermalState0, TEMP_SENSOR_FMT(100), kThermalState2 }, { TEMP_SENSOR_FMT(78), kThermalState1, TEMP_SENSOR_FMT(93), kThermalState3 }, { TEMP_SENSOR_FMT(88), kThermalState2, TEMP_SENSOR_FMT(117), kThermalState3 }, },
{ { TEMP_SENSOR_FMT(0), kThermalState0, TEMP_SENSOR_FMT(100), kThermalState1 }, { TEMP_SENSOR_FMT(95), kThermalState0, TEMP_SENSOR_FMT(100), kThermalState2 }, { TEMP_SENSOR_FMT(78), kThermalState1, TEMP_SENSOR_FMT(93), kThermalState3 }, { TEMP_SENSOR_FMT(88), kThermalState2, TEMP_SENSOR_FMT(117), kThermalState3 }, },
},
{ { { TEMP_SENSOR_FMT(0), kThermalState0, TEMP_SENSOR_FMT(100), kThermalState1 }, { TEMP_SENSOR_FMT(95), kThermalState0, TEMP_SENSOR_FMT(100), kThermalState2 }, { TEMP_SENSOR_FMT(78), kThermalState1, TEMP_SENSOR_FMT(93), kThermalState3 }, { TEMP_SENSOR_FMT(88), kThermalState2, TEMP_SENSOR_FMT(117), kThermalState3 }, },
{ { TEMP_SENSOR_FMT(0), kThermalState0, TEMP_SENSOR_FMT(100), kThermalState1 }, { TEMP_SENSOR_FMT(95), kThermalState0, TEMP_SENSOR_FMT(100), kThermalState2 }, { TEMP_SENSOR_FMT(78), kThermalState1, TEMP_SENSOR_FMT(93), kThermalState3 }, { TEMP_SENSOR_FMT(88), kThermalState2, TEMP_SENSOR_FMT(117), kThermalState3 }, },
},
{ { { TEMP_SENSOR_FMT(0), kThermalState0, TEMP_SENSOR_FMT(73), kThermalState1 }, { TEMP_SENSOR_FMT(68), kThermalState0, TEMP_SENSOR_FMT(100), kThermalState2 }, { TEMP_SENSOR_FMT(78), kThermalState1, TEMP_SENSOR_FMT(93), kThermalState3 }, { TEMP_SENSOR_FMT(88), kThermalState2, TEMP_SENSOR_FMT(117), kThermalState3 }, },
{ { TEMP_SENSOR_FMT(0), kThermalState0, TEMP_SENSOR_FMT(73), kThermalState1 }, { TEMP_SENSOR_FMT(68), kThermalState0, TEMP_SENSOR_FMT(100), kThermalState2 }, { TEMP_SENSOR_FMT(78), kThermalState1, TEMP_SENSOR_FMT(93), kThermalState3 }, { TEMP_SENSOR_FMT(88), kThermalState2, TEMP_SENSOR_FMT(117), kThermalState3 }, },
},
{ { { TEMP_SENSOR_FMT(0), kThermalState0, TEMP_SENSOR_FMT(100), kThermalState1 }, { TEMP_SENSOR_FMT(95), kThermalState0, TEMP_SENSOR_FMT(100), kThermalState2 }, { TEMP_SENSOR_FMT(78), kThermalState1, TEMP_SENSOR_FMT(93), kThermalState3 }, { TEMP_SENSOR_FMT(88), kThermalState2, TEMP_SENSOR_FMT(117), kThermalState3 }, },
{ { TEMP_SENSOR_FMT(0), kThermalState0, TEMP_SENSOR_FMT(100), kThermalState1 }, { TEMP_SENSOR_FMT(95), kThermalState0, TEMP_SENSOR_FMT(100), kThermalState2 }, { TEMP_SENSOR_FMT(78), kThermalState1, TEMP_SENSOR_FMT(93), kThermalState3 }, { TEMP_SENSOR_FMT(88), kThermalState2, TEMP_SENSOR_FMT(117), kThermalState3 }, },
},
{ { { TEMP_SENSOR_FMT(0), kThermalState0, TEMP_SENSOR_FMT(100), kThermalState1 }, { TEMP_SENSOR_FMT(95), kThermalState0, TEMP_SENSOR_FMT(100), kThermalState2 }, { TEMP_SENSOR_FMT(78), kThermalState1, TEMP_SENSOR_FMT(93), kThermalState3 }, { TEMP_SENSOR_FMT(88), kThermalState2, TEMP_SENSOR_FMT(117), kThermalState3 }, },
{ { TEMP_SENSOR_FMT(0), kThermalState0, TEMP_SENSOR_FMT(100), kThermalState1 }, { TEMP_SENSOR_FMT(95), kThermalState0, TEMP_SENSOR_FMT(100), kThermalState2 }, { TEMP_SENSOR_FMT(78), kThermalState1, TEMP_SENSOR_FMT(93), kThermalState3 }, { TEMP_SENSOR_FMT(88), kThermalState2, TEMP_SENSOR_FMT(117), kThermalState3 }, },
},
};
#ifndef sub_iokit_graphics
# define sub_iokit_graphics err_sub(5)
#endif
#ifndef kIOFBLowPowerAggressiveness
# define kIOFBLowPowerAggressiveness iokit_family_err(sub_iokit_graphics,1)
#endif
#define super IOPlatformMonitor
OSDefineMetaClassAndStructors(PB5_1_PlatformMonitor, IOPlatformMonitor)
static bool actionFullPower ()
{
IOService *serv;
if ((conSensorArray[kCPUController].state != kCPUPowerState0) &&
(serv = conSensorArray[kCPUController].conSensor)) {
conSensorArray[kCPUController].state = kCPUPowerState0;
IOLog ("IOPMon::actionFullPower - sending CPU aggressiveness 2\n");
serv->setAggressiveness (kPMSetProcessorSpeed, 2);
provider->setProperty (gIOPMonCPUActionKey, (OSObject *)gIOPMonFull);
}
if ((conSensorArray[kGPUController].state != kGPUPowerState0) &&
(serv = conSensorArray[kGPUController].conSensor)) {
conSensorArray[kGPUController].state = kGPUPowerState0;
IOLog ("IOPMon::actionFullPower - sending GPU aggressiveness 0\n");
serv->setAggressiveness (kIOFBLowPowerAggressiveness, 0);
provider->setProperty (gIOPMonGPUActionKey, (OSObject *)gIOPMonFull);
}
return true;
}
static bool actionPower1 ()
{
IOService *serv;
if ((conSensorArray[kCPUController].state != kCPUPowerState1) &&
(serv = conSensorArray[kCPUController].conSensor)) {
conSensorArray[kCPUController].state = kCPUPowerState1;
IOLog ("IOPMon::actionPower1 - sending CPU aggressiveness 3\n");
serv->setAggressiveness (kPMSetProcessorSpeed, 3);
provider->setProperty (gIOPMonCPUActionKey, (OSObject *)gIOPMonReduced);
}
if ((conSensorArray[kGPUController].state != kGPUPowerState0) &&
(serv = conSensorArray[kGPUController].conSensor)) {
conSensorArray[kGPUController].state = kGPUPowerState0;
IOLog ("IOPMon::actionPower1 - sending GPU aggressiveness 0\n");
serv->setAggressiveness (kIOFBLowPowerAggressiveness, 0);
provider->setProperty (gIOPMonGPUActionKey, (OSObject *)gIOPMonFull);
}
return true;
}
static bool actionPower1GPU1 ()
{
IOService *serv;
if ((conSensorArray[kCPUController].state != kCPUPowerState1) &&
(serv = conSensorArray[kCPUController].conSensor)) {
conSensorArray[kCPUController].state = kCPUPowerState1;
IOLog ("IOPMon::actionPower1GPU1 - CPU sending aggressiveness 3\n");
serv->setAggressiveness (kPMSetProcessorSpeed, 3);
provider->setProperty (gIOPMonCPUActionKey, (OSObject *)gIOPMonReduced);
}
if ((conSensorArray[kGPUController].state != kGPUPowerState1) &&
(serv = conSensorArray[kGPUController].conSensor)) {
conSensorArray[kGPUController].state = kGPUPowerState1;
IOLog ("IOPMon::actionPower1GPU1 - sending GPU aggressiveness 1\n");
serv->setAggressiveness (kIOFBLowPowerAggressiveness, 1);
provider->setProperty (gIOPMonGPUActionKey, (OSObject *)gIOPMonReduced);
}
return true;
}
static bool actionPower1GPU2 ()
{
IOService *serv;
if ((conSensorArray[kCPUController].state != kCPUPowerState1) &&
(serv = conSensorArray[kCPUController].conSensor)) {
conSensorArray[kCPUController].state = kCPUPowerState1;
IOLog ("IOPMon::actionPower1GPU2 - CPU sending aggressiveness 3\n");
serv->setAggressiveness (kPMSetProcessorSpeed, 3);
provider->setProperty (gIOPMonCPUActionKey, (OSObject *)gIOPMonReduced);
}
if ((conSensorArray[kGPUController].state != kGPUPowerState2) &&
(serv = conSensorArray[kGPUController].conSensor)) {
conSensorArray[kGPUController].state = kGPUPowerState2;
IOLog ("IOPMon::actionPower1GPU2 - sending GPU aggressiveness 2\n");
serv->setAggressiveness (kIOFBLowPowerAggressiveness, 2);
provider->setProperty (gIOPMonGPUActionKey, (OSObject *)gIOPMonSlow);
}
return true;
}
bool PB5_1_PlatformMonitor::start ( IOService * nub )
{
UInt32 i;
if (!initSymbols())
return false;
if (!initPlatformState ())
return false;
provider = nub;
commandGateCaller = &iopmonCommandGateCaller;
conSensorArray[kPowerSensor].conSensorType = kIOPMonPowerSensor; conSensorArray[kPowerSensor].conSensor = this; conSensorArray[kPowerSensor].numStates = kMaxPowerStates;
conSensorArray[kPowerSensor].sensorValid = true;
conSensorArray[kPowerSensor].registered = true;
conSensorArray[kThermalSensor].conSensorType = kIOPMonThermalSensor; conSensorArray[kThermalSensor].conSensor = this;
conSensorArray[kThermalSensor].numStates = kMaxThermalStates;
conSensorArray[kThermalSensor].sensorValid = true;
conSensorArray[kThermalSensor].registered = true;
conSensorArray[kClamshellSensor].conSensorType = kIOPMonClamshellSensor; conSensorArray[kClamshellSensor].numStates = kNumClamshellStates;
conSensorArray[kClamshellSensor].sensorValid = true;
conSensorArray[kClamshellSensor].registered = false;
conSensorArray[kCPUController].conSensorType = kIOPMonCPUController; conSensorArray[kCPUController].registered = false;
conSensorArray[kGPUController].conSensorType = kIOPMonGPUController; conSensorArray[kGPUController].state = kGPUPowerState0;
conSensorArray[kGPUController].registered = true;
for (i = 0; i < kMaxSensorIndex; i++) {
subSensorArray[i].conSensorType = kIOPMonThermalSensor;
subSensorArray[i].conSensorParent = kThermalSensor; subSensorArray[i].numStates = kMaxThermalStates;
subSensorArray[i].sensorValid = true;
subSensorArray[i].registered = false;
}
if (!(dictPowerLow = OSDictionary::withCapacity (3)))
return false;
if (!(dictPowerHigh = OSDictionary::withCapacity (3)))
return false;
if (!(dictClamshellOpen = OSDictionary::withCapacity (2)))
return false;
if (!(dictClamshellClosed = OSDictionary::withCapacity (2)))
return false;
dictPowerLow->setObject (gIOPMonCPUIDKey, OSNumber::withNumber ((unsigned long long)0, 32));
dictPowerLow->setObject (gIOPMonCurrentValueKey, OSNumber::withNumber ((unsigned long long)kPowerState1, 32));
dictPowerLow->setObject (gIOPMonTypeKey, gIOPMonTypePowerSens);
dictPowerHigh->setObject (gIOPMonCPUIDKey, OSNumber::withNumber ((unsigned long long)0, 32));
dictPowerHigh->setObject (gIOPMonCurrentValueKey, OSNumber::withNumber ((unsigned long long)kPowerState0, 32));
dictPowerHigh->setObject (gIOPMonTypeKey, gIOPMonTypePowerSens);
dictClamshellOpen->setObject (gIOPMonCurrentValueKey, OSNumber::withNumber ((unsigned long long)kClamshellStateOpen, 32));
dictClamshellOpen->setObject (gIOPMonTypeKey, gIOPMonTypeClamshellSens);
dictClamshellClosed->setObject (gIOPMonCurrentValueKey, OSNumber::withNumber ((unsigned long long)kClamshellStateClosed, 32));
dictClamshellClosed->setObject (gIOPMonTypeKey, gIOPMonTypeClamshellSens);
if (!gIOPMonPowerStateKey)
gIOPMonPowerStateKey = OSSymbol::withCString (kIOPMonPowerStateKey);
if (!gIOPMonThermalStateKey)
gIOPMonThermalStateKey = OSSymbol::withCString (kIOPMonThermalStateKey);
if (!gIOPMonClamshellStateKey)
gIOPMonClamshellStateKey = OSSymbol::withCString (kIOPMonClamshellStateKey);
if (!gIOPMonCPUActionKey)
gIOPMonCPUActionKey = OSSymbol::withCString (kIOPMonCPUActionKey);
if (!gIOPMonGPUActionKey)
gIOPMonGPUActionKey = OSSymbol::withCString (kIOPMonGPUActionKey);
if (!gIOPMonState0)
gIOPMonState0 = OSSymbol::withCString (kIOPMonState0);
if (!gIOPMonState1)
gIOPMonState1 = OSSymbol::withCString (kIOPMonState1);
if (!gIOPMonState2)
gIOPMonState2 = OSSymbol::withCString (kIOPMonState2);
if (!gIOPMonState3)
gIOPMonState3 = OSSymbol::withCString (kIOPMonState3);
if (!gIOPMonFull)
gIOPMonFull = OSSymbol::withCString (kIOPMonFull);
if (!gIOPMonReduced)
gIOPMonReduced = OSSymbol::withCString (kIOPMonReduced);
if (!gIOPMonSlow)
gIOPMonSlow = OSSymbol::withCString (kIOPMonSlow);
lastPowerState = kMaxPowerStates;
lastThermalState = kMaxThermalStates;
lastClamshellState = kNumClamshellStates;
updateIOPMonStateInfo(kIOPMonPowerSensor, currentPowerState);
updateIOPMonStateInfo(kIOPMonThermalSensor, currentThermalState);
updateIOPMonStateInfo(kIOPMonClamshellSensor, currentClamshellState);
provider->setProperty (gIOPMonCPUActionKey, (OSObject *)gIOPMonReduced);
provider->setProperty (gIOPMonGPUActionKey, (OSObject *)gIOPMonFull);
publishResource ("IOPlatformMonitor", this);
if (super::start (nub)) {
conSensorArray[kGPUController].conSensor = pmRootDomain;
return true;
} else
return false;
}
IOReturn PB5_1_PlatformMonitor::powerStateWillChangeTo (IOPMPowerFlags theFlags, unsigned long, IOService*)
{
if ( ! (theFlags & IOPMPowerOn) ) {
IOLog ("PB5_1_PlatformMonitor::powerStateWillChangeTo - sleep\n");
savePlatformState();
}
return IOPMAckImplied;
}
IOReturn PB5_1_PlatformMonitor::powerStateDidChangeTo (IOPMPowerFlags theFlags, unsigned long, IOService*)
{
if (theFlags & IOPMPowerOn) {
IOLog ("PB5_1_PlatformMonitor::powerStateDidChangeTo - wake\n");
restorePlatformState();
}
return IOPMAckImplied;
}
IOReturn PB5_1_PlatformMonitor::setAggressiveness(unsigned long selector, unsigned long newLevel)
{
IOPMonEventData event;
IOReturn result;
result = super::setAggressiveness(selector, newLevel);
newLevel &= 0x7FFFFFFF; if (selector == kPMSetProcessorSpeed) {
IOLog ("PB5_1_PlatformMonitor::setAggressiveness - newLevel %ld\n", newLevel);
if (newLevel != currentPowerState) { event.event = kIOPMonMessageStateChanged;
event.conSensor = this;
event.eventDict = (newLevel == 0) ? dictPowerHigh : dictPowerLow;
handleEvent (&event);
}
}
return result;
}
bool PB5_1_PlatformMonitor::initPowerState ()
{
currentPowerState = kPowerState0; return true;
}
void PB5_1_PlatformMonitor::savePowerState ()
{
return; }
bool PB5_1_PlatformMonitor::restorePowerState ()
{
IOService *serv;
conSensorArray[kCPUController].state = kCPUPowerState0;
serv = conSensorArray[kCPUController].conSensor;
IOLog ("IOPMon::actionFullPower - sending CPU aggressiveness 2\n");
serv->setAggressiveness (kPMSetProcessorSpeed, 2);
return (currentPowerState == kPowerState1);
}
bool PB5_1_PlatformMonitor::initThermalState ()
{
currentThermalState = kThermalState0;
return true;
}
void PB5_1_PlatformMonitor::saveThermalState ()
{
return; }
bool PB5_1_PlatformMonitor::restoreThermalState ()
{
OSNumber *threshLow, *threshHigh;
UInt32 i;
for (i = 0; i < kMaxSensorIndex; i++) {
if (subSensorArray[i].registered) { subSensorArray[i].state = kMaxThermalStates;
threshLow = (OSNumber *)subSensorArray[i].threshDict->getObject (gIOPMonLowThresholdKey);
threshLow->setValue((long long)0);
threshHigh = (OSNumber *)subSensorArray[i].threshDict->getObject (gIOPMonHighThresholdKey);
threshHigh->setValue((long long)0);
subSensorArray[i].conSensor->setProperties (subSensorArray[i].threshDict);
}
}
return false;
}
bool PB5_1_PlatformMonitor::initClamshellState ()
{
currentClamshellState = kClamshellStateOpen;
return true;
}
void PB5_1_PlatformMonitor::saveClamshellState ()
{
return; }
bool PB5_1_PlatformMonitor::restoreClamshellState ()
{
return false;
}
IOReturn PB5_1_PlatformMonitor::monitorPower (OSDictionary *dict, IOService *provider)
{
UInt32 type, index, subIndex, value;
OSNumber *num;
if (lookupConSensorInfo (dict, provider, &type, &index, &subIndex)) {
if (num = OSDynamicCast (OSNumber, dict->getObject (gIOPMonCurrentValueKey))) {
value = num->unsigned32BitValue();
value &= ~kIOPMForceLowSpeed;
num->setValue((long long)value); }
}
return kIOReturnBadArgument;
}
void PB5_1_PlatformMonitor::updateIOPMonStateInfo (UInt32 type, UInt32 state)
{
const OSSymbol *stateKey, *stateValue;
stateKey = stateValue = NULL;
if (type == kIOPMonPowerSensor)
stateKey = gIOPMonPowerStateKey;
else if (type == kIOPMonThermalSensor)
stateKey = gIOPMonThermalStateKey;
else if (type == kIOPMonClamshellSensor)
stateKey = gIOPMonClamshellStateKey;
if (state == kThermalState0)
stateValue = gIOPMonState0;
else if (state == kThermalState1)
stateValue = gIOPMonState1;
else if (state == kThermalState2)
stateValue = gIOPMonState2;
else if (state == kThermalState3)
stateValue = gIOPMonState3;
if (stateKey && stateValue)
provider->setProperty (stateKey, (OSObject *)stateValue);
return;
}
bool PB5_1_PlatformMonitor::initPlatformState ()
{
if (initPowerState() &&
initThermalState() &&
initClamshellState())
return true;
else
return false;
}
void PB5_1_PlatformMonitor::savePlatformState ()
{
savePowerState();
saveThermalState();
saveClamshellState();
return;
}
void PB5_1_PlatformMonitor::restorePlatformState ()
{
bool doAdjust;
lastPowerState = kMaxPowerStates;
lastThermalState = kMaxThermalStates;
lastClamshellState = kNumClamshellStates;
doAdjust = restorePowerState();
doAdjust |= restoreThermalState();
doAdjust |= restoreClamshellState();
if (doAdjust) {
lastAction = 0; adjustPlatformState ();
}
return;
}
bool PB5_1_PlatformMonitor::adjustPlatformState ()
{
IOPlatformMonitorAction actionToTake;
bool result = true;
IOLog ("PB5_1_PlatformMonitor::adjustPlatformState - entered, cps %ld, cts %ld, ccs %ld\n",
currentPowerState, currentThermalState, currentClamshellState);
actionToTake = platformActionGrid[currentPowerState][currentThermalState][currentClamshellState];
if (lastPowerState != currentPowerState) {
lastPowerState = currentPowerState;
updateIOPMonStateInfo(kIOPMonPowerSensor, currentPowerState);
}
if (lastThermalState != currentThermalState) {
lastAction = 0;
lastThermalState = currentThermalState;
updateIOPMonStateInfo(kIOPMonThermalSensor, currentThermalState);
}
if (lastClamshellState != currentClamshellState) {
lastClamshellState = currentClamshellState;
updateIOPMonStateInfo(kIOPMonClamshellSensor, currentClamshellState);
}
if (actionToTake != lastAction) {
result = (*actionToTake)(); lastAction = actionToTake; }
return result;
}
IOReturn PB5_1_PlatformMonitor::registerConSensor (OSDictionary *dict, IOService *conSensor)
{
UInt32 csi, subsi, type, initialState, initialValue;
ConSensorInfo *csInfo;
if (!lookupConSensorInfo (dict, conSensor, &type, &csi, &subsi))
return kIOReturnBadArgument;
IOLog ("PB5_1_PlatformMonitor::registerConSensor - type %ld, csi %ld, subsi %ld\n", type, csi, subsi);
if (subsi < kMaxSensorIndex) csInfo = &subSensorArray[subsi];
else
csInfo = &conSensorArray[csi];
csInfo->conSensor = conSensor;
csInfo->dict = dict;
dict->retain ();
initialState = initialValue = 0;
switch (csInfo->conSensorType) {
case kIOPMonThermalSensor:
if (!csInfo->sensorValid)
return kIOReturnUnsupported;
if (!(csInfo->threshDict = OSDictionary::withCapacity(3)))
return kIOReturnNoMemory;
csInfo->threshDict->setObject (gIOPMonIDKey, OSNumber::withNumber (subsi, 32));
csInfo->threshDict->setObject (gIOPMonLowThresholdKey,
OSNumber::withNumber (thermalThresholdInfoArray[subsi][currentClamshellState][initialState].thresholdLow, 32));
csInfo->threshDict->setObject (gIOPMonHighThresholdKey,
OSNumber::withNumber (thermalThresholdInfoArray[subsi][currentClamshellState][initialState].thresholdHigh, 32));
conSensor->setProperties (csInfo->threshDict);
csInfo->registered = true;
break;
case kIOPMonPowerSensor:
initialState = kPowerState0; break;
case kIOPMonClamshellSensor:
if (!retrieveCurrentValue (dict, &initialValue))
return kIOReturnBadArgument;
csInfo->registered = true;
break;
case kIOPMonCPUController:
initialState = kCPUPowerState0; csInfo->registered = true;
break;
case kIOPMonGPUController:
initialState = kGPUPowerState0; break;
default:
break;
}
csInfo->value = initialValue;
csInfo->state = initialState;
return kIOReturnSuccess;
}
bool PB5_1_PlatformMonitor::unregisterSensor (UInt32 sensorID)
{
if (sensorID >= kMaxSensors)
return false;
conSensorArray[sensorID].conSensor = NULL;
return true;
}
bool PB5_1_PlatformMonitor::lookupConSensorInfo (OSDictionary *dict, IOService *conSensor,
UInt32 *type, UInt32 *index, UInt32 *subIndex)
{
OSSymbol *typeString;
UInt32 tempType;
OSObject *obj;
*index = kMaxConSensors; *subIndex = kMaxSensorIndex; *type = tempType = kIOPMonUnknownSensor; obj = dict->getObject (gIOPMonTypeKey);
if (obj && (typeString = OSDynamicCast (OSSymbol, obj))) {
if (typeString->isEqualTo (gIOPMonTypePowerSens))
tempType = kIOPMonPowerSensor;
else if (typeString->isEqualTo (gIOPMonTypeThermalSens))
tempType = kIOPMonThermalSensor;
else if (typeString->isEqualTo (gIOPMonTypeClamshellSens))
tempType = kIOPMonClamshellSensor;
else if (typeString->isEqualTo (gIOPMonTypeCPUCon))
tempType = kIOPMonCPUController;
else if (typeString->isEqualTo (gIOPMonTypeGPUCon))
tempType = kIOPMonGPUController;
else if (typeString->isEqualTo (gIOPMonTypeSlewCon))
tempType = kIOPMonSlewController;
else if (typeString->isEqualTo (gIOPMonTypeFanCon))
tempType = kIOPMonFanController;
}
if (retrieveSensorIndex (dict, subIndex)) {
if (*subIndex >= kMaxSensorIndex)
return false;
*type = (tempType == kIOPMonUnknownSensor) ? subSensorArray[*subIndex].conSensorType : tempType;
return true;
}
for (*index = 0; *index < kMaxConSensors; (*index)++) {
if (conSensorArray[*index].conSensorType == tempType) {
*type = tempType;
break;
}
}
return (*index < kMaxConSensors);
}
UInt32 PB5_1_PlatformMonitor::lookupThermalStateFromValue (UInt32 sensorIndex, ThermalValue value)
{
UInt32 i;
if (value > thermalThresholdInfoArray[sensorIndex][currentClamshellState][0].thresholdLow) {
for (i = 0 ; i < subSensorArray[sensorIndex].numStates; i++)
if (value > thermalThresholdInfoArray[sensorIndex][currentClamshellState][i].thresholdLow &&
value < thermalThresholdInfoArray[sensorIndex][currentClamshellState][i].thresholdHigh)
return i;
IOLog ("PB5_1_PlatformMonitor::lookupStateFromValue - sensor %ld over limit\n", sensorIndex);
return kMaxSensorIndex;
}
return kThermalState0;
}
bool PB5_1_PlatformMonitor::handlePowerEvent (IOPMonEventData *eventData)
{
UInt32 nextPowerState;
bool result;
if (!(retrieveCurrentValue (eventData->eventDict, &nextPowerState)))
return false;
result = true;
if (currentPowerState != nextPowerState) {
currentPowerState = nextPowerState;
result = adjustPlatformState ();
}
return result;
}
bool PB5_1_PlatformMonitor::handleThermalEvent (IOPMonEventData *eventData)
{
UInt32 type, csi, subsi, myThermalState;
ThermalValue value;
OSNumber *threshLow, *threshHigh;
bool result;
result = true;
if (!(retrieveCurrentValue (eventData->eventDict, &value)))
return false;
switch (eventData->event) {
case kIOPMonMessageLowThresholdHit:
case kIOPMonMessageHighThresholdHit:
if (lookupConSensorInfo (eventData->eventDict, eventData->conSensor, &type, &csi, &subsi) &&
subSensorArray[subsi].registered) {
myThermalState = lookupThermalStateFromValue (subsi, value);
if (myThermalState >= kMaxSensorIndex)
result = false;
} else
result = false;
break;
default:
IOLog ("PB5_1_PlatformMonitor::handleThermalEvent - event %ld not handled\n",
eventData->event);
result = false;
break;
}
if (result) {
if (myThermalState != subSensorArray[subsi].state) {
subSensorArray[subsi].state = myThermalState;
if (!subSensorArray[subsi].registered)
return false;
threshLow = (OSNumber *)subSensorArray[subsi].threshDict->getObject (gIOPMonLowThresholdKey);
threshLow->setValue((long long)thermalThresholdInfoArray[subsi][currentClamshellState][myThermalState].thresholdLow);
threshHigh = (OSNumber *)subSensorArray[subsi].threshDict->getObject (gIOPMonHighThresholdKey);
threshHigh->setValue((long long)thermalThresholdInfoArray[subsi][currentClamshellState][myThermalState].thresholdHigh);
subSensorArray[subsi].conSensor->setProperties (subSensorArray[subsi].threshDict);
}
if (currentThermalState != myThermalState) {
UInt32 i, maxState;
maxState = 0;
for (i = 0; i < kMaxSensorIndex; i++)
if (subSensorArray[i].registered)
maxState = (maxState > subSensorArray[i].state) ? maxState : subSensorArray[i].state;
if (currentThermalState != maxState) {
currentThermalState = maxState;
result = adjustPlatformState ();
}
}
}
return result;
}
bool PB5_1_PlatformMonitor::handleClamshellEvent (IOPMonEventData *eventData)
{
UInt32 nextClamshellState;
bool result;
if (!(retrieveCurrentValue (eventData->eventDict, &nextClamshellState)))
return false;
result = true;
if (currentClamshellState != nextClamshellState) {
currentClamshellState = nextClamshellState;
result = adjustPlatformState ();
}
return result;
}
IOReturn PB5_1_PlatformMonitor::iopmonCommandGateCaller(OSObject *object, void *arg0, void *arg1, void *arg2, void *arg3)
{
PB5_1_PlatformMonitor *me;
IOPMonCommandThreadSet *commandSet;
UInt32 type, conSensorID, subSensorID;
bool result;
if (((commandSet = (IOPMonCommandThreadSet *)arg0) == NULL) ||
((me = OSDynamicCast(PB5_1_PlatformMonitor, commandSet->me)) == NULL))
return kIOReturnError;
result = true;
switch (commandSet->command) {
case kIOPMonCommandHandleEvent:
if (!(commandSet->eventData.eventDict)) {
IOLog ("PB5_1_PlatformMonitor::iopmonCommandGateCaller - bad dictionary\n");
return kIOReturnBadArgument;
}
if (!(commandSet->eventData.conSensor)) {
IOLog ("PB5_1_PlatformMonitor::iopmonCommandGateCaller - bad conSensor\n");
return kIOReturnBadArgument;
}
if (!me->lookupConSensorInfo (commandSet->eventData.eventDict, commandSet->eventData.conSensor,
&type, &conSensorID, &subSensorID)) {
IOLog ("PB5_1_PlatformMonitor::iopmonCommandGateCaller - bad sensor info lookup\n");
return kIOReturnBadArgument;
}
switch (type) {
case kIOPMonPowerSensor: result = me->handlePowerEvent (&commandSet->eventData);
break;
case kIOPMonThermalSensor: result = me->handleThermalEvent (&commandSet->eventData);
break;
case kIOPMonClamshellSensor: result = me->handleClamshellEvent (&commandSet->eventData);
break;
default:
IOLog ("PB5_1_PlatformMonitor::iopmonCommandGateCaller - bad sensorType(%ld), sensorID(%ld), subsi(%ld)\n",
type, conSensorID, subSensorID);
result = false;
break;
}
break;
case kIOPMonCommandSaveState:
me->savePlatformState ();
break;
case kIOPMonCommandRestoreState:
me->restorePlatformState ();
break;
default:
IOLog ("PB5_1_PlatformMonitor::iopmonCommandGateCaller - bad command %ld\n",
commandSet->command);
result = false;
break;
}
return result ? kIOReturnSuccess : kIOReturnError;
}