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; }
FakeSMCKey *FakeSMCDevice::addKeyWithHandler(const char *name, const char *type, unsigned char size, IOService *handler) { IORecursiveLockLock(device_lock); FakeSMCKey* key; if ((key = getKey(name))) { HWSensorsErrorLog("key %s already handled", name); if (key->getHandler() != NULL) { // TODO: check priority? HWSensorsErrorLog("key %s already handled", name); key = 0; } else { key->setType(type); key->setSize(size); key->setHandler(handler); } } else { FakeSMCDebugLog("adding key %s with handler, type: %s, size: %d", name, type, size); if ((key = FakeSMCKey::withHandler(name, type, size, handler))) { keys->setObject(key); updateKeyCounterKey(); } } IORecursiveLockUnlock(device_lock); if (!key) HWSensorsErrorLog("failed to create key %s", name); return key; }
FakeSMCKey *FakeSMCDevice::addKeyWithHandler(const char *name, const char *type, unsigned char size, IOService *handler) { if (FakeSMCKey *key = getKey(name)) { if (key->getHandler() != NULL) { // TODO: check priority? HWSensorsErrorLog("key %s already handled", name); return 0; } key->setType(type); key->setSize(size); key->setHandler(handler); return key; } FakeSMCDebugLog("adding key %s with handler, type: %s, size: %d", name, type, size); if (FakeSMCKey *key = FakeSMCKey::withHandler(name, type, size, handler)) { KEYSLOCK; keys->setObject(key); KEYSUNLOCK; updateKeyCounterKey(); return key; } HWSensorsErrorLog("failed to create key %s", name); return 0; }
FakeSMCKey *FakeSMCKeyStore::addKeyWithHandler(const char *name, const char *type, unsigned char size, FakeSMCKeyHandler *handler) { if (FakeSMCKey *key = getKey(name)) { FakeSMCKeyHandler *existedHandler = key->getHandler(); if (handler->getProbeScore() < existedHandler->getProbeScore()) { HWSensorsErrorLog("key %s already handled with prioritized handler %s", name, existedHandler ? existedHandler->getName() : "*Unreferenced*"); return 0; } else { HWSensorsInfoLog("key %s handler %s has been replaced with new prioritized handler %s", name, existedHandler ? existedHandler->getName() : "*Unreferenced*", handler ? handler->getName() : "*Unreferenced*"); } key->setType(type); key->setSize(size); key->setHandler(handler); return key; } HWSensorsDebugLog("adding key %s with handler, type: %s, size: %d", name, type, size); if (FakeSMCKey *key = FakeSMCKey::withHandler(name, type, size, handler)) { //KEYSLOCK; keys->setObject(key); //KEYSUNLOCK; updateKeyCounterKey(); return key; } HWSensorsErrorLog("failed to create key %s", name); return 0; }
void FakeSMCPlugin::stop(IOService* provider) { HWSensorsDebugLog("[stop] removing handler"); if (kIOReturnSuccess != storageProvider->callPlatformFunction(kFakeSMCRemoveKeyHandler, true, this, NULL, NULL, NULL)) HWSensorsFatalLog("failed to remove handler from storage provider"); HWSensorsDebugLog("[stop] releasing tachometers"); // Release all tachometers if (OSCollectionIterator *iterator = OSCollectionIterator::withCollection(sensors)) { while (OSString *key = OSDynamicCast(OSString, iterator->getNextObject())) { if (FakeSMCSensor *sensor = getSensor(key->getCStringNoCopy())) { if (sensor->getGroup() == kFakeSMCTachometerSensor) { UInt8 index = index_of_hex_char(sensor->getKey()[1]); HWSensorsInfoLog("releasing Fan%X", index); if (!releaseFanIndex(index)) HWSensorsErrorLog("failed to release Fan index: %d", index); } } } OSSafeRelease(iterator); } HWSensorsDebugLog("[stop] releasing sensors collection"); sensors->flushCollection(); super::stop(provider); }
SInt8 FakeSMCPlugin::takeVacantFanIndex() { SInt8 index = -1; if (kIOReturnSuccess != storageProvider->callPlatformFunction(kFakeSMCTakeVacantFanIndex, true, (void *)&index, 0, 0, 0)) HWSensorsErrorLog("failed to take Fan index"); return index; }
bool FakeSMCPlugin::releaseFanIndex(UInt8 index) { if (kIOReturnSuccess != storageProvider->callPlatformFunction(kFakeSMCReleaseFanIndex, true, (void *)&index, 0, 0, 0)) { HWSensorsErrorLog("failed to release Fan index"); return false; } return true; }
bool FakeSMCPlugin::takeGPUIndex(UInt8 index) { if (kIOReturnSuccess != storageProvider->callPlatformFunction(kFakeSMCTakeGPUIndex, true, (void *)&index, 0, 0, 0)) { HWSensorsErrorLog("failed to take GPU index %d", index); return false; } 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; }
FakeSMCKey *FakeSMCDevice::addKeyWithHandler(const char *name, const char *type, unsigned char size, IOService *handler) { KEYSLOCK; FakeSMCKey *key; if ((key = getKey(name))) { IOService *existedHandler = key->getHandler(); if (getHandlingPriority(handler) < getHandlingPriority(existedHandler)) { HWSensorsErrorLog("key %s already handled with prioritized handler %s", name, existedHandler ? existedHandler->getName() : "*Unreferenced*"); key = 0; } else { HWSensorsInfoLog("key %s handler %s has been replaced with new prioritized handler %s", name, existedHandler ? existedHandler->getName() : "*Unreferenced*", handler ? handler->getName() : "*Unreferenced*"); key->setType(type); key->setSize(size); key->setHandler(handler); } } else { FakeSMCDebugLog("adding key %s with handler, type: %s, size: %d", name, type, size); if ((key = FakeSMCKey::withHandler(name, type, size, handler))) { keys->setObject(key); updateKeyCounterKey(); } else { HWSensorsErrorLog("failed to create key %s", name); } } KEYSUNLOCK; return key; }
bool FakeSMCKeyStore::start(IOService *provider) { if (!super::start(provider)) return false; // Try to obtain OEM info from Clover EFI if (IORegistryEntry* platformNode = fromPath("/efi/platform", gIODTPlane)) { if (OSData *data = OSDynamicCast(OSData, platformNode->getProperty("OEMVendor"))) { if (OSString *vendor = OSString::withCString((char*)data->getBytesNoCopy())) { if (OSString *manufacturer = getManufacturerNameFromOEMName(vendor)) { this->setProperty(kOEMInfoManufacturer, manufacturer); OSSafeReleaseNULL(manufacturer); } //OSSafeReleaseNULL(vendor); } //OSSafeReleaseNULL(data); } if (OSData *data = OSDynamicCast(OSData, platformNode->getProperty("OEMBoard"))) { if (OSString *product = OSString::withCString((char*)data->getBytesNoCopy())) { this->setProperty(kOEMInfoProduct, product); //OSSafeReleaseNULL(product); } //OSSafeReleaseNULL(data); } } if ((!getProperty(kOEMInfoProduct) || !getProperty(kOEMInfoManufacturer)) && !setOemProperties(this)) { HWSensorsErrorLog("failed to get OEM info from Chameleon/Chimera or Clover EFI, platform profiles will be unavailable"); } if (OSString *manufacturer = OSDynamicCast(OSString, getProperty(kOEMInfoManufacturer)) ) { this->addKeyWithValue("HWS0", TYPE_CH8, manufacturer->getLength(), manufacturer->getCStringNoCopy()); } if (OSString *product = OSDynamicCast(OSString, getProperty(kOEMInfoProduct)) ) { this->addKeyWithValue("HWS1", TYPE_CH8, product->getLength(), product->getCStringNoCopy()); } IOService::publishResource(kFakeSMCKeyStoreService, this); registerService(); HWSensorsInfoLog("started"); return true; }
bool FakeSMCKey::setHandler(FakeSMCKeyHandler *newHandler) { if (handler && newHandler) { if (newHandler->getProbeScore() < handler->getProbeScore()) { HWSensorsErrorLog("key %s already handled with prioritized handler %s", key, handler->getName()); return false; } else { handler = newHandler; HWSensorsInfoLog("key %s handler %s has been replaced with new prioritized handler %s", key, handler->getName(), newHandler->getName()); } } return false; }
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 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 PTIDSensors::start(IOService * provider) { if (!super::start(provider)) return false; acpiDevice = (IOACPIPlatformDevice *)provider; if (!acpiDevice) { HWSensorsFatalLog("ACPI device not ready"); return false; } // On some computers (eg. RehabMan's ProBook 4530s), the system will hang on startup // if kernel cache is used, because of the early call to updateTemperatures and/or // updateTachometers. At least that is the case with an SSD and a valid pre-linked // kernel, along with kernel cache enabled. This 1000ms sleep seems to fix the problem, // enabling a clean boot with PTIDSensors enabled. IOSleep(1000); // 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) { if (OSArray *description = OSDynamicCast(OSArray, object)) { HWSensorsDebugLog("Parsing temperatures..."); int count = description->getCount(); for (int i = 1; i < count; i += 2) { parseTemperatureName(OSDynamicCast(OSString, description->getObject(i)), i/2); } } } else HWSensorsErrorLog("failed to evaluate TSDL table"); // Tachometers if(kIOReturnSuccess == acpiDevice->evaluateObject("OSDL", &object) && object) { if (OSArray *description = OSDynamicCast(OSArray, object)) { HWSensorsDebugLog("Parsing tachometers..."); int count = description->getCount(); for (int i = 2; i < count; i += 3) { parseTachometerName(OSDynamicCast(OSString, description->getObject(i)), OSDynamicCast(OSString, description->getObject(i-1)), i/3); } } } else HWSensorsErrorLog("failed to evaluate OSDL table"); break; } case 0x20001: { OSObject *object = NULL; // Temperatures if (kIOReturnSuccess == acpiDevice->evaluateObject("TMPV", &object) && object) { if (OSArray *description = OSDynamicCast(OSArray, object)) { HWSensorsDebugLog("Parsing temperatures..."); int count = description->getCount(); for (int i = 1; i < count; i += 3) { parseTemperatureName(OSDynamicCast(OSString, description->getObject(i)), i+1); } } } else HWSensorsErrorLog("failed to evaluate TMPV table"); // Tachometers if (kIOReturnSuccess == acpiDevice->evaluateObject("OSDV", &object) && object) { if (OSArray *description = OSDynamicCast(OSArray, object)) { HWSensorsDebugLog("Parsing tachometers..."); int count = description->getCount(); for (int i = 2; i < count; i += 4) { parseTachometerName(OSDynamicCast(OSString, description->getObject(i)), OSDynamicCast(OSString, description->getObject(i-1)), i+1); } } } else HWSensorsErrorLog("failed to evaluate OSDV table"); break; } default: HWSensorsFatalLog("usupported interface version: 0x%x", (UInt32)version); return false; } registerService(); HWSensorsInfoLog("started"); return true; }
FakeSMCKey *FakeSMCDevice::addKeyWithValue(const char *name, const char *type, unsigned char size, const void *value) { if (FakeSMCKey *key = getKey(name)) { if (type && strncmp(type, key->getType(), 4) == 0) { key->setType(type); } if (value) { key->setSize(size); key->setValueFromBuffer(value, size); } if (debug) { if (strncmp("NATJ", key->getKey(), 5) == 0) { UInt8 val = *(UInt8*)key->getValue(); switch (val) { case 0: HWSensorsInfoLog("Ninja Action Timer Job: do nothing"); break; case 1: HWSensorsInfoLog("Ninja Action Timer Job: force shutdown to S5"); break; case 2: HWSensorsInfoLog("Ninja Action Timer Job: force restart"); break; case 3: HWSensorsInfoLog("Ninja Action Timer Job: force startup"); break; default: break; } } else if (strncmp("NATi", key->getKey(), 5) == 0) { UInt16 val = *(UInt16*)key->getValue(); HWSensorsInfoLog("Ninja Action Timer is set to %d", val); } else if (strncmp("MSDW", key->getKey(), 5) == 0) { UInt8 val = *(UInt8*)key->getValue(); switch (val) { case 0: HWSensorsInfoLog("display is now asleep"); break; case 1: HWSensorsInfoLog("display is now awake"); break; default: break; } } } FakeSMCDebugLog("value updated for key %s, type: %s, size: %d", name, type, size); return key; } FakeSMCDebugLog("adding key %s with value, type: %s, size: %d", name, type, size); OSString *wellKnownType = 0; if (!type) wellKnownType = OSDynamicCast(OSString, types->getObject(name)); if (FakeSMCKey *key = FakeSMCKey::withValue(name, type ? type : wellKnownType ? wellKnownType->getCStringNoCopy() : 0, size, value)) { KEYSLOCK; keys->setObject(key); KEYSUNLOCK; updateKeyCounterKey(); return key; } HWSensorsErrorLog("failed to create key %s", name); return 0; }
bool ACPISensors::start(IOService * provider) { if (!super::start(provider)) return false; acpiDevice = (IOACPIPlatformDevice *)provider; if (!acpiDevice) { HWSensorsFatalLog("ACPI device not ready"); return false; } if (OSDictionary *configuration = getConfigurationNode()) { // Temperatures if (OSDictionary *temps = OSDynamicCast(OSDictionary, configuration->getObject("Temperatures"))) { temperatures = OSDictionary::withCapacity(0); OSCollectionIterator *iterator = OSCollectionIterator::withCollection(temps); UInt16 count = 0; while (OSString *key = OSDynamicCast(OSString, iterator->getNextObject())) { OSString *method = OSDynamicCast(OSString, temps->getObject(key)); if (method && kIOReturnSuccess == acpiDevice->validateObject(method->getCStringNoCopy())) { for (int i = 0; i < FakeSMCTemperatureCount; i++) { if (addSensorToList(temperatures, key, method, FakeSMCTemperature[i].name, FakeSMCTemperature[i].key, FakeSMCTemperature[i].type, FakeSMCTemperature[i].size, kFakeSMCTemperatureSensor, count)) { count++; break; } else HWSensorsErrorLog("Failed to register temperature sensor \"%s\" for method \"%s\"", key->getCStringNoCopy(), method->getCStringNoCopy()); } } }; if (count) HWSensorsInfoLog("%d temperature sensor%s added", count, count > 1 ? "s" : ""); } else return false; // Voltages if (OSDictionary *volts = OSDynamicCast(OSDictionary, configuration->getObject("Voltages"))) { voltages = OSDictionary::withCapacity(0); OSCollectionIterator *iterator = OSCollectionIterator::withCollection(volts); UInt16 count = 0; while (OSString *key = OSDynamicCast(OSString, iterator->getNextObject())) { OSString *method = OSDynamicCast(OSString, volts->getObject(key)); if (method && kIOReturnSuccess == acpiDevice->validateObject(method->getCStringNoCopy())) { for (int i = 0; i < FakeSMCVolatgeCount; i++) { if (addSensorToList(voltages, key, method, FakeSMCVolatge[i].name, FakeSMCVolatge[i].key, FakeSMCVolatge[i].type, FakeSMCVolatge[i].size, kFakeSMCVoltageSensor, count)) { count++; break; } else HWSensorsErrorLog("Failed to register voltage sensor \"%s\" for method \"%s\"", key->getCStringNoCopy(), method->getCStringNoCopy()); } } }; if (count) HWSensorsInfoLog("%d voltage sensor%s added", count, count > 1 ? "s" : ""); } else return false; // Tachometers if (OSDictionary *fans = OSDynamicCast(OSDictionary, configuration->getObject("Tachometers"))) { tachometers = OSDictionary::withCapacity(0); OSCollectionIterator *iterator = OSCollectionIterator::withCollection(fans); UInt16 count = 0; OSDictionary* fanNames = OSDynamicCast(OSDictionary, configuration->getObject("Fan Names")); while (OSString *key = OSDynamicCast(OSString, iterator->getNextObject())) { OSString *method = OSDynamicCast(OSString, fans->getObject(key)); if (method && kIOReturnSuccess == acpiDevice->validateObject(method->getCStringNoCopy())) { OSString* name = NULL; if (fanNames) name = OSDynamicCast(OSString, fanNames->getObject(key)); if (FakeSMCSensor *sensor = addTachometer(count, name ? name->getCStringNoCopy() : 0)) { tachometers->setObject(sensor->getKey(), method); count++; } else HWSensorsErrorLog("Failed to register tachometer sensor for method \"%s\"", method->getCStringNoCopy()); } }; if (count) HWSensorsInfoLog("%d tachometer sensor%s added", count, count > 1 ? "s" : ""); } else return false; } else HWSensorsErrorLog("no valid configuration provided"); registerService(); HWSensorsInfoLog("started"); return true; }
bool FakeSMC::init(OSDictionary *dictionary) { if (!super::init(dictionary)) return false; IOLog("HWSensors v%s Copyright %d netkas, slice, usr-sse2, kozlek, navi, THe KiNG, RehabMan. All rights reserved.\n", HWSENSORS_VERSION_STRING, 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)) { // Another try after 200 ms spin IOSleep(200); setOemProperties(this); } if (!getProperty(kOEMInfoProduct) || !getProperty(kOEMInfoManufacturer)) { HWSensorsErrorLog("failed to obtain OEM vendor & product information from DMI"); // Try to obtain OEM info from Clover EFI if (IORegistryEntry* platformNode = fromPath("/efi/platform", gIODTPlane)) { if (OSData *data = OSDynamicCast(OSData, platformNode->getProperty("OEMVendor"))) { if (OSString *vendor = OSString::withCString((char*)data->getBytesNoCopy())) { if (OSString *manufacturer = getManufacturerNameFromOEMName(vendor)) { this->setProperty(kOEMInfoManufacturer, manufacturer); //OSSafeReleaseNULL(manufacturer); } //OSSafeReleaseNULL(vendor); } //OSSafeReleaseNULL(data); } if (OSData *data = OSDynamicCast(OSData, platformNode->getProperty("OEMBoard"))) { if (OSString *product = OSString::withCString((char*)data->getBytesNoCopy())) { this->setProperty(kOEMInfoProduct, product); //OSSafeReleaseNULL(product); } //OSSafeReleaseNULL(data); } } else { HWSensorsErrorLog("failed to get OEM info from Clover EFI, specific platform profiles will be unavailable"); } } if (IORegistryEntry *efi = IORegistryEntry::fromPath("/efi", gIODTPlane)) { if (OSData *vendor = OSDynamicCast(OSData, efi->getProperty("firmware-vendor"))) { // firmware-vendor is in EFI node OSData *buffer = OSData::withCapacity(128); const unsigned char* data = static_cast<const unsigned char*>(vendor->getBytesNoCopy()); for (unsigned int index = 0; index < vendor->getLength(); index += 2) { buffer->appendByte(data[index], 1); } OSString *name = OSString::withCString(static_cast<const char *>(buffer->getBytesNoCopy())); setProperty(kFakeSMCFirmwareVendor, name); //OSSafeRelease(vendor); //OSSafeRelease(name); OSSafeRelease(buffer); } OSSafeRelease(efi); } return true; }
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 clock_get_system_nanotime((clock_sec_t*)&temperatureNextUpdate.tv_sec, (clock_nsec_t*)&temperatureNextUpdate.tv_nsec); acpiDevice->evaluateInteger("IVER", &version); if (version == 0) { OSString *name = OSDynamicCast(OSString, getProperty("IONameMatched")); 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); if (OSIterator *iterator = OSCollectionIterator::withCollection(description)) { HWSensorsDebugLog("Parsing temperatures..."); UInt32 count = 0; while (OSObject *item = iterator->getNextObject()) { parseTemperatureName(OSDynamicCast(OSString, item), count / 2); count += 2; } } } else HWSensorsErrorLog("failed to evaluate TSDL table"); // Tachometers if(kIOReturnSuccess == acpiDevice->evaluateObject("OSDL", &object) && object) { OSArray *description = OSDynamicCast(OSArray, object); if (OSIterator *iterator = OSCollectionIterator::withCollection(description)) { HWSensorsDebugLog("Parsing tachometers..."); UInt32 count = 0; while (OSObject *item = iterator->getNextObject()) { parseTachometerName(OSDynamicCast(OSString, item), count / 3); count += 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); if (OSIterator *iterator = OSCollectionIterator::withCollection(description)) { HWSensorsDebugLog("Parsing temperatures..."); UInt32 count = 0; while (OSObject *item = iterator->getNextObject()) { parseTemperatureName(OSDynamicCast(OSString, item), count + 1); count += 3; } } } else HWSensorsErrorLog("failed to evaluate TMPV table"); // Tachometers if(kIOReturnSuccess == acpiDevice->evaluateObject("OSDV", &object) && object) { OSArray *description = OSDynamicCast(OSArray, object); if (OSIterator *iterator = OSCollectionIterator::withCollection(description)) { HWSensorsDebugLog("Parsing tachometers..."); UInt32 count = 0; while (OSObject *item = iterator->getNextObject()) { parseTachometerName(OSDynamicCast(OSString, item), count + 2); count++; } } } else HWSensorsErrorLog("failed to evaluate OSDV table"); break; } default: HWSensorsFatalLog("usupported interface version: 0x%x", (UInt32)version); return false; } registerService(); HWSensorsInfoLog("started"); return true; }
FakeSMCKey *FakeSMCDevice::addKeyWithValue(const char *name, const char *type, unsigned char size, const void *value) { IORecursiveLockLock(device_lock); FakeSMCKey* key; if ((key = getKey(name))) { if (value) { key->setType(type); key->setSize(size); key->setValueFromBuffer(value, size); } if (debug) { if (strncmp("NATJ", key->getKey(), 5) == 0) { UInt8 val = *(UInt8*)key->getValue(); switch (val) { case 0: HWSensorsInfoLog("Ninja Action Timer Job: do nothing"); break; case 1: HWSensorsInfoLog("Ninja Action Timer Job: force shutdown to S5"); break; case 2: HWSensorsInfoLog("Ninja Action Timer Job: force restart"); break; case 3: HWSensorsInfoLog("Ninja Action Timer Job: force startup"); break; default: break; } } else if (strncmp("NATi", key->getKey(), 5) == 0) { UInt16 val = *(UInt16*)key->getValue(); HWSensorsInfoLog("Ninja Action Timer is set to %d", val); } else if (strncmp("MSDW", key->getKey(), 5) == 0) { UInt8 val = *(UInt8*)key->getValue(); switch (val) { case 0: HWSensorsInfoLog("display is now asleep"); break; case 1: HWSensorsInfoLog("display is now awake"); break; default: break; } } } FakeSMCDebugLog("updating value for key %s, type: %s, size: %d", name, type, size); } else { FakeSMCDebugLog("adding key %s with value, type: %s, size: %d", name, type, size); if ((key = FakeSMCKey::withValue(name, type, size, value))) { keys->setObject(key); updateKeyCounterKey(); } } IORecursiveLockUnlock(device_lock); if (!key) HWSensorsErrorLog("failed to create key %s", name); return key; }