bool X3100monitor::start(IOService * provider) { if (!super::start(provider)) return false; //Find card number SInt8 cardIndex = getVacantGPUIndex(); if (cardIndex < 0) { HWSensorsWarningLog("failed to obtain vacant GPU index"); return false; } char key[5]; snprintf(key, 5, KEY_FORMAT_GPU_PROXIMITY_TEMPERATURE, cardIndex); if (!addSensor(key, TYPE_SP78, 2, kFakeSMCTemperatureSensor, 0)) { HWSensorsWarningLog("failed to register temperature sensor"); return false; } registerService(); return true; }
const void *FakeSMCKey::getValue() { if (handler) { mach_timespec_t now, end; end.tv_sec = lastUpdated.tv_sec; end.tv_nsec = lastUpdated.tv_nsec; now.tv_sec = 1; now.tv_nsec = 0; ADD_MACH_TIMESPEC(&end, &now); clock_get_system_nanotime((clock_sec_t*)&now.tv_sec, (clock_nsec_t*)&now.tv_nsec); if (CMP_MACH_TIMESPEC(&end, &now) < 0) { IOReturn result = handler->callPlatformFunction(kFakeSMCGetValueCallback, false, (void *)key, (void *)value, (void *)size, 0); if (kIOReturnSuccess == result) clock_get_system_nanotime((clock_sec_t*)&lastUpdated.tv_sec, (clock_nsec_t*)&lastUpdated.tv_nsec); else HWSensorsWarningLog("value update request callback error for key %s, return 0x%x", key, result); } } return value; };
bool FakeSMCKey::setValueFromBuffer(const void *aBuffer, UInt8 aSize) { if (!aBuffer || aSize == 0) return false; if (aSize != size) { if (value) IOFree(value, size); size = aSize; if (!(value = IOMalloc(size))) return false; } bcopy(aBuffer, value, size); if (handler) { IOReturn result = handler->callPlatformFunction(kFakeSMCSetValueCallback, false, (void *)key, (void *)value, (void *)size, 0); if (kIOReturnSuccess != result) HWSensorsWarningLog("value changed event callback error for key %s, return 0x%x", key, result); } return true; }
bool SuperIOPlugin::addSensorFromConfigurationNode(OSObject *configuration, const char *name, const char *key, const char *type, UInt8 size, UInt32 group, UInt32 index) { float reference = 0, gain = 0, offset = 0; if (configuration) { if (OSString *configName = OSDynamicCast(OSString, configuration)) { if (!configName->isEqualTo(name)) return false; } else if (OSDictionary *configDict = OSDynamicCast(OSDictionary, configuration)) { if ((configName = OSDynamicCast(OSString, configDict->getObject("name")))) { if (configName->isEqualTo(name)) { if (OSNumber *number = OSDynamicCast(OSNumber, configDict->getObject("reference"))) reference = (float)number->unsigned64BitValue() / 1000.0f; if (OSNumber *number = OSDynamicCast(OSNumber, configDict->getObject("gain"))) gain = (float)number->unsigned64BitValue() / 1000.0f; if (OSNumber *number = OSDynamicCast(OSNumber, configDict->getObject("offset"))) offset = (float)number->unsigned64BitValue() / 1000.0f; } else return false; } else return false; } else return false; } if (!this->addSensor(key, type, size, group, index, reference, gain, offset)) { const char *group_name; switch (group) { case kFakeSMCTemperatureSensor: group_name = " temperature"; break; case kFakeSMCTachometerSensor: group_name = " tachometer"; break; case kFakeSMCVoltageSensor: group_name = " voltage"; break; case kFakeSMCFrequencySensor: group_name = " frequency"; break; case kFakeSMCMultiplierSensor: group_name = " multiplier"; break; default: group_name = ""; break; } HWSensorsWarningLog("failed to add %s%s sensor", name, group_name); return false; } return true; }
FakeSMCSensor *FakeSMCPlugin::addTachometer(UInt32 index, const char* name, SInt8 *fanIndex) { SInt8 vacantFanIndex = takeVacantFanIndex(); if (vacantFanIndex >= 0) { char key[5]; snprintf(key, 5, KEY_FORMAT_FAN_SPEED, vacantFanIndex); if (FakeSMCSensor *sensor = addSensor(key, TYPE_FPE2, 2, kFakeSMCTachometerSensor, index)) { if (name) { snprintf(key, 5, KEY_FORMAT_FAN_ID, vacantFanIndex); if (!setKeyValue(key, TYPE_CH8, strlen(name), name)) HWSensorsWarningLog("failed to add tachometer name for key %s", key); } if (fanIndex) *fanIndex = vacantFanIndex; return sensor; } else HWSensorsErrorLog("failed to add tachometer sensor for key %s", key); } else HWSensorsErrorLog("failed to take vacant Fan index"); return 0; }
UInt32 FakeSMCDevice::loadKeysFromNVRAM() { UInt32 count = 0; // Find driver and load keys from NVRAM if (OSDictionary *matching = serviceMatching("IODTNVRAM")) { if (IODTNVRAM *nvram = OSDynamicCast(IODTNVRAM, waitForMatchingService(matching, 1000000000ULL * 15))) { useNVRAM = true; if ((genericNVRAM = (0 == strncmp(nvram->getName(), "AppleNVRAM", sizeof("AppleNVRAM"))))) HWSensorsInfoLog("fallback to generic NVRAM methods"); OSSerialize *s = OSSerialize::withCapacity(0); // Workaround for IODTNVRAM->getPropertyTable returns IOKitPersonalities instead of NVRAM properties dictionary if (nvram->serializeProperties(s)) { if (OSDictionary *props = OSDynamicCast(OSDictionary, OSUnserializeXML(s->text()))) { if (OSCollectionIterator *iterator = OSCollectionIterator::withCollection(props)) { size_t prefix_length = strlen(kFakeSMCKeyPropertyPrefix); char name[5]; name[4] = 0; char type[5]; type[4] = 0; while (OSString *property = OSDynamicCast(OSString, iterator->getNextObject())) { const char *buffer = static_cast<const char *>(property->getCStringNoCopy()); if (property->getLength() >= prefix_length + 1 + 4 + 1 + 0 && 0 == strncmp(buffer, kFakeSMCKeyPropertyPrefix, prefix_length)) { if (OSData *data = OSDynamicCast(OSData, props->getObject(property))) { strncpy(name, buffer + prefix_length + 1, 4); // fakesmc-key-???? -> strncpy(type, buffer + prefix_length + 1 + 4 + 1, 4); // fakesmc-key-xxxx-???? -> if (addKeyWithValue(name, type, data->getLength(), data->getBytesNoCopy())) { HWSensorsDebugLog("key %s of type %s loaded from NVRAM", name, type); count++; } } } } OSSafeRelease(iterator); } OSSafeRelease(props); } } OSSafeRelease(s); OSSafeRelease(nvram); } else { HWSensorsWarningLog("NVRAM is unavailable"); } OSSafeRelease(matching); } return count; }
FakeSMCSensor *FakeSMCPlugin::addTachometer(UInt32 index, const char* name, UInt8 *fanIndex) { UInt8 length = 0; void * data = 0; if (kIOReturnSuccess == storageProvider->callPlatformFunction(kFakeSMCGetKeyValue, true, (void *)KEY_FAN_NUMBER, (void *)&length, (void *)&data, 0)) { length = 0; bcopy(data, &length, 1); for (int i = 0; i <= 0xf; i++) { char key[5]; snprintf(key, 5, KEY_FORMAT_FAN_SPEED, i); if (!isKeyHandled(key)) { if (FakeSMCSensor *sensor = addSensor(key, TYPE_FPE2, 2, kFakeSMCTachometerSensor, index)) { if (name) { snprintf(key, 5, KEY_FORMAT_FAN_ID, i); if (!setKeyValue(key, TYPE_CH8, strlen(name), name)) HWSensorsWarningLog("failed to add tachometer name for key %s", key); } if (i + 1 > length) { length++; if (kIOReturnSuccess != storageProvider->callPlatformFunction(kFakeSMCSetKeyValue, true, (void *)KEY_FAN_NUMBER, (void *)(UInt8)1, (void *)&length, 0)) HWSensorsWarningLog("failed to update FNum value"); } if (fanIndex) *fanIndex = i; return sensor; } else HWSensorsWarningLog("failed to add tachometer sensor for key %s", key); } } } else HWSensorsWarningLog("failed to read FNum value"); return 0; }
SInt8 FakeSMCPlugin::getVacantGPUIndex() { SInt8 index = -1; if (kIOReturnSuccess != storageProvider->callPlatformFunction(kFakeSMCGetVacantGPUIndex, true, (void *)&index, 0, 0, 0)) { HWSensorsWarningLog("failed to get vacant GPU index"); } return index; }
bool FakeSMCPlugin::start(IOService *provider) { if (!super::start(provider)) return false; if (!(fakeSMC = waitForService(serviceMatching(kFakeSMCDeviceService)))) { HWSensorsWarningLog("can't locate FakeSMCDevice"); return false; } return true; }
bool SuperIOMonitor::addTemperatureSensors(OSDictionary *configuration) { HWSensorsDebugLog("adding temperature sensors..."); for (int i = 0; i < temperatureSensorsLimit(); i++) { char key[8]; OSString* name; float reference = 0.0f; float gain = 0.0f; float offset = 0.0f; snprintf(key, 8, "TEMPIN%X", i); if (process_sensor_entry(configuration->getObject(key), &name, &reference, &gain, &offset)) { if (name->isEqualTo("CPU")) { if (!addSensor(KEY_CPU_HEATSINK_TEMPERATURE, TYPE_SP78, TYPE_SPXX_SIZE, kSuperIOTemperatureSensor, i, reference, gain, offset)) HWSensorsWarningLog("can't add CPU temperature sensor"); } if (name->isEqualTo("CPU Proximity")) { if (!addSensor(KEY_CPU_PROXIMITY_TEMPERATURE, TYPE_SP78, TYPE_SPXX_SIZE, kSuperIOTemperatureSensor, i, reference, gain, offset)) HWSensorsWarningLog("can't add CPU Proximity temperature sensor"); } else if (name->isEqualTo("System")) { if (!addSensor(KEY_NORTHBRIDGE_TEMPERATURE, TYPE_SP78, TYPE_SPXX_SIZE, kSuperIOTemperatureSensor, i, reference, gain, offset)) HWSensorsWarningLog("can't add System temperature sensor"); } else if (name->isEqualTo("Ambient")) { if (!addSensor(KEY_AMBIENT_TEMPERATURE, TYPE_SP78, TYPE_SPXX_SIZE, kSuperIOTemperatureSensor, i, reference, gain, offset)) HWSensorsWarningLog("can't add Ambient temperature sensor"); } else if (name->isEqualTo("PCH")) { if (!addSensor(KEY_PCH_DIE_TEMPERATURE, TYPE_SP78, TYPE_SPXX_SIZE, kSuperIOTemperatureSensor, i, reference, gain, offset)) HWSensorsWarningLog("can't add PCH temperature sensor"); } } } return true; }
bool ACPISensors::addSensorToList(OSDictionary *list, OSString *configKey, OSString *acpiMethod, const char *refName, const char* smcKey, const char *type, UInt8 size, UInt32 group, UInt32 index) { if (configKey->isEqualTo(refName)) { if (addSensor(smcKey, type, size, group, index)) { list->setObject(smcKey, acpiMethod); return true; } } HWSensorsWarningLog("failed to register sensor for key %s", configKey->getCStringNoCopy()); return false; }
bool FakeSMCPlugin::start(IOService *provider) { if (!super::start(provider)) return false; if (!(headingProvider = waitForService(serviceMatching(kFakeSMCService)))) HWSensorsWarningLog("failed to locate FakeSMC service, specific OEM configurations will be unavailable"); if (!(storageProvider = waitForService(serviceMatching(kFakeSMCDeviceService)))) { HWSensorsFatalLog("failed to locate FakeSMCDevice"); return false; } return true; }
bool SuperIOPlugin::addTachometerSensors(OSDictionary *configuration) { HWSensorsDebugLog("adding tachometer sensors..."); for (int i = 0; i < tachometerSensorsLimit(); i++) { char key[7]; snprintf(key, 7, "FANIN%X", i); if (OSString* name = OSDynamicCast(OSString, configuration->getObject(key))) if (!addTachometer(i, (name->getLength() > 0 ? name->getCStringNoCopy() : 0))) HWSensorsWarningLog("failed to add tachometer sensor %d", i); } return true; }
bool LPCSensors::addTachometerSensors(OSDictionary *configuration) { HWSensorsDebugLog("adding tachometer sensors..."); char key[7]; UInt16 value = 0; // FAN manual control key addSensorForKey(KEY_FAN_MANUAL, SMC_TYPE_UI16, SMC_TYPE_UI16_SIZE, kLPCSensorsFanManualSwitch, 0); int location = LEFT_LOWER_FRONT; for (int i = 0; i < tachometerSensorsLimit(); i++) { UInt8 fanIndex; snprintf(key, 7, "FANIN%X", i); if (OSString* name = OSDynamicCast(OSString, configuration->getObject(key))){ if (addTachometer(i, name->getLength() > 0 ? name->getCStringNoCopy() : 0, FAN_RPM, 0, (FanLocationType)location++, &fanIndex)){ if (isTachometerControlable(i) && fanIndex < UINT8_MAX) { tachometerControls[i].number = fanIndex; tachometerControls[i].target = -1; tachometerControls[i].minimum = -1; // Minimum RPM and fan control sensor snprintf(key, 5, KEY_FORMAT_FAN_MIN, fanIndex); addSensorForKey(key, SMC_TYPE_FPE2, SMC_TYPE_FPXX_SIZE, kLPCSensorsFanMinController, i); // Maximum RPM snprintf(key, 5, KEY_FORMAT_FAN_MAX, fanIndex); FakeSMCKey::encodeFloatValue(kLPCSensorsMaxRPM, SMC_TYPE_FPE2, SMC_TYPE_FPXX_SIZE, &value); setKeyValue(key, SMC_TYPE_FPE2, SMC_TYPE_FPXX_SIZE, &value); // Target RPM and fan control sensor snprintf(key, 5, KEY_FORMAT_FAN_TARGET, fanIndex); addSensorForKey(key, SMC_TYPE_FPE2, SMC_TYPE_FPXX_SIZE, kLPCSensorsFanTargetController, i); } } else HWSensorsWarningLog("failed to add tachometer sensor %d", i); } } return true; }
const void *FakeSMCKey::getValue() { if (handler) { UInt64 now = ptimer_read(); if (now - lastUpdated >= NSEC_PER_SEC) { IOReturn result = handler->callPlatformFunction(kFakeSMCGetValueCallback, true, (void *)key, (void *)value, (void *)size, 0); if (kIOReturnSuccess == result) lastUpdated = now; else HWSensorsWarningLog("value update request callback returned error for key %s, return 0x%x", key, result); } } return value; };
bool INT340EMonitor::updateTemperatures() { OSObject *object; if (kIOReturnSuccess == acpiDevice->evaluateObject("TSDD", &object) && object) { OSSafeRelease(temperatures); temperatures = OSDynamicCast(OSArray, object); //setProperty("temperatures", temperatures); return true; } else HWSensorsWarningLog("failed to evaluate TSDD method"); return false; }
bool PTIDSensors::updateTachometers() { OSObject *object; if (kIOReturnSuccess == acpiDevice->evaluateObject("OSDD", &object) && object) { OSSafeRelease(tachometers); tachometers = OSDynamicCast(OSArray, object); //setProperty("tachometers", tachometers); return true; } HWSensorsWarningLog("failed to evaluate OSDD method"); return false; }
bool FakeSMC::init(OSDictionary *dictionary) { if (!super::init(dictionary)) return false; IOLog("HWSensors Project Copyright %d netkas, slice, usr-sse2, kozlek, navi, THe KiNG. All rights reserved.\n",HWSENSORS_LASTYEAR); //HWSensorsInfoLog("Opensource SMC device emulator. Copyright 2009 netkas. All rights reserved."); if (!(smcDevice = new FakeSMCDevice)) { HWSensorsInfoLog("failed to create SMC device"); return false; } if (!setOemProperties(this)) HWSensorsWarningLog("failed to read OEM data, specific OEM configuration will be unavailable"); return true; }
FakeSMCSensor *FakeSMCPlugin::addTachometer(UInt32 index, const char *name, FanType type, UInt8 zone, FanLocationType location, SInt8 *fanIndex) { SYNCLOCK; SInt8 vacantFanIndex = takeVacantFanIndex(); if (vacantFanIndex >= 0) { char key[5]; snprintf(key, 5, KEY_FORMAT_FAN_SPEED, vacantFanIndex); if (FakeSMCSensor *sensor = addSensor(key, TYPE_FPE2, TYPE_FPXX_SIZE, kFakeSMCTachometerSensor, index)) { FanTypeDescStruct fds; bzero(&fds, sizeof(fds)); fds.type = type; fds.ui8Zone = zone; fds.location = location; if (name) strlcpy(fds.strFunction, name, DIAG_FUNCTION_STR_LEN); else snprintf(fds.strFunction, DIAG_FUNCTION_STR_LEN, "MB Fan %X", index); snprintf(key, 5, KEY_FORMAT_FAN_ID, vacantFanIndex); if (!setKeyValue(key, TYPE_FDS, sizeof(fds), &fds)) HWSensorsWarningLog("failed to add tachometer name for key %s", key); if (fanIndex) *fanIndex = vacantFanIndex; SYNCUNLOCK; return sensor; } else HWSensorsErrorLog("failed to add tachometer sensor for key %s", key); } else HWSensorsErrorLog("failed to take vacant Fan index"); SYNCUNLOCK; return 0; }
bool FakeSMCKey::setValueFromBuffer(const void *aBuffer, UInt8 aSize) { if (!aBuffer || aSize == 0) return false; if (aSize != size) { if (value) IOFree(value, size); size = aSize; if (!(value = IOMalloc(size))) return false; } bcopy(aBuffer, value, size); if (handler) { /*double time = ptimer_read_seconds(); if (time - lastValueWrote >= 0.5) { IOReturn result = handler->writeKeyCallback(key, type, size, value); if (kIOReturnSuccess == result) { lastValueWrote = time; } else { HWSensorsWarningLog("value changed event callback returned error for key %s (%s)", key, handler->stringFromReturn(result)); } }*/ IOReturn result = handler->writeKeyCallback(key, type, size, value); if (kIOReturnSuccess != result) { HWSensorsWarningLog("value changed event callback returned error for key %s (%s)", key, handler->stringFromReturn(result)); } } return true; }
const void *FakeSMCKey::getValue() { if (handler) { double time = ptimer_read_seconds(); if (time - lastValueRead >= 1.0) { IOReturn result = handler->getValueCallback(key, type, size, value); if (kIOReturnSuccess == result) { lastValueRead = time; } else { HWSensorsWarningLog("value update request callback returned error for key %s (%s)", key, handler->stringFromReturn(result)); } } } return value; };
bool SuperIOMonitor::addTachometerSensors(OSDictionary *configuration) { HWSensorsDebugLog("adding tachometer sensors..."); for (int i = 0; i < tachometerSensorsLimit(); i++) { OSString* name = NULL; char key[7]; snprintf(key, 7, "FANIN%X", i); name = OSDynamicCast(OSString, configuration->getObject(key)); UInt64 nameLength = name ? name->getLength() : 0; if (readTachometer(i) > 10 || nameLength > 0) if (!addTachometer(i, (nameLength > 0 ? name->getCStringNoCopy() : 0))) HWSensorsWarningLog("error adding tachometer sensor %d", i); } return true; }
const void *FakeSMCKey::getValue() { if (handler) { FakeSMCNanotime now; SET_FAKESMC_TIMESPEC(&now); if (CMP_FAKESMC_TIMESPEC(&now, &lastUpdated) >= NSEC_PER_SEC) { IOReturn result = handler->callPlatformFunction(kFakeSMCGetValueCallback, false, (void *)name, (void *)value, (void *)size, 0); if (kIOReturnSuccess == result) { lastUpdated.secs = now.secs; lastUpdated.nanosecs = now.nanosecs; } else HWSensorsWarningLog("value update request callback error for key %s, return 0x%x", name, result); } } return value; };
bool LPCSensors::addSensorFromConfigurationNode(OSObject *node, const char *key, const char *type, UInt8 size, UInt32 group, UInt32 index) { float reference = 0, gain = 0, offset = 0; if (OSDictionary *dictionary = OSDynamicCast(OSDictionary, node)) FakeSMCSensor::parseModifiers(dictionary, &reference, &gain, &offset); if (!this->addSensorForKey(key, type, size, group, index, reference, gain, offset)) { const char *group_name; switch (group) { case kFakeSMCTemperatureSensor: group_name = "temperature"; break; case kFakeSMCTachometerSensor: group_name = "tachometer"; break; case kFakeSMCVoltageSensor: group_name = "voltage"; break; case kFakeSMCFrequencySensor: group_name = "frequency"; break; case kFakeSMCMultiplierSensor: group_name = "multiplier"; break; default: group_name = ""; break; } HWSensorsWarningLog("failed to add %s sensor for key %s", group_name, key); return false; } return true; }
bool SuperIOMonitor::addVoltageSensors(OSDictionary *configuration) { HWSensorsDebugLog("adding voltage sensors..."); for (int i = 0; i < voltageSensorsLimit(); i++) { char key[5]; OSString* name; float reference = 0.0f; float gain = 0.0f; float offset = 0.0f; snprintf(key, 5, "VIN%X", i); if (process_sensor_entry(configuration->getObject(key), &name, &reference, &gain, &offset)) { if (name->isEqualTo("CPU")) { if (!addSensor(KEY_CPU_VOLTAGE, TYPE_FP2E, TYPE_FPXX_SIZE, kSuperIOVoltageSensor, i, reference, gain, offset)) HWSensorsWarningLog("can't add CPU voltage sensor"); } else if (name->isEqualTo("Memory")) { if (!addSensor(KEY_MEMORY_VOLTAGE, TYPE_FP2E, TYPE_FPXX_SIZE, kSuperIOVoltageSensor, i, reference, gain, offset)) HWSensorsWarningLog("can't add Memory voltage sensor"); } else if (name->isEqualTo("Main 12V")) { if (!addSensor(KEY_MAIN_12V_VOLTAGE, TYPE_FP4C, TYPE_FPXX_SIZE, kSuperIOVoltageSensor, i, reference, gain, offset)) HWSensorsWarningLog("can't add Main 12V voltage sensor"); } else if (name->isEqualTo("PCIe 12V")) { if (!addSensor(KEY_PCIE_12V_VOLTAGE, TYPE_FP4C, TYPE_FPXX_SIZE, kSuperIOVoltageSensor, i, reference, gain, offset)) HWSensorsWarningLog("can't add PCIe 12V voltage sensor"); } else if (name->isEqualTo("Main 5V")) { if (!addSensor(KEY_MAIN_5V_VOLTAGE, TYPE_FP4C, TYPE_FPXX_SIZE, kSuperIOVoltageSensor, i, reference, gain, offset)) HWSensorsWarningLog("can't add Main 5V voltage sensor"); } else if (name->isEqualTo("Standby 5V")) { if (!addSensor(KEY_STANDBY_5V_VOLTAGE, TYPE_FP4C, TYPE_FPXX_SIZE, kSuperIOVoltageSensor, i, reference, gain, offset)) HWSensorsWarningLog("can't add Standby 5V voltage sensor"); } else if (name->isEqualTo("Main 3V")) { if (!addSensor(KEY_MAIN_3V3_VOLTAGE, TYPE_FP2E, TYPE_FPXX_SIZE, kSuperIOVoltageSensor, i, reference, gain, offset)) HWSensorsWarningLog("can't add Main 3V voltage sensor"); } else if (name->isEqualTo("Auxiliary 3V")) { if (!addSensor(KEY_AUXILIARY_3V3V_VOLTAGE, TYPE_FP2E, TYPE_FPXX_SIZE, kSuperIOVoltageSensor, i, reference, gain, offset)) HWSensorsWarningLog("can't add Auxiliary 3V voltage sensor"); } else if (name->isEqualTo("Power/Battery")) { if (!addSensor(KEY_POWERBATTERY_VOLTAGE, TYPE_FP2E, TYPE_FPXX_SIZE, kSuperIOVoltageSensor, i, reference, gain, offset)) HWSensorsWarningLog("can't add Power/Battery voltage sensor"); } else if (name->isEqualTo("GPU")) { SInt8 index = getVacantGPUIndex(); if (index > -1) { snprintf(key, 5, KEY_FORMAT_GPU_VOLTAGE, index); if (!addSensor(key, TYPE_FP2E, TYPE_FPXX_SIZE, kSuperIOVoltageSensor, i, reference, gain, offset)) HWSensorsWarningLog("can't add GPU voltage sensor"); } else HWSensorsWarningLog("failed to obtain vacant GPU index"); } for (int j = 0; j <= 0xf; j++) { char caption[32]; snprintf(caption, 15, "Power Supply %X", j); if (name->isEqualTo(caption)) { snprintf(key, 5, KEY_FORMAT_POWERSUPPLY_VOLTAGE, j); if (!addSensor(key, TYPE_FP4C, TYPE_FPXX_SIZE, kSuperIOVoltageSensor, i, reference, gain, offset)) HWSensorsWarningLog("can't add PWR%X voltage sensor", j); } else { snprintf(caption, 17, "CPU VRM Supply %X", j); if (name->isEqualTo(caption)) { snprintf(key, 5, KEY_FORMAT_CPU_VRMSUPPLY_VOLTAGE, j); if (!addSensor(key, TYPE_FP4C, TYPE_FPXX_SIZE, kSuperIOVoltageSensor, i, reference, gain, offset)) HWSensorsWarningLog("can't add VRM%X voltage sensor", j); } } } } } return true; }
bool FakeSMC::start(IOService *provider) { if (!super::start(provider)) return false; if (!(keyStore = OSDynamicCast(FakeSMCKeyStore, waitForMatchingService(serviceMatching(kFakeSMCKeyStoreService), kFakeSMCDefaultWaitTimeout)))) { HWSensorsInfoLog("still waiting for FakeSMCKeyStore..."); return false; // HWSensorsDebugLog("creating FakeSMCKeyStore"); // // if (!(keyStore = new FakeSMCKeyStore)) { // HWSensorsInfoLog("failed to create FakeSMCKeyStore"); // return false; // } // // HWSensorsDebugLog("initializing FakeSMCKeyStore"); // // if (keyStore->initAndStart(this, configuration)) { // keyStore->setProperty("IOUserClientClass", "FakeSMCKeyStoreUserClient"); // } // else { // keyStore->release(); // HWSensorsFatalLog("failed to initialize FakeSMCKeyStore device"); // return false; // } } // if (IOService *resources = waitForMatchingService(serviceMatching("IOResources"), 0)) // this->attach(resources); OSDictionary *configuration = OSDynamicCast(OSDictionary, getProperty("Configuration")); // Load preconfigured keys HWSensorsDebugLog("loading keys..."); if (!configuration) { HWSensorsFatalLog("no configuration node found!"); return false; } if (UInt32 count = keyStore->addKeysFromDictionary(OSDynamicCast(OSDictionary, configuration->getObject("Keys")))) { HWSensorsInfoLog("%d preconfigured key%s added", count, count == 1 ? "" : "s"); } else { HWSensorsWarningLog("no preconfigured keys found"); } // Load wellknown type names HWSensorsDebugLog("loading types..."); keyStore->addWellKnownTypesFromDictionary(OSDynamicCast(OSDictionary, configuration->getObject("Types"))); // Set Clover platform keys if (OSDictionary *dictionary = OSDynamicCast(OSDictionary, configuration->getObject("Clover"))) { UInt32 count = 0; if (IORegistryEntry* cloverPlatformNode = fromPath("/efi/platform", gIODTPlane)) { if (OSIterator *iterator = OSCollectionIterator::withCollection(dictionary)) { while (OSString *name = OSDynamicCast(OSString, iterator->getNextObject())) { if (OSData *data = OSDynamicCast(OSData, cloverPlatformNode->getProperty(name))) { if (OSArray *items = OSDynamicCast(OSArray, dictionary->getObject(name))) { OSString *key = OSDynamicCast(OSString, items->getObject(0)); OSString *type = OSDynamicCast(OSString, items->getObject(1)); if (keyStore->addKeyWithValue(key->getCStringNoCopy(), type->getCStringNoCopy(), data->getLength(), data->getBytesNoCopy())) count++; } } } OSSafeRelease(iterator); } } if (count) HWSensorsInfoLog("%d key%s exported by Clover EFI", count, count == 1 ? "" : "s"); } // Check if we have SMC already bool smcDeviceFound = false; if (OSDictionary *matching = serviceMatching("IOACPIPlatformDevice")) { if (OSIterator *iterator = getMatchingServices(matching)) { OSString *smcNameProperty = OSString::withCString("APP0001"); while (IOService *service = (IOService*)iterator->getNextObject()) { OSObject *serviceNameProperty = service->getProperty("name"); if (serviceNameProperty && serviceNameProperty->isEqualTo(smcNameProperty)) { smcDeviceFound = true; } } OSSafeRelease(iterator); } OSSafeRelease(matching); } if (!smcDeviceFound) { if (!(smcDevice = new FakeSMCDevice)) { HWSensorsInfoLog("failed to create SMC device"); return false; } IOService *platformExpert = waitForMatchingService(serviceMatching("IOACPIPlatformExpert"), kFakeSMCDefaultWaitTimeout); if (!smcDevice->initAndStart(platformExpert, this)) { HWSensorsFatalLog("failed to initialize SMC device"); return false; } } else { HWSensorsInfoLog("found physical SMC device, will not create virtual one. Providing only basic plugins functionality"); } int arg_value = 1; // Load keys from NVRAM if (PE_parse_boot_argn("-fakesmc-use-nvram", &arg_value, sizeof(arg_value))) { if (UInt32 count = keyStore->loadKeysFromNVRAM()) HWSensorsInfoLog("%d key%s loaded from NVRAM", count, count == 1 ? "" : "s"); else HWSensorsInfoLog("NVRAM will be used to store system written keys..."); } registerService(); return true; }
bool FakeSMCDevice::initAndStart(IOService *platform, IOService *provider) { if (!provider || !super::init(platform, 0, 0)) return false; OSDictionary *properties = OSDynamicCast(OSDictionary, provider->getProperty("Configuration")); if (!properties) return false; status = (ApleSMCStatus *) IOMalloc(sizeof(struct AppleSMCStatus)); bzero((void*)status, sizeof(struct AppleSMCStatus)); interrupt_handler = 0; keys = OSArray::withCapacity(1); types = OSDictionary::withCapacity(0); exposedValues = OSDictionary::withCapacity(0); // Add fist key - counter key keyCounterKey = FakeSMCKey::withValue(KEY_COUNTER, TYPE_UI32, TYPE_UI32_SIZE, "\0\0\0\1"); keys->setObject(keyCounterKey); fanCounterKey = FakeSMCKey::withValue(KEY_FAN_NUMBER, TYPE_UI8, TYPE_UI8_SIZE, "\0"); keys->setObject(fanCounterKey); if (!gKeysLock) gKeysLock = IORecursiveLockAlloc(); // Load preconfigured keys FakeSMCDebugLog("loading keys..."); if (OSDictionary *dictionary = OSDynamicCast(OSDictionary, properties->getObject("Keys"))) { if (OSIterator *iterator = OSCollectionIterator::withCollection(dictionary)) { while (const OSSymbol *key = (const OSSymbol *)iterator->getNextObject()) { if (OSArray *array = OSDynamicCast(OSArray, dictionary->getObject(key))) { if (OSIterator *aiterator = OSCollectionIterator::withCollection(array)) { OSString *type = OSDynamicCast(OSString, aiterator->getNextObject()); OSData *value = OSDynamicCast(OSData, aiterator->getNextObject()); if (type && value) addKeyWithValue(key->getCStringNoCopy(), type->getCStringNoCopy(), value->getLength(), value->getBytesNoCopy()); OSSafeRelease(aiterator); } } key = 0; } OSSafeRelease(iterator); } HWSensorsInfoLog("%d preconfigured key%s added", keys->getCount(), keys->getCount() == 1 ? "" : "s"); } else { HWSensorsWarningLog("no preconfigured keys found"); } // Load wellknown type names FakeSMCDebugLog("loading types..."); if (OSDictionary *dictionary = OSDynamicCast(OSDictionary, properties->getObject("Types"))) { if (OSIterator *iterator = OSCollectionIterator::withCollection(dictionary)) { while (OSString *key = OSDynamicCast(OSString, iterator->getNextObject())) { if (OSString *value = OSDynamicCast(OSString, dictionary->getObject(key))) { types->setObject(key, value); } } OSSafeRelease(iterator); } } // Set Clover platform keys if (OSDictionary *dictionary = OSDynamicCast(OSDictionary, properties->getObject("Clover"))) { UInt32 count = 0; if (IORegistryEntry* cloverPlatformNode = fromPath("/efi/platform", gIODTPlane)) { if (OSIterator *iterator = OSCollectionIterator::withCollection(dictionary)) { while (OSString *name = OSDynamicCast(OSString, iterator->getNextObject())) { if (OSData *data = OSDynamicCast(OSData, cloverPlatformNode->getProperty(name))) { if (OSArray *items = OSDynamicCast(OSArray, dictionary->getObject(name))) { OSString *key = OSDynamicCast(OSString, items->getObject(0)); OSString *type = OSDynamicCast(OSString, items->getObject(1)); if (addKeyWithValue(key->getCStringNoCopy(), type->getCStringNoCopy(), data->getLength(), data->getBytesNoCopy())) count++; } } } OSSafeRelease(iterator); } } if (count) HWSensorsInfoLog("%d key%s exported by Clover EFI", count, count == 1 ? "" : "s"); } // Start SMC device if (!super::start(platform)) return false; this->setName("SMC"); FakeSMCSetProperty("name", "APP0001"); if (OSString *compatibleKey = OSDynamicCast(OSString, properties->getObject("smc-compatible"))) FakeSMCSetProperty("compatible", (const char *)compatibleKey->getCStringNoCopy()); else FakeSMCSetProperty("compatible", "smc-napa"); if (!this->setProperty("_STA", (unsigned long long)0x0000000b, 32)) { HWSensorsErrorLog("failed to set '_STA' property"); return false; } if (OSBoolean *debugKey = OSDynamicCast(OSBoolean, properties->getObject("debug"))) debug = debugKey->getValue(); else debug = false; if (OSBoolean *traceKey = OSDynamicCast(OSBoolean, properties->getObject("trace"))) trace = traceKey->getValue(); else trace = false; IODeviceMemory::InitElement rangeList[1]; rangeList[0].start = 0x300; rangeList[0].length = 0x20; // rangeList[1].start = 0xfef00000; // rangeList[1].length = 0x10000; if(OSArray *array = IODeviceMemory::arrayFromList(rangeList, 1)) { this->setDeviceMemory(array); OSSafeRelease(array); } else { HWSensorsFatalLog("failed to create Device memory array"); return false; } OSArray *controllers = OSArray::withCapacity(1); if(!controllers) { HWSensorsFatalLog("failed to create controllers array"); return false; } controllers->setObject((OSSymbol *)OSSymbol::withCStringNoCopy("io-apic-0")); OSArray *specifiers = OSArray::withCapacity(1); if(!specifiers) { HWSensorsFatalLog("failed to create specifiers array"); return false; } UInt64 line = 0x06; OSData *tmpData = OSData::withBytes(&line, sizeof(line)); if (!tmpData) { HWSensorsFatalLog("failed to create specifiers data"); return false; } specifiers->setObject(tmpData); this->setProperty(gIOInterruptControllersKey, controllers) && this->setProperty(gIOInterruptSpecifiersKey, specifiers); this->attachToParent(platform, gIOServicePlane); registerService(); HWSensorsInfoLog("successfully initialized"); return true; }
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 LPCSensors::start(IOService *provider) { if (!super::start(provider)) return false; OSNumber *number = OSDynamicCast(OSNumber, provider->getProperty(kSuperIOHWMAddress)); if (!number || !(address = number->unsigned16BitValue())) { HWSensorsFatalLog("wrong address provided"); return false; } number = OSDynamicCast(OSNumber, provider->getProperty(kSuperIOControlPort)); if (!number || !(port = number->unsigned8BitValue())) { HWSensorsFatalLog("wrong port provided"); return false; } number = OSDynamicCast(OSNumber, provider->getProperty(kSuperIOModelValue)); if (!number || !(model = number->unsigned16BitValue())) { HWSensorsFatalLog("wrong model provided"); return false; } OSString *string = OSDynamicCast(OSString, provider->getProperty(kSuperIOModelName)); if (!string || !(modelName = string->getCStringNoCopy())) { HWSensorsFatalLog("wrong model name provided"); return false; } string = OSDynamicCast(OSString, provider->getProperty(kSuperIOVendorName)); if (!string || !(vendorName = string->getCStringNoCopy())) { HWSensorsFatalLog("wrong vendor name provided"); return false; } if (!initialize()) return false; OSString *modelString = OSString::withCString(modelName); if (OSDictionary *configuration = getConfigurationNode(modelString)) { addTemperatureSensors(configuration); addVoltageSensors(configuration); addTachometerSensors(configuration); } else HWSensorsWarningLog("no platform profile provided"); OSSafeReleaseNULL(modelString); // woorkloop if (!(workloop = getWorkLoop())) { HWSensorsFatalLog("Failed to obtain workloop"); return false; } if (!(timerEventSource = IOTimerEventSource::timerEventSource(this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &LPCSensors::woorkloopTimerEvent)))) { HWSensorsFatalLog("failed to initialize timer event source"); return false; } if (kIOReturnSuccess != workloop->addEventSource(timerEventSource)) { HWSensorsFatalLog("failed to add timer event source into workloop"); return false; } // two power states - off and on static const IOPMPowerState powerStates[2] = { { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, IOPMDeviceUsable, IOPMPowerOn, IOPMPowerOn, 0, 0, 0, 0, 0, 0, 0, 0 } }; // register interest in power state changes PMinit(); provider->joinPMtree(this); registerPowerDriver(this, (IOPMPowerState *)powerStates, 2); registerService(); HWSensorsInfoLog("started"); return true; }
bool SuperIOPlugin::start(IOService *provider) { if (!super::start(provider)) return false; OSNumber *number = OSDynamicCast(OSNumber, provider->getProperty(kSuperIOHWMAddress)); if (!number || !(address = number->unsigned16BitValue())) { HWSensorsFatalLog("wrong address provided"); return false; } number = OSDynamicCast(OSNumber, provider->getProperty(kSuperIOControlPort)); if (!number || !(port = number->unsigned8BitValue())) { HWSensorsFatalLog("wrong port provided"); return false; } number = OSDynamicCast(OSNumber, provider->getProperty(kSuperIOModelValue)); if (!number || !(model = number->unsigned16BitValue())) { HWSensorsFatalLog("wrong model provided"); return false; } OSString *string = OSDynamicCast(OSString, provider->getProperty(kSuperIOModelName)); if (!string || !(modelName = string->getCStringNoCopy())) { HWSensorsFatalLog("wrong model name provided"); return false; } string = OSDynamicCast(OSString, provider->getProperty(kSuperIOVendorName)); if (!string || !(vendorName = string->getCStringNoCopy())) { HWSensorsFatalLog("wrong vendor name provided"); return false; } if (!initialize()) return false; OSString *modelString = OSString::withCString(modelName); if (OSDictionary *configuration = getConfigurationNode(modelString)) { addTemperatureSensors(configuration); addVoltageSensors(configuration); addTachometerSensors(configuration); } else HWSensorsWarningLog("no platform profile provided"); OSSafeReleaseNULL(modelString); registerService(); HWSensorsInfoLog("started"); return true; }